Code

Fixed SVG compliance problems with feMorphology (bug 181995 at least)
[inkscape.git] / src / display / sp-canvas.cpp
index 88a4574907c2fba5a1d448b5877a3742cce0f5b2..9cc37a1a0c5b6b1c5a885b3a33d737a1b828164b 100644 (file)
 #include <libnr/nr-matrix-ops.h>
 #include <libnr/nr-convex-hull.h>
 #include "prefs-utils.h"
-#include "box3d-context.h"
 #include "inkscape.h"
 #include "sodipodi-ctrlrect.h"
 #if ENABLE_LCMS
 #include "color-profile-fns.h"
 #endif // ENABLE_LCMS
+#include "display/rendermode.h"
 
 // Define this to visualize the regions to be redrawn
 //#define DEBUG_REDRAW 1;
 // If any part of it is dirtied, the entire tile is dirtied (its int is nonzero) and repainted.
 #define TILE_SIZE 16
 
-enum {
-    RENDERMODE_NORMAL,
-    RENDERMODE_NOAA,
-    RENDERMODE_OUTLINE
-};
-
 static gint const sp_canvas_update_priority = G_PRIORITY_HIGH_IDLE;
 
 #define SP_CANVAS_WINDOW(c) (((GtkWidget *) (c))->window)
@@ -682,25 +676,25 @@ static SPCanvasItemClass *group_parent_class;
 /**
  * Registers SPCanvasGroup class with Gtk and returns its type number.
  */
