diff options
Diffstat (limited to 'src/extension/internal')
| -rw-r--r-- | src/extension/internal/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/extension/internal/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/extension/internal/cairo-ps-out.cpp | 79 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.cpp | 11 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer-pdf-out.cpp | 51 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 9 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.h | 4 | ||||
| -rw-r--r-- | src/extension/internal/filter/filter.cpp | 4 | ||||
| -rw-r--r-- | src/extension/internal/filter/filter.h | 2 | ||||
| -rw-r--r-- | src/extension/internal/gdkpixbuf-input.cpp | 97 | ||||
| -rw-r--r-- | src/extension/internal/javafx-out.cpp | 8 | ||||
| -rw-r--r-- | src/extension/internal/latex-pstricks.cpp | 14 | ||||
| -rw-r--r-- | src/extension/internal/latex-text-renderer.cpp | 569 | ||||
| -rw-r--r-- | src/extension/internal/latex-text-renderer.h | 85 | ||||
| -rw-r--r-- | src/extension/internal/odf.cpp | 6 | ||||
| -rw-r--r-- | src/extension/internal/pdfinput/pdf-parser.cpp | 54 | ||||
| -rw-r--r-- | src/extension/internal/pov-out.cpp | 34 | ||||
| -rw-r--r-- | src/extension/internal/svg.cpp | 42 |
18 files changed, 979 insertions, 93 deletions
diff --git a/src/extension/internal/CMakeLists.txt b/src/extension/internal/CMakeLists.txt index c9c00e05b..8b23cb0ac 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 +latex-text-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..3c1ce7f43 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/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..61760e9d9 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 <print.h> #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 <textToLaTeX> 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, false); + 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 <textToLaTeX> 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, false); + g_free(tex_filename); + + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } } @@ -280,6 +331,7 @@ CairoPsOutput::init (void) #endif "</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n" @@ -317,6 +369,7 @@ CairoEpsOutput::init (void) #endif "</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">true</param>\n" 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 <pango/pangofc-fontmap.h> //#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; } diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 0598c388a..808590e04 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 <ted@gould.cx> * Ulf Erikson <ulferikson@users.sf.net> + * Johan Engelen <goejendaagh@zonnet.nl> * - * Copyright (C) 2004-2006 Authors + * Copyright (C) 2004-2010 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -20,6 +21,7 @@ #include "cairo-renderer-pdf-out.h" #include "cairo-render-context.h" #include "cairo-renderer.h" +#include "latex-text-renderer.h" #include <print.h> #include "extension/system.h" #include "extension/print.h" @@ -33,6 +35,8 @@ #include "sp-item.h" #include "sp-root.h" +#include <2geom/matrix.h> + namespace Inkscape { namespace Extension { namespace Internal { @@ -48,7 +52,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 omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas) { sp_document_ensure_up_to_date(doc); @@ -83,6 +87,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 = omittext; ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); @@ -106,7 +111,6 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int return ret; } - /** \brief This function calls the output module with the filename \param mod unused @@ -146,6 +150,14 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, g_warning("Parameter <textToPath> might not exist"); } + bool new_textToLaTeX = FALSE; + try { + new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + } + catch(...) { + g_warning("Parameter <textToLaTeX> might not exist"); + } + bool new_blurToBitmap = FALSE; try { new_blurToBitmap = mod->get_param_bool("blurToBitmap"); @@ -186,15 +198,31 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, g_warning("Parameter <exportCanvas> 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_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(); + } - if (!ret) - throw Inkscape::Extension::Output::save_failed(); + // Create LaTeX file (if requested) + if (new_textToLaTeX) { + gchar * 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, true); + g_free(tex_filename); + + if (!ret) + throw Inkscape::Extension::Output::save_failed(); + } } #include "clear-n_.h" @@ -217,6 +245,7 @@ CairoRendererPdfOutput::init (void) "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n" "</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToLaTeX\" gui-text=\"" N_("PDF+LaTeX: Omit text in PDF, and create LaTeX file") "\" type=\"boolean\">false</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi)") "\" type=\"int\" min=\"1\" max=\"10000\">90</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 8cc386135..6e4bb3b7e 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -29,6 +29,7 @@ #include <errno.h> #include "libnr/nr-rect.h" +#include "libnrtype/Layout-TNG.h" #include <2geom/transforms.h> #include <2geom/pathvector.h> @@ -102,6 +103,7 @@ namespace Extension { namespace Internal { CairoRenderer::CairoRenderer(void) + : _omitText(false) {} CairoRenderer::~CairoRenderer(void) @@ -567,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); @@ -591,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/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 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(); diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 64a099c8a..a1295406c 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -1,11 +1,14 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif +#include <glib/gprintf.h> #include "document-private.h" #include <dir-util.h> +#include "extension/input.h" #include "extension/system.h" #include "gdkpixbuf-input.h" #include "selection-chemistry.h" +#include "sp-image.h" namespace Inkscape { @@ -16,69 +19,88 @@ GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error ); namespace Extension { namespace Internal { +static std::set<Glib::ustring> create_lossy_set() +{ + std::set<Glib::ustring> 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 = (strcmp(mod->get_param_optiongroup("link"), "embed") == 0); + SPDocument *doc = NULL; GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL ); + static std::set<Glib::ustring> 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 <image> - 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) { + sp_embed_image(image_node, pb, mime_type); } 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 +148,11 @@ GdkpixbufInput::init(void) "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" "<name>" N_("%s GDK pixbuf Input") "</name>\n" "<id>org.inkscape.input.gdkpixbuf.%s</id>\n" + "<param name='link' type='optiongroup' appearance='full' _gui-text='" N_("Link or embed image:") "' >\n" + "<_option value='embed'>" N_("embed") "</_option>\n" + "<_option value='link'>" N_("link") "</_option>\n" + "</param>\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.") "</_param>\n" "<input>\n" "<extension>.%s</extension>\n" "<mimetype>%s</mimetype>\n" 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/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="<<fill_opacity; + } - os << "\\pscustom[linestyle=none,fillstyle=solid,fillcolor=curcolor]\n{\n"; + os << "]\n{\n"; print_pathvector(os, pathv, transform); @@ -230,14 +236,20 @@ PrintLatex::stroke (Inkscape::Extension::Print *mod, Geom::PathVector const &pat if (style->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_opacity; + } if (style->stroke_dasharray_set && style->stroke_dash.n_dash && diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp new file mode 100644 index 000000000..28bba1beb --- /dev/null +++ b/src/extension/internal/latex-text-renderer.cpp @@ -0,0 +1,569 @@ +#define EXTENSION_INTERNAL_LATEX_TEXT_RENDERER_CPP + +/** \file + * Rendering LaTeX file (pdf/eps/ps+latex output) + * + * The idea stems from GNUPlot's epslatex terminal output :-) + */ +/* + * Authors: + * Johan Engelen <goejendaagh@zonnet.nl> + * Miklos Erdelyi <erdelyim@gmail.com> + * + * Copyright (C) 2006-2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "latex-text-renderer.h" + +#include <signal.h> +#include <errno.h> + +#include "libnrtype/Layout-TNG.h" +#include <2geom/transforms.h> +#include <2geom/rect.h> + +#include <glibmm/i18n.h> +#include "sp-item.h" +#include "sp-item-group.h" +#include "style.h" +#include "sp-root.h" +#include "sp-use.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "sp-rect.h" +#include "text-editing.h" + +#include <unit-constants.h> + +#include "extension/system.h" + +#include "io/sys.h" + +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 <filename>.tex. + */ +bool +latex_render_document_text_to_file( SPDocument *doc, gchar const *filename, + const gchar * const exportId, bool exportDrawing, bool exportCanvas, + bool pdflatex) +{ + 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(pdflatex); + + 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(bool pdflatex) + : _stream(NULL), + _filename(NULL), + _pdflatex(pdflatex) +{ + 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, "%%%%\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; +} + +static char const preamble[] = +"%% To include the image in your LaTeX document, write\n" +"%% \\input{<filename>.tex}\n" +"%% instead of\n" +"%% \\includegraphics{<filename>.pdf}\n" +"%% To scale the image, write\n" +"%% \\def{\\svgwidth}{<desired width>}\n" +"%% \\input{<filename>.tex}\n" +"%% instead of\n" +"%% \\includegraphics[width=<desired width>]{<filename>.pdf}\n" +"\n" +"\\begingroup\n" +" \\makeatletter\n" +" \\providecommand\\color[2][]{%\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[] = +" \\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)); + push_transform(tp); + translated = true; + } + + if (use->child && SP_IS_ITEM(use->child)) { + renderItem(SP_ITEM(use->child)); + } + + if (translated) { + pop_transform(); + } +} + +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); + if (!str) { + return; + } + + // get position and alignment + // Align vertically on the baseline of the font (retreived from the anchor point) + // Align horizontally on anchorpoint + gchar const *alignment = NULL; + switch (style->text_anchor.computed) { + case SP_CSS_TEXT_ANCHOR_START: + alignment = "[lb]"; + break; + case SP_CSS_TEXT_ANCHOR_END: + alignment = "[rb]"; + break; + case SP_CSS_TEXT_ANCHOR_MIDDLE: + default: + alignment = "[b]"; + break; + } + Geom::Point anchor = textobj->attributes.firstXY() * transform(); + Geom::Point pos(anchor); + + // 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); // don't use scientific notation + + 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 << "\\smash{" << str << "}"; // smash the text, to be able to put the makebox coordinates at the baseline + 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) +{ +/* +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); // don't use scientific notation + + 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 +LaTeXTextRenderer::sp_root_render(SPItem *item) +{ + SPRoot *root = SP_ROOT(item); + + push_transform(root->c2p); + 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)) { + return sp_root_render(item); + } else if (SP_IS_GROUP(item)) { + return sp_group_render(item); + } else if (SP_IS_USE(item)) { + sp_use_render(item); + } else if (SP_IS_TEXT(item)) { + return sp_text_render(item); + } else if (SP_IS_FLOWTEXT(item)) { + return sp_flowtext_render(item); + } + // We are not interested in writing the other SPItem types to LaTeX +} + +void +LaTeXTextRenderer::renderItem(SPItem *item) +{ + push_transform(item->transform); + sp_item_invoke_render(item); + pop_transform(); +} + +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)); + + Geom::OptRect d; + if (pageBoundingBox) { + 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); + } + 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()); + double _width = d->width() * scale; + double _height = d->height() * scale; + push_transform( Geom::Scale(scale, scale) ); + + if (!pageBoundingBox) + { + push_transform( Geom::Translate( - d->min() ) ); + } + + // 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.setf(std::ios::fixed); // no scientific notation + + // scaling of the image when including it in LaTeX + + 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\\undefined\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. + 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(); +} + +} /* namespace Internal */ +} /* namespace Extension */ +} /* namespace Inkscape */ + +/* + 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..b5d4bfac1 --- /dev/null +++ b/src/extension/internal/latex-text-renderer.h @@ -0,0 +1,85 @@ +#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 exporting to PDF/EPS/PS + LaTeX + */ +/* + * Authors: + * Johan Engelen <goejendaagh@zonnet.nl> + * + * Copyright (C) 2010 Authors + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "extension/extension.h" +#include <2geom/matrix.h> +#include <stack> + +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, + bool pdflatex); + +class LaTeXTextRenderer { +public: + LaTeXTextRenderer(bool pdflatex); + virtual ~LaTeXTextRenderer(); + + bool setTargetFile(gchar const *filename); + + /** 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; + + bool _pdflatex; /** true if ouputting for pdfLaTeX*/ + + void push_transform(Geom::Matrix const &transform); + Geom::Matrix const & transform(); + void pop_transform(); + std::stack<Geom::Matrix> _transform_stack; + + 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_LATEX_TEXT_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/odf.cpp b/src/extension/internal/odf.cpp index 46e0361ce..5331c072c 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -1659,9 +1659,9 @@ bool OdfOutput::processGradient(Writer &outs, SPItem *item, GradientInfo gi; - SPGradient *grvec = sp_gradient_get_vector(gradient, FALSE); - for (SPStop *stop = sp_first_stop(grvec) ; - stop ; stop = sp_next_stop(stop)) + SPGradient *grvec = gradient->getVector(FALSE); + for (SPStop *stop = grvec->getFirstStop() ; + stop ; stop = stop->getNextStop()) { unsigned long rgba = sp_stop_get_rgba32(stop); unsigned long rgb = (rgba >> 8) & 0xffffff; 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<char*>("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<char*>("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<char*>("S"), &obj2)->isName(const_cast<char*>("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast<char*>("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<char*>("I"), &obj3)->isBool()) { 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 <path> - */ + */ 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 <path> - */ + */ 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<Geom::CubicBezier const*>(&*cit)) - { + { std::vector<Geom::Point> 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(); 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 <vector> +#include "xml/attribute-record.h" #ifdef WITH_GNOME_VFS # include <libgnomevfs/gnome-vfs.h> @@ -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<gchar const*> toBeRemoved; + for ( List<AttributeRecord const> 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<gchar const*>::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); } |
