summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-08-19 07:33:48 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-08-19 07:33:48 +0000
commita49c525365ff86ea1e22281d3a3b66d7ef0087c1 (patch)
tree91c9f6d2b29fc5e1141835c560a44dd0a5a6bd89 /src
parentFix large memory leaks in the swatches panel (diff)
downloadinkscape-a49c525365ff86ea1e22281d3a3b66d7ef0087c1.tar.gz
inkscape-a49c525365ff86ea1e22281d3a3b66d7ef0087c1.zip
Fix rendering glitches appearing when filtered, cached groups have
filtered, cached children (bzr r10347.1.36)
Diffstat (limited to 'src')
-rw-r--r--src/display/drawing-group.cpp10
-rw-r--r--src/display/drawing-item.cpp20
-rw-r--r--src/display/drawing-surface.cpp33
-rw-r--r--src/display/drawing-surface.h1
-rw-r--r--src/display/nr-filter-units.cpp4
5 files changed, 48 insertions, 20 deletions
diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp
index 002a5a2d4..d9a75925e 100644
--- a/src/display/drawing-group.cpp
+++ b/src/display/drawing-group.cpp
@@ -57,7 +57,7 @@ DrawingGroup::setChildTransform(Geom::Affine const &new_trans)
if (_child_transform) {
current = *_child_transform;
}
-
+
if (!Geom::are_near(current, new_trans, NR_EPSILON)) {
// mark the area where the object was for redraw.
_markForRendering();
@@ -77,11 +77,11 @@ DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u
unsigned beststate = STATE_ALL;
bool outline = _drawing.outline();
+ UpdateContext child_ctx(ctx);
+ if (_child_transform) {
+ child_ctx.ctm = *_child_transform * ctx.ctm;
+ }
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
- UpdateContext child_ctx(ctx);
- if (_child_transform) {
- child_ctx.ctm = *_child_transform * ctx.ctm;
- }
i->update(area, child_ctx, flags, reset);
}
if (beststate & STATE_BBOX) {
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index 1195bc56c..c517b1bb5 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -370,8 +370,8 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne
// so this will not execute (cache score threshold must be positive)
cr.cache_size = _cacheRect()->area() * 4;
cr.item = this;
- _drawing._candidate_items.push_back(cr);
- _cache_iterator = --_drawing._candidate_items.end();
+ _drawing._candidate_items.push_front(cr);
+ _cache_iterator = _drawing._candidate_items.begin();
_has_cache_iterator = true;
}
@@ -462,7 +462,7 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
} else {
// There is no cache. This could be because caching of this item
// was just turned on after the last update phase, or because
- // we are outside of the canvas.
+ // we were previously outside of the canvas.
Geom::OptIntRect cl = _drawing.cacheLimit();
cl.intersectWith(_drawbox);
if (cl) {
@@ -515,9 +515,8 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
// 3. copy from cache to output
Inkscape::DrawingContext::Save save(ct);
ct.rectangle(*carea);
- ct.clip();
ct.setSource(_cache);
- ct.paint();
+ ct.fill();
// 4. mark as clean
_cache->markClean(*carea);
return;
@@ -591,14 +590,14 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
if (_cached && _cache) {
DrawingContext cachect(*_cache);
cachect.rectangle(*carea);
- cachect.clip();
cachect.setOperator(CAIRO_OPERATOR_SOURCE);
cachect.setSource(&intermediate);
- cachect.paint();
+ cachect.fill();
_cache->markClean(*carea);
}
+ ct.rectangle(*carea);
ct.setSource(&intermediate);
- ct.paint();
+ ct.fill();
ct.setSource(0,0,0,0);
// the call above is to clear a ref on the intermediate surface held by ct
}
@@ -735,7 +734,10 @@ DrawingItem::_markForRendering()
DrawingItem *bkg_root = NULL;
for (DrawingItem *i = this; i; i = i->_parent) {
- if (i->_cached && i->_cache) {
+ if (i != this && i->_filter) {
+ i->_filter->area_enlarge(*dirty, i);
+ }
+ if (i->_cache) {
i->_cache->markDirty(*dirty);
}
if (i->_background_accumulate) {
diff --git a/src/display/drawing-surface.cpp b/src/display/drawing-surface.cpp
index e5564f2b3..5cbfaa3fe 100644
--- a/src/display/drawing-surface.cpp
+++ b/src/display/drawing-surface.cpp
@@ -275,26 +275,51 @@ DrawingCache::paintFromCache(DrawingContext &ct, Geom::OptIntRect &area)
} else {
cairo_rectangle_int_t to_repaint;
cairo_region_get_extents(dirty_region, &to_repaint);
- *area = _convertRect(to_repaint);
+ area = _convertRect(to_repaint);
cairo_region_subtract_rectangle(cache_region, &to_repaint);
}
cairo_region_destroy(dirty_region);
if (!cairo_region_is_empty(cache_region)) {
- Inkscape::DrawingContext::Save save(ct);
int nr = cairo_region_num_rectangles(cache_region);
cairo_rectangle_int_t tmp;
for (int i = 0; i < nr; ++i) {
cairo_region_get_rectangle(cache_region, i, &tmp);
ct.rectangle(_convertRect(tmp));
}
- ct.clip();
ct.setSource(this);
- ct.paint();
+ ct.fill();
}
cairo_region_destroy(cache_region);
}
+// debugging utility
+void
+DrawingCache::_dumpCache(Geom::OptIntRect const &area)
+{
+ static int dumpnr = 0;
+ cairo_surface_t *surface = ink_cairo_surface_copy(_surface);
+ DrawingContext ct(surface, _origin);
+ if (!cairo_region_is_empty(_clean_region)) {
+ Inkscape::DrawingContext::Save save(ct);
+ int nr = cairo_region_num_rectangles(_clean_region);
+ cairo_rectangle_int_t tmp;
+ for (int i = 0; i < nr; ++i) {
+ cairo_region_get_rectangle(_clean_region, i, &tmp);
+ ct.rectangle(_convertRect(tmp));
+ }
+ ct.setSource(0,1,0,0.1);
+ ct.fill();
+ }
+ ct.rectangle(*area);
+ ct.setSource(1,0,0,0.1);
+ ct.fill();
+ char *fn = g_strdup_printf("dump%d.png", dumpnr++);
+ cairo_surface_write_to_png(surface, fn);
+ cairo_surface_destroy(surface);
+ g_free(fn);
+}
+
cairo_rectangle_int_t
DrawingCache::_convertRect(Geom::IntRect const &area)
{
diff --git a/src/display/drawing-surface.h b/src/display/drawing-surface.h
index f3af33002..e3637d402 100644
--- a/src/display/drawing-surface.h
+++ b/src/display/drawing-surface.h
@@ -72,6 +72,7 @@ protected:
Geom::IntRect _pending_area;
Geom::Affine _pending_transform;
private:
+ void _dumpCache(Geom::OptIntRect const &area);
static cairo_rectangle_int_t _convertRect(Geom::IntRect const &r);
static Geom::IntRect _convertRect(cairo_rectangle_int_t const &r);
};
diff --git a/src/display/nr-filter-units.cpp b/src/display/nr-filter-units.cpp
index a8686545a..baf4af45d 100644
--- a/src/display/nr-filter-units.cpp
+++ b/src/display/nr-filter-units.cpp
@@ -71,10 +71,10 @@ Geom::Affine FilterUnits::get_matrix_user2pb() const {
Geom::Affine u2pb = ctm;
if (paraller_axis || !automatic_resolution) {
- u2pb[0] = resolution_x / (filter_area->max()[X] - filter_area->min()[X]);
+ u2pb[0] = resolution_x / filter_area->width();
u2pb[1] = 0;
u2pb[2] = 0;
- u2pb[3] = resolution_y / (filter_area->max()[Y] - filter_area->min()[Y]);
+ u2pb[3] = resolution_y / filter_area->height();
u2pb[4] = ctm[4];
u2pb[5] = ctm[5];
}