static Inkscape::XML::Node * sp_flowpara_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { // SPFlowpara *group = SP_FLOWPARA (object); if ( flags&SP_OBJECT_WRITE_BUILD ) { if ( repr == NULL ) repr = xml_doc->createElement("svg:flowPara"); 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_FLOWTSPAN (child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_FLOWPARA (child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } 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_FLOWTSPAN (child) ) { child->updateRepr(flags); } else if ( SP_IS_FLOWPARA (child) ) { child->updateRepr(flags); } else if ( SP_IS_STRING(child) ) { SP_OBJECT_REPR (child)->setContent(SP_STRING(child)->string.c_str()); } } } if (((SPObjectClass *) (flowpara_parent_class))->write) ((SPObjectClass *) (flowpara_parent_class))->write (object, xml_doc, repr, flags); return repr; }
void text_flow_into_shape() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) return; SPDocument *doc = sp_desktop_document (desktop); Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); Inkscape::Selection *selection = sp_desktop_selection(desktop); SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); if (!text || !shape || g_slist_length((GSList *) selection->itemList()) < 2) { sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); return; } if (SP_IS_TEXT(text)) { // remove transform from text, but recursively scale text's fontsize by the expansion SP_TEXT(text)->_adjustFontsizeRecursive(text, NR::expansion(SP_ITEM(text)->transform)); SP_OBJECT_REPR(text)->setAttribute("transform", NULL); } Inkscape::XML::Node *root_repr = xml_doc->createElement("svg:flowRoot"); root_repr->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create root_repr->setAttribute("style", SP_OBJECT_REPR(text)->attribute("style")); // fixme: transfer style attrs too SP_OBJECT_REPR(SP_OBJECT_PARENT(shape))->appendChild(root_repr); SPObject *root_object = doc->getObjectByRepr(root_repr); g_return_if_fail(SP_IS_FLOWTEXT(root_object)); Inkscape::XML::Node *region_repr = xml_doc->createElement("svg:flowRegion"); root_repr->appendChild(region_repr); SPObject *object = doc->getObjectByRepr(region_repr); g_return_if_fail(SP_IS_FLOWREGION(object)); /* Add clones */ for (GSList *items = (GSList *) selection->itemList(); items != NULL; items = items->next) { SPItem *item = SP_ITEM(items->data); if (SP_IS_SHAPE(item)){ Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0"); clone->setAttribute("y", "0"); clone->setAttribute("xlink:href", g_strdup_printf("#%s", SP_OBJECT_REPR(item)->attribute("id"))); // add the new clone to the region region_repr->appendChild(clone); } } if (SP_IS_TEXT(text)) { // flow from text, as string Inkscape::XML::Node *para_repr = xml_doc->createElement("svg:flowPara"); root_repr->appendChild(para_repr); object = doc->getObjectByRepr(para_repr); g_return_if_fail(SP_IS_FLOWPARA(object)); Inkscape::Text::Layout const *layout = te_get_layout(text); Glib::ustring text_ustring = sp_te_get_string_multiline(text, layout->begin(), layout->end()); Inkscape::XML::Node *text_repr = xml_doc->createTextNode(text_ustring.c_str()); // FIXME: transfer all formatting! and convert newlines into flowParas! para_repr->appendChild(text_repr); Inkscape::GC::release(para_repr); Inkscape::GC::release(text_repr); } else { // reflow an already flowed text, preserving paras for (SPObject *o = SP_OBJECT(text)->children; o != NULL; o = o->next) { if (SP_IS_FLOWPARA(o)) { Inkscape::XML::Node *para_repr = SP_OBJECT_REPR(o)->duplicate(xml_doc); root_repr->appendChild(para_repr); object = doc->getObjectByRepr(para_repr); g_return_if_fail(SP_IS_FLOWPARA(object)); Inkscape::GC::release(para_repr); } } } SP_OBJECT(text)->deleteObject (true); sp_document_done(doc, SP_VERB_CONTEXT_TEXT, _("Flow text into shape")); sp_desktop_selection(desktop)->set(SP_ITEM(root_object)); Inkscape::GC::release(root_repr); Inkscape::GC::release(region_repr); }