1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 #include "document-private.h"
5 #include <dir-util.h>
6 #include "prefs-utils.h"
7 #include "extension/system.h"
8 #include "gdkpixbuf-input.h"
9 #include "selection-chemistry.h"
11 namespace Inkscape {
13 namespace IO {
14 GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error );
15 }
17 namespace Extension {
18 namespace Internal {
20 SPDocument *
21 GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
22 {
23 SPDocument *doc = sp_document_new(NULL, TRUE, TRUE);
24 bool saved = sp_document_get_undo_sensitive(doc);
25 sp_document_set_undo_sensitive(doc, false); // no need to undo in this temporary document
26 GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL );
27 Inkscape::XML::Node *rdoc = sp_document_repr_root(doc);
28 gchar const *docbase = rdoc->attribute("sodipodi:docbase");
29 gchar const *relname = sp_relative_path_from_path(uri, docbase);
31 if (pb) { /* We are readable */
32 Inkscape::XML::Node *repr = NULL;
34 double width = gdk_pixbuf_get_width(pb);
35 double height = gdk_pixbuf_get_height(pb);
36 gchar const *str = gdk_pixbuf_get_option( pb, "Inkscape::DpiX" );
37 if ( str )
38 {
39 gint dpi = atoi(str);
40 if ( dpi > 0 && dpi != 72 )
41 {
42 double scale = 72.0 / (double)dpi;
43 width *= scale;
44 }
45 }
46 str = gdk_pixbuf_get_option( pb, "Inkscape::DpiY" );
47 if ( str )
48 {
49 gint dpi = atoi(str);
50 if ( dpi > 0 && dpi != 72 )
51 {
52 double scale = 72.0 / (double)dpi;
53 height *= scale;
54 }
55 }
57 if (prefs_get_int_attribute("options.importbitmapsasimages", "value", 1) == 1) {
58 // import as <image>
59 repr = sp_repr_new("svg:image");
60 repr->setAttribute("xlink:href", relname);
61 repr->setAttribute("sodipodi:absref", uri);
63 sp_repr_set_svg_double(repr, "width", width);
64 sp_repr_set_svg_double(repr, "height", height);
66 } else {
67 // import as pattern-filled rect
68 Inkscape::XML::Node *pat = sp_repr_new("svg:pattern");
69 pat->setAttribute("inkscape:collect", "always");
70 pat->setAttribute("patternUnits", "userSpaceOnUse");
71 sp_repr_set_svg_double(pat, "width", width);
72 sp_repr_set_svg_double(pat, "height", height);
73 SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->appendChild(pat);
74 gchar const *pat_id = pat->attribute("id");
75 SPObject *pat_object = doc->getObjectById(pat_id);
77 Inkscape::XML::Node *im = sp_repr_new("svg:image");
78 im->setAttribute("xlink:href", relname);
79 im->setAttribute("sodipodi:absref", uri);
80 sp_repr_set_svg_double(im, "width", width);
81 sp_repr_set_svg_double(im, "height", height);
82 SP_OBJECT_REPR(pat_object)->addChild(im, NULL);
84 repr = sp_repr_new("svg:rect");
85 repr->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id));
86 sp_repr_set_svg_double(repr, "width", width);
87 sp_repr_set_svg_double(repr, "height", height);
88 }
90 SP_DOCUMENT_ROOT(doc)->appendChildRepr(repr);
91 Inkscape::GC::release(repr);
92 gdk_pixbuf_unref(pb);
93 //alter the canvas size to fit the image size
94 fit_canvas_to_drawing(doc);
95 // restore undo, as now this document may be shown to the user if a bitmap was opened
96 sp_document_set_undo_sensitive(doc, saved);
97 } else {
98 printf("GdkPixbuf loader failed\n");
99 }
101 return doc;
102 }
104 #include "clear-n_.h"
106 void
107 GdkpixbufInput::init(void)
108 {
109 GSList * formatlist, * formatlisthead;
111 /* \todo I'm not sure if I need to free this list */
112 for (formatlist = formatlisthead = gdk_pixbuf_get_formats();
113 formatlist != NULL;
114 formatlist = g_slist_next(formatlist)) {
116 GdkPixbufFormat *pixformat = (GdkPixbufFormat *)formatlist->data;
118 gchar *name = gdk_pixbuf_format_get_name(pixformat);
119 gchar *description = gdk_pixbuf_format_get_description(pixformat);
120 gchar **extensions = gdk_pixbuf_format_get_extensions(pixformat);
121 gchar **mimetypes = gdk_pixbuf_format_get_mime_types(pixformat);
123 for (int i = 0; extensions[i] != NULL; i++) {
124 for (int j = 0; mimetypes[j] != NULL; j++) {
126 /* thanks but no thanks, we'll handle SVG extensions... */
127 if (strcmp(extensions[i], "svg") == 0) {
128 continue;
129 }
130 if (strcmp(extensions[i], "svgz") == 0) {
131 continue;
132 }
133 if (strcmp(extensions[i], "svg.gz") == 0) {
134 continue;
135 }
137 gchar *xmlString = g_strdup_printf(
138 "<inkscape-extension>\n"
139 "<name>" N_("%s GDK pixbuf Input") "</name>\n"
140 "<id>org.inkscape.input.gdkpixbuf.%s</id>\n"
141 "<input>\n"
142 "<extension>.%s</extension>\n"
143 "<mimetype>%s</mimetype>\n"
144 "<filetypename>%s (*.%s)</filetypename>\n"
145 "<filetypetooltip>%s</filetypetooltip>\n"
146 "</input>\n"
147 "</inkscape-extension>",
148 name,
149 extensions[i],
150 extensions[i],
151 mimetypes[j],
152 name,
153 extensions[i],
154 description
155 );
157 Inkscape::Extension::build_from_mem(xmlString, new GdkpixbufInput());
158 g_free(xmlString);
159 }}
161 g_free(name);
162 g_free(description);
163 g_strfreev(mimetypes);
164 g_strfreev(extensions);
165 }
167 g_slist_free(formatlisthead);
168 }
170 } } } /* namespace Inkscape, Extension, Implementation */
172 /*
173 Local Variables:
174 mode:c++
175 c-file-style:"stroustrup"
176 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
177 indent-tabs-mode:nil
178 fill-column:99
179 End:
180 */
181 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :