poppler/CairoOutputDev.cc |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

New commits:
commit 9c3b18b8741f6e68711ce807459504493d6a0be0
Author: Marek Kasik <mka...@redhat.com>
Date:   Fri Apr 6 15:06:46 2018 +0200

    cairo: Fix tiling patterns when pattern cell is too far
    
    Rendering of tiling pattern which has pattern matrix moving pattern cell
    far away can fail on allocation of memory. This commit solves the issue by
    modifying of cairo pattern matrix so that its offset is closer to the path
    filled by the pattern.
    
    Fixes #190

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 63e49c7a..231b9ab2 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -973,6 +973,26 @@ bool CairoOutputDev::tilingPatternFill(GfxState *state, 
Gfx *gfxA, Catalog *cat,
   if (cairo_pattern_status (pattern))
     return false;
 
+  // Cairo can fail if the pattern translation is too large. Fix by making the
+  // translation smaller.
+  const double det = pmat[0] * pmat[3] - pmat[1] * pmat[2];
+
+  // Find the number of repetitions of pattern we need to shift by. Transform
+  // the translation component of pmat (pmat[4] and pmat[5]) into the pattern's
+  // coordinate system by multiplying by inverse of pmat, then divide by
+  // pattern size (xStep and yStep).
+  const double xoffset = round ((pmat[3] * pmat[4] - pmat[2] * pmat[5]) / 
(xStep * det));
+  const double yoffset = - round ((pmat[1] * pmat[4] - pmat[0] * pmat[5]) / 
(yStep * det));
+
+  if (!std::isfinite(xoffset) || !std::isfinite(yoffset)) {
+    error(errSyntaxWarning, -1, "CairoOutputDev: Singular matrix in 
tilingPatternFill");
+    return false;
+  }
+
+  // Shift pattern_matrix by multiples of the pattern size.
+  pattern_matrix.x0 -= xoffset * pattern_matrix.xx * xStep + yoffset * 
pattern_matrix.xy * yStep;
+  pattern_matrix.y0 -= xoffset * pattern_matrix.yx * xStep + yoffset * 
pattern_matrix.yy * yStep;
+
   state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
   cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
 
_______________________________________________
poppler mailing list
poppler@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to