diff options
| author | Ted Gould <ted@gould.cx> | 2009-11-29 19:01:07 +0000 |
|---|---|---|
| committer | Ted Gould <ted@gould.cx> | 2009-11-29 19:01:07 +0000 |
| commit | 29d3c0b15028e61f176df3a75189bf0959d0d03e (patch) | |
| tree | 727afe596c693a9bdd098d72618abd9ceb0d1969 /src/extension/internal | |
| parent | Add the build dir dbus directory to grab some headerfiles for distcheck. (diff) | |
| parent | hopefully fix build on linux (diff) | |
| download | inkscape-29d3c0b15028e61f176df3a75189bf0959d0d03e.tar.gz inkscape-29d3c0b15028e61f176df3a75189bf0959d0d03e.zip | |
Merging in from trunk
(bzr r8254.1.37)
Diffstat (limited to 'src/extension/internal')
| -rw-r--r-- | src/extension/internal/bitmap/imagemagick.cpp | 1 | ||||
| -rw-r--r-- | src/extension/internal/cairo-ps-out.cpp | 20 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.cpp | 99 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.h | 3 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer-pdf-out.cpp | 6 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 80 | ||||
| -rw-r--r-- | src/extension/internal/filter/filter.cpp | 30 | ||||
| -rw-r--r-- | src/extension/internal/javafx-out.cpp | 2 | ||||
| -rw-r--r-- | src/extension/internal/pov-out.cpp | 41 |
9 files changed, 186 insertions, 96 deletions
diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index ab2834141..e907612fd 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -129,6 +129,7 @@ ImageMagickDocCache::readImage(const char *xlink, Magick::Image *image) image->read(path); } catch (...) {} } + g_free(search); } bool diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index dff89c1ed..9ac19326f 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -156,9 +156,9 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con new_bitmapResolution = mod->get_param_int("resolution"); } catch(...) {} - bool new_areaCanvas = true; + bool new_areaPage = true; try { - new_areaCanvas = mod->get_param_bool("areaCanvas"); + new_areaPage = mod->get_param_bool("areaPage"); } catch(...) {} bool new_areaDrawing = true; @@ -173,7 +173,7 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con 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_areaCanvas); + 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); if (!ret) @@ -220,9 +220,9 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co new_bitmapResolution = mod->get_param_int("resolution"); } catch(...) {} - bool new_areaCanvas = true; + bool new_areaPage = true; try { - new_areaCanvas = mod->get_param_bool("areaCanvas"); + new_areaPage = mod->get_param_bool("areaPage"); } catch(...) {} bool new_areaDrawing = true; @@ -237,7 +237,7 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co 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_areaCanvas, true); + 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); if (!ret) @@ -279,11 +279,11 @@ CairoPsOutput::init (void) "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" #endif "</param>\n" - "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n" - "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" 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" + "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n" "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" "<output>\n" "<extension>.ps</extension>\n" @@ -316,11 +316,11 @@ CairoEpsOutput::init (void) "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" #endif "</param>\n" - "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n" - "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" 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" + "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">true</param>\n" "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" "<output>\n" "<extension>.eps</extension>\n" diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index d1462e52e..c33beab8a 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -125,14 +125,27 @@ CairoRenderContext::CairoRenderContext(CairoRenderer *parent) : _renderer(parent), _render_mode(RENDER_MODE_NORMAL), _clip_mode(CLIP_MODE_MASK) -{} +{ + font_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, font_data_free); +} CairoRenderContext::~CairoRenderContext(void) { + if(font_table != NULL) { + g_hash_table_remove_all(font_table); + } + if (_cr) cairo_destroy(_cr); if (_surface) cairo_surface_destroy(_surface); if (_layout) g_object_unref(_layout); } +void CairoRenderContext::font_data_free(gpointer data) +{ + cairo_font_face_t *font_face = (cairo_font_face_t *)data; + if (font_face) { + cairo_font_face_destroy(font_face); + } +} CairoRenderer* CairoRenderContext::getRenderer(void) const @@ -192,6 +205,8 @@ CairoRenderContext::cloneMe(double width, double height) const (int)ceil(width), (int)ceil(height)); new_context->_cr = cairo_create(surface); new_context->_surface = surface; + new_context->_width = width; + new_context->_height = height; new_context->_is_valid = TRUE; return new_context; @@ -610,7 +625,7 @@ CairoRenderContext::popLayer(void) // copy over the correct CTM // It must be stored in item_transform of current state after pushState. - Geom::Matrix item_transform; + Geom::Matrix item_transform; if (_state->parent_has_userspace) item_transform = getParentState()->transform * _state->item_transform; else @@ -749,7 +764,12 @@ CairoRenderContext::setupSurface(double width, double height) if (_vector_based_target && _stream == NULL) return false; + _width = width; + _height = height; + cairo_surface_t *surface = NULL; + cairo_matrix_t ctm; + cairo_matrix_init_identity (&ctm); switch (_target) { case CAIRO_SURFACE_TYPE_IMAGE: surface = cairo_image_surface_create(_target_format, (int)ceil(width), (int)ceil(height)); @@ -762,10 +782,10 @@ CairoRenderContext::setupSurface(double width, double height) #ifdef CAIRO_HAS_PS_SURFACE case CAIRO_SURFACE_TYPE_PS: surface = cairo_ps_surface_create_for_stream(Inkscape::Extension::Internal::_write_callback, _stream, width, height); -#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2)) if(CAIRO_STATUS_SUCCESS != cairo_surface_status(surface)) { return FALSE; } +#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2)) cairo_ps_surface_restrict_to_level (surface, (cairo_ps_level_t)_ps_level); cairo_ps_surface_set_eps (surface, (cairo_bool_t) _eps); #endif @@ -776,7 +796,7 @@ CairoRenderContext::setupSurface(double width, double height) break; } - return _finishSurfaceSetup (surface); + return _finishSurfaceSetup (surface, &ctm); } bool @@ -796,13 +816,16 @@ bool CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t *ctm) { if(surface == NULL) { - return FALSE; + return false; } if(CAIRO_STATUS_SUCCESS != cairo_surface_status(surface)) { - return FALSE; + return false; } _cr = cairo_create(surface); + if(CAIRO_STATUS_SUCCESS != cairo_status(_cr)) { + return false; + } if (ctm) cairo_set_matrix(_cr, ctm); _surface = surface; @@ -1005,7 +1028,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver } - // Calculate the size of the surface which has to be created + // Calculate the size of the surface which has to be created #define SUBPIX_SCALE 100 // Cairo requires an integer pattern surface width/height. // Subtract 0.5 to prevent small rounding errors from increasing pattern size by one pixel. @@ -1313,7 +1336,7 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con } bool no_fill = style->fill.isNone() || style->fill_opacity.value == 0; - bool no_stroke = style->stroke.isNone() || style->stroke_width.computed < 1e-9 || + bool no_stroke = style->stroke.isNone() || style->stroke_width.computed < 1e-9 || style->stroke_opacity.value == 0; if (no_fill && no_stroke) @@ -1440,7 +1463,7 @@ CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsi #define GLYPH_ARRAY_SIZE 64 unsigned int -CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoGlyphInfo> const &glyphtext, bool is_stroke) +CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoGlyphInfo> const &glyphtext, bool path) { cairo_glyph_t glyph_array[GLYPH_ARRAY_SIZE]; cairo_glyph_t *glyphs = glyph_array; @@ -1464,15 +1487,10 @@ CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoG i++; } - if (is_stroke) { + if (path) { cairo_glyph_path(cr, glyphs, num_glyphs - num_invalid_glyphs); } else { - if (_is_texttopath) { - cairo_glyph_path(cr, glyphs, num_glyphs - num_invalid_glyphs); - cairo_fill_preserve(cr); - } else { - cairo_show_glyphs(cr, glyphs, num_glyphs - num_invalid_glyphs); - } + cairo_show_glyphs(cr, glyphs, num_glyphs - num_invalid_glyphs); } if (num_glyphs > GLYPH_ARRAY_SIZE) @@ -1487,10 +1505,11 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Matrix const *font_ma { // create a cairo_font_face from PangoFont double size = style->font_size.computed; - cairo_font_face_t *font_face = NULL; + gpointer fonthash = (gpointer)font; + cairo_font_face_t *font_face = (cairo_font_face_t *)g_hash_table_lookup(font_table, fonthash); FcPattern *fc_pattern = NULL; - + #ifdef USE_PANGO_WIN32 # ifdef CAIRO_HAS_WIN32_FONT LOGFONTA *lfa = pango_win32_font_logfont(font); @@ -1499,17 +1518,23 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Matrix const *font_ma ZeroMemory(&lfw, sizeof(LOGFONTW)); memcpy(&lfw, lfa, sizeof(LOGFONTA)); MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, lfa->lfFaceName, LF_FACESIZE, lfw.lfFaceName, LF_FACESIZE); - - font_face = cairo_win32_font_face_create_for_logfontw(&lfw); + + if(font_face == NULL) { + font_face = cairo_win32_font_face_create_for_logfontw(&lfw); + g_hash_table_insert(font_table, fonthash, font_face); + } # endif #else # ifdef CAIRO_HAS_FT_FONT PangoFcFont *fc_font = PANGO_FC_FONT(font); fc_pattern = fc_font->font_pattern; - font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); + if(font_face == NULL) { + font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); + g_hash_table_insert(font_table, fonthash, font_face); + } # endif #endif - + cairo_save(_cr); cairo_set_font_face(_cr, font_face); @@ -1534,28 +1559,36 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Matrix const *font_ma _showGlyphs(_cr, font, glyphtext, TRUE); } } else { - + bool fill = false, stroke = false, have_path = false; if (style->fill.isColor() || style->fill.isPaintserver()) { - // set fill style - _setFillStyle(style, NULL); - - _showGlyphs(_cr, font, glyphtext, FALSE); + fill = true; } if (style->stroke.isColor() || style->stroke.isPaintserver()) { - // set stroke style + stroke = true; + } + if (fill) { + _setFillStyle(style, NULL); + if (_is_texttopath) { + _showGlyphs(_cr, font, glyphtext, true); + have_path = true; + if (stroke) cairo_fill_preserve(_cr); + else cairo_fill(_cr); + } else { + _showGlyphs(_cr, font, glyphtext, false); + } + } + if (stroke) { _setStrokeStyle(style, NULL); - - // paint stroke - _showGlyphs(_cr, font, glyphtext, TRUE); + if (!have_path) _showGlyphs(_cr, font, glyphtext, true); cairo_stroke(_cr); } } cairo_restore(_cr); - if (font_face) - cairo_font_face_destroy(font_face); +// if (font_face) +// cairo_font_face_destroy(font_face); return true; } diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 930668e03..e6f2d698e 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -195,6 +195,9 @@ protected: void _concatTransform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0); void _concatTransform(cairo_t *cr, Geom::Matrix const *transform); + GHashTable *font_table; + static void font_data_free(gpointer data); + CairoRenderState *_createState(void); }; diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index b44e83449..0598c388a 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -180,7 +180,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, bool new_exportCanvas = FALSE; try { - new_exportCanvas = mod->get_param_bool("areaCanvas"); + new_exportCanvas = mod->get_param_bool("areaPage"); } catch(...) { g_warning("Parameter <exportCanvas> might not exist"); @@ -219,8 +219,8 @@ CairoRendererPdfOutput::init (void) "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" 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 drawing, not page") "\" type=\"boolean\">false</param>\n" - "<param name=\"areaCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n" + "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is drawing") "\" type=\"boolean\">false</param>\n" + "<param name=\"areaPage\" gui-text=\"" N_("Export area is page") "\" type=\"boolean\">false</param>\n" "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" "<output>\n" "<extension>.pdf</extension>\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index da88a5eae..8cc386135 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -192,11 +192,28 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) ctx->renderPathVector(pathv, style, &pbox); - for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { - // START position - for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START - if ( shape->marker[i] ) { - SPMarker* marker = SP_MARKER (shape->marker[i]); + // START marker + for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START + if ( shape->marker[i] ) { + SPMarker* marker = SP_MARKER (shape->marker[i]); + Geom::Matrix tr; + if (marker->orient_auto) { + tr = sp_shape_marker_get_transform_at_start(pathv.begin()->front()); + } else { + tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(pathv.begin()->front().pointAt(0)); + } + sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); + } + } + // MID marker + for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID + if ( !shape->marker[i] ) continue; + SPMarker* marker = SP_MARKER (shape->marker[i]); + for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { + // START position + if ( path_it != pathv.begin() + && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there + { Geom::Matrix tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); @@ -205,11 +222,8 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } - } - - // MID position - for (int i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID - if ( shape->marker[i] && (path_it->size_default() > 1) ) { + // MID position + if (path_it->size_default() > 1) { Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve while (curve_it2 != path_it->end_default()) @@ -217,9 +231,6 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) /* Put marker between curve_it1 and curve_it2. * Loop to end_default (so including closing segment), because when a path is closed, * there should be a midpoint marker between last segment and closing straight line segment */ - - SPMarker* marker = SP_MARKER (shape->marker[i]); - Geom::Matrix tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); @@ -233,32 +244,43 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) ++curve_it2; } } - } - - // END position - for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END - if ( shape->marker[i] ) { - SPMarker* marker = SP_MARKER (shape->marker[i]); - - /* Get reference to last curve in the path. - * For moveto-only path, this returns the "closing line segment". */ - unsigned int index = path_it->size_default(); - if (index > 0) { - index--; - } - Geom::Curve const &lastcurve = (*path_it)[index]; - + // END position + if ( path_it != (pathv.end()-1) && !path_it->empty()) { + Geom::Curve const &lastcurve = path_it->back_default(); Geom::Matrix tr; if (marker->orient_auto) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); } - sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } } } + // END marker + for (int i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END + if ( shape->marker[i] ) { + SPMarker* marker = SP_MARKER (shape->marker[i]); + + /* Get reference to last curve in the path. + * For moveto-only path, this returns the "closing line segment". */ + Geom::Path const &path_last = pathv.back(); + unsigned int index = path_last.size_default(); + if (index > 0) { + index--; + } + Geom::Curve const &lastcurve = path_last[index]; + + Geom::Matrix tr; + if (marker->orient_auto) { + tr = sp_shape_marker_get_transform_at_end(lastcurve); + } else { + tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + } + + sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); + } + } } static void sp_group_render(SPItem *item, CairoRenderContext *ctx) diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 048207332..d98f8e9a2 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -70,7 +70,7 @@ Filter::get_filter (Inkscape::Extension::Extension * ext) { return sp_repr_read_mem(filter, strlen(filter), NULL); } -void +void Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar * srcGraphic, gchar * srcGraphicAlpha) { if (from == NULL) return; @@ -99,7 +99,7 @@ Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Ink from_child != NULL ; from_child = from_child->next()) { Glib::ustring name = "svg:"; name += from_child->name(); - + Inkscape::XML::Node * to_child = doc->createElement(name.c_str()); to->appendChild(to_child); merge_filters(to_child, from_child, doc, srcGraphic, srcGraphicAlpha); @@ -149,7 +149,7 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d Glib::ustring url = "url(#"; url += newfilterroot->attribute("id"); url += ")"; merge_filters(newfilterroot, filterdoc->root(), xmldoc); - + Inkscape::GC::release(newfilterroot); sp_repr_css_set_property(css, "filter", url.c_str()); @@ -170,21 +170,29 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d } g_free(lfilter); + // no filter if (filternode == NULL) { + g_warning("no assoziating filter found!"); continue; } - filternode->lastChild()->setAttribute("result", FILTER_SRC_GRAPHIC); + if (filternode->lastChild() == NULL) { + // empty filter, we insert + merge_filters(filternode, filterdoc->root(), xmldoc); + } else { + // existing filter, we merge + filternode->lastChild()->setAttribute("result", FILTER_SRC_GRAPHIC); + Inkscape::XML::Node * alpha = xmldoc->createElement("svg:feColorMatrix"); + alpha->setAttribute("result", FILTER_SRC_GRAPHIC_ALPHA); + alpha->setAttribute("in", FILTER_SRC_GRAPHIC); // not required, but we're being explicit + alpha->setAttribute("values", "0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"); - Inkscape::XML::Node * alpha = xmldoc->createElement("svg:feColorMatrix"); - alpha->setAttribute("result", FILTER_SRC_GRAPHIC_ALPHA); - alpha->setAttribute("in", FILTER_SRC_GRAPHIC); // not required, but we're being explicit - alpha->setAttribute("values", "0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"); - filternode->appendChild(alpha); + filternode->appendChild(alpha); - merge_filters(filternode, filterdoc->root(), xmldoc, FILTER_SRC_GRAPHIC, FILTER_SRC_GRAPHIC_ALPHA); + merge_filters(filternode, filterdoc->root(), xmldoc, FILTER_SRC_GRAPHIC, FILTER_SRC_GRAPHIC_ALPHA); - Inkscape::GC::release(alpha); + Inkscape::GC::release(alpha); + } } } diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index 417755e19..a2f387406 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -141,7 +141,7 @@ static JavaFXOutput::String rgba(guint32 rgba) unsigned int a = SP_RGBA32_A_U(rgba); char buf[80]; snprintf(buf, 79, "Color.rgb(0x%02x, 0x%02x, 0x%02x, %s)", - r, g, b, DSTR((double)a/256.0)); + r, g, b, DSTR((double)a/255.0)); JavaFXOutput::String s = buf; return s; } diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index f30cbc317..1cb14fb58 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -303,14 +303,28 @@ bool PovOutput::doCurve(SPItem *item, const String &id) Geom::Matrix tf = sp_item_i2d_affine(item); Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf ); - //Count the NR_CURVETOs/LINETOs (including closing line segment) + /* + * We need to know the number of segments (NR_CURVETOs/LINETOs, including + * closing line segment) before we write out segment data. Since we are + * going to skip degenerate (zero length) paths, we need to loop over all + * subpaths and segments first. + */ int segmentCount = 0; - for(Geom::PathVector::const_iterator it = pathv.begin(); it != pathv.end(); ++it) - { - segmentCount += (*it).size(); - if (it->closed()) - segmentCount += 1; + /** + * 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) + { + + // Skip zero length segments. + if( !cit->isDegenerate() ) ++segmentCount; } + } out("/*###################################################\n"); out("### PRISM: %s\n", id.c_str()); @@ -340,10 +354,14 @@ bool PovOutput::doCurve(SPItem *item, const String &id) cminmax.expandTo(pit->initialPoint()); /** - * For all segments in the subpath + * 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) - { + { + + // Skip zero length segments + if( cit->isDegenerate() ) + continue; if( is_straight_curve(*cit) ) { @@ -365,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; } @@ -374,6 +392,11 @@ bool PovOutput::doCurve(SPItem *item, const String &id) out(",\n"); else out("\n"); + if (segmentNr > segmentCount) + { + err("Too many segments"); + return false; + } cminmax.expandTo(cit->finalPoint()); |
