Code

Modified filter rendering area handling to better accommodate upcoming feOffset
authorkiirala <kiirala@users.sourceforge.net>
Mon, 4 Jun 2007 17:22:12 +0000 (17:22 +0000)
committerkiirala <kiirala@users.sourceforge.net>
Mon, 4 Jun 2007 17:22:12 +0000 (17:22 +0000)
src/display/nr-arena-item.cpp
src/display/nr-filter-gaussian.cpp
src/display/nr-filter-gaussian.h
src/display/nr-filter-primitive.cpp
src/display/nr-filter-primitive.h
src/display/nr-filter.cpp
src/display/nr-filter.h

index b7ec966bb2fac5ec49b6823ee45464136b4a3dd6..b7ff825d28a98f61778a8eda13b63c3697ff8090 100644 (file)
@@ -319,7 +319,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
     if (nr_rect_l_test_empty (&carea))
         return item->state | NR_ARENA_ITEM_STATE_RENDER;
     if (item->filter && !outline) {
-        nr_rect_l_enlarge (&carea, item->filter->get_enlarge (item->ctm));
+        item->filter->area_enlarge (carea, item->ctm);
         nr_rect_l_intersect (&carea, &carea, &item->bbox);
     }
 
index ace41171d967facef80b30cb83d7f1fee5572e9f..ccbc018ef84b09da0e1b73aa4dd290b6536c54dc 100644 (file)
@@ -743,11 +743,17 @@ int FilterGaussian::render(FilterSlot &slot, Matrix const &trans)
     return 0;
 }
 
-int FilterGaussian::get_enlarge(Matrix const &trans)
+void FilterGaussian::area_enlarge(NRRectL &area, Matrix const &trans)
 {
     int area_x = _effect_area_scr(_deviation_x * trans.expansionX());
     int area_y = _effect_area_scr(_deviation_y * trans.expansionY());
-    return std::max(area_x, area_y);
+    // maximum is used because rotations can mix up these directions
+    // TODO: calculate a more tight-fitting rendering area
+    int area_max = std::max(area_x, area_y);
+    area.x0 -= area_max;
+    area.x1 += area_max;
+    area.y0 -= area_max;
+    area.y1 += area_max;
 }
 
 void FilterGaussian::set_deviation(double deviation)
index c6b0b72b962c5de540978a7d0523a9f54dc2fd1c..d4f6c942c373b1e88f132645470b5c42e25ca285 100644 (file)
@@ -18,6 +18,7 @@
 #include "display/nr-filter-slot.h"
 #include "libnr/nr-pixblock.h"
 #include "libnr/nr-matrix.h"
+#include "libnr/nr-rect-l.h"
 
 enum {
     BLUR_QUALITY_BEST = 2,
@@ -36,7 +37,7 @@ public:
     virtual ~FilterGaussian();
 
     virtual int render(FilterSlot &slot, Matrix const &trans);
-    virtual int get_enlarge(Matrix const &m);
+    virtual void area_enlarge(NRRectL &area, Matrix const &m);
 
     /**
      * Set the standard deviation value for gaussian blur. Deviation along
index 890cb96fe7ad81399c9c7a0422a24272373fc7a1..ec83645422b4d29a021b3055180e28d96a6c9e0c 100644 (file)
@@ -47,9 +47,9 @@ int FilterPrimitive::render(FilterSlot &slot, NRMatrix const *trans) {
     }
 }
 
-int FilterPrimitive::get_enlarge(Matrix const &m)
+void FilterPrimitive::area_enlarge(NRRectL &area, Matrix const &m)
 {
-    return 0;
+    // This doesn't need to do anything by default
 }
 
 void FilterPrimitive::set_input(int slot) {
index 7c8018fe2a40762747fe8219bbcb5078ae0897dc..ac747cb551d8b3c8e916548cbefd29357fb46b9b 100644 (file)
@@ -15,6 +15,7 @@
 #include "display/nr-filter-slot.h"
 #include "libnr/nr-pixblock.h"
 #include "libnr/nr-matrix.h"
+#include "libnr/nr-rect-l.h"
 #include "svg/svg-length.h"
 
 namespace NR {
@@ -26,7 +27,7 @@ public:
 
     int render(FilterSlot &slot, NRMatrix const *trans);
     virtual int render(FilterSlot &slot, Matrix const &trans) = 0;
-    virtual int get_enlarge(Matrix const &m);
+    virtual void area_enlarge(NRRectL &area, Matrix const &m);
 
     /**
      * Sets the input slot number 'slot' to be used as input in rendering
index d8cfb2ecf2c98261d06f08b0ee71cdd07f7d627f..38ed3938aec2b8818573ed66c7a349e621ac00a3 100644 (file)
@@ -241,16 +241,10 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
     return 0;
 }
 
-int Filter::get_enlarge(Matrix const &m)
-{
-    // Just sum the enlargement factor of all filter elements.
-    // TODO: this both sucks and blows for filters like feOffset
-    // -> ditch this method and design a better one...
-    int enlarge = 0;
-    for ( int i = 0 ; i < _primitive_count ; i++ ) {
-        if(_primitive[i]) enlarge += _primitive[i]->get_enlarge(m);
+void Filter::area_enlarge(NRRectL &bbox, Matrix const &m) {
+    for (int i = 0 ; i < _primitive_count ; i++) {
+        if (_primitive[i]) _primitive[i]->area_enlarge(bbox, m);
     }
-    return enlarge;
 }
 
 void Filter::bbox_enlarge(NRRectL &bbox)
index a6f71b9a56ca4d1f181ee36ca369b714d6c2943a..baf23886ebc7bc327aac100a34f29aa96191a4a4 100644 (file)
@@ -138,11 +138,13 @@ public:
     void set_primitive_units(SPFilterUnits unit);
 
     /** 
-     * Returns the amount of pixels the rendering area should be enlarged
-     * to prevent visual artefacts when filter needs to read pixels that
-     * are outside its output area (e.g. gaussian blur)
+     * Modifies the given area to accommodate for filters needing pixels
+     * outside the rendered area.
+     * When this function returns, area contains the area that needs
+     * to be rendered so that after filtering, the original area is
+     * drawn correctly.
      */
-    int get_enlarge(Matrix const &m);
+    void area_enlarge(NRRectL &area, Matrix const &m);
     /**
      * Given an object bounding box, this function enlarges it so that
      * it contains the filter effect area.