Skip to content

Commit

Permalink
Implementation of EnsoGL predefined Rectangle shape. (#6033)
Browse files Browse the repository at this point in the history
  • Loading branch information
wdanilo authored Mar 23, 2023
1 parent dd009fd commit ca0779c
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 21 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions lib/rust/ensogl/core/src/display/shape/primitive/def/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ where for<'t> &'t Self: IntoOwned<Owned = Self> {
Union(self, that)
}

/// Unify two shapes, blending their colors based on the foreground shape's SDF value. This
/// means that even if these shapes overlap and the foreground is semi-transparent, it will
/// blend with the background only in the anti-aliased areas.
fn union_exclusive<S: IntoOwned>(&self, that: S) -> UnionExclusive<Self, Owned<S>> {
UnionExclusive(self, that)
}

/// Subtracts the argument from this shape.
fn difference<S: IntoOwned>(&self, that: S) -> Difference<Self, Owned<S>> {
Difference(self, that)
Expand Down
27 changes: 14 additions & 13 deletions lib/rust/ensogl/core/src/display/shape/primitive/def/modifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,18 @@ macro_rules! _define_modifier {

pub use immutable::*;
define_modifiers! {
Translate translate (child) (v:Vector2<Pixels>)
Rotation rotation (child) (angle:Radians)
Scale scale (child) (value:f32)
FlipY flip_y (child) ()
Union union (child1,child2) ()
Difference difference (child1,child2) ()
Intersection intersection (child1,child2) ()
Fill fill (child) (color:Rgba)
Recolorize recolorize (child) (r: Rgba, g: Rgba, b: Rgba)
PixelSnap pixel_snap (child) ()
Grow grow (child) (value:f32)
Shrink shrink (child) (value:f32)
Repeat repeat (child) (tile_size:Vector2<Pixels>)
Translate translate (child) (v:Vector2<Pixels>)
Rotation rotation (child) (angle:Radians)
Scale scale (child) (value:f32)
FlipY flip_y (child) ()
Union union (child1,child2) ()
UnionExclusive union_exclusive (child1,child2) ()
Difference difference (child1,child2) ()
Intersection intersection (child1,child2) ()
Fill fill (child) (color:Rgba)
Recolorize recolorize (child) (r: Rgba, g: Rgba, b: Rgba)
PixelSnap pixel_snap (child) ()
Grow grow (child) (value:f32)
Shrink shrink (child) (value:f32)
Repeat repeat (child) (tile_size:Vector2<Pixels>)
}
24 changes: 18 additions & 6 deletions lib/rust/ensogl/core/src/display/shape/primitive/glsl/shape.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ Color unpremultiply(PremultipliedColor c) {
return color(rgb, alpha);
}

PremultipliedColor blend_with_ratio(PremultipliedColor bg, PremultipliedColor fg, float ratio) {
vec4 raw = fg.repr.raw + (1.0 - ratio) * bg.repr.raw;
return PremultipliedColor(rgba(raw));
}

/// Implements glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
/// in the [`Color`]'s color space. See docs of [`Color`] to learn more.
PremultipliedColor blend(PremultipliedColor bg, PremultipliedColor fg) {
vec4 raw = fg.repr.raw + (1.0 - fg.repr.raw.a) * bg.repr.raw;
return PremultipliedColor(rgba(raw));
return blend_with_ratio(bg, fg, fg.repr.raw.a);
}

Srgba srgba(PremultipliedColor color) {
Expand Down Expand Up @@ -370,7 +374,7 @@ Shape inverse (Shape s1) {
return shape(s1.id, inverse(s1.sdf), s1.color);
}

Shape unify (Shape s1, Shape s2) {
Shape unify (Shape bg, Shape fg) {
if (input_display_mode == DISPLAY_MODE_CACHED_SHAPES_TEXTURE) {
// In DISPLAY_MODE_CACHED_SHAPES_TEXTURE the color has not [`alpha`] field applied (See
// [`color`] documentation for explanation). That means, that even outside the
Expand All @@ -383,11 +387,19 @@ Shape unify (Shape s1, Shape s2) {
// results ([`alpha`] field).
// * We want to keep the color consistent near border of the both shapes.
// The code below meets the both conditions.
if (s2.sdf.distance > s1.sdf.distance) {
s2.color.repr.raw *= s2.alpha;
if (fg.sdf.distance > bg.sdf.distance) {
fg.color.repr.raw *= fg.alpha;
}
}
return shape(s1.id, unify(s1.sdf, s2.sdf), blend(s1.color, s2.color));
return shape(bg.id, unify(bg.sdf, fg.sdf), blend(bg.color, fg.color));
}

// Unify two shapes, blending their colors based on the foreground shape's SDF value. This means
// that even if these shapes overlap and the foreground is semi-transparent, it will blend with
// the background only in the anti-aliased areas.
Shape unify_exclusive (Shape bg, Shape fg) {
float ratio = render(fg.sdf);
return shape(bg.id, unify(bg.sdf, fg.sdf), blend_with_ratio(bg.color, fg.color, ratio));
}

Shape difference (Shape s1, Shape s2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ impl Canvas {
})
}

/// Create an exclusive union shape from the provided shape components.
pub fn union_exclusive(&mut self, num: usize, s1: Shape, s2: Shape) -> Shape {
self.if_not_defined(num, |this| {
let expr = format!("return unify_exclusive({},{});", s1.getter(), s2.getter());
this.new_shape_from_expr(&expr)
})
}

/// Create a difference shape from the provided shape components.
pub fn difference(&mut self, num: usize, s1: Shape, s2: Shape) -> Shape {
self.if_not_defined(num, |this| {
Expand Down
5 changes: 3 additions & 2 deletions lib/rust/ensogl/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
ensogl-example-animation = { path = "animation" }
ensogl-example-auto-layout = { path = "auto-layout" }
ensogl-example-built-in-shapes = { path = "built-in-shapes" }
ensogl-example-cached-shape = { path = "cached-shape" }
ensogl-example-complex-shape-system = { path = "complex-shape-system" }
ensogl-example-custom-shape-system = { path = "custom-shape-system" }
ensogl-example-dom-symbols = { path = "dom-symbols" }
ensogl-example-drop-down = { path = "drop-down" }
ensogl-example-drop-manager = { path = "drop-manager" }
ensogl-example-focus-management = { path = "focus-management" }
ensogl-example-easing-animator = { path = "easing-animator" }
ensogl-example-list-view = { path = "list-view" }
ensogl-example-focus-management = { path = "focus-management" }
ensogl-example-grid-view = { path = "grid-view" }
ensogl-example-list-view = { path = "list-view" }
ensogl-example-mouse-events = { path = "mouse-events" }
ensogl-example-profiling-run-graph = { path = "profiling-run-graph" }
ensogl-example-render-profile-flamegraph = { path = "render-profile-flamegraph" }
Expand Down
17 changes: 17 additions & 0 deletions lib/rust/ensogl/examples/built-in-shapes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "ensogl-example-built-in-shapes"
version = "0.1.0"
authors = ["Enso Team <[email protected]>"]
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
ensogl-core = { path = "../../core" }
wasm-bindgen = { workspace = true }
ensogl-hardcoded-theme = { path = "../../../ensogl/app/theme/hardcoded" }

# Stop wasm-pack from running wasm-opt, because we run it from our build scripts in order to customize options.
[package.metadata.wasm-pack.profile.release]
wasm-opt = false
Loading

0 comments on commit ca0779c

Please sign in to comment.