[poppler] poppler/CharCodeToUnicode.cc poppler/Gfx.cc poppler/GfxFont.cc poppler/GlobalParams.cc poppler/GlobalParams.h

mpsuzuki at hiroshima-u.ac.jp mpsuzuki at hiroshima-u.ac.jp
Tue Mar 27 02:32:00 PDT 2012


Dear Thomas,

Excuse me, could you post a patch after a check that proposed
patch does not break the compilation? Your last patch broke
the building under the configuration using win32 font backend.
Unfortunately, it is already committed to git head and I could
not build Win32 binary. I got following error.

Yet I've not checked if MSVC environment can build it, but the
error messages by GCC look quite fundamental error (e.g. the
number of arguments does not match), so I guess it is not mingw-gcc
specific issue.

I attached a patch to finish the compilation successfully, but
I'm not sure it is correctly reflecting your intention of the
patch. Please review and fix this issue until the official release
of 0.20.

Regards,
mpsuzuki

make[3]: Entering directory `/tmp/poppler-current/build-mingw/poppler'
/bin/sh ../libtool  --tag=CXX   --mode=compile i586-mingw32msvc-g++ -DHAVE_CONFIG_H -I. -I/tmp/poppler-current/poppler -I.. -I/tmp/poppler-current -I/tmp/poppler-current/goo      -I/tmp/libpng-mingw/include -I/tmp/zlib-mingw/include  -I/tmp/ft2-mingwinclude/freetype2 -I/tmp/ft2-mingwinclude   -D_WIN32_IE=0x0500  -Wall -Woverloaded-virtual -Wnon-virtual-dtor -Wcast-align -fno-exceptions -fno-check-new -fno-common -g -O2  -MT GlobalParams.lo -MD -MP -MF .deps/GlobalParams.Tpo -c -o GlobalParams.lo /tmp/poppler-current/poppler/GlobalParams.cc
libtool: compile:  i586-mingw32msvc-g++ -DHAVE_CONFIG_H -I. -I/tmp/poppler-current/poppler -I.. -I/tmp/poppler-current -I/tmp/poppler-current/goo -I/tmp/libpng-mingw/include -I/tmp/zlib-mingw/include -I/tmp/ft2-mingwinclude/freetype2 -I/tmp/ft2-mingwinclude -D_WIN32_IE=0x0500 -Wall -Woverloaded-virtual -Wnon-virtual-dtor -Wcast-align -fno-exceptions -fno-check-new -fno-common -g -O2 -MT GlobalParams.lo -MD -MP -MF .deps/GlobalParams.Tpo -c /tmp/poppler-current/poppler/GlobalParams.cc -o GlobalParams.o
/tmp/poppler-current/poppler/GlobalParams.cc: In function 'char* get_poppler_datadir()':
/tmp/poppler-current/poppler/GlobalParams.cc:180: warning: deprecated conversion from string constant to 'char*'
In file included from /tmp/poppler-current/poppler/GlobalParams.cc:1340:
/tmp/poppler-current/poppler/GlobalParamsWin.cc: In member function 'void SysFontList::scanWindowsFonts(GooString*)':
/tmp/poppler-current/poppler/GlobalParamsWin.cc:243: warning: deprecated conversion from string constant to 'char*'
/tmp/poppler-current/poppler/GlobalParamsWin.cc:245: warning: deprecated conversion from string constant to 'char*'
/tmp/poppler-current/poppler/GlobalParamsWin.cc: In member function 'SysFontInfo* SysFontList::makeWindowsFont(char*, int, char*)':
/tmp/poppler-current/poppler/GlobalParamsWin.cc:353: error: no matching function for call to 'SysFontInfo::SysFontInfo(GooString*&, GBool&, GBool&, GooString*, SysFontType&, int&)'
/tmp/poppler-current/poppler/GlobalParams.cc:225: note: candidates are: SysFontInfo::SysFontInfo(GooString*, GBool, GBool, GBool, GBool, GooString*, SysFontType, int)
/tmp/poppler-current/poppler/GlobalParams.cc:205: note:                 SysFontInfo::SysFontInfo(const SysFontInfo&)
/tmp/poppler-current/poppler/GlobalParamsWin.cc: At global scope:
/tmp/poppler-current/poppler/GlobalParamsWin.cc:475: error: prototype for 'GooString* GlobalParams::findSystemFontFile(GfxFont*, SysFontType*, int*, GooString*)' does not match any in class 'GlobalParams'
/tmp/poppler-current/poppler/GlobalParams.h:151: error: candidate is: GooString* GlobalParams::findSystemFontFile(GfxFont*, SysFontType*, int*, GooString*, GooString*)
/tmp/poppler-current/poppler/GlobalParamsWin.cc:452: warning: 'const char* findSubstituteName(GfxFont*, GooHash*, const char*)' defined but not used
make[3]: *** [GlobalParams.lo] Error 1








On Mon, 26 Mar 2012 15:02:29 -0700 (PDT)
aacid at kemper.freedesktop.org (Albert Astals Cid) wrote:

> poppler/CharCodeToUnicode.cc |    5 
> poppler/Gfx.cc               |  329 +++++++++++++++++++------------------------
> poppler/GfxFont.cc           |    3 
> poppler/GlobalParams.cc      |   78 +++++++---
> poppler/GlobalParams.h       |    6 
> 5 files changed, 218 insertions(+), 203 deletions(-)
>
>New commits:
>commit d6a1b7dcaeac1e49533519b9f8a279fd64d04c67
>Author: Thomas Freitag <Thomas.Freitag at alfa.de>
>Date:   Tue Mar 27 00:00:05 2012 +0200
>
>    Some regression fixes/improvements
>    
>    I just finished the patch for these regressions, they had differents reasons
>    1. In CharCodeToUnicode::mapToUnicode the identity support was missing
>    2. The new algorithms for axial and radial shading caused problems in
>    cairo. I revert these changes but removed the examination of hidden
>    content (this is already done in the calling function)
>    3. The examination of optional hidden content in showing text was wrong:
>    of course hidden text should not be shown, but text parameters like text
>    position in the state must be changed!
>    4. Searching and finding fonts especially with base14 fonts should be
>    more exact than just looking at the base14 name (i.e. fixed width and so
>    on) when using fontconfig. I implement that to find the best font
>    fitting to the needs.
>
>diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc
>index 076f5ba..d0e6c7f 100644
>--- a/poppler/CharCodeToUnicode.cc
>+++ b/poppler/CharCodeToUnicode.cc
>@@ -20,6 +20,7 @@
> // Copyright (C) 2008 Vasile Gaburici <gaburici at cs.umd.edu>
> // Copyright (C) 2010 William Bader <williambader at hotmail.com>
> // Copyright (C) 2010 Jakub Wilk <ubanus at users.sf.net>
>+// 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
>@@ -621,6 +622,10 @@ int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode **u) {
> int CharCodeToUnicode::mapToCharCode(Unicode* u, CharCode *c, int usize) {
>   //look for charcode in map
>   if (usize == 1) {
>+    if (isIdentity) {
>+      *c = (CharCode) *u;
>+      return 1;
>+    }
>     for (CharCode i=0; i<mapLen; i++) {
>       if (map[i] == *u) {
>         *c = i;
>diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
>index 2cc8e28..958194b 100644
>--- a/poppler/Gfx.cc
>+++ b/poppler/Gfx.cc
>@@ -28,7 +28,7 @@
> // Copyright (C) 2008 Michael Vrable <mvrable at cs.ucsd.edu>
> // Copyright (C) 2008 Hib Eris <hib at hiberis.nl>
> // Copyright (C) 2009 M Joonas Pihlaja <jpihlaja at cc.helsinki.fi>
>-// Copyright (C) 2009-2011 Thomas Freitag <Thomas.Freitag at alfa.de>
>+// Copyright (C) 2009-2012 Thomas Freitag <Thomas.Freitag at alfa.de>
> // Copyright (C) 2009 William Bader <williambader at hotmail.com>
> // Copyright (C) 2009, 2010 David Benjamin <davidben at mit.edu>
> // Copyright (C) 2010 Nils H旦glund <nils.hoglund at gmail.com>
>@@ -2576,10 +2576,10 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>   double xMin, yMin, xMax, yMax;
>   double x0, y0, x1, y1;
>   double dx, dy, mul;
>-  GBool dxdyZero, horiz;
>+  GBool dxZero, dyZero;
>   double bboxIntersections[4];
>   double tMin, tMax, tx, ty;
>-  double sMin, sMax, tmp;
>+  double s[4], sMin, sMax, tmp;
>   double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
>   double t0, t1, tt;
>   double ta[axialMaxSplits + 1];
>@@ -2597,9 +2597,9 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>   shading->getCoords(&x0, &y0, &x1, &y1);
>   dx = x1 - x0;
>   dy = y1 - y0;
>-  dxdyZero = fabs(dx) < 0.01 && fabs(dy) < 0.01;
>-  horiz = fabs(dy) < fabs(dx);
>-  if (dxdyZero) {
>+  dxZero = fabs(dx) < 0.01;
>+  dyZero = fabs(dy) < 0.01;
>+  if (dxZero && dyZero) {
>     tMin = tMax = 0;
>   } else {
>     mul = 1 / (dx * dx + dy * dy);
>@@ -2636,16 +2636,18 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>   //     y(s) = ty + s * dx    -->   s = (y - ty) / dx
>   //
>   // Then look at the intersection of this line with the bounding box
>-  // (xMin, yMin, xMax, yMax).  For -1 < |dy/dx| < 1, look at the
>-  // intersection with yMin, yMax:
>-  //
>-  //     s0 = (yMin - ty) / dx
>-  //     s1 = (yMax - ty) / dx
>-  //
>-  // else look at the intersection with xMin, xMax:
>+  // (xMin, yMin, xMax, yMax).  In the general case, there are four
>+  // intersection points:
>   //
>   //     s0 = (xMin - tx) / -dy
>   //     s1 = (xMax - tx) / -dy
>+  //     s2 = (yMin - ty) / dx
>+  //     s3 = (yMax - ty) / dx
>+  //
>+  // and we want the middle two s values.
>+  //
>+  // In the case where dx = 0, take s0 and s1; in the case where dy =
>+  // 0, take s2 and s3.
>   //
>   // Each filled polygon is bounded by two of these line segments
>   // perpdendicular to the t axis.
>@@ -2654,10 +2656,13 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>   // difference across a region is small enough, and then the region
>   // is painted with a single color.
> 
>-  // set up
>+  // set up: require at least one split to avoid problems when the two
>+  // ends of the t axis have the same color
>   nComps = shading->getColorSpace()->getNComps();
>   ta[0] = tMin;
>-  next[0] = axialMaxSplits;
>+  next[0] = axialMaxSplits / 2;
>+  ta[axialMaxSplits / 2] = 0.5 * (tMin + tMax);
>+  next[axialMaxSplits / 2] = axialMaxSplits;
>   ta[axialMaxSplits] = tMax;
> 
>   // compute the color at t = tMin
>@@ -2681,19 +2686,24 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>   // bounding box
>   tx = x0 + tMin * dx;
>   ty = y0 + tMin * dy;
>-  if (dxdyZero) {
>+  if (dxZero && dyZero) {
>     sMin = sMax = 0;
>+  } else if (dxZero) {
>+    sMin = (xMin - tx) / -dy;
>+    sMax = (xMax - tx) / -dy;
>+    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
>+  } else if (dyZero) {
>+    sMin = (yMin - ty) / dx;
>+    sMax = (yMax - ty) / dx;
>+    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
>   } else {
>-    if (horiz) {
>-      sMin = (yMin - ty) / dx;
>-      sMax = (yMax - ty) / dx;
>-    } else {
>-      sMin = (xMin - tx) / -dy;
>-      sMax = (xMax - tx) / -dy;
>-    }
>-    if (sMin > sMax) {
>-      tmp = sMin; sMin = sMax; sMax = tmp;
>-    }
>+    s[0] = (yMin - ty) / dx;
>+    s[1] = (yMax - ty) / dx;
>+    s[2] = (xMin - tx) / -dy;
>+    s[3] = (xMax - tx) / -dy;
>+    bubbleSort(s);
>+    sMin = s[1];
>+    sMax = s[2];
>   }
>   ux0 = tx - sMin * dy;
>   uy0 = ty + sMin * dx;
>@@ -2702,7 +2712,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
> 
>   i = 0;
>   bool doneBBox1, doneBBox2;
>-  if (dxdyZero) {
>+  if (dxZero && dyZero) {
>     doneBBox1 = doneBBox2 = true;
>   } else {
>     doneBBox1 = bboxIntersections[1] < tMin;
>@@ -2782,21 +2792,24 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
>     // bounding box
>     tx = x0 + ta[j] * dx;
>     ty = y0 + ta[j] * dy;
>-    tx = x0 + ta[j] * dx;
>-    ty = y0 + ta[j] * dy;
>-    if (dxdyZero) {
>+    if (dxZero && dyZero) {
>       sMin = sMax = 0;
>+    } else if (dxZero) {
>+      sMin = (xMin - tx) / -dy;
>+      sMax = (xMax - tx) / -dy;
>+      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
>+    } else if (dyZero) {
>+      sMin = (yMin - ty) / dx;
>+      sMax = (yMax - ty) / dx;
>+      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
>     } else {
>-      if (horiz) {
>-	sMin = (yMin - ty) / dx;
>-	sMax = (yMax - ty) / dx;
>-      } else {
>-	sMin = (xMin - tx) / -dy;
>-	sMax = (xMax - tx) / -dy;
>-      }
>-      if (sMin > sMax) {
>-	tmp = sMin; sMin = sMax; sMax = tmp;
>-      }
>+      s[0] = (yMin - ty) / dx;
>+      s[1] = (yMax - ty) / dx;
>+      s[2] = (xMin - tx) / -dy;
>+      s[3] = (xMax - tx) / -dy;
>+      bubbleSort(s);
>+      sMin = s[1];
>+      sMax = s[2];
>     }
>     ux1 = tx - sMin * dy;
>     uy1 = ty + sMin * dx;
>@@ -2874,10 +2887,7 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
>   GfxColor colorA, colorB;
>   double xa, ya, xb, yb, ra, rb;
>   double ta, tb, sa, sb;
>-  double sMin, sMax, h;
>-  double sLeft, sRight, sTop, sBottom, sZero, sDiag;
>-  GBool haveSLeft, haveSRight, haveSTop, haveSBottom, haveSZero;
>-  GBool haveSMin, haveSMax;
>+  double sz, xz, yz, sMin, sMax;
>   GBool enclosed;
>   int ia, ib, k, n;
>   double *ctm;
>@@ -2892,21 +2902,24 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
> 
>   // Compute the point at which r(s) = 0; check for the enclosed
>   // circles case; and compute the angles for the tangent lines.
>-  h = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
>-  if (h == 0) {
>+  if (x0 == x1 && y0 == y1) {
>     enclosed = gTrue;
>     theta = 0; // make gcc happy
>-  } else if (r1 - r0 == 0) {
>+    sz = 0; // make gcc happy
>+  } else if (r0 == r1) {
>     enclosed = gFalse;
>     theta = 0;
>-  } else if (fabs(r1 - r0) >= h) {
>-    enclosed = gTrue;
>-    theta = 0; // make gcc happy
>+    sz = 0; // make gcc happy
>   } else {
>-    enclosed = gFalse;
>-    theta = asin((r1 - r0) / h);
>+    sz = (r1 > r0) ? -r0 / (r1 - r0) : -r1 / (r0 - r1);
>+    xz = x0 + sz * (x1 - x0);
>+    yz = y0 + sz * (y1 - y0);
>+    enclosed = (xz - x0) * (xz - x0) + (yz - y0) * (yz - y0) <= r0 * r0;
>+    theta = asin(r0 / sqrt((x0 - xz) * (x0 - xz) + (y0 - yz) * (y0 - yz)));
>+    if (r0 > r1) {
>+      theta = -theta;
>+    }
>   }
>-
>   if (enclosed) {
>     alpha = 0;
>   } else {
>@@ -2919,101 +2932,59 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
>     sMin = 0;
>     sMax = 1;
>   } else {
>-    // solve x(sLeft) + r(sLeft) = xMin
>-    if ((haveSLeft = fabs((x1 + r1) - (x0 + r0)) > 0.000001)) {
>-      sLeft = (xMin - (x0 + r0)) / ((x1 + r1) - (x0 + r0));
>-    } else {
>-      sLeft = 0; // make gcc happy
>-    }
>-    // solve x(sRight) - r(sRight) = xMax
>-    if ((haveSRight = fabs((x1 - r1) - (x0 - r0)) > 0.000001)) {
>-      sRight = (xMax - (x0 - r0)) / ((x1 - r1) - (x0 - r0));
>-    } else {
>-      sRight = 0; // make gcc happy
>-    }
>-    // solve y(sBottom) + r(sBottom) = yMin
>-    if ((haveSBottom = fabs((y1 + r1) - (y0 + r0)) > 0.000001)) {
>-      sBottom = (yMin - (y0 + r0)) / ((y1 + r1) - (y0 + r0));
>-    } else {
>-      sBottom = 0; // make gcc happy
>-    }
>-    // solve y(sTop) - r(sTop) = yMax
>-    if ((haveSTop = fabs((y1 - r1) - (y0 - r0)) > 0.000001)) {
>-      sTop = (yMax - (y0 - r0)) / ((y1 - r1) - (y0 - r0));
>-    } else {
>-      sTop = 0; // make gcc happy
>+    sMin = 1;
>+    sMax = 0;
>+    // solve for x(s) + r(s) = xMin
>+    if ((x1 + r1) - (x0 + r0) != 0) {
>+      sa = (xMin - (x0 + r0)) / ((x1 + r1) - (x0 + r0));
>+      if (sa < sMin) {
>+	sMin = sa;
>+      } else if (sa > sMax) {
>+	sMax = sa;
>+      }
>     }
>-    // solve r(sZero) = 0
>-    if ((haveSZero = fabs(r1 - r0) > 0.000001)) {
>-      sZero = -r0 / (r1 - r0);
>-    } else {
>-      sZero = 0; // make gcc happy
>+    // solve for x(s) - r(s) = xMax
>+    if ((x1 - r1) - (x0 - r0) != 0) {
>+      sa = (xMax - (x0 - r0)) / ((x1 - r1) - (x0 - r0));
>+      if (sa < sMin) {
>+	sMin = sa;
>+      } else if (sa > sMax) {
>+	sMax = sa;
>+      }
>     }
>-    // solve r(sDiag) = sqrt((xMax-xMin)^2 + (yMax-yMin)^2)
>-    if (haveSZero) {
>-      sDiag = (sqrt((xMax - xMin) * (xMax - xMin) +
>-		    (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
>-    } else {
>-      sDiag = 0; // make gcc happy
>+    // solve for y(s) + r(s) = yMin
>+    if ((y1 + r1) - (y0 + r0) != 0) {
>+      sa = (yMin - (y0 + r0)) / ((y1 + r1) - (y0 + r0));
>+      if (sa < sMin) {
>+	sMin = sa;
>+      } else if (sa > sMax) {
>+	sMax = sa;
>+      }
>     }
>-    // compute sMin
>-    if (shading->getExtend0()) {
>-      sMin = 0;
>-      haveSMin = gFalse;
>-      if (x0 < x1 && haveSLeft && sLeft < 0) {
>-	sMin = sLeft;
>-	haveSMin = gTrue;
>-      } else if (x0 > x1 && haveSRight && sRight < 0) {
>-	sMin = sRight;
>-	haveSMin = gTrue;
>+    // solve for y(s) - r(s) = yMax
>+    if ((y1 - r1) - (y0 - r0) != 0) {
>+      sa = (yMax - (y0 - r0)) / ((y1 - r1) - (y0 - r0));
>+      if (sa < sMin) {
>+	sMin = sa;
>+      } else if (sa > sMax) {
>+	sMax = sa;
>       }
>-      if (y0 < y1 && haveSBottom && sBottom < 0) {
>-	if (!haveSMin || sBottom > sMin) {
>-	  sMin = sBottom;
>-	  haveSMin = gTrue;
>-	}
>-      } else if (y0 > y1 && haveSTop && sTop < 0) {
>-	if (!haveSMin || sTop > sMin) {
>-	  sMin = sTop;
>-	  haveSMin = gTrue;
>-	}
>+    }
>+    // check against sz
>+    if (r0 < r1) {
>+      if (sMin < sz) {
>+	sMin = sz;
>       }
>-      if (haveSZero && sZero < 0) {
>-	if (!haveSMin || sZero > sMin) {
>-	  sMin = sZero;
>-	}
>+    } else if (r0 > r1) {
>+      if (sMax > sz) {
>+	sMax = sz;
>       }
>-    } else {
>+    }
>+    // check the 'extend' flags
>+    if (!shading->getExtend0() && sMin < 0) {
>       sMin = 0;
>     }
>-    // compute sMax
>-    if (shading->getExtend1()) {
>-      sMax = 1;
>-      haveSMax = gFalse;
>-      if (x1 < x0 && haveSLeft && sLeft > 1) {
>-	sMax = sLeft;
>-	haveSMax = gTrue;
>-      } else if (x1 > x0 && haveSRight && sRight > 1) {
>-	sMax = sRight;
>-	haveSMax = gTrue;
>-      }
>-      if (y1 < y0 && haveSBottom && sBottom > 1) {
>-	if (!haveSMax || sBottom < sMax) {
>-	  sMax = sBottom;
>-	  haveSMax = gTrue;
>-	}
>-      } else if (y1 > y0 && haveSTop && sTop > 1) {
>-	if (!haveSMax || sTop < sMax) {
>-	  sMax = sTop;
>-	  haveSMax = gTrue;
>-	}
>-      }
>-      if (haveSZero && sDiag > 1) {
>-	if (!haveSMax || sDiag < sMax) {
>-	  sMax = sDiag;
>-	}
>-      }
>-    } else {
>+    if (!shading->getExtend1() && sMax > 1) {
>       sMax = 1;
>     }
>   }
>@@ -3758,11 +3729,10 @@ void Gfx::opShowText(Object args[], int numArgs) {
>     out->updateFont(state);
>     fontChanged = gFalse;
>   }
>-  if (ocState) {
>-    out->beginStringOp(state);
>-    doShowText(args[0].getString());
>-    out->endStringOp(state);
>-  } else {
>+  out->beginStringOp(state);
>+  doShowText(args[0].getString());
>+  out->endStringOp(state);
>+  if (!ocState) {
>     doIncCharCount(args[0].getString());
>   }
> }
>@@ -3782,11 +3752,10 @@ void Gfx::opMoveShowText(Object args[], int numArgs) {
>   ty = state->getLineY() - state->getLeading();
>   state->textMoveTo(tx, ty);
>   out->updateTextPos(state);
>-  if (ocState) {
>-    out->beginStringOp(state);
>-    doShowText(args[0].getString());
>-    out->endStringOp(state);
>-  } else {
>+  out->beginStringOp(state);
>+  doShowText(args[0].getString());
>+  out->endStringOp(state);
>+  if (!ocState) {
>     doIncCharCount(args[0].getString());
>   }
> }
>@@ -3810,11 +3779,10 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
>   out->updateWordSpace(state);
>   out->updateCharSpace(state);
>   out->updateTextPos(state);
>+  out->beginStringOp(state);
>+  doShowText(args[2].getString());
>+  out->endStringOp(state);
>   if (ocState) {
>-    out->beginStringOp(state);
>-    doShowText(args[2].getString());
>-    out->endStringOp(state);
>-  } else {
>     doIncCharCount(args[2].getString());
>   }
> }
>@@ -3833,34 +3801,33 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
>     out->updateFont(state);
>     fontChanged = gFalse;
>   }
>-  if (ocState) {
>-    out->beginStringOp(state);
>-    wMode = state->getFont()->getWMode();
>-    a = args[0].getArray();
>-    for (i = 0; i < a->getLength(); ++i) {
>-      a->get(i, &obj);
>-      if (obj.isNum()) {
>+  out->beginStringOp(state);
>+  wMode = state->getFont()->getWMode();
>+  a = args[0].getArray();
>+  for (i = 0; i < a->getLength(); ++i) {
>+    a->get(i, &obj);
>+    if (obj.isNum()) {
>       // this uses the absolute value of the font size to match
>       // Acrobat's behavior
>-	if (wMode) {
>-	  state->textShift(0, -obj.getNum() * 0.001 *
>-			   state->getFontSize());
>-	} else {
>-	  state->textShift(-obj.getNum() * 0.001 *
>-			   state->getFontSize() *
>-			   state->getHorizScaling(), 0);
>-	}
>-	out->updateTextShift(state, obj.getNum());
>-      } else if (obj.isString()) {
>-	doShowText(obj.getString());
>+      if (wMode) {
>+        state->textShift(0, -obj.getNum() * 0.001 *
>+          state->getFontSize());
>       } else {
>-	error(errSyntaxError, getPos(),
>-	      "Element of show/space array must be number or string");
>+        state->textShift(-obj.getNum() * 0.001 *
>+          state->getFontSize() *
>+          state->getHorizScaling(), 0);
>       }
>-      obj.free();
>+      out->updateTextShift(state, obj.getNum());
>+    } else if (obj.isString()) {
>+      doShowText(obj.getString());
>+    } else {
>+      error(errSyntaxError, getPos(),
>+        "Element of show/space array must be number or string");
>     }
>-    out->endStringOp(state);
>-  } else {
>+    obj.free();
>+  }
>+  out->endStringOp(state);
>+  if (!ocState) {
>     a = args[0].getArray();
>     for (i = 0; i < a->getLength(); ++i) {
>       a->get(i, &obj);
>@@ -4018,7 +3985,8 @@ void Gfx::doShowText(GooString *s) {
>       originX *= state->getFontSize();
>       originY *= state->getFontSize();
>       state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
>-      out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
>+      if (ocState)
>+        out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
> 		      tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
>       state->shift(tdx, tdy);
>       p += n;
>@@ -4055,7 +4023,8 @@ void Gfx::doShowText(GooString *s) {
>       dy *= state->getFontSize();
>     }
>     state->textTransformDelta(dx, dy, &tdx, &tdy);
>-    out->drawString(state, s);
>+    if (ocState)
>+      out->drawString(state, s);
>     state->shift(tdx, tdy);
>   }
> 
>@@ -4063,7 +4032,7 @@ void Gfx::doShowText(GooString *s) {
>     out->endString(state);
>   }
> 
>-  if (patternFill) {
>+  if (patternFill && ocState) {
>     out->saveTextPos(state);
>     // tell the OutputDev to do the clipping
>     out->endTextObject(state);
>diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
>index b3016f4..ea22af8 100644
>--- a/poppler/GfxFont.cc
>+++ b/poppler/GfxFont.cc
>@@ -29,6 +29,7 @@
> // Copyright (C) 2011, 2012 Adrian Johnson <ajohnson at redneon.com>
> // Copyright (C) 2012 Yi Yang <ahyangyi at gmail.com>
> // Copyright (C) 2012 Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
>+// 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
>@@ -693,7 +694,7 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
>   //----- external font file for Base-14 font
>   if (!ps && !isCIDFont() && ((Gfx8BitFont *)this)->base14) {
>     base14Name = new GooString(((Gfx8BitFont *)this)->base14->base14Name);
>-    if ((path = globalParams->findFontFile(base14Name))) {
>+    if ((path = globalParams->findBase14FontFile(base14Name, this))) {
>       if ((fontLoc = getExternalFont(path, gFalse))) {
> 	delete base14Name;
> 	return fontLoc;
>diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
>index 76da74a..662f8f9 100644
>--- a/poppler/GlobalParams.cc
>+++ b/poppler/GlobalParams.cc
>@@ -208,22 +208,27 @@ public:
>   GooString *name;
>   GBool bold;
>   GBool italic;
>+  GBool oblique;
>+  GBool fixedWidth;
>   GooString *path;
>   SysFontType type;
>   int fontNum;			// for TrueType collections
> 
>-  SysFontInfo(GooString *nameA, GBool boldA, GBool italicA,
>+  SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
> 	      GooString *pathA, SysFontType typeA, int fontNumA);
>   ~SysFontInfo();
>   GBool match(SysFontInfo *fi);
>+  GBool match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA);
>   GBool match(GooString *nameA, GBool boldA, GBool italicA);
> };
> 
>-SysFontInfo::SysFontInfo(GooString *nameA, GBool boldA, GBool italicA,
>+SysFontInfo::SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
> 			 GooString *pathA, SysFontType typeA, int fontNumA) {
>   name = nameA;
>   bold = boldA;
>   italic = italicA;
>+  oblique = obliqueA;
>+  fixedWidth = fixedWidthA;
>   path = pathA;
>   type = typeA;
>   fontNum = fontNumA;
>@@ -236,7 +241,12 @@ SysFontInfo::~SysFontInfo() {
> 
> GBool SysFontInfo::match(SysFontInfo *fi) {
>   return !strcasecmp(name->getCString(), fi->name->getCString()) &&
>-         bold == fi->bold && italic == fi->italic;
>+         bold == fi->bold && italic == fi->italic && oblique == fi->oblique && fixedWidth == fi->fixedWidth;
>+}
>+
>+GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA) {
>+  return !strcasecmp(name->getCString(), nameA->getCString()) &&
>+         bold == boldA && italic == italicA && oblique == obliqueA && fixedWidth == fixedWidthA;
> }
> 
> GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA) {
>@@ -253,7 +263,7 @@ public:
> 
>   SysFontList();
>   ~SysFontList();
>-  SysFontInfo *find(GooString *name, GBool exact);
>+  SysFontInfo *find(GooString *name, GBool isFixedWidth, GBool exact);
> 
> #ifdef WIN32
>   void scanWindowsFonts(GooString *winFontDir);
>@@ -279,9 +289,9 @@ SysFontList::~SysFontList() {
>   deleteGooList(fonts, SysFontInfo);
> }
> 
>-SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
>+SysFontInfo *SysFontList::find(GooString *name, GBool fixedWidth, GBool exact) {
>   GooString *name2;
>-  GBool bold, italic;
>+  GBool bold, italic, oblique;
>   SysFontInfo *fi;
>   char c;
>   int n, i;
>@@ -321,6 +331,15 @@ SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
>     italic = gFalse;
>   }
> 
>+  // look for "Oblique"
>+  if (n > 6 && !strcmp(name2->getCString() + n - 7, "Oblique")) {
>+    name2->del(n - 7, 7);
>+    oblique = gTrue;
>+    n -= 6;
>+  } else {
>+    oblique = gFalse;
>+  }
>+
>   // look for "Bold"
>   if (n > 4 && !strcmp(name2->getCString() + n - 4, "Bold")) {
>     name2->del(n - 4, 4);
>@@ -352,7 +371,7 @@ SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
>   fi = NULL;
>   for (i = 0; i < fonts->getLength(); ++i) {
>     fi = (SysFontInfo *)fonts->get(i);
>-    if (fi->match(name2, bold, italic)) {
>+    if (fi->match(name2, bold, italic, oblique, fixedWidth)) {
>       break;
>     }
>     fi = NULL;
>@@ -623,9 +642,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
>   unicodeMapCache = new UnicodeMapCache();
>   cMapCache = new CMapCache();
> 
>-#ifdef _WIN32
>   baseFontsInitialized = gFalse;
>-#endif
> #ifdef ENABLE_PLUGINS
>   plugins = new GooList();
>   securityHandlers = new GooList();
>@@ -985,7 +1002,7 @@ static const char *getFontLang(GfxFont *font)
>   return lang;
> }
> 
>-static FcPattern *buildFcPattern(GfxFont *font)
>+static FcPattern *buildFcPattern(GfxFont *font, GooString *base14Name)
> {
>   int weight = -1,
>       slant = -1,
>@@ -997,7 +1014,7 @@ static FcPattern *buildFcPattern(GfxFont *font)
>   FcPattern *p;
> 
>   // this is all heuristics will be overwritten if font had proper info
>-  name = font->getName()->getCString();
>+  name = (base14Name == NULL) ? font->getName()->getCString() : base14Name->getCString();
>   
>   modifiers = strchr (name, ',');
>   if (modifiers == NULL)
>@@ -1113,8 +1130,8 @@ GooString *GlobalParams::findFontFile(GooString *fontName) {
>   FILE *f;
>   int i, j;
> 
>-  lockGlobalParams;
>   setupBaseFonts(NULL);
>+  lockGlobalParams;
>   if ((path = (GooString *)fontFiles->lookup(fontName))) {
>     path = path->copy();
>     unlockGlobalParams;
>@@ -1152,9 +1169,16 @@ GooString *GlobalParams::findFontFile(GooString *fontName) {
> void GlobalParams::setupBaseFonts(char *dir) {
> }
> 
>+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
>+  SysFontType type;
>+  int fontNum;
>+  
>+  return findSystemFontFile(font, &type, &fontNum, NULL, base14Name);
>+}
>+
> GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 					  SysFontType *type,
>-					  int *fontNum, GooString *substituteFontName) {
>+					  int *fontNum, GooString *substituteFontName, GooString *base14Name) {
>   SysFontInfo *fi = NULL;
>   FcPattern *p=0;
>   GooString *path = NULL;
>@@ -1163,7 +1187,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
>   fontName = fontName->copy();
>   lockGlobalParams;
> 
>-  if ((fi = sysFonts->find(fontName, gTrue))) {
>+  if ((fi = sysFonts->find(fontName, font->isFixedWidth(), gTrue))) {
>     path = fi->path->copy();
>     *type = fi->type;
>     *fontNum = fi->fontNum;
>@@ -1174,7 +1198,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
>     FcFontSet *set;
>     int i;
>     FcLangSet *lb = NULL;
>-    p = buildFcPattern(font);
>+    p = buildFcPattern(font, base14Name);
> 
>     if (!p)
>       goto fin;
>@@ -1241,6 +1265,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 	  int weight, slant;
> 	  GBool bold = font->isBold();
> 	  GBool italic = font->isItalic();
>+	  GBool oblique = gFalse;
> 	  FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
> 	  FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
> 	  if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD 
>@@ -1250,10 +1275,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 	  }
> 	  if (slant == FC_SLANT_ITALIC)
> 	    italic = gTrue;
>+	  if (slant == FC_SLANT_OBLIQUE)
>+	    oblique = gTrue;
> 	  *fontNum = 0;
> 	  *type = (!strncasecmp(ext,".ttc",4)) ? sysFontTTC : sysFontTTF;
> 	  FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
>-	  fi = new SysFontInfo(fontName->copy(), bold, italic,
>+	  fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
> 			       new GooString((char*)s), *type, *fontNum);
> 	  sysFonts->addFcFont(fi);
> 	  path = new GooString((char*)s);
>@@ -1263,6 +1290,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 	  int weight, slant;
> 	  GBool bold = font->isBold();
> 	  GBool italic = font->isItalic();
>+	  GBool oblique = gFalse;
> 	  FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
> 	  FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
> 	  if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD 
>@@ -1272,10 +1300,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 	  }
> 	  if (slant == FC_SLANT_ITALIC)
> 	    italic = gTrue;
>+	  if (slant == FC_SLANT_OBLIQUE)
>+	    oblique = gTrue;
> 	  *fontNum = 0;
> 	  *type = (!strncasecmp(ext,".pfa",4)) ? sysFontPFA : sysFontPFB;
> 	  FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
>-	  fi = new SysFontInfo(fontName->copy(), bold, italic,
>+	  fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
> 			       new GooString((char*)s), *type, *fontNum);
> 	  sysFonts->addFcFont(fi);
> 	  path = new GooString((char*)s);
>@@ -1294,7 +1324,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
>     }
>     FcFontSetDestroy(set);
>   }
>-  if (path == NULL && (fi = sysFonts->find(fontName, gFalse))) {
>+  if (path == NULL && (fi = sysFonts->find(fontName, font->isFixedWidth(), gFalse))) {
>     path = fi->path->copy();
>     *type = fi->type;
>     *fontNum = fi->fontNum;
>@@ -1308,7 +1338,15 @@ fin:
> 
> #elif WITH_FONTCONFIGURATION_WIN32
> #include "GlobalParamsWin.cc"
>+
>+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
>+  return findFontFile(base14Name);
>+}
> #else
>+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
>+  return findFontFile(base14Name);
>+}
>+
> static struct {
>   const char *name;
>   const char *t1FileName;
>@@ -1390,12 +1428,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
> 
>   path = NULL;
>   lockGlobalParams;
>-  if ((fi = sysFonts->find(font->getName(), gFalse))) {
>+  if ((fi = sysFonts->find(font->getName(), font->isFixedWidth(), gFalse))) {
>     path = fi->path->copy();
>     *type = fi->type;
>     *fontNum = fi->fontNum;
>   }
>-  unlockGlobalParams;
>+  unlockGlobalParams; 
>   return path;
> }
> #endif
>diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
>index be14123..375ac2c 100644
>--- a/poppler/GlobalParams.h
>+++ b/poppler/GlobalParams.h
>@@ -147,8 +147,10 @@ public:
>   FILE *findCMapFile(GooString *collection, GooString *cMapName);
>   FILE *findToUnicodeFile(GooString *name);
>   GooString *findFontFile(GooString *fontName);
>+  GooString *findBase14FontFile(GooString *base14Name, GfxFont *font);
>   GooString *findSystemFontFile(GfxFont *font, SysFontType *type,
>-			      int *fontNum, GooString *substituteFontName = NULL);
>+			      int *fontNum, GooString *substituteFontName = NULL, 
>+		              GooString *base14Name = NULL);
>   GooString *findCCFontFile(GooString *collection);
>   GBool getPSExpandSmaller();
>   GBool getPSShrinkLarger();
>@@ -286,8 +288,8 @@ private:
>   GooHash *cMapDirs;		// list of CMap dirs, indexed by collection
> 				//   name [GooList[GooString]]
>   GooList *toUnicodeDirs;		// list of ToUnicode CMap dirs [GooString]
>-#ifdef _WIN32
>   GBool baseFontsInitialized;
>+#ifdef _WIN32
>   GooHash *substFiles;	// windows font substitutes (for CID fonts)
> #endif
>   GooHash *fontFiles;		// font files: font name mapped to path
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fix-d6a1b7dc.diff
Type: text/x-diff
Size: 2926 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/poppler/attachments/20120327/b10885c3/attachment-0001.diff>


More information about the poppler mailing list