summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-07-07 18:08:47 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-07-07 18:08:47 +0000
commitb80e2b5bb72ebb814745bd58ccf10bfa617dd7e9 (patch)
tree23b5587685ddf4f15b9a1d3a65a066e49a779455 /src
parentSwitch to nearest neighbor filtering when image is larger than original (diff)
downloadinkscape-b80e2b5bb72ebb814745bd58ccf10bfa617dd7e9.tar.gz
inkscape-b80e2b5bb72ebb814745bd58ccf10bfa617dd7e9.zip
Fix group opacity
(bzr r9508.1.13)
Diffstat (limited to 'src')
-rw-r--r--src/display/nr-arena-glyphs.cpp10
-rw-r--r--src/display/nr-arena-item.cpp23
-rw-r--r--src/display/nr-arena-shape.cpp10
-rw-r--r--src/display/nr-style.cpp2
-rw-r--r--src/display/nr-style.h1
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;