diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index ff98d34..38e7177 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -615,6 +615,25 @@ GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, return gFalse; } +GBool CairoOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) { + double x0, y0, r0, x1, y1, r1; + double dx, dy, dr; + + shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); + dx = x1 - x0; + dy = y1 - y0; + dr = r1 - r0; + cairo_pattern_destroy(fill_pattern); + fill_pattern = cairo_pattern_create_radial (x0 + sMin * dx, + y0 + sMin * dy, + r0 + sMin * dr, + x1 + sMax * dx, + y1 + sMax * dy, + r1 + sMax * dr); + + return gFalse; +} + void CairoOutputDev::clip(GfxState *state) { doPath (cairo, state, state->getPath()); cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 1c9bc0e..2bf0714 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -148,7 +148,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); //----- path clipping virtual void clip(GfxState *state); virtual void eoClip(GfxState *state); diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index b275858..77fd680 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -2623,11 +2623,6 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { double *ctm; double theta, alpha, angle, t; - if (out->useShadedFills() && - out->radialShadedFill(state, shading)) { - return; - } - // get the shading info shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); t0 = shading->getDomain0(); @@ -2723,6 +2718,11 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { } } + if (out->useShadedFills() && + out->radialShadedFill(state, shading, sMin, sMax)) { + return; + } + // compute the number of steps into which circles must be divided to // achieve a curve flatness of 0.1 pixel in device space for the // largest circle (note that "device space" is 72 dpi when generating @@ -2819,7 +2819,10 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { colorA.c[k] = (colorA.c[k] + colorB.c[k]) / 2; } state->setFillColor(&colorA); - out->updateFillColor(state); + if (out->useShadedFills()) + out->updateFillColorStop(state, (sb - sMin)/(sMax - sMin)); + else + out->updateFillColor(state); if (enclosed) { @@ -2873,9 +2876,11 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { } // fill the path - if (!contentIsHidden()) - out->fill(state); - state->clearPath(); + if (!out->useShadedFills()) { + if (!contentIsHidden()) + out->fill(state); + state->clearPath(); + } // step to the next value of t ia = ib; @@ -2902,18 +2907,24 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { xa = x1; ya = y1; } + sa = (ta - t0) / (t1 - t0); shading->getColor(ta, &colorA); state->setFillColor(&colorA); - out->updateFillColor(state); + if (out->useShadedFills()) + out->updateFillColorStop(state, (sa - sMin)/(sMax - sMin)); + else + out->updateFillColor(state); state->moveTo(xa + ra, ya); for (k = 1; k < n; ++k) { angle = ((double)k / (double)n) * 2 * M_PI; state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle)); } state->closePath(); - if (!contentIsHidden()) - out->fill(state); - state->clearPath(); + if (!out->useShadedFills()) { + if (!contentIsHidden()) + out->fill(state); + state->clearPath(); + } } // extend the larger circle @@ -2930,9 +2941,13 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { xa = x1; ya = y1; } + sa = (ta - t0) / (t1 - t0); shading->getColor(ta, &colorA); state->setFillColor(&colorA); - out->updateFillColor(state); + if (out->useShadedFills()) + out->updateFillColorStop(state, (sa - sMin)/(sMax - sMin)); + else + out->updateFillColor(state); state->moveTo(xMin, yMin); state->lineTo(xMin, yMax); state->lineTo(xMax, yMax); @@ -2944,11 +2959,20 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) { state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle)); } state->closePath(); - if (!contentIsHidden()) - out->fill(state); - state->clearPath(); + if (!out->useShadedFills()) { + if (!contentIsHidden()) + out->fill(state); + state->clearPath(); + } } } + + // fill the path + if (out->useShadedFills()) { + if (!contentIsHidden()) + out->fill(state); + state->clearPath(); + } } void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) { diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index b5f50eb..a1dee63 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -195,7 +195,7 @@ public: { return gFalse; } virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/, double /*tMin*/, double /*tMax*/) { return gFalse; } - virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/) + virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/, double /*sMin*/, double /*sMax*/) { return gFalse; } //----- path clipping