From eddfd5130995aedc4c07fdc0c55f2654ac9af9bc Mon Sep 17 00:00:00 2001 From: Jason Crain Date: Sun, 20 Dec 2015 09:54:43 -0600 Subject: [PATCH] cairo: use shape mask with soft mask Clear target with the shape mask whether the soft mask is set or not. Propagate the shape up to any higher level groups and destroy the shape pattern when done. Fix a memory leak by removing a call to 'cairo_reference (cairo_shape)'. We already keep track of the lifetime of cairo_shape using knockoutCount. bug 91931 --- poppler/CairoOutputDev.cc | 49 ++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 56cd06d..5c7082f 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1597,8 +1597,6 @@ void CairoOutputDev::beginTransparencyGroup(GfxState * /*state*/, double * /*bbo cairo_get_matrix (cairo, &matrix); //printMatrix(&matrix); cairo_set_matrix (cairo_shape, &matrix); - } else { - cairo_reference (cairo_shape); } } if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) { @@ -1638,33 +1636,22 @@ void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbo cairo_save (cairo); cairo_set_matrix (cairo, &groupColorSpaceStack->group_matrix); + + if (shape) { + /* OPERATOR_SOURCE w/ a mask is defined as (src IN mask) ADD (dest OUT mask) + * however our source has already been clipped to mask so we only need to + * do ADD and OUT */ + + /* clear the shape mask */ + cairo_set_source (cairo, shape); + cairo_set_operator (cairo, CAIRO_OPERATOR_DEST_OUT); + cairo_paint (cairo); + cairo_set_operator (cairo, CAIRO_OPERATOR_ADD); + } cairo_set_source (cairo, group); if (!mask) { - //XXX: deal with mask && shape case - if (shape) { - cairo_save (cairo); - - /* OPERATOR_SOURCE w/ a mask is defined as (src IN mask) ADD (dest OUT mask) - * however our source has already been clipped to mask so we only need to - * do ADD and OUT */ - - /* clear the shape mask */ - cairo_set_source (cairo, shape); - cairo_set_operator (cairo, CAIRO_OPERATOR_DEST_OUT); - cairo_paint (cairo); - - cairo_set_operator (cairo, CAIRO_OPERATOR_ADD); - cairo_set_source (cairo, group); - cairo_paint (cairo); - - cairo_restore (cairo); - - cairo_pattern_destroy (shape); - shape = NULL; - } else { - cairo_paint_with_alpha (cairo, fill_opacity); - } + cairo_paint_with_alpha (cairo, fill_opacity); cairo_status_t status = cairo_status(cairo); if (status) printf("BAD status: %s\n", cairo_status_to_string(status)); @@ -1684,6 +1671,16 @@ void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbo mask = NULL; } + if (shape) { + if (cairo_shape) { + cairo_set_source (cairo_shape, shape); + cairo_paint (cairo_shape); + cairo_set_source_rgb (cairo_shape, 0, 0, 0); + } + cairo_pattern_destroy (shape); + shape = NULL; + } + popTransparencyGroup(); cairo_restore(cairo); } -- 2.6.4