Am 03.01.2011 11:41, schrieb Thomas Freitag:
Am 03.01.2011 00:28, schrieb Albert Astals Cid:
A Diumenge, 2 de gener de 2011, Thomas Freitag va escriure:
Am 01.01.2011 22:34, schrieb Albert Astals Cid:
A Dissabte, 1 de gener de 2011, Thomas Freitag va escriure:
Please regtest this new patch. What I've done in the meantime:

a) speed up the implemenation but have enough quality left.
b) implement the shading extend in a correct way, test it against the
samples from the PDF spec (appendix L)
c) test it against all samples from Andrea, including bug 32349&   30887.
d) test it against ducks&   roses and all the PDF You send me because of
regressions with former patches.

So I'm think I'm quite near of finishing the implementation, just
waiting for the result of Your regtest.
There are a few empty pixels in the border of
http://bugsfiles.kde.org/attachment.cgi?id=20680
Sorry, I made such a lot changes in the last three days, that I forgot
to remove a test case where I wanted to see where normal shading stops
and extending shading starts, so the last circle of normal shading was
no more painted :-(

Please try the new patch.
There is a regression on page 25 of
http://download.tuxfamily.org/magnum/doc/magnum04.pdf

See attached files.
Have You already read this? Had problems in sending it, don't know if its the mailserver from kabelmail or from freedesktop, so try another mailserver then kabelmail. If You haven't already read it, please read the next few lines:

This was not really a bug in the new feature "radial shading": when I introduced the dynamic pattern in axial shading, and the ability to return gFalse in getColor() if nothing should be paint, I forgot to increase some pipe pointers in pipeRun, i.e. if softmask is used the softmask pointers must be increased, too.

Please try the new patch.

BTW, Albert: I start working again, and because this is almost a private pleasure, I can probably look only on weekend into new regressions. And because I think we are really quite near, could You please run the regression test over all PDF and send me them all or links to it instead stopping the test if You first regression? Then I can look at all regressions next weekend...

Thomas

Albert

Thomas

Albert

Happy new year,
Thomas

Am 31.12.2010 03:10, schrieb Thomas Freitag:
I made a lot of mistakes, but I'm quite close now, s. attached
rendering of Andrea's PDF. What is still up to do, is
a) speed it up again
b) implement the shading extend in a correct way (I'd already a look
at it, it's also wrong implemented in Gfx)
c) run it again through my own regression test.

Thomas

Am 30.12.2010 12:20, schrieb Thomas Freitag:
I just recognized a bug with Andrea's PDF when drawing non centered
circles. Want to fix that first before sending a new patch.

Thomas

Am 30.12.2010 11:29, schrieb Albert Astals Cid:
A Dijous, 30 de desembre de 2010, vàreu escriure:
Sorry, I attached Your "new.png", not mine. Here the correct one
produced with the above changes.
This looks good enough for me, can you send the full patch to the
list?

Thanks!

Albert

Thomas

Am 30.12.2010 10:31, schrieb Thomas Freitag:
Hi Albert!

I changed the SplashRadialPattern::getColor a little bit to solve
this. It is still a little bit different from the old one, in my
opinion a little bit better, but that's just a flavour, and in
other cases it could be a little bit more worse. So if You agree,
I can send
a complete new patch.

BTW, as You probably see, Andrea attached his PDF to the closed bug
32349. I saw already yesterday, that also the new rendering with
the latest patch is quite better than the old rendering, but it's
still not shown what Acrobat reader shows. I'll have an additional
look in it, but I fear that this will be again a bigger job (the
PDF has 128 radial shadings, and only some of them are still
buggy!). So (if not solvable in time) I would prefer to close this
thread first, and then reopen the bug or create a new one.

Do You agree, or do You have other ideas?

Thomas

FYI, here the changes:

GBool SplashRadialPattern::getColor(int x, int y, SplashColorPtr c)
{

     double xc, yc;
     int xs, ys;
     Guchar *bitmapAlpha;

     bitmapAlpha = bitmap->getAlphaPtr();
     ictm.transform(x, y,&xc,&yc);
     xs = splashRound(xc);
     ys = splashRound(yc);
     // Because of rounding problems, coordinates could be
     // outside the bitmap. Reset them on the outer bound now
     // and let it up to the alpha channel if they are shown:
     if (xs<    0) xs = 0;
     if (xs>= bitmap->getWidth()) xs = bitmap->getWidth() - 1;
     if (ys<    0) ys = 0;
     if (ys>= bitmap->getHeight()) ys = bitmap->getHeight() - 1;
     if (bitmapAlpha[ys * bitmap->getWidth() + xs])

         bitmap->getPixel(xs, ys, c);

     else

         return gFalse;

     return gTrue;

}

Am 29.12.2010 23:28, schrieb Albert Astals Cid:
First page, left of the "title". A few white pixels in there.

Albert

A Dimecres, 29 de desembre de 2010, Thomas Freitag va escriure:
Am 29.12.2010 18:53, schrieb Andrea Canciani:
On Wed, Dec 29, 2010 at 4:48 PM, Thomas Freitag

<[email protected]>      wrote:
...
I made a mistake when solving the problem with
altona_visual_1v2a_x3.pdf. I find now a better way to solve
it, which
also gives a better look of the printer paper back again.
I'd like to point yo to another pdf whose rendering regresses
with the
patch:https://bugs.freedesktop.org/attachment.cgi?id=41506
Albert, can You please just change two lines in the former patch?
1. In SplashOutputDev.cc in the constructor of
SplashRadialPattern, replace
+ bitmap = new SplashBitmap(splashRound(width) + 1,
splashRound(height)
+ 1, colorMode != splashModeMono1, colorMode, gTrue);
through
+      bitmap = new SplashBitmap(splashRound(width) + 2,
splashRound(height) + 2, colorMode != splashModeMono1, colorMode,
gTrue);
2. In Splash.cc in the painting routine radialShadedFill, where
the smaller extend circle is painted, replace
+ drawPartEllipseLine(&pipe, 2* yo - curY, xMin, xMax);
through
+                drawPartEllipseLine(&pipe, curY, xMin, xMax);
(curY is alfready recalculated two line before!)

