diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 0b3722a..65e4117 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -153,6 +153,257 @@ void SplashGouraudPattern::getParameterizedColor(double colorinterp, SplashColor
 }
 
 //------------------------------------------------------------------------
+// SplashRadialPattern
+//------------------------------------------------------------------------
+// Max number of splits along the t axis for a radial shading fill.
+#define radialMaxSplits 256
+
+// 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;
+  sMin = sMinA;
+  sMax = sMaxA;
+  colorMode = colorModeA;
+  state->getCTM(&ctm);
+  ctm.invertTo(&ictm);
+  ia = 0;
+  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 (radialMaxSize > 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;
+  bitmap = new SplashBitmap(splashRound(width), splashRound(height), 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;
+}
+
+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);
+  if (xs < 0 || xs >= bitmap->getWidth())
+	  return gFalse;
+  if (ys < 0 || ys >= bitmap->getHeight())
+	  return gFalse;
+  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();
+  sa = (r0 > r1) ? sMin : sMax;
+  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 >= radialMaxSplits)
+	  return gFalse;
+  getShadingColorRadialHelper(t0, t1, ta, shading, &colorA);
+  ib = radialMaxSplits;
+  sb = (r0 > r1) ? 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 = (r0 > r1) ? (double)ic / (double)radialMaxSplits : 1 - (double)ic / (double)radialMaxSplits; 
+			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 = (r0 > r1) ? (double)ib / (double)radialMaxSplits : 1 - (double)ib / (double)radialMaxSplits; 
+		  sb = sMin + factor * (sMax - sMin);
+		  tb = t0 + sb * (t1 - t0);
+		  getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
+		  break;
+      }
+      ib = (ia + ib) / 2;
+	  factor = (r0 > r1) ? (double)ib / (double)radialMaxSplits : 1 - (double)ib / (double)radialMaxSplits; 
+      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);
+		  return gTrue;
+  }
+  return gFalse;
+}
+
+GBool SplashRadialPattern::getSmallerExtendCircle(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);
+		  return gTrue;
+  }
+  return gFalse;
+}
+//------------------------------------------------------------------------
 // SplashAxialPattern
 //------------------------------------------------------------------------
 
@@ -3379,3 +3630,38 @@ 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 vaa = getVectorAntialias();
+  GBool retVal = gFalse;
+  // restore vector antialias because we support it here
+  setVectorAntialias(gTrue);
+  // 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);
+  }
+  setVectorAntialias(vaa);
+  state->clearPath();
+  delete pattern;
+  delete path;
+
+  return retVal;
+}
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index 570d036..1e243c2 100644
--- a/poppler/SplashOutputDev.h
+++ b/poppler/SplashOutputDev.h
@@ -105,6 +105,45 @@ 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 getSmallerExtendCircle(SplashCoord *x0, SplashCoord *y0, SplashCoord *radius, SplashColorPtr c);
+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;
+  double x0, y0, r0, x1, y1, r1, t0, t1;
+  Splash *splash;
+  SplashBitmap *bitmap;
+  SplashColorMode colorMode;
+};
+
 //------------------------------------------------------------------------
 
 // number of Type 3 fonts to cache
