diff --git a/Cargo.lock b/Cargo.lock index 2b764228..e5472d43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1987,6 +1987,7 @@ name = "scenes" version = "0.0.0" dependencies = [ "anyhow", + "bytemuck", "clap", "getrandom", "image", diff --git a/examples/scenes/Cargo.toml b/examples/scenes/Cargo.toml index 36c6688f..d9976ea2 100644 --- a/examples/scenes/Cargo.toml +++ b/examples/scenes/Cargo.toml @@ -19,6 +19,7 @@ rand = "0.8.5" # for pico_svg roxmltree = "0.20.0" +bytemuck.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] web-time = { workspace = true } diff --git a/examples/scenes/src/simple_text.rs b/examples/scenes/src/simple_text.rs index a6ce59a0..2c062f6f 100644 --- a/examples/scenes/src/simple_text.rs +++ b/examples/scenes/src/simple_text.rs @@ -3,7 +3,6 @@ use std::sync::Arc; -use skrifa::prelude::NormalizedCoord; use skrifa::{ raw::{FileRef, FontRef}, MetadataProvider, @@ -161,13 +160,7 @@ impl SimpleText { .font_size(size) .transform(transform) .glyph_transform(glyph_transform) - .normalized_coords( - var_loc - .coords() - .iter() - .copied() - .map(NormalizedCoord::to_bits), - ) + .normalized_coords(bytemuck::cast_slice(var_loc.coords())) .brush(brush) .hint(false) .draw( diff --git a/vello/src/lib.rs b/vello/src/lib.rs index 0c199dd2..71d36537 100644 --- a/vello/src/lib.rs +++ b/vello/src/lib.rs @@ -152,7 +152,7 @@ pub use peniko::kurbo; pub use wgpu; pub use scene::{DrawGlyphs, Scene}; -pub use vello_encoding::Glyph; +pub use vello_encoding::{Glyph, NormalizedCoord}; use low_level::ShaderId; #[cfg(feature = "wgpu")] diff --git a/vello/src/scene.rs b/vello/src/scene.rs index 5e75e67f..2a144528 100644 --- a/vello/src/scene.rs +++ b/vello/src/scene.rs @@ -14,7 +14,7 @@ use peniko::{ use png::{BitDepth, ColorType, Transformations}; use skrifa::{ color::{ColorGlyph, ColorPainter}, - instance::{LocationRef, NormalizedCoord}, + instance::LocationRef, outline::{DrawSettings, OutlinePen}, prelude::Size, raw::{tables::cpal::Cpal, TableProvider}, @@ -22,7 +22,7 @@ use skrifa::{ }; #[cfg(feature = "bump_estimate")] use vello_encoding::BumpAllocatorMemory; -use vello_encoding::{Encoding, Glyph, GlyphRun, Patch, Transform}; +use vello_encoding::{Encoding, Glyph, GlyphRun, NormalizedCoord, Patch, Transform}; // TODO - Document invariants and edge cases (#470) // - What happens when we pass a transform matrix with NaN values to the Scene? @@ -406,7 +406,7 @@ impl<'a> DrawGlyphs<'a> { /// Sets the normalized design space coordinates for a variable font instance. #[must_use] - pub fn normalized_coords(mut self, coords: impl Iterator) -> Self { + pub fn normalized_coords(mut self, coords: &[NormalizedCoord]) -> Self { self.scene .encoding .resources @@ -416,7 +416,7 @@ impl<'a> DrawGlyphs<'a> { .encoding .resources .normalized_coords - .extend(coords.map(NormalizedCoord::from_bits)); + .extend(coords); self.run.normalized_coords.end = self.scene.encoding.resources.normalized_coords.len(); self } @@ -508,10 +508,11 @@ impl<'a> DrawGlyphs<'a> { let mut final_glyph = None; let mut outline_count = 0; // We copy out of the variable font coords here because we need to call an exclusive self method - let coords = &self.scene.encoding.resources.normalized_coords - [self.run.normalized_coords.clone()] + let coords = bytemuck::cast_slice::<_, skrifa::instance::NormalizedCoord>( + &self.scene.encoding.resources.normalized_coords[self.run.normalized_coords.clone()], + ) .to_vec(); - let location = LocationRef::new(coords); + let location = LocationRef::new(&coords); loop { let ppem = self.run.font_size; let outline_glyphs = (&mut glyphs).take_while(|glyph| { diff --git a/vello_encoding/src/encoding.rs b/vello_encoding/src/encoding.rs index d581acd4..4e7f8029 100644 --- a/vello_encoding/src/encoding.rs +++ b/vello_encoding/src/encoding.rs @@ -3,13 +3,13 @@ use super::{ DrawBlurRoundedRect, DrawColor, DrawImage, DrawLinearGradient, DrawRadialGradient, - DrawSweepGradient, DrawTag, Glyph, GlyphRun, Patch, PathEncoder, PathTag, Style, Transform, + DrawSweepGradient, DrawTag, Glyph, GlyphRun, NormalizedCoord, Patch, PathEncoder, PathTag, + Style, Transform, }; use peniko::color::{palette, DynamicColor}; use peniko::kurbo::{Shape, Stroke}; use peniko::{BlendMode, BrushRef, ColorStop, Extend, Fill, GradientKind, Image}; -use skrifa::instance::NormalizedCoord; /// Encoded data streams for a scene. /// diff --git a/vello_encoding/src/lib.rs b/vello_encoding/src/lib.rs index 0c63b1f5..cb17c8d2 100644 --- a/vello_encoding/src/lib.rs +++ b/vello_encoding/src/lib.rs @@ -76,3 +76,21 @@ pub use resolve::{resolve_solid_paths_only, Layout, Patch, Resolver}; #[cfg(feature = "bump_estimate")] pub use estimate::BumpEstimator; + +/// A normalized variation coordinate (for variable fonts) in 2.14 fixed point format. +/// +/// In most cases, this can be [cast](bytemuck::cast_slice) from the +/// normalised coords provided by your text layout library. +/// +/// Equivalent to [`skrifa::instance::NormalizedCoord`], but defined +/// in Vello so that Skrifa is not part of Vello's public API. +/// This allows Vello to update its Skrifa in a patch release, and limits +/// the need for updates only to align Skrifa versions. +pub type NormalizedCoord = i16; + +#[cfg(test)] +mod tests { + const _NORMALISED_COORD_SIZE_MATCHES: () = assert!( + size_of::() == size_of::() + ); +} diff --git a/vello_encoding/src/resolve.rs b/vello_encoding/src/resolve.rs index 44c03e3f..78249355 100644 --- a/vello_encoding/src/resolve.rs +++ b/vello_encoding/src/resolve.rs @@ -422,10 +422,13 @@ impl Resolver { hint = false; } } - let Some(mut session) = self - .glyph_cache - .session(&run.font, coords, font_size, hint, &run.style) - else { + let Some(mut session) = self.glyph_cache.session( + &run.font, + bytemuck::cast_slice(coords), + font_size, + hint, + &run.style, + ) else { continue; }; let glyph_start = self.glyphs.len();