diff options
author | Thomas Freitag <Thomas.Freitag@alfa.de> | 2013-02-12 22:48:40 +0100 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2013-02-12 22:48:40 +0100 |
commit | 7f2c255ff28386ba992717f729f25a979f240375 (patch) | |
tree | 9911b87b37669527b411a8fcd96ac286f2af0ff7 | |
parent | c2ebcbea2267f861c491c0cd6c1fbf2dc2aff7d2 (diff) |
Introduce option SplashThinLineMode
More info at bug #37347
-rw-r--r-- | poppler/SplashOutputDev.cc | 9 | ||||
-rw-r--r-- | poppler/SplashOutputDev.h | 3 | ||||
-rw-r--r-- | splash/Splash.cc | 37 | ||||
-rw-r--r-- | splash/Splash.h | 9 | ||||
-rw-r--r-- | splash/SplashClip.cc | 7 | ||||
-rw-r--r-- | splash/SplashClip.h | 4 | ||||
-rw-r--r-- | splash/SplashTypes.h | 8 | ||||
-rw-r--r-- | splash/SplashXPath.cc | 14 | ||||
-rw-r--r-- | splash/SplashXPath.h | 17 | ||||
-rw-r--r-- | splash/SplashXPathScanner.cc | 9 | ||||
-rw-r--r-- | splash/SplashXPathScanner.h | 17 |
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 |