-GtkType
-sp_canvas_group_get_type (void)
+GType sp_canvas_group_get_type(void)
 {
-    static GtkType group_type = 0;
-
-    if (!group_type) {
-        static GtkTypeInfo const group_info = {
-            "SPCanvasGroup",
-            sizeof (SPCanvasGroup),
-            sizeof (SPCanvasGroupClass),
-            (GtkClassInitFunc) sp_canvas_group_class_init,
-            (GtkObjectInitFunc) sp_canvas_group_init,
-            NULL, NULL, NULL
+    static GType type = 0;
+    if (!type) {
+        GTypeInfo info = {
+            sizeof(SPCanvasGroupClass),
+            0, // base_init
+            0, // base_finalize
+            (GClassInitFunc)sp_canvas_group_class_init,
+            0, // class_finalize
+            0, // class_data
+            sizeof(SPCanvasGroup),
+            0, // n_preallocs
+            (GInstanceInitFunc)sp_canvas_group_init,
+            0 // value_table
         };
-
-        group_type = gtk_type_unique (sp_canvas_item_get_type (), &group_info);
+        type = g_type_register_static(sp_canvas_item_get_type(), "SPCanvasGroup", &info, static_cast<GTypeFlags>(0));
     }
-
-    return group_type;
+    return type;
 }
 
 /**
@@ -938,25 +932,25 @@ static int do_update (SPCanvas *canvas);
  *
  * \return The type ID of the SPCanvas class.
  **/
-GtkType
-sp_canvas_get_type (void)
-{
-    static GtkType canvas_type = 0;
-
-    if (!canvas_type) {
-        static GtkTypeInfo const canvas_info = {
-            "SPCanvas",
-            sizeof (SPCanvas),
-            sizeof (SPCanvasClass),
-            (GtkClassInitFunc) sp_canvas_class_init,
-            (GtkObjectInitFunc) sp_canvas_init,
-            NULL, NULL, NULL
+GType sp_canvas_get_type(void)
+{
+    static GType type = 0;
+    if (!type) {
+        GTypeInfo info = {
+            sizeof(SPCanvasClass),
+            0, // base_init
+            0, // base_finalize
+            (GClassInitFunc)sp_canvas_class_init,
+            0, // class_finalize
+            0, // class_data
+            sizeof(SPCanvas),
+            0, // n_preallocs
+            (GInstanceInitFunc)sp_canvas_init,
+            0 // value_table
         };
-
-        canvas_type = gtk_type_unique (GTK_TYPE_WIDGET, &canvas_info);
+        type = g_type_register_static(GTK_TYPE_WIDGET, "SPCanvas", &info, static_cast<GTypeFlags>(0));
     }
-
-    return canvas_type;
+    return type;
 }
 
 /**
@@ -1152,6 +1146,10 @@ sp_canvas_unrealize (GtkWidget *widget)
 {
     SPCanvas *canvas = SP_CANVAS (widget);
 
+    canvas->current_item = NULL;
+    canvas->grabbed_item = NULL;
+    canvas->focused_item = NULL;
+
     shutdown_transients (canvas);
 
     gdk_gc_destroy (canvas->pixmap_gc);
@@ -1545,6 +1543,9 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event)
     if (event->window != SP_CANVAS_WINDOW (canvas))
         return FALSE;
 
+    if (canvas->pixmap_gc == NULL) // canvas being deleted
+        return FALSE;
+
     if (canvas->grabbed_event_mask & GDK_POINTER_MOTION_HINT_MASK) {
         gint x, y;
         gdk_window_get_pointer (widget->window, &x, &y, NULL);
@@ -1564,7 +1565,7 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1,
     GtkWidget *widget = GTK_WIDGET (canvas);
 
     SPCanvasBuf buf;
-    if (canvas->rendermode != RENDERMODE_OUTLINE) {
+    if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) {
         buf.buf = nr_pixelstore_256K_new (FALSE, 0);
     } else {
         buf.buf = nr_pixelstore_1M_new (FALSE, 0);
@@ -1656,7 +1657,7 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1,
                                       x0 - canvas->x0, y0 - canvas->y0);
     }
 
-    if (canvas->rendermode != RENDERMODE_OUTLINE) {
+    if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) {
         nr_pixelstore_256K_free (buf.buf);
     } else {
         nr_pixelstore_1M_free (buf.buf);
@@ -1747,7 +1748,8 @@ faster.
 The default for now is the strips mode.
 */
     if (bw < bh || bh < 2 * TILE_SIZE) {
-        int mid = (this_rect.x0 + this_rect.x1) / 2;
+        // to correctly calculate the mean of two ints, we need to sum them into a larger int type
+        int mid = ((long long) this_rect.x0 + (long long) this_rect.x1) / 2;
         // Make sure that mid lies on a tile boundary
         mid = (mid / TILE_SIZE) * TILE_SIZE;
 
@@ -1763,7 +1765,8 @@ The default for now is the strips mode.
                 && sp_canvas_paint_rect_internal(setup, lo);
         }
     } else {
-        int mid = (this_rect.y0 + this_rect.y1) / 2;
+        // to correctly calculate the mean of two ints, we need to sum them into a larger int type
+        int mid = ((long long) this_rect.y0 + (long long) this_rect.y1) / 2;
         // Make sure that mid lies on a tile boundary
         mid = (mid / TILE_SIZE) * TILE_SIZE;
 
@@ -1825,7 +1828,7 @@ sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1)
     setup.mouse_loc = sp_canvas_window_to_world (canvas, NR::Point(x,y));
 
     // CAIRO FIXME: the sw/sh calculations below all assume 24bpp, need fixing for 32bpp
-    if (canvas->rendermode != RENDERMODE_OUTLINE) {
+    if (canvas->rendermode != Inkscape::RENDERMODE_OUTLINE) {
         // use 256K as a compromise to not slow down gradients
         // 256K is the cached buffer and we need 3 channels
         setup.max_pixels = 87381; // 256K/3
@@ -2014,7 +2017,7 @@ paint (SPCanvas *canvas)
 static int
 do_update (SPCanvas *canvas)
 {
-    if (!canvas->root) // canvas may have already be destroyed by closing desktop durring interrupted display!
+    if (!canvas->root || !canvas->pixmap_gc) // canvas may have already be destroyed by closing desktop durring interrupted display!
         return TRUE;
 
     /* Cause the update if necessary */
@@ -2115,15 +2118,6 @@ sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear,
     } else {
         // scrolling as part of zoom; do nothing here - the next do_update will perform full redraw
     }
-
-    /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
-    SPEventContext *ec = inkscape_active_event_context();
-    if (SP_IS_BOX3D_CONTEXT (ec)) {
-        // We could avoid redraw during panning by checking the status of is_scrolling, but this is
-        // neither faster nor does it get rid of artefacts, so we update PLs unconditionally
-        Box3DContext *bc = SP_BOX3D_CONTEXT (ec);
-        bc->_vpdrag->updateLines();
-    }
 }
 
 /**