diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index 97656375428a9f4eef0251254888b93cc9f322c9..ef58e4d6e316b6866ff46efaa3a9dc139270c5fb 100644 (file)
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
-#define __SP_ELLIPSE_C__
-
/*
* SVG <ellipse> and related implementations
*
* Lauris Kaplinski <lauris@kaplinski.com>
* Mitsuru Oka
* bulia byak <buliabyak@users.sf.net>
+ * Abhishek Sharma
*
* Copyright (C) 1999-2002 Lauris Kaplinski
* Copyright (C) 2000-2001 Ximian, Inc.
#include "display/curve.h"
#include <glibmm/i18n.h>
#include <2geom/transforms.h>
-
+#include <2geom/pathvector.h>
#include "document.h"
#include "sp-ellipse.h"
-
#include "preferences.h"
+#include "snap-candidate.h"
/* Common parent class */
static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs);
+static void sp_genericellipse_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_genericellipse_set_shape(SPShape *shape);
static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
SPGenericEllipse *ellipse = (SPGenericEllipse *) object;
SPStyle const *style = object->style;
Geom::OptRect viewbox = ((SPItemCtx const *) ctx)->vp;
- double const dx = viewbox->width();
- double const dy = viewbox->height();
- double const dr = sqrt(dx*dx + dy*dy)/sqrt(2);
- double const em = style->font_size.computed;
- double const ex = em * 0.5; // fixme: get from pango or libnrtype
- ellipse->cx.update(em, ex, dx);
- ellipse->cy.update(em, ex, dy);
- ellipse->rx.update(em, ex, dr);
- ellipse->ry.update(em, ex, dr);
- sp_shape_set_shape((SPShape *) object);
+ if (viewbox) {
+ double const dx = viewbox->width();
+ double const dy = viewbox->height();
+ double const dr = sqrt(dx*dx + dy*dy)/sqrt(2);
+ double const em = style->font_size.computed;
+ double const ex = em * 0.5; // fixme: get from pango or libnrtype
+ ellipse->cx.update(em, ex, dx);
+ ellipse->cy.update(em, ex, dy);
+ ellipse->rx.update(em, ex, dr);
+ ellipse->ry.update(em, ex, dr);
+ static_cast<SPShape *>(object)->setShape();
+ }
}
if (((SPObjectClass *) ge_parent_class)->update)
((SPObject *)shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
-
-#define C1 0.552
-
/* fixme: Think (Lauris) */
/* Can't we use arcto in this method? */
static void sp_genericellipse_set_shape(SPShape *shape)
{
+ if (sp_lpe_item_has_broken_path_effect(SP_LPE_ITEM(shape))) {
+ 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 (SP_OBJECT_REPR(shape)->attribute("d")) {
+ // unconditionally read the curve from d, if any, to preserve appearance
+ Geom::PathVector pv = sp_svg_read_pathv(SP_OBJECT_REPR(shape)->attribute("d"));
+ SPCurve *cold = new SPCurve(pv);
+ shape->setCurveInsync( cold, TRUE);
+ cold->unref();
+ }
+ return;
+ }
+
double rx, ry, s, e;
double x0, y0, x1, y1, x2, y2, x3, y3;
double len;
e = s + M_PI_2;
if (e > ellipse->end)
e = ellipse->end;
- len = C1 * (e - s) / M_PI_2;
+ len = 4*tan((e - s)/4)/3;
x0 = cos(s);
y0 = sin(s);
x1 = x0 + len * cos(s + M_PI_2);
/* Reset the shape'scurve to the "original_curve"
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
- sp_shape_set_curve_insync (shape, curve, TRUE);
+ shape->setCurveInsync( curve, TRUE);
if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
SPCurve *c_lpe = curve->copy();
bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
if (success) {
- sp_shape_set_curve_insync (shape, c_lpe, TRUE);
+ shape->setCurveInsync( c_lpe, TRUE);
}
c_lpe->unref();
}
curve->unref();
}
-static void sp_genericellipse_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs)
+static void sp_genericellipse_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
{
g_assert(item != NULL);
g_assert(SP_IS_GENERICELLIPSE(item));
// Help enforcing strict snapping, i.e. only return nodes when we're snapping nodes to nodes or a guide to nodes
- if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
- return;
- }
+ if (!(snapprefs->getSnapModeNode() || snapprefs->getSnapModeGuide())) {
+ return;
+ }
SPGenericEllipse *ellipse = SP_GENERICELLIPSE(item);
sp_genericellipse_normalize(ellipse);
- Geom::Matrix const i2d = sp_item_i2d_affine(item);
+ Geom::Matrix const i2d = item->i2d_affine();
// figure out if we have a slice, while guarding against rounding errors
bool slice = false;
@@ -295,19 +305,19 @@ static void sp_genericellipse_snappoints(SPItem const *item, bool const target,
// Snap to the 4 quadrant points of the ellipse, but only if the arc
// spans far enough to include them
if (snapprefs->getSnapToItemNode()) { //TODO: Make a separate snap option toggle for this?
- double angle = 0;
- for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
- if (angle >= ellipse->start && angle <= ellipse->end) {
- pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
- p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT) : int(Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT)));
- }
- }
+ double angle = 0;
+ for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
+ if (angle >= ellipse->start && angle <= ellipse->end) {
+ pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2d;
+ 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
if ((snapprefs->getSnapToItemNode() && slice && ellipse->closed) || snapprefs->getSnapObjectMidpoints()) {
- pt = Geom::Point(cx, cy) * i2d;
- p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_HANDLE) : int(Inkscape::SNAPSOURCE_HANDLE)));
+ pt = Geom::Point(cx, cy) * i2d;
+ p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_CENTER, Inkscape::SNAPTARGET_CENTER));
}
// And if we have a slice, also snap to the endpoints
@@ -315,12 +325,12 @@ static void sp_genericellipse_snappoints(SPItem const *item, bool const target,
// Add the start point, if it's not coincident with a quadrant point
if (fmod(ellipse->start, M_PI_2) != 0.0 ) {
pt = Geom::Point(cx + cos(ellipse->start)*rx, cy + sin(ellipse->start)*ry) * i2d;
- p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
+ 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(ellipse->end, M_PI_2) != 0.0 ) {
pt = Geom::Point(cx + cos(ellipse->end)*rx, cy + sin(ellipse->end)*ry) * i2d;
- p.push_back(std::make_pair(pt, target ? int(Inkscape::SNAPTARGET_NODE_CUSP) : int(Inkscape::SNAPSOURCE_NODE_CUSP)));
+ p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
}
}
}
@@ -424,10 +434,10 @@ sp_ellipse_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *re
if (((SPObjectClass *) ellipse_parent_class)->build)
(* ((SPObjectClass *) ellipse_parent_class)->build) (object, document, repr);
- sp_object_read_attr(object, "cx");
- sp_object_read_attr(object, "cy");
- sp_object_read_attr(object, "rx");
- sp_object_read_attr(object, "ry");
+ object->readAttr( "cx" );
+ object->readAttr( "cy" );
+ object->readAttr( "rx" );
+ object->readAttr( "ry" );
}
static Inkscape::XML::Node *
@@ -572,9 +582,9 @@ sp_circle_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *rep
if (((SPObjectClass *) circle_parent_class)->build)
(* ((SPObjectClass *) circle_parent_class)->build)(object, document, repr);
- sp_object_read_attr(object, "cx");
- sp_object_read_attr(object, "cy");
- sp_object_read_attr(object, "r");
+ object->readAttr( "cx" );
+ object->readAttr( "cy" );
+ object->readAttr( "r" );
}
static Inkscape::XML::Node *
@@ -697,16 +707,14 @@ sp_arc_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
if (((SPObjectClass *) arc_parent_class)->build)
(* ((SPObjectClass *) arc_parent_class)->build) (object, document, repr);
- Inkscape::Version version = sp_object_get_sodipodi_version(object);
-
- sp_object_read_attr(object, "sodipodi:cx");
- sp_object_read_attr(object, "sodipodi:cy");
- sp_object_read_attr(object, "sodipodi:rx");
- sp_object_read_attr(object, "sodipodi:ry");
+ object->readAttr( "sodipodi:cx" );
+ object->readAttr( "sodipodi:cy" );
+ object->readAttr( "sodipodi:rx" );
+ object->readAttr( "sodipodi:ry" );
- sp_object_read_attr(object, "sodipodi:start");
- sp_object_read_attr(object, "sodipodi:end");
- sp_object_read_attr(object, "sodipodi:open");
+ object->readAttr( "sodipodi:start" );
+ object->readAttr( "sodipodi:end" );
+ object->readAttr( "sodipodi:open" );
}
/*
sp_arc_modified(SPObject *object, guint flags)
{
if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
- sp_shape_set_shape((SPShape *) object);
+ ((SPShape *) object)->setShape();
}
if (((SPObjectClass *) arc_parent_class)->modified)
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);
+ 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);
+ ge->end = prefs->getDouble("/tools/shapes/arc/end", 0.0) * M_PI / 180;
if (!prefs->getBool("/tools/shapes/arc/open"))
ge->closed = 1;
else
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :