[poppler] 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
Wed Jul 8 09:56:26 PDT 2009


 poppler/CairoOutputDev.cc |   29 +++++++++++++++++++++++++++++
 poppler/CairoOutputDev.h  |   10 ++++++++++
 poppler/Gfx.cc            |   29 ++++++++++++++++++++---------
 poppler/OutputDev.h       |    6 +++++-
 poppler/PSOutputDev.cc    |    2 +-
 poppler/PSOutputDev.h     |    2 +-
 6 files changed, 66 insertions(+), 12 deletions(-)

New commits:
commit 569627ac4d56ddd58e109ce2a37179a85e042030
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Wed Jul 8 13:02:16 2009 +0200

    Implement axialShadedFill in cairo backend using cairo gradients
    
    See bug #10942.

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index e033e50..79c5c76 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -458,6 +458,18 @@ void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
   LOG(printf ("stroke opacity: %f\n", stroke_opacity));
 }
 
+void CairoOutputDev::updateFillColorStop(GfxState *state, double offset) {
+  state->getFillRGB(&fill_color);
+
+  cairo_pattern_add_color_stop_rgba(fill_pattern, offset,
+				    fill_color.r / 65535.0,
+				    fill_color.g / 65535.0,
+				    fill_color.b / 65535.0,
+				    fill_opacity);
+  LOG(printf ("fill color stop: %f (%d, %d, %d)\n",
+	      offset, fill_color.r, fill_color.g, fill_color.b));
+}
+
 void CairoOutputDev::updateFont(GfxState *state) {
   cairo_font_face_t *font_face;
   cairo_matrix_t matrix, invert_matrix;
@@ -586,6 +598,23 @@ void CairoOutputDev::eoFill(GfxState *state) {
 
 }
 
+GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) {
+  double x0, y0, x1, y1;
+  double dx, dy;
+
+  shading->getCoords(&x0, &y0, &x1, &y1);
+  dx = x1 - x0;
+  dy = y1 - y0;
+
+  cairo_pattern_destroy(fill_pattern);
+  fill_pattern = cairo_pattern_create_linear (x0 + tMin * dx, y0 + tMin * dy,
+					      x0 + tMax * dx, y0 + tMax * dy);
+
+  // TODO: use the actual stops in the shading in the case
+  // of linear interpolation (Type 2 Exponential functions with N=1)
+  return gFalse;
+}
+
 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 5af832d..cd66cb7 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -98,6 +98,14 @@ public:
   // Does this device use drawChar() or drawString()?
   virtual GBool useDrawChar() { 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 gTrue; }
+
+  // Does this device use FillColorStop()?
+  virtual GBool useFillColorStop() { return gTrue; }
+
   // Does this device use beginType3Char/endType3Char?  Otherwise,
   // text in Type 3 fonts will be drawn with drawChar/drawString.
   virtual GBool interpretType3Chars() { return gFalse; }
@@ -132,6 +140,7 @@ public:
   virtual void updateStrokeColor(GfxState *state);
   virtual void updateFillOpacity(GfxState *state);
   virtual void updateStrokeOpacity(GfxState *state);
+  virtual void updateFillColorStop(GfxState *state, double offset);
 
   //----- update text state
   virtual void updateFont(GfxState *state);
@@ -141,6 +150,7 @@ public:
   virtual void stroke(GfxState *state);
   virtual void fill(GfxState *state);
   virtual void eoFill(GfxState *state);
+  virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
 
   //----- path clipping
   virtual void clip(GfxState *state);
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index c11f551..c3f257f 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2361,11 +2361,6 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   int nComps;
   int i, j, k;
 
-  if (out->useShadedFills() &&
-      out->axialShadedFill(state, shading)) {
-    return;
-  }
-
   // get the clip region bbox
   state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
 
@@ -2395,6 +2390,11 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     }
   }
 
+  if (out->useShadedFills() &&
+      out->axialShadedFill(state, shading, tMin, tMax)) {
+	  return;
+  }
+
   // get the function domain
   t0 = shading->getDomain0();
   t1 = shading->getDomain1();
@@ -2584,7 +2584,10 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
 
     // set the color
     state->setFillColor(&color0);
-    out->updateFillColor(state);
+    if (out->useFillColorStop())
+      out->updateFillColorStop(state, (ta[j] - tMin)/(tMax - tMin));
+    else
+      out->updateFillColor(state);
 
     // fill the region
     state->moveTo(ux0, uy0);
@@ -2592,9 +2595,11 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     state->lineTo(vx1, vy1);
     state->lineTo(ux1, uy1);
     state->closePath();
-    if (!contentIsHidden())
-      out->fill(state);
-    state->clearPath();
+    if (!out->useFillColorStop()) {
+      if (!contentIsHidden())
+        out->fill(state);
+      state->clearPath();
+    }
 
     // set up for next region
     ux0 = ux1;
@@ -2604,6 +2609,12 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     color0 = color1;
     i = next[i];
   }
+
+  if (out->useFillColorStop()) {
+    if (!contentIsHidden())
+      out->fill(state);
+    state->clearPath();
+  }
 }
 
 void Gfx::doRadialShFill(GfxRadialShading *shading) {
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 35adadd..76d3611 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -85,6 +85,9 @@ public:
   // will be reduced to a series of other drawing operations.
   virtual GBool useShadedFills() { return gFalse; }
 
+  // Does this device use FillColorStop()?
+  virtual GBool useFillColorStop() { return gFalse; }
+
   // Does this device use drawForm()?  If this returns false,
   // form-type XObjects will be interpreted (i.e., unrolled).
   virtual GBool useDrawForm() { return gFalse; }
@@ -169,6 +172,7 @@ public:
   virtual void updateFillOverprint(GfxState * /*state*/) {}
   virtual void updateStrokeOverprint(GfxState * /*state*/) {}
   virtual void updateTransfer(GfxState * /*state*/) {}
+  virtual void updateFillColorStop(GfxState * /*state*/, double /*offset*/) {}
 
   //----- update text state
   virtual void updateFont(GfxState * /*state*/) {}
@@ -193,7 +197,7 @@ public:
   virtual GBool functionShadedFill(GfxState * /*state*/,
 				   GfxFunctionShading * /*shading*/)
     { return gFalse; }
-  virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/)
+  virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/, double /*tMin*/, double /*tMax*/)
     { return gFalse; }
   virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/)
     { return gFalse; }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 6bec12d..ea8aeea 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3850,7 +3850,7 @@ GBool PSOutputDev::functionShadedFill(GfxState *state,
   return gTrue;
 }
 
-GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) {
+GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/) {
   double xMin, yMin, xMax, yMax;
   double x0, y0, x1, y1, dx, dy, mul;
   double tMin, tMax, t, t0, t1;
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 6310375..be4763d 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -215,7 +215,7 @@ public:
 				 double xStep, double yStep);
   virtual GBool functionShadedFill(GfxState *state,
 				   GfxFunctionShading *shading);
-  virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading);
+  virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/);
   virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading);
 
   //----- path clipping


More information about the poppler mailing list