+
+void GFXOutputDev::transformXY(GfxState*state, double x, double y, double*nx, double*ny)
+{
+ state->transform(x,y,nx,ny);
+ *nx += user_movex + clipmovex;
+ *ny += user_movey + clipmovey;
+}
+
+
+#if (xpdfMajorVersion*10000 + xpdfMinorVersion*100 + xpdfUpdateVersion) < 30207
+void GFXOutputDev::tilingPatternFill(GfxState *state, Object *str,
+ int paintType, Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep)
+#else
+void GFXBitmapOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Object *str,
+ int paintType, Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep)
+#endif
+{
+ msg("<debug> tilingPatternFill");
+ infofeature("tiling pattern fills");
+}
+
+GBool GFXOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading)
+{
+ msg("<error> functionShadedFill not supported yet");
+ infofeature("function shaded fills");
+ return gFalse;
+}
+static gfxcolor_t col2col(GfxColorSpace*colspace, GfxColor* col)
+{
+ gfxcolor_t c;
+ GfxRGB rgb;
+ colspace->getRGB(col, &rgb);
+ c.r = colToByte(rgb.r);
+ c.g = colToByte(rgb.g);
+ c.b = colToByte(rgb.b);
+ c.a = 255;
+ return c;
+}
+
+GBool GFXOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading)
+{
+ double x0,y0,r0,x1,y1,x2,y2,x9,y9,r1;
+ shading->getCoords(&x0,&y0,&r0,&x9,&y9,&r1);
+ x1=x0+r1;y1=y0;
+ x2=x0; y2=y0+r1;
+ this->transformXY(state, x0,y0, &x0,&y0);
+ this->transformXY(state, x1,y1, &x1,&y1);
+ this->transformXY(state, x2,y2, &x2,&y2);
+
+ GfxColor color0;
+ GfxColor color1;
+ GfxColor color2;
+ shading->getColor(0.0, &color0);
+ shading->getColor(0.5, &color1);
+ shading->getColor(1.0, &color2);
+
+ GfxColorSpace* colspace = shading->getColorSpace();
+
+ msg("<verbose> radialShadedFill %f %f %f %f %f %f %02x%02x%02x->%02x%02x%02x", x0, y0, x1, y1, x2, y2,
+ colToByte(color0.c[0]), colToByte(color0.c[1]), colToByte(color0.c[2]),
+ colToByte(color1.c[0]), colToByte(color1.c[1]), colToByte(color1.c[2]),
+ colToByte(color2.c[0]), colToByte(color2.c[1]), colToByte(color2.c[2]));
+ infofeature("radial shaded fills");
+
+ gfxgradient_t*g = (gfxgradient_t*)malloc(sizeof(gfxgradient_t)*3);
+ g[0].next = &g[1];
+ g[1].next = &g[2];
+ g[2].next = 0;
+ g[0].color = col2col(colspace, &color0);
+ g[1].color = col2col(colspace, &color1);
+ g[2].color = col2col(colspace, &color2);
+ g[0].pos = 0.0;
+ g[1].pos = 0.5;
+ g[2].pos = 1.0;
+
+ gfxbbox_t b = states[statepos].clipbbox;
+ gfxline_t p1,p2,p3,p4,p5;
+ p1.type=gfx_moveTo;p1.x=b.xmin; p1.y=b.ymin; p1.next=&p2;
+ p2.type=gfx_lineTo;p2.x=b.xmin; p2.y=b.ymax; p2.next=&p3;
+ p3.type=gfx_lineTo;p3.x=b.xmax; p3.y=b.ymax; p3.next=&p4;
+ p4.type=gfx_lineTo;p4.x=b.xmax; p4.y=b.ymin; p4.next=&p5;
+ p5.type=gfx_lineTo;p5.x=b.xmin; p5.y=b.ymin; p5.next=0;
+
+ gfxmatrix_t m;
+ //m.m00 = (x3-x0); m.m10 = (x1-x0);
+ //m.m01 = (y3-y0); m.m11 = (y1-y0);
+ //x3/y3 specifies another (the ending) circle, not the second radius of an ellipse
+ m.m00 = (x1-x0); m.m10 = (x2-x0);
+ m.m01 = (y1-y0); m.m11 = (y2-y0);
+ m.tx = x0 - 0.5;
+ m.ty = y0 - 0.5;
+
+ device->fillgradient(device, &p1, g, gfxgradient_radial, &m);
+ return gTrue;
+}
+
+GBool GFXOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading)
+{
+ double x0,y0,x1,y1;
+ shading->getCoords(&x0,&y0,&x1,&y1);
+ this->transformXY(state, x0,y0,&x0,&y0);
+ this->transformXY(state, x1,y1,&x1,&y1);
+
+ GfxColor color0;
+ GfxColor color1;
+ GfxColor color2;
+ shading->getColor(0.0, &color0);
+ shading->getColor(0.5, &color1);
+ shading->getColor(1.0, &color2);
+
+ GfxColorSpace* colspace = shading->getColorSpace();
+
+ msg("<verbose> axialShadedFill %f %f %f %f %02x%02x%02x->%02x%02x%02x->%02x%02x%02x", x0, y0, x1, y1,
+ colToByte(color0.c[0]), colToByte(color0.c[1]), colToByte(color0.c[2]),
+ colToByte(color1.c[0]), colToByte(color1.c[1]), colToByte(color1.c[2]),
+ colToByte(color2.c[0]), colToByte(color2.c[1]), colToByte(color2.c[2])
+ );
+ infofeature("axial shaded fills");
+
+ gfxgradient_t*g = (gfxgradient_t*)malloc(sizeof(gfxgradient_t)*3);
+ g[0].next = &g[1];
+ g[1].next = &g[2];
+ g[2].next = 0;
+ g[0].color = col2col(colspace, &color0);
+ g[1].color = col2col(colspace, &color1);
+ g[2].color = col2col(colspace, &color2);
+ g[0].pos = 0.0;
+ g[1].pos = 0.5;
+ g[2].pos = 1.0;
+
+ double xMin,yMin,xMax,yMax;
+ state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+ this->transformXY(state, xMin, yMin, &xMin, &yMin);
+ msg("<verbose> userClipBox %f %f %f %f", xMin, yMin, xMax, yMax);
+
+ xMin = 0; yMin = 0;
+ xMin = 1024; yMin = 1024;
+
+ gfxbbox_t b = states[statepos].clipbbox;
+ gfxline_t p1,p2,p3,p4,p5;
+ p1.type=gfx_moveTo;p1.x=b.xmin; p1.y=b.ymin; p1.next=&p2;
+ p2.type=gfx_lineTo;p2.x=b.xmin; p2.y=b.ymax; p2.next=&p3;
+ p3.type=gfx_lineTo;p3.x=b.xmax; p3.y=b.ymax; p3.next=&p4;
+ p4.type=gfx_lineTo;p4.x=b.xmax; p4.y=b.ymin; p4.next=&p5;
+ p5.type=gfx_lineTo;p5.x=b.xmin; p5.y=b.ymin; p5.next=0;
+
+ /* the gradient starts at (-1.0,0.0), so move (0,0) to
+ the middle of the two control points */
+ gfxmatrix_t m;
+ m.m00 = (x1-x0)/2; m.m10 = -(y1-y0)/2;
+ m.m01 = (y1-y0)/2; m.m11 = (x1-x0)/2;
+ m.tx = (x0 + x1)/2 - 0.5;
+ m.ty = (y0 + y1)/2 - 0.5;
+
+ device->fillgradient(device, &p1, g, gfxgradient_linear, &m);
+ return gTrue;
+}