summaryrefslogtreecommitdiffstats
path: root/src/extension/internal
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2009-11-29 19:01:07 +0000
committerTed Gould <ted@gould.cx>2009-11-29 19:01:07 +0000
commit29d3c0b15028e61f176df3a75189bf0959d0d03e (patch)
tree727afe596c693a9bdd098d72618abd9ceb0d1969 /src/extension/internal
parentAdd the build dir dbus directory to grab some headerfiles for distcheck. (diff)
parenthopefully fix build on linux (diff)
downloadinkscape-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.cpp1
-rw-r--r--src/extension/internal/cairo-ps-out.cpp20
-rw-r--r--src/extension/internal/cairo-render-context.cpp99
-rw-r--r--src/extension/internal/cairo-render-context.h3
-rw-r--r--src/extension/internal/cairo-renderer-pdf-out.cpp6
-rw-r--r--src/extension/internal/cairo-renderer.cpp80
-rw-r--r--src/extension/internal/filter/filter.cpp30
-rw-r--r--src/extension/internal/javafx-out.cpp2
-rw-r--r--src/extension/internal/pov-out.cpp41
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());