From 31bb8269c26a781036448ed8f8cd93cc84fb2118 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 29 Nov 2009 16:33:18 +0100 Subject: First GSoC node tool commit to Bazaar (bzr r8846.1.1) --- src/extension/dxf2svg/entities2elements.cpp | 10 ++++++---- src/extension/dxf2svg/read_dxf.cpp | 10 ++++++---- src/extension/dxf2svg/tables2svg_info.cpp | 8 +++++--- src/extension/internal/cairo-renderer.cpp | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/extension') diff --git a/src/extension/dxf2svg/entities2elements.cpp b/src/extension/dxf2svg/entities2elements.cpp index cf42dac32..15d3e76ae 100644 --- a/src/extension/dxf2svg/entities2elements.cpp +++ b/src/extension/dxf2svg/entities2elements.cpp @@ -20,10 +20,12 @@ SoC 2005 */ -#include"entities2elements.h" -#include"tables2svg_info.h" -#include -#include +#include "entities2elements.h" +#include "tables2svg_info.h" +#include +#include +#include +#include // The names indicate the DXF entitiy first and the SVG element last // Common elements diff --git a/src/extension/dxf2svg/read_dxf.cpp b/src/extension/dxf2svg/read_dxf.cpp index 8a6a6d6ac..ecda343c6 100644 --- a/src/extension/dxf2svg/read_dxf.cpp +++ b/src/extension/dxf2svg/read_dxf.cpp @@ -11,11 +11,13 @@ -#include -#include -#include"read_dxf.h" +#include +#include +#include "read_dxf.h" -#include +#include +#include +#include using namespace std; diff --git a/src/extension/dxf2svg/tables2svg_info.cpp b/src/extension/dxf2svg/tables2svg_info.cpp index 17bc47beb..3b27a9c38 100644 --- a/src/extension/dxf2svg/tables2svg_info.cpp +++ b/src/extension/dxf2svg/tables2svg_info.cpp @@ -10,9 +10,11 @@ */ -#include"tables2svg_info.h" -#include -#include +#include "tables2svg_info.h" +#include +#include +#include +#include char* pattern2dasharray(ltype info, int precision, double scaling, char* out){ std::vector< double > pattern = info.ret_pattern(); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 8cc386135..0e68ae130 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -29,6 +29,7 @@ #include #include "libnr/nr-rect.h" +#include "libnrtype/Layout-TNG.h" #include <2geom/transforms.h> #include <2geom/pathvector.h> -- cgit v1.2.3 From 1607d480ed2a45fcdf68c428fd40f91ee2336e51 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 1 Jan 2010 23:15:16 -0800 Subject: Remove any "inkscape:*" or "sodipodi:*" attributes when saving as "plain SVG". Fixes bug #500440. Fixed bugs: - https://launchpad.net/bugs/500440 (bzr r8933) --- src/extension/internal/svg.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp index a3589e905..b10aa87ec 100644 --- a/src/extension/internal/svg.cpp +++ b/src/extension/internal/svg.cpp @@ -21,6 +21,7 @@ #include "extension/system.h" #include "extension/output.h" #include +#include "xml/attribute-record.h" #ifdef WITH_GNOME_VFS # include @@ -32,6 +33,37 @@ namespace Internal { #include "clear-n_.h" + +using Inkscape::Util::List; +using Inkscape::XML::AttributeRecord; +using Inkscape::XML::Node; + + + +void pruneExtendedAttributes( Inkscape::XML::Node *repr ) +{ + if (repr) { + if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) { + std::vector toBeRemoved; + for ( List it = repr->attributeList(); it; ++it ) { + const gchar* attrName = g_quark_to_string(it->key); + if ((strncmp("inkscape:", attrName, 9) == 0) || (strncmp("sodipodi:", attrName, 9) == 0)) { + toBeRemoved.push_back(attrName); + } + } + // Can't change the set we're interating over while we are iterating. + for ( std::vector::iterator it = toBeRemoved.begin(); it != toBeRemoved.end(); ++it ) { + repr->setAttribute(*it, 0); + } + } + + for ( Node *child = repr->firstChild(); child; child = child->next() ) { + pruneExtendedAttributes(child); + } + } +} + + /** \return None \brief What would an SVG editor be without loading/saving SVG @@ -179,7 +211,7 @@ Svg::open (Inkscape::Extension::Input */*mod*/, const gchar *uri) we're getting good data. It also checks the module ID of the incoming module to figure out whether this save should include the Inkscape namespace stuff or not. The result of that comparison - is stored in the spns variable. + is stored in the exportExtensions variable. If there is not to be Inkscape name spaces a new document is created without. (I think, I'm not sure on this code) @@ -198,18 +230,20 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena gchar *save_path = g_path_get_dirname(filename); - bool const spns = ( !mod->get_id() + bool const exportExtensions = ( !mod->get_id() || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE) || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE)); Inkscape::XML::Document *rdoc = NULL; Inkscape::XML::Node *repr = NULL; - if (spns) { + if (exportExtensions) { repr = sp_document_repr_root (doc); } else { rdoc = sp_repr_document_new ("svg:svg"); repr = rdoc->root(); repr = sp_document_root (doc)->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD); + + pruneExtendedAttributes(repr); } if (!sp_repr_save_rebased_file(repr->document(), filename, SP_SVG_NS_URI, @@ -217,7 +251,7 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena throw Inkscape::Extension::Output::save_failed(); } - if (!spns) { + if (!exportExtensions) { Inkscape::GC::release(rdoc); } -- cgit v1.2.3 From 473e7ed23c02cee40f316876daff4be728c2531d Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 21 Jan 2010 12:10:33 +1300 Subject: Fixing conts correctness. (bzr r9009) --- src/extension/internal/filter/filter.cpp | 4 +++- src/extension/internal/filter/filter.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index d98f8e9a2..30e622507 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -71,7 +71,9 @@ Filter::get_filter (Inkscape::Extension::Extension * ext) { } void -Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar * srcGraphic, gchar * srcGraphicAlpha) +Filter::merge_filters( Inkscape::XML::Node * to, Inkscape::XML::Node * from, + Inkscape::XML::Document * doc, + gchar const * srcGraphic, gchar const * srcGraphicAlpha) { if (from == NULL) return; diff --git a/src/extension/internal/filter/filter.h b/src/extension/internal/filter/filter.h index fe6b678d9..a5d5d9d4e 100644 --- a/src/extension/internal/filter/filter.h +++ b/src/extension/internal/filter/filter.h @@ -25,7 +25,7 @@ protected: private: Inkscape::XML::Document * get_filter (Inkscape::Extension::Extension * ext); - void merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar * srcGraphic = NULL, gchar * srcGraphicAlpha = NULL); + void merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar const * srcGraphic = NULL, gchar const * srcGraphicAlpha = NULL); public: Filter(); -- cgit v1.2.3 From 1c51deb0c68f8358e7db1501b6c0135364758c55 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 20 Feb 2010 22:01:12 +0100 Subject: add option to exclude/omit text from the PDF when saving to pdf (bzr r9101.1.1) --- src/extension/internal/cairo-renderer-pdf-out.cpp | 14 ++++++++++++-- src/extension/internal/cairo-renderer.cpp | 6 ++++++ src/extension/internal/cairo-renderer.h | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 0598c388a..a62d2cb14 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -48,7 +48,7 @@ CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module) static bool pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, - bool texttopath, bool filtertobitmap, int resolution, + bool texttopath, bool texttolatex, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas) { sp_document_ensure_up_to_date(doc); @@ -83,6 +83,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int CairoRenderContext *ctx = renderer->createContext(); ctx->setPDFLevel(level); ctx->setTextToPath(texttopath); + renderer->_omitText = texttolatex; ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); @@ -146,6 +147,14 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, g_warning("Parameter might not exist"); } + bool new_textToLaTeX = FALSE; + try { + new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + } + catch(...) { + g_warning("Parameter might not exist"); + } + bool new_blurToBitmap = FALSE; try { new_blurToBitmap = mod->get_param_bool("blurToBitmap"); @@ -189,7 +198,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar * final_name; final_name = g_strdup_printf("> %s", filename); ret = pdf_render_document_to_file(doc, final_name, level, - new_textToPath, new_blurToBitmap, new_bitmapResolution, + new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_exportDrawing, new_exportCanvas); g_free(final_name); @@ -217,6 +226,7 @@ CairoRendererPdfOutput::init (void) "<_item value='PDF14'>" N_("PDF 1.4") "\n" "\n" "false\n" + "false\n" "true\n" "90\n" "false\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 0e68ae130..6d75c1e5d 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -103,6 +103,7 @@ namespace Extension { namespace Internal { CairoRenderer::CairoRenderer(void) + : _omitText(false) {} CairoRenderer::~CairoRenderer(void) @@ -568,6 +569,11 @@ CairoRenderer::setStateForItem(CairoRenderContext *ctx, SPItem const *item) void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) { + if ( _omitText && (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) ) { + // skip text if _omitText is true + return; + } + ctx->pushState(); setStateForItem(ctx, item); diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h index ab5d4cf58..d69a60753 100644 --- a/src/extension/internal/cairo-renderer.h +++ b/src/extension/internal/cairo-renderer.h @@ -56,6 +56,10 @@ public: /** Traverses the object tree and invokes the render methods. */ void renderItem(CairoRenderContext *ctx, SPItem *item); + + /** If _omitText is true, no text will be output to the PDF document. + The PDF will be exactly the same as if the text was written to it and then erased. */ + bool _omitText; }; // FIXME: this should be a static method of CairoRenderer -- cgit v1.2.3 From 7b45e3a1ecaabfef62c786e59aeb8023981dfbba Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 20 Feb 2010 23:07:44 +0100 Subject: initial work, plugging in a LaTeX renderer to write the text stuff to a .tex file. implementation of renderer is all that is left to do :) (bzr r9101.1.2) --- src/extension/internal/CMakeLists.txt | 1 + src/extension/internal/Makefile_insert | 2 + src/extension/internal/cairo-renderer-pdf-out.cpp | 76 +++- src/extension/internal/cairo-renderer.cpp | 2 + src/extension/internal/pdflatex-renderer.cpp | 428 ++++++++++++++++++++++ src/extension/internal/pdflatex-renderer.h | 82 +++++ 6 files changed, 581 insertions(+), 10 deletions(-) create mode 100644 src/extension/internal/pdflatex-renderer.cpp create mode 100644 src/extension/internal/pdflatex-renderer.h (limited to 'src/extension') diff --git a/src/extension/internal/CMakeLists.txt b/src/extension/internal/CMakeLists.txt index c9c00e05b..3412b740c 100644 --- a/src/extension/internal/CMakeLists.txt +++ b/src/extension/internal/CMakeLists.txt @@ -20,6 +20,7 @@ latex-pstricks.cpp latex-pstricks-out.cpp odf.cpp pdfinput +pdflatex-renderer.cpp pdf-input-cairo.cpp pov-out.cpp javafx-out.cpp diff --git a/src/extension/internal/Makefile_insert b/src/extension/internal/Makefile_insert index d2ba9b3eb..881b3ec22 100644 --- a/src/extension/internal/Makefile_insert +++ b/src/extension/internal/Makefile_insert @@ -109,6 +109,8 @@ ink_common_sources += \ extension/internal/javafx-out.h \ extension/internal/gdkpixbuf-input.h \ extension/internal/gdkpixbuf-input.cpp \ + extension/internal/pdflatex-renderer.h \ + extension/internal/pdflatex-renderer.cpp \ extension/internal/pdfinput/svg-builder.h \ extension/internal/pdfinput/svg-builder.cpp \ extension/internal/pdfinput/pdf-parser.h \ diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index a62d2cb14..ba23f4bcc 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -20,6 +20,7 @@ #include "cairo-renderer-pdf-out.h" #include "cairo-render-context.h" #include "cairo-renderer.h" +#include "pdflatex-renderer.h" #include #include "extension/system.h" #include "extension/print.h" @@ -33,6 +34,8 @@ #include "sp-item.h" #include "sp-root.h" +#include <2geom/matrix.h> + namespace Inkscape { namespace Extension { namespace Internal { @@ -48,7 +51,7 @@ CairoRendererPdfOutput::check (Inkscape::Extension::Extension * module) static bool pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, - bool texttopath, bool texttolatex, bool filtertobitmap, int resolution, + bool texttopath, bool omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas) { sp_document_ensure_up_to_date(doc); @@ -83,7 +86,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int CairoRenderContext *ctx = renderer->createContext(); ctx->setPDFLevel(level); ctx->setTextToPath(texttopath); - renderer->_omitText = texttolatex; + renderer->_omitText = omittext; ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); @@ -107,6 +110,45 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int return ret; } +static bool +latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, + 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 renderer */ + PDFLaTeXRenderer *renderer = new PDFLaTeXRenderer(); + + /* Render document */ + bool ret = renderer->setupDocument(doc, pageBoundingBox, base); + if (ret) { + renderer->renderItem(base); + } + + delete renderer; + + return ret; +} + /** \brief This function calls the output module with the filename @@ -195,15 +237,29 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, g_warning("Parameter might not exist"); } - 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); + // 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) { + gchar * tex_filename; + tex_filename = g_strdup_printf("%s.tex", filename); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas); + g_free(tex_filename); - if (!ret) - throw Inkscape::Extension::Output::save_failed(); + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } } #include "clear-n_.h" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 6d75c1e5d..6e4bb3b7e 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -598,6 +598,8 @@ CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) bool CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, SPItem *base) { +// PLEASE note when making changes to the boundingbox and transform calculation, corresponding changes should be made to PDFLaTeXRenderer::setupDocument !!! + g_assert( ctx != NULL ); if (!base) diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp new file mode 100644 index 000000000..bcababf8e --- /dev/null +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -0,0 +1,428 @@ +#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_CPP + +/** \file + * Rendering LaTeX file (pdf+latex output) + */ +/* + * Authors: + * Johan Engelen + * Miklos Erdelyi + * + * Copyright (C) 2006-2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef PANGO_ENABLE_BACKEND +#define PANGO_ENABLE_BACKEND +#endif + +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + + +#include +#include + +#include "libnr/nr-rect.h" +#include "libnrtype/Layout-TNG.h" +#include <2geom/transforms.h> +#include <2geom/pathvector.h> + +#include + +#include +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" +#include "display/nr-arena-group.h" +#include "display/curve.h" +#include "display/canvas-bpath.h" +#include "sp-item.h" +#include "sp-item-group.h" +#include "style.h" +#include "marker.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-root.h" +#include "sp-use.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "sp-mask.h" +#include "sp-clippath.h" + +#include +#include "helper/png-write.h" +#include "helper/pixbuf-ops.h" + +#include "pdflatex-renderer.h" +#include "extension/system.h" + +#include "io/sys.h" + +#include + +// include support for only the compiled-in surface types +#ifdef CAIRO_HAS_PDF_SURFACE +#include +#endif +#ifdef CAIRO_HAS_PS_SURFACE +#include +#endif + +//#define TRACE(_args) g_printf _args +#define TRACE(_args) +//#define TEST(_args) _args +#define TEST(_args) + +// FIXME: expose these from sp-clippath/mask.cpp +struct SPClipPathView { + SPClipPathView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + +struct SPMaskView { + SPMaskView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + +namespace Inkscape { +namespace Extension { +namespace Internal { + +PDFLaTeXRenderer::PDFLaTeXRenderer(void) + : _m(Geom::identity()) +{} + +PDFLaTeXRenderer::~PDFLaTeXRenderer(void) +{ + /* restore default signal handling for SIGPIPE */ +#if !defined(_WIN32) && !defined(__WIN32__) + (void) signal(SIGPIPE, SIG_DFL); +#endif + + return; +} + +void +PDFLaTeXRenderer::sp_group_render(SPItem *item) +{ + SPGroup *group = SP_GROUP(item); + + GSList *l = g_slist_reverse(group->childList(false)); + while (l) { + SPObject *o = SP_OBJECT (l->data); + if (SP_IS_ITEM(o)) { + renderItem (SP_ITEM (o)); + } + l = g_slist_remove (l, o); + } +} + +void +PDFLaTeXRenderer::sp_use_render(SPItem *item) +{ +/* + bool translated = false; + SPUse *use = SP_USE(item); + + if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { + Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); + ctx->pushState(); + ctx->transform(&tp); + translated = true; + } + + if (use->child && SP_IS_ITEM(use->child)) { + renderItem(SP_ITEM(use->child)); + } + + if (translated) { + ctx->popState(); + } +*/ +} + +void +PDFLaTeXRenderer::sp_text_render(SPItem *item) +{ + SPText *group = SP_TEXT (item); +/* +implement +*/ +} + +void +PDFLaTeXRenderer::sp_flowtext_render(SPItem *item) +{ + SPFlowtext *group = SP_FLOWTEXT(item); +/* +implement +*/ +} + +void +PDFLaTeXRenderer::sp_root_render(SPItem *item) +{ + SPRoot *root = SP_ROOT(item); + +/* + if (!ctx->getCurrentState()->has_overflow && SP_OBJECT(item)->parent) + ctx->addClippingRect(root->x.computed, root->y.computed, root->width.computed, root->height.computed); + + ctx->pushState(); + setStateForItem(ctx, item); + Geom::Matrix tempmat (root->c2p); + ctx->transform(&tempmat); + sp_group_render(item, ctx); + ctx->popState(); +*/ +} + +void +PDFLaTeXRenderer::sp_item_invoke_render(SPItem *item) +{ + // Check item's visibility + if (item->isHidden()) { + return; + } + + if (SP_IS_ROOT(item)) { + TRACE(("root\n")); + return sp_root_render(item); + } else if (SP_IS_GROUP(item)) { + TRACE(("group\n")); + return sp_group_render(item); + } else if (SP_IS_USE(item)) { + TRACE(("use begin---\n")); + sp_use_render(item); + TRACE(("---use end\n")); + } else if (SP_IS_TEXT(item)) { + TRACE(("text\n")); + return sp_text_render(item); + } else if (SP_IS_FLOWTEXT(item)) { + TRACE(("flowtext\n")); + return sp_flowtext_render(item); + } + // We are not interested in writing the other SPItem types to LaTeX +} + +void +PDFLaTeXRenderer::setStateForItem(SPItem const *item) +{ +/* + SPStyle const *style = SP_OBJECT_STYLE(item); + ctx->setStateForStyle(style); + + CairoRenderState *state = ctx->getCurrentState(); + state->clip_path = item->clip_ref->getObject(); + state->mask = item->mask_ref->getObject(); + state->item_transform = Geom::Matrix (item->transform); + + // If parent_has_userspace is true the parent state's transform + // has to be used for the mask's/clippath's context. + // This is so because we use the image's/(flow)text's transform for positioning + // instead of explicitly specifying it and letting the renderer do the + // transformation before rendering the item. + if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_IMAGE(item)) + state->parent_has_userspace = TRUE; + TRACE(("setStateForItem opacity: %f\n", state->opacity)); +*/ +} + +void +PDFLaTeXRenderer::renderItem(SPItem *item) +{ +/* + ctx->pushState(); + setStateForItem(ctx, item); + + CairoRenderState *state = ctx->getCurrentState(); + state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); + + // Draw item on a temporary surface so a mask, clip path, or opacity can be applied to it. + if (state->need_layer) { + state->merge_opacity = FALSE; + ctx->pushLayer(); + } + Geom::Matrix tempmat (item->transform); + ctx->transform(&tempmat); + sp_item_invoke_render(item, ctx); + + if (state->need_layer) + ctx->popLayer(); + + ctx->popState(); +*/ +} + +bool +PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base) +{ +// The boundingbox calculation here should be exactly the same as the one by CairoRenderer::setupDocument ! + + if (!base) + base = SP_ITEM(sp_document_root(doc)); + + NRRect d; + if (pageBoundingBox) { + d.x0 = d.y0 = 0; + d.x1 = ceil(sp_document_width(doc)); + d.y1 = ceil(sp_document_height(doc)); + } else { + sp_item_invoke_bbox(base, &d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); + } + + // convert from px to pt + d.x0 *= PT_PER_PX; + d.x1 *= PT_PER_PX; + d.y0 *= PT_PER_PX; + d.y1 *= PT_PER_PX; + + double _width = d.x1-d.x0; + double _height = d.y1-d.y0; + + if (!pageBoundingBox) + { + double high = sp_document_height(doc); + high *= PT_PER_PX; + + transform( Geom::Translate( -d.x0 * PX_PER_PT, + (d.y1 - high) * PX_PER_PT ) ); + } + + return true; +} + +void +PDFLaTeXRenderer::transform(Geom::Matrix const &transform) +{ + _m *= transform; +} + + +/* +#include "macros.h" // SP_PRINT_* + +// Apply an SVG clip path +void +PDFLaTeXRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) +{ + g_assert( ctx != NULL && ctx->_is_valid ); + + if (cp == NULL) + return; + + CairoRenderContext::CairoRenderMode saved_mode = ctx->getRenderMode(); + ctx->setRenderMode(CairoRenderContext::RENDER_MODE_CLIP); + + Geom::Matrix saved_ctm; + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + //SP_PRINT_DRECT("clipd", cp->display->bbox); + NRRect clip_bbox(cp->display->bbox); + Geom::Matrix t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); + t[4] = clip_bbox.x0; + t[5] = clip_bbox.y0; + t *= ctx->getCurrentState()->transform; + ctx->getTransform(&saved_ctm); + ctx->setTransform(&t); + } + + TRACE(("BEGIN clip\n")); + SPObject *co = SP_OBJECT(cp); + for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + SPItem *item = SP_ITEM(child); + + // combine transform of the item in clippath and the item using clippath: + Geom::Matrix tempmat (item->transform); + tempmat = tempmat * (ctx->getCurrentState()->item_transform); + + // render this item in clippath + ctx->pushState(); + ctx->transform(&tempmat); + setStateForItem(ctx, item); + sp_item_invoke_render(item, ctx); + ctx->popState(); + } + } + TRACE(("END clip\n")); + + // do clipping only if this was the first call to applyClipPath + if (ctx->getClipMode() == CairoRenderContext::CLIP_MODE_PATH + && saved_mode == CairoRenderContext::RENDER_MODE_NORMAL) + cairo_clip(ctx->_cr); + + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) + ctx->setTransform(&saved_ctm); + + ctx->setRenderMode(saved_mode); +} + +// Apply an SVG mask +void +PDFLaTeXRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) +{ + g_assert( ctx != NULL && ctx->_is_valid ); + + if (mask == NULL) + return; + + //SP_PRINT_DRECT("maskd", &mask->display->bbox); + NRRect mask_bbox(mask->display->bbox); + // TODO: should the bbox be transformed if maskUnits != userSpaceOnUse ? + if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + Geom::Matrix t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); + t[4] = mask_bbox.x0; + t[5] = mask_bbox.y0; + t *= ctx->getCurrentState()->transform; + ctx->setTransform(&t); + } + + // Clip mask contents... but... + // The mask's bounding box is the "geometric bounding box" which doesn't allow for + // filters which extend outside the bounding box. So don't clip. + // ctx->addClippingRect(mask_bbox.x0, mask_bbox.y0, mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0); + + ctx->pushState(); + + TRACE(("BEGIN mask\n")); + SPObject *co = SP_OBJECT(mask); + for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + SPItem *item = SP_ITEM(child); + renderItem(ctx, item); + } + } + TRACE(("END mask\n")); + + ctx->popState(); +} +*/ + +} /* namespace Internal */ +} /* namespace Extension */ +} /* namespace Inkscape */ + +#undef TRACE + +/* End of GNU GPL code */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/pdflatex-renderer.h b/src/extension/internal/pdflatex-renderer.h new file mode 100644 index 000000000..21609e892 --- /dev/null +++ b/src/extension/internal/pdflatex-renderer.h @@ -0,0 +1,82 @@ +#ifndef EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN +#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN + +/** \file + * Declaration of PDFLaTeXRenderer, used for rendering the accompanying LaTeX file when saving PDF output + LaTeX + */ +/* + * Authors: + * Johan Engelen + * + * Copyright (C) 2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "extension/extension.h" +#include +#include + +#include "style.h" + +#include + +#include <2geom/matrix.h> + +class SPClipPath; +class SPMask; +class SPItem; + +namespace Inkscape { +namespace Extension { +namespace Internal { + +class PDFLaTeXRenderer { +public: + PDFLaTeXRenderer(); + virtual ~PDFLaTeXRenderer(); + + void setStateForItem(SPItem const *item); + +// void applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp); +// void applyMask(CairoRenderContext *ctx, SPMask const *mask); + + /** Initializes the PDFLaTeXRenderer according to the specified + SPDocument. Important to set the boundingbox to the pdf boundingbox */ + bool setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base); + + /** Traverses the object tree and invokes the render methods. */ + void renderItem(SPItem *item); + +protected: + void transform(Geom::Matrix const &transform); + Geom::Matrix _m; // the transform for current item + + void sp_item_invoke_render(SPItem *item); + void sp_root_render(SPItem *item); + void sp_group_render(SPItem *item); + void sp_use_render(SPItem *item); + void sp_text_render(SPItem *item); + void sp_flowtext_render(SPItem *item); +}; + +} /* namespace Internal */ +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_H_SEEN */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 76be5817cf9fdf8d74868516412bf9f46562a8a8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 01:05:44 +0100 Subject: writePreamble and writePostamble (bzr r9101.1.4) --- src/extension/internal/cairo-renderer-pdf-out.cpp | 9 +- src/extension/internal/pdflatex-renderer.cpp | 177 +++++++++++++++++++++- src/extension/internal/pdflatex-renderer.h | 10 ++ 3 files changed, 189 insertions(+), 7 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index ba23f4bcc..f308f58ca 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -138,10 +138,13 @@ latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, /* Create renderer */ PDFLaTeXRenderer *renderer = new PDFLaTeXRenderer(); - /* Render document */ - bool ret = renderer->setupDocument(doc, pageBoundingBox, base); + bool ret = renderer->setTargetFile(filename); if (ret) { - renderer->renderItem(base); + /* Render document */ + bool ret = renderer->setupDocument(doc, pageBoundingBox, base); + if (ret) { + renderer->renderItem(base); + } } delete renderer; diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index bcababf8e..2d8c98ca4 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -10,6 +10,8 @@ * * Copyright (C) 2006-2010 Authors * + * Most of the pre- and postamble is copied from GNUPlot's epslatex terminal output :-) + * * Licensed under GNU GPL */ @@ -98,20 +100,184 @@ namespace Inkscape { namespace Extension { namespace Internal { + PDFLaTeXRenderer::PDFLaTeXRenderer(void) - : _m(Geom::identity()) + : _stream(NULL), + _filename(NULL), + _m(Geom::identity()), + _width(0), + _height(0) {} PDFLaTeXRenderer::~PDFLaTeXRenderer(void) { + if (_stream) { + writePostamble(); + + fclose(_stream); + } + /* restore default signal handling for SIGPIPE */ #if !defined(_WIN32) && !defined(__WIN32__) (void) signal(SIGPIPE, SIG_DFL); #endif + if (_filename) { + g_free(_filename); + } + return; } +/** This should create the output LaTeX file, and assign it to _stream. + * @return Returns true when succesfull + */ +bool +PDFLaTeXRenderer::setTargetFile(gchar const *filename) { + if (filename != NULL) { + _filename = g_strdup(filename); + while (isspace(*filename)) filename += 1; + Inkscape::IO::dump_fopen_call(filename, "K"); + FILE *osf = Inkscape::IO::fopen_utf8name(filename, "w+"); + if (!osf) { + fprintf(stderr, "inkscape: fopen(%s): %s\n", + filename, strerror(errno)); + return false; + } + _stream = osf; + } + + if (_stream) { + /* fixme: this is kinda icky */ +#if !defined(_WIN32) && !defined(__WIN32__) + (void) signal(SIGPIPE, SIG_IGN); +#endif + } + + fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", PACKAGE_STRING); + fprintf(_stream, "%%%% PDF + LaTeX output extension by Johan Engelen, 2010\n"); + /* flush this to test output stream as early as possible */ + if (fflush(_stream)) { + if (ferror(_stream)) { + g_print("Error %d on LaTeX file output stream: %s\n", errno, + g_strerror(errno)); + } + g_print("Output to LaTeX file failed\n"); + /* fixme: should use pclose() for pipes */ + fclose(_stream); + _stream = NULL; + fflush(stdout); + return false; + } + + writePreamble(); + + return true; +} + +/* Most of this preamble is copied from GNUPlot's epslatex terminal output :-) */ +static char const preamble[] = +"\\begingroup \n" +" \\makeatletter \n" +" \\providecommand\\color[2][]{%% \n" +" \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%% \n" +" Package color not loaded in conjunction with \n" +" terminal option `colourtext'%% \n" +" }{See the gnuplot documentation for explanation.%% \n" +" }{Either use 'blacktext' in gnuplot or load the package \n" +" color.sty in LaTeX.}%% \n" +" \\renewcommand\\color[2][]{}%% \n" +" }%% \n" +" \\providecommand\\includegraphics[2][]{%% \n" +" \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%% \n" +" Package graphicx or graphics not loaded%% \n" +" }{See the gnuplot documentation for explanation.%% \n" +" }{The gnuplot epslatex terminal needs graphicx.sty or graphics.sty.}%% \n" +" \\renewcommand\\includegraphics[2][]{}%% \n" +" }%% \n" +" \\providecommand\\rotatebox[2]{#2}%% \n" +" \\@ifundefined{ifGPcolor}{%% \n" +" \\newif\\ifGPcolor \n" +" \\GPcolorfalse \n" +" }{}%% \n" +" \\@ifundefined{ifGPblacktext}{%% \n" +" \\newif\\ifGPblacktext \n" +" \\GPblacktexttrue \n" +" }{}%% \n" +" %% define a \\g@addto@macro without @ in the name: \n" +" \\let\\gplgaddtomacro\\g@addto@macro \n" +" %% define empty templates for all commands taking text: \n" +" \\gdef\\gplbacktext{}%% \n" +" \\gdef\\gplfronttext{}%% \n" +" \\makeatother \n" +" \\ifGPblacktext \n" +" %% no textcolor at all \n" +" \\def\\colorrgb#1{}%% \n" +" \\def\\colorgray#1{}%% \n" +" \\else \n" +" %% gray or color? \n" +" \\ifGPcolor \n" +" \\def\\colorrgb#1{\\color[rgb]{#1}}%% \n" +" \\def\\colorgray#1{\\color[gray]{#1}}%% \n" +" \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}%% \n" +" \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}%% \n" +" \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}%% \n" +" \\expandafter\\def\\csname LT0\\endcsname{\\color[rgb]{1,0,0}}%% \n" +" \\expandafter\\def\\csname LT1\\endcsname{\\color[rgb]{0,1,0}}%% \n" +" \\expandafter\\def\\csname LT2\\endcsname{\\color[rgb]{0,0,1}}%% \n" +" \\expandafter\\def\\csname LT3\\endcsname{\\color[rgb]{1,0,1}}%% \n" +" \\expandafter\\def\\csname LT4\\endcsname{\\color[rgb]{0,1,1}}%% \n" +" \\expandafter\\def\\csname LT5\\endcsname{\\color[rgb]{1,1,0}}%% \n" +" \\expandafter\\def\\csname LT6\\endcsname{\\color[rgb]{0,0,0}}%% \n" +" \\expandafter\\def\\csname LT7\\endcsname{\\color[rgb]{1,0.3,0}}%% \n" +" \\expandafter\\def\\csname LT8\\endcsname{\\color[rgb]{0.5,0.5,0.5}}%% \n" +" \\else \n" +" %% gray \n" +" \\def\\colorrgb#1{\\color{black}}%% \n" +" \\def\\colorgray#1{\\color[gray]{#1}}%% \n" +" \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}% \n" +" \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT0\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT1\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT2\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT3\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT4\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT5\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT6\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT7\\endcsname{\\color{black}}% \n" +" \\expandafter\\def\\csname LT8\\endcsname{\\color{black}}% \n" +" \\fi \n" +" \\fi \n" +" \\setlength{\\unitlength}{0.0500bp}%% \n"; + +static char const postamble1[] = +" }%% \n" +" \\gplgaddtomacro\\gplfronttext{% \n" +" }%% \n" +" \\gplbacktext \n"; + +static char const postamble2[] = +" \\gplfronttext \n" +" \\end{picture}% \n" +"\\endgroup \n"; + +void +PDFLaTeXRenderer::writePreamble() +{ + fprintf(_stream, "%s", preamble); +} +void +PDFLaTeXRenderer::writePostamble() +{ + fprintf(_stream, "%s", postamble1); + + // TODO: strip path from filename on Windows + fprintf(_stream, " \\put(0,0){\\includegraphics{%s}}%%\n", _filename); + + fprintf(_stream, "%s", postamble2); +} + void PDFLaTeXRenderer::sp_group_render(SPItem *item) { @@ -287,18 +453,21 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b d.y0 *= PT_PER_PX; d.y1 *= PT_PER_PX; - double _width = d.x1-d.x0; - double _height = d.y1-d.y0; + _width = d.x1-d.x0; + _height = d.y1-d.y0; if (!pageBoundingBox) { double high = sp_document_height(doc); high *= PT_PER_PX; - transform( Geom::Translate( -d.x0 * PX_PER_PT, + transform( Geom::Translate( -d.x0 * PX_PER_PT, (d.y1 - high) * PX_PER_PT ) ); } + // write the info to LaTeX: + + return true; } diff --git a/src/extension/internal/pdflatex-renderer.h b/src/extension/internal/pdflatex-renderer.h index 21609e892..856631f95 100644 --- a/src/extension/internal/pdflatex-renderer.h +++ b/src/extension/internal/pdflatex-renderer.h @@ -40,6 +40,8 @@ public: PDFLaTeXRenderer(); virtual ~PDFLaTeXRenderer(); + bool setTargetFile(gchar const *filename); + void setStateForItem(SPItem const *item); // void applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp); @@ -53,8 +55,16 @@ public: void renderItem(SPItem *item); protected: + FILE * _stream; + gchar * _filename; + void transform(Geom::Matrix const &transform); Geom::Matrix _m; // the transform for current item + double _width; + double _height; + + void writePreamble(); + void writePostamble(); void sp_item_invoke_render(SPItem *item); void sp_root_render(SPItem *item); -- cgit v1.2.3 From 9a944fdc46e88fc8ba1d7e437a04dc4d5ed0df21 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 02:23:33 +0100 Subject: start outputting text to tex. position is wrong. filename of pdf is wrong in latex code (bzr r9101.1.5) --- src/extension/internal/pdflatex-renderer.cpp | 95 +++++++++++++++++----------- 1 file changed, 57 insertions(+), 38 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index 2d8c98ca4..60b960ddb 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -56,6 +56,7 @@ #include "sp-flowtext.h" #include "sp-mask.h" #include "sp-clippath.h" +#include "text-editing.h" #include #include "helper/png-write.h" @@ -76,7 +77,7 @@ #include #endif -//#define TRACE(_args) g_printf _args +//#define TRACE(_args) g_message(_args) #define TRACE(_args) //#define TEST(_args) _args #define TEST(_args) @@ -135,8 +136,9 @@ PDFLaTeXRenderer::~PDFLaTeXRenderer(void) bool PDFLaTeXRenderer::setTargetFile(gchar const *filename) { if (filename != NULL) { - _filename = g_strdup(filename); while (isspace(*filename)) filename += 1; + + _filename = g_strdup(filename); Inkscape::IO::dump_fopen_call(filename, "K"); FILE *osf = Inkscape::IO::fopen_utf8name(filename, "w+"); if (!osf) { @@ -249,7 +251,7 @@ static char const preamble[] = " \\expandafter\\def\\csname LT8\\endcsname{\\color{black}}% \n" " \\fi \n" " \\fi \n" -" \\setlength{\\unitlength}{0.0500bp}%% \n"; +" \\setlength{\\unitlength}{1pt}% \n"; static char const postamble1[] = " }%% \n" @@ -273,7 +275,7 @@ PDFLaTeXRenderer::writePostamble() fprintf(_stream, "%s", postamble1); // TODO: strip path from filename on Windows - fprintf(_stream, " \\put(0,0){\\includegraphics{%s}}%%\n", _filename); + fprintf(_stream, " \\put(0,0){\\includegraphics{%s.pdf}}%%\n", _filename); fprintf(_stream, "%s", postamble2); } @@ -320,18 +322,34 @@ PDFLaTeXRenderer::sp_use_render(SPItem *item) void PDFLaTeXRenderer::sp_text_render(SPItem *item) { - SPText *group = SP_TEXT (item); -/* -implement -*/ + SPText *textobj = SP_TEXT (item); + + gchar *str = sp_te_get_string_multiline(item); + Geom::Point pos = SP_TEXT(item)->attributes.firstXY(); + gchar *alignment = "lb"; + + // write to LaTeX + Inkscape::SVGOStringStream os; + + os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; + + fprintf(_stream, "%s", os.str().c_str()); } void PDFLaTeXRenderer::sp_flowtext_render(SPItem *item) { - SPFlowtext *group = SP_FLOWTEXT(item); -/* -implement +/* SPFlowtext *group = SP_FLOWTEXT(item); + + // write to LaTeX + Inkscape::SVGOStringStream os; + + os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; + os << " \\gplgaddtomacro\\gplbacktext{%%\n"; + os << " \\csname LTb\\endcsname%%\n"; + os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}Position}}%%\n"; + + fprintf(_stream, "%s", os.str().c_str()); */ } @@ -340,17 +358,12 @@ PDFLaTeXRenderer::sp_root_render(SPItem *item) { SPRoot *root = SP_ROOT(item); -/* - if (!ctx->getCurrentState()->has_overflow && SP_OBJECT(item)->parent) - ctx->addClippingRect(root->x.computed, root->y.computed, root->width.computed, root->height.computed); - - ctx->pushState(); - setStateForItem(ctx, item); - Geom::Matrix tempmat (root->c2p); - ctx->transform(&tempmat); - sp_group_render(item, ctx); - ctx->popState(); -*/ +// ctx->pushState(); +// setStateForItem(ctx, item); +// Geom::Matrix tempmat (root->c2p); +// ctx->transform(&tempmat); + sp_group_render(item); +// ctx->popState(); } void @@ -361,6 +374,7 @@ PDFLaTeXRenderer::sp_item_invoke_render(SPItem *item) return; } + g_message("hier?"); if (SP_IS_ROOT(item)) { TRACE(("root\n")); return sp_root_render(item); @@ -407,27 +421,25 @@ PDFLaTeXRenderer::setStateForItem(SPItem const *item) void PDFLaTeXRenderer::renderItem(SPItem *item) { -/* - ctx->pushState(); - setStateForItem(ctx, item); +// ctx->pushState(); +// setStateForItem(ctx, item); - CairoRenderState *state = ctx->getCurrentState(); - state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); +// CairoRenderState *state = ctx->getCurrentState(); +// state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); // Draw item on a temporary surface so a mask, clip path, or opacity can be applied to it. - if (state->need_layer) { - state->merge_opacity = FALSE; - ctx->pushLayer(); - } +// if (state->need_layer) { +// state->merge_opacity = FALSE; +// ctx->pushLayer(); +// } Geom::Matrix tempmat (item->transform); - ctx->transform(&tempmat); - sp_item_invoke_render(item, ctx); +// ctx->transform(&tempmat); + sp_item_invoke_render(item); - if (state->need_layer) - ctx->popLayer(); +// if (state->need_layer) +// ctx->popLayer(); - ctx->popState(); -*/ +// ctx->popState(); } bool @@ -465,8 +477,15 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b (d.y1 - high) * PX_PER_PT ) ); } - // write the info to LaTeX: + // write the info to LaTeX + Inkscape::SVGOStringStream os; + + os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; + os << " \\gplgaddtomacro\\gplbacktext{%%\n"; + os << " \\csname LTb\\endcsname%%\n"; + os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}0,0}}%%\n"; + fprintf(_stream, "%s", os.str().c_str()); return true; } -- cgit v1.2.3 From a6149aae1803244c5a67200bfd953b57a3ee056d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 11:21:18 +0100 Subject: output test.tex instead of test.pdf.tex which does not work well. strip path from filename on windows (bzr r9101.1.6) --- src/extension/internal/cairo-renderer-pdf-out.cpp | 4 +++- src/extension/internal/pdflatex-renderer.cpp | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index f308f58ca..594389c60 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -256,7 +256,9 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, // Create LaTeX file (if requested) if (new_textToLaTeX) { gchar * tex_filename; - tex_filename = g_strdup_printf("%s.tex", filename); + //strip filename of ".pdf", do not add ".tex" here. + gsize n = g_str_has_suffix(filename, ".pdf") ? strlen(filename)-4 : strlen(filename); + tex_filename = g_strndup(filename, n); ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas); g_free(tex_filename); diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index 60b960ddb..0d2ffcc94 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -139,14 +139,17 @@ PDFLaTeXRenderer::setTargetFile(gchar const *filename) { while (isspace(*filename)) filename += 1; _filename = g_strdup(filename); - Inkscape::IO::dump_fopen_call(filename, "K"); - FILE *osf = Inkscape::IO::fopen_utf8name(filename, "w+"); + + gchar *filename_ext = g_strdup_printf("%s.tex", filename); + Inkscape::IO::dump_fopen_call(filename_ext, "K"); + FILE *osf = Inkscape::IO::fopen_utf8name(filename_ext, "w+"); if (!osf) { fprintf(stderr, "inkscape: fopen(%s): %s\n", - filename, strerror(errno)); + filename_ext, strerror(errno)); return false; } _stream = osf; + g_free(filename_ext); } if (_stream) { @@ -158,6 +161,7 @@ PDFLaTeXRenderer::setTargetFile(gchar const *filename) { fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", PACKAGE_STRING); fprintf(_stream, "%%%% PDF + LaTeX output extension by Johan Engelen, 2010\n"); + fprintf(_stream, "%%%% Accompanies %s.pdf\n", _filename); /* flush this to test output stream as early as possible */ if (fflush(_stream)) { if (ferror(_stream)) { @@ -274,8 +278,14 @@ PDFLaTeXRenderer::writePostamble() { fprintf(_stream, "%s", postamble1); - // TODO: strip path from filename on Windows - fprintf(_stream, " \\put(0,0){\\includegraphics{%s.pdf}}%%\n", _filename); + // strip pathname on windows, as it is probably desired. It is not possible to work without paths on windows yet. (bug) +#ifdef WIN32 + gchar *figurefile = g_path_get_basename(_filename); +#else + gchar *figurefile = g_strdup(_filename); +#endif + fprintf(_stream, " \\put(0,0){\\includegraphics{%s.pdf}}%%\n", figurefile); + g_free(figurefile); fprintf(_stream, "%s", postamble2); } -- cgit v1.2.3 From edbd390b53f84e021ad029a37d221deefd27238c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 12:39:17 +0100 Subject: fix transforms (bzr r9101.1.7) --- src/extension/internal/pdflatex-renderer.cpp | 56 +++++++++++++++++++--------- src/extension/internal/pdflatex-renderer.h | 7 +++- 2 files changed, 43 insertions(+), 20 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index 0d2ffcc94..d21457a89 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -105,10 +105,11 @@ namespace Internal { PDFLaTeXRenderer::PDFLaTeXRenderer(void) : _stream(NULL), _filename(NULL), - _m(Geom::identity()), _width(0), _height(0) -{} +{ + push_transform(Geom::identity()); +} PDFLaTeXRenderer::~PDFLaTeXRenderer(void) { @@ -334,10 +335,14 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) { SPText *textobj = SP_TEXT (item); + push_transform(sp_item_i2doc_affine(item)); + gchar *str = sp_te_get_string_multiline(item); - Geom::Point pos = SP_TEXT(item)->attributes.firstXY(); + Geom::Point pos = textobj->attributes.firstXY() * transform(); gchar *alignment = "lb"; + pop_transform(); + // write to LaTeX Inkscape::SVGOStringStream os; @@ -370,10 +375,10 @@ PDFLaTeXRenderer::sp_root_render(SPItem *item) // ctx->pushState(); // setStateForItem(ctx, item); -// Geom::Matrix tempmat (root->c2p); -// ctx->transform(&tempmat); + Geom::Matrix tempmat (root->c2p); + push_transform(tempmat); sp_group_render(item); -// ctx->popState(); + pop_transform(); } void @@ -470,23 +475,22 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b } // convert from px to pt - d.x0 *= PT_PER_PX; - d.x1 *= PT_PER_PX; - d.y0 *= PT_PER_PX; - d.y1 *= PT_PER_PX; - - _width = d.x1-d.x0; - _height = d.y1-d.y0; + push_transform( Geom::Scale(PT_PER_PX, PT_PER_PX) ); if (!pageBoundingBox) { double high = sp_document_height(doc); - high *= PT_PER_PX; - transform( Geom::Translate( -d.x0 * PX_PER_PT, - (d.y1 - high) * PX_PER_PT ) ); + push_transform( Geom::Translate( -d.x0, + -d.y0 ) ); } + // flip y-axis + push_transform( Geom::Scale(1,-1) * Geom::Translate(0, sp_document_height(doc)) ); + + _width = (d.x1-d.x0) * PT_PER_PX; + _height = (d.y1-d.y0) * PT_PER_PX; + // write the info to LaTeX Inkscape::SVGOStringStream os; @@ -500,12 +504,28 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b return true; } +Geom::Matrix const & +PDFLaTeXRenderer::transform() +{ + return _transform_stack.top(); +} + void -PDFLaTeXRenderer::transform(Geom::Matrix const &transform) +PDFLaTeXRenderer::push_transform(Geom::Matrix const &tr) { - _m *= transform; + if(_transform_stack.size()){ + Geom::Matrix tr_top = _transform_stack.top(); + _transform_stack.push(tr * tr_top); + } else { + _transform_stack.push(tr); + } } +void +PDFLaTeXRenderer::pop_transform() +{ + _transform_stack.pop(); +} /* #include "macros.h" // SP_PRINT_* diff --git a/src/extension/internal/pdflatex-renderer.h b/src/extension/internal/pdflatex-renderer.h index 856631f95..93c06b114 100644 --- a/src/extension/internal/pdflatex-renderer.h +++ b/src/extension/internal/pdflatex-renderer.h @@ -26,6 +26,7 @@ #include #include <2geom/matrix.h> +#include class SPClipPath; class SPMask; @@ -58,8 +59,10 @@ protected: FILE * _stream; gchar * _filename; - void transform(Geom::Matrix const &transform); - Geom::Matrix _m; // the transform for current item + void push_transform(Geom::Matrix const &transform); + Geom::Matrix const & transform(); + void pop_transform(); + std::stack _transform_stack; double _width; double _height; -- cgit v1.2.3 From 4c24ea8784247bc7d1ff715124c2c05236675bb8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 13:50:05 +0100 Subject: add rotation to text output (the positioning is a little off) (bzr r9101.1.8) --- src/extension/internal/pdflatex-renderer.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index d21457a89..ef97da444 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -335,18 +335,32 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) { SPText *textobj = SP_TEXT (item); - push_transform(sp_item_i2doc_affine(item)); + Geom::Matrix i2doc = sp_item_i2doc_affine(item); + push_transform(i2doc); gchar *str = sp_te_get_string_multiline(item); Geom::Point pos = textobj->attributes.firstXY() * transform(); gchar *alignment = "lb"; + // get rotation + Geom::Matrix wotransl = i2doc.without_translation(); + double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); + pop_transform(); // write to LaTeX Inkscape::SVGOStringStream os; - os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; +// os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; + os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; + if (!Geom::are_near(degrees,0.)) { + os << "\\rotatebox{" << degrees << "}{"; + } + os << str; + if (!Geom::are_near(degrees,0.)) { + os << "}"; + } + os << "}%%\n"; fprintf(_stream, "%s", os.str().c_str()); } @@ -497,7 +511,6 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; os << " \\gplgaddtomacro\\gplbacktext{%%\n"; os << " \\csname LTb\\endcsname%%\n"; - os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}0,0}}%%\n"; fprintf(_stream, "%s", os.str().c_str()); -- cgit v1.2.3 From 448efe9e05a1e3d8151fd19e00269556db6497ad Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 13:50:53 +0100 Subject: remove g_message (bzr r9101.1.9) --- src/extension/internal/pdflatex-renderer.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index ef97da444..866070bec 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -403,7 +403,6 @@ PDFLaTeXRenderer::sp_item_invoke_render(SPItem *item) return; } - g_message("hier?"); if (SP_IS_ROOT(item)) { TRACE(("root\n")); return sp_root_render(item); -- cgit v1.2.3 From 21ba76c6b6391eba5fb7e41798e1fe294e2fba5b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 15:42:52 +0100 Subject: add method to scale the image clean up the pre- and postamble add help text on how to use the tex file (bzr r9101.1.10) --- src/extension/internal/pdflatex-renderer.cpp | 135 ++++++--------------------- 1 file changed, 31 insertions(+), 104 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index 866070bec..5377ae57c 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -2,6 +2,8 @@ /** \file * Rendering LaTeX file (pdf+latex output) + * + * The idea stems from GNUPlot's epslatex terminal output :-) */ /* * Authors: @@ -10,8 +12,6 @@ * * Copyright (C) 2006-2010 Authors * - * Most of the pre- and postamble is copied from GNUPlot's epslatex terminal output :-) - * * Licensed under GNU GPL */ @@ -182,90 +182,26 @@ PDFLaTeXRenderer::setTargetFile(gchar const *filename) { return true; } -/* Most of this preamble is copied from GNUPlot's epslatex terminal output :-) */ static char const preamble[] = +"%% To include the image in your LaTeX document, write\n" +"%% \\setlength{\\unitlength}{}\n" +"%% \\input{filename.tex}\n" +"%% instead of\n" +"%% \\includegraphics[width=]{}\n" +"\n" "\\begingroup \n" " \\makeatletter \n" -" \\providecommand\\color[2][]{%% \n" -" \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%% \n" -" Package color not loaded in conjunction with \n" -" terminal option `colourtext'%% \n" -" }{See the gnuplot documentation for explanation.%% \n" -" }{Either use 'blacktext' in gnuplot or load the package \n" -" color.sty in LaTeX.}%% \n" -" \\renewcommand\\color[2][]{}%% \n" +" \\providecommand\\color[2][]{% \n" +" \\GenericError{(Inkscape) \\space\\space\\@spaces}{% \n" +" Color is used for the text in Inkscape, but the color package color is not loaded. \n" +" }{Either use black text in Inkscape or load the package \n" +" color.sty in LaTeX.}% \n" +" \\renewcommand\\color[2][]{}% \n" " }%% \n" -" \\providecommand\\includegraphics[2][]{%% \n" -" \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%% \n" -" Package graphicx or graphics not loaded%% \n" -" }{See the gnuplot documentation for explanation.%% \n" -" }{The gnuplot epslatex terminal needs graphicx.sty or graphics.sty.}%% \n" -" \\renewcommand\\includegraphics[2][]{}%% \n" -" }%% \n" -" \\providecommand\\rotatebox[2]{#2}%% \n" -" \\@ifundefined{ifGPcolor}{%% \n" -" \\newif\\ifGPcolor \n" -" \\GPcolorfalse \n" -" }{}%% \n" -" \\@ifundefined{ifGPblacktext}{%% \n" -" \\newif\\ifGPblacktext \n" -" \\GPblacktexttrue \n" -" }{}%% \n" -" %% define a \\g@addto@macro without @ in the name: \n" -" \\let\\gplgaddtomacro\\g@addto@macro \n" -" %% define empty templates for all commands taking text: \n" -" \\gdef\\gplbacktext{}%% \n" -" \\gdef\\gplfronttext{}%% \n" -" \\makeatother \n" -" \\ifGPblacktext \n" -" %% no textcolor at all \n" -" \\def\\colorrgb#1{}%% \n" -" \\def\\colorgray#1{}%% \n" -" \\else \n" -" %% gray or color? \n" -" \\ifGPcolor \n" -" \\def\\colorrgb#1{\\color[rgb]{#1}}%% \n" -" \\def\\colorgray#1{\\color[gray]{#1}}%% \n" -" \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}%% \n" -" \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}%% \n" -" \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}%% \n" -" \\expandafter\\def\\csname LT0\\endcsname{\\color[rgb]{1,0,0}}%% \n" -" \\expandafter\\def\\csname LT1\\endcsname{\\color[rgb]{0,1,0}}%% \n" -" \\expandafter\\def\\csname LT2\\endcsname{\\color[rgb]{0,0,1}}%% \n" -" \\expandafter\\def\\csname LT3\\endcsname{\\color[rgb]{1,0,1}}%% \n" -" \\expandafter\\def\\csname LT4\\endcsname{\\color[rgb]{0,1,1}}%% \n" -" \\expandafter\\def\\csname LT5\\endcsname{\\color[rgb]{1,1,0}}%% \n" -" \\expandafter\\def\\csname LT6\\endcsname{\\color[rgb]{0,0,0}}%% \n" -" \\expandafter\\def\\csname LT7\\endcsname{\\color[rgb]{1,0.3,0}}%% \n" -" \\expandafter\\def\\csname LT8\\endcsname{\\color[rgb]{0.5,0.5,0.5}}%% \n" -" \\else \n" -" %% gray \n" -" \\def\\colorrgb#1{\\color{black}}%% \n" -" \\def\\colorgray#1{\\color[gray]{#1}}%% \n" -" \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}% \n" -" \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT0\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT1\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT2\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT3\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT4\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT5\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT6\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT7\\endcsname{\\color{black}}% \n" -" \\expandafter\\def\\csname LT8\\endcsname{\\color{black}}% \n" -" \\fi \n" -" \\fi \n" -" \\setlength{\\unitlength}{1pt}% \n"; - -static char const postamble1[] = -" }%% \n" -" \\gplgaddtomacro\\gplfronttext{% \n" -" }%% \n" -" \\gplbacktext \n"; - -static char const postamble2[] = -" \\gplfronttext \n" +" \\providecommand\\rotatebox[2]{#2}% \n" +" \\makeatother \n"; + +static char const postamble[] = " \\end{picture}% \n" "\\endgroup \n"; @@ -277,18 +213,7 @@ PDFLaTeXRenderer::writePreamble() void PDFLaTeXRenderer::writePostamble() { - fprintf(_stream, "%s", postamble1); - - // strip pathname on windows, as it is probably desired. It is not possible to work without paths on windows yet. (bug) -#ifdef WIN32 - gchar *figurefile = g_path_get_basename(_filename); -#else - gchar *figurefile = g_strdup(_filename); -#endif - fprintf(_stream, " \\put(0,0){\\includegraphics{%s.pdf}}%%\n", figurefile); - g_free(figurefile); - - fprintf(_stream, "%s", postamble2); + fprintf(_stream, "%s", postamble); } void @@ -352,7 +277,7 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) Inkscape::SVGOStringStream os; // os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; - os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; + os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; if (!Geom::are_near(degrees,0.)) { os << "\\rotatebox{" << degrees << "}{"; } @@ -360,7 +285,7 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) if (!Geom::are_near(degrees,0.)) { os << "}"; } - os << "}%%\n"; + os << "}%\n"; fprintf(_stream, "%s", os.str().c_str()); } @@ -487,8 +412,11 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b sp_item_invoke_bbox(base, &d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); } - // convert from px to pt - push_transform( Geom::Scale(PT_PER_PX, PT_PER_PX) ); + // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX + double scale = 1/(d.x1-d.x0); + _width = (d.x1-d.x0) * scale; + _height = (d.y1-d.y0) * scale; + push_transform( Geom::Scale(scale, scale) ); if (!pageBoundingBox) { @@ -501,15 +429,14 @@ PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *b // flip y-axis push_transform( Geom::Scale(1,-1) * Geom::Translate(0, sp_document_height(doc)) ); - _width = (d.x1-d.x0) * PT_PER_PX; - _height = (d.y1-d.y0) * PT_PER_PX; - // write the info to LaTeX Inkscape::SVGOStringStream os; - os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; - os << " \\gplgaddtomacro\\gplbacktext{%%\n"; - os << " \\csname LTb\\endcsname%%\n"; + os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; + // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient. + gchar *figurefile = g_path_get_basename(_filename); + os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << figurefile << ".pdf}}%\n"; + g_free(figurefile); fprintf(_stream, "%s", os.str().c_str()); -- cgit v1.2.3 From e0812df4068e0242e6fba24a1416f97e242f2fc7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 21 Feb 2010 16:54:04 +0100 Subject: fix alignment issue. now the boundingbox is used for aligning, instead of the text anchor point. (bzr r9101.1.11) --- src/extension/internal/pdflatex-renderer.cpp | 40 ++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp index 5377ae57c..b70bac107 100644 --- a/src/extension/internal/pdflatex-renderer.cpp +++ b/src/extension/internal/pdflatex-renderer.cpp @@ -185,9 +185,9 @@ PDFLaTeXRenderer::setTargetFile(gchar const *filename) { static char const preamble[] = "%% To include the image in your LaTeX document, write\n" "%% \\setlength{\\unitlength}{}\n" -"%% \\input{filename.tex}\n" +"%% \\input{.tex}\n" "%% instead of\n" -"%% \\includegraphics[width=]{}\n" +"%% \\includegraphics[width=]{.pdf}\n" "\n" "\\begingroup \n" " \\makeatletter \n" @@ -264,12 +264,34 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) push_transform(i2doc); gchar *str = sp_te_get_string_multiline(item); - Geom::Point pos = textobj->attributes.firstXY() * transform(); - gchar *alignment = "lb"; + + // get position and alignment + Geom::Point pos; + gchar *alignment = NULL; + Geom::OptRect bbox = item->getBounds(transform()); + Geom::Interval bbox_x = (*bbox)[Geom::X]; + Geom::Interval bbox_y = (*bbox)[Geom::Y]; + SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); + switch (style->text_anchor.computed) { + case SP_CSS_TEXT_ANCHOR_START: + pos = Geom::Point( bbox_x.min() , bbox_y.middle() ); + alignment = "[l]"; + break; + case SP_CSS_TEXT_ANCHOR_END: + pos = Geom::Point( bbox_x.max() , bbox_y.middle() ); + alignment = "[r]"; + break; + case SP_CSS_TEXT_ANCHOR_MIDDLE: + default: + pos = bbox->midpoint(); + alignment = ""; + break; + } // get rotation Geom::Matrix wotransl = i2doc.without_translation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); + bool has_rotation = !Geom::are_near(degrees,0.); pop_transform(); @@ -278,14 +300,16 @@ PDFLaTeXRenderer::sp_text_render(SPItem *item) // os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; - if (!Geom::are_near(degrees,0.)) { + os << "\\makebox(0,0)" << alignment << "{"; + if (has_rotation) { os << "\\rotatebox{" << degrees << "}{"; } os << str; - if (!Geom::are_near(degrees,0.)) { - os << "}"; + if (has_rotation) { + os << "}"; // rotatebox end } - os << "}%\n"; + os << "}"; //makebox end + os << "}%\n"; // put end fprintf(_stream, "%s", os.str().c_str()); } -- cgit v1.2.3 From bde8ed1df082d20ca7bc31f9ede94419cde16b11 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 22 Feb 2010 20:33:37 +0100 Subject: - change cmdline option to --export-latex. - change source file names to reflect that it is "generic" latex renderer - make latex export work for EPS and PS aswell (bzr r9101.1.13) --- src/extension/internal/Makefile_insert | 4 +- src/extension/internal/cairo-ps-out.cpp | 79 ++- src/extension/internal/cairo-renderer-pdf-out.cpp | 50 +- src/extension/internal/latex-text-renderer.cpp | 648 ++++++++++++++++++++++ src/extension/internal/latex-text-renderer.h | 97 ++++ src/extension/internal/pdflatex-renderer.cpp | 609 -------------------- src/extension/internal/pdflatex-renderer.h | 95 ---- 7 files changed, 817 insertions(+), 765 deletions(-) create mode 100644 src/extension/internal/latex-text-renderer.cpp create mode 100644 src/extension/internal/latex-text-renderer.h delete mode 100644 src/extension/internal/pdflatex-renderer.cpp delete mode 100644 src/extension/internal/pdflatex-renderer.h (limited to 'src/extension') diff --git a/src/extension/internal/Makefile_insert b/src/extension/internal/Makefile_insert index 881b3ec22..3c1ce7f43 100644 --- a/src/extension/internal/Makefile_insert +++ b/src/extension/internal/Makefile_insert @@ -109,8 +109,8 @@ ink_common_sources += \ extension/internal/javafx-out.h \ extension/internal/gdkpixbuf-input.h \ extension/internal/gdkpixbuf-input.cpp \ - extension/internal/pdflatex-renderer.h \ - extension/internal/pdflatex-renderer.cpp \ + extension/internal/latex-text-renderer.h \ + extension/internal/latex-text-renderer.cpp \ extension/internal/pdfinput/svg-builder.h \ extension/internal/pdfinput/svg-builder.cpp \ extension/internal/pdfinput/pdf-parser.h \ diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 737bb2885..6f22dbdc7 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -21,6 +21,7 @@ #include "cairo-ps-out.h" #include "cairo-render-context.h" #include "cairo-renderer.h" +#include "latex-text-renderer.h" #include #include "extension/system.h" #include "extension/print.h" @@ -61,7 +62,8 @@ bool CairoEpsOutput::check (Inkscape::Extension::Extension * /*module*/) } static bool -ps_print_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, bool eps = false) +ps_print_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, bool eps = false) { sp_document_ensure_up_to_date(doc); @@ -93,6 +95,7 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l ctx->setPSLevel(level); ctx->setEPS(eps); ctx->setTextToPath(texttopath); + renderer->_omitText = omittext; ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); @@ -146,6 +149,14 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con new_textToPath = mod->get_param_bool("textToPath"); } catch(...) {} + bool new_textToLaTeX = FALSE; + try { + new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + } + catch(...) { + g_warning("Parameter might not exist"); + } + bool new_blurToBitmap = FALSE; try { new_blurToBitmap = mod->get_param_bool("blurToBitmap"); @@ -171,13 +182,29 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con new_exportId = mod->get_param_string("exportId"); } catch(...) {} - gchar * final_name; - final_name = g_strdup_printf("> %s", filename); - ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage); - g_free(final_name); + // Create PS + { + gchar * final_name; + final_name = g_strdup_printf("> %s", filename); + ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage); + g_free(final_name); - if (!ret) - throw Inkscape::Extension::Output::save_failed(); + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } + + // Create LaTeX file (if requested) + if (new_textToLaTeX) { + gchar * tex_filename; + //strip filename of ".ps", do not add ".tex" here. + gsize n = g_str_has_suffix(filename, ".ps") ? strlen(filename)-3 : strlen(filename); + tex_filename = g_strndup(filename, n); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage); + g_free(tex_filename); + + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } } @@ -210,6 +237,14 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co new_textToPath = mod->get_param_bool("textToPath"); } catch(...) {} + bool new_textToLaTeX = FALSE; + try { + new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + } + catch(...) { + g_warning("Parameter might not exist"); + } + bool new_blurToBitmap = FALSE; try { new_blurToBitmap = mod->get_param_bool("blurToBitmap"); @@ -235,13 +270,29 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co new_exportId = mod->get_param_string("exportId"); } catch(...) {} - gchar * final_name; - final_name = g_strdup_printf("> %s", filename); - ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage, true); - g_free(final_name); + // Create EPS + { + gchar * final_name; + final_name = g_strdup_printf("> %s", filename); + ret = ps_print_document_to_file(doc, final_name, level, new_textToPath, new_textToLaTeX, new_blurToBitmap, new_bitmapResolution, new_exportId, new_areaDrawing, new_areaPage, true); + g_free(final_name); - if (!ret) - throw Inkscape::Extension::Output::save_failed(); + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } + + // Create LaTeX file (if requested) + if (new_textToLaTeX) { + gchar * tex_filename; + //strip filename of ".eps", do not add ".tex" here. + gsize n = g_str_has_suffix(filename, ".eps") ? strlen(filename)-4 : strlen(filename); + tex_filename = g_strndup(filename, n); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage); + g_free(tex_filename); + + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } } @@ -280,6 +331,7 @@ CairoPsOutput::init (void) #endif "\n" "false\n" + "false\n" "true\n" "90\n" "true\n" @@ -317,6 +369,7 @@ CairoEpsOutput::init (void) #endif "\n" "false\n" + "false\n" "true\n" "90\n" "true\n" diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 594389c60..1dcfbdf1d 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -5,8 +5,9 @@ * Authors: * Ted Gould * Ulf Erikson + * Johan Engelen * - * Copyright (C) 2004-2006 Authors + * Copyright (C) 2004-2010 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -20,7 +21,7 @@ #include "cairo-renderer-pdf-out.h" #include "cairo-render-context.h" #include "cairo-renderer.h" -#include "pdflatex-renderer.h" +#include "latex-text-renderer.h" #include #include "extension/system.h" #include "extension/print.h" @@ -110,49 +111,6 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int return ret; } -static bool -latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, - 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 renderer */ - PDFLaTeXRenderer *renderer = new PDFLaTeXRenderer(); - - bool ret = renderer->setTargetFile(filename); - if (ret) { - /* Render document */ - bool ret = renderer->setupDocument(doc, pageBoundingBox, base); - if (ret) { - renderer->renderItem(base); - } - } - - delete renderer; - - return ret; -} - - /** \brief This function calls the output module with the filename \param mod unused @@ -287,7 +245,7 @@ CairoRendererPdfOutput::init (void) "<_item value='PDF14'>" N_("PDF 1.4") "\n" "\n" "false\n" - "false\n" + "false\n" "true\n" "90\n" "false\n" diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp new file mode 100644 index 000000000..83bb7c52d --- /dev/null +++ b/src/extension/internal/latex-text-renderer.cpp @@ -0,0 +1,648 @@ +#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_CPP + +/** \file + * Rendering LaTeX file (pdf+latex output) + * + * The idea stems from GNUPlot's epslatex terminal output :-) + */ +/* + * Authors: + * Johan Engelen + * Miklos Erdelyi + * + * Copyright (C) 2006-2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef PANGO_ENABLE_BACKEND +#define PANGO_ENABLE_BACKEND +#endif + +#ifndef PANGO_ENABLE_ENGINE +#define PANGO_ENABLE_ENGINE +#endif + + +#include +#include + +#include "libnr/nr-rect.h" +#include "libnrtype/Layout-TNG.h" +#include <2geom/transforms.h> +#include <2geom/pathvector.h> + +#include + +#include +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" +#include "display/nr-arena-group.h" +#include "display/curve.h" +#include "display/canvas-bpath.h" +#include "sp-item.h" +#include "sp-item-group.h" +#include "style.h" +#include "marker.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-root.h" +#include "sp-use.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "sp-mask.h" +#include "sp-clippath.h" +#include "text-editing.h" + +#include +#include "helper/png-write.h" +#include "helper/pixbuf-ops.h" + +#include "latex-text-renderer.h" +#include "extension/system.h" + +#include "io/sys.h" + +#include + +// include support for only the compiled-in surface types +#ifdef CAIRO_HAS_PDF_SURFACE +#include +#endif +#ifdef CAIRO_HAS_PS_SURFACE +#include +#endif + +//#define TRACE(_args) g_message(_args) +#define TRACE(_args) +//#define TEST(_args) _args +#define TEST(_args) + +// FIXME: expose these from sp-clippath/mask.cpp +struct SPClipPathView { + SPClipPathView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + +struct SPMaskView { + SPMaskView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + + +namespace Inkscape { +namespace Extension { +namespace Internal { + +bool +latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, + const gchar * const exportId, bool exportDrawing, bool exportCanvas) +{ + sp_document_ensure_up_to_date(doc); + + 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 renderer */ + LaTeXTextRenderer *renderer = new LaTeXTextRenderer(); + + bool ret = renderer->setTargetFile(filename); + if (ret) { + /* Render document */ + bool ret = renderer->setupDocument(doc, pageBoundingBox, base); + if (ret) { + renderer->renderItem(base); + } + } + + delete renderer; + + return ret; +} + +LaTeXTextRenderer::LaTeXTextRenderer(void) + : _stream(NULL), + _filename(NULL), + _width(0), + _height(0) +{ + push_transform(Geom::identity()); +} + +LaTeXTextRenderer::~LaTeXTextRenderer(void) +{ + if (_stream) { + writePostamble(); + + fclose(_stream); + } + + /* restore default signal handling for SIGPIPE */ +#if !defined(_WIN32) && !defined(__WIN32__) + (void) signal(SIGPIPE, SIG_DFL); +#endif + + if (_filename) { + g_free(_filename); + } + + return; +} + +/** This should create the output LaTeX file, and assign it to _stream. + * @return Returns true when succesfull + */ +bool +LaTeXTextRenderer::setTargetFile(gchar const *filename) { + if (filename != NULL) { + while (isspace(*filename)) filename += 1; + + _filename = g_path_get_basename(filename); + + gchar *filename_ext = g_strdup_printf("%s.tex", filename); + Inkscape::IO::dump_fopen_call(filename_ext, "K"); + FILE *osf = Inkscape::IO::fopen_utf8name(filename_ext, "w+"); + if (!osf) { + fprintf(stderr, "inkscape: fopen(%s): %s\n", + filename_ext, strerror(errno)); + return false; + } + _stream = osf; + g_free(filename_ext); + } + + if (_stream) { + /* fixme: this is kinda icky */ +#if !defined(_WIN32) && !defined(__WIN32__) + (void) signal(SIGPIPE, SIG_IGN); +#endif + } + + fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", PACKAGE_STRING); + fprintf(_stream, "%%%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010\n"); + fprintf(_stream, "%%%% Accompanies image file '%s' (pdf, eps, ps)\n", _filename); + fprintf(_stream, "%%%%"); + /* flush this to test output stream as early as possible */ + if (fflush(_stream)) { + if (ferror(_stream)) { + g_print("Error %d on LaTeX file output stream: %s\n", errno, + g_strerror(errno)); + } + g_print("Output to LaTeX file failed\n"); + /* fixme: should use pclose() for pipes */ + fclose(_stream); + _stream = NULL; + fflush(stdout); + return false; + } + + writePreamble(); + + return true; +} + +static char const preamble[] = +"%% To include the image in your LaTeX document, write\n" +"%% \\setlength{\\unitlength}{}\n" +"%% \\input{.tex}\n" +"%% instead of\n" +"%% \\includegraphics[width=]{.pdf}\n" +"\n" +"\\begingroup \n" +" \\makeatletter \n" +" \\providecommand\\color[2][]{% \n" +" \\GenericError{(Inkscape) \\space\\space\\@spaces}{% \n" +" Color is used for the text in Inkscape, but the color package color is not loaded. \n" +" }{Either use black text in Inkscape or load the package \n" +" color.sty in LaTeX.}% \n" +" \\renewcommand\\color[2][]{}% \n" +" }%% \n" +" \\providecommand\\rotatebox[2]{#2}% \n" +" \\makeatother \n"; + +static char const postamble[] = +" \\end{picture}% \n" +"\\endgroup \n"; + +void +LaTeXTextRenderer::writePreamble() +{ + fprintf(_stream, "%s", preamble); +} +void +LaTeXTextRenderer::writePostamble() +{ + fprintf(_stream, "%s", postamble); +} + +void +LaTeXTextRenderer::sp_group_render(SPItem *item) +{ + SPGroup *group = SP_GROUP(item); + + GSList *l = g_slist_reverse(group->childList(false)); + while (l) { + SPObject *o = SP_OBJECT (l->data); + if (SP_IS_ITEM(o)) { + renderItem (SP_ITEM (o)); + } + l = g_slist_remove (l, o); + } +} + +void +LaTeXTextRenderer::sp_use_render(SPItem *item) +{ +/* + bool translated = false; + SPUse *use = SP_USE(item); + + if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { + Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); + ctx->pushState(); + ctx->transform(&tp); + translated = true; + } + + if (use->child && SP_IS_ITEM(use->child)) { + renderItem(SP_ITEM(use->child)); + } + + if (translated) { + ctx->popState(); + } +*/ +} + +void +LaTeXTextRenderer::sp_text_render(SPItem *item) +{ + SPText *textobj = SP_TEXT (item); + + Geom::Matrix i2doc = sp_item_i2doc_affine(item); + push_transform(i2doc); + + gchar *str = sp_te_get_string_multiline(item); + + // get position and alignment + Geom::Point pos; + gchar *alignment = NULL; + Geom::OptRect bbox = item->getBounds(transform()); + Geom::Interval bbox_x = (*bbox)[Geom::X]; + Geom::Interval bbox_y = (*bbox)[Geom::Y]; + SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); + switch (style->text_anchor.computed) { + case SP_CSS_TEXT_ANCHOR_START: + pos = Geom::Point( bbox_x.min() , bbox_y.middle() ); + alignment = "[l]"; + break; + case SP_CSS_TEXT_ANCHOR_END: + pos = Geom::Point( bbox_x.max() , bbox_y.middle() ); + alignment = "[r]"; + break; + case SP_CSS_TEXT_ANCHOR_MIDDLE: + default: + pos = bbox->midpoint(); + alignment = ""; + break; + } + + // get rotation + Geom::Matrix wotransl = i2doc.without_translation(); + double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); + bool has_rotation = !Geom::are_near(degrees,0.); + + pop_transform(); + + // write to LaTeX + Inkscape::SVGOStringStream os; + +// os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; + os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; + os << "\\makebox(0,0)" << alignment << "{"; + if (has_rotation) { + os << "\\rotatebox{" << degrees << "}{"; + } + os << str; + if (has_rotation) { + os << "}"; // rotatebox end + } + os << "}"; //makebox end + os << "}%\n"; // put end + + fprintf(_stream, "%s", os.str().c_str()); +} + +void +LaTeXTextRenderer::sp_flowtext_render(SPItem *item) +{ +/* SPFlowtext *group = SP_FLOWTEXT(item); + + // write to LaTeX + Inkscape::SVGOStringStream os; + + os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; + os << " \\gplgaddtomacro\\gplbacktext{%%\n"; + os << " \\csname LTb\\endcsname%%\n"; + os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}Position}}%%\n"; + + fprintf(_stream, "%s", os.str().c_str()); +*/ +} + +void +LaTeXTextRenderer::sp_root_render(SPItem *item) +{ + SPRoot *root = SP_ROOT(item); + +// ctx->pushState(); +// setStateForItem(ctx, item); + Geom::Matrix tempmat (root->c2p); + push_transform(tempmat); + sp_group_render(item); + pop_transform(); +} + +void +LaTeXTextRenderer::sp_item_invoke_render(SPItem *item) +{ + // Check item's visibility + if (item->isHidden()) { + return; + } + + if (SP_IS_ROOT(item)) { + TRACE(("root\n")); + return sp_root_render(item); + } else if (SP_IS_GROUP(item)) { + TRACE(("group\n")); + return sp_group_render(item); + } else if (SP_IS_USE(item)) { + TRACE(("use begin---\n")); + sp_use_render(item); + TRACE(("---use end\n")); + } else if (SP_IS_TEXT(item)) { + TRACE(("text\n")); + return sp_text_render(item); + } else if (SP_IS_FLOWTEXT(item)) { + TRACE(("flowtext\n")); + return sp_flowtext_render(item); + } + // We are not interested in writing the other SPItem types to LaTeX +} + +void +LaTeXTextRenderer::setStateForItem(SPItem const *item) +{ +/* + SPStyle const *style = SP_OBJECT_STYLE(item); + ctx->setStateForStyle(style); + + CairoRenderState *state = ctx->getCurrentState(); + state->clip_path = item->clip_ref->getObject(); + state->mask = item->mask_ref->getObject(); + state->item_transform = Geom::Matrix (item->transform); + + // If parent_has_userspace is true the parent state's transform + // has to be used for the mask's/clippath's context. + // This is so because we use the image's/(flow)text's transform for positioning + // instead of explicitly specifying it and letting the renderer do the + // transformation before rendering the item. + if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_IMAGE(item)) + state->parent_has_userspace = TRUE; + TRACE(("setStateForItem opacity: %f\n", state->opacity)); +*/ +} + +void +LaTeXTextRenderer::renderItem(SPItem *item) +{ +// ctx->pushState(); +// setStateForItem(ctx, item); + +// CairoRenderState *state = ctx->getCurrentState(); +// state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); + + // Draw item on a temporary surface so a mask, clip path, or opacity can be applied to it. +// if (state->need_layer) { +// state->merge_opacity = FALSE; +// ctx->pushLayer(); +// } + Geom::Matrix tempmat (item->transform); +// ctx->transform(&tempmat); + sp_item_invoke_render(item); + +// if (state->need_layer) +// ctx->popLayer(); + +// ctx->popState(); +} + +bool +LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base) +{ +// The boundingbox calculation here should be exactly the same as the one by CairoRenderer::setupDocument ! + + if (!base) + base = SP_ITEM(sp_document_root(doc)); + + NRRect d; + if (pageBoundingBox) { + d.x0 = d.y0 = 0; + d.x1 = ceil(sp_document_width(doc)); + d.y1 = ceil(sp_document_height(doc)); + } else { + sp_item_invoke_bbox(base, &d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); + } + + // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX + double scale = 1/(d.x1-d.x0); + _width = (d.x1-d.x0) * scale; + _height = (d.y1-d.y0) * scale; + push_transform( Geom::Scale(scale, scale) ); + + if (!pageBoundingBox) + { + double high = sp_document_height(doc); + + push_transform( Geom::Translate( -d.x0, + -d.y0 ) ); + } + + // flip y-axis + push_transform( Geom::Scale(1,-1) * Geom::Translate(0, sp_document_height(doc)) ); + + // write the info to LaTeX + Inkscape::SVGOStringStream os; + + os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; + // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient. + os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << _filename << "}}%\n"; + + fprintf(_stream, "%s", os.str().c_str()); + + return true; +} + +Geom::Matrix const & +LaTeXTextRenderer::transform() +{ + return _transform_stack.top(); +} + +void +LaTeXTextRenderer::push_transform(Geom::Matrix const &tr) +{ + if(_transform_stack.size()){ + Geom::Matrix tr_top = _transform_stack.top(); + _transform_stack.push(tr * tr_top); + } else { + _transform_stack.push(tr); + } +} + +void +LaTeXTextRenderer::pop_transform() +{ + _transform_stack.pop(); +} + +/* +#include "macros.h" // SP_PRINT_* + +// Apply an SVG clip path +void +LaTeXTextRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) +{ + g_assert( ctx != NULL && ctx->_is_valid ); + + if (cp == NULL) + return; + + CairoRenderContext::CairoRenderMode saved_mode = ctx->getRenderMode(); + ctx->setRenderMode(CairoRenderContext::RENDER_MODE_CLIP); + + Geom::Matrix saved_ctm; + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + //SP_PRINT_DRECT("clipd", cp->display->bbox); + NRRect clip_bbox(cp->display->bbox); + Geom::Matrix t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); + t[4] = clip_bbox.x0; + t[5] = clip_bbox.y0; + t *= ctx->getCurrentState()->transform; + ctx->getTransform(&saved_ctm); + ctx->setTransform(&t); + } + + TRACE(("BEGIN clip\n")); + SPObject *co = SP_OBJECT(cp); + for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + SPItem *item = SP_ITEM(child); + + // combine transform of the item in clippath and the item using clippath: + Geom::Matrix tempmat (item->transform); + tempmat = tempmat * (ctx->getCurrentState()->item_transform); + + // render this item in clippath + ctx->pushState(); + ctx->transform(&tempmat); + setStateForItem(ctx, item); + sp_item_invoke_render(item, ctx); + ctx->popState(); + } + } + TRACE(("END clip\n")); + + // do clipping only if this was the first call to applyClipPath + if (ctx->getClipMode() == CairoRenderContext::CLIP_MODE_PATH + && saved_mode == CairoRenderContext::RENDER_MODE_NORMAL) + cairo_clip(ctx->_cr); + + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) + ctx->setTransform(&saved_ctm); + + ctx->setRenderMode(saved_mode); +} + +// Apply an SVG mask +void +LaTeXTextRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) +{ + g_assert( ctx != NULL && ctx->_is_valid ); + + if (mask == NULL) + return; + + //SP_PRINT_DRECT("maskd", &mask->display->bbox); + NRRect mask_bbox(mask->display->bbox); + // TODO: should the bbox be transformed if maskUnits != userSpaceOnUse ? + if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + Geom::Matrix t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); + t[4] = mask_bbox.x0; + t[5] = mask_bbox.y0; + t *= ctx->getCurrentState()->transform; + ctx->setTransform(&t); + } + + // Clip mask contents... but... + // The mask's bounding box is the "geometric bounding box" which doesn't allow for + // filters which extend outside the bounding box. So don't clip. + // ctx->addClippingRect(mask_bbox.x0, mask_bbox.y0, mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0); + + ctx->pushState(); + + TRACE(("BEGIN mask\n")); + SPObject *co = SP_OBJECT(mask); + for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + SPItem *item = SP_ITEM(child); + renderItem(ctx, item); + } + } + TRACE(("END mask\n")); + + ctx->popState(); +} +*/ + +} /* namespace Internal */ +} /* namespace Extension */ +} /* namespace Inkscape */ + +#undef TRACE + +/* End of GNU GPL code */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/latex-text-renderer.h b/src/extension/internal/latex-text-renderer.h new file mode 100644 index 000000000..a3c419015 --- /dev/null +++ b/src/extension/internal/latex-text-renderer.h @@ -0,0 +1,97 @@ +#ifndef EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN +#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN + +/** \file + * Declaration of LaTeXTextRenderer, used for rendering the accompanying LaTeX file when saving PDF output + LaTeX + */ +/* + * Authors: + * Johan Engelen + * + * Copyright (C) 2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "extension/extension.h" +#include +#include + +#include "style.h" + +#include + +#include <2geom/matrix.h> +#include + +class SPClipPath; +class SPMask; +class SPItem; + +namespace Inkscape { +namespace Extension { +namespace Internal { + +bool latex_render_document_text_to_file(SPDocument *doc, gchar const *filename, const gchar * const exportId, bool exportDrawing, bool exportCanvas); + +class LaTeXTextRenderer { +public: + LaTeXTextRenderer(); + virtual ~LaTeXTextRenderer(); + + bool setTargetFile(gchar const *filename); + + void setStateForItem(SPItem const *item); + +// void applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp); +// void applyMask(CairoRenderContext *ctx, SPMask const *mask); + + /** Initializes the LaTeXTextRenderer according to the specified + SPDocument. Important to set the boundingbox to the pdf boundingbox */ + bool setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base); + + /** Traverses the object tree and invokes the render methods. */ + void renderItem(SPItem *item); + +protected: + FILE * _stream; + gchar * _filename; + + void push_transform(Geom::Matrix const &transform); + Geom::Matrix const & transform(); + void pop_transform(); + std::stack _transform_stack; + double _width; + double _height; + + void writePreamble(); + void writePostamble(); + + void sp_item_invoke_render(SPItem *item); + void sp_root_render(SPItem *item); + void sp_group_render(SPItem *item); + void sp_use_render(SPItem *item); + void sp_text_render(SPItem *item); + void sp_flowtext_render(SPItem *item); +}; + +} /* namespace Internal */ +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_H_SEEN */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/pdflatex-renderer.cpp b/src/extension/internal/pdflatex-renderer.cpp deleted file mode 100644 index b70bac107..000000000 --- a/src/extension/internal/pdflatex-renderer.cpp +++ /dev/null @@ -1,609 +0,0 @@ -#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_CPP - -/** \file - * Rendering LaTeX file (pdf+latex output) - * - * The idea stems from GNUPlot's epslatex terminal output :-) - */ -/* - * Authors: - * Johan Engelen - * Miklos Erdelyi - * - * Copyright (C) 2006-2010 Authors - * - * Licensed under GNU GPL - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifndef PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_BACKEND -#endif - -#ifndef PANGO_ENABLE_ENGINE -#define PANGO_ENABLE_ENGINE -#endif - - -#include -#include - -#include "libnr/nr-rect.h" -#include "libnrtype/Layout-TNG.h" -#include <2geom/transforms.h> -#include <2geom/pathvector.h> - -#include - -#include -#include "display/nr-arena.h" -#include "display/nr-arena-item.h" -#include "display/nr-arena-group.h" -#include "display/curve.h" -#include "display/canvas-bpath.h" -#include "sp-item.h" -#include "sp-item-group.h" -#include "style.h" -#include "marker.h" -#include "sp-linear-gradient.h" -#include "sp-radial-gradient.h" -#include "sp-root.h" -#include "sp-use.h" -#include "sp-text.h" -#include "sp-flowtext.h" -#include "sp-mask.h" -#include "sp-clippath.h" -#include "text-editing.h" - -#include -#include "helper/png-write.h" -#include "helper/pixbuf-ops.h" - -#include "pdflatex-renderer.h" -#include "extension/system.h" - -#include "io/sys.h" - -#include - -// include support for only the compiled-in surface types -#ifdef CAIRO_HAS_PDF_SURFACE -#include -#endif -#ifdef CAIRO_HAS_PS_SURFACE -#include -#endif - -//#define TRACE(_args) g_message(_args) -#define TRACE(_args) -//#define TEST(_args) _args -#define TEST(_args) - -// FIXME: expose these from sp-clippath/mask.cpp -struct SPClipPathView { - SPClipPathView *next; - unsigned int key; - NRArenaItem *arenaitem; - NRRect bbox; -}; - -struct SPMaskView { - SPMaskView *next; - unsigned int key; - NRArenaItem *arenaitem; - NRRect bbox; -}; - -namespace Inkscape { -namespace Extension { -namespace Internal { - - -PDFLaTeXRenderer::PDFLaTeXRenderer(void) - : _stream(NULL), - _filename(NULL), - _width(0), - _height(0) -{ - push_transform(Geom::identity()); -} - -PDFLaTeXRenderer::~PDFLaTeXRenderer(void) -{ - if (_stream) { - writePostamble(); - - fclose(_stream); - } - - /* restore default signal handling for SIGPIPE */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_DFL); -#endif - - if (_filename) { - g_free(_filename); - } - - return; -} - -/** This should create the output LaTeX file, and assign it to _stream. - * @return Returns true when succesfull - */ -bool -PDFLaTeXRenderer::setTargetFile(gchar const *filename) { - if (filename != NULL) { - while (isspace(*filename)) filename += 1; - - _filename = g_strdup(filename); - - gchar *filename_ext = g_strdup_printf("%s.tex", filename); - Inkscape::IO::dump_fopen_call(filename_ext, "K"); - FILE *osf = Inkscape::IO::fopen_utf8name(filename_ext, "w+"); - if (!osf) { - fprintf(stderr, "inkscape: fopen(%s): %s\n", - filename_ext, strerror(errno)); - return false; - } - _stream = osf; - g_free(filename_ext); - } - - if (_stream) { - /* fixme: this is kinda icky */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_IGN); -#endif - } - - fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", PACKAGE_STRING); - fprintf(_stream, "%%%% PDF + LaTeX output extension by Johan Engelen, 2010\n"); - fprintf(_stream, "%%%% Accompanies %s.pdf\n", _filename); - /* flush this to test output stream as early as possible */ - if (fflush(_stream)) { - if (ferror(_stream)) { - g_print("Error %d on LaTeX file output stream: %s\n", errno, - g_strerror(errno)); - } - g_print("Output to LaTeX file failed\n"); - /* fixme: should use pclose() for pipes */ - fclose(_stream); - _stream = NULL; - fflush(stdout); - return false; - } - - writePreamble(); - - return true; -} - -static char const preamble[] = -"%% To include the image in your LaTeX document, write\n" -"%% \\setlength{\\unitlength}{}\n" -"%% \\input{.tex}\n" -"%% instead of\n" -"%% \\includegraphics[width=]{.pdf}\n" -"\n" -"\\begingroup \n" -" \\makeatletter \n" -" \\providecommand\\color[2][]{% \n" -" \\GenericError{(Inkscape) \\space\\space\\@spaces}{% \n" -" Color is used for the text in Inkscape, but the color package color is not loaded. \n" -" }{Either use black text in Inkscape or load the package \n" -" color.sty in LaTeX.}% \n" -" \\renewcommand\\color[2][]{}% \n" -" }%% \n" -" \\providecommand\\rotatebox[2]{#2}% \n" -" \\makeatother \n"; - -static char const postamble[] = -" \\end{picture}% \n" -"\\endgroup \n"; - -void -PDFLaTeXRenderer::writePreamble() -{ - fprintf(_stream, "%s", preamble); -} -void -PDFLaTeXRenderer::writePostamble() -{ - fprintf(_stream, "%s", postamble); -} - -void -PDFLaTeXRenderer::sp_group_render(SPItem *item) -{ - SPGroup *group = SP_GROUP(item); - - GSList *l = g_slist_reverse(group->childList(false)); - while (l) { - SPObject *o = SP_OBJECT (l->data); - if (SP_IS_ITEM(o)) { - renderItem (SP_ITEM (o)); - } - l = g_slist_remove (l, o); - } -} - -void -PDFLaTeXRenderer::sp_use_render(SPItem *item) -{ -/* - bool translated = false; - SPUse *use = SP_USE(item); - - if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); - ctx->pushState(); - ctx->transform(&tp); - translated = true; - } - - if (use->child && SP_IS_ITEM(use->child)) { - renderItem(SP_ITEM(use->child)); - } - - if (translated) { - ctx->popState(); - } -*/ -} - -void -PDFLaTeXRenderer::sp_text_render(SPItem *item) -{ - SPText *textobj = SP_TEXT (item); - - Geom::Matrix i2doc = sp_item_i2doc_affine(item); - push_transform(i2doc); - - gchar *str = sp_te_get_string_multiline(item); - - // get position and alignment - Geom::Point pos; - gchar *alignment = NULL; - Geom::OptRect bbox = item->getBounds(transform()); - Geom::Interval bbox_x = (*bbox)[Geom::X]; - Geom::Interval bbox_y = (*bbox)[Geom::Y]; - SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); - switch (style->text_anchor.computed) { - case SP_CSS_TEXT_ANCHOR_START: - pos = Geom::Point( bbox_x.min() , bbox_y.middle() ); - alignment = "[l]"; - break; - case SP_CSS_TEXT_ANCHOR_END: - pos = Geom::Point( bbox_x.max() , bbox_y.middle() ); - alignment = "[r]"; - break; - case SP_CSS_TEXT_ANCHOR_MIDDLE: - default: - pos = bbox->midpoint(); - alignment = ""; - break; - } - - // get rotation - Geom::Matrix wotransl = i2doc.without_translation(); - double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); - bool has_rotation = !Geom::are_near(degrees,0.); - - pop_transform(); - - // write to LaTeX - Inkscape::SVGOStringStream os; - -// os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; - os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; - os << "\\makebox(0,0)" << alignment << "{"; - if (has_rotation) { - os << "\\rotatebox{" << degrees << "}{"; - } - os << str; - if (has_rotation) { - os << "}"; // rotatebox end - } - os << "}"; //makebox end - os << "}%\n"; // put end - - fprintf(_stream, "%s", os.str().c_str()); -} - -void -PDFLaTeXRenderer::sp_flowtext_render(SPItem *item) -{ -/* SPFlowtext *group = SP_FLOWTEXT(item); - - // write to LaTeX - Inkscape::SVGOStringStream os; - - os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; - os << " \\gplgaddtomacro\\gplbacktext{%%\n"; - os << " \\csname LTb\\endcsname%%\n"; - os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}Position}}%%\n"; - - fprintf(_stream, "%s", os.str().c_str()); -*/ -} - -void -PDFLaTeXRenderer::sp_root_render(SPItem *item) -{ - SPRoot *root = SP_ROOT(item); - -// ctx->pushState(); -// setStateForItem(ctx, item); - Geom::Matrix tempmat (root->c2p); - push_transform(tempmat); - sp_group_render(item); - pop_transform(); -} - -void -PDFLaTeXRenderer::sp_item_invoke_render(SPItem *item) -{ - // Check item's visibility - if (item->isHidden()) { - return; - } - - if (SP_IS_ROOT(item)) { - TRACE(("root\n")); - return sp_root_render(item); - } else if (SP_IS_GROUP(item)) { - TRACE(("group\n")); - return sp_group_render(item); - } else if (SP_IS_USE(item)) { - TRACE(("use begin---\n")); - sp_use_render(item); - TRACE(("---use end\n")); - } else if (SP_IS_TEXT(item)) { - TRACE(("text\n")); - return sp_text_render(item); - } else if (SP_IS_FLOWTEXT(item)) { - TRACE(("flowtext\n")); - return sp_flowtext_render(item); - } - // We are not interested in writing the other SPItem types to LaTeX -} - -void -PDFLaTeXRenderer::setStateForItem(SPItem const *item) -{ -/* - SPStyle const *style = SP_OBJECT_STYLE(item); - ctx->setStateForStyle(style); - - CairoRenderState *state = ctx->getCurrentState(); - state->clip_path = item->clip_ref->getObject(); - state->mask = item->mask_ref->getObject(); - state->item_transform = Geom::Matrix (item->transform); - - // If parent_has_userspace is true the parent state's transform - // has to be used for the mask's/clippath's context. - // This is so because we use the image's/(flow)text's transform for positioning - // instead of explicitly specifying it and letting the renderer do the - // transformation before rendering the item. - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_IMAGE(item)) - state->parent_has_userspace = TRUE; - TRACE(("setStateForItem opacity: %f\n", state->opacity)); -*/ -} - -void -PDFLaTeXRenderer::renderItem(SPItem *item) -{ -// ctx->pushState(); -// setStateForItem(ctx, item); - -// CairoRenderState *state = ctx->getCurrentState(); -// state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); - - // Draw item on a temporary surface so a mask, clip path, or opacity can be applied to it. -// if (state->need_layer) { -// state->merge_opacity = FALSE; -// ctx->pushLayer(); -// } - Geom::Matrix tempmat (item->transform); -// ctx->transform(&tempmat); - sp_item_invoke_render(item); - -// if (state->need_layer) -// ctx->popLayer(); - -// ctx->popState(); -} - -bool -PDFLaTeXRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base) -{ -// The boundingbox calculation here should be exactly the same as the one by CairoRenderer::setupDocument ! - - if (!base) - base = SP_ITEM(sp_document_root(doc)); - - NRRect d; - if (pageBoundingBox) { - d.x0 = d.y0 = 0; - d.x1 = ceil(sp_document_width(doc)); - d.y1 = ceil(sp_document_height(doc)); - } else { - sp_item_invoke_bbox(base, &d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); - } - - // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX - double scale = 1/(d.x1-d.x0); - _width = (d.x1-d.x0) * scale; - _height = (d.y1-d.y0) * scale; - push_transform( Geom::Scale(scale, scale) ); - - if (!pageBoundingBox) - { - double high = sp_document_height(doc); - - push_transform( Geom::Translate( -d.x0, - -d.y0 ) ); - } - - // flip y-axis - push_transform( Geom::Scale(1,-1) * Geom::Translate(0, sp_document_height(doc)) ); - - // write the info to LaTeX - Inkscape::SVGOStringStream os; - - os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; - // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient. - gchar *figurefile = g_path_get_basename(_filename); - os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << figurefile << ".pdf}}%\n"; - g_free(figurefile); - - fprintf(_stream, "%s", os.str().c_str()); - - return true; -} - -Geom::Matrix const & -PDFLaTeXRenderer::transform() -{ - return _transform_stack.top(); -} - -void -PDFLaTeXRenderer::push_transform(Geom::Matrix const &tr) -{ - if(_transform_stack.size()){ - Geom::Matrix tr_top = _transform_stack.top(); - _transform_stack.push(tr * tr_top); - } else { - _transform_stack.push(tr); - } -} - -void -PDFLaTeXRenderer::pop_transform() -{ - _transform_stack.pop(); -} - -/* -#include "macros.h" // SP_PRINT_* - -// Apply an SVG clip path -void -PDFLaTeXRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) -{ - g_assert( ctx != NULL && ctx->_is_valid ); - - if (cp == NULL) - return; - - CairoRenderContext::CairoRenderMode saved_mode = ctx->getRenderMode(); - ctx->setRenderMode(CairoRenderContext::RENDER_MODE_CLIP); - - Geom::Matrix saved_ctm; - if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - //SP_PRINT_DRECT("clipd", cp->display->bbox); - NRRect clip_bbox(cp->display->bbox); - Geom::Matrix t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); - t[4] = clip_bbox.x0; - t[5] = clip_bbox.y0; - t *= ctx->getCurrentState()->transform; - ctx->getTransform(&saved_ctm); - ctx->setTransform(&t); - } - - TRACE(("BEGIN clip\n")); - SPObject *co = SP_OBJECT(cp); - for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); - - // combine transform of the item in clippath and the item using clippath: - Geom::Matrix tempmat (item->transform); - tempmat = tempmat * (ctx->getCurrentState()->item_transform); - - // render this item in clippath - ctx->pushState(); - ctx->transform(&tempmat); - setStateForItem(ctx, item); - sp_item_invoke_render(item, ctx); - ctx->popState(); - } - } - TRACE(("END clip\n")); - - // do clipping only if this was the first call to applyClipPath - if (ctx->getClipMode() == CairoRenderContext::CLIP_MODE_PATH - && saved_mode == CairoRenderContext::RENDER_MODE_NORMAL) - cairo_clip(ctx->_cr); - - if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) - ctx->setTransform(&saved_ctm); - - ctx->setRenderMode(saved_mode); -} - -// Apply an SVG mask -void -PDFLaTeXRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) -{ - g_assert( ctx != NULL && ctx->_is_valid ); - - if (mask == NULL) - return; - - //SP_PRINT_DRECT("maskd", &mask->display->bbox); - NRRect mask_bbox(mask->display->bbox); - // TODO: should the bbox be transformed if maskUnits != userSpaceOnUse ? - if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Matrix t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); - t[4] = mask_bbox.x0; - t[5] = mask_bbox.y0; - t *= ctx->getCurrentState()->transform; - ctx->setTransform(&t); - } - - // Clip mask contents... but... - // The mask's bounding box is the "geometric bounding box" which doesn't allow for - // filters which extend outside the bounding box. So don't clip. - // ctx->addClippingRect(mask_bbox.x0, mask_bbox.y0, mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0); - - ctx->pushState(); - - TRACE(("BEGIN mask\n")); - SPObject *co = SP_OBJECT(mask); - for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); - renderItem(ctx, item); - } - } - TRACE(("END mask\n")); - - ctx->popState(); -} -*/ - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - -#undef TRACE - -/* End of GNU GPL code */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/pdflatex-renderer.h b/src/extension/internal/pdflatex-renderer.h deleted file mode 100644 index 93c06b114..000000000 --- a/src/extension/internal/pdflatex-renderer.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN -#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN - -/** \file - * Declaration of PDFLaTeXRenderer, used for rendering the accompanying LaTeX file when saving PDF output + LaTeX - */ -/* - * Authors: - * Johan Engelen - * - * Copyright (C) 2010 Authors - * - * Licensed under GNU GPL - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "extension/extension.h" -#include -#include - -#include "style.h" - -#include - -#include <2geom/matrix.h> -#include - -class SPClipPath; -class SPMask; -class SPItem; - -namespace Inkscape { -namespace Extension { -namespace Internal { - -class PDFLaTeXRenderer { -public: - PDFLaTeXRenderer(); - virtual ~PDFLaTeXRenderer(); - - bool setTargetFile(gchar const *filename); - - void setStateForItem(SPItem const *item); - -// void applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp); -// void applyMask(CairoRenderContext *ctx, SPMask const *mask); - - /** Initializes the PDFLaTeXRenderer according to the specified - SPDocument. Important to set the boundingbox to the pdf boundingbox */ - bool setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base); - - /** Traverses the object tree and invokes the render methods. */ - void renderItem(SPItem *item); - -protected: - FILE * _stream; - gchar * _filename; - - void push_transform(Geom::Matrix const &transform); - Geom::Matrix const & transform(); - void pop_transform(); - std::stack _transform_stack; - double _width; - double _height; - - void writePreamble(); - void writePostamble(); - - void sp_item_invoke_render(SPItem *item); - void sp_root_render(SPItem *item); - void sp_group_render(SPItem *item); - void sp_use_render(SPItem *item); - void sp_text_render(SPItem *item); - void sp_flowtext_render(SPItem *item); -}; - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_H_SEEN */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 3c2f9385f7e3fa38fcd785d989edd90a167b1f8a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 22 Feb 2010 21:17:55 +0100 Subject: clean up code (bzr r9101.1.14) --- src/extension/internal/latex-text-renderer.cpp | 231 ++----------------------- src/extension/internal/latex-text-renderer.h | 24 +-- 2 files changed, 15 insertions(+), 240 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 83bb7c52d..159595a6d 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -1,7 +1,7 @@ -#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_CPP +#define EXTENSION_INTERNAL_LATEX_TEXT_RENDERER_CPP /** \file - * Rendering LaTeX file (pdf+latex output) + * Rendering LaTeX file (pdf/eps/ps+latex output) * * The idea stems from GNUPlot's epslatex terminal output :-) */ @@ -19,85 +19,30 @@ # include "config.h" #endif -#ifndef PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_BACKEND -#endif - -#ifndef PANGO_ENABLE_ENGINE -#define PANGO_ENABLE_ENGINE -#endif - +#include "latex-text-renderer.h" #include #include -#include "libnr/nr-rect.h" #include "libnrtype/Layout-TNG.h" #include <2geom/transforms.h> -#include <2geom/pathvector.h> - -#include #include -#include "display/nr-arena.h" -#include "display/nr-arena-item.h" -#include "display/nr-arena-group.h" -#include "display/curve.h" -#include "display/canvas-bpath.h" #include "sp-item.h" #include "sp-item-group.h" #include "style.h" -#include "marker.h" -#include "sp-linear-gradient.h" -#include "sp-radial-gradient.h" #include "sp-root.h" #include "sp-use.h" #include "sp-text.h" #include "sp-flowtext.h" -#include "sp-mask.h" -#include "sp-clippath.h" #include "text-editing.h" #include -#include "helper/png-write.h" -#include "helper/pixbuf-ops.h" -#include "latex-text-renderer.h" #include "extension/system.h" #include "io/sys.h" -#include - -// include support for only the compiled-in surface types -#ifdef CAIRO_HAS_PDF_SURFACE -#include -#endif -#ifdef CAIRO_HAS_PS_SURFACE -#include -#endif - -//#define TRACE(_args) g_message(_args) -#define TRACE(_args) -//#define TEST(_args) _args -#define TEST(_args) - -// FIXME: expose these from sp-clippath/mask.cpp -struct SPClipPathView { - SPClipPathView *next; - unsigned int key; - NRArenaItem *arenaitem; - NRRect bbox; -}; - -struct SPMaskView { - SPMaskView *next; - unsigned int key; - NRArenaItem *arenaitem; - NRRect bbox; -}; - - namespace Inkscape { namespace Extension { namespace Internal { @@ -144,9 +89,7 @@ latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, LaTeXTextRenderer::LaTeXTextRenderer(void) : _stream(NULL), - _filename(NULL), - _width(0), - _height(0) + _filename(NULL) { push_transform(Geom::identity()); } @@ -281,8 +224,7 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { Geom::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); - ctx->pushState(); - ctx->transform(&tp); + push_transform(tp); translated = true; } @@ -291,7 +233,7 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) } if (translated) { - ctx->popState(); + pop_transform(); } */ } @@ -339,7 +281,6 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) // write to LaTeX Inkscape::SVGOStringStream os; -// os << "\\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){\\makebox(0,0)[" << alignment << "]{\\strut{}" << str << "}}%%\n"; os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; os << "\\makebox(0,0)" << alignment << "{"; if (has_rotation) { @@ -377,8 +318,6 @@ LaTeXTextRenderer::sp_root_render(SPItem *item) { SPRoot *root = SP_ROOT(item); -// ctx->pushState(); -// setStateForItem(ctx, item); Geom::Matrix tempmat (root->c2p); push_transform(tempmat); sp_group_render(item); @@ -394,70 +333,26 @@ LaTeXTextRenderer::sp_item_invoke_render(SPItem *item) } if (SP_IS_ROOT(item)) { - TRACE(("root\n")); return sp_root_render(item); } else if (SP_IS_GROUP(item)) { - TRACE(("group\n")); return sp_group_render(item); } else if (SP_IS_USE(item)) { - TRACE(("use begin---\n")); sp_use_render(item); - TRACE(("---use end\n")); } else if (SP_IS_TEXT(item)) { - TRACE(("text\n")); return sp_text_render(item); } else if (SP_IS_FLOWTEXT(item)) { - TRACE(("flowtext\n")); return sp_flowtext_render(item); } // We are not interested in writing the other SPItem types to LaTeX } -void -LaTeXTextRenderer::setStateForItem(SPItem const *item) -{ -/* - SPStyle const *style = SP_OBJECT_STYLE(item); - ctx->setStateForStyle(style); - - CairoRenderState *state = ctx->getCurrentState(); - state->clip_path = item->clip_ref->getObject(); - state->mask = item->mask_ref->getObject(); - state->item_transform = Geom::Matrix (item->transform); - - // If parent_has_userspace is true the parent state's transform - // has to be used for the mask's/clippath's context. - // This is so because we use the image's/(flow)text's transform for positioning - // instead of explicitly specifying it and letting the renderer do the - // transformation before rendering the item. - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_IMAGE(item)) - state->parent_has_userspace = TRUE; - TRACE(("setStateForItem opacity: %f\n", state->opacity)); -*/ -} - void LaTeXTextRenderer::renderItem(SPItem *item) { -// ctx->pushState(); -// setStateForItem(ctx, item); - -// CairoRenderState *state = ctx->getCurrentState(); -// state->need_layer = ( state->mask || state->clip_path || state->opacity != 1.0 ); - - // Draw item on a temporary surface so a mask, clip path, or opacity can be applied to it. -// if (state->need_layer) { -// state->merge_opacity = FALSE; -// ctx->pushLayer(); -// } - Geom::Matrix tempmat (item->transform); -// ctx->transform(&tempmat); +// push_transform(item->transform); sp_item_invoke_render(item); -// if (state->need_layer) -// ctx->popLayer(); - -// ctx->popState(); +// pop_transform(); } bool @@ -479,16 +374,15 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX double scale = 1/(d.x1-d.x0); - _width = (d.x1-d.x0) * scale; - _height = (d.y1-d.y0) * scale; + double _width = (d.x1-d.x0) * scale; + double _height = (d.y1-d.y0) * scale; push_transform( Geom::Scale(scale, scale) ); if (!pageBoundingBox) { double high = sp_document_height(doc); - push_transform( Geom::Translate( -d.x0, - -d.y0 ) ); + push_transform( Geom::Translate(-d.x0, -d.y0) ); } // flip y-axis @@ -529,113 +423,10 @@ LaTeXTextRenderer::pop_transform() _transform_stack.pop(); } -/* -#include "macros.h" // SP_PRINT_* - -// Apply an SVG clip path -void -LaTeXTextRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) -{ - g_assert( ctx != NULL && ctx->_is_valid ); - - if (cp == NULL) - return; - - CairoRenderContext::CairoRenderMode saved_mode = ctx->getRenderMode(); - ctx->setRenderMode(CairoRenderContext::RENDER_MODE_CLIP); - - Geom::Matrix saved_ctm; - if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - //SP_PRINT_DRECT("clipd", cp->display->bbox); - NRRect clip_bbox(cp->display->bbox); - Geom::Matrix t(Geom::Scale(clip_bbox.x1 - clip_bbox.x0, clip_bbox.y1 - clip_bbox.y0)); - t[4] = clip_bbox.x0; - t[5] = clip_bbox.y0; - t *= ctx->getCurrentState()->transform; - ctx->getTransform(&saved_ctm); - ctx->setTransform(&t); - } - - TRACE(("BEGIN clip\n")); - SPObject *co = SP_OBJECT(cp); - for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); - - // combine transform of the item in clippath and the item using clippath: - Geom::Matrix tempmat (item->transform); - tempmat = tempmat * (ctx->getCurrentState()->item_transform); - - // render this item in clippath - ctx->pushState(); - ctx->transform(&tempmat); - setStateForItem(ctx, item); - sp_item_invoke_render(item, ctx); - ctx->popState(); - } - } - TRACE(("END clip\n")); - - // do clipping only if this was the first call to applyClipPath - if (ctx->getClipMode() == CairoRenderContext::CLIP_MODE_PATH - && saved_mode == CairoRenderContext::RENDER_MODE_NORMAL) - cairo_clip(ctx->_cr); - - if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) - ctx->setTransform(&saved_ctm); - - ctx->setRenderMode(saved_mode); -} - -// Apply an SVG mask -void -LaTeXTextRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) -{ - g_assert( ctx != NULL && ctx->_is_valid ); - - if (mask == NULL) - return; - - //SP_PRINT_DRECT("maskd", &mask->display->bbox); - NRRect mask_bbox(mask->display->bbox); - // TODO: should the bbox be transformed if maskUnits != userSpaceOnUse ? - if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Matrix t(Geom::Scale(mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0)); - t[4] = mask_bbox.x0; - t[5] = mask_bbox.y0; - t *= ctx->getCurrentState()->transform; - ctx->setTransform(&t); - } - - // Clip mask contents... but... - // The mask's bounding box is the "geometric bounding box" which doesn't allow for - // filters which extend outside the bounding box. So don't clip. - // ctx->addClippingRect(mask_bbox.x0, mask_bbox.y0, mask_bbox.x1 - mask_bbox.x0, mask_bbox.y1 - mask_bbox.y0); - - ctx->pushState(); - - TRACE(("BEGIN mask\n")); - SPObject *co = SP_OBJECT(mask); - for (SPObject *child = sp_object_first_child(co) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM(child)) { - SPItem *item = SP_ITEM(child); - renderItem(ctx, item); - } - } - TRACE(("END mask\n")); - - ctx->popState(); -} -*/ - } /* namespace Internal */ } /* namespace Extension */ } /* namespace Inkscape */ -#undef TRACE - -/* End of GNU GPL code */ - /* Local Variables: mode:c++ diff --git a/src/extension/internal/latex-text-renderer.h b/src/extension/internal/latex-text-renderer.h index a3c419015..69f539314 100644 --- a/src/extension/internal/latex-text-renderer.h +++ b/src/extension/internal/latex-text-renderer.h @@ -1,8 +1,8 @@ -#ifndef EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN -#define EXTENSION_INTERNAL_PDF_LATEX_RENDERER_H_SEEN +#ifndef EXTENSION_INTERNAL_LATEX_TEXT_RENDERER_H_SEEN +#define EXTENSION_INTERNAL_LATEX_TEXT_RENDERER_H_SEEN /** \file - * Declaration of LaTeXTextRenderer, used for rendering the accompanying LaTeX file when saving PDF output + LaTeX + * Declaration of LaTeXTextRenderer, used for rendering the accompanying LaTeX file when exporting to PDF/EPS/PS + LaTeX */ /* * Authors: @@ -18,18 +18,9 @@ #endif #include "extension/extension.h" -#include -#include - -#include "style.h" - -#include - #include <2geom/matrix.h> #include -class SPClipPath; -class SPMask; class SPItem; namespace Inkscape { @@ -45,11 +36,6 @@ public: bool setTargetFile(gchar const *filename); - void setStateForItem(SPItem const *item); - -// void applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp); -// void applyMask(CairoRenderContext *ctx, SPMask const *mask); - /** Initializes the LaTeXTextRenderer according to the specified SPDocument. Important to set the boundingbox to the pdf boundingbox */ bool setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *base); @@ -65,8 +51,6 @@ protected: Geom::Matrix const & transform(); void pop_transform(); std::stack _transform_stack; - double _width; - double _height; void writePreamble(); void writePostamble(); @@ -83,7 +67,7 @@ protected: } /* namespace Extension */ } /* namespace Inkscape */ -#endif /* !EXTENSION_INTERNAL_CAIRO_RENDERER_H_SEEN */ +#endif /* !EXTENSION_INTERNAL_LATEX_TEXT_RENDERER_H_SEEN */ /* Local Variables: -- cgit v1.2.3 From ee162daf2703adeba5ffc58574c0a6eb356583e9 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 22 Feb 2010 21:39:08 +0100 Subject: - proper transformations handling - 2geomify some stuff (bzr r9101.1.15) --- src/extension/internal/latex-text-renderer.cpp | 36 ++++++++++++-------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 159595a6d..7290bda56 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -26,6 +26,7 @@ #include "libnrtype/Layout-TNG.h" #include <2geom/transforms.h> +#include <2geom/rect.h> #include #include "sp-item.h" @@ -47,6 +48,10 @@ namespace Inkscape { namespace Extension { namespace Internal { +/** + * This method is called by the PDF, EPS and PS output extensions. + * @param filename This should be the filename without extension to which the tex code should be written. Output goes to .tex. + */ bool latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, const gchar * const exportId, bool exportDrawing, bool exportCanvas) @@ -243,9 +248,6 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) { SPText *textobj = SP_TEXT (item); - Geom::Matrix i2doc = sp_item_i2doc_affine(item); - push_transform(i2doc); - gchar *str = sp_te_get_string_multiline(item); // get position and alignment @@ -272,12 +274,11 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) } // get rotation + Geom::Matrix i2doc = sp_item_i2doc_affine(item); Geom::Matrix wotransl = i2doc.without_translation(); double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); bool has_rotation = !Geom::are_near(degrees,0.); - pop_transform(); - // write to LaTeX Inkscape::SVGOStringStream os; @@ -318,8 +319,7 @@ LaTeXTextRenderer::sp_root_render(SPItem *item) { SPRoot *root = SP_ROOT(item); - Geom::Matrix tempmat (root->c2p); - push_transform(tempmat); + push_transform(root->c2p); sp_group_render(item); pop_transform(); } @@ -349,10 +349,9 @@ LaTeXTextRenderer::sp_item_invoke_render(SPItem *item) void LaTeXTextRenderer::renderItem(SPItem *item) { -// push_transform(item->transform); + push_transform(item->transform); sp_item_invoke_render(item); - -// pop_transform(); + pop_transform(); } bool @@ -363,26 +362,25 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * if (!base) base = SP_ITEM(sp_document_root(doc)); - NRRect d; + Geom::OptRect d; if (pageBoundingBox) { - d.x0 = d.y0 = 0; - d.x1 = ceil(sp_document_width(doc)); - d.y1 = ceil(sp_document_height(doc)); + d = Geom::Rect( Geom::Point(0,0), + Geom::Point(sp_document_width(doc), sp_document_height(doc)) ); } else { - sp_item_invoke_bbox(base, &d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); + sp_item_invoke_bbox(base, d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); } // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX - double scale = 1/(d.x1-d.x0); - double _width = (d.x1-d.x0) * scale; - double _height = (d.y1-d.y0) * scale; + double scale = 1/(d->width()); + double _width = d->width() * scale; + double _height = d->height() * scale; push_transform( Geom::Scale(scale, scale) ); if (!pageBoundingBox) { double high = sp_document_height(doc); - push_transform( Geom::Translate(-d.x0, -d.y0) ); + push_transform( Geom::Translate( - d->min() ) ); } // flip y-axis -- cgit v1.2.3 From 5c391ba25dc2a08f6eeba290847c970e0a1a1433 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 22 Feb 2010 22:52:22 +0100 Subject: also output color to tex. ICC colors do not work yet. (bzr r9101.1.16) --- src/extension/internal/latex-text-renderer.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 7290bda56..e07b17fb8 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -247,6 +247,7 @@ void LaTeXTextRenderer::sp_text_render(SPItem *item) { SPText *textobj = SP_TEXT (item); + SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); gchar *str = sp_te_get_string_multiline(item); @@ -256,7 +257,6 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) Geom::OptRect bbox = item->getBounds(transform()); Geom::Interval bbox_x = (*bbox)[Geom::X]; Geom::Interval bbox_y = (*bbox)[Geom::Y]; - SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); switch (style->text_anchor.computed) { case SP_CSS_TEXT_ANCHOR_START: pos = Geom::Point( bbox_x.min() , bbox_y.middle() ); @@ -273,6 +273,20 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) break; } + // determine color (for now, use rgb color model as it is most native to Inkscape) + bool has_color = false; // if the item has no color set, don't force black color + // TODO: how to handle ICC colors? + // give priority to fill color + guint32 rgba = 0; + if (style->fill.set && style->fill.isColor()) { + has_color = true; + rgba = style->fill.value.color.toRGBA32(1.); + } else if (style->stroke.set && style->stroke.isColor()) { + has_color = true; + rgba = style->stroke.value.color.toRGBA32(1.); + } + + // get rotation Geom::Matrix i2doc = sp_item_i2doc_affine(item); Geom::Matrix wotransl = i2doc.without_translation(); @@ -283,6 +297,9 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) Inkscape::SVGOStringStream os; os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; + if (has_color) { + os << "\\color[rgb]{" << SP_RGBA32_R_F(rgba) << "," << SP_RGBA32_G_F(rgba) << "," << SP_RGBA32_B_F(rgba) << "}"; + } os << "\\makebox(0,0)" << alignment << "{"; if (has_rotation) { os << "\\rotatebox{" << degrees << "}{"; -- cgit v1.2.3 From ae163bd71f2232661ed5c43a72d571ec6b8a1111 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 23 Feb 2010 12:28:49 +0100 Subject: PStricks opacity fix. Fixed bugs: - https://launchpad.net/bugs/379790 (bzr r9106) --- src/extension/internal/latex-pstricks.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-pstricks.cpp b/src/extension/internal/latex-pstricks.cpp index 789e5ea34..34b7532ce 100644 --- a/src/extension/internal/latex-pstricks.cpp +++ b/src/extension/internal/latex-pstricks.cpp @@ -203,13 +203,19 @@ PrintLatex::fill(Inkscape::Extension::Print *mod, if (style->fill.isColor()) { Inkscape::SVGOStringStream os; float rgb[3]; + float fill_opacity; os.setf(std::ios::fixed); + fill_opacity=SP_SCALE24_TO_FLOAT(style->fill_opacity.value); sp_color_get_rgb_floatv(&style->fill.value.color, rgb); os << "{\n\\newrgbcolor{curcolor}{" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "}\n"; + os << "\\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor"; + if (fill_opacity!=1.0) { + os << ",opacity="<stroke.isColor()) { Inkscape::SVGOStringStream os; float rgb[3]; + float stroke_opacity; Geom::Matrix tr_stack = m_tr_stack.top(); double const scale = tr_stack.descrim(); os.setf(std::ios::fixed); + stroke_opacity=SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); sp_color_get_rgb_floatv(&style->stroke.value.color, rgb); os << "{\n\\newrgbcolor{curcolor}{" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "}\n"; os << "\\pscustom[linewidth=" << style->stroke_width.computed*scale<< ",linecolor=curcolor"; + + if (stroke_opacity!=1.0) { + os<<",strokeopacity="<stroke_dasharray_set && style->stroke_dash.n_dash && -- cgit v1.2.3 From 5ee3de5e8e6315a57cac1f34c9ceb5ef100c162a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 24 Feb 2010 22:07:31 +0100 Subject: output clones to latex too (bzr r9101.1.17) --- src/extension/internal/latex-text-renderer.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index e07b17fb8..6c09a7396 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -223,7 +223,6 @@ LaTeXTextRenderer::sp_group_render(SPItem *item) void LaTeXTextRenderer::sp_use_render(SPItem *item) { -/* bool translated = false; SPUse *use = SP_USE(item); @@ -240,7 +239,6 @@ LaTeXTextRenderer::sp_use_render(SPItem *item) if (translated) { pop_transform(); } -*/ } void -- cgit v1.2.3 From 8d7774019aa0bd74ac3fbc194c907643a2c21cab Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 24 Feb 2010 22:19:52 +0100 Subject: add original width of picture to be able to *not* specify width in latex doc. still work to be done. (bzr r9101.1.18) --- src/extension/internal/latex-text-renderer.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 6c09a7396..6a57f71e6 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -404,6 +404,10 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * // write the info to LaTeX Inkscape::SVGOStringStream os; + // also write original width to LaTeX + // TODO: add \ifdef statements to be able to choose between specifying width or not to specify it! + os << " %\\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; + os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient. os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << _filename << "}}%\n"; -- cgit v1.2.3 From a29676e2e739e0b508c3eabbf6bf40b61a70dc38 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 24 Feb 2010 22:27:16 +0100 Subject: fix bug: don't output scientific notation numbers to latex (bzr r9101.1.19) --- src/extension/internal/latex-text-renderer.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 6a57f71e6..7e7e94801 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -293,6 +293,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) // write to LaTeX Inkscape::SVGOStringStream os; + os.setf(std::ios::fixed); // don't use scientific notation os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; if (has_color) { @@ -319,6 +320,7 @@ LaTeXTextRenderer::sp_flowtext_render(SPItem *item) // write to LaTeX Inkscape::SVGOStringStream os; + os.setf(std::ios::fixed); // no scientific notation os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; os << " \\gplgaddtomacro\\gplbacktext{%%\n"; @@ -403,6 +405,7 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * // write the info to LaTeX Inkscape::SVGOStringStream os; + os.setf(std::ios::fixed); // no scientific notation // also write original width to LaTeX // TODO: add \ifdef statements to be able to choose between specifying width or not to specify it! -- cgit v1.2.3 From ce260704f96c6aad4042fb141e778fe7fe351a31 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 00:02:25 +0100 Subject: - align on text anchor - provide better scaling option. default, the image is not scaled. image can be scaled by \def\svgwidth{...} (bzr r9101.1.20) --- src/extension/internal/latex-text-renderer.cpp | 49 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 7e7e94801..d44652419 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -151,7 +151,7 @@ LaTeXTextRenderer::setTargetFile(gchar const *filename) { fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", PACKAGE_STRING); fprintf(_stream, "%%%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010\n"); fprintf(_stream, "%%%% Accompanies image file '%s' (pdf, eps, ps)\n", _filename); - fprintf(_stream, "%%%%"); + fprintf(_stream, "%%%%\n"); /* flush this to test output stream as early as possible */ if (fflush(_stream)) { if (ferror(_stream)) { @@ -173,9 +173,13 @@ LaTeXTextRenderer::setTargetFile(gchar const *filename) { static char const preamble[] = "%% To include the image in your LaTeX document, write\n" -"%% \\setlength{\\unitlength}{}\n" "%% \\input{.tex}\n" -"%% instead of\n" +"%% instead of\n" +"%% \\includegraphics{.pdf}\n" +"%% To scale the image, write\n" +"%% \\def{\\svgwidth}{}\n" +"%% \\input{.tex}\n" +"%% instead of\n" "%% \\includegraphics[width=]{.pdf}\n" "\n" "\\begingroup \n" @@ -187,8 +191,7 @@ static char const preamble[] = " color.sty in LaTeX.}% \n" " \\renewcommand\\color[2][]{}% \n" " }%% \n" -" \\providecommand\\rotatebox[2]{#2}% \n" -" \\makeatother \n"; +" \\providecommand\\rotatebox[2]{#2}% \n"; static char const postamble[] = " \\end{picture}% \n" @@ -250,26 +253,30 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) gchar *str = sp_te_get_string_multiline(item); // get position and alignment - Geom::Point pos; + // Align vertically on the baseline of the font (retreived from the anchor point) + // Align horizontally on boundingbox + Geom::Coord pos_x; gchar *alignment = NULL; Geom::OptRect bbox = item->getBounds(transform()); Geom::Interval bbox_x = (*bbox)[Geom::X]; - Geom::Interval bbox_y = (*bbox)[Geom::Y]; switch (style->text_anchor.computed) { case SP_CSS_TEXT_ANCHOR_START: - pos = Geom::Point( bbox_x.min() , bbox_y.middle() ); - alignment = "[l]"; + pos_x = bbox_x.min(); + alignment = "[lb]"; break; case SP_CSS_TEXT_ANCHOR_END: - pos = Geom::Point( bbox_x.max() , bbox_y.middle() ); - alignment = "[r]"; + pos_x = bbox_x.max(); + alignment = "[rb]"; break; case SP_CSS_TEXT_ANCHOR_MIDDLE: default: - pos = bbox->midpoint(); - alignment = ""; + pos_x = bbox_x.middle(); + alignment = "[b]"; break; } + Geom::Point anchor = textobj->attributes.firstXY() * transform(); + // If we want to align horizontally on bbox: Geom::Point pos(pos_x, anchor[Geom::Y]); + Geom::Point pos(anchor[Geom::X], anchor[Geom::Y]); // determine color (for now, use rgb color model as it is most native to Inkscape) bool has_color = false; // if the item has no color set, don't force black color @@ -299,11 +306,11 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) if (has_color) { os << "\\color[rgb]{" << SP_RGBA32_R_F(rgba) << "," << SP_RGBA32_G_F(rgba) << "," << SP_RGBA32_B_F(rgba) << "}"; } - os << "\\makebox(0,0)" << alignment << "{"; if (has_rotation) { os << "\\rotatebox{" << degrees << "}{"; } - os << str; + os << "\\makebox(0,0)" << alignment << "{"; + os << "\\smash{" << str << "}"; // smash the text, to be able to put the makebox coordinates at the baseline if (has_rotation) { os << "}"; // rotatebox end } @@ -407,9 +414,15 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * Inkscape::SVGOStringStream os; os.setf(std::ios::fixed); // no scientific notation - // also write original width to LaTeX - // TODO: add \ifdef statements to be able to choose between specifying width or not to specify it! - os << " %\\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; + // scaling of the image when including it in LaTeX + + os << " \\ifx \\svgwidth \\@empty\n"; + os << " \\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; + os << " \\else\n"; + os << " \\setlength{\\unitlength}{\\svgwidth}\n"; + os << " \\fi\n"; + os << " \\global\\let\\svgwidth\\@empty\n"; + os << " \\makeatother\n"; os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient. -- cgit v1.2.3 From db2cebbe4b243b26276f9fe2e9dd6213473e6ce9 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 00:15:29 +0100 Subject: remove whitespace (bzr r9101.1.21) --- src/extension/internal/latex-text-renderer.cpp | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index d44652419..825291e8c 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -53,7 +53,7 @@ namespace Internal { * @param filename This should be the filename without extension to which the tex code should be written. Output goes to .tex. */ bool -latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, +latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, const gchar * const exportId, bool exportDrawing, bool exportCanvas) { sp_document_ensure_up_to_date(doc); @@ -126,7 +126,7 @@ bool LaTeXTextRenderer::setTargetFile(gchar const *filename) { if (filename != NULL) { while (isspace(*filename)) filename += 1; - + _filename = g_path_get_basename(filename); gchar *filename_ext = g_strdup_printf("%s.tex", filename); @@ -182,20 +182,20 @@ static char const preamble[] = "%% instead of\n" "%% \\includegraphics[width=]{.pdf}\n" "\n" -"\\begingroup \n" -" \\makeatletter \n" -" \\providecommand\\color[2][]{% \n" -" \\GenericError{(Inkscape) \\space\\space\\@spaces}{% \n" -" Color is used for the text in Inkscape, but the color package color is not loaded. \n" -" }{Either use black text in Inkscape or load the package \n" -" color.sty in LaTeX.}% \n" -" \\renewcommand\\color[2][]{}% \n" -" }%% \n" -" \\providecommand\\rotatebox[2]{#2}% \n"; +"\\begingroup\n" +" \\makeatletter\n" +" \\providecommand\\color[2][]{%\n" +" \\GenericError{(Inkscape) \\space\\space\\@spaces}{%\n" +" Color is used for the text in Inkscape, but the color package color is not loaded.\n" +" }{Either use black text in Inkscape or load the package\n" +" color.sty in LaTeX.}%\n" +" \\renewcommand\\color[2][]{}%\n" +" }\n" +" \\providecommand\\rotatebox[2]{#2}\n"; static char const postamble[] = -" \\end{picture}% \n" -"\\endgroup \n"; +" \\end{picture}\n" +"\\endgroup\n"; void LaTeXTextRenderer::writePreamble() @@ -283,10 +283,10 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) // TODO: how to handle ICC colors? // give priority to fill color guint32 rgba = 0; - if (style->fill.set && style->fill.isColor()) { + if (style->fill.set && style->fill.isColor()) { has_color = true; rgba = style->fill.value.color.toRGBA32(1.); - } else if (style->stroke.set && style->stroke.isColor()) { + } else if (style->stroke.set && style->stroke.isColor()) { has_color = true; rgba = style->stroke.value.color.toRGBA32(1.); } @@ -415,12 +415,12 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * os.setf(std::ios::fixed); // no scientific notation // scaling of the image when including it in LaTeX - + os << " \\ifx \\svgwidth \\@empty\n"; os << " \\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; os << " \\else\n"; os << " \\setlength{\\unitlength}{\\svgwidth}\n"; - os << " \\fi\n"; + os << " \\fi\n"; os << " \\global\\let\\svgwidth\\@empty\n"; os << " \\makeatother\n"; -- cgit v1.2.3 From 1a16023189984da1735d6b2ea640af683443a136 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 20:03:16 +0100 Subject: fix 2 bugs (bzr r9101.1.22) --- src/extension/internal/latex-text-renderer.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 825291e8c..78b17a000 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -251,32 +251,28 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); gchar *str = sp_te_get_string_multiline(item); + if (!str) { + return; + } // get position and alignment // Align vertically on the baseline of the font (retreived from the anchor point) - // Align horizontally on boundingbox - Geom::Coord pos_x; + // Align horizontally on anchorpoint gchar *alignment = NULL; - Geom::OptRect bbox = item->getBounds(transform()); - Geom::Interval bbox_x = (*bbox)[Geom::X]; switch (style->text_anchor.computed) { case SP_CSS_TEXT_ANCHOR_START: - pos_x = bbox_x.min(); alignment = "[lb]"; break; case SP_CSS_TEXT_ANCHOR_END: - pos_x = bbox_x.max(); alignment = "[rb]"; break; case SP_CSS_TEXT_ANCHOR_MIDDLE: default: - pos_x = bbox_x.middle(); alignment = "[b]"; break; } Geom::Point anchor = textobj->attributes.firstXY() * transform(); - // If we want to align horizontally on bbox: Geom::Point pos(pos_x, anchor[Geom::Y]); - Geom::Point pos(anchor[Geom::X], anchor[Geom::Y]); + Geom::Point pos(anchor); // determine color (for now, use rgb color model as it is most native to Inkscape) bool has_color = false; // if the item has no color set, don't force black color @@ -393,6 +389,10 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * } else { sp_item_invoke_bbox(base, d, sp_item_i2d_affine(base), TRUE, SPItem::RENDERING_BBOX); } + if (!d) { + g_message("LaTeXTextRenderer: could not retrieve boundingbox."); + return false; + } // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX double scale = 1/(d->width()); -- cgit v1.2.3 From 1532813ff2c49d332d43d90ac8642b1983ef9f9b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 21:34:33 +0100 Subject: prevent extra vertical space after image (bzr r9101.1.23) --- src/extension/internal/latex-text-renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 78b17a000..94e1d9893 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -194,7 +194,7 @@ static char const preamble[] = " \\providecommand\\rotatebox[2]{#2}\n"; static char const postamble[] = -" \\end{picture}\n" +" \\end{picture}%\n" "\\endgroup\n"; void -- cgit v1.2.3 From 5b3a1f074a56d963d80db6314f2448eeb21da3d2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 22:05:59 +0100 Subject: fix cmakelist for rename (bzr r9101.1.24) --- src/extension/internal/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/CMakeLists.txt b/src/extension/internal/CMakeLists.txt index 3412b740c..8b23cb0ac 100644 --- a/src/extension/internal/CMakeLists.txt +++ b/src/extension/internal/CMakeLists.txt @@ -20,7 +20,7 @@ latex-pstricks.cpp latex-pstricks-out.cpp odf.cpp pdfinput -pdflatex-renderer.cpp +latex-text-renderer.cpp pdf-input-cairo.cpp pov-out.cpp javafx-out.cpp -- cgit v1.2.3 From b5a872ce37707cefd7c1202118d964e35300a3dc Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 25 Feb 2010 22:43:22 +0100 Subject: fix warnings (bzr r9112) --- src/extension/internal/latex-text-renderer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 94e1d9893..df0bfb8cb 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -317,7 +317,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) } void -LaTeXTextRenderer::sp_flowtext_render(SPItem *item) +LaTeXTextRenderer::sp_flowtext_render(SPItem * /*item*/) { /* SPFlowtext *group = SP_FLOWTEXT(item); @@ -402,8 +402,6 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * if (!pageBoundingBox) { - double high = sp_document_height(doc); - push_transform( Geom::Translate( - d->min() ) ); } -- cgit v1.2.3 From f0a5ede33f900b7c1aacf703914a8be8458b24df Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 26 Feb 2010 22:15:03 +0100 Subject: fix bug in latex export, when svgwidth has not been defined at all (bzr r9114) --- src/extension/internal/latex-text-renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index df0bfb8cb..07f3d5a6d 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -414,12 +414,12 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem * // scaling of the image when including it in LaTeX - os << " \\ifx \\svgwidth \\@empty\n"; + os << " \\ifx\\svgwidth\\undefined\n"; os << " \\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "pt}\n"; os << " \\else\n"; os << " \\setlength{\\unitlength}{\\svgwidth}\n"; os << " \\fi\n"; - os << " \\global\\let\\svgwidth\\@empty\n"; + os << " \\global\\let\\svgwidth\\undefined\n"; os << " \\makeatother\n"; os << " \\begin{picture}(" << _width << "," << _height << ")%\n"; -- cgit v1.2.3 From 45db5ae23a22758d0d72851534e60fc38fa5ff5d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 27 Feb 2010 00:29:26 +0100 Subject: latex export: add transparency export for pdf (bzr r9115) --- src/extension/internal/cairo-ps-out.cpp | 4 +-- src/extension/internal/cairo-renderer-pdf-out.cpp | 2 +- src/extension/internal/latex-text-renderer.cpp | 32 ++++++++++++++++------- src/extension/internal/latex-text-renderer.h | 8 ++++-- 4 files changed, 31 insertions(+), 15 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 6f22dbdc7..61760e9d9 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -199,7 +199,7 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con //strip filename of ".ps", do not add ".tex" here. gsize n = g_str_has_suffix(filename, ".ps") ? strlen(filename)-3 : strlen(filename); tex_filename = g_strndup(filename, n); - ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage, false); g_free(tex_filename); if (!ret) @@ -287,7 +287,7 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co //strip filename of ".eps", do not add ".tex" here. gsize n = g_str_has_suffix(filename, ".eps") ? strlen(filename)-4 : strlen(filename); tex_filename = g_strndup(filename, n); - ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_areaDrawing, new_areaPage, false); g_free(tex_filename); if (!ret) diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 1dcfbdf1d..808590e04 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -217,7 +217,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, //strip filename of ".pdf", do not add ".tex" here. gsize n = g_str_has_suffix(filename, ".pdf") ? strlen(filename)-4 : strlen(filename); tex_filename = g_strndup(filename, n); - ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas); + ret = latex_render_document_text_to_file(doc, tex_filename, new_exportId, new_exportDrawing, new_exportCanvas, true); g_free(tex_filename); if (!ret) diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index 07f3d5a6d..c058c4ff2 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -54,7 +54,8 @@ namespace Internal { */ bool latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, - const gchar * const exportId, bool exportDrawing, bool exportCanvas) + const gchar * const exportId, bool exportDrawing, bool exportCanvas, + bool pdflatex) { sp_document_ensure_up_to_date(doc); @@ -76,7 +77,7 @@ latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, return false; /* Create renderer */ - LaTeXTextRenderer *renderer = new LaTeXTextRenderer(); + LaTeXTextRenderer *renderer = new LaTeXTextRenderer(pdflatex); bool ret = renderer->setTargetFile(filename); if (ret) { @@ -92,9 +93,10 @@ latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, return ret; } -LaTeXTextRenderer::LaTeXTextRenderer(void) +LaTeXTextRenderer::LaTeXTextRenderer(bool pdflatex) : _stream(NULL), - _filename(NULL) + _filename(NULL), + _pdflatex(pdflatex) { push_transform(Geom::identity()); } @@ -185,12 +187,13 @@ static char const preamble[] = "\\begingroup\n" " \\makeatletter\n" " \\providecommand\\color[2][]{%\n" -" \\GenericError{(Inkscape) \\space\\space\\@spaces}{%\n" -" Color is used for the text in Inkscape, but the color package color is not loaded.\n" -" }{Either use black text in Inkscape or load the package\n" -" color.sty in LaTeX.}%\n" +" \\errmessage{(Inkscape) Color is used for the text in Inkscape, but the package \'color.sty\' is not loaded}\n" " \\renewcommand\\color[2][]{}%\n" " }\n" +" \\providecommand\\transparent[1]{%\n" +" \\errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package \'transparent.sty\' is not loaded}\n" +" \\renewcommand\\transparent[1]{}%\n" +" }\n" " \\providecommand\\rotatebox[2]{#2}\n"; static char const postamble[] = @@ -274,19 +277,25 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) Geom::Point anchor = textobj->attributes.firstXY() * transform(); Geom::Point pos(anchor); - // determine color (for now, use rgb color model as it is most native to Inkscape) + // determine color and transparency (for now, use rgb color model as it is most native to Inkscape) bool has_color = false; // if the item has no color set, don't force black color + bool has_transparency = false; // TODO: how to handle ICC colors? // give priority to fill color guint32 rgba = 0; + float opacity = SP_SCALE24_TO_FLOAT(style->opacity.value); if (style->fill.set && style->fill.isColor()) { has_color = true; rgba = style->fill.value.color.toRGBA32(1.); + opacity *= SP_SCALE24_TO_FLOAT(style->fill_opacity.value); } else if (style->stroke.set && style->stroke.isColor()) { has_color = true; rgba = style->stroke.value.color.toRGBA32(1.); + opacity *= SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); + } + if (opacity < 1.0) { + has_transparency = true; } - // get rotation Geom::Matrix i2doc = sp_item_i2doc_affine(item); @@ -302,6 +311,9 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) if (has_color) { os << "\\color[rgb]{" << SP_RGBA32_R_F(rgba) << "," << SP_RGBA32_G_F(rgba) << "," << SP_RGBA32_B_F(rgba) << "}"; } + if (_pdflatex && has_transparency) { + os << "\\transparent{" << opacity << "}"; + } if (has_rotation) { os << "\\rotatebox{" << degrees << "}{"; } diff --git a/src/extension/internal/latex-text-renderer.h b/src/extension/internal/latex-text-renderer.h index 69f539314..b5d4bfac1 100644 --- a/src/extension/internal/latex-text-renderer.h +++ b/src/extension/internal/latex-text-renderer.h @@ -27,11 +27,13 @@ namespace Inkscape { namespace Extension { namespace Internal { -bool latex_render_document_text_to_file(SPDocument *doc, gchar const *filename, const gchar * const exportId, bool exportDrawing, bool exportCanvas); +bool latex_render_document_text_to_file(SPDocument *doc, gchar const *filename, + const gchar * const exportId, bool exportDrawing, bool exportCanvas, + bool pdflatex); class LaTeXTextRenderer { public: - LaTeXTextRenderer(); + LaTeXTextRenderer(bool pdflatex); virtual ~LaTeXTextRenderer(); bool setTargetFile(gchar const *filename); @@ -47,6 +49,8 @@ protected: FILE * _stream; gchar * _filename; + bool _pdflatex; /** true if ouputting for pdfLaTeX*/ + void push_transform(Geom::Matrix const &transform); Geom::Matrix const & transform(); void pop_transform(); -- cgit v1.2.3 From 0dff587c9dd7ac0b02fc93f58883e24cd2d4e92e Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 28 Feb 2010 18:38:28 +0100 Subject: Compilation fixes for Windows 64-bit by Fridrich (bzr r9118) --- src/extension/implementation/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 5f1bef8d1..7a558b6fc 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -156,7 +156,7 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) char szExePath[MAX_PATH]; char szCurrentDir[MAX_PATH]; GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir); - unsigned int ret = (unsigned int)FindExecutable( + HINSTANCE ret = (unsigned int)FindExecutable( interpName.c_str(), szCurrentDir, szExePath); if (ret > 32) { interpName = szExePath; -- cgit v1.2.3 From 32db2da50e2c6d15fd465926386a57c422338226 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 28 Feb 2010 23:44:03 +0100 Subject: Fix Windows compile fail after 9118 (oops) (bzr r9120) --- src/extension/implementation/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 7a558b6fc..5eea2d1db 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -156,7 +156,7 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) char szExePath[MAX_PATH]; char szCurrentDir[MAX_PATH]; GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir); - HINSTANCE ret = (unsigned int)FindExecutable( + HINSTANCE ret = FindExecutable( interpName.c_str(), szCurrentDir, szExePath); if (ret > 32) { interpName = szExePath; -- cgit v1.2.3 From e85a9da0c5084ee2cf8c59cdb7d7d5644482072f Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 1 Mar 2010 00:06:38 +0100 Subject: Really fix the Windows build (bzr r9121) --- src/extension/implementation/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 5eea2d1db..cd25d593a 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -158,7 +158,7 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir); HINSTANCE ret = FindExecutable( interpName.c_str(), szCurrentDir, szExePath); - if (ret > 32) { + if (((unsigned long) ret) > 32) { interpName = szExePath; return interpName; } -- cgit v1.2.3 From 6ab9d600bc54afd257dfc4f136f01f191770f858 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 1 Mar 2010 00:18:58 +0100 Subject: pdf+latex: add support for flowed text! (bzr r9122) --- src/extension/internal/latex-text-renderer.cpp | 105 ++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 9 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp index c058c4ff2..28bba1beb 100644 --- a/src/extension/internal/latex-text-renderer.cpp +++ b/src/extension/internal/latex-text-renderer.cpp @@ -36,6 +36,7 @@ #include "sp-use.h" #include "sp-text.h" #include "sp-flowtext.h" +#include "sp-rect.h" #include "text-editing.h" #include @@ -261,7 +262,7 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) // get position and alignment // Align vertically on the baseline of the font (retreived from the anchor point) // Align horizontally on anchorpoint - gchar *alignment = NULL; + gchar const *alignment = NULL; switch (style->text_anchor.computed) { case SP_CSS_TEXT_ANCHOR_START: alignment = "[lb]"; @@ -329,21 +330,107 @@ LaTeXTextRenderer::sp_text_render(SPItem *item) } void -LaTeXTextRenderer::sp_flowtext_render(SPItem * /*item*/) +LaTeXTextRenderer::sp_flowtext_render(SPItem * item) { -/* SPFlowtext *group = SP_FLOWTEXT(item); +/* +Flowtext is possible by using a minipage! :) +Flowing in rectangle is possible, not in arb shape. +*/ + + SPFlowtext *flowtext = SP_FLOWTEXT(item); + SPStyle *style = SP_OBJECT_STYLE (SP_OBJECT(item)); + + gchar *strtext = sp_te_get_string_multiline(item); + if (!strtext) { + return; + } + // replace carriage return with double slash + gchar ** splitstr = g_strsplit(strtext, "\n", -1); + gchar *str = g_strjoinv("\\\\ ", splitstr); + g_free(strtext); + g_strfreev(splitstr); + + if (!flowtext->has_internal_frame()) { + // has_internal_frame includes a check that frame is a SPRect + g_warning("LaTeX export: non-rectangular flowed text shapes are not supported, skipping text."); + return; // don't know how to handle non-rect frames yet. is quite uncommon for latex users i think + } + + SPRect *frame = SP_RECT(flowtext->get_frame(NULL)); + Geom::Rect framebox = sp_rect_get_rect(frame) * transform(); + + // get position and alignment + // Align on topleft corner. + gchar const *alignment = "[lt]"; + gchar const *justification = ""; + switch (flowtext->layout.paragraphAlignment(flowtext->layout.begin())) { + case Inkscape::Text::Layout::LEFT: + justification = "\\raggedright"; + break; + case Inkscape::Text::Layout::RIGHT: + justification = "\\raggedleft"; + break; + case Inkscape::Text::Layout::CENTER: + justification = "\\centering"; + case Inkscape::Text::Layout::FULL: + default: + // no need to add LaTeX code for standard justified output :) + break; + } + Geom::Point pos(framebox.corner(3)); //topleft corner + + // determine color and transparency (for now, use rgb color model as it is most native to Inkscape) + bool has_color = false; // if the item has no color set, don't force black color + bool has_transparency = false; + // TODO: how to handle ICC colors? + // give priority to fill color + guint32 rgba = 0; + float opacity = SP_SCALE24_TO_FLOAT(style->opacity.value); + if (style->fill.set && style->fill.isColor()) { + has_color = true; + rgba = style->fill.value.color.toRGBA32(1.); + opacity *= SP_SCALE24_TO_FLOAT(style->fill_opacity.value); + } else if (style->stroke.set && style->stroke.isColor()) { + has_color = true; + rgba = style->stroke.value.color.toRGBA32(1.); + opacity *= SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); + } + if (opacity < 1.0) { + has_transparency = true; + } + + // get rotation + Geom::Matrix i2doc = sp_item_i2doc_affine(item); + Geom::Matrix wotransl = i2doc.without_translation(); + double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis()); + bool has_rotation = !Geom::are_near(degrees,0.); // write to LaTeX Inkscape::SVGOStringStream os; - os.setf(std::ios::fixed); // no scientific notation + os.setf(std::ios::fixed); // don't use scientific notation - os << " \\begin{picture}(" << _width << "," << _height << ")%%\n"; - os << " \\gplgaddtomacro\\gplbacktext{%%\n"; - os << " \\csname LTb\\endcsname%%\n"; - os << "\\put(0,0){\\makebox(0,0)[lb]{\\strut{}Position}}%%\n"; + os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){"; + if (has_color) { + os << "\\color[rgb]{" << SP_RGBA32_R_F(rgba) << "," << SP_RGBA32_G_F(rgba) << "," << SP_RGBA32_B_F(rgba) << "}"; + } + if (_pdflatex && has_transparency) { + os << "\\transparent{" << opacity << "}"; + } + if (has_rotation) { + os << "\\rotatebox{" << degrees << "}{"; + } + os << "\\makebox(0,0)" << alignment << "{"; + os << "\\begin{minipage}{" << framebox.width() << "\\unitlength}"; + os << justification; + os << str; + os << "\\end{minipage}"; + if (has_rotation) { + os << "}"; // rotatebox end + } + os << "}"; //makebox end + os << "}%\n"; // put end fprintf(_stream, "%s", os.str().c_str()); -*/ } void -- cgit v1.2.3 From 4b6975d17827e8687ca53c786920ebaf0090d025 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 28 Feb 2010 18:09:58 -0800 Subject: Fixed type problem with cast. General cleanup. (bzr r9123) --- src/extension/implementation/script.cpp | 137 +++++++++++++++----------------- src/extension/implementation/script.h | 28 +++---- 2 files changed, 79 insertions(+), 86 deletions(-) (limited to 'src/extension') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index cd25d593a..03bbf25c9 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -5,6 +5,7 @@ * Authors: * Bryce Harrington * Ted Gould + * Jon A. Cruz * * Copyright (C) 2002-2005,2007 Authors * @@ -67,10 +68,10 @@ namespace Implementation { This just keeps coming the events through so that we'll make the GUI update and look pretty. */ -void -Script::pump_events (void) { - while( Gtk::Main::events_pending() ) +void Script::pump_events (void) { + while ( Gtk::Main::events_pending() ) { Gtk::Main::iteration(); + } return; } @@ -100,13 +101,11 @@ Script::interpreter_t const Script::interpreterTab[] = { \param interpNameArg The name of the interpreter that we're looking for, should be an entry in interpreterTab */ -Glib::ustring -Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) +Glib::ustring Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) { - Glib::ustring interpName = interpNameArg; - interpreter_t const *interp; + interpreter_t const *interp = 0; bool foundInterp = false; for (interp = interpreterTab ; interp->identity ; interp++ ){ if (interpName == interp->identity) { @@ -116,8 +115,9 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) } // Do we have a supported interpreter type? - if (!foundInterp) + if (!foundInterp) { return ""; + } interpName = interp->defaultval; // 1. Check preferences @@ -137,6 +137,7 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) Glib::ustring path; Glib::ustring exeName; if (rt.getExeInfo(fullPath, path, exeName)) { +// TODO replace with proper glib/glibmm path building routines: Glib::ustring interpPath = path; interpPath.append("\\"); interpPath.append(interpNameArg); @@ -144,7 +145,7 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) interpPath.append(interpName); interpPath.append(".exe"); struct stat finfo; - if (stat(interpPath .c_str(), &finfo) ==0) { + if (stat(interpPath .c_str(), &finfo) == 0) { g_message("Found local interpreter, '%s', Size: %d", interpPath .c_str(), (int)finfo.st_size); @@ -153,12 +154,11 @@ Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) } // 3. Try searching the path - char szExePath[MAX_PATH]; - char szCurrentDir[MAX_PATH]; + char szExePath[MAX_PATH] = {0}; + char szCurrentDir[MAX_PATH] = {0}; GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir); - HINSTANCE ret = FindExecutable( - interpName.c_str(), szCurrentDir, szExePath); - if (((unsigned long) ret) > 32) { + HINSTANCE ret = FindExecutable(interpName.c_str(), szCurrentDir, szExePath); + if (ret > reinterpret_cast(32)) { interpName = szExePath; return interpName; } @@ -231,9 +231,9 @@ Script::solve_reldir(Inkscape::XML::Node *reprin) { Glib::ustring filename = fname; g_free(fname); - if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) ) + if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) ) { return filename; - + } } } else { Glib::ustring str = sp_repr_children(reprin)->content(); @@ -261,8 +261,7 @@ Script::solve_reldir(Inkscape::XML::Node *reprin) { then a TRUE is returned. If we get all the way through the path then a FALSE is returned, the command could not be found. */ -bool -Script::check_existance(const Glib::ustring &command) +bool Script::check_existance(const Glib::ustring &command) { // Check the simple case first @@ -272,21 +271,23 @@ Script::check_existance(const Glib::ustring &command) //Don't search when it contains a slash. */ if (command.find(G_DIR_SEPARATOR) != command.npos) { - if (Inkscape::IO::file_test(command.c_str(), G_FILE_TEST_EXISTS)) + if (Inkscape::IO::file_test(command.c_str(), G_FILE_TEST_EXISTS)) { return true; - else + } else { return false; + } } Glib::ustring path; gchar *s = (gchar *) g_getenv("PATH"); - if (s) + if (s) { path = s; - else + } else { /* There is no `PATH' in the environment. The default search path is the current directory */ path = G_SEARCHPATH_SEPARATOR_S; + } std::string::size_type pos = 0; std::string::size_type pos2 = 0; @@ -339,11 +340,11 @@ Script::check_existance(const Glib::ustring &command) and should error out at a higher level. */ -bool -Script::load(Inkscape::Extension::Extension *module) +bool Script::load(Inkscape::Extension::Extension *module) { - if (module->loaded()) + if (module->loaded()) { return true; + } helper_extension = ""; @@ -392,8 +393,7 @@ Script::load(Inkscape::Extension::Extension *module) This function just sets the module to unloaded. It free's the command if it has been allocated. */ -void -Script::unload(Inkscape::Extension::Extension */*module*/) +void Script::unload(Inkscape::Extension::Extension */*module*/) { command.clear(); helper_extension = ""; @@ -411,11 +411,11 @@ Script::unload(Inkscape::Extension::Extension */*module*/) bool Script::check(Inkscape::Extension::Extension *module) { - int script_count = 0; + int script_count = 0; Inkscape::XML::Node *child_repr = sp_repr_children(module->get_repr()); while (child_repr != NULL) { if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "script")) { - script_count++; + script_count++; child_repr = sp_repr_children(child_repr); while (child_repr != NULL) { if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "check")) { @@ -443,9 +443,9 @@ Script::check(Inkscape::Extension::Extension *module) child_repr = sp_repr_next(child_repr); } - if (script_count == 0) { - return false; - } + if (script_count == 0) { + return false; + } return true; } @@ -488,8 +488,7 @@ ScriptDocCache::~ScriptDocCache ( ) unlink(_filename.c_str()); } -ImplementationDocumentCache * -Script::newDocCache( Inkscape::Extension::Extension * /*ext*/, Inkscape::UI::View::View * view ) { +ImplementationDocumentCache *Script::newDocCache( Inkscape::Extension::Extension * /*ext*/, Inkscape::UI::View::View * view ) { return new ScriptDocCache(view); } @@ -502,8 +501,7 @@ Script::newDocCache( Inkscape::Extension::Extension * /*ext*/, Inkscape::UI::Vie This function should really do something, right now it doesn't. */ -Gtk::Widget * -Script::prefs_input(Inkscape::Extension::Input *module, +Gtk::Widget *Script::prefs_input(Inkscape::Extension::Input *module, const gchar */*filename*/) { return module->autogui(NULL, NULL); @@ -518,8 +516,7 @@ Script::prefs_input(Inkscape::Extension::Input *module, This function should really do something, right now it doesn't. */ -Gtk::Widget * -Script::prefs_output(Inkscape::Extension::Output *module) +Gtk::Widget *Script::prefs_output(Inkscape::Extension::Output *module) { return module->autogui(NULL, NULL); } @@ -545,8 +542,7 @@ Script::prefs_output(Inkscape::Extension::Output *module) the incoming filename (so that it's not the temporary filename). That document is then returned from this function. */ -SPDocument * -Script::open(Inkscape::Extension::Input *module, +SPDocument *Script::open(Inkscape::Extension::Input *module, const gchar *filenameArg) { std::list params; @@ -621,8 +617,7 @@ Script::open(Inkscape::Extension::Input *module, put the output of the script into the final output file. We then delete the temporary file. */ -void -Script::save(Inkscape::Extension::Output *module, +void Script::save(Inkscape::Extension::Output *module, SPDocument *doc, const gchar *filenameArg) { @@ -662,7 +657,7 @@ Script::save(Inkscape::Extension::Output *module, // FIXME: convert to utf8 (from "filename encoding") and unlink_utf8name unlink(tempfilename_in.c_str()); - if(success == false) { + if (success == false) { throw Inkscape::Extension::Output::save_failed(); } @@ -699,8 +694,7 @@ Script::save(Inkscape::Extension::Output *module, exists at the time, the other is created by that script). At that point both should be full, and the second one is loaded. */ -void -Script::effect(Inkscape::Extension::Effect *module, +void Script::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc, ImplementationDocumentCache * docCache) { @@ -801,8 +795,7 @@ Script::effect(Inkscape::Extension::Effect *module, elements and putting them into the old document. The copy is then complete. */ -void -Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot) +void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot) { std::vector delete_list; Inkscape::XML::Node * oldroot_namedview = NULL; @@ -821,8 +814,9 @@ Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot) delete_list.push_back(child); } } - for (unsigned int i = 0; i < delete_list.size(); i++) + for (unsigned int i = 0; i < delete_list.size(); i++) { sp_repr_unparent(delete_list[i]); + } for (Inkscape::XML::Node * child = newroot->firstChild(); child != NULL; @@ -851,8 +845,9 @@ Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot) } // Delete the attributes of the old root nodes. - for (std::vector::const_iterator it = attribs.begin(); it != attribs.end(); it++) + for (std::vector::const_iterator it = attribs.begin(); it != attribs.end(); it++) { oldroot->setAttribute(*it, NULL); + } // Set the new attributes. for (List iter = newroot->attributeList(); iter; ++iter) { @@ -869,8 +864,7 @@ Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot) shows it in a warning dialog to the user \param filename Filename of the stderr file */ -void -Script::checkStderr (const Glib::ustring &data, +void Script::checkStderr (const Glib::ustring &data, Gtk::MessageType type, const Glib::ustring &message) { @@ -902,8 +896,7 @@ Script::checkStderr (const Glib::ustring &data, return; } -bool -Script::cancelProcessing (void) { +bool Script::cancelProcessing (void) { _canceled = true; _main_loop->quit(); Glib::spawn_close_pid(_pid); @@ -939,8 +932,7 @@ Script::cancelProcessing (void) { At the very end (after the data has been copied) both of the files are closed, and we return to what we were doing. */ -int -Script::execute (const std::list &in_command, +int Script::execute (const std::list &in_command, const std::list &in_params, const Glib::ustring &filein, file_listener &fileout) @@ -968,52 +960,51 @@ Script::execute (const std::list &in_command, //std::cout << "first space " << first_space << std::endl; //std::cout << "first quote " << first_quote << std::endl; - if((first_quote != std::string::npos) && (first_quote == 0)) { + if ((first_quote != std::string::npos) && (first_quote == 0)) { size_t next_quote = param_str.find_first_of('"', first_quote + 1); //std::cout << "next quote " << next_quote << std::endl; - if(next_quote != std::string::npos) { + if (next_quote != std::string::npos) { //std::cout << "now split " << next_quote << std::endl; //std::cout << "now split " << param_str.substr(1, next_quote - 1) << std::endl; //std::cout << "now split " << param_str.substr(next_quote + 1) << std::endl; std::string part_str = param_str.substr(1, next_quote - 1); - if(part_str.size() > 0) + if (part_str.size() > 0) argv.push_back(part_str); param_str = param_str.substr(next_quote + 1); - } - else { - if(param_str.size() > 0) + } else { + if (param_str.size() > 0) argv.push_back(param_str); param_str = ""; } - } - else if(first_space != std::string::npos) { + } else if (first_space != std::string::npos) { //std::cout << "now split " << first_space << std::endl; //std::cout << "now split " << param_str.substr(0, first_space) << std::endl; //std::cout << "now split " << param_str.substr(first_space + 1) << std::endl; std::string part_str = param_str.substr(0, first_space); - if(part_str.size() > 0) + if (part_str.size() > 0) { argv.push_back(part_str); + } param_str = param_str.substr(first_space + 1); - } - else { - if(param_str.size() > 0) + } else { + if (param_str.size() > 0) { argv.push_back(param_str); + } param_str = ""; } - } while(param_str.size() > 0); + } while (param_str.size() > 0); } for (std::list::const_iterator i = in_params.begin(); i != in_params.end(); i++) { - //g_message("Script parameter: %s",(*i)g.c_str()); + //g_message("Script parameter: %s",(*i)g.c_str()); argv.push_back(*i); } if (!(filein.empty())) { - argv.push_back(filein); + argv.push_back(filein); } int stdout_pipe, stderr_pipe; @@ -1042,10 +1033,12 @@ Script::execute (const std::list &in_command, _main_loop->run(); // Ensure all the data is out of the pipe - while (!fileout.isDead()) + while (!fileout.isDead()) { fileout.read(Glib::IO_IN); - while (!fileerr.isDead()) + } + while (!fileerr.isDead()) { fileerr.read(Glib::IO_IN); + } if (_canceled) { // std::cout << "Script Canceled" << std::endl; diff --git a/src/extension/implementation/script.h b/src/extension/implementation/script.h index 8e25fb351..e0b6701bf 100644 --- a/src/extension/implementation/script.h +++ b/src/extension/implementation/script.h @@ -10,8 +10,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifndef __INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H__ -#define __INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H__ +#ifndef INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H_SEEN +#define INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H_SEEN #include "implementation.h" #include @@ -62,7 +62,7 @@ public: */ virtual bool check(Inkscape::Extension::Extension *module); - ImplementationDocumentCache * newDocCache (Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * view); + ImplementationDocumentCache * newDocCache(Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * view); /** * @@ -93,7 +93,7 @@ public: */ virtual void effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc, - ImplementationDocumentCache * docCache); + ImplementationDocumentCache * docCache); virtual bool cancelProcessing (void); @@ -204,18 +204,18 @@ private: const Glib::ustring &filein, file_listener &fileout); - void pump_events (void); + void pump_events(void); - /** \brief A definition of an interpreter, which can be specified - in the INX file, but we need to know what to call */ - struct interpreter_t { - gchar const *identity; /**< The ID that is in the INX file */ - gchar const *prefstring; /**< The preferences key that can override the default */ - gchar const *defaultval; /**< The default value if there are no preferences */ - }; + /** \brief A definition of an interpreter, which can be specified + in the INX file, but we need to know what to call */ + struct interpreter_t { + gchar const *identity; /**< The ID that is in the INX file */ + gchar const *prefstring; /**< The preferences key that can override the default */ + gchar const *defaultval; /**< The default value if there are no preferences */ + }; static interpreter_t const interpreterTab[]; - Glib::ustring resolveInterpreterExecutable(const Glib::ustring &interpNameArg); + Glib::ustring resolveInterpreterExecutable(const Glib::ustring &interpNameArg); }; // class Script @@ -227,7 +227,7 @@ private: } // namespace Extension } // namespace Inkscape -#endif /* __INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H__ */ +#endif // INKSCAPE_EXTENSION_IMPEMENTATION_SCRIPT_H_SEEN /* Local Variables: -- cgit v1.2.3 From 0dd576cf271b78b89809e71efd839f26deed8661 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 28 Feb 2010 20:04:49 -0800 Subject: Remove obsolete C macro use. (bzr r9125) --- src/extension/implementation/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 03bbf25c9..4e8d0b360 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -739,7 +739,7 @@ void Script::effect(Inkscape::Extension::Effect *module, while ( selected != NULL ) { Glib::ustring selected_id; selected_id += "--id="; - selected_id += SP_OBJECT_ID(*selected); + selected_id += (*selected)->id; params.insert(params.begin(), selected_id); ++selected; } -- cgit v1.2.3 From fd703018ee505f643f866aa4e0cc3f1bebf7aa7d Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 1 Mar 2010 22:10:16 -0800 Subject: Cleanup on id access. (bzr r9127) --- src/extension/execution-env.cpp | 4 ++-- src/extension/implementation/script.cpp | 10 +++++----- src/extension/init.cpp | 16 ++++++++-------- src/extension/internal/javafx-out.cpp | 8 ++++---- src/extension/internal/pov-out.cpp | 34 ++++++++++++++++----------------- 5 files changed, 36 insertions(+), 36 deletions(-) (limited to 'src/extension') diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index e8d7c4baf..7ed389195 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -58,7 +58,7 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp sp_desktop_selection(desktop)->itemList(); while ( selected != NULL ) { Glib::ustring selected_id; - selected_id = SP_OBJECT_ID(*selected); + selected_id = (*selected)->getId(); _selected.insert(_selected.end(), selected_id); //std::cout << "Selected: " << selected_id << std::endl; ++selected; @@ -127,7 +127,7 @@ ExecutionEnv::createWorkingDialog (void) { SPDesktop *desktop = (SPDesktop *)_doc; GtkWidget *toplevel = gtk_widget_get_toplevel(&(desktop->canvas->widget)); - if (!toplevel || !GTK_WIDGET_TOPLEVEL (toplevel)) + if (!toplevel || !GTK_WIDGET_TOPLEVEL (toplevel)) return; Gtk::Window *window = Glib::wrap(GTK_WINDOW(toplevel), false); diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 4e8d0b360..60623191f 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -65,8 +65,8 @@ namespace Implementation { /** \brief Make GTK+ events continue to come through a little bit - This just keeps coming the events through so that we'll make the GUI - update and look pretty. + This just keeps coming the events through so that we'll make the GUI + update and look pretty. */ void Script::pump_events (void) { while ( Gtk::Main::events_pending() ) { @@ -97,9 +97,9 @@ Script::interpreter_t const Script::interpreterTab[] = { /** \brief Look up an interpreter name, and translate to something that - is executable + is executable \param interpNameArg The name of the interpreter that we're looking - for, should be an entry in interpreterTab + for, should be an entry in interpreterTab */ Glib::ustring Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg) { @@ -739,7 +739,7 @@ void Script::effect(Inkscape::Extension::Effect *module, while ( selected != NULL ) { Glib::ustring selected_id; selected_id += "--id="; - selected_id += (*selected)->id; + selected_id += (*selected)->getId(); params.insert(params.begin(), selected_id); ++selected; } diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 84cc45de9..777e3d718 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -124,10 +124,10 @@ update_pref(Glib::ustring const &pref_path, /* gboolean missing=TRUE; for (GSList *list = extension_family; list; list = g_slist_next(list)) { - g_assert( list->data ); + g_assert( list->data ); - Inkscape::Extension *extension; - extension = reinterpret_cast(list->data); + Inkscape::Extension *extension; + extension = reinterpret_cast(list->data); if (!strcmp(extension->get_id(),pref)) missing=FALSE; } @@ -185,7 +185,7 @@ init() Internal::BlurEdge::init(); Internal::GimpGrad::init(); Internal::Grid::init(); - + /* Raster Effects */ #ifdef WITH_IMAGE_MAGICK Internal::Bitmap::AdaptiveThreshold::init(); @@ -224,14 +224,14 @@ init() Internal::Bitmap::Wave::init(); #endif /* WITH_IMAGE_MAGICK */ - Internal::Filter::Filter::filters_all(); + Internal::Filter::Filter::filters_all(); /* Load search path for extensions */ if (Inkscape::Extension::Extension::search_path.size() == 0) { - Inkscape::Extension::Extension::search_path.push_back(profile_path("extensions")); - - Inkscape::Extension::Extension::search_path.push_back(g_strdup(INKSCAPE_EXTENSIONDIR)); + Inkscape::Extension::Extension::search_path.push_back(profile_path("extensions")); + + Inkscape::Extension::Extension::search_path.push_back(g_strdup(INKSCAPE_EXTENSIONDIR)); } diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index a2f387406..ca061a63a 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -707,7 +707,7 @@ bool JavaFXOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) * Check the type of node and process */ String id; - if (!obj->id) + if (!obj->getId()) { char buf[16]; sprintf(buf, "id%d", idindex++); @@ -715,7 +715,7 @@ bool JavaFXOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) } else { - id = obj->id; + id = obj->getId(); } if (SP_IS_ITEM(obj)) { @@ -773,7 +773,7 @@ bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj) * Check the type of node and process */ String id; - if (!obj->id) + if (!obj->getId()) { char buf[16]; sprintf(buf, "id%d", idindex++); @@ -781,7 +781,7 @@ bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj) } else { - id = obj->id; + id = obj->getId(); } if (SP_IS_ITEM(obj)) { diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index 1cb14fb58..16877c370 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -312,12 +312,12 @@ bool PovOutput::doCurve(SPItem *item, const String &id) int segmentCount = 0; /** * For all Subpaths in the - */ + */ for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) { /** * For all segments in the subpath, including extra closing segment defined by 2geom - */ + */ for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit) { @@ -340,14 +340,14 @@ bool PovOutput::doCurve(SPItem *item, const String &id) nrSegments += segmentCount; /** - * at moment of writing, 2geom lacks proper initialization of empty intervals in rect... - */ - Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() ); - - + * at moment of writing, 2geom lacks proper initialization of empty intervals in rect... + */ + Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() ); + + /** * For all Subpaths in the - */ + */ for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) { @@ -355,7 +355,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id) /** * For all segments in the subpath, including extra closing segment defined by 2geom - */ + */ for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit) { @@ -372,7 +372,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id) nrNodes += 8; } else if(Geom::CubicBezier const *cubic = dynamic_cast(&*cit)) - { + { std::vector points = cubic->points(); Geom::Point p0 = points[0]; Geom::Point p1 = points[1]; @@ -383,7 +383,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id) nrNodes += 8; } else - { + { err("logical error, because pathv_to_linear_and_cubic_beziers was used"); return false; } @@ -444,7 +444,7 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) { String id; - if (!obj->id) + if (!obj->getId()) { char buf[16]; sprintf(buf, "id%d", idIndex++); @@ -452,7 +452,7 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) } else { - id = obj->id; + id = obj->getId(); } if (SP_IS_ITEM(obj)) @@ -467,9 +467,9 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) */ for (SPObject *child = obj->firstChild() ; child ; child = child->next) { - if (!doTreeRecursive(doc, child)) - return false; - } + if (!doTreeRecursive(doc, child)) + return false; + } return true; } @@ -610,7 +610,7 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8) err("Could not output curves for %s", filename_utf8); return; } - + String curveBuf = outbuf; outbuf.clear(); -- cgit v1.2.3 From 6d833eac6f8775095c3c0a0979a6dcab1e4f5c3c Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 5 Mar 2010 00:34:30 +0100 Subject: Improve behavior when pasting, DnDing and importing bitmap images (bzr r9143) --- src/extension/extension.cpp | 6 +- src/extension/extension.h | 2 + src/extension/input.h | 11 ++- src/extension/internal/gdkpixbuf-input.cpp | 113 ++++++++++++++++++++--------- 4 files changed, 93 insertions(+), 39 deletions(-) (limited to 'src/extension') diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 52d5f5148..b36d2e3a1 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -57,7 +57,9 @@ Parameter * param_shared (const gchar * name, GSList * list); not related to the module directly. If the Repr does not include a name and an ID the module will be left in an errored state. */ -Extension::Extension (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp) : _help(NULL) +Extension::Extension (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp) + : _help(NULL) + , _gui(true) { repr = in_repr; Inkscape::GC::anchor(in_repr); @@ -673,7 +675,7 @@ public: Gtk::Widget * Extension::autogui (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) { - if (param_visible_count() == 0) return NULL; + if (!_gui || param_visible_count() == 0) return NULL; AutoGUI * agui = Gtk::manage(new AutoGUI()); diff --git a/src/extension/extension.h b/src/extension/extension.h index 48ca86cf7..6210e2eba 100644 --- a/src/extension/extension.h +++ b/src/extension/extension.h @@ -99,6 +99,7 @@ private: state_t _state; /**< Which state the Extension is currently in */ std::vector _deps; /**< Dependencies for this extension */ static std::ofstream error_file; /**< This is the place where errors get reported */ + bool _gui; protected: Inkscape::XML::Node *repr; /**< The XML description of the Extension */ @@ -219,6 +220,7 @@ public: public: Gtk::Widget * autogui (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal = NULL); void paramListString (std::list & retlist); + void set_gui(bool s) { _gui = s; } /* Extension editor dialog stuff */ public: diff --git a/src/extension/input.h b/src/extension/input.h index 55d807ce2..24cbc4896 100644 --- a/src/extension/input.h +++ b/src/extension/input.h @@ -11,6 +11,7 @@ #ifndef INKSCAPE_EXTENSION_INPUT_H__ #define INKSCAPE_EXTENSION_INPUT_H__ +#include #include #include "extension.h" #include "xml/repr.h" @@ -30,8 +31,14 @@ public: /* this is a hack for this release, this will be private shortly */ gchar *output_extension; /**< Setting of what output extension should be used */ public: - class open_failed {}; /**< Generic failure for an undescribed reason */ - class no_extension_found {}; /**< Failed because we couldn't find an extension to match the filename */ + struct open_failed : public std::exception { + virtual ~open_failed() throw() {} + const char *what() const throw() { return "Open failed"; } + }; + struct no_extension_found : public std::exception { + virtual ~no_extension_found() throw() {} + const char *what() const throw() { return "No suitable input extension found"; } + }; Input (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp); diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 64a099c8a..47cde4a5a 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -1,8 +1,10 @@ #ifdef HAVE_CONFIG_H # include #endif +#include #include "document-private.h" #include +#include "extension/input.h" #include "extension/system.h" #include "gdkpixbuf-input.h" #include "selection-chemistry.h" @@ -16,69 +18,107 @@ GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error ); namespace Extension { namespace Internal { +static std::set create_lossy_set() +{ + std::set lossy; + lossy.insert(".jpg"); + lossy.insert(".jpeg"); + return lossy; +} + SPDocument * -GdkpixbufInput::open(Inkscape::Extension::Input */*mod*/, char const *uri) +GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) { + bool embed = !mod->get_param_bool("link"); SPDocument *doc = NULL; GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL ); + static std::set lossy = create_lossy_set(); if (pb) { /* We are readable */ + bool is_lossy; + Glib::ustring mime_type, ext; + Glib::ustring u = uri; + std::size_t dotpos = u.rfind('.'); + if (dotpos != Glib::ustring::npos) { + ext = u.substr(dotpos, Glib::ustring::npos); + } + + // HACK: replace with something better based on GIO + if (!ext.empty() && lossy.find(ext) != lossy.end()) { + is_lossy = true; + mime_type = "image/jpeg"; + } else { + is_lossy = false; + mime_type = "image/png"; + } + doc = sp_document_new(NULL, TRUE, TRUE); bool saved = sp_document_get_undo_sensitive(doc); sp_document_set_undo_sensitive(doc, false); // no need to undo in this temporary document - Inkscape::XML::Node *repr = NULL; - double width = gdk_pixbuf_get_width(pb); double height = gdk_pixbuf_get_height(pb); gchar const *str = gdk_pixbuf_get_option( pb, "Inkscape::DpiX" ); - if ( str ) - { + if ( str ) { gint dpi = atoi(str); - if ( dpi > 0 && dpi != 72 ) - { + if ( dpi > 0 && dpi != 72 ) { double scale = 72.0 / (double)dpi; width *= scale; } } str = gdk_pixbuf_get_option( pb, "Inkscape::DpiY" ); - if ( str ) - { + if ( str ) { gint dpi = atoi(str); - if ( dpi > 0 && dpi != 72 ) - { + if ( dpi > 0 && dpi != 72 ) { double scale = 72.0 / (double)dpi; height *= scale; } } + // Create image node Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); - // import as - repr = xml_doc->createElement("svg:image"); - - // convert filename to uri - gchar* _uri = g_filename_to_uri(uri, NULL, NULL); - if(_uri) { - repr->setAttribute("xlink:href", _uri); - g_free(_uri); + Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image"); + sp_repr_set_svg_double(image_node, "width", width); + sp_repr_set_svg_double(image_node, "height", height); + + if (embed) { + // Save pixbuf as JPEG or PNG for embedding + gchar *data; + gsize length; + gdk_pixbuf_save_to_buffer(pb, &data, &length, is_lossy ? "jpeg" : "png", NULL, NULL); + + // Save base64 encoded data in image node + // this formula taken from Glib docs + guint needed_size = length * 4 / 3 + length * 4 / (3 * 72) + 7; + needed_size += 5 + 8 + mime_type.size(); // 5 bytes for data:, 8 for ;base64, + + gchar *buffer = (gchar *) g_malloc(needed_size), *buf_work = buffer; + buf_work += g_sprintf(buffer, "data:%s;base64,", mime_type.data()); + + gint state = 0, save = 0; + gsize written = 0; + written += g_base64_encode_step((guchar*) data, length, TRUE, buf_work, &state, &save); + written += g_base64_encode_close(TRUE, buf_work + written, &state, &save); + buf_work[written] = 0; // null terminate + + image_node->setAttribute("xlink:href", buffer); + g_free(buffer); } else { - repr->setAttribute("xlink:href", uri); + // convert filename to uri + gchar* _uri = g_filename_to_uri(uri, NULL, NULL); + if(_uri) { + image_node->setAttribute("xlink:href", _uri); + g_free(_uri); + } else { + image_node->setAttribute("xlink:href", uri); + } } - /* impl: doc->base is currently NULL, so we can use uri for href whether it's absolute - * or relative. The href will get rewritten by rebase_hrefs if by chance uri is relative - * and doc gets saved to a different directory. - * - * We don't bother setting sodipodi:absref, as we assume it's never useful to have - * sodipodi:absref with the same value as xlink:href, and rebase_hrefs will provide - * sodipodi:absref values where necessary. */ - - sp_repr_set_svg_double(repr, "width", width); - sp_repr_set_svg_double(repr, "height", height); - - SP_DOCUMENT_ROOT(doc)->appendChildRepr(repr); - Inkscape::GC::release(repr); - gdk_pixbuf_unref(pb); - //alter the canvas size to fit the image size + + g_object_unref(pb); + + // Add it to the current layer + SP_DOCUMENT_ROOT(doc)->appendChildRepr(image_node); + Inkscape::GC::release(image_node); fit_canvas_to_drawing(doc); // restore undo, as now this document may be shown to the user if a bitmap was opened sp_document_set_undo_sensitive(doc, saved); @@ -126,6 +166,9 @@ GdkpixbufInput::init(void) "\n" "" N_("%s GDK pixbuf Input") "\n" "org.inkscape.input.gdkpixbuf.%s\n" + "false" "\n" ".%s\n" "%s\n" -- cgit v1.2.3 From a9b7c9028767417b2adda38f3dbf99418c73390f Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 5 Mar 2010 01:15:39 +0100 Subject: Always embed bitmap copies created with Alt+B. Fixed bugs: - https://launchpad.net/bugs/169108 (bzr r9144) --- src/extension/internal/gdkpixbuf-input.cpp | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 47cde4a5a..4f91825e2 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -8,6 +8,7 @@ #include "extension/system.h" #include "gdkpixbuf-input.h" #include "selection-chemistry.h" +#include "sp-image.h" namespace Inkscape { @@ -82,27 +83,7 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) sp_repr_set_svg_double(image_node, "height", height); if (embed) { - // Save pixbuf as JPEG or PNG for embedding - gchar *data; - gsize length; - gdk_pixbuf_save_to_buffer(pb, &data, &length, is_lossy ? "jpeg" : "png", NULL, NULL); - - // Save base64 encoded data in image node - // this formula taken from Glib docs - guint needed_size = length * 4 / 3 + length * 4 / (3 * 72) + 7; - needed_size += 5 + 8 + mime_type.size(); // 5 bytes for data:, 8 for ;base64, - - gchar *buffer = (gchar *) g_malloc(needed_size), *buf_work = buffer; - buf_work += g_sprintf(buffer, "data:%s;base64,", mime_type.data()); - - gint state = 0, save = 0; - gsize written = 0; - written += g_base64_encode_step((guchar*) data, length, TRUE, buf_work, &state, &save); - written += g_base64_encode_close(TRUE, buf_work + written, &state, &save); - buf_work[written] = 0; // null terminate - - image_node->setAttribute("xlink:href", buffer); - g_free(buffer); + sp_embed_image(image_node, pb, mime_type); } else { // convert filename to uri gchar* _uri = g_filename_to_uri(uri, NULL, NULL); -- cgit v1.2.3 From 998e601fb0de79b7617fa9402eb36537041663c6 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 5 Mar 2010 22:31:33 -0800 Subject: New tab in Fill&Stroke dialog for swatch fills. (bzr r9153) --- src/extension/internal/odf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 46e0361ce..3537be450 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1660,7 +1660,7 @@ bool OdfOutput::processGradient(Writer &outs, SPItem *item, GradientInfo gi; SPGradient *grvec = sp_gradient_get_vector(gradient, FALSE); - for (SPStop *stop = sp_first_stop(grvec) ; + for (SPStop *stop = grvec->getFirstStop() ; stop ; stop = sp_next_stop(stop)) { unsigned long rgba = sp_stop_get_rgba32(stop); -- cgit v1.2.3 From e0a60a7ea64f3576bac00b84c440769c7221e1c3 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 7 Mar 2010 17:31:49 -0800 Subject: Cleanup of gradients and stops. (bzr r9163) --- src/extension/internal/odf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 3537be450..76b901023 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1661,7 +1661,7 @@ bool OdfOutput::processGradient(Writer &outs, SPItem *item, SPGradient *grvec = sp_gradient_get_vector(gradient, FALSE); for (SPStop *stop = grvec->getFirstStop() ; - stop ; stop = sp_next_stop(stop)) + stop ; stop = stop->getNextStop()) { unsigned long rgba = sp_stop_get_rgba32(stop); unsigned long rgb = (rgba >> 8) & 0xffffff; -- cgit v1.2.3 From be18b3457f1b5c1205cdd45eae0a8a19b9c3e7b3 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Tue, 9 Mar 2010 02:12:09 -0800 Subject: Initial F&S dialog setting of swatch colors. (bzr r9169) --- src/extension/internal/odf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 76b901023..5331c072c 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1659,7 +1659,7 @@ bool OdfOutput::processGradient(Writer &outs, SPItem *item, GradientInfo gi; - SPGradient *grvec = sp_gradient_get_vector(gradient, FALSE); + SPGradient *grvec = gradient->getVector(FALSE); for (SPStop *stop = grvec->getFirstStop() ; stop ; stop = stop->getNextStop()) { -- cgit v1.2.3 From b4e77d3df0d0d9f3e648abe71a04cf782b559525 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 14 Mar 2010 17:09:04 +0100 Subject: Fixes crash of bug #537457, but export is incorrect. Fixed bugs: - https://launchpad.net/bugs/537457 (bzr r9187) --- src/extension/internal/cairo-render-context.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index c33beab8a..877bdb952 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -80,7 +80,7 @@ #include //#define TRACE(_args) g_printf _args -#define TRACE(_args) +#define TRACE(_args) g_message _args //#define TEST(_args) _args #define TEST(_args) @@ -662,7 +662,11 @@ CairoRenderContext::popLayer(void) surface_width *= 1.25; surface_height *= 1.25; } - mask_ctx->setupSurface( surface_width, surface_height ); + if (!mask_ctx->setupSurface( surface_width, surface_height )) { + TRACE(("mask: setupSurface failed\n")); + _renderer->destroyContext(mask_ctx); + return; + } TRACE(("mask surface: %f x %f at %i dpi\n", surface_width, surface_height, _dpi )); // set rendering mode to normal @@ -815,6 +819,7 @@ CairoRenderContext::setSurfaceTarget(cairo_surface_t *surface, bool is_vector, c bool CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t *ctm) { +g_message("enter"); if(surface == NULL) { return false; } @@ -841,7 +846,7 @@ CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t } _is_valid = TRUE; - +g_message("leave"); return true; } -- cgit v1.2.3 From 35d61a7c1ccd44ef8bd863ef3b6c298a63c61348 Mon Sep 17 00:00:00 2001 From: buliabyak <> Date: Wed, 17 Mar 2010 18:02:11 -0300 Subject: make label more informative (bzr r9198) --- src/extension/internal/gdkpixbuf-input.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/extension') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 4f91825e2..3f78b3f36 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -148,7 +148,7 @@ GdkpixbufInput::init(void) "" N_("%s GDK pixbuf Input") "\n" "org.inkscape.input.gdkpixbuf.%s\n" "false" "\n" ".%s\n" -- cgit v1.2.3 From 095cea090677d2fd6a4fd3c94b4812cff102772e Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Wed, 17 Mar 2010 17:41:44 -0700 Subject: Added wrappers for the "optiongroup" type that correspond to existing "float", "enum" etc. wrappers. (bzr r9201) --- src/extension/extension.cpp | 15 +++++++++++++++ src/extension/extension.h | 32 ++++++++++++++++++++++++++------ src/extension/param/parameter.cpp | 21 +++++++++++++++++++++ src/extension/param/parameter.h | 4 ++++ 4 files changed, 66 insertions(+), 6 deletions(-) (limited to 'src/extension') diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index b36d2e3a1..b4cf06bda 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -440,6 +440,14 @@ Extension::get_param_enum (const gchar * name, const SPDocument * doc, const Ink return param->get_enum(doc, node); } + +gchar const *Extension::get_param_optiongroup( gchar const * name, SPDocument const * doc, Inkscape::XML::Node const * node) +{ + Parameter* param = param_shared(name, parameters); + return param->get_optiongroup(doc, node); +} + + /** \return The value of the parameter identified by the name \brief Gets a parameter identified by name with the bool placed @@ -597,6 +605,13 @@ Extension::set_param_string (const gchar * name, const gchar * value, SPDocument return param->set_string(value, doc, node); } +gchar const * Extension::set_param_optiongroup(gchar const * name, gchar const * value, SPDocument * doc, Inkscape::XML::Node * node) +{ + Parameter * param = param_shared(name, parameters); + return param->set_optiongroup(value, doc, node); +} + + /** \return The passed in value \brief Sets a parameter identified by name with the string diff --git a/src/extension/extension.h b/src/extension/extension.h index 6210e2eba..c71ae59b4 100644 --- a/src/extension/extension.h +++ b/src/extension/extension.h @@ -139,8 +139,8 @@ public: g_slist_length(parameters); }; /** \brief A function to get the the number of parameters that are visible to the user that the extension has. - \return The number of visible parameters. - + \return The number of visible parameters. + \note Currently this just calls param_count as visible isn't implemented but in the future it'll do something different. Please call the appropriate function in code so that it'll work in the @@ -153,16 +153,17 @@ public: class param_wrong_type {}; class param_not_color_param {}; class param_not_enum_param {}; + class param_not_optiongroup_param {}; class param_not_string_param {}; class param_not_float_param {}; class param_not_int_param {}; class param_not_bool_param {}; - - /** An error class for when a parameter is looked for that just + + /** An error class for when a parameter is looked for that just * simply doesn't exist */ class param_not_exist {}; - - /** An error class for when a filename already exists, but the user + + /** An error class for when a filename already exists, but the user * doesn't want to overwrite it */ class no_overwrite {}; @@ -176,37 +177,56 @@ public: bool get_param_bool (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + int get_param_int (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + float get_param_float (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + const gchar * get_param_string (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + guint32 get_param_color (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + const gchar * get_param_enum (const gchar * name, const SPDocument * doc = NULL, const Inkscape::XML::Node * node = NULL); + + gchar const *get_param_optiongroup( gchar const * name, + SPDocument const * doc = 0, + Inkscape::XML::Node const * node = 0); + bool set_param_bool (const gchar * name, bool value, SPDocument * doc = NULL, Inkscape::XML::Node * node = NULL); + int set_param_int (const gchar * name, int value, SPDocument * doc = NULL, Inkscape::XML::Node * node = NULL); + float set_param_float (const gchar * name, float value, SPDocument * doc = NULL, Inkscape::XML::Node * node = NULL); + const gchar * set_param_string (const gchar * name, const gchar * value, SPDocument * doc = NULL, Inkscape::XML::Node * node = NULL); + + gchar const * set_param_optiongroup(gchar const * name, + gchar const * value, + SPDocument * doc = 0, + Inkscape::XML::Node * node = 0); + guint32 set_param_color (const gchar * name, guint32 color, SPDocument * doc = NULL, diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp index 2773af61d..3320cddca 100644 --- a/src/extension/param/parameter.cpp +++ b/src/extension/param/parameter.cpp @@ -204,6 +204,16 @@ Parameter::get_enum (const SPDocument * doc, const Inkscape::XML::Node * node) return param->get(doc, node); } +/** \brief Wrapper to cast to the object and use it's function. */ +gchar const *Parameter::get_optiongroup(SPDocument const * doc, Inkscape::XML::Node const * node) +{ + ParamRadioButton * param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_optiongroup_param(); + } + return param->get(doc, node); +} + guint32 Parameter::get_color(const SPDocument* doc, const Inkscape::XML::Node* node) { @@ -253,6 +263,17 @@ Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * throw Extension::param_not_string_param(); return stringpntr->set(in, doc, node); } + +gchar const * Parameter::set_optiongroup( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node ) +{ + ParamRadioButton *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_optiongroup_param(); + } + return param->set(in, doc, node); +} + + /** \brief Wrapper to cast to the object and use it's function. */ guint32 Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node) diff --git a/src/extension/param/parameter.h b/src/extension/param/parameter.h index 54249c12e..c62dad9cc 100644 --- a/src/extension/param/parameter.h +++ b/src/extension/param/parameter.h @@ -98,9 +98,13 @@ public: const gchar * get_enum (const SPDocument * doc, const Inkscape::XML::Node * node); + gchar const * get_optiongroup( SPDocument const * doc, + Inkscape::XML::Node const * node); + bool set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node); int set_int (int in, SPDocument * doc, Inkscape::XML::Node * node); float set_float (float in, SPDocument * doc, Inkscape::XML::Node * node); + gchar const * set_optiongroup(gchar const *in, SPDocument * doc, Inkscape::XML::Node *node); const gchar * set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node); guint32 set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node); -- cgit v1.2.3 From fae67e1661842bd514929aa41ce21528ae56c571 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Wed, 17 Mar 2010 18:21:55 -0700 Subject: Changed the embed/link dialog to use radio buttons instead of a checkbox to make the link/embed effect clearer. (bzr r9202) --- src/extension/internal/gdkpixbuf-input.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/extension') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 3f78b3f36..a1295406c 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -30,7 +30,8 @@ static std::set create_lossy_set() SPDocument * GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) { - bool embed = !mod->get_param_bool("link"); + bool embed = (strcmp(mod->get_param_optiongroup("link"), "embed") == 0); + SPDocument *doc = NULL; GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL ); static std::set lossy = create_lossy_set(); @@ -147,9 +148,11 @@ GdkpixbufInput::init(void) "\n" "" N_("%s GDK pixbuf Input") "\n" "org.inkscape.input.gdkpixbuf.%s\n" - "false" + "\n" + "<_option value='embed'>" N_("embed") "\n" + "<_option value='link'>" N_("link") "\n" + "\n" + "<_param name='help' type='description'>" N_("Embed results in stand-alone, larger SVG files. Link references a file outside this SVG document and all files must be moved together.") "\n" "\n" ".%s\n" "%s\n" -- cgit v1.2.3 From 047696d2bca0ad507e183409de669bab4dd1d228 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 21 Mar 2010 02:53:59 +0100 Subject: Fix build with poppler >= 0.12.2 Fixed bugs: - https://launchpad.net/bugs/487038 (bzr r9217) --- src/extension/internal/pdfinput/pdf-parser.cpp | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/extension') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 118896fd3..b37cbb777 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -809,7 +809,11 @@ void PdfParser::opSetExtGState(Object args[], int numArgs) { blendingColorSpace = NULL; isolated = knockout = gFalse; if (!obj4.dictLookup(const_cast("CS"), &obj5)->isNull()) { +#ifdef POPPLER_NEW_COLOR_SPACE_API + blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); +#else blendingColorSpace = GfxColorSpace::parse(&obj5); +#endif } obj5.free(); if (obj4.dictLookup(const_cast("I"), &obj5)->isBool()) { @@ -1008,11 +1012,19 @@ void PdfParser::opSetFillColorSpace(Object args[], int numArgs) { state->setFillPattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); +#ifdef POPPLER_NEW_COLOR_SPACE_API + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL); + } +#else if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0]); } else { colorSpace = GfxColorSpace::parse(&obj); } +#endif obj.free(); if (colorSpace) { state->setFillColorSpace(colorSpace); @@ -1031,11 +1043,19 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int numArgs) { state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); +#ifdef POPPLER_NEW_COLOR_SPACE_API + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL); + } +#else if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0]); } else { colorSpace = GfxColorSpace::parse(&obj); } +#endif obj.free(); if (colorSpace) { state->setStrokeColorSpace(colorSpace); @@ -1100,11 +1120,19 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { state->setFillColor(&color); builder->updateStyle(state); } +#ifdef POPPLER_NEW_COLOR_SPACE_API + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { + state->setFillPattern(pattern); + builder->updateStyle(state); + } +#else if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName()))) { state->setFillPattern(pattern); builder->updateStyle(state); } +#endif } else { if (numArgs != state->getFillColorSpace()->getNComps()) { @@ -1144,11 +1172,19 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { state->setStrokeColor(&color); builder->updateStyle(state); } +#ifdef POPPLER_NEW_COLOR_SPACE_API + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { + state->setStrokePattern(pattern); + builder->updateStyle(state); + } +#else if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName()))) { state->setStrokePattern(pattern); builder->updateStyle(state); } +#endif } else { if (numArgs != state->getStrokeColorSpace()->getNComps()) { @@ -1543,9 +1579,15 @@ void PdfParser::opShFill(Object args[], int numArgs) { double *matrix = NULL; GBool savedState = gFalse; +#ifdef POPPLER_NEW_COLOR_SPACE_API + if (!(shading = res->lookupShading(args[0].getName(), NULL))) { + return; + } +#else if (!(shading = res->lookupShading(args[0].getName()))) { return; } +#endif // save current graphics state if (shading->getType() != 2 && shading->getType() != 3) { @@ -2507,7 +2549,11 @@ void PdfParser::doImage(Object *ref, Stream *str, GBool inlineImg) { } } if (!obj1.isNull()) { +#ifdef POPPLER_NEW_COLOR_SPACE_API + colorSpace = GfxColorSpace::parse(&obj1, NULL); +#else colorSpace = GfxColorSpace::parse(&obj1); +#endif } else if (csMode == streamCSDeviceGray) { colorSpace = new GfxDeviceGrayColorSpace(); } else if (csMode == streamCSDeviceRGB) { @@ -2592,7 +2638,11 @@ void PdfParser::doImage(Object *ref, Stream *str, GBool inlineImg) { obj2.free(); } } +#ifdef POPPLER_NEW_COLOR_SPACE_API + maskColorSpace = GfxColorSpace::parse(&obj1, NULL); +#else maskColorSpace = GfxColorSpace::parse(&obj1); +#endif obj1.free(); if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) { goto err1; @@ -2767,7 +2817,11 @@ void PdfParser::doForm(Object *str) { if (obj1.dictLookup(const_cast("S"), &obj2)->isName(const_cast("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast("CS"), &obj3)->isNull()) { +#ifdef POPPLER_NEW_COLOR_SPACE_API + blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); +#else blendingColorSpace = GfxColorSpace::parse(&obj3); +#endif } obj3.free(); if (obj1.dictLookup(const_cast("I"), &obj3)->isBool()) { -- cgit v1.2.3