Or just reapply the attached patch.
This solves the rendering regressions mailed by Andrea.

Thomas

In the last row, half of the inner circle is transparent with
poppler/master+radialsh.patch.

Andrea

PS: Sorry for removing most of the thread from this message,
but gmail
squashed it to just one level.
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

.
.


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


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


diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 0b3722a..1dc4c8e 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -153,6 +153,328 @@ void SplashGouraudPattern::getParameterizedColor(double 
colorinterp, SplashColor
 }
 
 //------------------------------------------------------------------------
+// SplashRadialPattern
+//------------------------------------------------------------------------
+// Min number of splits along the t axis for a radial shading fill.
+#define radialMinSplits 256
+
+// Max number of splits along the t axis for a radial shading fill.
+#define radialMaxSplits 2048
+
+// Max delta allowed in any color component for a radial shading fill.
+#define radialColorDelta (dblToCol(1.0 / 256.0))
+
+// Max size of pattern bitmap of min (width, height)
+#define radialMaxSize 256
+
+SplashRadialPattern::SplashRadialPattern(GfxState *stateA, GfxRadialShading 
*shadingA,
+                                                                               
 double sMinA, double sMaxA, SplashColorMode colorModeA) {
+  double width, height;
+  Matrix ctm;
+
+  state = stateA;
+  shading = shadingA;
+  // ignore sMin ans sMax from Gfx (they include already extends!):
+  sMax = 1;
+  sMin = 0;
+  colorMode = colorModeA;
+  state->getCTM(&ctm);
+  ctm.invertTo(&ictm);
+  splash = NULL;
+  bitmap = NULL;
+  // get the shading info
+  shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
+  t0 = shading->getDomain0();
+  t1 = shading->getDomain1();
+  if (shading->getHasBBox())
+         shading->getBBox(&xMin, &yMin, &xMax, &yMax);
+  else 
+         state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+  width = xMax - xMin;
+  height = yMax - yMin;
+  if (splashRound(xMax) - splashRound(xMin) > width)
+       width = splashRound(xMax) - splashRound(xMin);
+  if (splashRound(yMax) - splashRound(yMin) > height)
+       height = splashRound(yMax) - splashRound(yMin);
+  if (radialMaxSize > 0 && width > 0 && height > 0) {
+         if ( width > height)
+                 scale = radialMaxSize / height;
+         else
+                 scale = radialMaxSize / width;
+  } else
+         scale = 1;
+  xMin *= scale;
+  xMax *= scale;
+  yMin *= scale;
+  yMax *= scale;
+  width *= scale;
+  height *= scale;
+  if (width > 0 && height > 0) {
+         bitmap = new SplashBitmap(splashRound(width) + 2, splashRound(height) 
+ 2, colorMode != splashModeMono1, colorMode, gTrue);
+         splash = new Splash(bitmap, gFalse /* AntiAlias in shading Dict! */);
+
+         // show only what is painted, delete alpha channel
+         Guchar *bitmapAlpha = bitmap->getAlphaPtr();
+         int size = bitmap->getWidth() * bitmap->getHeight();
+         for (int i = 0; i < size; ++i)
+                 bitmapAlpha[i] = 0;
+  }
+
+  // change transfer matrix to fit to scaled bitmap 
+  ictm.m[0] *= scale;
+  ictm.m[1] *= scale;
+  ictm.m[2] *= scale;
+  ictm.m[3] *= scale;
+  ictm.m[4] *= scale;
+  ictm.m[5] *= scale;
+  ictm.m[4] -= xMin;
+  ictm.m[5] -= yMin;
+  maxSplits = splashRound((r0 - r1) * scale / 5);
+  if (maxSplits < 0) maxSplits = -maxSplits;
+  if (maxSplits < radialMinSplits)
+         maxSplits = radialMinSplits;
+  if (maxSplits > radialMaxSplits)
+         maxSplits = radialMaxSplits;
+}
+
+SplashRadialPattern::~SplashRadialPattern() {
+  if (splash) {
+    delete splash;
+  }
+  if (bitmap) {
+    delete bitmap;
+  }
+}
+
+GBool SplashRadialPattern::getColor(int x, int y, SplashColorPtr c) {
+  double xc, yc;
+  int xs, ys;
+  Guchar *bitmapAlpha;
+
+  bitmapAlpha = bitmap->getAlphaPtr();
+  ictm.transform(x, y, &xc, &yc);
+  xs = splashRound(xc);
+  ys = splashRound(yc);
+  // Because of rounding problems, coordinates could be 
+  // outside the bitmap. Reset them on the outer bound now
+  // and let it up to the alpha channel if they are shown:
+  if (xs < 0) xs = 0;
+  if (xs >= bitmap->getWidth()) xs = bitmap->getWidth() - 1;
+  if (ys < 0) ys = 0;
+  if (ys >= bitmap->getHeight()) ys = bitmap->getHeight() - 1;
+  if (bitmapAlpha[ys * bitmap->getWidth() + xs])
+         bitmap->getPixel(xs, ys, c);
+  else
+         return gFalse;
+  return gTrue;
+}
+
+static inline void getShadingColorRadialHelper(double t0, double t1, double t, 
GfxRadialShading *shading, GfxColor *color)
+{
+  if (t0 < t1) {
+    if (t < t0) {
+      shading->getColor(t0, color);
+    } else if (t > t1) {
+      shading->getColor(t1, color);
+    } else {
+      shading->getColor(t, color);
+    }
+  } else {
+    if (t > t0) {
+      shading->getColor(t0, color);
+    } else if (t < t1) {
+      shading->getColor(t1, color);
+    } else {
+      shading->getColor(t, color);
+    }
+  }
+}
+
+void SplashRadialPattern::getStartCircle(SplashCoord *xsc, SplashCoord *ysc, 
+                                                                               
 SplashCoord *radius, 
+                                                                               
 SplashColorPtr c) {
+  GfxColor colorA;
+  GfxColorSpace* srcColorSpace = shading->getColorSpace();
+  ia = 0;
+  sa = sMin;
+  ta = t0 + sa * (t1 - t0);
+  xa = x0 + sa * (x1 - x0);
+  ya = y0 + sa * (y1 - y0);
+  ra = r0 + sa * (r1 - r0);
+  getShadingColorRadialHelper(t0, t1, ta, shading, &colorA);
+  *radius = splashRound(ra * scale); 
+  *xsc = splashRound(xa * scale - xMin); *ysc = splashRound(ya * scale - 
yMin); 
+  convertGfxColor(c, colorMode, srcColorSpace, &colorA);
+}
+
+static inline GBool isSameGfxColor(const GfxColor &colorA, const GfxColor 
&colorB, Guint nComps, double delta) {
+  for (Guint k = 0; k < nComps; ++k) {
+    if (abs(colorA.c[k] - colorB.c[k]) > delta) {
+      return false;
+    }
+  }
+  return true;
+}
+
+GBool SplashRadialPattern::getNextCircle(SplashCoord *xsc, SplashCoord *ysc, 
+                                                                               
 SplashCoord *radius, 
+                                                                               
 SplashColorPtr c) {
+  GfxColor colorA, colorB;
+  GfxColorSpace* srcColorSpace = shading->getColorSpace();
+  double sb, tb, factor;
+  int ib, nComps;
+  nComps = shading->getColorSpace()->getNComps();
+  if (ia >= maxSplits)
+         return gFalse;
+  getShadingColorRadialHelper(t0, t1, ta, shading, &colorA);
+  ib = maxSplits;
+  sb = (r1 > r0) ? sMax : sMin;
+  tb = t0 + sb * (t1 - t0);
+  getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
+  while (ib - ia > 1) {
+      if (isSameGfxColor(colorB, colorA, nComps, radialColorDelta)) {
+        // The shading is not necessarily lineal so having two points with the
+        // same color does not mean all the areas in between have the same 
color too
+                 int ic = ia + 1;
+                 for (; ic <= ib; ic++) {
+                       GfxColor colorC;
+                       factor = (double)ic / (double)maxSplits; 
+                       double sc = sMin + factor * (sMax - sMin);
+                       double tc = t0 + sc * (t1 - t0);
+                       getShadingColorRadialHelper(t0, t1, tc, shading, 
&colorC);
+                       if (!isSameGfxColor(colorC, colorA, nComps, 
radialColorDelta)) {
+                         break;
+                       }
+                 }
+                 ib = (ic > ia + 1)? ic - 1 : ia + 1;
+                 factor = (double)ib / (double)maxSplits; 
+                 sb = sMin + factor * (sMax - sMin);
+                 tb = t0 + sb * (t1 - t0);
+                 getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
+                 break;
+      }
+      ib = (ia + ib) / 2;
+         factor = (double)ib / (double)maxSplits; 
+      sb = sMin + factor * (sMax - sMin);
+      tb = t0 + sb * (t1 - t0);
+      getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
+  }
+  // compute center and radius of the circle
+  xa = x0 + sb * (x1 - x0);
+  ya = y0 + sb * (y1 - y0);
+  ra = r0 + sb * (r1 - r0);
+  *radius = splashRound(ra * scale); 
+  *xsc = splashRound(xa * scale - xMin); *ysc = splashRound(ya * scale - 
yMin); 
+  convertGfxColor(c, colorMode, srcColorSpace, &colorB);
+  ia = ib;
+  ta = tb;
+  return gTrue;
+}
+
+GBool SplashRadialPattern::getLargerExtendCircle(SplashCoord *xsc, SplashCoord 
*ysc, 
+                                                                               
 SplashCoord *radius, SplashColorPtr c) {
+  GfxColor colorA;
+  GfxColorSpace* srcColorSpace = shading->getColorSpace();
+  if ((shading->getExtend0() && r0 > r1) ||
+         (shading->getExtend1() && r1 >= r0)) {
+                 if (r0 >= r1) {
+                         ta = t0;
+                         ra = r0;
+                         xa = x0;
+                         ya = y0;
+                 } else {
+                         ta = t1;
+                         ra = r1;
+                         xa = x1;
+                         ya = y1;
+                 }
+                 shading->getColor(ta, &colorA);
+                 *radius = splashRound(ra * scale); 
+                 *xsc = splashRound(xa * scale - xMin); *ysc = splashRound(ya 
* scale - yMin); 
+                 convertGfxColor(c, colorMode, srcColorSpace, &colorA);
+                 ia = 0;
+                 return gTrue;
+  }
+  return gFalse;
+}
+
+GBool SplashRadialPattern::getNextLargerExtendCircle(SplashCoord *xsc, 
SplashCoord *ysc, 
+                                                                               
                          SplashCoord *radius, GBool fExtend) {
+  double sb, factor;
+  double sStart, sEnd;
+  if (ia++ + 1 >= radialMinSplits)
+         return gFalse;
+  sStart = (r0 > r1) ? sMin : sMax;
+  // buest guess:
+  sEnd = (fExtend) ? sMax * 16 : -sMax * 16; 
+  factor = (double)ia / (double)radialMinSplits; 
+  sb = sStart + factor * (sEnd - sStart);
+  // compute center and radius of the circle
+  xa = x0 + sb * (x1 - x0);
+  ya = y0 + sb * (y1 - y0);
+  ra = r0 + sb * (r1 - r0);
+  ra = ra * scale;
+  xa = xa * scale - xMin;
+  ya = ya * scale - yMin;
+  if (ya - ra < yMin && ya + ra > yMax && xa - ra < xMin && xa + ra > xMax)
+         ia = radialMinSplits;
+  *radius = splashRound(ra); 
+  *xsc = splashRound(xa); *ysc = splashRound(ya); 
+  return gTrue;
+}
+
+GBool SplashRadialPattern::getSmallerExtendCircle(SplashCoord *xsc, 
SplashCoord *ysc, 
+                                                                               
 SplashCoord *radius, SplashColorPtr c, GBool fExtend) {
+  GfxColor colorA;
+  GfxColorSpace* srcColorSpace = shading->getColorSpace();
+  if ((shading->getExtend0() && r0 <= r1 && r0 > 0) ||
+         (shading->getExtend1() && r1 < r0 && r1 > 0)) {
+                 double sStart, sEnd;
+                 sEnd = (r1 > r0) ? sMin : sMax;
+                 sStart = (r1!= r0) ? -r0 / (r1 - r0) : 0; 
+                 double sb = (fExtend) ? sStart : sEnd; 
+                 xa = x0 + sb * (x1 - x0);
+                 ya = y0 + sb * (y1 - y0);
+                 ra = r0 + sb * (r1 - r0);
+                 if (r0 < r1) {
+                         ta = t0;
+                 } else {
+                         ta = t1;
+                 }
+                 shading->getColor(ta, &colorA);
+                 *radius = splashRound(ra * scale); 
+                 *xsc = splashRound(xa * scale - xMin); *ysc = splashRound(ya 
* scale - yMin); 
+                 convertGfxColor(c, colorMode, srcColorSpace, &colorA);
+                 ia = 0;
+                 return gTrue;
+  }
+  return gFalse;
+}
+
+GBool SplashRadialPattern::getNextSmallerExtendCircle(SplashCoord *xsc, 
SplashCoord *ysc, 
+                                                                               
                          SplashCoord *radius, GBool fExtend) {
+  double sb, factor;
+  double sStart, sEnd;
+  if (ia++ + 1 >= maxSplits)
+         return gFalse;
+  sEnd = (r1 > r0) ? sMax : sMin;
+  sStart = (r1!= r0) ? -r0 / (r1 - r0) : sMax * 16; 
+  if (!fExtend) {
+         sEnd = sStart; 
+         sStart = (r1 > r0) ? sMin : sMax;
+  }
+  factor = (double)ia / (double)maxSplits; 
+  sb = sStart + factor * (sEnd - sStart);
+  // compute center and radius of the circle
+  xa = x0 + sb * (x1 - x0);
+  ya = y0 + sb * (y1 - y0);
+  ra = r0 + sb * (r1 - r0);
+  *radius = splashRound(ra * scale); 
+  *xsc = splashRound(xa * scale - xMin); *ysc = splashRound(ya * scale - 
yMin); 
+  return gTrue;
+}
+
+//------------------------------------------------------------------------
 // SplashAxialPattern
 //------------------------------------------------------------------------
 
@@ -3011,14 +3333,14 @@ void SplashOutputDev::beginTransparencyGroup(GfxState 
*state, double *bbox,
   tx = (int)floor(xMin);
   if (tx < 0) {
     tx = 0;
-  } else if (tx > bitmap->getWidth()) {
-    tx = bitmap->getWidth();
+  } else if (tx > bitmap->getWidth() - 1) {
+    tx = bitmap->getWidth() - 1;
   }
   ty = (int)floor(yMin);
   if (ty < 0) {
     ty = 0;
-  } else if (ty > bitmap->getHeight()) {
-    ty = bitmap->getHeight();
+  } else if (ty > bitmap->getHeight() - 1) {
+    ty = bitmap->getHeight() - 1;
   }
   w = (int)ceil(xMax) - tx + 1;
   if (tx + w > bitmap->getWidth()) {
@@ -3379,3 +3701,34 @@ GBool SplashOutputDev::axialShadedFill(GfxState *state, 
GfxAxialShading *shading
 
   return retVal;
 }
+
+GBool SplashOutputDev::radialShadedFill(GfxState *state, GfxRadialShading 
*shading, double sMin, double sMax) {
+  double xMin, yMin, xMax, yMax;
+  SplashPath *path;
+
+  GBool retVal = gFalse;
+  // get the clip region bbox
+  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+  // fill the region
+  state->moveTo(xMin, yMin);
+  state->lineTo(xMax, yMin);
+  state->lineTo(xMax, yMax);
+  state->lineTo(xMin, yMax);
+  state->closePath();
+  path = convertPath(state, state->getPath());
+
+  SplashRadialColor *pattern = new SplashRadialPattern(state, shading, sMin, 
sMax, colorMode);
+  if (pattern->isOk()) {
+         // first draw the radial shading in its own bitmap
+         retVal = (pattern->getSplash()->radialShadedFill(pattern) == 
splashOk);
+         // now use this bitmap as dynamic pattern:
+         if (retVal) {
+                 retVal = (splash->shadedFill(path, shading->getHasBBox(), 
pattern) == splashOk);
+         }
+  }
+  state->clearPath();
+  delete pattern;
+  delete path;
+
+  return retVal;
+}
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index 570d036..85fc130 100644
--- a/poppler/SplashOutputDev.h
+++ b/poppler/SplashOutputDev.h
@@ -105,6 +105,49 @@ private:
   GBool bDirectColorTranslation;
 };
 
+// see GfxState.h, GfxRadialShading
+class SplashRadialPattern: public SplashRadialColor {
+public:
+
+  SplashRadialPattern(GfxState *state, GfxRadialShading *shading, double sMin, 
double sMax, SplashColorMode colorMode);
+
+  GBool isOk() { return (bitmap != NULL); }
+
+  Splash *getSplash() { return splash; }
+
+  SplashBitmap *getBitmap() { return bitmap; }
+
+  virtual SplashPattern *copy() { return new SplashRadialPattern(state, 
shading, sMin, sMax, colorMode); }
+
+  virtual ~SplashRadialPattern();
+
+  virtual GBool getColor(int x, int y, SplashColorPtr c);
+
+  virtual GBool isStatic() { return gFalse; }
+  
+  virtual void getStartCircle(SplashCoord *x0, SplashCoord *y0, SplashCoord 
*radius, SplashColorPtr c);
+  virtual GBool getNextCircle(SplashCoord *x0, SplashCoord *y0, SplashCoord 
*radius, SplashColorPtr c);
+  virtual GBool getLargerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c);
+  virtual GBool getNextLargerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, GBool fExtend); 
+  virtual GBool getSmallerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c, GBool fExtend); 
+  virtual GBool getNextSmallerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, GBool fExtend); 
+  virtual GBool enlargeCircles() { return r1 > r0; }
+private:
+  GfxRadialShading *shading;
+  GfxState *state;
+  Matrix ictm;
+  double sMin, sMax;
+  double xMin, xMax, yMin, yMax;
+  double scale;
+  double xa, ya, ra, ta, sa;
+  int ia;
+  int maxSplits;
+  double x0, y0, r0, x1, y1, r1, t0, t1;
+  Splash *splash;
+  SplashBitmap *bitmap;
+  SplashColorMode colorMode;
+};
+
 //------------------------------------------------------------------------
 
 // number of Type 3 fonts to cache
