diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-08-27 12:36:15 +0000 |
|---|---|---|
| committer | Krzysztof Kosinski <tweenk.pl@gmail.com> | 2011-08-27 12:36:15 +0000 |
| commit | ac0bc3b7583e5b45ed6ec97923170a77b5648d2e (patch) | |
| tree | c6d354ccc7edf1a6deefe7ca1de53ea1fefa01c0 /src | |
| parent | Remove NRRect use from the extension system (diff) | |
| download | inkscape-ac0bc3b7583e5b45ed6ec97923170a77b5648d2e.tar.gz inkscape-ac0bc3b7583e5b45ed6ec97923170a77b5648d2e.zip | |
Update 2Geom. Remove all use of NRRectL.
(bzr r10582.1.3)
Diffstat (limited to 'src')
54 files changed, 376 insertions, 700 deletions
diff --git a/src/2geom/affine.cpp b/src/2geom/affine.cpp index c31b9ba90..1be5d9fe8 100644 --- a/src/2geom/affine.cpp +++ b/src/2geom/affine.cpp @@ -144,6 +144,7 @@ bool Affine::isNonzeroTranslation(Coord eps) const { 0 & b & 0 \\ 0 & 0 & 1 \end{array}\right]\f$. */ bool Affine::isScale(Coord eps) const { + if (isSingular(eps)) return false; return are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps); } @@ -156,6 +157,7 @@ bool Affine::isScale(Coord eps) const { 0 & b & 0 \\ 0 & 0 & 1 \end{array}\right]\f$ and \f$a, b \neq 1\f$. */ bool Affine::isNonzeroScale(Coord eps) const { + if (isSingular(eps)) return false; return (!are_near(_c[0], 1.0, eps) || !are_near(_c[3], 1.0, eps)) && //NOTE: these are the diags, and the next line opposite diags are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps); @@ -165,11 +167,12 @@ bool Affine::isNonzeroScale(Coord eps) const { * @param eps Numerical tolerance * @return True iff the matrix is of the form * \f$\left[\begin{array}{ccc} - a & 0 & 0 \\ - 0 & a & 0 \\ - 0 & 0 & 1 \end{array}\right]\f$. */ + a_1 & 0 & 0 \\ + 0 & a_2 & 0 \\ + 0 & 0 & 1 \end{array}\right]\f$ where \f$|a_1| = |a_2|\f$. */ bool Affine::isUniformScale(Coord eps) const { - return are_near(_c[0], _c[3], eps) && + if (isSingular(eps)) return false; + return are_near(fabs(_c[0]), fabs(_c[3]), eps) && are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps); } @@ -178,11 +181,16 @@ bool Affine::isUniformScale(Coord eps) const { * @param eps Numerical tolerance * @return True iff the matrix is of the form * \f$\left[\begin{array}{ccc} - a & 0 & 0 \\ - 0 & a & 0 \\ - 0 & 0 & 1 \end{array}\right]\f$ and \f$a \neq 1\f$. */ + a_1 & 0 & 0 \\ + 0 & a_2 & 0 \\ + 0 & 0 & 1 \end{array}\right]\f$ where \f$|a_1| = |a_2|\f$ + * and \f$a_1, a_2 \neq 1\f$. */ bool Affine::isNonzeroUniformScale(Coord eps) const { - return !are_near(_c[0], 1.0, eps) && are_near(_c[0], _c[3], eps) && + if (isSingular(eps)) return false; + // we need to test both c0 and c3 to handle the case of flips, + // which should be treated as nonzero uniform scales + return !(are_near(_c[0], 1.0, eps) && are_near(_c[3], 1.0, eps)) && + are_near(fabs(_c[0]), fabs(_c[3]), eps) && are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps); } @@ -266,15 +274,17 @@ bool Affine::isNonzeroVShear(Coord eps) const { } /** @brief Check whether this matrix represents zooming. - * Zooming is any combination of translation and uniform scaling. It preserves angles, ratios - * of distances between arbitrary points and unit vectors of line segments. + * Zooming is any combination of translation and uniform non-flipping scaling. + * It preserves angles, ratios of distances between arbitrary points + * and unit vectors of line segments. * @param eps Numerical tolerance - * @return True iff the matrix is of the form + * @return True iff the matrix is invertible and of the form * \f$\left[\begin{array}{ccc} a & 0 & 0 \\ 0 & a & 0 \\ b & c & 1 \end{array}\right]\f$. */ bool Affine::isZoom(Coord eps) const { + if (isSingular(eps)) return false; return are_near(_c[0], _c[3], eps) && are_near(_c[1], 0, eps) && are_near(_c[2], 0, eps); } @@ -290,30 +300,42 @@ bool Affine::preservesArea(Coord eps) const } /** @brief Check whether the transformation preserves angles between lines. - * This means that the transformation can be any combination of translation, uniform scaling - * and rotation. + * This means that the transformation can be any combination of translation, uniform scaling, + * rotation and flipping. * @param eps Numerical tolerance * @return True iff the matrix is of the form * \f$\left[\begin{array}{ccc} - a & b & 0 \\ - -b & a & 0 \\ - c & d & 1 \end{array}\right]\f$. */ + a & b & 0 \\ + -b & a & 0 \\ + c & d & 1 \end{array}\right]\f$ or + \f$\left[\begin{array}{ccc} + -a & b & 0 \\ + b & a & 0 \\ + c & d & 1 \end{array}\right]\f$. */ bool Affine::preservesAngles(Coord eps) const { - return are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps); + if (isSingular(eps)) return false; + return (are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps)) || + (are_near(_c[0], -_c[3], eps) && are_near(_c[1], _c[2], eps)); } /** @brief Check whether the transformation preserves distances between points. - * This means that the transformation can be any combination of translation and rotation. + * This means that the transformation can be any combination of translation, + * rotation and flipping. * @param eps Numerical tolerance * @return True iff the matrix is of the form * \f$\left[\begin{array}{ccc} a & b & 0 \\ -b & a & 0 \\ + c & d & 1 \end{array}\right]\f$ or + \f$\left[\begin{array}{ccc} + -a & b & 0 \\ + b & a & 0 \\ c & d & 1 \end{array}\right]\f$ and \f$a^2 + b^2 = 1\f$. */ bool Affine::preservesDistances(Coord eps) const { - return are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps) && + return ((are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps)) || + (are_near(_c[0], -_c[3], eps) && are_near(_c[1], _c[2], eps))) && are_near(_c[0] * _c[0] + _c[1] * _c[1], 1.0, eps); } diff --git a/src/2geom/coord.h b/src/2geom/coord.h index 90e776665..78a852f32 100644 --- a/src/2geom/coord.h +++ b/src/2geom/coord.h @@ -75,18 +75,18 @@ struct CoordTraits<IntCoord> { typedef OptIntRect OptRectType; typedef - boost::equality_comparable< IntervalType - , boost::additive< IntervalType - , boost::additive< IntervalType, IntCoord - , boost::orable< IntervalType + boost::equality_comparable< IntInterval + , boost::additive< IntInterval + , boost::additive< IntInterval, IntCoord + , boost::orable< IntInterval > > > > IntervalOps; typedef - boost::equality_comparable< RectType - , boost::orable< RectType - , boost::orable< RectType, OptRectType - , boost::additive< RectType, PointType + boost::equality_comparable< IntRect + , boost::orable< IntRect + , boost::orable< IntRect, OptIntRect + , boost::additive< IntRect, IntPoint > > > > RectOps; }; @@ -100,21 +100,23 @@ struct CoordTraits<Coord> { typedef OptRect OptRectType; typedef - boost::equality_comparable< IntervalType - , boost::additive< IntervalType - , boost::multipliable< IntervalType - , boost::orable< IntervalType - , boost::arithmetic< IntervalType, Coord - > > > > > + boost::equality_comparable< Interval + , boost::equality_comparable< Interval, IntInterval + , boost::additive< Interval + , boost::multipliable< Interval + , boost::orable< Interval + , boost::arithmetic< Interval, Coord + > > > > > > IntervalOps; typedef - boost::equality_comparable< RectType - , boost::orable< RectType - , boost::orable< RectType, OptRectType - , boost::additive< RectType, PointType - , boost::multipliable< RectType, Affine - > > > > > + boost::equality_comparable< Rect + , boost::equality_comparable< Rect, IntRect + , boost::orable< Rect + , boost::orable< Rect, OptRect + , boost::additive< Rect, Point + , boost::multipliable< Rect, Affine + > > > > > > RectOps; }; diff --git a/src/2geom/forward.h b/src/2geom/forward.h index 0dbd9fa94..70cac1f7d 100644 --- a/src/2geom/forward.h +++ b/src/2geom/forward.h @@ -49,13 +49,13 @@ class Ray; template <typename> class GenericInterval; template <typename> class GenericOptInterval; class Interval; -typedef GenericOptInterval<Coord> OptInterval; +class OptInterval; typedef GenericInterval<IntCoord> IntInterval; typedef GenericOptInterval<IntCoord> OptIntInterval; template <typename> class GenericRect; template <typename> class GenericOptRect; class Rect; -typedef GenericOptRect<Coord> OptRect; +class OptRect; typedef GenericRect<IntCoord> IntRect; typedef GenericOptRect<IntCoord> OptIntRect; diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index 0212da676..87d3be2c1 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -49,6 +49,7 @@ template <typename C> class GenericInterval : CoordTraits<C>::IntervalOps { + typedef typename CoordTraits<C>::IntervalType CInterval; typedef GenericInterval<C> Self; protected: C _b[2]; @@ -76,15 +77,15 @@ public: * @param end End of the range * @return Interval that contains all values from [start, end). */ template <typename InputIterator> - static Self from_range(InputIterator start, InputIterator end) { + static CInterval from_range(InputIterator start, InputIterator end) { assert(start != end); - Self result(*start++); + CInterval result(*start++); for (; start != end; ++start) result.expandTo(*start); return result; } /** @brief Create an interval from a C-style array of values it should contain. */ - static Self from_array(C const *c, unsigned n) { - Self result = from_range(c, c+n); + static CInterval from_array(C const *c, unsigned n) { + CInterval result = from_range(c, c+n); return result; } /// @} @@ -94,7 +95,7 @@ public: C min() const { return _b[0]; } C max() const { return _b[1]; } C extent() const { return max() - min(); } - C middle() const { return (max() + min()) * 0.5; } + C middle() const { return (max() + min()) / 2; } bool isSingular() const { return min() == max(); } /// @} @@ -105,11 +106,11 @@ public: return min() <= val && val <= max(); } /** @brief Check whether the interval includes the given interval. */ - bool contains(Self const &val) const { + bool contains(CInterval const &val) const { return min() <= val.min() && val.max() <= max(); } /** @brief Check whether the intervals have any common elements. */ - bool intersects(Self const &val) const { + bool intersects(CInterval const &val) const { return contains(val.min()) || contains(val.max()) || val.contains(*this); } /// @} @@ -159,7 +160,7 @@ public: * The resulting interval will contain all points of both intervals. * It might also contain some points which didn't belong to either - this happens * when the intervals did not have any common elements. */ - void unionWith(Self const &a) { + void unionWith(CInterval const &a) { if(a._b[0] < _b[0]) _b[0] = a._b[0]; if(a._b[1] > _b[1]) _b[1] = a._b[1]; } @@ -187,7 +188,7 @@ public: /** @brief Add two intervals. * Sum is defined as the set of points that can be obtained by adding any two values * from both operands: \f$S = \{x \in A, y \in B: x + y\}\f$ */ - Self &operator+=(Self const &o) { + Self &operator+=(CInterval const &o) { _b[0] += o._b[0]; _b[1] += o._b[1]; return *this; @@ -196,7 +197,7 @@ public: * Difference is defined as the set of points that can be obtained by subtracting * any value from the second operand from any value from the first operand: * \f$S = \{x \in A, y \in B: x - y\}\f$ */ - Self &operator-=(Self const &o) { + Self &operator-=(CInterval const &o) { // equal to *this += -o _b[0] -= o._b[1]; _b[1] -= o._b[0]; @@ -205,12 +206,12 @@ public: /** @brief Union two intervals. * Note that the intersection-and-assignment operator is not defined, * because the result of an intersection can be empty, while Interval cannot. */ - Self &operator|=(Self const &o) { + Self &operator|=(CInterval const &o) { unionWith(o); return *this; } /** @brief Test for interval equality. */ - bool operator==(Self const &other) const { + bool operator==(CInterval const &other) const { return min() == other.min() && max() == other.max(); } /// @} @@ -230,15 +231,15 @@ inline GenericInterval<C> unify(GenericInterval<C> const &a, GenericInterval<C> template <typename C> class GenericOptInterval : public boost::optional<typename CoordTraits<C>::IntervalType> - , boost::orable< GenericOptInterval<C>, typename CoordTraits<C>::OptIntervalType - , boost::andable< GenericOptInterval<C>, typename CoordTraits<C>::OptIntervalType + , boost::orable< GenericOptInterval<C> + , boost::andable< GenericOptInterval<C> > > { typedef typename CoordTraits<C>::IntervalType CInterval; typedef typename CoordTraits<C>::OptIntervalType OptCInterval; typedef boost::optional<CInterval> Base; public: - /// @name Create optionally empty intervals of integers. + /// @name Create optionally empty intervals. /// @{ /** @brief Create an empty interval. */ GenericOptInterval() : Base() {} diff --git a/src/2geom/generic-rect.h b/src/2geom/generic-rect.h index efe499809..719b37385 100644 --- a/src/2geom/generic-rect.h +++ b/src/2geom/generic-rect.h @@ -135,10 +135,10 @@ public: /** @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()); } + CPoint min() const { CPoint p(f[X].min(), f[Y].min()); return p; } /** @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()); } + CPoint max() const { CPoint p(f[X].max(), f[Y].max()); return p; } /** @brief Return the n-th corner of the rectangle. * Returns corners in the direction of growing angles, starting from * the one given by min(). For the standard coordinate system used @@ -242,7 +242,15 @@ public: * half of the width, the X interval will contain only the X coordinate * of the midpoint; same for height. */ void expandBy(C amount) { - f[X].expandBy(amount); f[Y].expandBy(amount); + expandBy(amount, amount); + } + /** @brief Expand the rectangle in both directions. + * Note that this is different from scaling. Negative values wil shrink the + * rectangle. If <code>-x</code> is larger than + * half of the width, the X interval will contain only the X coordinate + * of the midpoint; same for height. */ + void expandBy(C x, C y) { + f[X].expandBy(x); f[Y].expandBy(y); } /** @brief Expand the rectangle by the coordinates of the given point. * This will expand the width by the X coordinate of the point in both directions @@ -250,8 +258,8 @@ public: * 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. */ - void expandBy(CPoint const &p) { - f[X].expandBy(p[X]); f[Y].expandBy(p[Y]); + void expandBy(CPoint const &p) { + expandBy(p[X], p[Y]); } /// @} @@ -279,7 +287,7 @@ public: return *this; } /** @brief Test for equality of rectangles. */ - bool operator==(GenericRect<C> const &o) const { return f[X] == o[X] && f[Y] == o[Y]; } + bool operator==(CRect const &o) const { return f[X] == o[X] && f[Y] == o[Y]; } /// @} }; @@ -290,10 +298,12 @@ public: template <typename C> class GenericOptRect : public boost::optional<typename CoordTraits<C>::RectType> + , boost::equality_comparable< typename CoordTraits<C>::OptRectType + , boost::equality_comparable< typename CoordTraits<C>::OptRectType, typename CoordTraits<C>::RectType , boost::orable< typename CoordTraits<C>::OptRectType , boost::andable< typename CoordTraits<C>::OptRectType , boost::andable< typename CoordTraits<C>::OptRectType, typename CoordTraits<C>::RectType - > > > + > > > > > { typedef typename CoordTraits<C>::IntervalType CInterval; typedef typename CoordTraits<C>::OptIntervalType OptCInterval; @@ -307,6 +317,7 @@ public: GenericOptRect() : Base() {} GenericOptRect(GenericRect<C> const &a) : Base(CRect(a)) {} GenericOptRect(CPoint const &a, CPoint const &b) : Base(CRect(a, b)) {} + GenericOptRect(C x0, C y0, C x1, C y1) : Base(CRect(x0, y0, x1, y1)) {} /// 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) { @@ -314,6 +325,7 @@ public: } // 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. @@ -427,6 +439,16 @@ public: intersectWith(b); return *this; } + /** @brief Test for equality. + * All empty rectangles are equal. */ + bool operator==(OptCRect const &other) const { + if (!*this != !other) return false; + return *this ? (**this == *other) : true; + } + bool operator==(CRect const &other) const { + if (!*this) return false; + return **this == other; + } /// @} }; diff --git a/src/2geom/interval.h b/src/2geom/interval.h index 711eaa5e2..b1fac04d9 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -47,12 +47,6 @@ namespace Geom { -/** - * @brief Range of real numbers that can be empty. - * @ingroup Primitives - */ -typedef GenericOptInterval<Coord> OptInterval; - /** * @brief Range of real numbers that is never empty. * @@ -128,8 +122,6 @@ public: /// @name Operators /// @{ - inline operator OptInterval() { return OptInterval(*this); } - // IMPL: ScalableConcept /** @brief Scale an interval */ Interval &operator*=(Coord s) { @@ -158,6 +150,12 @@ public: expandTo(mx * o.max()); return *this; } + bool operator==(IntInterval const &ii) const { + return min() == Coord(ii.min()) && max() == Coord(ii.max()); + } + bool operator==(Interval const &other) const { + return Base::operator==(other); + } /// @} /// @name Rounding to integer values @@ -177,6 +175,35 @@ public: /// @} }; +/** + * @brief Range of real numbers that can be empty. + * @ingroup Primitives + */ +class OptInterval + : public GenericOptInterval<Coord> +{ + typedef GenericOptInterval<Coord> Base; +public: + /// @name Create optionally empty intervals. + /// @{ + /** @brief Create an empty interval. */ + OptInterval() : Base() {} + /** @brief Wrap an existing interval. */ + OptInterval(Interval const &a) : Base(a) {} + /** @brief Create an interval containing a single point. */ + OptInterval(Coord u) : Base(u) {} + /** @brief Create an interval containing a range of numbers. */ + OptInterval(Coord u, Coord v) : Base(u,v) {} + OptInterval(Base const &b) : Base(b) {} + + /** @brief Promote from IntInterval. */ + OptInterval(IntInterval const &i) : Base(Interval(i)) {} + /** @brief Promote from OptIntInterval. */ + OptInterval(OptIntInterval const &i) : Base() { + if (i) *this = Interval(*i); + } +}; + // functions required for Python bindings inline Interval unify(Interval const &a, Interval const &b) { diff --git a/src/2geom/linear.h b/src/2geom/linear.h index 448ab3bb7..df6dd9904 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -55,7 +55,7 @@ class SBasis; class Linear{ public: double a[2]; - Linear() { a[0] = 0; a[1] = 0; } + Linear() {} 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 b79a0a04f..2516bcfa6 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -48,12 +48,6 @@ namespace Geom { /** - * @brief Axis-aligned rectangle that can be empty. - * @ingroup Primitives - */ -typedef GenericOptRect<Coord> OptRect; - -/** * @brief Axis aligned, non-empty rectangle. * @ingroup Primitives */ @@ -118,9 +112,45 @@ public: /// @name Operators /// @{ Rect &operator*=(Affine const &m); + bool operator==(IntRect const &ir) const { + return f[X] == ir[X] && f[Y] == ir[Y]; + } + bool operator==(Rect const &other) const { + return Base::operator==(other); + } /// @} }; +/** + * @brief Axis-aligned rectangle that can be empty. + * @ingroup Primitives + */ +class OptRect + : public GenericOptRect<Coord> +{ + typedef GenericOptRect<Coord> Base; +public: + OptRect() : Base() {} + OptRect(Rect const &a) : Base(a) {} + OptRect(Point const &a, Point const &b) : Base(a, b) {} + OptRect(Coord x0, Coord y0, Coord x1, Coord y1) : Base(x0, y0, x1, y1) {} + OptRect(OptInterval const &x_int, OptInterval const &y_int) : Base(x_int, y_int) {} + OptRect(Base const &b) : Base(b) {} + + OptRect(IntRect const &r) : Base(Rect(r)) {} + OptRect(OptIntRect const &r) : Base() { + if (r) *this = Rect(*r); + } + // actually, the only reason we have this class, instead of typedefing + // to GenericOptRect<Coord>, are the above constructors + bool operator==(OptRect const &other) const { + return Base::operator==(other); + } + bool operator==(Rect const &other) const { + return Base::operator==(other); + } +}; + Coord distanceSq(Point const &p, Rect const &rect); Coord distance(Point const &p, Rect const &rect); diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 4688a58e3..34b0d7cab 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -376,16 +376,14 @@ sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky) } void -sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRRectL const &r) +sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, Geom::IntRect const &r) { g_return_if_fail (ca != NULL); g_return_if_fail (SP_IS_CANVAS_ARENA (ca)); - Geom::OptIntRect area = r.upgrade_2geom(); - if (!area) return; - Inkscape::DrawingContext ct(surface, area->min()); + Inkscape::DrawingContext ct(surface, r.min()); ca->drawing.update(Geom::IntRect::infinite(), ca->ctx); - ca->drawing.render(ct, *area); + ca->drawing.render(ct, r); } /* diff --git a/src/display/canvas-arena.h b/src/display/canvas-arena.h index f145a9c70..daab19d8e 100644 --- a/src/display/canvas-arena.h +++ b/src/display/canvas-arena.h @@ -61,7 +61,7 @@ GType sp_canvas_arena_get_type (void); void sp_canvas_arena_set_pick_delta (SPCanvasArena *ca, gdouble delta); void sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky); -void sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRRectL const &area); +void sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, Geom::IntRect const &area); G_END_DECLS diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 3ed1fa5a9..c0dabcc07 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -99,7 +99,7 @@ sp_caxonomgrid_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, g static void sp_grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba) { - if ((x < buf->rect.x0) || (x >= buf->rect.x1)) + if ((x < buf->rect.left()) || (x >= buf->rect.right())) return; cairo_move_to(buf->ct, 0.5 + x, 0.5 + ys); @@ -526,21 +526,21 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) } cairo_save(buf->ct); - cairo_translate(buf->ct, -buf->rect.x0, -buf->rect.y0); + cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top()); cairo_set_line_width(buf->ct, 1.0); cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE); // gc = gridcoordinates (the coordinates calculated from the grids origin 'grid->ow'. - // sc = screencoordinates ( for example "buf->rect.x0" is in screencoordinates ) + // sc = screencoordinates ( for example "buf->rect.left()" is in screencoordinates ) // bc = buffer patch coordinates // tl = topleft ; br = bottomright Geom::Point buf_tl_gc; Geom::Point buf_br_gc; - buf_tl_gc[Geom::X] = buf->rect.x0 - ow[Geom::X]; - buf_tl_gc[Geom::Y] = buf->rect.y0 - ow[Geom::Y]; - buf_br_gc[Geom::X] = buf->rect.x1 - ow[Geom::X]; - buf_br_gc[Geom::Y] = buf->rect.y1 - ow[Geom::Y]; + buf_tl_gc[Geom::X] = buf->rect.left() - ow[Geom::X]; + buf_tl_gc[Geom::Y] = buf->rect.top() - ow[Geom::Y]; + buf_br_gc[Geom::X] = buf->rect.right() - ow[Geom::X]; + buf_br_gc[Geom::Y] = buf->rect.bottom() - ow[Geom::Y]; gdouble x; gdouble y; @@ -549,15 +549,15 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) // x-axis always goes from topleft to bottomright. (0,0) - (1,1) gdouble const xintercept_y_bc = (buf_tl_gc[Geom::X] * tan_angle[X]) - buf_tl_gc[Geom::Y] ; - gdouble const xstart_y_sc = ( xintercept_y_bc - floor(xintercept_y_bc/lyw)*lyw ) + buf->rect.y0; - gint const xlinestart = round( (xstart_y_sc - buf->rect.x0*tan_angle[X] -ow[Geom::Y]) / lyw ); + gdouble const xstart_y_sc = ( xintercept_y_bc - floor(xintercept_y_bc/lyw)*lyw ) + buf->rect.top(); + gint const xlinestart = round( (xstart_y_sc - buf->rect.left()*tan_angle[X] -ow[Geom::Y]) / lyw ); gint xlinenum = xlinestart; // lines starting on left side. - for (y = xstart_y_sc; y < buf->rect.y1; y += lyw, xlinenum++) { - gint const x0 = buf->rect.x0; + for (y = xstart_y_sc; y < buf->rect.bottom(); y += lyw, xlinenum++) { + gint const x0 = buf->rect.left(); gint const y0 = round(y); - gint const x1 = x0 + round( (buf->rect.y1 - y) / tan_angle[X] ); - gint const y1 = buf->rect.y1; + gint const x1 = x0 + round( (buf->rect.bottom() - y) / tan_angle[X] ); + gint const y1 = buf->rect.bottom(); if (!scaled && (xlinenum % empspacing) != 0) { sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, color); @@ -566,11 +566,11 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) } } // lines starting from top side - gdouble const xstart_x_sc = buf->rect.x0 + (lxw_x - (xstart_y_sc - buf->rect.y0) / tan_angle[X]) ; + gdouble const xstart_x_sc = buf->rect.left() + (lxw_x - (xstart_y_sc - buf->rect.top()) / tan_angle[X]) ; xlinenum = xlinestart-1; - for (x = xstart_x_sc; x < buf->rect.x1; x += lxw_x, xlinenum--) { - gint const y0 = buf->rect.y0; - gint const y1 = buf->rect.y1; + for (x = xstart_x_sc; x < buf->rect.right(); x += lxw_x, xlinenum--) { + gint const y0 = buf->rect.top(); + gint const y1 = buf->rect.bottom(); gint const x0 = round(x); gint const x1 = x0 + round( (y1 - y0) / tan_angle[X] ); @@ -585,27 +585,27 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) gdouble const ystart_x_sc = floor (buf_tl_gc[Geom::X] / spacing_ylines) * spacing_ylines + ow[Geom::X]; gint const ylinestart = round((ystart_x_sc - ow[Geom::X]) / spacing_ylines); gint ylinenum = ylinestart; - for (x = ystart_x_sc; x < buf->rect.x1; x += spacing_ylines, ylinenum++) { + for (x = ystart_x_sc; x < buf->rect.right(); x += spacing_ylines, ylinenum++) { gint const x0 = round(x); if (!scaled && (ylinenum % empspacing) != 0) { - sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, color); + sp_grid_vline (buf, x0, buf->rect.top(), buf->rect.bottom() - 1, color); } else { - sp_grid_vline (buf, x0, buf->rect.y0, buf->rect.y1 - 1, _empcolor); + sp_grid_vline (buf, x0, buf->rect.top(), buf->rect.bottom() - 1, _empcolor); } } // z-axis always goes from bottomleft to topright. (0,1) - (1,0) gdouble const zintercept_y_bc = (buf_tl_gc[Geom::X] * -tan_angle[Z]) - buf_tl_gc[Geom::Y] ; - gdouble const zstart_y_sc = ( zintercept_y_bc - floor(zintercept_y_bc/lyw)*lyw ) + buf->rect.y0; - gint const zlinestart = round( (zstart_y_sc + buf->rect.x0*tan_angle[Z] - ow[Geom::Y]) / lyw ); + gdouble const zstart_y_sc = ( zintercept_y_bc - floor(zintercept_y_bc/lyw)*lyw ) + buf->rect.top(); + gint const zlinestart = round( (zstart_y_sc + buf->rect.left()*tan_angle[Z] - ow[Geom::Y]) / lyw ); gint zlinenum = zlinestart; // lines starting from left side - for (y = zstart_y_sc; y < buf->rect.y1; y += lyw, zlinenum++) { - gint const x0 = buf->rect.x0; + for (y = zstart_y_sc; y < buf->rect.bottom(); y += lyw, zlinenum++) { + gint const x0 = buf->rect.left(); gint const y0 = round(y); - gint const x1 = x0 + round( (y - buf->rect.y0 ) / tan_angle[Z] ); - gint const y1 = buf->rect.y0; + gint const x1 = x0 + round( (y - buf->rect.top() ) / tan_angle[Z] ); + gint const y1 = buf->rect.top(); if (!scaled && (zlinenum % empspacing) != 0) { sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, color); @@ -614,12 +614,12 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) } } // draw lines from bottom-up - gdouble const zstart_x_sc = buf->rect.x0 + (y - buf->rect.y1) / tan_angle[Z] ; - for (x = zstart_x_sc; x < buf->rect.x1; x += lxw_z, zlinenum++) { - gint const y0 = buf->rect.y1; - gint const y1 = buf->rect.y0; + gdouble const zstart_x_sc = buf->rect.left() + (y - buf->rect.bottom()) / tan_angle[Z] ; + for (x = zstart_x_sc; x < buf->rect.right(); x += lxw_z, zlinenum++) { + gint const y0 = buf->rect.bottom(); + gint const y1 = buf->rect.top(); gint const x0 = round(x); - gint const x1 = x0 + round( (buf->rect.y1 - buf->rect.y0) / tan_angle[Z] ); + gint const x1 = x0 + round(buf->rect.height() / tan_angle[Z] ); if (!scaled && (zlinenum % empspacing) != 0) { sp_caxonomgrid_drawline (buf, x0, y0, x1, y1, color); diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 306b523ca..e015655a6 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -26,8 +26,6 @@ #include "display/cairo-utils.h" #include "helper/geom.h" -void nr_pixblock_render_bpath_rgba (Shape* theS,uint32_t color,NRRectL &area,char* destBuf,int stride); - static void sp_canvas_bpath_class_init (SPCanvasBPathClass *klass); static void sp_canvas_bpath_init (SPCanvasBPath *path); static void sp_canvas_bpath_destroy (GtkObject *object); @@ -139,7 +137,7 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) { SPCanvasBPath *cbp = SP_CANVAS_BPATH (item); - Geom::Rect area (Geom::Point(buf->rect.x0, buf->rect.y0), Geom::Point(buf->rect.x1, buf->rect.y1)); + Geom::Rect area = buf->rect; if ( !cbp->curve || ((cbp->stroke_rgba & 0xff) == 0 && (cbp->fill_rgba & 0xff) == 0 ) || diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index b3ec73e78..38fe69628 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -834,94 +834,45 @@ CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/) static void grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba) { - if ((y < buf->rect.y0) || (y >= buf->rect.y1)) + if ((y < buf->rect.top()) || (y >= buf->rect.bottom())) return; cairo_move_to(buf->ct, 0.5 + xs, 0.5 + y); cairo_line_to(buf->ct, 0.5 + xe, 0.5 + y); ink_cairo_set_source_rgba32(buf->ct, rgba); cairo_stroke(buf->ct); -#if 0 - guint r, g, b, a; - gint x0, x1, x; - guchar *p; - r = NR_RGBA32_R (rgba); - g = NR_RGBA32_G (rgba); - b = NR_RGBA32_B (rgba); - a = NR_RGBA32_A (rgba); - x0 = MAX (buf->rect.x0, xs); - x1 = MIN (buf->rect.x1, xe + 1); - p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 4; - for (x = x0; x < x1; x++) { - p[0] = NR_COMPOSEN11_1111 (r, a, p[0]); - p[1] = NR_COMPOSEN11_1111 (g, a, p[1]); - p[2] = NR_COMPOSEN11_1111 (b, a, p[2]); - p += 4; - } -#endif } static void grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba) { - if ((x < buf->rect.x0) || (x >= buf->rect.x1)) + if ((x < buf->rect.left()) || (x >= buf->rect.right())) return; cairo_move_to(buf->ct, 0.5 + x, 0.5 + ys); cairo_line_to(buf->ct, 0.5 + x, 0.5 + ye); ink_cairo_set_source_rgba32(buf->ct, rgba); cairo_stroke(buf->ct); - #if 0 - guint r, g, b, a; - gint y0, y1, y; - guchar *p; - r = NR_RGBA32_R(rgba); - g = NR_RGBA32_G (rgba); - b = NR_RGBA32_B (rgba); - a = NR_RGBA32_A (rgba); - y0 = MAX (buf->rect.y0, ys); - y1 = MIN (buf->rect.y1, ye + 1); - p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 4; - for (y = y0; y < y1; y++) { - p[0] = NR_COMPOSEN11_1111 (r, a, p[0]); - p[1] = NR_COMPOSEN11_1111 (g, a, p[1]); - p[2] = NR_COMPOSEN11_1111 (b, a, p[2]); - p += buf->buf_rowstride; - } - #endif } static void grid_dot (SPCanvasBuf *buf, gint x, gint y, guint32 rgba) { - if ( (y < buf->rect.y0) || (y >= buf->rect.y1) - || (x < buf->rect.x0) || (x >= buf->rect.x1) ) + if ( (y < buf->rect.top()) || (y >= buf->rect.bottom()) + || (x < buf->rect.left()) || (x >= buf->rect.right()) ) return; cairo_rectangle(buf->ct, x, y, 1, 1); ink_cairo_set_source_rgba32(buf->ct, rgba); cairo_fill(buf->ct); - -#if 0 - guint r, g, b, a; - guchar *p; - r = NR_RGBA32_R (rgba); - g = NR_RGBA32_G (rgba); - b = NR_RGBA32_B (rgba); - a = NR_RGBA32_A (rgba); - p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 4; - p[0] = NR_COMPOSEN11_1111 (r, a, p[0]); - p[1] = NR_COMPOSEN11_1111 (g, a, p[1]); - p[2] = NR_COMPOSEN11_1111 (b, a, p[2]); -#endif } void CanvasXYGrid::Render (SPCanvasBuf *buf) { - gdouble const sxg = floor ((buf->rect.x0 - ow[Geom::X]) / sw[Geom::X]) * sw[Geom::X] + ow[Geom::X]; + gdouble const sxg = floor ((buf->rect.left() - ow[Geom::X]) / sw[Geom::X]) * sw[Geom::X] + ow[Geom::X]; gint const xlinestart = round((sxg - ow[Geom::X]) / sw[Geom::X]); - gdouble const syg = floor ((buf->rect.y0 - ow[Geom::Y]) / sw[Geom::Y]) * sw[Geom::Y] + ow[Geom::Y]; + gdouble const syg = floor ((buf->rect.top() - ow[Geom::Y]) / sw[Geom::Y]) * sw[Geom::Y] + ow[Geom::Y]; gint const ylinestart = round((syg - ow[Geom::Y]) / sw[Geom::Y]); //set correct coloring, depending preference (when zoomed out, always major coloring or minor coloring) @@ -935,41 +886,41 @@ CanvasXYGrid::Render (SPCanvasBuf *buf) } cairo_save(buf->ct); - cairo_translate(buf->ct, -buf->rect.x0, -buf->rect.y0); + cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top()); cairo_set_line_width(buf->ct, 1.0); cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE); if (!render_dotted) { gint ylinenum; gdouble y; - for (y = syg, ylinenum = ylinestart; y < buf->rect.y1; y += sw[Geom::Y], ylinenum++) { + for (y = syg, ylinenum = ylinestart; y < buf->rect.bottom(); y += sw[Geom::Y], ylinenum++) { gint const y0 = round(y); if (!scaled[Geom::Y] && (ylinenum % empspacing) != 0) { - grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, color); + grid_hline (buf, y0, buf->rect.left(), buf->rect.right() - 1, color); } else { - grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, _empcolor); + grid_hline (buf, y0, buf->rect.left(), buf->rect.right() - 1, _empcolor); } } gint xlinenum; gdouble x; - for (x = sxg, xlinenum = xlinestart; x < buf->rect.x1; x += sw[Geom::X], xlinenum++) { + for (x = sxg, xlinenum = xlinestart; x < buf->rect.right(); x += sw[Geom::X], xlinenum++) { gint const ix = round(x); if (!scaled[Geom::X] && (xlinenum % empspacing) != 0) { - grid_vline (buf, ix, buf->rect.y0, buf->rect.y1, color); + grid_vline (buf, ix, buf->rect.top(), buf->rect.bottom(), color); } else { - grid_vline (buf, ix, buf->rect.y0, buf->rect.y1, _empcolor); + grid_vline (buf, ix, buf->rect.top(), buf->rect.bottom(), _empcolor); } } } else { gint ylinenum; gdouble y; - for (y = syg, ylinenum = ylinestart; y < buf->rect.y1; y += sw[Geom::Y], ylinenum++) { + for (y = syg, ylinenum = ylinestart; y < buf->rect.bottom(); y += sw[Geom::Y], ylinenum++) { gint const iy = round(y); gint xlinenum; gdouble x; - for (x = sxg, xlinenum = xlinestart; x < buf->rect.x1; x += sw[Geom::X], xlinenum++) { + for (x = sxg, xlinenum = xlinestart; x < buf->rect.right(); x += sw[Geom::X], xlinenum++) { gint const ix = round(x); if ( (!scaled[Geom::X] && (xlinenum % empspacing) != 0) || (!scaled[Geom::Y] && (ylinenum % empspacing) != 0) diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 683e2f93c..185d10b15 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -116,8 +116,8 @@ sp_canvastext_render (SPCanvasItem *item, SPCanvasBuf *buf) return; Geom::Point s = cl->s * cl->affine; - double offsetx = s[Geom::X] - buf->rect.x0; - double offsety = s[Geom::Y] - buf->rect.y0; + double offsetx = s[Geom::X] - buf->rect.left(); + double offsety = s[Geom::Y] - buf->rect.top(); offsetx -= anchor_offset_x; offsety -= anchor_offset_y; diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 0d2905d23..f2802c6fe 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -111,7 +111,7 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) SPGuideLine const *gl = SP_GUIDELINE (item); cairo_save(buf->ct); - cairo_translate(buf->ct, -buf->rect.x0, -buf->rect.y0); + cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top()); ink_cairo_set_source_rgba32(buf->ct, gl->rgba); cairo_set_line_width(buf->ct, 1); cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE); @@ -134,49 +134,49 @@ static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) if ( Geom::are_near(normal_dt[Geom::Y], 0.) ) { // is vertical? int position = round(point_on_line_dt[Geom::X]); - cairo_move_to(buf->ct, position + 0.5, buf->rect.y0 + 0.5); - cairo_line_to(buf->ct, position + 0.5, buf->rect.y1 - 0.5); + cairo_move_to(buf->ct, position + 0.5, buf->rect.top() + 0.5); + cairo_line_to(buf->ct, position + 0.5, buf->rect.bottom() - 0.5); cairo_stroke(buf->ct); } else if ( Geom::are_near(normal_dt[Geom::X], 0.) ) { // is horizontal? int position = round(point_on_line_dt[Geom::Y]); - cairo_move_to(buf->ct, buf->rect.x0 + 0.5, position + 0.5); - cairo_line_to(buf->ct, buf->rect.x1 - 0.5, position + 0.5); + cairo_move_to(buf->ct, buf->rect.left() + 0.5, position + 0.5); + cairo_line_to(buf->ct, buf->rect.right() - 0.5, position + 0.5); cairo_stroke(buf->ct); } else { // render angled line. Once intersection has been detected, draw from there. Geom::Point parallel_to_line( normal_dt.ccw() ); //try to intersect with left vertical of rect - double y_intersect_left = (buf->rect.x0 - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - if ( (y_intersect_left >= buf->rect.y0) && (y_intersect_left <= buf->rect.y1) ) { + double y_intersect_left = (buf->rect.left() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; + if ( (y_intersect_left >= buf->rect.top()) && (y_intersect_left <= buf->rect.bottom()) ) { // intersects with left vertical! - double y_intersect_right = (buf->rect.x1 - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - sp_guideline_drawline (buf, buf->rect.x0, static_cast<gint>(round(y_intersect_left)), buf->rect.x1, static_cast<gint>(round(y_intersect_right)), gl->rgba); + double y_intersect_right = (buf->rect.right() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; + sp_guideline_drawline (buf, buf->rect.left(), static_cast<gint>(round(y_intersect_left)), buf->rect.right(), static_cast<gint>(round(y_intersect_right)), gl->rgba); goto end; } //try to intersect with right vertical of rect - double y_intersect_right = (buf->rect.x1 - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; - if ( (y_intersect_right >= buf->rect.y0) && (y_intersect_right <= buf->rect.y1) ) { + double y_intersect_right = (buf->rect.right() - point_on_line_dt[Geom::X]) * parallel_to_line[Geom::Y] / parallel_to_line[Geom::X] + point_on_line_dt[Geom::Y]; + if ( (y_intersect_right >= buf->rect.top()) && (y_intersect_right <= buf->rect.bottom()) ) { // intersects with right vertical! - sp_guideline_drawline (buf, buf->rect.x1, static_cast<gint>(round(y_intersect_right)), buf->rect.x0, static_cast<gint>(round(y_intersect_left)), gl->rgba); + sp_guideline_drawline (buf, buf->rect.right(), static_cast<gint>(round(y_intersect_right)), buf->rect.left(), static_cast<gint>(round(y_intersect_left)), gl->rgba); goto end; } //try to intersect with top horizontal of rect - double x_intersect_top = (buf->rect.y0 - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - if ( (x_intersect_top >= buf->rect.x0) && (x_intersect_top <= buf->rect.x1) ) { + double x_intersect_top = (buf->rect.top() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; + if ( (x_intersect_top >= buf->rect.left()) && (x_intersect_top <= buf->rect.right()) ) { // intersects with top horizontal! - double x_intersect_bottom = (buf->rect.y1 - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_top)), buf->rect.y0, static_cast<gint>(round(x_intersect_bottom)), buf->rect.y1, gl->rgba); + double x_intersect_bottom = (buf->rect.bottom() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; + sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_top)), buf->rect.top(), static_cast<gint>(round(x_intersect_bottom)), buf->rect.bottom(), gl->rgba); goto end; } //try to intersect with bottom horizontal of rect - double x_intersect_bottom = (buf->rect.y1 - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; - if ( (x_intersect_top >= buf->rect.x0) && (x_intersect_top <= buf->rect.x1) ) { + double x_intersect_bottom = (buf->rect.bottom() - point_on_line_dt[Geom::Y]) * parallel_to_line[Geom::X] / parallel_to_line[Geom::Y] + point_on_line_dt[Geom::X]; + if ( (x_intersect_top >= buf->rect.left()) && (x_intersect_top <= buf->rect.right()) ) { // intersects with bottom horizontal! - sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_bottom)), buf->rect.y1, static_cast<gint>(round(x_intersect_top)), buf->rect.y0, gl->rgba); + sp_guideline_drawline (buf, static_cast<gint>(round(x_intersect_bottom)), buf->rect.bottom(), static_cast<gint>(round(x_intersect_top)), buf->rect.top(), gl->rgba); goto end; } } diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp index 6fa34bf0b..33718ed68 100644 --- a/src/display/nr-filter-colormatrix.cpp +++ b/src/display/nr-filter-colormatrix.cpp @@ -188,10 +188,6 @@ bool FilterColorMatrix::can_handle_affine(Geom::Affine const &) return true; } -void FilterColorMatrix::area_enlarge(NRRectL &/*area*/, Geom::Affine const &/*trans*/) -{ -} - double FilterColorMatrix::complexity(Geom::Affine const &) { return 2.0; diff --git a/src/display/nr-filter-colormatrix.h b/src/display/nr-filter-colormatrix.h index 5864a010e..5f21a4210 100644 --- a/src/display/nr-filter-colormatrix.h +++ b/src/display/nr-filter-colormatrix.h @@ -37,7 +37,6 @@ public: virtual void render_cairo(FilterSlot &slot); virtual bool can_handle_affine(Geom::Affine const &); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); virtual void set_type(FilterColorMatrixType type); diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index 887352f62..226a73cef 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -304,10 +304,6 @@ bool FilterComponentTransfer::can_handle_affine(Geom::Affine const &) return true; } -void FilterComponentTransfer::area_enlarge(NRRectL &/*area*/, Geom::Affine const &/*trans*/) -{ -} - double FilterComponentTransfer::complexity(Geom::Affine const &) { return 2.0; diff --git a/src/display/nr-filter-component-transfer.h b/src/display/nr-filter-component-transfer.h index 6d65ae6d1..558d097a8 100644 --- a/src/display/nr-filter-component-transfer.h +++ b/src/display/nr-filter-component-transfer.h @@ -37,7 +37,6 @@ public: virtual void render_cairo(FilterSlot &slot); virtual bool can_handle_affine(Geom::Affine const &); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); FilterComponentTransferType type[4]; diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp index 469baf346..5469aff88 100644 --- a/src/display/nr-filter-convolve-matrix.cpp +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -202,14 +202,15 @@ void FilterConvolveMatrix::set_preserveAlpha(bool pa){ preserveAlpha = pa; } -void FilterConvolveMatrix::area_enlarge(NRRectL &area, Geom::Affine const &/*trans*/) +void FilterConvolveMatrix::area_enlarge(Geom::IntRect &area, Geom::Affine const &/*trans*/) { //Seems to me that since this filter's operation is resolution dependent, // some spurious pixels may still appear at the borders when low zooming or rotating. Needs a better fix. - area.x0 -= targetX; - area.y0 -= targetY; - area.x1 += orderX - targetX - 1; // This makes sure the last row/column in the original image corresponds to the last row/column in the new image that can be convolved without adjusting the boundary conditions). - area.y1 += orderY - targetY - 1; + area.setMin(area.min() - Geom::IntPoint(targetX, targetY)); + // This makes sure the last row/column in the original image corresponds + // to the last row/column in the new image that can be convolved without + // adjusting the boundary conditions). + area.setMax(area.max() + Geom::IntPoint(orderX - targetX - 1, orderY - targetY -1)); } double FilterConvolveMatrix::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-convolve-matrix.h b/src/display/nr-filter-convolve-matrix.h index 8b7fc35d1..c37fe721f 100644 --- a/src/display/nr-filter-convolve-matrix.h +++ b/src/display/nr-filter-convolve-matrix.h @@ -35,7 +35,7 @@ public: virtual ~FilterConvolveMatrix(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); void set_targetY(int coord); diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp index 14144ace5..c94df2d70 100644 --- a/src/display/nr-filter-diffuselighting.cpp +++ b/src/display/nr-filter-diffuselighting.cpp @@ -159,16 +159,13 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot) cairo_surface_destroy(out); } -void FilterDiffuseLighting::area_enlarge(NRRectL &area, Geom::Affine const & /*trans*/) +void FilterDiffuseLighting::area_enlarge(Geom::IntRect &area, Geom::Affine const & /*trans*/) { // TODO: support kernelUnitLength // We expand the area by 1 in every direction to avoid artifacts on tile edges. // However, it means that edge pixels will be incorrect. - area.x0 -= 1; - area.x1 += 1; - area.y0 -= 1; - area.y1 += 1; + area.expandBy(1); } double FilterDiffuseLighting::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h index bb3ceccb3..0da6cc218 100644 --- a/src/display/nr-filter-diffuselighting.h +++ b/src/display/nr-filter-diffuselighting.h @@ -32,7 +32,7 @@ public: static FilterPrimitive *create(); virtual ~FilterDiffuseLighting(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); union { diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp index 75e310339..01c644bc1 100644 --- a/src/display/nr-filter-displacement-map.cpp +++ b/src/display/nr-filter-displacement-map.cpp @@ -125,7 +125,7 @@ void FilterDisplacementMap::set_channel_selector(int s, FilterDisplacementMapCha if (s == 1) Ychannel = ch; } -void FilterDisplacementMap::area_enlarge(NRRectL &area, Geom::Affine const &trans) +void FilterDisplacementMap::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) { //I assume scale is in user coordinates (?!?) //FIXME: trans should be multiplied by some primitiveunits2user, shouldn't it? @@ -134,10 +134,7 @@ void FilterDisplacementMap::area_enlarge(NRRectL &area, Geom::Affine const &tran double scaley = scale/2.*(std::fabs(trans[2])+std::fabs(trans[3])); //FIXME: no +2 should be there!... (noticable only for big scales at big zoom factor) - area.x0 -= (int)(scalex)+2; - area.x1 += (int)(scalex)+2; - area.y0 -= (int)(scaley)+2; - area.y1 += (int)(scaley)+2; + area.expandBy(scalex+2, scaley+2); } double FilterDisplacementMap::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-displacement-map.h b/src/display/nr-filter-displacement-map.h index 393a904c1..e4228323a 100644 --- a/src/display/nr-filter-displacement-map.h +++ b/src/display/nr-filter-displacement-map.h @@ -28,7 +28,7 @@ public: virtual ~FilterDisplacementMap(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); virtual void set_input(int slot); diff --git a/src/display/nr-filter-flood.cpp b/src/display/nr-filter-flood.cpp index 5716c1bc5..7db14737b 100644 --- a/src/display/nr-filter-flood.cpp +++ b/src/display/nr-filter-flood.cpp @@ -81,11 +81,6 @@ void FilterFlood::set_opacity(double o) { void FilterFlood::set_icc(SVGICCColor *icc_color) { icc = icc_color; } - -void FilterFlood::area_enlarge(NRRectL &/*area*/, Geom::Affine const &/*trans*/) -{ -} - double FilterFlood::complexity(Geom::Affine const &) { // flood is actually less expensive than normal rendering, diff --git a/src/display/nr-filter-flood.h b/src/display/nr-filter-flood.h index f744e9f48..8568502ff 100644 --- a/src/display/nr-filter-flood.h +++ b/src/display/nr-filter-flood.h @@ -27,7 +27,6 @@ public: virtual void render_cairo(FilterSlot &slot); virtual bool can_handle_affine(Geom::Affine const &); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); virtual bool uses_background() { return false; } diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 8a7244e02..7a65519e0 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -667,17 +667,14 @@ void FilterGaussian::render_cairo(FilterSlot &slot) } } -void FilterGaussian::area_enlarge(NRRectL &area, Geom::Affine const &trans) +void FilterGaussian::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) { int area_x = _effect_area_scr(_deviation_x * trans.expansionX()); int area_y = _effect_area_scr(_deviation_y * trans.expansionY()); // maximum is used because rotations can mix up these directions // TODO: calculate a more tight-fitting rendering area int area_max = std::max(area_x, area_y); - area.x0 -= area_max; - area.x1 += area_max; - area.y0 -= area_max; - area.y1 += area_max; + area.expandBy(area_max); } bool FilterGaussian::can_handle_affine(Geom::Affine const &) diff --git a/src/display/nr-filter-gaussian.h b/src/display/nr-filter-gaussian.h index f52bea01e..1c35a0f1d 100644 --- a/src/display/nr-filter-gaussian.h +++ b/src/display/nr-filter-gaussian.h @@ -35,7 +35,7 @@ public: virtual ~FilterGaussian(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &m); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &m); virtual bool can_handle_affine(Geom::Affine const &m); virtual double complexity(Geom::Affine const &ctm); diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp index 9e43d01f3..b6aea1b06 100644 --- a/src/display/nr-filter-morphology.cpp +++ b/src/display/nr-filter-morphology.cpp @@ -147,15 +147,12 @@ void FilterMorphology::render_cairo(FilterSlot &slot) cairo_surface_destroy(out); } -void FilterMorphology::area_enlarge(NRRectL &area, Geom::Affine const &trans) +void FilterMorphology::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) { int enlarge_x = ceil(xradius * trans.expansionX()); int enlarge_y = ceil(yradius * trans.expansionY()); - area.x0 -= enlarge_x; - area.x1 += enlarge_x; - area.y0 -= enlarge_y; - area.y1 += enlarge_y; + area.expandBy(enlarge_x, enlarge_y); } double FilterMorphology::complexity(Geom::Affine const &trans) diff --git a/src/display/nr-filter-morphology.h b/src/display/nr-filter-morphology.h index 512eca83c..0574ff4ad 100644 --- a/src/display/nr-filter-morphology.h +++ b/src/display/nr-filter-morphology.h @@ -32,7 +32,7 @@ public: virtual ~FilterMorphology(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); void set_operator(FilterMorphologyOperator &o); diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp index db8b6d92a..da46095ef 100644 --- a/src/display/nr-filter-offset.cpp +++ b/src/display/nr-filter-offset.cpp @@ -65,24 +65,30 @@ void FilterOffset::set_dy(double amount) { dy = amount; } -void FilterOffset::area_enlarge(NRRectL &area, Geom::Affine const &trans) +void FilterOffset::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) { Geom::Point offset(dx, dy); offset *= trans; offset[X] -= trans[4]; offset[Y] -= trans[5]; + double x0, y0, x1, y1; + x0 = area.left(); + y0 = area.top(); + x1 = area.right(); + y1 = area.bottom(); if (offset[X] > 0) { - area.x0 -= ceil(offset[X]); + x0 -= ceil(offset[X]); } else { - area.x1 -= floor(offset[X]); + x1 -= floor(offset[X]); } if (offset[Y] > 0) { - area.y0 -= ceil(offset[Y]); + y0 -= ceil(offset[Y]); } else { - area.y1 -= floor(offset[Y]); + y1 -= floor(offset[Y]); } + area = Geom::IntRect(x0, y0, x1, y1); } double FilterOffset::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-offset.h b/src/display/nr-filter-offset.h index 841be6008..5551131f0 100644 --- a/src/display/nr-filter-offset.h +++ b/src/display/nr-filter-offset.h @@ -27,7 +27,7 @@ public: virtual ~FilterOffset(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual bool can_handle_affine(Geom::Affine const &); virtual double complexity(Geom::Affine const &ctm); diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index 0a445b9e6..c6bd8a74e 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -53,7 +53,7 @@ void FilterPrimitive::render_cairo(FilterSlot &slot) slot.set(_output, in); } -void FilterPrimitive::area_enlarge(NRRectL &/*area*/, Geom::Affine const &/*m*/) +void FilterPrimitive::area_enlarge(Geom::IntRect &/*area*/, Geom::Affine const &/*m*/) { // This doesn't need to do anything by default } diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 501d76447..42a1c98b7 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -12,11 +12,10 @@ #define SEEN_NR_FILTER_PRIMITIVE_H #include <2geom/forward.h> +#include <2geom/rect.h> #include "display/nr-filter-types.h" #include "svg/svg-length.h" -struct NRRectL; - namespace Inkscape { namespace Filters { @@ -30,7 +29,7 @@ public: virtual void render_cairo(FilterSlot &slot); virtual int render(FilterSlot & /*slot*/, FilterUnits const & /*units*/) { return 0; } - virtual void area_enlarge(NRRectL &area, Geom::Affine const &m); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &m); /** * Sets the input slot number 'slot' to be used as input in rendering diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index d41b5180b..805027bfe 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -67,7 +67,6 @@ public: FilterUnits const &get_units() const { return _units; } Geom::Rect get_slot_area() const; - NRRectL get_sg_area() const { NRRectL ret(_source_graphic_area); return ret; } private: typedef std::map<int, cairo_surface_t *> SlotMap; @@ -77,7 +76,6 @@ private: //Geom::Rect _source_bbox; ///< bounding box of source graphic surface //Geom::Rect _intermediate_bbox; ///< bounding box of intermediate surfaces -// NRRectL _slot_area; int _slot_w, _slot_h; double _slot_x, _slot_y; cairo_surface_t *_source_graphic; diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp index c28fd485a..ddb0c06eb 100644 --- a/src/display/nr-filter-specularlighting.cpp +++ b/src/display/nr-filter-specularlighting.cpp @@ -174,14 +174,10 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot) cairo_surface_destroy(out); } -void FilterSpecularLighting::area_enlarge(NRRectL &area, Geom::Affine const & /*trans*/) +void FilterSpecularLighting::area_enlarge(Geom::IntRect &area, Geom::Affine const & /*trans*/) { // TODO: support kernelUnitLength - - area.x0 -= 1; - area.x1 += 1; - area.y0 -= 1; - area.y1 += 1; + area.expandBy(1); } double FilterSpecularLighting::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h index 8471b70b0..33ea17a87 100644 --- a/src/display/nr-filter-specularlighting.h +++ b/src/display/nr-filter-specularlighting.h @@ -33,7 +33,7 @@ public: virtual ~FilterSpecularLighting(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); union { diff --git a/src/display/nr-filter-tile.cpp b/src/display/nr-filter-tile.cpp index 4aadde2aa..6680e7a46 100644 --- a/src/display/nr-filter-tile.cpp +++ b/src/display/nr-filter-tile.cpp @@ -41,10 +41,6 @@ void FilterTile::render_cairo(FilterSlot &slot) slot.set(_output, in); } -void FilterTile::area_enlarge(NRRectL &/*area*/, Geom::Affine const &/*trans*/) -{ -} - double FilterTile::complexity(Geom::Affine const &) { return 1.0; diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h index 37e257f79..dc5b99a42 100644 --- a/src/display/nr-filter-tile.h +++ b/src/display/nr-filter-tile.h @@ -26,7 +26,6 @@ public: virtual ~FilterTile(); virtual void render_cairo(FilterSlot &slot); - virtual void area_enlarge(NRRectL &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); }; diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 450ce689d..6e3eb91d5 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -177,11 +177,9 @@ void Filter::set_primitive_units(SPFilterUnits unit) { } 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(bbox, item->ctm()); } - bbox = *b.upgrade_2geom(); /* TODO: something. See images at the bottom of filters.svg with medium-low diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp index b4d2633bb..f4f0c485a 100644 --- a/src/display/sodipodi-ctrl.cpp +++ b/src/display/sodipodi-ctrl.cpp @@ -112,7 +112,7 @@ sp_ctrl_init (SPCtrl *ctrl) // If moveto() is called then it will not set _moved to true because we're initially already at (0, 0) ctrl->_moved = true; // Is this flag ever going to be set back to false? I can't find where that is supposed to happen - ctrl->box.x0 = ctrl->box.y0 = ctrl->box.x1 = ctrl->box.y1 = 0; + new (&ctrl->box) Geom::IntRect(0,0,0,0); ctrl->cache = NULL; ctrl->pixbuf = NULL; @@ -232,7 +232,7 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla if (!ctrl->_moved) return; if (ctrl->shown) { - sp_canvas_request_redraw (item->canvas, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1); + sp_canvas_request_redraw (item->canvas, ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1); } if (!ctrl->defined) return; @@ -278,12 +278,8 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla break; } - ctrl->box.x0 = x; - ctrl->box.y0 = y; - ctrl->box.x1 = ctrl->box.x0 + 2 * ctrl->span; - ctrl->box.y1 = ctrl->box.y0 + 2 * ctrl->span; - - sp_canvas_update_bbox (item, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1); + ctrl->box = Geom::IntRect::from_xywh(x, y, 2*ctrl->span, 2*ctrl->span); + sp_canvas_update_bbox (item, ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1); } static double @@ -293,11 +289,7 @@ sp_ctrl_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item) *actual_item = item; - double const x = p[Geom::X]; - double const y = p[Geom::Y]; - - if ((x >= ctrl->box.x0) && (x <= ctrl->box.x1) && (y >= ctrl->box.y0) && (y <= ctrl->box.y1)) return 0.0; - + if (ctrl->box.contains(p.floor())) return 0.0; return 1e18; } @@ -519,8 +511,8 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) // 1. Copy the affected part of output to a temporary surface cairo_surface_t *work = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); cairo_t *cr = cairo_create(work); - cairo_translate(cr, -ctrl->box.x0, -ctrl->box.y0); - cairo_set_source_surface(cr, cairo_get_target(buf->ct), buf->rect.x0, buf->rect.y0); + cairo_translate(cr, -ctrl->box.left(), -ctrl->box.top()); + cairo_set_source_surface(cr, cairo_get_target(buf->ct), buf->rect.left(), buf->rect.top()); cairo_paint(cr); cairo_destroy(cr); @@ -551,8 +543,8 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) // 3. Replace the affected part of output with contents of temporary surface cairo_save(buf->ct); cairo_set_source_surface(buf->ct, work, - ctrl->box.x0 - buf->rect.x0, ctrl->box.y0 - buf->rect.y0); - cairo_rectangle(buf->ct, ctrl->box.x0 - buf->rect.x0, ctrl->box.y0 - buf->rect.y0, w, h); + ctrl->box.left() - buf->rect.left(), ctrl->box.top() - buf->rect.top()); + cairo_rectangle(buf->ct, ctrl->box.left() - buf->rect.left(), ctrl->box.top() - buf->rect.top(), w, h); cairo_clip(buf->ct); cairo_set_operator(buf->ct, CAIRO_OPERATOR_SOURCE); cairo_paint(buf->ct); @@ -562,7 +554,7 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_surface_t *cache = cairo_image_surface_create_for_data( reinterpret_cast<unsigned char*>(ctrl->cache), CAIRO_FORMAT_ARGB32, w, h, w*4); cairo_set_source_surface(buf->ct, cache, - ctrl->box.x0 - buf->rect.x0, ctrl->box.y0 - buf->rect.y0); + ctrl->box.left() - buf->rect.left(), ctrl->box.top() - buf->rect.top()); cairo_paint(buf->ct); cairo_surface_destroy(cache); } diff --git a/src/display/sodipodi-ctrl.h b/src/display/sodipodi-ctrl.h index 4f114eac6..88cae28fd 100644 --- a/src/display/sodipodi-ctrl.h +++ b/src/display/sodipodi-ctrl.h @@ -48,7 +48,7 @@ struct SPCtrl : public SPCanvasItem { guint32 stroke_color; bool _moved; - NRRectL box; /* NB! x1 & y1 are included */ + Geom::IntRect box; /* NB! x1 & y1 are included */ guint32 *cache; GdkPixbuf * pixbuf; diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index b4539841b..c0e08c00a 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -132,7 +132,7 @@ void CtrlRect::render(SPCanvasBuf *buf) if ( area_w_shadow.intersects(buf->rect) ) { cairo_save(buf->ct); - cairo_translate(buf->ct, -buf->rect.x0, -buf->rect.y0); + cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top()); cairo_set_line_width(buf->ct, 1); if (_dashed) cairo_set_dash(buf->ct, dashes, 2, 0); cairo_rectangle(buf->ct, 0.5 + area[X].min(), 0.5 + area[Y].min(), diff --git a/src/display/sp-canvas-util.cpp b/src/display/sp-canvas-util.cpp index d1ea842fd..78936009b 100644 --- a/src/display/sp-canvas-util.cpp +++ b/src/display/sp-canvas-util.cpp @@ -38,15 +38,8 @@ sp_canvas_item_reset_bounds (SPCanvasItem *item) item->y2 = 0.0; } -void sp_canvas_prepare_buffer(SPCanvasBuf * /*buf*/) +void sp_canvas_prepare_buffer(SPCanvasBuf *) { - /*if (buf->is_empty) { - int y; - for (y = buf->rect.y0; y < buf->rect.y1; y++) { - memset (buf->buf + (y - buf->rect.y0) * buf->buf_rowstride, 0, 4 * (buf->rect.x1 - buf->rect.x0)); - } - buf->is_empty = false; - }*/ } Geom::Affine sp_canvas_item_i2p_affine (SPCanvasItem * item) diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 7d6727ff3..a4c8500ed 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -866,10 +866,10 @@ sp_canvas_group_render (SPCanvasItem *item, SPCanvasBuf *buf) for (GList *list = group->items; list; list = list->next) { SPCanvasItem *child = (SPCanvasItem *)list->data; if (child->flags & SP_CANVAS_ITEM_VISIBLE) { - if ((child->x1 < buf->rect.x1) && - (child->y1 < buf->rect.y1) && - (child->x2 > buf->rect.x0) && - (child->y2 > buf->rect.y0)) { + if ((child->x1 < buf->rect.right()) && + (child->y1 < buf->rect.bottom()) && + (child->x2 > buf->rect.left()) && + (child->y2 > buf->rect.top())) { if (SP_CANVAS_ITEM_GET_CLASS (child)->render) SP_CANVAS_ITEM_GET_CLASS (child)->render (child, buf); } @@ -963,8 +963,8 @@ static gint sp_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event); static GtkWidgetClass *canvas_parent_class; static void sp_canvas_resize_tiles(SPCanvas* canvas, int nl, int nt, int nr, int nb); -static void sp_canvas_dirty_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb); -static void sp_canvas_mark_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb, uint8_t val); +static void sp_canvas_dirty_rect(SPCanvas* canvas, Geom::IntRect const &area); +static void sp_canvas_mark_rect(SPCanvas* canvas, Geom::IntRect const &area, uint8_t val); static int do_update (SPCanvas *canvas); /** @@ -1634,46 +1634,38 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) return status; } -static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int x1, int y1, int draw_x1, int draw_y1, int draw_x2, int draw_y2, int /*sw*/) +static void sp_canvas_paint_single_buffer(SPCanvas *canvas, Geom::IntRect const &paint_rect, Geom::IntRect const &canvas_rect, int /*sw*/) { GtkWidget *widget = GTK_WIDGET (canvas); // Mark the region clean - sp_canvas_mark_rect(canvas, x0, y0, x1, y1, 0); + sp_canvas_mark_rect(canvas, paint_rect, 0); SPCanvasBuf buf; buf.buf = NULL; buf.buf_rowstride = 0; - buf.rect.x0 = x0; - buf.rect.y0 = y0; - buf.rect.x1 = x1; - buf.rect.y1 = y1; - buf.visible_rect.x0 = draw_x1; - buf.visible_rect.y0 = draw_y1; - buf.visible_rect.x1 = draw_x2; - buf.visible_rect.y1 = draw_y2; + buf.rect = paint_rect; + buf.visible_rect = canvas_rect; buf.is_empty = true; //buf.ct = gdk_cairo_create(widget->window); /* cairo_t *xctt = gdk_cairo_create(widget->window); - cairo_translate(xctt, x0 - canvas->x0, y0 - canvas->y0); + cairo_translate(xctt, paint_rect.left() - canvas->x0, paint_rect.top() - canvas->y0); cairo_set_source_rgb(xctt, 1,0,0); - cairo_rectangle(xctt, 0, 0, x1-x0, y1-y0); + cairo_rectangle(xctt, 0, 0, paint_rect.width(), paint_rect.height()); cairo_fill(xctt); cairo_destroy(xctt); //*/ // create temporary surface - int w = x1 - x0; - int h = y1 - y0; - cairo_surface_t *imgs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, x1 - x0, y1 - y0); + cairo_surface_t *imgs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, paint_rect.width(), paint_rect.height()); buf.ct = cairo_create(imgs); //cairo_translate(buf.ct, -x0, -y0); // fix coordinates, clip all drawing to the tile and clear the background - //cairo_translate(buf.ct, x0 - canvas->x0, y0 - canvas->y0); - //cairo_rectangle(buf.ct, 0, 0, x1 - x0, y1 - y0); + //cairo_translate(buf.ct, paint_rect.left() - canvas->x0, paint_rect.top() - canvas->y0); + //cairo_rectangle(buf.ct, 0, 0, paint_rect.width(), paint_rect.height()); //cairo_set_line_width(buf.ct, 3); //cairo_set_source_rgba(buf.ct, 1.0, 0.0, 0.0, 0.1); //cairo_stroke_preserve(buf.ct); @@ -1681,7 +1673,7 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int gdk_cairo_set_source_color(buf.ct, &widget->style->bg[GTK_STATE_NORMAL]); cairo_set_operator(buf.ct, CAIRO_OPERATOR_SOURCE); - //cairo_rectangle(buf.ct, 0, 0, x1 - x0, y1 - y0); + //cairo_rectangle(buf.ct, 0, 0, paint_rect.width(), paint_rec.height()); cairo_paint(buf.ct); cairo_set_operator(buf.ct, CAIRO_OPERATOR_OVER); @@ -1707,9 +1699,9 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int cairo_surface_flush(imgs); unsigned char *px = cairo_image_surface_get_data(imgs); int stride = cairo_image_surface_get_stride(imgs); - for (int i=0; i<h; ++i) { + for (int i=0; i<paint_rect.height(); ++i) { unsigned char *row = px + i*stride; - Inkscape::CMSSystem::doTransform(transf, row, row, w); + Inkscape::CMSSystem::doTransform(transf, row, row, paint_rect.height()); } cairo_surface_mark_dirty(imgs); } @@ -1717,8 +1709,8 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int #endif // ENABLE_LCMS cairo_t *xct = gdk_cairo_create(widget->window); - cairo_translate(xct, x0 - canvas->x0, y0 - canvas->y0); - cairo_rectangle(xct, 0, 0, x1-x0, y1-y0); + cairo_translate(xct, paint_rect.left() - canvas->x0, paint_rect.top() - canvas->y0); + cairo_rectangle(xct, 0, 0, paint_rect.width(), paint_rect.height()); cairo_clip(xct); cairo_set_source_surface(xct, imgs, 0, 0); cairo_set_operator(xct, CAIRO_OPERATOR_SOURCE); @@ -1734,7 +1726,7 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int struct PaintRectSetup { SPCanvas* canvas; - NRRectL big_rect; + Geom::IntRect big_rect; GTimeVal start_time; int max_pixels; Geom::Point mouse_loc; @@ -1747,7 +1739,7 @@ struct PaintRectSetup { * @return true if the drawing completes */ static int -sp_canvas_paint_rect_internal (PaintRectSetup const *setup, NRRectL this_rect) +sp_canvas_paint_rect_internal (PaintRectSetup const *setup, Geom::IntRect const &this_rect) { GTimeVal now; g_get_current_time (&now); @@ -1782,8 +1774,8 @@ sp_canvas_paint_rect_internal (PaintRectSetup const *setup, NRRectL this_rect) } // Find the optimal buffer dimensions - int bw = this_rect.x1 - this_rect.x0; - int bh = this_rect.y1 - this_rect.y0; + int bw = this_rect.width(); + int bh = this_rect.height(); if ((bw < 1) || (bh < 1)) return 0; @@ -1799,16 +1791,12 @@ sp_canvas_paint_rect_internal (PaintRectSetup const *setup, NRRectL this_rect) gdk_window_begin_paint_rect(window, &r);*/ sp_canvas_paint_single_buffer (setup->canvas, - this_rect.x0, this_rect.y0, - this_rect.x1, this_rect.y1, - setup->big_rect.x0, setup->big_rect.y0, - setup->big_rect.x1, setup->big_rect.y1, bw); + this_rect, setup->big_rect, bw); //gdk_window_end_paint(window); return 1; } - NRRectL lo = this_rect; - NRRectL hi = this_rect; + Geom::IntRect lo, hi; /* This test determines the redraw strategy: @@ -1826,13 +1814,12 @@ faster. The default for now is the strips mode. */ if (bw < bh || bh < 2 * TILE_SIZE) { - // to correctly calculate the mean of two ints, we need to sum them into a larger int type - int mid = ((long long) this_rect.x0 + (long long) this_rect.x1) / 2; + int mid = this_rect[Geom::X].middle(); // Make sure that mid lies on a tile boundary mid = (mid / TILE_SIZE) * TILE_SIZE; - lo.x1 = mid; - hi.x0 = mid; + lo = Geom::IntRect(this_rect.left(), this_rect.top(), mid, this_rect.bottom()); + hi = Geom::IntRect(mid, this_rect.top(), this_rect.right(), this_rect.bottom()); if (setup->mouse_loc[Geom::X] < mid) { // Always paint towards the mouse first @@ -1843,13 +1830,12 @@ The default for now is the strips mode. && sp_canvas_paint_rect_internal(setup, lo); } } else { - // to correctly calculate the mean of two ints, we need to sum them into a larger int type - int mid = ((long long) this_rect.y0 + (long long) this_rect.y1) / 2; + int mid = this_rect[Geom::Y].middle(); // Make sure that mid lies on a tile boundary mid = (mid / TILE_SIZE) * TILE_SIZE; - lo.y1 = mid; - hi.y0 = mid; + lo = Geom::IntRect(this_rect.left(), this_rect.top(), this_rect.right(), mid); + hi = Geom::IntRect(this_rect.left(), mid, this_rect.right(), this_rect.bottom()); if (setup->mouse_loc[Geom::Y] < mid) { // Always paint towards the mouse first @@ -1873,22 +1859,19 @@ sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1) { g_return_val_if_fail (!canvas->need_update, false); - NRRectL rect; - rect.x0 = xx0; - rect.x1 = xx1; - rect.y0 = yy0; - rect.y1 = yy1; + Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(canvas->x0, canvas->y0, + GTK_WIDGET (canvas)->allocation.width, GTK_WIDGET (canvas)->allocation.height); + Geom::IntRect paint_rect(xx0, yy0, xx1, yy1); - // Clip rect-to-draw by the current visible area - rect.x0 = MAX (rect.x0, canvas->x0); - rect.y0 = MAX (rect.y0, canvas->y0); - rect.x1 = MIN (rect.x1, canvas->x0/*draw_x1*/ + GTK_WIDGET (canvas)->allocation.width); - rect.y1 = MIN (rect.y1, canvas->y0/*draw_y1*/ + GTK_WIDGET (canvas)->allocation.height); + Geom::OptIntRect area = paint_rect & canvas_rect; + if (!area || area->hasZeroArea()) return 0; + + paint_rect = *area; PaintRectSetup setup; setup.canvas = canvas; - setup.big_rect = rect; + setup.big_rect = paint_rect; // Save the mouse location gint x, y; @@ -1909,7 +1892,7 @@ sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1) g_get_current_time(&(setup.start_time)); // Go - return sp_canvas_paint_rect_internal(&setup, rect); + return sp_canvas_paint_rect_internal(&setup, paint_rect); } /** @@ -1950,14 +1933,11 @@ sp_canvas_expose (GtkWidget *widget, GdkEventExpose *event) gdk_region_get_rectangles (event->region, &rects, &n_rects); for (int i = 0; i < n_rects; i++) { - NRRectL rect; - - rect.x0 = rects[i].x + canvas->x0; - rect.y0 = rects[i].y + canvas->y0; - rect.x1 = rect.x0 + rects[i].width; - rect.y1 = rect.y0 + rects[i].height; + Geom::IntRect r = Geom::IntRect::from_xywh( + rects[i].x + canvas->x0, rects[i].y + canvas->y0, + rects[i].width, rects[i].height); - sp_canvas_request_redraw (canvas, rect.x0, rect.y0, rect.x1, rect.y1); + sp_canvas_request_redraw (canvas, r.left(), r.top(), r.right(), r.bottom()); } if (n_rects > 0) @@ -2225,30 +2205,21 @@ sp_canvas_request_update (SPCanvas *canvas) void sp_canvas_request_redraw (SPCanvas *canvas, int x0, int y0, int x1, int y1) { - NRRectL bbox; - NRRectL visible; - NRRectL clip; - g_return_if_fail (canvas != NULL); g_return_if_fail (SP_IS_CANVAS (canvas)); if (!gtk_widget_is_drawable ( GTK_WIDGET (canvas))) return; if ((x0 >= x1) || (y0 >= y1)) return; - bbox.x0 = x0; - bbox.y0 = y0; - bbox.x1 = x1; - bbox.y1 = y1; - - visible.x0 = canvas->x0; - visible.y0 = canvas->y0; - visible.x1 = visible.x0 + GTK_WIDGET (canvas)->allocation.width; - visible.y1 = visible.y0 + GTK_WIDGET (canvas)->allocation.height; - - nr_rect_l_intersect (&clip, &bbox, &visible); - - sp_canvas_dirty_rect(canvas, clip.x0, clip.y0, clip.x1, clip.y1); - add_idle (canvas); + Geom::IntRect bbox(x0, y0, x1, y1); + Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(canvas->x0, canvas->y0, + GTK_WIDGET (canvas)->allocation.width, GTK_WIDGET (canvas)->allocation.height); + + Geom::OptIntRect clip = bbox & canvas_rect; + if (clip) { + sp_canvas_dirty_rect(canvas, *clip); + add_idle (canvas); + } } /** @@ -2386,24 +2357,21 @@ static void sp_canvas_resize_tiles(SPCanvas* canvas, int nl, int nt, int nr, int /* * Helper that queues a canvas rectangle for redraw */ -static void sp_canvas_dirty_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb) { +static void sp_canvas_dirty_rect(SPCanvas* canvas, Geom::IntRect const &area) { canvas->need_redraw = TRUE; - sp_canvas_mark_rect(canvas, nl, nt, nr, nb, 1); + sp_canvas_mark_rect(canvas, area, 1); } /** * Helper that marks specific canvas rectangle as clean (val == 0) or dirty (otherwise) */ -void sp_canvas_mark_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb, uint8_t val) +void sp_canvas_mark_rect(SPCanvas* canvas, Geom::IntRect const &area, uint8_t val) { - if ( nl >= nr || nt >= nb ) { - return; - } - int tl=sp_canvas_tile_floor(nl); - int tt=sp_canvas_tile_floor(nt); - int tr=sp_canvas_tile_ceil(nr); - int tb=sp_canvas_tile_ceil(nb); + int tl=sp_canvas_tile_floor(area.left()); + int tt=sp_canvas_tile_floor(area.top()); + int tr=sp_canvas_tile_ceil(area.right()); + int tb=sp_canvas_tile_ceil(area.bottom()); if ( tl >= canvas->tRight || tr <= canvas->tLeft || tt >= canvas->tBottom || tb <= canvas->tTop ) return; if ( tl < canvas->tLeft ) tl=canvas->tLeft; if ( tr > canvas->tRight ) tr=canvas->tRight; diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index f284afdf2..9e716b69c 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -60,8 +60,8 @@ enum { */ struct SPCanvasBuf { cairo_t *ct; - NRRectL rect; - NRRectL visible_rect; + Geom::IntRect rect; + Geom::IntRect visible_rect; unsigned char *buf; int buf_rowstride; diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp index c185234d4..cf70f324e 100644 --- a/src/display/sp-ctrlline.cpp +++ b/src/display/sp-ctrlline.cpp @@ -113,8 +113,8 @@ sp_ctrlline_render (SPCanvasItem *item, SPCanvasBuf *buf) Geom::Point s = cl->s * cl->affine; Geom::Point e = cl->e * cl->affine; - cairo_move_to (buf->ct, s[Geom::X] - buf->rect.x0, s[Geom::Y] - buf->rect.y0); - cairo_line_to (buf->ct, e[Geom::X] - buf->rect.x0, e[Geom::Y] - buf->rect.y0); + cairo_move_to (buf->ct, s[Geom::X] - buf->rect.left(), s[Geom::Y] - buf->rect.top()); + cairo_line_to (buf->ct, e[Geom::X] - buf->rect.left(), e[Geom::Y] - buf->rect.top()); cairo_stroke(buf->ct); } diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp index 1cf7dded0..3a29b9b7c 100644 --- a/src/display/sp-ctrlpoint.cpp +++ b/src/display/sp-ctrlpoint.cpp @@ -105,7 +105,7 @@ sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf) Geom::Point pt = cp->pt * cp->affine; - cairo_arc(buf->ct, pt[Geom::X] - buf->rect.x0, pt[Geom::Y] - buf->rect.y0, cp->radius, 0.0, 2 * M_PI); + cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->radius, 0.0, 2 * M_PI); cairo_stroke(buf->ct); } diff --git a/src/display/sp-ctrlquadr.cpp b/src/display/sp-ctrlquadr.cpp index b39886178..8cdd8170b 100644 --- a/src/display/sp-ctrlquadr.cpp +++ b/src/display/sp-ctrlquadr.cpp @@ -97,15 +97,13 @@ sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf) { SPCtrlQuadr *cq = SP_CTRLQUADR (item); - //Geom::Rect area (Geom::Point(buf->rect.x0, buf->rect.y0), Geom::Point(buf->rect.x1, buf->rect.y1)); - if (!buf->ct) return; // RGB / BGR cairo_new_path(buf->ct); - Geom::Point min = Geom::Point(buf->rect.x0, buf->rect.y0); + Geom::Point min = buf->rect.min(); Geom::Point p1 = (cq->p1 * cq->affine) - min; Geom::Point p2 = (cq->p2 * cq->affine) - min; diff --git a/src/dropper-context.cpp b/src/dropper-context.cpp index 9fbbcdc27..d91642bd2 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -225,25 +225,15 @@ static gint sp_dropper_context_root_handler(SPEventContext *event_context, GdkEv Geom::Rect r(dc->centre, dc->centre); r.expandBy(rw); if (!r.hasZeroArea()) { - NRRectL area; - area.x0 = r[Geom::X].min(); - area.y0 = r[Geom::Y].min(); - area.x1 = r[Geom::X].max(); - area.y1 = r[Geom::Y].max(); - int w = area.x1 - area.x0; - int h = area.y1 - area.y0; - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + Geom::IntRect area = r.roundOutwards(); + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, area.width(), area.height()); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); } } else { // pick single pixel - NRRectL area; - area.x0 = floor(event->button.x); - area.y0 = floor(event->button.y); - area.x1 = area.x0 + 1; - area.y1 = area.y0 + 1; + Geom::IntRect area = Geom::IntRect::from_xywh(floor(event->button.x), floor(event->button.y), 1, 1); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index a3a665b1c..5bc258dbc 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -441,11 +441,7 @@ sp_dyna_draw_brush(SPDynaDrawContext *dc) if (dc->trace_bg) { // pick single pixel double R, G, B, A; - NRRectL area; - area.x0 = floor(brush_w[Geom::X]); - area.y0 = floor(brush_w[Geom::Y]); - area.x1 = area.x0 + 1; - area.y1 = area.y0 + 1; + Geom::IntRect area = Geom::IntRect::from_xywh(brush_w.floor(), Geom::IntPoint(1, 1)); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(SP_EVENT_CONTEXT(dc)->desktop)), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); diff --git a/src/livarot/Path.h b/src/livarot/Path.h index 78e90c34f..6b5d4fd95 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -112,7 +112,6 @@ public: // transforms a description in a polyline (for stroking and filling) // treshhold is the max length^2 (sort of) void Convert (double treshhold); - void Convert(NRRectL *area, double treshhold); void ConvertEvenLines (double treshhold); // decomposes line segments too, for later recomposition // same function for use when you want to later recompose the curves from the polyline void ConvertWithBackData (double treshhold); diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp index 57609d1a2..74a057d06 100644 --- a/src/livarot/PathConversion.cpp +++ b/src/livarot/PathConversion.cpp @@ -401,282 +401,6 @@ void Path::Convert(double treshhold) } } -#define POINT_RELATION_TO_AREA(pt, area) ((pt)[0] < (area)->x0 ? 1 : ((pt)[0] > (area)->x1 ? 2 : ((pt)[1] < (area)->y0 ? 3 : ((pt)[1] > (area)->y1 ? 4 : 0)))) - -void Path::Convert(NRRectL *area, double treshhold) -{ - if ( descr_flags & descr_adding_bezier ) { - CancelBezier(); - } - - if ( descr_flags & descr_doing_subpath ) { - CloseSubpath(); - } - - SetBackData(false); - ResetPoints(); - if ( descr_cmd.empty() ) { - return; - } - - Geom::Point curX; - int curP = 1; - int lastMoveTo = 0; - short last_point_relation = 0; - short curent_point_relation = 0; - bool last_start_elimination = false; - bool start_elimination = false; - bool replace = false; - - // first point - { - int const firstTyp = descr_cmd[0]->getType(); - if ( firstTyp == descr_moveto ) { - curX = dynamic_cast<PathDescrMoveTo *>(descr_cmd[0])->p; - } else { - curP = 0; - curX[0] = curX[1] = 0; - } - - last_point_relation = POINT_RELATION_TO_AREA(curX, area); - lastMoveTo = AddPoint(curX, true); - } - descr_cmd[0]->associated = lastMoveTo; - - // process nodes one by one - while ( curP < int(descr_cmd.size()) ) { - - int const nType = descr_cmd[curP]->getType(); - Geom::Point nextX; - - switch (nType) { - case descr_forced: { - descr_cmd[curP]->associated = AddForcedPoint(curX); - last_point_relation = 0; - curP++; - break; - } - - case descr_moveto: { - PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[curP]); - nextX = nData->p; - lastMoveTo = AddPoint(nextX, true); - descr_cmd[curP]->associated = lastMoveTo; - - last_point_relation = POINT_RELATION_TO_AREA(nextX, area); - start_elimination = false; - - curP++; - break; - } - - case descr_close: { - nextX = pts[lastMoveTo].p; - descr_cmd[curP]->associated = AddPoint(nextX, false); - if ( descr_cmd[curP]->associated < 0 ) { - if ( curP == 0 ) { - descr_cmd[curP]->associated = 0; - } else { - descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; - } - } - if ( descr_cmd[curP]->associated > 0 ) { - pts[descr_cmd[curP]->associated].closed = true; - } - last_point_relation = 0; - curP++; - break; - } - - case descr_lineto: { - PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[curP]); - nextX = nData->p; - curent_point_relation = POINT_RELATION_TO_AREA(nextX, area); - replace = false; - last_start_elimination = start_elimination; - if (curent_point_relation > 0 && curent_point_relation == last_point_relation) { - if (!start_elimination) { - start_elimination = true; - } else { - replace = true; - descr_cmd[curP]->associated = ReplacePoint(nextX); - } - } else { - start_elimination = false; - } - - if (!replace) { - descr_cmd[curP]->associated = AddPoint(nextX, false); - } - - if ( descr_cmd[curP]->associated < 0 ) { - // point is not added as position is equal to the last added - start_elimination = last_start_elimination; - if ( curP == 0 ) { - descr_cmd[curP]->associated = 0; - } else { - descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; - } - } - last_point_relation = curent_point_relation; - curP++; - break; - } - - case descr_cubicto: { - PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[curP]); - nextX = nData->p; - - curent_point_relation = POINT_RELATION_TO_AREA(nextX, area); - replace = false; - last_start_elimination = start_elimination; - if (curent_point_relation > 0 && curent_point_relation == last_point_relation && - curent_point_relation == POINT_RELATION_TO_AREA(curX + (nData->start), area) && - curent_point_relation == POINT_RELATION_TO_AREA(nextX + (nData->end), area)) - { - if (!start_elimination) { - start_elimination = true; - } else { - replace = true; - descr_cmd[curP]->associated = ReplacePoint(nextX); - } - } else { - start_elimination = false; - } - - if (!replace) { - RecCubicTo(curX, nData->start, nextX, nData->end, treshhold, 8); - descr_cmd[curP]->associated = AddPoint(nextX,false); - } - - if ( descr_cmd[curP]->associated < 0 ) { - // point is not added as position is equal to the last added - start_elimination = last_start_elimination; - if ( curP == 0 ) { - descr_cmd[curP]->associated = 0; - } else { - descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; - } - } - last_point_relation = curent_point_relation; - curP++; - break; - } - - case descr_arcto: { - PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[curP]); - nextX = nData->p; - DoArc(curX, nextX, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise, treshhold); - descr_cmd[curP]->associated = AddPoint(nextX, false); - if ( descr_cmd[curP]->associated < 0 ) { - if ( curP == 0 ) { - descr_cmd[curP]->associated = 0; - } else { - descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; - } - } - last_point_relation = 0; - - curP++; - break; - } - - case descr_bezierto: { - PathDescrBezierTo *nBData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[curP]); - int nbInterm = nBData->nb; - nextX = nBData->p; - int curBD = curP; - - curP++; - int ip = curP; - PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]); - - if ( nbInterm == 1 ) { - Geom::Point const midX = nData->p; - RecBezierTo(midX, curX, nextX, treshhold, 8); - } else if ( nbInterm > 1 ) { - Geom::Point bx = curX; - Geom::Point cx = curX; - Geom::Point dx = curX; - - dx = nData->p; - ip++; - nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]); - - cx = 2 * bx - dx; - - for (int k = 0; k < nbInterm - 1; k++) { - bx = cx; - cx = dx; - - dx = nData->p; - ip++; - nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[ip]); - - Geom::Point stx = (bx + cx) / 2; - if ( k > 0 ) { - descr_cmd[ip - 2]->associated = AddPoint(stx, false); - if ( descr_cmd[ip - 2]->associated < 0 ) { - if ( curP == 0 ) { - descr_cmd[ip - 2]->associated = 0; - } else { - descr_cmd[ip - 2]->associated = descr_cmd[ip - 3]->associated; - } - } - } - - { - Geom::Point const mx = (cx + dx) / 2; - RecBezierTo(cx, stx, mx, treshhold, 8); - } - } - - { - bx = cx; - cx = dx; - - dx = nextX; - dx = 2 * dx - cx; - - Geom::Point stx = (bx + cx) / 2; - - descr_cmd[ip - 1]->associated = AddPoint(stx, false); - if ( descr_cmd[ip - 1]->associated < 0 ) { - if ( curP == 0 ) { - descr_cmd[ip - 1]->associated = 0; - } else { - descr_cmd[ip - 1]->associated = descr_cmd[ip - 2]->associated; - } - } - - { - Geom::Point mx = (cx + dx) / 2; - RecBezierTo(cx, stx, mx, treshhold, 8); - } - } - } - - descr_cmd[curBD]->associated = AddPoint(nextX, false); - if ( descr_cmd[curBD]->associated < 0 ) { - if ( curP == 0 ) { - descr_cmd[curBD]->associated = 0; - } else { - descr_cmd[curBD]->associated = descr_cmd[curBD - 1]->associated; - } - } - - last_point_relation = 0; - - curP += nbInterm; - break; - } - } - - curX = nextX; - } -} - - void Path::ConvertEvenLines(double treshhold) { if ( descr_flags & descr_adding_bezier ) { |
