Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / extension / internal / cairo-ps-out.cpp
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  *   Jon A. Cruz <jon@joncruz.org>
10  *   Abhishek Sharma
11  *
12  * Copyright (C) 2004-2006 Authors
13  *
14  * Released under GNU GPL, read the file 'COPYING' for more information
15  */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
21 #ifdef HAVE_CAIRO_PDF
23 #include "cairo-ps-out.h"
24 #include "cairo-render-context.h"
25 #include "cairo-renderer.h"
26 #include "latex-text-renderer.h"
27 #include <print.h>
28 #include "extension/system.h"
29 #include "extension/print.h"
30 #include "extension/db.h"
31 #include "extension/output.h"
32 #include "display/nr-arena.h"
33 #include "display/nr-arena-item.h"
35 #include "display/curve.h"
36 #include "display/canvas-bpath.h"
37 #include "sp-item.h"
38 #include "style.h"
39 #include "sp-root.h"
40 #include "sp-shape.h"
42 #include "io/sys.h"
44 namespace Inkscape {
45 namespace Extension {
46 namespace Internal {
48 bool CairoPsOutput::check (Inkscape::Extension::Extension * /*module*/)
49 {
50     if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS)) {
51         return FALSE;
52     } else {
53         return TRUE;
54     }
55 }
57 bool CairoEpsOutput::check (Inkscape::Extension::Extension * /*module*/)
58 {
59     if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS)) {
60         return FALSE;
61     } else {
62         return TRUE;
63     }
64 }
66 static bool
67 ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext,
68                           bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, bool eps = false)
69 {
70     doc->ensureUpToDate();
72     SPItem *base = NULL;
74     bool pageBoundingBox = TRUE;
75     if (exportId && strcmp(exportId, "")) {
76         // we want to export the given item only
77         base = SP_ITEM(doc->getObjectById(exportId));
78         pageBoundingBox = exportCanvas;
79     }
80     else {
81         // we want to export the entire document from root
82         base = SP_ITEM(doc->getRoot());
83         pageBoundingBox = !exportDrawing;
84     }
86     if (!base)
87         return false;
89     /* Create new arena */
90     NRArena *arena = NRArena::create();
91     unsigned dkey = SPItem::display_key_new(1);
92     base->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY);
94     /* Create renderer and context */
95     CairoRenderer *renderer = new CairoRenderer();
96     CairoRenderContext *ctx = renderer->createContext();
97     ctx->setPSLevel(level);
98     ctx->setEPS(eps);
99     ctx->setTextToPath(texttopath);
100     renderer->_omitText = omittext;
101     ctx->setFilterToBitmap(filtertobitmap);
102     ctx->setBitmapResolution(resolution);
104     bool ret = ctx->setPsTarget(filename);
105     if(ret) {
106         /* Render document */
107         ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
108         if (ret) {
109             renderer->renderItem(ctx, base);
110             ret = ctx->finish();
111         }
112     }
114     /* Release arena */
115     base->invoke_hide(dkey);
116     nr_object_unref((NRObject *) arena);
118     renderer->destroyContext(ctx);
119     delete renderer;
121     return ret;
125 /**
126     \brief  This function calls the output module with the filename
127         \param  mod   unused
128         \param  doc   Document to be saved
129     \param  filename   Filename to save to (probably will end in .ps)
130 */
131 void
132 CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
134     Inkscape::Extension::Extension * ext;
135     unsigned int ret;
137     ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
138     if (ext == NULL)
139         return;
141     const gchar *new_level = NULL;
142     int level = CAIRO_PS_LEVEL_2;
143     try {
144         new_level = mod->get_param_enum("PSlevel");
145         if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
146             level = CAIRO_PS_LEVEL_3;
147     } catch(...) {}
149     bool new_textToPath  = FALSE;
150     try {
151         new_textToPath  = mod->get_param_bool("textToPath");
152     } catch(...) {}
154     bool new_textToLaTeX  = FALSE;
155     try {
156         new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
157     }
158     catch(...) {
159         g_warning("Parameter <textToLaTeX> might not exist");
160     }
162     bool new_blurToBitmap  = FALSE;
163     try {
164         new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
165     } catch(...) {}
167     int new_bitmapResolution  = 72;
168     try {
169         new_bitmapResolution = mod->get_param_int("resolution");
170     } catch(...) {}
172     bool new_areaPage  = true;
173     try {
174         new_areaPage = mod->get_param_bool("areaPage");
175     } catch(...) {}
177     bool new_areaDrawing  = true;
178     try {
179         new_areaDrawing = mod->get_param_bool("areaDrawing");
180     } catch(...) {}
182     const gchar *new_exportId = NULL;
183     try {
184         new_exportId = mod->get_param_string("exportId");
185     } catch(...) {}
187     // Create PS
188     {
189         gchar * final_name;
190         final_name = g_strdup_printf("> %s", filename);
191         ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage);
192         g_free(final_name);
194         if (!ret)
195             throw Inkscape::Extension::Output::save_failed();
196     }
198     // Create LaTeX file (if requested)
199     if (new_textToLaTeX) {
200         ret = latex_render_document_text_to_file(doc, filename, new_exportId, new_areaDrawing, new_areaPage, false);
202         if (!ret)
203             throw Inkscape::Extension::Output::save_failed();
204     }
208 /**
209     \brief  This function calls the output module with the filename
210         \param  mod   unused
211         \param  doc   Document to be saved
212     \param  filename   Filename to save to (probably will end in .ps)
213 */
214 void
215 CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
217     Inkscape::Extension::Extension * ext;
218     unsigned int ret;
220     ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
221     if (ext == NULL)
222         return;
224     const gchar *new_level = NULL;
225     int level = CAIRO_PS_LEVEL_2;
226     try {
227         new_level = mod->get_param_enum("PSlevel");
228         if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
229             level = CAIRO_PS_LEVEL_3;
230     } catch(...) {}
232     bool new_textToPath  = FALSE;
233     try {
234         new_textToPath  = mod->get_param_bool("textToPath");
235     } catch(...) {}
237     bool new_textToLaTeX  = FALSE;
238     try {
239         new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
240     }
241     catch(...) {
242         g_warning("Parameter <textToLaTeX> might not exist");
243     }
245     bool new_blurToBitmap  = FALSE;
246     try {
247         new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
248     } catch(...) {}
250     int new_bitmapResolution  = 72;
251     try {
252         new_bitmapResolution = mod->get_param_int("resolution");
253     } catch(...) {}
255     bool new_areaPage  = true;
256     try {
257         new_areaPage = mod->get_param_bool("areaPage");
258     } catch(...) {}
260     bool new_areaDrawing  = true;
261     try {
262         new_areaDrawing = mod->get_param_bool("areaDrawing");
263     } catch(...) {}
265     const gchar *new_exportId = NULL;
266     try {
267         new_exportId = mod->get_param_string("exportId");
268     } catch(...) {}
270     // Create EPS
271     {
272         gchar * final_name;
273         final_name = g_strdup_printf("> %s", filename);
274         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);
275         g_free(final_name);
277         if (!ret)
278             throw Inkscape::Extension::Output::save_failed();
279     }
281     // Create LaTeX file (if requested)
282     if (new_textToLaTeX) {
283         ret = latex_render_document_text_to_file(doc, filename, new_exportId, new_areaDrawing, new_areaPage, false);
285         if (!ret)
286             throw Inkscape::Extension::Output::save_failed();
287     }
291 bool
292 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
294     return ext->get_param_bool("textToPath");
297 bool
298 CairoEpsOutput::textToPath(Inkscape::Extension::Print * ext)
300     return ext->get_param_bool("textToPath");
303 #include "clear-n_.h"
305 /**
306         \brief   A function allocate a copy of this function.
308         This is the definition of Cairo PS out.  This function just
309         calls the extension system with the memory allocated XML that
310         describes the data.
311 */
312 void
313 CairoPsOutput::init (void)
315         Inkscape::Extension::build_from_mem(
316                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
317                         "<name>" N_("PostScript") "</name>\n"
318                         "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
319                         "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"enum\" >\n"
320                                 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
321 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
322                 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
323 #endif
324             "</param>\n"
325                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
326                         "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
327                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
328                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
329                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
330                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
331                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID:") "\" type=\"string\"></param>\n"
332                         "<output>\n"
333                                 "<extension>.ps</extension>\n"
334                                 "<mimetype>image/x-postscript</mimetype>\n"
335                                 "<filetypename>" N_("PostScript (*.ps)") "</filetypename>\n"
336                                 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
337                         "</output>\n"
338                 "</inkscape-extension>", new CairoPsOutput());
340         return;
343 /**
344         \brief   A function allocate a copy of this function.
346         This is the definition of Cairo EPS out.  This function just
347         calls the extension system with the memory allocated XML that
348         describes the data.
349 */
350 void
351 CairoEpsOutput::init (void)
353         Inkscape::Extension::build_from_mem(
354                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
355                         "<name>" N_("Encapsulated PostScript") "</name>\n"
356                         "<id>" SP_MODULE_KEY_PRINT_CAIRO_EPS "</id>\n"
357                         "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"enum\" >\n"
358                                 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
359 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
360                 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
361 #endif
362             "</param>\n"
363                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
364                         "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
365                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
366                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
367                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
368                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
369                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID:") "\" type=\"string\"></param>\n"
370                         "<output>\n"
371                                 "<extension>.eps</extension>\n"
372                                 "<mimetype>image/x-e-postscript</mimetype>\n"
373                                 "<filetypename>" N_("Encapsulated PostScript (*.eps)") "</filetypename>\n"
374                                 "<filetypetooltip>" N_("Encapsulated PostScript File") "</filetypetooltip>\n"
375                         "</output>\n"
376                 "</inkscape-extension>", new CairoEpsOutput());
378         return;
381 } } }  /* namespace Inkscape, Extension, Implementation */
383 #endif /* HAVE_CAIRO_PDF */