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 if (exportId && strcmp(exportId, "")) {
67 // we want to export the given item only, not page
68 mod->base = SP_ITEM(doc->getObjectById(exportId));
69 mod->set_param_bool("pageBoundingBox", FALSE);
70 } else {
71 // we want to export the entire document from root
72 mod->base = SP_ITEM(sp_document_root(doc));
73 if (exportDrawing)
74 mod->set_param_bool("pageBoundingBox", FALSE);
75 else
76 mod->set_param_bool("pageBoundingBox", TRUE);
77 }
78 mod->arena = NRArena::create();
79 mod->dkey = sp_item_display_key_new(1);
80 mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
82 /* Print document */
83 ret = mod->begin(doc);
84 if (ret) {
85 sp_item_invoke_print(mod->base, &context);
86 ret = mod->finish();
87 }
89 /* Release arena */
90 sp_item_invoke_hide(mod->base, mod->dkey);
91 mod->base = NULL;
92 nr_arena_item_unref(mod->root);
93 mod->root = NULL;
94 nr_object_unref((NRObject *) mod->arena);
95 mod->arena = NULL;
96 /* end */
98 mod->set_param_string("destination", oldoutput);
99 g_free(oldoutput);
101 return ret;
102 }
105 /**
106 \brief This function calls the print system with the filename
107 \param mod unused
108 \param doc Document to be saved
109 \param uri Filename to save to (probably will end in .pdf)
111 The most interesting thing that this function does is just attach
112 an '>' on the front of the filename. This is the syntax used to
113 tell the printing system to save to file.
114 */
115 void
116 CairoPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
117 {
118 Inkscape::Extension::Extension * ext;
119 unsigned int ret;
121 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF);
122 if (ext == NULL)
123 return;
125 bool old_textToPath = FALSE;
126 bool new_textToPath = FALSE;
127 try {
128 old_textToPath = ext->get_param_bool("textToPath");
129 new_textToPath = mod->get_param_bool("textToPath");
130 ext->set_param_bool("textToPath", new_textToPath);
131 }
132 catch(...) {
133 g_warning("Parameter <textToPath> might not exist");
134 }
136 bool old_blurToBitmap = FALSE;
137 bool new_blurToBitmap = FALSE;
138 try {
139 old_blurToBitmap = ext->get_param_bool("blurToBitmap");
140 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
141 ext->set_param_bool("blurToBitmap", new_blurToBitmap);
142 }
143 catch(...) {
144 g_warning("Parameter <blurToBitmap> might not exist");
145 }
147 const gchar* old_exportId = NULL;
148 const gchar* new_exportId = NULL;
149 try {
150 old_exportId = ext->get_param_string("exportId");
151 new_exportId = mod->get_param_string("exportId");
152 ext->set_param_string("exportId", new_exportId);
153 }
154 catch(...) {
155 g_warning("Parameter <exportId> might not exist");
156 }
158 bool old_exportDrawing = NULL;
159 bool new_exportDrawing = NULL;
160 try {
161 old_exportDrawing = ext->get_param_bool("exportDrawing");
162 new_exportDrawing = mod->get_param_bool("exportDrawing");
163 ext->set_param_bool("exportDrawing", new_exportDrawing);
164 }
165 catch(...) {
166 g_warning("Parameter <exportDrawing> might not exist");
167 }
169 gchar * final_name;
170 final_name = g_strdup_printf("> %s", uri);
171 ret = pdf_print_document_to_file(doc, final_name, 0, new_textToPath, new_blurToBitmap);
172 g_free(final_name);
174 try {
175 ext->set_param_bool("blurToBitmap", old_blurToBitmap);
176 }
177 catch(...) {
178 g_warning("Parameter <blurToBitmap> might not exist");
179 }
180 try {
181 ext->set_param_bool("textToPath", old_textToPath);
182 }
183 catch(...) {
184 g_warning("Parameter <textToPath> might not exist");
185 }
186 try {
187 ext->set_param_string("exportId", old_exportId);
188 }
189 catch(...) {
190 g_warning("Parameter <exportId> might not exist");
191 }
192 try {
193 ext->set_param_bool("exportDrawing", old_exportDrawing);
194 }
195 catch(...) {
196 g_warning("Parameter <exportDrawing> might not exist");
197 }
199 if (!ret)
200 throw Inkscape::Extension::Output::save_failed();
202 return;
203 }
205 #include "clear-n_.h"
206 /**
207 \brief A function allocate a copy of this function.
209 This is the definition of PDF out. This function just
210 calls the extension system with the memory allocated XML that
211 describes the data.
212 */
213 void
214 CairoPdfOutput::init (void)
215 {
216 Inkscape::Extension::build_from_mem(
217 "<inkscape-extension>\n"
218 "<name>" N_("Cairo PDF Output") "</name>\n"
219 "<id>org.inkscape.output.pdf.cairo</id>\n"
220 "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
221 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
222 "</param>\n"
223 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
224 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n"
225 "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n"
226 "<param name=\"exportDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n"
227 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
228 "<output>\n"
229 "<extension>.pdf</extension>\n"
230 "<mimetype>application/pdf</mimetype>\n"
231 "<filetypename>" N_("PDF via Cairo (*.pdf)") "</filetypename>\n"
232 "<filetypetooltip>" N_("PDF File") "</filetypetooltip>\n"
233 "</output>\n"
234 "</inkscape-extension>", new CairoPdfOutput());
236 return;
237 }
239 } } } /* namespace Inkscape, Extension, Implementation */
241 #endif /* HAVE_CAIRO_PDF */