[poppler] poppler/poppler: ArthurOutputDev.cc, 1.9, 1.10 ArthurOutputDev.h, 1.2, 1.3 CairoOutputDev.cc, 1.20, 1.21 CairoOutputDev.h, 1.7, 1.8 Gfx.cc, 1.3, 1.4 Gfx.h, 1.2, 1.3 GfxState.cc, 1.4, 1.5 GfxState.h, 1.3, 1.4 OutputDev.cc, 1.2, 1.3 OutputDev.h, 1.2, 1.3 PDFDoc.cc, 1.7, 1.8 PDFDoc.h, 1.5, 1.6 PSOutputDev.cc, 1.6, 1.7 PSOutputDev.h, 1.4, 1.5 Page.cc, 1.6, 1.7 Page.h, 1.4, 1.5 SplashOutputDev.cc, 1.3, 1.4 SplashOutputDev.h, 1.3, 1.4 TextOutputDev.cc, 1.13, 1.14 TextOutputDev.h, 1.7, 1.8

Albert Astals Cid aacid at freedesktop.org
Sun Oct 30 12:29:07 PST 2005


Update of /cvs/poppler/poppler/poppler
In directory gabe:/tmp/cvs-serv31488/poppler

Modified Files:
	ArthurOutputDev.cc ArthurOutputDev.h CairoOutputDev.cc 
	CairoOutputDev.h Gfx.cc Gfx.h GfxState.cc GfxState.h 
	OutputDev.cc OutputDev.h PDFDoc.cc PDFDoc.h PSOutputDev.cc 
	PSOutputDev.h Page.cc Page.h SplashOutputDev.cc 
	SplashOutputDev.h TextOutputDev.cc TextOutputDev.h 
Log Message:
Last xpdf 3.01 merge (at least from my side)
It's very big, but noone has opposed in the 2 weeks time i gave on the ml so either poppler is dead or people agree with the patch


Index: ArthurOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/ArthurOutputDev.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- ArthurOutputDev.cc	16 Sep 2005 18:11:14 -0000	1.9
+++ ArthurOutputDev.cc	30 Oct 2005 20:29:05 -0000	1.10
@@ -485,7 +485,7 @@
 void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
 			       double dx, double dy,
 			       double originX, double originY,
-			       CharCode code, Unicode *u, int uLen) {
+			       CharCode code, int nBytes, Unicode *u, int uLen) {
   double x1, y1;
 //   SplashPath *path;
   int render;

Index: ArthurOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/ArthurOutputDev.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ArthurOutputDev.h	31 Jul 2005 09:54:04 -0000	1.2
+++ ArthurOutputDev.h	30 Oct 2005 20:29:05 -0000	1.3
@@ -102,7 +102,7 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode code, Unicode *u, int uLen);
+			CharCode code, int nBytes, Unicode *u, int uLen);
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,
 			       CharCode code, Unicode *u, int uLen);

Index: CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- CairoOutputDev.cc	5 Aug 2005 22:30:20 -0000	1.20
+++ CairoOutputDev.cc	30 Oct 2005 20:29:05 -0000	1.21
@@ -348,7 +348,7 @@
 void CairoOutputDev::drawChar(GfxState *state, double x, double y,
 			      double dx, double dy,
 			      double originX, double originY,
-			      CharCode code, Unicode *u, int uLen)
+			      CharCode code, int nBytes, Unicode *u, int uLen)
 {
   double tx, ty;
 

Index: CairoOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- CairoOutputDev.h	29 Jun 2005 21:24:57 -0000	1.7
+++ CairoOutputDev.h	30 Oct 2005 20:29:05 -0000	1.8
@@ -102,7 +102,7 @@
   void drawChar(GfxState *state, double x, double y,
 		double dx, double dy,
 		double originX, double originY,
-		CharCode code, Unicode *u, int uLen);
+		CharCode code, int nBytes, Unicode *u, int uLen);
 
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,

Index: Gfx.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Gfx.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Gfx.cc	27 Aug 2005 08:43:43 -0000	1.3
+++ Gfx.cc	30 Oct 2005 20:29:05 -0000	1.4
@@ -12,6 +12,7 @@
 #pragma implementation
 #endif
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <string.h>
@@ -48,19 +49,33 @@
 #define functionMaxDepth 6
 
 // Max delta allowed in any color component for a function shading fill.
[...1146 lines suppressed...]
     out->drawImage(state, ref, str, width, height, colorMap,
-		   haveMask ? maskColors : (int *)NULL,  inlineImg);
+		     haveColorKeyMask ? maskColors : (int *)NULL, inlineImg);
+    }
     delete colorMap;
 
     maskObj.free();
+    smaskObj.free();
   }
 
   if ((i = width * height) > 1000) {
@@ -2734,7 +3251,7 @@
 
   // check form type
   dict->lookup("FormType", &obj1);
-  if (!(obj1.isInt() && obj1.getInt() == 1)) {
+  if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
     error(getPos(), "Unknown form type");
   }
   obj1.free();

Index: Gfx.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Gfx.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Gfx.h	23 Aug 2005 18:20:45 -0000	1.2
+++ Gfx.h	30 Oct 2005 20:29:05 -0000	1.3
@@ -32,6 +32,9 @@
 class GfxFunctionShading;
 class GfxAxialShading;
 class GfxRadialShading;
+class GfxGouraudTriangleShading;
+class GfxPatchMeshShading;
+struct GfxPatch;
 class GfxState;
 struct GfxColor;
 class Gfx;
@@ -100,14 +103,14 @@
 
   // Constructor for regular output.
   Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict,
-      double hDPI, double vDPI, PDFRectangle *box, GBool crop,
+      double hDPI, double vDPI, PDFRectangle *box,
       PDFRectangle *cropBox, int rotate,
       GBool (*abortCheckCbkA)(void *data) = NULL,
       void *abortCheckCbkDataA = NULL);
 
   // Constructor for a sub-page object.
   Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
-      PDFRectangle *box, GBool crop, PDFRectangle *cropBox,
+      PDFRectangle *box, PDFRectangle *cropBox,
       GBool (*abortCheckCbkA)(void *data) = NULL,
       void *abortCheckCbkDataA = NULL);
 
@@ -127,6 +130,9 @@
   // Restore graphics state.
   void restoreState();
 
+  // Get the current graphics state object.
+  GfxState *getState() { return state; }
+
 private:
 
   XRef *xref;			// the xref table for this PDF file
@@ -216,6 +222,13 @@
 			 GfxColor *colors, int depth);
   void doAxialShFill(GfxAxialShading *shading);
   void doRadialShFill(GfxRadialShading *shading);
+  void doGouraudTriangleShFill(GfxGouraudTriangleShading *shading);
+  void gouraudFillTriangle(double x0, double y0, GfxColor *color0,
+			   double x1, double y1, GfxColor *color1,
+			   double x2, double y2, GfxColor *color2,
+			   int nComps, int depth);
+  void doPatchMeshShFill(GfxPatchMeshShading *shading);
+  void fillPatch(GfxPatch *patch, int nComps, int depth);
   void doEndPath();
 
   // path clipping operators

Index: GfxState.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxState.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- GfxState.cc	27 Aug 2005 08:43:43 -0000	1.4
+++ GfxState.cc	30 Oct 2005 20:29:05 -0000	1.5
@@ -14,7 +14,7 @@
 
 #include <stddef.h>
 #include <math.h>
-#include <string.h> // for memcpy()
+#include <string.h>
 #include "goo/gmem.h"
 #include "Error.h"
 #include "Object.h"
@@ -24,8 +24,12 @@
 
 //------------------------------------------------------------------------
[...1769 lines suppressed...]
+      obj->arrayGet(i, &obj2);
+      if (!obj2.isName()) {
+	obj2.free();
+	return gFalse;
+      }
+      for (j = 0; j < nGfxBlendModeNames; ++j) {
+	if (!strcmp(obj2.getName(), gfxBlendModeNames[j].name)) {
+	  obj2.free();
+	  *mode = gfxBlendModeNames[j].mode;
+	  return gTrue;
+	}
+      }
+      obj2.free();
+    }
+    *mode = gfxBlendNormal;
+    return gTrue;
+  } else {
+    return gFalse;
+  }
+}

Index: GfxState.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxState.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- GfxState.h	5 Aug 2005 22:30:20 -0000	1.3
+++ GfxState.h	30 Oct 2005 20:29:05 -0000	1.4
@@ -30,6 +30,58 @@
   void transform(double x, double y, double *tx, double *ty);
 };
 
+//------------------------------------------------------------------------
+// GfxBlendMode
+//------------------------------------------------------------------------
+ 
+enum GfxBlendMode {
+  gfxBlendNormal,
+  gfxBlendMultiply,
+  gfxBlendScreen,
+  gfxBlendOverlay,
+  gfxBlendDarken,
+  gfxBlendLighten,
+  gfxBlendColorDodge,
+  gfxBlendColorBurn,
+  gfxBlendHardLight,
+  gfxBlendSoftLight,
+  gfxBlendDifference,
+  gfxBlendExclusion,
+  gfxBlendHue,
+  gfxBlendSaturation,
+  gfxBlendColor,
+  gfxBlendLuminosity
+};
+
+//------------------------------------------------------------------------
+// GfxColorComp
+//------------------------------------------------------------------------
+
+// 16.16 fixed point color component
+typedef int GfxColorComp;
+
+#define gfxColorComp1 0x10000
+
+static inline GfxColorComp dblToCol(double x) {
+  return (GfxColorComp)(x * gfxColorComp1);
+}
+
+static inline double colToDbl(GfxColorComp x) {
+  return (double)x / (double)gfxColorComp1;
+}
+
+static inline GfxColorComp byteToCol(Guchar x) {
+  // (x / 255) << 16  =  (0.0000000100000001... * x) << 16
+  //                  =  ((x << 8) + (x) + (x >> 8) + ...) << 16
+  //                  =  (x << 8) + (x) + (x >> 7)
+  //                                      [for rounding]
+  return (GfxColorComp)((x << 8) + x + (x >> 7));
+}
+
+static inline Guchar colToByte(GfxColorComp x) {
+  // 255 * x + 0.5  =  256 * x - x + 0x8000
+  return (Guchar)(((x << 8) - x + 0x8000) >> 16);
+}
 
 //------------------------------------------------------------------------
 // GfxColor
