diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp
index edcea21a24cd757af5bfb77e28a2474ae9d61e37..7d3cd1c0c5639f53de382da822380d3293b2e03b 100644 (file)
--- a/src/sp-rect.cpp
+++ b/src/sp-rect.cpp
#include <libnr/nr-matrix-div.h>
#include <libnr/nr-matrix-fns.h>
+#include "document.h"
#include "attributes.h"
#include "style.h"
#include "sp-rect.h"
#include <glibmm/i18n.h>
#include "xml/repr.h"
+#include "sp-guide.h"
+#include "prefs-utils.h"
#define noRECT_VERBOSE
static void sp_rect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
static void sp_rect_set(SPObject *object, unsigned key, gchar const *value);
static void sp_rect_update(SPObject *object, SPCtx *ctx, guint flags);
-static Inkscape::XML::Node *sp_rect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_rect_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static gchar *sp_rect_description(SPItem *item);
static NR::Matrix sp_rect_set_transform(SPItem *item, NR::Matrix const &xform);
+static void sp_rect_convert_to_guides(SPItem *item);
static void sp_rect_set_shape(SPShape *shape);
+static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p);
static SPShapeClass *parent_class;
item_class->description = sp_rect_description;
item_class->set_transform = sp_rect_set_transform;
+ item_class->convert_to_guides = sp_rect_convert_to_guides;
+ item_class->snappoints = sp_rect_snappoints; //override the default sp_shape_snappoints; see sp_rect_snappoints for details
shape_class->set_shape = sp_rect_set_shape;
}
static void
-sp_rect_init(SPRect *rect)
+sp_rect_init(SPRect */*rect*/)
{
/* Initializing to zero is automatic */
/* sp_svg_length_unset(&rect->x, SP_SVG_UNIT_NONE, 0.0, 0.0); */
@@ -114,21 +121,6 @@ sp_rect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
sp_object_read_attr(object, "height");
sp_object_read_attr(object, "rx");
sp_object_read_attr(object, "ry");
-
- Inkscape::Version const version = sp_object_get_sodipodi_version(object);
-
- if ( version.major == 0 && version.minor == 29 ) {
- if (rect->rx._set && rect->ry._set) {
- /* 0.29 treated 0.0 radius as missing value */
- if ((rect->rx.value != 0.0) && (rect->ry.value == 0.0)) {
- repr->setAttribute("ry", NULL);
- sp_object_read_attr(object, "ry");
- } else if ((rect->ry.value != 0.0) && (rect->rx.value == 0.0)) {
- repr->setAttribute("rx", NULL);
- sp_object_read_attr(object, "rx");
- }
- }
- }
}
static void
}
static Inkscape::XML::Node *
-sp_rect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_rect_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPRect *rect = SP_RECT(object);
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- repr = sp_repr_new("svg:rect");
+ repr = xml_doc->createElement("svg:rect");
}
sp_repr_set_svg_double(repr, "width", rect->width.computed);
sp_repr_set_svg_double(repr, "y", rect->y.computed);
if (((SPObjectClass *) parent_class)->write)
- ((SPObjectClass *) parent_class)->write(object, repr, flags);
+ ((SPObjectClass *) parent_class)->write(object, xml_doc, repr, flags);
return repr;
}
{
SPRect *rect = (SPRect *) shape;
- if ((rect->height.computed < 1e-18) || (rect->width.computed < 1e-18)) return;
+ if ((rect->height.computed < 1e-18) || (rect->width.computed < 1e-18)) {
+ sp_shape_set_curve_insync(SP_SHAPE(rect), NULL, TRUE);
+ return;
+ }
- SPCurve *c = sp_curve_new();
+ SPCurve *c = new SPCurve();
double const x = rect->x.computed;
double const y = rect->y.computed;
* arc fairly well.
*/
if ((rx > 1e-18) && (ry > 1e-18)) {
- sp_curve_moveto(c, x + rx, y);
- if (rx < w2) sp_curve_lineto(c, x + w - rx, y);
- sp_curve_curveto(c, x + w - rx * (1 - C1), y, x + w, y + ry * (1 - C1), x + w, y + ry);
- if (ry < h2) sp_curve_lineto(c, x + w, y + h - ry);
- sp_curve_curveto(c, x + w, y + h - ry * (1 - C1), x + w - rx * (1 - C1), y + h, x + w - rx, y + h);
- if (rx < w2) sp_curve_lineto(c, x + rx, y + h);
- sp_curve_curveto(c, x + rx * (1 - C1), y + h, x, y + h - ry * (1 - C1), x, y + h - ry);
- if (ry < h2) sp_curve_lineto(c, x, y + ry);
- sp_curve_curveto(c, x, y + ry * (1 - C1), x + rx * (1 - C1), y, x + rx, y);
+ c->moveto(x + rx, y);
+ if (rx < w2) c->lineto(x + w - rx, y);
+ c->curveto(x + w - rx * (1 - C1), y, x + w, y + ry * (1 - C1), x + w, y + ry);
+ if (ry < h2) c->lineto(x + w, y + h - ry);
+ c->curveto(x + w, y + h - ry * (1 - C1), x + w - rx * (1 - C1), y + h, x + w - rx, y + h);
+ if (rx < w2) c->lineto(x + rx, y + h);
+ c->curveto(x + rx * (1 - C1), y + h, x, y + h - ry * (1 - C1), x, y + h - ry);
+ if (ry < h2) c->lineto(x, y + ry);
+ c->curveto(x, y + ry * (1 - C1), x + rx * (1 - C1), y, x + rx, y);
} else {
- sp_curve_moveto(c, x + 0.0, y + 0.0);
- sp_curve_lineto(c, x + w, y + 0.0);
- sp_curve_lineto(c, x + w, y + h);
- sp_curve_lineto(c, x + 0.0, y + h);
- sp_curve_lineto(c, x + 0.0, y + 0.0);
+ c->moveto(x + 0.0, y + 0.0);
+ c->lineto(x + w, y + 0.0);
+ c->lineto(x + w, y + h);
+ c->lineto(x + 0.0, y + h);
+ c->lineto(x + 0.0, y + 0.0);
}
- sp_curve_closepath_current(c);
+ c->closepath_current();
sp_shape_set_curve_insync(SP_SHAPE(rect), c, TRUE);
- sp_curve_unref(c);
+ c->unref();
}
/* fixme: Think (Lauris) */
SP_ITEM(rect)->transform);
}
+/**
+ * Sets the snappoint p to the unrounded corners of the rectangle
+ */
+static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p)
+{
+ /* This method overrides sp_shape_snappoints, which is the default for any shape. The default method
+ returns all eight points along the path of a rounded rectangle, but not the real corners. Snapping
+ the startpoint and endpoint of each rounded corner is not very usefull and really confusing. Instead
+ we could snap either the real corners, or not snap at all. Bulia Byak opted to snap the real corners,
+ but it should be noted that this might be confusing in some cases with relatively large radii. With
+ small radii though the user will easily understand which point is snapping. */
+
+ g_assert(item != NULL);
+ g_assert(SP_IS_RECT(item));
+
+ SPRect *rect = SP_RECT(item);
+
+ NR::Matrix const i2d (from_2geom(sp_item_i2d_affine (item)));
+
+ *p = NR::Point(rect->x.computed, rect->y.computed) * i2d;
+ *p = NR::Point(rect->x.computed, rect->y.computed + rect->height.computed) * i2d;
+ *p = NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d;
+ *p = NR::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
+}
+
+void
+sp_rect_convert_to_guides(SPItem *item) {
+ SPRect *rect = SP_RECT(item);
+
+ if (prefs_get_int_attribute("tools.shapes.rect", "convertguides", 1) == 0) {
+ sp_item_convert_to_guides(SP_ITEM(rect));
+ return;
+ }
+
+ SPDocument *doc = SP_OBJECT_DOCUMENT(rect);
+ std::list<std::pair<Geom::Point, Geom::Point> > pts;
+
+ NR::Matrix const i2d (from_2geom(sp_item_i2d_affine(SP_ITEM(rect))));
+
+ NR::Point A1(NR::Point(rect->x.computed, rect->y.computed) * i2d);
+ NR::Point A2(NR::Point(rect->x.computed, rect->y.computed + rect->height.computed) * i2d);
+ NR::Point A3(NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d);
+ NR::Point A4(NR::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d);
+
+ pts.push_back(std::make_pair(A1.to_2geom(), A2.to_2geom()));
+ pts.push_back(std::make_pair(A2.to_2geom(), A3.to_2geom()));
+ pts.push_back(std::make_pair(A3.to_2geom(), A4.to_2geom()));
+ pts.push_back(std::make_pair(A4.to_2geom(), A1.to_2geom()));
+
+ sp_guide_pt_pairs_to_guides(doc, pts);
+}
+
/*
Local Variables:
mode:c++