Commit bcce9853 authored by Wes Kocher's avatar Wes Kocher
Browse files

Backed out 2 changesets (bug 1205854) for apparently breaking a bunch of...

Backed out 2 changesets (bug 1205854) for apparently breaking a bunch of reftests, causing a CLOSED TREE

Backed out changeset aa291bcfb0e8 (bug 1205854)
Backed out changeset cbd0b9619978 (bug 1205854)
parent 3d40a38f
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -212,8 +212,6 @@ cairo-mask-extends-bug.patch: bug 918671, sometimes when building a mask we woul

ft-no-subpixel-if-surface-disables.patch: bug 929451, don't use subpixel aa for ft fonts on surfaces that don't support it

win32-printing-axis-swap.patch: bug 1205854, workaround for Windows printer drivers that can't handle swapped X and Y axes

==== pixman patches ====

pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
+12 −26
Original line number Diff line number Diff line
@@ -878,15 +878,13 @@ _cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix)
  see doc/tutorial/src/singular.c.
*/

/* determine the length of the major and minor axes of a circle of the given
   radius after applying the transformation matrix. */
void
_cairo_matrix_transformed_circle_axes (const cairo_matrix_t *matrix,
				       double radius,
				       double *major,
				       double *minor)
/* determine the length of the major axis of a circle of the given radius
   after applying the transformation matrix. */
double
_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
					     double radius)
{
    double  a, b, c, d, f, g, h, i, j, k;
    double  a, b, c, d, f, g, h, i, j;

    _cairo_matrix_get_affine (matrix,
                              &a, &b,
@@ -895,29 +893,17 @@ _cairo_matrix_transformed_circle_axes (const cairo_matrix_t *matrix,

    i = a*a + b*b;
    j = c*c + d*d;
    k = a*c + b*d;

    f = 0.5 * (i + j);
    g = 0.5 * (i - j);
    h = hypot (g, k);

    if (major)
	*major = radius * sqrt (f + h);
    if (minor)
	*minor = radius * sqrt (f - h);
}
    h = a*c + b*d;

/* determine the length of the major axis of a circle of the given radius
   after applying the transformation matrix. */
double
_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
					     double radius)
{
    double major = 0.0;

    _cairo_matrix_transformed_circle_axes (matrix, radius, &major, NULL);
    return radius * sqrt (f + hypot (g, h));

    return major;
    /*
     * we don't need the minor axis length, which is
     * double min = radius * sqrt (f - sqrt (g*g+h*h));
     */
}

void
+23 −62
Original line number Diff line number Diff line
@@ -615,7 +615,6 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
    cairo_image_info_t mime_info;
    cairo_bool_t use_mime;
    DWORD mime_type;
    cairo_bool_t axis_swap;

    /* If we can't use StretchDIBits with this surface, we can't do anything
     * here.
@@ -664,38 +663,19 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf

    use_mime = (status == CAIRO_STATUS_SUCCESS);

    m = pattern->base.matrix;
    status = cairo_matrix_invert (&m);
    /* _cairo_pattern_set_matrix guarantees invertibility */
    assert (status == CAIRO_STATUS_SUCCESS);
    cairo_matrix_multiply (&m, &m, &surface->ctm);
    cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
    /* Check if the matrix swaps the X and Y axes by checking if the diagonal
     * is effectively zero. This can happen, for example, if it was composed
     * with a rotation such as a landscape transform. Some printing devices
     * don't support such transforms in StretchDIBits.
     */
    axis_swap = fabs (m.xx*image->width) < 1 && fabs (m.yy*image->height) < 1;

    if (!use_mime && (image->format != CAIRO_FORMAT_RGB24 || axis_swap)) {
    if (!use_mime && image->format != CAIRO_FORMAT_RGB24) {
	cairo_surface_t *opaque_surface;
	cairo_surface_pattern_t image_pattern;
	cairo_solid_pattern_t background_pattern;
	int width = image->width, height = image->height;

	if (axis_swap) {
	    width = image->height;
	    height = image->width;
	}
	opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
						     width,
						     height);
						     image->width,
						     image->height);
	if (opaque_surface->status) {
	    status = opaque_surface->status;
	    goto CLEANUP_OPAQUE_IMAGE;
	}

	if (image->format != CAIRO_FORMAT_RGB24) {
	_cairo_pattern_init_solid (&background_pattern,
				   background_color);
	status = _cairo_surface_paint (opaque_surface,
@@ -704,15 +684,8 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
				       NULL);
	if (status)
	    goto CLEANUP_OPAQUE_IMAGE;
	}

	_cairo_pattern_init_for_surface (&image_pattern, &image->base);
	if (axis_swap) {
	    /* swap the X and Y axes to undo the axis swap in the matrix */
	    cairo_matrix_t swap_xy = { 0, 1, 1, 0, 0, 0 };
	    cairo_pattern_set_matrix (&image_pattern.base, &swap_xy);
	    cairo_matrix_multiply (&m, &swap_xy, &m);
	}
	status = _cairo_surface_paint (opaque_surface,
				       CAIRO_OPERATOR_OVER,
				       &image_pattern.base,
@@ -738,6 +711,13 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
    bi.bmiHeader.biClrUsed = 0;
    bi.bmiHeader.biClrImportant = 0;

    m = pattern->base.matrix;
    status = cairo_matrix_invert (&m);
    /* _cairo_pattern_set_matrix guarantees invertibility */
    assert (status == CAIRO_STATUS_SUCCESS);

    cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
    cairo_matrix_multiply(&m, &m, &surface->ctm);
    SaveDC (surface->dc);
    _cairo_matrix_to_win32_xform (&m, &xform);

@@ -1285,7 +1265,6 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
    cairo_matrix_t mat;
    double scale;
    double scaled_width;
    double major, minor;

    status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
    if (status)
@@ -1376,30 +1355,12 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
     */
    SaveDC (surface->dc);

    /* Some printers don't handle transformed strokes. Avoid the transform
     * if not required for the pen shape. Use the SVD here to find the major
     * and minor scales then check if they differ by more than 1 device unit.
     * If the difference is smaller, then just treat the scaling as uniform.
     * This check ignores rotations as the pen shape is symmetric before
     * transformation.
     */
    _cairo_matrix_transformed_circle_axes (&mat, scale, &major, &minor);
    if (fabs (major - minor) > 1) {
	/* Check if the matrix swaps the X and Y axes such that the diagonal
	 * is nearly zero. This was observed to cause problems with XPS export.
	 */
	if (fabs (mat.xx) < 1e-6 && fabs (mat.yy) < 1e-6) {
	    /* swap the X and Y axes to undo the axis swap in the matrix */
	    cairo_matrix_t swap_xy = { 0, 1, 1, 0, 0, 0 };
	    cairo_matrix_multiply (&mat, &swap_xy, &mat);
	}
    _cairo_matrix_to_win32_xform (&mat, &xform);
    xform.eDx = 0.0f;
    xform.eDy = 0.0f;

    if (!ModifyWorldTransform (surface->dc, &xform, MWT_LEFTMULTIPLY))
	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform");
    }

    if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
	StrokePath (surface->dc);
+0 −6
Original line number Diff line number Diff line
@@ -2120,12 +2120,6 @@ _cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix);
cairo_private cairo_bool_t
_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix) cairo_pure;

