diff options
author | Thomas Freitag <Thomas.Freitag@alfa.de> | 2011-03-21 21:34:46 +0000 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2011-03-21 21:34:46 +0000 |
commit | abf167af8b15e5f3b510275ce619e6fdb42edd40 (patch) | |
tree | 168604200e0404903fb29e63e048e7eab75a0994 | |
parent | 66575c990f379871e4b796befc899de178332670 (diff) |
Implement tiling/patterns in SplashOutputDev
Fixes bug 13518
-rw-r--r-- | poppler/CairoOutputDev.cc | 5 | ||||
-rw-r--r-- | poppler/CairoOutputDev.h | 10 | ||||
-rw-r--r-- | poppler/Gfx.cc | 6 | ||||
-rw-r--r-- | poppler/OutputDev.h | 6 | ||||
-rw-r--r-- | poppler/PSOutputDev.cc | 8 | ||||
-rw-r--r-- | poppler/PSOutputDev.h | 6 | ||||
-rw-r--r-- | poppler/PreScanOutputDev.cc | 22 | ||||
-rw-r--r-- | poppler/PreScanOutputDev.h | 16 | ||||
-rw-r--r-- | poppler/SplashOutputDev.cc | 265 | ||||
-rw-r--r-- | poppler/SplashOutputDev.h | 12 |
10 files changed, 334 insertions, 22 deletions
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index de0663c3..477030a5 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -25,6 +25,7 @@ // Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk> // Copyright (C) 2008 Hib Eris <hib@hiberis.nl> // Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu> +// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -690,8 +691,8 @@ void CairoOutputDev::eoFill(GfxState *state) { } -GBool CairoOutputDev::tilingPatternFill(GfxState *state, Object *str, - int paintType, Dict *resDict, +GBool CairoOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 8ef2a932..730a23c5 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -20,7 +20,7 @@ // Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2008, 2009, 2011 Adrian Johnson <ajohnson@redneon.com> // Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu> -// Copyright (C) 2010 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2010, 2011 Thomas Freitag <Thomas.Freitag@alfa.de> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -158,8 +158,8 @@ public: virtual void fill(GfxState *state); virtual void eoFill(GfxState *state); virtual void clipToStrokePath(GfxState *state); - virtual GBool tilingPatternFill(GfxState *state, Object *str, - int paintType, Dict *resDict, + virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep); @@ -411,8 +411,8 @@ 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, + virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) { return gTrue; } diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index daf50d35..dc5f8e30 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -28,7 +28,7 @@ // Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu> // Copyright (C) 2008 Hib Eris <hib@hiberis.nl> // Copyright (C) 2009 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> -// Copyright (C) 2009, 2010 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2009-2011 Thomas Freitag <Thomas.Freitag@alfa.de> // Copyright (C) 2009 William Bader <williambader@hotmail.com> // Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu> // Copyright (C) 2010 Nils Höglund <nils.hoglund@gmail.com> @@ -2082,8 +2082,8 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, m1[4] = m[4]; m1[5] = m[5]; if (out->useTilingPatternFill() && - out->tilingPatternFill(state, tPat->getContentStream(), - tPat->getPaintType(), tPat->getResDict(), + out->tilingPatternFill(state, catalog, tPat->getContentStream(), + tPat->getMatrix(), tPat->getPaintType(), tPat->getResDict(), m1, tPat->getBBox(), xi0, yi0, xi1, yi1, xstep, ystep)) { goto restore; diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index 065a4a2b..c922c7a7 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -17,7 +17,7 @@ // Copyright (C) 2006 Thorkild Stray <thorkild@ifi.uio.no> // Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net> // Copyright (C) 2007, 2011 Adrian Johnson <ajohnson@redneon.com> -// Copyright (C) 2009, 2010 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2009-2011 Thomas Freitag <Thomas.Freitag@alfa.de> // Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com> @@ -195,8 +195,8 @@ 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*/, + virtual GBool tilingPatternFill(GfxState * /*state*/, Catalog * /*cat*/, Object * /*str*/, + double * /*pmat*/, int /*paintType*/, Dict * /*resDict*/, double * /*mat*/, double * /*bbox*/, int /*x0*/, int /*y0*/, int /*x1*/, int /*y1*/, double /*xStep*/, double /*yStep*/) diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 34f09a5e..ca7c5cd4 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -20,7 +20,7 @@ // Copyright (C) 2007, 2008 Brad Hards <bradh@kde.org> // Copyright (C) 2008, 2009 Koji Otani <sho@bbr.jp> // Copyright (C) 2008, 2010 Hib Eris <hib@hiberis.nl> -// Copyright (C) 2009, 2010 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2009-2011 Thomas Freitag <Thomas.Freitag@alfa.de> // Copyright (C) 2009 Till Kamppeter <till.kamppeter@gmail.com> // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2009, 2011 William Bader <williambader@hotmail.com> @@ -2997,7 +2997,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, GBool useBinary; if (!forceRasterize) { - scan = new PreScanOutputDev(); + scan = new PreScanOutputDev(xref); page->displaySlice(scan, 72, 72, rotateA, useMediaBox, crop, sliceX, sliceY, sliceW, sliceH, printing, catalog, abortCheckCbk, abortCheckCbkData); @@ -3876,8 +3876,8 @@ void PSOutputDev::eoFill(GfxState *state) { writePS("f*\n"); } -GBool PSOutputDev::tilingPatternFill(GfxState *state, Object *str, - int paintType, Dict *resDict, +GBool PSOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) { diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index d3eddec7..6b37d181 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -17,7 +17,7 @@ // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com> // Copyright (C) 2006-2008 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2007 Brad Hards <bradh@kde.org> -// Copyright (C) 2009, 2010 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2009-2011 Thomas Freitag <Thomas.Freitag@alfa.de> // Copyright (C) 2009 Till Kamppeter <till.kamppeter@gmail.com> // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2009, 2011 William Bader <williambader@hotmail.com> @@ -209,8 +209,8 @@ 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, + virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep); diff --git a/poppler/PreScanOutputDev.cc b/poppler/PreScanOutputDev.cc index 8ccdfe6a..239aef8f 100644 --- a/poppler/PreScanOutputDev.cc +++ b/poppler/PreScanOutputDev.cc @@ -16,6 +16,7 @@ // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2010 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2011 William Bader <williambader@hotmail.com> +// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -28,16 +29,20 @@ #include <math.h> #include "GlobalParams.h" +#include "Gfx.h" #include "GfxFont.h" #include "Link.h" +#include "Catalog.h" +#include "Page.h" #include "PreScanOutputDev.h" //------------------------------------------------------------------------ // PreScanOutputDev //------------------------------------------------------------------------ -PreScanOutputDev::PreScanOutputDev() { +PreScanOutputDev::PreScanOutputDev(XRef *xrefA) { level = globalParams->getPSLevel(); + xref = xrefA; clearStats(); } @@ -73,6 +78,21 @@ void PreScanOutputDev::eoFill(GfxState *state) { state->getFillOpacity(), state->getBlendMode()); } +GBool PreScanOutputDev::tilingPatternFill(GfxState *state, Catalog *catalog, Object *str, + double *pmat, int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep) { + PDFRectangle box; + Gfx *gfx; + 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; + return gTrue; +} + void PreScanOutputDev::clip(GfxState * /*state*/) { //~ check for a rectangle "near" the edge of the page; //~ else set gdi to false diff --git a/poppler/PreScanOutputDev.h b/poppler/PreScanOutputDev.h index f09ecca9..d97f0f73 100644 --- a/poppler/PreScanOutputDev.h +++ b/poppler/PreScanOutputDev.h @@ -16,6 +16,7 @@ // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2010 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2011 William Bader <williambader@hotmail.com> +// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -30,7 +31,9 @@ #endif #include "goo/gtypes.h" +#include "Object.h" #include "GfxState.h" +#include "GlobalParams.h" #include "OutputDev.h" //------------------------------------------------------------------------ @@ -41,7 +44,7 @@ class PreScanOutputDev: public OutputDev { public: // Constructor. - PreScanOutputDev(); + PreScanOutputDev(XRef *xrefA); // Destructor. virtual ~PreScanOutputDev(); @@ -55,6 +58,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 beginType3Char/endType3Char? Otherwise, // text in Type 3 fonts will be drawn with drawChar/drawString. virtual GBool interpretType3Chars() { return gTrue; } @@ -71,6 +79,11 @@ public: virtual void stroke(GfxState *state); virtual void fill(GfxState *state); virtual void eoFill(GfxState *state); + virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str, + double *pmat, int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep); //----- path clipping virtual void clip(GfxState *state); @@ -145,6 +158,7 @@ private: void check(GfxColorSpace *colorSpace, GfxColor *color, double opacity, GfxBlendMode blendMode); + XRef *xref; GBool mono; GBool gray; GBool transparency; diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index fc838d31..3a56a78e 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -47,7 +47,9 @@ #include "GlobalParams.h" #include "Error.h" #include "Object.h" +#include "Gfx.h" #include "GfxFont.h" +#include "Page.h" #include "Link.h" #include "CharCodeToUnicode.h" #include "FontEncodingTables.h" @@ -2582,6 +2584,98 @@ GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine, return gTrue; } +struct TilingSplashOutBitmap { + SplashBitmap *bitmap; + SplashPattern *pattern; + SplashColorMode colorMode; + int paintType; + int repeatX; + int repeatY; + int y; +}; + +GBool SplashOutputDev::tilingBitmapSrc(void *data, SplashColorPtr colorLine, + Guchar *alphaLine) { + TilingSplashOutBitmap *imgData = (TilingSplashOutBitmap *)data; + + if (imgData->y == imgData->bitmap->getHeight()) { + imgData->repeatY--; + if (imgData->repeatY == 0) + return gFalse; + imgData->y = 0; + } + + if (imgData->paintType == 1) { + const SplashColorMode cMode = imgData->bitmap->getMode(); + SplashColorPtr q = colorLine; + // For splashModeBGR8 and splashModeXBGR8 we need to use getPixel + // for the others we can use raw access + if (cMode == splashModeBGR8 || cMode == splashModeXBGR8) { + for (int m = 0; m < imgData->repeatX; m++) { + for (int x = 0; x < imgData->bitmap->getWidth(); x++) { + imgData->bitmap->getPixel(x, imgData->y, q); + q += splashColorModeNComps[cMode]; + } + } + } else { + const int n = imgData->bitmap->getRowSize(); + SplashColorPtr p; + for (int m = 0; m < imgData->repeatX; m++) { + p = imgData->bitmap->getDataPtr() + imgData->y * imgData->bitmap->getRowSize(); + for (int x = 0; x < n; ++x) { // TODO memcopy? + *q++ = *p++; + } + } + } + if (alphaLine != NULL) { + SplashColorPtr aq = alphaLine; + SplashColorPtr p; + const int n = imgData->bitmap->getWidth() - 1; + for (int m = 0; m < imgData->repeatX; m++) { + p = imgData->bitmap->getAlphaPtr() + imgData->y * imgData->bitmap->getWidth(); + for (int x = 0; x < n; ++x) { // TODO memcopy? + *aq++ = *p++; + } + // This is a hack, because of how Splash antialias works if we overwrite the + // last alpha pixel of the tile most/all of the files look much better + *aq++ = (n == 0) ? *p : *(p - 1); + } + } + } else { + SplashColor col, pat; + SplashColorPtr dest = colorLine; + for (int m = 0; m < imgData->repeatX; m++) { + for (int x = 0; x < imgData->bitmap->getWidth(); x++) { + imgData->bitmap->getPixel(x, imgData->y, col); + imgData->pattern->getColor(x, imgData->y, pat); + for (int i = 0; i < splashColorModeNComps[imgData->colorMode]; ++i) { +#if SPLASH_CMYK + if (imgData->colorMode == splashModeCMYK8) + dest[i] = div255(pat[i] * (255 - col[0])); + else +#endif + dest[i] = 255 - div255((255 - pat[i]) * (255 - col[0])); + } + dest += splashColorModeNComps[imgData->colorMode]; + } + } + if (alphaLine != NULL) { + const int y = (imgData->y == imgData->bitmap->getHeight() - 1 && imgData->y > 50) ? imgData->y - 1 : imgData->y; + SplashColorPtr aq = alphaLine; + SplashColorPtr p; + const int n = imgData->bitmap->getWidth(); + for (int m = 0; m < imgData->repeatX; m++) { + p = imgData->bitmap->getAlphaPtr() + y * imgData->bitmap->getWidth(); + for (int x = 0; x < n; ++x) { // TODO memcopy? + *aq++ = *p++; + } + } + } + } + ++imgData->y; + return gTrue; +} + void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, @@ -3472,6 +3566,177 @@ void SplashOutputDev::setFreeTypeHinting(GBool enable, GBool enableSlightHinting enableSlightHinting = enableSlightHintingA; } +GBool SplashOutputDev::tilingPatternFill(GfxState *state, Catalog *catalog, Object *str, + double *ptm, int paintType, Dict *resDict, + double *mat, double *bbox, + int x0, int y0, int x1, int y1, + double xStep, double yStep) +{ + PDFRectangle box; + Gfx *gfx; + Splash *formerSplash = splash; + SplashBitmap *formerBitmap = bitmap; + double width, height; + int surface_width, surface_height, result_width, result_height, i; + int xMin, xMax, yMin, yMax; + int repeatX, repeatY; + SplashCoord matc[6]; + Matrix m1; + double *ctm, savedCTM[6]; + double kx, ky, sx, sy; + + width = bbox[2] - bbox[0]; + height = bbox[3] - bbox[1]; + + if (xStep != width || yStep != height) + return gFalse; + + // calculate offsets + ctm = state->getCTM(); + for (i = 0; i < 6; ++i) { + savedCTM[i] = ctm[i]; + } + state->concatCTM(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + state->concatCTM(1, 0, 0, 1, bbox[0], bbox[1]); + ctm = state->getCTM(); + for (i = 0; i < 6; ++i) { + if (!isfinite(ctm[i])) + return gFalse; + } + matc[4] = x0 * xStep * ctm[0] + y0 * yStep * ctm[2] + ctm[4]; + matc[5] = x0 * xStep * ctm[1] + y0 * yStep * ctm[3] + ctm[5]; + xMin = (int) ceil (matc[4]); + yMin = (int) ceil (matc[5]); + xMax = xMin; + yMax = yMin; + if (splashAbs(ctm[1]) > splashAbs(ctm[0])) { + kx = -ctm[1]; + ky = ctm[2] - (ctm[0] * ctm[3]) / ctm[1]; + } else { + kx = ctm[0]; + ky = ctm[3] - (ctm[1] * ctm[2]) / ctm[0]; + } + result_width = (int) ceil(fabs(kx * width * (x1 - x0))); + result_height = (int) ceil(fabs(ky * height * (y1 - y0))); + kx = state->getHDPI() / 72.0; + ky = state->getVDPI() / 72.0; + m1.m[0] = (ptm[0] == 0) ? fabs(ptm[2]) * kx : fabs(ptm[0]) * kx; + m1.m[1] = 0; + m1.m[2] = 0; + m1.m[3] = (ptm[3] == 0) ? fabs(ptm[1]) * ky : fabs(ptm[3]) * ky; + m1.m[4] = 0; + m1.m[5] = 0; + m1.transform(width, height, &kx, &ky); + surface_width = (int) ceil (fabs(kx)); + surface_height = (int) ceil (fabs(ky)); + + sx = (double) result_width / (surface_width * (x1 - x0)); + sy = (double) result_height / (surface_height * (y1 - y0)); + m1.m[0] *= sx; + m1.m[3] *= sy; + m1.transform(width, height, &kx, &ky); + + if(fabs(kx) < 1 && fabs(ky) < 1) { + kx = std::min<double>(kx, ky); + ky = 2 / kx; + m1.m[0] *= ky; + m1.m[3] *= ky; + m1.transform(width, height, &kx, &ky); + surface_width = (int) ceil (fabs(kx)); + surface_height = (int) ceil (fabs(ky)); + repeatX = x1 - x0; + repeatY = y1 - y0; + } else { + while(fabs(kx) > 16384 || fabs(ky) > 16384) { + // limit pattern bitmap size + m1.m[0] /= 2; + m1.m[3] /= 2; + m1.transform(width, height, &kx, &ky); + } + surface_width = (int) ceil (fabs(kx)); + surface_height = (int) ceil (fabs(ky)); + // adjust repeat values to completely fill region + repeatX = result_width / surface_width; + repeatY = result_height / surface_height; + if (surface_width * repeatX < result_width) + repeatX++; + if (surface_height * repeatY < result_height) + repeatY++; + if (x1 - x0 > repeatX) + repeatX = x1 - x0; + if (y1 - y0 > repeatY) + repeatY = y1 - y0; + } + // restore CTM and calculate rotate and scale with rounded matric + state->setCTM(savedCTM[0], savedCTM[1], savedCTM[2], savedCTM[3], savedCTM[4], savedCTM[5]); + state->concatCTM(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + state->concatCTM(width * repeatX, 0, 0, height * repeatY, bbox[0], bbox[1]); + ctm = state->getCTM(); + matc[0] = ctm[0]; + matc[1] = ctm[1]; + matc[2] = ctm[2]; + matc[3] = ctm[3]; + + if (surface_width == 0 || surface_height == 0) + return gFalse; + m1.transform(bbox[0], bbox[1], &kx, &ky); + m1.m[4] = -kx; + m1.m[5] = -ky; + + bitmap = new SplashBitmap(surface_width, surface_height, colorMode != splashModeMono1, + (paintType == 1) ? colorMode : splashModeMono8, gTrue); + memset(bitmap->getAlphaPtr(), 0, bitmap->getWidth() * bitmap->getHeight()); + if (paintType == 2) { +#ifdef SPLASH_CMYK + memset(bitmap->getDataPtr(), (colorMode == splashModeCMYK8) ? 0x00 : 0xFF, bitmap->getRowSize() * bitmap->getHeight()); +#else + memset(bitmap->getDataPtr(), 0xFF, bitmap->getRowSize() * bitmap->getHeight()); +#endif + } + splash = new Splash(bitmap, gTrue); + + 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); + // set pattern transformation matrix + gfx->getState()->setCTM(m1.m[0], m1.m[1], m1.m[2], m1.m[3], m1.m[4], m1.m[5]); + updateCTM(gfx->getState(), m1.m[0], m1.m[1], m1.m[2], m1.m[3], m1.m[4], m1.m[5]); + gfx->display(str); + splash = formerSplash; + TilingSplashOutBitmap imgData; + imgData.bitmap = bitmap; + imgData.paintType = paintType; + imgData.pattern = splash->getFillPattern(); + imgData.colorMode = colorMode; + imgData.y = 0; + imgData.repeatX = repeatX; + imgData.repeatY = repeatY; + SplashBitmap *tBitmap = bitmap; + bitmap = formerBitmap; + result_width = tBitmap->getWidth() * imgData.repeatX; + result_height = tBitmap->getHeight() * imgData.repeatY; + + if (splashAbs(matc[1]) > splashAbs(matc[0])) { + kx = -matc[1]; + ky = matc[2] - (matc[0] * matc[3]) / matc[1]; + } else { + kx = matc[0]; + ky = matc[3] - (matc[1] * matc[2]) / matc[0]; + } + kx = result_width / (fabs(kx) + 1); + ky = result_height / (fabs(ky) + 1); + state->concatCTM(kx, 0, 0, ky, 0, 0); + ctm = state->getCTM(); + matc[0] = ctm[0]; + matc[1] = ctm[1]; + matc[2] = ctm[2]; + matc[3] = ctm[3]; + splash->drawImage(&tilingBitmapSrc, &imgData, colorMode, gTrue, result_width, result_height, matc); + delete tBitmap; + delete gfx; + return gTrue; +} + GBool SplashOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) { GfxColorSpaceMode shadingMode = shading->getColorSpace()->getMode(); diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h index c8cb84f7..26f3ddf0 100644 --- a/poppler/SplashOutputDev.h +++ b/poppler/SplashOutputDev.h @@ -166,6 +166,11 @@ public: //----- get info about output device + // 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. @@ -223,6 +228,11 @@ public: virtual void stroke(GfxState *state); virtual void fill(GfxState *state); virtual void eoFill(GfxState *state); + virtual GBool tilingPatternFill(GfxState *state, Catalog *catalog, Object *str, + double *pmat, 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 radialShadedFill(GfxState *state, GfxRadialShading *shading, double tMin, double tMax); virtual GBool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading); @@ -349,6 +359,8 @@ private: Guchar *alphaLine); static GBool maskedImageSrc(void *data, SplashColorPtr line, Guchar *alphaLine); + static GBool tilingBitmapSrc(void *data, SplashColorPtr line, + Guchar *alphaLine); GBool haveCSPattern; // set if text has been drawn with a // clipping render mode because of pattern colorspace |