From 4dd33aa4d5c57706c7f64f63391174954160a308 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 6 Aug 2011 14:18:32 +0200 Subject: Rewrite NRArenaItem hierarchy into C++ (bzr r10347.1.21) --- src/display/drawing-group.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/display/drawing-group.cpp (limited to 'src/display/drawing-group.cpp') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp new file mode 100644 index 000000000..2d40f0a83 --- /dev/null +++ b/src/display/drawing-group.cpp @@ -0,0 +1,141 @@ +/** + * @file + * @brief Group belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiƄski + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/cairo-utils.h" +#include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "display/drawing-group.h" +#include "libnr/nr-values.h" +#include "nr-arena.h" +#include "style.h" + +namespace Inkscape { + +DrawingGroup::DrawingGroup(Drawing *drawing) + : DrawingItem(drawing) + , _style(NULL) + , _child_transform(NULL) +{} + +DrawingGroup::~DrawingGroup() +{ + if (_style) + sp_style_unref(_style); +} + +void +DrawingGroup::setPickChildren(bool p) +{ + _pick_children = p; +} + +void +DrawingGroup::setStyle(SPStyle *style) +{ + _setStyleCommon(_style, style); +} + +void +DrawingGroup::setChildTransform(Geom::Affine const &new_trans) +{ + Geom::Affine current; + 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(); + if (new_trans.isIdentity()) { + delete _child_transform; // delete NULL; is safe + _child_transform = NULL; + } else { + _child_transform = new Geom::Affine(new_trans); + } + _markForUpdate(STATE_ALL, true); + } +} + +unsigned +DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + unsigned beststate = STATE_ALL; + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + 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) { + _bbox = Geom::OptIntRect(); + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + if (i->visible()) { + _bbox.unionWith(outline ? i->geometricBounds() : i->visualBounds()); + } + } + } + return beststate; +} + +void +DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->render(ct, area, flags); + } +} + +void +DrawingGroup::_clipItem(DrawingContext &ct, Geom::IntRect const &area) +{ + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->clip(ct, area); + } +} + +DrawingItem * +DrawingGroup::_pickItem(Geom::Point const &p, double delta) +{ + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingItem *picked = i->pick(p, delta, false); + if (picked) { + return _pick_children ? picked : this; + } + } + return NULL; +} + +bool +DrawingGroup::_canClip() +{ + return true; +} + +bool is_drawing_group(DrawingItem *item) +{ + return dynamic_cast(item) != NULL; +} + +} // end namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 42c8636a2c5814746c41f1452ffa7df99cf21367 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 6 Aug 2011 15:38:28 +0200 Subject: Document things figured out during the rewriting (bzr r10347.1.22) --- src/display/drawing-group.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/display/drawing-group.cpp') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index 2d40f0a83..feaa7622a 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -31,6 +31,9 @@ DrawingGroup::~DrawingGroup() sp_style_unref(_style); } +/** @brief Set whether the group returns children from pick calls. + * Previously this feature was called "transparent groups". + */ void DrawingGroup::setPickChildren(bool p) { @@ -43,6 +46,10 @@ DrawingGroup::setStyle(SPStyle *style) _setStyleCommon(_style, style); } +/** @brief Set additional transform for the group. + * This is applied after the normal transform and mainly useful for + * markers, clipping paths, etc. + */ void DrawingGroup::setChildTransform(Geom::Affine const &new_trans) { @@ -105,10 +112,10 @@ DrawingGroup::_clipItem(DrawingContext &ct, Geom::IntRect const &area) } DrawingItem * -DrawingGroup::_pickItem(Geom::Point const &p, double delta) +DrawingGroup::_pickItem(Geom::Point const &p, double delta, bool sticky) { for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - DrawingItem *picked = i->pick(p, delta, false); + DrawingItem *picked = i->pick(p, delta, sticky); if (picked) { return _pick_children ? picked : this; } -- cgit v1.2.3 From 75976ea07dba9b97186667524d0a76603de416af Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 7 Aug 2011 12:53:12 +0200 Subject: Rewrite NRArena -> Inkscape::Drawing. Call render and update methods on the Drawing rather than on the root DrawingItem. (bzr r10347.1.25) --- src/display/drawing-group.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/display/drawing-group.cpp') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index feaa7622a..38ab73ca2 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -10,16 +10,16 @@ */ #include "display/cairo-utils.h" +#include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-item.h" #include "display/drawing-group.h" #include "libnr/nr-values.h" -#include "nr-arena.h" #include "style.h" namespace Inkscape { -DrawingGroup::DrawingGroup(Drawing *drawing) +DrawingGroup::DrawingGroup(Drawing &drawing) : DrawingItem(drawing) , _style(NULL) , _child_transform(NULL) @@ -75,7 +75,7 @@ unsigned DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) { unsigned beststate = STATE_ALL; - bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + bool outline = _drawing.outline(); for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { UpdateContext child_ctx(ctx); -- cgit v1.2.3 From caa510445fc091c63e1ca0ff8f44f2e81ae0638d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 13 Aug 2011 20:30:30 +0200 Subject: More generic handling of child type in DrawingItem. Fix clip object selection bug (LP #365458). Fixed bugs: - https://launchpad.net/bugs/365458 (bzr r10347.1.31) --- src/display/drawing-group.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/display/drawing-group.cpp') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index 38ab73ca2..002a5a2d4 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -112,10 +112,10 @@ DrawingGroup::_clipItem(DrawingContext &ct, Geom::IntRect const &area) } DrawingItem * -DrawingGroup::_pickItem(Geom::Point const &p, double delta, bool sticky) +DrawingGroup::_pickItem(Geom::Point const &p, double delta, unsigned flags) { for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - DrawingItem *picked = i->pick(p, delta, sticky); + DrawingItem *picked = i->pick(p, delta, flags); if (picked) { return _pick_children ? picked : this; } -- cgit v1.2.3 From a49c525365ff86ea1e22281d3a3b66d7ef0087c1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 19 Aug 2011 09:33:48 +0200 Subject: Fix rendering glitches appearing when filtered, cached groups have filtered, cached children (bzr r10347.1.36) --- src/display/drawing-group.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/display/drawing-group.cpp') 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) { -- cgit v1.2.3 From 0fc028f7050c91bfdb1a50ba8cb6462b2bf03d57 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 21 Aug 2011 17:33:09 +0200 Subject: Filter background rendering now matches the SVG specification. (bzr r10347.1.37) --- src/display/drawing-group.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/display/drawing-group.cpp') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index d9a75925e..a678c3feb 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -95,12 +95,29 @@ DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u return beststate; } -void -DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +unsigned +DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) { - for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - i->render(ct, area, flags); + if (stop_at == NULL) { + // normal rendering + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->render(ct, area, flags, stop_at); + } + } else { + // background rendering + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + if (&*i == stop_at) return RENDER_OK; // do not render the stop_at item at all + if (i->isAncestorOf(stop_at)) { + // render its ancestors without masks, opacity or filters + i->render(ct, area, flags | RENDER_FILTER_BACKGROUND, stop_at); + // stop further rendering + return RENDER_OK; + } else { + i->render(ct, area, flags, stop_at); + } + } } + return RENDER_OK; } void -- cgit v1.2.3