[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h poppler/Gfx.cc poppler/OutputDev.h poppler/PSOutputDev.cc poppler/PSOutputDev.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Wed Jul 8 09:56:26 PDT 2009
poppler/CairoOutputDev.cc | 29 +++++++++++++++++++++++++++++
poppler/CairoOutputDev.h | 10 ++++++++++
poppler/Gfx.cc | 29 ++++++++++++++++++++---------
poppler/OutputDev.h | 6 +++++-
poppler/PSOutputDev.cc | 2 +-
poppler/PSOutputDev.h | 2 +-
6 files changed, 66 insertions(+), 12 deletions(-)
New commits:
commit 569627ac4d56ddd58e109ce2a37179a85e042030
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Wed Jul 8 13:02:16 2009 +0200
Implement axialShadedFill in cairo backend using cairo gradients
See bug #10942.
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index e033e50..79c5c76 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -458,6 +458,18 @@ void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
LOG(printf ("stroke opacity: %f\n", stroke_opacity));
}
+void CairoOutputDev::updateFillColorStop(GfxState *state, double offset) {
+ state->getFillRGB(&fill_color);
+
+ cairo_pattern_add_color_stop_rgba(fill_pattern, offset,
+ fill_color.r / 65535.0,
+ fill_color.g / 65535.0,
+ fill_color.b / 65535.0,
+ fill_opacity);
+ LOG(printf ("fill color stop: %f (%d, %d, %d)\n",
+ offset, fill_color.r, fill_color.g, fill_color.b));
+}
+
void CairoOutputDev::updateFont(GfxState *state) {
cairo_font_face_t *font_face;
cairo_matrix_t matrix, invert_matrix;
@@ -586,6 +598,23 @@ void CairoOutputDev::eoFill(GfxState *state) {
}
+GBool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) {
+ double x0, y0, x1, y1;
+ double dx, dy;
+
+ shading->getCoords(&x0, &y0, &x1, &y1);
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ cairo_pattern_destroy(fill_pattern);
+ fill_pattern = cairo_pattern_create_linear (x0 + tMin * dx, y0 + tMin * dy,
+ x0 + tMax * dx, y0 + tMax * dy);
+
+ // TODO: use the actual stops in the shading in the case
+ // of linear interpolation (Type 2 Exponential functions with N=1)
+ 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 5af832d..cd66cb7 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -98,6 +98,14 @@ public:
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gTrue; }
+ // Does this device use functionShadedFill(), axialShadedFill(), and
+ // radialShadedFill()? If this returns false, these shaded fills
+ // will be reduced to a series of other drawing operations.
+ virtual GBool useShadedFills() { return gTrue; }
+
+ // Does this device use FillColorStop()?
+ virtual GBool useFillColorStop() { return gTrue; }
+
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gFalse; }
@@ -132,6 +140,7 @@ public:
virtual void updateStrokeColor(GfxState *state);
virtual void updateFillOpacity(GfxState *state);
virtual void updateStrokeOpacity(GfxState *state);
+ virtual void updateFillColorStop(GfxState *state, double offset);
//----- update text state
virtual void updateFont(GfxState *state);
@@ -141,6 +150,7 @@ public:
virtual void stroke(GfxState *state);
virtual void fill(GfxState *state);
virtual void eoFill(GfxState *state);
+ virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
//----- path clipping
virtual void clip(GfxState *state);
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index c11f551..c3f257f 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2361,11 +2361,6 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
int nComps;
int i, j, k;
- if (out->useShadedFills() &&
- out->axialShadedFill(state, shading)) {
- return;
- }
-
// get the clip region bbox
state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
@@ -2395,6 +2390,11 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
}
}
+ if (out->useShadedFills() &&
+ out->axialShadedFill(state, shading, tMin, tMax)) {
+ return;
+ }
+
// get the function domain
t0 = shading->getDomain0();
t1 = shading->getDomain1();
@@ -2584,7 +2584,10 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// set the color
state->setFillColor(&color0);
- out->updateFillColor(state);
+ if (out->useFillColorStop())
+ out->updateFillColorStop(state, (ta[j] - tMin)/(tMax - tMin));
+ else
+ out->updateFillColor(state);
// fill the region
state->moveTo(ux0, uy0);
@@ -2592,9 +2595,11 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
state->lineTo(vx1, vy1);
state->lineTo(ux1, uy1);
state->closePath();
- if (!contentIsHidden())
- out->fill(state);
- state->clearPath();
+ if (!out->useFillColorStop()) {
+ if (!contentIsHidden())
+ out->fill(state);
+ state->clearPath();
+ }
// set up for next region
ux0 = ux1;
@@ -2604,6 +2609,12 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
color0 = color1;
i = next[i];
}
+
+ if (out->useFillColorStop()) {
+ if (!contentIsHidden())
+ out->fill(state);
+ state->clearPath();
+ }
}
void Gfx::doRadialShFill(GfxRadialShading *shading) {
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 35adadd..76d3611 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -85,6 +85,9 @@ public:
// will be reduced to a series of other drawing operations.
virtual GBool useShadedFills() { return gFalse; }
+ // Does this device use FillColorStop()?
+ virtual GBool useFillColorStop() { return gFalse; }
+
// Does this device use drawForm()? If this returns false,
// form-type XObjects will be interpreted (i.e., unrolled).
virtual GBool useDrawForm() { return gFalse; }
@@ -169,6 +172,7 @@ public:
virtual void updateFillOverprint(GfxState * /*state*/) {}
virtual void updateStrokeOverprint(GfxState * /*state*/) {}
virtual void updateTransfer(GfxState * /*state*/) {}
+ virtual void updateFillColorStop(GfxState * /*state*/, double /*offset*/) {}
//----- update text state
virtual void updateFont(GfxState * /*state*/) {}
@@ -193,7 +197,7 @@ public:
virtual GBool functionShadedFill(GfxState * /*state*/,
GfxFunctionShading * /*shading*/)
{ return gFalse; }
- virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/)
+ virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/, double /*tMin*/, double /*tMax*/)
{ return gFalse; }
virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/)
{ return gFalse; }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 6bec12d..ea8aeea 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3850,7 +3850,7 @@ GBool PSOutputDev::functionShadedFill(GfxState *state,
return gTrue;
}
-GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) {
+GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/) {
double xMin, yMin, xMax, yMax;
double x0, y0, x1, y1, dx, dy, mul;
double tMin, tMax, t, t0, t1;
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 6310375..be4763d 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -215,7 +215,7 @@ public:
double xStep, double yStep);
virtual GBool functionShadedFill(GfxState *state,
GfxFunctionShading *shading);
- virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading);
+ virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/);
virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading);
//----- path clipping
More information about the poppler
mailing list