Commit 7f2c255f authored by Thomas Freitag's avatar Thomas Freitag Committed by Albert Astals Cid

Introduce option SplashThinLineMode

More info at bug #37347
parent c2ebcbea
......@@ -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];
......
......@@ -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();
......
......@@ -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) {
......
......@@ -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 Feuersnger <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;
......
......@@ -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;
......
......@@ -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; }
......
......@@ -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[];
......
......@@ -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;
......
......@@ -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); }
......
......@@ -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) {
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment