1 /*
2 * A quick hack to use the Cairo renderer to write out a file. This
3 * then makes 'save as...' PDF.
4 *
5 * Authors:
6 * Ted Gould <ted@gould.cx>
7 * Ulf Erikson <ulferikson@users.sf.net>
8 *
9 * Copyright (C) 2004-2006 Authors
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
18 #ifdef HAVE_CAIRO_PDF
20 #include "cairo-renderer-pdf-out.h"
21 #include "cairo-render-context.h"
22 #include "cairo-renderer.h"
23 #include <print.h>
24 #include "extension/system.h"
25 #include "extension/print.h"
26 #include "extension/db.h"
27 #include "extension/output.h"
28 #include "display/nr-arena.h"
29 #include "display/nr-arena-item.h"
31 #include "display/curve.h"
32 #include "display/canvas-bpath.h"
33 #include "sp-item.h"
34 #include "sp-root.h"
36 namespace Inkscape {
37 namespace Extension {
38 namespace Internal {
40 bool
41 CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)
42 {
43 if (NULL == Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer"))
44 return FALSE;
46 return TRUE;
47 }
49 static bool
50 pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level,
51 bool texttopath, bool texttolatex, bool filtertobitmap, int resolution,
52 const gchar * const exportId, bool exportDrawing, bool exportCanvas)
53 {
54 sp_document_ensure_up_to_date(doc);
56 /* Start */
58 SPItem *base = NULL;
60 bool pageBoundingBox = TRUE;
61 if (exportId && strcmp(exportId, "")) {
62 // we want to export the given item only
63 base = SP_ITEM(doc->getObjectById(exportId));
64 pageBoundingBox = exportCanvas;
65 }
66 else {
67 // we want to export the entire document from root
68 base = SP_ITEM(sp_document_root(doc));
69 pageBoundingBox = !exportDrawing;
70 }
72 if (!base)
73 return false;
75 /* Create new arena */
76 NRArena *arena = NRArena::create();
77 nr_arena_set_renderoffscreen (arena);
78 unsigned dkey = sp_item_display_key_new(1);
79 sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
81 /* Create renderer and context */
82 CairoRenderer *renderer = new CairoRenderer();
83 CairoRenderContext *ctx = renderer->createContext();
84 ctx->setPDFLevel(level);
85 ctx->setTextToPath(texttopath);
86 renderer->_omitText = texttolatex;
87 ctx->setFilterToBitmap(filtertobitmap);
88 ctx->setBitmapResolution(resolution);
90 bool ret = ctx->setPdfTarget (filename);
91 if(ret) {
92 /* Render document */
93 ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
94 if (ret) {
95 renderer->renderItem(ctx, base);
96 ret = ctx->finish();
97 }
98 }
100 /* Release arena */
101 sp_item_invoke_hide(base, dkey);
102 nr_object_unref((NRObject *) arena);
104 renderer->destroyContext(ctx);
105 delete renderer;
107 return ret;
108 }
111 /**
112 \brief This function calls the output module with the filename
113 \param mod unused
114 \param doc Document to be saved
115 \param filename Filename to save to (probably will end in .pdf)
117 The most interesting thing that this function does is just attach
118 an '>' on the front of the filename. This is the syntax used to
119 tell the printing system to save to file.
120 */
121 void
122 CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
123 {
124 Inkscape::Extension::Extension * ext;
125 unsigned int ret;
127 ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
128 if (ext == NULL)
129 return;
131 const gchar *new_level = NULL;
132 int level = 0;
133 try {
134 new_level = mod->get_param_enum("PDFversion");
135 // if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.x", new_level) == 0))
136 // level = 1;
137 }
138 catch(...) {
139 // g_warning("Parameter <PDFversion> might not exist");
140 }
142 bool new_textToPath = FALSE;
143 try {
144 new_textToPath = mod->get_param_bool("textToPath");
145 }
146 catch(...) {
147 g_warning("Parameter <textToPath> might not exist");
148 }
150 bool new_textToLaTeX = FALSE;
151 try {
152 new_textToLaTeX = mod->get_param_bool("textToLaTeX");
153 }
154 catch(...) {
155 g_warning("Parameter <textToLaTeX> might not exist");
156 }
158 bool new_blurToBitmap = FALSE;
159 try {
160 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
161 }
162 catch(...) {
163 g_warning("Parameter <blurToBitmap> might not exist");
164 }
166 int new_bitmapResolution = 72;
167 try {
168 new_bitmapResolution = mod->get_param_int("resolution");
169 }
170 catch(...) {
171 g_warning("Parameter <resolution> might not exist");
172 }
174 const gchar *new_exportId = NULL;
175 try {
176 new_exportId = mod->get_param_string("exportId");
177 }
178 catch(...) {
179 g_warning("Parameter <exportId> might not exist");
180 }
182 bool new_exportDrawing = FALSE;
183 try {
184 new_exportDrawing = mod->get_param_bool("areaDrawing");
185 }
186 catch(...) {
187 g_warning("Parameter <areaDrawing> might not exist");
188 }
190 bool new_exportCanvas = FALSE;
191 try {
192 new_exportCanvas = mod->get_param_bool("areaPage");
193 }
194 catch(...) {
195 g_warning("Parameter <exportCanvas> might not exist");
196 }
198 gchar * final_name;
199 final_name = g_strdup_printf("> %s", filename);
200 ret = pdf_render_document_to_file(doc, final_name, level,
201 new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution,
202 new_exportId, new_exportDrawing, new_exportCanvas);
203 g_free(final_name);
205 if (!ret)
206 throw Inkscape::Extension::Output::save_failed();
207 }
209 #include "clear-n_.h"
211 /**
212 \brief A function allocate a copy of this function.
214 This is the definition of Cairo PDF out. This function just
215 calls the extension system with the memory allocated XML that
216 describes the data.
217 */
218 void
219 CairoRendererPdfOutput::init (void)
220 {
221 Inkscape::Extension::build_from_mem(
222 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
223 "<name>Portable Document Format</name>\n"
224 "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
225 "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
226 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
227 "</param>\n"
228 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
229 "<param name=\"textToLaTeX\" gui-text=\"" N_("Exclude text, create LaTeX file") "\" type=\"boolean\">false</param>\n"
230 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
231 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
232 "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n"
233 "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">false</param>\n"
234 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
235 "<output>\n"
236 "<extension>.pdf</extension>\n"
237 "<mimetype>application/pdf</mimetype>\n"
238 "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
239 "<filetypetooltip>PDF File</filetypetooltip>\n"
240 "</output>\n"
241 "</inkscape-extension>", new CairoRendererPdfOutput());
243 return;
244 }
246 } } } /* namespace Inkscape, Extension, Internal */
248 #endif /* HAVE_CAIRO_PDF */