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"); } SPItem::write(xml_doc, repr, flags); 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 (this->ref->getURI()) { gchar *uri_string = this->ref->getURI()->toString(); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); } if (SP_IS_SHAPE(this->child)) { SP_SHAPE(this->child)->set_shape(); // evaluate SPCurve of child } else if (SP_IS_TEXT(this->child)) { SP_TEXT(this->child)->rebuildLayout(); // refresh Layout, LP Bug 1339305 } else if (SP_IS_FLOWTEXT(this->child)) { if (SP_IS_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())) SP_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())->UpdateComputed(); SP_FLOWTEXT(this->child)->rebuildLayout(); } return repr; }
void sp_textpath_to_text(SPObject *tp) { SPObject *text = SP_OBJECT_PARENT(tp); NRRect bbox; sp_item_invoke_bbox(SP_ITEM(text), &bbox, sp_item_i2doc_affine(SP_ITEM(text)), TRUE); Geom::Point xy(bbox.x0, bbox.y0); // make a list of textpath children GSList *tp_reprs = NULL; for (SPObject *o = SP_OBJECT(tp)->firstChild() ; o != NULL; o = o->next) { tp_reprs = g_slist_prepend(tp_reprs, SP_OBJECT_REPR(o)); } for ( GSList *i = tp_reprs ; i ; i = i->next ) { // make a copy of each textpath child Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(SP_OBJECT_REPR(text)->document()); // remove the old repr from under textpath SP_OBJECT_REPR(tp)->removeChild((Inkscape::XML::Node *) i->data); // put its copy under text SP_OBJECT_REPR(text)->addChild(copy, NULL); // fixme: copy id } //remove textpath tp->deleteObject(); g_slist_free(tp_reprs); // set x/y on text /* fixme: Yuck, is this really the right test? */ if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { sp_repr_set_svg_double(SP_OBJECT_REPR(text), "x", xy[Geom::X]); sp_repr_set_svg_double(SP_OBJECT_REPR(text), "y", xy[Geom::Y]); } }
Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:path"); } if (flags & SP_OBJECT_WRITE_EXT) { repr->setAttribute("sodipodi:type", "star"); sp_repr_set_int (repr, "sodipodi:sides", this->sides); sp_repr_set_svg_double(repr, "sodipodi:cx", this->center[Geom::X]); sp_repr_set_svg_double(repr, "sodipodi:cy", this->center[Geom::Y]); sp_repr_set_svg_double(repr, "sodipodi:r1", this->r[0]); sp_repr_set_svg_double(repr, "sodipodi:r2", this->r[1]); sp_repr_set_svg_double(repr, "sodipodi:arg1", this->arg[0]); sp_repr_set_svg_double(repr, "sodipodi:arg2", this->arg[1]); sp_repr_set_boolean (repr, "inkscape:flatsided", this->flatsided); sp_repr_set_svg_double(repr, "inkscape:rounded", this->rounded); sp_repr_set_svg_double(repr, "inkscape:randomized", this->randomized); } this->set_shape(); char *d = sp_svg_write_path (this->_curve->get_pathvector()); repr->setAttribute("d", d); g_free(d); // CPPIFY: see header file SPShape::write(xml_doc, repr, flags); return repr; }
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* SPLine::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:line"); } if (repr != this->getRepr()) { repr->mergeFrom(this->getRepr(), "id"); } sp_repr_set_svg_double(repr, "x1", this->x1.computed); sp_repr_set_svg_double(repr, "y1", this->y1.computed); sp_repr_set_svg_double(repr, "x2", this->x2.computed); sp_repr_set_svg_double(repr, "y2", this->y2.computed); SPShape::write(xml_doc, repr, flags); return repr; }
/** * Writes the object into the repr object, then calls the parent's write routine. */ static Inkscape::XML::Node * sp_root_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPRoot *root = SP_ROOT(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:svg"); } if (flags & SP_OBJECT_WRITE_EXT) { repr->setAttribute("inkscape:version", Inkscape::version_string); } if ( !repr->attribute("version") ) { gchar* myversion = sp_version_to_string(root->version.svg); repr->setAttribute("version", myversion); g_free(myversion); } if (fabs(root->x.computed) > 1e-9) sp_repr_set_svg_double(repr, "x", root->x.computed); if (fabs(root->y.computed) > 1e-9) sp_repr_set_svg_double(repr, "y", root->y.computed); /* Unlike all other SPObject, here we want to preserve absolute units too (and only here, * according to the recommendation in http://www.w3.org/TR/SVG11/coords.html#Units). */ repr->setAttribute("width", sp_svg_length_write_with_units(root->width).c_str()); repr->setAttribute("height", sp_svg_length_write_with_units(root->height).c_str()); if (root->viewBox_set) { Inkscape::SVGOStringStream os; os << root->viewBox.left() << " " << root->viewBox.top() << " " << root->viewBox.width() << " " << root->viewBox.height(); repr->setAttribute("viewBox", os.str().c_str()); } if (((SPObjectClass *) (parent_class))->write) ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags); return repr; }
void sp_textpath_to_text(SPObject *tp) { SPObject *text = tp->parent; Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine()); if (!bbox) { return; } Geom::Point xy = bbox->min(); xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. // make a list of textpath children GSList *tp_reprs = NULL; for (SPObject *o = tp->firstChild() ; o != NULL; o = o->next) { tp_reprs = g_slist_prepend(tp_reprs, o->getRepr()); } for ( GSList *i = tp_reprs ; i ; i = i->next ) { // make a copy of each textpath child Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(text->getRepr()->document()); // remove the old repr from under textpath tp->getRepr()->removeChild((Inkscape::XML::Node *) i->data); // put its copy under text text->getRepr()->addChild(copy, NULL); // fixme: copy id } //remove textpath tp->deleteObject(); g_slist_free(tp_reprs); // set x/y on text (to be near where it was when on path) /* fixme: Yuck, is this really the right test? */ if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { sp_repr_set_svg_double(text->getRepr(), "x", xy[Geom::X]); sp_repr_set_svg_double(text->getRepr(), "y", xy[Geom::Y]); } }
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"); } SPItem::write(xml_doc, repr, flags); 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 (this->ref->getURI()) { gchar *uri_string = this->ref->getURI()->toString(); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); } SPShape *shape = dynamic_cast<SPShape *>(child); if (shape) { shape->set_shape(); // evaluate SPCurve of child } else { SPText *text = dynamic_cast<SPText *>(child); if (text) { text->rebuildLayout(); // refresh Layout, LP Bug 1339305 } else { SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(child); if (flowtext) { SPFlowregion *flowregion = dynamic_cast<SPFlowregion *>(flowtext->firstChild()); if (flowregion) { flowregion->UpdateComputed(); } flowtext->rebuildLayout(); } } } return repr; }
Inkscape::XML::Node * SPLine::write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPLine *line = SP_LINE(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:line"); } if (repr != object->getRepr()) { repr->mergeFrom(object->getRepr(), "id"); } sp_repr_set_svg_double(repr, "x1", line->x1.computed); sp_repr_set_svg_double(repr, "y1", line->y1.computed); sp_repr_set_svg_double(repr, "x2", line->x2.computed); sp_repr_set_svg_double(repr, "y2", line->y2.computed); if (((SPObjectClass *) (SPLineClass::static_parent_class))->write) { ((SPObjectClass *) (SPLineClass::static_parent_class))->write(object, xml_doc, repr, flags); } return repr; }
Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:image"); } repr->setAttribute("xlink:href", this->href); /* fixme: Reset attribute if needed (Lauris) */ if (this->x._set) { sp_repr_set_svg_double(repr, "x", this->x.computed); } if (this->y._set) { sp_repr_set_svg_double(repr, "y", this->y.computed); } if (this->width._set) { sp_repr_set_svg_double(repr, "width", this->width.computed); } if (this->height._set) { sp_repr_set_svg_double(repr, "height", this->height.computed); } //XML Tree being used directly here while it shouldn't be... repr->setAttribute("preserveAspectRatio", this->getRepr()->attribute("preserveAspectRatio")); #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) if (this->color_profile) { repr->setAttribute("color-profile", this->color_profile); } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) SPItem::write(xml_doc, repr, flags); return repr; }
/** * Writes its settings to an incoming repr object, if any. */ Inkscape::XML::Node* SPFeDisplacementMap::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFilter *parent = SP_FILTER(this->parent); if (!repr) { repr = doc->createElement("svg:feDisplacementMap"); } gchar const *in2_name = sp_filter_name_for_image(parent, this->in2); if( !in2_name ) { // This code is very similar to sp_filter_primtive_name_previous_out() SPObject *i = parent->children; // Find previous filter primitive while (i && i->next != this) { i = i->next; } if( i ) { SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); in2_name = sp_filter_name_for_image(parent, i_prim->image_out); } } if (in2_name) { repr->setAttribute("in2", in2_name); } else { g_warning("Unable to set in2 for feDisplacementMap"); } sp_repr_set_svg_double(repr, "scale", this->scale); repr->setAttribute("xChannelSelector", get_channelselector_name(this->xChannelSelector)); repr->setAttribute("yChannelSelector", get_channelselector_name(this->yChannelSelector)); SPFilterPrimitive::write(doc, repr, flags); return repr; }
/** * Writes its settings to an incoming repr object, if any. */ static Inkscape::XML::Node * sp_feComposite_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFeComposite *comp = SP_FECOMPOSITE(object); SPFilter *parent = SP_FILTER(object->parent); if (!repr) { repr = doc->createElement("svg:feComposite"); } gchar const *out_name = sp_filter_name_for_image(parent, comp->in2); if (out_name) { repr->setAttribute("in2", out_name); } else { SPObject *i = parent->children; while (i && i->next != object) i = i->next; SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); out_name = sp_filter_name_for_image(parent, i_prim->image_out); repr->setAttribute("in2", out_name); if (!out_name) { g_warning("Unable to set in2 for feComposite"); } } char const *comp_op; switch (comp->composite_operator) { case COMPOSITE_OVER: comp_op = "over"; break; case COMPOSITE_IN: comp_op = "in"; break; case COMPOSITE_OUT: comp_op = "out"; break; case COMPOSITE_ATOP: comp_op = "atop"; break; case COMPOSITE_XOR: comp_op = "xor"; break; case COMPOSITE_ARITHMETIC: comp_op = "arithmetic"; break; default: comp_op = 0; } repr->setAttribute("operator", comp_op); if (comp->composite_operator == COMPOSITE_ARITHMETIC) { sp_repr_set_svg_double(repr, "k1", comp->k1); sp_repr_set_svg_double(repr, "k2", comp->k2); sp_repr_set_svg_double(repr, "k3", comp->k3); sp_repr_set_svg_double(repr, "k4", comp->k4); } else { repr->setAttribute("k1", 0); repr->setAttribute("k2", 0); repr->setAttribute("k3", 0); repr->setAttribute("k4", 0); } if (((SPObjectClass *) feComposite_parent_class)->write) { ((SPObjectClass *) feComposite_parent_class)->write(object, doc, repr, flags); } return repr; }
SPDocument * GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) { // Determine whether the image should be embedded Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool ask = prefs->getBool("/dialogs/import/ask"); Glib::ustring link = prefs->getString("/dialogs/import/link"); bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi"); Glib::ustring scale = prefs->getString("/dialogs/import/scale"); // std::cout << "GkdpixbufInput::open: " // << " ask: " << ask // << ", link: " << link // << ", forcexdpi: " << forcexdpi // << ", scale: " << scale << std::endl; // std::cout << " in preferences: " // << " ask: " << !mod->get_param_bool("do_not_ask") // << ", link: " << mod->get_param_optiongroup("link") // << ", mod_dpi: " << mod->get_param_optiongroup("dpi") // << ", scale: " << mod->get_param_optiongroup("scale") << std::endl; if( ask ) { Glib::ustring mod_link = mod->get_param_optiongroup("link"); Glib::ustring mod_dpi = mod->get_param_optiongroup("dpi"); bool mod_forcexdpi = ( mod_dpi.compare( "from_default" ) == 0 ); Glib::ustring mod_scale = mod->get_param_optiongroup("scale"); if( link.compare( mod_link ) != 0 ) { link = mod_link; } prefs->setString("/dialogs/import/link", link ); if( forcexdpi != mod_forcexdpi ) { forcexdpi = mod_forcexdpi; } prefs->setBool("/dialogs/import/forcexdpi", forcexdpi ); if( scale.compare( mod_scale ) != 0 ) { scale = mod_scale; } prefs->setString("/dialogs/import/scale", scale ); prefs->setBool("/dialogs/import/ask", !mod->get_param_bool("do_not_ask") ); } bool embed = ( link.compare( "embed" ) == 0 ); SPDocument *doc = NULL; boost::scoped_ptr<Inkscape::Pixbuf> pb(Inkscape::Pixbuf::create_from_file(uri)); // TODO: the pixbuf is created again from the base64-encoded attribute in SPImage. // Find a way to create the pixbuf only once. if (pb) { doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); // no need to undo in this temporary document double width = pb->width(); double height = pb->height(); double defaultxdpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", Inkscape::Util::Quantity::convert(1, "in", "px")); //bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi"); ImageResolution *ir = 0; double xscale = 1; double yscale = 1; if (!ir && !forcexdpi) { ir = new ImageResolution(uri); } if (ir && ir->ok()) { xscale = 900.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi yscale = 900.0 / floor(10.*ir->y() + .5); } else { xscale = 90.0 / defaultxdpi; yscale = 90.0 / defaultxdpi; } width *= xscale; height *= yscale; delete ir; // deleting NULL is safe // Create image node Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image"); sp_repr_set_svg_double(image_node, "width", width); sp_repr_set_svg_double(image_node, "height", height); // Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is // what Inkscaper's expect. image_node->setAttribute("preserveAspectRatio", "none"); if( scale.compare( "auto" ) != 0 ) { SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "image-rendering", scale.c_str()); sp_repr_css_set(image_node, css, "style"); sp_repr_css_attr_unref( css ); } if (embed) { sp_embed_image(image_node, pb.get()); } else { // convert filename to uri gchar* _uri = g_filename_to_uri(uri, NULL, NULL); if(_uri) { image_node->setAttribute("xlink:href", _uri); g_free(_uri); } else { image_node->setAttribute("xlink:href", uri); } } // Add it to the current layer doc->getRoot()->appendChildRepr(image_node); Inkscape::GC::release(image_node); fit_canvas_to_drawing(doc); // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { //std::cout << "Viewbox not set, setting" << std::endl; doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); } // restore undo, as now this document may be shown to the user if a bitmap was opened DocumentUndo::setUndoSensitive(doc, saved); } else { printf("GdkPixbuf loader failed\n"); } return doc; }
Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { // std::cout << "\nSPGenericEllipse::write: Entrance (" // << (repr == NULL ? " NULL" : g_quark_to_string(repr->code())) // << ")" << std::endl; GenericEllipseType new_type = SP_GENERIC_ELLIPSE_UNDEFINED; if (this->_isSlice() || hasPathEffect() ) { new_type = SP_GENERIC_ELLIPSE_ARC; } else if ( rx.computed == ry.computed ) { new_type = SP_GENERIC_ELLIPSE_CIRCLE; } else { new_type = SP_GENERIC_ELLIPSE_ELLIPSE; } // std::cout << " new_type: " << new_type << std::endl; if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { switch ( new_type ) { case SP_GENERIC_ELLIPSE_ARC: repr = xml_doc->createElement("svg:path"); break; case SP_GENERIC_ELLIPSE_CIRCLE: repr = xml_doc->createElement("svg:circle"); break; case SP_GENERIC_ELLIPSE_ELLIPSE: repr = xml_doc->createElement("svg:ellipse"); break; case SP_GENERIC_ELLIPSE_UNDEFINED: default: std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl; } } if( type != new_type ) { switch( new_type ) { case SP_GENERIC_ELLIPSE_ARC: repr->setCodeUnsafe(g_quark_from_string("svg:path")); break; case SP_GENERIC_ELLIPSE_CIRCLE: repr->setCodeUnsafe(g_quark_from_string("svg:circle")); break; case SP_GENERIC_ELLIPSE_ELLIPSE: repr->setCodeUnsafe(g_quark_from_string("svg:ellipse")); break; default: std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl; } type = new_type; // FIXME: The XML dialog won't update the element name. We need // a notifyElementNameChanged callback added to the XML observers // to trigger a refresh. } // std::cout << " type: " << g_quark_to_string( repr->code() ) << std::endl; // std::cout << " cx: " << cx.computed // << " cy: " << cy.computed // << " rx: " << rx.computed // << " ry: " << ry.computed << std::endl; switch ( type ) { case SP_GENERIC_ELLIPSE_UNDEFINED: case SP_GENERIC_ELLIPSE_ARC: repr->setAttribute("cx", NULL ); repr->setAttribute("cy", NULL ); repr->setAttribute("rx", NULL ); repr->setAttribute("ry", NULL ); repr->setAttribute("r", NULL ); if (flags & SP_OBJECT_WRITE_EXT) { repr->setAttribute("sodipodi:type", "arc"); sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed); sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed); sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed); sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); // write start and end only if they are non-trivial; otherwise remove if (this->_isSlice()) { sp_repr_set_svg_double(repr, "sodipodi:start", this->start); sp_repr_set_svg_double(repr, "sodipodi:end", this->end); repr->setAttribute("sodipodi:open", (!this->_closed) ? "true" : NULL); } else { repr->setAttribute("sodipodi:end", NULL); repr->setAttribute("sodipodi:start", NULL); repr->setAttribute("sodipodi:open", NULL); } } // write d= this->set_elliptical_path_attribute(repr); break; case SP_GENERIC_ELLIPSE_CIRCLE: sp_repr_set_svg_double(repr, "cx", this->cx.computed); sp_repr_set_svg_double(repr, "cy", this->cy.computed); sp_repr_set_svg_double(repr, "r", this->rx.computed); repr->setAttribute("rx", NULL ); repr->setAttribute("ry", NULL ); repr->setAttribute("sodipodi:cx", NULL ); repr->setAttribute("sodipodi:cy", NULL ); repr->setAttribute("sodipodi:rx", NULL ); repr->setAttribute("sodipodi:ry", NULL ); repr->setAttribute("sodipodi:end", NULL ); repr->setAttribute("sodipodi:start", NULL ); repr->setAttribute("sodipodi:open", NULL ); repr->setAttribute("sodipodi:type", NULL ); repr->setAttribute("d", NULL ); break; case SP_GENERIC_ELLIPSE_ELLIPSE: sp_repr_set_svg_double(repr, "cx", this->cx.computed); sp_repr_set_svg_double(repr, "cy", this->cy.computed); sp_repr_set_svg_double(repr, "rx", this->rx.computed); sp_repr_set_svg_double(repr, "ry", this->ry.computed); repr->setAttribute("r", NULL ); repr->setAttribute("sodipodi:cx", NULL ); repr->setAttribute("sodipodi:cy", NULL ); repr->setAttribute("sodipodi:rx", NULL ); repr->setAttribute("sodipodi:ry", NULL ); repr->setAttribute("sodipodi:end", NULL ); repr->setAttribute("sodipodi:start", NULL ); repr->setAttribute("sodipodi:open", NULL ); repr->setAttribute("sodipodi:type", NULL ); repr->setAttribute("d", NULL ); break; default: std::cerr << "SPGenericEllipse::write: unknown type." << std::endl; } this->set_shape(); // evaluate SPCurve SPShape::write(xml_doc, repr, flags); // std::cout << "SPGenericEllipse::write: Exit: " << g_quark_to_string(repr->code()) << "\n" << std::endl; return repr; }
static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { SPFontFace *face = SP_FONTFACE(object); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:font-face"); } //TODO: //sp_repr_set_svg_double(repr, "font-family", face->font_family); //sp_repr_set_svg_double(repr, "font-style", face->font_style); //sp_repr_set_svg_double(repr, "font-variant", face->font_variant); //sp_repr_set_svg_double(repr, "font-weight", face->font_weight); //sp_repr_set_svg_double(repr, "font-stretch", face->font_stretch); //sp_repr_set_svg_double(repr, "font-size", face->font_size); //sp_repr_set_svg_double(repr, "unicode-range", face->unicode_range); sp_repr_set_svg_double(repr, "units-per-em", face->units_per_em); //sp_repr_set_svg_double(repr, "panose-1", face->panose_1); sp_repr_set_svg_double(repr, "stemv", face->stemv); sp_repr_set_svg_double(repr, "stemh", face->stemh); sp_repr_set_svg_double(repr, "slope", face->slope); sp_repr_set_svg_double(repr, "cap-height", face->cap_height); sp_repr_set_svg_double(repr, "x-height", face->x_height); sp_repr_set_svg_double(repr, "accent-height", face->accent_height); sp_repr_set_svg_double(repr, "ascent", face->ascent); sp_repr_set_svg_double(repr, "descent", face->descent); //sp_repr_set_svg_double(repr, "widths", face->widths); //sp_repr_set_svg_double(repr, "bbox", face->bbox); sp_repr_set_svg_double(repr, "ideographic", face->ideographic); sp_repr_set_svg_double(repr, "alphabetic", face->alphabetic); sp_repr_set_svg_double(repr, "mathematical", face->mathematical); sp_repr_set_svg_double(repr, "hanging", face->hanging); sp_repr_set_svg_double(repr, "v-ideographic", face->v_ideographic); sp_repr_set_svg_double(repr, "v-alphabetic", face->v_alphabetic); sp_repr_set_svg_double(repr, "v-mathematical", face->v_mathematical); sp_repr_set_svg_double(repr, "v-hanging", face->v_hanging); sp_repr_set_svg_double(repr, "underline-position", face->underline_position); sp_repr_set_svg_double(repr, "underline-thickness", face->underline_thickness); sp_repr_set_svg_double(repr, "strikethrough-position", face->strikethrough_position); sp_repr_set_svg_double(repr, "strikethrough-thickness", face->strikethrough_thickness); sp_repr_set_svg_double(repr, "overline-position", face->overline_position); sp_repr_set_svg_double(repr, "overline-thickness", face->overline_thickness); if (repr != object->getRepr()) { // In all COPY_ATTR given below the XML tree is // being used directly while it shouldn't be. COPY_ATTR(repr, object->getRepr(), "font-family"); COPY_ATTR(repr, object->getRepr(), "font-style"); COPY_ATTR(repr, object->getRepr(), "font-variant"); COPY_ATTR(repr, object->getRepr(), "font-weight"); COPY_ATTR(repr, object->getRepr(), "font-stretch"); COPY_ATTR(repr, object->getRepr(), "font-size"); COPY_ATTR(repr, object->getRepr(), "unicode-range"); COPY_ATTR(repr, object->getRepr(), "units-per-em"); COPY_ATTR(repr, object->getRepr(), "panose-1"); COPY_ATTR(repr, object->getRepr(), "stemv"); COPY_ATTR(repr, object->getRepr(), "stemh"); COPY_ATTR(repr, object->getRepr(), "slope"); COPY_ATTR(repr, object->getRepr(), "cap-height"); COPY_ATTR(repr, object->getRepr(), "x-height"); COPY_ATTR(repr, object->getRepr(), "accent-height"); COPY_ATTR(repr, object->getRepr(), "ascent"); COPY_ATTR(repr, object->getRepr(), "descent"); COPY_ATTR(repr, object->getRepr(), "widths"); COPY_ATTR(repr, object->getRepr(), "bbox"); COPY_ATTR(repr, object->getRepr(), "ideographic"); COPY_ATTR(repr, object->getRepr(), "alphabetic"); COPY_ATTR(repr, object->getRepr(), "mathematical"); COPY_ATTR(repr, object->getRepr(), "hanging"); COPY_ATTR(repr, object->getRepr(), "v-ideographic"); COPY_ATTR(repr, object->getRepr(), "v-alphabetic"); COPY_ATTR(repr, object->getRepr(), "v-mathematical"); COPY_ATTR(repr, object->getRepr(), "v-hanging"); COPY_ATTR(repr, object->getRepr(), "underline-position"); COPY_ATTR(repr, object->getRepr(), "underline-thickness"); COPY_ATTR(repr, object->getRepr(), "strikethrough-position"); COPY_ATTR(repr, object->getRepr(), "strikethrough-thickness"); COPY_ATTR(repr, object->getRepr(), "overline-position"); COPY_ATTR(repr, object->getRepr(), "overline-thickness"); } if (((SPObjectClass *) (parent_class))->write) { ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags); } return repr; }
void text_unflow () { 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); if (!flowtext_in_selection(selection) || g_slist_length((GSList *) selection->itemList()) < 1) { sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); return; } GSList *new_objs = NULL; GSList *old_objs = NULL; for (GSList *items = g_slist_copy((GSList *) selection->itemList()); items != NULL; items = items->next) { if (!SP_IS_FLOWTEXT(SP_OBJECT(items->data))) { continue; } SPItem *flowtext = SP_ITEM(items->data); if (sp_te_get_string_multiline(flowtext) == NULL) { // flowtext is empty continue; } /* Create <text> */ Inkscape::XML::Node *rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create /* Set style */ rtext->setAttribute("style", SP_OBJECT_REPR(flowtext)->attribute("style")); // fixme: transfer style attrs too; and from descendants NRRect bbox; sp_item_invoke_bbox(SP_ITEM(flowtext), &bbox, sp_item_i2doc_affine(SP_ITEM(flowtext)), TRUE); Geom::Point xy(bbox.x0, bbox.y0); if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { sp_repr_set_svg_double(rtext, "x", xy[Geom::X]); sp_repr_set_svg_double(rtext, "y", xy[Geom::Y]); } /* Create <tspan> */ Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan"); rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan? rtext->addChild(rtspan, NULL); gchar *text_string = sp_te_get_string_multiline(flowtext); Inkscape::XML::Node *text_repr = xml_doc->createTextNode(text_string); // FIXME: transfer all formatting!!! free(text_string); rtspan->appendChild(text_repr); SP_OBJECT_REPR(SP_OBJECT_PARENT(flowtext))->appendChild(rtext); SPObject *text_object = doc->getObjectByRepr(rtext); new_objs = g_slist_prepend (new_objs, text_object); old_objs = g_slist_prepend (old_objs, flowtext); Inkscape::GC::release(rtext); Inkscape::GC::release(rtspan); Inkscape::GC::release(text_repr); } selection->clear(); selection->setList(new_objs); for (GSList *i = old_objs; i; i = i->next) { SP_OBJECT(i->data)->deleteObject (true); } g_slist_free (old_objs); g_slist_free (new_objs); sp_document_done(doc, SP_VERB_CONTEXT_TEXT, _("Unflow flowed text")); }
SPDocument * sp_document_create(Inkscape::XML::Document *rdoc, gchar const *uri, gchar const *base, gchar const *name, unsigned int keepalive) { SPDocument *document; Inkscape::XML::Node *rroot; Inkscape::Version sodipodi_version; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); rroot = rdoc->root(); document = new SPDocument(); document->keepalive = keepalive; document->rdoc = rdoc; document->rroot = rroot; #ifndef WIN32 prepend_current_dir_if_relative(&(document->uri), uri); #else // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test! document->uri = uri? g_strdup(uri) : NULL; #endif // base is simply the part of the path before filename; e.g. when running "inkscape ../file.svg" the base is "../" // which is why we use g_get_current_dir() in calculating the abs path above //This is NULL for a new document if (base) document->base = g_strdup(base); else document->base = NULL; document->name = g_strdup(name); document->root = sp_object_repr_build_tree(document, rroot); sodipodi_version = SP_ROOT(document->root)->version.sodipodi; /* fixme: Not sure about this, but lets assume ::build updates */ rroot->setAttribute("sodipodi:version", SODIPODI_VERSION); rroot->setAttribute("inkscape:version", Inkscape::version_string); /* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */ /* Quick hack 2 - get default image size into document */ if (!rroot->attribute("width")) rroot->setAttribute("width", "100%"); if (!rroot->attribute("height")) rroot->setAttribute("height", "100%"); /* End of quick hack 2 */ /* Quick hack 3 - Set uri attributes */ if (uri) { rroot->setAttribute("sodipodi:docname", uri); } /* End of quick hack 3 */ /* Eliminate obsolete sodipodi:docbase, for privacy reasons */ rroot->setAttribute("sodipodi:docbase", NULL); /* Eliminate any claim to adhere to a profile, as we don't try to */ rroot->setAttribute("baseProfile", NULL); // creating namedview if (!sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview")) { // if there's none in the document already, Inkscape::XML::Node *rnew = NULL; rnew = rdoc->createElement("sodipodi:namedview"); //rnew->setAttribute("id", "base"); // Add namedview data from the preferences // we can't use getAllEntries because this could produce non-SVG doubles Glib::ustring pagecolor = prefs->getString("/template/base/pagecolor"); if (!pagecolor.empty()) { rnew->setAttribute("pagecolor", pagecolor.data()); } Glib::ustring bordercolor = prefs->getString("/template/base/bordercolor"); if (!bordercolor.empty()) { rnew->setAttribute("bordercolor", bordercolor.data()); } sp_repr_set_svg_double(rnew, "borderopacity", prefs->getDouble("/template/base/borderopacity", 1.0)); sp_repr_set_svg_double(rnew, "objecttolerance", prefs->getDouble("/template/base/objecttolerance", 10.0)); sp_repr_set_svg_double(rnew, "gridtolerance", prefs->getDouble("/template/base/gridtolerance", 10.0)); sp_repr_set_svg_double(rnew, "guidetolerance", prefs->getDouble("/template/base/guidetolerance", 10.0)); sp_repr_set_svg_double(rnew, "inkscape:pageopacity", prefs->getDouble("/template/base/inkscape:pageopacity", 0.0)); sp_repr_set_int(rnew, "inkscape:pageshadow", prefs->getInt("/template/base/inkscape:pageshadow", 2)); sp_repr_set_int(rnew, "inkscape:window-width", prefs->getInt("/template/base/inkscape:window-width", 640)); sp_repr_set_int(rnew, "inkscape:window-height", prefs->getInt("/template/base/inkscape:window-height", 480)); // insert into the document rroot->addChild(rnew, NULL); // clean up Inkscape::GC::release(rnew); } /* Defs */ if (!SP_ROOT(document->root)->defs) { Inkscape::XML::Node *r; r = rdoc->createElement("svg:defs"); rroot->addChild(r, NULL); Inkscape::GC::release(r); g_assert(SP_ROOT(document->root)->defs); } /* Default RDF */ rdf_set_defaults( document ); if (keepalive) { inkscape_ref(); } // Remark: Here, we used to create a "currentpersp3d" element in the document defs. // But this is probably a bad idea since we need to adapt it for every change of selection, which will // completely clutter the undo history. Maybe rather save it to prefs on exit and re-read it on startup? document->current_persp3d = persp3d_document_first_persp(document); if (!document->current_persp3d) { document->current_persp3d = persp3d_create_xml_element (document); } sp_document_set_undo_sensitive(document, true); // reset undo key when selection changes, so that same-key actions on different objects are not coalesced if (!Inkscape::NSApplication::Application::getNewGui()) { g_signal_connect(G_OBJECT(INKSCAPE), "change_selection", G_CALLBACK(sp_document_reset_key), document); g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_document_reset_key), document); } else { document->_selection_changed_connection = Inkscape::NSApplication::Editor::connectSelectionChanged (sigc::mem_fun (*document, &SPDocument::reset_key)); document->_desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::mem_fun (*document, &SPDocument::reset_key)); } return document; }