1 /*
2 * A quick hack to use the Cairo renderer to write out a file. This
3 * then makes 'save as...' PS.
4 *
5 * Authors:
6 * Ted Gould <ted@gould.cx>
7 * Ulf Erikson <ulferikson@users.sf.net>
8 * Adib Taraben <theAdib@yahoo.com>
9 *
10 * Copyright (C) 2004-2006 Authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #ifdef HAVE_CAIRO_PDF
21 #include "cairo-ps-out.h"
22 #include "cairo-render-context.h"
23 #include "cairo-renderer.h"
24 #include <print.h>
25 #include "extension/system.h"
26 #include "extension/print.h"
27 #include "extension/db.h"
28 #include "extension/output.h"
29 #include "display/nr-arena.h"
30 #include "display/nr-arena-item.h"
32 #include "display/curve.h"
33 #include "display/canvas-bpath.h"
34 #include "sp-item.h"
35 #include "style.h"
36 #include "sp-root.h"
37 #include "sp-shape.h"
39 #include "io/sys.h"
41 namespace Inkscape {
42 namespace Extension {
43 namespace Internal {
45 bool
46 CairoPsOutput::check (Inkscape::Extension::Extension * module)
47 {
48 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS))
49 return FALSE;
51 return TRUE;
52 }
54 bool
55 CairoEpsOutput::check (Inkscape::Extension::Extension * module)
56 {
57 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS))
58 return FALSE;
60 return TRUE;
61 }
63 static bool
64 ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, bool eps = false)
65 {
66 sp_document_ensure_up_to_date(doc);
68 SPItem *base = NULL;
70 bool pageBoundingBox = TRUE;
71 if (exportId && strcmp(exportId, "")) {
72 // we want to export the given item only
73 base = SP_ITEM(doc->getObjectById(exportId));
74 pageBoundingBox = exportCanvas;
75 }
76 else {
77 // we want to export the entire document from root
78 base = SP_ITEM(sp_document_root(doc));
79 pageBoundingBox = !exportDrawing;
80 }
82 if (!base)
83 return false;
85 /* Create new arena */
86 NRArena *arena = NRArena::create();
87 unsigned dkey = sp_item_display_key_new(1);
88 sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
90 /* Create renderer and context */
91 CairoRenderer *renderer = new CairoRenderer();
92 CairoRenderContext *ctx = renderer->createContext();
93 ctx->setPSLevel(level);
94 ctx->setEPS(eps);
95 ctx->setTextToPath(texttopath);
96 ctx->setFilterToBitmap(filtertobitmap);
97 ctx->setBitmapResolution(resolution);
99 bool ret = ctx->setPsTarget(filename);
100 if(ret) {
101 /* Render document */
102 ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
103 if (ret) {
104 renderer->renderItem(ctx, base);
105 ret = ctx->finish();
106 }
107 }
109 /* Release arena */
110 sp_item_invoke_hide(base, dkey);
111 nr_object_unref((NRObject *) arena);
113 renderer->destroyContext(ctx);
114 delete renderer;
116 return ret;
117 }
120 /**
121 \brief This function calls the output module with the filename
122 \param mod unused
123 \param doc Document to be saved
124 \param filename Filename to save to (probably will end in .ps)
125 */
126 void
127 CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
128 {
129 Inkscape::Extension::Extension * ext;
130 unsigned int ret;
132 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
133 if (ext == NULL)
134 return;
136 const gchar *new_level = NULL;
137 int level = CAIRO_PS_LEVEL_2;
138 try {
139 new_level = mod->get_param_enum("PSlevel");
140 if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
141 level = CAIRO_PS_LEVEL_3;
142 } catch(...) {}
144 bool new_textToPath = FALSE;
145 try {
146 new_textToPath = mod->get_param_bool("textToPath");
147 } catch(...) {}
149 bool new_blurToBitmap = FALSE;
150 try {
151 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
152 } catch(...) {}
154 int new_bitmapResolution = 72;
155 try {
156 new_bitmapResolution = mod->get_param_int("resolution");
157 } catch(...) {}
159 bool new_areaCanvas = true;
160 try {
161 new_areaCanvas = mod->get_param_bool("areaCanvas");
162 } catch(...) {}
164 bool new_areaDrawing = true;
165 try {
166 new_areaDrawing = mod->get_param_bool("areaDrawing");
167 } catch(...) {}
169 const gchar *new_exportId = NULL;
170 try {
171 new_exportId = mod->get_param_string("exportId");
172 } catch(...) {}
174 gchar * final_name;
175 final_name = g_strdup_printf("> %s", filename);
176 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaCanvas);
177 g_free(final_name);
179 if (!ret)
180 throw Inkscape::Extension::Output::save_failed();
181 }
184 /**
185 \brief This function calls the output module with the filename
186 \param mod unused
187 \param doc Document to be saved
188 \param filename Filename to save to (probably will end in .ps)
189 */
190 void
191 CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
192 {
193 Inkscape::Extension::Extension * ext;
194 unsigned int ret;
196 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
197 if (ext == NULL)
198 return;
200 const gchar *new_level = NULL;
201 int level = CAIRO_PS_LEVEL_2;
202 try {
203 new_level = mod->get_param_enum("PSlevel");
204 if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
205 level = CAIRO_PS_LEVEL_3;
206 } catch(...) {}
208 bool new_textToPath = FALSE;
209 try {
210 new_textToPath = mod->get_param_bool("textToPath");
211 } catch(...) {}
213 bool new_blurToBitmap = FALSE;
214 try {
215 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
216 } catch(...) {}
218 int new_bitmapResolution = 72;
219 try {
220 new_bitmapResolution = mod->get_param_int("resolution");
221 } catch(...) {}
223 bool new_areaCanvas = true;
224 try {
225 new_areaCanvas = mod->get_param_bool("areaCanvas");
226 } catch(...) {}
228 bool new_areaDrawing = true;
229 try {
230 new_areaDrawing = mod->get_param_bool("areaDrawing");
231 } catch(...) {}
233 const gchar *new_exportId = NULL;
234 try {
235 new_exportId = mod->get_param_string("exportId");
236 } catch(...) {}
238 gchar * final_name;
239 final_name = g_strdup_printf("> %s", filename);
240 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaCanvas, true);
241 g_free(final_name);
243 if (!ret)
244 throw Inkscape::Extension::Output::save_failed();
245 }
248 bool
249 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
250 {
251 return ext->get_param_bool("textToPath");
252 }
254 bool
255 CairoEpsOutput::textToPath(Inkscape::Extension::Print * ext)
256 {
257 return ext->get_param_bool("textToPath");
258 }
260 #include "clear-n_.h"
262 /**
263 \brief A function allocate a copy of this function.
265 This is the definition of Cairo PS out. This function just
266 calls the extension system with the memory allocated XML that
267 describes the data.
268 */
269 void
270 CairoPsOutput::init (void)
271 {
272 Inkscape::Extension::build_from_mem(
273 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
274 "<name>" N_("PostScript") "</name>\n"
275 "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
276 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
277 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
278 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
279 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
280 #endif
281 "</param>\n"
282 "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n"
283 "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n"
284 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
285 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
286 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
287 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
288 "<output>\n"
289 "<extension>.ps</extension>\n"
290 "<mimetype>image/x-postscript</mimetype>\n"
291 "<filetypename>" N_("PostScript (*.ps)") "</filetypename>\n"
292 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
293 "</output>\n"
294 "</inkscape-extension>", new CairoPsOutput());
296 return;
297 }
299 /**
300 \brief A function allocate a copy of this function.
302 This is the definition of Cairo EPS out. This function just
303 calls the extension system with the memory allocated XML that
304 describes the data.
305 */
306 void
307 CairoEpsOutput::init (void)
308 {
309 Inkscape::Extension::build_from_mem(
310 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
311 "<name>" N_("Encapsulated PostScript") "</name>\n"
312 "<id>" SP_MODULE_KEY_PRINT_CAIRO_EPS "</id>\n"
313 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
314 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
315 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
316 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
317 #endif
318 "</param>\n"
319 "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n"
320 "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n"
321 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
322 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
323 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
324 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
325 "<output>\n"
326 "<extension>.eps</extension>\n"
327 "<mimetype>image/x-e-postscript</mimetype>\n"
328 "<filetypename>" N_("Encapsulated PostScript (*.eps)") "</filetypename>\n"
329 "<filetypetooltip>" N_("Encapsulated PostScript File") "</filetypetooltip>\n"
330 "</output>\n"
331 "</inkscape-extension>", new CairoEpsOutput());
333 return;
334 }
336 } } } /* namespace Inkscape, Extension, Implementation */
338 #endif /* HAVE_CAIRO_PDF */