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; }
void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) { g_return_if_fail (group != NULL); g_return_if_fail (SP_IS_GROUP (group)); SPDocument *doc = group->document; SPRoot *root = doc->getRoot(); SPObject *defs = root->defs; SPItem *gitem = group; Inkscape::XML::Node *grepr = gitem->getRepr(); g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") || !strcmp (grepr->name(), "svg:switch")); // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse gitem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); SPItem *pitem = SP_ITEM(gitem->parent); Inkscape::XML::Node *prepr = pitem->getRepr(); if (SP_IS_BOX3D(gitem)) { group = box3d_convert_to_group(SP_BOX3D(gitem)); gitem = group; } sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(group), false); /* Step 1 - generate lists of children objects */ GSList *items = NULL; GSList *objects = NULL; for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { if (SP_IS_ITEM (child)) { SPItem *citem = SP_ITEM (child); /* Merging of style */ // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); sp_style_merge_from_dying_parent(child->style, gitem->style); /* * fixme: We currently make no allowance for the case where child is cloned * and the group has any style settings. * * (This should never occur with documents created solely with the current * version of inkscape without using the XML editor: we usually apply group * style changes to children rather than to the group itself.) * * If the group has no style settings, then * sp_style_merge_from_dying_parent should be a no-op. Otherwise (i.e. if * we change the child's style to compensate for its parent going away) * then those changes will typically be reflected in any clones of child, * whereas we'd prefer for Ungroup not to affect the visual appearance. * * The only way of preserving styling appearance in general is for child to * be put into a new group -- a somewhat surprising response to an Ungroup * command. We could add a new groupmode:transparent that would mostly * hide the existence of such groups from the user (i.e. editing behaves as * if the transparent group's children weren't in a group), though that's * extra complication & maintenance burden and this case is rare. */ child->updateRepr(); Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document()); // Merging transform Geom::Affine ctrans; Geom::Affine const g(gitem->transform); if (SP_IS_USE(citem) && sp_use_get_original (SP_USE(citem)) && sp_use_get_original( SP_USE(citem) )->parent == SP_OBJECT(group)) { // make sure a clone's effective transform is the same as was under group ctrans = g.inverse() * citem->transform * g; } else { // We should not apply the group's transformation to both a linked offset AND to its source if (SP_IS_OFFSET(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? SPItem *source = sp_offset_get_source(SP_OFFSET(citem)); // When dealing with a chain of linked offsets, the transformation of an offset will be // tied to the transformation of the top-most source, not to any of the intermediate // offsets. So let's find the top-most source while (source != NULL && SP_IS_OFFSET(source)) { source = sp_offset_get_source(SP_OFFSET(source)); } if (source != NULL && // If true then we must be dealing with a linked offset ... group->isAncestorOf(source) == false) { // ... of which the source is not in the same group ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset } else { ctrans = citem->transform; } } else { ctrans = citem->transform * g; } } // FIXME: constructing a transform that would fully preserve the appearance of a // textpath if it is ungrouped with its path seems to be impossible in general // case. E.g. if the group was squeezed, to keep the ungrouped textpath squeezed // as well, we'll need to relink it to some "virtual" path which is inversely // stretched relative to the actual path, and then squeeze the textpath back so it // would both fit the actual path _and_ be squeezed as before. It's a bummer. // This is just a way to temporarily remember the transform in repr. When repr is // reattached outside of the group, the transform will be written more properly // (i.e. optimized into the object if the corresponding preference is set) gchar *affinestr=sp_svg_transform_write(ctrans); nrepr->setAttribute("transform", affinestr); g_free(affinestr); items = g_slist_prepend (items, nrepr); } else { Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document()); objects = g_slist_prepend (objects, nrepr); } } /* Step 2 - clear group */ // remember the position of the group gint pos = group->getRepr()->position(); // the group is leaving forever, no heir, clones should take note; its children however are going to reemerge group->deleteObject(true, false); /* Step 3 - add nonitems */ if (objects) { Inkscape::XML::Node *last_def = defs->getRepr()->lastChild(); while (objects) { Inkscape::XML::Node *repr = (Inkscape::XML::Node *) objects->data; if (!sp_repr_is_meta_element(repr)) { defs->getRepr()->addChild(repr, last_def); } Inkscape::GC::release(repr); objects = g_slist_remove (objects, objects->data); } } /* Step 4 - add items */ while (items) { Inkscape::XML::Node *repr = (Inkscape::XML::Node *) items->data; // add item prepr->appendChild(repr); // restore position; since the items list was prepended (i.e. reverse), we now add // all children at the same pos, which inverts the order once again repr->setPosition(pos > 0 ? pos : 0); // fill in the children list if non-null SPItem *item = static_cast<SPItem *>(doc->getObjectByRepr(repr)); item->doWriteTransform(repr, item->transform, NULL, false); Inkscape::GC::release(repr); if (children && SP_IS_ITEM (item)) *children = g_slist_prepend (*children, item); items = g_slist_remove (items, items->data); } if (do_done) { DocumentUndo::done(doc, SP_VERB_NONE, _("Ungroup")); } }
SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { RVNGFileStream input(uri); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } RVNGStringVector output; #if WITH_LIBVISIO01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libvisio::VisioDocument::parse(&input, &generator)) { #else if (!libvisio::VisioDocument::generateSVG(&input, output)) { #endif return NULL; } if (output.empty()) { return NULL; } std::vector<RVNGString> tmpSVGOutput; for (unsigned i=0; i<output.size(); ++i) { RVNGString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } unsigned page_num = 1; // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { VsdImportDialog *dlg = 0; if (inkscape_use_gui()) { dlg = new VsdImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; return NULL; } } // Get needed page if (dlg) { page_num = dlg->getSelectedPage(); if (page_num < 1) page_num = 1; if (page_num > tmpSVGOutput.size()) page_num = tmpSVGOutput.size(); } } SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); } return doc; } #include "clear-n_.h" void VsdInput::init(void) { /* VSD */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("VSD Input") "</name>\n" "<id>org.inkscape.input.vsd</id>\n" "<input>\n" "<extension>.vsd</extension>\n" "<mimetype>application/vnd.visio</mimetype>\n" "<filetypename>" N_("Microsoft Visio Diagram (*.vsd)") "</filetypename>\n" "<filetypetooltip>" N_("File format used by Microsoft Visio 6 and later") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new VsdInput()); /* VDX */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("VDX Input") "</name>\n" "<id>org.inkscape.input.vdx</id>\n" "<input>\n" "<extension>.vdx</extension>\n" "<mimetype>application/vnd.visio</mimetype>\n" "<filetypename>" N_("Microsoft Visio XML Diagram (*.vdx)") "</filetypename>\n" "<filetypetooltip>" N_("File format used by Microsoft Visio 2010 and later") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new VsdInput()); /* VSDM */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("VSDM Input") "</name>\n" "<id>org.inkscape.input.vsdm</id>\n" "<input>\n" "<extension>.vsdm</extension>\n" "<mimetype>application/vnd.visio</mimetype>\n" "<filetypename>" N_("Microsoft Visio 2013 drawing (*.vsdm)") "</filetypename>\n" "<filetypetooltip>" N_("File format used by Microsoft Visio 2013 and later") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new VsdInput()); /* VSDX */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("VSDX Input") "</name>\n" "<id>org.inkscape.input.vsdx</id>\n" "<input>\n" "<extension>.vsdx</extension>\n" "<mimetype>application/vnd.visio</mimetype>\n" "<filetypename>" N_("Microsoft Visio 2013 drawing (*.vsdx)") "</filetypename>\n" "<filetypetooltip>" N_("File format used by Microsoft Visio 2013 and later") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new VsdInput()); return; } // init
SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { RVNGFileStream input(uri); if (!libcdr::CDRDocument::isSupported(&input)) { return NULL; } RVNGStringVector output; #if WITH_LIBCDR01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libcdr::CDRDocument::parse(&input, &generator)) { #else if (!libcdr::CDRDocument::generateSVG(&input, output)) { #endif return NULL; } if (output.empty()) { return NULL; } std::vector<RVNGString> tmpSVGOutput; for (unsigned i=0; i<output.size(); ++i) { RVNGString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } unsigned page_num = 1; // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { CdrImportDialog *dlg = 0; if (inkscape_use_gui()) { dlg = new CdrImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; return NULL; } } // Get needed page if (dlg) { page_num = dlg->getSelectedPage(); if (page_num < 1) page_num = 1; if (page_num > tmpSVGOutput.size()) page_num = tmpSVGOutput.size(); } } SPDocument * doc = SPDocument::createNewDocFromMem(tmpSVGOutput[page_num-1].cstr(), strlen(tmpSVGOutput[page_num-1].cstr()), TRUE); // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); } return doc; } #include "clear-n_.h" void CdrInput::init(void) { /* CDR */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Corel DRAW Input") "</name>\n" "<id>org.inkscape.input.cdr</id>\n" "<input>\n" "<extension>.cdr</extension>\n" "<mimetype>image/x-xcdr</mimetype>\n" "<filetypename>" N_("Corel DRAW 7-X4 files (*.cdr)") "</filetypename>\n" "<filetypetooltip>" N_("Open files saved in Corel DRAW 7-X4") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new CdrInput()); /* CDT */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Corel DRAW templates input") "</name>\n" "<id>org.inkscape.input.cdt</id>\n" "<input>\n" "<extension>.cdt</extension>\n" "<mimetype>application/x-xcdt</mimetype>\n" "<filetypename>" N_("Corel DRAW 7-13 template files (*.cdt)") "</filetypename>\n" "<filetypetooltip>" N_("Open files saved in Corel DRAW 7-13") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new CdrInput()); /* CCX */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Corel DRAW Compressed Exchange files input") "</name>\n" "<id>org.inkscape.input.ccx</id>\n" "<input>\n" "<extension>.ccx</extension>\n" "<mimetype>application/x-xccx</mimetype>\n" "<filetypename>" N_("Corel DRAW Compressed Exchange files (*.ccx)") "</filetypename>\n" "<filetypetooltip>" N_("Open compressed exchange files saved in Corel DRAW") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new CdrInput()); /* CMX */ Inkscape::Extension::build_from_mem( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("Corel DRAW Presentation Exchange files input") "</name>\n" "<id>org.inkscape.input.cmx</id>\n" "<input>\n" "<extension>.cmx</extension>\n" "<mimetype>application/x-xcmx</mimetype>\n" "<filetypename>" N_("Corel DRAW Presentation Exchange files (*.cmx)") "</filetypename>\n" "<filetypetooltip>" N_("Open presentation exchange files saved in Corel DRAW") "</filetypetooltip>\n" "</input>\n" "</inkscape-extension>", new CdrInput()); return; } // init