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 "latex-text-renderer.h"
25 #include <print.h>
26 #include "extension/system.h"
27 #include "extension/print.h"
28 #include "extension/db.h"
29 #include "extension/output.h"
30 #include "display/nr-arena.h"
31 #include "display/nr-arena-item.h"
33 #include "display/curve.h"
34 #include "display/canvas-bpath.h"
35 #include "sp-item.h"
36 #include "style.h"
37 #include "sp-root.h"
38 #include "sp-shape.h"
40 #include "io/sys.h"
42 namespace Inkscape {
43 namespace Extension {
44 namespace Internal {
46 bool CairoPsOutput::check (Inkscape::Extension::Extension * /*module*/)
47 {
48 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS)) {
49 return FALSE;
50 } else {
51 return TRUE;
52 }
53 }
55 bool CairoEpsOutput::check (Inkscape::Extension::Extension * /*module*/)
56 {
57 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS)) {
58 return FALSE;
59 } else {
60 return TRUE;
61 }
62 }
64 static bool
65 ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext,
66 bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, bool eps = false)
67 {
68 sp_document_ensure_up_to_date(doc);
70 SPItem *base = NULL;
72 bool pageBoundingBox = TRUE;
73 if (exportId && strcmp(exportId, "")) {
74 // we want to export the given item only
75 base = SP_ITEM(doc->getObjectById(exportId));
76 pageBoundingBox = exportCanvas;
77 }
78 else {
79 // we want to export the entire document from root
80 base = SP_ITEM(sp_document_root(doc));
81 pageBoundingBox = !exportDrawing;
82 }
84 if (!base)
85 return false;
87 /* Create new arena */
88 NRArena *arena = NRArena::create();
89 unsigned dkey = sp_item_display_key_new(1);
90 sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
92 /* Create renderer and context */
93 CairoRenderer *renderer = new CairoRenderer();
94 CairoRenderContext *ctx = renderer->createContext();
95 ctx->setPSLevel(level);
96 ctx->setEPS(eps);
97 ctx->setTextToPath(texttopath);
98 renderer->_omitText = omittext;
99 ctx->setFilterToBitmap(filtertobitmap);
100 ctx->setBitmapResolution(resolution);
102 bool ret = ctx->setPsTarget(filename);
103 if(ret) {
104 /* Render document */
105 ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
106 if (ret) {
107 renderer->renderItem(ctx, base);
108 ret = ctx->finish();
109 }
110 }
112 /* Release arena */
113 sp_item_invoke_hide(base, dkey);
114 nr_object_unref((NRObject *) arena);
116 renderer->destroyContext(ctx);
117 delete renderer;
119 return ret;
120 }
123 /**
124 \brief This function calls the output module with the filename
125 \param mod unused
126 \param doc Document to be saved
127 \param filename Filename to save to (probably will end in .ps)
128 */
129 void
130 CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
131 {
132 Inkscape::Extension::Extension * ext;
133 unsigned int ret;
135 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
136 if (ext == NULL)
137 return;
139 const gchar *new_level = NULL;
140 int level = CAIRO_PS_LEVEL_2;
141 try {
142 new_level = mod->get_param_enum("PSlevel");
143 if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
144 level = CAIRO_PS_LEVEL_3;
145 } catch(...) {}
147 bool new_textToPath = FALSE;
148 try {
149 new_textToPath = mod->get_param_bool("textToPath");
150 } catch(...) {}
152 bool new_textToLaTeX = FALSE;
153 try {
154 new_textToLaTeX = mod->get_param_bool("textToLaTeX");
155 }
156 catch(...) {
157 g_warning("Parameter <textToLaTeX> might not exist");
158 }
160 bool new_blurToBitmap = FALSE;
161 try {
162 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
163 } catch(...) {}
165 int new_bitmapResolution = 72;
166 try {
167 new_bitmapResolution = mod->get_param_int("resolution");
168 } catch(...) {}
170 bool new_areaPage = true;
171 try {
172 new_areaPage = mod->get_param_bool("areaPage");
173 } catch(...) {}
175 bool new_areaDrawing = true;
176 try {
177 new_areaDrawing = mod->get_param_bool("areaDrawing");
178 } catch(...) {}
180 const gchar *new_exportId = NULL;
181 try {
182 new_exportId = mod->get_param_string("exportId");
183 } catch(...) {}
185 // Create PS
186 {
187 gchar * final_name;
188 final_name = g_strdup_printf("> %s", filename);
189 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage);
190 g_free(final_name);
192 if (!ret)
193 throw Inkscape::Extension::Output::save_failed();
194 }
196 // Create LaTeX file (if requested)
197 if (new_textToLaTeX) {
198 ret = latex_render_document_text_to_file(doc, filename, new_exportId, new_areaDrawing, new_areaPage, false);
200 if (!ret)
201 throw Inkscape::Extension::Output::save_failed();
202 }
203 }
206 /**
207 \brief This function calls the output module with the filename
208 \param mod unused
209 \param doc Document to be saved
210 \param filename Filename to save to (probably will end in .ps)
211 */
212 void
213 CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
214 {
215 Inkscape::Extension::Extension * ext;
216 unsigned int ret;
218 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
219 if (ext == NULL)
220 return;
222 const gchar *new_level = NULL;
223 int level = CAIRO_PS_LEVEL_2;
224 try {
225 new_level = mod->get_param_enum("PSlevel");
226 if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
227 level = CAIRO_PS_LEVEL_3;
228 } catch(...) {}
230 bool new_textToPath = FALSE;
231 try {
232 new_textToPath = mod->get_param_bool("textToPath");
233 } catch(...) {}
235 bool new_textToLaTeX = FALSE;
236 try {
237 new_textToLaTeX = mod->get_param_bool("textToLaTeX");
238 }
239 catch(...) {
240 g_warning("Parameter <textToLaTeX> might not exist");
241 }
243 bool new_blurToBitmap = FALSE;
244 try {
245 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
246 } catch(...) {}
248 int new_bitmapResolution = 72;
249 try {
250 new_bitmapResolution = mod->get_param_int("resolution");
251 } catch(...) {}
253 bool new_areaPage = true;
254 try {
255 new_areaPage = mod->get_param_bool("areaPage");
256 } catch(...) {}
258 bool new_areaDrawing = true;
259 try {
260 new_areaDrawing = mod->get_param_bool("areaDrawing");
261 } catch(...) {}
263 const gchar *new_exportId = NULL;
264 try {
265 new_exportId = mod->get_param_string("exportId");
266 } catch(...) {}
268 // Create EPS
269 {
270 gchar * final_name;
271 final_name = g_strdup_printf("> %s", filename);
272 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage, true);
273 g_free(final_name);
275 if (!ret)
276 throw Inkscape::Extension::Output::save_failed();
277 }
279 // Create LaTeX file (if requested)
280 if (new_textToLaTeX) {
281 ret = latex_render_document_text_to_file(doc, filename, new_exportId, new_areaDrawing, new_areaPage, false);
283 if (!ret)
284 throw Inkscape::Extension::Output::save_failed();
285 }
286 }
289 bool
290 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
291 {
292 return ext->get_param_bool("textToPath");
293 }
295 bool
296 CairoEpsOutput::textToPath(Inkscape::Extension::Print * ext)
297 {
298 return ext->get_param_bool("textToPath");
299 }
301 #include "clear-n_.h"
303 /**
304 \brief A function allocate a copy of this function.
306 This is the definition of Cairo PS out. This function just
307 calls the extension system with the memory allocated XML that
308 describes the data.
309 */
310 void
311 CairoPsOutput::init (void)
312 {
313 Inkscape::Extension::build_from_mem(
314 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
315 "<name>" N_("PostScript") "</name>\n"
316 "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
317 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"enum\" >\n"
318 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
319 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
320 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
321 #endif
322 "</param>\n"
323 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
324 "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
325 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
326 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
327 "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
328 "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
329 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID:") "\" type=\"string\"></param>\n"
330 "<output>\n"
331 "<extension>.ps</extension>\n"
332 "<mimetype>image/x-postscript</mimetype>\n"
333 "<filetypename>" N_("PostScript (*.ps)") "</filetypename>\n"
334 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
335 "</output>\n"
336 "</inkscape-extension>", new CairoPsOutput());
338 return;
339 }
341 /**
342 \brief A function allocate a copy of this function.
344 This is the definition of Cairo EPS out. This function just
345 calls the extension system with the memory allocated XML that
346 describes the data.
347 */
348 void
349 CairoEpsOutput::init (void)
350 {
351 Inkscape::Extension::build_from_mem(
352 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
353 "<name>" N_("Encapsulated PostScript") "</name>\n"
354 "<id>" SP_MODULE_KEY_PRINT_CAIRO_EPS "</id>\n"
355 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"enum\" >\n"
356 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
357 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
358 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
359 #endif
360 "</param>\n"
361 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
362 "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
363 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
364 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
365 "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
366 "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
367 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID:") "\" type=\"string\"></param>\n"
368 "<output>\n"
369 "<extension>.eps</extension>\n"
370 "<mimetype>image/x-e-postscript</mimetype>\n"
371 "<filetypename>" N_("Encapsulated PostScript (*.eps)") "</filetypename>\n"
372 "<filetypetooltip>" N_("Encapsulated PostScript File") "</filetypetooltip>\n"
373 "</output>\n"
374 "</inkscape-extension>", new CairoEpsOutput());
376 return;
377 }
379 } } } /* namespace Inkscape, Extension, Implementation */
381 #endif /* HAVE_CAIRO_PDF */