From 2ed673e7554d0fd8b775978a0ef80c9aa529f7de Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 27 Sep 2013 01:45:12 +0200 Subject: Further refactored SPEllipse. (bzr r12601) --- src/arc-context.cpp | 2 +- src/object-edit.cpp | 8 +- src/sp-ellipse.cpp | 265 ++++++++++++++------------------------------ src/sp-ellipse.h | 37 +++++-- src/svg/svg-length.cpp | 8 ++ src/svg/svg-length.h | 1 + src/widgets/arc-toolbar.cpp | 2 +- 7 files changed, 131 insertions(+), 192 deletions(-) (limited to 'src') diff --git a/src/arc-context.cpp b/src/arc-context.cpp index 350df908b..046541b9b 100644 --- a/src/arc-context.cpp +++ b/src/arc-context.cpp @@ -409,7 +409,7 @@ void SPArcContext::drag(Geom::Point pt, guint state) { } } - sp_arc_position_set(SP_ARC(this->arc), + this->arc->sp_arc_position_set( r.midpoint()[Geom::X], r.midpoint()[Geom::Y], r.dimensions()[Geom::X] / 2, r.dimensions()[Geom::Y] / 2); diff --git a/src/object-edit.cpp b/src/object-edit.cpp index 25bc62a7f..5ade37cb1 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -801,7 +801,7 @@ ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*or { ge->start = sp_round(ge->start, M_PI/snaps); } - sp_genericellipse_normalize(ge); + ge->normalize(); (static_cast(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -811,7 +811,7 @@ ArcKnotHolderEntityStart::knot_get() const SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); SPArc *arc = SP_ARC(item); - return sp_arc_get_xy(arc, ge->start); + return arc->getPointAtAngle(ge->start); } void @@ -844,7 +844,7 @@ ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*orig { ge->end = sp_round(ge->end, M_PI/snaps); } - sp_genericellipse_normalize(ge); + ge->normalize(); (static_cast(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -854,7 +854,7 @@ ArcKnotHolderEntityEnd::knot_get() const SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); SPArc *arc = SP_ARC(item); - return sp_arc_get_xy(arc, ge->end); + return arc->getPointAtAngle(ge->end); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index fc78b9777..e556f0dc5 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -24,6 +24,8 @@ #include "style.h" #include "display/curve.h" #include +#include <2geom/angle.h> +#include <2geom/ellipse.h> #include <2geom/transforms.h> #include <2geom/pathvector.h> #include <2geom/svg-path.h> @@ -32,8 +34,6 @@ #include "preferences.h" #include "snap-candidate.h" -/* Common parent class */ - #define noELLIPSE_VERBOSE @@ -64,40 +64,12 @@ namespace { #define SP_2PI (2 * M_PI) -#if 1 -/* Hmmm... shouldn't this also qualify */ -/* Whether it is faster or not, well, nobody knows */ -#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) -#else -/* we do not use C99 round(3) function yet */ -static double sp_round(double x, double y) +SPGenericEllipse::SPGenericEllipse() + : SPShape() + , closed(true) + , start(0) + , end(SP_2PI) { - double remain; - - g_assert(y > 0.0); - - /* return round(x/y) * y; */ - - remain = fmod(x, y); - - if (remain >= 0.5*y) - return x - remain + y; - else - return x - remain; -} -#endif - -static gboolean sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr); - -SPGenericEllipse::SPGenericEllipse() : SPShape() { - this->cx.unset(); - this->cy.unset(); - this->rx.unset(); - this->ry.unset(); - - this->start = 0.0; - this->end = SP_2PI; - this->closed = TRUE; } SPGenericEllipse::~SPGenericEllipse() { @@ -109,7 +81,7 @@ void SPGenericEllipse::update(SPCtx *ctx, guint flags) { double const dx = viewbox.width(); double const dy = viewbox.height(); - double const dr = sqrt(dx*dx + dy*dy)/sqrt(2); + double const dr = hypot(dx, dy) / sqrt(2); double const em = this->style->font_size.computed; double const ex = em * 0.5; // fixme: get from pango or libnrtype @@ -142,13 +114,22 @@ void SPGenericEllipse::update_patheffect(bool write) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -#include <2geom/ellipse.h> +bool SPGenericEllipse::isSlice() const { + // figure out if we have a slice, guarding against rounding errors + double diff = fmod(this->end - this->start, SP_2PI); + + if (diff < 0.0) { + diff += SP_2PI; + } + + return (fabs(diff) >= 1e-8 && fabs(diff - SP_2PI) >= 1e-8); +} /* fixme: Think (Lauris) */ /* Can't we use arcto in this method? */ void SPGenericEllipse::set_shape() { if (hasBrokenPathEffect()) { - g_warning ("The ellipse shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as ellipse will remove the bad LPE"); + g_warning("The ellipse shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as ellipse will remove the bad LPE"); if (this->getRepr()->attribute("d")) { // unconditionally read the curve from d, if any, to preserve appearance @@ -169,32 +150,17 @@ void SPGenericEllipse::set_shape() { return; } - sp_genericellipse_normalize(this); - - // figure out if we have a slice, guarding against rounding errors - double len = fmod(this->end - this->start, SP_2PI); - - if (len < 0.0) { - len += SP_2PI; - } - - bool slice = false; - - if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) { - slice = false; - this->end = this->start + SP_2PI; - } else { - slice = true; - } + this->normalize(); SPCurve *curve = NULL; // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. - if (slice) { - Geom::Point startPoint(cos(start), sin(start)); - Geom::Point endPoint(cos(end), sin(end)); - Geom::Point middlePoint = make_angle_bisector_ray(Geom::Ray(Geom::Point(), start), Geom::Ray(Geom::Point(), end)).versor(); + if (this->isSlice()) { + Geom::Point center(0, 0); + Geom::Point startPoint = Geom::Point::polar(start); + Geom::Point endPoint = Geom::Point::polar(end); + Geom::Point middlePoint = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor(); Geom::Ellipse ellipse(0, 0, 1, 1, 0); Geom::EllipticalArc *arc = ellipse.arc(startPoint, middlePoint, endPoint); @@ -209,7 +175,7 @@ void SPGenericEllipse::set_shape() { if (this->closed) { // "pizza slice" - pb.lineTo(Geom::Point(0, 0)); + pb.lineTo(center); pb.closePath(); } else { // arc only @@ -252,69 +218,49 @@ void SPGenericEllipse::set_shape() { } void SPGenericEllipse::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { - sp_genericellipse_normalize(this); + this->normalize(); Geom::Affine const i2dt = this->i2dt_affine(); - // figure out if we have a slice, while guarding against rounding errors - bool slice = false; - double len = fmod(this->end - this->start, SP_2PI); - - if (len < 0.0) { - len += SP_2PI; - } - - if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) { - slice = false; - this->end = this->start + SP_2PI; - } else { - slice = true; - } - - double rx = this->rx.computed; - double ry = this->ry.computed; - double cx = this->cx.computed; - double cy = this->cy.computed; - - // Snap to the 4 quadrant points of the this, but only if the arc + // Snap to the 4 quadrant points of the ellipse, but only if the arc // spans far enough to include them if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)) { double angle = 0; for (angle = 0; angle < SP_2PI; angle += M_PI_2) { if (angle >= this->start && angle <= this->end) { - Geom::Point pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2dt; + Geom::Point pt = this->getPointAtAngle(angle) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT, Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)); } } } - // Add the centre, if we have a closed slice or when explicitly asked for - bool c1 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->closed; - bool c2 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT); + double cx = this->cx.computed; + double cy = this->cy.computed; - if (c1 || c2) { - Geom::Point pt = Geom::Point(cx, cy) * i2dt; + bool slice = this->isSlice(); - if (c1) { - p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); - } + // Add the centre, if we have a closed slice or when explicitly asked for + if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->closed) { + Geom::Point pt = Geom::Point(cx, cy) * i2dt; + p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); + } - if (c2) { - p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT)); - } + if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) { + Geom::Point pt = Geom::Point(cx, cy) * i2dt; + p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT)); } // And if we have a slice, also snap to the endpoints if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) { // Add the start point, if it's not coincident with a quadrant point if (fmod(this->start, M_PI_2) != 0.0 ) { - Geom::Point pt = Geom::Point(cx + cos(this->start)*rx, cy + sin(this->start)*ry) * i2dt; + Geom::Point pt = this->getPointAtAngle(this->start) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } // Add the end point, if it's not coincident with a quadrant point if (fmod(this->end, M_PI_2) != 0.0 ) { - Geom::Point pt = Geom::Point(cx + cos(this->end)*rx, cy + sin(this->end)*ry) * i2dt; + Geom::Point pt = this->getPointAtAngle(this->end) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } } @@ -330,6 +276,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); gdouble const sw = hypot(ret[0], ret[1]); gdouble const sh = hypot(ret[2], ret[3]); + if (sw > 1e-9) { ret[0] /= sw; ret[1] /= sw; @@ -337,6 +284,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) ret[0] = 1.0; ret[1] = 0.0; } + if (sh > 1e-9) { ret[2] /= sh; ret[3] /= sh; @@ -348,6 +296,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) if (this->rx._set) { this->rx = this->rx.computed * sw; } + if (this->ry._set) { this->ry = this->ry.computed * sh; } @@ -373,20 +322,18 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) return ret; } -void -sp_genericellipse_normalize(SPGenericEllipse *ellipse) -{ - ellipse->start = fmod(ellipse->start, SP_2PI); - ellipse->end = fmod(ellipse->end, SP_2PI); +void SPGenericEllipse::normalize() { + this->start = fmod(this->start, SP_2PI); + this->end = fmod(this->end, SP_2PI); - if (ellipse->start < 0.0) { - ellipse->start += SP_2PI; + if (this->start < 0.0) { + this->start += SP_2PI; } - double diff = ellipse->start - ellipse->end; + double diff = this->start - this->end; if (diff >= 0.0) { - ellipse->end += diff - fmod(diff, SP_2PI) + SP_2PI; + this->end += diff - fmod(diff, SP_2PI) + SP_2PI; } /* Now we keep: 0 <= start < end <= 2*PI */ @@ -404,7 +351,7 @@ Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); if (SP_IS_ARC(this)) { - sp_arc_set_elliptical_path_attribute(SP_ARC(this), this->getRepr()); + SP_ARC(this)->sp_arc_set_elliptical_path_attribute(this->getRepr()); } } @@ -487,24 +434,6 @@ const char* SPEllipse::displayName() { } -void -sp_ellipse_position_set(SPEllipse *ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry) -{ - SPGenericEllipse *ge; - - g_return_if_fail(ellipse != NULL); - g_return_if_fail(SP_IS_ELLIPSE(ellipse)); - - ge = SP_GENERICELLIPSE(ellipse); - - ge->cx.computed = x; - ge->cy.computed = y; - ge->rx.computed = rx; - ge->ry.computed = ry; - - ((SPObject *)ge)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - /* SVG element */ SPCircle::SPCircle() : SPGenericEllipse() { } @@ -594,32 +523,32 @@ void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) { * See SVG 1.0 Specification W3C Recommendation * ``F.6 Ellptical arc implementation notes'' for more detail. */ -static gboolean -sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); - +bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) { Inkscape::SVG::PathString str; - Geom::Point p1 = sp_arc_get_xy(arc, ge->start); - Geom::Point p2 = sp_arc_get_xy(arc, ge->end); - double rx = ge->rx.computed; - double ry = ge->ry.computed; + Geom::Point p1 = this->getPointAtAngle(this->start); + Geom::Point p2 = this->getPointAtAngle(this->end); + double rx = this->rx.computed; + double ry = this->ry.computed; str.moveTo(p1); - double dt = fmod(ge->end - ge->start, SP_2PI); + double dt = fmod(this->end - this->start, SP_2PI); + if (fabs(dt) < 1e-6) { - Geom::Point ph = sp_arc_get_xy(arc, (ge->start + ge->end) / 2.0); + Geom::Point ph = getPointAtAngle((this->start + this->end) / 2.0); + str.arcTo(rx, ry, 0, true, true, ph) .arcTo(rx, ry, 0, true, true, p2) .closePath(); } else { bool fa = (fabs(dt) > M_PI); bool fs = (dt > 0); + str.arcTo(rx, ry, 0, fa, fs, p2); - if (ge->closed) { - Geom::Point center = Geom::Point(ge->cx.computed, ge->cy.computed); + + if (this->closed) { + Geom::Point center = Geom::Point(this->cx.computed, this->cy.computed); str.lineTo(center).closePath(); } } @@ -642,13 +571,7 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); // write start and end only if they are non-trivial; otherwise remove - gdouble len = fmod(this->end - this->start, SP_2PI); - - if (len < 0.0) { - len += SP_2PI; - } - - if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) { + if (this->isSlice()) { sp_repr_set_svg_double(repr, "sodipodi:start", this->start); sp_repr_set_svg_double(repr, "sodipodi:end", this->end); @@ -661,7 +584,7 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM } // write d= - sp_arc_set_elliptical_path_attribute(this, repr); + this->sp_arc_set_elliptical_path_attribute(repr); SPGenericEllipse::write(xml_doc, repr, flags); @@ -735,15 +658,8 @@ void SPArc::modified(guint flags) { SPGenericEllipse::modified(flags); } - const char* SPArc::displayName() { - gdouble len = fmod(this->end - this->start, SP_2PI); - - if (len < 0.0) { - len += SP_2PI; - } - - if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) { + if (this->isSlice()) { if (this->closed) { return _("Segment"); } else { @@ -754,40 +670,31 @@ const char* SPArc::displayName() { } } -void -sp_arc_position_set(SPArc *arc, gdouble x, gdouble y, gdouble rx, gdouble ry) -{ - g_return_if_fail(arc != NULL); - g_return_if_fail(SP_IS_ARC(arc)); - - SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); +void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) { + this->cx.computed = x; + this->cy.computed = y; + this->rx.computed = rx; + this->ry.computed = ry; - ge->cx.computed = x; - ge->cy.computed = y; - ge->rx.computed = rx; - ge->ry.computed = ry; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + // those pref values are in degrees, while we want radians - if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) - ge->start = prefs->getDouble("/tools/shapes/arc/start", 0.0) * M_PI / 180; - if (prefs->getDouble("/tools/shapes/arc/end", 0.0) != 0) - ge->end = prefs->getDouble("/tools/shapes/arc/end", 0.0) * M_PI / 180; - if (!prefs->getBool("/tools/shapes/arc/open")) - ge->closed = 1; - else - ge->closed = 0; + if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) { + this->start = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/start", 0.0)).radians0(); + } - ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} + if (prefs->getDouble("/tools/shapes/arc/end", 0.0) != 0) { + this->end = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/end", 0.0)).radians0(); + } -Geom::Point sp_arc_get_xy(SPArc *arc, gdouble arg) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); + this->closed = !prefs->getBool("/tools/shapes/arc/open"); - return Geom::Point(ge->rx.computed * cos(arg) + ge->cx.computed, - ge->ry.computed * sin(arg) + ge->cy.computed); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } +Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const { + return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); +} /* Local Variables: diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index 083f5847d..8c0f034cb 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -31,7 +31,9 @@ public: SVGLength rx; SVGLength ry; - unsigned int closed : 1; + // Stores whether the shape is closed ("pizza slice" or full ellipse) or not (arc only). + bool closed; + double start, end; virtual void update(SPCtx* ctx, unsigned int flags); @@ -42,10 +44,16 @@ public: virtual Geom::Affine set_transform(Geom::Affine const& xform); virtual void update_patheffect(bool write); + + void normalize(); + + Geom::Point getPointAtAngle(double arg) const; + +protected: + /// Determines whether the shape is a part of a ellipse. + bool isSlice() const; }; -/* This is technically priate by we need this in object edit (Lauris) */ -void sp_genericellipse_normalize (SPGenericEllipse *ellipse); /* SVG element */ #define SP_ELLIPSE(obj) (dynamic_cast((SPObject*)obj)) @@ -62,7 +70,6 @@ public: virtual const char* displayName(); }; -void sp_ellipse_position_set (SPEllipse * ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry); /* SVG element */ #define SP_CIRCLE(obj) (dynamic_cast((SPObject*)obj)) @@ -79,6 +86,7 @@ public: virtual const char* displayName(); }; + /* element */ #define SP_ARC(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_ARC(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -93,9 +101,24 @@ public: virtual void set(unsigned int key, gchar const* value); virtual const char* displayName(); virtual void modified(unsigned int flags); -}; -void sp_arc_position_set (SPArc * arc, gdouble x, gdouble y, gdouble rx, gdouble ry); -Geom::Point sp_arc_get_xy (SPArc *ge, gdouble arg); + void sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry); + +private: + bool sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr); + + friend class SPGenericEllipse; +}; #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/svg/svg-length.cpp b/src/svg/svg-length.cpp index bb6cc5428..8d26a95d2 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -171,6 +171,14 @@ unsigned int sp_svg_number_write_de(gchar *buf, int bufLen, double val, unsigned } } +SVGLength::SVGLength() + : _set(false) + , unit(NONE) + , value(0) + , computed(0) +{ +} + /* Length */ bool SVGLength::read(gchar const *str) diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index 3832a4eb5..477b3ef81 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -21,6 +21,7 @@ class SVGLength { public: + SVGLength(); enum Unit { NONE, diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 42f696bec..c31c61e32 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -123,7 +123,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180; } - sp_genericellipse_normalize(ge); + ge->normalize(); (SP_OBJECT(arc))->updateRepr(); (SP_OBJECT(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -- cgit v1.2.3 From fc710269ffba364187eb44df32d868addbbf30d9 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Fri, 27 Sep 2013 02:30:21 +0200 Subject: Adjusted code style of SPEllipse. (bzr r12602) --- src/measure-context.cpp | 8 +- src/sp-ellipse.cpp | 383 ++++++++++++++++++++++++++---------------------- src/sp-ellipse.h | 82 +++++------ 3 files changed, 253 insertions(+), 220 deletions(-) (limited to 'src') diff --git a/src/measure-context.cpp b/src/measure-context.cpp index 8db703205..9d8dc2b2f 100644 --- a/src/measure-context.cpp +++ b/src/measure-context.cpp @@ -48,10 +48,6 @@ using Inkscape::ControlManager; using Inkscape::CTLINE_SECONDARY; using Inkscape::Util::unit_table; -Geom::Point start_point; -boost::optional explicitBase; -boost::optional lastEnd; - std::vector measure_tmp_items; @@ -313,6 +309,10 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: } bool SPMeasureContext::root_handler(GdkEvent* event) { + Geom::Point start_point; + boost::optional explicitBase; + boost::optional lastEnd; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index e556f0dc5..bc6aa1c87 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -40,21 +40,24 @@ #include "sp-factory.h" namespace { - SPObject* createEllipse() { - return new SPEllipse(); - } +SPObject *create_ellipse() +{ + return new SPEllipse(); +} - SPObject* createCircle() { - return new SPCircle(); - } +SPObject *create_circle() +{ + return new SPCircle(); +} - SPObject* createArc() { - return new SPArc(); - } +SPObject *create_arc() +{ + return new SPArc(); +} - bool ellipseRegistered = SPFactory::instance().registerObject("svg:ellipse", createEllipse); - bool circleRegistered = SPFactory::instance().registerObject("svg:circle", createCircle); - bool arcRegistered = SPFactory::instance().registerObject("arc", createArc); +bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse); +bool circle_registered = SPFactory::instance().registerObject("svg:circle", create_circle); +bool arc_registered = SPFactory::instance().registerObject("arc", create_arc); } @@ -72,10 +75,12 @@ SPGenericEllipse::SPGenericEllipse() { } -SPGenericEllipse::~SPGenericEllipse() { +SPGenericEllipse::~SPGenericEllipse() +{ } -void SPGenericEllipse::update(SPCtx *ctx, guint flags) { +void SPGenericEllipse::update(SPCtx *ctx, guint flags) +{ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { Geom::Rect const &viewbox = ((SPItemCtx const *) ctx)->viewport; @@ -96,13 +101,14 @@ void SPGenericEllipse::update(SPCtx *ctx, guint flags) { SPShape::update(ctx, flags); } -void SPGenericEllipse::update_patheffect(bool write) { +void SPGenericEllipse::update_patheffect(bool write) +{ this->set_shape(); if (write) { Inkscape::XML::Node *repr = this->getRepr(); - if ( this->_curve != NULL ) { + if (this->_curve != NULL) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); g_free(str); @@ -114,7 +120,8 @@ void SPGenericEllipse::update_patheffect(bool write) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -bool SPGenericEllipse::isSlice() const { +bool SPGenericEllipse::_isSlice() const +{ // figure out if we have a slice, guarding against rounding errors double diff = fmod(this->end - this->start, SP_2PI); @@ -127,7 +134,8 @@ bool SPGenericEllipse::isSlice() const { /* fixme: Think (Lauris) */ /* Can't we use arcto in this method? */ -void SPGenericEllipse::set_shape() { +void SPGenericEllipse::set_shape() +{ if (hasBrokenPathEffect()) { g_warning("The ellipse shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as ellipse will remove the bad LPE"); @@ -135,7 +143,7 @@ void SPGenericEllipse::set_shape() { // unconditionally read the curve from d, if any, to preserve appearance Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d")); SPCurve *cold = new SPCurve(pv); - this->setCurveInsync( cold, TRUE); + this->setCurveInsync(cold, TRUE); cold->unref(); } @@ -143,11 +151,11 @@ void SPGenericEllipse::set_shape() { } if ((this->rx.computed < 1e-18) || (this->ry.computed < 1e-18)) { - return; + return; } if (fabs(this->end - this->start) < 1e-9) { - return; + return; } this->normalize(); @@ -156,16 +164,16 @@ void SPGenericEllipse::set_shape() { // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. - if (this->isSlice()) { + if (this->_isSlice()) { Geom::Point center(0, 0); - Geom::Point startPoint = Geom::Point::polar(start); - Geom::Point endPoint = Geom::Point::polar(end); - Geom::Point middlePoint = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor(); + Geom::Point start_point = Geom::Point::polar(start); + Geom::Point end_point = Geom::Point::polar(end); + Geom::Point middle_point = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor(); Geom::Ellipse ellipse(0, 0, 1, 1, 0); - Geom::EllipticalArc *arc = ellipse.arc(startPoint, middlePoint, endPoint); + Geom::EllipticalArc *arc = ellipse.arc(start_point, middle_point, end_point); - Geom::Path path(startPoint); + Geom::Path path(start_point); path.append(*arc); delete arc; @@ -200,7 +208,7 @@ void SPGenericEllipse::set_shape() { /* Reset the shape's curve to the "original_curve" * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ - this->setCurveInsync( curve, TRUE); + this->setCurveInsync(curve, TRUE); this->setCurveBeforeLPE(curve); if (hasPathEffect() && sp_lpe_item_path_effects_enabled(this)) { @@ -208,7 +216,7 @@ void SPGenericEllipse::set_shape() { bool success = sp_lpe_item_perform_path_effect(this, c_lpe); if (success) { - this->setCurveInsync( c_lpe, TRUE); + this->setCurveInsync(c_lpe, TRUE); } c_lpe->unref(); @@ -217,7 +225,8 @@ void SPGenericEllipse::set_shape() { curve->unref(); } -void SPGenericEllipse::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) { +void SPGenericEllipse::snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) +{ this->normalize(); Geom::Affine const i2dt = this->i2dt_affine(); @@ -237,7 +246,7 @@ void SPGenericEllipse::snappoints(std::vector &p, double cx = this->cx.computed; double cy = this->cy.computed; - bool slice = this->isSlice(); + bool slice = this->_isSlice(); // Add the centre, if we have a closed slice or when explicitly asked for if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->closed) { @@ -253,13 +262,13 @@ void SPGenericEllipse::snappoints(std::vector &p, // And if we have a slice, also snap to the endpoints if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) { // Add the start point, if it's not coincident with a quadrant point - if (fmod(this->start, M_PI_2) != 0.0 ) { + if (fmod(this->start, M_PI_2) != 0.0) { Geom::Point pt = this->getPointAtAngle(this->start) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } // Add the end point, if it's not coincident with a quadrant point - if (fmod(this->end, M_PI_2) != 0.0 ) { + if (fmod(this->end, M_PI_2) != 0.0) { Geom::Point pt = this->getPointAtAngle(this->end) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } @@ -269,7 +278,7 @@ void SPGenericEllipse::snappoints(std::vector &p, Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) { /* Calculate ellipse start in parent coords. */ - Geom::Point pos( Geom::Point(this->cx.computed, this->cy.computed) * xform ); + Geom::Point pos(Geom::Point(this->cx.computed, this->cy.computed) * xform); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ @@ -322,7 +331,8 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) return ret; } -void SPGenericEllipse::normalize() { +void SPGenericEllipse::normalize() +{ this->start = fmod(this->start, SP_2PI); this->end = fmod(this->end, SP_2PI); @@ -339,7 +349,8 @@ void SPGenericEllipse::normalize() { /* Now we keep: 0 <= start < end <= 2*PI */ } -Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if (flags & SP_OBJECT_WRITE_EXT) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:path"); @@ -363,23 +374,27 @@ Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I } /* SVG element */ -SPEllipse::SPEllipse() : SPGenericEllipse() { +SPEllipse::SPEllipse() : SPGenericEllipse() +{ } -SPEllipse::~SPEllipse() { +SPEllipse::~SPEllipse() +{ } -void SPEllipse::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPGenericEllipse::build(document, repr); +void SPEllipse::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPGenericEllipse::build(document, repr); - this->readAttr( "cx" ); - this->readAttr( "cy" ); - this->readAttr( "rx" ); - this->readAttr( "ry" ); + this->readAttr("cx"); + this->readAttr("cy"); + this->readAttr("rx"); + this->readAttr("ry"); } -Inkscape::XML::Node* SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node *SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:ellipse"); } @@ -395,62 +410,68 @@ Inkscape::XML::Node* SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape } -void SPEllipse::set(unsigned int key, gchar const* value) { +void SPEllipse::set(unsigned int key, gchar const *value) +{ switch (key) { - case SP_ATTR_CX: - this->cx.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_CY: - this->cy.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_RX: - if (!this->rx.read(value) || (this->rx.value <= 0.0)) { - this->rx.unset(); - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_RY: - if (!this->ry.read(value) || (this->ry.value <= 0.0)) { - this->ry.unset(); - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - default: - SPGenericEllipse::set(key, value); - break; + case SP_ATTR_CX: + this->cx.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_CY: + this->cy.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_RX: + if (!this->rx.read(value) || (this->rx.value <= 0.0)) { + this->rx.unset(); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_RY: + if (!this->ry.read(value) || (this->ry.value <= 0.0)) { + this->ry.unset(); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + default: + SPGenericEllipse::set(key, value); + break; } } -const char* SPEllipse::displayName() { +const char *SPEllipse::displayName() +{ return _("Ellipse"); } /* SVG element */ -SPCircle::SPCircle() : SPGenericEllipse() { +SPCircle::SPCircle() : SPGenericEllipse() +{ } -SPCircle::~SPCircle() { +SPCircle::~SPCircle() +{ } -void SPCircle::build(SPDocument *document, Inkscape::XML::Node *repr) { +void SPCircle::build(SPDocument *document, Inkscape::XML::Node *repr) +{ SPGenericEllipse::build(document, repr); - this->readAttr( "cx" ); - this->readAttr( "cy" ); - this->readAttr( "r" ); + this->readAttr("cx"); + this->readAttr("cy"); + this->readAttr("r"); } -Inkscape::XML::Node* SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node *SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:circle"); } @@ -464,55 +485,60 @@ Inkscape::XML::Node* SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape: return repr; } -void SPCircle::set(unsigned int key, gchar const* value) { +void SPCircle::set(unsigned int key, gchar const *value) +{ switch (key) { - case SP_ATTR_CX: - this->cx.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_CY: - this->cy.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_R: - if (!this->rx.read(value) || this->rx.value <= 0.0) { - this->rx.unset(); - } - - this->ry = this->rx; - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - default: - SPGenericEllipse::set(key, value); - break; + case SP_ATTR_CX: + this->cx.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_CY: + this->cy.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_R: + if (!this->rx.read(value) || this->rx.value <= 0.0) { + this->rx.unset(); + } + + this->ry = this->rx; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + default: + SPGenericEllipse::set(key, value); + break; } } -const char* SPCircle::displayName() { - return _("Circle"); +const char *SPCircle::displayName() +{ + return _("Circle"); } /* element */ -SPArc::SPArc() : SPGenericEllipse() { +SPArc::SPArc() : SPGenericEllipse() +{ } -SPArc::~SPArc() { +SPArc::~SPArc() +{ } -void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPGenericEllipse::build(document, repr); +void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPGenericEllipse::build(document, repr); - this->readAttr( "sodipodi:cx" ); - this->readAttr( "sodipodi:cy" ); - this->readAttr( "sodipodi:rx" ); - this->readAttr( "sodipodi:ry" ); + this->readAttr("sodipodi:cx"); + this->readAttr("sodipodi:cy"); + this->readAttr("sodipodi:rx"); + this->readAttr("sodipodi:ry"); - this->readAttr( "sodipodi:start" ); - this->readAttr( "sodipodi:end" ); - this->readAttr( "sodipodi:open" ); + this->readAttr("sodipodi:start"); + this->readAttr("sodipodi:end"); + this->readAttr("sodipodi:open"); } /* @@ -523,7 +549,8 @@ void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) { * See SVG 1.0 Specification W3C Recommendation * ``F.6 Ellptical arc implementation notes'' for more detail. */ -bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) { +bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) +{ Inkscape::SVG::PathString str; Geom::Point p1 = this->getPointAtAngle(this->start); @@ -539,8 +566,8 @@ bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) { Geom::Point ph = getPointAtAngle((this->start + this->end) / 2.0); str.arcTo(rx, ry, 0, true, true, ph) - .arcTo(rx, ry, 0, true, true, p2) - .closePath(); + .arcTo(rx, ry, 0, true, true, p2) + .closePath(); } else { bool fa = (fabs(dt) > M_PI); bool fs = (dt > 0); @@ -557,7 +584,8 @@ bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) { return true; } -Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node *SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:path"); } @@ -571,7 +599,7 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); // write start and end only if they are non-trivial; otherwise remove - if (this->isSlice()) { + if (this->_isSlice()) { sp_repr_set_svg_double(repr, "sodipodi:start", this->start); sp_repr_set_svg_double(repr, "sodipodi:end", this->end); @@ -591,66 +619,68 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM return repr; } -void SPArc::set(unsigned int key, gchar const* value) { +void SPArc::set(unsigned int key, gchar const *value) +{ switch (key) { - case SP_ATTR_SODIPODI_CX: - this->cx.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_SODIPODI_CY: - this->cy.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_SODIPODI_RX: - if (!this->rx.read(value) || this->rx.computed <= 0.0) { - this->rx.unset(); - } + case SP_ATTR_SODIPODI_CX: + this->cx.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_SODIPODI_CY: + this->cy.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_SODIPODI_RX: + if (!this->rx.read(value) || this->rx.computed <= 0.0) { + this->rx.unset(); + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; - case SP_ATTR_SODIPODI_RY: - if (!this->ry.read(value) || this->ry.computed <= 0.0) { - this->ry.unset(); - } + case SP_ATTR_SODIPODI_RY: + if (!this->ry.read(value) || this->ry.computed <= 0.0) { + this->ry.unset(); + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; - case SP_ATTR_SODIPODI_START: - if (value) { - sp_svg_number_read_d(value, &this->start); - } else { - this->start = 0; - } + case SP_ATTR_SODIPODI_START: + if (value) { + sp_svg_number_read_d(value, &this->start); + } else { + this->start = 0; + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; - case SP_ATTR_SODIPODI_END: - if (value) { - sp_svg_number_read_d(value, &this->end); - } else { - this->end = 2 * M_PI; - } + case SP_ATTR_SODIPODI_END: + if (value) { + sp_svg_number_read_d(value, &this->end); + } else { + this->end = 2 * M_PI; + } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; - case SP_ATTR_SODIPODI_OPEN: - this->closed = (!value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + case SP_ATTR_SODIPODI_OPEN: + this->closed = (!value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; - default: - SPGenericEllipse::set(key, value); - break; + default: + SPGenericEllipse::set(key, value); + break; } } -void SPArc::modified(guint flags) { +void SPArc::modified(guint flags) +{ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { this->set_shape(); } @@ -658,8 +688,9 @@ void SPArc::modified(guint flags) { SPGenericEllipse::modified(flags); } -const char* SPArc::displayName() { - if (this->isSlice()) { +const char *SPArc::displayName() +{ + if (this->_isSlice()) { if (this->closed) { return _("Segment"); } else { @@ -670,7 +701,8 @@ const char* SPArc::displayName() { } } -void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) { +void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) +{ this->cx.computed = x; this->cy.computed = y; this->rx.computed = rx; @@ -692,7 +724,8 @@ void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const { +Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const +{ return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); } diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index 8c0f034cb..d817b5511 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -23,35 +23,35 @@ class SPGenericEllipse : public SPShape { public: - SPGenericEllipse(); - virtual ~SPGenericEllipse(); + SPGenericEllipse(); + virtual ~SPGenericEllipse(); - SVGLength cx; - SVGLength cy; - SVGLength rx; - SVGLength ry; + SVGLength cx; + SVGLength cy; + SVGLength rx; + SVGLength ry; - // Stores whether the shape is closed ("pizza slice" or full ellipse) or not (arc only). - bool closed; + // Stores whether the shape is closed ("pizza slice" or full ellipse) or not (arc only). + bool closed; - double start, end; + double start, end; - virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs); - virtual void set_shape(); - virtual Geom::Affine set_transform(Geom::Affine const& xform); + virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs); + virtual void set_shape(); + virtual Geom::Affine set_transform(Geom::Affine const &xform); - virtual void update_patheffect(bool write); + virtual void update_patheffect(bool write); - void normalize(); + void normalize(); - Geom::Point getPointAtAngle(double arg) const; + Geom::Point getPointAtAngle(double arg) const; protected: - /// Determines whether the shape is a part of a ellipse. - bool isSlice() const; + /// Determines whether the shape is a part of a ellipse. + bool _isSlice() const; }; @@ -61,13 +61,13 @@ protected: class SPEllipse : public SPGenericEllipse { public: - SPEllipse(); - virtual ~SPEllipse(); + SPEllipse(); + virtual ~SPEllipse(); - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void set(unsigned int key, gchar const* value); - virtual const char* displayName(); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, gchar const *value); + virtual const char *displayName(); }; @@ -77,13 +77,13 @@ public: class SPCircle : public SPGenericEllipse { public: - SPCircle(); - virtual ~SPCircle(); + SPCircle(); + virtual ~SPCircle(); - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void set(unsigned int key, gchar const* value); - virtual const char* displayName(); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, gchar const *value); + virtual const char *displayName(); }; @@ -93,21 +93,21 @@ public: class SPArc : public SPGenericEllipse { public: - SPArc(); - virtual ~SPArc(); + SPArc(); + virtual ~SPArc(); - virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void set(unsigned int key, gchar const* value); - virtual const char* displayName(); - virtual void modified(unsigned int flags); + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, gchar const *value); + virtual const char *displayName(); + virtual void modified(unsigned int flags); - void sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry); + void sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry); private: - bool sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr); + bool sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr); - friend class SPGenericEllipse; + friend class SPGenericEllipse; }; #endif -- cgit v1.2.3 From 8bdeca099355f46c4f112144474ca470889dc668 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 27 Sep 2013 22:05:56 +0200 Subject: cppcheck: performance + variable type (bzr r12603) --- src/libavoid/vertices.h | 2 +- src/libcola/connected_components.cpp | 8 ++++---- src/libcola/cycle_detector.cpp | 4 ++-- src/libcola/gradient_projection.cpp | 2 +- src/libcola/straightener.cpp | 18 +++++++++--------- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/libavoid/vertices.h b/src/libavoid/vertices.h index b07c87f95..619692c23 100644 --- a/src/libavoid/vertices.h +++ b/src/libavoid/vertices.h @@ -129,7 +129,7 @@ class VertInfList unsigned int shapesSize(void) const; void stats(FILE *fp = stderr) { - fprintf(fp, "Conns %d, shapes %d\n", _connVertices, + fprintf(fp, "Conns %u, shapes %u\n", _connVertices, _shapeVertices); } private: diff --git a/src/libcola/connected_components.cpp b/src/libcola/connected_components.cpp index 1afec55b4..823f7cf6e 100644 --- a/src/libcola/connected_components.cpp +++ b/src/libcola/connected_components.cpp @@ -77,7 +77,7 @@ namespace cola { } vector::const_iterator ei; SimpleConstraints::const_iterator ci; - for(ei=es.begin();ei!=es.end();ei++) { + for(ei=es.begin();ei!=es.end();++ei) { vs[ei->first].neighbours.push_back(&vs[ei->second]); vs[ei->second].neighbours.push_back(&vs[ei->first]); } @@ -88,13 +88,13 @@ namespace cola { dfs(v,remaining,component,cmap); components.push_back(component); } - for(ei=es.begin();ei!=es.end();ei++) { + for(ei=es.begin();ei!=es.end();++ei) { pair u=cmap[ei->first], v=cmap[ei->second]; assert(u.first==v.first); u.first->edges.push_back(make_pair(u.second,v.second)); } - for(ci=scx.begin();ci!=scx.end();ci++) { + for(ci=scx.begin();ci!=scx.end();++ci) { SimpleConstraint *c=*ci; pair u=cmap[c->left], v=cmap[c->right]; @@ -102,7 +102,7 @@ namespace cola { u.first->scx.push_back( new SimpleConstraint(u.second,v.second,c->gap)); } - for(ci=scy.begin();ci!=scy.end();ci++) { + for(ci=scy.begin();ci!=scy.end();++ci) { SimpleConstraint *c=*ci; pair u=cmap[c->left], v=cmap[c->right]; diff --git a/src/libcola/cycle_detector.cpp b/src/libcola/cycle_detector.cpp index 89a2ccaae..11e24a0ba 100644 --- a/src/libcola/cycle_detector.cpp +++ b/src/libcola/cycle_detector.cpp @@ -53,7 +53,7 @@ void CycleDetector::make_matrix() { assert(traverse.empty()); // from the edges passed, fill the adjacency matrix - for (ei = edges->begin(); ei != edges->end(); ei++) { + for (ei = edges->begin(); ei != edges->end(); ++ei) { anEdge = *ei; // the matrix is indexed by the first vertex of the edge // the second vertex of the edge is pushed onto another @@ -241,7 +241,7 @@ bool CycleDetector::find_node(std::vector *& list, unsigned k) { } pair< bool, vector::iterator > CycleDetector::find_node(std::vector& list, unsigned k) { - for (vector::iterator ti = traverse.begin(); ti != traverse.end(); ti++) { + for (vector::iterator ti = traverse.begin(); ti != traverse.end(); ++ti) { if (*ti == k) { return pair< bool, vector::iterator >(true, ti); } } diff --git a/src/libcola/gradient_projection.cpp b/src/libcola/gradient_projection.cpp index 47109a4b0..3e41aceac 100644 --- a/src/libcola/gradient_projection.cpp +++ b/src/libcola/gradient_projection.cpp @@ -222,7 +222,7 @@ void GradientProjection::destroyVPSC(IncSolver *vpsc) { delete vpsc; delete [] cs; delete [] vs; - for(vector::iterator i=lcs.begin();i!=lcs.end();i++) { + for(vector::iterator i=lcs.begin();i!=lcs.end();++i) { delete *i; } lcs.clear(); diff --git a/src/libcola/straightener.cpp b/src/libcola/straightener.cpp index 650f41aac..fab30d48d 100644 --- a/src/libcola/straightener.cpp +++ b/src/libcola/straightener.cpp @@ -90,7 +90,7 @@ namespace straightener { ds.erase(copyit); } } - for(set >::iterator j=pntsOnLineSegment.begin();j!=pntsOnLineSegment.end();j++) { + for(set >::iterator j=pntsOnLineSegment.begin();j!=pntsOnLineSegment.end();++j) { path.push_back(j->second); } //printf("\n"); @@ -144,11 +144,11 @@ namespace straightener { e->ypos(conjpos,bs); } //cerr << "edge(intersections="<startNode<<","<endNode<<"))"<::iterator it=bs.begin();it!=bs.end();it++) { + for(vector::iterator it=bs.begin();it!=bs.end();++it) { sortedEdges.insert(make_pair(*it,e)); } } - for(set::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) { + for(set::iterator i=sortedEdges.begin();i!=sortedEdges.end();++i) { double pos=i->first; if(pos < minpos) continue; if(pos > v->scanpos) break; @@ -169,7 +169,7 @@ namespace straightener { if(r!=NULL) { maxpos=r->scanpos; } - for(set::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) { + for(set::iterator i=sortedEdges.begin();i!=sortedEdges.end();++i) { if(i->first < v->scanpos) continue; if(i->first > maxpos) break; double pos=i->first; @@ -262,7 +262,7 @@ namespace straightener { // Case A: create constraints between adjacent edges skipping edges joined // to l,v or r. Node* lastNode=NULL; - for(vector::iterator i=L.begin();i!=L.end();i++) { + for(vector::iterator i=L.begin();i!=L.end();++i) { if((*i)->dummy) { // node is on an edge Edge *edge=(*i)->edge; @@ -284,7 +284,7 @@ namespace straightener { // their own end, also in the scan line vector skipList; lastNode=NULL; - for(vector::iterator i=L.begin();i!=L.end();i++) { + for(vector::iterator i=L.begin();i!=L.end();++i) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { @@ -292,7 +292,7 @@ namespace straightener { skipList.push_back(*i); } else { for(vector::iterator j=skipList.begin(); - j!=skipList.end();j++) { + j!=skipList.end();++j) { //printf(" Rule B: Constraint: v%d +g <= v%d\n",(*j)->id,(*i)->id); cs.push_back(createConstraint(*j,*i,dim)); } @@ -309,7 +309,7 @@ namespace straightener { skipList.clear(); // Case C: reverse of B lastNode=NULL; - for(vector::reverse_iterator i=L.rbegin();i!=L.rend();i++) { + for(vector::reverse_iterator i=L.rbegin();i!=L.rend();++i) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { @@ -317,7 +317,7 @@ namespace straightener { skipList.push_back(*i); } else { for(vector::iterator j=skipList.begin(); - j!=skipList.end();j++) { + j!=skipList.end();++j) { //printf(" Rule C: Constraint: v%d +g <= v%d\n",(*i)->id,(*j)->id); cs.push_back(createConstraint(*i,*j,dim)); } -- cgit v1.2.3 From ad925e4014535e5f21794ee8ece424ffa83f94e5 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 01:09:04 -0300 Subject: bug fix: xml:space was not initialized, getting random values (bzr r12604) --- src/sp-object.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-object.h b/src/sp-object.h index 4e9a6c938..bcaa1dac7 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -106,7 +106,9 @@ enum { class SPDocument; /// Internal class consisting of two bits. -struct SPIXmlSpace { +class SPIXmlSpace { +public: + SPIXmlSpace(): set(0), value(SP_XML_SPACE_DEFAULT) {}; guint set : 1; guint value : 1; }; -- cgit v1.2.3 From a5e764ae43d4b3ba1d7cb63c9cfdb3f1b9e1b13e Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 28 Sep 2013 00:12:30 -0400 Subject: Allow pixmaps to specify their width and height to control/knots. Allows non-square nodes. (bzr r12605) --- src/display/sodipodi-ctrl.cpp | 191 +++++++++++++++++------------------------- src/display/sodipodi-ctrl.h | 4 +- src/knot.cpp | 30 ++----- 3 files changed, 83 insertions(+), 142 deletions(-) (limited to 'src') diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp index 45dc38a37..3636319df 100644 --- a/src/display/sodipodi-ctrl.cpp +++ b/src/display/sodipodi-ctrl.cpp @@ -108,81 +108,50 @@ sp_ctrl_set_property(GObject *object, guint prop_id, const GValue *value, GParam ctrl = SP_CTRL (object); switch (prop_id) { - case ARG_SHAPE: { - ctrl->shape = (SPCtrlShapeType) g_value_get_int(value); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_MODE: { - ctrl->mode = (SPCtrlModeType) g_value_get_int(value); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_ANCHOR: { - ctrl->anchor = (SPAnchorType) g_value_get_int(value); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_SIZE: { - ctrl->span = (gint)((g_value_get_double(value) - 1.0) / 2.0 + 0.5); - ctrl->defined = (ctrl->span > 0); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_FILLED: { - ctrl->filled = g_value_get_boolean(value); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_FILL_COLOR: { - guint32 fill = g_value_get_int(value); - ctrl->fill_color = fill; - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_STROKED: { - ctrl->stroked = g_value_get_boolean(value); - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_STROKE_COLOR: { - guint32 stroke = g_value_get_int(value); - ctrl->stroke_color = stroke; - ctrl->build = FALSE; - sp_canvas_item_request_update(item); - } - break; - - case ARG_PIXBUF: { - pixbuf = (GdkPixbuf*) g_value_get_pointer(value); - if (gdk_pixbuf_get_has_alpha(pixbuf)) { - ctrl->pixbuf = pixbuf; - } else { - ctrl->pixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0); - g_object_unref(pixbuf); - } - ctrl->build = FALSE; - } - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; + case ARG_SHAPE: + ctrl->shape = (SPCtrlShapeType) g_value_get_int(value); + break; + case ARG_MODE: + ctrl->mode = (SPCtrlModeType) g_value_get_int(value); + break; + case ARG_ANCHOR: + ctrl->anchor = (SPAnchorType) g_value_get_int(value); + break; + case ARG_SIZE: + ctrl->width = (gint)(g_value_get_double(value) / 2.0); + ctrl->height = ctrl->width; + ctrl->defined = (ctrl->width > 0); + break; + case ARG_FILLED: + ctrl->filled = g_value_get_boolean(value); + break; + case ARG_FILL_COLOR: + ctrl->fill_color = (guint32)g_value_get_int(value); + break; + case ARG_STROKED: + ctrl->stroked = g_value_get_boolean(value); + break; + case ARG_STROKE_COLOR: + ctrl->stroke_color = (guint32)g_value_get_int(value); + break; + case ARG_PIXBUF: + pixbuf = (GdkPixbuf*) g_value_get_pointer(value); + // A pixbuf defines it's own size, don't mess about with size. + ctrl->width = gdk_pixbuf_get_width(pixbuf) / 2.0; + ctrl->height = gdk_pixbuf_get_height(pixbuf) / 2.0; + if (gdk_pixbuf_get_has_alpha(pixbuf)) { + ctrl->pixbuf = pixbuf; + } else { + ctrl->pixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0); + g_object_unref(pixbuf); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + return; // Do not do an update } + ctrl->build = FALSE; + sp_canvas_item_request_update(item); } static void @@ -206,7 +175,7 @@ sp_ctrl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec break; case ARG_SIZE: - g_value_set_double(value, ctrl->span); + g_value_set_double(value, ctrl->width); break; case ARG_FILLED: @@ -241,7 +210,8 @@ sp_ctrl_init (SPCtrl *ctrl) ctrl->shape = SP_CTRL_SHAPE_SQUARE; ctrl->mode = SP_CTRL_MODE_COLOR; ctrl->anchor = SP_ANCHOR_CENTER; - ctrl->span = 3; + ctrl->width = 3; + ctrl->height = 3; ctrl->defined = TRUE; ctrl->shown = FALSE; ctrl->build = FALSE; @@ -250,12 +220,6 @@ sp_ctrl_init (SPCtrl *ctrl) ctrl->fill_color = 0x000000ff; ctrl->stroke_color = 0x000000ff; - // This way we make sure that the first sp_ctrl_update() call finishes properly; - // in subsequent calls it will not update anything it the control hasn't moved - // Consider for example the case in which a snap indicator is drawn at (0, 0); - // 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 - new (&ctrl->box) Geom::IntRect(0,0,0,0); ctrl->cache = NULL; ctrl->pixbuf = NULL; @@ -292,16 +256,14 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla sp_canvas_item_reset_bounds (item); - if (!ctrl->_moved) return; - if (ctrl->shown) { item->canvas->requestRedraw(ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1); } if (!ctrl->defined) return; - x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->span; - y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->span; + x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->width; + y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->height; switch (ctrl->anchor) { case SP_ANCHOR_N: @@ -312,13 +274,13 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla case SP_ANCHOR_NW: case SP_ANCHOR_W: case SP_ANCHOR_SW: - x += ctrl->span; + x += ctrl->width; break; case SP_ANCHOR_NE: case SP_ANCHOR_E: case SP_ANCHOR_SE: - x -= (ctrl->span + 1); + x -= (ctrl->width + 1); break; } @@ -331,17 +293,17 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla case SP_ANCHOR_NW: case SP_ANCHOR_N: case SP_ANCHOR_NE: - y += ctrl->span; + y += ctrl->height; break; case SP_ANCHOR_SW: case SP_ANCHOR_S: case SP_ANCHOR_SE: - y -= (ctrl->span + 1); + y -= (ctrl->height + 1); break; } - ctrl->box = Geom::IntRect::from_xywh(x, y, 2*ctrl->span, 2*ctrl->span); + ctrl->box = Geom::IntRect::from_xywh(x, y, 2*ctrl->width, 2*ctrl->height); sp_canvas_update_bbox (item, ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1); } @@ -360,7 +322,7 @@ static void sp_ctrl_build_cache (SPCtrl *ctrl) { guint32 *p, *q; - gint size, x, y, z, s, a, side, c; + gint size, x, y, z, s, a, width, height, c; guint32 stroke_color, fill_color; if (ctrl->filled) { @@ -382,11 +344,11 @@ sp_ctrl_build_cache (SPCtrl *ctrl) stroke_color = fill_color; } - - side = (ctrl->span * 2 +1); - c = ctrl->span; - size = side * side; - if (side < 2) return; + width = (ctrl->width * 2 +1); + height = (ctrl->height * 2 +1); + c = ctrl->width; // Only used for pre-set square drawing + size = width * height; + if (width < 2) return; if (ctrl->cache) delete[] ctrl->cache; ctrl->cache = new guint32[size]; @@ -395,19 +357,19 @@ sp_ctrl_build_cache (SPCtrl *ctrl) case SP_CTRL_SHAPE_SQUARE: p = ctrl->cache; // top edge - for (x=0; x < side; x++) { + for (x=0; x < width; x++) { *p++ = stroke_color; } // middle - for (y = 2; y < side; y++) { + for (y = 2; y < height; y++) { *p++ = stroke_color; // stroke at first and last pixel - for (x=2; x < side; x++) { + for (x=2; x < width; x++) { *p++ = fill_color; // fill in the middle } *p++ = stroke_color; } // bottom edge - for (x=0; x < side; x++) { + for (x=0; x < width; x++) { *p++ = stroke_color; } ctrl->build = TRUE; @@ -415,19 +377,19 @@ sp_ctrl_build_cache (SPCtrl *ctrl) case SP_CTRL_SHAPE_DIAMOND: p = ctrl->cache; - for (y = 0; y < side; y++) { + for (y = 0; y < height; y++) { z = abs (c - y); for (x = 0; x < z; x++) { *p++ = 0; } *p++ = stroke_color; x++; - for (; x < side - z -1; x++) { + for (; x < width - z -1; x++) { *p++ = fill_color; } if (z != c) { *p++ = stroke_color; x++; } - for (; x < side; x++) { + for (; x < width; x++) { *p++ = 0; } } @@ -462,7 +424,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl) *q-- = stroke_color; x++; } while (x <= c+z); - while (x < side) { + while (x < width) { *p++ = 0; *q-- = 0; x++; @@ -474,7 +436,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl) case SP_CTRL_SHAPE_CROSS: p = ctrl->cache; - for (y = 0; y < side; y++) { + for (y = 0; y < height; y++) { z = abs (c - y); for (x = 0; x < c-z; x++) { *p++ = 0; @@ -486,7 +448,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl) if (z != 0) { *p++ = stroke_color; x++; } - for (; x < side; x++) { + for (; x < width; x++) { *p++ = 0; } } @@ -499,12 +461,12 @@ sp_ctrl_build_cache (SPCtrl *ctrl) unsigned int rs; px = gdk_pixbuf_get_pixels (ctrl->pixbuf); rs = gdk_pixbuf_get_rowstride (ctrl->pixbuf); - for (y = 0; y < side; y++){ + for (y = 0; y < height; y++){ guint32 *d; unsigned char *s; s = px + y * rs; - d = ctrl->cache + side * y; - for (x = 0; x < side; x++) { + d = ctrl->cache + height * y; + for (x = 0; x < width; x++) { if (s[3] < 0x80) { *d++ = 0; } else if (s[0] < 0x80) { @@ -527,9 +489,9 @@ sp_ctrl_build_cache (SPCtrl *ctrl) guint32 *px; guchar *data = gdk_pixbuf_get_pixels (ctrl->pixbuf); p = ctrl->cache; - for (y = 0; y < side; y++){ + for (y = 0; y < height; y++){ px = reinterpret_cast(data + y * r); - for (x = 0; x < side; x++) { + for (x = 0; x < width; x++) { *p++ = *px++; } } @@ -566,8 +528,8 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) sp_ctrl_build_cache (ctrl); } - int w, h; - w = h = (ctrl->span * 2 +1); + int w = (ctrl->width * 2 + 1); + int h = (ctrl->height * 2 + 1); // The code below works even when the target is not an image surface if (ctrl->mode == SP_CTRL_MODE_XOR) { @@ -627,7 +589,6 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) void SPCtrl::moveto (Geom::Point const p) { if (p != _point) { sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (this), Geom::Affine(Geom::Translate (p))); - _moved = true; } _point = p; } diff --git a/src/display/sodipodi-ctrl.h b/src/display/sodipodi-ctrl.h index cd0fcadf1..ecdb896a7 100644 --- a/src/display/sodipodi-ctrl.h +++ b/src/display/sodipodi-ctrl.h @@ -37,7 +37,8 @@ struct SPCtrl : public SPCanvasItem { SPCtrlShapeType shape; SPCtrlModeType mode; SPAnchorType anchor; - gint span; + gint width; + gint height; guint defined : 1; guint shown : 1; guint build : 1; @@ -45,7 +46,6 @@ struct SPCtrl : public SPCanvasItem { guint stroked : 1; guint32 fill_color; guint32 stroke_color; - bool _moved; Geom::IntRect box; /* NB! x1 & y1 are included */ guint32 *cache; diff --git a/src/knot.cpp b/src/knot.cpp index 890abd0a1..2b67440dc 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -646,34 +646,14 @@ void sp_knot_update_ctrl(SPKnot *knot) */ static void sp_knot_set_ctrl_state(SPKnot *knot) { + int state = SP_KNOT_STATE_NORMAL; if (knot->flags & SP_KNOT_DRAGGING) { - g_object_set(knot->item, - "fill_color", - knot->fill[SP_KNOT_STATE_DRAGGING], - NULL); - g_object_set(knot->item, - "stroke_color", - knot->stroke[SP_KNOT_STATE_DRAGGING], - NULL); + state = SP_KNOT_STATE_DRAGGING; } else if (knot->flags & SP_KNOT_MOUSEOVER) { - g_object_set(knot->item, - "fill_color", - knot->fill[SP_KNOT_STATE_MOUSEOVER], - NULL); - g_object_set(knot->item, - "stroke_color", - knot->stroke[SP_KNOT_STATE_MOUSEOVER], - NULL); - } else { - g_object_set(knot->item, - "fill_color", - knot->fill[SP_KNOT_STATE_NORMAL], - NULL); - g_object_set(knot->item, - "stroke_color", - knot->stroke[SP_KNOT_STATE_NORMAL], - NULL); + state = SP_KNOT_STATE_MOUSEOVER; } + g_object_set(knot->item, "fill_color", knot->fill[state], NULL); + g_object_set(knot->item, "stroke_color", knot->stroke[state], NULL); } -- cgit v1.2.3 From 4dc2e0a91fc261f2c3cbc23e3b37cf9c1485d64c Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 10:56:40 -0300 Subject: obvious memleak (bzr r12606) --- src/number-opt-number.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/number-opt-number.h b/src/number-opt-number.h index 867d0535f..d9ab56102 100644 --- a/src/number-opt-number.h +++ b/src/number-opt-number.h @@ -120,6 +120,8 @@ public: _set = FALSE; optNumber_set = FALSE; } + + g_strfreev(values); } }; -- cgit v1.2.3 From d34822965a4fe7bab4e509c93b144ad1cabfa644 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 10:59:58 -0300 Subject: leak fixes: free marker value on delete; free the return value of uri's toString() (bzr r12607) --- src/style.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index 2807a7d9a..bea56e7b1 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -593,10 +593,18 @@ sp_style_unref(SPStyle *style) sp_style_filter_clear(style); g_free(style->stroke_dash.dash); + + for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) { + if (style->marker[i].value) { + g_free(style->marker[i].value); + style->marker[i].value = NULL; + } + } + g_free(style); + return NULL; } - - return NULL; + return style; } /** @@ -4447,6 +4455,7 @@ sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key, if ( paint->value.href && paint->value.href->getURI() ) { const gchar* uri = paint->value.href->getURI()->toString(); css << "url(" << uri << ")"; + g_free((void *)uri); } if ( paint->noneSet ) { @@ -4631,7 +4640,10 @@ sp_style_write_ifilter(gchar *p, gint const len, gchar const *key, if (val->inherit) { return g_snprintf(p, len, "%s:inherit;", key); } else if (val->href && val->href->getURI()) { - return g_snprintf(p, len, "%s:url(%s);", key, val->href->getURI()->toString()); + gchar *uri = val->href->getURI()->toString(); + gint ret = g_snprintf(p, len, "%s:url(%s);", key, uri); + g_free(uri); + return ret; } } -- cgit v1.2.3 From 45bdb1d8bdfe52de31ca28a2a26d4d1204bb9961 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 11:04:26 -0300 Subject: on hiding, texts must _clearFlow to release arena items, otherwise they leak (bzr r12608) --- src/sp-flowtext.cpp | 7 ++++++- src/sp-text.cpp | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 88564c0ac..266e9dfe0 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -326,7 +326,12 @@ Inkscape::DrawingItem* SPFlowtext::show(Inkscape::Drawing &drawing, unsigned int } void SPFlowtext::hide(unsigned int key) { - SPItem::hide(key); + for (SPItemView* v = this->display; v != NULL; v = v->next) { + if (v->key == key) { + Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); + this->_clearFlow(g); + } + } } diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 72a5996d1..c515828a4 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -318,7 +318,12 @@ Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned key, un void SPText::hide(unsigned int key) { -// SPItem::onHide(key); + for (SPItemView* v = this->display; v != NULL; v = v->next) { + if (v->key == key) { + Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); + this->_clearFlow(g); + } + } } const char* SPText::displayName() { -- cgit v1.2.3 From f9a958922e109295c9f4f3c12e5716ebf07a6dad Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 11:50:34 -0300 Subject: return value of g_utf16_to_utf8 was leaking here (bzr r12609) --- src/inkscape.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/inkscape.cpp b/src/inkscape.cpp index e1cabd2d5..cce4ca5b9 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1483,7 +1483,9 @@ profile_path(const char *filename) } if (prefdir) { - prefdir = g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, NULL); + const char *prefdir_profile = g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, NULL); + g_free((void *)prefdir); + prefdir = prefdir_profile; } } #endif -- cgit v1.2.3 From e3fe3144bd276bbab4b52aa5d65ac7d487989ff5 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 13:57:04 -0300 Subject: another place where getURI()->toString() values were leaking (bzr r12610) --- src/sp-item.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index a99bf85cc..89e995b5f 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -665,16 +665,20 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X if (item->clip_ref){ if (item->clip_ref->getObject()) { - const gchar *value = g_strdup_printf ("url(%s)", item->clip_ref->getURI()->toString()); + gchar *uri = item->clip_ref->getURI()->toString(); + const gchar *value = g_strdup_printf ("url(%s)", uri); repr->setAttribute ("clip-path", value); g_free ((void *) value); + g_free ((void *) uri); } } if (item->mask_ref){ if (item->mask_ref->getObject()) { - const gchar *value = g_strdup_printf ("url(%s)", item->mask_ref->getURI()->toString()); + gchar *uri = item->mask_ref->getURI()->toString(); + const gchar *value = g_strdup_printf ("url(%s)", uri); repr->setAttribute ("mask", value); g_free ((void *) value); + g_free ((void *) uri); } } -- cgit v1.2.3 From ae4fb171df25c328e398d0cf1909a4cbad33a897 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 13:58:09 -0300 Subject: dying document needs to delete its perspective (bzr r12611) --- src/document.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index 800f2f33d..dda072283 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -219,6 +219,11 @@ SPDocument::~SPDocument() { inkscape_unref(); keepalive = FALSE; } + + if (this->current_persp3d_impl) + delete this->current_persp3d_impl; + this->current_persp3d_impl = NULL; + //delete this->_whiteboard_session_manager; } -- cgit v1.2.3 From f1d2cd8504b1d7171b86d13130920297cd474aaf Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 15:37:37 -0300 Subject: components of _image_name were g_strdup'ed so need to be g_free'd (bzr r12612) --- src/sp-filter.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 91389bf7d..1a5c65be9 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -114,6 +114,10 @@ void SPFilter::release() { this->href = NULL; } + for (map::const_iterator i = this->_image_name->begin() ; i != this->_image_name->end() ; i++) { + g_free(i->first); + } + delete this->_image_name; SPObject::release(); -- cgit v1.2.3 From 6ee13490aaa9781b765589e22fb9206c6cb7e9e9 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 28 Sep 2013 20:47:16 +0200 Subject: Fixed MeasureContext. Fixed bugs: - https://launchpad.net/bugs/1232494 (bzr r12613) --- src/measure-context.cpp | 4 ---- src/measure-context.h | 6 ++++++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/measure-context.cpp b/src/measure-context.cpp index 9d8dc2b2f..7570e36e7 100644 --- a/src/measure-context.cpp +++ b/src/measure-context.cpp @@ -309,10 +309,6 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: } bool SPMeasureContext::root_handler(GdkEvent* event) { - Geom::Point start_point; - boost::optional explicitBase; - boost::optional lastEnd; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); diff --git a/src/measure-context.h b/src/measure-context.h index e42265045..7d5a88ab7 100644 --- a/src/measure-context.h +++ b/src/measure-context.h @@ -13,6 +13,8 @@ */ #include "event-context.h" +#include <2geom/point.h> +#include #define SP_MEASURE_CONTEXT(obj) (dynamic_cast((SPEventContext*)obj)) #define SP_IS_MEASURE_CONTEXT(obj) (dynamic_cast((const SPEventContext*)obj) != NULL) @@ -31,6 +33,10 @@ public: private: SPCanvasItem* grabbed; + + Geom::Point start_point; + boost::optional explicitBase; + boost::optional lastEnd; }; #endif // SEEN_SP_MEASURING_CONTEXT_H -- cgit v1.2.3 From bdcd0645191270e9136557237f7c48ca5944fc73 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 15:49:01 -0300 Subject: fix one code path where fullname wasn't freed (bzr r12614) --- src/sp-image.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 05dfb5f48..f2fc6a37a 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -682,11 +682,12 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre // and if it fails, we also try to use bare href regardless of its g_path_is_absolute if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) { inkpb = Inkscape::Pixbuf::create_from_file(fullname); - g_free (fullname); if (inkpb != NULL) { + g_free (fullname); return inkpb; } } + g_free (fullname); } /* try filename as absolute */ -- cgit v1.2.3 From cfb97f009e1a5f7e6908f53b7af47cf4d93614f6 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 28 Sep 2013 21:02:40 +0200 Subject: Fixed crash with calligraphic tool in subtract mode. Fixed bugs: - https://launchpad.net/bugs/1230007 (bzr r12615) --- src/dyna-draw-context.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index 01f71f76a..f8980e218 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -954,9 +954,20 @@ void SPDynaDrawContext::set_to_accumulated(bool unionize, bool subtract) { } } - SPItem *item=SP_ITEM(desktop->doc()->getObjectByRepr(this->repr)); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + // Now we need to write the transform information. + // First, find out whether our repr is still linked to a valid object. In this case, + // we need to write the transform data only for this element. + // Either there was no boolean op or it failed. + SPItem *result = SP_ITEM(desktop->doc()->getObjectByRepr(this->repr)); + + if (result == NULL) { + // The boolean operation succeeded. + // Now we fetch the single item, that has been set as selected by the boolean op. + // This is its result. + result = desktop->getSelection()->singleItem(); + } + result->doWriteTransform(result->getRepr(), result->transform, NULL, true); } else { if (this->repr) { sp_repr_unparent(this->repr); -- cgit v1.2.3 From 6e867cb6aa8b44a3bb9f2dec4361c67cefc8ca8f Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 16:20:27 -0300 Subject: effects don't need to merge into menus if we're running without gui; with this we can purge a redundant reading of menus skeleton, which leaked its xml tree (bzr r12616) --- src/extension/effect.cpp | 2 +- src/extension/init.cpp | 2 -- src/inkscape.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index dcccf3d7d..1575c2b10 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -89,7 +89,7 @@ Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation * } // children of "inkscape-extension" } // if we have an XML file - if (INKSCAPE != NULL) { + if (INKSCAPE != NULL && inkscape_use_gui()) { if (_effects_list == NULL) _effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST); if (_filters_list == NULL) diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 2dde9eeb8..0ff4b79c4 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -109,8 +109,6 @@ #include "init.h" -extern gboolean inkscape_app_use_gui( Inkscape::Application const *app ); - namespace Inkscape { namespace Extension { diff --git a/src/inkscape.cpp b/src/inkscape.cpp index cce4ca5b9..228841362 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -502,7 +502,7 @@ inkscape_init (SPObject * object) new (&inkscape->document_set) std::map(); new (&inkscape->selection_models) std::map(); - inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL); + inkscape->menus = NULL; inkscape->desktops = NULL; inkscape->dialogs_toggle = TRUE; inkscape->mapalt = GDK_MOD1_MASK; -- cgit v1.2.3 From 0b3a91c8ff18bd30b42beb71244ff9b0542ed2ca Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 28 Sep 2013 21:58:24 +0200 Subject: fix two memleaks (bzr r12617) --- src/ui/dialog/svg-fonts-dialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index ab5f4c0e9..56ecfdecc 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -541,7 +541,9 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){ Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d")); //XML Tree being directly used here while it shouldn't be. - glyph->getRepr()->setAttribute("d", (char*) sp_svg_write_path (flip_coordinate_system(pathv))); + gchar *str = sp_svg_write_path (flip_coordinate_system(pathv)); + glyph->getRepr()->setAttribute("d", str); + g_free(str); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves")); update_glyphs(); @@ -578,7 +580,9 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ if (SP_IS_MISSING_GLYPH(obj)){ //XML Tree being directly used here while it shouldn't be. - obj->getRepr()->setAttribute("d", (char*) sp_svg_write_path (flip_coordinate_system(pathv))); + gchar *str = sp_svg_write_path (flip_coordinate_system(pathv)); + obj->getRepr()->setAttribute("d", str); + g_free(str); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves")); } } -- cgit v1.2.3 From c83329cdf1c37fd1ee123a0f30e8b6582ac51547 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:24:31 -0300 Subject: prevent redundant firing of InitTheFace (pFont never changes, but init is called all over the place); also some nulling and freeing to prevent leaks, and removing the redundant daddy unreffing that is done in ~FontInstance anyway (bzr r12618) --- src/libnrtype/FontInstance.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index fd0cdd3d4..38a105459 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -192,6 +192,7 @@ font_instance::~font_instance(void) //printf("font instance death\n"); if ( pFont ) { + FreeTheFace(); g_object_unref(pFont); pFont = 0; } @@ -232,10 +233,6 @@ void font_instance::Unref(void) //printf("font %x %s unref'd %i\n",this,tc,refCount); //free(tc); if ( refCount <= 0 ) { - if ( daddy ) { - daddy->UnrefFace(this); - } - daddy=NULL; delete this; } } @@ -387,6 +384,7 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int void font_instance::InitTheFace() { + if (theFace == NULL && pFont != NULL) { #ifdef USE_PANGO_WIN32 if ( !theFace ) { LOGFONT *lf=pango_win32_font_logfont(pFont); @@ -404,6 +402,7 @@ void font_instance::InitTheFace() FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol); } #endif + } } void font_instance::FreeTheFace() @@ -423,6 +422,7 @@ void font_instance::InstallFace(PangoFont* iFace) return; } pFont=iFace; + iFace = NULL; InitTheFace(); -- cgit v1.2.3 From 6cc0d44d20de8e537e42dac66de344354ea80d1c Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:26:16 -0300 Subject: order correction: unreffing fonts in ents needs loadedPtr so that must go before loadedPrt is nulled; this didn't crash simply because we never freed FontFactory before; also some comments and remove redundant multiply in hash function (bzr r12619) --- src/libnrtype/FontFactory.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index c896cc470..9fc553efd 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -25,7 +25,6 @@ typedef INK_UNORDERED_MAP(g_malloc(maxEnt*sizeof(font_entry)))), @@ -327,12 +326,6 @@ font_factory::font_factory(void) : font_factory::~font_factory(void) { - if (loadedPtr) { - FaceMapType* tmp = static_cast(loadedPtr); - delete tmp; - loadedPtr = 0; - } - for (int i = 0;i < nbEnt;i++) ents[i].f->Unref(); if ( ents ) g_free(ents); @@ -344,6 +337,12 @@ font_factory::~font_factory(void) #endif //g_object_unref(fontContext); + if (loadedPtr) { + FaceMapType* tmp = static_cast(loadedPtr); + delete tmp; + loadedPtr = 0; + } + // Delete the pango font pointers in the string to instance map PangoStringToDescrMap::iterator it = fontInstanceMap.begin(); while (it != fontInstanceMap.end()) { @@ -1126,7 +1125,7 @@ void font_factory::AddInCache(font_instance *who) return; } who->Ref(); - if ( nbEnt == maxEnt ) { + if ( nbEnt == maxEnt ) { // cache is filled, unref the oldest-accessed font in it int bi = 0; double ba = ents[bi].age; for (int i = 1;i < nbEnt;i++) { -- cgit v1.2.3 From 6b8c701e9d74cff5c0b2eaa2b678d8e9f7410658 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 17:27:10 -0300 Subject: FontInstances were being leaked here by overreffing - every call to Face must unref when done (bzr r12620) --- src/libnrtype/Layout-TNG-Compute.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7ea089c93..973db0165 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -980,6 +980,7 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con attribute_font_description->end_index = para_text.bytes(); pango_attr_list_insert(attributes_list, attribute_font_description); // ownership of attribute is assumed by the list + font->Unref(); } } -- cgit v1.2.3 From 0c99cd46125045a7e94ae26985e47e1104860b4a Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sat, 28 Sep 2013 18:43:28 -0400 Subject: use geometric bbox to calculate filter effect region (Bug 1229971) Fixed bugs: - https://launchpad.net/bugs/1229971 (bzr r12621) --- src/sp-item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 89e995b5f..c342bfd9b 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -725,7 +725,7 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const // call the subclass method // CPPIFY //bbox = this->bbox(Geom::identity(), SPItem::VISUAL_BBOX); - bbox = const_cast(this)->bbox(Geom::identity(), SPItem::VISUAL_BBOX); + bbox = const_cast(this)->bbox(Geom::identity(), SPItem::GEOMETRIC_BBOX); // see LP Bug 1229971 SPFilter *filter = SP_FILTER(style->getFilter()); // default filer area per the SVG spec: -- cgit v1.2.3 From 447cf211335e4d902b10b77a8e4c5f9f9bb3690c Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 20:57:17 -0300 Subject: memleak fix (bzr r12622) --- src/proj_pt.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/proj_pt.cpp b/src/proj_pt.cpp index d9d4e06f1..28286948d 100644 --- a/src/proj_pt.cpp +++ b/src/proj_pt.cpp @@ -34,6 +34,7 @@ Pt2::Pt2(const gchar *coord_str) { pt[0] = g_ascii_strtod(coords[0], NULL); pt[1] = g_ascii_strtod(coords[1], NULL); pt[2] = g_ascii_strtod(coords[2], NULL); + g_strfreev (coords); } void -- cgit v1.2.3 From bf4e68d81307463eea90914566f6d6611688bb04 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 20:58:11 -0300 Subject: clear paints on delete to release reffed paintservers, fixes leaking of gradients (bzr r12623) --- src/display/nr-style.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index cd7e9575f..317f38635 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -77,6 +77,8 @@ NRStyle::~NRStyle() if (dash){ delete [] dash; } + fill.clear(); + stroke.clear(); } void NRStyle::set(SPStyle *style) -- cgit v1.2.3 From 1e82781408cc335ca29946a4de10349d868d65be Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 20:58:48 -0300 Subject: fix leaking of transforms (bzr r12624) --- src/display/drawing-group.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index 6d52b89fc..b5ce18891 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -28,6 +28,7 @@ DrawingGroup::~DrawingGroup() { if (_style) sp_style_unref(_style); + delete _child_transform; // delete NULL; is safe } /** -- cgit v1.2.3 From ee8f0667f84689466f68eecfb9498e7b092e168b Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Sat, 28 Sep 2013 23:09:39 -0300 Subject: collectOrphans moved to the end of destructor to prevent leaking of uncollected stuff (bzr r12625) --- src/document.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index dda072283..b94b72bda 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -139,8 +139,6 @@ SPDocument::SPDocument() : } SPDocument::~SPDocument() { - collectOrphans(); - // kill/unhook this first if ( profileManager ) { delete profileManager; @@ -224,6 +222,9 @@ SPDocument::~SPDocument() { delete this->current_persp3d_impl; this->current_persp3d_impl = NULL; + // This is at the end of the destructor, because preceding code adds new orphans to the queue + collectOrphans(); + //delete this->_whiteboard_session_manager; } -- cgit v1.2.3 From 421bdee0ed2b55d175459c898240b54762119569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Sun, 29 Sep 2013 08:35:21 -0300 Subject: Adding tutorial-tracing-pixelart (bzr r12626) --- src/menus-skeleton.h | 1 + src/verbs.cpp | 5 +++++ src/verbs.h | 1 + 3 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 2334a08c1..3fcb77207 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -285,6 +285,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/verbs.cpp b/src/verbs.cpp index 23a560423..bdef0526a 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2119,6 +2119,9 @@ void TutorialVerb::perform(SPAction *action, void *data) // TRANSLATORS: See "tutorial-basic.svg" comment. sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing.svg")); break; + case SP_VERB_TUTORIAL_TRACING_PIXELART: + sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing-pixelart.svg")); + break; case SP_VERB_TUTORIAL_CALLIGRAPHY: // TRANSLATORS: See "tutorial-basic.svg" comment. sp_help_open_tutorial(NULL, (gpointer)_("tutorial-calligraphy.svg")); @@ -2883,6 +2886,8 @@ Verb *Verb::_base_verbs[] = { // TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) new TutorialVerb(SP_VERB_TUTORIAL_TRACING, "TutorialsTracing", N_("Inkscape: T_racing"), N_("Using bitmap tracing"), NULL/*"tutorial_tracing"*/), + new TutorialVerb(SP_VERB_TUTORIAL_TRACING_PIXELART, "TutorialsTracingPixelArt", N_("Inkscape: Tracing Pixel Art"), + N_("Using Trace Pixel Art dialog"), NULL), new TutorialVerb(SP_VERB_TUTORIAL_CALLIGRAPHY, "TutorialsCalligraphy", N_("Inkscape: _Calligraphy"), N_("Using the Calligraphy pen tool"), NULL), new TutorialVerb(SP_VERB_TUTORIAL_INTERPOLATE, "TutorialsInterpolate", N_("Inkscape: _Interpolate"), diff --git a/src/verbs.h b/src/verbs.h index 40292745a..0f764eb29 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -304,6 +304,7 @@ enum { SP_VERB_TUTORIAL_SHAPES, SP_VERB_TUTORIAL_ADVANCED, SP_VERB_TUTORIAL_TRACING, + SP_VERB_TUTORIAL_TRACING_PIXELART, SP_VERB_TUTORIAL_CALLIGRAPHY, SP_VERB_TUTORIAL_INTERPOLATE, SP_VERB_TUTORIAL_DESIGN, -- cgit v1.2.3 From 48536172f551d67942217c6d78a7f37e79c68110 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Mon, 30 Sep 2013 00:17:20 +0200 Subject: Further changes to SPEllipse. (bzr r12629) --- src/object-edit.cpp | 50 ++++++++++++++++++-------------------- src/sp-ellipse.cpp | 70 ++++++++++++++++++++--------------------------------- src/sp-ellipse.h | 16 +++++++++--- 3 files changed, 63 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/object-edit.cpp b/src/object-edit.cpp index 5ade37cb1..28786bf66 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -785,24 +785,23 @@ sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p) void ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); SPArc *arc = SP_ARC(item); - ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; + arc->setClosed(sp_genericellipse_side(arc, p) == -1); - Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed); - Geom::Scale sc(ge->rx.computed, ge->ry.computed); - ge->start = atan2(delta * sc.inverse()); - if ( ( state & GDK_CONTROL_MASK ) - && snaps ) - { - ge->start = sp_round(ge->start, M_PI/snaps); + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->start = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->start = sp_round(arc->start, M_PI / snaps); } - ge->normalize(); - (static_cast(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point @@ -828,24 +827,23 @@ ArcKnotHolderEntityStart::knot_click(guint state) void ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); SPArc *arc = SP_ARC(item); - ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; + arc->setClosed(sp_genericellipse_side(arc, p) == -1); - Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed); - Geom::Scale sc(ge->rx.computed, ge->ry.computed); - ge->end = atan2(delta * sc.inverse()); - if ( ( state & GDK_CONTROL_MASK ) - && snaps ) - { - ge->end = sp_round(ge->end, M_PI/snaps); + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->end = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->end = sp_round(arc->end, M_PI/snaps); } - ge->normalize(); - (static_cast(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } Geom::Point diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index bc6aa1c87..80e57afc3 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -34,9 +34,6 @@ #include "preferences.h" #include "snap-candidate.h" -#define noELLIPSE_VERBOSE - - #include "sp-factory.h" namespace { @@ -69,9 +66,9 @@ bool arc_registered = SPFactory::instance().registerObject("arc", create_arc); SPGenericEllipse::SPGenericEllipse() : SPShape() - , closed(true) , start(0) , end(SP_2PI) + , _closed(true) { } @@ -79,6 +76,14 @@ SPGenericEllipse::~SPGenericEllipse() { } +bool SPGenericEllipse::closed() { + return _closed; +} + +void SPGenericEllipse::setClosed(bool value) { + _closed = value; +} + void SPGenericEllipse::update(SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { @@ -122,18 +127,11 @@ void SPGenericEllipse::update_patheffect(bool write) bool SPGenericEllipse::_isSlice() const { - // figure out if we have a slice, guarding against rounding errors - double diff = fmod(this->end - this->start, SP_2PI); - - if (diff < 0.0) { - diff += SP_2PI; - } + Geom::AngleInterval a(this->start, this->end, true); - return (fabs(diff) >= 1e-8 && fabs(diff - SP_2PI) >= 1e-8); + return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI)); } -/* fixme: Think (Lauris) */ -/* Can't we use arcto in this method? */ void SPGenericEllipse::set_shape() { if (hasBrokenPathEffect()) { @@ -150,11 +148,7 @@ void SPGenericEllipse::set_shape() return; } - if ((this->rx.computed < 1e-18) || (this->ry.computed < 1e-18)) { - return; - } - - if (fabs(this->end - this->start) < 1e-9) { + if (Geom::are_near(this->rx.computed, 0) || Geom::are_near(this->ry.computed, 0)) { return; } @@ -181,7 +175,7 @@ void SPGenericEllipse::set_shape() Geom::PathBuilder pb; pb.append(path); - if (this->closed) { + if (this->_closed) { // "pizza slice" pb.lineTo(center); pb.closePath(); @@ -233,10 +227,8 @@ void SPGenericEllipse::snappoints(std::vector &p, // Snap to the 4 quadrant points of the ellipse, but only if the arc // spans far enough to include them if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)) { - double angle = 0; - - for (angle = 0; angle < SP_2PI; angle += M_PI_2) { - if (angle >= this->start && angle <= this->end) { + for (double angle = 0; angle < SP_2PI; angle += M_PI_2) { + if (Geom::AngleInterval(this->start, this->end, true).contains(angle)) { Geom::Point pt = this->getPointAtAngle(angle) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT, Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)); } @@ -249,7 +241,7 @@ void SPGenericEllipse::snappoints(std::vector &p, bool slice = this->_isSlice(); // Add the centre, if we have a closed slice or when explicitly asked for - if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->closed) { + if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->_closed) { Geom::Point pt = Geom::Point(cx, cy) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } @@ -262,13 +254,13 @@ void SPGenericEllipse::snappoints(std::vector &p, // And if we have a slice, also snap to the endpoints if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) { // Add the start point, if it's not coincident with a quadrant point - if (fmod(this->start, M_PI_2) != 0.0) { + if (!Geom::are_near(std::fmod(this->start, M_PI_2), 0)) { Geom::Point pt = this->getPointAtAngle(this->start) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } // Add the end point, if it's not coincident with a quadrant point - if (fmod(this->end, M_PI_2) != 0.0) { + if (!Geom::are_near(std::fmod(this->end, M_PI_2), 0)) { Geom::Point pt = this->getPointAtAngle(this->end) * i2dt; p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); } @@ -333,20 +325,10 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) void SPGenericEllipse::normalize() { - this->start = fmod(this->start, SP_2PI); - this->end = fmod(this->end, SP_2PI); - - if (this->start < 0.0) { - this->start += SP_2PI; - } - - double diff = this->start - this->end; - - if (diff >= 0.0) { - this->end += diff - fmod(diff, SP_2PI) + SP_2PI; - } + Geom::AngleInterval a(this->start, this->end, true); - /* Now we keep: 0 <= start < end <= 2*PI */ + this->start = a.initialAngle().radians0(); + this->end = a.finalAngle().radians0(); } Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) @@ -574,7 +556,7 @@ bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr) str.arcTo(rx, ry, 0, fa, fs, p2); - if (this->closed) { + if (this->_closed) { Geom::Point center = Geom::Point(this->cx.computed, this->cy.computed); str.lineTo(center).closePath(); } @@ -603,7 +585,7 @@ Inkscape::XML::Node *SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM sp_repr_set_svg_double(repr, "sodipodi:start", this->start); sp_repr_set_svg_double(repr, "sodipodi:end", this->end); - repr->setAttribute("sodipodi:open", (!this->closed) ? "true" : NULL); + repr->setAttribute("sodipodi:open", (!this->_closed) ? "true" : NULL); } else { repr->setAttribute("sodipodi:end", NULL); repr->setAttribute("sodipodi:start", NULL); @@ -669,7 +651,7 @@ void SPArc::set(unsigned int key, gchar const *value) break; case SP_ATTR_SODIPODI_OPEN: - this->closed = (!value); + this->_closed = (!value); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -691,7 +673,7 @@ void SPArc::modified(guint flags) const char *SPArc::displayName() { if (this->_isSlice()) { - if (this->closed) { + if (this->_closed) { return _("Segment"); } else { return _("Arc"); @@ -719,7 +701,7 @@ void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) this->end = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/end", 0.0)).radians0(); } - this->closed = !prefs->getBool("/tools/shapes/arc/open"); + this->_closed = !prefs->getBool("/tools/shapes/arc/open"); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index d817b5511..eab0b4907 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -31,8 +31,11 @@ public: SVGLength rx; SVGLength ry; - // Stores whether the shape is closed ("pizza slice" or full ellipse) or not (arc only). - bool closed; + /** + * If we have a slice, returns whether the shape is closed ("pizza slice") or not (arc only). + */ + bool closed(); + void setClosed(bool value); double start, end; @@ -45,13 +48,20 @@ public: virtual void update_patheffect(bool write); + /** + * @brief Makes sure that start and end lie between 0 and 2 * PI. + */ void normalize(); Geom::Point getPointAtAngle(double arg) const; protected: - /// Determines whether the shape is a part of a ellipse. + /** + * @brief Determines whether the shape is a part of an ellipse. + */ bool _isSlice() const; + + bool _closed; }; -- cgit v1.2.3 From df16775103cd981612d363bd6937cd2d68801b5f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 30 Sep 2013 04:43:12 -0400 Subject: Reduce tools-switcher code, add description for node and select toos. (bzr r12630) --- src/tools-switch.cpp | 164 ++++++++++----------------------------------------- 1 file changed, 30 insertions(+), 134 deletions(-) (limited to 'src') diff --git a/src/tools-switch.cpp b/src/tools-switch.cpp index fd160e518..32fab9f7e 100644 --- a/src/tools-switch.cpp +++ b/src/tools-switch.cpp @@ -86,6 +86,31 @@ static char const *const tool_names[] = { "/tools/lpetool", NULL }; +static char const *const tool_msg[] = { + NULL, + _("Click to Select and Tranform objects, Drag to select many objects."), + _("Modify selected path points (nodes) directly."), + _("To tweak a path by pushing, select it and drag over it."), + _("Drag, click or click and scroll to spray the selected objects."), + _("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), + _("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), + _("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), + _("Drag to create a star. Drag controls to edit the star shape. Click to select."), + _("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), + _("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), + _("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), + _("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), + _("Click to select or create text, drag to create flowed text; then type."), + _("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), + _("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), + _("Click or drag around an area to zoom in, Shift+click to zoom out."), + _("Drag to measure the dimensions of objects."), + _("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), + _("Click and drag between shapes to create a connector."), + _("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), + _("Drag to erase."), + _("Choose a subtool from the toolbar"), +}; static int tools_prefpath2num(char const *id) @@ -123,140 +148,11 @@ tools_switch(SPDesktop *dt, int num) } dt->set_event_context2(tool_names[num]); - - switch (num) { - case TOOLS_SELECT: - //dt->set_event_context(SP_TYPE_SELECT_CONTEXT, tool_names[num]); - /* fixme: This is really ugly hack. We should bind and unbind class methods */ - dt->activate_guides(true); - inkscape_eventcontext_set(dt->getEventContext()); - break; - case TOOLS_NODES: - //dt->set_event_context(INK_TYPE_NODE_TOOL, tool_names[num]); - dt->activate_guides(true); - inkscape_eventcontext_set(dt->getEventContext()); - break; - case TOOLS_TWEAK: - //dt->set_event_context(SP_TYPE_TWEAK_CONTEXT, tool_names[num]); - dt->activate_guides(true); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("To tweak a path by pushing, select it and drag over it.")); - break; - case TOOLS_SPRAY: - //dt->set_event_context(SP_TYPE_SPRAY_CONTEXT, tool_names[num]); - dt->activate_guides(true); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag, click or click and scroll to spray the selected objects.")); - break; - case TOOLS_SHAPES_RECT: - //dt->set_event_context(SP_TYPE_RECT_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a rectangle. Drag controls to round corners and resize. Click to select.")); - break; - case TOOLS_SHAPES_3DBOX: - //dt->set_event_context(SP_TYPE_BOX3D_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces).")); - break; - case TOOLS_SHAPES_ARC: - //dt->set_event_context(SP_TYPE_ARC_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select.")); - break; - case TOOLS_SHAPES_STAR: - //dt->set_event_context(SP_TYPE_STAR_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a star. Drag controls to edit the star shape. Click to select.")); - break; - case TOOLS_SHAPES_SPIRAL: - //dt->set_event_context(SP_TYPE_SPIRAL_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select.")); - break; - case TOOLS_FREEHAND_PENCIL: - //dt->set_event_context(SP_TYPE_PENCIL_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode.")); - break; - case TOOLS_FREEHAND_PEN: - //dt->set_event_context(SP_TYPE_PEN_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only).")); - break; - case TOOLS_CALLIGRAPHIC: - //dt->set_event_context(SP_TYPE_DYNA_DRAW_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down).")); - break; - case TOOLS_TEXT: - //dt->set_event_context(SP_TYPE_TEXT_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click to select or create text, drag to create flowed text; then type.")); - break; - case TOOLS_GRADIENT: - //dt->set_event_context(SP_TYPE_GRADIENT_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients.")); - break; - case TOOLS_MESH: - //dt->set_event_context(SP_TYPE_MESH_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes.")); - break; - case TOOLS_ZOOM: - //dt->set_event_context(SP_TYPE_ZOOM_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click or drag around an area to zoom in, Shift+click to zoom out.")); - break; - case TOOLS_MEASURE: - //dt->set_event_context(SP_TYPE_MEASURE_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to measure the dimensions of objects.")); - break; - case TOOLS_DROPPER: - //dt->set_event_context(SP_TYPE_DROPPER_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard")); - break; - case TOOLS_CONNECTOR: - //dt->set_event_context(SP_TYPE_CONNECTOR_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click and drag between shapes to create a connector.")); - break; - case TOOLS_PAINTBUCKET: - //dt->set_event_context(SP_TYPE_FLOOD_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting.")); - break; - case TOOLS_ERASER: - //dt->set_event_context(SP_TYPE_ERASER_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to erase.")); - break; - case TOOLS_LPETOOL: - //dt->set_event_context(SP_TYPE_LPETOOL_CONTEXT, tool_names[num]); - dt->activate_guides(false); - inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Choose a subtool from the toolbar")); - break; - } + /* fixme: This is really ugly hack. We should bind and unbind class methods */ + /* First 4 tools use guides, first is undefined but we don't care */ + dt->activate_guides(num < 5); + inkscape_eventcontext_set(dt->getEventContext()); + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, tool_msg[num] ); } void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) -- cgit v1.2.3 From c6867ca8cc751a4cd04b029a6358740dbd4929d4 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 30 Sep 2013 11:38:50 -0400 Subject: Fix translations for tool messages (bzr r12631) --- src/tools-switch.cpp | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/tools-switch.cpp b/src/tools-switch.cpp index 32fab9f7e..a3c0f2daa 100644 --- a/src/tools-switch.cpp +++ b/src/tools-switch.cpp @@ -88,28 +88,28 @@ static char const *const tool_names[] = { }; static char const *const tool_msg[] = { NULL, - _("Click to Select and Tranform objects, Drag to select many objects."), - _("Modify selected path points (nodes) directly."), - _("To tweak a path by pushing, select it and drag over it."), - _("Drag, click or click and scroll to spray the selected objects."), - _("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), - _("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), - _("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), - _("Drag to create a star. Drag controls to edit the star shape. Click to select."), - _("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), - _("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), - _("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), - _("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), - _("Click to select or create text, drag to create flowed text; then type."), - _("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), - _("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), - _("Click or drag around an area to zoom in, Shift+click to zoom out."), - _("Drag to measure the dimensions of objects."), - _("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), - _("Click and drag between shapes to create a connector."), - _("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), - _("Drag to erase."), - _("Choose a subtool from the toolbar"), + N_("Click to Select and Tranform objects, Drag to select many objects."), + N_("Modify selected path points (nodes) directly."), + N_("To tweak a path by pushing, select it and drag over it."), + N_("Drag, click or click and scroll to spray the selected objects."), + N_("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), + N_("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), + N_("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), + N_("Drag to create a star. Drag controls to edit the star shape. Click to select."), + N_("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), + N_("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), + N_("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), + N_("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), + N_("Click to select or create text, drag to create flowed text; then type."), + N_("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), + N_("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), + N_("Click or drag around an area to zoom in, Shift+click to zoom out."), + N_("Drag to measure the dimensions of objects."), + N_("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), + N_("Click and drag between shapes to create a connector."), + N_("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), + N_("Drag to erase."), + N_("Choose a subtool from the toolbar"), }; static int @@ -152,7 +152,7 @@ tools_switch(SPDesktop *dt, int num) /* First 4 tools use guides, first is undefined but we don't care */ dt->activate_guides(num < 5); inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, tool_msg[num] ); + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, gettext( tool_msg[num] ) ); } void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) -- cgit v1.2.3 From 9a68082d3054fe803d44f052bccc28b2091185f5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 21:50:42 +0200 Subject: fix memleak (duplicating string is not necessary, as ustring's constructor already does that) (bzr r12632) --- src/color-profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index e8a6a9c98..e6a9ac71c 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -829,7 +829,7 @@ std::vector ColorProfile::getProfileFiles() for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { gchar *filepath = g_build_filename(it->c_str(), file, NULL); if ( g_file_test( filepath, G_FILE_TEST_IS_DIR ) ) { - sources.push_back(g_strdup(filepath)); + sources.push_back( filepath ); } else { if ( isIccFile( filepath ) ) { files.push_back( filepath ); -- cgit v1.2.3 From 799f473597d4eb61d843c37b2e294824c919db73 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 21:59:36 +0200 Subject: fix memleak (bzr r12633) --- src/display/guideline.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index f71bc82ef..55c1ee495 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -94,14 +94,20 @@ static void sp_guideline_destroy(SPCanvasItem *object) g_return_if_fail (SP_IS_GUIDELINE (object)); //g_return_if_fail (SP_GUIDELINE(object)->origin != NULL); //g_return_if_fail (SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)); - - if (SP_GUIDELINE(object)->origin != NULL && SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)) { - sp_canvas_item_destroy(SP_GUIDELINE(object)->origin); + + SPGuideLine *gl = SP_GUIDELINE(object); + + if (gl->origin != NULL && SP_IS_CTRLPOINT(gl->origin)) { + sp_canvas_item_destroy(gl->origin); } else { // FIXME: This branch shouldn't be reached (although it seems to be harmless). //g_error("Why can it be that gl->origin is not a valid SPCtrlPoint?\n"); } + if (gl->label) { + g_free(gl->label); + } + SP_CANVAS_ITEM_CLASS(parent_class)->destroy(object); } -- cgit v1.2.3 From 729db6f014a96c65417a06d8bf130e6af6737da0 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:05:43 +0200 Subject: fix obvious leak (bzr r12634) --- src/widgets/stroke-style.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 31f4bb2e5..a0b638031 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -85,6 +85,8 @@ SPObject* getMarkerObj(gchar const *n, SPDocument *doc) // FIXME: get the document from the object and let the caller pass it in SPObject *marker = doc->getObjectById(b); + + g_free(b); return marker; } -- cgit v1.2.3 From db2034fd3ccc754361e563410e590e1002d1f592 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:17:57 +0200 Subject: fix another g_strdup memleak (bzr r12635) --- src/text-chemistry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index 8a3fede0f..5bcdfdd33 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -234,9 +234,9 @@ text_remove_all_kerns_recursively(SPObject *o) gchar **xa_space = g_strsplit(x, " ", 0); gchar **xa_comma = g_strsplit(x, ",", 0); if (xa_space && *xa_space && *(xa_space + 1)) { - o->getRepr()->setAttribute("x", g_strdup(*xa_space)); + o->getRepr()->setAttribute("x", *xa_space); } else if (xa_comma && *xa_comma && *(xa_comma + 1)) { - o->getRepr()->setAttribute("x", g_strdup(*xa_comma)); + o->getRepr()->setAttribute("x", *xa_comma); } g_strfreev(xa_space); g_strfreev(xa_comma); -- cgit v1.2.3 From fec897e5f419344560c2b5e7691fcc207147c5bf Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:28:33 +0200 Subject: memleak! (bzr r12636) --- src/extension/dbus/document-interface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index ccc39fbef..221a3e879 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -268,7 +268,7 @@ dbus_call_verb (DocumentInterface *doc_interface, int verbid, GError **error) if ( action ) { sp_action_perform( action, NULL ); if (doc_interface->updates) - Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), verb->get_tip()); return TRUE; } } @@ -357,7 +357,7 @@ document_interface_call_verb (DocumentInterface *doc_interface, gchar *verbid, G if ( action ) { sp_action_perform( action, NULL ); if (doc_interface->updates) { - Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), verb->get_tip()); } return TRUE; } -- cgit v1.2.3 From 2be3de40a1be0f5bd3f246ba0c9a77a7967ecd3b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:32:05 +0200 Subject: memleak (bzr r12637) --- src/selection-chemistry.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index c22ed777b..a3bb9fd77 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2512,7 +2512,9 @@ void sp_selection_clone(SPDesktop *desktop) Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0", false); clone->setAttribute("y", "0", false); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", sel_repr->attribute("id")), false); + gchar *href_str = g_strdup_printf("#%s", sel_repr->attribute("id")); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); clone->setAttribute("inkscape:transform-center-x", sel_repr->attribute("inkscape:transform-center-x"), false); clone->setAttribute("inkscape:transform-center-y", sel_repr->attribute("inkscape:transform-center-y"), false); -- cgit v1.2.3 From f18fd209af016a01fd9e8a8da50c1c2f5ff84aab Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:38:56 +0200 Subject: memleaks (bzr r12638) --- src/selection-chemistry.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index a3bb9fd77..2105ca99a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2995,7 +2995,9 @@ void sp_selection_symbol(SPDocument *doc, SPObject *group) Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0", false); clone->setAttribute("y", "0", false); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", id.c_str()), false); + gchar *href_str = g_strdup_printf("#%s", id.c_str()); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); clone->setAttribute("inkscape:transform-center-x", group->getAttribute("inkscape:transform-center-x"), false); clone->setAttribute("inkscape:transform-center-y", group->getAttribute("inkscape:transform-center-y"), false); @@ -3155,7 +3157,9 @@ sp_selection_tile(SPDesktop *desktop, bool apply) if (apply) { Inkscape::XML::Node *rect = xml_doc->createElement("svg:rect"); - rect->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id)); + gchar *style_str = g_strdup_printf("stroke:none;fill:url(#%s)", pat_id); + rect->setAttribute("style", style_str); + g_free(style_str); Geom::Point min = bbox.min() * parent_transform.inverse(); Geom::Point max = bbox.max() * parent_transform.inverse(); @@ -3721,7 +3725,9 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ Inkscape::GC::release(group); } - apply_mask_to->setAttribute(attributeName, g_strdup_printf("url(#%s)", mask_id)); + gchar *value_str = g_strdup_printf("url(#%s)", mask_id); + apply_mask_to->setAttribute(attributeName, value_str); + g_free(value_str); } -- cgit v1.2.3 From 2ec94efdaa8e757acb2afb4c2c683b51bf08cf82 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:46:18 +0200 Subject: memleaks! (bzr r12639) --- src/splivarot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 8a57fa98a..319928d99 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2183,6 +2183,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, gchar *message = g_strdup_printf(_("%s %d of %d paths simplified..."), simplificationType, pathsSimplified, totalPathCount); desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, message); + g_free(message); } didSomething |= sp_selected_path_simplify_item(desktop, selection, item, @@ -2192,7 +2193,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, desktop->clearWaitingCursor(); if (pathsSimplified > 20) { - desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, g_strdup_printf(_("%d paths simplified."), pathsSimplified)); + desktop->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, _("%d paths simplified."), pathsSimplified); } return didSomething; -- cgit v1.2.3 From 402facfad7ee68aa208b1f8f9966e7492c8cc13f Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:49:26 +0200 Subject: string leaks (bzr r12640) --- src/ui/dialog/ocaldialogs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f87288494..90230286e 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1017,7 +1017,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast(cur_node->name), "enclosure")) { - xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast(g_strdup("url"))); + xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast("url")); char* url = reinterpret_cast(xml_url); char* filename = g_path_get_basename(url); @@ -1027,7 +1027,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast(cur_node->name), "thumbnail")) { - xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast(g_strdup("url"))); + xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast("url")); char* thumbnail_url = reinterpret_cast(xml_thumbnail_url); char* thumbnail_filename = g_path_get_basename(thumbnail_url); -- cgit v1.2.3 From d60357c24c3b0b67c9372b26fc94d9328efcf22f Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:53:03 +0200 Subject: fix previous commit (bzr r12641) --- src/ui/dialog/ocaldialogs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 90230286e..ca0edfadd 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1017,7 +1017,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast(cur_node->name), "enclosure")) { - xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast("url")); + xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast("url")); char* url = reinterpret_cast(xml_url); char* filename = g_path_get_basename(url); @@ -1027,7 +1027,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast(cur_node->name), "thumbnail")) { - xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast("url")); + xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast("url")); char* thumbnail_url = reinterpret_cast(xml_thumbnail_url); char* thumbnail_filename = g_path_get_basename(thumbnail_url); -- cgit v1.2.3 From fe0875caf2b1b0519ed009acbd004a675f14f772 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:54:01 +0200 Subject: more string leaks (bzr r12642) --- src/spray-context.cpp | 4 +++- src/text-chemistry.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/spray-context.cpp b/src/spray-context.cpp index fd9aff196..6b97dcc17 100644 --- a/src/spray-context.cpp +++ b/src/spray-context.cpp @@ -499,7 +499,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, // Ad the clone to the list of the father's sons parent->appendChild(clone); // Generates the link between father and son attributes - clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false); + gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id")); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); SPObject *clone_object = doc->getObjectByRepr(clone); // conversion object->item diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index 5bcdfdd33..532d19e02 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -152,7 +152,9 @@ text_put_on_path() // create textPath and put it into the text Inkscape::XML::Node *textpath = xml_doc->createElement("svg:textPath"); // reference the shape - textpath->setAttribute("xlink:href", g_strdup_printf("#%s", shape->getRepr()->attribute("id"))); + gchar *href_str = g_strdup_printf("#%s", shape->getRepr()->attribute("id")); + textpath->setAttribute("xlink:href", href_str); + g_free(href_str); if (text_alignment == Inkscape::Text::Layout::RIGHT) { textpath->setAttribute("startOffset", "100%"); } else if (text_alignment == Inkscape::Text::Layout::CENTER) { @@ -331,7 +333,9 @@ text_flow_into_shape() Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0"); clone->setAttribute("y", "0"); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", item->getRepr()->attribute("id"))); + gchar *href_str = g_strdup_printf("#%s", item->getRepr()->attribute("id")); + clone->setAttribute("xlink:href", href_str); + g_free(href_str); // add the new clone to the region region_repr->appendChild(clone); -- cgit v1.2.3 From 3f306a1dcb2eac6533ac70ba8dd27087a8c62dc0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 1 Oct 2013 02:04:26 +0200 Subject: Fix computed shapes disappearing when grouping within filtered groups. Fixes blocker LP bug #850992. Fixed bugs: - https://launchpad.net/bugs/850992 (bzr r12643) --- src/sp-item-group.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index a99a3e988..284d3317a 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -161,44 +161,49 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol } void SPGroup::update(SPCtx *ctx, unsigned int flags) { - SPLPEItem::update(ctx, flags); - SPItemCtx *ictx, cctx; ictx = (SPItemCtx *) ctx; cctx = *ictx; - if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + unsigned childflags = flags; - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *group = dynamic_cast(v->arenaitem); - group->setStyle(this->style); - } + if (flags & SP_OBJECT_MODIFIED_FLAG) { + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = g_slist_reverse(this->childList(true, SPObject::ActionUpdate)); while (l) { SPObject *child = SP_OBJECT (l->data); l = g_slist_remove (l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM (child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + // For a group, we need to update ourselves *after* updating children. + // this is because the group might contain shapes such as rect or ellipse, + // which recompute their equivalent path (a.k.a curve) in the update callback, + // and this is in turn used when computing bbox. + SPLPEItem::update(ctx, flags); + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *group = dynamic_cast(v->arenaitem); + group->setStyle(this->style); + } + } } void SPGroup::modified(guint flags) { -- cgit v1.2.3 From 1c5f7de99f4da6e945c3c72bcd7a6efc1df37762 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 1 Oct 2013 01:40:28 +0100 Subject: Fix mismatched tags (bzr r12644) --- src/extension/internal/metafile-print.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/metafile-print.h b/src/extension/internal/metafile-print.h index cba4d564d..a21f9de58 100644 --- a/src/extension/internal/metafile-print.h +++ b/src/extension/internal/metafile-print.h @@ -26,8 +26,8 @@ #include "splivarot.h" #include "display/canvas-bpath.h" -struct SPGradient; -struct SPObject; +class SPGradient; +class SPObject; namespace Inkscape { class Pixbuf; -- cgit v1.2.3 From 5cf6f3cac4b8dce6a3059c2547cf376fd382e741 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 1 Oct 2013 02:55:12 +0200 Subject: Minor improvements to DrawingItem code and documentation (bzr r12645) --- src/display/drawing-item.cpp | 45 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 1af07cb44..526fc3000 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -141,7 +141,11 @@ DrawingItem::appendChild(DrawingItem *item) assert(item->_child_type == CHILD_ORPHAN); item->_child_type = CHILD_NORMAL; _children.push_back(*item); - _markForUpdate(STATE_ALL, false); + // Because _markForUpdate recurses through ancestors, we can simply call it + // on the just-added child. This has the additional benefit that we do not + // rely on the appended child being in the default non-updated state. + // We set propagate to true, because the child might have descendants of its own. + item->_markForUpdate(STATE_ALL, true); } void @@ -151,7 +155,8 @@ DrawingItem::prependChild(DrawingItem *item) assert(item->_child_type == CHILD_ORPHAN); item->_child_type = CHILD_NORMAL; _children.push_front(*item); - _markForUpdate(STATE_ALL, false); + // See appendChild for explanation + item->_markForUpdate(STATE_ALL, true); } /// Delete all regular children of this item (not mask or clip). @@ -714,8 +719,11 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) { // 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)) + if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) { + g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", + _state & STATE_BBOX, _state & STATE_PICK); return NULL; + } // ignore invisible and insensitive items unless sticky if (!(flags & PICK_STICKY) && !(_visible && _sensitive)) return NULL; @@ -736,7 +744,10 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) } Geom::OptIntRect box = (outline || (flags & PICK_AS_CLIP)) ? _bbox : _drawbox; - if (!box) return NULL; + if (!box) { + g_warning("bbox unset when picking"); + return NULL; + } Geom::Rect expanded = *box; expanded.expandBy(delta); @@ -756,6 +767,9 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) void DrawingItem::_markForRendering() { + // TODO: this function does too much work when a large subtree + // is invalidated - fix + bool outline = _drawing.outline(); Geom::OptIntRect dirty = outline ? _bbox : _drawbox; if (!dirty) return; @@ -807,8 +821,8 @@ DrawingItem::_invalidateFilterBackground(Geom::IntRect const &area) * all children should also have the corresponding flags unset before checking * whether they need to be traversed. This way there is one less traversal * of the tree. Without this we would need to unset state bits in all children. - * With _propagate we do this during the update call, when we have to traverse - * the tree anyway. + * With _propagate we do this during the update call, when we have to recurse + * into children anyway. */ void DrawingItem::_markForUpdate(unsigned flags, bool propagate) @@ -818,15 +832,31 @@ DrawingItem::_markForUpdate(unsigned flags, bool propagate) } if (_state & flags) { + unsigned oldstate = _state; _state &= ~flags; - if (_parent) { + if (oldstate != _state && _parent) { + // If we actually reset anything in state, recurse on the parent. _parent->_markForUpdate(flags, false); } else { + // If nothing changed, it means our ancestors are already invalidated + // up to the root. Do not bother recursing, because it won't change anything. + // Also do this if we are the root item, because we have no more ancestors + // to invalidate. _drawing.signal_request_update.emit(this); } } } +/** + * Process information related to the new style. + * + * This function is something of a hack to avoid creating an extra class in the hierarchy + * which would differ from DrawingItem only by having a _style member. + * This is mainly to the benefit of DrawingGlyphs, which use the style of their parent. + * This should probably be refactored some day, possibly by creating the relevant class + * or creating a more complex data model in DrawingText and removing DrawingGlyphs, + * which would cause every item to have a style. + */ void DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) { @@ -834,7 +864,6 @@ DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *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())); -- cgit v1.2.3 From 1595a83d610f4e328d84eb1fc2764041ea9335db Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 1 Oct 2013 07:55:55 -0400 Subject: Revert render svg:patern segment for fill and stroke (bzr r12646) --- src/display/drawing-shape.cpp | 4 ++-- src/display/nr-filter.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index e689d0755..9ad18243e 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -179,8 +179,8 @@ DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne // 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, _bbox); - has_stroke = _nrstyle.prepareStroke(ct, _bbox); + has_fill = _nrstyle.prepareFill(ct, _filter_bbox); + has_stroke = _nrstyle.prepareStroke(ct, _filter_bbox); has_stroke &= (_nrstyle.stroke_width != 0); if (has_fill || has_stroke) { diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index c0044c5d8..1289362aa 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -114,7 +114,7 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D Geom::Affine trans = item->ctm(); - // Get filter are, the filter_effect_area is already done in visualBounds + // Get filter area, the filter_effect_area is already done in visualBounds Geom::OptRect filter_area = item->filterBounds(); // Use the geometricBounds as a backup solution if (!filter_area) return 1; -- cgit v1.2.3 From 56791e9c202001bf29b089f1f52ad128e548f198 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 1 Oct 2013 14:31:34 +0200 Subject: Fix possible bug in DrawingItem code (bzr r12647) --- src/display/drawing-item.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 526fc3000..b2b3e68a2 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -141,6 +141,9 @@ DrawingItem::appendChild(DrawingItem *item) assert(item->_child_type == CHILD_ORPHAN); item->_child_type = CHILD_NORMAL; _children.push_back(*item); + + // This ensures that _markForUpdate() called on the child will recurse to this item + item->_state = STATE_ALL; // Because _markForUpdate recurses through ancestors, we can simply call it // on the just-added child. This has the additional benefit that we do not // rely on the appended child being in the default non-updated state. @@ -156,6 +159,7 @@ DrawingItem::prependChild(DrawingItem *item) item->_child_type = CHILD_NORMAL; _children.push_front(*item); // See appendChild for explanation + item->_state = STATE_ALL; item->_markForUpdate(STATE_ALL, true); } -- cgit v1.2.3 From 87d93e27330577c2fd632dbaccbd3103884aa590 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 1 Oct 2013 15:25:44 +0200 Subject: Comprehensive fix for the issues with disappearing filtered objects. Fixes #304407 and possibly a few other bugs. Revert incorrect _item_bbox changes from r12528. Fixed bugs: - https://launchpad.net/bugs/304407 (bzr r12648) --- src/display/drawing-item.cpp | 25 +++++++++++-------------- src/display/drawing-item.h | 6 ++++-- src/display/drawing-shape.cpp | 4 ++-- src/display/drawing-text.cpp | 4 ++-- src/display/nr-filter.cpp | 8 +++----- src/libnrtype/Layout-TNG-Output.cpp | 1 + src/sp-flowdiv.cpp | 32 ++++++++++++++++---------------- src/sp-flowregion.cpp | 16 ++++++++-------- src/sp-flowtext.cpp | 17 ++++++++++------- src/sp-item-group.cpp | 7 ------- src/sp-item.cpp | 14 +++++--------- src/sp-text.cpp | 14 +++++++------- src/sp-tref.cpp | 14 +++++++------- src/sp-tspan.cpp | 12 ++++++------ src/sp-use.cpp | 29 +++++++++++++++-------------- 15 files changed, 97 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index b2b3e68a2..71a7f8906 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -290,17 +290,10 @@ DrawingItem::setZOrder(unsigned z) _markForRendering(); } -void DrawingItem::setItemBounds(Geom::OptRect const &bounds) -{ - if (!bounds) return; - Geom::IntRect copy = bounds->roundOutwards(); - if (_filter) _filter->area_enlarge(copy, this); - this->setFilterBounds(copy); -} - -void DrawingItem::setFilterBounds(Geom::OptRect const &bounds) +void +DrawingItem::setItemBounds(Geom::OptRect const &bounds) { - if (bounds) _filter_bbox = bounds; + _item_bbox = bounds; } /** @@ -368,10 +361,14 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne if (to_update & STATE_BBOX) { // compute drawbox - if (_filter && render_filters && _filter_bbox) { - Geom::OptRect enlarged = _filter_bbox; - *enlarged *= ctm(); - _drawbox = enlarged->roundOutwards(); + if (_filter && render_filters) { + Geom::OptRect enlarged = _filter->filter_effect_area(_item_bbox); + if (enlarged) { + *enlarged *= ctm(); + _drawbox = enlarged->roundOutwards(); + } else { + _drawbox = Geom::OptIntRect(); + } } else { _drawbox = _bbox; } diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index c69b996b4..e03bbd0f7 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -89,7 +89,7 @@ public: Geom::OptIntRect geometricBounds() const { return _bbox; } Geom::OptIntRect visualBounds() const { return _drawbox; } - Geom::OptRect filterBounds() const { return _filter_bbox; } + 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; } @@ -176,7 +176,9 @@ protected: Geom::Affine _ctm; ///< Total transform from item coords to display coords Geom::OptIntRect _bbox; ///< Bounding box in display (pixel) coords including stroke Geom::OptIntRect _drawbox; ///< Full visual bounding box - enlarged by filters, shrunk by clips and masks - Geom::OptRect _filter_bbox; ///< Used by filters when settings bounds + Geom::OptRect _item_bbox; ///< Geometric bounding box in item's user space. + /// This is used to compute the filter effect region and render in + /// objectBoundingBox units. DrawingItem *_clip; DrawingItem *_mask; diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 9ad18243e..e80f12486 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -179,8 +179,8 @@ DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne // 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, _filter_bbox); - has_stroke = _nrstyle.prepareStroke(ct, _filter_bbox); + has_fill = _nrstyle.prepareFill(ct, _item_bbox); + has_stroke = _nrstyle.prepareStroke(ct, _item_bbox); has_stroke &= (_nrstyle.stroke_width != 0); if (has_fill || has_stroke) { diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index fa9ce4ff8..55d54b770 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -398,8 +398,8 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are using Geom::X; using Geom::Y; - has_fill = _nrstyle.prepareFill( ct, _bbox); - has_stroke = _nrstyle.prepareStroke(ct, _bbox); + has_fill = _nrstyle.prepareFill( ct, _item_bbox); + has_stroke = _nrstyle.prepareStroke(ct, _item_bbox); if (has_fill || has_stroke) { Geom::Affine rotinv; diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 1289362aa..af9c15cd8 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -114,14 +114,12 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D Geom::Affine trans = item->ctm(); - // Get filter area, the filter_effect_area is already done in visualBounds - Geom::OptRect filter_area = item->filterBounds(); - // Use the geometricBounds as a backup solution + Geom::OptRect filter_area = filter_effect_area(item->itemBounds()); if (!filter_area) return 1; FilterUnits units(_filter_units, _primitive_units); units.set_ctm(trans); - units.set_item_bbox(filter_area); + units.set_item_bbox(item->itemBounds()); units.set_filter_area(*filter_area); std::pair resolution @@ -201,7 +199,7 @@ void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item } Geom::Rect item_bbox; - Geom::OptRect maybe_bbox = item->geometricBounds(); + Geom::OptRect maybe_bbox = item->itemBounds(); if (maybe_bbox.isEmpty()) { // Code below needs a bounding box return; diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1989c495a..bdc786749 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,6 +181,7 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); + nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); // Set item bounds without filter enlargement in_arena->setItemBounds(paintbox); diff --git a/src/sp-flowdiv.cpp b/src/sp-flowdiv.cpp index 867e68441..00ba48b06 100644 --- a/src/sp-flowdiv.cpp +++ b/src/sp-flowdiv.cpp @@ -54,13 +54,11 @@ void SPFlowdiv::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { @@ -74,19 +72,21 @@ void SPFlowdiv::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + SPItem::update(ctx, flags); } void SPFlowdiv::modified(unsigned int flags) { @@ -195,13 +195,11 @@ void SPFlowtspan::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { @@ -215,19 +213,21 @@ void SPFlowtspan::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + SPItem::update(ctx, flags); } void SPFlowtspan::modified(unsigned int flags) { diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index ed17f1948..13ab7bc64 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -72,13 +72,11 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; @@ -93,20 +91,22 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM (child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + SPItem::update(ctx, flags); + this->UpdateComputed(); } diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 266e9dfe0..49360f9d9 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -72,10 +72,11 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - flags &= SP_OBJECT_MODIFIED_CASCADE; + unsigned childflags = flags; + if (flags & SP_OBJECT_MODIFIED_FLAG) { + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; @@ -90,20 +91,22 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + SPItem::update(ctx, flags); + this->rebuildLayout(); Geom::OptRect pbox = this->geometricBounds(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 284d3317a..41e049b86 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -217,13 +217,6 @@ void SPGroup::modified(guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *group = dynamic_cast(v->arenaitem); - group->setStyle(this->style); - } - } - GSList *l = g_slist_reverse(this->childList(true)); while (l) { diff --git a/src/sp-item.cpp b/src/sp-item.cpp index c342bfd9b..5bf0afdeb 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -603,13 +603,13 @@ void SPItem::update(SPCtx *ctx, guint flags) { } } } - /* Update bounding box data used by filters */ + /* Update bounding box in user space, used for filter and objectBoundingBox units */ if (item->style->filter.set && item->display) { - Geom::OptRect item_bbox = item->visualBounds(); + Geom::OptRect item_bbox = item->geometricBounds(); SPItemView *itemview = item->display; do { - if (itemview->arenaitem) // Already enlarged by visualBounds - itemview->arenaitem->setFilterBounds(item_bbox); + if (itemview->arenaitem) + itemview->arenaitem->setItemBounds(item_bbox); } while ( (itemview = itemview->next) ); } @@ -1065,12 +1065,8 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned SP_MASK(mask)->sp_mask_set_bbox(mask_key, item_bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - if (style->filter.set && display) { - item_bbox = visualBounds(); - } ai->setData(this); - // Already enlarged by visualBounds for filters - ai->setFilterBounds(item_bbox); + ai->setItemBounds(geometricBounds()); } return ai; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index c515828a4..c431f52da 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -135,12 +135,9 @@ void SPText::remove_child(Inkscape::XML::Node *rch) { void SPText::update(SPCtx *ctx, guint flags) { - SPItem::update(ctx, flags); - - guint cflags = (flags & SP_OBJECT_MODIFIED_CASCADE); - + unsigned childflags = (flags & SP_OBJECT_MODIFIED_CASCADE); if (flags & SP_OBJECT_MODIFIED_FLAG) { - cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } // Create temporary list of children @@ -157,14 +154,17 @@ void SPText::update(SPCtx *ctx, guint flags) { SPObject *child = reinterpret_cast(l->data); // We just built this list, so cast is safe. l = g_slist_remove (l, child); - if (cflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { /* fixme: Do we need transform? */ - child->updateDisplay(ctx, cflags); + child->updateDisplay(ctx, childflags); } sp_object_unref(child, this); } + // update ourselves after updating children + SPItem::update(ctx, flags); + if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 4f9947a04..1c0481547 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -148,21 +148,21 @@ void SPTRef::set(unsigned int key, const gchar* value) { void SPTRef::update(SPCtx *ctx, guint flags) { debug("0x%p",this); - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; SPObject *child = this->stringChild; if (child) { - if ( flags || ( child->uflags & SP_OBJECT_MODIFIED_FLAG )) { - child->updateDisplay(ctx, flags); + if ( childflags || ( child->uflags & SP_OBJECT_MODIFIED_FLAG )) { + child->updateDisplay(ctx, childflags); } } + + SPItem::update(ctx, flags); } void SPTRef::modified(unsigned int flags) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 21c5ee11f..20d404130 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -107,19 +107,19 @@ void SPTSpan::set(unsigned int key, const gchar* value) { } void SPTSpan::update(SPCtx *ctx, guint flags) { - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { - ochild->updateDisplay(ctx, flags); + ochild->updateDisplay(ctx, childflags); } } + + SPItem::update(ctx, flags); } void SPTSpan::modified(unsigned int flags) { diff --git a/src/sp-use.cpp b/src/sp-use.cpp index a558c6bf4..ec367d786 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -476,20 +476,12 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - flags &= SP_OBJECT_MODIFIED_CASCADE; - - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); - g->setStyle(this->style); - } - } + childflags &= SP_OBJECT_MODIFIED_CASCADE; /* Set up child viewport */ if (this->x.unit == SVGLength::PERCENT) { @@ -510,21 +502,30 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); - flags&=~SP_OBJECT_USER_MODIFIED_FLAG_B; + childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); - if (flags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { SPItem const &chi = *SP_ITEM(this->child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - this->child->updateDisplay((SPCtx *)&cctx, flags); + this->child->updateDisplay((SPCtx *)&cctx, childflags); } sp_object_unref(this->child); } + SPItem::update(ctx, flags); + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); + g->setStyle(this->style); + } + } + /* As last step set additional transform of arena group */ for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); -- cgit v1.2.3 From 5dc15e1d0593adc1d5c4ac99aa399642e7e2482d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 2 Oct 2013 01:13:48 +0200 Subject: Fix outfocus gradients. Fixes a regression from 0.48 in the SVG test suite (test case pserver-grad-13-b.svg). (bzr r12649) --- src/sp-radial-gradient.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index c8bf5db81..7c481fead 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -156,28 +156,36 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const // https://bugs.launchpad.net/inkscape/+bug/970355 Geom::Affine gs2user = this->gradientTransform; - Geom::Scale gs2user_scale; if (this->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX && bbox) { Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); gs2user *= bbox2user; - gs2user_scale = Geom::Scale( gs2user[0], gs2user[3] ); } - Geom::Point d = focus - center; - Geom::Point d_user = d * gs2user_scale; - Geom::Point r_user( radius, 0 ); - r_user *= gs2user_scale; - - if (d_user.length() + tolerance > r_user.length()) { + // we need to use vectors with the same direction to represent the transformed + // radius and the focus-center delta, because gs2user might contain non-uniform scaling + Geom::Point d(focus - center); + Geom::Point d_user(d.length(), 0); + Geom::Point r_user(radius, 0); + d_user *= gs2user.withoutTranslation(); + r_user *= gs2user.withoutTranslation(); + + double dx = d_user.x(), dy = d_user.y(); + cairo_user_to_device_distance(ct, &dx, &dy); + + // compute the tolerance distance in user space + // create a vector with the same direction as the transformed d, + // with the length equal to tolerance + double dl = hypot(dx, dy); + double tx = tolerance * dx / dl, ty = tolerance * dy / dl; + cairo_device_to_user_distance(ct, &tx, &ty); + double tolerance_user = hypot(tx, ty); + + if (d_user.length() + tolerance_user > r_user.length()) { scale = r_user.length() / d_user.length(); - double dx = d_user.x(), dy = d_user.y(); - cairo_user_to_device_distance(ct, &dx, &dy); - if (!Geom::are_near(dx, 0, tolerance) || !Geom::are_near(dy, 0, tolerance)) - { - scale *= 1.0 - 2.0 * tolerance / hypot(dx, dy); - } + // nudge the focus slightly inside + scale *= 1.0 - 2.0 * tolerance / dl; } cairo_pattern_t *cp = cairo_pattern_create_radial( -- cgit v1.2.3 From 31c244b7e2d06d67d67142696351507b1a08bb09 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 2 Oct 2013 03:28:57 +0200 Subject: Fix segment welding in the node tool hanging when a two-point segment and at least one additional point is selected. Fixes LP bug #710101. Fixed bugs: - https://launchpad.net/bugs/710101 (bzr r12650) --- src/ui/tool/path-manipulator.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 6e14e8e97..b775c0637 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -459,7 +459,10 @@ void PathManipulator::weldSegments() if (j->selected()) ++num_selected; else ++num_unselected; } - if (num_selected < 3) continue; + + // if 2 or fewer nodes are selected, there can't be any middle points to remove. + if (num_selected <= 2) continue; + if (num_unselected == 0 && sp->closed()) { // if all nodes in a closed subpath are selected, the operation doesn't make much sense continue; @@ -489,14 +492,16 @@ void PathManipulator::weldSegments() } if (num_points > 2) { // remove nodes in the middle + // TODO: fit bezier to the former shape sel_beg = sel_beg.next(); while (sel_beg != sel_end.prev()) { NodeList::iterator next = sel_beg.next(); sp->erase(sel_beg); sel_beg = next; } - sel_beg = sel_end; } + sel_beg = sel_end; + // decrease num_selected by the number of points processed num_selected -= num_points; } } -- cgit v1.2.3