diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 0bc0ab4..a213613 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -328,6 +328,102 @@ void CairoOutputDev::updateFillOpacity(GfxState *state) { LOG(printf ("fill opacity: %f\n", fill_opacity)); } +GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) { + double x0, y0, x1, y1; + cairo_extend_t extend; + printf("axialShaded\n"); + + if (shading->getExtend0() != shading->getExtend1()) { + printf("non matching extents\n"); + return gFalse; + } else { + extend = shading->getExtend0() ? CAIRO_EXTEND_PAD : CAIRO_EXTEND_NONE; + } + + if (shading->getDomain0() != 0 || shading->getDomain1() != 1) + return gFalse; + + if (shading->getNFuncs() == 1) { + Function *func = shading->getFunc(0); + + if (func->getType() != 2) { + printf("wrong function type\n"); + return gFalse; + } + + ExponentialFunction *func2 = (ExponentialFunction *)func; + + if (func2->getE() != 1) + return gFalse; + + if (func2->getDomainMin(0) != 0 || func2->getDomainMax(0) != 1) + return gFalse; + + if (func2->getHasRange()) + return gFalse; + + shading->getCoords(&x0, &y0, &x1, &y1); + cairo_pattern_t *linear_pattern = cairo_pattern_create_linear(x0, y0, x1, y1); + if (func2->getOutputSize() == 3 && + shading->getColorSpace()->getMode() == csDeviceRGB) { + //XXX: are the offsets correct? + cairo_pattern_add_color_stop_rgb(linear_pattern, + 0.0, + func2->getC0()[0], + func2->getC0()[1], + func2->getC0()[2]); + + cairo_pattern_add_color_stop_rgb(linear_pattern, + 1.1, + func2->getC1()[0], + func2->getC1()[1], + func2->getC1()[2]); + } else if (func2->getOutputSize() == 1 && + shading->getColorSpace()->getMode() == csDeviceGray) { + //XXX: are the offsets correct? + cairo_pattern_add_color_stop_rgb(linear_pattern, + 0.0, + func2->getC0()[0], + func2->getC0()[0], + func2->getC0()[0]); + + cairo_pattern_add_color_stop_rgb(linear_pattern, + 1.1, + func2->getC1()[0], + func2->getC1()[0], + func2->getC1()[0]); + } else { + printf("bad color space %d %d\n", shading->getColorSpace()->getMode(), + func2->getOutputSize()); + cairo_pattern_destroy(linear_pattern); + return gFalse; + } + + cairo_pattern_set_extend(linear_pattern, extend); + cairo_pattern_destroy(fill_pattern); + fill_pattern = linear_pattern; + + double xMin, yMin, xMax, yMax; + // get the clip region bbox + state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); + cairo_save (cairo); + cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin); + cairo_set_source (cairo, fill_pattern); + cairo_fill (cairo); + cairo_restore (cairo); + if (cairo_shape) { + cairo_save (cairo_shape); + cairo_rectangle (cairo_shape, xMin, yMin, xMax - xMin, yMax - yMin); + cairo_fill (cairo_shape); + cairo_restore (cairo_shape); + } + } else { + return gFalse; + } + printf("linear output\n"); + return gTrue; +} + void CairoOutputDev::updateStrokeOpacity(GfxState *state) { stroke_opacity = state->getStrokeOpacity(); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 5d2b658..d5e1b1f 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -82,6 +82,8 @@ public: // text in Type 3 fonts will be drawn with drawChar/drawString. virtual GBool interpretType3Chars() { return gTrue; } + virtual GBool useShadedFills() { return gTrue; } + //----- initialization and control // Start a page. @@ -185,6 +187,8 @@ public: virtual void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury); + + virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading); //----- special access // Called to indicate that a new PDF document has been loaded. @@ -262,6 +266,8 @@ public: // Does this device need non-text content? virtual GBool needNonText() { return gTrue; } + virtual GBool useShadedFills() { return gTrue; } + //----- link borders virtual void drawLink(Link *link, Catalog *catalog) { }