1 /*
2 * A quick hack to use the print output to write out a file. This
3 * then makes 'save as...' PDF.
4 *
5 * Authors:
6 * Ted Gould <ted@gould.cx>
7 * Ulf Erikson <ulferikson@users.sf.net>
8 *
9 * Copyright (C) 2004-2006 Authors
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
18 #ifdef HAVE_CAIRO_PDF
20 #include "cairo-pdf-out.h"
21 #include <print.h>
22 #include "extension/system.h"
23 #include "extension/print.h"
24 #include "extension/db.h"
25 #include "extension/output.h"
26 #include "display/nr-arena.h"
27 #include "display/nr-arena-item.h"
28 #include "sp-path.h"
30 namespace Inkscape {
31 namespace Extension {
32 namespace Internal {
34 bool
35 CairoPdfOutput::check (Inkscape::Extension::Extension * module)
36 {
37 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF))
38 return FALSE;
40 return TRUE;
41 }
44 static unsigned int
45 pdf_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int pdf_level, bool texttopath, bool filtertobitmap)
46 {
47 Inkscape::Extension::Print *mod;
48 SPPrintContext context;
49 gchar const *oldconst;
50 gchar *oldoutput;
51 unsigned int ret;
53 sp_document_ensure_up_to_date(doc);
55 mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_CAIRO_PDF);
56 oldconst = mod->get_param_string("destination");
57 oldoutput = g_strdup(oldconst);
58 mod->set_param_string("destination", (gchar *)filename);
60 /* Start */
61 context.module = mod;
62 /* fixme: This has to go into module constructor somehow */
63 /* Create new arena */
64 const gchar* exportId = mod->get_param_string("exportId");
65 bool exportDrawing = mod->get_param_bool("exportDrawing");
66 bool exportCanvas = mod->get_param_bool("exportCanvas");
67 if (exportId && strcmp(exportId, "")) {
68 // we want to export the given item only
69 mod->base = SP_ITEM(doc->getObjectById(exportId));
70 if (exportCanvas)
71 mod->set_param_bool("pageBoundingBox", TRUE);
72 else
73 mod->set_param_bool("pageBoundingBox", FALSE);
74 } else {
75 // we want to export the entire document from root
76 mod->base = SP_ITEM(sp_document_root(doc));
77 if (exportDrawing)
78 mod->set_param_bool("pageBoundingBox", FALSE);
79 else
80 mod->set_param_bool("pageBoundingBox", TRUE);
81 }
82 mod->arena = NRArena::create();
83 mod->dkey = sp_item_display_key_new(1);
84 mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
86 /* Print document */
87 ret = mod->begin(doc);
88 if (ret) {
89 sp_item_invoke_print(mod->base, &context);
90 ret = mod->finish();
91 }
93 /* Release arena */
94 sp_item_invoke_hide(mod->base, mod->dkey);
95 mod->base = NULL;
96 mod->root = NULL;
97 nr_object_unref((NRObject *) mod->arena);
98 mod->arena = NULL;
99 /* end */
101 mod->set_param_string("destination", oldoutput);
102 g_free(oldoutput);
104 return ret;
105 }
108 /**
109 \brief This function calls the print system with the filename
110 \param mod unused
111 \param doc Document to be saved
112 \param uri Filename to save to (probably will end in .pdf)
114 The most interesting thing that this function does is just attach
115 an '>' on the front of the filename. This is the syntax used to
116 tell the printing system to save to file.
117 */
118 void
119 CairoPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
120 {
121 Inkscape::Extension::Extension * ext;
122 unsigned int ret;
124 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF);
125 if (ext == NULL)
126 return;
128 bool old_textToPath = FALSE;
129 bool new_textToPath = FALSE;
130 try {
131 old_textToPath = ext->get_param_bool("textToPath");
132 new_textToPath = mod->get_param_bool("textToPath");
133 ext->set_param_bool("textToPath", new_textToPath);
134 }
135 catch(...) {
136 g_warning("Parameter <textToPath> might not exist");
137 }
139 bool old_blurToBitmap = FALSE;
140 bool new_blurToBitmap = FALSE;
141 try {
142 old_blurToBitmap = ext->get_param_bool("blurToBitmap");
143 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
144 ext->set_param_bool("blurToBitmap", new_blurToBitmap);
145 }
146 catch(...) {
147 g_warning("Parameter <blurToBitmap> might not exist");
148 }
150 const gchar* old_exportId = NULL;
151 const gchar* new_exportId = NULL;
152 try {
153 old_exportId = ext->get_param_string("exportId");
154 new_exportId = mod->get_param_string("exportId");
155 ext->set_param_string("exportId", new_exportId);
156 }
157 catch(...) {
158 g_warning("Parameter <exportId> might not exist");
159 }
161 bool old_exportDrawing = false;
162 bool new_exportDrawing = false;
163 try {
164 old_exportDrawing = ext->get_param_bool("exportDrawing");
165 new_exportDrawing = mod->get_param_bool("exportDrawing");
166 ext->set_param_bool("exportDrawing", new_exportDrawing);
167 }
168 catch(...) {
169 g_warning("Parameter <exportDrawing> might not exist");
170 }
172 bool old_exportCanvas = false;
173 bool new_exportCanvas = false;
174 try {
175 old_exportCanvas = ext->get_param_bool("exportCanvas");
176 new_exportCanvas = mod->get_param_bool("exportCanvas");
177 ext->set_param_bool("exportCanvas", new_exportCanvas);
178 }
179 catch(...) {
180 g_warning("Parameter <exportCanvas> might not exist");
181 }
183 gchar * final_name;
184 final_name = g_strdup_printf("> %s", uri);
185 ret = pdf_print_document_to_file(doc, final_name, 0, new_textToPath, new_blurToBitmap);
186 g_free(final_name);
188 try {
189 ext->set_param_bool("blurToBitmap", old_blurToBitmap);
190 }
191 catch(...) {
192 g_warning("Parameter <blurToBitmap> might not exist");
193 }
194 try {
195 ext->set_param_bool("textToPath", old_textToPath);
196 }
197 catch(...) {
198 g_warning("Parameter <textToPath> might not exist");
199 }
200 try {
201 ext->set_param_string("exportId", old_exportId);
202 }
203 catch(...) {
204 g_warning("Parameter <exportId> might not exist");
205 }
206 try {
207 ext->set_param_bool("exportDrawing", old_exportDrawing);
208 }
209 catch(...) {
210 g_warning("Parameter <exportDrawing> might not exist");
211 }
212 try {
213 ext->set_param_bool("exportCanvas", old_exportCanvas);
214 }
215 catch(...) {
216 g_warning("Parameter <exportCanvas> might not exist");
217 }
219 if (!ret)
220 throw Inkscape::Extension::Output::save_failed();
222 return;
223 }
225 #include "clear-n_.h"
226 /**
227 \brief A function allocate a copy of this function.
229 This is the definition of PDF out. This function just
230 calls the extension system with the memory allocated XML that
231 describes the data.
232 */
233 void
234 CairoPdfOutput::init (void)
235 {
236 Inkscape::Extension::build_from_mem(
237 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
238 "<name>" N_("Cairo PDF Output") "</name>\n"
239 "<id>org.inkscape.output.pdf.cairo</id>\n"
240 "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
241 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
242 "</param>\n"
243 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
244 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n"
245 "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n"
246 "<param name=\"exportDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n"
247 "<param name=\"exportCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n"
248 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
249 "<output>\n"
250 "<extension>.pdf</extension>\n"
251 "<mimetype>application/pdf</mimetype>\n"
252 "<filetypename>" N_("PDF via Cairo (*.pdf)") "</filetypename>\n"
253 "<filetypetooltip>" N_("PDF File") "</filetypetooltip>\n"
254 "</output>\n"
255 "</inkscape-extension>", new CairoPdfOutput());
257 return;
258 }
260 } } } /* namespace Inkscape, Extension, Implementation */
262 #endif /* HAVE_CAIRO_PDF */
264 /*
265 Local Variables:
266 mode:c++
267 c-file-style:"stroustrup"
268 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
269 indent-tabs-mode:nil
270 fill-column:99
271 End:
272 */
273 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :