[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h poppler/Gfx.cc poppler/OutputDev.h

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Wed Jan 26 03:02:56 PST 2011


 poppler/CairoOutputDev.cc |  139 ++++++++++++++++++++++++++++++++++++++++++++++
 poppler/CairoOutputDev.h  |   12 +++
 poppler/Gfx.cc            |   10 ++-
 poppler/OutputDev.h       |    2 
 4 files changed, 161 insertions(+), 2 deletions(-)

New commits:
commit e57c75fbd95ef8399b0785500f6893465bc808c3
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Jan 24 19:48:09 2011 +1030

    cairo: Implement Type 4,5,6,7 shadings using cairo mesh gradients
    
    Fixes bugs #19076 and #32791.

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 03e6c06..6bfe5a8 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -816,6 +816,145 @@ GBool CairoOutputDev::radialShadedSupportExtend(GfxState *state, GfxRadialShadin
   return (shading->getExtend0() == shading->getExtend1());
 }
 
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
+GBool CairoOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading)
+{
+  double x0, y0, x1, y1, x2, y2;
+  GfxColor color[3];
+  int i, j;
+  GfxRGB rgb;
+
+  cairo_pattern_destroy(fill_pattern);
+  fill_pattern = cairo_pattern_create_mesh ();
+
+  for (i = 0; i < shading->getNTriangles(); i++) {
+    shading->getTriangle(i,
+			 &x0, &y0, &color[0],
+			 &x1, &y1, &color[1],
+			 &x2, &y2, &color[2]);
+
+    cairo_pattern_mesh_begin_patch (fill_pattern);
+
+    cairo_pattern_mesh_move_to (fill_pattern, x0, y0);
+    cairo_pattern_mesh_line_to (fill_pattern, x1, y1);
+    cairo_pattern_mesh_line_to (fill_pattern, x2, y2);
+
+    for (j = 0; j < 3; j++) {
+	shading->getColorSpace()->getRGB(&color[j], &rgb);
+	cairo_pattern_mesh_set_corner_color_rgb (fill_pattern, j,
+						 colToDbl(rgb.r),
+						 colToDbl(rgb.g),
+						 colToDbl(rgb.b));
+    }
+
+    cairo_pattern_mesh_end_patch (fill_pattern);
+  }
+
+  double xMin, yMin, xMax, yMax;
+  // get the clip region bbox
+  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+  state->moveTo(xMin, yMin);
+  state->lineTo(xMin, yMax);
+  state->lineTo(xMax, yMax);
+  state->lineTo(xMax, yMin);
+  state->closePath();
+  fill(state);
+  state->clearPath();
+
+  return gTrue;
+}
+
+GBool CairoOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading)
+{
+  int i, j, k;
+
+  cairo_pattern_destroy(fill_pattern);
+  fill_pattern = cairo_pattern_create_mesh ();
+
+  for (i = 0; i < shading->getNPatches(); i++) {
+    GfxPatch *patch = shading->getPatch(i);
+    GfxColor color;
+    GfxRGB rgb;
+
+    cairo_pattern_mesh_begin_patch (fill_pattern);
+
+    cairo_pattern_mesh_move_to (fill_pattern, patch->x[0][0], patch->y[0][0]);
+    cairo_pattern_mesh_curve_to (fill_pattern,
+			    patch->x[0][1], patch->y[0][1],
+			    patch->x[0][2], patch->y[0][2],
+			    patch->x[0][3], patch->y[0][3]);
+
+    cairo_pattern_mesh_curve_to (fill_pattern,
+			    patch->x[1][3], patch->y[1][3],
+			    patch->x[2][3], patch->y[2][3],
+			    patch->x[3][3], patch->y[3][3]);
+
+    cairo_pattern_mesh_curve_to (fill_pattern,
+			    patch->x[3][2], patch->y[3][2],
+			    patch->x[3][1], patch->y[3][1],
+			    patch->x[3][0], patch->y[3][0]);
+
+    cairo_pattern_mesh_curve_to (fill_pattern,
+			    patch->x[2][0], patch->y[2][0],
+			    patch->x[1][0], patch->y[1][0],
+			    patch->x[0][0], patch->y[0][0]);
+
+    cairo_pattern_mesh_set_control_point (fill_pattern, 0, patch->x[1][1], patch->y[1][1]);
+    cairo_pattern_mesh_set_control_point (fill_pattern, 1, patch->x[1][2], patch->y[1][2]);
+    cairo_pattern_mesh_set_control_point (fill_pattern, 2, patch->x[2][2], patch->y[2][2]);
+    cairo_pattern_mesh_set_control_point (fill_pattern, 3, patch->x[2][1], patch->y[2][1]);
+
+    for (j = 0; j < 4; j++) {
+      int u, v;
+
+      switch (j) {
+	case 0:
+	  u = 0; v = 0;
+	  break;
+	case 1:
+	  u = 0; v = 1;
+	  break;
+	case 2:
+	  u = 1; v = 1;
+	  break;
+	case 3:
+	  u = 1; v = 0;
+	  break;
+      }
+
+      if (shading->isParameterized()) {
+	shading->getParameterizedColor (patch->color[u][v].c[0], &color);
+      } else {
+	for (k = 0; k < shading->getColorSpace()->getNComps(); k++) {
+          // simply cast to the desired type; that's all what is needed.
+	  color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
+	}
+      }
+
+      shading->getColorSpace()->getRGB(&color, &rgb);
+      cairo_pattern_mesh_set_corner_color_rgb (fill_pattern, j,
+					       colToDbl(rgb.r),
+					       colToDbl(rgb.g),
+					       colToDbl(rgb.b));
+    }
+    cairo_pattern_mesh_end_patch (fill_pattern);
+  }
+
+  double xMin, yMin, xMax, yMax;
+  // get the clip region bbox
+  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+  state->moveTo(xMin, yMin);
+  state->lineTo(xMin, yMax);
+  state->lineTo(xMax, yMax);
+  state->lineTo(xMax, yMin);
+  state->closePath();
+  fill(state);
+  state->clearPath();
+
+  return gTrue;
+}
+#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) */
+
 void CairoOutputDev::clip(GfxState *state) {
   doPath (cairo, state, state->getPath());
   cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 72ca6a0..8e25575 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -107,7 +107,11 @@ public:
   // 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.
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
+  virtual GBool useShadedFills(int type) { return type <= 7; }
+#else
   virtual GBool useShadedFills(int type) { return type < 4; }
+#endif
 
   // Does this device use FillColorStop()?
   virtual GBool useFillColorStop() { return gTrue; }
@@ -166,6 +170,10 @@ public:
   virtual GBool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading);
   virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax);
   virtual GBool radialShadedSupportExtend(GfxState *state, GfxRadialShading *shading);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
