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 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 unsigned dkey = sp_item_display_key_new(1);
78 NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
80 /* Create renderer and context */
81 CairoRenderer *renderer = new CairoRenderer();
82 CairoRenderContext *ctx = renderer->createContext();
83 ctx->setPDFLevel(level);
84 ctx->setTextToPath(texttopath);
85 ctx->setFilterToBitmap(filtertobitmap);
86 ctx->setBitmapResolution(resolution);
88 bool ret = ctx->setPdfTarget (filename);
89 if(ret) {
90 /* Render document */
91 ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
92 if (ret) {
93 renderer->renderItem(ctx, base);
94 ret = ctx->finish();
95 }
96 }
98 /* Release arena */
99 sp_item_invoke_hide(base, dkey);
100 nr_arena_item_unref(root);
101 nr_object_unref((NRObject *) arena);
102 /* end */
103 renderer->destroyContext(ctx);
104 delete renderer;
106 return ret;
107 }
110 /**
111 \brief This function calls the output module with the filename
112 \param mod unused
113 \param doc Document to be saved
114 \param uri Filename to save to (probably will end in .pdf)
116 The most interesting thing that this function does is just attach
117 an '>' on the front of the filename. This is the syntax used to
118 tell the printing system to save to file.
119 */
120 void
121 CairoRendererPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
122 {
123 Inkscape::Extension::Extension * ext;
124 unsigned int ret;
126 ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
127 if (ext == NULL)
128 return;
130 const gchar *new_level = NULL;
131 int level = 0;
132 try {
133 new_level = mod->get_param_enum("PDFversion");
134 // if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.x", new_level) == 0))
135 // level = 1;
136 }
137 catch(...) {
138 // g_warning("Parameter <PDFversion> might not exists");
139 }
141 bool new_textToPath = FALSE;
142 try {
143 new_textToPath = mod->get_param_bool("textToPath");
144 }
145 catch(...) {
146 g_warning("Parameter <textToPath> might not exists");
147 }
149 bool new_blurToBitmap = FALSE;
150 try {
151 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
152 }
153 catch(...) {
154 g_warning("Parameter <blurToBitmap> might not exists");
155 }
157 int new_bitmapResolution = 72;
158 try {
159 new_bitmapResolution = mod->get_param_int("resolution");
160 }
161 catch(...) {
162 g_warning("Parameter <resolution> might not exists");
163 }
165 const gchar *new_exportId = NULL;
166 try {
167 new_exportId = mod->get_param_string("exportId");
168 }
169 catch(...) {
170 g_warning("Parameter <exportId> might not exists");
171 }
173 bool new_exportDrawing = FALSE;
174 try {
175 new_exportDrawing = mod->get_param_bool("exportDrawing");
176 }
177 catch(...) {
178 g_warning("Parameter <exportDrawing> might not exists");
179 }
181 bool new_exportCanvas = FALSE;
182 try {
183 new_exportCanvas = mod->get_param_bool("exportCanvas");
184 }
185 catch(...) {
186 g_warning("Parameter <exportCanvas> might not exists");
187 }
189 gchar * final_name;
190 final_name = g_strdup_printf("> %s", uri);
191 ret = pdf_render_document_to_file(doc, final_name, level,
192 new_textToPath, new_blurToBitmap, new_bitmapResolution,
193 new_exportId, new_exportDrawing, new_exportCanvas);
194 g_free(final_name);
196 if (!ret)
197 throw Inkscape::Extension::Output::save_failed();
199 return;
200 }
202 #include "clear-n_.h"
204 /**
205 \brief A function allocate a copy of this function.
207 This is the definition of Cairo PDF out. This function just
208 calls the extension system with the memory allocated XML that
209 describes the data.
210 */
211 void
212 CairoRendererPdfOutput::init (void)
213 {
214 Inkscape::Extension::build_from_mem(
215 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
216 "<name>Portable Document Format</name>\n"
217 "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
218 "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
219 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
220 "</param>\n"
221 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
222 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n"
223 "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n"
224 "<param name=\"exportDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n"
225 "<param name=\"exportCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n"
226 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
227 "<output>\n"
228 "<extension>.pdf</extension>\n"
229 "<mimetype>application/pdf</mimetype>\n"
230 "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
231 "<filetypetooltip>PDF File</filetypetooltip>\n"
232 "</output>\n"
233 "</inkscape-extension>", new CairoRendererPdfOutput());
235 return;
236 }
238 } } } /* namespace Inkscape, Extension, Internal */
240 #endif /* HAVE_CAIRO_PDF */