@@ -132,7 +175,7 @@ public:
   // radialShadedFill()?  If this returns false, these shaded fills
   // will be reduced to a series of other drawing operations.
   virtual GBool useShadedFills(int type)
-  { return (type == 2 || type == 4 || type == 5 ) ? gTrue : gFalse; }
+  { return (type >= 2 && type <= 5) ? gTrue : gFalse; }
 
   // Does this device use upside-down coordinates?
   // (Upside-down means (0,0) is the top left corner of the page.)
@@ -186,6 +229,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 radialShadedFill(GfxState *state, GfxRadialShading *shading, 
double sMin, double sMax);
   virtual GBool gouraudTriangleShadedFill(GfxState *state, 
GfxGouraudTriangleShading *shading);
 
   //----- path clipping
diff --git a/splash/Splash.cc b/splash/Splash.cc
index bc317a6..f5c2f7b 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -272,10 +272,16 @@ inline void Splash::pipeRun(SplashPipe *pipe) {
           pipe->destColorPtr += 4;
         break;
       }
+         if (state->softMask) {
+                 pipe->softMaskPtr++;
+         }
       if (pipe->destAlphaPtr) {
         ++pipe->destAlphaPtr;
       }
-      ++pipe->x;
+      if (pipe->alpha0Ptr) {
+                 pipe->alpha0Ptr++;
+         }
+         ++pipe->x;
       return;
     }
   }
