Code

A simple layout document as to what, why and how is cppification.
[inkscape.git] / src / extension / internal / gdkpixbuf-input.cpp
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 #include <glib/gprintf.h>
5 #include "document-private.h"
6 #include <dir-util.h>
7 #include "extension/input.h"
8 #include "extension/system.h"
9 #include "gdkpixbuf-input.h"
10 #include "selection-chemistry.h"
11 #include "sp-image.h"
13 namespace Inkscape {
15 namespace IO {
16 GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error );
17 }
19 namespace Extension {
20 namespace Internal {
22 static std::set<Glib::ustring> create_lossy_set()
23 {
24     std::set<Glib::ustring> lossy;
25     lossy.insert(".jpg");
26     lossy.insert(".jpeg");
27     return lossy;
28 }
30 SPDocument *
31 GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
32 {
33     bool embed = (strcmp(mod->get_param_optiongroup("link"), "embed") == 0);
35     SPDocument *doc = NULL;
36     GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL );
37     static std::set<Glib::ustring> lossy = create_lossy_set();
39     if (pb) {         /* We are readable */
40         bool is_lossy;
41         Glib::ustring mime_type, ext;
42         Glib::ustring u = uri;
43         std::size_t dotpos = u.rfind('.');
44         if (dotpos != Glib::ustring::npos) {
45             ext = u.substr(dotpos, Glib::ustring::npos);
46         }
48         // HACK: replace with something better based on GIO
49         if (!ext.empty() && lossy.find(ext) != lossy.end()) {
50             is_lossy = true;
51             mime_type = "image/jpeg";
52         } else {
53             is_lossy = false;
54             mime_type = "image/png";
55         }
57         doc = SPDocument::createNewDoc(NULL, TRUE, TRUE);
58         bool saved = SPDocumentUndo::get_undo_sensitive(doc);
59                 SPDocumentUndo::set_undo_sensitive(doc, false); // no need to undo in this temporary document
61         double width = gdk_pixbuf_get_width(pb);
62         double height = gdk_pixbuf_get_height(pb);
63         gchar const *str = gdk_pixbuf_get_option( pb, "Inkscape::DpiX" );
64         if ( str ) {
65             gint dpi = atoi(str);
66             if ( dpi > 0 && dpi != 72 ) {
67                 double scale = 72.0 / (double)dpi;
68                 width *= scale;
69             }
70         }
71         str = gdk_pixbuf_get_option( pb, "Inkscape::DpiY" );
72         if ( str ) {
73             gint dpi = atoi(str);
74             if ( dpi > 0 && dpi != 72 ) {
75                 double scale = 72.0 / (double)dpi;
76                 height *= scale;
77             }
78         }
80         // Create image node
81         Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
82         Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image");
83         sp_repr_set_svg_double(image_node, "width", width);
84         sp_repr_set_svg_double(image_node, "height", height);
86         if (embed) {
87             sp_embed_image(image_node, pb, mime_type);
88         } else {
89             // convert filename to uri
90             gchar* _uri = g_filename_to_uri(uri, NULL, NULL);
91             if(_uri) {
92                 image_node->setAttribute("xlink:href", _uri);
93                 g_free(_uri);
94             } else {
95                 image_node->setAttribute("xlink:href", uri);
96             }
97         }
99         g_object_unref(pb);
101         // Add it to the current layer
102         SP_DOCUMENT_ROOT(doc)->appendChildRepr(image_node);
103         Inkscape::GC::release(image_node);
104         fit_canvas_to_drawing(doc);
105         // restore undo, as now this document may be shown to the user if a bitmap was opened
106                 SPDocumentUndo::set_undo_sensitive(doc, saved);
107     } else {
108         printf("GdkPixbuf loader failed\n");
109     }
111     return doc;
114 #include "clear-n_.h"
116 void
117 GdkpixbufInput::init(void)
119     GSList * formatlist, * formatlisthead;
121     /* \todo I'm not sure if I need to free this list */
122     for (formatlist = formatlisthead = gdk_pixbuf_get_formats();
123          formatlist != NULL;
124          formatlist = g_slist_next(formatlist)) {
126         GdkPixbufFormat *pixformat = (GdkPixbufFormat *)formatlist->data;
128         gchar *name =        gdk_pixbuf_format_get_name(pixformat);
129         gchar *description = gdk_pixbuf_format_get_description(pixformat);
130         gchar **extensions =  gdk_pixbuf_format_get_extensions(pixformat);
131         gchar **mimetypes =   gdk_pixbuf_format_get_mime_types(pixformat);
133         for (int i = 0; extensions[i] != NULL; i++) {
134         for (int j = 0; mimetypes[j] != NULL; j++) {
136             /* thanks but no thanks, we'll handle SVG extensions... */
137             if (strcmp(extensions[i], "svg") == 0) {
138                 continue;
139             }
140             if (strcmp(extensions[i], "svgz") == 0) {
141                 continue;
142             }
143             if (strcmp(extensions[i], "svg.gz") == 0) {
144                 continue;
145             }
147             gchar *xmlString = g_strdup_printf(
148                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
149                     "<name>" N_("%s GDK pixbuf Input") "</name>\n"
150                     "<id>org.inkscape.input.gdkpixbuf.%s</id>\n"
151                     "<param name='link' type='optiongroup'  appearance='full' _gui-text='" N_("Link or embed image:") "' >\n"
152                         "<_option value='embed'>" N_("embed") "</_option>\n"
153                         "<_option value='link'>" N_("link") "</_option>\n"
154                     "</param>\n"
155                     "<_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"
156                     "<input>\n"
157                         "<extension>.%s</extension>\n"
158                         "<mimetype>%s</mimetype>\n"
159                         "<filetypename>%s (*.%s)</filetypename>\n"
160                         "<filetypetooltip>%s</filetypetooltip>\n"
161                     "</input>\n"
162                 "</inkscape-extension>",
163                 name,
164                 extensions[i],
165                 extensions[i],
166                 mimetypes[j],
167                 name,
168                 extensions[i],
169                 description
170                 );
172             Inkscape::Extension::build_from_mem(xmlString, new GdkpixbufInput());
173             g_free(xmlString);
174         }}
176         g_free(name);
177         g_free(description);
178         g_strfreev(mimetypes);
179         g_strfreev(extensions);
180     }
182     g_slist_free(formatlisthead);
185 } } }  /* namespace Inkscape, Extension, Implementation */
187 /*
188   Local Variables:
189   mode:c++
190   c-file-style:"stroustrup"
191   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
192   indent-tabs-mode:nil
193   fill-column:99
194   End:
195 */
196 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :