From ddc1f1d1291eb21b244c7328d260c7d4a43be2fc Mon Sep 17 00:00:00 2001 From: buliabyak Date: Fri, 29 Aug 2008 00:46:35 +0000 Subject: [PATCH] Ulf Ericson's patch for implementing missing properties in the new pdf exporter --- src/extension/internal/cairo-png-out.cpp | 2 +- src/extension/internal/cairo-ps-out.cpp | 2 +- .../internal/cairo-renderer-pdf-out.cpp | 143 +++++++++++++++--- src/extension/internal/cairo-renderer.cpp | 22 ++- src/extension/internal/cairo-renderer.h | 2 +- src/ui/dialog/print.cpp | 2 +- 6 files changed, 146 insertions(+), 27 deletions(-) diff --git a/src/extension/internal/cairo-png-out.cpp b/src/extension/internal/cairo-png-out.cpp index e56158970..6a7295dd8 100644 --- a/src/extension/internal/cairo-png-out.cpp +++ b/src/extension/internal/cairo-png-out.cpp @@ -67,7 +67,7 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename) ctx = renderer->createContext(); /* Render document */ - bool ret = renderer->setupDocument(ctx, doc); + bool ret = renderer->setupDocument(ctx, doc, TRUE, NULL); if (ret) { renderer->renderItem(ctx, base); ctx->saveAsPng(filename); diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 735c3cf7a..fa35079f9 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -76,7 +76,7 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l bool ret = ctx->setPsTarget(filename); if(ret) { /* Render document */ - ret = renderer->setupDocument(ctx, doc); + ret = renderer->setupDocument(ctx, doc, TRUE, NULL); if (ret) { renderer->renderItem(ctx, base); ret = ctx->finish(); diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 6c727a479..788791c31 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -40,17 +40,39 @@ namespace Internal { bool CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module) { - return TRUE; + 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) +pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, + bool texttopath, 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 */ - SPItem *base = SP_ITEM(sp_document_root(doc)); NRArena *arena = NRArena::create(); unsigned dkey = sp_item_display_key_new(1); NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY); @@ -58,11 +80,19 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename) /* Create renderer and context */ CairoRenderer *renderer = new CairoRenderer(); CairoRenderContext *ctx = renderer->createContext(); - ctx->setPdfTarget (filename); - bool ret = renderer->setupDocument(ctx, doc); - if (ret) { - renderer->renderItem(ctx, base); - ret = ctx->finish(); + ctx->setPDFLevel(level); + ctx->setTextToPath(texttopath); + 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 */ @@ -79,28 +109,98 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename) /** \brief This function calls the output module with the filename - \param mod unused - \param doc Document to be saved - \param uri Filename to save to (probably will end in .png) + \param mod unused + \param doc Document to be saved + \param uri 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. + 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, const gchar *uri) { + 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.x", new_level) == 0)) +// level = 1; + } + catch(...) { +// g_warning("Parameter might not exists"); + } + + bool new_textToPath = FALSE; + try { + new_textToPath = mod->get_param_bool("textToPath"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + + bool new_blurToBitmap = FALSE; + try { + new_blurToBitmap = mod->get_param_bool("blurToBitmap"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + + int new_bitmapResolution = 72; + try { + new_bitmapResolution = mod->get_param_int("resolution"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + + const gchar *new_exportId = NULL; + try { + new_exportId = mod->get_param_string("exportId"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + + bool new_exportDrawing = FALSE; + try { + new_exportDrawing = mod->get_param_bool("exportDrawing"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + + bool new_exportCanvas = FALSE; + try { + new_exportCanvas = mod->get_param_bool("exportCanvas"); + } + catch(...) { + g_warning("Parameter might not exists"); + } + gchar * final_name; final_name = g_strdup_printf("> %s", uri); - bool ret = pdf_render_document_to_file(doc, final_name); + ret = pdf_render_document_to_file(doc, final_name, level, + new_textToPath, new_blurToBitmap, new_bitmapResolution, + new_exportId, new_exportDrawing, new_exportCanvas); g_free(final_name); if (!ret) throw Inkscape::Extension::Output::save_failed(); - return; + return; } +#include "clear-n_.h" + /** \brief A function allocate a copy of this function. @@ -113,8 +213,17 @@ CairoRendererPdfOutput::init (void) { Inkscape::Extension::build_from_mem( "\n" - "Cairo PDF Output (experimental)\n" + "Cairo PDF Output (experimental)\n" "org.inkscape.output.pdf.cairorenderer\n" + "\n" + "<_item value='PDF14'>" N_("PDF 1.4") "\n" + "\n" + "false\n" + "false\n" + "90\n" + "false\n" + "false\n" + "\n" "\n" ".pdf\n" "application/pdf\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 8c27632e1..8d4b95f85 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -621,7 +621,7 @@ CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) } bool -CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc) +CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, SPItem *base) { g_assert( ctx != NULL ); @@ -635,14 +635,12 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc) } NRRect d; - bool pageBoundingBox = true; - if (pageBoundingBox) { + if (pageBoundingBox || !base) { d.x0 = d.y0 = 0; d.x1 = ceil(ctx->_width); d.y1 = ceil(ctx->_height); } else { - SPItem* doc_item = SP_ITEM(sp_document_root(doc)); - sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE); + sp_item_invoke_bbox(base, &d, sp_item_i2r_affine(base), TRUE); if (ctx->_vector_based_target) { // convert from px to pt d.x0 *= PT_PER_PX; @@ -653,7 +651,19 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc) } TRACE(("%f x %f\n", ctx->_width, ctx->_height)); - return ctx->setupSurface(d.x1-d.x0, d.y1-d.y0); + bool ret = ctx->setupSurface(d.x1-d.x0, d.y1-d.y0); + + if (ret && !pageBoundingBox && base) + { + Geom::Matrix tp(Geom::Translate(-d.x0 * (ctx->_vector_based_target ? PX_PER_PT : 1.0), + (d.y1 - ctx->_height) * (ctx->_vector_based_target ? PX_PER_PT : 1.0))); + ctx->transform(&tp); + + ctx->_width = d.x1 - d.x0; + ctx->_height = d.y1 - d.y0; + } + + return ret; } #include "macros.h" // SP_PRINT_* diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h index 4056a8697..147472407 100644 --- a/src/extension/internal/cairo-renderer.h +++ b/src/extension/internal/cairo-renderer.h @@ -53,7 +53,7 @@ public: /** Initializes the CairoRenderContext according to the specified SPDocument. A set*Target function can only be called on the context before setupDocument. */ - bool setupDocument(CairoRenderContext *ctx, SPDocument *doc); + bool setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, SPItem *base); /** Traverses the object tree and invokes the render methods. */ void renderItem(CairoRenderContext *ctx, SPItem *item); diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index d45f1374e..474b57306 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -164,7 +164,7 @@ draw_page (GtkPrintOperation */*operation*/, #endif bool ret = ctx->setSurfaceTarget (surface, true); if (ret) { - ret = renderer.setupDocument (ctx, junk->_doc); + ret = renderer.setupDocument (ctx, junk->_doc, TRUE, NULL); if (ret) { renderer.renderItem(ctx, junk->_base); ret = ctx->finish(); -- 2.30.2