diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index db06453..1f5bbc2 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -27,6 +27,7 @@ // Copyright (C) 2008 Pino Toscano // Copyright (C) 2008 Michael Vrable // Copyright (C) 2008 Hib Eris +// Copyright (C) 2009 Thomas Freitag // // 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 @@ -497,6 +498,9 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, Catalog *cata subPage = gFalse; printCommands = globalParams->getPrintCommands(); profileCommands = globalParams->getProfileCommands(); + textHaveCSPattern = gFalse; + drawText = gFalse; + maskHaveCSPattern = gFalse; mcStack = NULL; // start the resource stack @@ -541,6 +545,9 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, Catalog *catalogA, catalog = catalogA; subPage = gTrue; printCommands = globalParams->getPrintCommands(); + textHaveCSPattern = gFalse; + drawText = gFalse; + maskHaveCSPattern = gFalse; mcStack = NULL; // start the resource stack @@ -657,7 +664,7 @@ void Gfx::go(GBool topLevel) { data_p = new ProfileData(); hash->add (cmd_g, data_p); } - + data_p->addElement(timer.getElapsed ()); } } @@ -1229,12 +1236,17 @@ void Gfx::opSetRenderingIntent(Object args[], int numArgs) { void Gfx::opSetFillGray(Object args[], int numArgs) { GfxColor color; - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); - out->updateFillColorSpace(state); - color.c[0] = dblToCol(args[0].getNum()); - state->setFillColor(&color); - out->updateFillColor(state); + if (textHaveCSPattern) { + colorSpaceText = new GfxDeviceGrayColorSpace(); + colorText.c[0] = dblToCol(args[0].getNum()); + } else { + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceGrayColorSpace()); + out->updateFillColorSpace(state); + color.c[0] = dblToCol(args[0].getNum()); + state->setFillColor(&color); + out->updateFillColor(state); + } } void Gfx::opSetStrokeGray(Object args[], int numArgs) { @@ -1252,14 +1264,21 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { GfxColor color; int i; - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); - out->updateFillColorSpace(state); - for (i = 0; i < 4; ++i) { - color.c[i] = dblToCol(args[i].getNum()); + if (textHaveCSPattern) { + colorSpaceText = new GfxDeviceCMYKColorSpace(); + for (i = 0; i < 4; ++i) { + colorText.c[i] = dblToCol(args[i].getNum()); + } + } else { + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); } - state->setFillColor(&color); - out->updateFillColor(state); } void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) { @@ -1280,14 +1299,21 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) { GfxColor color; int i; - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceRGBColorSpace()); - out->updateFillColorSpace(state); - for (i = 0; i < 3; ++i) { - color.c[i] = dblToCol(args[i].getNum()); + if (textHaveCSPattern) { + colorSpaceText = new GfxDeviceRGBColorSpace(); + for (i = 0; i < 3; ++i) { + colorText.c[i] = dblToCol(args[i].getNum()); + } + } else { + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceRGBColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); } - state->setFillColor(&color); - out->updateFillColor(state); } void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) { @@ -1323,6 +1349,11 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { colorSpace->getDefaultColor(&color); state->setFillColor(&color); out->updateFillColor(state); + if (drawText && colorSpace->getMode() == csPattern) { + colorSpaceText = NULL; + textHaveCSPattern = gTrue; + out->beginTextObject(state); + } } else { error(getPos(), "Bad color space (fill)"); } @@ -1846,7 +1877,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, if (stroke) { state->clipToStrokePath(); out->clipToStrokePath(state); - } else { + } else if (!textHaveCSPattern && !maskHaveCSPattern) { state->clip(); if (eoFill) { out->eoClip(state); @@ -1974,7 +2005,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat, if (stroke) { state->clipToStrokePath(); out->clipToStrokePath(state); - } else { + } else if (!textHaveCSPattern && !maskHaveCSPattern) { state->clip(); if (eoFill) { out->eoClip(state); @@ -2239,14 +2270,14 @@ void Gfx::doFunctionShFill1(GfxFunctionShading *shading, colors2[2] = colorM0; colors2[3] = colorMM; doFunctionShFill1(shading, x0, y0, xM, yM, colors2, depth + 1); - + // lower-left sub-rectangle colors2[0] = color0M; colors2[1] = colors[1]; colors2[2] = colorMM; colors2[3] = colorM1; doFunctionShFill1(shading, x0, yM, xM, y1, colors2, depth + 1); - + // upper-right sub-rectangle colors2[0] = colorM0; colors2[1] = colorMM; @@ -3090,15 +3121,35 @@ void Gfx::opEOClip(Object args[], int numArgs) { //------------------------------------------------------------------------ void Gfx::opBeginText(Object args[], int numArgs) { + out->beginTextObject(state); + drawText = gTrue; state->setTextMat(1, 0, 0, 1, 0, 0); state->textMoveTo(0, 0); out->updateTextMat(state); out->updateTextPos(state); fontChanged = gTrue; + if (out->supportTextCSPattern(state)) { + colorSpaceText = NULL; + textHaveCSPattern = gTrue; + } } void Gfx::opEndText(Object args[], int numArgs) { out->endTextObject(state); + drawText = gFalse; + if (out->supportTextCSPattern(state) && textHaveCSPattern) { + doPatternFill(gTrue); + out->restoreState(state); + if (colorSpaceText != NULL) { + state->setFillPattern(NULL); + state->setFillColorSpace(colorSpaceText); + out->updateFillColorSpace(state); + state->setFillColor(&colorText); + out->updateFillColor(state); + colorSpaceText = NULL; + } + } + textHaveCSPattern = gFalse; } //------------------------------------------------------------------------ @@ -3664,6 +3715,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { // draw it if (!contentIsHidden()) out->drawImageMask(state, ref, str, width, height, invert, inlineImg); + if (out->fillMaskCSPattern(state)) { + maskHaveCSPattern = gTrue; + doPatternFill(gTrue); + out->endMaskClip(state); + maskHaveCSPattern = gFalse; + } } else { @@ -4084,7 +4141,7 @@ void Gfx::opBeginImage(Object args[], int numArgs) { // display the image if (str) { doImage(NULL, str, gTrue); - + // skip 'EI' tag c1 = str->getUndecodedStream()->getChar(); c2 = str->getUndecodedStream()->getChar(); @@ -4200,7 +4257,7 @@ GBool Gfx::contentIsHidden() { void Gfx::opBeginMarkedContent(Object args[], int numArgs) { // push a new stack entry pushMarkedContent(); - + OCGs *contentConfig = catalog->getOptContentConfig(); char* name0 = args[0].getName(); if ( strncmp( name0, "OC", 2) == 0 && contentConfig) { diff --git a/poppler/Gfx.h b/poppler/Gfx.h index a75a92a..e425cc0 100644 --- a/poppler/Gfx.h +++ b/poppler/Gfx.h @@ -18,6 +18,7 @@ // Copyright (C) 2008 Brad Hards // Copyright (C) 2008 Carlos Garcia Campos // Copyright (C) 2009 Albert Astals Cid +// Copyright (C) 2009 Thomas Freitag // // 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 @@ -33,6 +34,7 @@ #include "goo/gtypes.h" #include "goo/GooList.h" +#include "GfxState.h" #include "Object.h" class GooString; @@ -170,11 +172,17 @@ public: private: XRef *xref; // the xref table for this PDF file - Catalog *catalog; // the Catalog for this PDF file + Catalog *catalog; // the Catalog for this PDF file OutputDev *out; // output device GBool subPage; // is this a sub-page object? GBool printCommands; // print the drawing commands (for debugging) GBool profileCommands; // profile the drawing commands (for debugging) + GBool textHaveCSPattern; // in text drawing and text has pattern colorspace + GBool drawText; // in text drawing + GfxColorSpace *colorSpaceText; // colorspace after text has filled with pattern + GfxColor colorText; // fill color after after text has filled with pattern + GBool maskHaveCSPattern; // in mask drawing and mask has pattern colorspace + GfxResources *res; // resource stack int updateLevel; diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index 66b5c38..79a29b8 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -17,6 +17,7 @@ // Copyright (C) 2006 Thorkild Stray // Copyright (C) 2007 Jeff Muizelaar // Copyright (C) 2007 Adrian Johnson +// Copyright (C) 2009 Thomas Freitag // // 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 @@ -94,6 +95,17 @@ public: // Does this device need non-text content? virtual GBool needNonText() { return gTrue; } + // If current colorspace ist pattern, + // does this device support text in pattern colorspace? + // Default is false + virtual GBool supportTextCSPattern(GfxState * /*state*/) { return gFalse; } + + // If current colorspace ist pattern, + // need this device special handling for masks in pattern colorspace? + // Default is false + virtual GBool fillMaskCSPattern(GfxState * /*state*/) { return gFalse; } + virtual void endMaskClip(GfxState * /*state*/) {} + //----- initialization and control // Set default transform matrix. @@ -204,6 +216,7 @@ public: double /*dx*/, double /*dy*/, CharCode /*code*/, Unicode * /*u*/, int /*uLen*/); virtual void endType3Char(GfxState * /*state*/) {} + virtual void beginTextObject(GfxState * /*state*/) {} virtual void endTextObject(GfxState * /*state*/) {} //----- image drawing @@ -232,8 +245,8 @@ public: virtual void beginMarkedContent(char *name, Dict *properties); virtual void markPoint(char *name); virtual void markPoint(char *name, Dict *properties); - - + + #if OPI_SUPPORT //----- OPI functions