@@ -3531,6 +3537,336 @@ GBool 
Splash::gouraudTriangleShadedFill(SplashGouraudColor *shading)
   return gTrue;
 }
 
+SplashPath *Splash::getBresenhamPoints(SplashCoord xc, SplashCoord yc, 
SplashCoord rc) {
+  int radius = splashRound(rc);
+  int x0 = splashRound(xc);
+  int y0 = splashRound(yc);
+  int f = 1 - radius;
+  int ddF_x = 1;
+  int ddF_y = -2 * radius;
+  int x = 0, lastX = x;
+  int y = radius, lastY = y;
+  Guchar dummy;
+  SplashPath *splashPath = new SplashPath();
+  
+  if (radius == 0) {
+         splashPath->moveTo(lastX, lastY);
+         return splashPath;
+  }
+ 
+  while(x < y)
+  {
+    if(f >= 0) 
+    {
+      y--;
+      ddF_y += 2;
+      f += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f += ddF_x;   
+       if (lastY != y) {
+               if (splashPath->getLength())
+                       splashPath->lineTo(lastX, lastY);
+               else
+                       splashPath->moveTo(lastX, lastY);
+               lastY = y;
+       }
+       lastX = x;
+  }
+  for (int i = splashPath->getLength() -1; i >= 0; i--) {
+         SplashCoord curX, curY;
+         splashPath->getPoint(i, &curY, &curX, &dummy);
+         for (SplashCoord j = lastY; j >= curY; j--)
+                 splashPath->lineTo(curX, j);
+         lastY = splashRound(curY - 1);
+  }
+  while (lastY >= 0)
+         splashPath->lineTo(rc, lastY--);
+  return splashPath;
+}      
+
+static inline void getBCircleLine(SplashPath *bresPoints, SplashCoord y, 
SplashCoord y0, SplashCoord r, SplashCoord *x) {
+       SplashCoord curX, curY;
+       Guchar dummy;
+       int i = (y > y0) ? splashRound(r - (y - y0)) : splashRound(r - (y0 - 
y));
+       if (i < bresPoints->getLength()) {
+               bresPoints->getPoint(i, &curX, &curY, &dummy);
+               *x = curX;
+       }
+}
+
+void Splash::drawPartCircleLine(SplashPipe *pipe, 
+                                                                  SplashCoord 
y, 
+                                                                  SplashCoord 
xMin, SplashCoord xMax) {
+       int yI, xmaxI, xminI;
+       int height = bitmap->getHeight();
+       int width = bitmap->getWidth();
+       Guchar *bitmapAlpha = bitmap->getAlphaPtr();
+       yI = splashRound(y);
+       xmaxI = splashRound(xMax);
+       xminI = splashRound(xMin);
+       if (yI >= 0 && yI < height && xMax >= 0) {
+               if (xminI < 0) 
+                       xminI = 0;
+               if (xminI < width) {
+                       if (xmaxI > width - 1) 
+                               xmaxI = width - 1;
+                       drawSpan(pipe, xminI, xmaxI, yI, gTrue);
+               }
+       }
+}
+
+void Splash::drawBCircleLine(SplashPipe *pipe, SplashPath *bresInnerPoints,
+                                                                  SplashCoord 
y, SplashCoord yiMin, SplashCoord yiMax,
+                                                                  SplashCoord 
yi, SplashCoord xi, SplashCoord iradius,
+                                                                  SplashCoord 
xMin, SplashCoord xMax, int lineWidth) {
+       if (y > yiMax || y < yiMin)
+               drawPartCircleLine(pipe, y, xMin, xMax);
+       else {
+               SplashCoord xiMin, xiMax;
+               getBCircleLine(bresInnerPoints, y, yi, iradius, &xiMin);
+               xiMax = xi + xiMin;
+               xiMin = xi - xiMin;
+               if (xiMin >= xMin || xiMax <= xMax) {
+                       if (xiMax < xMin || xiMin > xMax)
+                               drawPartCircleLine(pipe, y, xMin, xMax);
+                       else if (xiMin <= xMin && xiMax < xMax) {
+                               if (xiMin != xMin)
+                                       drawPartCircleLine(pipe, y, xMin, xMin 
+ lineWidth);
+                               drawPartCircleLine(pipe, y, (xMax - xiMax > 
lineWidth) ? xiMax : xMax - lineWidth, xMax);
+                       } else if (xiMin >= xMin && xiMax <= xMax) {
+                               if (xiMin != xMin)
+                                       drawPartCircleLine(pipe, y, xMin, 
(xiMin - xMin > lineWidth) ? xiMin : xMin + lineWidth);
+                               drawPartCircleLine(pipe, y, (xMax - xiMax > 
lineWidth) ? xiMax : xMax - lineWidth, xMax);
+                       } else {
+                               if (xiMin != xMin)
+                                       drawPartCircleLine(pipe, y, xMin, 
(xiMin - xMin > lineWidth) ? xiMin : xMin + lineWidth);
+                               drawPartCircleLine(pipe, y, xMax - lineWidth, 
xMax);
+                       }
+               }
+       }
+}
+
+SplashPath *Splash::drawCircle(SplashCoord xo, SplashCoord yo, SplashCoord 
oradius, SplashColorPtr cur, SplashPath *bresOuterPoints,
+                                               SplashCoord xi, SplashCoord yi, 
SplashCoord iradius, SplashColorPtr curNext, GBool fExtend, 
+                                               SplashPipe *pipe) {
+       SplashPath *bresInnerPoints = getBresenhamPoints(xi, yi, iradius);
+       if (bresInnerPoints == NULL)
+               return bresInnerPoints;
+
+       if (!fExtend) {
+               SplashCoord yiMax = yi + iradius, yiMin = yi - iradius;
+               SplashCoord yoMax = yo + oradius, yoMin = yo - oradius;
+               Guchar dummy;
+               int lineWidth = splashRound(oradius - iradius);
+               if (lineWidth > 3) lineWidth = 3;
+               // draw upper half
+               int startPoint = 0;
+               if (yoMax >= bitmap->getHeight()) {
+                       startPoint = splashRound(yoMax - bitmap->getHeight() + 
1);
+               }
+               int endPoint = startPoint + bitmap->getHeight();
+               if (endPoint > bresOuterPoints->getLength())
+                       endPoint = bresOuterPoints->getLength();
+               for (int i = startPoint; i < endPoint; i++) {
+                       SplashCoord curX, curY;
+                       SplashCoord xMin, xMax;
+                       bresOuterPoints->getPoint(i, &curX, &curY, &dummy);
+                       xMax = xo + curX;
+                       xMin = xo - curX;
+                       curY = yo + curY;
+                       drawBCircleLine(pipe, bresInnerPoints,
+                               curY, yiMin, yiMax, yi, xi, iradius, xMin, 
xMax, lineWidth);
+               }
+               // draw lower half
+               endPoint = splashRound(bitmap->getHeight() - yoMin);
+               startPoint = endPoint - bitmap->getHeight();
+               if (endPoint > bresOuterPoints->getLength())
+                       endPoint = bresOuterPoints->getLength();
+               if (startPoint < 0)
+                       startPoint = 0;
+               for (int i = startPoint; i < endPoint; i++) {
+                       SplashCoord curX, curY;
+                       SplashCoord xMin, xMax;
+                       bresOuterPoints->getPoint(i, &curX, &curY, &dummy);
+                       xMax = xo + curX;
+                       xMin = xo - curX;
+                       curY = yo - curY;
+                       drawBCircleLine(pipe, bresInnerPoints,
+                               curY, yiMin, yiMax, yi, xi, iradius, xMin, 
xMax, lineWidth);
+               }
+               splashColorCopy(cur, curNext);
+       } else {
+               SplashCoord yoMax = yo + oradius, yoMin = yo - oradius;
+               SplashCoord yiMax = yi + iradius, yiMin = yi - iradius;
+               Guchar dummy;
+               int lineWidth = splashRound(iradius - oradius);
+               if (lineWidth > 3) lineWidth = 3;
+               splashColorCopy(cur, curNext);
+               // draw upper half
+               int startPoint = 0;
+               if (yiMax >= bitmap->getHeight()) {
+                       startPoint = splashRound(yiMax - bitmap->getHeight() + 
1);
+               }
+               int endPoint = startPoint + bitmap->getHeight();
+               if (endPoint > bresInnerPoints->getLength())
+                       endPoint = bresInnerPoints->getLength();
+               for (int i = startPoint; i < endPoint; i++) {
+                       SplashCoord curX, curY;
+                       SplashCoord xMin, xMax;
+                       bresInnerPoints->getPoint(i, &curX, &curY, &dummy);
+                       xMax = xi + curX;
+                       xMin = xi - curX;
+                       curY = yi + curY;
+                       drawBCircleLine(pipe, bresOuterPoints,
+                               curY, yoMin, yoMax, yo, xo, oradius, xMin, 
xMax, lineWidth);
+               }
+               // draw lower half
+               endPoint = splashRound(bitmap->getHeight() - yiMin);
+               startPoint = endPoint - bitmap->getHeight();
+               if (endPoint > bresInnerPoints->getLength())
+                       endPoint = bresInnerPoints->getLength();
+               if (startPoint < 0)
+                       startPoint = 0;
+               for (int i = startPoint; i < endPoint; i++) {
+                       SplashCoord curX, curY;
+                       SplashCoord xMin, xMax;
+                       bresInnerPoints->getPoint(i, &curX, &curY, &dummy);
+                       xMax = xi + curX;
+                       xMin = xi - curX;
+                       curY = yi - curY;
+                       drawBCircleLine(pipe, bresOuterPoints,
+                               curY, yoMin, yoMax, yo, xo, oradius, xMin, 
xMax, lineWidth);
+               }
+       }
+       return bresInnerPoints;
+}
+
+SplashError Splash::radialShadedFill(SplashRadialColor *shading) {
+       SplashPipe pipe;
+       SplashColor cSrcVal, cNextVal;
+       SplashColorPtr cur = cSrcVal, curNext = cNextVal;
+       SplashCoord xo, yo, oradius;
+       SplashCoord xi, yi, iradius;
+       GBool fExtend = shading->enlargeCircles();
+       
+       pipeInit(&pipe, 0, 0, NULL, cSrcVal, state->strokeAlpha, gFalse, 
gFalse);
+       pipe.cSrc = cur;
+       
+       // extend starting circle
+       if (fExtend && shading->getSmallerExtendCircle(&xo, &yo, &oradius, cur, 
fExtend)) {
+               SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, 
oradius);
+               if (bresOuterPoints == NULL)
+                       return splashErrEmptyPath;
+               while (shading->getNextSmallerExtendCircle(&xi, &yi, &iradius, 
fExtend)) {
+                       if (xi == xo && yi == yo && iradius == oradius) {
+                               continue;
+                       }
+                       SplashPath *bresInnerPoints = drawCircle(xo, yo, 
oradius, cur, bresOuterPoints,
+                               xi, yi, iradius, cur, fExtend, &pipe);
+                       if (bresInnerPoints == NULL)
+                               break;
+                       delete bresOuterPoints;
+                       bresOuterPoints = bresInnerPoints;
+                       yo = yi; xo = xi; oradius = iradius;
+               }
+               delete bresOuterPoints;
+       }
+       if (!fExtend && shading->getLargerExtendCircle(&xo, &yo, &oradius, 
cur)) {
+               SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, 
oradius);
+               if (bresOuterPoints == NULL)
+                       return splashErrEmptyPath;
+               // start with filling the circle
+               SplashCoord xMin, xMax;
+               Guchar dummy;
+               for (int i = 0; i < bresOuterPoints->getLength(); i++) {
+                       SplashCoord curX, curY;
+                       bresOuterPoints->getPoint(i, &curX, &curY, &dummy);
+                       curY += yo;
+                       xMax = xo + curX;
+                       xMin = xo - curX;
+                       if (curY >= 0 && curY < bitmap->getHeight())
+                               drawPartCircleLine(&pipe, curY, xMin, xMax);
+                       curY = 2 * yo - curY;
+                       if (curY >= 0 && curY < bitmap->getHeight())
+                               drawPartCircleLine(&pipe, curY, xMin, xMax);
+               }
+               while (shading->getNextLargerExtendCircle(&xi, &yi, &iradius, 
fExtend)) {
+                       if (xi == xo && yi == yo && iradius == oradius) {
+                               continue;
+                       }
+                       SplashPath *bresInnerPoints = drawCircle(xo, yo, 
oradius, cur, bresOuterPoints,
+                               xi, yi, iradius, cur, gTrue, &pipe);
+                       if (bresInnerPoints == NULL)
+                               break;
+                       delete bresOuterPoints;
+                       bresOuterPoints = bresInnerPoints;
+                       yo = yi; xo = xi; oradius = iradius;
+               }
+               delete bresOuterPoints;
+       }
+
+       shading->getStartCircle(&xo, &yo, &oradius, cur);
+       SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, oradius);
+       if (bresOuterPoints == NULL)
+               return splashErrEmptyPath;
+       while (shading->getNextCircle(&xi, &yi, &iradius, curNext)) {
+               if (xi == xo && yi == yo && iradius == oradius) {
+                       splashColorCopy(cur, curNext);
+                       continue;
+               }
+               SplashPath *bresInnerPoints = drawCircle(xo, yo, oradius, cur, 
bresOuterPoints,
+                       xi, yi, iradius, curNext, fExtend, &pipe);
+               if (bresInnerPoints == NULL)
+                       break;
+               delete bresOuterPoints;
+               bresOuterPoints = bresInnerPoints;
+               yo = yi; xo = xi; oradius = iradius;
+       } 
+       delete bresOuterPoints;
+
+       // extend ending circle
+       if (!fExtend && shading->getSmallerExtendCircle(&xo, &yo, &oradius, 
cur, fExtend)) {
+               SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, 
oradius);
+               if (bresOuterPoints == NULL)
+                       return splashErrEmptyPath;
+               while (shading->getNextSmallerExtendCircle(&xi, &yi, &iradius, 
fExtend)) {
+                       if (xi == xo && yi == yo && iradius == oradius) {
+                               continue;
+                       }
+                       SplashPath *bresInnerPoints = drawCircle(xo, yo, 
oradius, cur, bresOuterPoints,
+                               xi, yi, iradius, cur, fExtend, &pipe);
+                       if (bresInnerPoints == NULL)
+                               break;
+                       delete bresOuterPoints;
+                       bresOuterPoints = bresInnerPoints;
+                       yo = yi; xo = xi; oradius = iradius;
+               }
+               delete bresOuterPoints;
+       }
+       if (fExtend && shading->getLargerExtendCircle(&xo, &yo, &oradius, cur)) 
{
+               SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, 
oradius);
+               if (bresOuterPoints == NULL)
+                       return splashErrEmptyPath;
+               // don't fill the circle here, just extend:
+               while (shading->getNextLargerExtendCircle(&xi, &yi, &iradius, 
gTrue)) {
+                       if (xi == xo && yi == yo && iradius == oradius) {
+                               continue;
+                       }
+                       SplashPath *bresInnerPoints = drawCircle(xo, yo, 
oradius, cur, bresOuterPoints,
+                               xi, yi, iradius, cur, gTrue, &pipe);
+                       if (bresInnerPoints == NULL)
+                               break;
+                       delete bresOuterPoints;
+                       bresOuterPoints = bresInnerPoints;
+                       yo = yi; xo = xi; oradius = iradius;
+               }
+               delete bresOuterPoints;
+       }
+       return splashOk;
+}
+
 SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
                                    int xDest, int yDest, int w, int h) {
   SplashColor pixel;
@@ -3950,19 +4286,25 @@ SplashError Splash::shadedFill(SplashPath *path, GBool 
hasBBox,
   int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
   SplashClipResult clipRes;
 
-  if (aaBuf == NULL) { // should not happen, but to be secure
+  if (vectorAntialias && aaBuf == NULL) { // should not happen, but to be 
secure
     return splashErrGeneric;
   }
   if (path->length == 0) {
     return splashErrEmptyPath;
   }
   xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);
-  xPath->aaScale();
+  if (vectorAntialias) {
+    xPath->aaScale();
+  }
   xPath->sort();
   scanner = new SplashXPathScanner(xPath, gFalse);
 
-  // get the min and max x and y values
-  scanner->getBBoxAA(&xMinI, &yMinI, &xMaxI, &yMaxI);
+  // get the min and max x and y values
+  if (vectorAntialias) {
+    scanner->getBBoxAA(&xMinI, &yMinI, &xMaxI, &yMaxI);
+  } else {
+    scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);
+  }
 
   // check clipping
   if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI)) != 
