From 2d7e690eb6a2add552b84370d56d56ec1b1fbfd4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 19 Oct 2019 04:33:22 +0000 Subject: Add export/import PDF blend modes and add isolation modifier --- src/extension/internal/pdfinput/svg-builder.cpp | 66 +++++++++++++++++++------ 1 file changed, 50 insertions(+), 16 deletions(-) (limited to 'src/extension/internal/pdfinput/svg-builder.cpp') diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 9b4b55e21..14727eba5 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -408,6 +408,26 @@ void SvgBuilder::_setFillStyle(SPCSSAttr *css, GfxState *state, bool even_odd) { sp_repr_css_set_property(css, "fill-rule", even_odd ? "evenodd" : "nonzero"); } +/** + * \brief Sets blend style properties from poppler's GfxState data structure + * \update a SPCSSAttr with all mix-blend-mode set + */ +void SvgBuilder::_setBlendMode(Inkscape::XML::Node *node, GfxState *state) +{ + SPCSSAttr *css = sp_repr_css_attr(node, "style"); + GfxBlendMode blendmode = state->getBlendMode(); + if (blendmode) { + sp_repr_css_set_property(css, "mix-blend-mode", enum_blend_mode[blendmode].key); + } + Glib::ustring value; + sp_repr_css_write_string(css, value); + if (value.empty()) { + node->setAttribute("style", nullptr); + } else { + node->setAttribute("style", value.c_str()); + } + sp_repr_css_attr_unref(css); +} /** * \brief Sets style properties from poppler's GfxState data structure * \return SPCSSAttr with all the relevant properties set @@ -447,7 +467,7 @@ void SvgBuilder::addPath(GfxState *state, bool fill, bool stroke, bool even_odd) SPCSSAttr *css = _setStyle(state, fill, stroke, even_odd); sp_repr_css_change(path, css, "style"); sp_repr_css_attr_unref(css); - + _setBlendMode(path, state); _container->appendChild(path); Inkscape::GC::release(path); } @@ -1427,6 +1447,11 @@ void SvgBuilder::addChar(GfxState *state, double x, double y, bool has_fill = !( render_mode & 1 ); bool has_stroke = ( render_mode & 3 ) == 1 || ( render_mode & 3 ) == 2; new_glyph.style = _setStyle(state, has_fill, has_stroke); + // Find a way to handle blend modes on text + /* GfxBlendMode blendmode = state->getBlendMode(); + if (blendmode) { + sp_repr_css_set_property(new_glyph.style, "mix-blend-mode", enum_blend_mode[blendmode].key); + } */ new_glyph.render_mode = render_mode; sp_repr_css_merge(new_glyph.style, _font_style); // Merge with font style _invalidated_style = false; @@ -1435,6 +1460,10 @@ void SvgBuilder::addChar(GfxState *state, double x, double y, // Point to previous glyph's style information const SvgGlyph& prev_glyph = _glyphs.back(); new_glyph.style = prev_glyph.style; + /* GfxBlendMode blendmode = state->getBlendMode(); + if (blendmode) { + sp_repr_css_set_property(new_glyph.style, "mix-blend-mode", enum_blend_mode[blendmode].key); + } */ new_glyph.render_mode = prev_glyph.render_mode; } new_glyph.font_specification = _font_specification; @@ -1710,14 +1739,16 @@ Inkscape::XML::Node *SvgBuilder::_createMask(double width, double height) { } } -void SvgBuilder::addImage(GfxState * /*state*/, Stream *str, int width, int height, - GfxImageColorMap *color_map, bool interpolate, int *mask_colors) { +void SvgBuilder::addImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, + bool interpolate, int *mask_colors) +{ - Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, interpolate, mask_colors); - if (image_node) { - _container->appendChild(image_node); + Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, interpolate, mask_colors); + if (image_node) { + _setBlendMode(image_node, state); + _container->appendChild(image_node); Inkscape::GC::release(image_node); - } + } } void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int height, @@ -1735,6 +1766,7 @@ void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int heigh _setFillStyle(css, state, false); sp_repr_css_change(rect, css, "style"); sp_repr_css_attr_unref(css); + _setBlendMode(rect, state); // Scaling 1x1 surfaces might not work so skip setting a mask with this size if ( width > 1 || height > 1 ) { @@ -1758,10 +1790,10 @@ void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int heigh Inkscape::GC::release(rect); } -void SvgBuilder::addMaskedImage(GfxState * /*state*/, Stream *str, int width, int height, - GfxImageColorMap *color_map, bool interpolate, - Stream *mask_str, int mask_width, int mask_height, - bool invert_mask, bool mask_interpolate) { +void SvgBuilder::addMaskedImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, + bool interpolate, Stream *mask_str, int mask_width, int mask_height, bool invert_mask, + bool mask_interpolate) +{ Inkscape::XML::Node *mask_image_node = _createImage(mask_str, mask_width, mask_height, nullptr, mask_interpolate, nullptr, true, invert_mask); @@ -1787,14 +1819,15 @@ void SvgBuilder::addMaskedImage(GfxState * /*state*/, Stream *str, int width, in Inkscape::GC::release(mask_image_node); } if (image_node) { + _setBlendMode(image_node, state); Inkscape::GC::release(image_node); } } - -void SvgBuilder::addSoftMaskedImage(GfxState * /*state*/, Stream *str, int width, int height, - GfxImageColorMap *color_map, bool interpolate, - Stream *mask_str, int mask_width, int mask_height, - GfxImageColorMap *mask_color_map, bool mask_interpolate) { + +void SvgBuilder::addSoftMaskedImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *color_map, + bool interpolate, Stream *mask_str, int mask_width, int mask_height, + GfxImageColorMap *mask_color_map, bool mask_interpolate) +{ Inkscape::XML::Node *mask_image_node = _createImage(mask_str, mask_width, mask_height, mask_color_map, mask_interpolate, nullptr, true); @@ -1815,6 +1848,7 @@ void SvgBuilder::addSoftMaskedImage(GfxState * /*state*/, Stream *str, int width Inkscape::GC::release(mask_image_node); } if (image_node) { + _setBlendMode(image_node, state); Inkscape::GC::release(image_node); } } -- cgit v1.2.3