diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2013-12-05 19:27:44 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2013-12-05 19:27:44 +0000 |
| commit | 74bdba2b41e6609f3cee0e5eac4f766307577968 (patch) | |
| tree | 16fff098e56126eddfe1abdd4f0f7cb490bcb7ba /src | |
| parent | ImageMagick exception handling improvements (see Bug #1252719). (diff) | |
| download | inkscape-74bdba2b41e6609f3cee0e5eac4f766307577968.tar.gz inkscape-74bdba2b41e6609f3cee0e5eac4f766307577968.zip | |
New CSS blending and compositing modes.
Define WITH_CSSBLEND and/or WITH_CSSCOMPOSITE to try out.
Note: these new modes are not yet defined to apply to SVG filters in the
CSS Compositing and Blending Level 1 or in CSS Filters Level 1 specifications.
They are expected to be included in Level 2.
(bzr r12837)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/nr-filter-blend.cpp | 52 | ||||
| -rw-r--r-- | src/display/nr-filter-blend.h | 16 | ||||
| -rw-r--r-- | src/display/nr-filter-composite.cpp | 35 | ||||
| -rw-r--r-- | src/filter-enums.cpp | 49 | ||||
| -rw-r--r-- | src/filters/blend.cpp | 69 | ||||
| -rw-r--r-- | src/filters/composite.cpp | 39 | ||||
| -rw-r--r-- | src/filters/composite.h | 23 |
7 files changed, 249 insertions, 34 deletions
diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index bff7405b7..099816bce 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -83,6 +83,43 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LIGHTEN: cairo_set_operator(out_ct, CAIRO_OPERATOR_LIGHTEN); break; +#ifdef WITH_CSSBLEND + // NEW + case BLEND_OVERLAY: + cairo_set_operator(out_ct, CAIRO_OPERATOR_OVERLAY); + break; + case BLEND_COLORDODGE: + cairo_set_operator(out_ct, CAIRO_OPERATOR_COLOR_DODGE); + break; + case BLEND_COLORBURN: + cairo_set_operator(out_ct, CAIRO_OPERATOR_COLOR_BURN); + break; + case BLEND_HARDLIGHT: + cairo_set_operator(out_ct, CAIRO_OPERATOR_HARD_LIGHT); + break; + case BLEND_SOFTLIGHT: + cairo_set_operator(out_ct, CAIRO_OPERATOR_SOFT_LIGHT); + break; + case BLEND_DIFFERENCE: + cairo_set_operator(out_ct, CAIRO_OPERATOR_DIFFERENCE); + break; + case BLEND_EXCLUSION: + cairo_set_operator(out_ct, CAIRO_OPERATOR_EXCLUSION); + break; + case BLEND_HUE: + cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_HUE); + break; + case BLEND_SATURATION: + cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_SATURATION); + break; + case BLEND_COLOR: + cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_COLOR); + break; + case BLEND_LUMINOSITY: + cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_LUMINOSITY); + break; +#endif + case BLEND_NORMAL: default: cairo_set_operator(out_ct, CAIRO_OPERATOR_OVER); @@ -128,9 +165,18 @@ void FilterBlend::set_input(int input, int slot) { } void FilterBlend::set_mode(FilterBlendMode mode) { - if (mode == BLEND_NORMAL || mode == BLEND_MULTIPLY || - mode == BLEND_SCREEN || mode == BLEND_DARKEN || - mode == BLEND_LIGHTEN) + if (mode == BLEND_NORMAL || mode == BLEND_MULTIPLY || + mode == BLEND_SCREEN || mode == BLEND_DARKEN || + mode == BLEND_LIGHTEN +#ifdef WITH_CSSBLEND + || mode == BLEND_OVERLAY || + mode == BLEND_COLORDODGE || mode == BLEND_COLORBURN || + mode == BLEND_HARDLIGHT || mode == BLEND_SOFTLIGHT || + mode == BLEND_DIFFERENCE || mode == BLEND_EXCLUSION || + mode == BLEND_HUE || mode == BLEND_SATURATION || + mode == BLEND_COLOR || mode == BLEND_LUMINOSITY +#endif + ) { _blend_mode = mode; } diff --git a/src/display/nr-filter-blend.h b/src/display/nr-filter-blend.h index 957d3cfc8..0a2927d87 100644 --- a/src/display/nr-filter-blend.h +++ b/src/display/nr-filter-blend.h @@ -28,7 +28,21 @@ enum FilterBlendMode { BLEND_SCREEN, BLEND_DARKEN, BLEND_LIGHTEN, - BLEND_ENDMODE +#ifdef WITH_CSSBLEND + // New in CSS Compositing and Blending Level 1 + BLEND_OVERLAY, + BLEND_COLORDODGE, + BLEND_COLORBURN, + BLEND_HARDLIGHT, + BLEND_SOFTLIGHT, + BLEND_DIFFERENCE, + BLEND_EXCLUSION, + BLEND_HUE, + BLEND_SATURATION, + BLEND_COLOR, + BLEND_LUMINOSITY, +#endif + BLEND_ENDMODE, }; class FilterBlend : public FilterPrimitive { diff --git a/src/display/nr-filter-composite.cpp b/src/display/nr-filter-composite.cpp index f6decad0d..dc5e4278f 100644 --- a/src/display/nr-filter-composite.cpp +++ b/src/display/nr-filter-composite.cpp @@ -98,6 +98,33 @@ void FilterComposite::render_cairo(FilterSlot &slot) case COMPOSITE_XOR: cairo_set_operator(ct, CAIRO_OPERATOR_XOR); break; +#ifdef WITH_CSSCOMPOSITE + /* New CSS Operators */ + case COMPOSITE_CLEAR: + cairo_set_operator(ct, CAIRO_OPERATOR_CLEAR); + break; + case COMPOSITE_COPY: + cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); + break; + case COMPOSITE_DESTINATION: + cairo_set_operator(ct, CAIRO_OPERATOR_DEST); + break; + case COMPOSITE_DESTINATION_OVER: + cairo_set_operator(ct, CAIRO_OPERATOR_DEST_OVER); + break; + case COMPOSITE_DESTINATION_IN: + cairo_set_operator(ct, CAIRO_OPERATOR_DEST_IN); + break; + case COMPOSITE_DESTINATION_OUT: + cairo_set_operator(ct, CAIRO_OPERATOR_DEST_OUT); + break; + case COMPOSITE_DESTINATION_ATOP: + cairo_set_operator(ct, CAIRO_OPERATOR_DEST_ATOP); + break; + case COMPOSITE_LIGHTER: + cairo_set_operator(ct, CAIRO_OPERATOR_ADD); + break; +#endif case COMPOSITE_OVER: case COMPOSITE_DEFAULT: default: @@ -129,13 +156,7 @@ void FilterComposite::set_input(int input, int slot) { void FilterComposite::set_operator(FeCompositeOperator op) { if (op == COMPOSITE_DEFAULT) { this->op = COMPOSITE_OVER; - } else if (op == COMPOSITE_OVER || - op == COMPOSITE_IN || - op == COMPOSITE_OUT || - op == COMPOSITE_ATOP || - op == COMPOSITE_XOR || - op == COMPOSITE_ARITHMETIC) - { + } else if (op != COMPOSITE_ENDOPERATOR) { this->op = op; } } diff --git a/src/filter-enums.cpp b/src/filter-enums.cpp index 315b242bf..7ee57f7fa 100644 --- a/src/filter-enums.cpp +++ b/src/filter-enums.cpp @@ -48,11 +48,25 @@ const EnumDataConverter<FilterPrimitiveInput> FPInputConverter(FPInputData, FPIN // feBlend const EnumData<Inkscape::Filters::FilterBlendMode> BlendModeData[Inkscape::Filters::BLEND_ENDMODE] = { - {Inkscape::Filters::BLEND_NORMAL, _("Normal"), "normal"}, - {Inkscape::Filters::BLEND_MULTIPLY, _("Multiply"), "multiply"}, - {Inkscape::Filters::BLEND_SCREEN, _("Screen"), "screen"}, - {Inkscape::Filters::BLEND_DARKEN, _("Darken"), "darken"}, - {Inkscape::Filters::BLEND_LIGHTEN, _("Lighten"), "lighten"} + {Inkscape::Filters::BLEND_NORMAL, _("Normal"), "normal"}, + {Inkscape::Filters::BLEND_MULTIPLY, _("Multiply"), "multiply"}, + {Inkscape::Filters::BLEND_SCREEN, _("Screen"), "screen"}, + {Inkscape::Filters::BLEND_DARKEN, _("Darken"), "darken"}, + {Inkscape::Filters::BLEND_LIGHTEN, _("Lighten"), "lighten"}, +#ifdef WITH_CSSBLEND +// New in Compositing and Blending Level 1 + {Inkscape::Filters::BLEND_OVERLAY, _("Overlay"), "overlay"}, + {Inkscape::Filters::BLEND_COLORDODGE, _("Color Dodge"), "color-dodge"}, + {Inkscape::Filters::BLEND_COLORBURN, _("Color Burn"), "color-burn"}, + {Inkscape::Filters::BLEND_HARDLIGHT, _("Hard Light"), "hard-light"}, + {Inkscape::Filters::BLEND_SOFTLIGHT, _("Soft Light"), "soft-light"}, + {Inkscape::Filters::BLEND_DIFFERENCE, _("Difference"), "difference"}, + {Inkscape::Filters::BLEND_EXCLUSION, _("Exclusion"), "exclusion"}, + {Inkscape::Filters::BLEND_HUE, _("Hue"), "hue"}, + {Inkscape::Filters::BLEND_SATURATION, _("Saturation"), "saturation"}, + {Inkscape::Filters::BLEND_COLOR, _("Color"), "color"}, + {Inkscape::Filters::BLEND_LUMINOSITY, _("Luminosity"), "luminosity"} +#endif }; const EnumDataConverter<Inkscape::Filters::FilterBlendMode> BlendModeConverter(BlendModeData, Inkscape::Filters::BLEND_ENDMODE); @@ -67,13 +81,24 @@ const EnumDataConverter<Inkscape::Filters::FilterColorMatrixType> ColorMatrixTyp // feComposite const EnumData<FeCompositeOperator> CompositeOperatorData[COMPOSITE_ENDOPERATOR] = { - {COMPOSITE_DEFAULT, _("Default"), ""}, - {COMPOSITE_OVER, _("Over"), "over"}, - {COMPOSITE_IN, _("In"), "in"}, - {COMPOSITE_OUT, _("Out"), "out"}, - {COMPOSITE_ATOP, _("Atop"), "atop"}, - {COMPOSITE_XOR, _("XOR"), "xor"}, - {COMPOSITE_ARITHMETIC, _("Arithmetic"), "arithmetic"} + {COMPOSITE_DEFAULT, _("Default"), "" }, + {COMPOSITE_OVER, _("Over"), "over" }, + {COMPOSITE_IN, _("In"), "in" }, + {COMPOSITE_OUT, _("Out"), "out" }, + {COMPOSITE_ATOP, _("Atop"), "atop" }, + {COMPOSITE_XOR, _("XOR"), "xor" }, +#ifdef WITH_CSSCOMPOSITE +// New CSS + {COMPOSITE_CLEAR, _("Clear"), "clear" }, + {COMPOSITE_COPY, _("Copy"), "copy" }, + {COMPOSITE_DESTINATION, _("Destination"), "destination" }, + {COMPOSITE_DESTINATION_OVER, _("Destination Over"),"destination-over" }, + {COMPOSITE_DESTINATION_IN, _("Destination In"), "destination-in" }, + {COMPOSITE_DESTINATION_OUT, _("Destination Out"), "destination-out" }, + {COMPOSITE_DESTINATION_ATOP, _("Destination Atop"),"destination-atop" }, + {COMPOSITE_LIGHTER, _("Lighter"), "lighter" }, +#endif + {COMPOSITE_ARITHMETIC, _("Arithmetic"), "arithmetic" } }; const EnumDataConverter<FeCompositeOperator> CompositeOperatorConverter(CompositeOperatorData, COMPOSITE_ENDOPERATOR); diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index 219a099d1..5c78f4f9f 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -96,16 +96,50 @@ static Inkscape::Filters::FilterBlendMode sp_feBlend_readmode(gchar const *value case 's': if (strncmp(value, "screen", 6) == 0) return Inkscape::Filters::BLEND_SCREEN; +#ifdef WITH_CSSBLEND + if (strncmp(value, "saturation", 6) == 0) + return Inkscape::Filters::BLEND_SATURATION; +#endif break; case 'd': if (strncmp(value, "darken", 6) == 0) return Inkscape::Filters::BLEND_DARKEN; +#ifdef WITH_CSSBLEND + if (strncmp(value, "difference", 10) == 0) + return Inkscape::Filters::BLEND_DIFFERENCE; +#endif break; case 'l': if (strncmp(value, "lighten", 7) == 0) return Inkscape::Filters::BLEND_LIGHTEN; +#ifdef WITH_CSSBLEND + if (strncmp(value, "luminosity", 10) == 0) + return Inkscape::Filters::BLEND_LUMINOSITY; + break; + case 'o': + if (strncmp(value, "overlay", 7) == 0) + return Inkscape::Filters::BLEND_OVERLAY; + break; + case 'c': + if (strncmp(value, "color-dodge", 11) == 0) + return Inkscape::Filters::BLEND_COLORDODGE; + if (strncmp(value, "color-burn", 10) == 0) + return Inkscape::Filters::BLEND_COLORBURN; + if (strncmp(value, "color", 5) == 0) + return Inkscape::Filters::BLEND_COLOR; break; + case 'h': + if (strncmp(value, "hard-light", 7) == 0) + return Inkscape::Filters::BLEND_HARDLIGHT; + if (strncmp(value, "hue", 3) == 0) + return Inkscape::Filters::BLEND_HUE; + break; + case 'e': + if (strncmp(value, "exclusion", 10) == 0) + return Inkscape::Filters::BLEND_EXCLUSION; +#endif default: + std::cout << "Inkscape::Filters::FilterBlendMode: Unimplemented mode: " << value << std::endl; // do nothing by default break; } @@ -201,15 +235,40 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM char const *mode; switch(this->blend_mode) { case Inkscape::Filters::BLEND_NORMAL: - mode = "normal"; break; + mode = "normal"; break; case Inkscape::Filters::BLEND_MULTIPLY: - mode = "multiply"; break; + mode = "multiply"; break; case Inkscape::Filters::BLEND_SCREEN: - mode = "screen"; break; + mode = "screen"; break; case Inkscape::Filters::BLEND_DARKEN: - mode = "darken"; break; + mode = "darken"; break; case Inkscape::Filters::BLEND_LIGHTEN: - mode = "lighten"; break; + mode = "lighten"; break; +#ifdef WITH_CSSBLEND + // New + case Inkscape::Filters::BLEND_OVERLAY: + mode = "overlay"; break; + case Inkscape::Filters::BLEND_COLORDODGE: + mode = "color-dodge"; break; + case Inkscape::Filters::BLEND_COLORBURN: + mode = "color-burn"; break; + case Inkscape::Filters::BLEND_HARDLIGHT: + mode = "hard-light"; break; + case Inkscape::Filters::BLEND_SOFTLIGHT: + mode = "soft-light"; break; + case Inkscape::Filters::BLEND_DIFFERENCE: + mode = "difference"; break; + case Inkscape::Filters::BLEND_EXCLUSION: + mode = "exclusion"; break; + case Inkscape::Filters::BLEND_HUE: + mode = "hue"; break; + case Inkscape::Filters::BLEND_SATURATION: + mode = "saturation"; break; + case Inkscape::Filters::BLEND_COLOR: + mode = "color"; break; + case Inkscape::Filters::BLEND_LUMINOSITY: + mode = "luminosity"; break; +#endif default: mode = 0; } diff --git a/src/filters/composite.cpp b/src/filters/composite.cpp index 3c214a7a1..257292f12 100644 --- a/src/filters/composite.cpp +++ b/src/filters/composite.cpp @@ -100,6 +100,26 @@ sp_feComposite_read_operator(gchar const *value) { } else if (strcmp(value, "arithmetic") == 0) { return COMPOSITE_ARITHMETIC; } +#ifdef WITH_CSSCOMPOSITE + else if (strcmp(value, "clear") == 0) { + return COMPOSITE_CLEAR; + } else if (strcmp(value, "copy") == 0) { + return COMPOSITE_COPY; + } else if (strcmp(value, "destination") == 0) { + return COMPOSITE_DESTINATION; + } else if (strcmp(value, "destination-over") == 0) { + return COMPOSITE_DESTINATION_OVER; + } else if (strcmp(value, "destination-in") == 0) { + return COMPOSITE_DESTINATION_IN; + } else if (strcmp(value, "destination-out") == 0) { + return COMPOSITE_DESTINATION_OUT; + } else if (strcmp(value, "destination-atop") == 0) { + return COMPOSITE_DESTINATION_ATOP; + } else if (strcmp(value, "lighter") == 0) { + return COMPOSITE_LIGHTER; + } +#endif + std::cout << "Inkscape::Filters::FilterCompositeOperator: Unimplemented operator: " << value << std::endl; return COMPOSITE_DEFAULT; } @@ -243,6 +263,25 @@ Inkscape::XML::Node* SPFeComposite::write(Inkscape::XML::Document *doc, Inkscape comp_op = "xor"; break; case COMPOSITE_ARITHMETIC: comp_op = "arithmetic"; break; +#ifdef WITH_CSSCOMPOSITE + // New CSS operators + case COMPOSITE_CLEAR: + comp_op = "clear"; break; + case COMPOSITE_COPY: + comp_op = "copy"; break; + case COMPOSITE_DESTINATION: + comp_op = "destination"; break; + case COMPOSITE_DESTINATION_OVER: + comp_op = "destination-over"; break; + case COMPOSITE_DESTINATION_IN: + comp_op = "destination-in"; break; + case COMPOSITE_DESTINATION_OUT: + comp_op = "destination-out"; break; + case COMPOSITE_DESTINATION_ATOP: + comp_op = "destination-atop"; break; + case COMPOSITE_LIGHTER: + comp_op = "lighter"; break; +#endif default: comp_op = 0; } diff --git a/src/filters/composite.h b/src/filters/composite.h index b8c0178d1..42ec9d6b7 100644 --- a/src/filters/composite.h +++ b/src/filters/composite.h @@ -20,13 +20,24 @@ enum FeCompositeOperator { // Default value is 'over', but let's distinquish specifying the // default and implicitely using the default COMPOSITE_DEFAULT, - COMPOSITE_OVER, - COMPOSITE_IN, - COMPOSITE_OUT, - COMPOSITE_ATOP, + COMPOSITE_OVER, /* Source Over */ + COMPOSITE_IN, /* Source In */ + COMPOSITE_OUT, /* Source Out */ + COMPOSITE_ATOP, /* Source Atop */ COMPOSITE_XOR, - COMPOSITE_ARITHMETIC, - COMPOSITE_ENDOPERATOR + COMPOSITE_ARITHMETIC, /* Not a fundamental PorterDuff operator, nor Cairo */ +#ifdef WITH_CSSCOMPOSITE + // New in CSS + COMPOSITE_CLEAR, + COMPOSITE_COPY, /* Source */ + COMPOSITE_DESTINATION, + COMPOSITE_DESTINATION_OVER, + COMPOSITE_DESTINATION_IN, + COMPOSITE_DESTINATION_OUT, + COMPOSITE_DESTINATION_ATOP, + COMPOSITE_LIGHTER, /* Plus, Add (Not a fundamental PorterDuff operator */ +#endif + COMPOSITE_ENDOPERATOR /* Cairo Saturate is not included in CSS */ }; class SPFeComposite : public SPFilterPrimitive { |
