[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sat Apr 2 10:03:23 UTC 2016
poppler/CairoOutputDev.cc | 38 ++++++++++++++++++++++++++++++--------
poppler/CairoOutputDev.h | 1 +
2 files changed, 31 insertions(+), 8 deletions(-)
New commits:
commit 7d8dfb09d2b9d69d4e80838ce58fdbd091bce7ec
Author: Jason Crain <jason at aquaticape.us>
Date: Sun Feb 28 16:18:05 2016 -0600
cairo: fix fillToStrokePathClip crash and rendering
The cairo backend can crash if the dash pattern changes between calling
clipToStrokePathClip and fillToStrokePathClip because fillToStrokePathClip
calls cairo_set_dash with the saved dash pattern but the current dash count.
Fixes the crash by removing the call to cairo_get_dash_count in
fillToStrokePathClip. Makes strokePathClip reference counted because when
drawing tiling patterns it may need to be kept around for more than one drawing
operation. Uses fillToStrokePathClip in a few more places to fix rendering.
bug #62905
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index d0d6cb4..eab1ccc 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -278,6 +278,9 @@ void CairoOutputDev::saveState(GfxState *state) {
ms->mask_matrix = mask_matrix;
ms->next = maskStack;
maskStack = ms;
+
+ if (strokePathClip)
+ strokePathClip->ref_count++;
}
void CairoOutputDev::restoreState(GfxState *state) {
@@ -305,6 +308,14 @@ void CairoOutputDev::restoreState(GfxState *state) {
maskStack = ms->next;
delete ms;
}
+
+ if (strokePathClip && --strokePathClip->ref_count == 0) {
+ delete strokePathClip->path;
+ if (strokePathClip->dashes)
+ gfree (strokePathClip->dashes);
+ gfree (strokePathClip);
+ strokePathClip = NULL;
+ }
}
void CairoOutputDev::updateAll(GfxState *state) {
@@ -780,7 +791,14 @@ void CairoOutputDev::stroke(GfxState *state) {
align_stroke_coords = gFalse;
cairo_set_source (cairo, stroke_pattern);
LOG(printf ("stroke\n"));
- cairo_stroke (cairo);
+ if (strokePathClip) {
+ cairo_push_group (cairo);
+ cairo_stroke (cairo);
+ cairo_pop_group_to_source (cairo);
+ fillToStrokePathClip (state);
+ } else {
+ cairo_stroke (cairo);
+ }
if (cairo_shape) {
doPath (cairo_shape, state, state->getPath());
cairo_stroke (cairo_shape);
@@ -803,6 +821,11 @@ void CairoOutputDev::fill(GfxState *state) {
if (mask) {
cairo_save (cairo);
cairo_clip (cairo);
+ if (strokePathClip) {
+ cairo_push_group (cairo);
+ fillToStrokePathClip (state);
+ cairo_pop_group_to_source (cairo);
+ }
cairo_set_matrix (cairo, &mask_matrix);
cairo_mask (cairo, mask);
cairo_restore (cairo);
@@ -1296,6 +1319,7 @@ void CairoOutputDev::clipToStrokePath(GfxState *state) {
strokePathClip->cap = cairo_get_line_cap (cairo);
strokePathClip->join = cairo_get_line_join (cairo);
strokePathClip->miter = cairo_get_miter_limit (cairo);
+ strokePathClip->ref_count = 1;
}
void CairoOutputDev::fillToStrokePathClip(GfxState *state) {
@@ -1303,7 +1327,6 @@ void CairoOutputDev::fillToStrokePathClip(GfxState *state) {
cairo_set_matrix (cairo, &strokePathClip->ctm);
cairo_set_line_width (cairo, strokePathClip->line_width);
- strokePathClip->dash_count = cairo_get_dash_count (cairo);
cairo_set_dash (cairo, strokePathClip->dashes, strokePathClip->dash_count, strokePathClip->dash_offset);
cairo_set_line_cap (cairo, strokePathClip->cap);
cairo_set_line_join (cairo, strokePathClip->join);
@@ -1312,12 +1335,6 @@ void CairoOutputDev::fillToStrokePathClip(GfxState *state) {
cairo_stroke (cairo);
cairo_restore (cairo);
-
- delete strokePathClip->path;
- if (strokePathClip->dashes)
- gfree (strokePathClip->dashes);
- gfree (strokePathClip);
- strokePathClip = NULL;
}
void CairoOutputDev::beginString(GfxState *state, GooString *s)
@@ -2425,6 +2442,11 @@ void CairoOutputDev::drawImageMaskPrescaled(GfxState *state, Object *ref, Stream
cairo_rectangle (cairo, 0., 0., scaledWidth, scaledHeight);
cairo_clip (cairo);
+ if (strokePathClip) {
+ cairo_push_group (cairo);
+ fillToStrokePathClip (state);
+ cairo_pop_group_to_source (cairo);
+ }
cairo_mask (cairo, pattern);
//cairo_get_matrix(cairo, &matrix);
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index c146ce0..0f88778 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -308,6 +308,7 @@ protected:
cairo_line_cap_t cap;
cairo_line_join_t join;
double miter;
+ int ref_count;
} *strokePathClip;
PDFDoc *doc; // the current document
More information about the poppler
mailing list