diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index f558bc229322735dc33a728f1d6edb12666b367c..087c323f12d4af3bedf0eda18890121570420a65 100644 (file)
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p);
static void sp_genericellipse_set_shape(SPShape *shape);
-static void sp_genericellipse_update_patheffect (SPShape *shape, bool write);
+static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
-static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Node *repr,
+static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr,
guint flags);
static gboolean sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr);
{
SPObjectClass *sp_object_class = (SPObjectClass *) klass;
SPItemClass *item_class = (SPItemClass *) klass;
+ SPLPEItemClass *lpe_item_class = (SPLPEItemClass *) klass;
SPShapeClass *shape_class = (SPShapeClass *) klass;
ge_parent_class = (SPShapeClass*) g_type_class_ref(SP_TYPE_SHAPE);
item_class->snappoints = sp_genericellipse_snappoints;
shape_class->set_shape = sp_genericellipse_set_shape;
- shape_class->update_patheffect = sp_genericellipse_update_patheffect;
+ lpe_item_class->update_patheffect = sp_genericellipse_update_patheffect;
}
static void
}
static void
-sp_genericellipse_update_patheffect(SPShape *shape, bool write)
+sp_genericellipse_update_patheffect(SPLPEItem *lpeitem, bool write)
{
+ SPShape *shape = (SPShape *) lpeitem;
sp_genericellipse_set_shape(shape);
if (write) {
Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
if ( shape->curve != NULL ) {
- NArtBpath *abp = sp_curve_first_bpath(shape->curve);
- if (abp) {
- gchar *str = sp_svg_write_path(abp);
- repr->setAttribute("d", str);
- g_free(str);
- } else {
- repr->setAttribute("d", "");
- }
+ gchar *str = sp_svg_write_path(shape->curve->get_pathvector());
+ repr->setAttribute("d", str);
+ g_free(str);
} else {
repr->setAttribute("d", NULL);
}
static void sp_genericellipse_set_shape(SPShape *shape)
{
- double cx, cy, rx, ry, s, e;
+ double rx, ry, s, e;
double x0, y0, x1, y1, x2, y2, x3, y3;
double len;
gint slice = FALSE;
sp_genericellipse_normalize(ellipse);
- cx = 0.0;
- cy = 0.0;
rx = ellipse->rx.computed;
ry = ellipse->ry.computed;
}
bpath[i].code = NR_END;
- SPCurve *c = sp_curve_new_from_bpath(nr_artpath_affine(bpath, aff));
+ SPCurve *c = SPCurve::new_from_bpath(nr_artpath_affine(bpath, aff));
g_assert(c != NULL);
- sp_shape_perform_path_effect(c, SP_SHAPE (ellipse));
+ sp_lpe_item_perform_path_effect(SP_LPE_ITEM (ellipse), c);
sp_shape_set_curve_insync((SPShape *) ellipse, c, TRUE);
- sp_curve_unref(c);
+ c->unref();
}
static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p)
{
- SPGenericEllipse const *ge = SP_GENERICELLIPSE(item);
-
- NR::Matrix const i2d = sp_item_i2d_affine(item);
+ g_assert(item != NULL);
+ g_assert(SP_IS_GENERICELLIPSE(item));
+
+ SPGenericEllipse *ellipse = SP_GENERICELLIPSE(item);
+ sp_genericellipse_normalize(ellipse);
+ NR::Matrix const i2d = from_2geom(sp_item_i2d_affine(item));
- /* Add the centre */
- *p = NR::Point(ge->cx.computed, ge->cy.computed) * i2d;
+ // figure out if we have a slice, whilst guarding against rounding errors
+ bool slice = false;
+ double len = fmod(ellipse->end - ellipse->start, SP_2PI);
+ if (len < 0.0) len += SP_2PI;
+ if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) {
+ slice = false;
+ ellipse->end = ellipse->start + SP_2PI;
+ } else {
+ slice = true;
+ }
- // TODO: add the ends of radii
+ double rx = ellipse->rx.computed;
+ double ry = ellipse->ry.computed;
+ double cx = ellipse->cx.computed;
+ double cy = ellipse->cy.computed;
+
+ // Snap to the 4 quadrant points of the ellipse, but only if the arc
+ // spans far enough to include them
+ double angle = 0;
+ for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
+ if (angle >= ellipse->start && angle <= ellipse->end) {
+ *p = NR::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+ }
+ }
+
+ // And if we have a slice, also snap to the endpoints and the centre point
+ if (slice) {
+ // Add the centre, if we have a closed slice
+ if (ellipse->closed) {
+ *p = NR::Point(cx, cy) * i2d;
+ }
+ // Add the start point, if it's not coincident with a quadrant point
+ if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
+ *p = NR::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
+ }
+ // Add the end point, if it's not coincident with a quadrant point
+ if (fmod(ellipse->end, M_PI_2) != 0.0 ) {
+ *p = NR::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
+ }
+ }
}
void
/* Now we keep: 0 <= start < end <= 2*PI */
}
-static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPGenericEllipse *ellipse = SP_GENERICELLIPSE(object);
if (flags & SP_OBJECT_WRITE_EXT) {
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
repr = xml_doc->createElement("svg:path");
}
@@ -328,7 +361,7 @@ static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::
}
if (((SPObjectClass *) ge_parent_class)->write)
- ((SPObjectClass *) ge_parent_class)->write(object, repr, flags);
+ ((SPObjectClass *) ge_parent_class)->write(object, xml_doc, repr, flags);
return repr;
}
static void sp_ellipse_init(SPEllipse *ellipse);
static void sp_ellipse_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static Inkscape::XML::Node *sp_ellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_ellipse_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static void sp_ellipse_set(SPObject *object, unsigned int key, gchar const *value);
static gchar *sp_ellipse_description(SPItem *item);
}
static void
-sp_ellipse_init(SPEllipse *ellipse)
+sp_ellipse_init(SPEllipse */*ellipse*/)
{
/* Nothing special */
}
@@ -400,14 +433,13 @@ sp_ellipse_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *re
}
static Inkscape::XML::Node *
-sp_ellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_ellipse_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPGenericEllipse *ellipse;
ellipse = SP_GENERICELLIPSE(object);
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
repr = xml_doc->createElement("svg:ellipse");
}
sp_repr_set_svg_double(repr, "ry", ellipse->ry.computed);
if (((SPObjectClass *) ellipse_parent_class)->write)
- (* ((SPObjectClass *) ellipse_parent_class)->write) (object, repr, flags);
+ (* ((SPObjectClass *) ellipse_parent_class)->write) (object, xml_doc, repr, flags);
return repr;
}
}
}
-static gchar *sp_ellipse_description(SPItem *item)
+static gchar *sp_ellipse_description(SPItem */*item*/)
{
return g_strdup(_("<b>Ellipse</b>"));
}
static void sp_circle_init(SPCircle *circle);
static void sp_circle_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static Inkscape::XML::Node *sp_circle_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_circle_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static void sp_circle_set(SPObject *object, unsigned int key, gchar const *value);
static gchar *sp_circle_description(SPItem *item);
}
static void
-sp_circle_init(SPCircle *circle)
+sp_circle_init(SPCircle */*circle*/)
{
/* Nothing special */
}
@@ -548,14 +580,13 @@ sp_circle_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *rep
}
static Inkscape::XML::Node *
-sp_circle_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_circle_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPGenericEllipse *ellipse;
ellipse = SP_GENERICELLIPSE(object);
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
repr = xml_doc->createElement("svg:circle");
}
sp_repr_set_svg_double(repr, "r", ellipse->rx.computed);
if (((SPObjectClass *) circle_parent_class)->write)
- ((SPObjectClass *) circle_parent_class)->write(object, repr, flags);
+ ((SPObjectClass *) circle_parent_class)->write(object, xml_doc, repr, flags);
return repr;
}
}
}
-static gchar *sp_circle_description(SPItem *item)
+static gchar *sp_circle_description(SPItem */*item*/)
{
return g_strdup(_("<b>Circle</b>"));
}
static void sp_arc_init(SPArc *arc);
static void sp_arc_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static Inkscape::XML::Node *sp_arc_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_arc_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static void sp_arc_set(SPObject *object, unsigned int key, gchar const *value);
static void sp_arc_modified(SPObject *object, guint flags);
}
static void
-sp_arc_init(SPArc *arc)
+sp_arc_init(SPArc */*arc*/)
{
/* Nothing special */
}
}
static Inkscape::XML::Node *
-sp_arc_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_arc_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPGenericEllipse *ge = SP_GENERICELLIPSE(object);
SPArc *arc = SP_ARC(object);
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
repr = xml_doc->createElement("svg:path");
}
sp_arc_set_elliptical_path_attribute(arc, repr);
if (((SPObjectClass *) arc_parent_class)->write)
- ((SPObjectClass *) arc_parent_class)->write(object, repr, flags);
+ ((SPObjectClass *) arc_parent_class)->write(object, xml_doc, repr, flags);
return repr;
}