summaryrefslogtreecommitdiff
path: root/gfx/cairo/win32-printing-axis-swap.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/win32-printing-axis-swap.patch')
-rw-r--r--gfx/cairo/win32-printing-axis-swap.patch292
1 files changed, 0 insertions, 292 deletions
diff --git a/gfx/cairo/win32-printing-axis-swap.patch b/gfx/cairo/win32-printing-axis-swap.patch
deleted file mode 100644
index 87a1a91e41..0000000000
--- a/gfx/cairo/win32-printing-axis-swap.patch
+++ /dev/null
@@ -1,292 +0,0 @@
-# HG changeset patch
-# User Lee Salzman <lsalzman@mozilla.com>
-# Date 1445463645 14400
-# Wed Oct 21 17:40:45 2015 -0400
-# Node ID 9e84563cbd73c5b0993dfd018ca25b660b667e94
-# Parent 2d3fd51c4182c253a2f102655e8e9e466032853f
-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;
-+
-+ _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_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,