Code

Patch from codedread. Prevents rendering of title/desc/metadata elements in text...
[inkscape.git] / src / display / nr-filter.cpp
index 2e973b4ec9d258b0f928ed912c6fb0d7c4ab77ba..f7a04fd50383541d17dbd62f395b26ff993299a5 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <glib.h>
 #include <cmath>
+#include <cstring>
+#include <string>
 
 #include "display/nr-filter.h"
 #include "display/nr-filter-primitive.h"
@@ -44,7 +46,7 @@
 #include "libnr/nr-scale.h"
 #include "svg/svg-length.h"
 #include "sp-filter-units.h"
-#if defined (SOLARIS_2_8)
+#if defined (SOLARIS) && (SOLARIS == 8)
 #include "round.h"
 using Inkscape::round;
 #endif 
@@ -104,16 +106,35 @@ Filter::~Filter()
 
 int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
 {
-    if(!_primitive[0]) {
+    if (!_primitive[0]) {
         // TODO: Should clear the input buffer instead of just returning
-       return 0
+       return 1
     }
 
-    Matrix trans = *item->ctm;
+    Matrix trans = item->ctm;
     FilterSlot slot(_slot_count, item);
 
-    Rect item_bbox = *item->item_bbox;
+    Rect item_bbox;
+    try {
+        item_bbox = *item->item_bbox;
+    } catch (NR::IsNothing) {
+        // Bounding box might not exist, so create a dummy one.
+        Point zero(0, 0);
+        item_bbox = Rect(zero, zero);
+    }
+    if (item_bbox.min()[X] > item_bbox.max()[X]
+        || item_bbox.min()[Y] > item_bbox.max()[Y])
+    {
+        // Code below assumes non-negative size.
+        return 1;
+    }
+
     Rect filter_area = filter_effect_area(item_bbox);
+    if (item_bbox.isEmpty()) {
+        // It's no use to try and filter an empty object.
+        return 1;
+    }
+        
     FilterUnits units(_filter_units, _primitive_units);
     units.set_ctm(trans);
     units.set_item_bbox(item_bbox);
@@ -157,7 +178,7 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
 
     NRPixBlock *in = new NRPixBlock;
     nr_pixblock_setup_fast(in, pb->mode, pb->area.x0, pb->area.y0,
-                           pb->area.x1, pb->area.y1, false);
+                           pb->area.x1, pb->area.y1, true);
     if (in->size != NR_PIXBLOCK_SIZE_TINY && in->data.px == NULL) {
         g_warning("NR::Filter::render: failed to reserve temporary buffer");
         return 0;
@@ -177,11 +198,8 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
     }
     in = NULL; // in is now handled by FilterSlot, we should not touch it
 
-    // TODO: filters may need both filterUnits and primitiveUnits,
-    // so we should pass FilterUnits to render method, not just one Matrix
-    Matrix primitiveunits2pixblock = units.get_matrix_primitiveunits2pb();
     for (int i = 0 ; i < _primitive_count ; i++) {
-        _primitive[i]->render(slot, primitiveunits2pixblock);
+        _primitive[i]->render(slot, units);
     }
 
     slot.get_final(_output_slot, pb);
@@ -200,6 +218,10 @@ void Filter::area_enlarge(NRRectL &bbox, Matrix const &m) {
 }
 
 void Filter::bbox_enlarge(NRRectL &bbox) {
+    // Modifying empty bounding boxes confuses rest of the renderer, so
+    // let's not do that.
+    if (bbox.x0 > bbox.x1 || bbox.y0 > bbox.y1) return;
+
     /* TODO: this is wrong. Should use bounding box in user coordinates
      * and find its extents in display coordinates. */
     Point min(bbox.x0, bbox.y0);