cairo_private void
_cairo_matrix_transformed_circle_axes (const cairo_matrix_t *matrix,
				       double radius,
				       double *major,
				       double *minor) cairo_pure;

cairo_private double
_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
					     double radius) cairo_pure;
+0 −292
Original line number Diff line number Diff line
# HG changeset patch
# User Lee Salzman <lsalzman@mozilla.com>
# Date 1444853724 14400
#      Wed Oct 14 16:15:24 2015 -0400
# Node ID 16f823e9271803a54a0f98f47fdb268cd67f858c
# Parent  833c3c37daa6a88494d227e4819535fc337e5704
workaround for Windows printer drivers that can't handle swapped X and Y axes

diff --git a/gfx/cairo/cairo/src/cairo-matrix.c b/gfx/cairo/cairo/src/cairo-matrix.c
--- a/gfx/cairo/cairo/src/cairo-matrix.c
+++ b/gfx/cairo/cairo/src/cairo-matrix.c
@@ -873,42 +873,56 @@ cairo_bool_t
   (Note that the minor axis length is at the minimum of the above solution,
   which is just sqrt ( f - sqrt(g² + h²) ) given the symmetry of (D)).
 
 
   For another derivation of the same result, using Singular Value Decomposition,
   see doc/tutorial/src/singular.c.
 */
 
-/* determine the length of the major axis of a circle of the given radius
-   after applying the transformation matrix. */
-double
-_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
-					     double radius)
+/* determine the length of the major and minor axes of a circle of the given
+   radius after applying the transformation matrix. */
+void
+_cairo_matrix_transformed_circle_axes (const cairo_matrix_t *matrix,
+				       double radius,
+				       double *major,
+				       double *minor)
 {
-    double  a, b, c, d, f, g, h, i, j;
+    double  a, b, c, d, f, g, h, i, j, k;
 
     _cairo_matrix_get_affine (matrix,
                               &a, &b,
                               &c, &d,
                               NULL, NULL);
 
     i = a*a + b*b;
     j = c*c + d*d;
+    k = a*c + b*d;
 
     f = 0.5 * (i + j);
     g = 0.5 * (i - j);
-    h = a*c + b*d;
+    h = hypot (g, k);
 
-    return radius * sqrt (f + hypot (g, h));
+    if (major)
+	*major = radius * sqrt (f + h);
+    if (minor)
+	*minor = radius * sqrt (f - h);
+}
 
