diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2013-10-08 10:22:49 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2013-10-08 10:22:49 +0000 |
| commit | f5d74fe46345673252807be3b6812bbb0469e457 (patch) | |
| tree | 2dd29c409d36d5dbfbe008cfff774880fd310b3d | |
| parent | cppcheck (diff) | |
| download | inkscape-f5d74fe46345673252807be3b6812bbb0469e457.tar.gz inkscape-f5d74fe46345673252807be3b6812bbb0469e457.zip | |
Seamlessly switch between SVG circle, ellipse, and path (arc) elements while using the Circle, Ellipse, and Arc tool.
(bzr r12670)
| -rw-r--r-- | src/arc-context.cpp | 8 | ||||
| -rw-r--r-- | src/arc-context.h | 2 | ||||
| -rw-r--r-- | src/knotholder.cpp | 2 | ||||
| -rw-r--r-- | src/object-edit.cpp | 12 | ||||
| -rw-r--r-- | src/selection-chemistry.cpp | 4 | ||||
| -rw-r--r-- | src/sp-ellipse.cpp | 699 | ||||
| -rw-r--r-- | src/sp-ellipse.h | 81 | ||||
| -rw-r--r-- | src/sp-lpe-item.cpp | 14 | ||||
| -rw-r--r-- | src/sp-mesh-array.cpp | 8 | ||||
| -rw-r--r-- | src/ui/dialog/find.cpp | 2 | ||||
| -rw-r--r-- | src/widgets/arc-toolbar.cpp | 13 |
11 files changed, 407 insertions, 438 deletions
diff --git a/src/arc-context.cpp b/src/arc-context.cpp index 046541b9b..dc869ce60 100644 --- a/src/arc-context.cpp +++ b/src/arc-context.cpp @@ -363,7 +363,7 @@ void SPArcContext::drag(Geom::Point pt, guint state) { // Set style sp_desktop_apply_style_tool(desktop, repr, "/tools/shapes/arc", false); - this->arc = SP_ARC(desktop->currentLayer()->appendChildRepr(repr)); + this->arc = SP_GENERICELLIPSE(desktop->currentLayer()->appendChildRepr(repr)); Inkscape::GC::release(repr); this->arc->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); this->arc->updateRepr(); @@ -409,9 +409,9 @@ void SPArcContext::drag(Geom::Point pt, guint state) { } } - this->arc->sp_arc_position_set( - r.midpoint()[Geom::X], r.midpoint()[Geom::Y], - r.dimensions()[Geom::X] / 2, r.dimensions()[Geom::Y] / 2); + this->arc->position_set( + r.midpoint()[Geom::X], r.midpoint()[Geom::Y], + r.dimensions()[Geom::X] / 2, r.dimensions()[Geom::Y] / 2); double rdimx = r.dimensions()[Geom::X]; double rdimy = r.dimensions()[Geom::Y]; diff --git a/src/arc-context.h b/src/arc-context.h index 56eb02943..6a0a6c071 100644 --- a/src/arc-context.h +++ b/src/arc-context.h @@ -41,7 +41,7 @@ public: virtual const std::string& getPrefsPath(); private: - SPArc *arc; + SPGenericEllipse *arc; Geom::Point center; diff --git a/src/knotholder.cpp b/src/knotholder.cpp index 9abba83d7..7129348c2 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -242,7 +242,7 @@ KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/) void KnotHolder::add(KnotHolderEntity *e) { - g_message("Adding a knot at %p", e); + // g_message("Adding a knot at %p", e); entity.push_back(e); updateControlSizes(); } diff --git a/src/object-edit.cpp b/src/object-edit.cpp index 2021b91f5..e9b183eca 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -69,7 +69,7 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) knotholder = new RectKnotHolder(desktop, item, NULL); } else if (SP_IS_BOX3D(item)) { knotholder = new Box3DKnotHolder(desktop, item, NULL); - } else if (SP_IS_ARC(item)) { + } else if (SP_IS_GENERICELLIPSE(item)) { knotholder = new ArcKnotHolder(desktop, item, NULL); } else if (SP_IS_STAR(item)) { knotholder = new StarKnotHolder(desktop, item, NULL); @@ -787,7 +787,7 @@ ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*or { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPArc *arc = SP_ARC(item); + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); arc->setClosed(sp_genericellipse_side(arc, p) == -1); @@ -808,9 +808,8 @@ Geom::Point ArcKnotHolderEntityStart::knot_get() const { SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - SPArc *arc = SP_ARC(item); - return arc->getPointAtAngle(ge->start); + return ge->getPointAtAngle(ge->start); } void @@ -829,7 +828,7 @@ ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*orig { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - SPArc *arc = SP_ARC(item); + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); arc->setClosed(sp_genericellipse_side(arc, p) == -1); @@ -850,9 +849,8 @@ Geom::Point ArcKnotHolderEntityEnd::knot_get() const { SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - SPArc *arc = SP_ARC(item); - return arc->getPointAtAngle(ge->end); + return ge->getPointAtAngle(ge->end); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 49a731b15..3a91f7b4d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1915,8 +1915,8 @@ static bool item_type_match (SPItem *i, SPItem *j) if ( SP_IS_RECT(i)) { return ( SP_IS_RECT(j) ); - } else if (SP_IS_GENERICELLIPSE(i) || SP_IS_ELLIPSE(i) || SP_IS_ARC(i) || SP_IS_CIRCLE(i)) { - return (SP_IS_GENERICELLIPSE(j) || SP_IS_ELLIPSE(j) || SP_IS_ARC(j) || SP_IS_CIRCLE(j)); + } else if (SP_IS_GENERICELLIPSE(i)) { + return (SP_IS_GENERICELLIPSE(j)); } else if (SP_IS_STAR(i) || SP_IS_POLYGON(i)) { return (SP_IS_STAR(j) || SP_IS_POLYGON(j)) ; diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 06201859f..fa74508e3 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -9,6 +9,7 @@ * * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2013 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -39,17 +40,23 @@ namespace { SPObject *create_ellipse() { - return new SPEllipse(); + SPGenericEllipse *ellipse = new SPGenericEllipse(); + ellipse->type = SP_GENERIC_ELLIPSE_ELLIPSE; + return (SPObject*)ellipse; } SPObject *create_circle() { - return new SPCircle(); + SPGenericEllipse *circle = new SPGenericEllipse(); + circle->type = SP_GENERIC_ELLIPSE_CIRCLE; + return (SPObject*)circle; } SPObject *create_arc() { - return new SPArc(); + SPGenericEllipse *arc = new SPGenericEllipse(); + arc->type = SP_GENERIC_ELLIPSE_ARC; + return (SPObject*)arc; } bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse); @@ -76,16 +83,120 @@ SPGenericEllipse::~SPGenericEllipse() { } +void SPGenericEllipse::setClosed(bool value) { + _closed = value; +} + bool SPGenericEllipse::closed() { return _closed; } -void SPGenericEllipse::setClosed(bool value) { - _closed = value; +void SPGenericEllipse::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + // std::cout << "SPGenericEllipse::build: Entrance: " << this->type + // << " (" << g_quark_to_string(repr->code()) << ")" << std::endl; + + switch ( type ) { + case SP_GENERIC_ELLIPSE_ARC: + 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"); + break; + + case SP_GENERIC_ELLIPSE_CIRCLE: + this->readAttr("cx"); + this->readAttr("cy"); + this->readAttr("r"); + break; + + case SP_GENERIC_ELLIPSE_ELLIPSE: + this->readAttr("cx"); + this->readAttr("cy"); + this->readAttr("rx"); + this->readAttr("ry"); + break; + + default: + std::cerr << "SPGenericEllipse::build() unknown defined type." << std::endl; + } + + SPShape::build(document, repr); +} + +void SPGenericEllipse::set(unsigned int key, gchar const *value) +{ + // There are multiple ways to set internal cx, cy, rx, and ry (via SVG attributes or Sodipodi + // attributes) thus we don't want to unset them if a read fails (e.g., when we explicitly clear + // an attribute by setting it to NULL). + SVGLength t; + switch (key) { + case SP_ATTR_CX: + case SP_ATTR_SODIPODI_CX: + if( t.read(value) ) cx = t; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_CY: + case SP_ATTR_SODIPODI_CY: + if( t.read(value) ) cy = t; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_RX: + case SP_ATTR_SODIPODI_RX: + if( t.read(value) && t.value > 0.0 ) this->rx = t; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_RY: + case SP_ATTR_SODIPODI_RY: + if( t.read(value) && t.value > 0.0 ) this->ry = t; + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_R: + if( t.read(value) && t.value > 0.0 ) { + this->ry = this->rx = t; + } + 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; + } + 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; + } + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_SODIPODI_OPEN: + this->_closed = (!value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + default: + SPShape::set(key, value); + break; + } } void SPGenericEllipse::update(SPCtx *ctx, guint flags) { + // std::cout << "\nSPGenericEllipse::update: Entrance" << std::endl; if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { Geom::Rect const &viewbox = ((SPItemCtx const *) ctx)->viewport; @@ -104,36 +215,185 @@ void SPGenericEllipse::update(SPCtx *ctx, guint flags) } SPShape::update(ctx, flags); + // std::cout << "SPGenericEllipse::update: Exit\n" << std::endl; } -void SPGenericEllipse::update_patheffect(bool write) +Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - this->set_shape(); + // std::cout << "\nSPGenericEllipse::write: Entrance (" + // << (repr == NULL ? " NULL" : g_quark_to_string(repr->code())) + // << ")" << std::endl; - if (write) { - Inkscape::XML::Node *repr = this->getRepr(); + GenericEllipseType new_type = SP_GENERIC_ELLIPSE_UNDEFINED; + if (this->_isSlice() || hasPathEffect() ) { + new_type = SP_GENERIC_ELLIPSE_ARC; + } else if ( rx.computed == ry.computed ) { + new_type = SP_GENERIC_ELLIPSE_CIRCLE; + } else { + new_type = SP_GENERIC_ELLIPSE_ELLIPSE; + } + // std::cout << " new_type: " << new_type << std::endl; - if (this->_curve != NULL) { - gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + + switch ( new_type ) { + + case SP_GENERIC_ELLIPSE_ARC: + repr = xml_doc->createElement("svg:path"); + break; + case SP_GENERIC_ELLIPSE_CIRCLE: + repr = xml_doc->createElement("svg:circle"); + break; + case SP_GENERIC_ELLIPSE_ELLIPSE: + repr = xml_doc->createElement("svg:ellipse"); + break; + case SP_GENERIC_ELLIPSE_UNDEFINED: + default: + std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl; } } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + if( type != new_type ) { + switch( new_type ) { + case SP_GENERIC_ELLIPSE_ARC: + repr->setCodeUnsafe(g_quark_from_string("svg:path")); + break; + case SP_GENERIC_ELLIPSE_CIRCLE: + repr->setCodeUnsafe(g_quark_from_string("svg:circle")); + break; + case SP_GENERIC_ELLIPSE_ELLIPSE: + repr->setCodeUnsafe(g_quark_from_string("svg:ellipse")); + break; + default: + std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl; + } + type = new_type; + + // FIXME: The XML dialog won't update the element name. We need + // a notifyElementNameChanged callback added to the XML observers + // to trigger a refresh. + } + + // std::cout << " type: " << g_quark_to_string( repr->code() ) << std::endl; + // std::cout << " cx: " << cx.computed + // << " cy: " << cy.computed + // << " rx: " << rx.computed + // << " ry: " << ry.computed << std::endl; + + switch ( type ) { + case SP_GENERIC_ELLIPSE_UNDEFINED: + case SP_GENERIC_ELLIPSE_ARC: + + repr->setAttribute("cx", NULL ); + repr->setAttribute("cy", NULL ); + repr->setAttribute("rx", NULL ); + repr->setAttribute("ry", NULL ); + repr->setAttribute("r", NULL ); + + if (flags & SP_OBJECT_WRITE_EXT) { + + repr->setAttribute("sodipodi:type", "arc"); + sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed); + sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed); + sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed); + 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()) { + 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); + } else { + repr->setAttribute("sodipodi:end", NULL); + repr->setAttribute("sodipodi:start", NULL); + repr->setAttribute("sodipodi:open", NULL); + } + } + + // write d= + this->set_elliptical_path_attribute(repr); + break; + + case SP_GENERIC_ELLIPSE_CIRCLE: + sp_repr_set_svg_double(repr, "cx", this->cx.computed); + sp_repr_set_svg_double(repr, "cy", this->cy.computed); + sp_repr_set_svg_double(repr, "r", this->rx.computed); + repr->setAttribute("rx", NULL ); + repr->setAttribute("ry", NULL ); + repr->setAttribute("sodipodi:cx", NULL ); + repr->setAttribute("sodipodi:cy", NULL ); + repr->setAttribute("sodipodi:rx", NULL ); + repr->setAttribute("sodipodi:ry", NULL ); + repr->setAttribute("sodipodi:end", NULL ); + repr->setAttribute("sodipodi:start", NULL ); + repr->setAttribute("sodipodi:open", NULL ); + repr->setAttribute("sodipodi:type", NULL ); + repr->setAttribute("d", NULL ); + break; + + case SP_GENERIC_ELLIPSE_ELLIPSE: + sp_repr_set_svg_double(repr, "cx", this->cx.computed); + sp_repr_set_svg_double(repr, "cy", this->cy.computed); + sp_repr_set_svg_double(repr, "rx", this->rx.computed); + sp_repr_set_svg_double(repr, "ry", this->ry.computed); + repr->setAttribute("r", NULL ); + repr->setAttribute("sodipodi:cx", NULL ); + repr->setAttribute("sodipodi:cy", NULL ); + repr->setAttribute("sodipodi:rx", NULL ); + repr->setAttribute("sodipodi:ry", NULL ); + repr->setAttribute("sodipodi:end", NULL ); + repr->setAttribute("sodipodi:start", NULL ); + repr->setAttribute("sodipodi:open", NULL ); + repr->setAttribute("sodipodi:type", NULL ); + repr->setAttribute("d", NULL ); + break; + + default: + std::cerr << "SPGenericEllipse::write: unknown type." << std::endl; + } + + this->set_shape(); // evaluate SPCurve + + SPShape::write(xml_doc, repr, flags); + + // std::cout << "SPGenericEllipse::write: Exit: " << g_quark_to_string(repr->code()) << "\n" << std::endl; + return repr; } -bool SPGenericEllipse::_isSlice() const +const char *SPGenericEllipse::displayName() { - Geom::AngleInterval a(this->start, this->end, true); - return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI)); + switch ( type ) { + case SP_GENERIC_ELLIPSE_UNDEFINED: + case SP_GENERIC_ELLIPSE_ARC: + + if (this->_isSlice()) { + if (this->_closed) { + return _("Segment"); + } else { + return _("Arc"); + } + } else { + return _("Ellipse"); + } + + case SP_GENERIC_ELLIPSE_CIRCLE: + return _("Circle"); + + case SP_GENERIC_ELLIPSE_ELLIPSE: + return _("Ellipse"); + + default: + return "Unknown ellipse: ERROR"; + } + return ("Shouldn't be here"); } +// Create path for rendering shape on screen void SPGenericEllipse::set_shape() { + // std::cout << "SPGenericEllipse::set_shape: Entrance" << std::endl; 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"); @@ -147,7 +407,6 @@ void SPGenericEllipse::set_shape() return; } - if (Geom::are_near(this->rx.computed, 0) || Geom::are_near(this->ry.computed, 0)) { return; } @@ -196,6 +455,10 @@ void SPGenericEllipse::set_shape() curve->closepath(); } + // gchar *str = sp_svg_write_path(curve->get_pathvector()); + // std::cout << " path: " << str << std::endl; + // g_free(str); + // Stretching / moving the calculated shape to fit the actual dimensions. Geom::Affine aff = Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); curve->transform(aff); @@ -217,54 +480,7 @@ void SPGenericEllipse::set_shape() } curve->unref(); -} - -void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) -{ - this->normalize(); - Geom::Affine const i2dt = this->i2dt_affine(); - - // 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)) { - 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)); - } - } - } - - double cx = this->cx.computed; - double cy = this->cy.computed; - - 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) { - Geom::Point pt = Geom::Point(cx, cy) * i2dt; - p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP)); - } - - 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 (!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 (!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)); - } - } + // std::cout << "SPGenericEllipse::set_shape: Exit" << std::endl; } Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) @@ -323,215 +539,105 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) return ret; } -void SPGenericEllipse::normalize() -{ - Geom::AngleInterval a(this->start, this->end, true); - - 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) +void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { - if (flags & SP_OBJECT_WRITE_EXT) { - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:path"); - } - - sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed); - sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed); - sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed); - sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); + this->normalize(); + Geom::Affine const i2dt = this->i2dt_affine(); - if (SP_IS_ARC(this)) { - SP_ARC(this)->sp_arc_set_elliptical_path_attribute(this->getRepr()); + // 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)) { + 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)); + } } } - this->set_shape(); // evaluate SPCurve - - SPShape::write(xml_doc, repr, flags); - - return repr; -} - -/* SVG <ellipse> element */ -SPEllipse::SPEllipse() : SPGenericEllipse() -{ -} - -SPEllipse::~SPEllipse() -{ -} - -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"); -} + double cx = this->cx.computed; + double cy = this->cy.computed; + + bool slice = this->_isSlice(); -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"); + // 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)); } - sp_repr_set_svg_double(repr, "cx", this->cx.computed); - sp_repr_set_svg_double(repr, "cy", this->cy.computed); - sp_repr_set_svg_double(repr, "rx", this->rx.computed); - sp_repr_set_svg_double(repr, "ry", this->ry.computed); - - SPGenericEllipse::write(xml_doc, repr, flags); - - return repr; -} - - -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; + 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)); + } - case SP_ATTR_RX: - if (!this->rx.read(value) || (this->rx.value <= 0.0)) { - this->rx.unset(); + // 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 (!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)); } - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_RY: - if (!this->ry.read(value) || (this->ry.value <= 0.0)) { - this->ry.unset(); + // Add the end point, if it's not coincident with a quadrant point + 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)); } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - default: - SPGenericEllipse::set(key, value); - break; } } -const char *SPEllipse::displayName() -{ - return _("Ellipse"); -} - - -/* SVG <circle> element */ -SPCircle::SPCircle() : SPGenericEllipse() +void SPGenericEllipse::modified(guint flags) { -} - -SPCircle::~SPCircle() -{ -} - -void SPCircle::build(SPDocument *document, Inkscape::XML::Node *repr) -{ - SPGenericEllipse::build(document, repr); - - 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) -{ - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:circle"); + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + this->set_shape(); } - sp_repr_set_svg_double(repr, "cx", this->cx.computed); - sp_repr_set_svg_double(repr, "cy", this->cy.computed); - sp_repr_set_svg_double(repr, "r", this->rx.computed); - - SPGenericEllipse::write(xml_doc, repr, flags); - - return repr; + SPShape::modified(flags); } -void SPCircle::set(unsigned int key, gchar const *value) +void SPGenericEllipse::update_patheffect(bool write) { - switch (key) { - case SP_ATTR_CX: - this->cx.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + this->set_shape(); - case SP_ATTR_CY: - this->cy.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; + if (write) { + Inkscape::XML::Node *repr = this->getRepr(); - case SP_ATTR_R: - if (!this->rx.read(value) || this->rx.value <= 0.0) { - this->rx.unset(); + if (this->_curve != NULL) { + gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); } - - this->ry = this->rx; - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - - default: - SPGenericEllipse::set(key, value); - break; } -} -const char *SPCircle::displayName() -{ - return _("Circle"); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } -/* <path sodipodi:type="arc"> element */ -SPArc::SPArc() : SPGenericEllipse() +void SPGenericEllipse::normalize() { -} + Geom::AngleInterval a(this->start, this->end, true); -SPArc::~SPArc() -{ + this->start = a.initialAngle().radians0(); + this->end = a.finalAngle().radians0(); } -void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) +Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const { - SPGenericEllipse::build(document, repr); - - 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"); + return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); } /* - * sp_arc_set_elliptical_path_attribute: + * set_elliptical_path_attribute: * * Convert center to endpoint parameterization and set it to 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 SPGenericEllipse::set_elliptical_path_attribute(Inkscape::XML::Node *repr) { Inkscape::SVG::PathString str; @@ -566,124 +672,7 @@ 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) -{ - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:path"); - } - - if (flags & SP_OBJECT_WRITE_EXT) { - repr->setAttribute("sodipodi:type", "arc"); - - sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed); - sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed); - sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed); - 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()) { - 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); - } else { - repr->setAttribute("sodipodi:end", NULL); - repr->setAttribute("sodipodi:start", NULL); - repr->setAttribute("sodipodi:open", NULL); - } - } - - // write d= - this->sp_arc_set_elliptical_path_attribute(repr); - - SPGenericEllipse::write(xml_doc, repr, flags); - - return repr; -} - -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(); - } - - 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(); - } - - 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; - } - - 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; - } - - 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; - } -} - -void SPArc::modified(guint flags) -{ - if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - this->set_shape(); - } - - SPGenericEllipse::modified(flags); -} - -const char *SPArc::displayName() -{ - if (this->_isSlice()) { - if (this->_closed) { - return _("Segment"); - } else { - return _("Arc"); - } - } else { - return _("Ellipse"); - } -} - -void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) +void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) { this->cx.computed = x; this->cy.computed = y; @@ -706,9 +695,11 @@ 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 +bool SPGenericEllipse::_isSlice() const { - return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed); + Geom::AngleInterval a(this->start, this->end, true); + + return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI)); } /* diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index eab0b4907..94bddde98 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -7,9 +7,11 @@ * Authors: * Lauris Kaplinski <lauris@kaplinski.com> * Mitsuru Oka + * Tavmjong Bah * * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2013 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -21,11 +23,20 @@ #define SP_GENERICELLIPSE(obj) (dynamic_cast<SPGenericEllipse*>((SPObject*)obj)) #define SP_IS_GENERICELLIPSE(obj) (dynamic_cast<const SPGenericEllipse*>((SPObject*)obj) != NULL) +enum GenericEllipseType { + SP_GENERIC_ELLIPSE_UNDEFINED, + SP_GENERIC_ELLIPSE_ARC, + SP_GENERIC_ELLIPSE_CIRCLE, + SP_GENERIC_ELLIPSE_ELLIPSE +}; + class SPGenericEllipse : public SPShape { public: SPGenericEllipse(); virtual ~SPGenericEllipse(); + // Regardless of type, the ellipse/circle/arc is stored + // internally with these variables. (Circle radius is rx). SVGLength cx; SVGLength cy; SVGLength rx; @@ -38,14 +49,23 @@ public: void setClosed(bool value); double start, end; + GenericEllipseType type; + + virtual void build(SPDocument *document, Inkscape::XML::Node *repr); + virtual void set(unsigned int key, gchar const *value); 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 const char *displayName(); - virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); virtual void set_shape(); virtual Geom::Affine set_transform(Geom::Affine const &xform); + virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); + + virtual void modified(unsigned int flags); + virtual void update_patheffect(bool write); /** @@ -55,6 +75,9 @@ public: Geom::Point getPointAtAngle(double arg) const; + bool set_elliptical_path_attribute(Inkscape::XML::Node *repr); + void position_set(gdouble x, gdouble y, gdouble rx, gdouble ry); + protected: /** * @brief Determines whether the shape is a part of an ellipse. @@ -64,62 +87,6 @@ protected: bool _closed; }; - -/* SVG <ellipse> element */ -#define SP_ELLIPSE(obj) (dynamic_cast<SPEllipse*>((SPObject*)obj)) -#define SP_IS_ELLIPSE(obj) (dynamic_cast<const SPEllipse*>((SPObject*)obj) != NULL) - -class SPEllipse : public SPGenericEllipse { -public: - 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(); -}; - - -/* SVG <circle> element */ -#define SP_CIRCLE(obj) (dynamic_cast<SPCircle*>((SPObject*)obj)) -#define SP_IS_CIRCLE(obj) (dynamic_cast<const SPCircle*>((SPObject*)obj) != NULL) - -class SPCircle : public SPGenericEllipse { -public: - 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(); -}; - - -/* <path sodipodi:type="arc"> element */ -#define SP_ARC(obj) (dynamic_cast<SPArc*>((SPObject*)obj)) -#define SP_IS_ARC(obj) (dynamic_cast<const SPArc*>((SPObject*)obj) != NULL) - -class SPArc : public SPGenericEllipse { -public: - 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); - - 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 /* diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index b7e4ee4a9..61ba2ae0d 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -35,6 +35,7 @@ #include "inkscape.h" #include "desktop.h" #include "shape-editor.h" +#include "sp-ellipse.h" #include <algorithm> @@ -387,6 +388,10 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) this->getRepr()->setAttribute("inkscape:path-effect", hrefs.c_str()); + // Make sure that ellipse is stored as <svg:path> + if( SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); + } // make sure there is an original-d for paths!!! sp_lpe_item_create_original_path_recursive(this); @@ -436,6 +441,10 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); } else { this->getRepr()->setAttribute("inkscape:path-effect", NULL); + // Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible. + if( SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); + } } if (!keep_paths) { @@ -447,6 +456,11 @@ void SPLPEItem::removeAllPathEffects(bool keep_paths) { this->getRepr()->setAttribute("inkscape:path-effect", NULL); + // Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible. + if( SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); + } + if (!keep_paths) { sp_lpe_item_cleanup_original_path_recursive(this); } diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 2c3c7fa65..5a204e8b0 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1058,9 +1058,9 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb end = start + 2.0 * M_PI; } - if ( SP_IS_ARC( item ) ) { + if ( SP_IS_GENERICELLIPSE( item ) ) { // For arcs use set start/stop - SPArc* arc = SP_ARC( item ); + SPGenericEllipse* arc = SP_GENERICELLIPSE( item ); center[Geom::X] = arc->cx.computed; center[Geom::Y] = arc->cy.computed; rx = arc->rx.computed; @@ -1130,11 +1130,11 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // Normal grid meshes - if( SP_IS_ARC( item ) ) { + if( SP_IS_GENERICELLIPSE( item ) ) { // std::cout << "We've got ourselves an arc!" << std::endl; - SPArc* arc = SP_ARC( item ); + SPGenericEllipse* arc = SP_GENERICELLIPSE( item ); center[Geom::X] = arc->cx.computed; center[Geom::Y] = arc->cy.computed; gdouble rx = arc->rx.computed; diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index def7b5bdb..37f2761df 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -664,7 +664,7 @@ bool Find::item_type_match (SPItem *item) if ( SP_IS_RECT(item)) { return ( all ||check_rects.get_active()); - } else if (SP_IS_GENERICELLIPSE(item) || SP_IS_ELLIPSE(item) || SP_IS_ARC(item) || SP_IS_CIRCLE(item)) { + } else if (SP_IS_GENERICELLIPSE(item)) { return ( all || check_ellipses.get_active()); } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index c31c61e32..5569780e7 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -112,10 +112,9 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v { SPItem *item = SP_ITEM(items->data); - if (SP_IS_ARC(item) && SP_IS_GENERICELLIPSE(item)) { + if (SP_IS_GENERICELLIPSE(item)) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - SPArc *arc = SP_ARC(item); if (!strcmp(value_name, "start")) { ge->start = (gtk_adjustment_get_value(adj) * M_PI)/ 180; @@ -124,8 +123,8 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v } ge->normalize(); - (SP_OBJECT(arc))->updateRepr(); - (SP_OBJECT(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + (SP_OBJECT(ge))->updateRepr(); + (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); modmade = true; } @@ -181,7 +180,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) items = items->next) { SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_ARC(item)) { + if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", "true"); item->updateRepr(); @@ -194,7 +193,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_ARC(item)) { + if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", NULL); item->updateRepr(); @@ -286,7 +285,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_ARC(item)) { + if (SP_IS_GENERICELLIPSE(item)) { n_selected++; repr = item->getRepr(); } |