+  virtual GBool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading);
+  virtual GBool patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading);
+#endif
 
   //----- path clipping
   virtual void clip(GfxState *state);
@@ -362,7 +370,11 @@ public:
   // 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.
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
+  virtual GBool useShadedFills(int type) { return type <= 7; }
+#else
   virtual GBool useShadedFills(int type) { return type < 4; }
+#endif
 
   // Does this device use FillColorStop()?
   virtual GBool useFillColorStop() { return gFalse; }
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 09c5381..9cff25f 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -3119,10 +3119,11 @@ void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) {
   double x0, y0, x1, y1, x2, y2;
   int i;
 
-  if( out->useShadedFills( shading->getType() ) ) {
-    if( out->gouraudTriangleShadedFill( state, shading ) )
+  if (out->useShadedFills( shading->getType()) && !contentIsHidden()) {
+    if (out->gouraudTriangleShadedFill( state, shading))
       return;
   }
+
   // preallocate a path (speed improvements)
   state->moveTo(0., 0.);
   state->lineTo(1., 0.);
@@ -3270,6 +3271,11 @@ void Gfx::gouraudFillTriangle(double x0, double y0, double color0,
 void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) {
   int start, i;
 
+  if (out->useShadedFills( shading->getType()) && !contentIsHidden()) {
+    if (out->patchMeshShadedFill( state, shading))
+      return;
+  }
+
   if (shading->getNPatches() > 128) {
     start = 3;
   } else if (shading->getNPatches() > 64) {
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 057d84a..af016b6 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -51,6 +51,8 @@ class GfxAxialShading;
 class GfxGouraudTriangleShading;
 class GfxPatchMeshShading;
 class GfxRadialShading;
+class GfxGouraudTriangleShading;
+class GfxPatchMeshShading;
 class Stream;
 class Links;
 class Link;


More information about the poppler mailing list