static Inkscape::XML::Node * sp_textpath_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPTextPath *textpath = SP_TEXTPATH(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:textPath"); } textpath->attributes.writeTo(repr); if (textpath->startOffset._set) { if (textpath->startOffset.unit == SVGLength::PERCENT) { Inkscape::SVGOStringStream os; os << (textpath->startOffset.computed * 100.0) << "%"; SP_OBJECT_REPR(textpath)->setAttribute("startOffset", os.str().c_str()); } else { /* FIXME: This logic looks rather undesirable if e.g. startOffset is to be in ems. */ sp_repr_set_svg_double(repr, "startOffset", textpath->startOffset.computed); } } if ( textpath->sourcePath->sourceHref ) repr->setAttribute("xlink:href", textpath->sourcePath->sourceHref); if ( flags&SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { Inkscape::XML::Node* c_repr=NULL; if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } if ( c_repr ) l = g_slist_prepend(l, c_repr); } while ( l ) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove(l, l->data); } } else { for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { child->updateRepr(flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { SP_OBJECT_REPR(child)->setContent(SP_STRING(child)->string.c_str()); } } } if (((SPObjectClass *) textpath_parent_class)->write) ((SPObjectClass *) textpath_parent_class)->write(object, xml_doc, repr, flags); return repr; }
Inkscape::XML::Node* SPTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:tspan"); } this->attributes.writeTo(repr); if ( flags&SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { Inkscape::XML::Node* c_repr=NULL; if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } if ( c_repr ) { l = g_slist_prepend(l, c_repr); } } while ( l ) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove(l, l->data); } } else { for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { child->updateRepr(flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { child->getRepr()->setContent(SP_STRING(child)->string.c_str()); } } } SPItem::write(xml_doc, repr, flags); return repr; }
static Inkscape::XML::Node * sp_tspan_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPTSpan *tspan = SP_TSPAN(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:tspan"); } tspan->attributes.writeTo(repr); if ( flags&SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { Inkscape::XML::Node* c_repr=NULL; if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } if ( c_repr ) l = g_slist_prepend(l, c_repr); } while ( l ) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove(l, l->data); } } else { for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { child->updateRepr(flags); } else if ( SP_IS_TEXTPATH(child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen } else if ( SP_IS_STRING(child) ) { SP_OBJECT_REPR(child)->setContent(SP_STRING(child)->string.c_str()); } } } if (((SPObjectClass *) tspan_parent_class)->write) ((SPObjectClass *) tspan_parent_class)->write(object, xml_doc, repr, flags); return repr; }
/** * Returns true if a tref is fully contained in the confines of the given * iterators and layout (or if there is no tref). */ bool sp_tref_fully_contained(SPObject *start_item, Glib::ustring::iterator &start, SPObject *end_item, Glib::ustring::iterator &end) { bool fully_contained = false; if (start_item && end_item) { // If neither the beginning or the end is a tref then we return true (whether there // is a tref in the innards or not, because if there is one then it must be totally // contained) if (!(SP_IS_STRING(start_item) && SP_IS_TREF(start_item->parent)) && !(SP_IS_STRING(end_item) && SP_IS_TREF(end_item->parent))) { fully_contained = true; } // Both the beginning and end are trefs; but in this case, the string iterators // must be at the right places else if ((SP_IS_STRING(start_item) && SP_IS_TREF(start_item->parent)) && (SP_IS_STRING(end_item) && SP_IS_TREF(end_item->parent))) { if (start == SP_STRING(start_item)->string.begin() && end == SP_STRING(start_item)->string.end()) { fully_contained = true; } } // If the beginning is a string that is a child of a tref, the iterator has to be // at the beginning of the item else if ((SP_IS_STRING(start_item) && SP_IS_TREF(start_item->parent)) && !(SP_IS_STRING(end_item) && SP_IS_TREF(end_item->parent))) { if (start == SP_STRING(start_item)->string.begin()) { fully_contained = true; } } // Same, but the for the end else if (!(SP_IS_STRING(start_item) && SP_IS_TREF(start_item->parent)) && (SP_IS_STRING(end_item) && SP_IS_TREF(end_item->parent))) { if (end == SP_STRING(start_item)->string.end()) { fully_contained = true; } } } return fully_contained; }
bool item_type_match (SPItem *item, GtkWidget *widget) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (SP_IS_RECT(item)) { return (type_checkbox (widget, "shapes") || type_checkbox (widget, "rects")); } else if (SP_IS_GENERICELLIPSE(item) || SP_IS_ELLIPSE(item) || SP_IS_ARC(item) || SP_IS_CIRCLE(item)) { return (type_checkbox (widget, "shapes") || type_checkbox (widget, "ellipses")); } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { return (type_checkbox (widget, "shapes") || type_checkbox (widget, "stars")); } else if (SP_IS_SPIRAL(item)) { return (type_checkbox (widget, "shapes") || type_checkbox (widget, "spirals")); } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { return (type_checkbox (widget, "paths")); } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) { return (type_checkbox (widget, "texts")); } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! return (type_checkbox (widget, "groups")); } else if (SP_IS_USE(item)) { return (type_checkbox (widget, "clones")); } else if (SP_IS_IMAGE(item)) { return (type_checkbox (widget, "images")); } else if (SP_IS_OFFSET(item)) { return (type_checkbox (widget, "offsets")); } return false; }
/** * This function will create a new tspan element with the same attributes as * the tref had and add the same text as a child. The tref is replaced in the * tree with the new tspan. * The code is based partially on sp_use_unlink */ SPObject * sp_tref_convert_to_tspan(SPObject *obj) { SPObject * new_tspan = NULL; //////////////////// // BASE CASE //////////////////// if (SP_IS_TREF(obj)) { SPTRef *tref = SP_TREF(obj); if (tref && tref->stringChild) { Inkscape::XML::Node *tref_repr = tref->getRepr(); Inkscape::XML::Node *tref_parent = tref_repr->parent(); SPDocument *document = tref->document; Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *new_tspan_repr = xml_doc->createElement("svg:tspan"); // Add the new tspan element just after the current tref tref_parent->addChild(new_tspan_repr, tref_repr); Inkscape::GC::release(new_tspan_repr); new_tspan = document->getObjectByRepr(new_tspan_repr); // Create a new string child for the tspan Inkscape::XML::Node *new_string_repr = tref->stringChild->getRepr()->duplicate(xml_doc); new_tspan_repr->addChild(new_string_repr, NULL); //SPObject * new_string_child = document->getObjectByRepr(new_string_repr); // Merge style from the tref SPStyle *new_tspan_sty = new_tspan->style; SPStyle const *tref_sty = tref->style; sp_style_merge_from_dying_parent(new_tspan_sty, tref_sty); sp_style_merge_from_parent(new_tspan_sty, new_tspan->parent->style); new_tspan->updateRepr(); // Hold onto our SPObject and repr for now. sp_object_ref(tref, NULL); Inkscape::GC::anchor(tref_repr); // Remove ourselves, not propagating delete events to avoid a // chain-reaction with other elements that might reference us. tref->deleteObject(false); // Give the copy our old id and let go of our old repr. new_tspan_repr->setAttribute("id", tref_repr->attribute("id")); Inkscape::GC::release(tref_repr); // Establish the succession and let go of our object. tref->setSuccessor(new_tspan); sp_object_unref(tref, NULL); } } //////////////////// // RECURSIVE CASE //////////////////// else { GSList *l = NULL; for (SPObject *child = obj->firstChild() ; child != NULL ; child = child->getNext() ) { sp_object_ref(child, obj); l = g_slist_prepend (l, child); } l = g_slist_reverse (l); while (l) { SPObject *child = reinterpret_cast<SPObject *>(l->data); // We just built this list, so cast is safe. l = g_slist_remove (l, child); // Note that there may be more than one conversion happening here, so if it's not a // tref being passed into this function, the returned value can't be specifically known new_tspan = sp_tref_convert_to_tspan(child); sp_object_unref(child, obj); } } return new_tspan; }