@@ -38,15 +90,21 @@
 #define gfxColorMaxComps funcMaxOutputs
 
 struct GfxColor {
-  double c[gfxColorMaxComps];
+  GfxColorComp c[gfxColorMaxComps];
 };
 
 //------------------------------------------------------------------------
+// GfxGray
+//------------------------------------------------------------------------
+
+typedef GfxColorComp GfxGray;
+
+//------------------------------------------------------------------------
 // GfxRGB
 //------------------------------------------------------------------------
 
 struct GfxRGB {
-  double r, g, b;
+  GfxColorComp r, g, b;
 };
 
 //------------------------------------------------------------------------
@@ -54,7 +112,7 @@
 //------------------------------------------------------------------------
 
 struct GfxCMYK {
-  double c, m, y, k;
+  GfxColorComp c, m, y, k;
 };
 
 //------------------------------------------------------------------------
@@ -89,7 +147,7 @@
   static GfxColorSpace *parse(Object *csObj);
 
   // Convert to gray, RGB, or CMYK.
-  virtual void getGray(GfxColor *color, double *gray) = 0;
+  virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
   virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
@@ -123,7 +181,7 @@
   virtual GfxColorSpace *copy();
   virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
@@ -149,7 +207,7 @@
   // Construct a CalGray color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
@@ -185,7 +243,7 @@
   virtual GfxColorSpace *copy();
   virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
@@ -211,7 +269,7 @@
   // Construct a CalRGB color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
@@ -251,7 +309,7 @@
   virtual GfxColorSpace *copy();
   virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -275,7 +333,7 @@
   // Construct a Lab color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -320,7 +378,7 @@
   // Construct an ICCBased color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -357,7 +415,7 @@
   // Construct a Lab color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
@@ -396,7 +454,7 @@
   // Construct a Separation color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -429,7 +487,7 @@
   // Construct a DeviceN color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -464,7 +522,7 @@
   // Construct a Pattern color space.  Returns NULL if unsuccessful.
   static GfxColorSpace *parse(Array *arr);
 
-  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getGray(GfxColor *color, GfxGray *gray);
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
@@ -617,6 +675,8 @@
   void getDomain(double *x0A, double *y0A, double *x1A, double *y1A)
     { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
   double *getMatrix() { return matrix; }
+  int getNFuncs() { return nFuncs; }
+  Function *getFunc(int i) { return funcs[i]; }
   void getColor(double x, double y, GfxColor *color);
 
 private:
@@ -650,9 +710,11 @@
     { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
   double getDomain0() { return t0; }
   double getDomain1() { return t1; }
-  void getColor(double t, GfxColor *color);
   GBool getExtend0() { return extend0; }
   GBool getExtend1() { return extend1; }
+  int getNFuncs() { return nFuncs; }
+  Function *getFunc(int i) { return funcs[i]; }
+  void getColor(double t, GfxColor *color);
 
 private:
 
@@ -687,9 +749,11 @@
     { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
   double getDomain0() { return t0; }
   double getDomain1() { return t1; }
-  void getColor(double t, GfxColor *color);
   GBool getExtend0() { return extend0; }
   GBool getExtend1() { return extend1; }
+  int getNFuncs() { return nFuncs; }
+  Function *getFunc(int i) { return funcs[i]; }
+  void getColor(double t, GfxColor *color);
 
 private:
 
@@ -701,6 +765,77 @@
 };
 
 //------------------------------------------------------------------------
+// GfxGouraudTriangleShading
+//------------------------------------------------------------------------
+
+struct GfxGouraudVertex {
+  double x, y;
+  GfxColor color;
+};
+
+class GfxGouraudTriangleShading: public GfxShading {
+public:
+
+  GfxGouraudTriangleShading(int typeA,
+			    GfxGouraudVertex *verticesA, int nVerticesA,
+			    int (*trianglesA)[3], int nTrianglesA,
+			    Function **funcsA, int nFuncsA);
+  GfxGouraudTriangleShading(GfxGouraudTriangleShading *shading);
+  virtual ~GfxGouraudTriangleShading();
+
+  static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream *str);
+
+  virtual GfxShading *copy();
+
+  int getNTriangles() { return nTriangles; }
+  void getTriangle(int i, double *x0, double *y0, GfxColor *color0,
+		   double *x1, double *y1, GfxColor *color1,
+		   double *x2, double *y2, GfxColor *color2);
+
+private:
+
+  GfxGouraudVertex *vertices;
+  int nVertices;
+  int (*triangles)[3];
+  int nTriangles;
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+};
+
+//------------------------------------------------------------------------
+// GfxPatchMeshShading
+//------------------------------------------------------------------------
+
+struct GfxPatch {
+  double x[4][4];
+  double y[4][4];
+  GfxColor color[2][2];
+};
+
+class GfxPatchMeshShading: public GfxShading {
+public:
+
+  GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA,
+		      Function **funcsA, int nFuncsA);
+  GfxPatchMeshShading(GfxPatchMeshShading *shading);
+  virtual ~GfxPatchMeshShading();
+
+  static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str);
+
+  virtual GfxShading *copy();
+
+  int getNPatches() { return nPatches; }
+  GfxPatch *getPatch(int i) { return &patches[i]; }
+
+private:
+
+  GfxPatch *patches;
+  int nPatches;
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+};
+
+//------------------------------------------------------------------------
 // GfxImageColorMap
 //------------------------------------------------------------------------
 
@@ -731,7 +866,7 @@
   double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
 
   // Convert an image pixel to a color.
-  void getGray(Guchar *x, double *gray);
+  void getGray(Guchar *x, GfxGray *gray);
   void getRGB(Guchar *x, GfxRGB *rgb);
   void getRGBLine(Guchar *in, unsigned int *out, int length);
   void getCMYK(Guchar *x, GfxCMYK *cmyk);
@@ -746,7 +881,8 @@
   int nComps;			// number of components in a pixel
   GfxColorSpace *colorSpace2;	// secondary color space
   int nComps2;			// number of components in colorSpace2
-  double *lookup;		// lookup table
+  GfxColorComp *		// lookup table
+    lookup[gfxColorMaxComps];
   Guchar *byte_lookup;
   Guchar *tmp_line;
   double			// minimum values for each component
@@ -874,10 +1010,10 @@
 public:
 
   // Construct a default GfxState, for a device with resolution <hDPI>
-  // x <vDPI>, page box <pageBox>, page rotation <rotate>, and
+  // x <vDPI>, page box <pageBox>, page rotation <rotateA>, and
   // coordinate system specified by <upsideDown>.
   GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
-	   int rotate, GBool upsideDown);
+	   int rotateA, GBool upsideDown);
 
   // Destructor.
   ~GfxState();
@@ -894,11 +1030,12 @@
   double getY2() { return py2; }
   double getPageWidth() { return pageWidth; }
   double getPageHeight() { return pageHeight; }
+  int getRotate() { return rotate; }
   GfxColor *getFillColor() { return &fillColor; }
   GfxColor *getStrokeColor() { return &strokeColor; }
-  void getFillGray(double *gray)
+  void getFillGray(GfxGray *gray)
     { fillColorSpace->getGray(&fillColor, gray); }
-  void getStrokeGray(double *gray)
+  void getStrokeGray(GfxGray *gray)
     { strokeColorSpace->getGray(&strokeColor, gray); }
   void getFillRGB(GfxRGB *rgb)
     { fillColorSpace->getRGB(&fillColor, rgb); }
@@ -912,8 +1049,11 @@
   GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
   GfxPattern *getFillPattern() { return fillPattern; }
   GfxPattern *getStrokePattern() { return strokePattern; }
+  GfxBlendMode getBlendMode() { return blendMode; }
   double getFillOpacity() { return fillOpacity; }
   double getStrokeOpacity() { return strokeOpacity; }
+  GBool getFillOverprint() { return fillOverprint; }
+  GBool getStrokeOverprint() { return strokeOverprint; }
   double getLineWidth() { return lineWidth; }
   void getLineDash(double **dash, int *length, double *start)
     { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
@@ -974,8 +1114,11 @@
   void setStrokeColor(GfxColor *color) { strokeColor = *color; }
   void setFillPattern(GfxPattern *pattern);
   void setStrokePattern(GfxPattern *pattern);
+  void setBlendMode(GfxBlendMode mode) { blendMode = mode; }
   void setFillOpacity(double opac) { fillOpacity = opac; }
   void setStrokeOpacity(double opac) { strokeOpacity = opac; }
+  void setFillOverprint(GBool op) { fillOverprint = op; }
+  void setStrokeOverprint(GBool op) { strokeOverprint = op; }
   void setLineWidth(double width) { lineWidth = width; }
   void setLineDash(double *dash, int length, double start);
   void setFlatness(int flatness1) { flatness = flatness1; }
@@ -1028,11 +1171,15 @@
   GfxState *restore();
   GBool hasSaves() { return saved != NULL; }
 
+  // Misc
+  GBool parseBlendMode(Object *obj, GfxBlendMode *mode);
+
 private:
 
   double ctm[6];		// coord transform matrix
   double px1, py1, px2, py2;	// page corners (user coords)
   double pageWidth, pageHeight;	// page size (pixels)
+  int rotate;			// page rotation angle
 
   GfxColorSpace *fillColorSpace;   // fill color space
   GfxColorSpace *strokeColorSpace; // stroke color space
@@ -1040,8 +1187,11 @@
   GfxColor strokeColor;		// stroke color
   GfxPattern *fillPattern;	// fill pattern
   GfxPattern *strokePattern;	// stroke pattern
+  GfxBlendMode blendMode;	// transparency blend mode
   double fillOpacity;		// fill opacity
   double strokeOpacity;		// stroke opacity
+  GBool fillOverprint;		// fill overprint
+  GBool strokeOverprint;	// stroke overprint
 
   double lineWidth;		// line width
   double *lineDash;		// line dash

Index: OutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/OutputDev.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- OutputDev.cc	23 Aug 2005 18:20:45 -0000	1.2
+++ OutputDev.cc	30 Oct 2005 20:29:05 -0000	1.3
@@ -56,8 +56,15 @@
   updateLineCap(state);
   updateMiterLimit(state);
   updateLineWidth(state);
+  updateFillColorSpace(state);
   updateFillColor(state);
+  updateStrokeColorSpace(state);
   updateStrokeColor(state);
+  updateBlendMode(state);
+  updateFillOpacity(state);
+  updateStrokeOpacity(state);
+  updateFillOverprint(state);
+  updateStrokeOverprint(state);
   updateFont(state);
 }
 
