Code

Fix luminance to alpha calculation in masks.
[inkscape.git] / src / display / nr-arena-item.cpp
index b80df727340113407243f4f3424d698645115135..5598efa326e1c733992abbbbe283a8d5e104afba 100644 (file)
@@ -323,8 +323,11 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
                            item->state);
 
 #ifdef NR_ARENA_ITEM_VERBOSE
-    printf ("Invoke render %p: %d %d - %d %d\n", item, area->x0, area->y0,
-            area->x1, area->y1);
+    g_message ("Invoke render %p on %p: %d %d - %d %d, %d %d - %d %d", item, pb,
+            area->x0, area->y0,
+            area->x1, area->y1,
+            item->drawbox.x0, item->drawbox.y0,
+            item->drawbox.x1, item->drawbox.y1);
 #endif
 
     /* If we are invisible, just return successfully */
@@ -415,8 +418,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
     /* Determine, whether we need temporary buffer */
     if (item->clip || item->mask
         || ((item->opacity != 255) && !item->render_opacity)
-        || (item->filter && filter) || item->background_new
-        || (item->parent && item->parent->background_pb)) {
+        || (item->filter && filter) || item->background_new) {
 
         /* Setup and render item buffer */
         NRPixBlock ipb;
@@ -432,8 +434,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
 
         /* If background access is used, save the pixblock address.
          * This address is set to NULL at the end of this block */
-        if (item->background_new ||
-            (item->parent && item->parent->background_pb)) {
+        if (item->background_new) {
             item->background_pb = &ipb;
         }
 
@@ -513,11 +514,12 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
                                 d = NR_PIXBLOCK_PX (&mpb) + (y -
                                                              carea.y0) * mpb.rs;
                                 for (x = carea.x0; x < carea.x1; x++) {
+                                    // See below for calculation
                                     unsigned int m;
-                                    m = NR_PREMUL_112 (s[0] + s[1] + s[2], s[3]);
-                                    d[0] =
-                                        FAST_DIV_ROUND < 3 * 255 * 255 >
-                                        (NR_PREMUL_123 (d[0], m));
+                                    m = NR_PREMUL_112 ( (NR_PREMUL_112 (s[0],  54) +
+                                                         NR_PREMUL_112 (s[1], 183) +
+                                                         NR_PREMUL_112 (s[2],  19) ) >> 8, s[3]);
+                                    d[0] = FAST_DIV_ROUND < 255 * 255 > ( NR_PREMUL_123 (d[0], m));
                                     s += 4;
                                     d += 1;
                                 }
@@ -532,8 +534,17 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
                                                              carea.y0) * mpb.rs;
                                 for (x = carea.x0; x < carea.x1; x++) {
                                     unsigned int m;
-                                    m = NR_PREMUL_112 (s[0] + s[1] + s[2], s[3]);
-                                    d[0] = FAST_DIV_ROUND < 3 * 255 > (m);
+                                    // m = NR_PREMUL_112 (s[0] + s[1] + s[2], s[3]);
+                                    // d[0] = FAST_DIV_ROUND < 3 * 255 > (m);
+                                    // Must use luminance to alpha from feColorMatrix.
+                                    // This is an approximation, optimized(?) for speed.
+                                    // 0.2125 * 256 =  54.4000
+                                    // 0.7154 * 256 = 183.1424
+                                    // 0.0721 * 256 =  18.4576
+                                    m = NR_PREMUL_112 ( (NR_PREMUL_112 (s[0],  54) +
+                                                         NR_PREMUL_112 (s[1], 183) +
+                                                         NR_PREMUL_112 (s[2],  19) ) >> 8, s[3]);
+                                    d[0] = FAST_DIV_ROUND < 255 > (m);
                                     s += 4;
                                     d += 1;
                                 }
@@ -859,29 +870,15 @@ nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect &bbox)
 
 /** Returns a background image for use with filter effects. */
 NRPixBlock *
-nr_arena_item_get_background (NRArenaItem const *item, int depth)
+nr_arena_item_get_background (NRArenaItem const *item)
 {
-    NRPixBlock *pb;
-    if (!item->background_pb)
-        return NULL;
     if (item->background_new) {
-        pb = new NRPixBlock ();
-        nr_pixblock_setup_fast (pb, item->background_pb->mode,
-                                item->background_pb->area.x0,
-                                item->background_pb->area.y0,
-                                item->background_pb->area.x1,
-                                item->background_pb->area.y1, true);
-        if (pb->size != NR_PIXBLOCK_SIZE_TINY && pb->data.px == NULL) // allocation failed
-            return NULL;
+        return item->background_pb;
     } else if (item->parent) {
-        pb = nr_arena_item_get_background (item->parent, depth + 1);
-    } else
+        return nr_arena_item_get_background (item->parent);
+    } else {
         return NULL;
-
-    if (depth > 0)
-        nr_blit_pixblock_pixblock (pb, item->background_pb);
-
-    return pb;
+    }
 }
 
 /* Helpers */
@@ -949,4 +946,4 @@ nr_arena_item_detach (NRArenaItem *parent, NRArenaItem *child)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :