From 94f7b51bc5aaf0b253a8340a75cc356f1f8011e1 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 18 May 2022 16:22:27 -0400 Subject: [PATCH 1/7] Add kurbo conversions Adds kurbo as an optional dependency and implements conversions to/from the common types. This also removes the direct pinot dependency and changes moscato (temporarily) to a git based dep to allow iteration on the underlying glyph loading code without PR churn here. --- Cargo.lock | 26 ++++++++--- piet-scene/Cargo.toml | 4 +- piet-scene/src/glyph/mod.rs | 2 +- piet-scene/src/lib.rs | 93 +++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f80fa371..1b9a6e3fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "ash" version = "0.33.3+1.2.191" @@ -596,7 +602,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cb54cd28cb3d2e964d9444ca185676a94fd9b7cce5f02b22c717947ed8e9a2" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", +] + +[[package]] +name = "kurbo" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" +dependencies = [ + "arrayvec 0.7.2", ] [[package]] @@ -755,8 +770,7 @@ dependencies = [ [[package]] name = "moscato" version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8372f6cdc8b2c431750a9c4edbc8d9c511ef1a68472aaa02500493414a407c64" +source = "git+https://github.com/dfrg/pinot#59db153ff83420449a909dfaace18466bddbf814" dependencies = [ "pinot", ] @@ -954,7 +968,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f00543608fb5ee6063f5ff1259246ae23073c1a5e413e643d0469da3d4b7b4de" dependencies = [ - "kurbo", + "kurbo 0.7.1", "unic-bidi", ] @@ -1012,7 +1026,7 @@ version = "0.1.0" dependencies = [ "bytemuck", "clap", - "kurbo", + "kurbo 0.7.1", "piet-gpu", "piet-gpu-hal", "rand", @@ -1031,8 +1045,8 @@ name = "piet-scene" version = "0.1.0" dependencies = [ "bytemuck", + "kurbo 0.8.3", "moscato", - "pinot", "smallvec", ] diff --git a/piet-scene/Cargo.toml b/piet-scene/Cargo.toml index df66483e3..e80cbb826 100644 --- a/piet-scene/Cargo.toml +++ b/piet-scene/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" [dependencies] bytemuck = { version = "1.7.2", features = ["derive"] } smallvec = "1.8.0" -pinot = "0.1.5" -moscato = "0.1.2" +moscato = { git = "https://github.com/dfrg/pinot" } +kurbo = { version = "0.8.3", optional = true } diff --git a/piet-scene/src/glyph/mod.rs b/piet-scene/src/glyph/mod.rs index 3bfa36ce6..690873cdf 100644 --- a/piet-scene/src/glyph/mod.rs +++ b/piet-scene/src/glyph/mod.rs @@ -14,7 +14,7 @@ // // Also licensed under MIT license, at your choice. -pub use pinot; +pub use moscato::pinot; use crate::brush::{Brush, Color}; use crate::geometry::Affine; diff --git a/piet-scene/src/lib.rs b/piet-scene/src/lib.rs index a72ff5425..4f8da3dbd 100644 --- a/piet-scene/src/lib.rs +++ b/piet-scene/src/lib.rs @@ -20,3 +20,96 @@ pub mod glyph; pub mod path; pub mod resource; pub mod scene; + +/// Implement conversions to and from Kurbo types when the `kurbo` feature is +/// enabled. +#[cfg(feature = "kurbo")] +mod kurbo_conv { + use super::geometry::{Affine, Point, Rect}; + use super::path::Element; + + impl From for Point { + fn from(p: kurbo::Point) -> Self { + Self::new(p.x as f32, p.y as f32) + } + } + + impl From for kurbo::Point { + fn from(p: Point) -> kurbo::Point { + Self::new(p.x as f64, p.y as f64) + } + } + + impl From for Affine { + fn from(a: kurbo::Affine) -> Self { + let c = a.as_coeffs(); + Self { + xx: c[0] as f32, + yx: c[1] as f32, + xy: c[2] as f32, + yy: c[3] as f32, + dx: c[4] as f32, + dy: c[5] as f32, + } + } + } + + impl From for kurbo::Affine { + fn from(a: Affine) -> Self { + Self::new([ + a.xx as f64, + a.yx as f64, + a.yx as f64, + a.yy as f64, + a.dx as f64, + a.dy as f64, + ]) + } + } + + impl From for Rect { + fn from(r: kurbo::Rect) -> Self { + Self { + min: Point::new(r.x0 as f32, r.y0 as f32), + max: Point::new(r.x1 as f32, r.y1 as f32), + } + } + } + + impl From for kurbo::Rect { + fn from(r: Rect) -> Self { + Self { + x0: r.min.x as f64, + y0: r.min.y as f64, + x1: r.max.x as f64, + y1: r.max.y as f64, + } + } + } + + impl From for Element { + fn from(e: kurbo::PathEl) -> Self { + use kurbo::PathEl::*; + match e { + MoveTo(p0) => Self::MoveTo(p0.into()), + LineTo(p0) => Self::LineTo(p0.into()), + QuadTo(p0, p1) => Self::QuadTo(p0.into(), p1.into()), + CurveTo(p0, p1, p2) => Self::CurveTo(p0.into(), p1.into(), p2.into()), + ClosePath => Self::Close, + } + } + } + + impl From for kurbo::PathEl { + fn from(e: Element) -> Self { + use Element::*; + match e { + MoveTo(p0) => Self::MoveTo(p0.into()), + LineTo(p0) => Self::LineTo(p0.into()), + QuadTo(p0, p1) => Self::QuadTo(p0.into(), p1.into()), + CurveTo(p0, p1, p2) => Self::CurveTo(p0.into(), p1.into(), p2.into()), + Close => Self::ClosePath, + } + } + } +} From e600bdbbe47512fb59eb2e51b6b1ab4ca088d4cb Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 18 May 2022 16:23:17 -0400 Subject: [PATCH 2/7] Remove PlusDarker composition mode Reassigns value 13 to PlusLighter to match the upcoming blend fixes --- piet-scene/src/scene/blend.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/piet-scene/src/scene/blend.rs b/piet-scene/src/scene/blend.rs index 7edc6cd69..09b6e508e 100644 --- a/piet-scene/src/scene/blend.rs +++ b/piet-scene/src/scene/blend.rs @@ -53,8 +53,7 @@ pub enum Compose { DestAtop = 10, Xor = 11, Plus = 12, - PlusDarker = 13, - PlusLighter = 14, + PlusLighter = 13, } /// Blend mode consisting of mixing and composition functions. From a20dd43b398aff592e954433563659bc39f6899c Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 18 May 2022 16:26:31 -0400 Subject: [PATCH 3/7] Updates to scene/fragment builder * Add impl Into for pushing transforms. * Small QOL API changes to Scene and Fragment. * Add some missing docs. --- piet-scene/src/scene/builder.rs | 7 ++++--- piet-scene/src/scene/mod.rs | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/piet-scene/src/scene/builder.rs b/piet-scene/src/scene/builder.rs index 85d75b22f..39abc938f 100644 --- a/piet-scene/src/scene/builder.rs +++ b/piet-scene/src/scene/builder.rs @@ -24,8 +24,8 @@ use core::borrow::Borrow; const MAX_BLEND_STACK: usize = 256; /// Creates a new builder for constructing a scene. -pub fn build_scene<'a>(scene: &'a mut Scene, resources: &'a mut ResourceContext) -> Builder<'a> { - Builder::new(&mut scene.data, ResourceData::Scene(resources)) +pub fn build_scene<'a>(scene: &'a mut Scene, rcx: &'a mut ResourceContext) -> Builder<'a> { + Builder::new(&mut scene.data, ResourceData::Scene(rcx)) } /// Creates a new builder for construction a scene fragment. @@ -62,7 +62,8 @@ impl<'a> Builder<'a> { } /// Pushes a transform matrix onto the stack. - pub fn push_transform(&mut self, transform: Affine) { + pub fn push_transform(&mut self, transform: impl Into) { + let transform = transform.into(); self.transform(transform); self.transforms.push(transform); } diff --git a/piet-scene/src/scene/mod.rs b/piet-scene/src/scene/mod.rs index 9f7be2f6d..abbc6d93f 100644 --- a/piet-scene/src/scene/mod.rs +++ b/piet-scene/src/scene/mod.rs @@ -23,11 +23,13 @@ pub use builder::{build_fragment, build_scene, Builder}; pub use style::*; use super::brush::*; -use super::geometry::{Affine, Point, Rect}; +use super::geometry::{Affine, Point}; use super::path::Element; +use super::resource::ResourceContext; use core::ops::Range; +/// Raw data streams describing an encoded scene. #[derive(Default)] pub struct SceneData { pub transform_stream: Vec, @@ -83,6 +85,13 @@ pub struct Scene { } impl Scene { + /// Creates a new builder for filling the scene. Any current content in + /// the scene is cleared. + pub fn build<'a>(&'a mut self, rcx: &'a mut ResourceContext) -> Builder<'a> { + build_scene(self, rcx) + } + + /// Returns the raw encoded scene data streams. pub fn data(&self) -> &SceneData { &self.data } @@ -96,9 +105,17 @@ pub struct Fragment { } impl Fragment { + /// Returns the underlying stream of points that defined all encoded path + /// segments. pub fn points(&self) -> &[Point] { bytemuck::cast_slice(&self.data.pathseg_stream) } + + /// Creates a new builder for filling the fragment. Any current content in + /// the fragment is cleared. + pub fn build<'a>(&'a mut self) -> Builder<'a> { + build_fragment(self) + } } #[derive(Default)] From 938d6fc052bbe59295039ff4d6931f0d4ec94576 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Thu, 19 May 2022 16:59:14 -0400 Subject: [PATCH 4/7] Add clip mode for blends This matches the changes in the fix_blends PR. --- piet-scene/src/scene/blend.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/piet-scene/src/scene/blend.rs b/piet-scene/src/scene/blend.rs index 09b6e508e..d6aa080d4 100644 --- a/piet-scene/src/scene/blend.rs +++ b/piet-scene/src/scene/blend.rs @@ -34,6 +34,8 @@ pub enum Mix { Saturation = 13, Color = 14, Luminosity = 15, + // Clip is the same as normal, but doesn't always push a blend group. + Clip = 128, } /// Defines the layer composition function for a blend operation. @@ -76,7 +78,7 @@ impl Blend { impl Default for Blend { fn default() -> Self { Self { - mix: Mix::Normal, + mix: Mix::Clip, compose: Compose::SrcOver, } } From 39b773c611f61e9ad548361970949f717f13ebfa Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Thu, 19 May 2022 18:04:00 -0400 Subject: [PATCH 5/7] Replace lossy conversions with methods --- piet-scene/src/lib.rs | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/piet-scene/src/lib.rs b/piet-scene/src/lib.rs index 4f8da3dbd..8501d3311 100644 --- a/piet-scene/src/lib.rs +++ b/piet-scene/src/lib.rs @@ -28,9 +28,10 @@ mod kurbo_conv { use super::geometry::{Affine, Point, Rect}; use super::path::Element; - impl From for Point { - fn from(p: kurbo::Point) -> Self { - Self::new(p.x as f32, p.y as f32) + impl Point { + /// Creates a new point from the equivalent kurbo type. + pub fn from_kurbo(point: kurbo::Point) -> Self { + Self::new(point.x as f32, point.y as f32) } } @@ -40,9 +41,10 @@ mod kurbo_conv { } } - impl From for Affine { - fn from(a: kurbo::Affine) -> Self { - let c = a.as_coeffs(); + impl Affine { + /// Creates a new affine transformation from the equivalent kurbo type. + pub fn from_kurbo(affine: kurbo::Affine) -> Self { + let c = affine.as_coeffs(); Self { xx: c[0] as f32, yx: c[1] as f32, @@ -67,11 +69,12 @@ mod kurbo_conv { } } - impl From for Rect { - fn from(r: kurbo::Rect) -> Self { + impl Rect { + /// Creates a new rectangle from the equivalent kurbo type. + pub fn from_kurbo(rect: kurbo::Rect) -> Self { Self { - min: Point::new(r.x0 as f32, r.y0 as f32), - max: Point::new(r.x1 as f32, r.y1 as f32), + min: Point::new(rect.x0 as f32, rect.y0 as f32), + max: Point::new(rect.x1 as f32, rect.y1 as f32), } } } @@ -100,6 +103,23 @@ mod kurbo_conv { } } + impl Element { + /// Creates a new path element from the equivalent kurbo type. + pub fn from_kurbo(el: kurbo::PathEl) -> Self { + use kurbo::PathEl::*; + use Point::from_kurbo; + match e { + MoveTo(p0) => Self::MoveTo(from_kurbo(p0)), + LineTo(p0) => Self::LineTo(from_kurbo(p0)), + QuadTo(p0, p1) => Self::QuadTo(from_kurbo(p0), from_kurbo(p1)), + CurveTo(p0, p1, p2) => { + Self::CurveTo(from_kurbo(p0), from_kurbo(p1), from_kurbo(p2)) + } + ClosePath => Self::Close, + } + } + } + impl From for kurbo::PathEl { fn from(e: Element) -> Self { use Element::*; From d30750e8a74a0f88c20081bed2347bcd2c606b07 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Thu, 19 May 2022 18:07:07 -0400 Subject: [PATCH 6/7] Remove poorly named functions Moves the more descriptive comments to the free functions. --- piet-scene/src/scene/builder.rs | 9 +++++---- piet-scene/src/scene/mod.rs | 13 ------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/piet-scene/src/scene/builder.rs b/piet-scene/src/scene/builder.rs index 39abc938f..8aa1bf52b 100644 --- a/piet-scene/src/scene/builder.rs +++ b/piet-scene/src/scene/builder.rs @@ -23,12 +23,14 @@ use core::borrow::Borrow; const MAX_BLEND_STACK: usize = 256; -/// Creates a new builder for constructing a scene. +/// Creates a new builder for filling a scene. Any current content in the scene +/// will be cleared. pub fn build_scene<'a>(scene: &'a mut Scene, rcx: &'a mut ResourceContext) -> Builder<'a> { Builder::new(&mut scene.data, ResourceData::Scene(rcx)) } -/// Creates a new builder for construction a scene fragment. +/// Creates a new builder for filling a scene fragment. Any current content in +/// the fragment will be cleared. pub fn build_fragment<'a>(fragment: &'a mut Fragment) -> Builder<'a> { Builder::new( &mut fragment.data, @@ -62,8 +64,7 @@ impl<'a> Builder<'a> { } /// Pushes a transform matrix onto the stack. - pub fn push_transform(&mut self, transform: impl Into) { - let transform = transform.into(); + pub fn push_transform(&mut self, transform: Affine) { self.transform(transform); self.transforms.push(transform); } diff --git a/piet-scene/src/scene/mod.rs b/piet-scene/src/scene/mod.rs index abbc6d93f..577f81eb4 100644 --- a/piet-scene/src/scene/mod.rs +++ b/piet-scene/src/scene/mod.rs @@ -25,7 +25,6 @@ pub use style::*; use super::brush::*; use super::geometry::{Affine, Point}; use super::path::Element; -use super::resource::ResourceContext; use core::ops::Range; @@ -85,12 +84,6 @@ pub struct Scene { } impl Scene { - /// Creates a new builder for filling the scene. Any current content in - /// the scene is cleared. - pub fn build<'a>(&'a mut self, rcx: &'a mut ResourceContext) -> Builder<'a> { - build_scene(self, rcx) - } - /// Returns the raw encoded scene data streams. pub fn data(&self) -> &SceneData { &self.data @@ -110,12 +103,6 @@ impl Fragment { pub fn points(&self) -> &[Point] { bytemuck::cast_slice(&self.data.pathseg_stream) } - - /// Creates a new builder for filling the fragment. Any current content in - /// the fragment is cleared. - pub fn build<'a>(&'a mut self) -> Builder<'a> { - build_fragment(self) - } } #[derive(Default)] From 5252a33c5da8a8c2ff7d3eb4553253b71b84a758 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Thu, 19 May 2022 18:16:30 -0400 Subject: [PATCH 7/7] Oops. Delete one remaining lossy conversion --- piet-scene/src/lib.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/piet-scene/src/lib.rs b/piet-scene/src/lib.rs index 8501d3311..8f436b20c 100644 --- a/piet-scene/src/lib.rs +++ b/piet-scene/src/lib.rs @@ -90,19 +90,6 @@ mod kurbo_conv { } } - impl From for Element { - fn from(e: kurbo::PathEl) -> Self { - use kurbo::PathEl::*; - match e { - MoveTo(p0) => Self::MoveTo(p0.into()), - LineTo(p0) => Self::LineTo(p0.into()), - QuadTo(p0, p1) => Self::QuadTo(p0.into(), p1.into()), - CurveTo(p0, p1, p2) => Self::CurveTo(p0.into(), p1.into(), p2.into()), - ClosePath => Self::Close, - } - } - } - impl Element { /// Creates a new path element from the equivalent kurbo type. pub fn from_kurbo(el: kurbo::PathEl) -> Self {