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