Commit 9c3b18b8 authored by Marek Kasik's avatar Marek Kasik Committed by Albert Astals Cid

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
parent 02ec7a70
......@@ -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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment