Code

Filters. New Chromolitho custom predefined filter (experimental). Some UI (notebooks...
[inkscape.git] / src / extension / internal / cairo-renderer-pdf-out.cpp
index 5d27656609ab8bcfe34acf8261d1ddfc425691e3..32df1193b97730eac1072dd09be3c484a2956c77 100644 (file)
-/*\r
- * A quick hack to use the Cairo renderer to write out a file.  This\r
- * then makes 'save as...' PDF.\r
- *\r
- * Authors:\r
- *   Ted Gould <ted@gould.cx>\r
- *   Ulf Erikson <ulferikson@users.sf.net>\r
- *\r
- * Copyright (C) 2004-2006 Authors\r
- *\r
- * Released under GNU GPL, read the file 'COPYING' for more information\r
- */\r
-\r
-#ifdef HAVE_CONFIG_H\r
-# include <config.h>\r
-#endif\r
-\r
-#ifdef HAVE_CAIRO_PDF\r
-\r
-#include "cairo-renderer-pdf-out.h"\r
-#include "cairo-render-context.h"\r
-#include "cairo-renderer.h"\r
-#include <print.h>\r
-#include "extension/system.h"\r
-#include "extension/print.h"\r
-#include "extension/db.h"\r
-#include "extension/output.h"\r
-#include "display/nr-arena.h"\r
-#include "display/nr-arena-item.h"\r
-\r
-#include <libnr/n-art-bpath.h>\r
-\r
-#include "display/curve.h"\r
-#include "display/canvas-bpath.h"\r
-#include "sp-item.h"\r
-#include "sp-root.h"\r
-\r
-namespace Inkscape {\r
-namespace Extension {\r
-namespace Internal {\r
-\r
-bool\r
-CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)\r
-{\r
-       return TRUE;\r
-}\r
-\r
-static bool\r
-pdf_render_document_to_file(SPDocument *doc, gchar const *filename)\r
-{\r
-    sp_document_ensure_up_to_date(doc);\r
-\r
-/* Start */\r
-    /* Create new arena */\r
-    SPItem *base = SP_ITEM(sp_document_root(doc));\r
-    NRArena *arena = NRArena::create();\r
-    unsigned dkey = sp_item_display_key_new(1);\r
-    NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);\r
-    \r
-    /* Create renderer and context */\r
-    CairoRenderer *renderer = new CairoRenderer();\r
-    CairoRenderContext *ctx = renderer->createContext();\r
-    ctx->setPdfTarget (filename);\r
-    bool ret = renderer->setupDocument(ctx, doc);\r
-    if (ret) {\r
-        renderer->renderItem(ctx, base);\r
-        ret = ctx->finish();\r
-    }\r
-\r
-    /* Release arena */\r
-    sp_item_invoke_hide(base, dkey);\r
-    nr_arena_item_unref(root);\r
-    nr_object_unref((NRObject *) arena);\r
-/* end */\r
-    renderer->destroyContext(ctx);\r
-    delete renderer;\r
-\r
-    return ret;\r
-}\r
-\r
-\r
-/**\r
-    \brief  This function calls the output module with the filename\r
-       \param  mod   unused\r
-       \param  doc   Document to be saved\r
-    \param  uri   Filename to save to (probably will end in .png)\r
-\r
-       The most interesting thing that this function does is just attach\r
-       an '>' on the front of the filename.  This is the syntax used to\r
-       tell the printing system to save to file.\r
-*/\r
-void\r
-CairoRendererPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)\r
-{\r
-    gchar * final_name;\r
-    final_name = g_strdup_printf("> %s", uri);\r
-    bool ret = pdf_render_document_to_file(doc, final_name);\r
-    g_free(final_name);\r
-\r
-    if (!ret)\r
-        throw Inkscape::Extension::Output::save_failed();\r
-\r
-       return;\r
-}\r
-\r
-/**\r
-       \brief   A function allocate a copy of this function.\r
-\r
-       This is the definition of Cairo PDF out.  This function just\r
-       calls the extension system with the memory allocated XML that\r
-       describes the data.\r
-*/\r
-void\r
-CairoRendererPdfOutput::init (void)\r
-{\r
-       Inkscape::Extension::build_from_mem(\r
-               "<inkscape-extension>\n"\r
-            "<name>Cairo PDF Output (experimental)</name>\n"\r
-                       "<id>org.inkscape.output.pdf.cairorenderer</id>\n"\r
-                       "<output>\n"\r
-                               "<extension>.pdf</extension>\n"\r
-                               "<mimetype>application/pdf</mimetype>\n"\r
-                               "<filetypename>Cairo PDF experimental (*.pdf)</filetypename>\n"\r
-                               "<filetypetooltip>PDF File</filetypetooltip>\n"\r
-                       "</output>\n"\r
-               "</inkscape-extension>", new CairoRendererPdfOutput());\r
-\r
-       return;\r
-}\r
-\r
-} } }  /* namespace Inkscape, Extension, Internal */\r
-\r
-#endif /* HAVE_CAIRO_PDF */\r
+/*
+ * A quick hack to use the Cairo renderer to write out a file.  This
+ * then makes 'save as...' PDF.
+ *
+ * Authors:
+ *   Ted Gould <ted@gould.cx>
+ *   Ulf Erikson <ulferikson@users.sf.net>
+ *   Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2004-2010 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_CAIRO_PDF
+
+#include "cairo-renderer-pdf-out.h"
+#include "cairo-render-context.h"
+#include "cairo-renderer.h"
+#include "latex-text-renderer.h"
+#include <print.h>
+#include "extension/system.h"
+#include "extension/print.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+
+#include "display/curve.h"
+#include "display/canvas-bpath.h"
+#include "sp-item.h"
+#include "sp-root.h"
+
+#include <2geom/matrix.h>
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+bool
+CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module)
+{
+    if (NULL == Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer"))
+        return FALSE;
+
+    return TRUE;
+}
+
+static bool
+pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level,
+                            bool texttopath, bool omittext, bool filtertobitmap, int resolution,
+                            const gchar * const exportId, bool exportDrawing, bool exportCanvas)
+{
+    sp_document_ensure_up_to_date(doc);
+
+/* Start */
+
+    SPItem *base = NULL;
+
+    bool pageBoundingBox = TRUE;
+    if (exportId && strcmp(exportId, "")) {
+        // we want to export the given item only
+        base = SP_ITEM(doc->getObjectById(exportId));
+        pageBoundingBox = exportCanvas;
+    }
+    else {
+        // we want to export the entire document from root
+        base = SP_ITEM(sp_document_root(doc));
+        pageBoundingBox = !exportDrawing;
+    }
+
+    if (!base)
+        return false;
+    
+    /* Create new arena */
+    NRArena *arena = NRArena::create();
+    nr_arena_set_renderoffscreen (arena);
+    unsigned dkey = sp_item_display_key_new(1);
+    sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY);
+
+    /* Create renderer and context */
+    CairoRenderer *renderer = new CairoRenderer();
+    CairoRenderContext *ctx = renderer->createContext();
+    ctx->setPDFLevel(level);
+    ctx->setTextToPath(texttopath);
+    renderer->_omitText = omittext;
+    ctx->setFilterToBitmap(filtertobitmap);
+    ctx->setBitmapResolution(resolution);
+
+    bool ret = ctx->setPdfTarget (filename);
+    if(ret) {
+        /* Render document */
+        ret = renderer->setupDocument(ctx, doc, pageBoundingBox, base);
+        if (ret) {
+            renderer->renderItem(ctx, base);
+            ret = ctx->finish();
+        }
+    }
+
+    /* Release arena */
+    sp_item_invoke_hide(base, dkey);
+    nr_object_unref((NRObject *) arena);
+
+    renderer->destroyContext(ctx);
+    delete renderer;
+
+    return ret;
+}
+
+/**
+    \brief  This function calls the output module with the filename
+    \param  mod   unused
+    \param  doc   Document to be saved
+    \param  filename   Filename to save to (probably will end in .pdf)
+
+    The most interesting thing that this function does is just attach
+    an '>' on the front of the filename.  This is the syntax used to
+    tell the printing system to save to file.
+*/
+void
+CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
+{
+    Inkscape::Extension::Extension * ext;
+    unsigned int ret;
+
+    ext = Inkscape::Extension::db.get("org.inkscape.output.pdf.cairorenderer");
+    if (ext == NULL)
+        return;
+
+    const gchar *new_level = NULL;
+    int level = 0;
+    try {
+        new_level = mod->get_param_enum("PDFversion");
+        if((new_level != NULL) && (g_ascii_strcasecmp("PDF-1.5", new_level) == 0))
+            level = 1;
+    }
+    catch(...) {
+        g_warning("Parameter <PDFversion> might not exist");
+    }
+
+    bool new_textToPath  = FALSE;
+    try {
+        new_textToPath  = mod->get_param_bool("textToPath");
+    }
+    catch(...) {
+        g_warning("Parameter <textToPath> might not exist");
+    }
+
+    bool new_textToLaTeX  = FALSE;
+    try {
+        new_textToLaTeX  = mod->get_param_bool("textToLaTeX");
+    }
+    catch(...) {
+        g_warning("Parameter <textToLaTeX> might not exist");
+    }
+
+    bool new_blurToBitmap  = FALSE;
+    try {
+        new_blurToBitmap  = mod->get_param_bool("blurToBitmap");
+    }
+    catch(...) {
+        g_warning("Parameter <blurToBitmap> might not exist");
+    }
+
+    int new_bitmapResolution  = 72;
+    try {
+        new_bitmapResolution = mod->get_param_int("resolution");
+    }
+    catch(...) {
+        g_warning("Parameter <resolution> might not exist");
+    }
+
+    const gchar *new_exportId = NULL;
+    try {
+        new_exportId = mod->get_param_string("exportId");
+    }
+    catch(...) {
+        g_warning("Parameter <exportId> might not exist");
+    }
+
+    bool new_exportDrawing  = FALSE;
+    try {
+        new_exportDrawing  = mod->get_param_bool("areaDrawing");
+    }
+    catch(...) {
+        g_warning("Parameter <areaDrawing> might not exist");
+    }
+
+    bool new_exportCanvas  = FALSE;
+    try {
+        new_exportCanvas  = mod->get_param_bool("areaPage");
+    }
+    catch(...) {
+        g_warning("Parameter <exportCanvas> might not exist");
+    }
+
+    // Create PDF file
+    {
+        gchar * final_name;
+        final_name = g_strdup_printf("> %s", filename);
+        ret = pdf_render_document_to_file(doc, final_name, level,
+                                          new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution,
+                                          new_exportId, new_exportDrawing, new_exportCanvas);
+        g_free(final_name);
+
+        if (!ret)
+            throw Inkscape::Extension::Output::save_failed();
+    }
+
+    // Create LaTeX file (if requested)
+    if (new_textToLaTeX) {
+        ret = latex_render_document_text_to_file(doc, filename, new_exportId, new_exportDrawing, new_exportCanvas, true);
+
+        if (!ret)
+            throw Inkscape::Extension::Output::save_failed();
+    }
+}
+
+#include "clear-n_.h"
+
+/**
+       \brief   A function allocate a copy of this function.
+
+       This is the definition of Cairo PDF out.  This function just
+       calls the extension system with the memory allocated XML that
+       describes the data.
+*/
+void
+CairoRendererPdfOutput::init (void)
+{
+       Inkscape::Extension::build_from_mem(
+               "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+                       "<name>Portable Document Format</name>\n"
+                       "<id>org.inkscape.output.pdf.cairorenderer</id>\n"
+                       "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version:") "\" type=\"enum\" >\n"
+#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0))
+                               "<_item value='PDF-1.5'>" N_("PDF 1.5") "</_item>\n"
+#endif
+                "<_item value='PDF-1.4'>" N_("PDF 1.4") "</_item>\n"
+                       "</param>\n"
+                       "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n"
+                       "<param name=\"textToLaTeX\" gui-text=\"" N_("PDF+LaTeX: Omit text in PDF, and create LaTeX file") "\" type=\"boolean\">false</param>\n"
+                       "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n"
+                       "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n"
+                       "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n"
+                       "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">false</param>\n"
+                       "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID:") "\" type=\"string\"></param>\n"
+                       "<output>\n"
+                               "<extension>.pdf</extension>\n"
+                               "<mimetype>application/pdf</mimetype>\n"
+                               "<filetypename>Portable Document Format (*.pdf)</filetypename>\n"
+                               "<filetypetooltip>PDF File</filetypetooltip>\n"
+                       "</output>\n"
+               "</inkscape-extension>", new CairoRendererPdfOutput());
+
+       return;
+}
+
+} } }  /* namespace Inkscape, Extension, Internal */
+
+#endif /* HAVE_CAIRO_PDF */