diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-08-06 12:18:32 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-08-06 12:18:32 +0000 |
| commit | 4dd33aa4d5c57706c7f64f63391174954160a308 (patch) | |
| tree | b9d4ea1278348836a718c5e6aaeaff9f82c790bf /src | |
| parent | Per-item render cache. (diff) | |
| download | inkscape-4dd33aa4d5c57706c7f64f63391174954160a308.tar.gz inkscape-4dd33aa4d5c57706c7f64f63391174954160a308.zip | |
Rewrite NRArenaItem hierarchy into C++
(bzr r10347.1.21)
Diffstat (limited to 'src')
98 files changed, 2919 insertions, 3986 deletions
diff --git a/src/2geom/affine.cpp b/src/2geom/affine.cpp index 2a1f18d77..c31b9ba90 100644 --- a/src/2geom/affine.cpp +++ b/src/2geom/affine.cpp @@ -410,6 +410,9 @@ Affine &Affine::operator*=(Affine const &o) { } //TODO: What's this!?! +/** Given a matrix m such that unit_circle = m*x, this returns the + * quadratic form x*A*x = 1. + * @relates Affine */ Affine elliptic_quadratic_form(Affine const &m) { double od = m[0] * m[1] + m[2] * m[3]; Affine ret (m[0]*m[0] + m[1]*m[1], od, @@ -469,6 +472,15 @@ Eigen::Eigen(double m[2][2]) { vectors[i] = Point(0,0); } +/** @brief Nearness predicate for affine transforms + * @returns True if all entries of matrices are within eps of each other */ +bool are_near(Affine const &a, Affine const &b, Coord eps) +{ + return are_near(a[0], b[0], eps) && are_near(a[1], b[1], eps) && + are_near(a[2], b[2], eps) && are_near(a[3], b[3], eps) && + are_near(a[4], b[4], eps) && are_near(a[5], b[5], eps); +} + } //namespace Geom /* diff --git a/src/2geom/affine.h b/src/2geom/affine.h index d7a7a0692..22f8bd9f5 100644 --- a/src/2geom/affine.h +++ b/src/2geom/affine.h @@ -200,9 +200,8 @@ inline std::ostream &operator<< (std::ostream &out_file, const Geom::Affine &m) return out_file; } -/** Given a matrix m such that unit_circle = m*x, this returns the - * quadratic form x*A*x = 1. - * @relates Affine */ +// Affine factories +Affine from_basis(const Point x_basis, const Point y_basis, const Point offset=Point(0,0)); Affine elliptic_quadratic_form(Affine const &m); /** Given a matrix (ignoring the translation) this returns the eigen @@ -215,9 +214,6 @@ public: Eigen(double M[2][2]); }; -// Affine factories -Affine from_basis(const Point x_basis, const Point y_basis, const Point offset=Point(0,0)); - /** @brief Create an identity matrix. * This is a convenience function identical to Affine::identity(). */ inline Affine identity() { @@ -239,6 +235,8 @@ inline Affine Affine::identity() { return ret; // allow NRVO } +bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON); + } // end namespace Geom #endif // LIB2GEOM_SEEN_AFFINE_H diff --git a/src/2geom/coord.h b/src/2geom/coord.h index f7bf2c5d0..90e776665 100644 --- a/src/2geom/coord.h +++ b/src/2geom/coord.h @@ -34,6 +34,7 @@ #include <cmath> #include <limits> +#include <boost/operators.hpp> #include <2geom/forward.h> namespace Geom { @@ -62,6 +63,9 @@ inline bool rel_error_bound(Coord a, Coord b, double eps=EPSILON) { return a <= template <typename C> struct CoordTraits {}; +// NOTE: operator helpers for Rect and Interval are defined here. +// This is to avoid increasing their size through multiple inheritance. + template<> struct CoordTraits<IntCoord> { typedef IntPoint PointType; @@ -69,6 +73,22 @@ struct CoordTraits<IntCoord> { typedef OptIntInterval OptIntervalType; typedef IntRect RectType; typedef OptIntRect OptRectType; + + typedef + boost::equality_comparable< IntervalType + , boost::additive< IntervalType + , boost::additive< IntervalType, IntCoord + , boost::orable< IntervalType + > > > > + IntervalOps; + + typedef + boost::equality_comparable< RectType + , boost::orable< RectType + , boost::orable< RectType, OptRectType + , boost::additive< RectType, PointType + > > > > + RectOps; }; template<> @@ -78,6 +98,24 @@ struct CoordTraits<Coord> { typedef OptInterval OptIntervalType; typedef Rect RectType; typedef OptRect OptRectType; + + typedef + boost::equality_comparable< IntervalType + , boost::additive< IntervalType + , boost::multipliable< IntervalType + , boost::orable< IntervalType + , boost::arithmetic< IntervalType, Coord + > > > > > + IntervalOps; + + typedef + boost::equality_comparable< RectType + , boost::orable< RectType + , boost::orable< RectType, OptRectType + , boost::additive< RectType, PointType + , boost::multipliable< RectType, Affine + > > > > > + RectOps; }; } // end namespace Geom diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index a32e97d4b..0212da676 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -34,7 +34,7 @@ #include <cassert> #include <boost/none.hpp> #include <boost/optional.hpp> -#include <boost/operators.hpp> +#include <2geom/coord.h> namespace Geom { @@ -47,11 +47,7 @@ class GenericOptInterval; */ template <typename C> class GenericInterval - : boost::equality_comparable< GenericInterval<C> - , boost::additive< GenericInterval<C> - , boost::additive< GenericInterval<C>, C - , boost::orable< GenericInterval<C> - > > > > + : CoordTraits<C>::IntervalOps { typedef GenericInterval<C> Self; protected: diff --git a/src/2geom/generic-rect.h b/src/2geom/generic-rect.h index 2db30dfa9..efe499809 100644 --- a/src/2geom/generic-rect.h +++ b/src/2geom/generic-rect.h @@ -42,6 +42,7 @@ #include <limits> #include <boost/optional.hpp> +#include <2geom/coord.h> namespace Geom { @@ -54,11 +55,7 @@ class GenericOptRect; */ template <typename C> class GenericRect - : boost::additive< typename CoordTraits<C>::RectType, typename CoordTraits<C>::PointType - , boost::equality_comparable< typename CoordTraits<C>::RectType - , boost::orable< typename CoordTraits<C>::RectType - , boost::orable< typename CoordTraits<C>::RectType, typename CoordTraits<C>::OptRectType - > > > > + : CoordTraits<C>::RectOps { typedef typename CoordTraits<C>::IntervalType CInterval; typedef typename CoordTraits<C>::PointType CPoint; @@ -131,15 +128,22 @@ public: /// @name Inspect dimensions. /// @{ - CInterval &operator[](unsigned i) { return f[i]; } + CInterval &operator[](unsigned i) { return f[i]; } CInterval const &operator[](unsigned i) const { return f[i]; } + CInterval &operator[](Dim2 d) { return f[d]; } + CInterval const &operator[](Dim2 d) const { return f[d]; } + /** @brief Get the corner of the rectangle with smallest coordinate values. + * In 2Geom standard coordinate system, this means upper left. */ CPoint min() const { return CPoint(f[X].min(), f[Y].min()); } + /** @brief Get the corner of the rectangle with largest coordinate values. + * In 2Geom standard coordinate system, this means lower right. */ CPoint max() const { return CPoint(f[X].max(), f[Y].max()); } /** @brief Return the n-th corner of the rectangle. - * If the Y axis grows upwards, this returns corners in clockwise order - * starting from the lower left. If Y grows downwards, it returns the corners - * in counter-clockwise order starting from the upper left. */ + * Returns corners in the direction of growing angles, starting from + * the one given by min(). For the standard coordinate system used + * in 2Geom (+Y downwards), this means clockwise starting from + * the upper left. */ CPoint corner(unsigned i) const { switch(i % 4) { case 0: return CPoint(f[X].min(), f[Y].min()); @@ -196,10 +200,10 @@ public: } /** @brief Check whether the rectangles have any common points. - * A non-empty rectangle will not intersect empty rectangles. */ + * Empty rectangles will not intersect with any other rectangle. */ inline bool intersects(OptCRect const &r) const; /** @brief Check whether the rectangle includes all points in the given rectangle. - * A non-empty rectangle will contain any empty rectangle. */ + * Empty rectangles will be contained in any non-empty rectangle. */ inline bool contains(OptCRect const &r) const; /** @brief Check whether the given point is within the rectangle. */ @@ -224,11 +228,11 @@ public: void expandTo(CPoint const &p) { f[X].expandTo(p[X]); f[Y].expandTo(p[Y]); } - /** @brief Enlarge the rectangle to contain the given rectangle. */ + /** @brief Enlarge the rectangle to contain the argument. */ void unionWith(CRect const &b) { f[X].unionWith(b[X]); f[Y].unionWith(b[Y]); } - /** @brief Enlarge the rectangle to contain the given rectangle. + /** @brief Enlarge the rectangle to contain the argument. * Unioning with an empty rectangle results in no changes. */ void unionWith(OptCRect const &b); @@ -244,7 +248,8 @@ public: * This will expand the width by the X coordinate of the point in both directions * and the height by Y coordinate of the point. Negative coordinate values will * shrink the rectangle. If <code>-p[X]</code> is larger than half of the width, - * the X interval will contain only the X coordinate of the midpoint; same for height. */ + * the X interval will contain only the X coordinate of the midpoint; + * same for height. */ void expandBy(CPoint const &p) { f[X].expandBy(p[X]); f[Y].expandBy(p[Y]); } @@ -297,30 +302,66 @@ class GenericOptRect typedef typename CoordTraits<C>::OptRectType OptCRect; typedef boost::optional<CRect> Base; public: + /// @name Create potentially empty rectangles. + /// @{ GenericOptRect() : Base() {} GenericOptRect(GenericRect<C> const &a) : Base(CRect(a)) {} GenericOptRect(CPoint const &a, CPoint const &b) : Base(CRect(a, b)) {} - /** - * Creates an empty OptRect when one of the argument intervals is empty. - */ + /// Creates an empty OptRect when one of the argument intervals is empty. GenericOptRect(OptCInterval const &x_int, OptCInterval const &y_int) { if (x_int && y_int) { *this = CRect(*x_int, *y_int); } // else, stay empty. } + /** @brief Create a rectangle from a range of points. + * The resulting rectangle will contain all ponts from the range. + * If the range contains no points, the result will be an empty rectangle. + * The return type of iterators must be convertible to the corresponding + * point type (Point or IntPoint). + * @param start Beginning of the range + * @param end End of the range + * @return Rectangle that contains all points from [start, end). */ + template <typename InputIterator> + static OptCRect from_range(InputIterator start, InputIterator end) { + OptCRect result; + for (; start != end; ++start) { + result.expandTo(*start); + } + return result; + } + /// @} + /// @name Check other rectangles and points for inclusion. + /// @{ /** @brief Check for emptiness. */ inline bool isEmpty() const { return !*this; }; - + /** @brief Check whether the rectangles have any common points. + * Empty rectangles will not intersect with any other rectangle. */ bool intersects(CRect const &r) const { return r.intersects(*this); } + /** @brief Check whether the rectangle includes all points in the given rectangle. + * Empty rectangles will be contained in any non-empty rectangle. */ bool contains(CRect const &r) const { return *this && (*this)->contains(r); } + /** @brief Check whether the rectangles have any common points. + * Empty rectangles will not intersect with any other rectangle. + * Two empty rectangles will not intersect each other. */ bool intersects(OptCRect const &r) const { return *this && (*this)->intersects(r); } + /** @brief Check whether the rectangle includes all points in the given rectangle. + * Empty rectangles will be contained in any non-empty rectangle. + * An empty rectangle will not contain other empty rectangles. */ bool contains(OptCRect const &r) const { return *this && (*this)->contains(r); } + /** @brief Check whether the given point is within the rectangle. + * An empty rectangle will not contain any points. */ bool contains(CPoint const &p) const { return *this && (*this)->contains(p); } + /// @} + /// @name Modify the potentially empty rectangle. + /// @{ + /** @brief Enlarge the rectangle to contain the argument. + * If this rectangle is empty, after callng this method it will + * be equal to the argument. */ void unionWith(CRect const &b) { if (*this) { (*this)->unionWith(b); @@ -328,9 +369,16 @@ public: *this = b; } } + /** @brief Enlarge the rectangle to contain the argument. + * Unioning with an empty rectangle results in no changes. + * If this rectangle is empty, after calling this method it will + * be equal to the argument. */ void unionWith(OptCRect const &b) { if (b) unionWith(*b); } + /** @brief Leave only the area overlapping with the argument. + * If the rectangles do not have any points in common, after calling + * this method the rectangle will be empty. */ void intersectWith(CRect const &b) { if (!*this) return; OptCInterval x = (**this)[X] & b[X], y = (**this)[Y] & b[Y]; @@ -340,6 +388,9 @@ public: *(static_cast<Base*>(this)) = boost::none; } } + /** @brief Leave only the area overlapping with the argument. + * If the argument is empty or the rectangles do not have any points + * in common, after calling this method the rectangle will be empty. */ void intersectWith(OptCRect const &b) { if (b) { intersectWith(*b); @@ -347,18 +398,36 @@ public: *(static_cast<Base*>(this)) = boost::none; } } + /** @brief Create or enlarge the rectangle to contain the given point. + * If the rectangle is empty, after calling this method it will be non-empty + * and it will contain only the given point. */ + void expandTo(CPoint const &p) { + if (*this) { + (*this).expandTo(p); + } else { + *this = CRect(p, p); + } + } + /// @} + + /// @name Operators + /// @{ + /** @brief Union with @a b */ GenericOptRect<C> &operator|=(OptCRect const &b) { unionWith(b); return *this; } + /** @brief Intersect with @a b */ GenericOptRect<C> &operator&=(CRect const &b) { intersectWith(b); return *this; } + /** @brief Intersect with @a b */ GenericOptRect<C> &operator&=(OptCRect const &b) { intersectWith(b); return *this; } + /// @} }; template <typename C> diff --git a/src/2geom/interval.h b/src/2geom/interval.h index e95da4811..711eaa5e2 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -63,9 +63,6 @@ typedef GenericOptInterval<Coord> OptInterval; */ class Interval : public GenericInterval<Coord> - , boost::multipliable< Interval - , boost::multiplicative< Interval, Coord - > > { typedef GenericInterval<Coord> Base; public: diff --git a/src/2geom/linear.h b/src/2geom/linear.h index df6dd9904..448ab3bb7 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -55,7 +55,7 @@ class SBasis; class Linear{ public: double a[2]; - Linear() {} + Linear() { a[0] = 0; a[1] = 0; } Linear(double aa, double b) {a[0] = aa; a[1] = b;} Linear(double aa) {a[0] = aa; a[1] = aa;} diff --git a/src/2geom/rect.h b/src/2geom/rect.h index f7d331523..b79a0a04f 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -59,7 +59,6 @@ typedef GenericOptRect<Coord> OptRect; */ class Rect : public GenericRect<Coord> - , boost::multipliable< Rect, Affine > { typedef GenericRect<Coord> Base; public: diff --git a/src/2geom/transforms.h b/src/2geom/transforms.h index 5627e8b6f..eaf869056 100644 --- a/src/2geom/transforms.h +++ b/src/2geom/transforms.h @@ -45,10 +45,11 @@ namespace Geom { * @ingroup Concepts */ template <typename T> struct TransformConcept { - T t; + T t, t2; Affine m; Point p; bool bool_; + Coord epsilon; void constraints() { m = t; //implicit conversion m *= t; @@ -63,6 +64,8 @@ struct TransformConcept { bool_ = (t != t); t = T::identity(); t = t.inverse(); + bool_ = are_near(t, t2); + bool_ = are_near(t, t2, epsilon); } }; @@ -130,6 +133,10 @@ public: friend class Point; }; +inline bool are_near(Translate const &a, Translate const &b, Coord eps=EPSILON) { + return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps); +} + /** @brief Scaling from the origin. * During scaling, the point (0,0) will not move. To obtain a scale with a different * invariant point, combine with translation to the origin and back. @@ -164,6 +171,10 @@ public: friend class Point; }; +inline bool are_near(Scale const &a, Scale const &b, Coord eps=EPSILON) { + return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps); +} + /** @brief Rotation around the origin. * Combine with translations to the origin and back to get a rotation around a different point. * @ingroup Transforms */ @@ -207,6 +218,10 @@ public: friend class Point; }; +inline bool are_near(Rotate const &a, Rotate const &b, Coord eps=EPSILON) { + return are_near(a[X], b[X], eps) && are_near(a[Y], b[Y], eps); +} + /** @brief Common base for shearing transforms. * This class is an implementation detail and should not be used directly. * @ingroup Transforms */ @@ -241,6 +256,10 @@ public: operator Affine() const { Affine ret(1, 0, f, 1, 0, 0); return ret; } }; +inline bool are_near(HShear const &a, HShear const &b, Coord eps=EPSILON) { + return are_near(a.factor(), b.factor(), eps); +} + /** @brief Vertical shearing. * Points on the Y axis will not move. Combine with translations to get a shear * with a different invariant line. @@ -253,6 +272,10 @@ public: operator Affine() const { Affine ret(1, f, 0, 1, 0, 0); return ret; } }; +inline bool are_near(VShear const &a, VShear const &b, Coord eps=EPSILON) { + return are_near(a.factor(), b.factor(), eps); +} + /** @brief Combination of a translation and uniform scale. * The translation part is applied first, then the result is scaled from the new origin. * This way when the class is used to accumulate a zoom transform, trans always points @@ -295,6 +318,11 @@ public: friend class Affine; }; +inline bool are_near(Zoom const &a, Zoom const &b, Coord eps=EPSILON) { + return are_near(a.scale(), b.scale(), eps) && + are_near(a.translation(), b.translation(), eps); +} + /** @brief Specialization of exponentiation for Scale. * @relates Scale */ template<> diff --git a/src/context-fns.h b/src/context-fns.h index c86640aba..c56c67a27 100644 --- a/src/context-fns.h +++ b/src/context-fns.h @@ -16,6 +16,7 @@ struct SPDesktop; struct SPItem; +struct SPEventContext; const double goldenratio = 1.61803398874989484820; // golden ratio diff --git a/src/desktop.cpp b/src/desktop.cpp index 5e968b08b..cceee9499 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -59,55 +59,56 @@ #include <2geom/transforms.h> #include <2geom/rect.h> -#include "macros.h" -#include "inkscape-private.h" -#include "desktop.h" + +#include "box3d-context.h" +#include "color.h" #include "desktop-events.h" +#include "desktop.h" #include "desktop-handles.h" -#include "document.h" -#include "message-stack.h" -#include "selection.h" -#include "select-context.h" -#include "sp-namedview.h" -#include "color.h" -#include "sp-item-group.h" -#include "preferences.h" -#include "object-hierarchy.h" -#include "helper/units.h" +#include "desktop-style.h" +#include "device-manager.h" #include "display/canvas-arena.h" -#include "display/nr-arena.h" -#include "display/gnome-canvas-acetate.h" -#include "display/sodipodi-ctrlrect.h" -#include "display/sp-canvas-util.h" +#include "display/canvas-grid.h" #include "display/canvas-temporary-item-list.h" +#include "display/drawing-group.h" +#include "display/gnome-canvas-acetate.h" +#include "display/nr-arena.h" #include "display/snap-indicator.h" +#include "display/sodipodi-ctrlrect.h" #include "display/sp-canvas-group.h" -#include "ui/dialog/dialog-manager.h" -#include "xml/repr.h" -#include "message-context.h" -#include "device-manager.h" +#include "display/sp-canvas.h" +#include "display/sp-canvas-util.h" +#include "document.h" +#include "event-log.h" +#include "helper/units.h" +#include "inkscape-private.h" #include "layer-fns.h" #include "layer-manager.h" +#include "macros.h" +#include "message-context.h" +#include "message-stack.h" +#include "object-hierarchy.h" +#include "preferences.h" #include "resource-manager.h" -#include "event-log.h" -#include "display/canvas-grid.h" -#include "widgets/desktop-widget.h" -#include "box3d-context.h" -#include "desktop-style.h" +#include "select-context.h" +#include "selection.h" #include "sp-item-group.h" +#include "sp-item-group.h" +#include "sp-namedview.h" #include "sp-root.h" +#include "ui/dialog/dialog-manager.h" +#include "widgets/desktop-widget.h" +#include "xml/repr.h" // TODO those includes are only for node tool quick zoom. Remove them after fixing it. #include "ui/tool/node-tool.h" #include "ui/tool/control-point-selection.h" -#include "display/sp-canvas.h" - namespace Inkscape { namespace XML { class Node; }} // Callback declarations static void _onSelectionChanged (Inkscape::Selection *selection, SPDesktop *desktop); -static gint _arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop); +static gint _arena_handler (SPCanvasArena *arena, Inkscape::DrawingItem *ai, GdkEvent *event, SPDesktop *desktop); static void _layer_activated(SPObject *layer, SPDesktop *desktop); static void _layer_deactivated(SPObject *layer, SPDesktop *desktop); static void _layer_hierarchy_changed(SPObject *top, SPObject *bottom, SPDesktop *desktop); @@ -158,7 +159,7 @@ SPDesktop::SPDesktop() : _layer_hierarchy( 0 ), _reconstruction_old_layer_id( 0 ), _display_mode(Inkscape::RENDERMODE_NORMAL), - _display_color_mode(Inkscape::COLORRENDERMODE_NORMAL), + _display_color_mode(Inkscape::COLORMODE_NORMAL), _widget( 0 ), _inkscape( 0 ), _guides_message_context( 0 ), @@ -285,12 +286,12 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); - NRArenaItem *ai = document->getRoot()->invoke_show( + Inkscape::DrawingItem *ai = document->getRoot()->invoke_show( SP_CANVAS_ARENA (drawing)->arena, dkey, SP_ITEM_SHOW_DISPLAY); if (ai) { - nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL); + SP_CANVAS_ARENA (drawing)->root->prependChild(ai); } namedview->show(this); @@ -460,8 +461,8 @@ void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) { sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw _widget->setTitle( sp_desktop_document(this)->getName() ); } -void SPDesktop::_setDisplayColorMode(Inkscape::ColorRenderMode mode) { - SP_CANVAS_ARENA (drawing)->arena->colorrendermode = mode; +void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { + SP_CANVAS_ARENA (drawing)->arena->colormode = mode; canvas->colorrendermode = mode; _display_color_mode = mode; sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw @@ -485,15 +486,15 @@ void SPDesktop::displayModeToggle() { } void SPDesktop::displayColorModeToggle() { switch (_display_color_mode) { - case Inkscape::COLORRENDERMODE_NORMAL: - _setDisplayColorMode(Inkscape::COLORRENDERMODE_GRAYSCALE); + case Inkscape::COLORMODE_NORMAL: + _setDisplayColorMode(Inkscape::COLORMODE_GRAYSCALE); break; - case Inkscape::COLORRENDERMODE_GRAYSCALE: - _setDisplayColorMode(Inkscape::COLORRENDERMODE_NORMAL); + case Inkscape::COLORMODE_GRAYSCALE: + _setDisplayColorMode(Inkscape::COLORMODE_NORMAL); break; -// case Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW: +// case Inkscape::COLORMODE_PRINT_COLORS_PREVIEW: default: - _setDisplayColorMode(Inkscape::COLORRENDERMODE_NORMAL); + _setDisplayColorMode(Inkscape::COLORMODE_NORMAL); } } @@ -1562,7 +1563,7 @@ SPDesktop::setDocument (SPDocument *doc) /// are surely more safe methods to accomplish this. // TODO since the comment had reversed logic, check the intent of this block of code: if (drawing) { - NRArenaItem *ai = 0; + Inkscape::DrawingItem *ai = 0; namedview = sp_document_namedview (doc, NULL); _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); @@ -1573,7 +1574,7 @@ SPDesktop::setDocument (SPDocument *doc) dkey, SP_ITEM_SHOW_DISPLAY); if (ai) { - nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL); + SP_CANVAS_ARENA (drawing)->root->prependChild(ai); } namedview->show(this); /* Ugly hack */ @@ -1662,10 +1663,10 @@ _onSelectionChanged * \todo fixme */ static gint -_arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop) +_arena_handler (SPCanvasArena */*arena*/, Inkscape::DrawingItem *ai, GdkEvent *event, SPDesktop *desktop) { if (ai) { - SPItem *spi = (SPItem*)NR_ARENA_ITEM_GET_DATA (ai); + SPItem *spi = (SPItem*) ai->data(); return sp_event_context_item_handler (desktop->event_context, spi, event); } else { return sp_event_context_root_handler (desktop->event_context, event); diff --git a/src/desktop.h b/src/desktop.h index a7264e4aa..26c308f5d 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -211,19 +211,19 @@ public: Inkscape::RenderMode _display_mode; Inkscape::RenderMode getMode() const { return _display_mode; } - void _setDisplayColorMode(Inkscape::ColorRenderMode mode); + void _setDisplayColorMode(Inkscape::ColorMode mode); void setDisplayColorModeNormal() { - _setDisplayColorMode(Inkscape::COLORRENDERMODE_NORMAL); + _setDisplayColorMode(Inkscape::COLORMODE_NORMAL); } void setDisplayColorModeGrayscale() { - _setDisplayColorMode(Inkscape::COLORRENDERMODE_GRAYSCALE); + _setDisplayColorMode(Inkscape::COLORMODE_GRAYSCALE); } // void setDisplayColorModePrintColorsPreview() { -// _setDisplayColorMode(Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW); +// _setDisplayColorMode(Inkscape::COLORMODE_PRINT_COLORS_PREVIEW); // } void displayColorModeToggle(); - Inkscape::ColorRenderMode _display_color_mode; - Inkscape::ColorRenderMode getColorMode() const { return _display_color_mode; } + Inkscape::ColorMode _display_color_mode; + Inkscape::ColorMode getColorMode() const { return _display_color_mode; } Inkscape::UI::Widget::Dock* getDock() { return _widget->getDock(); } diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index 55b405523..2b08a307a 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -27,7 +27,7 @@ #include "display/cairo-utils.h" #include "display/drawing-context.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "document.h" #include "filter-chemistry.h" #include "helper/unit-menu.h" @@ -834,7 +834,7 @@ static bool clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) static NRArena const *trace_arena = NULL; static unsigned trace_visionkey; -static NRArenaItem *trace_root; +static Inkscape::DrawingItem *trace_root; static gdouble trace_zoom; static SPDocument *trace_doc; @@ -852,6 +852,8 @@ static void clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) static void clonetiler_trace_setup(SPDocument *doc, gdouble zoom, SPItem *original) { + // FIXME MEMORY LEAK: the stuff here is never freed + trace_arena = NRArena::create(); /* Create ArenaItem and set transform */ trace_visionkey = SPItem::display_key_new(1); @@ -874,13 +876,8 @@ static guint32 clonetiler_trace_pick(Geom::Rect box) return 0; } - Geom::Affine t(Geom::Scale(trace_zoom, trace_zoom)); - nr_arena_item_set_transform(trace_root, &t); - NRGC gc(NULL); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( trace_root, Geom::IntRect::infinite(), &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + trace_root->setTransform(Geom::Scale(trace_zoom)); + trace_root->update(); /* Item integer bbox in points */ Geom::IntRect ibox = (box * Geom::Scale(trace_zoom)).roundOutwards(); @@ -889,8 +886,7 @@ static guint32 clonetiler_trace_pick(Geom::Rect box) cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); Inkscape::DrawingContext ct(s, ibox.min()); /* Render */ - nr_arena_item_invoke_render(ct, trace_root, ibox, - NR_ARENA_ITEM_RENDER_NO_CACHE ); + trace_root->render(ct, ibox, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); double R = 0, G = 0, B = 0, A = 0; ink_cairo_surface_average_color(s, R, G, B, A); cairo_surface_destroy(s); diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 53f87efb1..1c51f19a0 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -25,8 +25,18 @@ ink_common_sources += \ display/curve.h \ display/drawing-context.cpp \ display/drawing-context.h \ + display/drawing-group.cpp \ + display/drawing-group.h \ + display/drawing-image.cpp \ + display/drawing-image.h \ + display/drawing-item.cpp \ + display/drawing-item.h \ + display/drawing-shape.cpp \ + display/drawing-shape.h \ display/drawing-surface.cpp \ display/drawing-surface.h \ + display/drawing-text.cpp \ + display/drawing-text.h \ display/gnome-canvas-acetate.cpp \ display/gnome-canvas-acetate.h \ display/grayscale.cpp \ @@ -35,19 +45,9 @@ ink_common_sources += \ display/guideline.h \ display/nr-3dutils.cpp \ display/nr-3dutils.h \ + display/nr-arena.h \ display/nr-arena.cpp \ display/nr-arena-forward.h \ - display/nr-arena-glyphs.cpp \ - display/nr-arena-glyphs.h \ - display/nr-arena-group.cpp \ - display/nr-arena-group.h \ - display/nr-arena.h \ - display/nr-arena-image.cpp \ - display/nr-arena-image.h \ - display/nr-arena-item.cpp \ - display/nr-arena-item.h \ - display/nr-arena-shape.cpp \ - display/nr-arena-shape.h \ display/nr-filter-blend.cpp \ display/nr-filter-blend.h \ display/nr-filter-colormatrix.cpp \ diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 0f653a258..81416fefb 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -16,12 +16,15 @@ #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" #include "display/nr-arena.h" -#include "display/nr-arena-group.h" #include "display/canvas-arena.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "display/drawing-group.h" #include "display/drawing-surface.h" +using namespace Inkscape; + enum { ARENA_EVENT, LAST_SIGNAL @@ -31,6 +34,7 @@ static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass); static void sp_canvas_arena_init(SPCanvasArena *group); static void sp_canvas_arena_destroy(GtkObject *object); +static void sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item); static void sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); @@ -39,7 +43,7 @@ static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event); static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); -static void sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, void *data); +static void sp_canvas_arena_request_update (NRArena *arena, DrawingItem *item, void *data); static void sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data); NRArenaEventVector carenaev = { @@ -105,10 +109,16 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->sticky = FALSE; arena->arena = NRArena::create(); + nr_object_ref(arena->arena); arena->arena->canvasarena = arena; - arena->root = NRArenaGroup::create(arena->arena); - nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE); - nr_arena_item_set_cache(arena->root, true); + arena->arena->item_deleted.connect( + sigc::bind<0>( + sigc::ptr_fun(&sp_canvas_arena_item_deleted), + arena)); + + arena->root = new DrawingGroup(arena->arena); + arena->root->setPickChildren(true); + arena->root->setCached(true); arena->active = NULL; @@ -120,22 +130,11 @@ sp_canvas_arena_destroy (GtkObject *object) { SPCanvasArena *arena = SP_CANVAS_ARENA (object); - if (arena->active) { - nr_object_unref ((NRObject *) arena->active); - arena->active = NULL; - } - - if (arena->root) { - nr_arena_item_unref (arena->root); - arena->root = NULL; - } - - if (arena->arena) { - nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); + delete arena->root; - nr_object_unref ((NRObject *) arena->arena); - arena->arena = NULL; - } + nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); + nr_object_unref ((NRObject *) arena->arena); + arena->arena = NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -149,14 +148,12 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned if (((SPCanvasItemClass *) parent_class)->update) (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); - arena->gc.transform = affine; + arena->ctx.ctm = affine; - guint reset; - reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE; + unsigned reset = flags & SP_CANVAS_UPDATE_AFFINE ? DrawingItem::STATE_ALL : 0; + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, reset); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset); - - Geom::OptIntRect b = arena->root->bbox; + Geom::OptIntRect b = arena->root->visualBounds(); if (b) { item->x1 = b->left() - 1; item->y1 = b->top() - 1; @@ -166,7 +163,7 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned if (arena->cursor) { /* Mess with enter/leave notifiers */ - NRArenaItem *new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + DrawingItem *new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = GTK_WIDGET (item->canvas)->window; @@ -180,10 +177,7 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned ec.type = GDK_LEAVE_NOTIFY; sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); } - /* fixme: This is not optimal - better track ::destroy (Lauris) */ - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = new_arena; - if (arena->active) nr_object_ref ((NRObject *) arena->active); if (arena->active) { ec.type = GDK_ENTER_NOTIFY; sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); @@ -193,6 +187,14 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned } static void +sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item) +{ + if (arena->active == item) { + arena->active = NULL; + } +} + +static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) { // todo: handle NR_ARENA_ITEM_RENDER_NO_CACHE @@ -203,10 +205,8 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) Inkscape::DrawingContext ct(buf->ct, r->min()); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, - NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, - NR_ARENA_ITEM_STATE_NONE); - nr_arena_item_invoke_render (ct, arena->root, *r, 0); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, 0); + arena->root->render(ct, *r, 0); } static double @@ -214,11 +214,8 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, - NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK, - NR_ARENA_ITEM_STATE_NONE); - - NRArenaItem *picked = nr_arena_item_invoke_pick (arena->root, p, arena->arena->delta, arena->sticky); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + DrawingItem *picked = arena->root->pick(p, arena->arena->delta, arena->sticky); arena->picked = picked; @@ -244,7 +241,7 @@ sp_canvas_arena_viewbox_changed (SPCanvasItem *item, Geom::IntRect const &new_ar static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) { - NRArenaItem *new_arena; + Inkscape::DrawingItem *new_arena; /* fixme: This sucks, we have to handle enter/leave notifiers */ SPCanvasArena *arena = SP_CANVAS_ARENA (item); @@ -256,7 +253,6 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) if (!arena->cursor) { if (arena->active) { //g_warning ("Cursor entered to arena with already active item"); - nr_object_unref ((NRObject *) arena->active); } arena->cursor = TRUE; @@ -264,9 +260,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->crossing.x, event->crossing.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); - arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); - if (arena->active) nr_object_ref ((NRObject *) arena->active); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + arena->active = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); ret = sp_canvas_arena_send_event (arena, event); } break; @@ -274,7 +269,6 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) case GDK_LEAVE_NOTIFY: if (arena->cursor) { ret = sp_canvas_arena_send_event (arena, event); - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = NULL; arena->cursor = FALSE; } @@ -285,8 +279,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->motion.x, event->motion.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); - new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = event->motion.window; @@ -300,9 +294,7 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) ec.type = GDK_LEAVE_NOTIFY; ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); } - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = new_arena; - if (arena->active) nr_object_ref ((NRObject *) arena->active); if (arena->active) { ec.type = GDK_ENTER_NOTIFY; ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); @@ -332,7 +324,7 @@ sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event) } static void -sp_canvas_arena_request_update (NRArena */*arena*/, NRArenaItem */*item*/, void *data) +sp_canvas_arena_request_update (NRArena */*arena*/, DrawingItem */*item*/, void *data) { sp_canvas_item_request_update (SP_CANVAS_ITEM (data)); } @@ -373,7 +365,8 @@ sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRR Geom::OptIntRect area = r.upgrade_2geom(); if (!area) return; Inkscape::DrawingContext ct(surface, area->min()); - nr_arena_item_invoke_render (ct, ca->root, *area, 0); + ca->root->update(Geom::IntRect::infinite(), ca->ctx, DrawingItem::STATE_ALL, 0); + ca->root->render(ct, *area, 0); } diff --git a/src/display/canvas-arena.h b/src/display/canvas-arena.h index 4cfeccb5a..e63a524f2 100644 --- a/src/display/canvas-arena.h +++ b/src/display/canvas-arena.h @@ -15,9 +15,10 @@ #include <cairo.h> #include <2geom/rect.h> +#include "display/display-forward.h" +#include "display/drawing-item.h" #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" -#include "display/nr-arena-item.h" G_BEGIN_DECLS @@ -38,19 +39,19 @@ struct _SPCanvasArena { Geom::Point c; // what is this? NRArena *arena; - NRArenaItem *root; - NRGC gc; + Inkscape::DrawingGroup *root; + Inkscape::UpdateContext ctx; - NRArenaItem *active; + Inkscape::DrawingItem *active; /* fixme: */ - NRArenaItem *picked; - gdouble delta; + Inkscape::DrawingItem *picked; + double delta; }; struct _SPCanvasArenaClass { SPCanvasItemClass parent_class; - gint (* arena_event) (SPCanvasArena *carena, NRArenaItem *item, GdkEvent *event); + gint (* arena_event) (SPCanvasArena *carena, Inkscape::DrawingItem *item, GdkEvent *event); }; GType sp_canvas_arena_get_type (void); diff --git a/src/display/display-forward.h b/src/display/display-forward.h index 288da829a..d7e7d72ab 100644 --- a/src/display/display-forward.h +++ b/src/display/display-forward.h @@ -11,9 +11,17 @@ struct SPCanvasGroup; struct SPCanvasGroupClass; class SPCurve; +class NRArena; + namespace Inkscape { class DrawingContext; class DrawingSurface; +class DrawingItem; +class DrawingGroup; +class DrawingImage; +class DrawingShape; +class DrawingGlyphs; +class DrawingText; namespace Display { class TemporaryItem; 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 <tweenk.pl@gmail.com> + * + * 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<DrawingGroup *>(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 : diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h new file mode 100644 index 000000000..f7d6a2be3 --- /dev/null +++ b/src/display/drawing-group.h @@ -0,0 +1,61 @@ +/** + * @file + * @brief Group belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_GROUP_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_GROUP_H + +#include "display/drawing-item.h" + +class SPStyle; + +namespace Inkscape { + +class DrawingGroup + : public DrawingItem +{ +public: + DrawingGroup(Drawing *drawing); + ~DrawingGroup(); + + bool pickChildren() { return _pick_children; } + void setPickChildren(bool p); + + void setStyle(SPStyle *style); + void setChildTransform(Geom::Affine const &new_trans); + +protected: + 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 void _clipItem(DrawingContext &ct, Geom::IntRect const &area); + virtual DrawingItem *_pickItem(Geom::Point const &p, double delta); + virtual bool _canClip(); + + SPStyle *_style; + Geom::Affine *_child_transform; +}; + +bool is_drawing_group(DrawingItem *item); + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +/* + 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 : diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp new file mode 100644 index 000000000..ea6f6ce3c --- /dev/null +++ b/src/display/drawing-image.cpp @@ -0,0 +1,263 @@ +/** + * @file + * @brief Bitmap image belonging to an SVG drawing + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * 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-image.h" +#include "nr-arena.h" +#include "preferences.h" +#include "style.h" + +namespace Inkscape { + +DrawingImage::DrawingImage(Drawing *drawing) + : DrawingItem(drawing) + , _pixbuf(NULL) + , _surface(NULL) + , _style(NULL) +{} + +DrawingImage::~DrawingImage() +{ + if (_style) + sp_style_unref(_style); + if (_pixbuf) { + cairo_surface_destroy(_surface); + g_object_unref(_pixbuf); + } +} + +void +DrawingImage::setARGB32Pixbuf(GdkPixbuf *pb) +{ + // when done in this order, it won't break if pb == image->pixbuf and the refcount is 1 + if (pb != NULL) { + g_object_ref (pb); + } + if (_pixbuf != NULL) { + g_object_unref(_pixbuf); + cairo_surface_destroy(_surface); + } + _pixbuf = pb; + _surface = pb ? ink_cairo_surface_create_for_argb32_pixbuf(pb) : NULL; + + _markForUpdate(STATE_ALL, false); +} + +void +DrawingImage::setStyle(SPStyle *style) +{ + _setStyleCommon(_style, style); +} + +void +DrawingImage::setScale(double sx, double sy) +{ + _scale = Geom::Scale(sx, sy); + _markForUpdate(STATE_ALL, false); +} + +void +DrawingImage::setOrigin(Geom::Point const &o) +{ + _origin = o; + _markForUpdate(STATE_ALL, false); +} + +void +DrawingImage::setClipbox(Geom::Rect const &box) +{ + _clipbox = box; + _markForUpdate(STATE_ALL, false); +} + +Geom::Rect +DrawingImage::bounds() const +{ + if (!_pixbuf) return _clipbox; + + double pw = gdk_pixbuf_get_width(_pixbuf); + double ph = gdk_pixbuf_get_height(_pixbuf); + double vw = pw * _scale[Geom::X]; + double vh = ph * _scale[Geom::Y]; + Geom::Point wh(vw, vh); + Geom::Rect view(_origin, _origin+wh); + Geom::OptRect res = _clipbox & view; + Geom::Rect ret = res ? *res : _clipbox; + + return ret; +} + +unsigned +DrawingImage::_updateItem(Geom::IntRect const &, UpdateContext const &, unsigned, unsigned) +{ + _markForRendering(); + + // Calculate bbox + if (_pixbuf) { + Geom::Rect r = bounds() * _ctm; + _bbox = r.roundOutwards(); + } else { + _bbox = Geom::OptIntRect(); + } + + return STATE_ALL; +} + +void +DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + if (!outline) { + if (!_pixbuf) return; + + Inkscape::DrawingContext::Save save(ct); + ct.transform(_ctm); + ct.newPath(); + ct.rectangle(_clipbox); + ct.clip(); + + ct.translate(_origin); + ct.scale(_scale); + ct.setSource(_surface, 0, 0); + + cairo_matrix_t tt; + Geom::Affine total; + cairo_get_matrix(ct.raw(), &tt); + ink_matrix_to_2geom(total, tt); + + if (total.expansionX() > 1.0 || total.expansionY() > 1.0) { + cairo_pattern_t *p = cairo_get_source(ct.raw()); + cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST); + } + //ct.paint(_opacity); + ct.paint(); + + } else { // outline; draw a rect instead + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); + + { Inkscape::DrawingContext::Save save(ct); + ct.transform(_ctm); + ct.newPath(); + + Geom::Rect r = bounds(); + Geom::Point c00 = r.corner(0); + Geom::Point c01 = r.corner(3); + Geom::Point c11 = r.corner(2); + Geom::Point c10 = r.corner(1); + + ct.moveTo(c00); + // the box + ct.lineTo(c10); + ct.lineTo(c11); + ct.lineTo(c01); + ct.lineTo(c00); + // the diagonals + ct.lineTo(c11); + ct.moveTo(c10); + ct.lineTo(c01); + } + + ct.setLineWidth(0.5); + ct.setSource(rgba); + ct.stroke(); + } +} + +/** Calculates the closest distance from p to the segment a1-a2*/ +static double +distance_to_segment (Geom::Point const &p, Geom::Point const &a1, Geom::Point const &a2) +{ + // calculate sides of the triangle and their squares + double d1 = Geom::L2(p - a1); + double d1_2 = d1 * d1; + double d2 = Geom::L2(p - a2); + double d2_2 = d2 * d2; + double a = Geom::L2(a1 - a2); + double a_2 = a * a; + + // if one of the angles at the base is > 90, return the corresponding side + if (d1_2 + a_2 <= d2_2) return d1; + if (d2_2 + a_2 <= d1_2) return d2; + + // otherwise calculate the height to the base + double peri = (a + d1 + d2)/2; + return (2*sqrt(peri * (peri - a) * (peri - d1) * (peri - d2))/a); +} + +DrawingItem * +DrawingImage::_pickItem(Geom::Point const &p, double delta) +{ + if (!_pixbuf) return NULL; + + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + if (outline) { + Geom::Rect r = bounds(); + + Geom::Point c00 = r.corner(0); + Geom::Point c01 = r.corner(3); + Geom::Point c11 = r.corner(2); + Geom::Point c10 = r.corner(1); + + // frame + if (distance_to_segment (p, c00, c10) < delta) return this; + if (distance_to_segment (p, c10, c11) < delta) return this; + if (distance_to_segment (p, c11, c01) < delta) return this; + if (distance_to_segment (p, c01, c00) < delta) return this; + + // diagonals + if (distance_to_segment (p, c00, c11) < delta) return this; + if (distance_to_segment (p, c10, c01) < delta) return this; + + return NULL; + + } else { + unsigned char *const pixels = gdk_pixbuf_get_pixels(_pixbuf); + int width = gdk_pixbuf_get_width(_pixbuf); + int height = gdk_pixbuf_get_height(_pixbuf); + int rowstride = gdk_pixbuf_get_rowstride(_pixbuf); + + Geom::Point tp = p * _ctm.inverse(); + Geom::Rect r = bounds(); + + if (!r.contains(tp)) + return NULL; + + double vw = width * _scale[Geom::X]; + double vh = height * _scale[Geom::Y]; + int ix = floor((tp[Geom::X] - _origin[Geom::X]) / vw * width); + int iy = floor((tp[Geom::Y] - _origin[Geom::Y]) / vh * height); + + if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height)) + return NULL; + + unsigned char *pix_ptr = pixels + iy * rowstride + ix * 4; + // pick if the image is less than 99% transparent + float alpha = (pix_ptr[3] / 255.0f) * _opacity; + return alpha > 0.01 ? this : 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 : diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h new file mode 100644 index 000000000..570c10360 --- /dev/null +++ b/src/display/drawing-image.h @@ -0,0 +1,66 @@ +/** + * @file + * @brief Bitmap image belonging to an SVG drawing + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_IMAGE_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_IMAGE_H + +#include <cairo.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <2geom/transforms.h> + +#include "display/drawing-item.h" + +namespace Inkscape { + +class DrawingImage + : public DrawingItem +{ +public: + DrawingImage(Drawing *drawing); + ~DrawingImage(); + + void setARGB32Pixbuf(GdkPixbuf *pb); + void setStyle(SPStyle *style); + void setScale(double sx, double sy); + void setOrigin(Geom::Point const &o); + void setClipbox(Geom::Rect const &box); + Geom::Rect bounds() const; + +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); + + GdkPixbuf *_pixbuf; + cairo_surface_t *_surface; + SPStyle *_style; + + // TODO: the following three should probably be merged into a new Geom::Viewbox object + Geom::Rect _clipbox; ///< for preserveAspectRatio + Geom::Point _origin; + Geom::Scale _scale; +}; + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +/* + 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 : diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp new file mode 100644 index 000000000..318ff28e7 --- /dev/null +++ b/src/display/drawing-item.cpp @@ -0,0 +1,620 @@ +/** + * @file + * @brief Canvas item belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/cairo-utils.h" +#include "display/cairo-templates.h" +#include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "display/drawing-group.h" +#include "display/drawing-surface.h" +#include "nr-arena.h" +#include "nr-filter.h" +#include "preferences.h" +#include "style.h" + +namespace Inkscape { + +DrawingItem::DrawingItem(Drawing *drawing) + : _drawing(drawing) + , _parent(NULL) + , _key(0) + , _opacity(1.0) + , _transform(NULL) + , _clip(NULL) + , _mask(NULL) + , _filter(NULL) + , _user_data(NULL) + , _cache(NULL) + , _state(0) + , _visible(true) + , _sensitive(true) + , _cached(0) + , _propagate(0) +// , _renders_opacity(0) + , _clip_child(0) + , _mask_child(0) + , _pick_children(0) +{ + nr_object_ref(_drawing); +} + +DrawingItem::~DrawingItem() +{ + _drawing->item_deleted.emit(this); + //if (!_children.empty()) { + // g_warning("Removing item with children"); + //} + + // remove from the set of cached items + if (_cached) { + _drawing->cached_items.erase(this); + } + // remove this item from parent's children list + // due to the effect of clearChildren(), this only happens for the top-level deleted item + if (_parent) { + _markForRendering(); + // we cannot call setClip(NULL) or setMask(NULL), + // because that would be an endless loop + if (_clip_child) { + _parent->_clip = NULL; + } else if (_mask_child) { + _parent->_mask = NULL; + } else { + ChildrenList::iterator ithis = _parent->_children.iterator_to(*this); + _parent->_children.erase(ithis); + } + _parent->_markForUpdate(STATE_ALL, false); + } + clearChildren(); + delete _transform; + delete _clip; + delete _mask; + delete _filter; + nr_object_unref(_drawing); +} + +DrawingItem * +DrawingItem::parent() const +{ + //if (_clip_child || _mask_child) + // return NULL; + + return _parent; +} + +void +DrawingItem::appendChild(DrawingItem *item) +{ + item->_parent = this; + _children.push_back(*item); + _markForUpdate(STATE_ALL, false); +} + +void +DrawingItem::prependChild(DrawingItem *item) +{ + item->_parent = this; + _children.push_front(*item); + _markForUpdate(STATE_ALL, false); +} + +void +DrawingItem::clearChildren() +{ + // prevent children from referencing the parent during deletion + // this way, children won't try to remove themselves from a list + // from which they have already been removed by clear_and_dispose + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->_parent = NULL; + } + _children.clear_and_dispose(DeleteDisposer()); +} + +void +DrawingItem::setTransform(Geom::Affine const &new_trans) +{ + Geom::Affine current; + if (_transform) { + current = *_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 _transform; // delete NULL; is safe + _transform = NULL; + } else { + _transform = new Geom::Affine(new_trans); + } + _markForUpdate(STATE_ALL, true); + } +} + +void +DrawingItem::setOpacity(float opacity) +{ + _opacity = opacity; + _markForRendering(); +} + +void +DrawingItem::setVisible(bool v) +{ + _visible = v; + _markForRendering(); +} + +void +DrawingItem::setSensitive(bool s) +{ + _sensitive = s; +} + +void +DrawingItem::setCached(bool c) +{ + _cached = c; + if (c) { + _drawing->cached_items.insert(this); + } else { + _drawing->cached_items.erase(this); + } + _markForUpdate(STATE_CACHE, false); +} + +void +DrawingItem::setClip(DrawingItem *item) +{ + _markForRendering(); + delete _clip; + _clip = item; + if (item) { + item->_parent = this; + item->_clip_child = true; + } + _markForUpdate(STATE_ALL, true); +} + +void +DrawingItem::setMask(DrawingItem *item) +{ + _markForRendering(); + delete _mask; + _mask = item; + if (item) { + item->_parent = this; + item->_mask_child = true; + } + _markForUpdate(STATE_ALL, true); +} + +void +DrawingItem::setZOrder(unsigned z) +{ + if (!_parent) return; + + ChildrenList::iterator it = _parent->_children.iterator_to(*this); + _parent->_children.erase(it); + + ChildrenList::iterator i = _parent->_children.begin(); + std::advance(i, std::min(z, unsigned(_parent->_children.size()))); + _parent->_children.insert(i, *this); + _markForRendering(); +} + +void +DrawingItem::setItemBounds(Geom::OptRect const &bounds) +{ + _item_bbox = bounds; +} + +void +DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + bool render_filters = (_drawing->rendermode == Inkscape::RENDERMODE_NORMAL); + bool outline = (_drawing->rendermode == Inkscape::RENDERMODE_OUTLINE); + + // Set reset flags according to propagation status + if (_propagate) { + reset |= ~_state; + _propagate = FALSE; + } + _state &= ~reset; // reset state of this item + + if ((~_state & flags) == 0) return; // nothing to do + + // TODO this might be wrong + if (_state & STATE_BBOX) { + // we have up-to-date bbox + if (!area.intersects(outline ? _bbox : _drawbox)) return; + } + + UpdateContext child_ctx(ctx); + if (_transform) { + child_ctx.ctm = *_transform * ctx.ctm; + } + /* Remember the transformation matrix */ + Geom::Affine ctm_change = _ctm.inverse() * child_ctx.ctm; + _ctm = child_ctx.ctm; + + // update _bbox + _state = _updateItem(area, child_ctx, flags, reset); + + // compute drawbox + if (_filter && render_filters && _item_bbox) { + _drawbox = _filter->compute_drawbox(this, *_item_bbox); + } else { + _drawbox = _bbox; + } + + // Clipping + if (_clip) { + _clip->update(area, child_ctx, flags, reset); + if (outline) { + _bbox.unionWith(_clip->_bbox); + } else { + _drawbox.intersectWith(_clip->_bbox); + } + } + // masking + if (_mask) { + _mask->update(area, child_ctx, flags, reset); + if (outline) { + _bbox.unionWith(_mask->_bbox); + } else { + // for masking, we need full drawbox of mask + _drawbox.intersectWith(_mask->_drawbox); + } + } + + // update cache if enabled + if (_cached) { + Geom::OptIntRect cl = _drawing->cache_limit; + cl.intersectWith(_drawbox); + if (cl) { + if (_cache) { + // this takes care of invalidation on transform + _cache->resizeAndTransform(*cl, ctm_change); + } else { + _cache = new Inkscape::DrawingCache(*cl); + // the cache is initially dirty + } + } else { + // disable cache for this item - not visible + delete _cache; + _cache = NULL; + } + } + + // now that we know drawbox, dirty the corresponding rect on canvas + // unless filtered, groups do not need to render by themselves, only their members + if (!is_drawing_group(this) || (_filter && render_filters)) { + if (flags & ~STATE_CACHE) { + _markForRendering(); + } + } +} + +struct MaskLuminanceToAlpha { + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a, r, g, b) + // the operation of unpremul -> luminance-to-alpha -> multiply by alpha + // is equivalent to luminance-to-alpha on premultiplied color values + // original computation in double: r*0.2125 + g*0.7154 + b*0.0721 + guint32 ao = r*109 + g*366 + b*37; // coeffs add up to 512 + return ((ao + 256) << 15) & 0xff000000; // equivalent to ((ao + 256) / 512) << 24 + } +}; + +void +DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + bool outline = (_drawing->rendermode == Inkscape::RENDERMODE_OUTLINE); + bool render_filters = (_drawing->rendermode == Inkscape::RENDERMODE_NORMAL); + + /* If we are invisible, just return successfully */ + if (!_visible) return; + + if (outline) { + _renderOutline(ct, area, flags); + return; + } + + // carea is the bounding box for intermediate rendering. + Geom::OptIntRect carea = Geom::intersect(area, _drawbox); + if (!carea) return; + + // render from cache + if (_cached && _cache) { + if (_cache->paintFromCache(ct, *carea)) + return; + } + + // expand carea to contain the dependent area of filters. + if (_filter && render_filters) { + _filter->area_enlarge(*carea, this); + carea.intersectWith(_drawbox); + } + + // determine whether this shape needs intermediate rendering. + bool needs_intermediate_rendering = false; + bool &nir = needs_intermediate_rendering; + bool needs_opacity = (_opacity < 0.995); + + // this item needs an intermediate rendering if: + nir |= (_clip != NULL); // 1. it has a clipping path + nir |= (_mask != NULL); // 2. it has a mask + nir |= (_filter != NULL && render_filters); // 3. it has a filter + nir |= needs_opacity; // 4. it is non-opaque + + /* How the rendering is done. + * + * Clipping, masking and opacity are done by rendering them to a surface + * and then compositing the object's rendering onto it with the IN operator. + * The object itself is rendered to a group. + * + * Opacity is done by rendering the clipping path with an alpha + * value corresponding to the opacity. If there is no clipping path, + * the entire intermediate surface is painted with alpha corresponding + * to the opacity value. + */ + + // short-circuit the simple case. + if (!needs_intermediate_rendering) { + if (_cached && _cache) { + Inkscape::DrawingContext cachect(*_cache); + cachect.rectangle(area); + cachect.clip(); + + { // 1. clear the corresponding part of cache + Inkscape::DrawingContext::Save save(cachect); + cachect.setSource(0,0,0,0); + cachect.setOperator(CAIRO_OPERATOR_SOURCE); + cachect.paint(); + } + // 2. render to cache + _renderItem(cachect, *carea, flags); + // 3. copy from cache to output + Inkscape::DrawingContext::Save save(ct); + ct.rectangle(*carea); + ct.clip(); + ct.setSource(_cache); + ct.paint(); + // 4. mark as clean + _cache->markClean(area); + return; + } else { + _renderItem(ct, *carea, flags); + return; + } + } + + DrawingSurface intermediate(*carea); + DrawingContext ict(intermediate); + + // 1. Render clipping path with alpha = opacity. + ict.setSource(0,0,0,_opacity); + // Since clip can be combined with opacity, the result could be incorrect + // for overlapping clip children. To fix this we use the SOURCE operator + // instead of the default OVER. + ict.setOperator(CAIRO_OPERATOR_SOURCE); + if (_clip) { + _clip->clip(ict, *carea); // fixme: carea or area? + } else { + // if there is no clipping path, fill the entire surface with alpha = opacity. + ict.paint(); + } + ict.setOperator(CAIRO_OPERATOR_OVER); // reset back to default + + // 2. Render the mask if present and compose it with the clipping path + opacity. + if (_mask) { + ict.pushGroup(); + _mask->render(ict, *carea, flags); + + cairo_surface_t *mask_s = ict.rawTarget(); + // Convert mask's luminance to alpha + ink_cairo_surface_filter(mask_s, mask_s, MaskLuminanceToAlpha()); + ict.popGroupToSource(); + ict.setOperator(CAIRO_OPERATOR_IN); + ict.paint(); + ict.setOperator(CAIRO_OPERATOR_OVER); + } + + // 3. Render object itself. + ict.pushGroup(); + _renderItem(ict, *carea, flags); + + // 4. Apply filter. + if (_filter && render_filters) { + _filter->render(this, ct, ict); + // Note that because the object was rendered to a group, + // the internals of the filter need to use cairo_get_group_target() + // instead of cairo_get_target(). + } + + // 5. Render object inside the composited mask + clip + ict.popGroupToSource(); + ict.setOperator(CAIRO_OPERATOR_IN); + ict.paint(); + + // 6. Paint the completed rendering onto the base context (or into cache) + if (_cached && _cache) { + DrawingContext cachect(*_cache); + cachect.rectangle(area); + cachect.clip(); + cachect.setOperator(CAIRO_OPERATOR_SOURCE); + cachect.setSource(&intermediate); + cachect.paint(); + _cache->markClean(area); + } + ct.setSource(&intermediate); + ct.paint(); + ct.setSource(0,0,0,0); + // the call above is to clear a ref on the intermediate surface held by ct +} + +void +DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + // intersect with bbox rather than drawbox, as we want to render things outside + // of the clipping path as well + Geom::OptIntRect carea = Geom::intersect(area, _bbox); + if (!carea) return; + + // just render everything: item, clip, mask + // First, render the object itself + _renderItem(ct, *carea, flags); + + // render clip and mask, if any + guint32 saved_rgba = _drawing->outlinecolor; // save current outline color + // render clippath as an object, using a different color + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (_clip) { + _drawing->outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips + _clip->render(ct, *carea, flags); + } + // render mask as an object, using a different color + if (_mask) { + _drawing->outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks + _mask->render(ct, *carea, flags); + } + _drawing->outlinecolor = saved_rgba; // restore outline color +} + +void +DrawingItem::clip(Inkscape::DrawingContext &ct, Geom::IntRect const &area) +{ + // don't bother if the object does not implement clipping (e.g. DrawingImage) + if (!_canClip()) return; + if (!_visible) return; + if (!area.intersects(_bbox)) return; + + // The item used as the clipping path itself has a clipping path. + // Render this item's clipping path onto a temporary surface, then composite it + // with the item using the IN operator + if (_clip) { + ct.pushAlphaGroup(); + { Inkscape::DrawingContext::Save save(ct); + ct.setSource(0,0,0,1); + _clip->clip(ct, area); + } + ct.pushAlphaGroup(); + } + + // rasterize the clipping path + _clipItem(ct, area); + + if (_clip) { + ct.popGroupToSource(); + ct.setOperator(CAIRO_OPERATOR_IN); + ct.paint(); + ct.popGroupToSource(); + ct.setOperator(CAIRO_OPERATOR_SOURCE); + ct.paint(); + } +} + +DrawingItem * +DrawingItem::pick(Geom::Point const &p, double delta, bool sticky) +{ + // Sometimes there's no BBOX in state, reason unknown (bug 992817) + // I made this not an assert to remove the warning + if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) + return NULL; + + if (!sticky && !(_visible && _sensitive)) + return NULL; + + if (!_bbox) return NULL; + Geom::Rect expanded(*_bbox); + expanded.expandBy(delta); + + if (expanded.contains(p)) { + return _pickItem(p, delta); + } + return NULL; +} + +void +DrawingItem::_markForRendering() +{ + bool outline = (_drawing->rendermode == Inkscape::RENDERMODE_OUTLINE); + Geom::OptIntRect dirty = outline ? _bbox : _drawbox; + if (!dirty) return; + + // dirty the caches of all parents + for (DrawingItem *i = this; i; i = i->_parent) { + if (i->_cached && i->_cache) { + i->_cache->markDirty(*dirty); + } + } + + nr_arena_request_render_rect (_drawing, dirty); +} + +void +DrawingItem::_markForUpdate(unsigned flags, bool propagate) +{ + // here 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; + + if (_state & flags) { + _state &= ~flags; + if (_parent) { + _parent->_markForUpdate(flags, false); + } else { + nr_arena_request_update (_drawing, this); + } + } +} + +void +DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) +{ + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; + + // if group has a filter + if (style->filter.set && style->getFilter()) { + if (!_filter) { + int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); + _filter = new Inkscape::Filters::Filter(primitives); + } + sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); + } else { + // no filter set for this group + delete _filter; + _filter = NULL; + } + + /* + if (style && style->enable_background.set + && style->enable_background.value == SP_CSS_BACKGROUND_NEW) { + _background_new = true; + }*/ +} + +} // 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 : diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h new file mode 100644 index 000000000..b34ddf0e4 --- /dev/null +++ b/src/display/drawing-item.h @@ -0,0 +1,168 @@ +/** + * @file + * @brief Canvas item belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +#include <exception> +#include <boost/intrusive/list.hpp> +#include <2geom/rect.h> +#include <2geom/affine.h> + +class NRArena; +class SPStyle; +void nr_arena_set_cache_limit(NRArena *, Geom::OptIntRect const &); + +namespace Inkscape { + +typedef ::NRArena Drawing; +class DrawingContext; +class DrawingCache; +class DrawingItem; +namespace Filters { class Filter; } + +struct UpdateContext { + Geom::Affine ctm; +}; + +class InvalidItemException : public std::exception { + virtual const char *what() const throw() { + return "Invalid item in drawing"; + } +}; + +typedef boost::intrusive::list_base_hook<> ChildrenListHook; + +class DrawingItem + : public ChildrenListHook +{ +public: + enum RenderFlags { + RENDER_DEFAULT = 0, + RENDER_CACHE_ONLY = 1, + RENDER_BYPASS_CACHE = 2 + }; + enum StateFlags { + STATE_NONE = 0, + STATE_BBOX = (1<<0), // geometric bounding box is up-to-date + STATE_DRAWBOX = (1<<1), // visual bounding box is up-to-date + STATE_CACHE = (1<<2), // cache extents and clean area are up-to-date + STATE_PICK = (1<<3), // can process pick requests + STATE_RENDER = (1<<4), // can be rendered + STATE_ALL = (1<<5)-1 + }; + typedef boost::intrusive::list<DrawingItem> ChildrenList; + + DrawingItem(Drawing *drawing); + virtual ~DrawingItem(); + + Geom::OptIntRect geometricBounds() const { return _bbox; } + Geom::OptIntRect visualBounds() const { return _drawbox; } + Geom::OptRect itemBounds() const { return _item_bbox; } + Geom::Affine ctm() const { return _ctm; } + Geom::Affine transform() const { return _transform ? *_transform : Geom::identity(); } + Drawing *drawing() const { return _drawing; } + DrawingItem *parent() const; + + void appendChild(DrawingItem *item); + void prependChild(DrawingItem *item); + void clearChildren(); + + bool visible() const { return _visible; } + void setVisible(bool v); + bool sensitive() const { return _sensitive; } + void setSensitive(bool v); + bool cached() const { return _cached; } + void setCached(bool c); + + void setOpacity(float opacity); + void setTransform(Geom::Affine const &trans); + void setClip(DrawingItem *item); + void setMask(DrawingItem *item); + void setZOrder(unsigned z); + void setItemBounds(Geom::OptRect const &bounds); + + void setKey(unsigned key) { _key = key; } + unsigned key() const { return _key; } + void setData(void *data) { _user_data = data; } + void *data() const { return _user_data; } + + void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = STATE_ALL, unsigned reset = 0); + void render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags = 0); + void clip(DrawingContext &ct, Geom::IntRect const &area); + DrawingItem *pick(Geom::Point const &p, double delta, bool sticky); + +protected: + void _renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsigned flags); + void _markForUpdate(unsigned state, bool propagate); + void _markForRendering(); + void _setStyleCommon(SPStyle *&_style, SPStyle *style); + virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, + 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 bool _canClip() { return false; } + + Drawing *_drawing; + DrawingItem *_parent; + ChildrenList _children; + + unsigned _key; ///< Some SPItems can have more than one NRArenaItem; + /// this value is a hack used to distinguish between them + float _opacity; + + Geom::Affine *_transform; ///< Incremental transform from parent to this item's coords + Geom::Affine _ctm; ///< Total transform from item coords to display coords + Geom::OptIntRect _bbox; ///< Bounding box in display (pixel) coords + Geom::OptIntRect _drawbox; ///< Bounding box enlarged by filters, shrinked by clips and masks + Geom::OptRect _item_bbox; ///< Bounding box in item coordinates + + DrawingItem *_clip; + DrawingItem *_mask; + Inkscape::Filters::Filter *_filter; + void *_user_data; ///< Used to associate DrawingItems with SPItems that created them + DrawingCache *_cache; + + unsigned _state : 8; + unsigned _visible : 1; + unsigned _sensitive : 1; ///< Whether this item responds to events + unsigned _cached : 1; ///< Whether the rendering is stored for reuse + unsigned _propagate : 1; ///< Whether to call update for all children on next update + //unsigned _renders_opacity : 1; ///< Whether object needs temporary surface for opacity + unsigned _clip_child : 1; ///< If set, this is not a child of _parent, but a clipping path + unsigned _mask_child : 1; ///< If set, this is not a child of _parent, but a mask + unsigned _pick_children : 1; ///< For groups: if true, children are returned from pick(), + /// otherwise the group is returned + + // temporary hacks until I rewrite NRArena to Inkscape::Drawing + friend class NRArena; + friend void ::nr_arena_set_cache_limit(NRArena *, Geom::OptIntRect const &); +}; + +struct DeleteDisposer { + void operator()(DrawingItem *item) { delete item; } +}; + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +/* + 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 : diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp new file mode 100644 index 000000000..1a56eea9b --- /dev/null +++ b/src/display/drawing-shape.cpp @@ -0,0 +1,340 @@ +/** + * @file + * @brief Shape (styled path) belonging to an SVG drawing + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <glib.h> +#include <2geom/curves.h> +#include <2geom/pathvector.h> +#include <2geom/svg-path.h> +#include <2geom/svg-path-parser.h> + +#include "display/cairo-utils.h" +#include "display/canvas-arena.h" +#include "display/canvas-bpath.h" +#include "display/curve.h" +#include "display/drawing-context.h" +#include "display/drawing-group.h" +#include "display/drawing-shape.h" +#include "display/nr-arena.h" +#include "helper/geom-curves.h" +#include "helper/geom.h" +#include "libnr/nr-convert2geom.h" +#include "preferences.h" +#include "style.h" +#include "svg/svg.h" + +namespace Inkscape { + +DrawingShape::DrawingShape(Drawing *drawing) + : DrawingItem(drawing) + , _curve(NULL) + , _style(NULL) + , _last_pick(NULL) + , _repick_after(0) +{} + +DrawingShape::~DrawingShape() +{ + if (_style) + sp_style_unref(_style); + if (_curve) + _curve->unref(); +} + +void +DrawingShape::setPath(SPCurve *curve) +{ + _markForRendering(); + + if (_curve) { + _curve->unref(); + _curve = NULL; + } + if (curve) { + _curve = curve; + curve->ref(); + } + + _markForUpdate(STATE_ALL, false); +} + +void +DrawingShape::setStyle(SPStyle *style) +{ + _setStyleCommon(_style, style); + _nrstyle.set(style); +} + +void +DrawingShape::setPaintBox(Geom::Rect const &box) +{ + _paintbox = box; + _markForUpdate(STATE_ALL, false); +} + +unsigned +DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + Geom::OptRect boundingbox; + + unsigned beststate = STATE_ALL; + + // update markers + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->update(area, ctx, flags, reset); + } + + if (!(flags & STATE_RENDER)) { + /* We do not have to create rendering structures */ + if (flags & STATE_BBOX) { + if (_curve) { + boundingbox = bounds_exact_transformed(_curve->get_pathvector(), ctx.ctm); + if (boundingbox) { + _bbox = boundingbox->roundOutwards(); + } else { + _bbox = Geom::OptIntRect(); + } + } + if (beststate & STATE_BBOX) { + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + _bbox.unionWith(i->geometricBounds()); + } + } + } + return (flags | _state); + } + + boundingbox = Geom::OptRect(); + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + // clear Cairo data to force update + _nrstyle.update(); + + if (_curve) { + boundingbox = bounds_exact_transformed(_curve->get_pathvector(), ctx.ctm); + + if (boundingbox && (_nrstyle.stroke.type != NRStyle::PAINT_NONE || outline)) { + float width, scale; + scale = ctx.ctm.descrim(); + width = std::max(0.125f, _nrstyle.stroke_width * scale); + if ( fabs(_nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true + boundingbox->expandBy(width); + } + // those pesky miters, now + float miterMax = width * _nrstyle.miter_limit; + if ( miterMax > 0.01 ) { + // grunt mode. we should compute the various miters instead + // (one for each point on the curve) + boundingbox->expandBy(miterMax); + } + } + } + + _bbox = boundingbox ? boundingbox->roundOutwards() : Geom::OptIntRect(); + + if (!_curve || + !_style || + _curve->is_empty() || + (( _nrstyle.fill.type != NRStyle::PAINT_NONE ) && + ( _nrstyle.stroke.type != NRStyle::PAINT_NONE && !outline) )) + { + return STATE_ALL; + } + + if (beststate & STATE_BBOX) { + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + _bbox.unionWith(i->geometricBounds()); + } + } + + return STATE_ALL; +} + +void +DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + if (!_curve || !_style) return; + if (!area.intersects(_bbox)) return; // skip if not within bounding box + + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + if (outline) { + guint32 rgba = _drawing->outlinecolor; + + { Inkscape::DrawingContext::Save save(ct); + ct.transform(_ctm); + ct.path(_curve->get_pathvector()); + } + { Inkscape::DrawingContext::Save save(ct); + ct.setSource(rgba); + ct.setLineWidth(0.5); + ct.setTolerance(1.25); + ct.stroke(); + } + } else { + bool has_stroke, has_fill; + // we assume the context has no path + Inkscape::DrawingContext::Save save(ct); + ct.transform(_ctm); + + // update fill and stroke paints. + // this cannot be done during nr_arena_shape_update, because we need a Cairo context + // to render svg:pattern + has_fill = _nrstyle.prepareFill(ct, _paintbox); + has_stroke = _nrstyle.prepareStroke(ct, _paintbox); + has_stroke &= (_nrstyle.stroke_width != 0); + + if (has_fill || has_stroke) { + // TODO: remove segments outside of bbox when no dashes present + ct.path(_curve->get_pathvector()); + if (has_fill) { + _nrstyle.applyFill(ct); + ct.fillPreserve(); + } + if (has_stroke) { + _nrstyle.applyStroke(ct); + ct.strokePreserve(); + } + ct.newPath(); // clear path + } // has fill or stroke pattern + } + + // marker rendering + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->render(ct, area, flags); + } +} + +void +DrawingShape::_clipItem(DrawingContext &ct, Geom::IntRect const &area) +{ + if (!_curve) return; + + Inkscape::DrawingContext::Save save(ct); + // handle clip-rule + if (_style) { + if (_style->clip_rule.computed == SP_WIND_RULE_EVENODD) { + ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD); + } else { + ct.setFillRule(CAIRO_FILL_RULE_WINDING); + } + } + ct.transform(_ctm); + ct.path(_curve->get_pathvector()); + ct.fill(); +} + +DrawingItem * +DrawingShape::_pickItem(Geom::Point const &p, double delta) +{ + 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 (!_curve) return NULL; + if (!_style) return NULL; + + bool outline = (_drawing->rendermode == RENDERMODE_OUTLINE); + + if (SP_SCALE24_TO_FLOAT(_style->opacity.value) == 0 && !outline) + // fully transparent, no pick unless outline mode + return NULL; + + GTimeVal tstart, tfinish; + g_get_current_time (&tstart); + + double width; + if (outline) { + width = 0.5; + } else if (_nrstyle.stroke.type != NRStyle::PAINT_NONE && _nrstyle.stroke.opacity > 1e-3) { + float const scale = _ctm.descrim(); + width = std::max(0.125f, _nrstyle.stroke_width * scale) / 2; + } else { + width = 0; + } + + double dist = Geom::infinity(); + int wind = 0; + bool needfill = (_nrstyle.fill.type != NRStyle::PAINT_NONE + && _nrstyle.fill.opacity > 1e-3 && !outline); + + if (_drawing->canvasarena) { + Geom::Rect viewbox = _drawing->canvasarena->item.canvas->getViewbox(); + viewbox.expandBy (width); + pathv_matrix_point_bbox_wind_distance(_curve->get_pathvector(), _ctm, p, NULL, needfill? &wind : NULL, &dist, 0.5, &viewbox); + } else { + pathv_matrix_point_bbox_wind_distance(_curve->get_pathvector(), _ctm, p, NULL, needfill? &wind : NULL, &dist, 0.5, NULL); + } + + g_get_current_time (&tfinish); + glong this_pick = (tfinish.tv_sec - tstart.tv_sec) * 1000000 + (tfinish.tv_usec - tstart.tv_usec); + //g_print ("pick time %lu\n", this_pick); + + if (this_pick > 10000) { // slow picking, remember to skip several new picks + _repick_after = this_pick / 5000; + } + + // covered by fill? + if (needfill) { + if (!_style->fill_rule.computed) { + if (wind != 0) { + _last_pick = this; + return this; + } + } else { + if (wind & 0x1) { + _last_pick = this; + return this; + } + } + } + + // close to the edge, as defined by strokewidth and delta? + // this ignores dashing (as if the stroke is solid) and always works as if caps are round + if (needfill || width > 0) { // if either fill or stroke visible, + if ((dist - width) < delta) { + _last_pick = this; + return this; + } + } + + // if not picked on the shape itself, try its markers + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingItem *ret = i->pick(p, delta, false); + if (ret) { + _last_pick = this; + return this; + } + } + + _last_pick = NULL; + return NULL; +} + +bool +DrawingShape::_canClip() +{ + return true; +} + +} // 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 : diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h new file mode 100644 index 000000000..7fd16374e --- /dev/null +++ b/src/display/drawing-shape.h @@ -0,0 +1,64 @@ +/** + * @file + * @brief Group belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_SHAPE_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_SHAPE_H + +#include "display/drawing-item.h" +#include "display/nr-style.h" + +class SPStyle; +class SPCurve; + +namespace Inkscape { + +class DrawingShape + : public DrawingItem +{ +public: + DrawingShape(Drawing *drawing); + ~DrawingShape(); + + void setPath(SPCurve *curve); + void setStyle(SPStyle *style); + void setPaintBox(Geom::Rect const &box); + +protected: + 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 void _clipItem(DrawingContext &ct, Geom::IntRect const &area); + virtual DrawingItem *_pickItem(Geom::Point const &p, double delta); + virtual bool _canClip(); + + SPCurve *_curve; + SPStyle *_style; + NRStyle _nrstyle; + + Geom::OptRect _paintbox; + DrawingItem *_last_pick; + unsigned _repick_after; +}; + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +/* + 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 : diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp new file mode 100644 index 000000000..784888bd7 --- /dev/null +++ b/src/display/drawing-text.cpp @@ -0,0 +1,275 @@ +/** + * @file + * @brief Group belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/cairo-utils.h" +#include "display/canvas-bpath.h" // for SPWindRule (WTF!) +#include "display/drawing-context.h" +#include "display/drawing-surface.h" +#include "display/drawing-text.h" +#include "display/nr-arena.h" +#include "helper/geom.h" +#include "libnrtype/font-instance.h" +#include "style.h" + +namespace Inkscape { + +DrawingGlyphs::DrawingGlyphs(Drawing *drawing) + : DrawingItem(drawing) + , _glyph_transform(NULL) + , _font(NULL) + , _glyph(0) +{} + +DrawingGlyphs::~DrawingGlyphs() +{ + if (_font) { + _font->Unref(); + _font = NULL; + } + delete _glyph_transform; +} + +void +DrawingGlyphs::setGlyph(font_instance *font, int glyph, Geom::Affine const &trans) +{ + _markForRendering(); + + if (trans.isIdentity()) { + delete _glyph_transform; // delete NULL; is safe + _glyph_transform = NULL; + } else { + _glyph_transform = new Geom::Affine(trans); + } + + if (font) font->Ref(); + if (_font) _font->Unref(); + _font = font; + _glyph = glyph; + + _markForUpdate(STATE_ALL, false); +} + +unsigned +DrawingGlyphs::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + DrawingText *ggroup = dynamic_cast<DrawingText *>(_parent); + if (!ggroup) throw InvalidItemException(); + + if (!_font || !ggroup->_style) return STATE_ALL; + if (ggroup->_nrstyle.fill.type == NRStyle::PAINT_NONE && + ggroup->_nrstyle.stroke.type == NRStyle::PAINT_NONE) + { + return STATE_ALL; + } + + Geom::OptRect b; + Geom::Affine t = _glyph_transform ? *_glyph_transform * ctx.ctm : ctx.ctm; + _x = t[4]; + _y = t[5]; + + b = bounds_exact_transformed(*_font->PathVector(_glyph), t); + if (b && ggroup->_nrstyle.stroke.type != NRStyle::PAINT_NONE) { + float width, scale; + scale = ctx.ctm.descrim(); + width = MAX(0.125, ggroup->_nrstyle.stroke_width * scale); + if ( fabs(ggroup->_nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true + b->expandBy(width); + } + // those pesky miters, now + float miterMax = width * ggroup->_nrstyle.miter_limit; + if ( miterMax > 0.01 ) { + // grunt mode. we should compute the various miters instead + // (one for each point on the curve) + b->expandBy(miterMax); + } + } + + if (b) { + _bbox = b->roundOutwards(); + } else { + _bbox = Geom::OptIntRect(); + } + + return STATE_ALL; +} + +DrawingItem * +DrawingGlyphs::_pickItem(Geom::Point const &p, double delta) +{ + if (!_font || !_bbox) return NULL; + + // With text we take a simple approach: pick if the point is in a characher bbox + Geom::Rect expanded(*_bbox); + expanded.expandBy(delta); + if (expanded.contains(p)) return this; + return NULL; +} + + + +DrawingText::DrawingText(Drawing *drawing) + : DrawingGroup(drawing) +{} + +DrawingText::~DrawingText() +{} + +void +DrawingText::clear() +{ + _markForRendering(); + _children.clear_and_dispose(DeleteDisposer()); +} + +void +DrawingText::addComponent(font_instance *font, int glyph, Geom::Affine const &trans) +{ + if (!font || !font->PathVector(glyph)) return; + + _markForRendering(); + DrawingGlyphs *ng = new DrawingGlyphs(_drawing); + ng->setGlyph(font, glyph, trans); + appendChild(ng); +} + +void +DrawingText::setStyle(SPStyle *style) +{ + _nrstyle.set(style); + DrawingGroup::setStyle(style); +} + +void +DrawingText::setPaintBox(Geom::OptRect const &box) +{ + _paintbox = box; + _markForUpdate(STATE_ALL, false); +} + +unsigned +DrawingText::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + _nrstyle.update(); + return DrawingGroup::_updateItem(area, ctx, flags, reset); +} + +void +DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) +{ + if (_drawing->rendermode == RENDERMODE_OUTLINE) { + DrawingContext::Save save(ct); + guint32 rgba = _drawing->outlinecolor; + ct.setSource(rgba); + ct.setTolerance(1.25); // low quality, but good enough for outline mode + ct.newPath(); + ct.transform(_ctm); + + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(ct); + if (g->_glyph_transform) { + ct.transform(*g->_glyph_transform); + } + ct.path(*g->_font->PathVector(g->_glyph)); + ct.fill(); + } + return; + } + + // NOTE: this is very similar to drawing-shape.cpp; the only difference is in path feeding + bool has_stroke, has_fill; + + Inkscape::DrawingContext::Save save(ct); + ct.transform(_ctm); + + has_fill = _nrstyle.prepareFill(ct, _paintbox); + has_stroke = _nrstyle.prepareStroke(ct, _paintbox); + + if (has_fill || has_stroke) { + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(ct); + if (g->_glyph_transform) { + ct.transform(*g->_glyph_transform); + } + ct.path(*g->_font->PathVector(g->_glyph)); + } + + if (has_fill) { + _nrstyle.applyFill(ct); + ct.fillPreserve(); + } + if (has_stroke) { + _nrstyle.applyStroke(ct); + ct.strokePreserve(); + } + ct.newPath(); // clear path + } +} + +void +DrawingText::_clipItem(DrawingContext &ct, Geom::IntRect const &area) +{ + Inkscape::DrawingContext::Save save(ct); + + // handle clip-rule + if (_style) { + if (_style->clip_rule.computed == SP_WIND_RULE_EVENODD) { + ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD); + } else { + ct.setFillRule(CAIRO_FILL_RULE_WINDING); + } + } + ct.transform(_ctm); + + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(ct); + if (g->_glyph_transform) { + ct.transform(*g->_glyph_transform); + } + ct.path(*g->_font->PathVector(g->_glyph)); + } + ct.fill(); +} + +DrawingItem * +DrawingText::_pickItem(Geom::Point const &p, double delta) +{ + DrawingItem *picked = DrawingGroup::_pickItem(p, delta); + if (picked) return this; + return NULL; +} + +bool +DrawingText::_canClip() +{ + return true; +} + +} // 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 : diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h new file mode 100644 index 000000000..58fecc067 --- /dev/null +++ b/src/display/drawing-text.h @@ -0,0 +1,84 @@ +/** + * @file + * @brief Group belonging to an SVG drawing element + *//* + * Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_TEXT_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_TEXT_H + +#include "display/drawing-group.h" +#include "display/nr-style.h" + +class SPStyle; +class font_instance; + +namespace Inkscape { + +class DrawingGlyphs + : public DrawingItem +{ +public: + DrawingGlyphs(Drawing *drawing); + ~DrawingGlyphs(); + + void setGlyph(font_instance *font, int glyph, Geom::Affine const &trans); + +protected: + unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, + unsigned flags, unsigned reset); + virtual DrawingItem *_pickItem(Geom::Point const &p, double delta); + + Geom::Affine *_glyph_transform; + font_instance *_font; + int _glyph; + float _x, _y; + + friend class DrawingText; +}; + +class DrawingText + : public DrawingGroup +{ +public: + DrawingText(Drawing *drawing); + ~DrawingText(); + + void clear(); + void addComponent(font_instance *font, int glyph, Geom::Affine const &trans); + void setStyle(SPStyle *style); + void setPaintBox(Geom::OptRect const &box); + +protected: + 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 void _clipItem(DrawingContext &ct, Geom::IntRect const &area); + virtual DrawingItem *_pickItem(Geom::Point const &p, double delta); + virtual bool _canClip(); + + Geom::OptRect _paintbox; + NRStyle _nrstyle; + + friend class DrawingGlyphs; +}; + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H + +/* + 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 : diff --git a/src/display/grayscale.cpp b/src/display/grayscale.cpp index 745a08c1e..e468044d3 100644 --- a/src/display/grayscale.cpp +++ b/src/display/grayscale.cpp @@ -82,7 +82,7 @@ guchar luminance(guchar r, guchar g, guchar b) { */ bool activeDesktopIsGrayscale() { if (SP_ACTIVE_DESKTOP) { - return (SP_ACTIVE_DESKTOP->getColorMode() == Inkscape::COLORRENDERMODE_GRAYSCALE); + return (SP_ACTIVE_DESKTOP->getColorMode() == Inkscape::COLORMODE_GRAYSCALE); } else { return false; } diff --git a/src/display/nr-arena-forward.h b/src/display/nr-arena-forward.h deleted file mode 100644 index 5a5cf228a..000000000 --- a/src/display/nr-arena-forward.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __NR_ARENA_FORWARD_H__ -#define __NR_ARENA_FORWARD_H__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -struct NRArena; -struct NRArenaClass; - -struct NRArenaItem; -struct NRArenaItemClass; - -struct NRArenaGroup; -struct NRArenaGroupClass; - -struct NRArenaShape; -struct NRArenaShapeClass; - -struct NRArenaShapeGroup; -struct NRArenaShapeGroupClass; - -struct NRArenaImage; -struct NRArenaImageClass; - -struct NRArenaGlyphs; -struct NRArenaGlyphsClass; - -struct NRArenaGlyphsGroup; -struct NRArenaGlyphsGroupClass; - -#endif - -/* - 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 : diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp deleted file mode 100644 index 99b0a004e..000000000 --- a/src/display/nr-arena-glyphs.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2002 Lauris Kaplinski - * - * Released under GNU GPL - * - */ - - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <cairo.h> -#include <2geom/affine.h> -#include <2geom/rect.h> -#include "libnr/nr-convert2geom.h" -#include "style.h" -#include "display/nr-arena.h" -#include "display/nr-arena-glyphs.h" -#include "display/cairo-utils.h" -#include "display/drawing-context.h" -#include "helper/geom.h" - -#ifdef test_glyph_liv -#include "../display/canvas-bpath.h" -#include "libnrtype/font-instance.h" - -// defined in nr-arena-shape.cpp -void nr_pixblock_render_shape_mask_or(NRPixBlock &m, Shape *theS); -#endif - -#ifdef ENABLE_SVG_FONTS -#include "nr-svgfonts.h" -#endif //#ifdef ENABLE_SVG_FONTS - -static void nr_arena_glyphs_class_init(NRArenaGlyphsClass *klass); -static void nr_arena_glyphs_init(NRArenaGlyphs *glyphs); -static void nr_arena_glyphs_finalize(NRObject *object); - -static guint nr_arena_glyphs_update(NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, guint state, guint reset); -static NRArenaItem *nr_arena_glyphs_pick(NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); - -static NRArenaItemClass *glyphs_parent_class; - -NRType -nr_arena_glyphs_get_type(void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type(NR_TYPE_ARENA_ITEM, - "NRArenaGlyphs", - sizeof(NRArenaGlyphsClass), - sizeof(NRArenaGlyphs), - (void (*)(NRObjectClass *)) nr_arena_glyphs_class_init, - (void (*)(NRObject *)) nr_arena_glyphs_init); - } - return type; -} - -static void -nr_arena_glyphs_class_init(NRArenaGlyphsClass *klass) -{ - NRObjectClass *object_class; - NRArenaItemClass *item_class; - - object_class = (NRObjectClass *) klass; - item_class = (NRArenaItemClass *) klass; - - glyphs_parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; - - object_class->finalize = nr_arena_glyphs_finalize; - object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaGlyphs>; - - item_class->update = nr_arena_glyphs_update; - item_class->pick = nr_arena_glyphs_pick; -} - -static void -nr_arena_glyphs_init(NRArenaGlyphs *glyphs) -{ - glyphs->g_transform.setIdentity(); - glyphs->font = NULL; - glyphs->glyph = 0; - glyphs->x = glyphs->y = 0.0; -} - -static void -nr_arena_glyphs_finalize(NRObject *object) -{ - NRArenaGlyphs *glyphs = static_cast<NRArenaGlyphs *>(object); - - if (glyphs->font) { - glyphs->font->Unref(); - glyphs->font=NULL; - } - - ((NRObjectClass *) glyphs_parent_class)->finalize(object); -} - -static guint -nr_arena_glyphs_update(NRArenaItem *item, Geom::IntRect const &/*area*/, NRGC *gc, guint /*state*/, guint /*reset*/) -{ - NRArenaGlyphs *glyphs = NR_ARENA_GLYPHS(item); - NRArenaGlyphsGroup *ggroup = NR_ARENA_GLYPHS_GROUP(item->parent); - - if (!glyphs->font || !ggroup->style) - return NR_ARENA_ITEM_STATE_ALL; - if (ggroup->nrstyle.fill.type == NRStyle::PAINT_NONE && ggroup->nrstyle.stroke.type == NRStyle::PAINT_NONE) - return NR_ARENA_ITEM_STATE_ALL; - - Geom::OptRect b; - Geom::Affine t = glyphs->g_transform * gc->transform; - glyphs->x = t[4]; - glyphs->y = t[5]; - - b = bounds_exact_transformed(*glyphs->font->PathVector(glyphs->glyph), t); - if (b && ggroup->nrstyle.stroke.type != NRStyle::PAINT_NONE) { - float width, scale; - scale = gc->transform.descrim(); - width = MAX(0.125, ggroup->nrstyle.stroke_width * scale); - if ( fabs(ggroup->nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true - b->expandBy(width); - } - // those pesky miters, now - float miterMax = width * ggroup->nrstyle.miter_limit; - if ( miterMax > 0.01 ) { - // grunt mode. we should compute the various miters instead - // (one for each point on the curve) - b->expandBy(miterMax); - } - } - - if (b) { - item->bbox = b->roundOutwards(); - } else { - item->bbox = Geom::OptIntRect(); - } - - return NR_ARENA_ITEM_STATE_ALL; -} - -static NRArenaItem * -nr_arena_glyphs_pick(NRArenaItem *item, Geom::Point const &p, gdouble delta, unsigned int /*sticky*/) -{ - NRArenaGlyphs *glyphs; - - glyphs = NR_ARENA_GLYPHS(item); - - if (!glyphs->font ) return NULL; - if (!item->bbox) return NULL; - - // With text we take a simple approach: pick if the point is in a characher bbox - Geom::Rect expanded(*item->bbox); - expanded.expandBy(delta); - if (expanded.contains(p)) - return item; - return NULL; -} - -void -nr_arena_glyphs_set_path(NRArenaGlyphs *glyphs, SPCurve */*curve*/, unsigned int /*lieutenant*/, font_instance *font, gint glyph, Geom::Affine const *transform) -{ - nr_return_if_fail(glyphs != NULL); - nr_return_if_fail(NR_IS_ARENA_GLYPHS(glyphs)); - - nr_arena_item_request_render(NR_ARENA_ITEM(glyphs)); - - if (transform) { - glyphs->g_transform = *transform; - } else { - glyphs->g_transform.setIdentity(); - } - - if (font) font->Ref(); - if (glyphs->font) glyphs->font->Unref(); - glyphs->font=font; - glyphs->glyph = glyph; - - nr_arena_item_request_update(NR_ARENA_ITEM(glyphs), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -static void nr_arena_glyphs_group_class_init(NRArenaGlyphsGroupClass *klass); -static void nr_arena_glyphs_group_init(NRArenaGlyphsGroup *group); -static void nr_arena_glyphs_group_finalize(NRObject *object); - -static guint nr_arena_glyphs_group_update(NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, guint state, guint reset); -static unsigned int nr_arena_glyphs_group_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); -static unsigned int nr_arena_glyphs_group_clip(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area); -static NRArenaItem *nr_arena_glyphs_group_pick(NRArenaItem *item, Geom::Point const &p, gdouble delta, unsigned int sticky); - -static NRArenaGroupClass *group_parent_class; - -NRType -nr_arena_glyphs_group_get_type(void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type(NR_TYPE_ARENA_GROUP, - "NRArenaGlyphsGroup", - sizeof(NRArenaGlyphsGroupClass), - sizeof(NRArenaGlyphsGroup), - (void (*)(NRObjectClass *)) nr_arena_glyphs_group_class_init, - (void (*)(NRObject *)) nr_arena_glyphs_group_init); - } - return type; -} - -static void -nr_arena_glyphs_group_class_init(NRArenaGlyphsGroupClass *klass) -{ - NRObjectClass *object_class; - NRArenaItemClass *item_class; - - object_class = (NRObjectClass *) klass; - item_class = (NRArenaItemClass *) klass; - - group_parent_class = (NRArenaGroupClass *) ((NRObjectClass *) klass)->parent; - - object_class->finalize = nr_arena_glyphs_group_finalize; - object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaGlyphsGroup>; - - item_class->update = nr_arena_glyphs_group_update; - item_class->render = nr_arena_glyphs_group_render; - item_class->clip = nr_arena_glyphs_group_clip; - item_class->pick = nr_arena_glyphs_group_pick; -} - -static void -nr_arena_glyphs_group_init(NRArenaGlyphsGroup *group) -{ - group->style = NULL; -} - -static void -nr_arena_glyphs_group_finalize(NRObject *object) -{ - NRArenaGlyphsGroup *group = static_cast<NRArenaGlyphsGroup *>(object); - - if (group->style) { - sp_style_unref(group->style); - group->style = NULL; - } - - ((NRObjectClass *) group_parent_class)->finalize(object); -} - -static guint -nr_arena_glyphs_group_update(NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, guint state, guint reset) -{ - NRArenaGlyphsGroup *group = NR_ARENA_GLYPHS_GROUP(item); - - group->nrstyle.update(); - - if (((NRArenaItemClass *) group_parent_class)->update) - return ((NRArenaItemClass *) group_parent_class)->update(item, area, gc, state, reset); - - return NR_ARENA_ITEM_STATE_ALL; -} - - -static unsigned int -nr_arena_glyphs_group_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int /*flags*/) -{ - NRArenaItem *child = 0; - - NRArenaGroup *group = NR_ARENA_GROUP(item); - NRArenaGlyphsGroup *ggroup = NR_ARENA_GLYPHS_GROUP(item); - - if (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE) { - Inkscape::DrawingContext::Save save(ct); - guint32 rgba = item->arena->outlinecolor; - ct.setSource(rgba); - ct.setTolerance(1.25); // low quality, but good enough for outline mode - ct.newPath(); - ct.transform(ggroup->ctm); - - for (child = group->children; child != NULL; child = child->next) { - NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); - - Geom::PathVector const * pathv = g->font->PathVector(g->glyph); - Geom::Affine transform = g->g_transform; - - Inkscape::DrawingContext::Save save(ct); - ct.transform(transform); - ct.path(*pathv); - ct.fill(); - } - return item->state; - } - - // NOTE: this is very similar to nr-arena-shape.cpp; the only difference is path feeding - bool has_stroke, has_fill; - - Inkscape::DrawingContext::Save save(ct); - ct.transform(ggroup->ctm); - - has_fill = ggroup->nrstyle.prepareFill(ct, ggroup->paintbox); - has_stroke = ggroup->nrstyle.prepareStroke(ct, ggroup->paintbox); - - if (has_fill || has_stroke) { - for (NRArenaItem *child = ggroup->children; child != NULL; child = child->next) { - NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); - Geom::PathVector const &pathv = *g->font->PathVector(g->glyph); - - Inkscape::DrawingContext::Save save(ct); - ct.transform(g->g_transform); - ct.path(pathv); - } - - if (has_fill) { - ggroup->nrstyle.applyFill(ct); - ct.fillPreserve(); - } - if (has_stroke) { - ggroup->nrstyle.applyStroke(ct); - ct.strokePreserve(); - } - ct.newPath(); // clear path - } // has fill or stroke pattern - - return item->state; -} - -static unsigned int nr_arena_glyphs_group_clip(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &/*area*/) -{ - NRArenaGroup *ggroup = NR_ARENA_GLYPHS_GROUP(item); - - Inkscape::DrawingContext::Save save(ct); - - // handle clip-rule - if (ggroup->style) { - if (ggroup->style->clip_rule.computed == SP_WIND_RULE_EVENODD) { - ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD); - } else { - ct.setFillRule(CAIRO_FILL_RULE_WINDING); - } - } - ct.transform(ggroup->ctm); - - for (NRArenaItem *child = ggroup->children; child != NULL; child = child->next) { - NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); - Geom::PathVector const &pathv = *g->font->PathVector(g->glyph); - - Inkscape::DrawingContext::Save save(ct); - ct.transform(g->g_transform); - ct.path(pathv); - } - ct.fill(); - - return item->state; -} - -static NRArenaItem * -nr_arena_glyphs_group_pick(NRArenaItem *item, Geom::Point const &p, gdouble delta, unsigned int sticky) -{ - NRArenaItem *picked = NULL; - - if (((NRArenaItemClass *) group_parent_class)->pick) - picked = ((NRArenaItemClass *) group_parent_class)->pick(item, p, delta, sticky); - - if (picked) picked = item; - - return picked; -} - -void -nr_arena_glyphs_group_clear(NRArenaGlyphsGroup *sg) -{ - NRArenaGroup *group = NR_ARENA_GROUP(sg); - - nr_arena_item_request_render(NR_ARENA_ITEM(group)); - - while (group->children) { - nr_arena_item_remove_child(NR_ARENA_ITEM(group), group->children); - } -} - -void -nr_arena_glyphs_group_add_component(NRArenaGlyphsGroup *sg, font_instance *font, int glyph, Geom::Affine const &transform) -{ - NRArenaGroup *group; - - group = NR_ARENA_GROUP(sg); - - Geom::PathVector const * pathv = ( font - ? font->PathVector(glyph) - : NULL ); - if ( pathv ) { - nr_arena_item_request_render(NR_ARENA_ITEM(group)); - - NRArenaItem *new_arena = NRArenaGlyphs::create(group->arena); - nr_arena_item_append_child(NR_ARENA_ITEM(group), new_arena); - nr_arena_item_unref(new_arena); - nr_arena_glyphs_set_path(NR_ARENA_GLYPHS(new_arena), NULL, FALSE, font, glyph, &transform); - } -} - -void -nr_arena_glyphs_group_set_style(NRArenaGlyphsGroup *sg, SPStyle *style) -{ - nr_return_if_fail(sg != NULL); - nr_return_if_fail(NR_IS_ARENA_GLYPHS_GROUP(sg)); - - if (style) sp_style_ref(style); - if (sg->style) sp_style_unref(sg->style); - sg->style = style; - - sg->nrstyle.set(style); - - nr_arena_item_request_update(NR_ARENA_ITEM(sg), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void -nr_arena_glyphs_group_set_paintbox(NRArenaGlyphsGroup *gg, NRRect const *pbox) -{ - nr_return_if_fail(gg != NULL); - nr_return_if_fail(NR_IS_ARENA_GLYPHS_GROUP(gg)); - nr_return_if_fail(pbox != NULL); - - gg->paintbox = pbox->upgrade_2geom(); - - nr_arena_item_request_update(NR_ARENA_ITEM(gg), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - - -/* - 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 : diff --git a/src/display/nr-arena-glyphs.h b/src/display/nr-arena-glyphs.h deleted file mode 100644 index 4b2aed7b9..000000000 --- a/src/display/nr-arena-glyphs.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef SEEN_NR_ARENA_GLYPHS_H -#define SEEN_NR_ARENA_GLYPHS_H - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2002 Lauris Kaplinski - * - * Released under GNU GPL - * - */ - -#define NR_TYPE_ARENA_GLYPHS (nr_arena_glyphs_get_type ()) -#define NR_ARENA_GLYPHS(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_GLYPHS, NRArenaGlyphs)) -#define NR_IS_ARENA_GLYPHS(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_GLYPHS)) - -#include "libnrtype/nrtype-forward.h" -#include "display/display-forward.h" -#include "forward.h" -#include "display/nr-arena-item.h" -#include "display/nr-style.h" - -#define test_glyph_liv - -struct SPCurve; -class Shape; -class SPPainter; - -NRType nr_arena_glyphs_get_type (void); - -struct NRArenaGlyphs : public NRArenaItem { - /* Glyphs data */ - Geom::Affine g_transform; - - font_instance *font; - gint glyph; - float x, y; - - static NRArenaGlyphs *create(NRArena *arena) { - NRArenaGlyphs *obj=reinterpret_cast<NRArenaGlyphs *>(nr_object_new(NR_TYPE_ARENA_GLYPHS)); - obj->init(arena); - return obj; - } -}; - -struct NRArenaGlyphsClass { - NRArenaItemClass parent_class; -}; - -void nr_arena_glyphs_set_path ( NRArenaGlyphs *glyphs, - SPCurve *curve, unsigned int lieutenant, - font_instance *font, int glyph, - Geom::Affine const *transform ); -void nr_arena_glyphs_set_style (NRArenaGlyphs *glyphs, SPStyle *style); - -/* Integrated group of component glyphss */ - -typedef struct NRArenaGlyphsGroup NRArenaGlyphsGroup; -typedef struct NRArenaGlyphsGroupClass NRArenaGlyphsGroupClass; - -#include "nr-arena-group.h" - -#define NR_TYPE_ARENA_GLYPHS_GROUP (nr_arena_glyphs_group_get_type ()) -#define NR_ARENA_GLYPHS_GROUP(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_GLYPHS_GROUP, NRArenaGlyphsGroup)) -#define NR_IS_ARENA_GLYPHS_GROUP(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_GLYPHS_GROUP)) - -NRType nr_arena_glyphs_group_get_type (void); - -struct NRArenaGlyphsGroup : public NRArenaGroup { - Geom::OptRect paintbox; - NRStyle nrstyle; - - static NRArenaGlyphsGroup *create(NRArena *arena) { - NRArenaGlyphsGroup *obj=reinterpret_cast<NRArenaGlyphsGroup *>(nr_object_new(NR_TYPE_ARENA_GLYPHS_GROUP)); - obj->init(arena); - return obj; - } -}; - -struct NRArenaGlyphsGroupClass { - NRArenaGroupClass parent_class; -}; - -/* Utility functions */ - -void nr_arena_glyphs_group_clear (NRArenaGlyphsGroup *group); - -void nr_arena_glyphs_group_add_component (NRArenaGlyphsGroup *group, font_instance *font, int glyph, Geom::Affine const &transform); - -void nr_arena_glyphs_group_set_style (NRArenaGlyphsGroup *group, SPStyle *style); - -void nr_arena_glyphs_group_set_paintbox (NRArenaGlyphsGroup *group, const NRRect *pbox); - -#endif // SEEN_NR_ARENA_GLYPHS_H - -/* - 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 : diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp deleted file mode 100644 index 1f7c421d0..000000000 --- a/src/display/nr-arena-group.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#define __NR_ARENA_GROUP_C__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "display/canvas-bpath.h" -#include "display/nr-arena.h" -#include "display/nr-arena-group.h" -#include "display/nr-filter.h" -#include "display/nr-filter-types.h" -#include "display/rendermode.h" -#include "style.h" -#include "sp-filter.h" -#include "sp-filter-reference.h" -#include "filters/blend.h" -#include "display/nr-filter-blend.h" -#include "helper/geom.h" -#include "display/drawing-context.h" - -static void nr_arena_group_class_init (NRArenaGroupClass *klass); -static void nr_arena_group_init (NRArenaGroup *group); - -static NRArenaItem *nr_arena_group_children (NRArenaItem *item); -static NRArenaItem *nr_arena_group_last_child (NRArenaItem *item); -static void nr_arena_group_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); -static void nr_arena_group_remove_child (NRArenaItem *item, NRArenaItem *child); -static void nr_arena_group_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); - -static unsigned int nr_arena_group_update (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, unsigned int state, unsigned int reset); -static unsigned int nr_arena_group_render (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); -static unsigned int nr_arena_group_clip (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area); -static NRArenaItem *nr_arena_group_pick (NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); - -static NRArenaItemClass *parent_class; - -NRType -nr_arena_group_get_type (void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type (NR_TYPE_ARENA_ITEM, - "NRArenaGroup", - sizeof (NRArenaGroupClass), - sizeof (NRArenaGroup), - (void (*) (NRObjectClass *)) nr_arena_group_class_init, - (void (*) (NRObject *)) nr_arena_group_init); - } - return type; -} - -static void -nr_arena_group_class_init (NRArenaGroupClass *klass) -{ - NRObjectClass *object_class; - NRArenaItemClass *item_class; - - object_class = (NRObjectClass *) klass; - item_class = (NRArenaItemClass *) klass; - - parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; - - object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaGroup>; - - item_class->children = nr_arena_group_children; - item_class->last_child = nr_arena_group_last_child; - item_class->add_child = nr_arena_group_add_child; - item_class->set_child_position = nr_arena_group_set_child_position; - item_class->remove_child = nr_arena_group_remove_child; - item_class->update = nr_arena_group_update; - item_class->render = nr_arena_group_render; - item_class->clip = nr_arena_group_clip; - item_class->pick = nr_arena_group_pick; -} - -static void -nr_arena_group_init (NRArenaGroup *group) -{ - group->transparent = FALSE; - group->children = NULL; - group->last = NULL; - group->style = NULL; - group->child_transform.setIdentity(); -} - -static NRArenaItem * -nr_arena_group_children (NRArenaItem *item) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - return group->children; -} - -static NRArenaItem * -nr_arena_group_last_child (NRArenaItem *item) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - return group->last; -} - -static void -nr_arena_group_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - if (!ref) { - group->children = nr_arena_item_attach (item, child, NULL, group->children); - } else { - ref->next = nr_arena_item_attach (item, child, ref, ref->next); - } - - if (ref == group->last) group->last = child; - - nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -static void -nr_arena_group_remove_child (NRArenaItem *item, NRArenaItem *child) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - if (child == group->last) group->last = child->prev; - - if (child->prev) { - nr_arena_item_detach (item, child); - } else { - group->children = nr_arena_item_detach (item, child); - } - - nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -static void -nr_arena_group_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - if (child == group->last) group->last = child->prev; - - if (child->prev) { - nr_arena_item_detach (item, child); - } else { - group->children = nr_arena_item_detach (item, child); - } - - if (!ref) { - group->children = nr_arena_item_attach (item, child, NULL, group->children); - } else { - ref->next = nr_arena_item_attach (item, child, ref, ref->next); - } - - if (ref == group->last) group->last = child; - - nr_arena_item_request_render (child); -} - -static unsigned int -nr_arena_group_update (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, unsigned int state, unsigned int reset) -{ - unsigned int newstate; - NRArenaGroup *group = NR_ARENA_GROUP (item); - unsigned int beststate = NR_ARENA_ITEM_STATE_ALL; - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - for (NRArenaItem *child = group->children; child != NULL; child = child->next) { - NRGC cgc(gc); - cgc.transform = group->child_transform * gc->transform; - newstate = nr_arena_item_invoke_update (child, area, &cgc, state, reset); - beststate = beststate & newstate; - } - - if (beststate & NR_ARENA_ITEM_STATE_BBOX) { - item->bbox = Geom::OptIntRect(); - for (NRArenaItem *child = group->children; child != NULL; child = child->next) { - if (child->visible) - item->bbox.unionWith(outline ? child->bbox : child->drawbox); - } - } - - return beststate; -} - -void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style) -{ - g_return_if_fail(group != NULL); - g_return_if_fail(NR_IS_ARENA_GROUP(group)); - - if (style) sp_style_ref(style); - if (group->style) sp_style_unref(group->style); - group->style = style; - - //if group has a filter - if (style->filter.set && style->getFilter()) { - if (!group->filter) { - int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - group->filter = new Inkscape::Filters::Filter(primitives); - } - sp_filter_build_renderer(SP_FILTER(style->getFilter()), group->filter); - } else { - //no filter set for this group - delete group->filter; - group->filter = NULL; - } - - if (style && style->enable_background.set - && style->enable_background.value == SP_CSS_BACKGROUND_NEW) { - group->background_new = true; - } -} - -static unsigned int -nr_arena_group_render (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - unsigned int ret = item->state; - - /* Just compose children into parent buffer */ - for (NRArenaItem *child = group->children; child != NULL; child = child->next) { - ret = nr_arena_item_invoke_render (ct, child, area, flags); - if (ret & NR_ARENA_ITEM_STATE_INVALID) break; - } - - return ret; -} - -static unsigned int -nr_arena_group_clip (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - unsigned int ret = item->state; - - for (NRArenaItem *child = group->children; child != NULL; child = child->next) { - ret = nr_arena_item_invoke_clip (ct, child, area); - if (ret & NR_ARENA_ITEM_STATE_INVALID) break; - } - - return ret; -} - -static NRArenaItem * -nr_arena_group_pick (NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky) -{ - NRArenaGroup *group = NR_ARENA_GROUP (item); - - for (NRArenaItem *child = group->last; child != NULL; child = child->prev) { - NRArenaItem *picked = nr_arena_item_invoke_pick (child, p, delta, sticky); - if (picked) - return (group->transparent) ? picked : item; - } - - return NULL; -} - -void -nr_arena_group_set_transparent (NRArenaGroup *group, unsigned int transparent) -{ - nr_return_if_fail (group != NULL); - nr_return_if_fail (NR_IS_ARENA_GROUP (group)); - - group->transparent = transparent; -} - -void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Affine const &t) -{ - Geom::Affine nt(t); - nr_arena_group_set_child_transform(group, &nt); -} - -void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Affine const *t) -{ - if (!t) t = &GEOM_MATRIX_IDENTITY; - - if (!Geom::matrix_equalp(*t, group->child_transform, NR_EPSILON)) { - nr_arena_item_request_render (NR_ARENA_ITEM (group)); - group->child_transform = *t; - nr_arena_item_request_update (NR_ARENA_ITEM (group), NR_ARENA_ITEM_STATE_ALL, TRUE); - } -} - - -/* - 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 : diff --git a/src/display/nr-arena-group.h b/src/display/nr-arena-group.h deleted file mode 100644 index 58394643c..000000000 --- a/src/display/nr-arena-group.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __NR_ARENA_GROUP_H__ -#define __NR_ARENA_GROUP_H__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@ximian.com> - * - * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. - * - * Released under GNU GPL - * - */ - -#define NR_TYPE_ARENA_GROUP (nr_arena_group_get_type ()) -#define NR_ARENA_GROUP(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_GROUP, NRArenaGroup)) -#define NR_IS_ARENA_GROUP(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_GROUP)) - -#include "nr-arena-item.h" -#include "style.h" - -NRType nr_arena_group_get_type (void); - -struct NRArenaGroup : public NRArenaItem{ - unsigned int transparent : 1; - NRArenaItem *children; - NRArenaItem *last; - Geom::Affine child_transform; - SPStyle *style; - - static NRArenaGroup *create(NRArena *arena) { - NRArenaGroup *obj = reinterpret_cast<NRArenaGroup *>(nr_object_new(NR_TYPE_ARENA_GROUP)); - obj->init(arena); - return obj; - } -}; - -struct NRArenaGroupClass { - NRArenaItemClass parent_class; -}; - -void nr_arena_group_set_transparent(NRArenaGroup *group, unsigned int transparent); - -void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Affine const &t); -void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Affine const *t); -void nr_arena_group_set_style(NRArenaGroup *group, SPStyle *style); - -#endif - - -/* - 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 : diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp deleted file mode 100644 index 5336fcda9..000000000 --- a/src/display/nr-arena-image.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#define __NR_ARENA_IMAGE_C__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <2geom/transforms.h> -#include "../preferences.h" -#include "nr-arena-image.h" -#include "style.h" -#include "display/cairo-utils.h" -#include "display/drawing-context.h" -#include "display/nr-arena.h" -#include "display/nr-filter.h" -#include "sp-filter.h" -#include "sp-filter-reference.h" - -int nr_arena_image_x_sample = 1; -int nr_arena_image_y_sample = 1; - -/* - * NRArenaCanvasImage - * - */ - -static void nr_arena_image_class_init (NRArenaImageClass *klass); -static void nr_arena_image_init (NRArenaImage *image); -static void nr_arena_image_finalize (NRObject *object); - -static unsigned int nr_arena_image_update (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, unsigned int state, unsigned int reset); -static unsigned int nr_arena_image_render (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); -static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); -static Geom::Rect nr_arena_image_rect (NRArenaImage *image); - -static NRArenaItemClass *parent_class; - -NRType -nr_arena_image_get_type (void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type (NR_TYPE_ARENA_ITEM, - "NRArenaImage", - sizeof (NRArenaImageClass), - sizeof (NRArenaImage), - (void (*) (NRObjectClass *)) nr_arena_image_class_init, - (void (*) (NRObject *)) nr_arena_image_init); - } - return type; -} - -static void -nr_arena_image_class_init (NRArenaImageClass *klass) -{ - NRObjectClass *object_class; - NRArenaItemClass *item_class; - - object_class = (NRObjectClass *) klass; - item_class = (NRArenaItemClass *) klass; - - parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; - - object_class->finalize = nr_arena_image_finalize; - object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaImage>; - - item_class->update = nr_arena_image_update; - item_class->render = nr_arena_image_render; - item_class->pick = nr_arena_image_pick; -} - -static void -nr_arena_image_init (NRArenaImage *image) -{ - image->pixbuf = NULL; - image->ctm.setIdentity(); - image->clipbox = Geom::Rect(); - image->ox = image->oy = 0.0; - image->sx = image->sy = 1.0; - - image->style = 0; - image->render_opacity = TRUE; -} - -static void -nr_arena_image_finalize (NRObject *object) -{ - NRArenaImage *image = NR_ARENA_IMAGE (object); - - if (image->pixbuf != NULL) { - g_object_unref(image->pixbuf); - cairo_surface_destroy(image->surface); - } - if (image->style) - sp_style_unref(image->style); - - ((NRObjectClass *) parent_class)->finalize (object); -} - -static unsigned int -nr_arena_image_update( NRArenaItem *item, Geom::IntRect const &/*area*/, NRGC *gc, unsigned int /*state*/, unsigned int /*reset*/ ) -{ - // clear old bbox - nr_arena_item_request_render(item); - - NRArenaImage *image = NR_ARENA_IMAGE (item); - - /* Copy affine */ - image->ctm = gc->transform; - - /* Calculate bbox */ - if (image->pixbuf) { - Geom::Rect r = nr_arena_image_rect(image) * gc->transform; - item->bbox = r.roundOutwards(); - } else { - item->bbox = Geom::OptIntRect(); - } - - return NR_ARENA_ITEM_STATE_ALL; -} - -static unsigned int nr_arena_image_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &/*area*/, unsigned int /*flags*/ ) -{ - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - NRArenaImage *image = NR_ARENA_IMAGE (item); - - if (!outline) { - if (!image->pixbuf) { - return item->state; - } - - // FIXME: at the moment gdk_cairo_set_source_pixbuf creates an ARGB copy - // of the pixbuf. Fix this in Cairo and/or GDK. - Inkscape::DrawingContext::Save save(ct); - ct.transform(image->ctm); - ct.newPath(); - ct.rectangle(image->clipbox); - ct.clip(); - - ct.translate(image->ox, image->oy); - ct.scale(image->sx, image->sy); - ct.setSource(image->surface, 0, 0); - - cairo_matrix_t tt; - Geom::Affine total; - cairo_get_matrix(ct.raw(), &tt); - ink_matrix_to_2geom(total, tt); - - if (total.expansionX() > 1.0 || total.expansionY() > 1.0) { - cairo_pattern_t *p = cairo_get_source(ct.raw()); - cairo_pattern_set_filter(p, CAIRO_FILTER_NEAREST); - } - ct.paint(((double) item->opacity) / 255.0); - - } else { // outline; draw a rect instead - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); - - { Inkscape::DrawingContext::Save save(ct); - ct.transform(image->ctm); - ct.newPath(); - - Geom::Rect r = nr_arena_image_rect (image); - Geom::Point c00 = r.corner(0); - Geom::Point c01 = r.corner(3); - Geom::Point c11 = r.corner(2); - Geom::Point c10 = r.corner(1); - - ct.moveTo(c00); - // the box - ct.lineTo(c10); - ct.lineTo(c11); - ct.lineTo(c01); - ct.lineTo(c00); - // the diagonals - ct.lineTo(c11); - ct.moveTo(c10); - ct.lineTo(c01); - } - - ct.setLineWidth(0.5); - ct.setSource(rgba); - ct.stroke(); - } - return item->state; -} - -/** Calculates the closest distance from p to the segment a1-a2*/ -double -distance_to_segment (Geom::Point const &p, Geom::Point const &a1, Geom::Point const &a2) -{ - // calculate sides of the triangle and their squares - double d1 = Geom::L2(p - a1); - double d1_2 = d1 * d1; - double d2 = Geom::L2(p - a2); - double d2_2 = d2 * d2; - double a = Geom::L2(a1 - a2); - double a_2 = a * a; - - // if one of the angles at the base is > 90, return the corresponding side - if (d1_2 + a_2 <= d2_2) return d1; - if (d2_2 + a_2 <= d1_2) return d2; - - // otherwise calculate the height to the base - double peri = (a + d1 + d2)/2; - return (2*sqrt(peri * (peri - a) * (peri - d1) * (peri - d2))/a); -} - -static NRArenaItem * -nr_arena_image_pick( NRArenaItem *item, Geom::Point const &p, double delta, unsigned int /*sticky*/ ) -{ - NRArenaImage *image = NR_ARENA_IMAGE (item); - - if (!image->pixbuf) return NULL; - - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - if (outline) { - Geom::Rect r = nr_arena_image_rect (image); - - Geom::Point c00 = r.corner(0); - Geom::Point c01 = r.corner(3); - Geom::Point c11 = r.corner(2); - Geom::Point c10 = r.corner(1); - - // frame - if (distance_to_segment (p, c00, c10) < delta) return item; - if (distance_to_segment (p, c10, c11) < delta) return item; - if (distance_to_segment (p, c11, c01) < delta) return item; - if (distance_to_segment (p, c01, c00) < delta) return item; - - // diagonals - if (distance_to_segment (p, c00, c11) < delta) return item; - if (distance_to_segment (p, c10, c01) < delta) return item; - - return NULL; - - } else { - - unsigned char *const pixels = gdk_pixbuf_get_pixels(image->pixbuf); - int const width = gdk_pixbuf_get_width(image->pixbuf); - int const height = gdk_pixbuf_get_height(image->pixbuf); - int const rowstride = gdk_pixbuf_get_rowstride(image->pixbuf); - - Geom::Point tp = p * image->ctm.inverse(); - Geom::Rect r = nr_arena_image_rect(image); - - if (!r.contains(tp)) - return NULL; - - double vw = width * image->sx; - double vh = height * image->sy; - int ix = floor((tp[Geom::X] - image->ox) / vw * width); - int iy = floor((tp[Geom::Y] - image->oy) / vh * height); - - if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height)) - return NULL; - - unsigned char *pix_ptr = pixels + iy * rowstride + ix * 4; - // is the alpha not transparent? - return (pix_ptr[3] > 0) ? item : NULL; - } -} - -Geom::Rect -nr_arena_image_rect (NRArenaImage *image) -{ - Geom::Rect r = image->clipbox; - - if (image->pixbuf) { - double pw = gdk_pixbuf_get_width(image->pixbuf); - double ph = gdk_pixbuf_get_height(image->pixbuf); - double vw = pw * image->sx; - double vh = ph * image->sy; - Geom::Point p(image->ox, image->oy); - Geom::Point wh(vw, vh); - Geom::Rect view(p, p+wh); - Geom::OptRect res = r & view; - r = res ? *res : r; - } - - return r; -} - -/* Utility */ - -void -nr_arena_image_set_argb32_pixbuf (NRArenaImage *image, GdkPixbuf *pb) -{ - nr_return_if_fail (image != NULL); - nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); - - // when done in this order, it won't break if pb == image->pixbuf and the refcount is 1 - if (pb != NULL) { - g_object_ref (pb); - } - if (image->pixbuf != NULL) { - g_object_unref(image->pixbuf); - cairo_surface_destroy(image->surface); - } - image->pixbuf = pb; - image->surface = pb ? ink_cairo_surface_create_for_argb32_pixbuf(pb) : NULL; - - nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void -nr_arena_image_set_clipbox (NRArenaImage *image, Geom::Rect const &clip) -{ - nr_return_if_fail (image != NULL); - nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); - - image->clipbox = clip; - - nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void -nr_arena_image_set_origin (NRArenaImage *image, Geom::Point const &origin) -{ - nr_return_if_fail (image != NULL); - nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); - - image->ox = origin[Geom::X]; - image->oy = origin[Geom::Y]; - - nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void -nr_arena_image_set_scale (NRArenaImage *image, double sx, double sy) -{ - nr_return_if_fail (image != NULL); - nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); - - image->sx = sx; - image->sy = sy; - - nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style) -{ - g_return_if_fail(image != NULL); - g_return_if_fail(NR_IS_ARENA_IMAGE(image)); - - if (style) sp_style_ref(style); - if (image->style) sp_style_unref(image->style); - image->style = style; - - //if image has a filter - if (style->filter.set && style->getFilter()) { - if (!image->filter) { - int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - image->filter = new Inkscape::Filters::Filter(primitives); - } - sp_filter_build_renderer(SP_FILTER(style->getFilter()), image->filter); - } else { - //no filter set for this image - delete image->filter; - image->filter = NULL; - } - - if (style && style->enable_background.set - && style->enable_background.value == SP_CSS_BACKGROUND_NEW) { - image->background_new = true; - } - - nr_arena_item_request_update(image, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - - -/* - 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 : diff --git a/src/display/nr-arena-image.h b/src/display/nr-arena-image.h deleted file mode 100644 index 6fa9223dd..000000000 --- a/src/display/nr-arena-image.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __NR_ARENA_IMAGE_H__ -#define __NR_ARENA_IMAGE_H__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <2geom/rect.h> -#include "nr-arena-item.h" -#include "style.h" - -#define NR_TYPE_ARENA_IMAGE (nr_arena_image_get_type ()) -#define NR_ARENA_IMAGE(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_IMAGE, NRArenaImage)) -#define NR_IS_ARENA_IMAGE(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_IMAGE)) - -NRType nr_arena_image_get_type (void); - -struct NRArenaImage : public NRArenaItem { - GdkPixbuf *pixbuf; - cairo_surface_t *surface; - - Geom::Affine ctm; - Geom::Rect clipbox; - double ox, oy; - double sx, sy; - - SPStyle *style; - - static NRArenaImage *create(NRArena *arena) { - NRArenaImage *obj=reinterpret_cast<NRArenaImage *>(nr_object_new(NR_TYPE_ARENA_IMAGE)); - obj->init(arena); - return obj; - } -}; - -struct NRArenaImageClass { - NRArenaItemClass parent_class; -}; - -void nr_arena_image_set_argb32_pixbuf (NRArenaImage *image, GdkPixbuf *pb); -void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style); -void nr_arena_image_set_clipbox (NRArenaImage *image, Geom::Rect const &clip); -void nr_arena_image_set_origin (NRArenaImage *image, Geom::Point const &origin); -void nr_arena_image_set_scale (NRArenaImage *image, double sx, double sy); - -#endif - -/* - 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 : diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp deleted file mode 100644 index 264b8ab10..000000000 --- a/src/display/nr-arena-item.cpp +++ /dev/null @@ -1,932 +0,0 @@ -#define __NR_ARENA_ITEM_C__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#define noNR_ARENA_ITEM_VERBOSE -#define noNR_ARENA_ITEM_DEBUG_CASCADE - -#include <cstring> -#include <string> -#include <cairomm/cairomm.h> - -#include "display/cairo-utils.h" -#include "display/cairo-templates.h" -#include "display/drawing-context.h" -#include "display/drawing-surface.h" -#include "display/canvas-arena.h" -#include "nr-arena.h" -#include "nr-arena-item.h" -#include "gc-core.h" -#include "helper/geom.h" - -#include "nr-filter.h" -#include "nr-arena-group.h" -#include "preferences.h" - -namespace GC = Inkscape::GC; - -static void nr_arena_item_class_init (NRArenaItemClass *klass); -static void nr_arena_item_init (NRArenaItem *item); -static void nr_arena_item_private_finalize (NRObject *object); - -static NRObjectClass *parent_class; - -NRType -nr_arena_item_get_type (void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type (NR_TYPE_OBJECT, - "NRArenaItem", - sizeof (NRArenaItemClass), - sizeof (NRArenaItem), - (void (*)(NRObjectClass *)) - nr_arena_item_class_init, - (void (*)(NRObject *)) - nr_arena_item_init); - } - return type; -} - -static void -nr_arena_item_class_init (NRArenaItemClass *klass) -{ - NRObjectClass *object_class; - - object_class = (NRObjectClass *) klass; - - parent_class = ((NRObjectClass *) klass)->parent; - - object_class->finalize = nr_arena_item_private_finalize; - object_class->cpp_ctor = NRObject::invoke_ctor < NRArenaItem >; -} - -static void -nr_arena_item_init (NRArenaItem *item) -{ - item->arena = NULL; - item->parent = NULL; - item->next = item->prev = NULL; - - item->key = 0; - - item->state = 0; - item->sensitive = TRUE; - item->visible = TRUE; - - memset (&item->bbox, 0, sizeof (item->bbox)); - memset (&item->drawbox, 0, sizeof (item->drawbox)); - item->transform = NULL; - item->ctm.setIdentity(); - item->opacity = 255; - item->render_opacity = FALSE; - item->render_cache = FALSE; - - item->transform = NULL; - item->clip = NULL; - item->mask = NULL; - item->cache = NULL; - item->data = NULL; - item->filter = NULL; - item->background_new = false; -} - -static void -nr_arena_item_private_finalize (NRObject *object) -{ - NRArenaItem *item = static_cast < NRArenaItem * >(object); - - item->transform = NULL; - - if (item->clip) - nr_arena_item_detach(item, item->clip); - if (item->mask) - nr_arena_item_detach(item, item->mask); - delete item->cache; - - ((NRObjectClass *) (parent_class))->finalize (object); -} - -NRArenaItem * -nr_arena_item_children (NRArenaItem *item) -{ - nr_return_val_if_fail (item != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); - - if (NR_ARENA_ITEM_VIRTUAL (item, children)) - return NR_ARENA_ITEM_VIRTUAL (item, children) (item); - - return NULL; -} - -NRArenaItem * -nr_arena_item_last_child (NRArenaItem *item) -{ - nr_return_val_if_fail (item != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); - - if (NR_ARENA_ITEM_VIRTUAL (item, last_child)) { - return NR_ARENA_ITEM_VIRTUAL (item, last_child) (item); - } else { - NRArenaItem *ref = nr_arena_item_children (item); - if (ref) - while (ref->next) - ref = ref->next; - return ref; - } -} - -void -nr_arena_item_add_child (NRArenaItem *item, NRArenaItem *child, - NRArenaItem *ref) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (child != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (child)); - nr_return_if_fail (child->parent == NULL); - nr_return_if_fail (child->prev == NULL); - nr_return_if_fail (child->next == NULL); - nr_return_if_fail (child->arena == item->arena); - nr_return_if_fail (child != ref); - nr_return_if_fail (!ref || NR_IS_ARENA_ITEM (ref)); - nr_return_if_fail (!ref || (ref->parent == item)); - - if (NR_ARENA_ITEM_VIRTUAL (item, add_child)) - NR_ARENA_ITEM_VIRTUAL (item, add_child) (item, child, ref); -} - -void -nr_arena_item_remove_child (NRArenaItem *item, NRArenaItem *child) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (child != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (child)); - nr_return_if_fail (child->parent == item); - - if (NR_ARENA_ITEM_VIRTUAL (item, remove_child)) - NR_ARENA_ITEM_VIRTUAL (item, remove_child) (item, child); -} - -void -nr_arena_item_set_child_position (NRArenaItem *item, NRArenaItem *child, - NRArenaItem *ref) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (child != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (child)); - nr_return_if_fail (child->parent == item); - nr_return_if_fail (!ref || NR_IS_ARENA_ITEM (ref)); - nr_return_if_fail (!ref || (ref->parent == item)); - - if (NR_ARENA_ITEM_VIRTUAL (item, set_child_position)) - NR_ARENA_ITEM_VIRTUAL (item, set_child_position) (item, child, ref); -} - -NRArenaItem * -nr_arena_item_ref (NRArenaItem *item) -{ - nr_object_ref ((NRObject *) item); - - return item; -} - -NRArenaItem * -nr_arena_item_unref (NRArenaItem *item) -{ - nr_object_unref ((NRObject *) item); - - return NULL; -} - -unsigned int -nr_arena_item_invoke_update (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, - unsigned int state, unsigned int reset) -{ - NRGC childgc (gc); - bool filter = (item->arena->rendermode == Inkscape::RENDERMODE_NORMAL); - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), - NR_ARENA_ITEM_STATE_INVALID); - nr_return_val_if_fail (!(state & NR_ARENA_ITEM_STATE_INVALID), - NR_ARENA_ITEM_STATE_INVALID); - -#ifdef NR_ARENA_ITEM_DEBUG_CASCADE - printf ("Update %s:%p %x %x %x\n", - nr_type_name_from_instance ((GTypeInstance *) item), item, state, - item->state, reset); -#endif - - /* return if in error */ - if (item->state & NR_ARENA_ITEM_STATE_INVALID) - return item->state; - /* Set reset flags according to propagation status */ - if (item->propagate) { - reset |= ~item->state; - item->propagate = FALSE; - } - /* Reset our state */ - item->state &= ~reset; - /* Return if NOP */ - if (!(~item->state & state)) - return item->state; - /* Test whether to return immediately */ - if (item->state & NR_ARENA_ITEM_STATE_BBOX) { - // we have up-to-date bbox - if (!area.intersects(outline ? item->bbox : item->drawbox)) - return item->state; - } - - /* Set up local gc */ - childgc = *gc; - if (item->transform) { - childgc.transform = (*item->transform) * childgc.transform; - } - /* Remember the transformation matrix */ - Geom::Affine ctm_change = item->ctm.inverse() * childgc.transform; - item->ctm = childgc.transform; - - /* Invoke the real method */ - // that will update bbox - item->state = NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state, reset); - if (item->state & NR_ARENA_ITEM_STATE_INVALID) - return item->state; - - /* Enlarge the drawbox to contain filter effects */ - if (item->filter && filter && item->item_bbox) { - item->drawbox = item->filter->compute_drawbox(item, *item->item_bbox); - } else { - item->drawbox = item->bbox; - } - - /* Clipping */ - if (item->clip) { - // FIXME: since here we only need bbox, consider passing - // ((state & !(NR_ARENA_ITEM_STATE_RENDER)) | NR_ARENA_ITEM_STATE_BBOX) - // instead of state, so it does not have to create rendering structures in nr_arena_shape_update - unsigned int newstate = nr_arena_item_invoke_update (item->clip, area, &childgc, state, reset); - if (newstate & NR_ARENA_ITEM_STATE_INVALID) { - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - if (outline) { - item->bbox.unionWith(item->clip->bbox); - } else { - item->drawbox.intersectWith(item->clip->bbox); - } - } - /* Masking */ - if (item->mask) { - unsigned int newstate = nr_arena_item_invoke_update (item->mask, area, &childgc, state, reset); - if (newstate & NR_ARENA_ITEM_STATE_INVALID) { - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - if (outline) { - item->bbox.unionWith(item->mask->bbox); - } else { - // for masking, we need full drawbox of mask - item->drawbox.intersectWith(item->mask->drawbox); - } - } - - // update cache if enabled - if (item->render_cache) { - Geom::OptIntRect cl = item->arena->cache_limit; - cl.intersectWith(item->drawbox); - if (cl) { - if (item->cache) { - // this takes care of invalidation on transform - item->cache->resizeAndTransform(*cl, ctm_change); - } else { - item->cache = new Inkscape::DrawingCache(*cl); - // the cache is initially dirty - } - } else { - // disable cache for this item - not visible - delete item->cache; - item->cache = NULL; - } - } - - // now that we know drawbox, dirty the corresponding rect on canvas: - if (!NR_IS_ARENA_GROUP(item) || (item->filter && filter)) { - // unless filtered, groups do not need to render by themselves, only their members - if (state & ~NR_ARENA_ITEM_STATE_CACHE) { - nr_arena_item_request_render (item); - } - } - - return item->state; -} - -struct MaskLuminanceToAlpha { - guint32 operator()(guint32 in) { - EXTRACT_ARGB32(in, a, r, g, b) - // the operation of unpremul -> luminance-to-alpha -> multiply by alpha - // is equivalent to luminance-to-alpha on premultiplied color values - // original computation in double: r*0.2125 + g*0.7154 + b*0.0721 - guint32 ao = r*109 + g*366 + b*37; // coeffs add up to 512 - return ((ao + 256) << 15) & 0xff000000; // equivalent to ((ao + 256) / 512) << 24 - } -}; - -unsigned int -nr_arena_item_invoke_render (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, - unsigned int flags) -{ - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - bool filter = (item->arena->rendermode != Inkscape::RENDERMODE_OUTLINE && - item->arena->rendermode != Inkscape::RENDERMODE_NO_FILTERS); - - nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), - NR_ARENA_ITEM_STATE_INVALID); - nr_return_val_if_fail (item->state & NR_ARENA_ITEM_STATE_BBOX, - item->state); - - /* If we are invisible, just return successfully */ - if (!item->visible) - return item->state | NR_ARENA_ITEM_STATE_RENDER; - - if (outline) { - // intersect with bbox rather than drawbox, as we want to render things outside - // of the clipping path as well - Geom::OptIntRect carea = Geom::intersect(area, item->bbox); - if (!carea) - return item->state | NR_ARENA_ITEM_STATE_RENDER; - - // No caching in outline mode for now; investigate if it really gives any advantage with cairo. - // Also no attempts to clip anything; just render everything: item, clip, mask - // First, render the object itself - unsigned int state = NR_ARENA_ITEM_VIRTUAL (item, render) (ct, item, *carea, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - /* Clean up and return error */ - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - - // render clip and mask, if any - guint32 saved_rgba = item->arena->outlinecolor; // save current outline color - // render clippath as an object, using a different color - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (item->clip) { - item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips - NR_ARENA_ITEM_VIRTUAL (item->clip, render) (ct, item->clip, *carea, flags); - } - // render mask as an object, using a different color - if (item->mask) { - item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks - NR_ARENA_ITEM_VIRTUAL (item->mask, render) (ct, item->mask, *carea, flags); - } - item->arena->outlinecolor = saved_rgba; // restore outline color - - return item->state | NR_ARENA_ITEM_STATE_RENDER; - } - - // carea is the bounding box for intermediate rendering. - Geom::OptIntRect carea = Geom::intersect(area, item->drawbox); - if (!carea) - return item->state | NR_ARENA_ITEM_STATE_RENDER; - - // render from cache - if (item->render_cache && item->cache) { - if(item->cache->paintFromCache(ct, *carea)) - return item->state | NR_ARENA_ITEM_STATE_RENDER; - } - - // expand carea to contain the dependent area of filters. - if (item->filter && filter) { - item->filter->area_enlarge(*carea, item); - carea.intersectWith(item->drawbox); - } - - using namespace Inkscape; - - unsigned state; - unsigned retstate; - - // determine whether this shape needs intermediate rendering. - bool needs_intermediate_rendering = false; - bool &nir = needs_intermediate_rendering; - bool needs_opacity = (item->opacity != 255 && !item->render_opacity); - - // this item needs an intermediate rendering if: - nir |= (item->clip != NULL); // 1. it has a clipping path - nir |= (item->mask != NULL); // 2. it has a mask - nir |= (item->filter != NULL && filter); // 3. it has a filter - nir |= needs_opacity; // 4. it is non-opaque - - double opacity = static_cast<double>(item->opacity) / 255.0; - - /* How the rendering is done. - * - * Clipping, masking and opacity are done by rendering them to a surface - * and then compositing the object's rendering onto it with the IN operator. - * The object itself is rendered to a group. - * - * Opacity is done by rendering the clipping path with an alpha - * value corresponding to the opacity. If there is no clipping path, - * the entire intermediate surface is painted with alpha corresponding - * to the opacity value. - */ - - // short-circuit the simple case. - if (!needs_intermediate_rendering) { - if (item->render_cache && item->cache) { - Inkscape::DrawingContext cachect(*item->cache); - cachect.rectangle(area); - cachect.clip(); - - { // 1. clear the corresponding part of cache - Inkscape::DrawingContext::Save save(cachect); - cachect.setSource(0,0,0,0); - cachect.setOperator(CAIRO_OPERATOR_SOURCE); - cachect.paint(); - } - // 2. render to cache - state = NR_ARENA_ITEM_VIRTUAL (item, render) (cachect, item, *carea, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - // 3. copy from cache to output - Inkscape::DrawingContext::Save save(ct); - ct.rectangle(*carea); - ct.clip(); - ct.setSource(item->cache); - ct.paint(); - // 4. mark as clean - item->cache->markClean(area); - return item->state | NR_ARENA_ITEM_STATE_RENDER; - } else { - state = NR_ARENA_ITEM_VIRTUAL (item, render) (ct, item, *carea, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - item->state |= NR_ARENA_ITEM_STATE_INVALID; - return item->state; - } - return item->state | NR_ARENA_ITEM_STATE_RENDER; - } - } - - DrawingSurface intermediate(*carea); - DrawingContext ict(intermediate); - - // 1. Render clipping path with alpha = opacity. - ict.setSource(0,0,0,opacity); - // Since clip can be combined with opacity, the result could be incorrect - // for overlapping clip children. To fix this we use the SOURCE operator - // instead of the default OVER. - ict.setOperator(CAIRO_OPERATOR_SOURCE); - if (item->clip) { - state = nr_arena_item_invoke_clip(ict, item->clip, *carea); // fixme: carea or area? - if (state & NR_ARENA_ITEM_STATE_INVALID) { - retstate = (item->state |= NR_ARENA_ITEM_STATE_INVALID); - goto cleanup; - } - } else { - // if there is no clipping path, fill the entire surface with alpha = opacity. - ict.paint(); - } - // reset back to default - ict.setOperator(CAIRO_OPERATOR_OVER); - - // 2. Render the mask if present and compose it with the clipping path + opacity. - if (item->mask) { - ict.pushGroup(); - state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (ict, item->mask, *carea, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - retstate = (item->state |= NR_ARENA_ITEM_STATE_INVALID); - goto cleanup; - } - cairo_surface_t *mask_s = ict.rawTarget(); - // Convert mask's luminance to alpha - ink_cairo_surface_filter(mask_s, mask_s, MaskLuminanceToAlpha()); - ict.popGroupToSource(); - ict.setOperator(CAIRO_OPERATOR_IN); - ict.paint(); - ict.setOperator(CAIRO_OPERATOR_OVER); - } - - // 3. Render object itself. - ict.pushGroup(); - state = NR_ARENA_ITEM_VIRTUAL (item, render) (ict, item, *carea, flags); - if (state & NR_ARENA_ITEM_STATE_INVALID) { - retstate = (item->state |= NR_ARENA_ITEM_STATE_INVALID); - goto cleanup; - } - - // 4. Apply filter. - if (item->filter && filter) { - item->filter->render(item, ct, ict); - // Note that because the object was rendered to a group, - // the internals of the filter need to use cairo_get_group_target() - // instead of cairo_get_target(). - } - - // 5. Render object inside the composited mask + clip - ict.popGroupToSource(); - ict.setOperator(CAIRO_OPERATOR_IN); - ict.paint(); - - // 6. Paint the completed rendering onto the base context (or into cache) - if (item->render_cache && item->cache) { - DrawingContext cachect(*item->cache); - cachect.rectangle(area); - cachect.clip(); - cachect.setOperator(CAIRO_OPERATOR_SOURCE); - cachect.setSource(&intermediate); - cachect.paint(); - item->cache->markClean(area); - } - ct.setSource(&intermediate); - ct.paint(); - ct.setSource(0,0,0,0); - // the call above is to clear a ref on the intermediate surface held by ct - - retstate = item->state | NR_ARENA_ITEM_STATE_RENDER; - - cleanup: - return retstate; -} - -unsigned int -nr_arena_item_invoke_clip (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area) -{ - nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), - NR_ARENA_ITEM_STATE_INVALID); - - unsigned retstate = 0; - - // don't bother if the object does not implement clipping (e.g. NRArenaImage) - if (!((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))->clip) - return retstate; - - if (item->visible && area.intersects(item->bbox)) { - // The item used as the clipping path itself has a clipping path. - // Render this item's clipping path onto a temporary surface, then composite it - // with the item using the IN operator - if (item->clip) { - ct.pushAlphaGroup(); - { Inkscape::DrawingContext::Save save(ct); - ct.setSource(0,0,0,1); - nr_arena_item_invoke_clip(ct, item->clip, area); - } - ct.pushAlphaGroup(); - } - - // rasterize the clipping path - retstate = ((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))-> - clip (ct, item, area); - - if (item->clip) { - ct.popGroupToSource(); - ct.setOperator(CAIRO_OPERATOR_IN); - ct.paint(); - ct.popGroupToSource(); - ct.setOperator(CAIRO_OPERATOR_SOURCE); - ct.paint(); - } - } - - return retstate; -} - -NRArenaItem * -nr_arena_item_invoke_pick (NRArenaItem *item, Geom::Point const &p, double delta, - unsigned int sticky) -{ - nr_return_val_if_fail (item != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); - - // Sometimes there's no BBOX in item->state, reason unknown (bug 992817); I made this not an assert to remove the warning - if (!(item->state & NR_ARENA_ITEM_STATE_BBOX) - || !(item->state & NR_ARENA_ITEM_STATE_PICK)) - return NULL; - - if (!sticky && !(item->visible && item->sensitive)) - return NULL; - - if (!item->bbox) return NULL; - Geom::Rect expanded(*item->bbox); - expanded.expandBy(delta); - - if (expanded.contains(p)) { - if (((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))->pick) - return ((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))-> - pick (item, p, delta, sticky); - } - - return NULL; -} - -void -nr_arena_item_request_update (NRArenaItem *item, unsigned int reset, - unsigned int propagate) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (!(reset & NR_ARENA_ITEM_STATE_INVALID)); - - if (propagate && !item->propagate) - item->propagate = TRUE; - - if (item->state & reset) { - item->state &= ~reset; - if (item->parent) { - nr_arena_item_request_update (item->parent, reset, FALSE); - } else { - nr_arena_request_update (item->arena, item); - } - } -} - -void -nr_arena_item_request_render (NRArenaItem *item) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - Geom::OptIntRect dirty = outline ? item->bbox : item->drawbox; - if (!dirty) return; - - // dirty the caches of all parents - for (NRArenaItem *i = item; i; i = i->parent) { - if (i->render_cache && i->cache) { - i->cache->markDirty(*dirty); - } - } - - nr_arena_request_render_rect (item->arena, dirty); -} - -/* Public */ - -NRArenaItem * -nr_arena_item_unparent (NRArenaItem *item) -{ - nr_return_val_if_fail (item != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); - - nr_arena_item_request_render (item); - - if (item->parent) { - nr_arena_item_remove_child (item->parent, item); - } - - return NULL; -} - -void -nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child) -{ - nr_return_if_fail (parent != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (parent)); - nr_return_if_fail (child != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (child)); - nr_return_if_fail (parent->arena == child->arena); - nr_return_if_fail (child->parent == NULL); - nr_return_if_fail (child->prev == NULL); - nr_return_if_fail (child->next == NULL); - - nr_arena_item_add_child (parent, child, nr_arena_item_last_child (parent)); -} - -void -nr_arena_item_set_transform (NRArenaItem *item, Geom::Affine const &transform) -{ - Geom::Affine const t (transform); - nr_arena_item_set_transform (item, &t); -} - -void -nr_arena_item_set_transform (NRArenaItem *item, Geom::Affine const *transform) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - if (!transform && !item->transform) - return; - - const Geom::Affine *md = (item->transform) ? item->transform : &GEOM_MATRIX_IDENTITY; - const Geom::Affine *ms = (transform) ? transform : &GEOM_MATRIX_IDENTITY; - - if (!Geom::matrix_equalp(*md, *ms, NR_EPSILON)) { - // mark the area where the object was for redraw. - nr_arena_item_request_render (item); - if (!transform || transform->isIdentity()) { - /* Set to identity affine */ - item->transform = NULL; - } else { - if (!item->transform) - item->transform = new (GC::ATOMIC) Geom::Affine (); - *item->transform = *transform; - } - // when update is called, the area where the object was moved - // will be redrawn as well - nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); - } -} - -void -nr_arena_item_set_opacity (NRArenaItem *item, double opacity) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - nr_arena_item_request_render (item); - - item->opacity = (unsigned int) (opacity * 255.9999); -} - -void -nr_arena_item_set_sensitive (NRArenaItem *item, unsigned int sensitive) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - /* fixme: mess with pick/repick... */ - - item->sensitive = sensitive; -} - -void -nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - item->visible = visible; - - nr_arena_item_request_render (item); -} - -void -nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (!clip || NR_IS_ARENA_ITEM (clip)); - - if (clip != item->clip) { - nr_arena_item_request_render (item); - if (item->clip) - item->clip = nr_arena_item_detach (item, item->clip); - if (clip) - item->clip = nr_arena_item_attach (item, clip, NULL, NULL); - nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); - } -} - -void -nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - nr_return_if_fail (!mask || NR_IS_ARENA_ITEM (mask)); - - if (mask != item->mask) { - nr_arena_item_request_render (item); - if (item->mask) - item->mask = nr_arena_item_detach (item, item->mask); - if (mask) - item->mask = nr_arena_item_attach (item, mask, NULL, NULL); - nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); - } -} - -void -nr_arena_item_set_order (NRArenaItem *item, int order) -{ - nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); - - if (!item->parent) - return; - - NRArenaItem *children = nr_arena_item_children (item->parent); - - NRArenaItem *ref = NULL; - int pos = 0; - for (NRArenaItem *child = children; child != NULL; child = child->next) { - if (pos >= order) - break; - if (child != item) { - ref = child; - pos += 1; - } - } - - nr_arena_item_set_child_position (item->parent, item, ref); -} - -void -nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect const &bbox) -{ - nr_return_if_fail(item != NULL); - nr_return_if_fail(NR_IS_ARENA_ITEM(item)); - - item->item_bbox = bbox; -} - -void -nr_arena_item_set_cache (NRArenaItem *item, bool cache) -{ - if (cache) { - item->render_cache = TRUE; - item->arena->cached_items.insert(item); - } else { - item->render_cache = FALSE; - item->arena->cached_items.erase(item); - } - nr_arena_item_request_update(item, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -/** Returns a background image for use with filter effects. */ -NRPixBlock *nr_arena_item_get_background(NRArenaItem const * /*item*/) -{ - return NULL; -} - -/* Helpers */ - -NRArenaItem * -nr_arena_item_attach (NRArenaItem *parent, NRArenaItem *child, - NRArenaItem *prev, NRArenaItem *next) -{ - nr_return_val_if_fail (parent != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (parent), NULL); - nr_return_val_if_fail (child != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (child), NULL); - nr_return_val_if_fail (child->parent == NULL, NULL); - nr_return_val_if_fail (child->prev == NULL, NULL); - nr_return_val_if_fail (child->next == NULL, NULL); - nr_return_val_if_fail (!prev || NR_IS_ARENA_ITEM (prev), NULL); - nr_return_val_if_fail (!prev || (prev->parent == parent), NULL); - nr_return_val_if_fail (!prev || (prev->next == next), NULL); - nr_return_val_if_fail (!next || NR_IS_ARENA_ITEM (next), NULL); - nr_return_val_if_fail (!next || (next->parent == parent), NULL); - nr_return_val_if_fail (!next || (next->prev == prev), NULL); - - child->parent = parent; - child->prev = prev; - child->next = next; - - if (prev) - prev->next = child; - if (next) - next->prev = child; - - return child; -} - -NRArenaItem * -nr_arena_item_detach (NRArenaItem *parent, NRArenaItem *child) -{ - nr_return_val_if_fail (parent != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (parent), NULL); - nr_return_val_if_fail (child != NULL, NULL); - nr_return_val_if_fail (NR_IS_ARENA_ITEM (child), NULL); - nr_return_val_if_fail (child->parent == parent, NULL); - - NRArenaItem *prev = child->prev; - NRArenaItem *next = child->next; - - child->parent = NULL; - child->prev = NULL; - child->next = NULL; - - if (prev) - prev->next = next; - if (next) - next->prev = prev; - - return next; -} - -/* - 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 : diff --git a/src/display/nr-arena-item.h b/src/display/nr-arena-item.h deleted file mode 100644 index 2c00c0bf3..000000000 --- a/src/display/nr-arena-item.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_DISPLAY_NR_ARENA_ITEM_H -#define SEEN_DISPLAY_NR_ARENA_ITEM_H - -#include <cairo.h> -#include <2geom/affine.h> -#include <2geom/rect.h> -#include "libnr/nr-forward.h" -#include "libnr/nr-rect-l.h" -#include "libnr/nr-object.h" -#include "gc-soft-ptr.h" -#include "nr-arena-forward.h" - -namespace Inkscape { -class DrawingContext; -class DrawingCache; -namespace Filters { -class Filter; -} } - -#define NR_TYPE_ARENA_ITEM (nr_arena_item_get_type ()) -#define NR_ARENA_ITEM(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_ITEM, NRArenaItem)) -#define NR_IS_ARENA_ITEM(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_ITEM)) - -#define NR_ARENA_ITEM_VIRTUAL(i,m) (((NRArenaItemClass *) NR_OBJECT_GET_CLASS (i))->m) - -/* - * NRArenaItem state flags - */ - -/* - * NR_ARENA_ITEM_STATE_INVALID - * - * If set or retuned indicates, that given object is in error. - * Calling method has to return immediately, with appropriate - * error flag. - */ - -#define NR_ARENA_ITEM_STATE_INVALID (1 << 0) - - -#define NR_ARENA_ITEM_STATE_BBOX (1 << 1) -#define NR_ARENA_ITEM_STATE_COVERAGE (1 << 2) -#define NR_ARENA_ITEM_STATE_DRAFT (1 << 3) -#define NR_ARENA_ITEM_STATE_RENDER (1 << 4) -#define NR_ARENA_ITEM_STATE_CLIP (1 << 5) -#define NR_ARENA_ITEM_STATE_MASK (1 << 6) -#define NR_ARENA_ITEM_STATE_PICK (1 << 7) -#define NR_ARENA_ITEM_STATE_IMAGE (1 << 8) -#define NR_ARENA_ITEM_STATE_CACHE (1 << 9) - -#define NR_ARENA_ITEM_STATE_NONE 0x0000 -#define NR_ARENA_ITEM_STATE_ALL 0x03fe - -#define NR_ARENA_ITEM_STATE(i,s) (NR_ARENA_ITEM (i)->state & (s)) -#define NR_ARENA_ITEM_SET_STATE(i,s) (NR_ARENA_ITEM (i)->state |= (s)) -#define NR_ARENA_ITEM_UNSET_STATE(i,s) (NR_ARENA_ITEM (i)->state &= ~(s)) - -#define NR_ARENA_ITEM_RENDER_NO_CACHE (1 << 0) -#define NR_ARENA_ITEM_RENDER_CACHE (1 << 1) - -struct NRGC { - NRGC(NRGC const *p) : parent(p) {} - NRGC const *parent; - Geom::Affine transform; -}; - -struct NRArenaItem : public NRObject { - - NRArena *arena; - Inkscape::GC::soft_ptr<NRArenaItem> parent; - NRArenaItem *next; - Inkscape::GC::soft_ptr<NRArenaItem> prev; - - /* Item state */ - unsigned state : 16; - /* Opacity itself */ - unsigned opacity : 8; - unsigned propagate : 1; - unsigned sensitive : 1; - unsigned visible : 1; - /* Whether items renders opacity itself */ - unsigned render_opacity : 1; - unsigned render_cache : 1; - - unsigned int key; ///< Some SPItems can have more than one NRArenaItem, - ///this value is a hack used to distinguish between them - - Geom::OptIntRect bbox; ///< Bounding box in pixel grid coordinates; (0,0) is at page origin - Geom::OptIntRect drawbox; ///< Bounding box enlarged by filters, shrinked by clips and masks - Geom::OptRect item_bbox; ///< Bounding box in item coordinates, required by filters - Geom::Affine *transform; ///< Incremental transform of this item, as given by the transform= attribute - Geom::Affine ctm; ///< Total transform from pixel grid to item coords - NRArenaItem *clip; ///< Clipping path - NRArenaItem *mask; ///< Mask - Inkscape::Filters::Filter *filter; ///< Filter - Inkscape::DrawingCache *cache; ///< Render cache - - void *data; ///< Anonymous data member - this is used to associate SPItems with arena items - - bool background_new; - - void init(NRArena *arena) { - this->arena = arena; - } -}; - -struct NRArenaItemClass : public NRObjectClass { - NRArenaItem * (* children) (NRArenaItem *item); - NRArenaItem * (* last_child) (NRArenaItem *item); - void (* add_child) (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); - void (* remove_child) (NRArenaItem *item, NRArenaItem *child); - void (* set_child_position) (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); - - unsigned int (* update) (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, unsigned int state, unsigned int reset); - unsigned int (* render) (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); - unsigned int (* clip) (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area); - NRArenaItem * (* pick) (NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); -}; - -#define NR_ARENA_ITEM_ARENA(ai) (((NRArenaItem *) (ai))->arena) - -NRType nr_arena_item_get_type (void); - -NRArenaItem *nr_arena_item_ref (NRArenaItem *item); -NRArenaItem *nr_arena_item_unref (NRArenaItem *item); - -NRArenaItem *nr_arena_item_children (NRArenaItem *item); -NRArenaItem *nr_arena_item_last_child (NRArenaItem *item); -void nr_arena_item_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); -void nr_arena_item_remove_child (NRArenaItem *item, NRArenaItem *child); -void nr_arena_item_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); - -/* - * Invoke update to given state, if item is inside area - * - * area == NULL is infinite - * gc is PARENT gc for invoke, CHILD gc in corresponding virtual method - * state - requested to state (bitwise or of requested flags) - * reset - reset to state (bitwise or of flags to reset) - */ - -unsigned int nr_arena_item_invoke_update (NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, unsigned int state, unsigned int reset); - -unsigned int nr_arena_item_invoke_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); - -unsigned int nr_arena_item_invoke_clip (Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area); -NRArenaItem *nr_arena_item_invoke_pick (NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); - -void nr_arena_item_request_update (NRArenaItem *item, unsigned int reset, unsigned int propagate); -void nr_arena_item_request_render (NRArenaItem *item); - -/* Public */ - -NRArenaItem *nr_arena_item_unparent (NRArenaItem *item); - -void nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child); - -void nr_arena_item_set_transform(NRArenaItem *item, Geom::Affine const &transform); -void nr_arena_item_set_transform(NRArenaItem *item, Geom::Affine const *transform); -void nr_arena_item_set_opacity (NRArenaItem *item, double opacity); -void nr_arena_item_set_sensitive (NRArenaItem *item, unsigned int sensitive); -void nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible); -void nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip); -void nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask); -void nr_arena_item_set_order (NRArenaItem *item, int order); -void nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect const &bbox); -void nr_arena_item_set_cache (NRArenaItem *item, bool cache); - -NRPixBlock *nr_arena_item_get_background (NRArenaItem const *item); - -/* Helpers */ - -NRArenaItem *nr_arena_item_attach (NRArenaItem *parent, NRArenaItem *child, NRArenaItem *prev, NRArenaItem *next); -NRArenaItem *nr_arena_item_detach (NRArenaItem *parent, NRArenaItem *child); - -#define NR_ARENA_ITEM_SET_DATA(i,v) (((NRArenaItem *) (i))->data = (v)) -#define NR_ARENA_ITEM_GET_DATA(i) (((NRArenaItem *) (i))->data) - -#define NR_ARENA_ITEM_SET_KEY(i,k) (((NRArenaItem *) (i))->key = (k)) -#define NR_ARENA_ITEM_GET_KEY(i) (((NRArenaItem *) (i))->key) - -#endif /* !SEEN_DISPLAY_NR_ARENA_ITEM_H */ - -/* - 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 : diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp deleted file mode 100644 index ff985550c..000000000 --- a/src/display/nr-arena-shape.cpp +++ /dev/null @@ -1,565 +0,0 @@ -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <cairo.h> -#include <glib.h> -#include <fenv.h> -#include <typeinfo> - -#include <2geom/curves.h> -#include <2geom/pathvector.h> -#include <2geom/svg-path.h> -#include <2geom/svg-path-parser.h> -#include "display/cairo-utils.h" -#include "display/canvas-arena.h" -#include "display/canvas-bpath.h" -#include "display/curve.h" -#include "display/drawing-context.h" -#include "display/nr-arena.h" -#include "display/nr-arena-shape.h" -#include "display/nr-filter.h" -#include "helper/geom-curves.h" -#include "helper/geom.h" -#include "libnr/nr-convert2geom.h" -#include "preferences.h" -#include "sp-filter.h" -#include "sp-filter-reference.h" -#include "style.h" -#include "svg/svg.h" - -static void nr_arena_shape_class_init(NRArenaShapeClass *klass); -static void nr_arena_shape_init(NRArenaShape *shape); -static void nr_arena_shape_finalize(NRObject *object); - -static NRArenaItem *nr_arena_shape_children(NRArenaItem *item); -static void nr_arena_shape_add_child(NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); -static void nr_arena_shape_remove_child(NRArenaItem *item, NRArenaItem *child); -static void nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); - -static guint nr_arena_shape_update(NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, guint state, guint reset); -static unsigned int nr_arena_shape_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags); -static guint nr_arena_shape_clip(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area); -static NRArenaItem *nr_arena_shape_pick(NRArenaItem *item, Geom::Point const &p, double delta, unsigned int sticky); - -static NRArenaItemClass *shape_parent_class; - -NRType -nr_arena_shape_get_type(void) -{ - static NRType type = 0; - if (!type) { - type = nr_object_register_type(NR_TYPE_ARENA_ITEM, - "NRArenaShape", - sizeof(NRArenaShapeClass), - sizeof(NRArenaShape), - (void (*)(NRObjectClass *)) nr_arena_shape_class_init, - (void (*)(NRObject *)) nr_arena_shape_init); - } - return type; -} - -static void -nr_arena_shape_class_init(NRArenaShapeClass *klass) -{ - NRObjectClass *object_class; - NRArenaItemClass *item_class; - - object_class = (NRObjectClass *) klass; - item_class = (NRArenaItemClass *) klass; - - shape_parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; - - object_class->finalize = nr_arena_shape_finalize; - object_class->cpp_ctor = NRObject::invoke_ctor<NRArenaShape>; - - item_class->children = nr_arena_shape_children; - item_class->add_child = nr_arena_shape_add_child; - item_class->set_child_position = nr_arena_shape_set_child_position; - item_class->remove_child = nr_arena_shape_remove_child; - item_class->update = nr_arena_shape_update; - item_class->render = nr_arena_shape_render; - item_class->clip = nr_arena_shape_clip; - item_class->pick = nr_arena_shape_pick; -} - -/** - * Initializes the arena shape, setting all parameters to null, 0, false, - * or other defaults - */ -static void -nr_arena_shape_init(NRArenaShape *shape) -{ - shape->curve = NULL; - shape->style = NULL; - shape->markers = NULL; - shape->last_pick = NULL; - shape->repick_after = 0; -} - -static void -nr_arena_shape_finalize(NRObject *object) -{ - NRArenaShape *shape = (NRArenaShape *) object; - - if (shape->style) sp_style_unref(shape->style); - if (shape->curve) shape->curve->unref(); - shape->last_pick = NULL; - - ((NRObjectClass *) shape_parent_class)->finalize(object); -} - -/** - * Retrieves the markers from the item - */ -static NRArenaItem * -nr_arena_shape_children(NRArenaItem *item) -{ - NRArenaShape *shape = (NRArenaShape *) item; - - return shape->markers; -} - -/** - * Attaches child to item, and if ref is not NULL, sets it and ref->next as - * the prev and next items. If ref is NULL, then it sets the item's markers - * as the next items. - */ -static void -nr_arena_shape_add_child(NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) -{ - NRArenaShape *shape = (NRArenaShape *) item; - - if (!ref) { - shape->markers = nr_arena_item_attach(item, child, NULL, shape->markers); - } else { - ref->next = nr_arena_item_attach(item, child, ref, ref->next); - } - - nr_arena_item_request_update(item, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -/** - * Removes child from the shape. If there are no prev items in - * the child, it sets items' markers to the next item in the child. - */ -static void -nr_arena_shape_remove_child(NRArenaItem *item, NRArenaItem *child) -{ - NRArenaShape *shape = (NRArenaShape *) item; - - if (child->prev) { - nr_arena_item_detach(item, child); - } else { - shape->markers = nr_arena_item_detach(item, child); - } - - nr_arena_item_request_update(item, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -/** - * Detaches child from item, and if there are no previous items in child, it - * sets item's markers to the child. It then attaches the child back onto the item. - * If ref is null, it sets the markers to be the next item, otherwise it uses - * the next/prev items in ref. - */ -static void -nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) -{ - NRArenaShape *shape = (NRArenaShape *) item; - - if (child->prev) { - nr_arena_item_detach(item, child); - } else { - shape->markers = nr_arena_item_detach(item, child); - } - - if (!ref) { - shape->markers = nr_arena_item_attach(item, child, NULL, shape->markers); - } else { - ref->next = nr_arena_item_attach(item, child, ref, ref->next); - } - - nr_arena_item_request_render(child); -} - -/** - * Updates the arena shape 'item' and all of its children, including the markers. - */ -static guint -nr_arena_shape_update(NRArenaItem *item, Geom::IntRect const &area, NRGC *gc, guint state, guint reset) -{ - Geom::OptRect boundingbox; - - NRArenaShape *shape = NR_ARENA_SHAPE(item); - - unsigned int beststate = NR_ARENA_ITEM_STATE_ALL; - - // update markers - unsigned int newstate; - for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { - newstate = nr_arena_item_invoke_update(child, area, gc, state, reset); - beststate = beststate & newstate; - } - - if (!(state & NR_ARENA_ITEM_STATE_RENDER)) { - /* We do not have to create rendering structures */ - if (state & NR_ARENA_ITEM_STATE_BBOX) { - if (shape->curve) { - boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - if (boundingbox) { - item->bbox = boundingbox->roundOutwards(); - } else { - item->bbox = Geom::OptIntRect(); - } - } - if (beststate & NR_ARENA_ITEM_STATE_BBOX) { - for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { - item->bbox.unionWith(child->bbox); - } - } - } - return (state | item->state); - } - - boundingbox = Geom::OptRect(); - - bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - // clear Cairo data to force update - shape->nrstyle.update(); - - if (shape->curve) { - boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - - if (boundingbox && (shape->nrstyle.stroke.type != NRStyle::PAINT_NONE || outline)) { - float width, scale; - scale = gc->transform.descrim(); - width = MAX(0.125, shape->nrstyle.stroke_width * scale); - if ( fabs(shape->nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true - boundingbox->expandBy(width); - } - // those pesky miters, now - float miterMax = width * shape->nrstyle.miter_limit; - if ( miterMax > 0.01 ) { - // grunt mode. we should compute the various miters instead - // (one for each point on the curve) - boundingbox->expandBy(miterMax); - } - } - } - - item->bbox = boundingbox ? boundingbox->roundOutwards() : Geom::OptIntRect(); - - if (!shape->curve || - !shape->style || - shape->curve->is_empty() || - (( shape->nrstyle.fill.type != NRStyle::PAINT_NONE ) && - ( shape->nrstyle.stroke.type != NRStyle::PAINT_NONE && !outline) )) - { - //item->bbox = shape->approx_bbox; - return NR_ARENA_ITEM_STATE_ALL; - } - - if (beststate & NR_ARENA_ITEM_STATE_BBOX) { - for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { - item->bbox.unionWith(child->bbox); - } - } - - return NR_ARENA_ITEM_STATE_ALL; -} - -// cairo outline rendering: -static unsigned int -cairo_arena_shape_render_outline(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &/*area*/) -{ - NRArenaShape *shape = NR_ARENA_SHAPE(item); - - guint32 rgba = NR_ARENA_ITEM(shape)->arena->outlinecolor; - - { Inkscape::DrawingContext::Save save(ct); - ct.transform(shape->ctm); - ct.path(shape->curve->get_pathvector()); - } - { Inkscape::DrawingContext::Save save(ct); - ct.setSource(rgba); - ct.setLineWidth(0.5); - ct.setTolerance(1.25); - ct.stroke(); - } - - return item->state; -} - -/** - * Renders the item. Markers are just composed into the parent buffer. - */ -static unsigned int -nr_arena_shape_render(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &area, unsigned int flags) -{ - NRArenaShape *shape = NR_ARENA_SHAPE(item); - - if (!shape->curve) return item->state; - if (!shape->style) return item->state; - - // skip if not within bounding box - if (!area.intersects(item->bbox)) { - return item->state; - } - - bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - if (outline) { - // cairo outline rendering - unsigned int ret = cairo_arena_shape_render_outline (ct, item, area); - if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; - } else { - bool has_stroke, has_fill; - // we assume the context has no path - Inkscape::DrawingContext::Save save(ct); - ct.transform(shape->ctm); - - // update fill and stroke paints. - // this cannot be done during nr_arena_shape_update, because we need a Cairo context - // to render svg:pattern - has_fill = shape->nrstyle.prepareFill(ct, shape->paintbox); - has_stroke = shape->nrstyle.prepareStroke(ct, shape->paintbox); - has_stroke &= (shape->nrstyle.stroke_width != 0); - - if (has_fill || has_stroke) { - // TODO: remove segments outside of bbox when no dashes present - ct.path(shape->curve->get_pathvector()); - if (has_fill) { - shape->nrstyle.applyFill(ct); - ct.fillPreserve(); - } - if (has_stroke) { - shape->nrstyle.applyStroke(ct); - ct.strokePreserve(); - } - ct.newPath(); // clear path - } // has fill or stroke pattern - } - - // marker rendering - for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { - unsigned int ret = nr_arena_item_invoke_render(ct, child, area, flags); - if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; - } - - return item->state; -} - - -static guint nr_arena_shape_clip(Inkscape::DrawingContext &ct, NRArenaItem *item, Geom::IntRect const &/*area*/) -{ - NRArenaShape *shape = NR_ARENA_SHAPE(item); - if (!shape->curve) { - return item->state; - } - - Inkscape::DrawingContext::Save save(ct); - // handle clip-rule - if (shape->style) { - if (shape->style->clip_rule.computed == SP_WIND_RULE_EVENODD) { - ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD); - } else { - ct.setFillRule(CAIRO_FILL_RULE_WINDING); - } - } - ct.transform(shape->ctm); - ct.path(shape->curve->get_pathvector()); - ct.fill(); - - return item->state; -} - -static NRArenaItem * -nr_arena_shape_pick(NRArenaItem *item, Geom::Point const &p, double delta, unsigned int /*sticky*/) -{ - NRArenaShape *shape = NR_ARENA_SHAPE(item); - - if (shape->repick_after > 0) - shape->repick_after--; - - if (shape->repick_after > 0) // we are a slow, huge path. skip this pick, returning what was returned last time - return shape->last_pick; - - if (!shape->curve) return NULL; - if (!shape->style) return NULL; - - bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - - if (SP_SCALE24_TO_FLOAT(shape->style->opacity.value) == 0 && !outline) - // fully transparent, no pick unless outline mode - return NULL; - - GTimeVal tstart, tfinish; - g_get_current_time (&tstart); - - double width; - if (outline) { - width = 0.5; - } else if (shape->nrstyle.stroke.type != NRStyle::PAINT_NONE && shape->nrstyle.stroke.opacity > 1e-3) { - float const scale = shape->ctm.descrim(); - width = MAX(0.125, shape->nrstyle.stroke_width * scale) / 2; - } else { - width = 0; - } - - double dist = Geom::infinity(); - int wind = 0; - bool needfill = (shape->nrstyle.fill.type != NRStyle::PAINT_NONE - && shape->nrstyle.fill.opacity > 1e-3 && !outline); - - if (item->arena->canvasarena) { - Geom::Rect viewbox = item->arena->canvasarena->item.canvas->getViewbox(); - viewbox.expandBy (width); - pathv_matrix_point_bbox_wind_distance(shape->curve->get_pathvector(), shape->ctm, p, NULL, needfill? &wind : NULL, &dist, 0.5, &viewbox); - } else { - pathv_matrix_point_bbox_wind_distance(shape->curve->get_pathvector(), shape->ctm, p, NULL, needfill? &wind : NULL, &dist, 0.5, NULL); - } - - g_get_current_time (&tfinish); - glong this_pick = (tfinish.tv_sec - tstart.tv_sec) * 1000000 + (tfinish.tv_usec - tstart.tv_usec); - //g_print ("pick time %lu\n", this_pick); - - if (this_pick > 10000) { // slow picking, remember to skip several new picks - shape->repick_after = this_pick / 5000; - } - - // covered by fill? - if (needfill) { - if (!shape->style->fill_rule.computed) { - if (wind != 0) { - shape->last_pick = item; - return item; - } - } else { - if (wind & 0x1) { - shape->last_pick = item; - return item; - } - } - } - - // close to the edge, as defined by strokewidth and delta? - // this ignores dashing (as if the stroke is solid) and always works as if caps are round - if (needfill || width > 0) { // if either fill or stroke visible, - if ((dist - width) < delta) { - shape->last_pick = item; - return item; - } - } - - // if not picked on the shape itself, try its markers - for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { - NRArenaItem *ret = nr_arena_item_invoke_pick(child, p, delta, 0); - if (ret) { - shape->last_pick = item; - return item; - } - } - - shape->last_pick = NULL; - return NULL; -} - -/** - * - * Requests a render of the shape, then if the shape is already a curve it - * unrefs the old curve; if the new curve is valid it creates a copy of the - * curve and adds it to the shape. Finally, it requests an update of the - * arena for the shape. - */ -void nr_arena_shape_set_path(NRArenaShape *shape, SPCurve *curve, bool /*justTrans*/) -{ - g_return_if_fail(shape != NULL); - g_return_if_fail(NR_IS_ARENA_SHAPE(shape)); - - nr_arena_item_request_render(NR_ARENA_ITEM(shape)); - - if (shape->curve) { - shape->curve->unref(); - shape->curve = NULL; - } - - if (curve) { - shape->curve = curve; - curve->ref(); - } - - nr_arena_item_request_update(NR_ARENA_ITEM(shape), NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -/** nr_arena_shape_set_style - * - * Unrefs any existing style and ref's to the given one, then requests an update of the arena - */ -void -nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style) -{ - g_return_if_fail(shape != NULL); - g_return_if_fail(NR_IS_ARENA_SHAPE(shape)); - g_return_if_fail(style != NULL); - - sp_style_ref(style); - if (shape->style) sp_style_unref(shape->style); - shape->style = style; - - shape->nrstyle.set(style); - - //if shape has a filter - if (style->filter.set && style->getFilter()) { - if (!shape->filter) { - int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - shape->filter = new Inkscape::Filters::Filter(primitives); - } - sp_filter_build_renderer(SP_FILTER(style->getFilter()), shape->filter); - } else { - //no filter set for this shape - delete shape->filter; - shape->filter = NULL; - } - - nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void -nr_arena_shape_set_paintbox(NRArenaShape *shape, NRRect const *pbox) -{ - g_return_if_fail(shape != NULL); - g_return_if_fail(NR_IS_ARENA_SHAPE(shape)); - g_return_if_fail(pbox != NULL); - - shape->paintbox = pbox->upgrade_2geom(); - - nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -void NRArenaShape::setPaintBox(Geom::Rect const &pbox) -{ - paintbox = pbox; - - nr_arena_item_request_update(this, NR_ARENA_ITEM_STATE_ALL, FALSE); -} - -/* - 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 : diff --git a/src/display/nr-arena-shape.h b/src/display/nr-arena-shape.h deleted file mode 100644 index 317cff7fb..000000000 --- a/src/display/nr-arena-shape.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __NR_ARENA_SHAPE_H__ -#define __NR_ARENA_SHAPE_H__ - -/* - * RGBA display list system for inkscape - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#define NR_TYPE_ARENA_SHAPE (nr_arena_shape_get_type ()) -#define NR_ARENA_SHAPE(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_SHAPE, NRArenaShape)) -#define NR_IS_ARENA_SHAPE(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_SHAPE)) - -#include <cairo.h> -#include "display/display-forward.h" -#include "forward.h" -#include "nr-arena-item.h" -#include "nr-style.h" -#include "libnr/nr-rect.h" - -NRType nr_arena_shape_get_type (void); - -struct NRArenaShape : public NRArenaItem { - /* Shape data */ - SPCurve *curve; - SPStyle *style; - NRStyle nrstyle; - Geom::OptRect paintbox; - - /* Markers */ - NRArenaItem *markers; - - NRArenaItem *last_pick; - guint repick_after; - - static NRArenaShape *create(NRArena *arena) { - NRArenaShape *obj=reinterpret_cast<NRArenaShape *>(nr_object_new(NR_TYPE_ARENA_SHAPE)); - obj->init(arena); - obj->key = 0; - return obj; - } - - void setPaintBox(Geom::Rect const &pbox); -}; - -struct NRArenaShapeClass { - NRArenaItemClass parent_class; -}; - -void nr_arena_shape_set_path(NRArenaShape *shape, SPCurve *curve, bool justTrans); -void nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style); -void nr_arena_shape_set_paintbox(NRArenaShape *shape, NRRect const *pbox); - - -#endif /* !__NR_ARENA_SHAPE_H__ */ - -/* - 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 : diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp index 735d44e9e..b3e962201 100644 --- a/src/display/nr-arena.cpp +++ b/src/display/nr-arena.cpp @@ -12,13 +12,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "nr-arena-item.h" -#include "nr-arena.h" -#include "nr-filter-gaussian.h" -#include "nr-filter-types.h" +#include "display/drawing-item.h" +#include "display/nr-arena.h" +#include "display/nr-filter-gaussian.h" +#include "display/nr-filter-types.h" #include "preferences.h" #include "color.h" #include "libnr/nr-rect.h" +#include "libnr/nr-rect-l.h" static void nr_arena_class_init (NRArenaClass *klass); static void nr_arena_init (NRArena *arena); @@ -58,7 +59,7 @@ nr_arena_init (NRArena *arena) arena->delta = 0; // to be set by desktop from prefs arena->renderoffscreen = false; // use render values from preferences otherwise render exact arena->rendermode = Inkscape::RENDERMODE_NORMAL; // default is normal render - arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL; // default is normal color + arena->colormode = Inkscape::COLORMODE_NORMAL; // default is normal color arena->blurquality = BLUR_QUALITY_NORMAL; arena->filterquality = Inkscape::Filters::FILTER_QUALITY_NORMAL; arena->outlinecolor = 0xff; // black; to be set by desktop from bg color @@ -72,14 +73,14 @@ nr_arena_finalize (NRObject *object) } void -nr_arena_request_update (NRArena *arena, NRArenaItem *item) +nr_arena_request_update (NRArena *arena, Inkscape::DrawingItem *item) { NRActiveObject *aobject = (NRActiveObject *) arena; nr_return_if_fail (arena != NULL); nr_return_if_fail (NR_IS_ARENA (arena)); nr_return_if_fail (item != NULL); - nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + // setup render parameter if (arena->renderoffscreen == false) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -89,7 +90,7 @@ nr_arena_request_update (NRArena *arena, NRArenaItem *item) arena->blurquality = BLUR_QUALITY_BEST; arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST; arena->rendermode = Inkscape::RENDERMODE_NORMAL; - arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL; + arena->colormode = Inkscape::COLORMODE_NORMAL; } if (aobject->callbacks) { @@ -121,7 +122,7 @@ nr_arena_request_render_rect (NRArena *arena, Geom::OptIntRect const &area) arena->blurquality = BLUR_QUALITY_BEST; arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST; arena->rendermode = Inkscape::RENDERMODE_NORMAL; - arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL; + arena->colormode = Inkscape::COLORMODE_NORMAL; } NRRectL nr_area(*area); if (aobject->callbacks) { @@ -155,10 +156,10 @@ void nr_arena_set_cache_limit (NRArena *arena, Geom::OptIntRect const &cache_limit) { arena->cache_limit = cache_limit; - for (std::set<NRArenaItem *>::iterator i = arena->cached_items.begin(); + for (std::set<Inkscape::DrawingItem *>::iterator i = arena->cached_items.begin(); i != arena->cached_items.end(); ++i) { - nr_arena_item_request_update(*i, NR_ARENA_ITEM_STATE_CACHE, FALSE); + (*i)->_markForUpdate(Inkscape::DrawingItem::STATE_CACHE, false); } } diff --git a/src/display/nr-arena.h b/src/display/nr-arena.h index 5d078e19d..a444ed505 100644 --- a/src/display/nr-arena.h +++ b/src/display/nr-arena.h @@ -13,9 +13,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include <set> #include <glib/gmacros.h> - +#include <sigc++/sigc++.h> +#include <2geom/rect.h> #include "display/rendermode.h" +#include "libnr/nr-forward.h" +#include "libnr/nr-object.h" +#include "display/display-forward.h" G_BEGIN_DECLS @@ -27,19 +32,13 @@ G_END_DECLS #define NR_ARENA(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA, NRArena)) #define NR_IS_ARENA(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA)) -#include <set> -#include <2geom/rect.h> -#include <libnr/nr-forward.h> -#include <libnr/nr-object.h> -#include "nr-arena-forward.h" - class SPPainter; NRType nr_arena_get_type (void); struct NRArenaEventVector { NRObjectEventVector parent; - void (* request_update) (NRArena *arena, NRArenaItem *item, void *data); + void (* request_update) (NRArena *arena, Inkscape::DrawingItem *item, void *data); void (* request_render) (NRArena *arena, NRRectL *area, void *data); }; @@ -51,20 +50,22 @@ struct NRArena : public NRActiveObject { double delta; bool renderoffscreen; // if true then rendering must be exact Inkscape::RenderMode rendermode; - Inkscape::ColorRenderMode colorrendermode; + Inkscape::ColorMode colormode; int blurquality; // will be updated during update from preferences int filterquality; // will be updated during update from preferences Geom::OptIntRect cache_limit; - std::set<NRArenaItem *> cached_items; + std::set<Inkscape::DrawingItem *> cached_items; guint32 outlinecolor; SPCanvasArena *canvasarena; // may be NULL is this arena is not the screen but used for export etc. + + sigc::signal<void, Inkscape::DrawingItem *> item_deleted; }; struct NRArenaClass : public NRActiveObjectClass { }; -void nr_arena_request_update (NRArena *arena, NRArenaItem *item); +void nr_arena_request_update (NRArena *arena, Inkscape::DrawingItem *item); void nr_arena_request_render_rect (NRArena *arena, Geom::OptIntRect const &area); void nr_arena_set_renderoffscreen (NRArena *arena); void nr_arena_set_cache_limit (NRArena *arena, Geom::OptIntRect const &cache_limit); diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp index eaed2a8bd..039e56bb0 100644 --- a/src/display/nr-filter-diffuselighting.cpp +++ b/src/display/nr-filter-diffuselighting.cpp @@ -16,7 +16,6 @@ #include "display/cairo-templates.h" #include "display/cairo-utils.h" #include "display/nr-3dutils.h" -#include "display/nr-arena-item.h" #include "display/nr-filter-diffuselighting.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 01d2eca64..55cd02697 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -15,7 +15,7 @@ #include "display/cairo-utils.h" #include "display/drawing-context.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "display/nr-filter.h" #include "display/nr-filter-image.h" #include "display/nr-filter-units.h" @@ -70,7 +70,7 @@ void FilterImage::render_cairo(FilterSlot &slot) // TODO: do not recreate the rendering tree every time // TODO: the entire thing is a hack, we should give filter primitives an "update" method - // like the one for NRArenaItems + // like the one for DrawingItems document->ensureUpToDate(); NRArena* arena = NRArena::create(); @@ -78,7 +78,7 @@ void FilterImage::render_cairo(FilterSlot &slot) if (!optarea) return; unsigned const key = SPItem::display_key_new(1); - NRArenaItem* ai = SVGElem->invoke_show(arena, key, SP_ITEM_SHOW_DISPLAY); + DrawingItem *ai = SVGElem->invoke_show(arena, key, SP_ITEM_SHOW_DISPLAY); if (!ai) { g_warning("feImage renderer: error creating NRArenaItem for SVG Element"); @@ -104,15 +104,12 @@ void FilterImage::render_cairo(FilterSlot &slot) ct.translate(render_rect.min()); // Update to renderable state - NRGC gc(NULL); - Geom::Affine t = Geom::identity(); - nr_arena_item_set_transform(ai, &t); - gc.transform.setIdentity(); - nr_arena_item_invoke_update(ai, render_rect, &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE); - nr_arena_item_invoke_render(ct, ai, render_rect, NR_ARENA_ITEM_RENDER_NO_CACHE); + UpdateContext ctx; + ai->setTransform(Geom::identity()); + ai->update(render_rect, ctx, DrawingItem::STATE_ALL, 0); + ai->render(ct, render_rect, DrawingItem::RENDER_BYPASS_CACHE); SVGElem->invoke_hide(key); + //delete ai; // should be deleted by hide() above nr_object_unref((NRObject*) arena); slot.set(_output, out); diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index 494d77749..d2f992859 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -17,7 +17,6 @@ #include <2geom/transforms.h> #include "display/cairo-utils.h" #include "display/drawing-context.h" -#include "display/nr-arena-item.h" #include "display/nr-filter-types.h" #include "display/nr-filter-gaussian.h" #include "display/nr-filter-slot.h" @@ -26,7 +25,7 @@ namespace Inkscape { namespace Filters { -FilterSlot::FilterSlot(NRArenaItem *item, DrawingContext &bgct, +FilterSlot::FilterSlot(DrawingItem *item, DrawingContext &bgct, DrawingContext &graphic, FilterUnits const &u) : _item(item) , _source_graphic(graphic.rawTarget()) diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index 6a86ded8c..1e7c3a5a6 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -19,17 +19,16 @@ #include "display/nr-filter-types.h" #include "display/nr-filter-units.h" -struct NRArenaItem; - namespace Inkscape { class DrawingContext; +class DrawingItem; namespace Filters { class FilterSlot { public: /** Creates a new FilterSlot object. */ - FilterSlot(NRArenaItem *item, DrawingContext &bgct, + FilterSlot(DrawingItem *item, DrawingContext &bgct, DrawingContext &graphic, FilterUnits const &u); /** Destroys the FilterSlot object and all its contents */ virtual ~FilterSlot(); @@ -73,7 +72,7 @@ public: private: typedef std::map<int, cairo_surface_t *> SlotMap; SlotMap _slots; - NRArenaItem *_item; + DrawingItem *_item; //Geom::Rect _source_bbox; ///< bounding box of source graphic surface //Geom::Rect _intermediate_bbox; ///< bounding box of intermediate surfaces diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 25ef80c17..abd102452 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -39,7 +39,7 @@ #include "display/nr-filter-turbulence.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "display/drawing-context.h" #include <2geom/affine.h> #include <2geom/rect.h> @@ -97,7 +97,7 @@ Filter::~Filter() } -int Filter::render(NRArenaItem const *item, DrawingContext &bgct, DrawingContext &graphic) +int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &bgct, DrawingContext &graphic) { if (_primitive.empty()) { // when no primitives are defined, clear source graphic @@ -108,14 +108,14 @@ int Filter::render(NRArenaItem const *item, DrawingContext &bgct, DrawingContext return 1; } - FilterQuality const filterquality = (FilterQuality)item->arena->filterquality; - int const blurquality = item->arena->blurquality; + FilterQuality const filterquality = (FilterQuality)item->drawing()->filterquality; + int const blurquality = item->drawing()->blurquality; - Geom::Affine trans = item->ctm; + Geom::Affine trans = item->ctm(); Geom::Rect item_bbox; { - Geom::OptRect maybe_bbox = item->item_bbox; + Geom::OptRect maybe_bbox = item->itemBounds(); if (maybe_bbox.isEmpty()) { // Code below needs a bounding box return 1; @@ -161,7 +161,7 @@ int Filter::render(NRArenaItem const *item, DrawingContext &bgct, DrawingContext } } - FilterSlot slot(const_cast<NRArenaItem*>(item), bgct, graphic, units); + FilterSlot slot(const_cast<Inkscape::DrawingItem*>(item), bgct, graphic, units); slot.set_quality(filterquality); slot.set_blurquality(blurquality); @@ -188,10 +188,10 @@ void Filter::set_primitive_units(SPFilterUnits unit) { _primitive_units = unit; } -void Filter::area_enlarge(Geom::IntRect &bbox, NRArenaItem const *item) const { +void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item) const { NRRectL b(bbox); for (unsigned i = 0 ; i < _primitive.size() ; i++) { - if (_primitive[i]) _primitive[i]->area_enlarge(b, item->ctm); + if (_primitive[i]) _primitive[i]->area_enlarge(b, item->ctm()); } bbox = *b.upgrade_2geom(); @@ -208,7 +208,7 @@ void Filter::area_enlarge(Geom::IntRect &bbox, NRArenaItem const *item) const { } Geom::Rect item_bbox; - Geom::OptRect maybe_bbox = item->item_bbox; + Geom::OptRect maybe_bbox = item->itemBounds(); if (maybe_bbox.isEmpty()) { // Code below needs a bounding box return; @@ -216,9 +216,9 @@ void Filter::area_enlarge(Geom::IntRect &bbox, NRArenaItem const *item) const { item_bbox = *maybe_bbox; std::pair<double,double> res_low - = _filter_resolution(item_bbox, item->ctm, filterquality); + = _filter_resolution(item_bbox, item->ctm(), filterquality); //std::pair<double,double> res_full - // = _filter_resolution(item_bbox, item->ctm, FILTER_QUALITY_BEST); + // = _filter_resolution(item_bbox, item->ctm(), FILTER_QUALITY_BEST); double pixels_per_block = fmax(item_bbox.width() / res_low.first, item_bbox.height() / res_low.second); bbox.x0 -= (int)pixels_per_block; @@ -228,10 +228,10 @@ void Filter::area_enlarge(Geom::IntRect &bbox, NRArenaItem const *item) const { */ } -Geom::IntRect Filter::compute_drawbox(NRArenaItem const *item, Geom::Rect const &item_bbox) { +Geom::IntRect Filter::compute_drawbox(Inkscape::DrawingItem const *item, Geom::Rect const &item_bbox) { Geom::Rect enlarged = filter_effect_area(item_bbox); - enlarged *= item->ctm; + enlarged *= item->ctm(); Geom::IntRect ret(enlarged.roundOutwards()); return ret; diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index 5cebf3ad3..31705f53b 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -21,21 +21,20 @@ #include "sp-filter-units.h" #include "gc-managed.h" -struct NRArenaItem; - namespace Inkscape { class DrawingContext; +class DrawingItem; namespace Filters { -class Filter : public Inkscape::GC::Managed<> { +class Filter { public: /** Given background state from @a bgct and an intermediate rendering from the surface * backing @a graphic, modify the contents of the surface backing @a graphic to represent * the results of filter rendering. @a bgarea and @a area specify bounding boxes * of both surfaces in world coordinates; Cairo contexts are assumed to be in default state * (0,0 = surface origin, no path, OVER operator) */ - int render(NRArenaItem const *item, DrawingContext &bgct, DrawingContext &graphic); + int render(Inkscape::DrawingItem const *item, DrawingContext &bgct, DrawingContext &graphic); /** * Creates a new filter primitive under this filter object. @@ -151,13 +150,13 @@ public: * to be rendered so that after filtering, the original area is * drawn correctly. */ - void area_enlarge(Geom::IntRect &area, NRArenaItem const *item) const; + void area_enlarge(Geom::IntRect &area, Inkscape::DrawingItem const *item) const; /** * Given an item bounding box (in user coords), this function enlarges it * to contain the filter effects region and transforms it to screen * coordinates */ - Geom::IntRect compute_drawbox(NRArenaItem const *item, Geom::Rect const &item_bbox); + Geom::IntRect compute_drawbox(Inkscape::DrawingItem const *item, Geom::Rect const &item_bbox); /** * Returns the filter effects area in user coordinate system. * The given bounding box should be a bounding box as specified in diff --git a/src/display/rendermode.h b/src/display/rendermode.h index 8fc022bfb..cbd35de73 100644 --- a/src/display/rendermode.h +++ b/src/display/rendermode.h @@ -15,10 +15,10 @@ enum RenderMode { RENDERMODE_OUTLINE }; -enum ColorRenderMode { - COLORRENDERMODE_NORMAL, - COLORRENDERMODE_GRAYSCALE, - COLORRENDERMODE_PRINT_COLORS_PREVIEW +enum ColorMode { + COLORMODE_NORMAL, + COLORMODE_GRAYSCALE, + COLORMODE_PRINT_COLORS_PREVIEW }; } diff --git a/src/document.cpp b/src/document.cpp index 5bcf1bf40..64f4ea92a 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -44,7 +44,7 @@ #include "desktop.h" #include "dir-util.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "document-private.h" #include "helper/units.h" #include "inkscape-private.h" @@ -1113,8 +1113,8 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro for ( SPObject *o = group->firstChild() ; o && !bottomMost; o = o->getNext() ) { if ( SP_IS_ITEM(o) ) { SPItem *item = SP_ITEM(o); - NRArenaItem *arenaitem = item->get_arenaitem(dkey); - if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL + Inkscape::DrawingItem *arenaitem = item->get_arenaitem(dkey); + if (arenaitem && arenaitem->pick(p, delta, 1) != NULL && (take_insensitive || item->isVisibleAndUnlocked(dkey))) { if (g_slist_find((GSList *) list, item) != NULL) { bottomMost = item; @@ -1167,10 +1167,10 @@ SPItem *find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const } } else { SPItem *child = SP_ITEM(o); - NRArenaItem *arenaitem = child->get_arenaitem(dkey); + Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); // seen remembers the last (topmost) of items pickable at this point - if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL + if (arenaitem && arenaitem->pick(p, delta, 1) != NULL && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { seen = child; } @@ -1201,10 +1201,10 @@ SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Point const } if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) { SPItem *child = SP_ITEM(o); - NRArenaItem *arenaitem = child->get_arenaitem(dkey); + Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); // seen remembers the last (topmost) of groups pickable at this point - if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL) { + if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) { seen = child; } } diff --git a/src/extension/internal/cairo-png-out.cpp b/src/extension/internal/cairo-png-out.cpp index f741c9f39..4b551e730 100644 --- a/src/extension/internal/cairo-png-out.cpp +++ b/src/extension/internal/cairo-png-out.cpp @@ -28,7 +28,6 @@ #include "extension/db.h" #include "extension/output.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "display/curve.h" #include "display/canvas-bpath.h" @@ -61,7 +60,7 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename) SPItem *base = doc->getRoot(); NRArena *arena = NRArena::create(); unsigned dkey = SPItem::display_key_new(1); - NRArenaItem *root = base->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY); + base->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY); /* Create renderer and context */ renderer = new CairoRenderer(); diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 7fdfaf8df..7e5324e57 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -30,7 +30,6 @@ #include "extension/db.h" #include "extension/output.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "display/curve.h" #include "display/canvas-bpath.h" diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 22b68b0ca..c7cba09bb 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -33,8 +33,7 @@ #include <glibmm/i18n.h> #include "display/nr-arena.h" -#include "display/nr-arena-item.h" -#include "display/nr-arena-group.h" +#include "display/display-forward.h" #include "display/curve.h" #include "display/canvas-bpath.h" #include "display/cairo-utils.h" @@ -91,14 +90,14 @@ struct SPClipPathView { SPClipPathView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; struct SPMaskView { SPMaskView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 5d7c82bff..5be9e15c3 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -30,7 +30,6 @@ #include "extension/db.h" #include "extension/output.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "display/curve.h" #include "display/canvas-bpath.h" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 7eb7881dc..76fc5073f 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -37,8 +37,7 @@ #include <glibmm/i18n.h> #include "display/nr-arena.h" -#include "display/nr-arena-item.h" -#include "display/nr-arena-group.h" +#include "display/display-forward.h" #include "display/curve.h" #include "display/canvas-bpath.h" #include "display/cairo-utils.h" @@ -88,14 +87,14 @@ struct SPClipPathView { SPClipPathView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; struct SPMaskView { SPMaskView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; diff --git a/src/extension/internal/latex-pstricks-out.cpp b/src/extension/internal/latex-pstricks-out.cpp index 376db7ee3..000280158 100644 --- a/src/extension/internal/latex-pstricks-out.cpp +++ b/src/extension/internal/latex-pstricks-out.cpp @@ -19,7 +19,7 @@ #include "extension/print.h" #include "extension/db.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" +#include "display/display-forward.h" #include "sp-root.h" @@ -73,7 +73,7 @@ void LatexOutput::save(Inkscape::Extension::Output * /*mod2*/, SPDocument *doc, /* Release arena */ (mod->base)->invoke_hide (mod->dkey); mod->base = NULL; - mod->root = NULL; + mod->root = NULL; // should have been deleted by invoke_hide nr_object_unref ((NRObject *) mod->arena); mod->arena = NULL; /* end */ diff --git a/src/extension/print.h b/src/extension/print.h index d5218aed8..b3c686d26 100644 --- a/src/extension/print.h +++ b/src/extension/print.h @@ -13,7 +13,7 @@ #include "extension.h" -#include "display/nr-arena-forward.h" +#include "display/display-forward.h" #include "forward.h" #include "sp-item.h" namespace Inkscape { @@ -22,10 +22,10 @@ namespace Extension { class Print : public Extension { public: /* TODO: These are public for the short term, but this should be fixed */ - SPItem *base; /**< TODO: Document these */ - NRArena *arena; /**< TODO: Document these */ - NRArenaItem *root; /**< TODO: Document these */ - unsigned int dkey; /**< TODO: Document these */ + SPItem *base; + NRArena *arena; + Inkscape::DrawingItem *root; + unsigned int dkey; public: Print (Inkscape::XML::Node * in_repr, diff --git a/src/flood-context.cpp b/src/flood-context.cpp index 84c97b096..a71333a4f 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -20,54 +20,53 @@ #include "config.h" #endif +#include <2geom/pathvector.h> #include <gdk/gdkkeysyms.h> #include <queue> #include <deque> +#include <glibmm/i18n.h> -#include "macros.h" -#include "display/sp-canvas.h" -#include "document.h" -#include "sp-namedview.h" -#include "sp-object.h" -#include "sp-rect.h" -#include "selection.h" -#include "desktop-handles.h" +#include "color.h" +#include "context-fns.h" #include "desktop.h" +#include "desktop-handles.h" #include "desktop-style.h" -#include "message-stack.h" -#include "message-context.h" -#include "pixmaps/cursor-paintbucket.xpm" +#include "display/cairo-utils.h" +#include "display/canvas-arena.h" +#include "display/drawing-context.h" +#include "display/drawing-image.h" +#include "display/drawing-item.h" +#include "display/nr-arena.h" +#include "display/sp-canvas.h" +#include "document.h" #include "flood-context.h" -#include "sp-metrics.h" -#include <glibmm/i18n.h> +#include "livarot/Path.h" +#include "livarot/Shape.h" +#include "macros.h" +#include "message-context.h" +#include "message-stack.h" #include "object-edit.h" -#include "xml/repr.h" -#include "xml/node-event-vector.h" #include "preferences.h" -#include "context-fns.h" #include "rubberband.h" +#include "selection.h" #include "shape-editor.h" - -#include "display/nr-arena-item.h" -#include "display/nr-arena.h" -#include "display/nr-arena-image.h" -#include "display/canvas-arena.h" -#include "display/cairo-utils.h" -#include "display/drawing-context.h" -#include <2geom/pathvector.h> -#include "sp-item.h" -#include "sp-root.h" #include "sp-defs.h" -#include "sp-path.h" +#include "sp-item.h" #include "splivarot.h" -#include "livarot/Path.h" -#include "livarot/Shape.h" +#include "sp-metrics.h" +#include "sp-namedview.h" +#include "sp-object.h" +#include "sp-path.h" +#include "sp-rect.h" +#include "sp-root.h" #include "svg/svg.h" -#include "color.h" - -#include "trace/trace.h" #include "trace/imagemap.h" #include "trace/potrace/inkscape-potrace.h" +#include "trace/trace.h" +#include "xml/node-event-vector.h" +#include "xml/repr.h" + +#include "pixmaps/cursor-paintbucket.xpm" using Inkscape::DocumentUndo; @@ -812,15 +811,12 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even Geom::Affine affine = scale * Geom::Translate(-origin * scale); /* Create ArenaItems and set transform */ - NRArenaItem *root = document->getRoot()->invoke_show( arena, dkey, SP_ITEM_SHOW_DISPLAY); - nr_arena_item_set_transform(NR_ARENA_ITEM(root), affine); - - NRGC gc(NULL); - gc.transform.setIdentity(); + Inkscape::DrawingItem *root = document->getRoot()->invoke_show( arena, dkey, SP_ITEM_SHOW_DISPLAY); + root->setTransform(affine); + Inkscape::UpdateContext ctx; Geom::IntRect final_bbox = Geom::IntRect::from_xywh(0, 0, width, height); - - nr_arena_item_invoke_update(root, final_bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); + root->update(final_bbox, ctx, Inkscape::DrawingItem::STATE_ALL, 0); int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); guchar *px = g_new(guchar, stride * height); @@ -842,7 +838,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even ct.paint(); ct.setOperator(CAIRO_OPERATOR_OVER); - nr_arena_item_invoke_render(ct, root, final_bbox, NR_ARENA_ITEM_RENDER_NO_CACHE ); + root->render(ct, final_bbox, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); cairo_surface_flush(s); cairo_surface_destroy(s); diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert index 2ccec8d16..7110c2025 100644 --- a/src/helper/Makefile_insert +++ b/src/helper/Makefile_insert @@ -18,7 +18,6 @@ ink_common_sources += \ helper/recthull.h \ helper/sp-marshal.cpp \ helper/sp-marshal.h \ - helper/stlport.h \ helper/unit-menu.cpp \ helper/unit-menu.h \ helper/unit-tracker.cpp \ diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index c845da011..959007450 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -24,7 +24,7 @@ #include "helper/png-write.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "display/nr-arena.h" #include "document.h" #include "sp-item.h" @@ -111,43 +111,40 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, { if (width == 0 || height == 0) return NULL; - GdkPixbuf* pixbuf = NULL; - /* Create new arena for offscreen rendering*/ - NRArena *arena = NRArena::create(); - nr_arena_set_renderoffscreen(arena); - unsigned dkey = SPItem::display_key_new(1); + GdkPixbuf* pixbuf = NULL; + /* Create new arena for offscreen rendering*/ + NRArena *arena = NRArena::create(); + nr_arena_set_renderoffscreen(arena); + unsigned dkey = SPItem::display_key_new(1); - doc->ensureUpToDate(); + doc->ensureUpToDate(); - Geom::Rect screen=Geom::Rect(Geom::Point(x0,y0), Geom::Point(x1, y1)); + Geom::Rect screen=Geom::Rect(Geom::Point(x0,y0), Geom::Point(x1, y1)); - double padding = 1.0; + double padding = 1.0; - Geom::Point origin(screen.min()[Geom::X], - doc->getHeight() - screen[Geom::Y].extent() - screen.min()[Geom::Y]); + Geom::Point origin(screen.min()[Geom::X], + doc->getHeight() - screen[Geom::Y].extent() - screen.min()[Geom::Y]); - origin[Geom::X] = origin[Geom::X] + (screen[Geom::X].extent() * ((1 - padding) / 2)); - origin[Geom::Y] = origin[Geom::Y] + (screen[Geom::Y].extent() * ((1 - padding) / 2)); + origin[Geom::X] = origin[Geom::X] + (screen[Geom::X].extent() * ((1 - padding) / 2)); + origin[Geom::Y] = origin[Geom::Y] + (screen[Geom::Y].extent() * ((1 - padding) / 2)); - Geom::Scale scale( (xdpi / PX_PER_IN), (ydpi / PX_PER_IN)); - Geom::Affine affine = scale * Geom::Translate(-origin * scale); + Geom::Scale scale( (xdpi / PX_PER_IN), (ydpi / PX_PER_IN)); + Geom::Affine affine = scale * Geom::Translate(-origin * scale); - /* Create ArenaItems and set transform */ - NRArenaItem *root = doc->getRoot()->invoke_show( arena, dkey, SP_ITEM_SHOW_DISPLAY); - nr_arena_item_set_transform(NR_ARENA_ITEM(root), affine); + /* Create ArenaItems and set transform */ + Inkscape::DrawingItem *root = doc->getRoot()->invoke_show( arena, dkey, SP_ITEM_SHOW_DISPLAY); + root->setTransform(affine); + Inkscape::UpdateContext ctx; - NRGC gc(NULL); - gc.transform.setIdentity(); - - // We show all and then hide all items we don't want, instead of showing only requested items, - // because that would not work if the shown item references something in defs - if (items_only) { - hide_other_items_recursively(doc->getRoot(), items_only, dkey); - } + // We show all and then hide all items we don't want, instead of showing only requested items, + // because that would not work if the shown item references something in defs + if (items_only) { + hide_other_items_recursively(doc->getRoot(), items_only, dkey); + } Geom::IntRect final_bbox = Geom::IntRect::from_xywh(0, 0, width, height); - - nr_arena_item_invoke_update(root, final_bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); + root->update(final_bbox, ctx, Inkscape::DrawingItem::STATE_ALL, 0); cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); @@ -155,7 +152,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, Inkscape::DrawingContext ct(surface, Geom::Point(0,0)); // render items - nr_arena_item_invoke_render(ct, root, final_bbox, NR_ARENA_ITEM_RENDER_NO_CACHE ); + root->render(ct, final_bbox, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(surface), GDK_COLORSPACE_RGB, TRUE, diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index d2983806a..7812969a0 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -24,7 +24,7 @@ #include "png-write.h" #include "io/sys.h" #include "display/drawing-context.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "display/nr-arena.h" #include "document.h" #include "sp-item.h" @@ -51,7 +51,7 @@ static unsigned int const MAX_STRIPE_SIZE = 1024*1024; struct SPEBP { unsigned long int width, height, sheight; guint32 background; - NRArenaItem *root; // the root arena item to show; it is assumed that all unneeded items are hidden + Inkscape::DrawingItem *root; // the root arena item to show; it is assumed that all unneeded items are hidden guchar *px; unsigned (*status)(float, void *); void *data; @@ -326,11 +326,8 @@ sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, v Geom::IntRect bbox = Geom::IntRect::from_xywh(0, row, ebp->width, num_rows); /* Update to renderable state */ - NRGC gc(NULL); - gc.transform.setIdentity(); - - nr_arena_item_invoke_update(ebp->root, bbox, &gc, - NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); + Inkscape::UpdateContext ctx; + ebp->root->update(bbox, ctx, Inkscape::DrawingItem::STATE_ALL, 0); int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, ebp->width); unsigned char *px = g_new(guchar, num_rows * stride); @@ -344,7 +341,7 @@ sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, v ct.setOperator(CAIRO_OPERATOR_OVER); /* Render */ - nr_arena_item_invoke_render(ct, ebp->root, bbox, 0); + ebp->root->render(ct, bbox, 0); cairo_surface_destroy(s); *to_free = px; @@ -462,7 +459,7 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, // Create ArenaItems and set transform ebp.root = doc->getRoot()->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY); - nr_arena_item_set_transform(NR_ARENA_ITEM(ebp.root), affine); + ebp.root->setTransform(affine); // We show all and then hide all items we don't want, instead of showing only requested items, // because that would not work if the shown item references something in defs diff --git a/src/interface.cpp b/src/interface.cpp index 25153097d..a981424fa 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -646,7 +646,7 @@ update_view_menu(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_dat Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(widget), "view"); SPDesktop *dt = static_cast<SPDesktop*>(view); Inkscape::RenderMode mode = dt->getMode(); - Inkscape::ColorRenderMode colormode = dt->getColorMode(); + Inkscape::ColorMode colormode = dt->getColorMode(); bool new_state = false; if (!strcmp(action->id, "ViewModeNormal")) { @@ -656,11 +656,11 @@ update_view_menu(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_dat } else if (!strcmp(action->id, "ViewModeOutline")) { new_state = mode == Inkscape::RENDERMODE_OUTLINE; } else if (!strcmp(action->id, "ViewColorModeNormal")) { - new_state = colormode == Inkscape::COLORRENDERMODE_NORMAL; + new_state = colormode == Inkscape::COLORMODE_NORMAL; } else if (!strcmp(action->id, "ViewColorModeGrayscale")) { - new_state = colormode == Inkscape::COLORRENDERMODE_GRAYSCALE; + new_state = colormode == Inkscape::COLORMODE_GRAYSCALE; } else if (!strcmp(action->id, "ViewColorModePrintColorsPreview")) { - new_state = colormode == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW; + new_state = colormode == Inkscape::COLORMODE_PRINT_COLORS_PREVIEW; } else { g_warning("update_view_menu does not handle this verb"); } diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 610f92582..a72fa0180 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -10,7 +10,7 @@ */ #include <glib/gmem.h> #include "Layout-TNG.h" -#include "display/nr-arena-glyphs.h" +#include "display/drawing-text.h" #include "style.h" #include "print.h" #include "extension/print.h" @@ -81,28 +81,27 @@ void Layout::_getGlyphTransformMatrix(int glyph_index, Geom::Affine *matrix) con } } -void Layout::show(NRArenaGroup *in_arena, NRRect const *paintbox) const +void Layout::show(DrawingGroup *in_arena, NRRect const *paintbox) const { int glyph_index = 0; for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) continue; InputStreamTextSource const *text_source = static_cast<InputStreamTextSource const *>(_input_stream[_spans[span_index].in_input_stream_item]); - NRArenaGlyphsGroup *nr_group = NRArenaGlyphsGroup::create(in_arena->arena); - nr_arena_item_add_child(in_arena, nr_group, NULL); - nr_arena_item_unref(nr_group); - nr_arena_glyphs_group_set_style(nr_group, text_source->style); + DrawingText *nr_text = new DrawingText(in_arena->drawing()); + nr_text->setStyle(text_source->style); + while (glyph_index < (int)_glyphs.size() && _characters[_glyphs[glyph_index].in_character].in_span == span_index) { if (_characters[_glyphs[glyph_index].in_character].in_glyph != -1) { Geom::Affine glyph_matrix; _getGlyphTransformMatrix(glyph_index, &glyph_matrix); - nr_arena_glyphs_group_add_component(nr_group, _spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix); + nr_text->addComponent(_spans[span_index].font, _glyphs[glyph_index].glyph, glyph_matrix); } glyph_index++; } - nr_arena_glyphs_group_set_paintbox(NR_ARENA_GLYPHS_GROUP(nr_group), paintbox); + nr_text->setPaintBox(paintbox ? paintbox->upgrade_2geom() : Geom::OptRect()); + in_arena->prependChild(nr_text); } - nr_arena_item_request_update(NR_ARENA_ITEM(in_arena), NR_ARENA_ITEM_STATE_ALL, FALSE); } void Layout::getBoundingBox(NRRect *bounding_box, Geom::Affine const &transform, int start, int length) const diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 6ab02c0e3..25f80e9e9 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -37,7 +37,6 @@ using Inkscape::Extension::Internal::CairoRenderContext; class SPStyle; class Shape; -class NRArenaGroup; class SPPrintContext; class SVGLength; class Path; @@ -46,6 +45,8 @@ class font_instance; typedef struct _PangoFontDescription PangoFontDescription; namespace Inkscape { +class DrawingGroup; + namespace Text { /** \brief Generates the layout for either wrapped or non-wrapped text and stores the result @@ -327,7 +328,7 @@ public: \param in_arena The arena to add the glyphs group to \param paintbox The current rendering tile */ - void show(NRArenaGroup *in_arena, NRRect const *paintbox) const; + void show(DrawingGroup *in_arena, NRRect const *paintbox) const; /** Calculates the smallest rectangle completely enclosing all the glyphs. diff --git a/src/marker.cpp b/src/marker.cpp index d3fa83ed6..11a270e73 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -21,7 +21,7 @@ #include <2geom/affine.h> #include <2geom/transforms.h> #include "svg/svg.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "xml/repr.h" #include "attributes.h" #include "marker.h" @@ -31,7 +31,7 @@ struct SPMarkerView { SPMarkerView *next; unsigned int key; - std::vector<NRArenaItem *> items; + std::vector<Inkscape::DrawingItem *> items; }; static void sp_marker_class_init (SPMarkerClass *klass); @@ -43,7 +43,7 @@ static void sp_marker_set (SPObject *object, unsigned int key, const gchar *valu static void sp_marker_update (SPObject *object, SPCtx *ctx, guint flags); static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static NRArenaItem *sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static Inkscape::DrawingItem *sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_marker_private_hide (SPItem *item, unsigned int key); static void sp_marker_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags); static void sp_marker_print (SPItem *item, SPPrintContext *ctx); @@ -448,8 +448,8 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) for (SPMarkerView *v = marker->views; v != NULL; v = v->next) { for (unsigned i = 0 ; i < v->items.size() ; i++) { if (v->items[i]) { - Geom::Affine tmp = marker->c2p; - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->items[i]), &tmp); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[i]); + g->setChildTransform(marker->c2p); } } } @@ -522,7 +522,7 @@ sp_marker_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::X /** * This routine is disabled to break propagation. */ -static NRArenaItem * +static Inkscape::DrawingItem * sp_marker_private_show (SPItem */*item*/, NRArena */*arena*/, unsigned int /*key*/, unsigned int /*flags*/) { /* Break propagation */ @@ -560,14 +560,14 @@ sp_marker_print (SPItem */*item*/, SPPrintContext */*ctx*/) /** * Removes any SPMarkerViews that a marker has with a specific key. - * Set up the NRArenaItem array's size in the specified SPMarker's SPMarkerView. + * Set up the DrawingItem array's size in the specified SPMarker's SPMarkerView. * This is called from sp_shape_update() for shapes that have markers. It * removes the old view of the marker and establishes a new one, registering * it with the marker's list of views for future updates. * * \param marker Marker to create views in. * \param key Key to give each SPMarkerView. - * \param size Number of NRArenaItems to put in the SPMarkerView. + * \param size Number of DrawingItems to put in the SPMarkerView. */ void sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size) @@ -601,8 +601,8 @@ sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size) * Shows an instance of a marker. This is called during sp_shape_update_marker_view() * show and transform a child item in the arena for all views with the given key. */ -NRArenaItem * -sp_marker_show_instance ( SPMarker *marker, NRArenaItem *parent, +Inkscape::DrawingItem * +sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, unsigned int key, unsigned int pos, Geom::Affine const &base, float linewidth) { @@ -621,14 +621,13 @@ sp_marker_show_instance ( SPMarker *marker, NRArenaItem *parent, if (!v->items[pos]) { /* Parent class ::show method */ v->items[pos] = ((SPItemClass *) parent_class)->show ((SPItem *) marker, - parent->arena, key, + parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); if (v->items[pos]) { /* fixme: Position (Lauris) */ - nr_arena_item_add_child (parent, v->items[pos], NULL); - /* nr_arena_item_unref (v->items[pos]); */ - Geom::Affine tmp = marker->c2p; - nr_arena_group_set_child_transform((NRArenaGroup *) v->items[pos], &tmp); + parent->prependChild(v->items[pos]); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[pos]); + if (g) g->setChildTransform(marker->c2p); } } if (v->items[pos]) { @@ -643,8 +642,7 @@ sp_marker_show_instance ( SPMarker *marker, NRArenaItem *parent, if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { m = Geom::Scale(linewidth) * m; } - - nr_arena_item_set_transform(v->items[pos], m); + v->items[pos]->setTransform(m); } return v->items[pos]; } @@ -695,7 +693,7 @@ sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destro if (destroyitems) { for (i = 0; i < view->items.size(); i++) { /* We have to walk through the whole array because there may be hidden items */ - if (view->items[i]) nr_arena_item_unref (view->items[i]); + delete view->items[i]; } } view->items.clear(); diff --git a/src/marker.h b/src/marker.h index 09461b3a1..eb907e2fb 100644 --- a/src/marker.h +++ b/src/marker.h @@ -85,7 +85,7 @@ protected: }; void sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size); -NRArenaItem *sp_marker_show_instance (SPMarker *marker, NRArenaItem *parent, +Inkscape::DrawingItem *sp_marker_show_instance (SPMarker *marker, Inkscape::DrawingItem *parent, unsigned int key, unsigned int pos, Geom::Affine const &base, float linewidth); void sp_marker_hide (SPMarker *marker, unsigned int key); diff --git a/src/print.cpp b/src/print.cpp index 1ee58a3e6..29c5b0ed2 100644 --- a/src/print.cpp +++ b/src/print.cpp @@ -15,6 +15,8 @@ # include "config.h" #endif +#include "display/nr-arena.h" +#include "display/drawing-item.h" #include "inkscape.h" #include "desktop.h" #include "sp-item.h" @@ -80,9 +82,6 @@ unsigned int sp_print_text(SPPrintContext *ctx, char const *text, Geom::Point p, return ctx->module->text(text, p, style); } -#include "display/nr-arena.h" -#include "display/nr-arena-item.h" - /* UI */ void @@ -92,19 +91,11 @@ sp_print_document(Gtk::Window& parentWindow, SPDocument *doc) // Build arena SPItem *base = doc->getRoot(); - NRArena *arena = NRArena::create(); - unsigned int dkey = SPItem::display_key_new(1); - // TODO investigate why we are grabbing root and then ignoring it. - NRArenaItem *root = base->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY); // Run print dialog Inkscape::UI::Dialog::Print printop(doc,base); Gtk::PrintOperationResult res = printop.run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, parentWindow); (void)res; // TODO handle this - - // Release arena - base->invoke_hide(dkey); - nr_object_unref((NRObject *) arena); } void @@ -138,8 +129,8 @@ sp_print_document_to_file(SPDocument *doc, gchar const *filename) /* Release arena */ (mod->base)->invoke_hide(mod->dkey); mod->base = NULL; - mod->root = NULL; nr_object_unref((NRObject *) mod->arena); + mod->root = NULL; // should be deleted by invoke_hide mod->arena = NULL; /* end */ diff --git a/src/print.h b/src/print.h index caea6ae3a..6bdbe4b82 100644 --- a/src/print.h +++ b/src/print.h @@ -17,6 +17,7 @@ #include "forward.h" #include "extension/extension-forward.h" +struct NRRect; struct SPPrintContext { Inkscape::Extension::Print *module; }; diff --git a/src/select-context.cpp b/src/select-context.cpp index 143fb1ae2..b3e38bf7b 100644 --- a/src/select-context.cpp +++ b/src/select-context.cpp @@ -43,7 +43,7 @@ #include "seltrans.h" #include "box3d.h" #include "display/sp-canvas.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" using Inkscape::DocumentUndo; @@ -414,7 +414,7 @@ sp_select_context_cycle_through_items(SPSelectContext *sc, Inkscape::Selection * if (!sc->cycling_cur_item) return; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop; SPItem *item = SP_ITEM(sc->cycling_cur_item->data); @@ -422,7 +422,7 @@ sp_select_context_cycle_through_items(SPSelectContext *sc, Inkscape::Selection * if (!g_list_find(sc->cycling_items_selected_before, item) && selection->includes(item)) selection->remove(item); arenaitem = item->get_arenaitem(desktop->dkey); - nr_arena_item_set_opacity (arenaitem, 0.3); + arenaitem->setOpacity(0.3); // Find next item and activate it GList *next; @@ -438,7 +438,7 @@ sp_select_context_cycle_through_items(SPSelectContext *sc, Inkscape::Selection * sc->cycling_cur_item = next; item = SP_ITEM(sc->cycling_cur_item->data); arenaitem = item->get_arenaitem(desktop->dkey); - nr_arena_item_set_opacity (arenaitem, 1.0); + arenaitem->setOpacity(1.0); if (shift_pressed) selection->add(item); @@ -788,10 +788,10 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) g_assert(sc->cycling_cur_item != NULL || sc->cycling_items == NULL); } else { // ... otherwise reset opacities for outdated items ... - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; for(GList *l = sc->cycling_items_cmp; l != NULL; l = l->next) { arenaitem = SP_ITEM(l->data)->get_arenaitem(desktop->dkey); - nr_arena_item_set_opacity (arenaitem, 1.0); + arenaitem->setOpacity(1.0); //if (!shift_pressed && !g_list_find(sc->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) if (!g_list_find(sc->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) selection->remove(SP_ITEM(l->data)); @@ -810,7 +810,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) for(GList *l = sc->cycling_items; l != NULL; l = l->next) { item = SP_ITEM(l->data); arenaitem = item->get_arenaitem(desktop->dkey); - nr_arena_item_set_opacity (arenaitem, 0.3); + arenaitem->setOpacity(0.3); if (selection->includes(item)) { // already selected items are stored separately, too sc->cycling_items_selected_before = g_list_append(sc->cycling_items_selected_before, item); @@ -1085,10 +1085,10 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) if (alt) { // TODO: Should we have a variable like is_cycling or is it harmless to run this piece of code each time? // quit cycle-selection and reset opacities SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; for (GList *l = sc->cycling_items; l != NULL; l = g_list_next(l)) { arenaitem = SP_ITEM(l->data)->get_arenaitem(desktop->dkey); - nr_arena_item_set_opacity (arenaitem, 1.0); + arenaitem->setOpacity(1.0); } g_list_free(sc->cycling_items); g_list_free(sc->cycling_items_selected_before); diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 48e466628..14c206828 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -16,7 +16,7 @@ #include <string> #include "display/nr-arena.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "xml/repr.h" #include "enums.h" @@ -24,6 +24,7 @@ #include "document.h" #include "document-private.h" #include "sp-item.h" +#include "style.h" #include <2geom/transforms.h> @@ -32,11 +33,11 @@ struct SPClipPathView { SPClipPathView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; -SPClipPathView *sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, NRArenaItem *arenaitem); +SPClipPathView *sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::DrawingItem *arenaitem); SPClipPathView *sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view); SPObjectGroupClass * SPClipPathClass::static_parent_class = 0; @@ -155,11 +156,11 @@ void SPClipPath::childAdded(SPObject *object, Inkscape::XML::Node *child, Inksca if (SP_IS_ITEM(ochild)) { SPClipPath *cp = SP_CLIPPATH(object); for (SPClipPathView *v = cp->display; v != NULL; v = v->next) { - NRArenaItem *ac = SP_ITEM(ochild)->invoke_show( NR_ARENA_ITEM_ARENA(v->arenaitem), + Inkscape::DrawingItem *ac = SP_ITEM(ochild)->invoke_show( v->arenaitem->drawing(), v->key, SP_ITEM_REFERENCE_FLAGS); if (ac) { - nr_arena_item_add_child(v->arenaitem, ac, NULL); + v->arenaitem->prependChild(ac); } } } @@ -191,13 +192,14 @@ void SPClipPath::update(SPObject *object, SPCtx *ctx, guint flags) SPClipPath *cp = SP_CLIPPATH(object); for (SPClipPathView *v = cp->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { Geom::Affine t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); t[4] = v->bbox.x0; t[5] = v->bbox.y0; - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), &t); + g->setChildTransform(t); } else { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), NULL); + g->setChildTransform(Geom::identity()); } } } @@ -240,20 +242,20 @@ Inkscape::XML::Node *SPClipPath::write(SPObject *object, Inkscape::XML::Document return repr; } -NRArenaItem *SPClipPath::show(NRArena *arena, unsigned int key) +Inkscape::DrawingItem *SPClipPath::show(NRArena *arena, unsigned int key) { g_return_val_if_fail(arena != NULL, NULL); g_return_val_if_fail(NR_IS_ARENA(arena), NULL); - NRArenaItem *ai = NRArenaGroup::create(arena); + Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(arena); display = sp_clippath_view_new_prepend(display, key, ai); for ( SPObject *child = firstChild() ; child ; child = child->getNext() ) { if (SP_IS_ITEM(child)) { - NRArenaItem *ac = SP_ITEM(child)->invoke_show(arena, key, SP_ITEM_REFERENCE_FLAGS); + Inkscape::DrawingItem *ac = SP_ITEM(child)->invoke_show(arena, key, SP_ITEM_REFERENCE_FLAGS); if (ac) { /* The order is not important in clippath */ - nr_arena_item_add_child(ai, ac, NULL); + ai->appendChild(ac); } } } @@ -262,9 +264,9 @@ NRArenaItem *SPClipPath::show(NRArena *arena, unsigned int key) Geom::Affine t(Geom::Scale(display->bbox.x1 - display->bbox.x0, display->bbox.y1 - display->bbox.y0)); t[4] = display->bbox.x0; t[5] = display->bbox.y0; - nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), &t); + ai->setChildTransform(t); } - nr_arena_group_set_style(NR_ARENA_GROUP(ai), this->style); + ai->setStyle(this->style); return ai; } @@ -329,13 +331,13 @@ void SPClipPath::getBBox(NRRect *bbox, Geom::Affine const &transform, unsigned c /* ClipPath views */ SPClipPathView * -sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, NRArenaItem *arenaitem) +sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::DrawingItem *arenaitem) { SPClipPathView *new_path_view = g_new(SPClipPathView, 1); new_path_view->next = list; new_path_view->key = key; - new_path_view->arenaitem = nr_arena_item_ref(arenaitem); + new_path_view->arenaitem = arenaitem; new_path_view->bbox.x0 = new_path_view->bbox.x1 = 0.0; new_path_view->bbox.y0 = new_path_view->bbox.y1 = 0.0; @@ -354,7 +356,7 @@ sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view) prev->next = view->next; } - nr_arena_item_unref(view->arenaitem); + delete view->arenaitem; g_free(view); return list; diff --git a/src/sp-clippath.h b/src/sp-clippath.h index d3c650ca6..d163e0709 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -23,7 +23,7 @@ class SPClipPathView; -#include "display/nr-arena-forward.h" +#include "display/display-forward.h" #include "libnr/nr-forward.h" #include "sp-object-group.h" #include "uri-references.h" @@ -40,7 +40,7 @@ public: static const gchar *create(GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform); static GType sp_clippath_get_type(void); - NRArenaItem *show(NRArena *arena, unsigned int key); + Inkscape::DrawingItem *show(NRArena *arena, unsigned int key); void hide(unsigned int key); void setBBox(unsigned int key, NRRect *bbox); diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 87266464c..cbdc8684b 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -31,7 +31,7 @@ #include "livarot/Shape.h" -#include "display/nr-arena-glyphs.h" +#include "display/drawing-text.h" static void sp_flowtext_class_init(SPFlowtextClass *klass); @@ -50,7 +50,7 @@ static void sp_flowtext_bbox(SPItem const *item, NRRect *bbox, Geom::Affine cons static void sp_flowtext_print(SPItem *item, SPPrintContext *ctx); static gchar *sp_flowtext_description(SPItem *item); static void sp_flowtext_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); -static NRArenaItem *sp_flowtext_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags); +static Inkscape::DrawingItem *sp_flowtext_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags); static void sp_flowtext_hide(SPItem *item, unsigned key); static SPItemClass *parent_class; @@ -179,10 +179,11 @@ static void sp_flowtext_update(SPObject *object, SPCtx *ctx, unsigned flags) NRRect paintbox; group->invoke_bbox( &paintbox, Geom::identity(), TRUE); for (SPItemView *v = group->display; v != NULL; v = v->next) { - group->_clearFlow(NR_ARENA_GROUP(v->arenaitem)); - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + group->_clearFlow(g); + g->setStyle(object->style); // pass the bbox of the flowtext object as paintbox (used for paintserver fills) - group->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox); + group->layout.show(g, &paintbox); } } @@ -200,9 +201,10 @@ static void sp_flowtext_modified(SPObject *object, guint flags) NRRect paintbox; text->invoke_bbox( &paintbox, Geom::identity(), TRUE); for (SPItemView* v = text->display; v != NULL; v = v->next) { - text->_clearFlow(NR_ARENA_GROUP(v->arenaitem)); - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); - text->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + text->_clearFlow(g); + g->setStyle(object->style); + text->layout.show(g, &paintbox); } } @@ -406,14 +408,13 @@ static void sp_flowtext_snappoints(SPItem const *item, std::vector<Inkscape::Sna } } -static NRArenaItem * +static Inkscape::DrawingItem * sp_flowtext_show(SPItem *item, NRArena *arena, unsigned/* key*/, unsigned /*flags*/) { SPFlowtext *group = (SPFlowtext *) item; - NRArenaGroup *flowed = NRArenaGroup::create(arena); - nr_arena_group_set_transparent(flowed, FALSE); - - nr_arena_group_set_style(flowed, group->style); + Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(arena); + flowed->setPickChildren(false); + flowed->setStyle(group->style); // pass the bbox of the flowtext object as paintbox (used for paintserver fills) NRRect paintbox; @@ -541,17 +542,9 @@ void SPFlowtext::rebuildLayout() //g_print(layout.dumpAsText().c_str()); } -void SPFlowtext::_clearFlow(NRArenaGroup *in_arena) +void SPFlowtext::_clearFlow(Inkscape::DrawingGroup *in_arena) { - nr_arena_item_request_render(NR_ARENA_ITEM(in_arena)); - for (NRArenaItem *child = in_arena->children; child != NULL; ) { - NRArenaItem *nchild = child->next; - - nr_arena_glyphs_group_clear(NR_ARENA_GLYPHS_GROUP(child)); - nr_arena_item_remove_child(NR_ARENA_ITEM(in_arena), child); - - child = nchild; - } + in_arena->clearChildren(); } Inkscape::XML::Node *SPFlowtext::getAsText() diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h index 3b0ce178a..d06105c30 100644 --- a/src/sp-flowtext.h +++ b/src/sp-flowtext.h @@ -6,7 +6,7 @@ #include "sp-item.h" -#include "display/nr-arena-forward.h" +#include "display/display-forward.h" #include <2geom/forward.h> #include "libnrtype/Layout-TNG.h" @@ -32,7 +32,7 @@ struct SPFlowtext : public SPItem { Inkscape::Text::Layout layout; /** discards the NRArena objects representing this text. */ - void _clearFlow(NRArenaGroup* in_arena); + void _clearFlow(Inkscape::DrawingGroup* in_arena); double par_indent; diff --git a/src/sp-image.cpp b/src/sp-image.cpp index c9647c939..3a1280aa0 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -28,7 +28,7 @@ #include <2geom/transforms.h> #include <glibmm/i18n.h> -#include "display/nr-arena-image.h" +#include "display/drawing-image.h" #include "display/cairo-utils.h" #include "display/curve.h" //Added for preserveAspectRatio support -- EAF @@ -84,14 +84,14 @@ static void sp_image_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const & static void sp_image_print (SPItem * item, SPPrintContext *ctx); static gchar * sp_image_description (SPItem * item); static void sp_image_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); -static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static Inkscape::DrawingItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static Geom::Affine sp_image_set_transform (SPItem *item, Geom::Affine const &xform); static void sp_image_set_curve(SPImage *image); static GdkPixbuf *sp_image_repr_read_image( time_t& modTime, gchar*& pixPath, const gchar *href, const gchar *absref, const gchar *base ); static GdkPixbuf *sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf); -static void sp_image_update_arenaitem (SPImage *img, NRArenaImage *ai); +static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai); static void sp_image_update_canvas_image (SPImage *image); static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); static GdkPixbuf * sp_image_repr_read_b64 (const gchar * uri_data); @@ -1018,7 +1018,8 @@ static void sp_image_modified( SPObject *object, unsigned int flags ) if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = image->display; v != NULL; v = v->next) { - nr_arena_image_set_style (NR_ARENA_IMAGE (v->arenaitem), object->style); + Inkscape::DrawingImage *img = dynamic_cast<Inkscape::DrawingImage *>(v->arenaitem); + img->setStyle(object->style); } } } @@ -1148,12 +1149,12 @@ static gchar *sp_image_description( SPItem *item ) return ret; } -static NRArenaItem *sp_image_show( SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int /*flags*/ ) +static Inkscape::DrawingItem *sp_image_show( SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int /*flags*/ ) { SPImage * image = SP_IMAGE(item); - NRArenaItem *ai = NRArenaImage::create(arena); + Inkscape::DrawingImage *ai = new Inkscape::DrawingImage(arena); - sp_image_update_arenaitem(image, NR_ARENA_IMAGE(ai)); + sp_image_update_arenaitem(image, ai); return ai; } @@ -1264,13 +1265,13 @@ static GdkPixbuf *sp_image_pixbuf_force_rgba( GdkPixbuf * pixbuf ) /* We assert that realpixbuf is either NULL or identical size to pixbuf */ static void -sp_image_update_arenaitem (SPImage *image, NRArenaImage *ai) +sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai) { - nr_arena_image_set_style(ai, SP_OBJECT(image)->style); - nr_arena_image_set_argb32_pixbuf(ai, image->pixbuf); - nr_arena_image_set_origin(ai, Geom::Point(image->ox, image->oy)); - nr_arena_image_set_scale(ai, image->sx, image->sy); - nr_arena_image_set_clipbox(ai, image->clipbox); + ai->setStyle(SP_OBJECT(image)->style); + ai->setARGB32Pixbuf(image->pixbuf); + ai->setOrigin(Geom::Point(image->ox, image->oy)); + ai->setScale(image->sx, image->sy); + ai->setClipbox(image->clipbox); } static void sp_image_update_canvas_image(SPImage *image) @@ -1278,7 +1279,7 @@ static void sp_image_update_canvas_image(SPImage *image) SPItem *item = SP_ITEM(image); for (SPItemView *v = item->display; v != NULL; v = v->next) { - sp_image_update_arenaitem(image, NR_ARENA_IMAGE(v->arenaitem)); + sp_image_update_arenaitem(image, dynamic_cast<Inkscape::DrawingImage *>(v->arenaitem)); } } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 491b2a62a..c27319c83 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -22,7 +22,7 @@ #include <cstring> #include <string> -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "display/curve.h" #include "xml/repr.h" #include "svg/svg.h" @@ -68,7 +68,7 @@ static void sp_group_set(SPObject *object, unsigned key, char const *value); static void sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags); static void sp_group_print (SPItem * item, SPPrintContext *ctx); static gchar * sp_group_description (SPItem * item); -static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static Inkscape::DrawingItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_group_hide (SPItem * item, unsigned int key); static void sp_group_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); @@ -312,7 +312,7 @@ static void sp_group_set(SPObject *object, unsigned key, char const *value) { } } -static NRArenaItem * +static Inkscape::DrawingItem * sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) { return SP_GROUP(item)->group->show(arena, key, flags); @@ -562,9 +562,9 @@ void SPGroup::_updateLayerMode(unsigned int display_key) { SPItemView *view; for ( view = this->display ; view ; view = view->next ) { if ( !display_key || view->key == display_key ) { - NRArenaGroup *arena_group=NR_ARENA_GROUP(view->arenaitem); - if (arena_group) { - nr_arena_group_set_transparent(arena_group, effectiveLayerMode(view->key) == SPGroup::LAYER); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(view->arenaitem); + if (g) { + g->setPickChildren(effectiveLayerMode(view->key) == SPGroup::LAYER); } } } @@ -596,13 +596,13 @@ void CGroup::onChildAdded(Inkscape::XML::Node *child) { if ( SP_IS_ITEM(ochild) ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; - NRArenaItem *ac; + Inkscape::DrawingItem *ac; for (v = _group->display; v != NULL; v = v->next) { - ac = SP_ITEM (ochild)->invoke_show (NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags); + ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { - nr_arena_item_append_child (v->arenaitem, ac); + v->arenaitem->appendChild(ac); } } } @@ -611,16 +611,16 @@ void CGroup::onChildAdded(Inkscape::XML::Node *child) { if ( ochild && SP_IS_ITEM(ochild) ) { /* TODO: this should be moved into SPItem somehow */ SPItemView *v; - NRArenaItem *ac; + Inkscape::DrawingItem *ac; unsigned position = SP_ITEM(ochild)->pos_in_parent(); for (v = _group->display; v != NULL; v = v->next) { - ac = SP_ITEM (ochild)->invoke_show (NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags); + ac = SP_ITEM (ochild)->invoke_show (v->arenaitem->drawing(), v->key, v->flags); if (ac) { - nr_arena_item_add_child (v->arenaitem, ac, NULL); - nr_arena_item_set_order (ac, position); + v->arenaitem->prependChild(ac); + ac->setZOrder(position); } } } @@ -646,10 +646,11 @@ void CGroup::onUpdate(SPCtx *ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - SPObject *object = _group; - for (SPItemView *v = _group->display; v != NULL; v = v->next) { - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); - } + SPObject *object = _group; + for (SPItemView *v = _group->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + group->setStyle(object->style); + } } GSList *l = g_slist_reverse(_group->childList(true, SPObject::ActionUpdate)); @@ -677,10 +678,11 @@ void CGroup::onModified(guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - SPObject *object = _group; - for (SPItemView *v = _group->display; v != NULL; v = v->next) { - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); - } + SPObject *object = _group; + for (SPItemView *v = _group->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + group->setStyle(object->style); + } } GSList *l = g_slist_reverse(_group->childList(true)); @@ -742,24 +744,20 @@ gchar *CGroup::getDescription() { len), len); } -NRArenaItem *CGroup::show (NRArena *arena, unsigned int key, unsigned int flags) { - NRArenaItem *ai; +Inkscape::DrawingItem *CGroup::show (NRArena *arena, unsigned int key, unsigned int flags) { + Inkscape::DrawingGroup *ai; SPObject *object = _group; - ai = NRArenaGroup::create(arena); - - nr_arena_group_set_transparent(NR_ARENA_GROUP (ai), - _group->effectiveLayerMode(key) == - SPGroup::LAYER); - nr_arena_group_set_style(NR_ARENA_GROUP(ai), object->style); + ai = new Inkscape::DrawingGroup(arena); + ai->setPickChildren(_group->effectiveLayerMode(key) == SPGroup::LAYER); + ai->setStyle(object->style); _showChildren(arena, ai, key, flags); return ai; } -void CGroup::_showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, unsigned int flags) { - NRArenaItem *ac = NULL; - NRArenaItem *ar = NULL; +void CGroup::_showChildren (NRArena *arena, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) { + Inkscape::DrawingItem *ac = NULL; SPItem * child = NULL; GSList *l = g_slist_reverse(_group->childList(false, SPObject::ActionShow)); while (l) { @@ -767,10 +765,7 @@ void CGroup::_showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, u if (SP_IS_ITEM (o)) { child = SP_ITEM (o); ac = child->invoke_show (arena, key, flags); - if (ac) { - nr_arena_item_add_child (ai, ac, ar); - ar = ac; - } + ai->appendChild(ac); } l = g_slist_remove (l, o); } @@ -801,7 +796,7 @@ void CGroup::onOrderChanged (Inkscape::XML::Node *child, Inkscape::XML::Node *, SPItemView *v; unsigned position = SP_ITEM(ochild)->pos_in_parent(); for ( v = SP_ITEM (ochild)->display ; v != NULL ; v = v->next ) { - nr_arena_item_set_order (v->arenaitem, position); + v->arenaitem->setZOrder(position); } } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index e2aeb8bc5..88586a6b0 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -73,13 +73,13 @@ public: virtual void onPrint(SPPrintContext *ctx); virtual void onOrderChanged(Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref); virtual gchar *getDescription(); - virtual NRArenaItem *show (NRArena *arena, unsigned int key, unsigned int flags); + virtual Inkscape::DrawingItem *show (NRArena *arena, unsigned int key, unsigned int flags); virtual void hide (unsigned int key); gint getItemCount(); protected: - virtual void _showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, unsigned int flags); + virtual void _showChildren (NRArena *arena, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags); SPGroup *_group; }; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 946c94353..9ab924423 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -30,7 +30,7 @@ #include "svg/svg.h" #include "print.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" +#include "display/drawing-item.h" #include "attributes.h" #include "document.h" #include "uri.h" @@ -145,14 +145,10 @@ void SPItem::init() { display = NULL; clip_ref = new SPClipPathReference(this); - sigc::signal<void, SPObject *, SPObject *> cs1 = clip_ref->changedSignal(); - sigc::slot2<void,SPObject*, SPObject *> sl1 = sigc::bind(sigc::ptr_fun(clip_ref_changed), this); - _clip_ref_connection = cs1.connect(sl1); + clip_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(clip_ref_changed), this)); mask_ref = new SPMaskReference(this); - sigc::signal<void, SPObject *, SPObject *> cs2 = mask_ref->changedSignal(); - sigc::slot2<void,SPObject*, SPObject *> sl2=sigc::bind(sigc::ptr_fun(mask_ref_changed), this); - _mask_ref_connection = cs2.connect(sl2); + mask_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(mask_ref_changed), this)); avoidRef = new SPAvoidRef(this); @@ -204,10 +200,10 @@ bool SPItem::isHidden(unsigned display_key) const { for ( SPItemView *view(display) ; view ; view = view->next ) { if ( view->key == display_key ) { g_assert(view->arenaitem != NULL); - for ( NRArenaItem *arenaitem = view->arenaitem ; - arenaitem ; arenaitem = arenaitem->parent ) + for ( Inkscape::DrawingItem *arenaitem = view->arenaitem ; + arenaitem ; arenaitem = arenaitem->parent() ) { - if (!arenaitem->visible) { + if (!arenaitem->visible()) { return true; } } @@ -394,35 +390,22 @@ void SPItem::sp_item_release(SPObject *object) { SPItem *item = (SPItem *) object; - item->_clip_ref_connection.disconnect(); - item->_mask_ref_connection.disconnect(); - // Note: do this here before the clip_ref is deleted, since calling // ensureUpToDate() for triggered routing may reference // the deleted clip_ref. - if (item->avoidRef) { - delete item->avoidRef; - item->avoidRef = NULL; - } - - if (item->clip_ref) { - item->clip_ref->detach(); - delete item->clip_ref; - item->clip_ref = NULL; - } + delete item->avoidRef; - if (item->mask_ref) { - item->mask_ref->detach(); - delete item->mask_ref; - item->mask_ref = NULL; - } + // we do NOT disconnect from the changed signal of those before deletion. + // The destructor will call *_ref_changed with NULL as the new value, + // which will cause the hide() function to be called. + delete item->clip_ref; + delete item->mask_ref; if (((SPObjectClass *) (SPItemClass::static_parent_class))->release) { ((SPObjectClass *) SPItemClass::static_parent_class)->release(object); } while (item->display) { - nr_arena_item_unparent(item->display->arenaitem); item->display = sp_item_view_list_remove(item->display, item->display); } @@ -478,7 +461,7 @@ void SPItem::sp_item_set(SPObject *object, unsigned key, gchar const *value) case SP_ATTR_SODIPODI_INSENSITIVE: item->sensitive = !value; for (SPItemView *v = item->display; v != NULL; v = v->next) { - nr_arena_item_set_sensitive(v->arenaitem, item->sensitive); + v->arenaitem->setSensitive(item->sensitive); } break; case SP_ATTR_CONNECTOR_AVOID: @@ -529,23 +512,22 @@ void SPItem::clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item) SPItemView *v; /* Hide clippath */ for (v = item->display; v != NULL; v = v->next) { - SP_CLIPPATH(old_clip)->hide(NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_clip(v->arenaitem, NULL); + SP_CLIPPATH(old_clip)->hide(v->arenaitem->key()); + v->arenaitem->setClip(NULL); } } if (SP_IS_CLIPPATH(clip)) { NRRect bbox; item->invoke_bbox( &bbox, Geom::identity(), TRUE); for (SPItemView *v = item->display; v != NULL; v = v->next) { - if (!v->arenaitem->key) { - NR_ARENA_ITEM_SET_KEY(v->arenaitem, SPItem::display_key_new(3)); + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); } - NRArenaItem *ai = SP_CLIPPATH(clip)->show( - NR_ARENA_ITEM_ARENA(v->arenaitem), - NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_clip(v->arenaitem, ai); - nr_arena_item_unref(ai); - SP_CLIPPATH(clip)->setBBox(NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + Inkscape::DrawingItem *ai = SP_CLIPPATH(clip)->show( + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setClip(ai); + SP_CLIPPATH(clip)->setBBox(v->arenaitem->key(), &bbox); clip->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -556,23 +538,22 @@ void SPItem::mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item) if (old_mask) { /* Hide mask */ for (SPItemView *v = item->display; v != NULL; v = v->next) { - sp_mask_hide(SP_MASK(old_mask), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_mask(v->arenaitem, NULL); + sp_mask_hide(SP_MASK(old_mask), v->arenaitem->key()); + v->arenaitem->setMask(NULL); } } if (SP_IS_MASK(mask)) { NRRect bbox; item->invoke_bbox( &bbox, Geom::identity(), TRUE); for (SPItemView *v = item->display; v != NULL; v = v->next) { - if (!v->arenaitem->key) { - NR_ARENA_ITEM_SET_KEY(v->arenaitem, SPItem::display_key_new(3)); + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new(3)); } - NRArenaItem *ai = sp_mask_show(SP_MASK(mask), - NR_ARENA_ITEM_ARENA(v->arenaitem), - NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_mask(v->arenaitem, ai); - nr_arena_item_unref(ai); - sp_mask_set_bbox(SP_MASK(mask), NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + Inkscape::DrawingItem *ai = sp_mask_show(SP_MASK(mask), + v->arenaitem->drawing(), + v->arenaitem->key()); + v->arenaitem->setMask(ai); + sp_mask_set_bbox(SP_MASK(mask), v->arenaitem->key(), &bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -589,7 +570,7 @@ void SPItem::sp_item_update(SPObject *object, SPCtx *ctx, guint flags) if (flags & (SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { if (flags & SP_OBJECT_MODIFIED_FLAG) { for (SPItemView *v = item->display; v != NULL; v = v->next) { - nr_arena_item_set_transform(v->arenaitem, item->transform); + v->arenaitem->setTransform(item->transform); } } @@ -601,20 +582,20 @@ void SPItem::sp_item_update(SPObject *object, SPCtx *ctx, guint flags) item->invoke_bbox( &bbox, Geom::identity(), TRUE); if (clip_path) { for (SPItemView *v = item->display; v != NULL; v = v->next) { - clip_path->setBBox(NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + clip_path->setBBox(v->arenaitem->key(), &bbox); } } if (mask) { for (SPItemView *v = item->display; v != NULL; v = v->next) { - sp_mask_set_bbox(mask, NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + sp_mask_set_bbox(mask, v->arenaitem->key(), &bbox); } } } if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = item->display; v != NULL; v = v->next) { - nr_arena_item_set_opacity(v->arenaitem, SP_SCALE24_TO_FLOAT(object->style->opacity.value)); - nr_arena_item_set_visible(v->arenaitem, !item->isHidden()); + v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(object->style->opacity.value)); + v->arenaitem->setVisible(!item->isHidden()); } } } @@ -627,7 +608,7 @@ void SPItem::sp_item_update(SPObject *object, SPCtx *ctx, guint flags) SPItemView *itemview = item->display; do { if (itemview->arenaitem) - nr_arena_item_set_item_bbox(itemview->arenaitem, item_bbox); + itemview->arenaitem->setItemBounds(item_bbox); } while ( (itemview = itemview->next) ); } @@ -1036,34 +1017,33 @@ unsigned SPItem::display_key_new(unsigned numkeys) return dkey - numkeys; } -NRArenaItem *SPItem::invoke_show(NRArena *arena, unsigned key, unsigned flags) +Inkscape::DrawingItem *SPItem::invoke_show(NRArena *arena, unsigned key, unsigned flags) { g_assert(arena != NULL); g_assert(NR_IS_ARENA(arena)); - NRArenaItem *ai = NULL; + Inkscape::DrawingItem *ai = NULL; if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->show) { ai = ((SPItemClass *) G_OBJECT_GET_CLASS(this))->show(this, arena, key, flags); } if (ai != NULL) { display = sp_item_view_new_prepend(display, this, flags, key, ai); - nr_arena_item_set_transform(ai, transform); - nr_arena_item_set_opacity(ai, SP_SCALE24_TO_FLOAT(style->opacity.value)); - nr_arena_item_set_visible(ai, !isHidden()); - nr_arena_item_set_sensitive(ai, sensitive); + ai->setTransform(transform); + ai->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value)); + ai->setVisible(!isHidden()); + ai->setSensitive(sensitive); if (clip_ref->getObject()) { SPClipPath *cp = clip_ref->getObject(); - if (!display->arenaitem->key) { - NR_ARENA_ITEM_SET_KEY(display->arenaitem, display_key_new(3)); + if (!display->arenaitem->key()) { + display->arenaitem->setKey(display_key_new(3)); } - int clip_key = NR_ARENA_ITEM_GET_KEY(display->arenaitem); + int clip_key = display->arenaitem->key(); // Show and set clip - NRArenaItem *ac = cp->show(arena, clip_key); - nr_arena_item_set_clip(ai, ac); - nr_arena_item_unref(ac); + Inkscape::DrawingItem *ac = cp->show(arena, clip_key); + ai->setClip(ac); // Update bbox, in case the clip uses bbox units NRRect bbox; @@ -1074,15 +1054,14 @@ NRArenaItem *SPItem::invoke_show(NRArena *arena, unsigned key, unsigned flags) if (mask_ref->getObject()) { SPMask *mask = mask_ref->getObject(); - if (!display->arenaitem->key) { - NR_ARENA_ITEM_SET_KEY(display->arenaitem, display_key_new(3)); + if (!display->arenaitem->key()) { + display->arenaitem->setKey(display_key_new(3)); } - int mask_key = NR_ARENA_ITEM_GET_KEY(display->arenaitem); + int mask_key = display->arenaitem->key(); // Show and set mask - NRArenaItem *ac = sp_mask_show(mask, arena, mask_key); - nr_arena_item_set_mask(ai, ac); - nr_arena_item_unref(ac); + Inkscape::DrawingItem *ac = sp_mask_show(mask, arena, mask_key); + ai->setMask(ac); // Update bbox, in case the mask uses bbox units NRRect bbox; @@ -1090,10 +1069,10 @@ NRArenaItem *SPItem::invoke_show(NRArena *arena, unsigned key, unsigned flags) sp_mask_set_bbox(SP_MASK(mask), mask_key, &bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - NR_ARENA_ITEM_SET_DATA(ai, this); + ai->setData(this); Geom::OptRect item_bbox; invoke_bbox( item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); - nr_arena_item_set_item_bbox(ai, item_bbox); + ai->setItemBounds(item_bbox); } return ai; @@ -1111,20 +1090,19 @@ void SPItem::invoke_hide(unsigned key) SPItemView *next = v->next; if (v->key == key) { if (clip_ref->getObject()) { - (clip_ref->getObject())->hide(NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_clip(v->arenaitem, NULL); + (clip_ref->getObject())->hide(v->arenaitem->key()); + v->arenaitem->setClip(NULL); } if (mask_ref->getObject()) { - sp_mask_hide(mask_ref->getObject(), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); - nr_arena_item_set_mask(v->arenaitem, NULL); + sp_mask_hide(mask_ref->getObject(), v->arenaitem->key()); + v->arenaitem->setMask(NULL); } if (!ref) { display = v->next; } else { ref->next = v->next; } - nr_arena_item_unparent(v->arenaitem); - nr_arena_item_unref(v->arenaitem); + delete v->arenaitem; g_free(v); } else { ref = v; @@ -1501,27 +1479,27 @@ Geom::Affine SPItem::dt2i_affine() const /* Item views */ -SPItemView *SPItem::sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem) +SPItemView *SPItem::sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, Inkscape::DrawingItem *drawing_item) { g_assert(item != NULL); g_assert(SP_IS_ITEM(item)); - g_assert(arenaitem != NULL); - g_assert(NR_IS_ARENA_ITEM(arenaitem)); + g_assert(drawing_item != NULL); SPItemView *new_view = g_new(SPItemView, 1); new_view->next = list; new_view->flags = flags; new_view->key = key; - new_view->arenaitem = arenaitem; + new_view->arenaitem = drawing_item; return new_view; } SPItemView *SPItem::sp_item_view_list_remove(SPItemView *list, SPItemView *view) { + SPItemView *ret = list; if (view == list) { - list = list->next; + ret = list->next; } else { SPItemView *prev; prev = list; @@ -1529,17 +1507,17 @@ SPItemView *SPItem::sp_item_view_list_remove(SPItemView *list, SPItemView *view) prev->next = view->next; } - nr_arena_item_unref(view->arenaitem); + delete view->arenaitem; g_free(view); - return list; + return ret; } /** * Return the arenaitem corresponding to the given item in the display * with the given key */ -NRArenaItem *SPItem::get_arenaitem(unsigned key) +Inkscape::DrawingItem *SPItem::get_arenaitem(unsigned key) { for ( SPItemView *iv = display ; iv ; iv = iv->next ) { if ( iv->key == key ) { diff --git a/src/sp-item.h b/src/sp-item.h index 0065a9c0e..f8cc948bb 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -20,7 +20,7 @@ */ #include <vector> -#include "display/nr-arena-forward.h" +#include "display/display-forward.h" #include "sp-object.h" #include <2geom/affine.h> #include <libnr/nr-rect.h> @@ -66,7 +66,7 @@ public: SPItemView *next; unsigned int flags; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; }; /* flags */ @@ -169,9 +169,6 @@ public: Geom::OptRect getBounds(Geom::Affine const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const; - sigc::connection _clip_ref_connection; - sigc::connection _mask_ref_connection; - sigc::connection connectTransformed(sigc::slot<void, Geom::Affine const *, SPItem *> slot) { return _transformed_signal.connect(slot); } @@ -184,7 +181,7 @@ public: gchar *description(); void invoke_print(SPPrintContext *ctx); static unsigned int display_key_new(unsigned int numkeys); - NRArenaItem *invoke_show(NRArena *arena, unsigned int key, unsigned int flags); + Inkscape::DrawingItem *invoke_show(NRArena *arena, unsigned int key, unsigned int flags); void invoke_hide(unsigned int key); void getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs=0) const; void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false); @@ -197,7 +194,7 @@ public: void set_item_transform(Geom::Affine const &transform_matrix); void convert_item_to_guides(); gint emitEvent (SPEvent &event); - NRArenaItem *get_arenaitem(unsigned int key); + Inkscape::DrawingItem *get_arenaitem(unsigned int key); void getBboxDesktop(NRRect *bbox, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); Geom::OptRect getBboxDesktop(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); Geom::Affine i2doc_affine() const; @@ -226,7 +223,7 @@ private: static gchar *sp_item_private_description(SPItem *item); static void sp_item_private_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); - static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem); + static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, Inkscape::DrawingItem *arenaitem); static SPItemView *sp_item_view_list_remove(SPItemView *list, SPItemView *view); static void clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item); static void mask_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item); @@ -249,7 +246,7 @@ public: /** Give short description of item (for status display) */ gchar * (* description) (SPItem * item); - NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); + Inkscape::DrawingItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); void (* hide) (SPItem *item, unsigned int key); /** Write to an iterator the points that should be considered for snapping diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 38599188f..f23be6fc5 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -16,7 +16,7 @@ #include <2geom/transforms.h> #include "display/nr-arena.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "xml/repr.h" #include "enums.h" @@ -30,7 +30,7 @@ struct SPMaskView { SPMaskView *next; unsigned int key; - NRArenaItem *arenaitem; + Inkscape::DrawingItem *arenaitem; NRRect bbox; }; @@ -45,7 +45,7 @@ static void sp_mask_update (SPObject *object, SPCtx *ctx, guint flags); static void sp_mask_modified (SPObject *object, guint flags); static Inkscape::XML::Node *sp_mask_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -SPMaskView *sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, NRArenaItem *arenaitem); +SPMaskView *sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, Inkscape::DrawingItem *arenaitem); SPMaskView *sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view); static SPObjectGroupClass *parent_class; @@ -179,11 +179,11 @@ sp_mask_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML if (SP_IS_ITEM (ochild)) { SPMask *cp = SP_MASK (object); for (SPMaskView *v = cp->display; v != NULL; v = v->next) { - NRArenaItem *ac = SP_ITEM (ochild)->invoke_show ( NR_ARENA_ITEM_ARENA (v->arenaitem), + Inkscape::DrawingItem *ac = SP_ITEM (ochild)->invoke_show ( v->arenaitem->drawing(), v->key, SP_ITEM_REFERENCE_FLAGS); if (ac) { - nr_arena_item_add_child (v->arenaitem, ac, NULL); + v->arenaitem->prependChild(ac); } } } @@ -215,13 +215,14 @@ static void sp_mask_update(SPObject *object, SPCtx *ctx, guint flags) SPMask *mask = SP_MASK(object); for (SPMaskView *v = mask->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { Geom::Affine t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); t[4] = v->bbox.x0; t[5] = v->bbox.y0; - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), &t); + g->setChildTransform(t); } else { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), NULL); + g->setChildTransform(Geom::identity()); } } } @@ -296,22 +297,21 @@ sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTr return mask_id; } -NRArenaItem *sp_mask_show(SPMask *mask, NRArena *arena, unsigned int key) +Inkscape::DrawingItem *sp_mask_show(SPMask *mask, NRArena *arena, unsigned int key) { g_return_val_if_fail (mask != NULL, NULL); g_return_val_if_fail (SP_IS_MASK (mask), NULL); g_return_val_if_fail (arena != NULL, NULL); g_return_val_if_fail (NR_IS_ARENA (arena), NULL); - NRArenaItem *ai = NRArenaGroup::create(arena); + Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(arena); mask->display = sp_mask_view_new_prepend (mask->display, key, ai); for ( SPObject *child = mask->firstChild() ; child; child = child->getNext() ) { if (SP_IS_ITEM (child)) { - NRArenaItem *ac = SP_ITEM (child)->invoke_show (arena, key, SP_ITEM_REFERENCE_FLAGS); + Inkscape::DrawingItem *ac = SP_ITEM (child)->invoke_show (arena, key, SP_ITEM_REFERENCE_FLAGS); if (ac) { - /* The order is not important in mask */ - nr_arena_item_add_child (ai, ac, NULL); + ai->prependChild(ac); } } } @@ -320,7 +320,7 @@ NRArenaItem *sp_mask_show(SPMask *mask, NRArena *arena, unsigned int key) Geom::Affine t(Geom::Scale(mask->display->bbox.x1 - mask->display->bbox.x0, mask->display->bbox.y1 - mask->display->bbox.y0)); t[4] = mask->display->bbox.x0; t[5] = mask->display->bbox.y0; - nr_arena_group_set_child_transform (NR_ARENA_GROUP (ai), &t); + ai->setChildTransform(t); } return ai; @@ -367,13 +367,13 @@ sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox) /* Mask views */ SPMaskView * -sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, NRArenaItem *arenaitem) +sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, Inkscape::DrawingItem *arenaitem) { SPMaskView *new_mask_view = g_new (SPMaskView, 1); new_mask_view->next = list; new_mask_view->key = key; - new_mask_view->arenaitem = nr_arena_item_ref(arenaitem); + new_mask_view->arenaitem = arenaitem; new_mask_view->bbox.x0 = new_mask_view->bbox.x1 = 0.0; new_mask_view->bbox.y0 = new_mask_view->bbox.y1 = 0.0; @@ -392,7 +392,7 @@ sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view) prev->next = view->next; } - nr_arena_item_unref (view->arenaitem); + delete view->arenaitem; g_free (view); return list; diff --git a/src/sp-mask.h b/src/sp-mask.h index 5a98ac8c5..e7a4723cf 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -23,7 +23,7 @@ class SPMask; class SPMaskClass; class SPMaskView; -#include "display/nr-arena-forward.h" +#include "display/display-forward.h" #include "libnr/nr-forward.h" #include "sp-object-group.h" #include "uri-references.h" @@ -90,7 +90,7 @@ protected: } }; -NRArenaItem *sp_mask_show (SPMask *mask, NRArena *arena, unsigned int key); +Inkscape::DrawingItem *sp_mask_show (SPMask *mask, NRArena *arena, unsigned int key); void sp_mask_hide (SPMask *mask, unsigned int key); void sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox); diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 3a3d01ebd..805a93267 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -25,10 +25,11 @@ #include "display/drawing-context.h" #include "display/drawing-surface.h" #include "display/nr-arena.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "attributes.h" #include "document-private.h" #include "uri.h" +#include "style.h" #include "sp-pattern.h" #include "xml/repr.h" #include "display/grayscale.h" @@ -632,15 +633,15 @@ sp_pattern_create_pattern(SPPaintServer *ps, /* Create arena */ NRArena *arena = NRArena::create(); unsigned int dkey = SPItem::display_key_new (1); - NRArenaGroup *root = NRArenaGroup::create(arena); + Inkscape::DrawingGroup *root = new Inkscape::DrawingGroup(arena); for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { // for each item in pattern, show it on our arena, add to the group, // and connect to the release signal in case the item gets deleted - NRArenaItem *cai; + Inkscape::DrawingItem *cai; cai = SP_ITEM(child)->invoke_show (arena, dkey, SP_ITEM_SHOW_DISPLAY); - nr_arena_item_append_child (root, cai); + root->appendChild(cai); } } @@ -689,17 +690,17 @@ sp_pattern_create_pattern(SPPaintServer *ps, } // TODO: make sure there are no leaks. - NRGC gc(NULL); - gc.transform = vb2ps; - nr_arena_item_invoke_update (root, Geom::IntRect::infinite(), &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); - nr_arena_item_invoke_render (ct, root, one_tile, 0); + Inkscape::UpdateContext ctx; + ctx.ctm = vb2ps; + root->update(Geom::IntRect::infinite(), ctx, Inkscape::DrawingItem::STATE_ALL, 0); + root->render(ct, one_tile, 0); for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { SP_ITEM(child)->invoke_hide(dkey); } } - nr_object_unref(root); nr_object_unref(arena); + delete root; if (needs_opacity) { ct.popGroupToSource(); // pop raw pattern diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 918bd3295..bbb12f5d3 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -22,7 +22,7 @@ #include <2geom/transforms.h> #include "svg/svg.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "attributes.h" #include "print.h" #include "document.h" @@ -46,7 +46,7 @@ static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags); static void sp_root_modified(SPObject *object, guint flags); static Inkscape::XML::Node *sp_root_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static NRArenaItem *sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static Inkscape::DrawingItem *sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_root_print(SPItem *item, SPPrintContext *ctx); static SPGroupClass *parent_class; @@ -540,7 +540,8 @@ static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags) /* As last step set additional transform of arena group */ for (SPItemView *v = root->display; v != NULL; v = v->next) { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), root->c2p); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + g->setChildTransform(root->c2p); } } @@ -609,16 +610,17 @@ sp_root_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: /** * Displays the SPRoot item on the NRArena. */ -static NRArenaItem * +static Inkscape::DrawingItem * sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) { SPRoot *root = SP_ROOT(item); - NRArenaItem *ai; + Inkscape::DrawingItem *ai; if (((SPItemClass *) (parent_class))->show) { ai = ((SPItemClass *) (parent_class))->show(item, arena, key, flags); if (ai) { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), root->c2p); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); + g->setChildTransform(root->c2p); } } else { ai = NULL; diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index beec860be..1512898f5 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -30,7 +30,7 @@ #include <sigc++/adaptors/bind.h> #include "macros.h" -#include "display/nr-arena-shape.h" +#include "display/drawing-shape.h" #include "display/curve.h" #include "print.h" #include "document.h" @@ -182,7 +182,7 @@ void SPShape::sp_shape_release(SPObject *object) for (i = 0; i < SP_MARKER_LOC_QTY; i++) { if (shape->marker[i]) { for (v = item->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) shape->marker[i], NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + sp_marker_hide ((SPMarker *) shape->marker[i], v->arenaitem->key() + i); } shape->release_connect[i].disconnect(); shape->modified_connect[i].disconnect(); @@ -247,7 +247,8 @@ void SPShape::sp_shape_update(SPObject *object, SPCtx *ctx, unsigned int flags) double const aw = 1.0 / ictx->i2vp.descrim(); style->stroke_width.computed = style->stroke_width.value * aw; for (SPItemView *v = ((SPItem *) (shape))->display; v != NULL; v = v->next) { - nr_arena_shape_set_style ((NRArenaShape *) v->arenaitem, style); + Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); + sh->setStyle(style); } } } @@ -257,12 +258,12 @@ void SPShape::sp_shape_update(SPObject *object, SPCtx *ctx, unsigned int flags) /* But on the other hand - how can we know that parent does not tie style and transform */ Geom::OptRect paintbox = SP_ITEM(object)->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); for (SPItemView *v = shape->display; v != NULL; v = v->next) { - NRArenaShape * const s = NR_ARENA_SHAPE(v->arenaitem); + Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); if (flags & SP_OBJECT_MODIFIED_FLAG) { - nr_arena_shape_set_path(s, shape->curve, (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)); + sh->setPath(shape->curve); } if (paintbox) { - s->setPaintBox(*paintbox); + sh->setPaintBox(*paintbox); } } } @@ -270,13 +271,13 @@ void SPShape::sp_shape_update(SPObject *object, SPCtx *ctx, unsigned int flags) if (shape->hasMarkers ()) { /* Dimension marker views */ for (SPItemView *v = shape->display; v != NULL; v = v->next) { - if (!v->arenaitem->key) { - NR_ARENA_ITEM_SET_KEY (v->arenaitem, SPItem::display_key_new (SP_MARKER_LOC_QTY)); + if (!v->arenaitem->key()) { + v->arenaitem->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); } for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { if (shape->marker[i]) { sp_marker_show_dimension ((SPMarker *) shape->marker[i], - NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i, + v->arenaitem->key() + i, shape->numberOfMarkers (i)); } } @@ -375,7 +376,7 @@ Geom::Affine sp_shape_marker_get_transform_at_end(Geom::Curve const & c) * * @todo figure out what to do when both 'marker' and for instance 'marker-end' are set. */ -void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) +void SPShape::sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) { SPStyle *style = ((SPObject *) shape)->style; @@ -395,7 +396,7 @@ void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START if ( shape->marker[i] ) { sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, - NR_ARENA_ITEM_GET_KEY(ai) + i, counter[i], m, + ai->key() + i, counter[i], m, style->stroke_width.computed); counter[i]++; } @@ -413,7 +414,7 @@ void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if ( shape->marker[i] ) { sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, - NR_ARENA_ITEM_GET_KEY(ai) + i, counter[i], m, + ai->key() + i, counter[i], m, style->stroke_width.computed); counter[i]++; } @@ -433,7 +434,7 @@ void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if (shape->marker[i]) { sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, - NR_ARENA_ITEM_GET_KEY(ai) + i, counter[i], m, + ai->key() + i, counter[i], m, style->stroke_width.computed); counter[i]++; } @@ -450,7 +451,7 @@ void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID if (shape->marker[i]) { sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, - NR_ARENA_ITEM_GET_KEY(ai) + i, counter[i], m, + ai->key() + i, counter[i], m, style->stroke_width.computed); counter[i]++; } @@ -474,7 +475,7 @@ void SPShape::sp_shape_update_marker_view(SPShape *shape, NRArenaItem *ai) for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END if (shape->marker[i]) { sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, - NR_ARENA_ITEM_GET_KEY(ai) + i, counter[i], m, + ai->key() + i, counter[i], m, style->stroke_width.computed); counter[i]++; } @@ -495,7 +496,8 @@ void SPShape::sp_shape_modified(SPObject *object, unsigned int flags) if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = shape->display; v != NULL; v = v->next) { - nr_arena_shape_set_style (NR_ARENA_SHAPE (v->arenaitem), object->style); + Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); + sh->setStyle(object->style); } } } @@ -850,15 +852,14 @@ sp_shape_print (SPItem *item, SPPrintContext *ctx) /** * Sets style, path, and paintbox. Updates marker views, including dimensions. */ -NRArenaItem * SPShape::sp_shape_show(SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int /*flags*/) +Inkscape::DrawingItem * SPShape::sp_shape_show(SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int /*flags*/) { SPObject *object = item; SPShape *shape = SP_SHAPE(item); - NRArenaItem *arenaitem = NRArenaShape::create(arena); - NRArenaShape * const s = NR_ARENA_SHAPE(arenaitem); - nr_arena_shape_set_style(s, object->style); - nr_arena_shape_set_path(s, shape->curve, false); + Inkscape::DrawingShape *s = new Inkscape::DrawingShape(arena); + s->setStyle(object->style); + s->setPath(shape->curve); Geom::OptRect paintbox = item->getBounds(Geom::identity()); if (paintbox) { s->setPaintBox(*paintbox); @@ -876,23 +877,23 @@ NRArenaItem * SPShape::sp_shape_show(SPItem *item, NRArena *arena, unsigned int if (shape->hasMarkers ()) { /* provide key and dimension the marker views */ - if (!arenaitem->key) { - NR_ARENA_ITEM_SET_KEY (arenaitem, SPItem::display_key_new (SP_MARKER_LOC_QTY)); + if (!s->key()) { + s->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); } for (int i = 0; i < SP_MARKER_LOC_QTY; i++) { if (shape->marker[i]) { sp_marker_show_dimension ((SPMarker *) shape->marker[i], - NR_ARENA_ITEM_GET_KEY (arenaitem) + i, + s->key() + i, shape->numberOfMarkers (i)); } } /* Update marker views */ - sp_shape_update_marker_view (shape, arenaitem); + sp_shape_update_marker_view (shape, s); } - return arenaitem; + return s; } /** @@ -911,7 +912,7 @@ void SPShape::sp_shape_hide(SPItem *item, unsigned int key) for (v = item->display; v != NULL; v = v->next) { if (key == v->key) { sp_marker_hide ((SPMarker *) shape->marker[i], - NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + v->arenaitem->key() + i); } } } @@ -1013,9 +1014,9 @@ sp_shape_marker_release (SPObject *marker, SPShape *shape) SPItemView *v; /* Hide marker */ for (v = item->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) (shape->marker[i]), NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + sp_marker_hide ((SPMarker *) (shape->marker[i]), v->arenaitem->key() + i); /* fixme: Do we need explicit remove here? (Lauris) */ - /* nr_arena_item_set_mask (v->arenaitem, NULL); */ + /* v->arenaitem->setMask(NULL); */ } /* Detach marker */ shape->release_connect[i].disconnect(); @@ -1064,9 +1065,9 @@ sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value) /* Hide marker */ for (v = item->display; v != NULL; v = v->next) { sp_marker_hide ((SPMarker *) (shape->marker[key]), - NR_ARENA_ITEM_GET_KEY (v->arenaitem) + key); + v->arenaitem->key() + key); /* fixme: Do we need explicit remove here? (Lauris) */ - /* nr_arena_item_set_mask (v->arenaitem, NULL); */ + /* v->arenaitem->setMask(NULL); */ } /* Unref marker */ diff --git a/src/sp-shape.h b/src/sp-shape.h index b91850d1f..4da2d5a2d 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -67,11 +67,11 @@ private: static Inkscape::XML::Node *sp_shape_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags); - static NRArenaItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); + static Inkscape::DrawingItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_shape_hide (SPItem *item, unsigned int key); static void sp_shape_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); - static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai); + static void sp_shape_update_marker_view (SPShape *shape, Inkscape::DrawingItem *ai); diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index eb30f2644..bb1495387 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -19,7 +19,7 @@ #include <glibmm/i18n.h> #include "sp-switch.h" -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "conditions.h" #include <sigc++/functors/ptr_fun.h> @@ -157,20 +157,18 @@ void CSwitch::_releaseLastItem(SPObject *obj) _cached_item = NULL; } -void CSwitch::_showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, unsigned int flags) { +void CSwitch::_showChildren (NRArena *arena, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags) { SPObject *evaluated_child = _evaluateFirst(); - NRArenaItem *ar = NULL; GSList *l = _childList(false, SPObject::ActionShow); while (l) { SPObject *o = SP_OBJECT (l->data); if (SP_IS_ITEM (o)) { SPItem * child = SP_ITEM(o); child->setEvaluated(o == evaluated_child); - NRArenaItem *ac = child->invoke_show (arena, key, flags); + Inkscape::DrawingItem *ac = child->invoke_show (arena, key, flags); if (ac) { - nr_arena_item_add_child (ai, ac, ar); - ar = ac; + ai->appendChild(ac); } } l = g_slist_remove (l, o); diff --git a/src/sp-switch.h b/src/sp-switch.h index 310655a23..7b108947d 100644 --- a/src/sp-switch.h +++ b/src/sp-switch.h @@ -42,7 +42,7 @@ public: protected: virtual GSList *_childList(bool add_ref, SPObject::Action action); - virtual void _showChildren (NRArena *arena, NRArenaItem *ai, unsigned int key, unsigned int flags); + virtual void _showChildren (NRArena *arena, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags); SPObject *_evaluateFirst(); void _reevaluate(bool add_to_arena = false); diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index 91218c986..1f35a0ee1 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -19,7 +19,7 @@ #include <string> #include <2geom/transforms.h> -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "xml/repr.h" #include "attributes.h" #include "print.h" @@ -37,7 +37,7 @@ static void sp_symbol_update (SPObject *object, SPCtx *ctx, guint flags); static void sp_symbol_modified (SPObject *object, guint flags); static Inkscape::XML::Node *sp_symbol_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static NRArenaItem *sp_symbol_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static Inkscape::DrawingItem *sp_symbol_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_symbol_hide (SPItem *item, unsigned int key); static void sp_symbol_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags); static void sp_symbol_print (SPItem *item, SPPrintContext *ctx); @@ -327,7 +327,8 @@ static void sp_symbol_update(SPObject *object, SPCtx *ctx, guint flags) // As last step set additional transform of arena group for (SPItemView *v = symbol->display; v != NULL; v = v->next) { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), symbol->c2p); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + g->setChildTransform(symbol->c2p); } } else { // No-op @@ -367,17 +368,18 @@ static Inkscape::XML::Node *sp_symbol_write(SPObject *object, Inkscape::XML::Doc return repr; } -static NRArenaItem *sp_symbol_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +static Inkscape::DrawingItem *sp_symbol_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) { SPSymbol *symbol = SP_SYMBOL(item); - NRArenaItem *ai = 0; + Inkscape::DrawingItem *ai = 0; if (symbol->cloned) { // Cloned <symbol> is actually renderable if (((SPItemClass *) (parent_class))->show) { ai = ((SPItemClass *) (parent_class))->show (item, arena, key, flags); - if (ai) { - nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), symbol->c2p); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); + if (g) { + g->setChildTransform(symbol->c2p); } } } diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 89ca4ace4..ed848c646 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -35,7 +35,7 @@ #include <glibmm/i18n.h> #include "svg/svg.h" #include "svg/stringstream.h" -#include "display/nr-arena-glyphs.h" +#include "display/drawing-text.h" #include "attributes.h" #include "document.h" #include "desktop-handles.h" @@ -72,7 +72,7 @@ static void sp_text_modified (SPObject *object, guint flags); static Inkscape::XML::Node *sp_text_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); static void sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags); -static NRArenaItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, unsigned flags); +static Inkscape::DrawingItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, unsigned flags); static void sp_text_hide (SPItem *item, unsigned key); static char *sp_text_description (SPItem *item); static void sp_text_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); @@ -251,10 +251,11 @@ static void sp_text_update(SPObject *object, SPCtx *ctx, guint flags) NRRect paintbox; text->invoke_bbox( &paintbox, Geom::identity(), TRUE); for (SPItemView* v = text->display; v != NULL; v = v->next) { - text->_clearFlow(NR_ARENA_GROUP(v->arenaitem)); - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + text->_clearFlow(g); + g->setStyle(object->style); // pass the bbox of the text object as paintbox (used for paintserver fills) - text->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox); + text->layout.show(g, &paintbox); } } } @@ -270,8 +271,8 @@ static void sp_text_modified(SPObject *object, guint flags) cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - // FIXME: all that we need to do here is nr_arena_glyphs_[group_]set_style, to set the changed - // style, but there's no easy way to access the arena glyphs or glyph groups corresponding to a + // FIXME: all that we need to do here is to call setStyle, to set the changed + // style, but there's no easy way to access the drawing glyphs or texts corresponding to a // text object. Therefore we do here the same as in _update, that is, destroy all arena items // and create new ones. This is probably quite wasteful. if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) { @@ -279,9 +280,10 @@ static void sp_text_modified(SPObject *object, guint flags) NRRect paintbox; text->invoke_bbox( &paintbox, Geom::identity(), TRUE); for (SPItemView* v = text->display; v != NULL; v = v->next) { - text->_clearFlow(NR_ARENA_GROUP(v->arenaitem)); - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); - text->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + text->_clearFlow(g); + g->setStyle(object->style); + text->layout.show(g, &paintbox); } } @@ -383,15 +385,14 @@ sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, un } -static NRArenaItem * +static Inkscape::DrawingItem * sp_text_show(SPItem *item, NRArena *arena, unsigned /* key*/, unsigned /*flags*/) { SPText *group = (SPText *) item; - NRArenaGroup *flowed = NRArenaGroup::create(arena); - nr_arena_group_set_transparent (flowed, FALSE); - - nr_arena_group_set_style(flowed, group->style); + Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(arena); + flowed->setPickChildren(false); + flowed->setStyle(group->style); // pass the bbox of the text object as paintbox (used for paintserver fills) NRRect paintbox; @@ -662,17 +663,9 @@ void SPText::_adjustCoordsRecursive(SPItem *item, Geom::Affine const &m, double } -void SPText::_clearFlow(NRArenaGroup *in_arena) +void SPText::_clearFlow(Inkscape::DrawingGroup *in_arena) { - nr_arena_item_request_render (in_arena); - for (NRArenaItem *child = in_arena->children; child != NULL; ) { - NRArenaItem *nchild = child->next; - - nr_arena_glyphs_group_clear(NR_ARENA_GLYPHS_GROUP(child)); - nr_arena_item_remove_child (in_arena, child); - - child=nchild; - } + in_arena->clearChildren(); } diff --git a/src/sp-text.h b/src/sp-text.h index cd103aa2a..f865713c7 100644 --- a/src/sp-text.h +++ b/src/sp-text.h @@ -57,7 +57,7 @@ struct SPText : public SPItem { static void _adjustFontsizeRecursive(SPItem *item, double ex, bool is_root = true); /** discards the NRArena objects representing this text. */ - void _clearFlow(NRArenaGroup *in_arena); + void _clearFlow(Inkscape::DrawingGroup *in_arena); private: /** Recursively walks the xml tree adding tags and their contents. The diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index b301add7f..dcf46f6ac 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -32,7 +32,6 @@ #include "text-editing.h" #include "uri.h" -#include "display/nr-arena-group.h" #include "xml/node.h" #include "xml/repr.h" diff --git a/src/sp-use.cpp b/src/sp-use.cpp index a05b28a5f..2f83679de 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -22,7 +22,7 @@ #include <2geom/transforms.h> #include <glibmm/i18n.h> -#include "display/nr-arena-group.h" +#include "display/drawing-group.h" #include "attributes.h" #include "document.h" #include "sp-object-repr.h" @@ -53,7 +53,7 @@ static void sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &tr static void sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); static void sp_use_print(SPItem *item, SPPrintContext *ctx); static gchar *sp_use_description(SPItem *item); -static NRArenaItem *sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags); +static Inkscape::DrawingItem *sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags); static void sp_use_hide(SPItem *item, unsigned key); static void sp_use_href_changed(SPObject *old_ref, SPObject *ref, SPUse *use); @@ -346,23 +346,23 @@ sp_use_description(SPItem *item) } } -static NRArenaItem * +static Inkscape::DrawingItem * sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) { SPUse *use = SP_USE(item); - NRArenaItem *ai = NRArenaGroup::create(arena); - nr_arena_group_set_transparent(NR_ARENA_GROUP(ai), FALSE); - nr_arena_group_set_style(NR_ARENA_GROUP(ai), item->style); + Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(arena); + ai->setPickChildren(false); + ai->setStyle(item->style); if (use->child) { - NRArenaItem *ac = SP_ITEM(use->child)->invoke_show(arena, key, flags); + Inkscape::DrawingItem *ac = SP_ITEM(use->child)->invoke_show(arena, key, flags); if (ac) { - nr_arena_item_add_child(ai, ac, NULL); + ai->prependChild(ac); } Geom::Translate t(use->x.computed, use->y.computed); - nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), Geom::Affine(t)); + ai->setChildTransform(t); } return ai; @@ -540,10 +540,10 @@ sp_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPUse *use) (use->child)->invoke_build(use->document, childrepr, TRUE); for (SPItemView *v = item->display; v != NULL; v = v->next) { - NRArenaItem *ai; - ai = SP_ITEM(use->child)->invoke_show(NR_ARENA_ITEM_ARENA(v->arenaitem), v->key, v->flags); + Inkscape::DrawingItem *ai; + ai = SP_ITEM(use->child)->invoke_show(v->arenaitem->drawing(), v->key, v->flags); if (ai) { - nr_arena_item_add_child(v->arenaitem, ai, NULL); + v->arenaitem->prependChild(ai); } } @@ -592,7 +592,8 @@ sp_use_update(SPObject *object, SPCtx *ctx, unsigned flags) if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + g->setStyle(object->style); } } @@ -633,8 +634,9 @@ sp_use_update(SPObject *object, SPCtx *ctx, unsigned flags) /* As last step set additional transform of arena group */ for (SPItemView *v = item->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); Geom::Affine t(Geom::Translate(use->x.computed, use->y.computed)); - nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), t); + g->setChildTransform(t); } } @@ -650,7 +652,8 @@ sp_use_modified(SPObject *object, guint flags) if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { - nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), object->style); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + g->setStyle(object->style); } } diff --git a/src/svg-view.cpp b/src/svg-view.cpp index 2f1a20b82..3221ce146 100644 --- a/src/svg-view.cpp +++ b/src/svg-view.cpp @@ -15,6 +15,7 @@ #include <2geom/transforms.h> #include "display/canvas-arena.h" +#include "display/drawing-group.h" #include "document.h" #include "sp-item.h" #include "svg-view.h" @@ -129,13 +130,13 @@ SPSVGView::mouseout() */ /// \todo fixme. static gint -arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPSVGView *svgview) +arena_handler (SPCanvasArena */*arena*/, Inkscape::DrawingItem *ai, GdkEvent *event, SPSVGView *svgview) { static gdouble x, y; static gboolean active = FALSE; SPEvent spev; - SPItem *spitem = (ai) ? (SPItem*)NR_ARENA_ITEM_GET_DATA (ai) : 0; + SPItem *spitem = (ai) ? (SPItem*) ai->data() : 0; switch (event->type) { case GDK_BUTTON_PRESS: @@ -202,13 +203,13 @@ SPSVGView::setDocument (SPDocument *document) View::setDocument (document); if (document) { - NRArenaItem *ai = document->getRoot()->invoke_show( + Inkscape::DrawingItem *ai = document->getRoot()->invoke_show( SP_CANVAS_ARENA (_drawing)->arena, _dkey, SP_ITEM_SHOW_DISPLAY); if (ai) { - nr_arena_item_add_child (SP_CANVAS_ARENA (_drawing)->root, ai, NULL); + SP_CANVAS_ARENA (_drawing)->root->prependChild(ai); } doRescale (!_rescale); diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index ef75d8b23..7093ff683 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -12,8 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - - #include "trace/potrace/inkscape-potrace.h" #include "inkscape.h" @@ -32,22 +30,13 @@ #include <2geom/transforms.h> #include "display/nr-arena.h" -#include "display/nr-arena-shape.h" +#include "display/drawing-shape.h" #include "siox.h" #include "imagemap-gdk.h" - - -namespace Inkscape -{ - -namespace Trace -{ - - - - +namespace Inkscape { +namespace Trace { /** * Get the selected image. Also check for any SPItems over it, in @@ -247,12 +236,12 @@ Tracer::sioxProcessImage(SPImage *img, return Glib::RefPtr<Gdk::Pixbuf>(NULL); } - NRArenaItem *aImg = img->get_arenaitem(desktop->dkey); + Inkscape::DrawingItem *aImg = img->get_arenaitem(desktop->dkey); //g_message("img: %d %d %d %d\n", aImg->bbox.x0, aImg->bbox.y0, // aImg->bbox.x1, aImg->bbox.y1); - double width = aImg->bbox->width(); - double height = aImg->bbox->height(); + double width = aImg->geometricBounds()->width(); + double height = aImg->geometricBounds()->height(); double iwidth = simage.getWidth(); double iheight = simage.getHeight(); @@ -260,12 +249,12 @@ Tracer::sioxProcessImage(SPImage *img, double iwscale = width / iwidth; double ihscale = height / iheight; - std::vector<NRArenaItem *> arenaItems; + std::vector<Inkscape::DrawingItem *> arenaItems; std::vector<SPShape *>::iterator iter; for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++) { SPItem *item = *iter; - NRArenaItem *aItem = item->get_arenaitem(desktop->dkey); + Inkscape::DrawingItem *aItem = item->get_arenaitem(desktop->dkey); arenaItems.push_back(aItem); } @@ -278,25 +267,22 @@ Tracer::sioxProcessImage(SPImage *img, for (int row=0 ; row<iheight ; row++) { - double ypos = aImg->bbox->top() + ihscale * (double) row; + double ypos = aImg->geometricBounds()->top() + ihscale * (double) row; for (int col=0 ; col<simage.getWidth() ; col++) { //Get absolute X,Y position - double xpos = aImg->bbox->left() + iwscale * (double)col; + double xpos = aImg->geometricBounds()->left() + iwscale * (double)col; Geom::Point point(xpos, ypos); - if (aImg->transform) - point *= *aImg->transform; + point *= aImg->transform(); //point *= imgMat; //point = desktop->doc2dt(point); //g_message("x:%f y:%f\n", point[0], point[1]); bool weHaveAHit = false; - std::vector<NRArenaItem *>::iterator aIter; + std::vector<Inkscape::DrawingItem *>::iterator aIter; for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++) { - NRArenaItem *arenaItem = *aIter; - NRArenaItemClass *arenaClass = - (NRArenaItemClass *) NR_OBJECT_GET_CLASS (arenaItem); - if (arenaClass->pick(arenaItem, point, 1.0f, 1)) + Inkscape::DrawingItem *arenaItem = *aIter; + if (arenaItem->pick(point, 1.0f, 1)) { weHaveAHit = true; break; @@ -338,17 +324,6 @@ Tracer::sioxProcessImage(SPImage *img, //result.writePPM("siox2.ppm"); - /* Free Arena and ArenaItem */ - /* - std::vector<NRArenaItem *>::iterator aIter; - for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++) - { - NRArenaItem *arenaItem = *aIter; - nr_arena_item_unref(arenaItem); - } - nr_object_unref((NRObject *) arena); - */ - Glib::RefPtr<Gdk::Pixbuf> newPixbuf = Glib::wrap(result.getGdkPixbuf()); //g_message("siox: done"); diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index 67ec701cb..ae5355c58 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -29,23 +29,19 @@ #include "document-private.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" +#include "display/drawing-item.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "ui/cache/svg_preview_cache.h" -GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize) { - NRGC gc(NULL); - +GdkPixbuf* render_pixbuf(Inkscape::DrawingItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize) +{ Geom::Affine t(Geom::Scale(scale_factor, scale_factor)); - nr_arena_item_set_transform(root, t); - gc.transform.setIdentity(); + root->setTransform(Geom::Scale(scale_factor)); Geom::IntRect ibox = (dbox * Geom::Scale(scale_factor)).roundOutwards(); - nr_arena_item_invoke_update( root, ibox, &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + root->update(ibox); /* Find visible area */ int width = ibox.width(); @@ -63,8 +59,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rec CAIRO_FORMAT_ARGB32, psize, psize); Inkscape::DrawingContext ct(s, area.min()); - nr_arena_item_invoke_render(ct, root, area, - NR_ARENA_ITEM_RENDER_NO_CACHE ); + root->render(ct, area, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); cairo_surface_flush(s); GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(s), @@ -111,7 +106,7 @@ void SvgPreview::set_preview_in_cache(const Glib::ustring& key, GdkPixbuf* px) { _pixmap_cache[key] = px; } -GdkPixbuf* SvgPreview::get_preview(const gchar* uri, const gchar* id, NRArenaItem */*root*/, +GdkPixbuf* SvgPreview::get_preview(const gchar* uri, const gchar* id, Inkscape::DrawingItem */*root*/, double /*scale_factor*/, unsigned int psize) { // First try looking up the cached preview in the cache map Glib::ustring key = cache_key(uri, id, psize); diff --git a/src/ui/cache/svg_preview_cache.h b/src/ui/cache/svg_preview_cache.h index 0fac94782..b9fa6f627 100644 --- a/src/ui/cache/svg_preview_cache.h +++ b/src/ui/cache/svg_preview_cache.h @@ -1,17 +1,22 @@ -#ifndef __SVG_PREVIEW_CACHE_H__ -#define __SVG_PREVIEW_CACHE_H__ - -/** \file - * SPIcon: Generic icon widget +/** @file + * @brief Preview cache */ /* * Copyright (C) 2007 Bryce W. Harrington <bryce@bryceharrington.org> - * * Released under GNU GPL, read the file 'COPYING' for more information - * */ -GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize); +#ifndef SEEN_INKSCAPE_UI_SVG_PREVIEW_CACHE_H +#define SEEN_INKSCAPE_UI_SVG_PREVIEW_CACHE_H + +#include <map> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <glibmm/ustring.h> +#include <2geom/rect.h> + +#include "display/display-forward.h" + +GdkPixbuf* render_pixbuf(Inkscape::DrawingItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize); namespace Inkscape { namespace UI { @@ -28,7 +33,7 @@ class SvgPreview { Glib::ustring cache_key(gchar const *uri, gchar const *name, unsigned psize) const; GdkPixbuf* get_preview_from_cache(const Glib::ustring& key); void set_preview_in_cache(const Glib::ustring& key, GdkPixbuf* px); - GdkPixbuf* get_preview(const gchar* uri, const gchar* id, NRArenaItem *root, double scale_factor, unsigned int psize); + GdkPixbuf* get_preview(const gchar* uri, const gchar* id, Inkscape::DrawingItem *root, double scale_factor, unsigned int psize); }; }; // namespace Cache diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 38ec6d1be..a6d76eb13 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -38,7 +38,7 @@ extern "C" { // takes doc, root, icon, and icon name to produce pixels guchar * -sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, +sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, const gchar *name, unsigned int psize, unsigned &stride); } @@ -438,7 +438,7 @@ void IconPreviewPanel::renderPreview( SPObject* obj ) g_message("%s setting up to render '%s' as the icon", getTimestr().c_str(), id ); #endif // ICON_VERBOSE - NRArenaItem *root = NULL; + Inkscape::DrawingItem *root = NULL; /* Create new arena */ NRArena *arena = NRArena::create(); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 7958a9d07..af329f3fc 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -641,10 +641,10 @@ SPDesktopWidget::updateTitle(gchar const* uri) gchar const *colormodename = ""; gchar const *colormodenamecomma = ""; - if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_GRAYSCALE) { + if (this->desktop->getColorMode() == Inkscape::COLORMODE_GRAYSCALE) { colormodename = grayscalename; colormodenamecomma = grayscalenamecomma; - } else if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW) { + } else if (this->desktop->getColorMode() == Inkscape::COLORMODE_PRINT_COLORS_PREVIEW) { colormodename = printcolorsname; colormodenamecomma = printcolorsnamecomma; } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index c6823e2d8..fea825444 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -32,8 +32,8 @@ #include "sp-item.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" +#include "display/drawing-item.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "io/sys.h" #include "sp-root.h" @@ -1090,7 +1090,7 @@ static Geom::IntRect round_rect(Geom::Rect const &r) // takes doc, root, icon, and icon name to produce pixels extern "C" guchar * -sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, +sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, gchar const *name, unsigned psize, unsigned &stride) { @@ -1113,14 +1113,10 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, /* This is in document coordinates, i.e. pixels */ if ( dbox ) { - NRGC gc(NULL); /* Update to renderable state */ double sf = 1.0; - nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + root->setTransform(Geom::Scale(sf)); + root->update(); /* Item integer bbox in points */ // NOTE: previously, each rect coordinate was rounded using floor(c + 0.5) Geom::IntRect ibox = round_rect(*dbox); @@ -1145,11 +1141,8 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, } sf = (double)psize / (double)block; - nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + root->setTransform(Geom::Scale(sf)); + root->update(); ibox = round_rect(*dbox * Geom::Scale(sf)); if ( dump ) { @@ -1192,8 +1185,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, CAIRO_FORMAT_ARGB32, psize, psize, stride); Inkscape::DrawingContext ct(s, ua.min()); - nr_arena_item_invoke_render(ct, root, ua, - NR_ARENA_ITEM_RENDER_NO_CACHE ); + root->render(ct, ua, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); cairo_surface_destroy(s); // convert to GdkPixbuf format @@ -1214,9 +1206,9 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, class SVGDocCache { public: - SVGDocCache( SPDocument *doc, NRArenaItem *root ) : doc(doc), root(root) {} + SVGDocCache( SPDocument *doc, Inkscape::DrawingItem *root ) : doc(doc), root(root) {} SPDocument *doc; - NRArenaItem *root; + Inkscape::DrawingItem *root; }; static std::map<Glib::ustring, SVGDocCache *> doc_cache; @@ -1294,7 +1286,7 @@ guchar *IconImpl::load_svg_pixels(std::list<Glib::ustring> const &names, // fixme: Memory manage root if needed (Lauris) // This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days // because shapes are being rendered which are not being freed - NRArenaItem *root = doc->getRoot()->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + Inkscape::DrawingItem *root = doc->getRoot()->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); // store into the cache info = new SVGDocCache(doc, root); diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 8b5582163..4f6466ce8 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -28,8 +28,8 @@ #include "desktop-style.h" #include "dialogs/dialog-events.h" #include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* +#include "display/display-forward.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "document-private.h" #include "gradient-chemistry.h" #include "helper/stock-items.h" @@ -153,7 +153,8 @@ sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, static Gtk::Image * sp_marker_prev_new(unsigned psize, gchar const *mname, SPDocument *source, SPDocument *sandbox, - gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, NRArenaItem *root) + gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, + Inkscape::DrawingItem *root) { // Retrieve the marker named 'mname' from the source SVG document SPObject const *marker = source->getObjectById(mname); @@ -250,7 +251,7 @@ sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPD // Do this here, outside of loop, to speed up preview generation: NRArena const *arena = NRArena::create(); unsigned const visionkey = SPItem::display_key_new(1); - NRArenaItem *root = sandbox->getRoot()->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); + Inkscape::DrawingItem *root = sandbox->getRoot()->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(marker_list->data)->getRepr(); |