@@ -132,7 +171,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 +225,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..98178d9 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -3531,6 +3531,257 @@ 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)
+  {
+    // ddF_x == 2 * x + 1;
+    // ddF_y == -2 * y;
+    // f == x*x + y*y - radius*radius + 2*x - y + 1;
+    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 getBEllipseLine(SplashPath *bresPoints, SplashCoord y, SplashCoord y0, SplashCoord r, SplashCoord *x) {
+	GBool found = gFalse;
+	if (y == y0)
+		*x = r;
+	else if (y > y0) {
+		SplashCoord curX, curY;
+		Guchar dummy;
+		for (int i = 0; i < bresPoints->getLength(); i++) { 
+			bresPoints->getPoint(i, &curX, &curY, &dummy);
+			if (curY + y0 == y) {
+				*x = curX;
+				return;
+			} 
+		}
+	} else {
+		SplashCoord curX, curY;
+		Guchar dummy;
+		for (int i = bresPoints->getLength() - 1; i >= 0; i--) { 
+			bresPoints->getPoint(i, &curX, &curY, &dummy);
+			if (y0 - curY == y) {
+				*x = curX;
+				return;
+			} 
+		}
+	}
+}
+
+void Splash::drawPartEllipseLine(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) {
+		if (xminI < 0) 
+			xminI = 0;
+		if (xminI < width) {
+			if (xmaxI > width - 1) 
+				xmaxI = width - 1;
+			drawSpan(pipe, xminI, xmaxI, yI, gTrue);
+		}
+	}
+}
+
+void Splash::drawBEllipseLine(SplashPipe *pipe, SplashPath *bresInnerPoints,
+								   SplashCoord y, SplashCoord yiMin, SplashCoord yiMax,
+								   SplashCoord yi, SplashCoord xi, SplashCoord iradius,
+								   SplashCoord xMin, SplashCoord xMax) {
+	if (y > yiMax || y < yiMin)
+		drawPartEllipseLine(pipe, y, xMin, xMax);
+	else {
+		SplashCoord xiMin, xiMax;
+		getBEllipseLine(bresInnerPoints, y, yi, iradius, &xiMin);
+		xiMax = xi + xiMin;
+		xiMin = xi - xiMin;
+		if (xiMin >= xMin || xiMax <= xMax) {
+			if (xiMax < xMin || xiMin > xMax)
+				drawPartEllipseLine(pipe, y, xMin - 1, xMax + 1);
+			else if (xiMin < xMin && xiMax < xMax)
+				drawPartEllipseLine(pipe, y, xiMax - 1, xMax + 1);
+			else if (xiMin > xMin && xiMax < xMax) {
+				drawPartEllipseLine(pipe, y, xMin - 1, xiMin + 1);
+				drawPartEllipseLine(pipe, y, xiMax - 1, xMax + 1);
+			} else
+				drawPartEllipseLine(pipe, y, xMin - 1, xiMin + 1);
+		}
+	}
+}
+
+SplashError Splash::radialShadedFill(SplashRadialColor *shading) {
+	SplashPipe pipe;
+	SplashColor cSrcVal, cNextVal;
+	SplashColorPtr cur = cSrcVal, curNext = cNextVal;
+
+	pipeInit(&pipe, 0, 0, NULL, cSrcVal, state->strokeAlpha, gFalse, gFalse);
+	
+	SplashCoord xo, yo, oradius;
+	SplashCoord xi, yi, iradius;
+	shading->getStartCircle(&xo, &yo, &oradius, cur);
+	SplashPath *bresOuterPoints = getBresenhamPoints(xo, yo, oradius);
+	if (bresOuterPoints == NULL)
+		return splashErrEmptyPath;
+	pipe.cSrc = cur;
+	while (shading->getNextCircle(&xi, &yi, &iradius, curNext)) {
+		if (xi == xo && yi == yo && iradius == oradius) {
+			splashColorCopy(cur, curNext);
+			continue;
+		}
+		SplashPath *bresInnerPoints = getBresenhamPoints(xi, yi, iradius);
+		if (bresInnerPoints == NULL)
+			break;
+		SplashCoord yiMax = yi + iradius, yiMin = yi - iradius;
+		Guchar dummy;
+
+		for (int i = 0; i < bresOuterPoints->getLength(); i++) {
+			SplashCoord curX, curY;
+			SplashCoord xMin, xMax;
+			bresOuterPoints->getPoint(i, &curX, &curY, &dummy);
+			xMax = xo + curX;
+			xMin = xo - curX;
+			curY += yo;
+			if (curY >= 0 && curY < bitmap->getHeight())
+				drawBEllipseLine(&pipe, bresInnerPoints,
+					curY, yiMin, yiMax, yi, xi, iradius, xMin, xMax);
+			curY = 2 * yo - curY;
+			if (curY >= 0 && curY < bitmap->getHeight())
+				drawBEllipseLine(&pipe, bresInnerPoints,
+					curY, yiMin, yiMax, yi, xi, iradius, xMin, xMax);
+		}
+		delete bresOuterPoints;
+		bresOuterPoints = bresInnerPoints;
+		yo = yi; xo = xi; oradius = iradius;
+		splashColorCopy(cur, curNext);
+	} 
+	delete bresOuterPoints;
+	if (shading->getSmallerExtendCircle(&xo, &yo, &oradius, cur)) {
+		SplashPath *bresPoints = getBresenhamPoints(xo, yo, oradius);
+		if (bresPoints == NULL)
+			goto DrawLarge;
+		SplashCoord xMin, xMax;
+		Guchar dummy;
+		for (int i = 0; i < bresPoints->getLength(); i++) {
+			SplashCoord curX, curY;
+			bresPoints->getPoint(i, &curX, &curY, &dummy);
+			curY += yo;
+			xMax = xo + curX;
+			xMin = xo - curX;
+			if (curY >= 0 && curY < bitmap->getHeight())
+				drawPartEllipseLine(&pipe, curY, xMin, xMax);
+			curY = 2 * yo - curY;
+			if (curY >= 0 && curY < bitmap->getHeight())
+				drawPartEllipseLine(&pipe, 2* yo - curY, xMin, xMax);
+		}
+		delete bresPoints;
+	}
+DrawLarge:
+	if (shading->getLargerExtendCircle(&xo, &yo, &oradius, cur)) {
+		SplashPath *bresPoints = getBresenhamPoints(xo, yo, oradius);
+		if (bresPoints == NULL)
+			goto RadialEnd;
+		SplashCoord xMin, xMax, y;
+		SplashCoord yMin, yMax;
+		yMax = yo + oradius;
+		yMin = yo - oradius;
+		Guchar dummy;
+		int i = 0;
+		if (yMax >= bitmap->getHeight()) {
+			i = splashRound(yMax - bitmap->getHeight() + 1);
+		}
+		if (yo >= bitmap->getHeight()) {
+			i = bresPoints->getLength() - 1 - splashRound(yo - bitmap->getHeight() + 1);
+		}
+		for (y = bitmap->getHeight() - 1; y >= 0; y--) {
+			if (y > yMax || y < yMin)
+				drawPartEllipseLine(&pipe, y, 0, bitmap->getWidth() - 1);
+			else if (y > yo) {
+				SplashCoord curX, curY;
+				bresPoints->getPoint(i++, &curX, &curY, &dummy);
+				xMin = xo - curX;
+				xMax = xo + curX;
+				if (xMin - 1 > 0)
+					drawPartEllipseLine(&pipe, y, 0, xMin + 1);
+				if (xMax + 1  < 0)
+					drawPartEllipseLine(&pipe, y, 0, bitmap->getWidth() - 1);
+				else if (xMax + 1 < bitmap->getWidth())
+					drawPartEllipseLine(&pipe, y, xMax - 1, bitmap->getWidth() - 1);
+			} else if (y == yo) {
+				i = bresPoints->getLength() - 1;
+				xMin = xo - oradius;
+				xMax = xo + oradius;
+				if (xMin - 1 > 0)
+					drawPartEllipseLine(&pipe, y, 0, xMin + 1);
+				if (xMax + 1  < 0)
+					drawPartEllipseLine(&pipe, y, 0, bitmap->getWidth() - 1);
+				else if (xMax + 1 < bitmap->getWidth())
+					drawPartEllipseLine(&pipe, y, xMax - 1, bitmap->getWidth() - 1);
+			} else {
+				SplashCoord curX, curY;
+				bresPoints->getPoint(--i, &curX, &curY, &dummy);
+				xMin = xo - curX;
+				xMax = xo + curX;
+				if (xMin - 1 > 0)
+					drawPartEllipseLine(&pipe, y, 0, xMin + 1);
+				if (xMax + 1  < 0)
+					drawPartEllipseLine(&pipe, y, 0, bitmap->getWidth() - 1);
+				else if (xMax + 1 < bitmap->getWidth())
+					drawPartEllipseLine(&pipe, y, xMax - 1, bitmap->getWidth() - 1);
+			}
+		}
+		delete bresPoints;	
+	}
+RadialEnd:
+	return splashOk;
+}
+
 SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
 				    int xDest, int yDest, int w, int h) {
   SplashColor pixel;
diff --git a/splash/Splash.h b/splash/Splash.h
index a52dc13..37e63f9 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -255,6 +255,14 @@ public:
                          SplashPattern *pattern);
   // Draw a gouraud triangle shading.
   GBool gouraudTriangleShadedFill(SplashGouraudColor *shading);
+  // Draw a radial shading.
+  void drawPartEllipseLine(SplashPipe *pipe, SplashCoord y, SplashCoord xMin, SplashCoord xMax);
+  void drawBEllipseLine(SplashPipe *pipe, SplashPath *bresInnerPoints,
+								   SplashCoord y, SplashCoord yiMin, SplashCoord yiMax,
+								   SplashCoord yi, SplashCoord xi, SplashCoord iradius,
+								   SplashCoord xMin, SplashCoord xMax);
+  SplashPath *getBresenhamPoints(SplashCoord x0, SplashCoord y0, SplashCoord radius);
+  SplashError radialShadedFill(SplashRadialColor *shading);
 
 private:
 
diff --git a/splash/SplashPattern.h b/splash/SplashPattern.h
index 09e9b1a..fb82df2 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,19 @@ 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) = 0;
+	virtual GBool getLargerExtendCircle(SplashCoord *x0, SplashCoord *y0, SplashCoord *radius, SplashColorPtr c) = 0;
+	virtual GBool isOk() = 0;
+	virtual Splash *getSplash() = 0;
+	virtual SplashBitmap *getBitmap() = 0;
+};
+
 #endif