-    /*
-     * we don't need the minor axis length, which is
-     * double min = radius * sqrt (f - sqrt (g*g+h*h));
-     */
+/* determine the length of the major axis of a circle of the given radius
+   after applying the transformation matrix. */
+double
+_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
+					     double radius)
+{
+    double major = 0.0;
+
+    _cairo_matrix_transformed_circle_axes (matrix, radius, &major, NULL);
+
+    return major;
 }
 
 void
 _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
 				pixman_transform_t	*pixman_transform,
 				double xc,
 				double yc)
 {
diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
@@ -610,16 +610,17 @@ static cairo_status_t
     int x_tile, y_tile, left, right, top, bottom;
     RECT clip;
     const cairo_color_t *background_color;
     const unsigned char *mime_data;
     unsigned long mime_size;
     cairo_image_info_t mime_info;
     cairo_bool_t use_mime;
     DWORD mime_type;
+    cairo_bool_t axis_swap;
 
     /* If we can't use StretchDIBits with this surface, we can't do anything
      * here.
      */
     if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (surface->content == CAIRO_CONTENT_COLOR_ALPHA)
@@ -658,39 +659,65 @@ static cairo_status_t
 							  &mime_size,
 							  &mime_info);
     }
     if (_cairo_status_is_error (status))
 	return status;
 
     use_mime = (status == CAIRO_STATUS_SUCCESS);
 
-    if (!use_mime && image->format != CAIRO_FORMAT_RGB24) {
+    m = pattern->base.matrix;
+    status = cairo_matrix_invert (&m);
+    /* _cairo_pattern_set_matrix guarantees invertibility */
+    assert (status == CAIRO_STATUS_SUCCESS);
+    cairo_matrix_multiply (&m, &m, &surface->ctm);
+    cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
+    /* Check if the matrix swaps the X and Y axes by checking if the diagonal
+     * is effectively zero. This can happen, for example, if it was composed
+     * with a rotation such as a landscape transform. Some printing devices
+     * don't support such transforms in StretchDIBits.
+     */
+    axis_swap = fabs (m.xx*image->width) < 1 && fabs (m.yy*image->height) < 1;
+
+    if (!use_mime && (image->format != CAIRO_FORMAT_RGB24 || axis_swap)) {
 	cairo_surface_t *opaque_surface;
 	cairo_surface_pattern_t image_pattern;
 	cairo_solid_pattern_t background_pattern;
+	int width = image->width, height = image->height;
 
+	if (axis_swap) {
+	    width = image->height;
+	    height = image->width;
+	}
 	opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
-						     image->width,
-						     image->height);
+						     width,
+						     height);
 	if (opaque_surface->status) {
 	    status = opaque_surface->status;
 	    goto CLEANUP_OPAQUE_IMAGE;
 	}
 
-	_cairo_pattern_init_solid (&background_pattern,
-				   background_color);
-	status = _cairo_surface_paint (opaque_surface,
-				       CAIRO_OPERATOR_SOURCE,
-				       &background_pattern.base,
-				       NULL);
-	if (status)
-	    goto CLEANUP_OPAQUE_IMAGE;
+	if (image->format != CAIRO_FORMAT_RGB24) {
+	    _cairo_pattern_init_solid (&background_pattern,
+				       background_color);
+	    status = _cairo_surface_paint (opaque_surface,
+					   CAIRO_OPERATOR_SOURCE,
+					   &background_pattern.base,
+					   NULL);
+	    if (status)
+		goto CLEANUP_OPAQUE_IMAGE;
+	}
 
 	_cairo_pattern_init_for_surface (&image_pattern, &image->base);
+	if (axis_swap) {
+	    /* swap the X and Y axes to undo the axis swap in the matrix */
+	    cairo_matrix_t swap_xy = { 0, 1, 1, 0, 0, 0 };
+	    cairo_pattern_set_matrix (&image_pattern.base, &swap_xy);
+	    cairo_matrix_multiply (&m, &swap_xy, &m);
+	}
 	status = _cairo_surface_paint (opaque_surface,
 				       CAIRO_OPERATOR_OVER,
 				       &image_pattern.base,
 				       NULL);
 	_cairo_pattern_fini (&image_pattern.base);
 	if (status)
 	    goto CLEANUP_OPAQUE_IMAGE;
 
