summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2013-12-10 12:40:42 +0000
committertavmjong-free <tavmjong@free.fr>2013-12-10 12:40:42 +0000
commitcd9fae530b0cf7e48a7b8cb41ef5efb7e99717fe (patch)
tree9835ce4a35ad3ff6d0f9b073f08a3f6aefc463cb
parentAdd JessyInk namespace. (diff)
downloadinkscape-cd9fae530b0cf7e48a7b8cb41ef5efb7e99717fe.tar.gz
inkscape-cd9fae530b0cf7e48a7b8cb41ef5efb7e99717fe.zip
New CSS blending modes (outside of filters).
Define WITH_CSSBLEND to try out. Note: The modes are defined in CSS Compositing and Blending Level 1. To do: GUI. Isolate SVG drawing from Inkscape background (i.e. page border). (bzr r12845)
-rw-r--r--src/attributes.cpp2
-rw-r--r--src/attributes.h2
-rw-r--r--src/display/drawing-item.cpp88
-rw-r--r--src/display/drawing-item.h5
-rw-r--r--src/sp-item.cpp5
-rw-r--r--src/style.cpp51
-rw-r--r--src/style.h29
7 files changed, 182 insertions, 0 deletions
diff --git a/src/attributes.cpp b/src/attributes.cpp
index b93bcfd57..40e11b023 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -440,6 +440,8 @@ static SPStyleProp const props[] = {
{SP_PROP_DISPLAY, "display"},
{SP_PROP_OVERFLOW, "overflow"},
{SP_PROP_VISIBILITY, "visibility"},
+ {SP_PROP_BLEND_MODE, "mix-blend-mode"}, // CSS Blending and Compositing
+ {SP_PROP_ISOLATION, "isolation"},
/* SVG */
/* Clip/Mask */
{SP_PROP_CLIP_PATH, "clip-path"},
diff --git a/src/attributes.h b/src/attributes.h
index 24244c237..ecf7ce966 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -441,6 +441,8 @@ enum SPAttributeEnum {
SP_PROP_DISPLAY,
SP_PROP_OVERFLOW,
SP_PROP_VISIBILITY,
+ SP_PROP_BLEND_MODE,
+ SP_PROP_ISOLATION,
/* SVG */
/* Clip/Mask */
SP_PROP_CLIP_PATH,
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index a8257e6e5..a9b07bb6e 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -23,6 +23,66 @@
namespace Inkscape {
+#ifdef WITH_CSSBLEND
+void set_cairo_blend_operator( DrawingContext &ct, unsigned blend_mode ) {
+
+ // All of the blend modes are implemented in Cairo as of 1.10.
+ // For a detailed description, see:
+ // http://cairographics.org/operators/
+ switch (blend_mode) {
+ case SP_CSS_BLEND_MULTIPLY:
+ ct.setOperator(CAIRO_OPERATOR_MULTIPLY);
+ break;
+ case SP_CSS_BLEND_SCREEN:
+ ct.setOperator(CAIRO_OPERATOR_SCREEN);
+ break;
+ case SP_CSS_BLEND_DARKEN:
+ ct.setOperator(CAIRO_OPERATOR_DARKEN);
+ break;
+ case SP_CSS_BLEND_LIGHTEN:
+ ct.setOperator(CAIRO_OPERATOR_LIGHTEN);
+ break;
+ case SP_CSS_BLEND_OVERLAY:
+ ct.setOperator(CAIRO_OPERATOR_OVERLAY);
+ break;
+ case SP_CSS_BLEND_COLORDODGE:
+ ct.setOperator(CAIRO_OPERATOR_COLOR_DODGE);
+ break;
+ case SP_CSS_BLEND_COLORBURN:
+ ct.setOperator(CAIRO_OPERATOR_COLOR_BURN);
+ break;
+ case SP_CSS_BLEND_HARDLIGHT:
+ ct.setOperator(CAIRO_OPERATOR_HARD_LIGHT);
+ break;
+ case SP_CSS_BLEND_SOFTLIGHT:
+ ct.setOperator(CAIRO_OPERATOR_SOFT_LIGHT);
+ break;
+ case SP_CSS_BLEND_DIFFERENCE:
+ ct.setOperator(CAIRO_OPERATOR_DIFFERENCE);
+ break;
+ case SP_CSS_BLEND_EXCLUSION:
+ ct.setOperator(CAIRO_OPERATOR_EXCLUSION);
+ break;
+ case SP_CSS_BLEND_HUE:
+ ct.setOperator(CAIRO_OPERATOR_HSL_HUE);
+ break;
+ case SP_CSS_BLEND_SATURATION:
+ ct.setOperator(CAIRO_OPERATOR_HSL_SATURATION);
+ break;
+ case SP_CSS_BLEND_COLOR:
+ ct.setOperator(CAIRO_OPERATOR_HSL_COLOR);
+ break;
+ case SP_CSS_BLEND_LUMINOSITY:
+ ct.setOperator(CAIRO_OPERATOR_HSL_LUMINOSITY);
+ break;
+ case SP_CSS_BLEND_NORMAL:
+ default:
+ ct.setOperator(CAIRO_OPERATOR_OVER);
+ break;
+ }
+}
+#endif
+
/**
* @class DrawingItem
* SVG drawing item for display.
@@ -67,6 +127,8 @@ DrawingItem::DrawingItem(Drawing &drawing)
, _propagate(0)
// , _renders_opacity(0)
, _pick_children(0)
+ , _isolation(SP_CSS_ISOLATION_AUTO)
+ , _blend_mode(SP_CSS_BLEND_NORMAL)
{}
DrawingItem::~DrawingItem()
@@ -209,6 +271,22 @@ DrawingItem::setOpacity(float opacity)
}
void
+DrawingItem::setIsolation(unsigned isolation)
+{
+ _isolation = isolation;
+ //if( isolation != 0 ) std::cout << "isolation: " << isolation << std::endl;
+ _markForRendering();
+}
+
+void
+DrawingItem::setBlendMode(unsigned blend_mode)
+{
+ _blend_mode = blend_mode;
+ //if( blend_mode != 0 ) std::cout << "setBlendMode: " << blend_mode << std::endl;
+ _markForRendering();
+}
+
+void
DrawingItem::setVisible(bool v)
{
_visible = v;
@@ -494,6 +572,9 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
if (_cached) {
if (_cache) {
_cache->prepare();
+#ifdef WITH_CSSBLEND
+ set_cairo_blend_operator( ct, _blend_mode );
+#endif
_cache->paintFromCache(ct, carea);
if (!carea) return RENDER_OK;
} else {
@@ -522,6 +603,10 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
nir |= (_filter != NULL && render_filters); // 3. it has a filter
nir |= needs_opacity; // 4. it is non-opaque
nir |= (_cache != NULL); // 5. it is cached
+#ifdef WITH_CSSBLEND
+ nir |= (_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal
+ nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom
+#endif
/* How the rendering is done.
*
@@ -633,6 +718,9 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
}
ct.rectangle(*carea);
ct.setSource(&intermediate);
+#ifdef WITH_CSSBLEND
+ set_cairo_blend_operator( ct, _blend_mode );
+#endif
ct.fill();
ct.setSource(0,0,0,0);
// the call above is to clear a ref on the intermediate surface held by ct
diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h
index e03bbd0f7..1796d29d6 100644
--- a/src/display/drawing-item.h
+++ b/src/display/drawing-item.h
@@ -108,6 +108,8 @@ public:
void setCached(bool c, bool persistent = false);
void setOpacity(float opacity);
+ void setIsolation(unsigned isolation); // CSS Compositing and Blending
+ void setBlendMode(unsigned blend_mode);
void setTransform(Geom::Affine const &trans);
void setClip(DrawingItem *item);
void setMask(DrawingItem *item);
@@ -204,6 +206,9 @@ protected:
unsigned _pick_children : 1; ///< For groups: if true, children are returned from pick(),
/// otherwise the group is returned
+ unsigned _isolation : 1;
+ unsigned _blend_mode : 4;
+
friend class Drawing;
};
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index c6daa853c..5e126f486 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -599,6 +599,8 @@ void SPItem::update(SPCtx* /*ctx*/, guint flags) {
if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
for (SPItemView *v = item->display; v != NULL; v = v->next) {
v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(object->style->opacity.value));
+ v->arenaitem->setIsolation( object->style->isolation.value );
+ v->arenaitem->setBlendMode( object->style->blend_mode.value );
v->arenaitem->setVisible(!item->isHidden());
}
}
@@ -1023,6 +1025,9 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned
display = sp_item_view_new_prepend(display, this, flags, key, ai);
ai->setTransform(transform);
ai->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value));
+ ai->setIsolation( style->isolation.value );
+ ai->setBlendMode( style->blend_mode.value );
+ //ai->setCompositeOperator( style->composite_op.value );
ai->setVisible(!isHidden());
ai->setSensitive(sensitive);
if (clip_ref->getObject()) {
diff --git a/src/style.cpp b/src/style.cpp
index fc0c97c15..bb5603f1c 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -303,6 +303,33 @@ static SPStyleEnum const enum_overflow[] = {
{NULL, -1}
};
+// CSS Compositing and Blending Level 1
+static SPStyleEnum const enum_isolation[] = {
+ {"auto", SP_CSS_ISOLATION_AUTO},
+ {"isolate", SP_CSS_ISOLATION_ISOLATE},
+ {NULL, -1}
+};
+
+static SPStyleEnum const enum_blend_mode[] = {
+ {"normal", SP_CSS_BLEND_NORMAL},
+ {"multiply", SP_CSS_BLEND_MULTIPLY},
+ {"screen", SP_CSS_BLEND_SCREEN},
+ {"darken", SP_CSS_BLEND_DARKEN},
+ {"lighten", SP_CSS_BLEND_LIGHTEN},
+ {"overlay", SP_CSS_BLEND_OVERLAY},
+ {"color-dodge", SP_CSS_BLEND_COLORDODGE},
+ {"color-burn", SP_CSS_BLEND_COLORBURN},
+ {"hard-light", SP_CSS_BLEND_HARDLIGHT},
+ {"soft-light", SP_CSS_BLEND_SOFTLIGHT},
+ {"difference", SP_CSS_BLEND_DIFFERENCE},
+ {"exclusion", SP_CSS_BLEND_EXCLUSION},
+ {"hue", SP_CSS_BLEND_HUE},
+ {"saturation", SP_CSS_BLEND_SATURATION},
+ {"color", SP_CSS_BLEND_COLOR},
+ {"luminosity", SP_CSS_BLEND_LUMINOSITY},
+ {NULL, -1}
+};
+
static SPStyleEnum const enum_display[] = {
{"none", SP_CSS_DISPLAY_NONE},
{"inline", SP_CSS_DISPLAY_INLINE},
@@ -643,6 +670,11 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr)
SPS_READ_PENUM_IF_UNSET(&style->visibility, repr, "visibility", enum_visibility, true);
SPS_READ_PENUM_IF_UNSET(&style->display, repr, "display", enum_display, true);
SPS_READ_PENUM_IF_UNSET(&style->overflow, repr, "overflow", enum_overflow, true);
+
+ /* CSS Compositing and Blending Level 1 */
+ SPS_READ_PENUM_IF_UNSET(&style->isolation, repr, "isolation", enum_isolation, true);
+ SPS_READ_PENUM_IF_UNSET(&style->blend_mode, repr, "mix_blend_mode", enum_blend_mode, true);
+
/* Font */
SPS_READ_PFONTSIZE_IF_UNSET(&style->font_size, repr, "font-size");
SPS_READ_PENUM_IF_UNSET(&style->font_style, repr, "font-style", enum_font_style, true);
@@ -1207,6 +1239,13 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val)
case SP_PROP_VISIBILITY:
SPS_READ_IENUM_IF_UNSET(&style->visibility, val, enum_visibility, true);
break;
+ case SP_PROP_ISOLATION:
+ SPS_READ_IENUM_IF_UNSET(&style->isolation, val, enum_isolation, true);
+ break;
+ case SP_PROP_BLEND_MODE:
+ SPS_READ_IENUM_IF_UNSET(&style->blend_mode, val, enum_blend_mode, true);
+ break;
+
/* SVG */
/* Clip/Mask */
case SP_PROP_CLIP_PATH:
@@ -2180,6 +2219,7 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare
/* Enum values that don't have any relative settings (other than `inherit'). */
{
SPIEnum SPStyle::*const fields[] = {
+ &SPStyle::blend_mode,
&SPStyle::clip_rule,
&SPStyle::color_interpolation,
&SPStyle::color_interpolation_filters,
@@ -2189,6 +2229,7 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare
&SPStyle::font_style,
&SPStyle::font_variant,
&SPStyle::image_rendering,
+ &SPStyle::isolation,
//nyi: SPStyle::pointer_events,
&SPStyle::shape_rendering,
&SPStyle::stroke_linecap,
@@ -2791,6 +2832,8 @@ sp_style_write_string(SPStyle const *const style, guint const flags)
p += sp_style_write_ienum(p, c + BMAX - p, "visibility", enum_visibility, &style->visibility, NULL, flags);
p += sp_style_write_ienum(p, c + BMAX - p, "display", enum_display, &style->display, NULL, flags);
p += sp_style_write_ienum(p, c + BMAX - p, "overflow", enum_overflow, &style->overflow, NULL, flags);
+ p += sp_style_write_ienum(p, c + BMAX - p, "isolation", enum_isolation, &style->isolation, NULL, flags);
+ p += sp_style_write_ienum(p, c + BMAX - p, "mix-blend-mode", enum_blend_mode, &style->blend_mode, NULL, flags);
/* filter: */
p += sp_style_write_ifilter(p, c + BMAX - p, "filter", &style->filter, NULL, flags);
@@ -2949,6 +2992,8 @@ sp_style_write_difference(SPStyle const *const from, SPStyle const *const to)
p += sp_style_write_ienum(p, c + BMAX - p, "visibility", enum_visibility, &from->visibility, &to->visibility, SP_STYLE_FLAG_IFSET);
p += sp_style_write_ienum(p, c + BMAX - p, "display", enum_display, &from->display, &to->display, SP_STYLE_FLAG_IFSET);
p += sp_style_write_ienum(p, c + BMAX - p, "overflow", enum_overflow, &from->overflow, &to->overflow, SP_STYLE_FLAG_IFSET);
+ p += sp_style_write_ienum(p, c + BMAX - p, "isolation", enum_isolation, &from->isolation, &to->isolation, SP_STYLE_FLAG_IFSET);
+ p += sp_style_write_ienum(p, c + BMAX - p, "mix-blend-mode", enum_blend_mode, &from->blend_mode, &to->blend_mode, SP_STYLE_FLAG_IFSET);
/* filter: */
p += sp_style_write_ifilter(p, c + BMAX - p, "filter", &from->filter, &to->filter, SP_STYLE_FLAG_IFDIFF);
@@ -3168,6 +3213,12 @@ sp_style_clear(SPStyle *style)
style->overflow.set = FALSE;
style->overflow.inherit = FALSE;
style->overflow.value = style->overflow.computed = SP_CSS_OVERFLOW_VISIBLE;
+ style->isolation.set = FALSE;
+ style->isolation.inherit = FALSE;
+ style->isolation.value = style->isolation.computed = SP_CSS_ISOLATION_AUTO;
+ style->blend_mode.set = FALSE;
+ style->blend_mode.inherit = FALSE;
+ style->blend_mode.value = style->blend_mode.computed = SP_CSS_BLEND_NORMAL;
style->color.clear();
style->color.setColor(0.0, 0.0, 0.0);
diff --git a/src/style.h b/src/style.h
index bc4df96e2..014d2b72f 100644
--- a/src/style.h
+++ b/src/style.h
@@ -364,6 +364,11 @@ struct SPStyle {
/** opacity */
SPIScale24 opacity;
+ /** mix-blend-mode: CSS Compositing and Blending Level 1 */
+ SPIEnum isolation;
+ // Could be shared with Filter blending mode
+ SPIEnum blend_mode;
+
/** color */
SPIPaint color;
/** color-interpolation */
@@ -606,6 +611,30 @@ enum SPCSSDisplay {
SP_CSS_DISPLAY_TABLE_CAPTION
};
+enum SPIsolation {
+ SP_CSS_ISOLATION_AUTO,
+ SP_CSS_ISOLATION_ISOLATE
+};
+
+enum SPBlendMode {
+ SP_CSS_BLEND_NORMAL,
+ SP_CSS_BLEND_MULTIPLY,
+ SP_CSS_BLEND_SCREEN,
+ SP_CSS_BLEND_DARKEN,
+ SP_CSS_BLEND_LIGHTEN,
+ SP_CSS_BLEND_OVERLAY,
+ SP_CSS_BLEND_COLORDODGE,
+ SP_CSS_BLEND_COLORBURN,
+ SP_CSS_BLEND_HARDLIGHT,
+ SP_CSS_BLEND_SOFTLIGHT,
+ SP_CSS_BLEND_DIFFERENCE,
+ SP_CSS_BLEND_EXCLUSION,
+ SP_CSS_BLEND_HUE,
+ SP_CSS_BLEND_SATURATION,
+ SP_CSS_BLEND_COLOR,
+ SP_CSS_BLEND_LUMINOSITY
+};
+
enum SPEnableBackground {
SP_CSS_BACKGROUND_ACCUMULATE,
SP_CSS_BACKGROUND_NEW