c82cc76112a69e8be431b0b00d606a18c4a75190
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 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_object_unref((NRObject *) arena);
102 renderer->destroyContext(ctx);
103 delete renderer;
105 return ret;
106 }
109 /**
110 \brief This function calls the output module with the filename
111 \param mod unused
112 \param doc Document to be saved
113 \param uri Filename to save to (probably will end in .pdf)
115 The most interesting thing that this function does is just attach
116 an '>' on the front of the filename. This is the syntax used to
117 tell the printing system to save to file.
118 */
119 void
120 CairoRendererPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
121 {
122 Inkscape::Extension::Extension * ext;
123 unsigned int ret;
125 ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
126 if (ext == NULL)
127 return;
129 const gchar *new_level = NULL;
130 int level = 0;
131 try {
132 new_level = mod->get_param_enum("PDFversion");
133 // if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.x", new_level) == 0))
134 // level = 1;
135 }
136 catch(...) {
137 // g_warning("Parameter <PDFversion> might not exist");
138 }
140 bool new_textToPath = FALSE;
141 try {
142 new_textToPath = mod->get_param_bool("textToPath");
143 }
144 catch(...) {
145 g_warning("Parameter <textToPath> might not exist");
146 }
148 bool new_blurToBitmap = FALSE;
149 try {
150 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
151 }
152 catch(...) {
153 g_warning("Parameter <blurToBitmap> might not exist");
154 }
156 int new_bitmapResolution = 72;
157 try {
158 new_bitmapResolution = mod->get_param_int("resolution");
159 }
160 catch(...) {
161 g_warning("Parameter <resolution> might not exist");
162 }
164 const gchar *new_exportId = NULL;
165 try {
166 new_exportId = mod->get_param_string("exportId");
167 }
168 catch(...) {
169 g_warning("Parameter <exportId> might not exist");
170 }
172 bool new_exportDrawing = FALSE;
173 try {
174 new_exportDrawing = mod->get_param_bool("areaDrawing");
175 }
176 catch(...) {
177 g_warning("Parameter <areaDrawing> might not exist");
178 }
180 bool new_exportCanvas = FALSE;
181 try {
182 new_exportCanvas = mod->get_param_bool("areaCanvas");
183 }
184 catch(...) {
185 g_warning("Parameter <exportCanvas> might not exist");
186 }
188 gchar * final_name;
189 final_name = g_strdup_printf("> %s", uri);
190 ret = pdf_render_document_to_file(doc, final_name, level,
191 new_textToPath, new_blurToBitmap, new_bitmapResolution,
192 new_exportId, new_exportDrawing, new_exportCanvas);
193 g_free(final_name);
195 if (!ret)
196 throw Inkscape::Extension::Output::save_failed();
197 }
199 #include "clear-n_.h"
201 /**
202 \brief A function allocate a copy of this function.
204 This is the definition of Cairo PDF out. This function just
205 calls the extension system with the memory allocated XML that
206 describes the data.
207 */
208 void
209 CairoRendererPdfOutput::init (void)
210 {
211 Inkscape::Extension::build_from_mem(
212 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
213 "<name>Portable Document Format</name>\n"
214 "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
215 "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
216 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
217 "</param>\n"
218 "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
219 "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert filter effects to bitmaps") "\" type=\"boolean\">false</param>\n"
220 "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n"
221 "<param name=\"areaDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n"
222 "<param name=\"areaCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n"
223 "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
224 "<output>\n"
225 "<extension>.pdf</extension>\n"
226 "<mimetype>application/pdf</mimetype>\n"
227 "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
228 "<filetypetooltip>PDF File</filetypetooltip>\n"
229 "</output>\n"
230 "</inkscape-extension>", new CairoRendererPdfOutput());
232 return;
233 }
235 } } } /* namespace Inkscape, Extension, Internal */
237 #endif /* HAVE_CAIRO_PDF */