diff options
Diffstat (limited to 'src/sp-ellipse.cpp')
| -rw-r--r-- | src/sp-ellipse.cpp | 112 |
1 files changed, 42 insertions, 70 deletions
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 25e4c07d7..a74d4687d 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -14,26 +14,25 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "svg/svg.h" -#include "svg/path-string.h" -#include "xml/repr.h" -#include "attributes.h" -#include "style.h" -#include "display/curve.h" +#include <glibmm.h> #include <glibmm/i18n.h> + #include <2geom/angle.h> #include <2geom/ellipse.h> -#include <2geom/transforms.h> -#include <2geom/pathvector.h> #include <2geom/path-sink.h> +#include <2geom/pathvector.h> +#include <2geom/transforms.h> + +#include "attributes.h" +#include "display/curve.h" #include "document.h" -#include "sp-ellipse.h" #include "preferences.h" #include "snap-candidate.h" +#include "sp-ellipse.h" +#include "style.h" +#include "svg/svg.h" +#include "svg/path-string.h" +#include "xml/repr.h" #include "sp-factory.h" @@ -42,21 +41,21 @@ SPObject *create_ellipse() { SPGenericEllipse *ellipse = new SPGenericEllipse(); ellipse->type = SP_GENERIC_ELLIPSE_ELLIPSE; - return (SPObject*)ellipse; + return ellipse; } SPObject *create_circle() { SPGenericEllipse *circle = new SPGenericEllipse(); circle->type = SP_GENERIC_ELLIPSE_CIRCLE; - return (SPObject*)circle; + return circle; } SPObject *create_arc() { SPGenericEllipse *arc = new SPGenericEllipse(); arc->type = SP_GENERIC_ELLIPSE_ARC; - return (SPObject*)arc; + return arc; } bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse); @@ -419,62 +418,35 @@ void SPGenericEllipse::set_shape() // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. Geom::Circle circle(0, 0, 1); - if (this->_isSlice()) { - Geom::Point center(0, 0); - 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::EllipticalArc *arc = circle.arc(start_point, middle_point, end_point); - - Geom::Path path(start_point); - path.append(*arc); - - delete arc; - - Geom::PathBuilder pb; - pb.append(path); - - if (this->_closed) { - // "pizza slice" - pb.lineTo(center); - pb.closePath(); - } else { - // arc only - pb.flush(); - } - - curve = new SPCurve(pb.peek()); - } else { - // Full ellipse - // This code converts the circle to four elliptical arcs explicitly. - // Circle::getPath currently creates cubic bezier curves, these are not suitable here - // as a circle should have four mid markers at 0, 90, 180, 270 degrees. - Geom::Path path(Geom::Point::polar(0)); - Geom::EllipticalArc* arc; - - arc = circle.arc(Geom::Point::polar(0), Geom::Point::polar(M_PI / 4.0), Geom::Point::polar(M_PI / 2.0)); - path.append(*arc); - delete arc; - - arc = circle.arc(Geom::Point::polar(M_PI / 2.0), Geom::Point::polar(3.0 * M_PI / 4.0), Geom::Point::polar(M_PI)); - path.append(*arc); - delete arc; + if (!this->_isSlice()) { + start = 0.0; + end = 2.0*M_PI; + } + double incr = end - start; // arc angle + if (incr < 0.0) incr += 2.0*M_PI; - arc = circle.arc(Geom::Point::polar(M_PI), Geom::Point::polar(5.0 * M_PI / 4.0), Geom::Point::polar(3.0 * M_PI / 2.0)); - path.append(*arc); - delete arc; + int numsegs = 1 + int(incr*2.0/M_PI); // number of arc segments + if (numsegs > 4) numsegs = 4; - arc = circle.arc(Geom::Point::polar(3.0 * M_PI / 2.0), Geom::Point::polar(7.0 * M_PI / 4.0), Geom::Point::polar(2.0 * M_PI)); + incr = incr/numsegs; // limit arc angle to less than 90 degrees + Geom::Path path(Geom::Point::polar(start)); + Geom::EllipticalArc* arc; + for (int seg = 0; seg < numsegs; seg++) { + arc = circle.arc(Geom::Point::polar(start + seg*incr), Geom::Point::polar(start + (seg + 0.5)*incr), Geom::Point::polar(start + (seg + 1.0)*incr)); path.append(*arc); delete arc; - - Geom::PathBuilder pb; - pb.append(path); + } + Geom::PathBuilder pb; + pb.append(path); + if (this->_isSlice() && this->_closed) { + pb.lineTo(Geom::Point(0, 0)); + } + if (this->_closed) { pb.closePath(); - - curve = new SPCurve(pb.peek()); + } else { + pb.flush(); } + curve = new SPCurve(pb.peek()); // gchar *str = sp_svg_write_path(curve->get_pathvector()); // std::cout << " path: " << str << std::endl; @@ -632,7 +604,7 @@ void SPGenericEllipse::update_patheffect(bool write) if (write) { Inkscape::XML::Node *repr = this->getRepr(); - if (this->_curve != NULL) { + if (this->_curve != NULL && type == SP_GENERIC_ELLIPSE_ARC) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); g_free(str); @@ -670,8 +642,8 @@ bool SPGenericEllipse::set_elliptical_path_attribute(Inkscape::XML::Node *repr) // Make sure our pathvector is up to date. this->set_shape(); - if (this->getCurve() != NULL) { - gchar* d = sp_svg_write_path(this->getCurve()->get_pathvector()); + if (_curve != NULL) { + gchar* d = sp_svg_write_path(_curve->get_pathvector()); repr->setAttribute("d", d); @@ -722,4 +694,4 @@ bool SPGenericEllipse::_isSlice() const fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : |
