diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2010-07-07 18:08:47 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2010-07-07 18:08:47 +0000 |
| commit | b80e2b5bb72ebb814745bd58ccf10bfa617dd7e9 (patch) | |
| tree | 23b5587685ddf4f15b9a1d3a65a066e49a779455 /src/display | |
| parent | Switch to nearest neighbor filtering when image is larger than original (diff) | |
| download | inkscape-b80e2b5bb72ebb814745bd58ccf10bfa617dd7e9.tar.gz inkscape-b80e2b5bb72ebb814745bd58ccf10bfa617dd7e9.zip | |
Fix group opacity
(bzr r9508.1.13)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/nr-arena-glyphs.cpp | 10 | ||||
| -rw-r--r-- | src/display/nr-arena-item.cpp | 23 | ||||
| -rw-r--r-- | src/display/nr-arena-shape.cpp | 10 | ||||
| -rw-r--r-- | src/display/nr-style.cpp | 2 | ||||
| -rw-r--r-- | src/display/nr-style.h | 1 |
5 files changed, 21 insertions, 25 deletions
diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index ad3006950..faf10bd38 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -322,7 +322,6 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi } // NOTE: this is very similar to nr-arena-shape.cpp; the only difference is path feeding - bool needs_opacity = ((1.0 - ggroup->nrstyle.opacity) >= 0.01); bool has_stroke, has_fill; cairo_save(ct); @@ -333,10 +332,6 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi has_stroke = ggroup->nrstyle.prepareStroke(ct, &ggroup->paintbox); if (has_fill || has_stroke) { - if (needs_opacity) { - cairo_push_group(ct); - } - for (NRArenaItem *child = ggroup->children; child != NULL; child = child->next) { NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); Geom::PathVector const &pathv = *g->font->PathVector(g->glyph); @@ -356,11 +351,6 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi cairo_stroke_preserve(ct); } cairo_new_path(ct); // clear path - - if (needs_opacity) { - cairo_pop_group_to_source(ct); - cairo_paint_with_alpha(ct, ggroup->nrstyle.opacity); - } } // has fill or stroke pattern cairo_restore(ct); diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index 338940fb6..f5731c0e3 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -571,10 +571,14 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area bool needs_intermediate_rendering = false; bool &nir = needs_intermediate_rendering; + bool needs_opacity = (item->opacity != 255); // this item needs an intermediate rendering if: nir |= (item->mask != NULL); // 1. it has a mask nir |= (item->filter != NULL && filter); // 2. it has a filter + nir |= needs_opacity; // 3. it is non-opaque + + double opacity = static_cast<double>(item->opacity) / 255.0; if (needs_intermediate_rendering) { cairo_surface_t *intermediate = cairo_surface_create_similar( @@ -590,6 +594,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area CairoSave clipsave(this_ct); // RAII for save / restore CairoGroup maskgroup(this_ct); // RAII for push_group / pop_group CairoGroup drawgroup(this_ct); + CairoGroup maskopacitygroup(this_ct); if (item->clip && !(item->filter && filter)) { clipsave.save(); @@ -603,12 +608,20 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area if (item->mask) { maskgroup.push_with_content(CAIRO_CONTENT_ALPHA); - + // handle opacity of a masked object by composing it with the mask + // this uses 1/4 the memory of composing it with full rendering + if (needs_opacity) { + maskopacitygroup.push(); + } state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (this_ct, item->mask, this_area, pb, flags); if (state & NR_ARENA_ITEM_STATE_INVALID) { item->state |= NR_ARENA_ITEM_STATE_INVALID; return item->state; } + if (needs_opacity) { + maskopacitygroup.pop_to_source(); + cct.paint_with_alpha(opacity); + } mask = maskgroup.popmm(); } @@ -632,8 +645,14 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area cairo_matrix_translate(&m, area->x0 - carea.x0, area->y0 - carea.y0); cairo_pattern_set_matrix(cmask, &m); cairo_mask(ct, cmask); + // opacity of masked objects is handled by premultiplying the mask } else { - cairo_paint(ct); + // opacity of non-masked objects must be rendered explicitly + if (needs_opacity) { + cairo_paint_with_alpha(ct, opacity); + } else { + cairo_paint(ct); + } } cairo_set_source_rgba(ct,0,0,0,0); cairo_destroy(this_ct); diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 3f673c944..b51f3a9cf 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -360,7 +360,6 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; } else { - bool needs_opacity = ((1.0 - shape->nrstyle.opacity) >= 0.01); bool has_stroke, has_fill; // we assume the context has no path cairo_save(ct); @@ -374,10 +373,6 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock has_stroke = shape->nrstyle.prepareStroke(ct, &shape->paintbox); if (has_fill || has_stroke) { - if (needs_opacity) { - cairo_push_group(ct); - } - // TODO: remove segments outside of bbox when no dashes present feed_pathvector_to_cairo(ct, shape->curve->get_pathvector()); if (has_fill) { @@ -389,11 +384,6 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock cairo_stroke_preserve(ct); } cairo_new_path(ct); // clear path - - if (needs_opacity) { - cairo_pop_group_to_source(ct); - cairo_paint_with_alpha(ct, shape->nrstyle.opacity); - } } // has fill or stroke pattern cairo_restore(ct); } diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index c15dd78a3..bf2f2d305 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -137,8 +137,6 @@ void NRStyle::set(SPStyle *style) dash = NULL; } - opacity = SP_SCALE24_TO_FLOAT(style->opacity.value); - update(); } diff --git a/src/display/nr-style.h b/src/display/nr-style.h index b2116a6c5..e741e46b4 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -55,7 +55,6 @@ struct NRStyle { Paint stroke; float stroke_width; float miter_limit; - float opacity; unsigned int n_dash; double *dash; float dash_offset; |