@@ -706,23 +733,16 @@ static cairo_status_t
     bi.bmiHeader.biXPelsPerMeter = PELS_72DPI;
     bi.bmiHeader.biYPelsPerMeter = PELS_72DPI;
     bi.bmiHeader.biPlanes = 1;
     bi.bmiHeader.biBitCount = 32;
     bi.bmiHeader.biCompression = use_mime ? mime_type : BI_RGB;
     bi.bmiHeader.biClrUsed = 0;
     bi.bmiHeader.biClrImportant = 0;
 
-    m = pattern->base.matrix;
-    status = cairo_matrix_invert (&m);
-    /* _cairo_pattern_set_matrix guarantees invertibility */
-    assert (status == CAIRO_STATUS_SUCCESS);
-
-    cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
-    cairo_matrix_multiply(&m, &m, &surface->ctm);
     SaveDC (surface->dc);
     _cairo_matrix_to_win32_xform (&m, &xform);
 
     if (! SetWorldTransform (surface->dc, &xform)) {
 	status = _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_image_pattern");
 	goto CLEANUP_OPAQUE_IMAGE;
     }
 
@@ -1260,16 +1280,17 @@ static cairo_int_status_t
     DWORD pen_width;
     DWORD *dash_array;
     HGDIOBJ obj;
     unsigned int i;
     cairo_solid_pattern_t clear;
     cairo_matrix_t mat;
     double scale;
     double scaled_width;
+    double major, minor;
 
     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     if (status)
 	return status;
 
     if (op == CAIRO_OPERATOR_CLEAR) {
 	_cairo_win32_printing_surface_init_clear_color (surface, &clear);
 	source = (cairo_pattern_t*) &clear;
@@ -1350,22 +1371,40 @@ static cairo_int_status_t
     if (status)
 	return status;
 
     /*
      * Switch to user space to set line parameters
      */
     SaveDC (surface->dc);
 
-    _cairo_matrix_to_win32_xform (&mat, &xform);
-    xform.eDx = 0.0f;
-    xform.eDy = 0.0f;
+    /* Some printers don't handle transformed strokes. Avoid the transform
+     * if not required for the pen shape. Use the SVD here to find the major
+     * and minor scales then check if they differ by more than 1 device unit.
+     * If the difference is smaller, then just treat the scaling as uniform.
+     * This check ignores rotations as the pen shape is symmetric before
+     * transformation.
+     */
+    _cairo_matrix_transformed_circle_axes (&mat, scale, &major, &minor);
+    if (fabs (major - minor) > 1) {
+	/* Check if the matrix swaps the X and Y axes such that the diagonal
+	 * is nearly zero. This was observed to cause problems with XPS export.
+	 */
+	if (fabs (mat.xx) < 1e-6 && fabs (mat.yy) < 1e-6) {
+	    /* swap the X and Y axes to undo the axis swap in the matrix */
+	    cairo_matrix_t swap_xy = { 0, 1, 1, 0, 0, 0 };
+	    cairo_matrix_multiply (&mat, &swap_xy, &mat);
+	}
+	_cairo_matrix_to_win32_xform (&mat, &xform);
+	xform.eDx = 0.0f;
+	xform.eDy = 0.0f;
 
-    if (!ModifyWorldTransform (surface->dc, &xform, MWT_LEFTMULTIPLY))
-	return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform");
+	if (!ModifyWorldTransform (surface->dc, &xform, MWT_LEFTMULTIPLY))
+	    return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform");
+    }
 
     if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
 	StrokePath (surface->dc);
     } else {
 	if (!WidenPath (surface->dc))
 	    return _cairo_win32_print_gdi_error ("_win32_surface_stroke:WidenPath");
 	if (!SelectClipPath (surface->dc, RGN_AND))
 	    return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectClipPath");
diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -2115,16 +2115,22 @@ cairo_private cairo_bool_t
 				     int *itx, int *ity);
 
 cairo_private cairo_bool_t
 _cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix);
 
 cairo_private cairo_bool_t
 _cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix) cairo_pure;
 
+cairo_private void
+_cairo_matrix_transformed_circle_axes (const cairo_matrix_t *matrix,
+				       double radius,
+				       double *major,
+				       double *minor) cairo_pure;
+
 cairo_private double
 _cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
 					     double radius) cairo_pure;
 
 cairo_private void
 _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
 				pixman_transform_t	*pixman_transform,
 				double                   xc,