From fc1a6e9e4e5d75c0bbbe51054a55dd8af16ae0fc Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 23 Nov 2022 12:50:28 -0500 Subject: [PATCH] update for improved kurbo/peniko ergonomics also removes some annoying lingering tabs from blend.wgsl --- Cargo.lock | 9 ++--- piet-gpu/src/samples.rs | 54 ++++++++++++++++-------------- piet-scene/src/glyph.rs | 10 +++--- piet-scene/src/scene/builder.rs | 30 ++++++++++------- piet-wgsl/shader/shared/blend.wgsl | 8 ++--- piet-wgsl/src/test_scene.rs | 16 ++++----- 6 files changed, 68 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54d359d..0bc75b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -710,8 +710,9 @@ dependencies = [ [[package]] name = "kurbo" -version = "0.8.3" -source = "git+https://github.com/linebender/kurbo#79e5787a57f12d4965fcea01ab9442ecf6795775" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e119590a03caff1f7a582e8ee8c2164ddcc975791701188132fd1d1b518d3871" dependencies = [ "arrayvec 0.7.2", ] @@ -1070,9 +1071,9 @@ dependencies = [ [[package]] name = "peniko" version = "0.1.0" -source = "git+https://github.com/linebender/peniko?rev=aca2934#aca29349e7dcbd31f598172953ea88b5ddcd86df" +source = "git+https://github.com/linebender/peniko#b83821720aa51a3942be5d20c71525a1ae61ac0a" dependencies = [ - "kurbo 0.8.3", + "kurbo 0.9.0", "smallvec", ] diff --git a/piet-gpu/src/samples.rs b/piet-gpu/src/samples.rs index bcde384..f0629ae 100644 --- a/piet-gpu/src/samples.rs +++ b/piet-gpu/src/samples.rs @@ -1,45 +1,45 @@ use crate::PicoSvg; -use piet_scene::kurbo::{Affine, BezPath, Ellipse, PathEl, Point, Rect}; +use piet_scene::kurbo::{Affine, Ellipse, PathEl, Point, Rect}; use piet_scene::*; use crate::SimpleText; pub fn render_funky_paths(sb: &mut SceneBuilder) { use PathEl::*; - let missing_movetos = &[ + let missing_movetos = [ LineTo((100.0, 100.0).into()), LineTo((100.0, 200.0).into()), ClosePath, LineTo((0.0, 400.0).into()), LineTo((100.0, 400.0).into()), - ][..]; - let only_movetos = &[MoveTo((0.0, 0.0).into()), MoveTo((100.0, 100.0).into())][..]; - let empty: &[PathEl] = &[]; + ]; + let only_movetos = [MoveTo((0.0, 0.0).into()), MoveTo((100.0, 100.0).into())]; + let empty: [PathEl; 0] = []; sb.fill( Fill::NonZero, Affine::translate((100.0, 100.0)), - &Color::rgb8(0, 0, 255).into(), + Color::rgb8(0, 0, 255), None, &missing_movetos, ); sb.fill( Fill::NonZero, Affine::IDENTITY, - &Color::rgb8(0, 0, 255).into(), + Color::rgb8(0, 0, 255), None, &empty, ); sb.fill( Fill::NonZero, Affine::IDENTITY, - &Color::rgb8(0, 0, 255).into(), + Color::rgb8(0, 0, 255), None, &only_movetos, ); sb.stroke( &Stroke::new(8.0), Affine::translate((100.0, 100.0)), - &Color::rgb8(0, 255, 255).into(), + Color::rgb8(0, 255, 255), None, &missing_movetos, ); @@ -58,7 +58,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) { sb.fill( Fill::NonZero, Affine::IDENTITY, - &fill.color.into(), + fill.color, None, &fill.path, ); @@ -67,7 +67,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) { sb.stroke( &Stroke::new(stroke.width as f32), Affine::IDENTITY, - &stroke.color.into(), + stroke.color, None, &stroke.path, ); @@ -120,7 +120,7 @@ fn render_cardioid(sb: &mut SceneBuilder) { sb.stroke( &Stroke::new(2.0), Affine::IDENTITY, - &Brush::Solid(Color::rgb8(0, 0, 0)), + Color::rgb8(0, 0, 0), None, &&path[..], ); @@ -138,15 +138,15 @@ fn render_clip_test(sb: &mut SceneBuilder) { let step = 1.0 / ((N + 1) as f64); for i in 0..N { let t = ((i + 1) as f64) * step; - let path = &[ + let path = [ PathEl::MoveTo((X0, Y0).into()), PathEl::LineTo((X1, Y0).into()), PathEl::LineTo((X1, Y0 + t * (Y1 - Y0)).into()), PathEl::LineTo((X1 + t * (X0 - X1), Y1).into()), PathEl::LineTo((X0, Y1).into()), PathEl::ClosePath, - ][..]; - sb.push_layer(Mix::Clip.into(), Affine::IDENTITY, &path); + ]; + sb.push_layer(Mix::Clip, Affine::IDENTITY, &path); } let rect = Rect::new(X0, Y0, X1, Y1); sb.fill( @@ -167,26 +167,26 @@ fn render_alpha_test(sb: &mut SceneBuilder) { sb.fill( Fill::NonZero, Affine::IDENTITY, - &Color::rgb8(255, 0, 0).into(), + Color::rgb8(255, 0, 0), None, &&make_diamond(1024.0, 100.0)[..], ); sb.fill( Fill::NonZero, Affine::IDENTITY, - &Color::rgba8(0, 255, 0, 0x80).into(), + Color::rgba8(0, 255, 0, 0x80), None, &&make_diamond(1024.0, 125.0)[..], ); sb.push_layer( - Mix::Clip.into(), + Mix::Clip, Affine::IDENTITY, &&make_diamond(1024.0, 150.0)[..], ); sb.fill( Fill::NonZero, Affine::IDENTITY, - &Color::rgba8(0, 0, 255, 0x80).into(), + Color::rgba8(0, 0, 255, 0x80), None, &&make_diamond(1024.0, 175.0)[..], ); @@ -227,7 +227,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin // Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.)); let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]); - sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect); + sb.fill(Fill::NonZero, transform, &linear, None, &rect); const GRADIENTS: &[(f64, f64, Color)] = &[ (150., 0., Color::rgb8(255, 240, 64)), (175., 100., Color::rgb8(255, 96, 240)), @@ -237,14 +237,14 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin let mut color2 = c.clone(); color2.a = 0; let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]); - sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect); + sb.fill(Fill::NonZero, transform, &radial, None, &rect); } const COLORS: &[Color] = &[ Color::rgb8(255, 0, 0), Color::rgb8(0, 255, 0), Color::rgb8(0, 0, 255), ]; - sb.push_layer(Mix::Normal.into(), transform, &rect); + sb.push_layer(Mix::Normal, transform, &rect); for (i, c) in COLORS.iter().enumerate() { let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]); sb.push_layer(blend, transform, &rect); @@ -257,7 +257,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin sb.fill( Fill::NonZero, a, - &linear.into(), + &linear, None, &Ellipse::new((100., 100.), (90., 90.), 0.), ); @@ -319,9 +319,11 @@ pub fn render_anim_frame(sb: &mut SceneBuilder, text: &mut SimpleText, i: usize) #[allow(unused)] pub fn render_brush_transform(sb: &mut SceneBuilder, i: usize) { let th = (std::f64::consts::PI / 180.0) * (i as f64); - let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)) - .stops([Color::RED, Color::GREEN, Color::BLUE]) - .into(); + let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([ + Color::RED, + Color::GREEN, + Color::BLUE, + ]); sb.fill( Fill::NonZero, Affine::translate((200.0, 200.0)), diff --git a/piet-scene/src/glyph.rs b/piet-scene/src/glyph.rs index 4e2f6a6..d18a89e 100644 --- a/piet-scene/src/glyph.rs +++ b/piet-scene/src/glyph.rs @@ -20,7 +20,7 @@ pub use moscato::pinot; use crate::scene::{SceneBuilder, SceneFragment}; use peniko::kurbo::{Affine, Rect}; -use peniko::{Brush, Color, Fill}; +use peniko::{Brush, Color, Fill, Mix}; use moscato::{Context, Scaler}; use pinot::{types::Tag, FontRef}; @@ -123,13 +123,13 @@ impl<'a> GlyphProvider<'a> { let path = glyph.path(*path_index)?; if let Some(xform) = xform_stack.last() { builder.push_layer( - Default::default(), + Mix::Clip, Affine::IDENTITY, &convert_transformed_path(path.elements(), xform), ); } else { builder.push_layer( - Default::default(), + Mix::Clip, Affine::IDENTITY, &convert_path(path.elements()), ); @@ -144,7 +144,7 @@ impl<'a> GlyphProvider<'a> { max = *xform * max; } let rect = Rect::from_points(min, max); - builder.push_layer(Default::default(), Affine::IDENTITY, &rect); + builder.push_layer(Mix::Normal, Affine::IDENTITY, &rect); } Command::PopLayer => builder.pop_layer(), Command::BeginBlend(bounds, mode) => { @@ -212,7 +212,7 @@ fn convert_transformed_path( fn convert_blend(mode: moscato::CompositeMode) -> peniko::BlendMode { use moscato::CompositeMode; - use peniko::{BlendMode, Compose, Mix}; + use peniko::{BlendMode, Compose}; let mut mix = Mix::Normal; let mut compose = Compose::SrcOver; match mode { diff --git a/piet-scene/src/scene/builder.rs b/piet-scene/src/scene/builder.rs index 65ff186..606fb49 100644 --- a/piet-scene/src/scene/builder.rs +++ b/piet-scene/src/scene/builder.rs @@ -18,7 +18,7 @@ use super::{conv, Scene, SceneData, SceneFragment}; use crate::ResourcePatch; use bytemuck::{Pod, Zeroable}; use peniko::kurbo::{Affine, PathEl, Shape}; -use peniko::{BlendMode, Brush, ColorStop, Fill, Stroke}; +use peniko::{BlendMode, BrushRef, ColorStop, Fill, Stroke}; use smallvec::SmallVec; /// Builder for constructing a scene or scene fragment. @@ -51,7 +51,13 @@ impl<'a> SceneBuilder<'a> { /// Pushes a new layer bound by the specifed shape and composed with /// previous layers using the specified blend mode. - pub fn push_layer(&mut self, blend: BlendMode, transform: Affine, shape: &impl Shape) { + pub fn push_layer( + &mut self, + blend: impl Into, + transform: Affine, + shape: &impl Shape, + ) { + let blend = blend.into(); self.maybe_encode_transform(transform); self.linewidth(-1.0); if self.encode_path(shape, true) { @@ -75,11 +81,11 @@ impl<'a> SceneBuilder<'a> { } /// Fills a shape using the specified style and brush. - pub fn fill( + pub fn fill<'b>( &mut self, _style: Fill, transform: Affine, - brush: &Brush, + brush: impl Into>, brush_transform: Option, shape: &impl Shape, ) { @@ -97,11 +103,11 @@ impl<'a> SceneBuilder<'a> { } /// Strokes a shape using the specified style and brush. - pub fn stroke( + pub fn stroke<'b>( &mut self, style: &Stroke, transform: Affine, - brush: &Brush, + brush: impl Into>, brush_transform: Option, shape: &impl Shape, ) { @@ -194,16 +200,16 @@ impl<'a> SceneBuilder<'a> { } } - fn encode_brush(&mut self, brush: &Brush) { - match brush { - Brush::Solid(color) => { + fn encode_brush<'b>(&mut self, brush: impl Into>) { + match brush.into() { + BrushRef::Solid(color) => { self.scene.drawtag_stream.push(DRAWTAG_FILLCOLOR); let rgba_color = color.to_premul_u32(); self.scene .drawdata_stream .extend(bytemuck::bytes_of(&FillColor { rgba_color })); } - Brush::LinearGradient(gradient) => { + BrushRef::LinearGradient(gradient) => { let index = self.add_ramp(&gradient.stops); self.scene.drawtag_stream.push(DRAWTAG_FILLLINGRADIENT); self.scene @@ -214,7 +220,7 @@ impl<'a> SceneBuilder<'a> { p1: conv::point_to_f32(gradient.end), })); } - Brush::RadialGradient(gradient) => { + BrushRef::RadialGradient(gradient) => { let index = self.add_ramp(&gradient.stops); self.scene.drawtag_stream.push(DRAWTAG_FILLRADGRADIENT); self.scene @@ -227,7 +233,7 @@ impl<'a> SceneBuilder<'a> { r1: gradient.end_radius, })); } - Brush::SweepGradient(_gradient) => todo!("sweep gradients aren't done yet!"), + BrushRef::SweepGradient(_gradient) => todo!("sweep gradients aren't done yet!"), } } diff --git a/piet-wgsl/shader/shared/blend.wgsl b/piet-wgsl/shader/shared/blend.wgsl index cb1c586..5f9c583 100644 --- a/piet-wgsl/shader/shared/blend.wgsl +++ b/piet-wgsl/shader/shared/blend.wgsl @@ -45,11 +45,11 @@ fn color_burn(cb: f32, cs: f32) -> f32 { } fn hard_light(cb: vec3, cs: vec3) -> vec3 { - return mix( - screen(cb, 2.0 * cs - 1.0), - cb * 2.0 * cs, + return mix( + screen(cb, 2.0 * cs - 1.0), + cb * 2.0 * cs, vec3(cs <= vec3(0.5)) - ); + ); } fn soft_light(cb: vec3, cs: vec3) -> vec3 { diff --git a/piet-wgsl/src/test_scene.rs b/piet-wgsl/src/test_scene.rs index bb4c4ae..84195f7 100644 --- a/piet-wgsl/src/test_scene.rs +++ b/piet-wgsl/src/test_scene.rs @@ -28,13 +28,13 @@ pub fn gen_test_scene() -> Scene { let scene_ix = 1; match scene_ix { 0 => { - let path = &[ + let path = [ PathEl::MoveTo(Point::new(100.0, 100.0)), PathEl::LineTo(Point::new(500.0, 120.0)), PathEl::LineTo(Point::new(300.0, 150.0)), PathEl::LineTo(Point::new(200.0, 260.0)), PathEl::LineTo(Point::new(150.0, 210.0)), - ][..]; + ]; let brush = Brush::Solid(Color::rgb8(0x40, 0x40, 0xff)); builder.fill(Fill::NonZero, Affine::IDENTITY, &brush, None, &path); let transform = Affine::translate((50.0, 50.0)); @@ -79,7 +79,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) { sb.fill( Fill::NonZero, Affine::IDENTITY, - &fill.color.into(), + fill.color, None, &fill.path, ); @@ -88,7 +88,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) { sb.stroke( &Stroke::new(stroke.width as f32), Affine::IDENTITY, - &stroke.color.into(), + stroke.color, None, &stroke.path, ); @@ -134,7 +134,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin // Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.)); let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]); - sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect); + sb.fill(Fill::NonZero, transform, &linear, None, &rect); const GRADIENTS: &[(f64, f64, Color)] = &[ (150., 0., Color::rgb8(255, 240, 64)), (175., 100., Color::rgb8(255, 96, 240)), @@ -144,14 +144,14 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin let mut color2 = c.clone(); color2.a = 0; let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]); - sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect); + sb.fill(Fill::NonZero, transform, &radial, None, &rect); } const COLORS: &[Color] = &[ Color::rgb8(255, 0, 0), Color::rgb8(0, 255, 0), Color::rgb8(0, 0, 255), ]; - sb.push_layer(Mix::Normal.into(), transform, &rect); + sb.push_layer(Mix::Normal, transform, &rect); for (i, c) in COLORS.iter().enumerate() { let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]); sb.push_layer(blend, transform, &rect); @@ -164,7 +164,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin sb.fill( Fill::NonZero, a, - &linear.into(), + &linear, None, &Ellipse::new((100., 100.), (90., 90.), 0.), );