Hi all, 

when drawing gradients with cairo, we don't need to fill a path for
every region, we can just fill the bounding box with the gradient
pattern, but this only works when shading->getExtend0() ==
shading->getExtend1(), since we can use CAIRO_EXTEND_NONE when they are
FALSE and CAIRO_EXTEND_PAD when they are TRUE. When they are different,
we could just use the current approach, adding a path for every region.
This is exactly what the attached patch does.

-- 
Carlos Garcia Campos
PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462
From 1ebe7b4b6079a8b556fa148ec38c196f292c804d Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <[email protected]>
Date: Sat, 25 Jul 2009 12:22:32 +0200
Subject: [PATCH] Use cairo_pattern_set_extend for linear gradients

---
 poppler/CairoOutputDev.cc |    4 ++++
 poppler/Gfx.cc            |   26 ++++++++++++++++++--------
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 0f9b621..3780624 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -609,6 +609,10 @@ 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_PAD);
+  else
+    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);
 
   // TODO: use the actual stops in the shading in the case
   // of linear interpolation (Type 2 Exponential functions with N=1)
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index c3f257f..5797ce8 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2360,6 +2360,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   GfxColor color0, color1;
   int nComps;
   int i, j, k;
+  GBool needFill = gTrue;
 
   // get the clip region bbox
   state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
@@ -2484,6 +2485,9 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
     doneBBox1 = bboxIntersections[1] < tMin;
     doneBBox2 = bboxIntersections[2] > tMax;
   }
+  if (out->useFillColorStop() && (shading->getExtend0() == shading->getExtend1()))
+    needFill = gFalse;
+
   while (i < axialMaxSplits) {
 
     // bisect until color difference is small enough or we hit the
@@ -2588,14 +2592,13 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
       out->updateFillColorStop(state, (ta[j] - tMin)/(tMax - tMin));
     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 (!out->useFillColorStop()) {
+    if (needFill) {
+      // fill the region
+      state->moveTo(ux0, uy0);
+      state->lineTo(vx0, vy0);
+      state->lineTo(vx1, vy1);
+      state->lineTo(ux1, uy1);
+      state->closePath();
       if (!contentIsHidden())
         out->fill(state);
       state->clearPath();
@@ -2611,6 +2614,13 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
   }
 
   if (out->useFillColorStop()) {
+    if (!needFill) {
+      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();
-- 
1.6.0.4

Attachment: signature.asc
Description: Esta parte del mensaje está firmada digitalmente

_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to