From: kiirala Date: Mon, 4 Jun 2007 17:22:12 +0000 (+0000) Subject: Modified filter rendering area handling to better accommodate upcoming feOffset X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=724821145d62dee9f97465c706952582da6e432d;p=inkscape.git Modified filter rendering area handling to better accommodate upcoming feOffset --- diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index b7ec966bb..b7ff825d2 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -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); } diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index ace41171d..ccbc018ef 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -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) diff --git a/src/display/nr-filter-gaussian.h b/src/display/nr-filter-gaussian.h index c6b0b72b9..d4f6c942c 100644 --- a/src/display/nr-filter-gaussian.h +++ b/src/display/nr-filter-gaussian.h @@ -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 diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index 890cb96fe..ec8364542 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -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) { diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 7c8018fe2..ac747cb55 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -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 diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index d8cfb2ecf..38ed3938a 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -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) diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index a6f71b9a5..baf23886e 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -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.