diff --git a/poppler/Function.cc b/poppler/Function.cc index 73a6b5f..606b451 100644 --- a/poppler/Function.cc +++ b/poppler/Function.cc @@ -49,6 +49,13 @@ //------------------------------------------------------------------------ Function::Function() { + int c; + for (c = 0; c < funcMaxInputs; c++) { + domain[0][0] = 0.0; + domain[0][1] = 1.0; + range[0][0] = 0.0; + range[0][1] = 1.0; + } } Function::~Function() { diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 85d657b..43a018d 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -487,7 +487,7 @@ GBool GfxResources::lookupGState(char *name, Object *obj) { if (!obj->isRef()) return gTrue; - + const Ref ref = obj->getRef(); if (!gStateCache.lookup(ref, obj)->isNull()) return gTrue; @@ -714,7 +714,7 @@ void Gfx::go(GBool topLevel) { data_p = new ProfileData(); hash->add (cmd_g, data_p); } - + data_p->addElement(timer.getElapsed ()); } } @@ -1304,24 +1304,19 @@ void Gfx::opSetFillGray(Object args[], int numArgs) { doPatternFill(gTrue); } out->restoreState(state); - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); - out->updateFillColorSpace(state); - color.c[0] = dblToCol(args[0].getNum()); - state->setFillColor(&color); - out->updateFillColor(state); + } + 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) { out->beginTextObject(state); out->updateRender(state); out->updateTextMat(state); out->updateTextPos(state); textHaveCSPattern = gFalse; - } else { - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); - out->updateFillColorSpace(state); - color.c[0] = dblToCol(args[0].getNum()); - state->setFillColor(&color); - out->updateFillColor(state); } } @@ -1341,19 +1336,27 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { int i; 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()); + GBool needFill = out->deviceHasTextClip(state); + out->endTextObject(state); + if (needFill) { + doPatternFill(gTrue); } - state->setFillColor(&color); - out->updateFillColor(state); + out->restoreState(state); + } + 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); + if (textHaveCSPattern) { + out->beginTextObject(state); + out->updateRender(state); + out->updateTextMat(state); + out->updateTextPos(state); + textHaveCSPattern = gFalse; } } @@ -1376,19 +1379,27 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) { int i; 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()); + GBool needFill = out->deviceHasTextClip(state); + out->endTextObject(state); + if (needFill) { + doPatternFill(gTrue); } - state->setFillColor(&color); - out->updateFillColor(state); + out->restoreState(state); + } + 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); + if (textHaveCSPattern) { + out->beginTextObject(state); + out->updateRender(state); + out->updateTextMat(state); + out->updateTextPos(state); + textHaveCSPattern = gFalse; } } @@ -1411,7 +1422,6 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { GfxColorSpace *colorSpace; GfxColor color; - state->setFillPattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], this); @@ -1434,7 +1444,6 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { doPatternFill(gTrue); out->restoreState(state); } - colorSpaceText = NULL; textHaveCSPattern = gTrue; out->beginTextObject(state); } else if (textHaveCSPattern) { @@ -1453,6 +1462,7 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { } else { error(getPos(), "Bad color space (fill)"); } + state->setFillPattern(NULL); } void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) { @@ -2375,14 +2385,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; @@ -2580,10 +2590,10 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) { } shading->getColor(tt, &color1); if (isSameGfxColor(color1, color0, nComps, axialColorDelta)) { - // in these two if what we guarantee is that if we are skipping lots of + // in these two if what we guarantee is that if we are skipping lots of // positions because the colors are the same, we still create a region // with vertexs passing by bboxIntersections[1] and bboxIntersections[2] - // otherwise we can have empty regions that should really be painted + // otherwise we can have empty regions that should really be painted // like happened in bug 19896 // What we do to ensure that we pass a line through this points // is making sure use the exact bboxIntersections[] value as one of the used ta[] values @@ -3329,7 +3339,6 @@ void Gfx::opBeginText(Object args[], int numArgs) { out->updateTextPos(state); fontChanged = gTrue; if (out->supportTextCSPattern(state)) { - colorSpaceText = NULL; textHaveCSPattern = gTrue; } } @@ -3343,14 +3352,6 @@ void Gfx::opEndText(Object args[], int numArgs) { 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; } @@ -4355,7 +4356,7 @@ void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox, // draw the form display(str, gFalse); - + if (stateBefore != state) { if (state->isParentState(stateBefore)) { error(-1, "There's a form with more q than Q, trying to fix"); @@ -4408,7 +4409,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(); @@ -4530,7 +4531,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 3e12509..e029d71 100644 --- a/poppler/Gfx.h +++ b/poppler/Gfx.h @@ -196,8 +196,6 @@ private: GBool drawText; // in text drawing GBool maskHaveCSPattern; // in mask drawing and mask has pattern colorspace GBool commandAborted; // did the previous command abort the drawing? - GfxColorSpace *colorSpaceText;// colorspace after text has filled with pattern - GfxColor colorText; // fill color after after text has filled with pattern GfxResources *res; // resource stack int updateLevel; diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index ab0722a..5e7a0e3 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -1974,7 +1974,20 @@ GBool SplashOutputDev::imageMaskSrc(void *data, SplashColorPtr line) { } void SplashOutputDev::endMaskClip(GfxState * state) { - splash->setSoftMask(NULL); + double bbox[4] = {0,0,1,1}; // dummy + /* transfer mask to alpha channel! */ + // memcpy(maskBitmap->getAlphaPtr(), maskBitmap->getDataPtr(), bitmap->getRowSize() * bitmap->getHeight()); + // memset(maskBitmap->getDataPtr(), 0, bitmap->getRowSize() * bitmap->getHeight()); + int c; + Guchar *dest = bitmap->getAlphaPtr(); + Guchar *src = maskBitmap->getDataPtr(); + for (c= 0; c < maskBitmap->getRowSize() * maskBitmap->getHeight(); c++) { + dest[c] = src[c]; + } + delete maskBitmap; + maskBitmap = NULL; + endTransparencyGroup(state); + paintTransparencyGroup(state, bbox); } void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, @@ -2007,10 +2020,31 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, imgMaskData.y = 0; if (state->getFillColorSpace()->getMode() == csPattern) { - SplashBitmap *maskBitmap; Splash *maskSplash; - SplashColor maskColor; - + SplashColor maskColor; + + /* from beginTransparencyGroup: */ + // push a new stack entry + SplashTransparencyGroup *transpGroup = new SplashTransparencyGroup(); + transpGroup->tx = 0; + transpGroup->ty = 0; + transpGroup->blendingColorSpace = NULL; + transpGroup->isolated = gFalse; + transpGroup->next = transpGroupStack; + transpGroupStack = transpGroup; + // save state + transpGroup->origBitmap = bitmap; + transpGroup->origSplash = splash; + //~ this ignores the blendingColorSpace arg + // create the temporary bitmap + bitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), bitmapRowPad, colorMode, gTrue, + bitmapTopDown); + splash = new Splash(bitmap, vectorAntialias, + transpGroup->origSplash->getScreen()); + splash->blitTransparent(transpGroup->origBitmap, 0, 0, 0, 0, bitmap->getWidth(), bitmap->getHeight()); + splash->setInNonIsolatedGroup(transpGroup->origBitmap, 0, 0); + transpGroup->tBitmap = bitmap; + maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), 1, splashModeMono8, gFalse); maskSplash = new Splash(maskBitmap, vectorAntialias); maskColor[0] = 0; @@ -2019,7 +2053,6 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, maskSplash->setFillPattern(new SplashSolidColor(maskColor)); maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat, t3GlyphStack != NULL); delete maskSplash; - splash->setSoftMask(maskBitmap); } else { splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat, t3GlyphStack != NULL); if (inlineImg) { @@ -2630,6 +2663,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref, delete imgData.imgStr; str->close(); } + } void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, @@ -3002,7 +3036,12 @@ void SplashOutputDev::setSoftMask(GfxState * /*state*/, double * /*bbox*/, softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), 1, splashModeMono8, gFalse); - memset(softMask->getDataPtr(), 0, + unsigned char fill = 0; + if (transpGroupStack->blendingColorSpace) { + transpGroupStack->blendingColorSpace->getGray(backdropColor, &gray); + fill = colToByte(gray); + } + memset(softMask->getDataPtr(), fill, softMask->getRowSize() * softMask->getHeight()); p = softMask->getDataPtr() + ty * softMask->getRowSize() + tx; int xMax = tBitmap->getWidth(); diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h index df33850..116b477 100644 --- a/poppler/SplashOutputDev.h +++ b/poppler/SplashOutputDev.h @@ -277,6 +277,7 @@ private: SplashTransparencyGroup * // transparency group stack transpGroupStack; + SplashBitmap *maskBitmap; // for image masks in pattern colorspace }; #endif