splashClipAllOutside) {
@@ -3977,13 +4319,34 @@ SplashError Splash::shadedFill(SplashPath *path, GBool 
hasBBox,
     pipeInit(&pipe, 0, yMinI, pattern, NULL, state->fillAlpha, vectorAntialias 
&& !hasBBox, gFalse);
 
     // draw the spans
-    for (y = yMinI; y <= yMaxI; ++y) {
-      scanner->renderAALine(aaBuf, &x0, &x1, y);
-      if (clipRes != splashClipAllInside) {
-        state->clip->clipAALine(aaBuf, &x0, &x1, y);
-      }
-      drawAALine(&pipe, x0, x1, y);
-    }
+    if (vectorAntialias) {
+               for (y = yMinI; y <= yMaxI; ++y) {
+                       scanner->renderAALine(aaBuf, &x0, &x1, y);
+                       if (clipRes != splashClipAllInside) {
+                               state->clip->clipAALine(aaBuf, &x0, &x1, y);
+                       }
+                       drawAALine(&pipe, x0, x1, y);
+               }
+       } else {
+               SplashClipResult clipRes2;
+               for (y = yMinI; y <= yMaxI; ++y) {
+                       while (scanner->getNextSpan(y, &x0, &x1)) {
+                               if (clipRes == splashClipAllInside) {
+                                       drawSpan(&pipe, x0, x1, y, gTrue);
+                               } else {
+                                       // limit the x range
+                                       if (x0 < state->clip->getXMinI()) {
+                                               x0 = state->clip->getXMinI();
+                                       }
+                                       if (x1 > state->clip->getXMaxI()) {
+                                               x1 = state->clip->getXMaxI();
+                                       }
+                                       clipRes2 = state->clip->testSpan(x0, 
x1, y);
+                                       drawSpan(&pipe, x0, x1, y, clipRes2 == 
splashClipAllInside);
+                               }
+                       }
+               }
+       }
   }
   opClipRes = clipRes;
 
diff --git a/splash/Splash.h b/splash/Splash.h
index a52dc13..a06f694 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -255,6 +255,17 @@ public:
                          SplashPattern *pattern);
   // Draw a gouraud triangle shading.
   GBool gouraudTriangleShadedFill(SplashGouraudColor *shading);
