poppler/SplashOutputDev.cc | 31 ++++++++++++++++++++++++++++--- splash/Splash.cc | 21 ++++++++++++++++++--- splash/Splash.h | 6 ++++-- splash/SplashBitmap.cc | 22 +++++++++++++++++++++- splash/SplashBitmap.h | 2 ++ 5 files changed, 73 insertions(+), 9 deletions(-)
New commits: commit be41f1c7905d695d17e19ced83a1018531d00199 Author: Albert Astals Cid <[email protected]> Date: Sun Apr 29 16:02:45 2012 +0200 SplashOutputDev: Fix rendering of knockout groups Bug #12185 diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index 0e956c7..ce666b9 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -1145,6 +1145,11 @@ struct SplashTransparencyGroup { GfxColorSpace *blendingColorSpace; GBool isolated; + //----- for knockout + SplashBitmap *shape; + GBool knockout; + SplashCoord knockoutOpacity; + //----- saved state SplashBitmap *origBitmap; Splash *origSplash; @@ -1631,10 +1636,16 @@ void SplashOutputDev::updateBlendMode(GfxState *state) { void SplashOutputDev::updateFillOpacity(GfxState *state) { splash->setFillAlpha((SplashCoord)state->getFillOpacity()); + if (transpGroupStack != NULL && (SplashCoord)state->getFillOpacity() < transpGroupStack->knockoutOpacity) { + transpGroupStack->knockoutOpacity = (SplashCoord)state->getFillOpacity(); + } } void SplashOutputDev::updateStrokeOpacity(GfxState *state) { splash->setStrokeAlpha((SplashCoord)state->getStrokeOpacity()); + if (transpGroupStack != NULL && (SplashCoord)state->getStrokeOpacity() < transpGroupStack->knockoutOpacity) { + transpGroupStack->knockoutOpacity = (SplashCoord)state->getStrokeOpacity(); + } } void SplashOutputDev::updateFillOverprint(GfxState *state) { @@ -3585,6 +3596,9 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, transpGroup->ty = ty; transpGroup->blendingColorSpace = blendingColorSpace; transpGroup->isolated = isolated; + transpGroup->shape = (knockout) ? SplashBitmap::copy(bitmap) : NULL; + transpGroup->knockout = gFalse; + transpGroup->knockoutOpacity = 1.0; transpGroup->next = transpGroupStack; transpGroupStack = transpGroup; @@ -3637,8 +3651,10 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, if (colorMode == splashModeXBGR8) color[3] = 255; splash->clear(color, 0); } else { + SplashBitmap *shape = (knockout) ? transpGroup->shape : + (transpGroup->next != NULL && transpGroup->next->shape != NULL) ? transpGroup->next->shape : transpGroup->origBitmap; splash->blitTransparent(transpGroup->origBitmap, tx, ty, 0, 0, w, h); - splash->setInNonIsolatedGroup(transpGroup->origBitmap, tx, ty); + splash->setInNonIsolatedGroup(shape, tx, ty); } transpGroup->tBitmap = bitmap; state->shiftCTM(-tx, -ty); @@ -3671,15 +3687,24 @@ void SplashOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) { // paint the transparency group onto the parent bitmap // - the clip path was set in the parent's state) if (tx < bitmap->getWidth() && ty < bitmap->getHeight()) { + SplashCoord knockoutOpacity = (transpGroupStack->next != NULL) ? transpGroupStack->next->knockoutOpacity + : transpGroupStack->knockoutOpacity; splash->setOverprintMask(0xffffffff, gFalse); splash->composite(tBitmap, 0, 0, tx, ty, - tBitmap->getWidth(), tBitmap->getHeight(), - gFalse, !isolated); + tBitmap->getWidth(), tBitmap->getHeight(), + gFalse, !isolated, transpGroupStack->next != NULL && transpGroupStack->next->knockout, knockoutOpacity); + if (transpGroupStack->next != NULL && transpGroupStack->next->shape != NULL) { + transpGroupStack->next->knockout = gTrue; + } } // pop the stack transpGroup = transpGroupStack; transpGroupStack = transpGroup->next; + if (transpGroupStack != NULL && transpGroup->knockoutOpacity < transpGroupStack->knockoutOpacity) { + transpGroupStack->knockoutOpacity = transpGroup->knockoutOpacity; + } + delete transpGroup->shape; delete transpGroup; delete tBitmap; diff --git a/splash/Splash.cc b/splash/Splash.cc index 0e2058c..047bbe8 100644 --- a/splash/Splash.cc +++ b/splash/Splash.cc @@ -135,6 +135,10 @@ struct SplashPipe { // non-isolated group alpha0 Guchar *alpha0Ptr; + // knockout groups + GBool knockout; + Guchar knockoutOpacity; + // soft mask SplashColorPtr softMaskPtr; @@ -240,7 +244,8 @@ inline void Splash::updateModY(int y) { inline void Splash::pipeInit(SplashPipe *pipe, int x, int y, SplashPattern *pattern, SplashColorPtr cSrc, Guchar aInput, GBool usesShape, - GBool nonIsolatedGroup) { + GBool nonIsolatedGroup, + GBool knockout, Guchar knockoutOpacity) { pipeSetXY(pipe, x, y); pipe->pattern = NULL; @@ -260,6 +265,10 @@ inline void Splash::pipeInit(SplashPipe *pipe, int x, int y, pipe->aInput = aInput; pipe->usesShape = usesShape; + // knockout + pipe->knockout = knockout; + pipe->knockoutOpacity = knockoutOpacity; + // result alpha if (aInput == 255 && !state->softMask && !usesShape && !state->inNonIsolatedGroup && !nonIsolatedGroup) { @@ -500,6 +509,10 @@ void Splash::pipeRun(SplashPipe *pipe) { break; } cSrc = cSrcNonIso; + // knockout: remove backdrop color + if (pipe->knockout && pipe->shape >= pipe->knockoutOpacity) { + aDest = 0; + } } } else { cSrc = pipe->cSrc; @@ -4651,7 +4664,8 @@ void Splash::blitImageClipped(SplashBitmap *src, GBool srcAlpha, SplashError Splash::composite(SplashBitmap *src, int xSrc, int ySrc, int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated) { + GBool noClip, GBool nonIsolated, + GBool knockout, SplashCoord knockoutOpacity) { SplashPipe pipe; SplashColor pixel; Guchar alpha; @@ -4664,7 +4678,8 @@ SplashError Splash::composite(SplashBitmap *src, int xSrc, int ySrc, if (src->alpha) { pipeInit(&pipe, xDest, yDest, NULL, pixel, - (Guchar)splashRound(state->fillAlpha * 255), gTrue, nonIsolated); + (Guchar)splashRound(state->fillAlpha * 255), gTrue, nonIsolated, + knockout, (Guchar)splashRound(knockoutOpacity * 255)); if (noClip) { for (y = 0; y < h; ++y) { pipeSetXY(&pipe, xDest, yDest + y); diff --git a/splash/Splash.h b/splash/Splash.h index 53bfa81..bc82faa 100644 --- a/splash/Splash.h +++ b/splash/Splash.h @@ -215,7 +215,8 @@ public: // object. SplashError composite(SplashBitmap *src, int xSrc, int ySrc, int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated); + GBool noClip, GBool nonIsolated, + GBool knockout = gFalse, SplashCoord knockoutOpacity = 1.0); // Composite this Splash object onto a background color. The // background alpha is assumed to be 1. @@ -274,7 +275,8 @@ private: void pipeInit(SplashPipe *pipe, int x, int y, SplashPattern *pattern, SplashColorPtr cSrc, Guchar aInput, GBool usesShape, - GBool nonIsolatedGroup); + GBool nonIsolatedGroup, + GBool knockout = gFalse, Guchar knockoutOpacity = 255); void pipeRun(SplashPipe *pipe); void pipeRunSimpleMono1(SplashPipe *pipe); void pipeRunSimpleMono8(SplashPipe *pipe); diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index ab5176e..6d37434 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -19,7 +19,7 @@ // Copyright (C) 2010 Harry Roberts <[email protected]> // Copyright (C) 2010 Christian Feuersänger <[email protected]> // Copyright (C) 2010 William Bader <[email protected]> -// Copyright (C) 2011 Thomas Freitag <[email protected]> +// Copyright (C) 2011, 2012 Thomas Freitag <[email protected]> // // 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 @@ -111,6 +111,26 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPadA, } } +SplashBitmap *SplashBitmap::copy(SplashBitmap *src) { + SplashBitmap *result = new SplashBitmap(src->getWidth(), src->getHeight(), src->getRowPad(), + src->getMode(), src->getAlphaPtr() != NULL, src->getRowSize() >= 0); + Guchar *dataSource = src->getDataPtr(); + Guchar *dataDest = result->getDataPtr(); + int amount = src->getRowSize(); + if (amount < 0) { + dataSource = dataSource + (src->getHeight() - 1) * amount; + dataDest = dataDest + (src->getHeight() - 1) * amount; + amount *= -src->getHeight(); + } else { + amount *= src->getHeight(); + } + memcpy(dataDest, dataSource, amount); + if (src->getAlphaPtr() != NULL) { + memcpy(result->getAlphaPtr(), src->getAlphaPtr(), src->getWidth() * src->getHeight()); + } + return result; +} + SplashBitmap::~SplashBitmap() { if (data) { if (rowSize < 0) { diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h index 8bcc941..5ef5573 100644 --- a/splash/SplashBitmap.h +++ b/splash/SplashBitmap.h @@ -19,6 +19,7 @@ // Copyright (C) 2010 Harry Roberts <[email protected]> // Copyright (C) 2010 Christian Feuersänger <[email protected]> // Copyright (C) 2010 William Bader <[email protected]> +// Copyright (C) 2012 Thomas Freitag <[email protected]> // // 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 @@ -51,6 +52,7 @@ public: SplashBitmap(int widthA, int heightA, int rowPad, SplashColorMode modeA, GBool alphaA, GBool topDown = gTrue); + static SplashBitmap *copy(SplashBitmap *src); ~SplashBitmap();
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
