X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fsp-rect.cpp;h=7d3cd1c0c5639f53de382da822380d3293b2e03b;hb=2aa7286c975e2f20280576be54adfa67d861cd7f;hp=6823f21229dca2aa254e9c291881538aeabe6593;hpb=f1244c7e85def8dc339fc92a29c0bd26ffc247d7;p=inkscape.git diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index 6823f2122..7d3cd1c0c 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -28,6 +28,8 @@ #include "sp-rect.h" #include #include "xml/repr.h" +#include "sp-guide.h" +#include "prefs-utils.h" #define noRECT_VERBOSE @@ -37,12 +39,14 @@ static void sp_rect_init(SPRect *rect); 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; @@ -85,12 +89,14 @@ sp_rect_class_init(SPRectClass *klass) 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); */ @@ -115,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 @@ -206,12 +197,11 @@ sp_rect_update(SPObject *object, SPCtx *ctx, guint flags) } 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) { - Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object)); repr = xml_doc->createElement("svg:rect"); } @@ -223,7 +213,7 @@ sp_rect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) 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; } @@ -243,9 +233,12 @@ sp_rect_set_shape(SPShape *shape) { 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; @@ -274,26 +267,26 @@ sp_rect_set_shape(SPShape *shape) * 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) */ @@ -551,6 +544,58 @@ sp_rect_get_visible_height(SPRect *rect) 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 > 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++