Code

Fix for bug #455302 and bug #165529, also partially fixes bounding box of various...
[inkscape.git] / src / display / nr-arena-image.cpp
index 4803228739ce51217085f242a73ddd7226da67e7..4939431689555e6ddb958a0caac58cbb0eaffc6f 100644 (file)
@@ -13,8 +13,9 @@
  */
 
 #include <libnr/nr-compose-transform.h>
+#include <2geom/transforms.h>
 #include <libnr/nr-blit.h>
-#include "../prefs-utils.h"
+#include "../preferences.h"
 #include "nr-arena-image.h"
 #include "style.h"
 #include "display/nr-arena.h"
@@ -23,7 +24,7 @@
 #include "sp-filter.h"
 #include "sp-filter-reference.h"
 #include "sp-gaussian-blur.h"
-#include "sp-feblend.h"
+#include "filters/blend.h"
 #include "display/nr-filter-blend.h"
 
 int nr_arena_image_x_sample = 1;
@@ -40,7 +41,7 @@ static void nr_arena_image_finalize (NRObject *object);
 
 static unsigned int nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset);
 static unsigned int nr_arena_image_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags);
-static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky);
+static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky);
 
 static NRArenaItemClass *parent_class;
 
@@ -88,7 +89,7 @@ nr_arena_image_init (NRArenaImage *image)
     image->width = 256.0;
     image->height = 256.0;
 
-    image->grid2px.set_identity();
+    image->grid2px.setIdentity();
 
     image->style = 0;
 }
@@ -106,16 +107,16 @@ nr_arena_image_finalize (NRObject *object)
 static unsigned int
 nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned int /*state*/, unsigned int /*reset*/ )
 {
-    NR::Matrix grid2px;
+    Geom::Matrix grid2px;
 
-    NRArenaImage *image = NR_ARENA_IMAGE (item);
+    // clear old bbox
+    nr_arena_item_request_render(item);
 
-    /* Request render old */
-    nr_arena_item_request_render (item);
+    NRArenaImage *image = NR_ARENA_IMAGE (item);
 
     /* Copy affine */
     grid2px = gc->transform.inverse();
-    double hscale, vscale; // todo: replace with NR::scale
+    double hscale, vscale; // todo: replace with Geom::Scale
     if (image->px) {
         hscale = image->pxw / image->width;
         vscale = image->pxh / image->height;
@@ -143,17 +144,17 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned
         bbox.x1 = image->x + image->width;
         bbox.y1 = image->y + image->height;
 
-        image->c00 = (NR::Point(bbox.x0, bbox.y0) * gc->transform);
-        image->c01 = (NR::Point(bbox.x0, bbox.y1) * gc->transform);
-        image->c10 = (NR::Point(bbox.x1, bbox.y0) * gc->transform);
-        image->c11 = (NR::Point(bbox.x1, bbox.y1) * gc->transform);
+        image->c00 = (Geom::Point(bbox.x0, bbox.y0) * gc->transform);
+        image->c01 = (Geom::Point(bbox.x0, bbox.y1) * gc->transform);
+        image->c10 = (Geom::Point(bbox.x1, bbox.y0) * gc->transform);
+        image->c11 = (Geom::Point(bbox.x1, bbox.y1) * gc->transform);
 
-        nr_rect_d_matrix_transform (&bbox, &bbox, &gc->transform);
+        nr_rect_d_matrix_transform (&bbox, &bbox, gc->transform);
 
-        item->bbox.x0 = (int) floor (bbox.x0);
-        item->bbox.y0 = (int) floor (bbox.y0);
-        item->bbox.x1 = (int) ceil (bbox.x1);
-        item->bbox.y1 = (int) ceil (bbox.y1);
+        item->bbox.x0 = static_cast<NR::ICoord>(floor(bbox.x0)); // Floor gives the coordinate in which the point resides
+        item->bbox.y0 = static_cast<NR::ICoord>(floor(bbox.y0));
+        item->bbox.x1 = static_cast<NR::ICoord>(ceil (bbox.x1)); // Ceil gives the first coordinate beyond the point
+        item->bbox.y1 = static_cast<NR::ICoord>(ceil (bbox.y1));
     } else {
         item->bbox.x0 = (int) gc->transform[4];
         item->bbox.y0 = (int) gc->transform[5];
@@ -161,8 +162,6 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned
         item->bbox.y1 = item->bbox.y0 - 1;
     }
 
-    nr_arena_item_request_render (item);
-
     return NR_ARENA_ITEM_STATE_ALL;
 }
 
@@ -172,14 +171,15 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned
 static unsigned int
 nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixBlock *pb, unsigned int /*flags*/ )
 {
-    nr_arena_image_x_sample = prefs_get_int_attribute ("options.bitmapoversample", "value", 1);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    nr_arena_image_x_sample = prefs->getInt("/options/bitmapoversample/value", 1);
     nr_arena_image_y_sample = nr_arena_image_x_sample;
 
     bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE);
 
     NRArenaImage *image = NR_ARENA_IMAGE (item);
 
-    NR::Matrix d2s;
+    Geom::Matrix d2s;
 
     d2s[0] = b2i[0];
     d2s[1] = b2i[1];
