summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-08-10 21:54:29 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-08-10 21:54:29 +0000
commitec6081bc21bacd807d6e5869182a439623466181 (patch)
tree784f77597b56941cf03b995fcd286301b27d2f32 /src
parentFix performance regression when displaying large images (diff)
downloadinkscape-ec6081bc21bacd807d6e5869182a439623466181.tar.gz
inkscape-ec6081bc21bacd807d6e5869182a439623466181.zip
Fix rendering of masks with non-opaque alpha channel
(bzr r9508.1.55)
Diffstat (limited to 'src')
-rw-r--r--src/display/cairo-templates.h16
-rw-r--r--src/display/nr-arena-item.cpp21
-rw-r--r--src/display/nr-filter-colormatrix.cpp15
3 files changed, 30 insertions, 22 deletions
diff --git a/src/display/cairo-templates.h b/src/display/cairo-templates.h
index 3c8a6fea3..2b97dd6d6 100644
--- a/src/display/cairo-templates.h
+++ b/src/display/cairo-templates.h
@@ -686,22 +686,6 @@ pxclamp(gint32 v, gint32 low, gint32 high) {
#define ASSEMBLE_ARGB32(px,a,r,g,b) \
guint32 px = (a << 24) | (r << 16) | (g << 8) | b;
-// this is also used for masks, so it resides in this header
-struct ColorMatrixLuminanceToAlpha {
- guint32 operator()(guint32 in) {
- // original computation in double: r*0.2125 + g*0.7154 + b*0.0721
- EXTRACT_ARGB32(in, a, r, g, b)
- // unpremultiply color values
- if (a != 0) {
- r = unpremul_alpha(r, a);
- g = unpremul_alpha(g, a);
- b = unpremul_alpha(b, a);
- }
- guint32 ao = r*54 + g*182 + b*18;
- return ((ao + 127) / 255) << 24;
- }
-};
-
#endif
/*
Local Variables:
diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp
index d9c04ae95..fe50f7753 100644
--- a/src/display/nr-arena-item.cpp
+++ b/src/display/nr-arena-item.cpp
@@ -308,11 +308,20 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc,
return item->state;
}
-/**
- * Render item to pixblock.
- *
- * \return Has NR_ARENA_ITEM_STATE_RENDER set on success.
- */
+struct MaskLuminanceToAlpha {
+ guint32 operator()(guint32 in) {
+ // original computation in double: r*0.2125 + g*0.7154 + b*0.0721
+ EXTRACT_ARGB32(in, a, r, g, b)
+ // unpremultiply color values
+ if (a != 0) {
+ r = unpremul_alpha(r, a);
+ g = unpremul_alpha(g, a);
+ b = unpremul_alpha(b, a);
+ }
+ guint32 ao = r*54 + g*182 + b*18;
+ return premul_alpha((ao + 127) / 255, a) << 24;
+ }
+};
unsigned int
nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area,
@@ -462,7 +471,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
cairo_pattern_t *p = mask->cobj();
cairo_surface_t *s;
cairo_pattern_get_surface(p, &s);
- ink_cairo_surface_filter(s, s, ColorMatrixLuminanceToAlpha());
+ ink_cairo_surface_filter(s, s, MaskLuminanceToAlpha());
}
// render the object (possibly to the intermediate surface)
diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp
index d77898180..7ab606182 100644
--- a/src/display/nr-filter-colormatrix.cpp
+++ b/src/display/nr-filter-colormatrix.cpp
@@ -135,6 +135,21 @@ private:
gint32 _v[9];
};
+struct ColorMatrixLuminanceToAlpha {
+ guint32 operator()(guint32 in) {
+ // original computation in double: r*0.2125 + g*0.7154 + b*0.0721
+ EXTRACT_ARGB32(in, a, r, g, b)
+ // unpremultiply color values
+ if (a != 0) {
+ r = unpremul_alpha(r, a);
+ g = unpremul_alpha(g, a);
+ b = unpremul_alpha(b, a);
+ }
+ guint32 ao = r*54 + g*182 + b*18;
+ return ((ao + 127) / 255) << 24;
+ }
+};
+
void FilterColorMatrix::render_cairo(FilterSlot &slot)
{
cairo_surface_t *input = slot.getcairo(_input);