@@ -96,6 +103,24 @@
   }
 }
 
+void OutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+				int width, int height,
+				GfxImageColorMap *colorMap,
+				Stream *maskStr,
+				int maskWidth, int maskHeight,
+				GBool maskInvert) {
+  drawImage(state, ref, str, width, height, colorMap, NULL, gFalse);
+}
+
+void OutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+				    int width, int height,
+				    GfxImageColorMap *colorMap,
+				    Stream *maskStr,
+				    int maskWidth, int maskHeight,
+				    GfxImageColorMap *maskColorMap) {
+  drawImage(state, ref, str, width, height, colorMap, NULL, gFalse);
+}
+
 #if OPI_SUPPORT
 void OutputDev::opiBegin(GfxState *state, Dict *opiDict) {
 }

Index: OutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/OutputDev.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- OutputDev.h	23 Aug 2005 18:20:45 -0000	1.2
+++ OutputDev.h	30 Oct 2005 20:29:05 -0000	1.3
@@ -19,10 +19,12 @@
 
 class GooHash;
 class GooString;
-class Object;
 class GfxState;
 class GfxColorSpace;
 class GfxImageColorMap;
+class GfxFunctionShading;
+class GfxAxialShading;
+class GfxRadialShading;
 class Stream;
 class Link;
 class Catalog;
@@ -49,6 +51,16 @@
   // Does this device use drawChar() or drawString()?
   virtual GBool useDrawChar() = 0;
 
+  // Does this device use tilingPatternFill()?  If this returns false,
+  // tiling pattern fills will be reduced to a series of other drawing
+  // operations.
+  virtual GBool useTilingPatternFill() { return gFalse; }
+
+  // Does this device use functionShadedFill(), axialShadedFill(), and
+  // radialShadedFill()?  If this returns false, these shaded fills
+  // will be reduced to a series of other drawing operations.
+  virtual GBool useShadedFills() { return gFalse; }
+
   // Does this device use beginType3Char/endType3Char?  Otherwise,
   // text in Type 3 fonts will be drawn with drawChar/drawString.
   virtual GBool interpretType3Chars() = 0;
@@ -76,6 +88,9 @@
   virtual void cvtDevToUser(double dx, double dy, double *ux, double *uy);
   virtual void cvtUserToDev(double ux, double uy, int *dx, int *dy);
 
+  double *getDefCTM() { return defCTM; }
+  double *getDefICTM() { return defICTM; }
+
   //----- link borders
   virtual void drawLink(Link *link, Catalog *catalog) {}
 
@@ -93,10 +108,15 @@
   virtual void updateLineCap(GfxState *state) {}
   virtual void updateMiterLimit(GfxState *state) {}
   virtual void updateLineWidth(GfxState *state) {}
+  virtual void updateFillColorSpace(GfxState *state) {}
+  virtual void updateStrokeColorSpace(GfxState *state) {}
   virtual void updateFillColor(GfxState *state) {}
   virtual void updateStrokeColor(GfxState *state) {}
+  virtual void updateBlendMode(GfxState *state) {}
   virtual void updateFillOpacity(GfxState *state) {}
   virtual void updateStrokeOpacity(GfxState *state) {}
+  virtual void updateFillOverprint(GfxState *state) {}
+  virtual void updateStrokeOverprint(GfxState *state) {}
 
   //----- update text state
   virtual void updateFont(GfxState *state) {}
@@ -113,18 +133,29 @@
   virtual void stroke(GfxState *state) {}
   virtual void fill(GfxState *state) {}
   virtual void eoFill(GfxState *state) {}
+  virtual void tilingPatternFill(GfxState *state, Object *str,
+				 int paintType, Dict *resDict,
+				 double *mat, double *bbox,
+				 int x0, int y0, int x1, int y1,
+				 double xStep, double yStep) {}
+  virtual void functionShadedFill(GfxState *state,
+				  GfxFunctionShading *shading) {}
+  virtual void axialShadedFill(GfxState *state, GfxAxialShading *shading) {}
+  virtual void radialShadedFill(GfxState *state, GfxRadialShading *shading) {}
 
   //----- path clipping
   virtual void clip(GfxState *state) {}
   virtual void eoClip(GfxState *state) {}
 
   //----- text drawing
+  virtual void beginStringOp(GfxState *state) {}
+  virtual void endStringOp(GfxState *state) {}
   virtual void beginString(GfxState *state, GooString *s) {}
   virtual void endString(GfxState *state) {}
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode code, Unicode *u, int uLen) {}
+			CharCode code, int nBytes, Unicode *u, int uLen) {}
   virtual void drawString(GfxState *state, GooString *s) {}
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,
@@ -139,6 +170,17 @@
   virtual void drawImage(GfxState *state, Object *ref, Stream *str,
 			 int width, int height, GfxImageColorMap *colorMap,
 			 int *maskColors, GBool inlineImg);
+  virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+			       int width, int height,
+			       GfxImageColorMap *colorMap,
+			       Stream *maskStr, int maskWidth, int maskHeight,
+			       GBool maskInvert);
+  virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+				   int width, int height,
+				   GfxImageColorMap *colorMap,
+				   Stream *maskStr,
+				   int maskWidth, int maskHeight,
+				   GfxImageColorMap *maskColorMap);
 
 #if OPI_SUPPORT
   //----- OPI functions

Index: PDFDoc.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- PDFDoc.cc	16 Sep 2005 19:33:05 -0000	1.7
+++ PDFDoc.cc	30 Oct 2005 20:29:05 -0000	1.8
@@ -17,6 +17,9 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
+#ifdef WIN32
+#  include <windows.h>
+#endif
 #include "goo/GooString.h"
 #include "poppler-config.h"
 #include "GlobalParams.h"
@@ -100,6 +103,63 @@
   ok = setup(ownerPassword, userPassword);
 }
 
+#ifdef WIN32
+PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword,
+	       GooString *userPassword, void *guiDataA) {
+  OSVERSIONINFO version;
+  wchar_t fileName2[_MAX_PATH + 1];
+  Object obj;
+  int i;
+
+  ok = gFalse;
+  errCode = errNone;
+
+  guiData = guiDataA;
+
+  file = NULL;
+  str = NULL;
+  xref = NULL;
+  catalog = NULL;
+  links = NULL;
+#ifndef DISABLE_OUTLINE
+  outline = NULL;
+#endif
+
+  //~ file name should be stored in Unicode (?)
+  fileName = new GooString();
+  for (i = 0; i < fileNameLen; ++i) {
+    fileName->append((char)fileNameA[i]);
+  }
+
+  // zero-terminate the file name string
+  for (i = 0; i < fileNameLen && i < _MAX_PATH; ++i) {
+    fileName2[i] = fileNameA[i];
+  }
+  fileName2[i] = 0;
+
+  // try to open file
+  // NB: _wfopen is only available in NT
+  version.dwOSVersionInfoSize = sizeof(version);
+  GetVersionEx(&version);
+  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+    file = _wfopen(fileName2, L"rb");
+  } else {
+    file = fopen(fileName->getCString(), "rb");
+  }
+  if (!file) {
+    error(-1, "Couldn't open file '%s'", fileName->getCString());
+    errCode = errOpenFile;
+    return;
+  }
+
+  // create stream
+  obj.initNull();
+  str = new FileStream(file, 0, gFalse, 0, &obj);
+
+  ok = setup(ownerPassword, userPassword);
+}
+#endif
+
 PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword,
 	       GooString *userPassword, void *guiDataA) {
   ok = gFalse;
@@ -293,7 +353,7 @@
 }
 
 void PDFDoc::displayPage(OutputDev *out, int page, double hDPI, double vDPI,
-			 int rotate, GBool crop, GBool doLinks,
+			 int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
 			 GBool (*abortCheckCbk)(void *data),
 			 void *abortCheckCbkData,
                          GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
@@ -307,21 +367,20 @@
   if (doLinks) {
     if (links) {
       delete links;
-      links = NULL;
     }
     getLinks(p);
-    p->display(out, hDPI, vDPI, rotate, crop, links, catalog,
+    p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, links, catalog,
 	       abortCheckCbk, abortCheckCbkData,
                annotDisplayDecideCbk, annotDisplayDecideCbkData);
   } else {
-    p->display(out, hDPI, vDPI, rotate, crop, NULL, catalog,
+    p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, NULL, catalog,
 	       abortCheckCbk, abortCheckCbkData,
                annotDisplayDecideCbk, annotDisplayDecideCbkData);
   }
 }
 
 void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
-			  double hDPI, double vDPI, int rotate,
+			  double hDPI, double vDPI, int rotate, GBool useMediaBox,
 			  GBool crop, GBool doLinks,
 			  GBool (*abortCheckCbk)(void *data),
 			  void *abortCheckCbkData,
@@ -330,7 +389,7 @@
   int page;
 
   for (page = firstPage; page <= lastPage; ++page) {
-    displayPage(out, page, hDPI, vDPI, rotate, crop, doLinks,
+    displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, doLinks,
 		abortCheckCbk, abortCheckCbkData,
                 annotDisplayDecideCbk, annotDisplayDecideCbkData);
   }
