[poppler] poppler/SplashOutputDev.cc poppler/SplashOutputDev.h splash/Splash.cc splash/SplashClip.cc splash/SplashClip.h splash/Splash.h splash/SplashTypes.h splash/SplashXPath.cc splash/SplashXPath.h splash/SplashXPathScanner.cc splash/SplashXPathScanner.h

Albert Astals Cid aacid at kemper.freedesktop.org
Tue Feb 12 13:50:01 PST 2013


 poppler/SplashOutputDev.cc   |    9 ++++++++-
 poppler/SplashOutputDev.h    |    3 ++-
 splash/Splash.cc             |   37 ++++++++++++++++++++++++++++++-------
 splash/Splash.h              |    9 +++++++--
 splash/SplashClip.cc         |    7 ++++---
 splash/SplashClip.h          |    4 +++-
 splash/SplashTypes.h         |    8 +++++++-
 splash/SplashXPath.cc        |   14 ++++++++++++--
 splash/SplashXPath.h         |   17 ++++++++++++++++-
 splash/SplashXPathScanner.cc |    9 +++++----
 splash/SplashXPathScanner.h  |   17 ++++++++++++++++-
 11 files changed, 110 insertions(+), 24 deletions(-)

New commits:
commit 7f2c255ff28386ba992717f729f25a979f240375
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Tue Feb 12 22:48:40 2013 +0100

    Introduce option SplashThinLineMode
    
    More info at bug #37347

diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 84023a6..31d6fce 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 dbc1312..d9fdd29 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 d0d986e..ce2befb 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -13,7 +13,7 @@
 //
 // Copyright (C) 2005-2013 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2005 Marco Pesenti Gritti <mpg at redhat.com>
-// Copyright (C) 2010-2012 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
 // Copyright (C) 2011, 2012 William Bader <williambader at hotmail.com>
 // Copyright (C) 2012 Markus Trippelsdorf <markus at 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 c31dbc8..49bad83 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -13,7 +13,7 @@
 //
 // Copyright (C) 2005 Marco Pesenti Gritti <mpg at redhat.com>
 // Copyright (C) 2007, 2011 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2010-2012 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
 // Copyright (C) 2012 Adrian Johnson <ajohnson at 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 fb18831..85c6b11 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 at kde.org>
+// Copyright (C) 2013 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
@@ -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 3eb2d78..5c0fdba 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 at kde.org>
+// Copyright (C) 2013 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
@@ -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 531b945..fa4a379 100644
--- a/splash/SplashTypes.h
+++ b/splash/SplashTypes.h
@@ -13,7 +13,7 @@
 //
 // Copyright (C) 2006, 2010 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2008 Tomas Are Haavet <tomasare at gmail.com>
-// Copyright (C) 2009, 2011, 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2009, 2011-2013 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
 // Copyright (C) 2010 William Bader <williambader at 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 b82d355..27106ee 100644
--- a/splash/SplashXPath.cc
+++ b/splash/SplashXPath.cc
@@ -13,6 +13,7 @@
 //
 // Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha at gmail.com>
 // Copyright (C) 2010, 2011 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2013 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
@@ -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 db06978..1c7040d 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 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
+//
+//========================================================================
+
 #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 738cef7..0fd5ccd 100644
--- a/splash/SplashXPathScanner.cc
+++ b/splash/SplashXPathScanner.cc
@@ -13,6 +13,7 @@
 //
 // Copyright (C) 2008, 2010 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha at gmail.com>
+// Copyright (C) 2013 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
@@ -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 719fae4..b59e306 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 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
+//
+//========================================================================
+
 #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


More information about the poppler mailing list