From 4933efb5131c45c81d4732fe9a7957dfc4c49ce1 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 20 Feb 2020 20:38:43 -0800 Subject: [PATCH] Add Lighten and Darken composite ops --- Cargo.lock | 2 +- canvas/src/lib.rs | 34 ++++++++++++++++++++++-- content/src/effects.rs | 3 +++ examples/canvas_metal_minimal/Cargo.toml | 2 +- gl/src/lib.rs | 1 + gpu/src/lib.rs | 1 + metal/src/lib.rs | 1 + renderer/src/gpu/renderer.rs | 18 +++++++++++++ 8 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb7bf19d..8f219b8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ name = "canvas_metal_minimal" version = "0.1.0" dependencies = [ - "foreign-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 9da3d29e..6c2105f2 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -232,6 +232,7 @@ impl CanvasRenderingContext2D { fn push_path(&mut self, outline: Outline, paint_id: PaintId, fill_rule: FillRule) { let clip_path = self.current_state.clip_path; + let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); if !self.current_state.shadow_paint.is_fully_transparent() { let paint = self.current_state.resolve_paint(&self.current_state.shadow_paint); @@ -243,7 +244,7 @@ impl CanvasRenderingContext2D { paint_id, clip_path, fill_rule, - BlendMode::SourceOver, + blend_mode, String::new())) } @@ -251,7 +252,7 @@ impl CanvasRenderingContext2D { paint_id, clip_path, fill_rule, - BlendMode::SourceOver, + blend_mode, String::new())) } @@ -284,6 +285,16 @@ impl CanvasRenderingContext2D { self.current_state.global_alpha = new_global_alpha; } + #[inline] + pub fn global_composite_operation(&self) -> CompositeOperation { + self.current_state.global_composite_operation + } + + #[inline] + pub fn set_global_composite_operation(&mut self, new_composite_operation: CompositeOperation) { + self.current_state.global_composite_operation = new_composite_operation; + } + // The canvas state #[inline] @@ -316,6 +327,7 @@ struct State { shadow_offset: Vector2F, text_align: TextAlign, global_alpha: f32, + global_composite_operation: CompositeOperation, clip_path: Option, } @@ -337,6 +349,7 @@ impl State { shadow_offset: Vector2F::default(), text_align: TextAlign::Left, global_alpha: 1.0, + global_composite_operation: CompositeOperation::SourceOver, clip_path: None, } } @@ -507,3 +520,20 @@ pub enum LineJoin { Bevel, Round, } + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum CompositeOperation { + SourceOver, + Lighten, + Darken, +} + +impl CompositeOperation { + fn to_blend_mode(self) -> BlendMode { + match self { + CompositeOperation::SourceOver => BlendMode::SourceOver, + CompositeOperation::Lighten => BlendMode::Lighten, + CompositeOperation::Darken => BlendMode::Darken, + } + } +} diff --git a/content/src/effects.rs b/content/src/effects.rs index 3db7e9c9..4413e943 100644 --- a/content/src/effects.rs +++ b/content/src/effects.rs @@ -66,6 +66,8 @@ pub enum CompositeOp { pub enum BlendMode { SourceOver, Clear, + Lighten, + Darken, } #[derive(Clone, Copy, PartialEq, Debug)] @@ -92,6 +94,7 @@ impl BlendMode { pub fn occludes_backdrop(self) -> bool { match self { BlendMode::SourceOver | BlendMode::Clear => true, + BlendMode::Lighten | BlendMode::Darken => false, } } } diff --git a/examples/canvas_metal_minimal/Cargo.toml b/examples/canvas_metal_minimal/Cargo.toml index 3027d8ca..b1c862fa 100644 --- a/examples/canvas_metal_minimal/Cargo.toml +++ b/examples/canvas_metal_minimal/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Patrick Walton "] edition = "2018" [dependencies] -foreign-types = "0.5" +foreign-types = "0.3" gl = "0.14" metal = "0.17" objc = "0.2" diff --git a/gl/src/lib.rs b/gl/src/lib.rs index 46eda09a..8c26b5ed 100644 --- a/gl/src/lib.rs +++ b/gl/src/lib.rs @@ -965,6 +965,7 @@ impl BlendFactorExt for BlendFactor { BlendFactor::One => gl::ONE, BlendFactor::SrcAlpha => gl::SRC_ALPHA, BlendFactor::OneMinusSrcAlpha => gl::ONE_MINUS_SRC_ALPHA, + BlendFactor::DestColor => gl::DST_COLOR, } } } diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 34069d78..2775b268 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -226,6 +226,7 @@ pub enum BlendFactor { One, SrcAlpha, OneMinusSrcAlpha, + DestColor, } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/metal/src/lib.rs b/metal/src/lib.rs index b998a725..001412f0 100644 --- a/metal/src/lib.rs +++ b/metal/src/lib.rs @@ -1170,6 +1170,7 @@ impl BlendFactorExt for BlendFactor { BlendFactor::One => MTLBlendFactor::One, BlendFactor::SrcAlpha => MTLBlendFactor::SourceAlpha, BlendFactor::OneMinusSrcAlpha => MTLBlendFactor::OneMinusSourceAlpha, + BlendFactor::DestColor => MTLBlendFactor::DestinationColor, } } } diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 6026f29e..28305fa6 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -1151,6 +1151,24 @@ impl BlendModeExt for BlendMode { ..BlendState::default() } } + BlendMode::Lighten => { + BlendState { + src_rgb_factor: BlendFactor::SrcAlpha, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::One, + dest_alpha_factor: BlendFactor::One, + op: BlendOp::Max, + } + } + BlendMode::Darken => { + BlendState { + src_rgb_factor: BlendFactor::SrcAlpha, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::One, + dest_alpha_factor: BlendFactor::One, + op: BlendOp::Min, + } + } } } }