@@ -338,7 +397,7 @@
 
 void PDFDoc::displayPageSlice(OutputDev *out, int page,
 			      double hDPI, double vDPI,
-			      int rotate, GBool crop,
+			      int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
 			      int sliceX, int sliceY, int sliceW, int sliceH,
 			      GBool (*abortCheckCbk)(void *data),
 			      void *abortCheckCbkData,
@@ -347,11 +406,32 @@
   Page *p;
 
   p = catalog->getPage(page);
-  p->displaySlice(out, hDPI, vDPI, rotate, crop,
+  if (doLinks)
+  {
+    if (links) {
+      delete links;
+    }
+    getLinks(p);
+    p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop,
 		  sliceX, sliceY, sliceW, sliceH,
-		  NULL, catalog,
+		  links, catalog,
                   abortCheckCbk, abortCheckCbkData,
                   annotDisplayDecideCbk, annotDisplayDecideCbkData);
+  } else {
+    p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop,
+                  sliceX, sliceY, sliceW, sliceH,
+	          NULL, catalog,
+	          abortCheckCbk, abortCheckCbkData,
+	          annotDisplayDecideCbk, annotDisplayDecideCbkData);
+  } 
+}
+
+Links *PDFDoc::takeLinks() {
+  Links *ret;
+
+  ret = links;
+  links = NULL;
+  return ret;
 }
 
 GBool PDFDoc::isLinearized() {

Index: PDFDoc.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- PDFDoc.h	16 Sep 2005 19:33:05 -0000	1.5
+++ PDFDoc.h	30 Oct 2005 20:29:05 -0000	1.6
@@ -36,6 +36,12 @@
 
   PDFDoc(GooString *fileNameA, GooString *ownerPassword = NULL,
 	 GooString *userPassword = NULL, void *guiDataA = NULL);
+
+#ifdef WIN32
+  PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = NULL,
+	 GooString *userPassword = NULL, void *guiDataA = NULL);
+#endif
+
   PDFDoc(BaseStream *strA, GooString *ownerPassword = NULL,
 	 GooString *userPassword = NULL, void *guiDataA = NULL);
   ~PDFDoc();
@@ -59,10 +65,14 @@
   BaseStream *getBaseStream() { return str; }
 
   // Get page parameters.
-  double getPageWidth(int page)
-    { return catalog->getPage(page)->getWidth(); }
-  double getPageHeight(int page)
-    { return catalog->getPage(page)->getHeight(); }
+  double getPageMediaWidth(int page)
+    { return catalog->getPage(page)->getMediaWidth(); }
+  double getPageMediaHeight(int page)
+    { return catalog->getPage(page)->getMediaHeight(); }
+  double getPageCropWidth(int page)
+    { return catalog->getPage(page)->getCropWidth(); }
+  double getPageCropHeight(int page)
+    { return catalog->getPage(page)->getCropHeight(); }
   int getPageRotate(int page)
     { return catalog->getPage(page)->getRotate(); }
 
@@ -78,7 +88,7 @@
 
   // Display a page.
   void displayPage(OutputDev *out, int page, double hDPI, double vDPI,
-		   int rotate, GBool crop, GBool doLinks,
+		   int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
 		   GBool (*abortCheckCbk)(void *data) = NULL,
 		   void *abortCheckCbkData = NULL,
                    GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
@@ -87,7 +97,7 @@
   // Display a range of pages.
   void displayPages(OutputDev *out, int firstPage, int lastPage,
 		    double hDPI, double vDPI, int rotate,
-		    GBool crop, GBool doLinks,
+		    GBool useMediaBox, GBool crop, GBool doLinks,
 		    GBool (*abortCheckCbk)(void *data) = NULL,
 		    void *abortCheckCbkData = NULL,
                     GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
@@ -96,7 +106,7 @@
   // Display part of a page.
   void displayPageSlice(OutputDev *out, int page,
 			double hDPI, double vDPI,
-			int rotate, GBool crop,
+			int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
 			int sliceX, int sliceY, int sliceW, int sliceH,
 			GBool (*abortCheckCbk)(void *data) = NULL,
 			void *abortCheckCbkData = NULL,

Index: PSOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PSOutputDev.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- PSOutputDev.cc	16 Oct 2005 14:54:17 -0000	1.6
+++ PSOutputDev.cc	30 Oct 2005 20:29:05 -0000	1.7
@@ -45,18 +45,25 @@
 // PostScript prolog and setup
 //------------------------------------------------------------------------
 
+// The '~' escapes mark prolog code that is emitted only in certain
+// levels:
+//
+//   ~[123][sn]
+//      ^   ^----- s=psLevel*Sep, n=psLevel*
+//      +----- 1=psLevel1*, 2=psLevel2*, 3=psLevel3*
+
 static char *prolog[] = {
[...2094 lines suppressed...]
+    }
     if (*p == '(' || *p == ')' || *p == '\\') {
       writePSChar('\\');
       writePSChar((char)*p);
+      line += 2;
     } else if (*p < 0x20 || *p >= 0x80) {
       sprintf(buf, "\\%03o", *p);
-      if (t3String) {
-	t3String->append(buf);
-      } else {
-	(*outputFunc)(outputStream, buf, strlen(buf));
-      }
+      writePS(buf);
+      line += 4;
     } else {
       writePSChar((char)*p);
+      ++line;
     }
   }
   writePSChar(')');

Index: PSOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PSOutputDev.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- PSOutputDev.h	14 Sep 2005 21:20:36 -0000	1.4
+++ PSOutputDev.h	30 Oct 2005 20:29:05 -0000	1.5
@@ -26,6 +26,7 @@
 class PDFRectangle;
 struct PSFont16Enc;
 class PSOutCustomColor;
+class Function;
 
 //------------------------------------------------------------------------
 // PSOutputDev
@@ -83,6 +84,17 @@
   // Does this device use drawChar() or drawString()?
   virtual GBool useDrawChar() { return gFalse; }
 
+  // Does this device use tilingPatternFill()?  If this returns false,
+  // tiling pattern fills will be reduced to a series of other drawing
+  // operations.
+  virtual GBool useTilingPatternFill() { return gTrue; }
+
+  // Does this device use functionShadedFill(), axialShadedFill(), and
+  // radialShadedFill()?  If this returns false, these shaded fills
+  // will be reduced to a series of other drawing operations.
+  virtual GBool useShadedFills()
+    { return level == psLevel2 || level == psLevel3; }
+
   // Does this device use beginType3Char/endType3Char?  Otherwise,
   // text in Type 3 fonts will be drawn with drawChar/drawString.
   virtual GBool interpretType3Chars() { return gFalse; }
@@ -91,7 +103,8 @@
 
   // Write the document-level header.
   void writeHeader(int firstPage, int lastPage,
-		   PDFRectangle *mediaBox, PDFRectangle *cropBox);
+		   PDFRectangle *mediaBox, PDFRectangle *cropBox,
+		   int pageRotate);
 
   // Write the Xpdf procset.
   void writeXpdfProcset();
@@ -99,9 +112,6 @@
   // Write the document-level setup.
   void writeDocSetup(Catalog *catalog, int firstPage, int lastPage, GBool duplexA);
 
-  // Write the setup for the current page.
-  void writePageSetup();
-
   // Write the trailer for the current page.
   void writePageTrailer();
 
@@ -129,8 +139,12 @@
   virtual void updateLineCap(GfxState *state);
   virtual void updateMiterLimit(GfxState *state);
   virtual void updateLineWidth(GfxState *state);
+  virtual void updateFillColorSpace(GfxState *state);
+  virtual void updateStrokeColorSpace(GfxState *state);
   virtual void updateFillColor(GfxState *state);
   virtual void updateStrokeColor(GfxState *state);
+  virtual void updateFillOverprint(GfxState *state);
+  virtual void updateStrokeOverprint(GfxState *state);
 
   //----- update text state
   virtual void updateFont(GfxState *state);
@@ -147,6 +161,15 @@
   virtual void stroke(GfxState *state);
   virtual void fill(GfxState *state);
   virtual void eoFill(GfxState *state);
+  virtual void tilingPatternFill(GfxState *state, Object *str,
+				 int paintType, Dict *resDict,
+				 double *mat, double *bbox,
+				 int x0, int y0, int x1, int y1,
+				 double xStep, double yStep);
+  virtual void functionShadedFill(GfxState *state,
+				  GfxFunctionShading *shading);
+  virtual void axialShadedFill(GfxState *state, GfxAxialShading *shading);
+  virtual void radialShadedFill(GfxState *state, GfxRadialShading *shading);
 
   //----- path clipping
   virtual void clip(GfxState *state);
@@ -163,6 +186,11 @@
   virtual void drawImage(GfxState *state, Object *ref, Stream *str,
 			 int width, int height, GfxImageColorMap *colorMap,
 			 int *maskColors, GBool inlineImg);
+  virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+			       int width, int height,
+			       GfxImageColorMap *colorMap,
+			       Stream *maskStr, int maskWidth, int maskHeight,
+			       GBool maskInvert);
 
 #if OPI_SUPPORT
   //----- OPI functions
@@ -227,8 +255,11 @@
 		    Stream *str, int width, int height, int len);
   void doImageL2(Object *ref, GfxImageColorMap *colorMap,
 		 GBool invert, GBool inlineImg,
-		 Stream *str, int width, int height, int len);
-  void dumpColorSpaceL2(GfxColorSpace *colorSpace);
+		 Stream *str, int width, int height, int len,
+		 int *maskColors, Stream *maskStr,
+		 int maskWidth, int maskHeight, GBool maskInvert);
+  void dumpColorSpaceL2(GfxColorSpace *colorSpace,
+			GBool genXform, GBool updateColors);
 #if OPI_SUPPORT
   void opiBegin20(GfxState *state, Dict *dict);
   void opiBegin13(GfxState *state, Dict *dict);
@@ -236,6 +267,7 @@
 		    double *x1, double *y1);
   GBool getFileSpec(Object *fileSpec, Object *fileName);
 #endif
+  void cvtFunction(Function *func);
   void writePSChar(char c);
   void writePS(char *s);
   void writePSFmt(const char *fmt, ...) GCC_PRINTF_FORMAT(2, 3);
@@ -279,6 +311,8 @@
   GooList *xobjStack;		// stack of XObject dicts currently being
 				//   processed
   int numSaves;			// current number of gsaves
