Code

remove cairo and experimental from the name; now this is THE pdf exporter
[inkscape.git] / src / extension / internal / cairo-renderer-pdf-out.cpp
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;
74     
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;
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)
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;
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)
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;
238 } } }  /* namespace Inkscape, Extension, Internal */
240 #endif /* HAVE_CAIRO_PDF */