From eceed28ec761fee4331f9c0cc4f9521dfa1b761c Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Thu, 13 Aug 2009 14:48:10 +0200 Subject: [PATCH] Change OutputDev::tilingPatternFill to return a GBool It allows outputdevs to decide whether render the pattern or not depending on the parameters, like shaded patterns currently do. --- poppler/Gfx.cc | 42 ++++++++++++++++++++++++------------------ poppler/OutputDev.h | 11 ++++++----- poppler/PSOutputDev.cc | 12 +++++++----- poppler/PSOutputDev.h | 10 +++++----- 4 files changed, 42 insertions(+), 33 deletions(-) diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index ccf818a..5872c07 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -1832,6 +1832,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, int xi0, yi0, xi1, yi1, xi, yi; double *ctm, *btm, *ptm; double m[6], ictm[6], m1[6], imb[6]; + double m1x, m1y; double det; double xstep, ystep; int i; @@ -1927,7 +1928,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, // get the clip region, check for empty state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); if (cxMin > cxMax || cyMin > cyMax) { - goto err; + goto restore; } // transform clip region bbox to pattern space @@ -1982,30 +1983,35 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, for (i = 0; i < 4; ++i) { m1[i] = m[i]; } - if (out->useTilingPatternFill()) { + if (!contentIsHidden()) { + m1x = m1[4]; + m1y = m1[5]; m1[4] = m[4]; m1[5] = m[5]; - if (!contentIsHidden()) { - out->tilingPatternFill(state, tPat->getContentStream(), - tPat->getPaintType(), tPat->getResDict(), - m1, tPat->getBBox(), - xi0, yi0, xi1, yi1, xstep, ystep); - } - } else { - for (yi = yi0; yi < yi1; ++yi) { - for (xi = xi0; xi < xi1; ++xi) { - x = xi * xstep; - y = yi * ystep; - m1[4] = x * m[0] + y * m[2] + m[4]; - m1[5] = x * m[1] + y * m[3] + m[5]; - doForm1(tPat->getContentStream(), tPat->getResDict(), - m1, tPat->getBBox()); + if (out->useTilingPatternFill() && + out->tilingPatternFill(state, tPat->getContentStream(), + tPat->getPaintType(), tPat->getResDict(), + m1, tPat->getBBox(), + xi0, yi0, xi1, yi1, xstep, ystep)) { + goto restore; + } else { + m1[4] = m1x; + m1[5] = m1y; + for (yi = yi0; yi < yi1; ++yi) { + for (xi = xi0; xi < xi1; ++xi) { + x = xi * xstep; + y = yi * ystep; + m1[4] = x * m[0] + y * m[2] + m[4]; + m1[5] = x * m[1] + y * m[3] + m[5]; + doForm1(tPat->getContentStream(), tPat->getResDict(), + m1, tPat->getBBox()); + } } } } // restore graphics state - err: + restore: restoreState(); state->setPath(savedPath); } diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index ffd91a0..4f98b81 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -190,11 +190,12 @@ public: virtual void stroke(GfxState * /*state*/) {} virtual void fill(GfxState * /*state*/) {} virtual void eoFill(GfxState * /*state*/) {} - virtual void tilingPatternFill(GfxState * /*state*/, Object * /*str*/, - int /*paintType*/, Dict * /*resDict*/, - double * /*mat*/, double * /*bbox*/, - int /*x0*/, int /*y0*/, int /*x1*/, int /*y1*/, - double /*xStep*/, double /*yStep*/) {} + virtual GBool tilingPatternFill(GfxState * /*state*/, Object * /*str*/, + int /*paintType*/, Dict * /*resDict*/, + double * /*mat*/, double * /*bbox*/, + int /*x0*/, int /*y0*/, int /*x1*/, int /*y1*/, + double /*xStep*/, double /*yStep*/) + { return gFalse; } virtual GBool functionShadedFill(GfxState * /*state*/, GfxFunctionShading * /*shading*/) { return gFalse; } diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index bebe48a..6dcf06b 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -3752,11 +3752,11 @@ void PSOutputDev::eoFill(GfxState *state) { writePS("f*\n"); } -void PSOutputDev::tilingPatternFill(GfxState *state, Object *str, - int paintType, Dict *resDict, - double *mat, double *bbox, - int x0, int y0, int x1, int y1, - double xStep, double yStep) { +GBool PSOutputDev::tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep) { PDFRectangle box; Gfx *gfx; @@ -3814,6 +3814,8 @@ void PSOutputDev::tilingPatternFill(GfxState *state, Object *str, writePSFmt("{0:d} 1 {1:d} {{ {2:.4g} exch {3:.4g} mul m {4:d} 1 {5:d} {{ pop (x) show }} for }} for\n", y0, y1 - 1, x0 * xStep, yStep, x0, x1 - 1); writePS("grestore\n"); + + return gTrue; } GBool PSOutputDev::functionShadedFill(GfxState *state, diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index e8bf29f..d364777 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -209,11 +209,11 @@ public: virtual void stroke(GfxState *state); virtual void fill(GfxState *state); virtual void eoFill(GfxState *state); - virtual void tilingPatternFill(GfxState *state, Object *str, - int paintType, Dict *resDict, - double *mat, double *bbox, - int x0, int y0, int x1, int y1, - double xStep, double yStep); + virtual GBool tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep); virtual GBool functionShadedFill(GfxState *state, GfxFunctionShading *shading); virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/); -- 1.6.0.4 From aeee9438a16a5a2374246949016c7b7060f7d99b Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Thu, 13 Aug 2009 14:51:58 +0200 Subject: [PATCH] [cairo] Implement tiling patterns in cairo backend Fixes bug #13518 for the cairo backend. --- poppler/CairoOutputDev.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++ poppler/CairoOutputDev.h | 10 ++++++++ 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index af92776..19d1245 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -45,8 +45,10 @@ #include "GlobalParams.h" #include "Error.h" #include "Object.h" +#include "Gfx.h" #include "GfxState.h" #include "GfxFont.h" +#include "Page.h" #include "Link.h" #include "CharCodeToUnicode.h" #include "FontEncodingTables.h" @@ -657,6 +659,60 @@ void CairoOutputDev::eoFill(GfxState *state) { } +GBool CairoOutputDev::tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep) +{ + PDFRectangle box; + Gfx *gfx; + cairo_pattern_t *pattern; + cairo_surface_t *surface; + cairo_matrix_t matrix; + cairo_t *old_cairo; + double xMin, yMin, xMax, yMax; + + if (xStep != bbox[2] || yStep != bbox[3]) + return gFalse; + /* TODO: implement the other cases here too */ + + surface = cairo_surface_create_similar (cairo_get_target (cairo), + CAIRO_CONTENT_COLOR_ALPHA, + bbox[2], bbox[3]); + if (cairo_surface_status (surface)) + return gFalse; + + old_cairo = cairo; + cairo = cairo_create (surface); + cairo_surface_destroy (surface); + + box.x1 = bbox[0]; box.y1 = bbox[1]; + box.x2 = bbox[2]; box.y2 = bbox[3]; + gfx = new Gfx(xref, this, resDict, catalog, &box, NULL); + gfx->display(str); + delete gfx; + + pattern = cairo_pattern_create_for_surface (cairo_get_target (cairo)); + cairo_destroy (cairo); + cairo = old_cairo; + if (cairo_pattern_status (pattern)) + return gFalse; + + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin); + + cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + cairo_transform (cairo, &matrix); + cairo_set_source (cairo, pattern); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + cairo_fill (cairo); + + cairo_pattern_destroy (pattern); + + return gTrue; +} + GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) { double x0, y0, x1, y1; double dx, dy; diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index e0e1813..3543ce4 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -98,6 +98,11 @@ public: // Does this device use drawChar() or drawString()? virtual GBool useDrawChar() { return gTrue; } + // Does this device use tilingPatternFill()? If this returns false, + // tiling pattern fills will be reduced to a series of other drawing + // operations. + virtual GBool useTilingPatternFill() { return gTrue; } + // Does this device use functionShadedFill(), axialShadedFill(), and // radialShadedFill()? If this returns false, these shaded fills // will be reduced to a series of other drawing operations. @@ -151,6 +156,11 @@ public: virtual void stroke(GfxState *state); virtual void fill(GfxState *state); virtual void eoFill(GfxState *state); + virtual GBool tilingPatternFill(GfxState *state, Object *str, + int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep); virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax); virtual GBool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading); virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax); -- 1.6.0.4