Code

Merge from fe-moved
[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     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;
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)
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();
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)
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\">true</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;
235 } } }  /* namespace Inkscape, Extension, Internal */
237 #endif /* HAVE_CAIRO_PDF */