+  // Draw a radial shading.
+  void drawPartCircleLine(SplashPipe *pipe, SplashCoord y, SplashCoord xMin, 
SplashCoord xMax);
+  void drawBCircleLine(SplashPipe *pipe, SplashPath *bresInnerPoints,
+                                          SplashCoord y, SplashCoord yiMin, 
SplashCoord yiMax,
+                                          SplashCoord yi, SplashCoord xi, 
SplashCoord iradius,
+                                          SplashCoord xMin, SplashCoord xMax, 
int lineWidth);
+  SplashPath *getBresenhamPoints(SplashCoord x0, SplashCoord y0, SplashCoord 
radius);
+  SplashPath *drawCircle(SplashCoord xo, SplashCoord yo, SplashCoord oradius, 
SplashColorPtr cur, 
+                                               SplashPath *bresOuterPoints, 
SplashCoord xi, SplashCoord yi, SplashCoord iradius, 
+                                               SplashColorPtr curNext, GBool 
fExtend, SplashPipe *pipe);
+  SplashError radialShadedFill(SplashRadialColor *shading);
 
 private:
 
diff --git a/splash/SplashPattern.h b/splash/SplashPattern.h
index 09e9b1a..02cc18d 100644
--- a/splash/SplashPattern.h
+++ b/splash/SplashPattern.h
@@ -28,6 +28,8 @@
 #include "SplashTypes.h"
 
 class SplashScreen;
