Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / display / nr-arena-item.cpp
index b9a0cc371e6f19e445de19b26c73a08d3f023023..9b3a6214cf1877ae7e092d211e459b3ffc392bcd 100644 (file)
 
 #include <libnr/nr-blit.h>
 #include <libnr/nr-pixops.h>
-#include <libnr/nr-matrix-ops.h>
-#include <libnr/nr-matrix-fns.h>
 #include "nr-arena.h"
 #include "nr-arena-item.h"
 #include "gc-core.h"
 #include "helper/geom.h"
 
 #include "nr-filter.h"
-#include "libnr/nr-rect.h"
 #include "nr-arena-group.h"
-#include "prefs-utils.h"
+#include "preferences.h"
 
 namespace GC = Inkscape::GC;
 
@@ -84,6 +81,7 @@ nr_arena_item_init (NRArenaItem *item)
     item->visible = TRUE;
 
     memset (&item->bbox, 0, sizeof (item->bbox));
+    memset (&item->drawbox, 0, sizeof (item->drawbox));
     item->transform = NULL;
     item->opacity = 255;
     item->render_opacity = FALSE;
@@ -237,7 +235,7 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc,
         return item->state;
     /* Test whether to return immediately */
     if (area && (item->state & NR_ARENA_ITEM_STATE_BBOX)) {
-        if (!nr_rect_l_test_intersect_ptr(area, &item->bbox))
+        if (!nr_rect_l_test_intersect_ptr(area, &item->drawbox))
             return item->state;
     }
 
@@ -255,14 +253,17 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc,
     item->ctm = childgc.transform;
 
     /* Invoke the real method */
-    item->state =
-        NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state,
-                                              reset);
+    // that will update bbox
+    item->state = NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state, reset);
     if (item->state & NR_ARENA_ITEM_STATE_INVALID)
         return item->state;
-    /* Enlarge the bounding box to contain filter effects */
+
+    // get a copy of bbox
+    memcpy(&item->drawbox, &item->bbox, sizeof(item->bbox));
+
+    /* Enlarge the drawbox to contain filter effects */
     if (item->filter && filter) {
-        item->filter->bbox_enlarge (item->bbox);
+        item->filter->bbox_enlarge (item->drawbox);
     }
     // fixme: to fix the display glitches, in outline mode bbox must be a combination of 
     // full item bbox and its clip and mask (after we have the API to get these)
@@ -277,7 +278,8 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc,
             item->state |= NR_ARENA_ITEM_STATE_INVALID;
             return item->state;
         }
-        nr_rect_l_intersect (&item->bbox, &item->bbox, &item->clip->bbox);
+        // for clipping, we need geometric bbox
+        nr_rect_l_intersect (&item->drawbox, &item->drawbox, &item->clip->bbox);
     }
     /* Masking */
     if (item->mask) {
@@ -286,7 +288,14 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc,
             item->state |= NR_ARENA_ITEM_STATE_INVALID;
             return item->state;
         }
-        nr_rect_l_intersect (&item->bbox, &item->bbox, &item->mask->bbox);
+        // for masking, we need full drawbox of mask
+        nr_rect_l_intersect (&item->drawbox, &item->drawbox, &item->mask->drawbox);
+    }
+
+    // now that we know drawbox, dirty the corresponding rect on canvas:
+    if (!NR_IS_ARENA_GROUP(item) || (item->filter && filter)) {
+        // unless filtered, groups do not need to render by themselves, only their members
+        nr_arena_item_request_render (item);
     }
 
     return item->state;
@@ -303,7 +312,9 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
                              NRPixBlock *pb, unsigned int flags)
 {
    bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE);
-    bool filter = (item->arena->rendermode == Inkscape::RENDERMODE_NORMAL);
+    bool filter = (item->arena->rendermode != Inkscape::RENDERMODE_OUTLINE &&
+                   item->arena->rendermode != Inkscape::RENDERMODE_NO_FILTERS);
+    bool print_colors = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW);
 
     nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID);
     nr_return_val_if_fail (NR_IS_ARENA_ITEM (item),
@@ -312,21 +323,24 @@ 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 outside bbox just return successfully */
+    /* If we are invisible, just return successfully */
     if (!item->visible)
         return item->state | NR_ARENA_ITEM_STATE_RENDER;
 
     NRRectL carea;
-    nr_rect_l_intersect (&carea, area, &item->bbox);
+    nr_rect_l_intersect (&carea, area, &item->drawbox);
     if (nr_rect_l_test_empty(carea))
         return item->state | NR_ARENA_ITEM_STATE_RENDER;
     if (item->filter && filter) {
-        item->filter->area_enlarge (carea, item->ctm);
-        nr_rect_l_intersect (&carea, &carea, &item->bbox);
+        item->filter->area_enlarge (carea, item);
+        nr_rect_l_intersect (&carea, &carea, &item->drawbox);
     }
 
     if (outline) {
@@ -343,13 +357,14 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
             // render clip and mask, if any
             guint32 saved_rgba = item->arena->outlinecolor; // save current outline color
             // render clippath as an object, using a different color
+            Inkscape::Preferences *prefs = Inkscape::Preferences::get();
             if (item->clip) {
-                item->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "clips", 0x00ff00ff); // green clips
+                item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips
                 NR_ARENA_ITEM_VIRTUAL (item->clip, render) (ct, item->clip, &carea, pb, flags);
             } 
             // render mask as an object, using a different color
             if (item->mask) {
-                item->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "masks", 0x0000ffff); // blue masks
+                item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks
                 NR_ARENA_ITEM_VIRTUAL (item->mask, render) (ct, item->mask, &carea, pb, flags);
             }
             item->arena->outlinecolor = saved_rgba; // restore outline color
