From 9fc02b1f7a30f730127ab348d7ceb05f1704f91e Mon Sep 17 00:00:00 2001 From: Jason Crain Date: Fri, 22 Aug 2014 00:51:36 -0500 Subject: [PATCH] cairo: Scale radial pattern Scale the radial pattern because cairo/pixman do not work well with a very large or small scaled matrix. See cairo bug #81657. bug #22098 --- poppler/CairoOutputDev.cc | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 1c67b5c..64d8c21 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -934,18 +934,32 @@ GBool CairoOutputDev::axialShadedSupportExtend(GfxState *state, GfxAxialShading GBool CairoOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) { double x0, y0, r0, x1, y1, r1; double dx, dy, dr; + cairo_matrix_t matrix; + double scale; shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); dx = x1 - x0; dy = y1 - y0; dr = r1 - r0; + + // Cairo/pixman do not work well with a very large or small scaled + // matrix. See cairo bug #81657. + // + // As a workaround, scale the pattern by the average of the vertical + // and horizontal scaling of the current transformation matrix. + cairo_get_matrix(cairo, &matrix); + scale = (sqrt(matrix.xx * matrix.xx + matrix.yx * matrix.yx) + + sqrt(matrix.xy * matrix.xy + matrix.yy * matrix.yy)) / 2; + cairo_matrix_init_scale(&matrix, scale, scale); + cairo_pattern_destroy(fill_pattern); - fill_pattern = cairo_pattern_create_radial (x0 + sMin * dx, - y0 + sMin * dy, - r0 + sMin * dr, - x0 + sMax * dx, - y0 + sMax * dy, - r0 + sMax * dr); + fill_pattern = cairo_pattern_create_radial ((x0 + sMin * dx) * scale, + (y0 + sMin * dy) * scale, + (r0 + sMin * dr) * scale, + (x0 + sMax * dx) * scale, + (y0 + sMax * dy) * scale, + (r0 + sMax * dr) * scale); + cairo_pattern_set_matrix(fill_pattern, &matrix); if (shading->getExtend0() && shading->getExtend1()) cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD); else -- 2.1.0.rc1