+  int numTilingPatterns;	// current number of nested tiling patterns
+  int nextFunc;			// next unique number to use for a function
 
   double tx0, ty0;		// global translation
   double xScale0, yScale0;	// global scaling
@@ -288,6 +322,8 @@
   double tx, ty;		// global translation for current page
   double xScale, yScale;	// global scaling for current page
   int rotate;			// rotation angle for current page
+  double epsX1, epsY1,		// EPS bounding box (unrotated)
+         epsX2, epsY2;
 
   GooString *embFontList;		// resource comments for embedded fonts
 

Index: Page.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Page.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- Page.cc	16 Oct 2005 14:54:17 -0000	1.6
+++ Page.cc	30 Oct 2005 20:29:05 -0000	1.7
@@ -36,7 +36,6 @@
 
 PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
   Object obj1;
-  double w, h;
 
   // get old/default values
   if (attrs) {
@@ -69,18 +68,6 @@
     cropBox = mediaBox;
   }
 
-  // if the MediaBox is excessively larger than the CropBox,
-  // just use the CropBox
-  limitToCropBox = gFalse;
-  if (haveCropBox) {
-    w = 0.25 * (cropBox.x2 - cropBox.x1);
-    h = 0.25 * (cropBox.y2 - cropBox.y1);
-    if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
-	(cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
-      limitToCropBox = gTrue;
-    }
-  }
-
   // other boxes
   bleedBox = cropBox;
   readBox(dict, "BleedBox", &bleedBox);
@@ -131,6 +118,7 @@
 
 GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
   PDFRectangle tmp;
+  double t;
   Object obj1, obj2;
   GBool ok;
 
@@ -166,6 +154,12 @@
     }
     obj2.free();
     if (ok) {
+      if (tmp.x1 > tmp.x2) {
+	t = tmp.x1; tmp.x1 = tmp.x2; tmp.x2 = t;
+      }
+      if (tmp.y1 > tmp.y2) {
+	t = tmp.y1; tmp.y1 = tmp.y2; tmp.y2 = t;
+      }
       *box = tmp;
     }
   } else {
@@ -240,26 +234,26 @@
 }
 
 void Page::display(OutputDev *out, double hDPI, double vDPI,
-		   int rotate, GBool crop,
+		   int rotate, GBool useMediaBox, GBool crop,
 		   Links *links, Catalog *catalog,
 		   GBool (*abortCheckCbk)(void *data),
 		   void *abortCheckCbkData,
                    GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
                    void *annotDisplayDecideCbkData) {
-  displaySlice(out, hDPI, vDPI, rotate, crop, -1, -1, -1, -1, links, catalog,
+  displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, -1, -1, -1, -1, links, catalog,
 	       abortCheckCbk, abortCheckCbkData,
                annotDisplayDecideCbk, annotDisplayDecideCbkData);
 }
 
 Gfx *Page::createGfx(OutputDev *out, double hDPI, double vDPI,
-		     int rotate, GBool crop,
+		     int rotate, GBool useMediaBox, GBool crop,
 		     int sliceX, int sliceY, int sliceW, int sliceH,
 		     Links *links, Catalog *catalog,
 		     GBool (*abortCheckCbk)(void *data),
 		     void *abortCheckCbkData,
 		     GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
 		     void *annotDisplayDecideCbkData) {
-  PDFRectangle *mediaBox, *cropBox;
+  PDFRectangle *mediaBox, *cropBox, *baseBox;
   PDFRectangle box;
   Gfx *gfx;
   double kx, ky;
@@ -271,75 +265,77 @@
     rotate += 360;
   }
 
-  mediaBox = getBox();
+  mediaBox = getMediaBox();
+  cropBox = getCropBox();
   if (sliceW >= 0 && sliceH >= 0) {
+    baseBox =  useMediaBox ? mediaBox : cropBox;
     kx = 72.0 / hDPI;
     ky = 72.0 / vDPI;
     if (rotate == 90) {
       if (out->upsideDown()) {
-	box.x1 = mediaBox->x1 + ky * sliceY;
-	box.x2 = mediaBox->x1 + ky * (sliceY + sliceH);
+	box.x1 = baseBox->x1 + ky * sliceY;
+	box.x2 = baseBox->x1 + ky * (sliceY + sliceH);
       } else {
-	box.x1 = mediaBox->x2 - ky * (sliceY + sliceH);
-	box.x2 = mediaBox->x2 - ky * sliceY;
+	box.x1 = baseBox->x2 - ky * (sliceY + sliceH);
+	box.x2 = baseBox->x2 - ky * sliceY;
       }
-      box.y1 = mediaBox->y1 + kx * sliceX;
-      box.y2 = mediaBox->y1 + kx * (sliceX + sliceW);
+      box.y1 = baseBox->y1 + kx * sliceX;
+      box.y2 = baseBox->y1 + kx * (sliceX + sliceW);
     } else if (rotate == 180) {
-      box.x1 = mediaBox->x2 - kx * (sliceX + sliceW);
-      box.x2 = mediaBox->x2 - kx * sliceX;
+      box.x1 = baseBox->x2 - kx * (sliceX + sliceW);
+      box.x2 = baseBox->x2 - kx * sliceX;
       if (out->upsideDown()) {
-	box.y1 = mediaBox->y1 + ky * sliceY;
-	box.y2 = mediaBox->y1 + ky * (sliceY + sliceH);
+	box.y1 = baseBox->y1 + ky * sliceY;
+	box.y2 = baseBox->y1 + ky * (sliceY + sliceH);
       } else {
-	box.y1 = mediaBox->y2 - ky * (sliceY + sliceH);
-	box.y2 = mediaBox->y2 - ky * sliceY;
+	box.y1 = baseBox->y2 - ky * (sliceY + sliceH);
+	box.y2 = baseBox->y2 - ky * sliceY;
       }
     } else if (rotate == 270) {
       if (out->upsideDown()) {
-	box.x1 = mediaBox->x2 - ky * (sliceY + sliceH);
-	box.x2 = mediaBox->x2 - ky * sliceY;
+	box.x1 = baseBox->x2 - ky * (sliceY + sliceH);
+	box.x2 = baseBox->x2 - ky * sliceY;
       } else {
-	box.x1 = mediaBox->x1 + ky * sliceY;
-	box.x2 = mediaBox->x1 + ky * (sliceY + sliceH);
+	box.x1 = baseBox->x1 + ky * sliceY;
+	box.x2 = baseBox->x1 + ky * (sliceY + sliceH);
       }
-      box.y1 = mediaBox->y2 - kx * (sliceX + sliceW);
-      box.y2 = mediaBox->y2 - kx * sliceX;
+      box.y1 = baseBox->y2 - kx * (sliceX + sliceW);
+      box.y2 = baseBox->y2 - kx * sliceX;
     } else {
-      box.x1 = mediaBox->x1 + kx * sliceX;
-      box.x2 = mediaBox->x1 + kx * (sliceX + sliceW);
+      box.x1 = baseBox->x1 + kx * sliceX;
+      box.x2 = baseBox->x1 + kx * (sliceX + sliceW);
       if (out->upsideDown()) {
-	box.y1 = mediaBox->y2 - ky * (sliceY + sliceH);
-	box.y2 = mediaBox->y2 - ky * sliceY;
+	box.y1 = baseBox->y2 - ky * (sliceY + sliceH);
+	box.y2 = baseBox->y2 - ky * sliceY;
       } else {
-	box.y1 = mediaBox->y1 + ky * sliceY;
-	box.y2 = mediaBox->y1 + ky * (sliceY + sliceH);
+	box.y1 = baseBox->y1 + ky * sliceY;
+	box.y2 = baseBox->y1 + ky * (sliceY + sliceH);
       }
     }
-  } else {
+  } else if (useMediaBox) {
     box = *mediaBox;
+  } else {
+    box = *cropBox;
+    crop = gFalse;
   }
-  cropBox = getCropBox();
 
   if (globalParams->getPrintCommands()) {
     printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
-	   box.x1, box.y1, box.x2, box.y2);
-    if (isCropped()) {
+	    mediaBox->x1, mediaBox->y1, mediaBox->x2, mediaBox->y2);
       printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
 	     cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
-    }
     printf("***** Rotate = %d\n", attrs->getRotate());
   }
 
   gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
-		hDPI, vDPI, &box, crop && isCropped(), cropBox, rotate,
-		abortCheckCbk, abortCheckCbkData);
+		hDPI, vDPI, &box, crop ? cropBox : (PDFRectangle *)NULL,
+		rotate, abortCheckCbk, abortCheckCbkData);
 
   return gfx;
 }
 
 void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
-			int rotate, GBool crop,
+			int rotate, GBool useMediaBox, GBool crop,
 			int sliceX, int sliceY, int sliceW, int sliceH,
 			Links *links, Catalog *catalog,
 			GBool (*abortCheckCbk)(void *data),
@@ -352,7 +348,7 @@
   Annots *annotList;
   int i;
 
-  gfx = createGfx(out, hDPI, vDPI, rotate, crop,
+  gfx = createGfx(out, hDPI, vDPI, rotate, useMediaBox, crop,
 		  sliceX, sliceY, sliceW, sliceH,
 		  links, catalog,
 		  abortCheckCbk, abortCheckCbkData,
@@ -516,3 +512,20 @@
 
   return success;
 }
+
+void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI,
+			 int rotate, GBool upsideDown) {
+  GfxState *state;
+  int i;
+  rotate += getRotate();
+  if (rotate >= 360) {
+    rotate -= 360;
+  } else if (rotate < 0) {
+    rotate += 360;
+  }
+  state = new GfxState(hDPI, vDPI, getMediaBox(), rotate, upsideDown);
+  for (i = 0; i < 6; ++i) {
+    ctm[i] = state->getCTM()[i];
+  }
+ delete state;
+}

Index: Page.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Page.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Page.h	29 Jun 2005 21:24:57 -0000	1.4
+++ Page.h	30 Oct 2005 20:29:05 -0000	1.5
@@ -52,7 +52,6 @@
   ~PageAttrs();
 
   // Accessors.