@@ -364,10 +379,10 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
                                   /* fixme: This probably cannot overflow, because we render only if visible */
                                   /* fixme: and pixel cache is there only for small items */
                                   /* fixme: But this still needs extra check (Lauris) */
-                                  item->bbox.x0, item->bbox.y0,
-                                  item->bbox.x1, item->bbox.y1,
+                                  item->drawbox.x0, item->drawbox.y0,
+                                  item->drawbox.x1, item->drawbox.y1,
                                   item->px,
-                                  4 * (item->bbox.x1 - item->bbox.x0), FALSE,
+                                  4 * (item->drawbox.x1 - item->drawbox.x0), FALSE,
                                   FALSE);
         nr_blit_pixblock_pixblock (pb, &cpb);
         nr_pixblock_release (&cpb);
@@ -379,15 +394,15 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
 
     /* Setup cache if we can */
     if ((!(flags & NR_ARENA_ITEM_RENDER_NO_CACHE)) &&
-        (carea.x0 <= item->bbox.x0) && (carea.y0 <= item->bbox.y0) &&
-        (carea.x1 >= item->bbox.x1) && (carea.y1 >= item->bbox.y1) &&
-        (((item->bbox.x1 - item->bbox.x0) * (item->bbox.y1 -
-                                             item->bbox.y0)) <= 4096)) {
-        // Item bbox is fully in renderable area and size is acceptable
-        carea.x0 = item->bbox.x0;
-        carea.y0 = item->bbox.y0;
-        carea.x1 = item->bbox.x1;
-        carea.y1 = item->bbox.y1;
+        (carea.x0 <= item->drawbox.x0) && (carea.y0 <= item->drawbox.y0) &&
+        (carea.x1 >= item->drawbox.x1) && (carea.y1 >= item->drawbox.y1) &&
+        (((item->drawbox.x1 - item->drawbox.x0) * (item->drawbox.y1 -
+                                             item->drawbox.y0)) <= 4096)) {
+        // Item drawbox is fully in renderable area and size is acceptable
+        carea.x0 = item->drawbox.x0;
+        carea.y0 = item->drawbox.y0;
+        carea.x1 = item->drawbox.x1;
+        carea.y1 = item->drawbox.y1;
         item->px =
             new (GC::ATOMIC) unsigned char[4 * (carea.x1 - carea.x0) *
                                            (carea.y1 - carea.y0)];
@@ -403,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;
@@ -420,14 +434,13 @@ 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;
         }
 
         ipb.visible_area = pb->visible_area;
         if (item->filter && filter) {
-              item->filter->area_enlarge (ipb.visible_area, item->ctm);
+              item->filter->area_enlarge (ipb.visible_area, item);
         }
 
         unsigned int state = NR_ARENA_ITEM_VIRTUAL (item, render) (ct, item, &carea, &ipb, flags);
@@ -676,7 +689,7 @@ nr_arena_item_request_render (NRArenaItem *item)
     nr_return_if_fail (item != NULL);
     nr_return_if_fail (NR_IS_ARENA_ITEM (item));
 
-    nr_arena_request_render_rect (item->arena, &item->bbox);
+    nr_arena_request_render_rect (item->arena, &item->drawbox);
 }
 
 /* Public */
@@ -837,39 +850,25 @@ nr_arena_item_set_order (NRArenaItem *item, int order)
 }
 
 void
-nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<Geom::Rect> &bbox)
+nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect &bbox)
 {
     nr_return_if_fail(item != NULL);
     nr_return_if_fail(NR_IS_ARENA_ITEM(item));
 
-    if(bbox)  item->item_bbox = *bbox;
+    item->item_bbox = 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 */
@@ -937,4 +936,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 :