summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Freitag <Thomas.Freitag@alfa.de>2011-03-21 21:34:46 +0000
committerAlbert Astals Cid <aacid@kde.org>2011-03-21 21:34:46 +0000
commitabf167af8b15e5f3b510275ce619e6fdb42edd40 (patch)
tree168604200e0404903fb29e63e048e7eab75a0994
parent66575c990f379871e4b796befc899de178332670 (diff)
Implement tiling/patterns in SplashOutputDev
Fixes bug 13518
-rw-r--r--poppler/CairoOutputDev.cc5
-rw-r--r--poppler/CairoOutputDev.h10
-rw-r--r--poppler/Gfx.cc6
-rw-r--r--poppler/OutputDev.h6
-rw-r--r--poppler/PSOutputDev.cc8
-rw-r--r--poppler/PSOutputDev.h6
-rw-r--r--poppler/PreScanOutputDev.cc22
-rw-r--r--poppler/PreScanOutputDev.h16
-rw-r--r--poppler/SplashOutputDev.cc265
-rw-r--r--poppler/SplashOutputDev.h12
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