-  PDFRectangle *getBox() { return limitToCropBox ? &cropBox : &mediaBox; }
   PDFRectangle *getMediaBox() { return &mediaBox; }
   PDFRectangle *getCropBox() { return &cropBox; }
   GBool isCropped() { return haveCropBox; }
@@ -84,7 +83,6 @@
   PDFRectangle mediaBox;
   PDFRectangle cropBox;
   GBool haveCropBox;
-  GBool limitToCropBox;
   PDFRectangle bleedBox;
   PDFRectangle trimBox;
   PDFRectangle artBox;
@@ -115,12 +113,17 @@
   GBool isOk() { return ok; }
 
   // Get page parameters.
-  PDFRectangle *getBox() { return attrs->getBox(); }
   PDFRectangle *getMediaBox() { return attrs->getMediaBox(); }
   PDFRectangle *getCropBox() { return attrs->getCropBox(); }
   GBool isCropped() { return attrs->isCropped(); }
-  double getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; }
-  double getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; }
+  double getMediaWidth() 
+    { return attrs->getMediaBox()->x2 - attrs->getMediaBox()->x1; }
+  double getMediaHeight()
+    { return attrs->getMediaBox()->y2 - attrs->getMediaBox()->y1; }
+  double getCropWidth() 
+    { return attrs->getCropBox()->x2 - attrs->getCropBox()->x1; }
+  double getCropHeight()
+    { return attrs->getCropBox()->y2 - attrs->getCropBox()->y1; }
   PDFRectangle *getBleedBox() { return attrs->getBleedBox(); }
   PDFRectangle *getTrimBox() { return attrs->getTrimBox(); }
   PDFRectangle *getArtBox() { return attrs->getArtBox(); }
@@ -149,7 +152,7 @@
   Object *getTrans(Object *obj) { return trans.fetch(xref, obj); }
 
   Gfx *createGfx(OutputDev *out, double hDPI, double vDPI,
-		 int rotate, GBool crop,
+		 int rotate, GBool useMediaBox, GBool crop,
 		 int sliceX, int sliceY, int sliceW, int sliceH,
 		 Links *links, Catalog *catalog,
 		 GBool (*abortCheckCbk)(void *data),
@@ -159,7 +162,7 @@
 
   // Display a page.
   void display(OutputDev *out, double hDPI, double vDPI,
-	       int rotate, GBool crop,
+	       int rotate, GBool useMediaBox, GBool crop,
 	       Links *links, Catalog *catalog,
 	       GBool (*abortCheckCbk)(void *data) = NULL,
 	       void *abortCheckCbkData = NULL,
@@ -168,7 +171,7 @@
 
   // Display part of a page.
   void displaySlice(OutputDev *out, double hDPI, double vDPI,
-		    int rotate, GBool crop,
+		    int rotate, GBool useMediaBox, GBool crop,
 		    int sliceX, int sliceY, int sliceW, int sliceH,
 		    Links *links, Catalog *catalog,
 		    GBool (*abortCheckCbk)(void *data) = NULL,
@@ -177,6 +180,10 @@
                     void *annotDisplayDecideCbkData = NULL);
 
   void display(Gfx *gfx);
+  
+  // Get the page's default CTM.
+  void getDefaultCTM(double *ctm, double hDPI, double vDPI,
+		     int rotate, GBool upsideDown);
 
 private:
 

Index: SplashOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SplashOutputDev.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- SplashOutputDev.cc	27 Aug 2005 08:43:43 -0000	1.3
+++ SplashOutputDev.cc	30 Oct 2005 20:29:05 -0000	1.4
@@ -18,7 +18,6 @@
 #include "GlobalParams.h"
 #include "Error.h"
 #include "Object.h"
-#include "GfxState.h"
 #include "GfxFont.h"
 #include "Link.h"
 #include "CharCodeToUnicode.h"
@@ -39,8 +38,383 @@
 #include "SplashOutputDev.h"
 
 //------------------------------------------------------------------------
[...1781 lines suppressed...]
-  rgb.b = b / 255.0;
-  gray = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.g;
+  rgb.r = byteToCol(r);
+  rgb.g = byteToCol(g);
+  rgb.b = byteToCol(b);
+  gray = (GfxColorComp)(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.g + 0.5);
+  if (gray > gfxColorComp1) {
+    gray = gfxColorComp1;
+  }
+#if SPLASH_CMYK
+  cmyk.c = gfxColorComp1 - rgb.r;
+  cmyk.m = gfxColorComp1 - rgb.g;
+  cmyk.y = gfxColorComp1 - rgb.b;
+  cmyk.k = 0;
+  splash->setFillPattern(getColor(gray, &rgb, &cmyk));
+#else
   splash->setFillPattern(getColor(gray, &rgb));
+#endif
 }
+

Index: SplashOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SplashOutputDev.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- SplashOutputDev.h	16 Sep 2005 18:32:30 -0000	1.3
+++ SplashOutputDev.h	30 Oct 2005 20:29:05 -0000	1.4
@@ -17,9 +17,8 @@
 #include "splash/SplashTypes.h"
 #include "poppler-config.h"
 #include "OutputDev.h"
+#include "GfxState.h"
 
-class GfxState;
-class GfxPath;
 class Gfx8BitFont;
 class SplashBitmap;
 class Splash;
@@ -28,10 +27,8 @@
 class SplashFontEngine;
 class SplashFont;
 class T3FontCache;
-class XRef;
 struct T3FontCacheTag;
 struct T3GlyphStack;
-struct GfxRGB;
 
 //------------------------------------------------------------------------
 
@@ -46,8 +43,10 @@
 public:
 
   // Constructor.
-  SplashOutputDev(SplashColorMode colorModeA, GBool reverseVideoA,
-		  SplashColor paperColorA);
+  SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
+		  GBool reverseVideoA, SplashColorPtr paperColorA,
+		  GBool bitmapTopDownA = gTrue,
+		  GBool allowAntialiasA = gTrue);
 
   // Destructor.
   virtual ~SplashOutputDev();
@@ -92,6 +91,9 @@
   virtual void updateLineWidth(GfxState *state);
   virtual void updateFillColor(GfxState *state);
   virtual void updateStrokeColor(GfxState *state);
+  virtual void updateBlendMode(GfxState *state);
+  virtual void updateFillOpacity(GfxState *state);
+  virtual void updateStrokeOpacity(GfxState *state);
 
   //----- update text state
   virtual void updateFont(GfxState *state);
@@ -109,7 +111,7 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode code, Unicode *u, int uLen);
+			CharCode code, int nBytes, Unicode *u, int uLen);
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,
 			       CharCode code, Unicode *u, int uLen);
@@ -123,6 +125,17 @@
   virtual void drawImage(GfxState *state, Object *ref, Stream *str,
 			 int width, int height, GfxImageColorMap *colorMap,
 			 int *maskColors, GBool inlineImg);
+  virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+			       int width, int height,
+			       GfxImageColorMap *colorMap,
+			       Stream *maskStr, int maskWidth, int maskHeight,
+			       GBool maskInvert);
+  virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+				   int width, int height,
+				   GfxImageColorMap *colorMap,
+				   Stream *maskStr,
+				   int maskWidth, int maskHeight,
+				   GfxImageColorMap *maskColorMap);
 
   //----- Type 3 font operators
   virtual void type3D0(GfxState *state, double wx, double wy);
@@ -134,20 +147,23 @@
   // Called to indicate that a new PDF document has been loaded.
   void startDoc(XRef *xrefA);
  
+  void setPaperColor(SplashColorPtr paperColorA);
+
   GBool isReverseVideo() { return reverseVideo; }
+  void setReverseVideo(GBool reverseVideoA) { reverseVideo = reverseVideoA; }
 
   // Get the bitmap and its size.
   SplashBitmap *getBitmap() { return bitmap; }
   int getBitmapWidth();
   int getBitmapHeight();
 
+  // Returns the last rasterized bitmap, transferring ownership to the
+  // caller.
+  SplashBitmap *takeBitmap();
+
   // Get the Splash object.
   Splash *getSplash() { return splash; }
 
-  // XOR a rectangular region in the bitmap with <pattern>.  <pattern>
-  // is passed to Splash::setFillPattern, so it should not be used
-  // after calling this function.
-  void xorRectangle(int x0, int y0, int x1, int y1, SplashPattern *pattern);
   // Get the modified region.
   void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax);
 
@@ -157,20 +173,28 @@
   // Set the Splash fill color.
   void setFillColor(int r, int g, int b);
 
-  void setUnderlayCbk(void (*cbk)(void *data), void *data)
-    { underlayCbk = cbk; underlayCbkData = data; }
+  SplashFont *getCurrentFont() { return font; }
 
 private:
 
-  SplashPattern *getColor(double gray, GfxRGB *rgb);
+#if SPLASH_CMYK
+  SplashPattern *getColor(GfxGray gray, GfxRGB *rgb, GfxCMYK *cmyk);
+#else
+  SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
+#endif
   SplashPath *convertPath(GfxState *state, GfxPath *path);
   void drawType3Glyph(T3FontCache *t3Font,
 		      T3FontCacheTag *tag, Guchar *data,
 		      double x, double y);
-  static GBool imageMaskSrc(void *data, SplashMono1 *pixel);
-  static GBool imageSrc(void *data, SplashColor *pixel, Guchar *alpha);
+  static GBool imageMaskSrc(void *data, SplashColorPtr line);
+  static GBool imageSrc(void *data, SplashColorPtr line);
+  static GBool alphaImageSrc(void *data, SplashColorPtr line);
+  static GBool maskedImageSrc(void *data, SplashColorPtr line);
 
   SplashColorMode colorMode;
+  int bitmapRowPad;
+  GBool bitmapTopDown;
+  GBool allowAntialias;
   GBool reverseVideo;		// reverse video mode
   SplashColor paperColor;	// paper color
 
@@ -188,9 +212,6 @@
   SplashFont *font;		// current font
   GBool needFontUpdate;		// set when the font needs to be updated
   SplashPath *textClipPath;	// clipping path built with text object
-
-  void (*underlayCbk)(void *data);
-  void *underlayCbkData;
 };
 
 #endif

