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

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Fri Jul 31 09:01:10 PDT 2009


 poppler/CairoOutputDev.cc |    9 +++++++++
 poppler/CairoOutputDev.h  |    1 +
 poppler/Gfx.cc            |   34 ++++++++++++++++++++++++++++------
 poppler/OutputDev.h       |    4 ++++
 4 files changed, 42 insertions(+), 6 deletions(-)

New commits:
commit 2ba937545d1a2b9fa798f04fee755ccdf0e74ec7
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Fri Jul 31 17:49:18 2009 +0200

    [cairo] Use cairo_pattern_set_extend for linear gradients

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index d1f5f3c..89335f8 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -668,12 +668,21 @@ GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading,
   cairo_pattern_destroy(fill_pattern);
   fill_pattern = cairo_pattern_create_linear (x0 + tMin * dx, y0 + tMin * dy,
 					      x0 + tMax * dx, y0 + tMax * dy);
+  if (!shading->getExtend0() && !shading->getExtend1())
+    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);
+  else
+    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD);
 
   // TODO: use the actual stops in the shading in the case
   // of linear interpolation (Type 2 Exponential functions with N=1)
   return gFalse;
 }
 
+GBool CairoOutputDev::axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading)
+{
+  return (shading->getExtend0() == shading->getExtend1());
+}
+
 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 f25e402..f2bcb55 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -152,6 +152,7 @@ public:
   virtual void fill(GfxState *state);
   virtual void eoFill(GfxState *state);
   virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
+  virtual GBool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading);
 
   //----- path clipping
   virtual void clip(GfxState *state);
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index e46f0e6..4b8ff35 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2361,6 +2361,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   GfxColor color0, color1;
   int nComps;
   int i, j, k;
+  GBool needExtend = gTrue;
 
   // get the clip region bbox
   state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
@@ -2448,6 +2449,12 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   }
   shading->getColor(tt, &color0);
 
+  if (out->useFillColorStop()) {
+    // make sure we add stop color when t = tMin
+    state->setFillColor(&color0);
+    out->updateFillColorStop(state, (tt - tMin)/(tMax - tMin));
+  }
+
   // compute the coordinates of the point on the t axis at t = tMin;
   // then compute the intersection of the perpendicular line with the
   // bounding box
@@ -2485,6 +2492,11 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     doneBBox1 = bboxIntersections[1] < tMin;
     doneBBox2 = bboxIntersections[2] > tMax;
   }
+
+  // If output device doesn't support the extended mode required
+  // we have to do it here
+  needExtend = !out->axialShadedSupportExtend(state, shading);
+
   while (i < axialMaxSplits) {
 
     // bisect until color difference is small enough or we hit the
@@ -2590,12 +2602,15 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     else
       out->updateFillColor(state);
 
-    // fill the region
-    state->moveTo(ux0, uy0);
-    state->lineTo(vx0, vy0);
-    state->lineTo(vx1, vy1);
-    state->lineTo(ux1, uy1);
-    state->closePath();
+    if (needExtend) {
+      // fill the region
+      state->moveTo(ux0, uy0);
+      state->lineTo(vx0, vy0);
+      state->lineTo(vx1, vy1);
+      state->lineTo(ux1, uy1);
+      state->closePath();
+    }
+
     if (!out->useFillColorStop()) {
       if (!contentIsHidden())
         out->fill(state);
@@ -2612,6 +2627,13 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   }
 
   if (out->useFillColorStop()) {
+    if (!needExtend) {
+      state->moveTo(xMin, yMin);
+      state->lineTo(xMin, yMax);
+      state->lineTo(xMax, yMax);
+      state->lineTo(xMax, yMin);
+      state->closePath();
+    }
     if (!contentIsHidden())
       out->fill(state);
     state->clearPath();
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 76d3611..d1cb2b0 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -199,8 +199,12 @@ public:
     { return gFalse; }
   virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/, double /*tMin*/, double /*tMax*/)
     { return gFalse; }
+  virtual GBool axialShadedSupportExtend(GfxState * /*state*/, GfxAxialShading * /*shading*/)
+    { return gFalse; }
   virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/)
     { return gFalse; }
+  virtual GBool radialShadedSupportExtend(GfxState * /*state*/, GfxRadialShading * /*shading*/)
+    { return gFalse; }
 
   //----- path clipping
   virtual void clip(GfxState * /*state*/) {}


More information about the poppler mailing list