summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-04-10 01:49:27 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-04-10 01:49:27 +0000
commit05ec291fd2cd12474c33ee65f3fec03f18322527 (patch)
tree01a67f4a2e8d5ca6bcc02b95b03c4c74daa259c7 /src
parentInitialize cached patterns to NULL in NRStyle, should fix crashes (diff)
downloadinkscape-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.cpp5
-rw-r--r--src/display/nr-filter-gaussian.cpp6
-rw-r--r--src/display/nr-filter-image.cpp12
-rw-r--r--src/display/nr-filter-slot.cpp37
-rw-r--r--src/display/nr-filter-slot.h6
-rw-r--r--src/display/nr-filter-specularlighting.cpp5
-rw-r--r--src/display/nr-filter-turbulence.cpp6
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);