summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-09-29 22:17:20 +0000
committerMarkus Engel <markus.engel@tum.de>2013-09-29 22:17:20 +0000
commit48536172f551d67942217c6d78a7f37e79c68110 (patch)
tree67df2165aa2d13c72026314620c6f4dfd1ff6219 /src
parentAdd logging documentation and ignore QtCreator files (diff)
downloadinkscape-48536172f551d67942217c6d78a7f37e79c68110.tar.gz
inkscape-48536172f551d67942217c6d78a7f37e79c68110.zip
Further changes to SPEllipse.
(bzr r12629)
Diffstat (limited to 'src')
-rw-r--r--src/object-edit.cpp50
-rw-r--r--src/sp-ellipse.cpp70
-rw-r--r--src/sp-ellipse.h16
3 files changed, 63 insertions, 73 deletions
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<SPObject *>(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<SPObject *>(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<Inkscape::SnapCandidatePoint> &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<Inkscape::SnapCandidatePoint> &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<Inkscape::SnapCandidatePoint> &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;
};