|
|
76f8c5 |
--- poppler-0.26.5/poppler/CairoOutputDev.cc
|
|
|
76f8c5 |
+++ poppler-0.26.5/poppler/CairoOutputDev.cc
|
|
|
76f8c5 |
@@ -837,11 +837,17 @@ GBool CairoOutputDev::tilingPatternFill(
|
|
|
76f8c5 |
cairo_pattern_t *pattern;
|
|
|
76f8c5 |
cairo_surface_t *surface;
|
|
|
76f8c5 |
cairo_matrix_t matrix;
|
|
|
76f8c5 |
+ cairo_matrix_t pattern_matrix;
|
|
|
76f8c5 |
cairo_t *old_cairo;
|
|
|
76f8c5 |
double xMin, yMin, xMax, yMax;
|
|
|
76f8c5 |
double width, height;
|
|
|
76f8c5 |
+ double scaleX, scaleY;
|
|
|
76f8c5 |
int surface_width, surface_height;
|
|
|
76f8c5 |
StrokePathClip *strokePathTmp;
|
|
|
76f8c5 |
+ GBool adjusted_stroke_width_tmp;
|
|
|
76f8c5 |
+ cairo_pattern_t *maskTmp;
|
|
|
76f8c5 |
+ double xoffset, yoffset;
|
|
|
76f8c5 |
+ double det;
|
|
|
76f8c5 |
|
|
|
76f8c5 |
width = bbox[2] - bbox[0];
|
|
|
76f8c5 |
height = bbox[3] - bbox[1];
|
|
|
76f8c5 |
@@ -850,8 +856,20 @@ GBool CairoOutputDev::tilingPatternFill(
|
|
|
76f8c5 |
return gFalse;
|
|
|
76f8c5 |
/* TODO: implement the other cases here too */
|
|
|
76f8c5 |
|
|
|
76f8c5 |
- surface_width = (int) ceil (width);
|
|
|
76f8c5 |
- surface_height = (int) ceil (height);
|
|
|
76f8c5 |
+ // Find the width and height of the transformed pattern
|
|
|
76f8c5 |
+ cairo_get_matrix (cairo, &matrix);
|
|
|
76f8c5 |
+ cairo_matrix_init (&pattern_matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
|
|
|
76f8c5 |
+ cairo_matrix_multiply (&matrix, &matrix, &pattern_matrix);
|
|
|
76f8c5 |
+
|
|
|
76f8c5 |
+ double widthX = width, widthY = 0;
|
|
|
76f8c5 |
+ cairo_matrix_transform_distance (&matrix, &widthX, &widthY);
|
|
|
76f8c5 |
+ surface_width = ceil (sqrt (widthX * widthX + widthY * widthY));
|
|
|
76f8c5 |
+
|
|
|
76f8c5 |
+ double heightX = 0, heightY = height;
|
|
|
76f8c5 |
+ cairo_matrix_transform_distance (&matrix, &heightX, &heightY);
|
|
|
76f8c5 |
+ surface_height = ceil (sqrt (heightX * heightX + heightY * heightY));
|
|
|
76f8c5 |
+ scaleX = surface_width / width;
|
|
|
76f8c5 |
+ scaleY = surface_height / height;
|
|
|
76f8c5 |
|
|
|
76f8c5 |
surface = cairo_surface_create_similar (cairo_get_target (cairo),
|
|
|
76f8c5 |
CAIRO_CONTENT_COLOR_ALPHA,
|
|
|
76f8c5 |
@@ -865,9 +883,15 @@ GBool CairoOutputDev::tilingPatternFill(
|
|
|
76f8c5 |
|
|
|
76f8c5 |
box.x1 = bbox[0]; box.y1 = bbox[1];
|
|
|
76f8c5 |
box.x2 = bbox[2]; box.y2 = bbox[3];
|
|
|
76f8c5 |
+ cairo_scale (cairo, scaleX, scaleY);
|
|
|
76f8c5 |
+ cairo_translate (cairo, -box.x1, -box.y1);
|
|
|
76f8c5 |
+
|
|
|
76f8c5 |
strokePathTmp = strokePathClip;
|
|
|
76f8c5 |
- strokePathClip = NULL;
|
|
|
76f8c5 |
- gfx = new Gfx(doc, this, resDict, &box, NULL, NULL, NULL, gfxA->getXRef());
|
|
|
76f8c5 |
+ strokePathClip = NULL;
|
|
|
76f8c5 |
+ adjusted_stroke_width_tmp = adjusted_stroke_width;
|
|
|
76f8c5 |
+ maskTmp = mask;
|
|
|
76f8c5 |
+ mask = NULL;
|
|
|
76f8c5 |
+ gfx = new Gfx(doc, this, resDict, &box, NULL, NULL, NULL, gfxA->getXRef());
|
|
|
76f8c5 |
if (paintType == 2)
|
|
|
76f8c5 |
inUncoloredPattern = gTrue;
|
|
|
76f8c5 |
gfx->display(str);
|
|
|
76f8c5 |
@@ -875,6 +899,8 @@ GBool CairoOutputDev::tilingPatternFill(
|
|
|
76f8c5 |
inUncoloredPattern = gFalse;
|
|
|
76f8c5 |
delete gfx;
|
|
|
76f8c5 |
strokePathClip = strokePathTmp;
|
|
|
76f8c5 |
+ adjusted_stroke_width = adjusted_stroke_width_tmp;
|
|
|
76f8c5 |
+ mask = maskTmp;
|
|
|
76f8c5 |
|
|
|
76f8c5 |
pattern = cairo_pattern_create_for_surface (cairo_get_target (cairo));
|
|
|
76f8c5 |
cairo_destroy (cairo);
|
|
|
76f8c5 |
@@ -882,14 +908,23 @@ GBool CairoOutputDev::tilingPatternFill(
|
|
|
76f8c5 |
if (cairo_pattern_status (pattern))
|
|
|
76f8c5 |
return gFalse;
|
|
|
76f8c5 |
|
|
|
76f8c5 |
+ det = pmat[0] * pmat[3] - pmat[1] * pmat[2];
|
|
|
76f8c5 |
+ if (fabs(det) < 0.000001)
|
|
|
76f8c5 |
+ return gFalse;
|
|
|
76f8c5 |
+
|
|
|
76f8c5 |
+ xoffset = round ((pmat[3] * pmat[4] - pmat[2] * pmat[5]) / (xStep * det));
|
|
|
76f8c5 |
+ yoffset = - round ((pmat[1] * pmat[4] - pmat[0] * pmat[5]) / (yStep * det));
|
|
|
76f8c5 |
+ pattern_matrix.x0 -= xoffset * pattern_matrix.xx * xStep + yoffset * pattern_matrix.xy * yStep;
|
|
|
76f8c5 |
+ pattern_matrix.y0 -= xoffset * pattern_matrix.yx * xStep + yoffset * pattern_matrix.yy * yStep;
|
|
|
76f8c5 |
+
|
|
|
76f8c5 |
state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
|
|
|
76f8c5 |
cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
|
|
|
76f8c5 |
|
|
|
76f8c5 |
- cairo_matrix_init_scale (&matrix, surface_width / width, surface_height / height);
|
|
|
76f8c5 |
+ cairo_matrix_init_scale (&matrix, scaleX, scaleY);
|
|
|
76f8c5 |
+ cairo_matrix_translate (&matrix, -box.x1, -box.y1);
|
|
|
76f8c5 |
cairo_pattern_set_matrix (pattern, &matrix);
|
|
|
76f8c5 |
|
|
|
76f8c5 |
- cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
|
|
|
76f8c5 |
- cairo_transform (cairo, &matrix);
|
|
|
76f8c5 |
+ cairo_transform (cairo, &pattern_matrix);
|
|
|
76f8c5 |
cairo_set_source (cairo, pattern);
|
|
|
76f8c5 |
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
|
|
|
76f8c5 |
if (strokePathClip) {
|