Code

initial work, plugging in a LaTeX renderer to write the text stuff to a .tex file...
[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     /* Render document */
142     bool ret = renderer->setupDocument(doc, pageBoundingBox, base);
143     if (ret) {
144         renderer->renderItem(base);
145     }
147     delete renderer;
149     return ret;
153 /**
154     \brief  This function calls the output module with the filename
155     \param  mod   unused
156     \param  doc   Document to be saved
157     \param  filename   Filename to save to (probably will end in .pdf)
159     The most interesting thing that this function does is just attach
160     an '>' on the front of the filename.  This is the syntax used to
161     tell the printing system to save to file.
162 */
163 void
164 CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
166     Inkscape::Extension::Extension * ext;
167     unsigned int ret;
169     ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
170     if (ext == NULL)
171         return;
173     const gchar *new_level = NULL;
174     int level = 0;
175     try {
176         new_level = mod->get_param_enum("PDFversion");
177 //        if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.x", new_level) == 0))
178 //            level = 1;
179     }
180     catch(...) {
181 //        g_warning("Parameter <PDFversion> might not exist");
182     }
184     bool new_textToPath  = FALSE;
185     try {
186         new_textToPath  = mod->get_param_bool("textToPath");
187     }
188     catch(...) {
189         g_warning("Parameter <textToPath> might not exist");
190     }
192     bool new_textToLaTeX  = FALSE;
193     try {
194         new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
195     }
196     catch(...) {
197         g_warning("Parameter <textToLaTeX> might not exist");
198     }
200     bool new_blurToBitmap  = FALSE;
201     try {
202         new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
203     }
204     catch(...) {
205         g_warning("Parameter <blurToBitmap> might not exist");
206     }
208     int new_bitmapResolution  = 72;
209     try {
210         new_bitmapResolution = mod->get_param_int("resolution");
211     }
212     catch(...) {
213         g_warning("Parameter <resolution> might not exist");
214     }
216     const gchar *new_exportId = NULL;
217     try {
218         new_exportId = mod->get_param_string("exportId");
219     }
220     catch(...) {
221         g_warning("Parameter <exportId> might not exist");
222     }
224     bool new_exportDrawing  = FALSE;
225     try {
226         new_exportDrawing  = mod->get_param_bool("areaDrawing");
227     }
228     catch(...) {
229         g_warning("Parameter <areaDrawing> might not exist");
230     }
232     bool new_exportCanvas  = FALSE;
233     try {
234         new_exportCanvas  = mod->get_param_bool("areaPage");
235     }
236     catch(...) {
237         g_warning("Parameter <exportCanvas> might not exist");
238     }
240     // Create PDF file
241     {
242         gchar * final_name;
243         final_name = g_strdup_printf("> %s", filename);
244         ret = pdf_render_document_to_file(doc, final_name, level,
245                                           new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution,
246                                           new_exportId, new_exportDrawing, new_exportCanvas);
247         g_free(final_name);
249         if (!ret)
250             throw Inkscape::Extension::Output::save_failed();
251     }
253     // Create LaTeX file (if requested)
254     if (new_textToLaTeX) {
255         gchar * tex_filename;
256         tex_filename = g_strdup_printf("%s.tex", filename);
257         ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas);
258         g_free(tex_filename);
260         if (!ret)
261             throw Inkscape::Extension::Output::save_failed();
262     }
265 #include "clear-n_.h"
267 /**
268         \brief   A function allocate a copy of this function.
270         This is the definition of Cairo PDF out.  This function just
271         calls the extension system with the memory allocated XML that
272         describes the data.
273 */
274 void
275 CairoRendererPdfOutput::init (void)
277         Inkscape::Extension::build_from_mem(
278                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
279                         "<name>Portable Document Format</name>\n"
280                         "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
281                         "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n"
282                                 "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n"
283                         "</param>\n"
284                         "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
285                         "<param name=\"textToLaTeX\" gui-text=\"" N_("Exclude text, create LaTeX file") "\" type=\"boolean\">false</param>\n"
286                         "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
287                         "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
288                         "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n"
289                         "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">false</param>\n"
290                         "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n"
291                         "<output>\n"
292                                 "<extension>.pdf</extension>\n"
293                                 "<mimetype>application/pdf</mimetype>\n"
294                                 "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
295                                 "<filetypetooltip>PDF File</filetypetooltip>\n"
296                         "</output>\n"
297                 "</inkscape-extension>", new CairoRendererPdfOutput());
299         return;
302 } } }  /* namespace Inkscape, Extension, Internal */
304 #endif /* HAVE_CAIRO_PDF */