Index: TextOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.cc,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- TextOutputDev.cc	20 Sep 2005 15:08:52 -0000	1.13
+++ TextOutputDev.cc	30 Oct 2005 20:29:05 -0000	1.14
@@ -222,9 +222,9 @@
   } else {
     state->getFillRGB(&rgb);
   }
-  colorR = rgb.r;
-  colorG = rgb.g;
-  colorB = rgb.b;
+  colorR = colToDbl(rgb.r);
+  colorG = colToDbl(rgb.g);
+  colorB = colToDbl(rgb.b);
 #endif
 }
 
@@ -875,22 +875,22 @@
   cmp = 0; // make gcc happy
   switch (frag1->line->blk->page->primaryRot) {
   case 0:
-    if ((cmp = frag1->yMin - frag2->yMin) == 0) {
+    if (fabs(cmp = frag1->yMin - frag2->yMin) < 0.01) {
       cmp = frag1->xMin - frag2->xMin;
     }
     break;
   case 1:
-    if ((cmp = frag2->xMax - frag1->xMax) == 0) {
+    if (fabs(cmp = frag2->xMax - frag1->xMax) < 0.01) {
       cmp = frag1->yMin - frag2->yMin;
     }
     break;
   case 2:
-    if ((cmp = frag2->yMin - frag1->yMin) == 0) {
+    if (fabs(cmp = frag2->yMin - frag1->yMin) < 0.01) {
       cmp = frag2->xMax - frag1->xMax;
     }
     break;
   case 3:
-    if ((cmp = frag1->xMax - frag2->xMax) == 0) {
+    if (fabs(cmp = frag1->xMax - frag2->xMax) < 0.01) {
       cmp = frag2->yMax - frag1->yMax;
     }
     break;
@@ -1763,7 +1763,7 @@
 }
 
 void TextPage::beginWord(GfxState *state, double x0, double y0) {
-  double *txtm, *ctm, *fontm;
+  double *fontm;
   double m[4], m2[4];
   int rot;
 
@@ -1776,12 +1776,7 @@
   }
 
   // compute the rotation
-  txtm = state->getTextMat();
-  ctm = state->getCTM();
-  m[0] = txtm[0] * ctm[0] + txtm[1] * ctm[2];
-  m[1] = txtm[0] * ctm[1] + txtm[1] * ctm[3];
-  m[2] = txtm[2] * ctm[0] + txtm[3] * ctm[2];
-  m[3] = txtm[2] * ctm[1] + txtm[3] * ctm[3];
+  state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]);
   if (state->getFont()->getType() == fontType3) {
     fontm = state->getFont()->getFontMatrix();
     m2[0] = fontm[0] * m[0] + fontm[1] * m[2];
@@ -1804,20 +1799,16 @@
 
 void TextPage::addChar(GfxState *state, double x, double y,
 		       double dx, double dy,
-		       CharCode c, Unicode *u, int uLen) {
-  double x1, y1, w1, h1, dx2, dy2, base, sp;
+		       CharCode c, int nBytes, Unicode *u, int uLen) {
+  double x1, y1, w1, h1, dx2, dy2, base, sp, delta;
+  GBool overlap;
   int i;
 
-  // if the previous char was a space, addChar will have called
-  // endWord, so we need to start a new word
-  if (!curWord) {
-    beginWord(state, x, y);
-  }
-
   // throw away chars that aren't inside the page bounds
   state->transform(x, y, &x1, &y1);
   if (x1 < 0 || x1 > pageWidth ||
       y1 < 0 || y1 > pageHeight) {
+    charPos += nBytes;
     return;
   }
 
@@ -1835,60 +1826,72 @@
   if (!globalParams->getTextKeepTinyChars() &&
       fabs(w1) < 3 && fabs(h1) < 3) {
     if (++nTinyChars > 50000) {
+      charPos += nBytes;
       return;
     }
   }
 
   // break words at space character
   if (uLen == 1 && u[0] == (Unicode)0x20) {
+    if (curWord) {
     ++curWord->charLen;
-    ++charPos;
+    }
+    charPos += nBytes;
     endWord();
     return;
   }
 
   // start a new word if:
-  // (1) this character's baseline doesn't match the current word's
-  //     baseline, or
-  // (2) there is space between the end of the current word and this
-  //     character, or
-  // (3) this character overlaps the previous one (duplicated text), or
-  // (4) the previous character was an overlap (we want each duplicated
-  //     characters to be in a word by itself)
-  base = sp = 0; // make gcc happy
-  if (curWord->len > 0) {
+  // (1) this character doesn't fall in the right place relative to
+  //     the end of the previous word (this places upper and lower
+  //     constraints on the position deltas along both the primary
+  //     and secondary axes), or
+  // (2) this character overlaps the previous one (duplicated text), or
+  // (3) the previous character was an overlap (we want each duplicated
+  //     character to be in a word by itself at this stage)
+  if (curWord && curWord->len > 0) {
+    base = sp = delta = 0; // make gcc happy
     switch (curWord->rot) {
     case 0:
       base = y1;
       sp = x1 - curWord->xMax;
+      delta = x1 - curWord->edge[curWord->len - 1];
       break;
     case 1:
       base = x1;
       sp = y1 - curWord->yMax;
+      delta = y1 - curWord->edge[curWord->len - 1];
       break;
     case 2:
       base = y1;
       sp = curWord->xMin - x1;
+      delta = curWord->edge[curWord->len - 1] - x1;
       break;
     case 3:
       base = x1;
       sp = curWord->yMin - y1;
+      delta = curWord->edge[curWord->len - 1] - y1;
       break;
     }
-    if (fabs(base - curWord->base) > 0.5 ||
-	sp > minWordBreakSpace * curWord->fontSize ||
+    overlap = fabs(delta) < dupMaxPriDelta * curWord->fontSize &&
+              fabs(base - curWord->base) < dupMaxSecDelta * curWord->fontSize;
+    if (overlap || lastCharOverlap ||
 	sp < -minDupBreakOverlap * curWord->fontSize ||
-	lastCharOverlap) {
-      lastCharOverlap = gTrue;
+	sp > minWordBreakSpace * curWord->fontSize ||
+	fabs(base - curWord->base) > 0.5) {
       endWord();
-      beginWord(state, x, y);
-    } else {
-      lastCharOverlap = gFalse;
     }
+    lastCharOverlap = overlap;
   } else {
     lastCharOverlap = gFalse;
   }
 
+  if (uLen != 0) {
+    // start a new word if needed
+    if (!curWord) {
+      beginWord(state, x, y);
+    }
+
   // page rotation and/or transform matrices can cause text to be
   // drawn in reverse order -- in this case, swap the begin/end
   // coordinates and break text into individual chars
@@ -1905,15 +1908,16 @@
   }
 
   // add the characters to the current word
-  if (uLen != 0) {
     w1 /= uLen;
     h1 /= uLen;
-  }
   for (i = 0; i < uLen; ++i) {
-    curWord->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, c, u[i]);
+      curWord->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, c, u[i]);
   }
-  ++curWord->charLen;
-  ++charPos;
+  }
+  if (curWord) {
+    curWord->charLen += nBytes;
+  }
+  charPos += nBytes;
 }
 
 void TextPage::endWord() {
@@ -1987,9 +1991,9 @@
     pool = pools[rot];
     for (baseIdx = pool->minBaseIdx; baseIdx <= pool->maxBaseIdx; ++baseIdx) {
       for (word0 = pool->getPool(baseIdx); word0; word0 = word0->next) {
-	printf("    word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f '",
+	printf("    word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f rot=%d '",
 	       word0->xMin, word0->xMax, word0->yMin, word0->yMax,
-	       word0->base, word0->fontSize);
+	       word0->base, word0->fontSize, rot*90);
 	for (i = 0; i < word0->len; ++i) {
 	  fputc(word0->text[i] & 0xff, stdout);
 	}
@@ -2388,6 +2392,8 @@
       case 0:
 	if (blk0->xMin > blk1->xMax) {
 	  col2 = blk1->col + blk1->nColumns + 3;
+	} else if (blk1->xMax == blk1->xMin) {
+	  col2 = blk1->col;
 	} else {
 	  col2 = blk1->col + (int)(((blk0->xMin - blk1->xMin) /
 				    (blk1->xMax - blk1->xMin)) *
@@ -2397,6 +2403,8 @@
       case 1:
 	if (blk0->yMin > blk1->yMax) {
 	  col2 = blk1->col + blk1->nColumns + 3;
+	} else if (blk1->yMax == blk1->yMin) {
+	  col2 = blk1->col;
 	} else {
 	  col2 = blk1->col + (int)(((blk0->yMin - blk1->yMin) /
 				    (blk1->yMax - blk1->yMin)) *
@@ -2406,6 +2414,8 @@
       case 2:
 	if (blk0->xMax < blk1->xMin) {
 	  col2 = blk1->col + blk1->nColumns + 3;
+	} else if (blk1->xMin == blk1->xMax) {
+	  col2 = blk1->col;
 	} else {
 	  col2 = blk1->col + (int)(((blk0->xMax - blk1->xMax) /
 				    (blk1->xMin - blk1->xMax)) *
@@ -2415,6 +2425,8 @@
       case 3:
 	if (blk0->yMax < blk1->yMin) {
 	  col2 = blk1->col + blk1->nColumns + 3;
+	} else if (blk1->yMin == blk1->yMax) {
+	  col2 = blk1->col;
 	} else {
 	  col2 = blk1->col + (int)(((blk0->yMax - blk1->yMax) /
 				    (blk1->yMin - blk1->yMax)) *
@@ -2619,13 +2631,14 @@
 GBool TextPage::findText(Unicode *s, int len,
 			 GBool startAtTop, GBool stopAtBottom,
 			 GBool startAtLast, GBool stopAtLast,
+			 GBool caseSensitive, GBool backward,
 			 double *xMin, double *yMin,
 			 double *xMax, double *yMax) {
   TextBlock *blk;
   TextLine *line;
+  Unicode *s2, *txt;
   Unicode *p;
-  Unicode u1, u2;
-  int m, i, j, k;
+  int txtSize, m, i, j, k;
   double xStart, yStart, xStop, yStop;
   double xMin0, yMin0, xMax0, yMax0;
   double xMin1, yMin1, xMax1, yMax1;
@@ -2637,6 +2650,19 @@
     return gFalse;
   }
 
+  // convert the search string to uppercase
+  if (!caseSensitive) {
+    s2 = (Unicode *)gmallocn(len, sizeof(Unicode));
+    for (i = 0; i < len; ++i) {
+      s2[i] = unicodeToUpper(s[i]);
+    }
+  } else {
+    s2 = s;
+  }
+
+  txt = NULL;
+  txtSize = 0;
+
   xStart = yStart = xStop = yStop = 0;
   if (startAtLast && haveLastFind) {
     xStart = lastFindXMin;
@@ -2657,51 +2683,57 @@
   xMin0 = xMax0 = yMin0 = yMax0 = 0; // make gcc happy
   xMin1 = xMax1 = yMin1 = yMax1 = 0; // make gcc happy
 
-  for (i = 0; i < nBlocks; ++i) {
+  for (i = backward ? nBlocks - 1 : 0;
+       backward ? i >= 0 : i < nBlocks;
+       i += backward ? -1 : 1) {
     blk = blocks[i];
 
     // check: is the block above the top limit?
-    if (!startAtTop && blk->yMax < yStart) {
+    if (!startAtTop && (backward ? blk->yMin > yStart : blk->yMax < yStart)) {
       continue;
     }
 
     // check: is the block below the bottom limit?
-    if (!stopAtBottom && blk->yMin > yStop) {
+    if (!stopAtBottom && (backward ? blk->yMax < yStop : blk->yMin > yStop)) {
       break;
     }
 
     for (line = blk->lines; line; line = line->next) {
 
       // check: is the line above the top limit?
-      if (!startAtTop && line->yMin < yStart) {
+      if (!startAtTop &&
+	  (backward ? line->yMin > yStart : line->yMin < yStart)) {
 	continue;
       }
 
       // check: is the line below the bottom limit?
-      if (!stopAtBottom && line->yMin > yStop) {
+      if (!stopAtBottom &&
+	  (backward ? line->yMin < yStop : line->yMin > yStop)) {
 	continue;
       }
 
-      // search each position in this line
+      // convert the line to uppercase
       m = line->len;
-      for (j = 0, p = line->text; j <= m - len; ++j, ++p) {
-
-	// compare the strings
-	for (k = 0; k < len; ++k) {
-#if 1 //~ this lowercases Latin A-Z only -- this will eventually be
-      //~ extended to handle other character sets
-	  if (p[k] >= 0x41 && p[k] <= 0x5a) {
-	    u1 = p[k] + 0x20;
-	  } else {
-	    u1 = p[k];
+      if (!caseSensitive) {
+	if (m > txtSize) {
+	  txt = (Unicode *)greallocn(txt, m, sizeof(Unicode));
+	  txtSize = m;
+	}
+	for (k = 0; k < m; ++k) {
+	  txt[k] = unicodeToUpper(line->text[k]);
 	  }
-	  if (s[k] >= 0x41 && s[k] <= 0x5a) {
-	    u2 = s[k] + 0x20;
 	  } else {
-	    u2 = s[k];
+	txt = line->text;
 	  }
-#endif
-	  if (u1 != u2) {
+
+      // search each position in this line
+      j = backward ? m - len : 0;
+      p = txt + j;
+      while (backward ? j >= 0 : j <= m - len) {
+
+	// compare the strings
+	for (k = 0; k < len; ++k) {
+	  if (p[k] != s2[k]) {
 	    break;
 	  }
 	}
@@ -2734,11 +2766,27 @@
 	    yMax1 = line->edge[j];
 	    break;
 	  }
+	  if (backward) {
+	    if ((startAtTop ||
+		 yMin1 < yStart || (yMin1 == yStart && xMin1 < xStart)) &&
+		(stopAtBottom ||
+		 yMin1 > yStop || (yMin1 == yStop && xMin1 > xStop))) {
+	      if (!found ||
+		  yMin1 > yMin0 || (yMin1 == yMin0 && xMin1 > xMin0)) {
+		xMin0 = xMin1;
+		xMax0 = xMax1;
+		yMin0 = yMin1;
+		yMax0 = yMax1;
+		found = gTrue;
+	      }
+	    }
+	  } else {
 	  if ((startAtTop ||
 	       yMin1 > yStart || (yMin1 == yStart && xMin1 > xStart)) &&
 	      (stopAtBottom ||
-	       yMin1 < yStop || (yMin1 == yStop && xMin1 < yStop))) {
-	    if (!found || yMin1 < yMin0 || (yMin1 == yMin0 && xMin1 < xMin0)) {
+		 yMin1 < yStop || (yMin1 == yStop && xMin1 < xStop))) {
+	      if (!found ||
+		  yMin1 < yMin0 || (yMin1 == yMin0 && xMin1 < xMin0)) {
 	      xMin0 = xMin1;
 	      xMax0 = xMax1;
 	      yMin0 = yMin1;
@@ -2748,7 +2796,20 @@
 	  }
 	}
       }
+	if (backward) {
+	  --j;
+	  --p;
+	} else {
+	  ++j;
+	  ++p;
+	}
+      }
+    }
     }
+
+  if (!caseSensitive) {
+    gfree(s2);
+    gfree(txt);
   }
 
   if (found) {
@@ -3308,9 +3369,11 @@
 
   out->beginString(state, string);
 
+#warning krh this is yours have a look here
+//TODO what value of nBytes should we use? i put a 1 but not sure
   for (i = begin; i < end; i++)
     out->drawChar(state, word->edge[i], word->base, 0, 0, 0, 0,
-		  word->charcode[i], NULL, 0);
+		  word->charcode[i], 1, NULL, 0);
   
   out->endString(state);
 }
@@ -3723,6 +3786,20 @@
     }
     qsort(frags, nFrags, sizeof(TextLineFrag), &TextLineFrag::cmpYXPrimaryRot);
 
+#if 0 // for debugging
+    printf("*** line fragments ***\n");
+    for (i = 0; i < nFrags; ++i) {
+      frag = &frags[i];
+      printf("frag: x=%.2f..%.2f y=%.2f..%.2f base=%.2f '",
+	     frag->xMin, frag->xMax, frag->yMin, frag->yMax, frag->base);
+      for (n = 0; n < frag->len; ++n) {
+	fputc(frag->line->text[frag->start + n] & 0xff, stdout);
+      }
+      printf("'\n");
+    }
+    printf("\n");
+#endif
+
     // generate output
     col = 0;
     for (i = 0; i < nFrags; ++i) {
@@ -3801,7 +3878,6 @@
   // end of page
   if (pageBreaks) {
     (*outputFunc)(outputStream, eop, eopLen);
-    (*outputFunc)(outputStream, eol, eolLen);
   }
 
   uMap->decRefCnt();
@@ -4078,17 +4154,19 @@
 void TextOutputDev::drawChar(GfxState *state, double x, double y,
 			     double dx, double dy,
 			     double originX, double originY,
-			     CharCode c, Unicode *u, int uLen) {
-  text->addChar(state, x, y, dx, dy, c, u, uLen);
+			     CharCode c, int nBytes, Unicode *u, int uLen) {
+  text->addChar(state, x, y, dx, dy, c, nBytes, u, uLen);
 }
 
 GBool TextOutputDev::findText(Unicode *s, int len,
 			      GBool startAtTop, GBool stopAtBottom,
 			      GBool startAtLast, GBool stopAtLast,
+			      GBool caseSensitive, GBool backward,
 			      double *xMin, double *yMin,
 			      double *xMax, double *yMax) {
   return text->findText(s, len, startAtTop, stopAtBottom,
-			startAtLast, stopAtLast, xMin, yMin, xMax, yMax);
+			startAtLast, stopAtLast, caseSensitive, backward,
+			xMin, yMin, xMax, yMax);
 }
 
 GooString *TextOutputDev::getText(double xMin, double yMin,

Index: TextOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- TextOutputDev.h	20 Sep 2005 15:08:52 -0000	1.7
+++ TextOutputDev.h	30 Oct 2005 20:29:05 -0000	1.8
@@ -26,9 +26,15 @@
 class GfxFont;
 class GfxState;
 class UnicodeMap;
+
+class TextWord;
+class TextPool;
+class TextLine;
+class TextLineFrag;
 class TextBlock;
+class TextFlow;
+class TextWordList;
 class TextPage;
-class TextLineFrag;
 class TextSelectionVisitor;
 
 //------------------------------------------------------------------------
@@ -102,6 +108,8 @@
     { *r = colorR; *g = colorG; *b = colorB; }
   void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
     { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
+  double getFontSize() { return fontSize; }
+  int getRotation() { return rot; }
   int getCharPos() { return charPos; }
   int getCharLen() { return charLen; }
 #endif
@@ -392,7 +400,7 @@
   // Add a character to the current word.
   void addChar(GfxState *state, double x, double y,
 	       double dx, double dy,
-	       CharCode c, Unicode *u, int uLen);
+	       CharCode c, int nBytes, Unicode *u, int uLen);
 
   // End the current word, sorting it into the list of words.
   void endWord();
@@ -413,6 +421,7 @@
   GBool findText(Unicode *s, int len,
 		 GBool startAtTop, GBool stopAtBottom,
 		 GBool startAtLast, GBool stopAtLast,
+		 GBool caseSensitive, GBool backward,
 		 double *xMin, double *yMin,
 		 double *xMax, double *yMax);
 
@@ -559,7 +568,7 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode c, Unicode *u, int uLen);
+			CharCode c, int nBytes, Unicode *u, int uLen);
 
   //----- special access
 
@@ -573,6 +582,7 @@
   GBool findText(Unicode *s, int len,
 		 GBool startAtTop, GBool stopAtBottom,
 		 GBool startAtLast, GBool stopAtLast,
+		 GBool caseSensitive, GBool backward,
 		 double *xMin, double *yMin,
 		 double *xMax, double *yMax);
 



More information about the poppler mailing list