@@ -211,13 +211,7 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB
         } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
             nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
         } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) {
-
-            //FIXME: The _N_N_N_ version gives a gray border around images, see bug 906376
-            // This mode is only used when exporting, screen rendering always has _P_P_P_, so I decided to simply replace it for now
-            // Feel free to propose a better fix
-
-            //nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
-            nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
+            nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
         }
 
         pb->empty = FALSE;
@@ -227,7 +221,7 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB
         if (!ct)
             return item->state;
 
-        guint32 rgba = prefs_get_int_attribute("options.wireframecolors", "images", 0xff0000ff);
+        guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff);
         // FIXME: we use RGBA buffers but cairo writes BGRA (on i386), so we must cheat
         // by setting color channels in the "wrong" order
         cairo_set_source_rgba(ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba));
@@ -235,23 +229,23 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB
         cairo_set_line_width(ct, 0.5);
         cairo_new_path(ct);
 
-        NR::Point shift(pb->area.x0, pb->area.y0);
-        NR::Point c00 = image->c00 - shift;
-        NR::Point c01 = image->c01 - shift;
-        NR::Point c11 = image->c11 - shift;
-        NR::Point c10 = image->c10 - shift;
+        Geom::Point shift(pb->area.x0, pb->area.y0);
+        Geom::Point c00 = image->c00 - shift;
+        Geom::Point c01 = image->c01 - shift;
+        Geom::Point c11 = image->c11 - shift;
+        Geom::Point c10 = image->c10 - shift;
 
-        cairo_move_to (ct, c00[NR::X], c00[NR::Y]);
+        cairo_move_to (ct, c00[Geom::X], c00[Geom::Y]);
 
         // the box
-        cairo_line_to (ct, c10[NR::X], c10[NR::Y]);
-        cairo_line_to (ct, c11[NR::X], c11[NR::Y]);
-        cairo_line_to (ct, c01[NR::X], c01[NR::Y]);
-        cairo_line_to (ct, c00[NR::X], c00[NR::Y]);
+        cairo_line_to (ct, c10[Geom::X], c10[Geom::Y]);
+        cairo_line_to (ct, c11[Geom::X], c11[Geom::Y]);
+        cairo_line_to (ct, c01[Geom::X], c01[Geom::Y]);
+        cairo_line_to (ct, c00[Geom::X], c00[Geom::Y]);
         // the diagonals
-        cairo_line_to (ct, c11[NR::X], c11[NR::Y]);
-        cairo_move_to (ct, c10[NR::X], c10[NR::Y]);
-        cairo_line_to (ct, c01[NR::X], c01[NR::Y]);
+        cairo_line_to (ct, c11[Geom::X], c11[Geom::Y]);
+        cairo_move_to (ct, c10[Geom::X], c10[Geom::Y]);
+        cairo_line_to (ct, c01[Geom::X], c01[Geom::Y]);
 
         cairo_stroke(ct);
 
@@ -263,14 +257,14 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB
 
 /** Calculates the closest distance from p to the segment a1-a2*/
 double
-distance_to_segment (NR::Point p, NR::Point a1, NR::Point a2)
+distance_to_segment (Geom::Point p, Geom::Point a1, Geom::Point a2)
 {
     // calculate sides of the triangle and their squares
-    double d1 = NR::L2(p - a1);
+    double d1 = Geom::L2(p - a1);
     double d1_2 = d1 * d1;
-    double d2 = NR::L2(p - a2);
+    double d2 = Geom::L2(p - a2);
     double d2_2 = d2 * d2;
-    double a = NR::L2(a1 - a2);
+    double a = Geom::L2(a1 - a2);
     double a_2 = a * a;
 
     // if one of the angles at the base is > 90, return the corresponding side
@@ -283,7 +277,7 @@ distance_to_segment (NR::Point p, NR::Point a1, NR::Point a2)
 }
 
 static NRArenaItem *
-nr_arena_image_pick( NRArenaItem *item, NR::Point p, double delta, unsigned int /*sticky*/ )
+nr_arena_image_pick( NRArenaItem *item, Geom::Point p, double delta, unsigned int /*sticky*/ )
 {
     NRArenaImage *image = NR_ARENA_IMAGE (item);
 
@@ -311,9 +305,9 @@ nr_arena_image_pick( NRArenaItem *item, NR::Point p, double delta, unsigned int
         int const width = image->pxw;
         int const height = image->pxh;
         int const rowstride = image->pxrs;
-        NR::Point tp = p * image->grid2px;
-        int const ix = (int)(tp[NR::X]);
-        int const iy = (int)(tp[NR::Y]);
+        Geom::Point tp = p * image->grid2px;
+        int const ix = (int)(tp[Geom::X]);
+        int const iy = (int)(tp[Geom::Y]);
 
         if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height))
             return NULL;
@@ -367,7 +361,7 @@ void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style)
     if (style->filter.set && style->getFilter()) {
         if (!image->filter) {
             int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter()));
-            image->filter = new NR::Filter(primitives);
+            image->filter = new Inkscape::Filters::Filter(primitives);
         }
         sp_filter_build_renderer(SP_FILTER(style->getFilter()), image->filter);
     } else {
@@ -380,6 +374,8 @@ void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style)
         && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
         image->background_new = true;
     }
+
+    nr_arena_item_request_update(image, NR_ARENA_ITEM_STATE_ALL, FALSE);
 }