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 <libnr/n-art-bpath.h>
34 #include "display/curve.h"
35 #include "display/canvas-bpath.h"
36 #include "sp-item.h"
37 #include "style.h"
38 #include "sp-root.h"
39 #include "sp-shape.h"
41 #include "io/sys.h"
43 namespace Inkscape {
44 namespace Extension {
45 namespace Internal {
47 bool
48 CairoPsOutput::check (Inkscape::Extension::Extension * module)
49 {
50 if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS))
51 return FALSE;
53 return TRUE;}
55 static bool
56 ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool filtertobitmap, int resolution)
57 {
58 CairoRenderer *renderer;
59 CairoRenderContext *ctx;
61 sp_document_ensure_up_to_date(doc);
63 /* Start */
64 /* Create new arena */
65 SPItem *base = SP_ITEM(sp_document_root(doc));
66 NRArena *arena = NRArena::create();
67 unsigned dkey = sp_item_display_key_new(1);
68 NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
70 /* Create renderer and context */
71 renderer = new CairoRenderer();
72 ctx = renderer->createContext();
73 ctx->setPSLevel(level);
74 ctx->setTextToPath(texttopath);
75 ctx->setFilterToBitmap(filtertobitmap);
76 ctx->setBitmapResolution(resolution);
78 bool ret = ctx->setPsTarget(filename);
79 if(ret) {
80 /* Render document */
81 ret = renderer->setupDocument(ctx, doc);
82 if (ret) {
83 renderer->renderItem(ctx, base);
84 ret = ctx->finish();
85 }
86 }
87 renderer->destroyContext(ctx);
89 /* Release arena */
90 sp_item_invoke_hide(base, dkey);
91 nr_arena_item_unref(root);
92 nr_object_unref((NRObject *) arena);
93 /* end */
94 delete renderer;
96 return ret;
98 }
101 /**
102 \brief This function calls the output module with the filename
103 \param mod unused
104 \param doc Document to be saved
105 \param uri Filename to save to (probably will end in .ps)
106 */
107 void
108 CairoPsOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
109 {
110 Inkscape::Extension::Extension * ext;
111 unsigned int ret;
113 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
114 if (ext == NULL)
115 return;
117 const gchar *old_level = NULL;
118 const gchar *new_level = NULL;
119 int level = 1;
120 try {
121 old_level = ext->get_param_enum("PSlevel");
122 new_level = mod->get_param_enum("PSlevel");
123 if((new_level != NULL) && (g_ascii_strcasecmp("PS2", new_level) == 0))
124 level = 0;
125 // ext->set_param_enum("PSlevel", new_level);
126 }
127 catch(...) {
128 g_warning("Parameter <PSlevel> might not exists");
129 }
131 bool old_textToPath = FALSE;
132 bool new_textToPath = FALSE;
133 try {
134 old_textToPath = ext->get_param_bool("textToPath");
135 new_textToPath = mod->get_param_bool("textToPath");
136 ext->set_param_bool("textToPath", new_textToPath);
137 }
138 catch(...) {
139 g_warning("Parameter <textToPath> might not exists");
140 }
142 bool old_blurToBitmap = FALSE;
143 bool new_blurToBitmap = FALSE;
144 try {
145 old_blurToBitmap = ext->get_param_bool("blurToBitmap");
146 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
147 ext->set_param_bool("blurToBitmap", new_blurToBitmap);
148 }
149 catch(...) {
150 g_warning("Parameter <blurToBitmap> might not exists");
151 }
153 int old_bitmapResolution = 72;
154 int new_bitmapResolution = 72;
155 try {
156 old_bitmapResolution = ext->get_param_int("resolution");
157 new_bitmapResolution = mod->get_param_int("resolution");
158 ext->set_param_int("resolution", new_bitmapResolution);
159 }
160 catch(...) {
161 g_warning("Parameter <resolution> might not exists");
162 }
164 gchar * final_name;
165 final_name = g_strdup_printf("> %s", uri);
166 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap, new_bitmapResolution);
167 g_free(final_name);
169 try {
170 ext->set_param_int("resolution", old_bitmapResolution);
171 }
172 catch(...) {
173 g_warning("Parameter <resolution> might not exists");
174 }
175 try {
176 ext->set_param_bool("blurToBitmap", old_blurToBitmap);
177 }
178 catch(...) {
179 g_warning("Parameter <blurToBitmap> might not exists");
180 }
181 try {
182 ext->set_param_bool("textToPath", old_textToPath);
183 }
184 catch(...) {
185 g_warning("Parameter <textToPath> might not exists");
186 }
187 try {
188 // ext->set_param_enum("PSlevel", old_level);
189 }
190 catch(...) {
191 g_warning("Parameter <PSlevel> might not exists");
192 }
195 if (!ret)
196 throw Inkscape::Extension::Output::save_failed();
198 return;
200 }
202 bool
203 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
204 {
205 return ext->get_param_bool("textToPath");
206 }
208 #include "clear-n_.h"
210 /**
211 \brief A function allocate a copy of this function.
213 This is the definition of Cairo PS out. This function just
214 calls the extension system with the memory allocated XML that
215 describes the data.
216 */
217 void
218 CairoPsOutput::init (void)
219 {
220 Inkscape::Extension::build_from_mem(
221 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
222 "<name>" N_("Cairo PS Output") "</name>\n"
223 "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
224 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
225 "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n"
226 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
227 "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n"
228 #endif
229 "</param>\n"
230 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
231 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n"
232 "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n"
233 "<output>\n"
234 "<extension>.ps</extension>\n"
235 "<mimetype>application/ps</mimetype>\n"
236 "<filetypename>" N_("PostScript via Cairo (*.ps)") "</filetypename>\n"
237 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
238 "</output>\n"
239 "</inkscape-extension>", new CairoPsOutput());
241 return;
242 }
244 } } } /* namespace Inkscape, Extension, Implementation */
246 #endif /* HAVE_CAIRO_PDF */