diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-08-19 07:33:48 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-08-19 07:33:48 +0000 |
| commit | a49c525365ff86ea1e22281d3a3b66d7ef0087c1 (patch) | |
| tree | 91c9f6d2b29fc5e1141835c560a44dd0a5a6bd89 /src | |
| parent | Fix large memory leaks in the swatches panel (diff) | |
| download | inkscape-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.cpp | 10 | ||||
| -rw-r--r-- | src/display/drawing-item.cpp | 20 | ||||
| -rw-r--r-- | src/display/drawing-surface.cpp | 33 | ||||
| -rw-r--r-- | src/display/drawing-surface.h | 1 | ||||
| -rw-r--r-- | src/display/nr-filter-units.cpp | 4 |
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]; } |