+class Splash;
+class SplashBitmap;
 
 //------------------------------------------------------------------------
 // SplashPattern
@@ -92,4 +94,22 @@ public:
   virtual void getParameterizedColor(double t, SplashColorMode mode, 
SplashColorPtr c) = 0;
 };
 
+//------------------------------------------------------------------------
+// SplashRadialColor (needed for radialShadedFill)
+//------------------------------------------------------------------------
+
+class SplashRadialColor: public SplashPattern {
+public:
+       virtual void getStartCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c) = 0;
+       virtual GBool getNextCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c) = 0;
+       virtual GBool getSmallerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c, GBool fExtend) = 0;
+       virtual GBool getNextSmallerExtendCircle(SplashCoord *x0, SplashCoord 
*y0, SplashCoord *radius, GBool fExtend) = 0;
+       virtual GBool getLargerExtendCircle(SplashCoord *x0, SplashCoord *y0, 
SplashCoord *radius, SplashColorPtr c) = 0;
+       virtual GBool getNextLargerExtendCircle(SplashCoord *x0, SplashCoord 
*y0, SplashCoord *radius, GBool fExtend) = 0;
+       virtual GBool enlargeCircles() = 0;
+       virtual GBool isOk() = 0;
+       virtual Splash *getSplash() = 0;
+       virtual SplashBitmap *getBitmap() = 0;
+};
+
 #endif
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to