Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / extension / internal / gdkpixbuf-input.cpp
index 4a46b146df2979da59dfac0b752d79fc9e723c6f..c3a30a2f002f072dcc1ed128a2274d1058b7857a 100644 (file)
@@ -1,12 +1,15 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
+#include <glib/gprintf.h>
+#include <glibmm/i18n.h>
 #include "document-private.h"
 #include <dir-util.h>
-#include "prefs-utils.h"
+#include "extension/input.h"
 #include "extension/system.h"
 #include "gdkpixbuf-input.h"
 #include "selection-chemistry.h"
+#include "sp-image.h"
 
 namespace Inkscape {
 
@@ -17,82 +20,91 @@ GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error );
 namespace Extension {
 namespace Internal {
 
+static std::set<Glib::ustring> create_lossy_set()
+{
+    std::set<Glib::ustring> lossy;
+    lossy.insert(".jpg");
+    lossy.insert(".jpeg");
+    return lossy;
+}
+
 SPDocument *
 GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
 {
-    SPDocument *doc = sp_document_new(NULL, TRUE, TRUE);
-    bool saved = sp_document_get_undo_sensitive(doc);
-    sp_document_set_undo_sensitive(doc, false); // no need to undo in this temporary document
+    bool embed = (strcmp(mod->get_param_optiongroup("link"), "embed") == 0);
+
+    SPDocument *doc = NULL;
     GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL );
+    static std::set<Glib::ustring> lossy = create_lossy_set();
 
     if (pb) {         /* We are readable */
-        Inkscape::XML::Node *repr = NULL;
+        bool is_lossy;
+        Glib::ustring mime_type, ext;
+        Glib::ustring u = uri;
+        std::size_t dotpos = u.rfind('.');
+        if (dotpos != Glib::ustring::npos) {
+            ext = u.substr(dotpos, Glib::ustring::npos);
+        }
+
+        // HACK: replace with something better based on GIO
+        if (!ext.empty() && lossy.find(ext) != lossy.end()) {
+            is_lossy = true;
+            mime_type = "image/jpeg";
+        } else {
+            is_lossy = false;
+            mime_type = "image/png";
+        }
+
+        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 = gdk_pixbuf_get_width(pb);
         double height = gdk_pixbuf_get_height(pb);
         gchar const *str = gdk_pixbuf_get_option( pb, "Inkscape::DpiX" );
-        if ( str )
-        {
+        if ( str ) {
             gint dpi = atoi(str);
-            if ( dpi > 0 && dpi != 72 )
-            {
+            if ( dpi > 0 && dpi != 72 ) {
                 double scale = 72.0 / (double)dpi;
                 width *= scale;
             }
         }
         str = gdk_pixbuf_get_option( pb, "Inkscape::DpiY" );
-        if ( str )
-        {
+        if ( str ) {
             gint dpi = atoi(str);
-            if ( dpi > 0 && dpi != 72 )
-            {
+            if ( dpi > 0 && dpi != 72 ) {
                 double scale = 72.0 / (double)dpi;
                 height *= scale;
             }
         }
 
-        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
-        if (prefs_get_int_attribute("options.importbitmapsasimages", "value", 1) == 1) {
-            // import as <image>
-            repr = xml_doc->createElement("svg:image");
-            // both are the same, as we don't know our base dir here and cannot relativate href (importer will fixupHrefs):
-            repr->setAttribute("xlink:href", uri); 
-            repr->setAttribute("sodipodi:absref", uri); 
-
-            sp_repr_set_svg_double(repr, "width", width);
-            sp_repr_set_svg_double(repr, "height", height);
+        // 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);
 
+        if (embed) {
+            sp_embed_image(image_node, pb, mime_type);
         } else {
-            // import as pattern-filled rect
-            Inkscape::XML::Node *pat = xml_doc->createElement("svg:pattern");
-            pat->setAttribute("inkscape:collect", "always");
-            pat->setAttribute("patternUnits", "userSpaceOnUse");
-            sp_repr_set_svg_double(pat, "width", width);
-            sp_repr_set_svg_double(pat, "height", height);
-            SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->appendChild(pat);
-            gchar const *pat_id = pat->attribute("id");
-            SPObject *pat_object = doc->getObjectById(pat_id);
-
-            Inkscape::XML::Node *im = xml_doc->createElement("svg:image");
-            im->setAttribute("xlink:href", uri);
-            im->setAttribute("sodipodi:absref", uri);
-            sp_repr_set_svg_double(im, "width", width);
-            sp_repr_set_svg_double(im, "height", height);
-            SP_OBJECT_REPR(pat_object)->addChild(im, NULL);
-
-            repr = xml_doc->createElement("svg:rect");
-            repr->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id));
-            sp_repr_set_svg_double(repr, "width", width);
-            sp_repr_set_svg_double(repr, "height", height);
+            // 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);
+            }
         }
 
-        SP_DOCUMENT_ROOT(doc)->appendChildRepr(repr);
-        Inkscape::GC::release(repr);
-        gdk_pixbuf_unref(pb);
-        //alter the canvas size to fit the image size
+        g_object_unref(pb);
+
+        // Add it to the current layer
+        doc->getRoot()->appendChildRepr(image_node);
+        Inkscape::GC::release(image_node);
         fit_canvas_to_drawing(doc);
         // restore undo, as now this document may be shown to the user if a bitmap was opened
-        sp_document_set_undo_sensitive(doc, saved);
+        DocumentUndo::setUndoSensitive(doc, saved);
     } else {
         printf("GdkPixbuf loader failed\n");
     }
@@ -132,11 +144,16 @@ GdkpixbufInput::init(void)
             if (strcmp(extensions[i], "svg.gz") == 0) {
                 continue;
             }
-
+            gchar *caption = g_strdup_printf(_("%s GDK pixbuf Input"), name);
             gchar *xmlString = g_strdup_printf(
-                "<inkscape-extension>\n"
-                    "<name>" N_("%s GDK pixbuf Input") "</name>\n"
+                "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+                    "<name>%s</name>\n"
                     "<id>org.inkscape.input.gdkpixbuf.%s</id>\n"
+                    "<param name='link' type='optiongroup'  appearance='full' _gui-text='" N_("Link or embed image:") "' >\n"
+                        "<_option value='embed'>" N_("embed") "</_option>\n"
+                        "<_option value='link'>" N_("link") "</_option>\n"
+                    "</param>\n"
+                    "<_param name='help' type='description'>" N_("Embed results in stand-alone, larger SVG files. Link references a file outside this SVG document and all files must be moved together.") "</_param>\n"
                     "<input>\n"
                         "<extension>.%s</extension>\n"
                         "<mimetype>%s</mimetype>\n"
@@ -144,7 +161,7 @@ GdkpixbufInput::init(void)
                         "<filetypetooltip>%s</filetypetooltip>\n"
                     "</input>\n"
                 "</inkscape-extension>",
-                name,
+                caption,
                 extensions[i],
                 extensions[i],
                 mimetypes[j],
@@ -155,6 +172,7 @@ GdkpixbufInput::init(void)
 
             Inkscape::Extension::build_from_mem(xmlString, new GdkpixbufInput());
             g_free(xmlString);
+            g_free(caption);
         }}
 
         g_free(name);
@@ -177,4 +195,4 @@ GdkpixbufInput::init(void)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :