summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Freitag <Thomas.Freitag@alfa.de>2013-02-12 22:48:40 +0100
committerAlbert Astals Cid <aacid@kde.org>2013-02-12 22:48:40 +0100
commit7f2c255ff28386ba992717f729f25a979f240375 (patch)
tree9911b87b37669527b411a8fcd96ac286f2af0ff7
parentc2ebcbea2267f861c491c0cd6c1fbf2dc2aff7d2 (diff)
Introduce option SplashThinLineMode
More info at bug #37347
-rw-r--r--poppler/SplashOutputDev.cc9
-rw-r--r--poppler/SplashOutputDev.h3
-rw-r--r--splash/Splash.cc37
-rw-r--r--splash/Splash.h9
-rw-r--r--splash/SplashClip.cc7
-rw-r--r--splash/SplashClip.h4
-rw-r--r--splash/SplashTypes.h8
-rw-r--r--splash/SplashXPath.cc14
-rw-r--r--splash/SplashXPath.h17
-rw-r--r--splash/SplashXPathScanner.cc9
-rw-r--r--splash/SplashXPathScanner.h17
11 files changed, 110 insertions, 24 deletions
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 84023a66..31d6fce1 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -1211,7 +1211,7 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
GBool reverseVideoA,
SplashColorPtr paperColorA,
GBool bitmapTopDownA,
- GBool allowAntialiasA) {
+ GBool allowAntialiasA, SplashThinLineMode thinLineMode) {
colorMode = colorModeA;
bitmapRowPad = bitmapRowPadA;
bitmapTopDown = bitmapTopDownA;
@@ -1239,6 +1239,7 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
colorMode != splashModeMono1, bitmapTopDown);
splash = new Splash(bitmap, vectorAntialias, &screenParams);
splash->setMinLineWidth(globalParams->getMinLineWidth());
+ splash->setThinLineMode(thinLineMode);
splash->clear(paperColor, 0);
fontEngine = NULL;
@@ -1367,7 +1368,9 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
} else {
w = h = 1;
}
+ SplashThinLineMode thinLineMode = splashThinLineDefault;
if (splash) {
+ thinLineMode = splash->getThinLineMode();
delete splash;
splash = NULL;
}
@@ -1380,6 +1383,7 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
colorMode != splashModeMono1, bitmapTopDown);
}
splash = new Splash(bitmap, vectorAntialias, &screenParams);
+ splash->setThinLineMode(thinLineMode);
splash->setMinLineWidth(globalParams->getMinLineWidth());
if (state) {
ctm = state->getCTM();
@@ -2584,6 +2588,7 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
color[0] = 0xff;
}
splash->setMinLineWidth(globalParams->getMinLineWidth());
+ splash->setThinLineMode(splashThinLineDefault);
splash->setFillPattern(new SplashSolidColor(color));
splash->setStrokePattern(new SplashSolidColor(color));
//~ this should copy other state from t3GlyphStack->origSplash?
@@ -3819,6 +3824,7 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
bitmapTopDown, bitmap->getSeparationList());
splash = new Splash(bitmap, vectorAntialias,
transpGroup->origSplash->getScreen());
+ splash->setThinLineMode(transpGroup->origSplash->getThinLineMode());
splash->setMinLineWidth(globalParams->getMinLineWidth());
//~ Acrobat apparently copies at least the fill and stroke colors, and
//~ maybe other state(?) -- but not the clipping path (and not sure
@@ -4207,6 +4213,7 @@ GBool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *ca
} else {
splash->clear(paperColor, 0);
}
+ splash->setThinLineMode(formerSplash->getThinLineMode());
splash->setMinLineWidth(globalParams->getMinLineWidth());
box.x1 = bbox[0]; box.y1 = bbox[1];
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index dbc13121..d9fdd299 100644
--- a/poppler/SplashOutputDev.h
+++ b/poppler/SplashOutputDev.h
@@ -163,7 +163,8 @@ public:
SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
GBool reverseVideoA, SplashColorPtr paperColorA,
GBool bitmapTopDownA = gTrue,
- GBool allowAntialiasA = gTrue);
+ GBool allowAntialiasA = gTrue,
+ SplashThinLineMode thinLineMode = splashThinLineDefault);
// Destructor.
virtual ~SplashOutputDev();
diff --git a/splash/Splash.cc b/splash/Splash.cc
index d0d986ef..ce2befb5 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -13,7 +13,7 @@
//
// Copyright (C) 2005-2013 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
-// Copyright (C) 2010-2012 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2011, 2012 William Bader <williambader@hotmail.com>
// Copyright (C) 2012 Markus Trippelsdorf <markus@trippelsdorf.de>
@@ -1450,7 +1450,7 @@ inline void Splash::drawSpan(SplashPipe *pipe, int x0, int x1, int y,
}
}
-inline void Splash::drawAALine(SplashPipe *pipe, int x0, int x1, int y) {
+inline void Splash::drawAALine(SplashPipe *pipe, int x0, int x1, int y, GBool adjustLine, Guchar lineOpacity) {
#if splashAASize == 4
static int bitCount4[16] = { 0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4 };
@@ -1493,7 +1493,7 @@ inline void Splash::drawAALine(SplashPipe *pipe, int x0, int x1, int y) {
#endif
if (t != 0) {
- pipe->shape = aaGamma[t];
+ pipe->shape = (adjustLine) ? div255((int) lineOpacity * aaGamma[t]) : aaGamma[t];
(this->*pipe->run)(pipe);
updateModX(x);
updateModY(y);
@@ -1542,6 +1542,7 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
aaBuf = NULL;
}
minLineWidth = 0;
+ thinLineMode = splashThinLineDefault;
clearModRegion();
debugMode = gFalse;
}
@@ -1568,6 +1569,7 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
aaBuf = NULL;
}
minLineWidth = 0;
+ thinLineMode = splashThinLineDefault;
clearModRegion();
debugMode = gFalse;
}
@@ -2365,6 +2367,8 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
SplashXPathScanner *scanner;
int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
SplashClipResult clipRes, clipRes2;
+ GBool adjustLine = gFalse;
+ int linePosI = 0;
if (path->length == 0) {
return splashErrEmptyPath;
@@ -2397,7 +2401,24 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
}
}
- xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);
+ if (thinLineMode != splashThinLineDefault) {
+ if (state->clip->getXMinI() == state->clip->getXMaxI()) {
+ linePosI = state->clip->getXMinI();
+ adjustLine = gTrue;
+ } else if (state->clip->getXMinI() == state->clip->getXMaxI() - 1) {
+ adjustLine = gTrue;
+ linePosI = splashFloor(state->clip->getXMin() + state->lineWidth);
+ } else if (state->clip->getYMinI() == state->clip->getYMaxI()) {
+ linePosI = state->clip->getYMinI();
+ adjustLine = gTrue;
+ } else if (state->clip->getYMinI() == state->clip->getYMaxI() - 1) {
+ adjustLine = gTrue;
+ linePosI = splashFloor(state->clip->getYMin() + state->lineWidth);
+ }
+ }
+
+ xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue,
+ adjustLine, linePosI);
if (vectorAntialias && !inShading) {
xPath->aaScale();
}
@@ -2430,11 +2451,13 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
// draw the spans
if (vectorAntialias && !inShading) {
for (y = yMinI; y <= yMaxI; ++y) {
- scanner->renderAALine(aaBuf, &x0, &x1, y);
+ scanner->renderAALine(aaBuf, &x0, &x1, y, thinLineMode != splashThinLineDefault && xMinI == xMaxI);
if (clipRes != splashClipAllInside) {
- state->clip->clipAALine(aaBuf, &x0, &x1, y);
+ state->clip->clipAALine(aaBuf, &x0, &x1, y, thinLineMode != splashThinLineDefault && xMinI == xMaxI);
}
- drawAALine(&pipe, x0, x1, y);
+ drawAALine(&pipe, x0, x1, y,
+ thinLineMode == splashThinLineShape && (xMinI == xMaxI || yMinI == yMaxI),
+ clip255(splashRound(state->lineWidth * 255)));
}
} else {
for (y = yMinI; y <= yMaxI; ++y) {
diff --git a/splash/Splash.h b/splash/Splash.h
index c31dbc85..49bad837 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -13,7 +13,7 @@
//
// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
// Copyright (C) 2007, 2011 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2010-2012 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
//
@@ -248,6 +248,10 @@ public:
// Set the minimum line width.
void setMinLineWidth(SplashCoord w) { minLineWidth = w; }
+ // Setter/Getter for thin line mode
+ void setThinLineMode(SplashThinLineMode thinLineModeA) { thinLineMode = thinLineModeA; }
+ SplashThinLineMode getThinLineMode() { return thinLineMode; }
+
// Get a bounding box which includes all modifications since the
// last call to clearModRegion.
void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax)
@@ -307,7 +311,7 @@ private:
void drawAAPixelInit();
void drawAAPixel(SplashPipe *pipe, int x, int y);
void drawSpan(SplashPipe *pipe, int x0, int x1, int y, GBool noClip);
- void drawAALine(SplashPipe *pipe, int x0, int x1, int y);
+ void drawAALine(SplashPipe *pipe, int x0, int x1, int y, GBool adjustLine = gFalse, Guchar lineOpacity = 0);
void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
SplashCoord *xo, SplashCoord *yo);
void updateModX(int x);
@@ -409,6 +413,7 @@ private:
int alpha0X, alpha0Y; // offset within alpha0Bitmap
SplashCoord aaGamma[splashAASize * splashAASize + 1];
SplashCoord minLineWidth;
+ SplashThinLineMode thinLineMode;
int modXMin, modYMin, modXMax, modYMax;
SplashClipResult opClipRes;
GBool vectorAntialias;
diff --git a/splash/SplashClip.cc b/splash/SplashClip.cc
index fb188317..85c6b114 100644
--- a/splash/SplashClip.cc
+++ b/splash/SplashClip.cc
@@ -12,6 +12,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2010 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2013 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
@@ -334,7 +335,7 @@ SplashClipResult SplashClip::testSpan(int spanXMin, int spanXMax, int spanY) {
return splashClipAllInside;
}
-void SplashClip::clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y) {
+void SplashClip::clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y, GBool adjustVertLine) {
int xx0, xx1, xx, yy, i;
SplashColorPtr p;
@@ -351,7 +352,7 @@ void SplashClip::clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y) {
for (xx = xx0; xx + 7 < xx1; xx += 8) {
*p++ = 0;
}
- if (xx < xx1) {
+ if (xx < xx1 && !adjustVertLine) {
*p &= 0xff >> (xx1 & 7);
}
}
@@ -364,7 +365,7 @@ void SplashClip::clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y) {
xx0 = 0;
}
xx1 = (*x1 + 1) * splashAASize;
- if (xx0 < xx1) {
+ if (xx0 < xx1 && !adjustVertLine) {
for (yy = 0; yy < splashAASize; ++yy) {
p = aaBuf->getDataPtr() + yy * aaBuf->getRowSize() + (xx0 >> 3);
xx = xx0;
diff --git a/splash/SplashClip.h b/splash/SplashClip.h
index 3eb2d780..5c0fdba9 100644
--- a/splash/SplashClip.h
+++ b/splash/SplashClip.h
@@ -12,6 +12,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2010 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2013 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
@@ -116,7 +117,8 @@ public:
// Clips an anti-aliased line by setting pixels to zero. On entry,
// all non-zero pixels are between <x0> and <x1>. This function
// will update <x0> and <x1>.
- void clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y);
+ void clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y,
+ GBool adjustVertLine = gFalse);
// Get the rectangle part of the clip region.
SplashCoord getXMin() { return xMin; }
diff --git a/splash/SplashTypes.h b/splash/SplashTypes.h
index 531b945b..fa4a3796 100644
--- a/splash/SplashTypes.h
+++ b/splash/SplashTypes.h
@@ -13,7 +13,7 @@
//
// Copyright (C) 2006, 2010 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
-// Copyright (C) 2009, 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2009, 2011-2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
// Copyright (C) 2010 William Bader <williambader@hotmail.com>
//
@@ -76,6 +76,12 @@ enum SplashColorMode {
#endif
};
+enum SplashThinLineMode {
+ splashThinLineDefault, // if SA on: draw solid if requested line width, transformed into
+ // device space, is less than half a pixel and a shaped line else
+ splashThinLineSolid, // draw line solid at least with 1 pixel
+ splashThinLineShape // draw line shaped at least with 1 pixel
+};
// number of components in each color mode
// (defined in SplashState.cc)
extern int splashColorModeNComps[];
diff --git a/splash/SplashXPath.cc b/splash/SplashXPath.cc
index b82d3559..27106ee3 100644
--- a/splash/SplashXPath.cc
+++ b/splash/SplashXPath.cc
@@ -13,6 +13,7 @@
//
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2010, 2011 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2013 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
@@ -66,7 +67,8 @@ inline void SplashXPath::transform(SplashCoord *matrix,
//------------------------------------------------------------------------
SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool closeSubpaths) {
+ SplashCoord flatness, GBool closeSubpaths,
+ GBool adjustLines, int linePosI) {
SplashPathHint *hint;
SplashXPathPoint *pts;
SplashXPathAdjust *adjusts, *adjust;
@@ -127,7 +129,15 @@ SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
x0 = splashRound(adj0);
x1 = splashRound(adj1);
if (x1 == x0) {
- x1 = x1 + 1;
+ if (adjustLines) {
+ // the adjustment moves thin lines (clip rectangle with
+ // empty width or height) out of clip area, here we need
+ // a special adjustment:
+ x0 = linePosI;
+ x1 = x0 + 1;
+ } else {
+ x1 = x1 + 1;
+ }
}
adjusts[i].x0 = (SplashCoord)x0;
adjusts[i].x1 = (SplashCoord)x1 - 0.01;
diff --git a/splash/SplashXPath.h b/splash/SplashXPath.h
index db06978a..1c7040da 100644
--- a/splash/SplashXPath.h
+++ b/splash/SplashXPath.h
@@ -4,6 +4,20 @@
//
//========================================================================
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2013 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
+//
+//========================================================================
+
#ifndef SPLASHXPATH_H
#define SPLASHXPATH_H
@@ -50,7 +64,8 @@ public:
// space, via <matrix>. If <closeSubpaths> is true, closes all open
// subpaths.
SplashXPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool closeSubpaths);
+ SplashCoord flatness, GBool closeSubpaths,
+ GBool adjustLines = gFalse, int linePosI = 0);
// Copy an expanded path.
SplashXPath *copy() { return new SplashXPath(this); }
diff --git a/splash/SplashXPathScanner.cc b/splash/SplashXPathScanner.cc
index 738cef7b..0fd5ccdc 100644
--- a/splash/SplashXPathScanner.cc
+++ b/splash/SplashXPathScanner.cc
@@ -13,6 +13,7 @@
//
// Copyright (C) 2008, 2010 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
+// Copyright (C) 2013 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
@@ -367,7 +368,7 @@ void SplashXPathScanner::addIntersection(double segYMin, double segYMax,
}
void SplashXPathScanner::renderAALine(SplashBitmap *aaBuf,
- int *x0, int *x1, int y) {
+ int *x0, int *x1, int y, GBool adjustVertLine) {
int xx0, xx1, xx, xxMin, xxMax, yy, interEnd;
Guchar mask;
SplashColorPtr p;
@@ -418,8 +419,8 @@ void SplashXPathScanner::renderAALine(SplashBitmap *aaBuf,
xx = xx0;
p = aaBuf->getDataPtr() + yy * aaBuf->getRowSize() + (xx >> 3);
if (xx & 7) {
- mask = 0xff >> (xx & 7);
- if ((xx & ~7) == (xx1 & ~7)) {
+ mask = adjustVertLine ? 0xff : 0xff >> (xx & 7);
+ if (!adjustVertLine && (xx & ~7) == (xx1 & ~7)) {
mask &= (Guchar)(0xff00 >> (xx1 & 7));
}
*p++ |= mask;
@@ -429,7 +430,7 @@ void SplashXPathScanner::renderAALine(SplashBitmap *aaBuf,
*p++ |= 0xff;
}
if (xx < xx1) {
- *p |= (Guchar)(0xff00 >> (xx1 & 7));
+ *p |= adjustVertLine ? 0xff : (Guchar)(0xff00 >> (xx1 & 7));
}
}
if (xx0 < xxMin) {
diff --git a/splash/SplashXPathScanner.h b/splash/SplashXPathScanner.h
index 719fae48..b59e3068 100644
--- a/splash/SplashXPathScanner.h
+++ b/splash/SplashXPathScanner.h
@@ -4,6 +4,20 @@
//
//========================================================================
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2013 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
+//
+//========================================================================
+
#ifndef SPLASHXPATHSCANNER_H
#define SPLASHXPATHSCANNER_H
@@ -60,7 +74,8 @@ public:
// Renders one anti-aliased line into <aaBuf>. Returns the min and
// max x coordinates with non-zero pixels in <x0> and <x1>.
- void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y);
+ void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y,
+ GBool adjustVertLine = gFalse);
// Clips an anti-aliased line by setting pixels to zero. On entry,
// all non-zero pixels are between <x0> and <x1>. This function