diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-04-10 01:49:27 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-04-10 01:49:27 +0000 |
| commit | 05ec291fd2cd12474c33ee65f3fec03f18322527 (patch) | |
| tree | 01a67f4a2e8d5ca6bcc02b95b03c4c74daa259c7 /src | |
| parent | Initialize cached patterns to NULL in NRStyle, should fix crashes (diff) | |
| download | inkscape-05ec291fd2cd12474c33ee65f3fec03f18322527.tar.gz inkscape-05ec291fd2cd12474c33ee65f3fec03f18322527.zip | |
Fix a rounding error that resulted in seams at some zoom levels when
rendering filters that use BackgroundImage.
(bzr r9508.1.81)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/nr-filter-diffuselighting.cpp | 5 | ||||
| -rw-r--r-- | src/display/nr-filter-gaussian.cpp | 6 | ||||
| -rw-r--r-- | src/display/nr-filter-image.cpp | 12 | ||||
| -rw-r--r-- | src/display/nr-filter-slot.cpp | 37 | ||||
| -rw-r--r-- | src/display/nr-filter-slot.h | 6 | ||||
| -rw-r--r-- | src/display/nr-filter-specularlighting.cpp | 5 | ||||
| -rw-r--r-- | src/display/nr-filter-turbulence.cpp | 6 |
7 files changed, 47 insertions, 30 deletions
diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp index e2954c3b1..0a46a5c86 100644 --- a/src/display/nr-filter-diffuselighting.cpp +++ b/src/display/nr-filter-diffuselighting.cpp @@ -128,9 +128,10 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot) cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); - NRRectL const &slot_area = slot.get_slot_area(); + Geom::Rect slot_area = slot.get_slot_area(); + Geom::Point p = slot_area.min(); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); - double x0 = slot_area.x0, y0 = slot_area.y0; + double x0 = p[Geom::X], y0 = p[Geom::Y]; double scale = surfaceScale * trans.descrim(); switch (light_type) { diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index fdffabfeb..326c37160 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -82,7 +82,7 @@ static inline Tt round_cast(Ts v) { static Ts const rndoffset(.5); return static_cast<Tt>(v+rndoffset); } - +/* template<> inline unsigned char round_cast(double v) { // This (fast) rounding method is based on: @@ -99,7 +99,7 @@ inline unsigned char round_cast(double v) { static double const rndoffset(.5); return static_cast<unsigned char>(v+rndoffset); #endif -} +}*/ template<typename Tt, typename Ts> static inline Tt clip_round_cast(Ts const v) { @@ -142,7 +142,7 @@ FilterGaussian::~FilterGaussian() static int _effect_area_scr(double const deviation) { - return (int)std::ceil(deviation * 3.0); + return (int)std::ceil(std::fabs(deviation) * 3.0); } static void diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index eea4f9781..0cb7901b3 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -91,11 +91,11 @@ void FilterImage::render_cairo(FilterSlot &slot) double scaleX = feImageWidth / area.width(); double scaleY = feImageHeight / area.height(); - NRRectL const &sa = slot.get_slot_area(); + Geom::Rect sa = slot.get_slot_area(); cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - sa.x1 - sa.x0, sa.y1 - sa.y0); + sa.width(), sa.height()); cairo_t *ct = cairo_create(out); - cairo_translate(ct, -sa.x0, -sa.y0); + cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]); ink_cairo_transform(ct, pu2pb); // we are now in primitive units cairo_translate(ct, feImageX, feImageY); cairo_scale(ct, scaleX, scaleY); @@ -179,12 +179,12 @@ void FilterImage::render_cairo(FilterSlot &slot) CAIRO_FORMAT_ARGB32, image->get_width(), image->get_height(), image->get_rowstride()); } - NRRectL const &sa = slot.get_slot_area(); + Geom::Rect sa = slot.get_slot_area(); cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - sa.x1 - sa.x0, sa.y1 - sa.y0); + sa.width(), sa.height()); cairo_t *ct = cairo_create(out); - cairo_translate(ct, -sa.x0, -sa.y0); + cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]); // now ct is in pb coordinates ink_cairo_transform(ct, slot.get_units().get_matrix_primitiveunits2pb()); // now ct is in the coordinates of feImageX etc. diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index 63f9dc1a6..ce07ff086 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -46,14 +46,18 @@ FilterSlot::FilterSlot(NRArenaItem *item, cairo_t *bgct, NRRectL const *bgarea, Geom::Point(_source_graphic_area->x1, _source_graphic_area->y1)); Geom::Affine trans = _units.get_matrix_display2pb(); - Geom::Rect bbox_trans = bbox * trans; Geom::Point min = bbox_trans.min(); - Geom::Point max = bbox_trans.max(); - _slot_area.x0 = floor(min[X]); - _slot_area.y0 = floor(min[Y]); - _slot_area.x1 = ceil(max[X]); - _slot_area.y1 = ceil(max[Y]); + _slot_x = min[X]; + _slot_y = min[Y]; + + if (trans.isTranslation()) { + _slot_w = _source_graphic_area->x1 - _source_graphic_area->x0; + _slot_h = _source_graphic_area->y1 - _source_graphic_area->y0; + } else { + _slot_w = ceil(bbox_trans.width()); + _slot_h = ceil(bbox_trans.height()); + } } FilterSlot::~FilterSlot() @@ -115,7 +119,7 @@ cairo_surface_t *FilterSlot::getcairo(int slot_nr) // create empty surface cairo_surface_t *empty = cairo_surface_create_similar( _source_graphic, cairo_surface_get_content(_source_graphic), - _slot_area.x1 - _slot_area.x0, _slot_area.y1 - _slot_area.y0); + _slot_w, _slot_h); _set_internal(slot_nr, empty); cairo_surface_destroy(empty); s = _slots.find(slot_nr); @@ -127,17 +131,17 @@ cairo_surface_t *FilterSlot::_get_transformed_source_graphic() { Geom::Affine trans = _units.get_matrix_display2pb(); - if (trans.isIdentity()) { + if (trans.isTranslation()) { cairo_surface_reference(_source_graphic); return _source_graphic; } cairo_surface_t *tsg = cairo_surface_create_similar( _source_graphic, cairo_surface_get_content(_source_graphic), - _slot_area.x1 - _slot_area.x0, _slot_area.y1 - _slot_area.y0); + _slot_w, _slot_h); cairo_t *tsg_ct = cairo_create(tsg); - cairo_translate(tsg_ct, -_slot_area.x0, -_slot_area.y0); + cairo_translate(tsg_ct, -_slot_x, -_slot_y); ink_cairo_transform(tsg_ct, trans); cairo_translate(tsg_ct, _source_graphic_area->x0, _source_graphic_area->y0); cairo_set_source_surface(tsg_ct, _source_graphic, 0, 0); @@ -155,10 +159,10 @@ cairo_surface_t *FilterSlot::_get_transformed_background() cairo_surface_t *bg = cairo_get_target(_background_ct); cairo_surface_t *tbg = cairo_surface_create_similar( bg, cairo_surface_get_content(bg), - _slot_area.x1 - _slot_area.x0, _slot_area.y1 - _slot_area.y0); + _slot_w, _slot_h); cairo_t *tbg_ct = cairo_create(tbg); - cairo_translate(tbg_ct, -_slot_area.x0, -_slot_area.y0); + cairo_translate(tbg_ct, -_slot_x, -_slot_y); ink_cairo_transform(tbg_ct, trans); cairo_translate(tbg_ct, _background_area->x0, _background_area->y0); cairo_set_source_surface(tbg_ct, bg, 0, 0); @@ -186,7 +190,7 @@ cairo_surface_t *FilterSlot::get_result(int res) cairo_translate(r_ct, -_source_graphic_area->x0, -_source_graphic_area->y0); ink_cairo_transform(r_ct, trans); - cairo_translate(r_ct, _slot_area.x0, _slot_area.y0); + cairo_translate(r_ct, _slot_x, _slot_y); cairo_set_source_surface(r_ct, getcairo(res), 0, 0); cairo_set_operator(r_ct, CAIRO_OPERATOR_SOURCE); cairo_paint(r_ct); @@ -237,6 +241,13 @@ int FilterSlot::get_blurquality(void) { return blurquality; } +Geom::Rect FilterSlot::get_slot_area() const { + Geom::Point p(_slot_x, _slot_y); + Geom::Point dim(_slot_w, _slot_h); + Geom::Rect r(p, p+dim); + return r; +} + } /* namespace Filters */ } /* namespace Inkscape */ diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index f477b7b73..3b08743ed 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -65,7 +65,7 @@ public: int get_blurquality(void); FilterUnits const &get_units() const { return _units; } - NRRectL const &get_slot_area() const { return _slot_area; } + Geom::Rect get_slot_area() const; NRRectL const &get_sg_area() const { return *_source_graphic_area; } private: @@ -76,7 +76,9 @@ private: //Geom::Rect _source_bbox; ///< bounding box of source graphic surface //Geom::Rect _intermediate_bbox; ///< bounding box of intermediate surfaces - NRRectL _slot_area; +// NRRectL _slot_area; + int _slot_w, _slot_h; + double _slot_x, _slot_y; cairo_surface_t *_source_graphic; cairo_t *_background_ct; NRRectL const *_source_graphic_area; diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp index e9e3f2b28..eddab36a1 100644 --- a/src/display/nr-filter-specularlighting.cpp +++ b/src/display/nr-filter-specularlighting.cpp @@ -140,9 +140,10 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot) cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); - NRRectL const &slot_area = slot.get_slot_area(); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); - double x0 = slot_area.x0, y0 = slot_area.y0; + Geom::Point p = slot.get_slot_area().min(); + double x0 = p[Geom::X]; + double y0 = p[Geom::Y]; double scale = surfaceScale * trans.descrim(); double ks = specularConstant; double se = specularExponent; diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index c1a3abd45..6aa435715 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -376,9 +376,11 @@ void FilterTurbulence::render_cairo(FilterSlot &slot) } Geom::Affine unit_trans = slot.get_units().get_matrix_primitiveunits2pb().inverse(); - NRRectL const &slot_area = slot.get_slot_area(); + Geom::Rect slot_area = slot.get_slot_area(); + double x0 = slot_area.min()[Geom::X]; + double y0 = slot_area.min()[Geom::Y]; - ink_cairo_surface_synthesize(out, Turbulence(*gen, unit_trans, slot_area.x0, slot_area.y0)); + ink_cairo_surface_synthesize(out, Turbulence(*gen, unit_trans, x0, y0)); cairo_surface_mark_dirty(out); |
