Code

A simple layout document as to what, why and how is cppification.
[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  *
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     doc->ensure_up_to_date();
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 = SPItem::display_key_new(1);
90     base->invoke_show(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     base->invoke_hide(dkey);
114     nr_object_unref((NRObject *) arena);
116     renderer->destroyContext(ctx);
117     delete renderer;
119     return ret;
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)
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         gchar * tex_filename;
199         //strip filename of ".ps", do not add ".tex" here.
200         gsize n = g_str_has_suffix(filename, ".ps") ? strlen(filename)-3 : strlen(filename);
201         tex_filename = g_strndup(filename, n);
202         ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage, false);
203         g_free(tex_filename);
205         if (!ret)
206             throw Inkscape::Extension::Output::save_failed();
207     }
211 /**
212     \brief  This function calls the output module with the filename
213         \param  mod   unused
214         \param  doc   Document to be saved
215     \param  filename   Filename to save to (probably will end in .ps)
216 */
217 void
218 CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
220     Inkscape::Extension::Extension * ext;
221     unsigned int ret;
223     ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
224     if (ext == NULL)
225         return;
227     const gchar *new_level = NULL;
228     int level = CAIRO_PS_LEVEL_2;
229     try {
230         new_level = mod->get_param_enum("PSlevel");
231         if((new_level != NULL) && !(g_ascii_strcasecmp("PS3", new_level) == 0))
232             level = CAIRO_PS_LEVEL_3;
233     } catch(...) {}
235     bool new_textToPath  = FALSE;
236     try {
237         new_textToPath  = mod->get_param_bool("textToPath");
238     } catch(...) {}
240     bool new_textToLaTeX  = FALSE;
241     try {
242         new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
243     }
244     catch(...) {
245         g_warning("Parameter <textToLaTeX> might not exist");
246     }
248     bool new_blurToBitmap  = FALSE;
249     try {
250         new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
251     } catch(...) {}
253     int new_bitmapResolution  = 72;
254     try {
255         new_bitmapResolution = mod->get_param_int("resolution");
256     } catch(...) {}
258     bool new_areaPage  = true;
259     try {
260         new_areaPage = mod->get_param_bool("areaPage");
261     } catch(...) {}
263     bool new_areaDrawing  = true;
264     try {
265         new_areaDrawing = mod->get_param_bool("areaDrawing");
266     } catch(...) {}
268     const gchar *new_exportId = NULL;
269     try {
270         new_exportId = mod->get_param_string("exportId");
271     } catch(...) {}
273     // Create EPS
274     {
275         gchar * final_name;
276         final_name = g_strdup_printf("> %s", filename);
277         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);
278         g_free(final_name);
280         if (!ret)
281             throw Inkscape::Extension::Output::save_failed();
282     }
284     // Create LaTeX file (if requested)
285     if (new_textToLaTeX) {
286         gchar * tex_filename;
287         //strip filename of ".eps", do not add ".tex" here.
288         gsize n = g_str_has_suffix(filename, ".eps") ? strlen(filename)-4 : strlen(filename);
289         tex_filename = g_strndup(filename, n);
290         ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage, false);
291         g_free(tex_filename);
293         if (!ret)
294             throw Inkscape::Extension::Output::save_failed();
295     }
299 bool
300 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
302     return ext->get_param_bool("textToPath");
305 bool
306 CairoEpsOutput::textToPath(Inkscape::Extension::Print * ext)
308     return ext->get_param_bool("textToPath");
311 #include "clear-n_.h"
313 /**
314         \brief   A function allocate a copy of this function.
316         This is the definition of Cairo PS out.  This function just
317         calls the extension system with the memory allocated XML that
318         describes the data.
319 */
320 void
321 CairoPsOutput::init (void)
323         Inkscape::Extension::build_from_mem(
324                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
325                         "<name>" N_("PostScript") "</name>\n"
326                         "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
327                         "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
328                                 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
329 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
330                 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
331 #endif
332             "</param>\n"
333                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
334                         "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
335                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
336                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
337                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
338                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
339                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
340                         "<output>\n"
341                                 "<extension>.ps</extension>\n"
342                                 "<mimetype>image/x-postscript</mimetype>\n"
343                                 "<filetypename>" N_("PostScript (*.ps)") "</filetypename>\n"
344                                 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
345                         "</output>\n"
346                 "</inkscape-extension>", new CairoPsOutput());
348         return;
351 /**
352         \brief   A function allocate a copy of this function.
354         This is the definition of Cairo EPS out.  This function just
355         calls the extension system with the memory allocated XML that
356         describes the data.
357 */
358 void
359 CairoEpsOutput::init (void)
361         Inkscape::Extension::build_from_mem(
362                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
363                         "<name>" N_("Encapsulated PostScript") "</name>\n"
364                         "<id>" SP_MODULE_KEY_PRINT_CAIRO_EPS "</id>\n"
365                         "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
366                                 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
367 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
368                 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
369 #endif
370             "</param>\n"
371                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
372                         "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
373                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
374                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
375                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n"
376                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n"
377                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
378                         "<output>\n"
379                                 "<extension>.eps</extension>\n"
380                                 "<mimetype>image/x-e-postscript</mimetype>\n"
381                                 "<filetypename>" N_("Encapsulated PostScript (*.eps)") "</filetypename>\n"
382                                 "<filetypetooltip>" N_("Encapsulated PostScript File") "</filetypetooltip>\n"
383                         "</output>\n"
384                 "</inkscape-extension>", new CairoEpsOutput());
386         return;
389 } } }  /* namespace Inkscape, Extension, Implementation */
391 #endif /* HAVE_CAIRO_PDF */