diff options
Diffstat (limited to 'src/sp-use.cpp')
| -rw-r--r-- | src/sp-use.cpp | 424 |
1 files changed, 186 insertions, 238 deletions
diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 5ec1f2523..44935e61d 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -25,7 +25,7 @@ #include "display/drawing-group.h" #include "attributes.h" #include "document.h" -#include "sp-object-repr.h" +#include "sp-factory.h" #include "sp-flowregion.h" #include "uri.h" #include "print.h" @@ -38,213 +38,153 @@ #include "sp-use-reference.h" /* fixme: */ - -static void sp_use_finalize(GObject *obj); - -static void sp_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_use_release(SPObject *object); -static void sp_use_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_use_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static void sp_use_update(SPObject *object, SPCtx *ctx, guint flags); -static void sp_use_modified(SPObject *object, guint flags); - -static Geom::OptRect sp_use_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type); -static void sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); -static void sp_use_print(SPItem *item, SPPrintContext *ctx); -static gchar *sp_use_description(SPItem *item); -static Inkscape::DrawingItem *sp_use_show(SPItem *item, Inkscape::Drawing &drawing, unsigned key, unsigned flags); -static void sp_use_hide(SPItem *item, unsigned key); - static void sp_use_href_changed(SPObject *old_ref, SPObject *ref, SPUse *use); - static void sp_use_delete_self(SPObject *deleted, SPUse *self); -//void m_print(gchar *say, Geom::Affine m) -//{ g_print("%s %g %g %g %g %g %g\n", say, m[0], m[1], m[2], m[3], m[4], m[5]); } +#include "sp-factory.h" -G_DEFINE_TYPE(SPUse, sp_use, SP_TYPE_ITEM); +namespace { + SPObject* createUse() { + return new SPUse(); + } -static void -sp_use_class_init(SPUseClass *classname) -{ - GObjectClass *gobject_class = (GObjectClass *) classname; - SPObjectClass *sp_object_class = (SPObjectClass *) classname; - SPItemClass *item_class = (SPItemClass *) classname; - - gobject_class->finalize = sp_use_finalize; - - sp_object_class->build = sp_use_build; - sp_object_class->release = sp_use_release; - sp_object_class->set = sp_use_set; - sp_object_class->write = sp_use_write; - sp_object_class->update = sp_use_update; - sp_object_class->modified = sp_use_modified; - - item_class->bbox = sp_use_bbox; - item_class->description = sp_use_description; - item_class->print = sp_use_print; - item_class->show = sp_use_show; - item_class->hide = sp_use_hide; - item_class->snappoints = sp_use_snappoints; + bool useRegistered = SPFactory::instance().registerObject("svg:use", createUse); } -static void -sp_use_init(SPUse *use) -{ - use->x.unset(); - use->y.unset(); - use->width.unset(SVGLength::PERCENT, 1.0, 1.0); - use->height.unset(SVGLength::PERCENT, 1.0, 1.0); - use->href = NULL; +SPUse::SPUse() : SPItem() { + this->child = NULL; - new (&use->_delete_connection) sigc::connection(); - new (&use->_changed_connection) sigc::connection(); + this->x.unset(); + this->y.unset(); + this->width.unset(SVGLength::PERCENT, 1.0, 1.0); + this->height.unset(SVGLength::PERCENT, 1.0, 1.0); + this->href = NULL; - new (&use->_transformed_connection) sigc::connection(); + //new (&this->_delete_connection) sigc::connection(); + //new (&this->_changed_connection) sigc::connection(); - use->ref = new SPUseReference(use); + //new (&this->_transformed_connection) sigc::connection(); - use->_changed_connection = use->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_use_href_changed), use)); -} + this->ref = new SPUseReference(this); -static void -sp_use_finalize(GObject *obj) -{ - SPUse *use = reinterpret_cast<SPUse *>(obj); + this->_changed_connection = this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_use_href_changed), this)); +} - if (use->child) { - use->detach(use->child); - use->child = NULL; +SPUse::~SPUse() { + if (this->child) { + this->detach(this->child); + this->child = NULL; } - use->ref->detach(); - delete use->ref; - use->ref = 0; + this->ref->detach(); + delete this->ref; + this->ref = 0; - use->_delete_connection.~connection(); - use->_changed_connection.~connection(); + //this->_delete_connection.~connection(); + //this->_changed_connection.~connection(); - use->_transformed_connection.~connection(); + //this->_transformed_connection.~connection(); } -static void -sp_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) sp_use_parent_class)->build) { - (* ((SPObjectClass *) sp_use_parent_class)->build)(object, document, repr); - } +void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { + SPItem::build(document, repr); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "xlink:href" ); + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "width" ); + this->readAttr( "height" ); + this->readAttr( "xlink:href" ); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, // which will call sp_use_href_changed, and that will take care of the child } -static void -sp_use_release(SPObject *object) -{ - SPUse *use = SP_USE(object); - - if (use->child) { - object->detach(use->child); - use->child = NULL; +void SPUse::release() { + if (this->child) { + this->detach(this->child); + this->child = NULL; } - use->_delete_connection.disconnect(); - use->_changed_connection.disconnect(); - use->_transformed_connection.disconnect(); + this->_delete_connection.disconnect(); + this->_changed_connection.disconnect(); + this->_transformed_connection.disconnect(); - g_free(use->href); - use->href = NULL; + g_free(this->href); + this->href = NULL; - use->ref->detach(); + this->ref->detach(); - if (((SPObjectClass *) sp_use_parent_class)->release) { - ((SPObjectClass *) sp_use_parent_class)->release(object); - } + SPItem::release(); } -static void -sp_use_set(SPObject *object, unsigned key, gchar const *value) -{ - SPUse *use = SP_USE(object); - +void SPUse::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_X: - use->x.readOrUnset(value); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->x.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_Y: - use->y.readOrUnset(value); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->y.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_WIDTH: - use->width.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->width.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HEIGHT: - use->height.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->height.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_XLINK_HREF: { - if ( value && use->href && ( strcmp(value, use->href) == 0 ) ) { + if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* No change, do nothing. */ } else { - g_free(use->href); - use->href = NULL; + g_free(this->href); + this->href = NULL; + if (value) { // First, set the href field, because sp_use_href_changed will need it. - use->href = g_strdup(value); + this->href = g_strdup(value); // Now do the attaching, which emits the changed signal. try { - use->ref->attach(Inkscape::URI(value)); + this->ref->attach(Inkscape::URI(value)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); - use->ref->detach(); + this->ref->detach(); } } else { - use->ref->detach(); + this->ref->detach(); } } break; } default: - if (((SPObjectClass *) sp_use_parent_class)->set) { - ((SPObjectClass *) sp_use_parent_class)->set(object, key, value); - } + SPItem::set(key, value); break; } } -static Inkscape::XML::Node * -sp_use_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPUse *use = SP_USE(object); - +Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:use"); } - if (((SPObjectClass *) (sp_use_parent_class))->write) { - ((SPObjectClass *) (sp_use_parent_class))->write(object, xml_doc, repr, flags); - } - - sp_repr_set_svg_double(repr, "x", use->x.computed); - sp_repr_set_svg_double(repr, "y", use->y.computed); + SPItem::write(xml_doc, repr, flags); - repr->setAttribute("width", sp_svg_length_write_with_units(use->width).c_str()); - repr->setAttribute("height", sp_svg_length_write_with_units(use->height).c_str()); + sp_repr_set_svg_double(repr, "x", this->x.computed); + sp_repr_set_svg_double(repr, "y", this->y.computed); + repr->setAttribute("width", sp_svg_length_write_with_units(this->width).c_str()); + repr->setAttribute("height", sp_svg_length_write_with_units(this->height).c_str()); - if (use->ref->getURI()) { - gchar *uri_string = use->ref->getURI()->toString(); + if (this->ref->getURI()) { + gchar *uri_string = this->ref->getURI()->toString(); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); } @@ -252,35 +192,33 @@ sp_use_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML:: return repr; } -static Geom::OptRect sp_use_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type) -{ - SPUse const *use = SP_USE(item); +Geom::OptRect SPUse::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) { Geom::OptRect bbox; - if (use->child && SP_IS_ITEM(use->child)) { - SPItem *child = SP_ITEM(use->child); + if (this->child && SP_IS_ITEM(this->child)) { + SPItem *child = SP_ITEM(this->child); Geom::Affine const ct( child->transform - * Geom::Translate(use->x.computed, - use->y.computed) + * Geom::Translate(this->x.computed, + this->y.computed) * transform ); - bbox = child->bounds(type, ct); + + bbox = child->bounds(bboxtype, ct); } + return bbox; } -static void sp_use_print(SPItem *item, SPPrintContext *ctx) -{ +void SPUse::print(SPPrintContext* ctx) { bool translated = false; - SPUse *use = SP_USE(item); - if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed)); + if ((this->x._set && this->x.computed != 0) || (this->y._set && this->y.computed != 0)) { + Geom::Affine tp(Geom::Translate(this->x.computed, this->y.computed)); sp_print_bind(ctx, tp, 1.0); translated = true; } - if (use->child && SP_IS_ITEM(use->child)) { - SP_ITEM(use->child)->invoke_print(ctx); + if (this->child && SP_IS_ITEM(this->child)) { + SP_ITEM(this->child)->invoke_print(ctx); } if (translated) { @@ -288,19 +226,16 @@ static void sp_use_print(SPItem *item, SPPrintContext *ctx) } } -static gchar *sp_use_description(SPItem *item) -{ - SPUse *use = SP_USE(item); - - if (use->child) { - - if( SP_IS_SYMBOL( use->child ) ) { - char *symbol_desc = SP_ITEM(use->child)->title(); +gchar* SPUse::description() { + if (this->child) { + if( SP_IS_SYMBOL( this->child ) ) { + char *symbol_desc = SP_ITEM(this->child)->title(); return g_strdup_printf(_("<b>'%s' Symbol</b>"), symbol_desc ); g_free(symbol_desc); } static unsigned recursion_depth = 0; + if (recursion_depth >= 4) { /* TRANSLATORS: Used for statusbar description for long <use> chains: * "Clone of: Clone of: ... in Layer 1". */ @@ -308,54 +243,47 @@ static gchar *sp_use_description(SPItem *item) /* We could do better, e.g. chasing the href chain until we reach something other than * a <use>, and giving its description. */ } + ++recursion_depth; - char *child_desc = SP_ITEM(use->child)->description(); + char *child_desc = SP_ITEM(this->child)->getDetailedDescription(); --recursion_depth; char *ret = g_strdup_printf(_("<b>Clone</b> of: %s"), child_desc); g_free(child_desc); + return ret; } else { return g_strdup(_("<b>Orphaned clone</b>")); } } -static Inkscape::DrawingItem * -sp_use_show(SPItem *item, Inkscape::Drawing &drawing, unsigned key, unsigned flags) -{ - SPUse *use = SP_USE(item); - +Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); - ai->setStyle(item->style); + ai->setStyle(this->style); - if (use->child) { - Inkscape::DrawingItem *ac = SP_ITEM(use->child)->invoke_show(drawing, key, flags); + if (this->child) { + Inkscape::DrawingItem *ac = SP_ITEM(this->child)->invoke_show(drawing, key, flags); if (ac) { ai->prependChild(ac); } - Geom::Translate t(use->x.computed, - use->y.computed); + + Geom::Translate t(this->x.computed, this->y.computed); ai->setChildTransform(t); } return ai; } -static void -sp_use_hide(SPItem *item, unsigned key) -{ - SPUse *use = SP_USE(item); - - if (use->child) { - SP_ITEM(use->child)->invoke_hide(key); +void SPUse::hide(unsigned int key) { + if (this->child) { + SP_ITEM(this->child)->invoke_hide(key); } - if (((SPItemClass *) sp_use_parent_class)->hide) { - ((SPItemClass *) sp_use_parent_class)->hide(item, key); - } +// SPItem::onHide(key); } + /** * Returns the ultimate original of a SPUse (i.e. the first object in the chain of its originals * which is not an SPUse). If no original is found, NULL is returned (it is the responsibility @@ -505,10 +433,28 @@ sp_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPUse *use) SPItem *refobj = use->ref->getObject(); if (refobj) { Inkscape::XML::Node *childrepr = refobj->getRepr(); - GType type = sp_repr_type_lookup(childrepr); - g_return_if_fail(type > G_TYPE_NONE); - if (g_type_is_a(type, SP_TYPE_ITEM)) { - use->child = (SPObject*) g_object_new(type, 0); + +// GType type = sp_repr_type_lookup(childrepr); +// g_return_if_fail(type > G_TYPE_NONE); +// if (g_type_is_a(type, SP_TYPE_ITEM)) { +// use->child = (SPObject*) g_object_new(type, 0); +// use->attach(use->child, use->lastChild()); +// sp_object_unref(use->child, use); +// (use->child)->invoke_build(use->document, childrepr, TRUE); +// +// for (SPItemView *v = item->display; v != NULL; v = v->next) { +// Inkscape::DrawingItem *ai; +// ai = SP_ITEM(use->child)->invoke_show(v->arenaitem->drawing(), v->key, v->flags); +// if (ai) { +// v->arenaitem->prependChild(ai); +// } +// } +// } + + SPObject* obj = SPFactory::instance().createObject(NodeTraits::get_type_string(*childrepr)); + if (SP_IS_ITEM(obj)) { + use->child = obj; + use->attach(use->child, use->lastChild()); sp_object_unref(use->child, use); (use->child)->invoke_build(use->document, childrepr, TRUE); @@ -520,8 +466,10 @@ sp_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPUse *use) v->arenaitem->prependChild(ai); } } - + } else { + delete obj; } + use->_delete_connection = refobj->connectDelete(sigc::bind(sigc::ptr_fun(&sp_use_delete_self), use)); use->_transformed_connection = SP_ITEM(refobj)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_use_move_compensate), use)); } @@ -548,93 +496,95 @@ sp_use_delete_self(SPObject */*deleted*/, SPUse *self) } } -static void -sp_use_update(SPObject *object, SPCtx *ctx, unsigned flags) -{ - SPItem *item = SP_ITEM(object); - SPUse *use = SP_USE(object); +void SPUse::update(SPCtx *ctx, unsigned flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; - if (((SPObjectClass *) (sp_use_parent_class))->update) - ((SPObjectClass *) (sp_use_parent_class))->update(object, ctx, flags); + SPItem::update(ctx, flags); if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { + for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(object->style); + g->setStyle(this->style); } } /* Set up child viewport */ - if (use->x.unit == SVGLength::PERCENT) { - use->x.computed = use->x.value * ictx->viewport.width(); + if (this->x.unit == SVGLength::PERCENT) { + this->x.computed = this->x.value * ictx->viewport.width(); } - if (use->y.unit == SVGLength::PERCENT) { - use->y.computed = use->y.value * ictx->viewport.height(); + + if (this->y.unit == SVGLength::PERCENT) { + this->y.computed = this->y.value * ictx->viewport.height(); } - if (use->width.unit == SVGLength::PERCENT) { - use->width.computed = use->width.value * ictx->viewport.width(); + + if (this->width.unit == SVGLength::PERCENT) { + this->width.computed = this->width.value * ictx->viewport.width(); } - if (use->height.unit == SVGLength::PERCENT) { - use->height.computed = use->height.value * ictx->viewport.height(); + + if (this->height.unit == SVGLength::PERCENT) { + this->height.computed = this->height.value * ictx->viewport.height(); } - cctx.viewport = Geom::Rect::from_xywh(0, 0, use->width.computed, use->height.computed); + + cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); flags&=~SP_OBJECT_USER_MODIFIED_FLAG_B; - if (use->child) { - g_object_ref(G_OBJECT(use->child)); - if (flags || (use->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM(use->child)) { - SPItem const &chi = *SP_ITEM(use->child); + if (this->child) { + sp_object_ref(this->child); + + if (flags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM(this->child)) { + SPItem const &chi = *SP_ITEM(this->child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - use->child->updateDisplay((SPCtx *)&cctx, flags); + this->child->updateDisplay((SPCtx *)&cctx, flags); } else { - use->child->updateDisplay(ctx, flags); + this->child->updateDisplay(ctx, flags); } } - g_object_unref(G_OBJECT(use->child)); + + sp_object_unref(this->child); } /* As last step set additional transform of arena group */ - for (SPItemView *v = item->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - Geom::Affine t(Geom::Translate(use->x.computed, use->y.computed)); + Geom::Affine t(Geom::Translate(this->x.computed, this->y.computed)); g->setChildTransform(t); } } -static void -sp_use_modified(SPObject *object, guint flags) -{ - SPUse *use_obj = SP_USE(object); - +void SPUse::modified(unsigned int flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { + for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(object->style); + g->setStyle(this->style); } } - SPObject *child = use_obj->child; + SPObject *child = this->child; + if (child) { - g_object_ref(G_OBJECT(child)); + sp_object_ref(child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->emitModified(flags); } - g_object_unref(G_OBJECT(child)); + + sp_object_unref(child); } } @@ -655,6 +605,7 @@ SPItem *sp_use_unlink(SPUse *use) // Track the ultimate source of a chain of uses. SPItem *orig = sp_use_root(use); + if (!orig) { return NULL; } @@ -663,8 +614,10 @@ SPItem *sp_use_unlink(SPUse *use) Geom::Affine t = sp_use_get_root_transform(use); Inkscape::XML::Node *copy = NULL; + if (SP_IS_SYMBOL(orig)) { // make a group, copy children copy = xml_doc->createElement("svg:g"); + for (Inkscape::XML::Node *child = orig->getRepr()->firstChild() ; child != NULL; child = child->next()) { Inkscape::XML::Node *newchild = child->duplicate(xml_doc); copy->appendChild(newchild); @@ -717,36 +670,31 @@ SPItem *sp_use_unlink(SPUse *use) // Advertise ourselves as not moving. item->doWriteTransform(item->getRepr(), t, &nomove); } + return item; } SPItem *sp_use_get_original(SPUse *use) { SPItem *ref = NULL; - if (use){ + + if (use) { if (use->ref){ ref = use->ref->getObject(); } } + return ref; } -static void -sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) -{ - g_assert (item != NULL); - g_assert (SP_IS_ITEM(item)); - g_assert (SP_IS_USE(item)); +void SPUse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { + SPItem *root = sp_use_root(this); - SPUse *use = SP_USE(item); - SPItem *root = sp_use_root(use); - if (!root) + if (!root) { return; - - SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(root); - if (item_class.snappoints) { - item_class.snappoints(root, p, snapprefs); } + + root->snappoints(p, snapprefs); } |
