Code

output test.tex instead of test.pdf.tex which does not work well. strip path from...
[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 "pdflatex-renderer.h"
24 #include <print.h>
25 #include "extension/system.h"
26 #include "extension/print.h"
27 #include "extension/db.h"
28 #include "extension/output.h"
29 #include "display/nr-arena.h"
30 #include "display/nr-arena-item.h"
32 #include "display/curve.h"
33 #include "display/canvas-bpath.h"
34 #include "sp-item.h"
35 #include "sp-root.h"
37 #include <2geom/matrix.h>
39 namespace Inkscape {
40 namespace Extension {
41 namespace Internal {
43 bool
44 CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)
45 {
46     if (NULL == Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer"))
47         return FALSE;
49     return TRUE;
50 }
52 static bool
53 pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level,
54                             bool texttopath, bool omittext, bool filtertobitmap, int resolution,
55                             const gchar * const exportId, bool exportDrawing, bool exportCanvas)
56 {
57     sp_document_ensure_up_to_date(doc);
59 /* Start */
61     SPItem *base = NULL;
63     bool pageBoundingBox = TRUE;
64     if (exportId && strcmp(exportId, "")) {
65         // we want to export the given item only
66         base = SP_ITEM(doc->getObjectById(exportId));
67         pageBoundingBox = exportCanvas;
68     }
69     else {
70         // we want to export the entire document from root
71         base = SP_ITEM(sp_document_root(doc));
72         pageBoundingBox = !exportDrawing;
73     }
75     if (!base)
76         return false;
77     
78     /* Create new arena */
79     NRArena *arena = NRArena::create();
80     nr_arena_set_renderoffscreen (arena);
81     unsigned dkey = sp_item_display_key_new(1);
82     sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
84     /* Create renderer and context */
85     CairoRenderer *renderer = new CairoRenderer();
86     CairoRenderContext *ctx = renderer->createContext();
87     ctx->setPDFLevel(level);
88     ctx->setTextToPath(texttopath);
89     renderer->_omitText = omittext;
90     ctx->setFilterToBitmap(filtertobitmap);
91     ctx->setBitmapResolution(resolution);
93     bool ret = ctx->setPdfTarget (filename);
94     if(ret) {
95         /* Render document */
96         ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
97         if (ret) {
98             renderer->renderItem(ctx, base);
99             ret = ctx->finish();
100         }
101     }
103     /* Release arena */
104     sp_item_invoke_hide(base, dkey);
105     nr_object_unref((NRObject *) arena);
107     renderer->destroyContext(ctx);
108     delete renderer;
110     return ret;
113 static bool
114 latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, 
115                                     const gchar * const exportId, bool exportDrawing, bool exportCanvas)
117     sp_document_ensure_up_to_date(doc);
119 /* Start */
121     SPItem *base = NULL;
123     bool pageBoundingBox = true;
124     if (exportId && strcmp(exportId, "")) {
125         // we want to export the given item only
126         base = SP_ITEM(doc->getObjectById(exportId));
127         pageBoundingBox = exportCanvas;
128     }
129     else {
130         // we want to export the entire document from root
131         base = SP_ITEM(sp_document_root(doc));
132         pageBoundingBox = !exportDrawing;
133     }
135     if (!base)
136         return false;
138     /* Create renderer */
139     PDFLaTeXRenderer *renderer = new PDFLaTeXRenderer();
141     bool ret = renderer->setTargetFile(filename);
142     if (ret) {
143         /* Render document */
144         bool ret = renderer->setupDocument(doc, pageBoundingBox, base);
145         if (ret) {
146             renderer->renderItem(base);
147         }
148     }
150     delete renderer;
152     return ret;
156 /**
157     \brief  This function calls the output module with the filename
158     \param  mod   unused
159     \param  doc   Document to be saved
160     \param  filename   Filename to save to (probably will end in .pdf)
162     The most interesting thing that this function does is just attach
163     an '>' on the front of the filename.  This is the syntax used to
164     tell the printing system to save to file.
165 */
166 void
167 CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
169     Inkscape::Extension::Extension * ext;
170     unsigned int ret;
172     ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
173     if (ext == NULL)
174         return;
176     const gchar *new_level = NULL;
177     int level = 0;
178     try {
179         new_level = mod->get_param_enum("PDFversion");
180 //        if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.x", new_level) == 0))
181 //            level = 1;
182     }
183     catch(...) {
184 //        g_warning("Parameter <PDFversion> might not exist");
185     }
187     bool new_textToPath  = FALSE;
188     try {
189         new_textToPath  = mod->get_param_bool("textToPath");
190     }
191     catch(...) {
192         g_warning("Parameter <textToPath> might not exist");
193     }
195     bool new_textToLaTeX  = FALSE;
196     try {
197         new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
198     }
199     catch(...) {
200         g_warning("Parameter <textToLaTeX> might not exist");
201     }
203     bool new_blurToBitmap  = FALSE;
204     try {
205         new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
206     }
207     catch(...) {
208         g_warning("Parameter <blurToBitmap> might not exist");
209     }
211     int new_bitmapResolution  = 72;
212     try {
213         new_bitmapResolution = mod->get_param_int("resolution");
214     }
215     catch(...) {
216         g_warning("Parameter <resolution> might not exist");
217     }
219     const gchar *new_exportId = NULL;
220     try {
221         new_exportId = mod->get_param_string("exportId");
222     }
223     catch(...) {
224         g_warning("Parameter <exportId> might not exist");
225     }
227     bool new_exportDrawing  = FALSE;
228     try {
229         new_exportDrawing  = mod->get_param_bool("areaDrawing");
230     }
231     catch(...) {
232         g_warning("Parameter <areaDrawing> might not exist");
233     }
235     bool new_exportCanvas  = FALSE;
236     try {
237         new_exportCanvas  = mod->get_param_bool("areaPage");
238     }
239     catch(...) {
240         g_warning("Parameter <exportCanvas> might not exist");
241     }
243     // Create PDF file
244     {
245         gchar * final_name;
246         final_name = g_strdup_printf("> %s", filename);
247         ret = pdf_render_document_to_file(doc, final_name, level,
248                                           new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution,
249                                           new_exportId, new_exportDrawing, new_exportCanvas);
250         g_free(final_name);
252         if (!ret)
253             throw Inkscape::Extension::Output::save_failed();
254     }
256     // Create LaTeX file (if requested)
257     if (new_textToLaTeX) {
258         gchar * tex_filename;
259         //strip filename of ".pdf", do not add ".tex" here.
260         gsize n = g_str_has_suffix(filename, ".pdf") ? strlen(filename)-4 : strlen(filename);
261         tex_filename = g_strndup(filename, n);
262         ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas);
263         g_free(tex_filename);
265         if (!ret)
266             throw Inkscape::Extension::Output::save_failed();
267     }
270 #include "clear-n_.h"
272 /**
273         \brief   A function allocate a copy of this function.
275         This is the definition of Cairo PDF out.  This function just
276         calls the extension system with the memory allocated XML that
277         describes the data.
278 */
279 void
280 CairoRendererPdfOutput::init (void)
282         Inkscape::Extension::build_from_mem(
283                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
284                         "<name>Portable Document Format</name>\n"
285                         "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
286                         "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
287                                 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
288                         "</param>\n"
289                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
290                         "<param name=\"textToLaTeX\" gui-text=\"" N_("Exclude text, create LaTeX file") "\" type=\"boolean\">false</param>\n"
291                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
292                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
293                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n"
294                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">false</param>\n"
295                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
296                         "<output>\n"
297                                 "<extension>.pdf</extension>\n"
298                                 "<mimetype>application/pdf</mimetype>\n"
299                                 "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
300                                 "<filetypetooltip>PDF File</filetypetooltip>\n"
301                         "</output>\n"
302                 "</inkscape-extension>", new CairoRendererPdfOutput());
304         return;
307 } } }  /* namespace Inkscape, Extension, Internal */
309 #endif /* HAVE_CAIRO_PDF */