summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxo Arraiza Cenoz <jtx@jtx.markerlab.es>2018-05-04 14:37:02 +0000
committerJabiertxo Arraiza Cenoz <jtx@jtx.markerlab.es>2018-05-10 16:46:08 +0000
commit21abf74176d6a2db53a274f13421b84ee17714e7 (patch)
tree591bfa96068a2c6b5b02224f49023d6ce3a5b3f4 /src
parentImprove sort handling in XML (diff)
downloadinkscape-21abf74176d6a2db53a274f13421b84ee17714e7.tar.gz
inkscape-21abf74176d6a2db53a274f13421b84ee17714e7.zip
Allow link a SVG as image
Diffstat (limited to 'src')
-rw-r--r--src/display/cairo-utils.cpp96
-rw-r--r--src/extension/internal/svg.cpp105
-rw-r--r--src/object/sp-lpe-item.cpp13
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp2
-rw-r--r--src/verbs.cpp5
5 files changed, 190 insertions, 31 deletions
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp
index 82373c27c..29e542b01 100644
--- a/src/display/cairo-utils.cpp
+++ b/src/display/cairo-utils.cpp
@@ -28,11 +28,17 @@
#include <2geom/transforms.h>
#include <2geom/sbasis-to-bezier.h>
+#include <boost/algorithm/string.hpp>
#include <boost/operators.hpp>
#include <boost/optional/optional.hpp>
#include "color.h"
#include "cairo-templates.h"
+#include "document.h"
+#include "preferences.h"
+#include "util/units.h"
+#include "helper/pixbuf-ops.h"
+
/**
* Key for cairo_surface_t to keep track of current color interpolation value
@@ -312,37 +318,81 @@ Pixbuf *Pixbuf::create_from_file(std::string const &fn)
std::cerr << " (" << fn << ")" << std::endl;
return NULL;
}
-
- GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
- gdk_pixbuf_loader_write(loader, (guchar *) data, len, &error);
- if (error != NULL) {
- std::cerr << "Pixbuf::create_from_file: " << error->message << std::endl;
- std::cerr << " (" << fn << ")" << std::endl;
- g_free(data);
- g_object_unref(loader);
- return NULL;
+ GdkPixbuf *buf = NULL;
+ GdkPixbufLoader *loader = NULL;
+ std::string::size_type idx;
+ idx = fn.rfind('.');
+ bool is_svg = false;
+ if(idx != std::string::npos)
+ {
+ if (boost::iequals(fn.substr(idx+1).c_str(), "svg")) {
+ SPDocument *svgDoc = SPDocument::createNewDoc(fn.c_str(), TRUE);
+ // Check the document loaded properly
+ if (svgDoc == NULL) {
+ return NULL;
+ }
+ if (svgDoc->getRoot() == NULL)
+ {
+ svgDoc->doUnref();
+ return NULL;
+ }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ const double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0);
+ // Get the size of the document
+ Inkscape::Util::Quantity svgWidth = svgDoc->getWidth();
+ Inkscape::Util::Quantity svgHeight = svgDoc->getHeight();
+ const double svgWidth_px = svgWidth.value("px");
+ const double svgHeight_px = svgHeight.value("px");
+
+ // Now get the resized values
+ const int scaledSvgWidth = round(svgWidth_px/(96.0/dpi));
+ const int scaledSvgHeight = round(svgHeight_px/(96.0/dpi));
+
+ buf = sp_generate_internal_bitmap(svgDoc, NULL, 0, 0, svgWidth_px, svgHeight_px, scaledSvgWidth, scaledSvgHeight, dpi, dpi, (guint32) 0xffffff00, NULL)->getPixbufRaw();
+
+ // Tidy up
+ svgDoc->doUnref();
+ if (buf == NULL) {
+ return NULL;
+ }
+ is_svg = true;
+ }
}
+ if (!is_svg) {
+ loader = gdk_pixbuf_loader_new();
+ gdk_pixbuf_loader_write(loader, (guchar *) data, len, &error);
+ if (error != NULL) {
+ std::cerr << "Pixbuf::create_from_file: " << error->message << std::endl;
+ std::cerr << " (" << fn << ")" << std::endl;
+ g_free(data);
+ g_object_unref(loader);
+ return NULL;
+ }
- gdk_pixbuf_loader_close(loader, &error);
- if (error != NULL) {
- std::cerr << "Pixbuf::create_from_file: " << error->message << std::endl;
- std::cerr << " (" << fn << ")" << std::endl;
- g_free(data);
- g_object_unref(loader);
- return NULL;
+ gdk_pixbuf_loader_close(loader, &error);
+ if (error != NULL) {
+ std::cerr << "Pixbuf::create_from_file: " << error->message << std::endl;
+ std::cerr << " (" << fn << ")" << std::endl;
+ g_free(data);
+ g_object_unref(loader);
+ return NULL;
+ }
+
+ buf = gdk_pixbuf_loader_get_pixbuf(loader);
}
-
- GdkPixbuf *buf = gdk_pixbuf_loader_get_pixbuf(loader);
if (buf) {
g_object_ref(buf);
pb = new Pixbuf(buf);
pb->_mod_time = stdir.st_mtime;
pb->_path = fn;
-
- GdkPixbufFormat *fmt = gdk_pixbuf_loader_get_format(loader);
- gchar *fmt_name = gdk_pixbuf_format_get_name(fmt);
- pb->_setMimeData((guchar *) data, len, fmt_name);
- g_free(fmt_name);
+ if (!is_svg) {
+ GdkPixbufFormat *fmt = gdk_pixbuf_loader_get_format(loader);
+ gchar *fmt_name = gdk_pixbuf_format_get_name(fmt);
+ pb->_setMimeData((guchar *) data, len, fmt_name);
+ g_free(fmt_name);
+ } else {
+ pb->_setMimeData((guchar *) data, len, "svg");
+ }
} else {
std::cerr << "Pixbuf::create_from_file: failed to load contents: " << fn << std::endl;
g_free(data);
diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp
index 7bf4f34e6..27a1efef0 100644
--- a/src/extension/internal/svg.cpp
+++ b/src/extension/internal/svg.cpp
@@ -18,17 +18,32 @@
# include <config.h>
#endif
+#include <gtkmm.h>
+
+#include <giomm/file.h>
#include <vector>
#include <giomm/file.h>
-
+#include "document.h"
+#include "inkscape.h"
+#include "preferences.h"
+#include "extension/output.h"
+#include "extension/system.h"
+#include "file.h"
#include "svg.h"
#include "file.h"
#include "extension/system.h"
#include "extension/output.h"
#include "xml/attribute-record.h"
#include "xml/simple-document.h"
-#include "document.h"
+
+#include "object/sp-namedview.h"
+#include "object/sp-root.h"
+#include "util/units.h"
+#include "selection-chemistry.h"
+
+// TODO due to internal breakage in glibmm headers, this must be last:
+#include <glibmm/i18n.h>
namespace Inkscape {
namespace Extension {
@@ -173,7 +188,93 @@ Svg::open (Inkscape::Extension::Input */*mod*/, const gchar *uri)
{
auto file = Gio::File::create_for_uri(uri);
const auto path = file->get_path();
+ bool link = false;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool is_import = false;
+ if (strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") == 0) {
+ is_import = true;
+ }
+ if (INKSCAPE.use_gui() && is_import) {
+ Gtk::Dialog svg_open_dialog(_("Select how to import your SVG"));
+ svg_open_dialog.set_transient_for( *(INKSCAPE.active_desktop()->getToplevel()) );
+ svg_open_dialog.set_border_width(10);
+ svg_open_dialog.set_resizable(false);
+ Gtk::Label explanation;
+ explanation.set_markup(Glib::ustring("How you want the SVG become imported?"));
+ explanation.set_line_wrap(true);
+ explanation.set_size_request(600,-1);
+ Gtk::RadioButton::Group c1, c2;
+ Gtk::Label choice1_label;
+ choice1_label.set_markup(
+ _("The SVG is incrusted inside document, you could edit it"));
+ Gtk::RadioButton choice1(c1);
+ choice1.add(choice1_label);
+ Gtk::RadioButton choice2(c1, _("The SVG is linked from outside document as a image, you can edit only original file"));
+ Gtk::Box *content = svg_open_dialog.get_content_area();
+ content->pack_start(explanation, false, false, 5);
+ content->pack_start(choice1, false, false, 5);
+ content->pack_start(choice2, false, false, 5);
+ Gtk::Button *ok_button = svg_open_dialog.add_button(_("OK"), GTK_RESPONSE_ACCEPT);
+ svg_open_dialog.show_all_children();
+ ok_button->grab_focus();
+ int status = svg_open_dialog.run();
+ if ( status == GTK_RESPONSE_ACCEPT ) {
+ link = choice2.get_active();
+ }
+ }
+
+ SPDocument * doc = SPDocument::createNewDoc (NULL, TRUE, TRUE);
+ if (link) {
+
+ SPDocument * ret = SPDocument::createNewDoc(uri, TRUE);
+ SPNamedView *nv = sp_document_namedview(doc, NULL);
+ Glib::ustring display_unit = nv->display_units->abbr;
+ if (display_unit.empty()) {
+ display_unit = "px";
+ }
+ double width = ret->getWidth().value(display_unit);
+ double height = ret->getHeight().value(display_unit);
+ // Create image node
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image");
+
+ // Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is
+ // what Inkscaper's expect.
+ image_node->setAttribute("preserveAspectRatio", "none");
+ image_node->setAttribute("width", Glib::ustring::format(width));
+ image_node->setAttribute("height", Glib::ustring::format(height));
+ Glib::ustring scale = prefs->getString("/dialogs/import/scale");
+ 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 );
+ }
+ // 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
+ Inkscape::XML::Node *layer_node = xml_doc->createElement("svg:g");
+ layer_node->setAttribute("inkscape:groupmode", "layer");
+ layer_node->setAttribute("inkscape:label", "Image");
+ doc->getRoot()->appendChildRepr(layer_node);
+ layer_node->appendChild(image_node);
+ Inkscape::GC::release(image_node);
+ Inkscape::GC::release(layer_node);
+ fit_canvas_to_drawing(doc);
+
+ // Set viewBox if it doesn't exist
+ if (!doc->getRoot()->viewBox_set) {
+ doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit())));
+ }
+ return doc;
+ }
if (!file->get_uri_scheme().empty()) {
if (path.empty()) {
try {
diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp
index c7c925c55..98c99e3ae 100644
--- a/src/object/sp-lpe-item.cpp
+++ b/src/object/sp-lpe-item.cpp
@@ -391,7 +391,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths,
std::vector<SPObject*> clip_path_list = clip_path->childList(true);
for ( std::vector<SPObject*>::const_iterator iter=clip_path_list.begin();iter!=clip_path_list.end();++iter) {
SPLPEItem* clip_data = dynamic_cast<SPLPEItem*>(*iter);
- sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, lpeitem && !lpeitem->hasPathEffectRecursive(), true);
+ if (clip_data) {
+ sp_lpe_item_cleanup_original_path_recursive(clip_data, keep_paths, lpeitem && !lpeitem->hasPathEffectRecursive(), true);
+ }
}
}
@@ -400,7 +402,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths,
std::vector<SPObject*> mask_path_list = mask_path->childList(true);
for ( std::vector<SPObject*>::const_iterator iter = mask_path_list.begin(); iter != mask_path_list.end();++iter) {
SPLPEItem* mask_data = dynamic_cast<SPLPEItem*>(*iter);
- sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, lpeitem && !lpeitem->hasPathEffectRecursive(), true);
+ if (mask_data) {
+ sp_lpe_item_cleanup_original_path_recursive(mask_data, keep_paths, lpeitem && !lpeitem->hasPathEffectRecursive(), true);
+ }
}
}
@@ -408,8 +412,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths,
std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
for ( std::vector<SPItem*>::const_iterator iter=item_list.begin();iter!=item_list.end();++iter) {
SPLPEItem* subitem = dynamic_cast<SPLPEItem*>(*iter);
- sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths);
-
+ if (subitem) {
+ sp_lpe_item_cleanup_original_path_recursive(subitem, keep_paths);
+ }
}
} else if (path) {
Inkscape::XML::Node *repr = lpeitem->getRepr();
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 96c446d0c..18b38c68d 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -1570,7 +1570,7 @@ void InkscapePreferences::initPageBitmaps()
/* Note: /dialogs/import/quality removed use of in r12542 */
_importexport_import_res.init("/dialogs/import/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, Inkscape::Util::Quantity::convert(1, "in", "px"), true, false);
_page_bitmaps.add_line( false, _("Default _import resolution:"), _importexport_import_res, _("dpi"),
- _("Default bitmap resolution (in dots per inch) for bitmap import"), false);
+ _("Default bitmap resolution (in dots per inch) for bitmap and SVG import"), false);
_importexport_import_res_override.init(_("Override file resolution"), "/dialogs/import/forcexdpi", false);
_page_bitmaps.add_line( false, "", _importexport_import_res_override, "",
_("Use default bitmap resolution in favor of information from file"));
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 0c51c5314..4ac94ec1b 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -877,7 +877,7 @@ void FileVerb::perform(SPAction *action, void *data)
if (handled) {
return;
}
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
g_return_if_fail(ensure_desktop_valid(action));
SPDesktop *desktop = sp_action_get_desktop(action);
@@ -889,6 +889,7 @@ void FileVerb::perform(SPAction *action, void *data)
sp_file_new_default();
break;
case SP_VERB_FILE_OPEN:
+ prefs->setString("/options/openmethod/value", "open");
sp_file_open_dialog(*parent, NULL, NULL);
break;
case SP_VERB_FILE_REVERT:
@@ -910,12 +911,14 @@ void FileVerb::perform(SPAction *action, void *data)
sp_file_print(*parent);
break;
case SP_VERB_FILE_IMPORT:
+ prefs->setString("/options/openmethod/value","import");
sp_file_import(*parent);
break;
// case SP_VERB_FILE_EXPORT:
// sp_file_export_dialog(*parent);
// break;
case SP_VERB_FILE_IMPORT_FROM_OCAL:
+ prefs->setString("/options/openmethod/value", "ocal");
sp_file_import_from_ocal(*parent);
break;
// case SP_VERB_FILE_EXPORT_TO_OCAL: