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 return TRUE;
51 }
53 static bool
54 ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool filtertobitmap)
55 {
56 CairoRenderer *renderer;
57 CairoRenderContext *ctx;
59 sp_document_ensure_up_to_date(doc);
61 /* Start */
62 /* Create new arena */
63 SPItem *base = SP_ITEM(sp_document_root(doc));
64 NRArena *arena = NRArena::create();
65 unsigned dkey = sp_item_display_key_new(1);
66 NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
68 /* Create renderer and context */
69 renderer = new CairoRenderer();
70 ctx = renderer->createContext();
71 ctx->setPSLevel(level);
72 ctx->setTextToPath(texttopath);
73 ctx->setFilterToBitmap(filtertobitmap);
75 bool ret = ctx->setPsTarget(filename);
76 if(ret) {
77 /* Render document */
78 ret = renderer->setupDocument(ctx, doc);
79 if (ret) {
80 renderer->renderItem(ctx, base);
81 ret = ctx->finish();
82 }
83 }
84 renderer->destroyContext(ctx);
86 /* Release arena */
87 sp_item_invoke_hide(base, dkey);
88 nr_arena_item_unref(root);
89 nr_object_unref((NRObject *) arena);
90 /* end */
91 delete renderer;
93 return ret;
94 }
97 /**
98 \brief This function calls the output module with the filename
99 \param mod unused
100 \param doc Document to be saved
101 \param uri Filename to save to (probably will end in .ps)
102 */
103 void
104 CairoPsOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
105 {
106 Inkscape::Extension::Extension * ext;
107 unsigned int ret;
109 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
110 if (ext == NULL)
111 return;
113 const gchar *old_level = ext->get_param_enum("PSlevel");
114 const gchar *new_level = mod->get_param_enum("PSlevel");
115 int level = 1;
117 bool old_textToPath = ext->get_param_bool("textToPath");
118 bool new_textToPath = mod->get_param_bool("textToPath");
119 ext->set_param_bool("textToPath", new_textToPath);
121 bool old_blurToBitmap = ext->get_param_bool("blurToBitmap");
122 bool new_blurToBitmap = mod->get_param_bool("blurToBitmap");
123 ext->set_param_bool("blurToBitmap", new_blurToBitmap);
126 if(g_ascii_strcasecmp("PS2", new_level) == 0)
127 level = 0;
128 gchar * final_name;
129 final_name = g_strdup_printf("> %s", uri);
130 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap);
131 g_free(final_name);
133 ext->set_param_bool("blurToBitmap", old_blurToBitmap);
134 ext->set_param_bool("textToPath", old_textToPath);
136 if (!ret)
137 throw Inkscape::Extension::Output::save_failed();
139 return;
141 }
143 bool
144 CairoPsOutput::textToPath(Inkscape::Extension::Print * ext)
145 {
146 return ext->get_param_bool("textToPath");
147 }
149 #include "clear-n_.h"
151 /**
152 \brief A function allocate a copy of this function.
154 This is the definition of Cairo PS out. This function just
155 calls the extension system with the memory allocated XML that
156 describes the data.
157 */
158 void
159 CairoPsOutput::init (void)
160 {
161 Inkscape::Extension::build_from_mem(
162 "<inkscape-extension>\n"
163 "<name>Cairo PS Output</name>\n"
164 "<id>org.inkscape.print.ps.cairo</id>\n"
165 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level") "\" type=\"enum\" >\n"
166 "<item value='PS3'>" N_("PostScript 3") "</item>\n"
167 #if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
168 "<item value='PS2'>" N_("PostScript level 2") "</item>\n"
169 #endif
170 "</param>\n"
171 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">true</param>\n"
172 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n"
173 "<output>\n"
174 "<extension>.ps</extension>\n"
175 "<mimetype>application/ps</mimetype>\n"
176 "<filetypename>PostScript via Cairo (*.ps)</filetypename>\n"
177 "<filetypetooltip>PostScript File</filetypetooltip>\n"
178 "</output>\n"
179 "</inkscape-extension>", new CairoPsOutput());
181 return;
182 }
184 } } } /* namespace Inkscape, Extension, Implementation */
186 #endif /* HAVE_CAIRO_PDF */