[poppler] poppler/SplashOutputDev.cc splash/SplashBitmap.cc splash/SplashBitmap.h splash/Splash.cc splash/Splash.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Sun Apr 29 07:04:05 PDT 2012
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 <aacid at kde.org>
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 <harry.roberts at midnight-labs.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2010 William Bader <williambader at hotmail.com>
-// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag at 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
@@ -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 <harry.roberts at midnight-labs.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2010 William Bader <williambader at hotmail.com>
+// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at 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
@@ -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();
More information about the poppler
mailing list