summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-08-06 13:38:28 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-08-06 13:38:28 +0000
commit42c8636a2c5814746c41f1452ffa7df99cf21367 (patch)
tree07cfd6d6d3766e252a6edfce0d1c7f9ff67cb1ba /src
parentRewrite NRArenaItem hierarchy into C++ (diff)
downloadinkscape-42c8636a2c5814746c41f1452ffa7df99cf21367.tar.gz
inkscape-42c8636a2c5814746c41f1452ffa7df99cf21367.zip
Document things figured out during the rewriting
(bzr r10347.1.22)
Diffstat (limited to 'src')
-rw-r--r--src/display/drawing-group.cpp11
-rw-r--r--src/display/drawing-image.cpp2
-rw-r--r--src/display/drawing-image.h2
-rw-r--r--src/display/drawing-item.cpp99
-rw-r--r--src/display/drawing-item.h2
-rw-r--r--src/display/drawing-shape.cpp6
-rw-r--r--src/display/drawing-shape.h2
-rw-r--r--src/display/drawing-text.cpp4
-rw-r--r--src/display/drawing-text.h4
9 files changed, 115 insertions, 17 deletions
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;
}
diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp
index ea6f6ce3c..879809cfa 100644
--- a/src/display/drawing-image.cpp
+++ b/src/display/drawing-image.cpp
@@ -196,7 +196,7 @@ distance_to_segment (Geom::Point const &p, Geom::Point const &a1, Geom::Point co
}
DrawingItem *
-DrawingImage::_pickItem(Geom::Point const &p, double delta)
+DrawingImage::_pickItem(Geom::Point const &p, double delta, bool /*sticky*/)
{
if (!_pixbuf) return NULL;
diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h
index 570c10360..d66395aab 100644
--- a/src/display/drawing-image.h
+++ b/src/display/drawing-image.h
@@ -38,7 +38,7 @@ protected:
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
virtual void _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags);
- virtual DrawingItem *_pickItem(Geom::Point const &p, double delta);
+ virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, bool sticky);
GdkPixbuf *_pixbuf;
cairo_surface_t *_surface;
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index 318ff28e7..caed08e6f 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -22,6 +22,26 @@
namespace Inkscape {
+/** @class DrawingItem
+ * @brief SVG drawing item for display.
+ *
+ * This was previously known as NRArenaItem. It represents the renderable
+ * portion of the SVG document. Typically this is created by the SP tree,
+ * in particular the show() virtual function.
+ *
+ * @section ObjectLifetime Object Lifetime
+ * Deleting a DrawingItem will cause all of its children to be deleted as well.
+ * This can lead to nasty surprises if you hold references to things
+ * which are children of what is being deleted. Therefore, in the SP tree,
+ * you always need to delete the item views of children before deleting
+ * the view of the parent. Do not call delete on things returned from show()
+ * - this will cause dangling pointers inside the SPItem and lead to a crash.
+ * Use the corresponing hide() method.
+ *
+ * Outside of the SP tree you should not use any references after the root node
+ * has been deleted.
+ */
+
DrawingItem::DrawingItem(Drawing *drawing)
: _drawing(drawing)
, _parent(NULL)
@@ -84,9 +104,8 @@ DrawingItem::~DrawingItem()
DrawingItem *
DrawingItem::parent() const
{
- //if (_clip_child || _mask_child)
- // return NULL;
-
+ // initially I wanted to return NULL if we are a clip or mask child,
+ // but the previous behavior was just to return the parent
return _parent;
}
@@ -106,6 +125,7 @@ DrawingItem::prependChild(DrawingItem *item)
_markForUpdate(STATE_ALL, false);
}
+/// Delete all regular children of this item (not mask or clip).
void
DrawingItem::clearChildren()
{
@@ -118,6 +138,7 @@ DrawingItem::clearChildren()
_children.clear_and_dispose(DeleteDisposer());
}
+/// Set the incremental transform for this item
void
DrawingItem::setTransform(Geom::Affine const &new_trans)
{
@@ -153,12 +174,14 @@ DrawingItem::setVisible(bool v)
_markForRendering();
}
+/// This is currently unused
void
DrawingItem::setSensitive(bool s)
{
_sensitive = s;
}
+/// Enable / disable storing the rendering in memory.
void
DrawingItem::setCached(bool c)
{
@@ -197,6 +220,8 @@ DrawingItem::setMask(DrawingItem *item)
_markForUpdate(STATE_ALL, true);
}
+/// Move this item to the given place in the Z order of siblings.
+/// Does nothing if the item has no parent.
void
DrawingItem::setZOrder(unsigned z)
{
@@ -217,6 +242,27 @@ DrawingItem::setItemBounds(Geom::OptRect const &bounds)
_item_bbox = bounds;
}
+/** @brief Update derived data before operations.
+ * The purpose of this call is to recompute internal data which depends
+ * on the attributes of the object, but is not directly settable by the user.
+ * Precomputing this data speeds up later rendering, because some items
+ * can be omitted.
+ *
+ * Currently this method handles updating the visual and geometric bounding boxes
+ * in pixels, storing the total transformation from item space to the screen
+ * and cache invalidation.
+ *
+ * @param area Area to which the update should be restricted. Only takes effect
+ * if the bounding box is known.
+ * @param ctx A structure to store cascading state.
+ * @param flags Which internal data should be recomputed. This can be any combination
+ * of StateFlags.
+ * @param reset State fields that should be reset before processing them. This is
+ * a means to force a recomputation of internal data even if the item
+ * considers it up to date. Mainly for internal use, such as
+ * propagating bunding box recomputation to children when the item's
+ * transform changes.
+ */
void
DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset)
{
@@ -315,6 +361,15 @@ struct MaskLuminanceToAlpha {
}
};
+/** @brief Rasterize items.
+ * This method submits the drawing opeartions required to draw this item
+ * to the supplied DrawingContext, restricting drawing the the specified area.
+ *
+ * This method does some common tasks and calls the item-specific rendering
+ * function, _renderItem(), to render e.g. paths or bitmaps.
+ *
+ * @param flags Rendering options. This deals mainly with cache control.
+ */
void
DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags)
{
@@ -490,6 +545,13 @@ DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsig
_drawing->outlinecolor = saved_rgba; // restore outline color
}
+/** @brief Rasterize the clipping path.
+ * This method submits drawing operations required to draw a basic filled shape
+ * of the item to the supplied drawing context. Rendering is limited to the
+ * given area. The rendering of the clipped object is composited into
+ * the result of this call using the IN operator. See the implementation
+ * of render() for details.
+ */
void
DrawingItem::clip(Inkscape::DrawingContext &ct, Geom::IntRect const &area)
{
@@ -523,6 +585,16 @@ DrawingItem::clip(Inkscape::DrawingContext &ct, Geom::IntRect const &area)
}
}
+/** @brief Get the item under the specified point.
+ * Searches the tree for the first item in the Z-order which is closer than
+ * @a delta to the given point. The pick should be visual - for example
+ * an object with a thick stroke should pick on the entire area of the stroke.
+ * @param p Search point
+ * @param delta Maximum allowed distance from the point
+ * @param sticky Whether the pick should ignore visibility and sensitivity.
+ * When false, only visible and sensitive objects are considered.
+ * When true, invisible and insensitive objects can also be picked.
+ */
DrawingItem *
DrawingItem::pick(Geom::Point const &p, double delta, bool sticky)
{
@@ -544,6 +616,11 @@ DrawingItem::pick(Geom::Point const &p, double delta, bool sticky)
return NULL;
}
+/** Marks the current visual bounding box of the item for redrawing.
+ * This is called whenever the object changes its visible appearance.
+ * For some cases (such as setting opacity) this is enough, but for others
+ * _markForUpdate() also needs to be called.
+ */
void
DrawingItem::_markForRendering()
{
@@ -561,10 +638,24 @@ DrawingItem::_markForRendering()
nr_arena_request_render_rect (_drawing, dirty);
}
+/** @brief Marks the item as needing a recomputation of internal data.
+ *
+ * This mechanism avoids traversing the entire rendering tree (which could be vast)
+ * on every trivial state changed in any item. Only items marked as needing
+ * an update (having some bits in their _state unset) will be traversed
+ * during the update call.
+ *
+ * The _propagate variable is another optimization. We use it to specify that
+ * all children should also have the corresponding flags unset before checking
+ * whether they need to be traversed. This way there is one less traversal
+ * of the tree. Without this we would need to unset state bits in all children.
+ * With _propagate we do this during the update call, when we have to traverse
+ * the tree anyway.
+ */
void
DrawingItem::_markForUpdate(unsigned flags, bool propagate)
{
- // here we can't simply assign because a previous markForUpdate call
+ // we can't simply assign because a previous markForUpdate call
// could have had propagate=true even if this one has propagate=false
if (propagate)
_propagate = true;
diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h
index b34ddf0e4..87b9ba048 100644
--- a/src/display/drawing-item.h
+++ b/src/display/drawing-item.h
@@ -109,7 +109,7 @@ protected:
unsigned flags, unsigned reset) { return 0; }
virtual void _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) {}
virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area) {}
- virtual DrawingItem *_pickItem(Geom::Point const &p, double delta) { return NULL; }
+ virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, bool sticky) { return NULL; }
virtual bool _canClip() { return false; }
Drawing *_drawing;
diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp
index 1a56eea9b..602aa2515 100644
--- a/src/display/drawing-shape.cpp
+++ b/src/display/drawing-shape.cpp
@@ -232,13 +232,13 @@ DrawingShape::_clipItem(DrawingContext &ct, Geom::IntRect const &area)
}
DrawingItem *
-DrawingShape::_pickItem(Geom::Point const &p, double delta)
+DrawingShape::_pickItem(Geom::Point const &p, double delta, bool /*sticky*/)
{
if (_repick_after > 0)
--_repick_after;
- if (_repick_after > 0) // we are a slow, huge path. skip this pick, returning what was returned last time
- return _last_pick;
+ if (_repick_after > 0) // we are a slow, huge path
+ return _last_pick; // skip this pick, returning what was returned last time
if (!_curve) return NULL;
if (!_style) return NULL;
diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h
index 7fd16374e..4b7b75e2a 100644
--- a/src/display/drawing-shape.h
+++ b/src/display/drawing-shape.h
@@ -36,7 +36,7 @@ protected:
unsigned flags, unsigned reset);
virtual void _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags);
virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area);
- virtual DrawingItem *_pickItem(Geom::Point const &p, double delta);
+ virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, bool sticky);
virtual bool _canClip();
SPCurve *_curve;
diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp
index 784888bd7..e03a91b39 100644
--- a/src/display/drawing-text.cpp
+++ b/src/display/drawing-text.cpp
@@ -102,7 +102,7 @@ DrawingGlyphs::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
}
DrawingItem *
-DrawingGlyphs::_pickItem(Geom::Point const &p, double delta)
+DrawingGlyphs::_pickItem(Geom::Point const &p, double delta, bool /*sticky*/)
{
if (!_font || !_bbox) return NULL;
@@ -248,7 +248,7 @@ DrawingText::_clipItem(DrawingContext &ct, Geom::IntRect const &area)
}
DrawingItem *
-DrawingText::_pickItem(Geom::Point const &p, double delta)
+DrawingText::_pickItem(Geom::Point const &p, double delta, bool /*sticky*/)
{
DrawingItem *picked = DrawingGroup::_pickItem(p, delta);
if (picked) return this;
diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h
index 58fecc067..f95a5073c 100644
--- a/src/display/drawing-text.h
+++ b/src/display/drawing-text.h
@@ -32,7 +32,7 @@ public:
protected:
unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
- virtual DrawingItem *_pickItem(Geom::Point const &p, double delta);
+ virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, bool sticky);
Geom::Affine *_glyph_transform;
font_instance *_font;
@@ -59,7 +59,7 @@ protected:
unsigned flags, unsigned reset);
virtual void _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags);
virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area);
- virtual DrawingItem *_pickItem(Geom::Point const &p, double delta);
+ virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, bool sticky);
virtual bool _canClip();
Geom::OptRect _paintbox;