diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-04-05 13:37:33 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-04-05 13:37:33 +0000 |
| commit | cfe48de7f071e2e07a1f2f2ace3456f7b410e93b (patch) | |
| tree | 281d760873c84db3a67518ab19e61bb213f1eab7 /src/sp-shape.cpp | |
| parent | Combined some classes. (diff) | |
| download | inkscape-cfe48de7f071e2e07a1f2f2ace3456f7b410e93b.tar.gz inkscape-cfe48de7f071e2e07a1f2f2ace3456f7b410e93b.zip | |
Merged Shape and subclasses. Cleaned up a bit.
(bzr r11608.1.76)
Diffstat (limited to 'src/sp-shape.cpp')
| -rw-r--r-- | src/sp-shape.cpp | 366 |
1 files changed, 193 insertions, 173 deletions
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index fc80defb3..64e905328 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -53,35 +53,22 @@ #define noSHAPE_VERBOSE -static void sp_shape_finalize (GObject *object); static void sp_shape_update_marker_view (SPShape *shape, Inkscape::DrawingItem *ai); - -CShape::CShape(SPShape* shape) : CLPEItem(shape) { - this->spshape = shape; -} - -CShape::~CShape() { -} - -SPShape::SPShape() : SPLPEItem() { - SPShape* shape = this; - - shape->cshape = new CShape(shape); - shape->typeHierarchy.insert(typeid(SPShape)); - - delete shape->clpeitem; - shape->clpeitem = shape->cshape; - shape->citem = shape->cshape; - shape->cobject = shape->cshape; +SPShape::SPShape() : SPLPEItem(), CLPEItem(this) { + delete this->clpeitem; + this->clpeitem = this; + this->citem = this; + this->cobject = this; for ( int i = 0 ; i < SP_MARKER_LOC_QTY ; i++ ) { - new (&shape->_release_connect[i]) sigc::connection(); - new (&shape->_modified_connect[i]) sigc::connection(); - shape->_marker[i] = NULL; + new (&this->_release_connect[i]) sigc::connection(); + new (&this->_modified_connect[i]) sigc::connection(); + this->_marker[i] = NULL; } - shape->_curve = NULL; - shape->_curve_before_lpe = NULL; + + this->_curve = NULL; + this->_curve_before_lpe = NULL; } SPShape::~SPShape() { @@ -91,13 +78,11 @@ SPShape::~SPShape() { } } -void CShape::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPShape* object = this->spshape; - +void SPShape::build(SPDocument *document, Inkscape::XML::Node *repr) { CLPEItem::build(document, repr); for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (object, i, object->style->marker[i].value); + sp_shape_set_marker (this, i, this->style->marker[i].value); } } @@ -112,50 +97,45 @@ void CShape::build(SPDocument *document, Inkscape::XML::Node *repr) { * * \see SPObject::release() */ -void CShape::release() { - SPItem *item; - SPShape *shape; +void SPShape::release() { SPItemView *v; int i; - SPShape* object = this->spshape; - - item = (SPItem *) object; - shape = (SPShape *) object; for (i = 0; i < SP_MARKER_LOC_QTY; i++) { - if (shape->_marker[i]) { - for (v = item->display; v != NULL; v = v->next) { - sp_marker_hide ((SPMarker *) shape->_marker[i], v->arenaitem->key() + i); + if (this->_marker[i]) { + + for (v = this->display; v != NULL; v = v->next) { + sp_marker_hide ((SPMarker *) this->_marker[i], v->arenaitem->key() + i); } - shape->_release_connect[i].disconnect(); - shape->_modified_connect[i].disconnect(); - shape->_marker[i] = sp_object_hunref (shape->_marker[i], object); + + this->_release_connect[i].disconnect(); + this->_modified_connect[i].disconnect(); + this->_marker[i] = sp_object_hunref (this->_marker[i], this); } } - if (shape->_curve) { - shape->_curve = shape->_curve->unref(); + + if (this->_curve) { + this->_curve = this->_curve->unref(); } - if (shape->_curve_before_lpe) { - shape->_curve_before_lpe = shape->_curve_before_lpe->unref(); + + if (this->_curve_before_lpe) { + this->_curve_before_lpe = this->_curve_before_lpe->unref(); } CLPEItem::release(); } -void CShape::set(unsigned int key, const gchar* value) { +void SPShape::set(unsigned int key, const gchar* value) { CLPEItem::set(key, value); } -Inkscape::XML::Node* CShape::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +Inkscape::XML::Node* SPShape::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { CLPEItem::write(xml_doc, repr, flags); return repr; } -void CShape::update(SPCtx* ctx, guint flags) { - SPShape* shape = this->spshape; - SPShape* object = shape; - +void SPShape::update(SPCtx* ctx, guint flags) { CLPEItem::update(ctx, flags); /* This stanza checks that an object's marker style agrees with @@ -164,16 +144,18 @@ void CShape::update(SPCtx* ctx, guint flags) { * match the style. */ for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (object, i, object->style->marker[i].value); - } + sp_shape_set_marker (this, i, this->style->marker[i].value); + } if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - SPStyle *style = object->style; + SPStyle *style = this->style; + if (style->stroke_width.unit == SP_CSS_UNIT_PERCENT) { SPItemCtx *ictx = (SPItemCtx *) ctx; double const aw = 1.0 / ictx->i2vp.descrim(); style->stroke_width.computed = style->stroke_width.value * aw; - for (SPItemView *v = ((SPItem *) (shape))->display; v != NULL; v = v->next) { + + for (SPItemView *v = ((SPItem *) (this))->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); sh->setStyle(style); } @@ -183,32 +165,34 @@ void CShape::update(SPCtx* ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { /* This is suboptimal, because changing parent style schedules recalculation */ /* But on the other hand - how can we know that parent does not tie style and transform */ - for (SPItemView *v = shape->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); + if (flags & SP_OBJECT_MODIFIED_FLAG) { - sh->setPath(shape->_curve); + sh->setPath(this->_curve); } } } - if (shape->hasMarkers ()) { + if (this->hasMarkers ()) { /* Dimension marker views */ - for (SPItemView *v = shape->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { if (!v->arenaitem->key()) { v->arenaitem->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); } + for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - if (shape->_marker[i]) { - sp_marker_show_dimension ((SPMarker *) shape->_marker[i], + if (this->_marker[i]) { + sp_marker_show_dimension ((SPMarker *) this->_marker[i], v->arenaitem->key() + i, - shape->numberOfMarkers (i)); + this->numberOfMarkers (i)); } } } /* Update marker views */ - for (SPItemView *v = shape->display; v != NULL; v = v->next) { - sp_shape_update_marker_view (shape, v->arenaitem); + for (SPItemView *v = this->display; v != NULL; v = v->next) { + sp_shape_update_marker_view (this, v->arenaitem); } } } @@ -407,54 +391,61 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) } } -void CShape::modified(unsigned int flags) { - SPShape* shape = this->spshape; - +void SPShape::modified(unsigned int flags) { CLPEItem::modified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = shape->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); - sh->setStyle(shape->style); + sh->setStyle(this->style); } } } -Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) { - SPShape const* shape = this->spshape; - SPShape const* item = shape; +Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) { Geom::OptRect bbox; - if (!shape->_curve) return bbox; - bbox = bounds_exact_transformed(shape->_curve->get_pathvector(), transform); - if (!bbox) return bbox; + if (!this->_curve) { + return bbox; + } + + bbox = bounds_exact_transformed(this->_curve->get_pathvector(), transform); + + if (!bbox) { + return bbox; + } if (bboxtype == SPItem::VISUAL_BBOX) { // convert the stroke to a path and calculate that path's geometric bbox - SPStyle* style = item->style; + SPStyle* style = this->style; + if (!style->stroke.isNone()) { - Geom::PathVector *pathv = item_outline(item, true); // calculate bbox_only + Geom::PathVector *pathv = item_outline(this, true); // calculate bbox_only + if (pathv) { bbox |= bounds_exact_transformed(*pathv, transform); delete pathv; } } + // Union with bboxes of the markers, if any - if ( shape->hasMarkers() && !shape->_curve->get_pathvector().empty() ) { + if ( this->hasMarkers() && !this->_curve->get_pathvector().empty() ) { /** \todo make code prettier! */ - Geom::PathVector const & pathv = shape->_curve->get_pathvector(); + Geom::PathVector const & pathv = this->_curve->get_pathvector(); // START marker for (unsigned i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START - if ( shape->_marker[i] ) { - SPMarker* marker = SP_MARKER (shape->_marker[i]); + if ( this->_marker[i] ) { + SPMarker* marker = SP_MARKER (this->_marker[i]); SPItem* marker_item = sp_item_first_item_child( marker ); if (marker_item) { Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front())); + if (!marker->orient_auto) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; } @@ -467,12 +458,19 @@ Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxt } } } + // MID marker for (unsigned i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID - if ( !shape->_marker[i] ) continue; - SPMarker* marker = SP_MARKER (shape->_marker[i]); + if ( !this->_marker[i] ) { + continue; + } + + SPMarker* marker = SP_MARKER (this->_marker[i]); SPItem* marker_item = sp_item_first_item_child( marker ); - if ( !marker_item ) continue; + + if ( !marker_item ) { + continue; + } for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { // START position @@ -480,38 +478,46 @@ Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxt && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there { Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front())); + if (!marker->orient_auto) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; } + tr = marker_item->transform * marker->c2p * tr * transform; bbox |= marker_item->visualBounds(tr); } + // MID position if ( path_it->size_default() > 1) { Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + while (curve_it2 != path_it->end_default()) { /* Put marker between curve_it1 and curve_it2. * Loop to end_default (so including closing segment), because when a path is closed, * there should be a midpoint marker between last segment and closing straight line segment */ - SPMarker* marker = SP_MARKER (shape->_marker[i]); + SPMarker* marker = SP_MARKER (this->_marker[i]); SPItem* marker_item = sp_item_first_item_child( marker ); if (marker_item) { Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2)); + if (!marker->orient_auto) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; } + tr = marker_item->transform * marker->c2p * tr * transform; bbox |= marker_item->visualBounds(tr); } @@ -520,26 +526,31 @@ Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxt ++curve_it2; } } + // END position if ( path_it != (pathv.end()-1) && !path_it->empty()) { Geom::Curve const &lastcurve = path_it->back_default(); Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); + if (!marker->orient_auto) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; } + tr = marker_item->transform * marker->c2p * tr * transform; bbox |= marker_item->visualBounds(tr); } } } + // END marker for (unsigned i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END - if ( shape->_marker[i] ) { - SPMarker* marker = SP_MARKER (shape->_marker[i]); + if ( this->_marker[i] ) { + SPMarker* marker = SP_MARKER (this->_marker[i]); SPItem* marker_item = sp_item_first_item_child( marker ); if (marker_item) { @@ -547,16 +558,20 @@ Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxt * For moveto-only path, this returns the "closing line segment". */ Geom::Path const &path_last = pathv.back(); unsigned int index = path_last.size_default(); + if (index > 0) { index--; } + Geom::Curve const &lastcurve = path_last[index]; Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); + if (!marker->orient_auto) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; } @@ -571,6 +586,7 @@ Geom::OptRect CShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxt } } } + return bbox; } @@ -593,32 +609,35 @@ sp_shape_print_invoke_marker_printing(SPObject *obj, Geom::Affine tr, SPStyle co } } -void CShape::print(SPPrintContext* ctx) { - SPShape *shape = this->spshape; - SPShape* item = shape; - - Geom::OptRect pbox, dbox, bbox; - if (!shape->_curve) return; +void SPShape::print(SPPrintContext* ctx) { + if (!this->_curve) { + return; + } - Geom::PathVector const & pathv = shape->_curve->get_pathvector(); - if (pathv.empty()) return; + Geom::PathVector const & pathv = this->_curve->get_pathvector(); + + if (pathv.empty()) { + return; + } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint add_comments = prefs->getBool("/printing/debug/add-label-comments"); - if (add_comments) { - gchar * comment = g_strdup_printf("begin '%s'", - item->defaultLabel()); - sp_print_comment(ctx, comment); - g_free(comment); - } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint add_comments = prefs->getBool("/printing/debug/add-label-comments"); + + if (add_comments) { + gchar * comment = g_strdup_printf("begin '%s'", this->defaultLabel()); + sp_print_comment(ctx, comment); + g_free(comment); + } /* fixme: Think (Lauris) */ - pbox = item->geometricBounds(); - bbox = item->desktopVisualBounds(); - dbox = Geom::Rect::from_xywh(Geom::Point(0,0), item->document->getDimensions()); - Geom::Affine const i2dt(item->i2dt_affine()); + Geom::OptRect pbox, dbox, bbox; + pbox = this->geometricBounds(); + bbox = this->desktopVisualBounds(); + dbox = Geom::Rect::from_xywh(Geom::Point(0,0), this->document->getDimensions()); + + Geom::Affine const i2dt(this->i2dt_affine()); - SPStyle* style = item->style; + SPStyle* style = this->style; if (!style->fill.isNone()) { sp_print_fill (ctx, pathv, i2dt, style, pbox, dbox, bbox); @@ -631,26 +650,29 @@ void CShape::print(SPPrintContext* ctx) { /** \todo make code prettier */ // START marker for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START - if ( shape->_marker[i] ) { + if ( this->_marker[i] ) { Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front())); - sp_shape_print_invoke_marker_printing(shape->_marker[i], tr, style, ctx); + sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx); } } + // MID marker for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID - if (shape->_marker[i]) { + if (this->_marker[i]) { for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { // START position if ( path_it != pathv.begin() && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there { Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front())); - sp_shape_print_invoke_marker_printing(shape->_marker[i], tr, style, ctx); + sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx); } + // MID position if ( path_it->size_default() > 1) { Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + while (curve_it2 != path_it->end_default()) { /* Put marker between curve_it1 and curve_it2. @@ -658,55 +680,56 @@ void CShape::print(SPPrintContext* ctx) { * there should be a midpoint marker between last segment and closing straight line segment */ Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2)); - sp_shape_print_invoke_marker_printing(shape->_marker[i], tr, style, ctx); + sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx); ++curve_it1; ++curve_it2; } } + if ( path_it != (pathv.end()-1) && !path_it->empty()) { Geom::Curve const &lastcurve = path_it->back_default(); Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); - sp_shape_print_invoke_marker_printing(shape->_marker[i], tr, style, ctx); + sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx); } } } } + // END marker - if ( shape->_marker[SP_MARKER_LOC_END] || shape->_marker[SP_MARKER_LOC]) { + if ( this->_marker[SP_MARKER_LOC_END] || this->_marker[SP_MARKER_LOC]) { /* Get reference to last curve in the path. * For moveto-only path, this returns the "closing line segment". */ Geom::Path const &path_last = pathv.back(); unsigned int index = path_last.size_default(); + if (index > 0) { index--; } + Geom::Curve const &lastcurve = path_last[index]; Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END - if (shape->_marker[i]) { - sp_shape_print_invoke_marker_printing(shape->_marker[i], tr, style, ctx); + if (this->_marker[i]) { + sp_shape_print_invoke_marker_printing(this->_marker[i], tr, style, ctx); } } } - if (add_comments) { - gchar * comment = g_strdup_printf("end '%s'", - item->defaultLabel()); - sp_print_comment(ctx, comment); - g_free(comment); - } + if (add_comments) { + gchar * comment = g_strdup_printf("end '%s'", + this->defaultLabel()); + sp_print_comment(ctx, comment); + g_free(comment); + } } -Inkscape::DrawingItem* CShape::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - SPObject *object = this->spshape; - SPShape *shape = this->spshape; - +Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); - s->setStyle(object->style); - s->setPath(shape->_curve); + s->setStyle(this->style); + s->setPath(this->_curve); /* This stanza checks that an object's marker style agrees with * the marker objects it has allocated. sp_shape_set_marker ensures @@ -714,26 +737,25 @@ Inkscape::DrawingItem* CShape::show(Inkscape::Drawing &drawing, unsigned int key * match the style. */ for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (object, i, object->style->marker[i].value); - } - - if (shape->hasMarkers ()) { + sp_shape_set_marker (this, i, this->style->marker[i].value); + } + if (this->hasMarkers ()) { /* provide key and dimension the marker views */ if (!s->key()) { s->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); } for (int i = 0; i < SP_MARKER_LOC_QTY; i++) { - if (shape->_marker[i]) { - sp_marker_show_dimension ((SPMarker *) shape->_marker[i], + if (this->_marker[i]) { + sp_marker_show_dimension ((SPMarker *) this->_marker[i], s->key() + i, - shape->numberOfMarkers (i)); + this->numberOfMarkers (i)); } } /* Update marker views */ - sp_shape_update_marker_view (shape, s); + sp_shape_update_marker_view (this, s); } return s; @@ -742,25 +764,18 @@ Inkscape::DrawingItem* CShape::show(Inkscape::Drawing &drawing, unsigned int key /** * Sets style, path, and paintbox. Updates marker views, including dimensions. */ -void CShape::hide(unsigned int key) { - SPShape *shape = this->spshape; - SPShape* item = shape; - - SPItemView *v; - int i; - - for (i=0; i<SP_MARKER_LOC_QTY; i++) { - if (shape->_marker[i]) { - for (v = item->display; v != NULL; v = v->next) { - if (key == v->key) { - sp_marker_hide ((SPMarker *) shape->_marker[i], - v->arenaitem->key() + i); - } - } - } - } - -// CLPEItem::onHide(key); +void SPShape::hide(unsigned int key) { + for (int i=0; i<SP_MARKER_LOC_QTY; i++) { + if (this->_marker[i]) { + for (SPItemView* v = this->display; v != NULL; v = v->next) { + if (key == v->key) { + sp_marker_hide ((SPMarker *) this->_marker[i], v->arenaitem->key() + i); + } + } + } + } + + //CLPEItem::onHide(key); } /** @@ -791,6 +806,7 @@ int SPShape::hasMarkers() const int SPShape::numberOfMarkers(int type) { Geom::PathVector const & pathv = this->_curve->get_pathvector(); + if (pathv.size() == 0) { return 0; } @@ -918,7 +934,7 @@ sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value) } // CPPIFY: make pure virtual -void CShape::set_shape() { +void SPShape::set_shape() { //throw; } @@ -927,10 +943,6 @@ void CShape::set_shape() { /** * Calls any registered handlers for the set_shape action */ -void SPShape::setShape() -{ - this->cshape->set_shape(); -} /** * Adds a curve to the shape. If owner is specified, a reference @@ -943,6 +955,7 @@ void SPShape::setCurve(SPCurve *new_curve, unsigned int owner) if (_curve) { _curve = _curve->unref(); } + if (new_curve) { if (owner) { _curve = new_curve->ref(); @@ -950,6 +963,7 @@ void SPShape::setCurve(SPCurve *new_curve, unsigned int owner) _curve = new_curve->copy(); } } + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -962,6 +976,7 @@ SPShape::setCurveBeforeLPE (SPCurve *new_curve) if (_curve_before_lpe) { _curve_before_lpe = _curve_before_lpe->unref(); } + if (new_curve) { _curve_before_lpe = new_curve->ref(); } @@ -975,6 +990,7 @@ SPCurve * SPShape::getCurve() const if (_curve) { return _curve->copy(); } + return NULL; } @@ -992,6 +1008,7 @@ SPCurve * SPShape::getCurveBeforeLPE() const return _curve->copy(); } } + return NULL; } @@ -1003,6 +1020,7 @@ void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) if (_curve) { _curve = _curve->unref(); } + if (new_curve) { if (owner) { _curve = new_curve->ref(); @@ -1012,25 +1030,22 @@ void SPShape::setCurveInsync(SPCurve *new_curve, unsigned int owner) } } -void CShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { - SPShape const *shape = this->spshape; - SPShape const *item = shape; - - g_assert(item != NULL); - g_assert(SP_IS_SHAPE(item)); - - if (shape->_curve == NULL) { +void SPShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { + if (this->_curve == NULL) { return; } - Geom::PathVector const &pathv = shape->_curve->get_pathvector(); - if (pathv.empty()) + Geom::PathVector const &pathv = this->_curve->get_pathvector(); + + if (pathv.empty()) { return; + } - Geom::Affine const i2dt (item->i2dt_affine ()); + Geom::Affine const i2dt (this->i2dt_affine ()); if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) { - Geom::OptRect bbox = item->desktopVisualBounds(); + Geom::OptRect bbox = this->desktopVisualBounds(); + if (bbox) { p.push_back(Inkscape::SnapCandidatePoint(bbox->midpoint(), Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT)); } @@ -1044,6 +1059,7 @@ void CShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape:: Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + while (curve_it1 != path_it->end_default()) { // For each path: consider midpoints of line segments for snapping @@ -1071,6 +1087,7 @@ void CShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape:: if (c1 || c2) { Inkscape::SnapSourceType sst; Inkscape::SnapTargetType stt; + switch (nodetype) { case Geom::NODE_CUSP: sst = Inkscape::SNAPSOURCE_NODE_CUSP; @@ -1086,6 +1103,7 @@ void CShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape:: stt = Inkscape::SNAPTARGET_UNDEFINED; break; } + p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2dt, sst, stt)); } } @@ -1098,8 +1116,10 @@ void CShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape:: // (using "Method 1" as described in Inkscape::ObjectSnapper::_collectNodes()) if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_PATH_INTERSECTION) || snapprefs->isSourceSnappable(Inkscape::SNAPSOURCE_PATH_INTERSECTION)) { Geom::Crossings cs; + try { cs = self_crossings(*path_it); // This can be slow! + if (!cs.empty()) { // There might be multiple intersections... for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); ++i) { Geom::Point p_ix = (*path_it).pointAt((*i).ta); |
