Brush blend modes and erase/restore (#1261)

* Made blit node numerically stable.

* Added blend mode parameter to brush strokes.

* Fixed difference blend mode.

* Added erase/restore blend modes.

* Added blend mode and draw mode widgets.

* Added comment explaining the ImageFrame.transform.

* Initial blit/blend version.

* Working version of erase/restore.

* Improved inlining for blend functions.

* Dsiable the blend mode selector in erase/draw mode.

* Fixed incorrect bounds calculation.

* Use factor instead of percentage for opacity

* Rearrange options bar widgets

* Tidy up blend modes

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Orson Peters
2023-06-02 21:59:55 +02:00
committed by GitHub
parent c9e7436879
commit b7f5ac4af5
13 changed files with 397 additions and 153 deletions

View File

@@ -5,19 +5,19 @@ use std::fmt;
/// See the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/blend-mode#examples) for examples.
#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize, specta::Type)]
pub enum BlendMode {
// Basic group
// Normal group
Normal,
// Not supported by SVG, but we should someday support: Dissolve
// Darken group
Multiply,
Darken,
Multiply,
ColorBurn,
// Not supported by SVG, but we should someday support: Linear Burn, Darker Color
// Lighten group
Screen,
Lighten,
Screen,
ColorDodge,
// Not supported by SVG, but we should someday support: Linear Dodge (Add), Lighter Color
@@ -42,23 +42,29 @@ pub enum BlendMode {
impl fmt::Display for BlendMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
// Normal group
BlendMode::Normal => write!(f, "Normal"),
BlendMode::Multiply => write!(f, "Multiply"),
// Darken group
BlendMode::Darken => write!(f, "Darken"),
BlendMode::Multiply => write!(f, "Multiply"),
BlendMode::ColorBurn => write!(f, "Color Burn"),
BlendMode::Screen => write!(f, "Screen"),
// Lighten group
BlendMode::Lighten => write!(f, "Lighten"),
BlendMode::Screen => write!(f, "Screen"),
BlendMode::ColorDodge => write!(f, "Color Dodge"),
// Contrast group
BlendMode::Overlay => write!(f, "Overlay"),
BlendMode::SoftLight => write!(f, "Soft Light"),
BlendMode::HardLight => write!(f, "Hard Light"),
// Inversion group
BlendMode::Difference => write!(f, "Difference"),
BlendMode::Exclusion => write!(f, "Exclusion"),
// Component group
BlendMode::Hue => write!(f, "Hue"),
BlendMode::Saturation => write!(f, "Saturation"),
BlendMode::Color => write!(f, "Color"),
@@ -72,18 +78,24 @@ impl BlendMode {
/// [Read more](https://developer.mozilla.org/en-US/docs/Web/CSS/blend-mode#values)
pub fn to_svg_style_name(&self) -> &str {
match self {
// Normal group
BlendMode::Normal => "normal",
BlendMode::Multiply => "multiply",
// Darken group
BlendMode::Darken => "darken",
BlendMode::Multiply => "multiply",
BlendMode::ColorBurn => "color-burn",
BlendMode::Screen => "screen",
// Lighten group
BlendMode::Lighten => "lighten",
BlendMode::Screen => "screen",
BlendMode::ColorDodge => "color-dodge",
// Contrast group
BlendMode::Overlay => "overlay",
BlendMode::SoftLight => "soft-light",
BlendMode::HardLight => "hard-light",
// Inversion group
BlendMode::Difference => "difference",
BlendMode::Exclusion => "exclusion",
// Component group
BlendMode::Hue => "hue",
BlendMode::Saturation => "saturation",
BlendMode::Color => "color",
@@ -94,11 +106,17 @@ impl BlendMode {
/// List of all the blend modes in their conventional ordering and grouping.
pub fn list_modes_in_groups() -> [&'static [BlendMode]; 6] {
[
// Normal group
&[BlendMode::Normal],
&[BlendMode::Multiply, BlendMode::Darken, BlendMode::ColorBurn],
&[BlendMode::Screen, BlendMode::Lighten, BlendMode::ColorDodge],
// Darken group
&[BlendMode::Darken, BlendMode::Multiply, BlendMode::ColorBurn],
// Lighten group
&[BlendMode::Lighten, BlendMode::Screen, BlendMode::ColorDodge],
// Contrast group
&[BlendMode::Overlay, BlendMode::SoftLight, BlendMode::HardLight],
// Inversion group
&[BlendMode::Difference, BlendMode::Exclusion],
// Component group
&[BlendMode::Hue, BlendMode::Saturation, BlendMode::Color, BlendMode::Luminosity],
]
}