[poppler] 2 commits - poppler/CairoOutputDev.cc poppler/CairoOutputDev.h poppler/Gfx.cc poppler/OutputDev.h poppler/PSOutputDev.cc poppler/PSOutputDev.h

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Sun Aug 16 08:38:59 PDT 2009


 poppler/CairoOutputDev.cc |   56 ++++++++++++++++++++++++++++++++++++++++++++++
 poppler/CairoOutputDev.h  |   10 ++++++++
 poppler/Gfx.cc            |   37 +++++++++++++++---------------
 poppler/OutputDev.h       |   11 ++++-----
 poppler/PSOutputDev.cc    |   12 +++++----
 poppler/PSOutputDev.h     |   10 ++++----
 6 files changed, 103 insertions(+), 33 deletions(-)

New commits:
commit d20d65111aee2ee4b8cdea2962ed1bb149122ba9
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Sun Aug 16 17:36:14 2009 +0200

    [cairo] Implement tiling patterns in cairo backend
    
    Fixes bug #13518 for the cairo backend.

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index af92776..19d1245 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -45,8 +45,10 @@
 #include "GlobalParams.h"
 #include "Error.h"
 #include "Object.h"
+#include "Gfx.h"
 #include "GfxState.h"
 #include "GfxFont.h"
+#include "Page.h"
 #include "Link.h"
 #include "CharCodeToUnicode.h"
 #include "FontEncodingTables.h"
@@ -657,6 +659,60 @@ void CairoOutputDev::eoFill(GfxState *state) {
 
 }
 
+GBool CairoOutputDev::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)
+{
+  PDFRectangle box;
+  Gfx *gfx;
+  cairo_pattern_t *pattern;
+  cairo_surface_t *surface;
+  cairo_matrix_t matrix;
+  cairo_t *old_cairo;
+  double xMin, yMin, xMax, yMax;
+
+  if (xStep != bbox[2] || yStep != bbox[3])
+    return gFalse;
+  /* TODO: implement the other cases here too */
+
+  surface = cairo_surface_create_similar (cairo_get_target (cairo),
+					  CAIRO_CONTENT_COLOR_ALPHA,
+					  bbox[2], bbox[3]);
+  if (cairo_surface_status (surface))
+    return gFalse;
+
+  old_cairo = cairo;
+  cairo = cairo_create (surface);
+  cairo_surface_destroy (surface);
+
+  box.x1 = bbox[0]; box.y1 = bbox[1];
+  box.x2 = bbox[2]; box.y2 = bbox[3];
+  gfx = new Gfx(xref, this, resDict, catalog, &box, NULL);
+  gfx->display(str);
+  delete gfx;
+
+  pattern = cairo_pattern_create_for_surface (cairo_get_target (cairo));
+  cairo_destroy (cairo);
+  cairo = old_cairo;
+  if (cairo_pattern_status (pattern))
+    return gFalse;
+
+  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+  cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
+
+  cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+  cairo_transform (cairo, &matrix);
+  cairo_set_source (cairo, pattern);
+  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+  cairo_fill (cairo);
+
+  cairo_pattern_destroy (pattern);
+
+  return gTrue;
+}
+
 GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) {
   double x0, y0, x1, y1;
   double dx, dy;
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index e0e1813..3543ce4 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -98,6 +98,11 @@ public:
   // Does this device use drawChar() or drawString()?
   virtual GBool useDrawChar() { return gTrue; }
 
+  // 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.
@@ -151,6 +156,11 @@ public:
   virtual void stroke(GfxState *state);
   virtual void fill(GfxState *state);
   virtual void eoFill(GfxState *state);
+  virtual GBool 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 GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
   virtual GBool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading);
   virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax);
commit e965d0686d979c775b64a93f8e2f775f81885417
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Thu Aug 13 14:48:10 2009 +0200

    Change OutputDev::tilingPatternFill to return a GBool
    
    It allows outputdevs to decide whether render the pattern or not depending
    on the parameters, like shaded patterns currently do.

diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index ccf818a..3023cba 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -1927,7 +1927,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
   // get the clip region, check for empty
   state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
   if (cxMin > cxMax || cyMin > cyMax) {
-    goto err;
+    goto restore;
   }
 
   // transform clip region bbox to pattern space
@@ -1982,30 +1982,31 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
   for (i = 0; i < 4; ++i) {
     m1[i] = m[i];
   }
-  if (out->useTilingPatternFill()) {
+  if (!contentIsHidden()) {
     m1[4] = m[4];
     m1[5] = m[5];
-    if (!contentIsHidden()) {
-      out->tilingPatternFill(state, tPat->getContentStream(),
-			     tPat->getPaintType(), tPat->getResDict(),
-			     m1, tPat->getBBox(),
-			     xi0, yi0, xi1, yi1, xstep, ystep);
-    }
-  } else {
-    for (yi = yi0; yi < yi1; ++yi) {
-      for (xi = xi0; xi < xi1; ++xi) {
-	x = xi * xstep;
-	y = yi * ystep;
-	m1[4] = x * m[0] + y * m[2] + m[4];
-	m1[5] = x * m[1] + y * m[3] + m[5];
-	doForm1(tPat->getContentStream(), tPat->getResDict(),
-		m1, tPat->getBBox());
+    if (out->useTilingPatternFill() &&
+	out->tilingPatternFill(state, tPat->getContentStream(),
+			       tPat->getPaintType(), tPat->getResDict(),
+			       m1, tPat->getBBox(),
+			       xi0, yi0, xi1, yi1, xstep, ystep)) {
+	    goto restore;
+    } else {
+      for (yi = yi0; yi < yi1; ++yi) {
+        for (xi = xi0; xi < xi1; ++xi) {
+	  x = xi * xstep;
+	  y = yi * ystep;
+	  m1[4] = x * m[0] + y * m[2] + m[4];
+	  m1[5] = x * m[1] + y * m[3] + m[5];
+	  doForm1(tPat->getContentStream(), tPat->getResDict(),
+		  m1, tPat->getBBox());
+	}
       }
     }
   }
 
   // restore graphics state
- err:
+ restore:
   restoreState();
   state->setPath(savedPath);
 }
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index ffd91a0..4f98b81 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -190,11 +190,12 @@ public:
   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 GBool 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*/)
+    { return gFalse; }
   virtual GBool functionShadedFill(GfxState * /*state*/,
 				   GfxFunctionShading * /*shading*/)
     { return gFalse; }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index bebe48a..6dcf06b 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3752,11 +3752,11 @@ void PSOutputDev::eoFill(GfxState *state) {
   writePS("f*\n");
 }
 
-void PSOutputDev::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) {
+GBool PSOutputDev::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) {
   PDFRectangle box;
   Gfx *gfx;
 
@@ -3814,6 +3814,8 @@ void PSOutputDev::tilingPatternFill(GfxState *state, Object *str,
   writePSFmt("{0:d} 1 {1:d} {{ {2:.4g} exch {3:.4g} mul m {4:d} 1 {5:d} {{ pop (x) show }} for }} for\n",
 	     y0, y1 - 1, x0 * xStep, yStep, x0, x1 - 1);
   writePS("grestore\n");
+
+  return gTrue;
 }
 
 GBool PSOutputDev::functionShadedFill(GfxState *state,
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index e8bf29f..d364777 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -209,11 +209,11 @@ public:
   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 GBool 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 GBool functionShadedFill(GfxState *state,
 				   GfxFunctionShading *shading);
   virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/);


More information about the poppler mailing list