From 70870a6a695b49c9967452dd9f35f549c7bf2084 Mon Sep 17 00:00:00 2001 From: Kaylee Simmons Date: Fri, 20 Sep 2024 01:13:00 -0700 Subject: [PATCH 1/5] Change Quad interface and take layout as reference when adding to a scene. --- src/lib.rs | 2 + src/prelude.rs | 6 + src/scene.rs | 4 +- src/scene/layer.rs | 7 +- src/scene/path.rs | 5 + src/scene/quad.rs | 14 +- src/test.rs | 497 ++---------------- ...parley_line_breaking_and_font_fallback.png | Bin 27505 -> 27031 bytes 8 files changed, 55 insertions(+), 480 deletions(-) create mode 100644 src/prelude.rs diff --git a/src/lib.rs b/src/lib.rs index 744298b..fc063a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ mod drawable; mod drawable_pipeline; mod drawable_reference; mod offscreen_renderer; +pub mod prelude; mod renderer; mod scene; mod shader; @@ -15,6 +16,7 @@ mod test; pub use glamour; pub use palette; pub use parley; +pub use winit; pub use offscreen_renderer::OffscreenRenderer; pub use renderer::Renderer; diff --git a/src/prelude.rs b/src/prelude.rs new file mode 100644 index 0000000..28c371f --- /dev/null +++ b/src/prelude.rs @@ -0,0 +1,6 @@ +pub use crate::offscreen_renderer::OffscreenRenderer; +pub use crate::renderer::Renderer; +pub use crate::scene::*; +pub use crate::shader::*; +pub use crate::shaper::Shaper; +pub use crate::winit_renderer::WinitRenderer; diff --git a/src/scene.rs b/src/scene.rs index 21a086b..f4dc826 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -121,13 +121,13 @@ impl Scene { self } - pub fn add_text_layout(&mut self, layout: Layout, top_left: Point2) { + pub fn add_text_layout(&mut self, layout: &Layout, top_left: Point2) { self.update_layer(|resources, layer| { layer.add_text_layout(resources, layout, top_left); }); } - pub fn with_text_layout(mut self, layout: Layout, top_left: Point2) -> Self { + pub fn with_text_layout(mut self, layout: &Layout, top_left: Point2) -> Self { self.add_text_layout(layout, top_left); self } diff --git a/src/scene/layer.rs b/src/scene/layer.rs index df500b0..abcce1b 100644 --- a/src/scene/layer.rs +++ b/src/scene/layer.rs @@ -63,8 +63,7 @@ impl Layer { pub fn add_clear(&mut self, color: Srgba) { self.add_quad(Quad::new( - point2!(0.0, 0.0), - size2!(f32::MAX / 2., f32::MAX / 2.), + Rect::new(point2!(0.0, 0.0), size2!(f32::MAX / 2., f32::MAX / 2.)), color, )); } @@ -163,7 +162,7 @@ impl Layer { pub fn add_text_layout( &mut self, resources: &mut Resources, - layout: Layout, + layout: &Layout, position: Point2, ) { for line in layout.lines() { @@ -208,7 +207,7 @@ impl Layer { pub fn with_text_layout( mut self, resources: &mut Resources, - layout: Layout, + layout: &Layout, position: Point2, ) -> Self { self.add_text_layout(resources, layout, position); diff --git a/src/scene/path.rs b/src/scene/path.rs index 34a2520..827b987 100644 --- a/src/scene/path.rs +++ b/src/scene/path.rs @@ -52,7 +52,12 @@ impl Path { } } + #[deprecated(note = "Use new_line_instead")] pub fn new_open_stroke(width: f32, color: Srgba, start: Point2) -> Self { + Self::new_line(width, color, start) + } + + pub fn new_line(width: f32, color: Srgba, start: Point2) -> Self { Self { fill: None, stroke: Some((width, color)), diff --git a/src/scene/quad.rs b/src/scene/quad.rs index 25051ec..572657c 100644 --- a/src/scene/quad.rs +++ b/src/scene/quad.rs @@ -1,13 +1,12 @@ use crate::default_drawables::InstancedQuad; use glam::Vec4; -use glamour::{AsRaw, Point2, Size2}; +use glamour::{AsRaw, Point2, Rect, Size2}; use palette::Srgba; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Quad { - pub top_left: Point2, - pub size: Size2, + pub region: Rect, pub color: Srgba, #[serde(default)] pub corner_radius: f32, @@ -16,10 +15,9 @@ pub struct Quad { } impl Quad { - pub fn new(top_left: Point2, size: Size2, color: Srgba) -> Self { + pub fn new(region: Rect, color: Srgba) -> Self { Self { - top_left, - size, + region, color, corner_radius: 0.0, edge_blur: 0.0, @@ -38,8 +36,8 @@ impl Quad { pub fn to_instanced(&self) -> InstancedQuad { InstancedQuad { - top_left: *self.top_left.as_raw(), - size: *self.size.as_raw(), + top_left: *self.region.origin.as_raw(), + size: *self.region.size.as_raw(), color: Vec4::from_array(self.color.into_linear().into()), corner_radius: self.corner_radius, edge_blur: self.edge_blur, diff --git a/src/test.rs b/src/test.rs index bfb5c8a..490828e 100644 --- a/src/test.rs +++ b/src/test.rs @@ -98,8 +98,7 @@ fn simple_quad() { Scene::new() .with_clear(Srgba::new(1., 0., 0.5, 1.)) .with_quad(Quad::new( - point2!(10., 10.), - size2!(50., 50.), + Rect::new(point2!(10., 10.), size2!(50., 50.)), Srgba::new(0., 0., 1., 1.), )), ); @@ -120,7 +119,7 @@ fn simple_text() { builder.push_default(&StyleProperty::FontSize(font_size)); }); - scene.add_text_layout(layout, point2!(0., y)); + scene.add_text_layout(&layout, point2!(0., y)); } assert_eq!(scene.resources.fonts.len(), 1); @@ -160,12 +159,12 @@ fn simple_blur() { shaper.push_default(StyleProperty::FontStack(FontStack::Source("monospace"))); shaper.push_default(StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); + let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { + builder.push_default(&StyleProperty::FontSize(15.)); + }); for i in 0..20 { let bottom = 15. * i as f32; - let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { - builder.push_default(&StyleProperty::FontSize(15.)); - }); - scene.add_text_layout(layout, point2!(0., bottom)); + scene.add_text_layout(&layout, point2!(0., bottom)); } for x in 0..3 { @@ -190,8 +189,10 @@ fn simple_blurred_quad() { for y in 0..5 { scene.add_quad( Quad::new( - point2!(15., 15.) + vec2!(x as f32 * 60., y as f32 * 60.), - size2!(50., 50.), + Rect::new( + point2!(15., 15.) + vec2!(x as f32 * 60., y as f32 * 60.), + size2!(50., 50.), + ), Srgba::new(x as f32 / 5., y as f32 / 5., 1., 1.), ) .with_corner_radius(x as f32 * 2.) @@ -216,8 +217,10 @@ fn overlapping_quads() { for (i, color) in colors.into_iter().enumerate() { scene.add_quad(Quad::new( - point2!(10., 10.) + vec2!(i as f32 * 10., i as f32 * 10.), - size2!(50., 50.), + Rect::new( + point2!(10., 10.) + vec2!(i as f32 * 10., i as f32 * 10.), + size2!(50., 50.), + ), color, )); } @@ -246,7 +249,7 @@ fn swash_modern_ligatures() { .collect::>>(), ))); }); - scene.add_text_layout(layout, point2!(5., 5.)); + scene.add_text_layout(&layout, point2!(5., 5.)); assert_no_regressions(200, 30, scene); } @@ -263,11 +266,10 @@ fn text_layout_bounds() { }); scene.add_quad(Quad::new( - point2!(10., 10.), - size2!(layout.width(), layout.height()), + Rect::new(point2!(10., 10.), size2!(layout.width(), layout.height())), Srgba::new(0., 1., 0., 0.5), )); - scene.add_text_layout(layout, point2!(10., 10.)); + scene.add_text_layout(&layout, point2!(10., 10.)); assert_no_regressions(325, 35, scene); } @@ -292,446 +294,7 @@ fn parley_line_breaking_and_font_fallback() { let layout_width = layout.width(); let layout_height = layout.height(); - scene.add_text_layout(layout, point2!(padding, padding)); - - assert_no_regressions( - (layout_width + padding * 2.) as u32, - (layout_height + padding * 2.) as u32, - scene, - ); -} - -#[test] -fn font_styles() { - let mut scene = Scene::new(); - let mut shaper = Shaper::new(); - - let padding = 10.; - #[derive(Debug, PartialEq, Eq)] - struct Expected { - fullname: String, - attributes: Attributes, - synthesis: Synthesis, - } - let lines = vec![ - ( - "FiraCode Normal", - vec![StyleProperty::FontStack(FontStack::Source( - "FiraCode Nerd Font", - ))], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "FiraCode (Native) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "FiraCode Nerd Font Bold".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "FiraCode (Faux) Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 14.0.into(), - }, - }, - ), - ( - "FiraCode Oblique 5 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(5.0))), - ], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 5.0.into(), - }, - }, - ), - ( - "FiraCode Synthetic Stretch Wide (Buggy)", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStretch(FontStretch::EXPANDED), - ], - Expected { - // FIXME: Fontique does not support synthetic stretch - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "ProFontWindows Nerd Font", - vec![StyleProperty::FontStack(FontStack::Source( - "ProFontWindows Nerd Font", - ))], - Expected { - fullname: "ProFontWindows Nerd Font".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "ProFontWindows Nerd Font (Faux) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("ProFontWindows Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "ProFontWindows Nerd Font".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: true, - skew: 0.0.into(), - }, - }, - ), - ( - "CaskaydiaCove Nerd Font Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("CaskaydiaCove Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "CaskaydiaCove NF Italic".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var", - vec![StyleProperty::FontStack(FontStack::Source( - "Monaspace Xenon Var", - ))], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var (Variadic) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![crate::Setting { - tag: WGHT, - value: swash::Weight::BOLD.0.into(), - }], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var (Variadic) Italic (Buggy)", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![ - crate::Setting { - tag: SLNT, - // FIXME: This should be -11 - // See: https://github.com/linebender/parley/issues/94 - value: (14.0).into(), - }, - ], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Oblique -10 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-10.0))), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![ - crate::Setting { - tag: SLNT, - value: (-10.0).into(), - }, - ], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Oblique 5 degreees = no italic", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-5.0))), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![ - crate::Setting { - tag: SLNT, - value: (-5.0).into(), - }, - ], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Stretch=113 Weight = 637, Oblique -8 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontWeight(FontWeight::new(637.0)), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-8.0))), - StyleProperty::FontStretch(FontStretch::from_percentage(113.0)), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![ - crate::Setting { - tag: WDTH, - value: 113.0.into(), - }, - crate::Setting { - tag: WGHT, - value: 637.0.into(), - }, - crate::Setting { - tag: SLNT, - value: (-8.0).into(), - }, - ], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Normal", - vec![StyleProperty::FontStack(FontStack::Source( - "NotoSerif Nerd Font", - ))], - Expected { - fullname: "NotoSerif NF Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "NotoSerif NF Bold".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Condensed", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontStretch(FontStretch::CONDENSED), - ], - Expected { - fullname: "NotoSerif NF Cond Reg".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Bold Condensed", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - StyleProperty::FontStretch(FontStretch::CONDENSED), - ], - Expected { - fullname: "NotoSerif NF Cond Bold".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "NotoSerif NF Italic".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Bold Condensed Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - StyleProperty::FontStretch(FontStretch::CONDENSED), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "NotoSerif NF Cond Bold Italic".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ]; - let layout = shaper.layout_within_with( - &lines - .iter() - .map(|line| line.0) - .collect::>() - .join("\n"), - 800., - |builder| { - builder.push_default(&StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); - builder.push_default(&StyleProperty::FontSize(16.)); - let mut start = 0; - for line in &lines { - let line_len = line.0.len(); - let range = start..start + line_len; - for prop in &line.1 { - builder.push(prop, range.clone()); - } - start += line_len + 1; - } - }, - ); - - let layout_width = layout.width(); - let layout_height = layout.height(); - scene.add_text_layout(layout, point2!(padding, padding)); - - let current_layer = scene.layer(); - assert_eq!( - current_layer - .contents - .primitives - .last() - .unwrap() - .as_glyph_run_vec() - .unwrap() - .len(), - lines.len() - ); - for (index, line) in lines.iter().enumerate() { - let glyph_runs = current_layer - .contents - .primitives - .last() - .unwrap() - .as_glyph_run_vec() - .unwrap(); - let glyph_run = &glyph_runs[index]; - let font = scene.resources.fonts.get(&glyph_run.font_id).unwrap(); - let font_ref = font.as_swash_font_ref(glyph_run.font_index).unwrap(); - let fullname = font_ref - .localized_strings() - .find_by_id(swash::StringId::Full, None) - .map_or("".into(), |str| str.chars().collect::()); - let attributes = font_ref.attributes(); - let synthesis = glyph_run.synthesis.clone(); - let actual = Expected { - fullname, - attributes, - synthesis, - }; - assert_eq!(line.2, actual, "line number {index}"); - } + scene.add_text_layout(&layout, point2!(padding, padding)); assert_no_regressions( (layout_width + padding * 2.) as u32, @@ -754,8 +317,10 @@ fn complex_mask_clips_properly() { for (i, color) in colors.into_iter().enumerate() { scene.add_quad(Quad::new( - point2!(10., 10.) + vec2!(i as f32 * 20., i as f32 * 20.), - size2!(100., 100.), + Rect::new( + point2!(10., 10.) + vec2!(i as f32 * 20., i as f32 * 20.), + size2!(100., 100.), + ), color, )); } @@ -765,12 +330,12 @@ fn complex_mask_clips_properly() { shaper.push_default(StyleProperty::FontStack(FontStack::Source("monospace"))); shaper.push_default(StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); + let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { + builder.push_default(&StyleProperty::FontSize(20.)); + }); for i in 0..20 { let bottom = 20. * i as f32; - let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { - builder.push_default(&StyleProperty::FontSize(20.)); - }); - mask_layer.add_text_layout(&mut scene.resources, layout, point2!(0., bottom)); + mask_layer.add_text_layout(&mut scene.resources, &layout, point2!(0., bottom)); } scene.set_mask(mask_layer); @@ -809,7 +374,7 @@ fn open_paths() { for i in 0..10 { scene.add_path( - Path::new_open_stroke(5., Srgba::new(0., 0., 0., 1.), point2!(20., 20.)) + Path::new_line(5., Srgba::new(0., 0., 0., 1.), point2!(20., 20.)) .with_quadratic_bezier_to(point2!(20. + i as f32 * 30., 100.), point2!(20., 180.)), ); } @@ -824,12 +389,12 @@ fn simple_mask() { shaper.push_default(StyleProperty::FontStack(FontStack::Source("monospace"))); shaper.push_default(StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); + let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { + builder.push_default(&StyleProperty::FontSize(15.)); + }); for i in 0..20 { let bottom = 15. * i as f32; - let layout = shaper.layout_with("TestTestTestTestTestTestTestTest", |builder| { - builder.push_default(&StyleProperty::FontSize(15.)); - }); - scene.add_text_layout(layout, point2!(0., bottom)); + scene.add_text_layout(&layout, point2!(0., bottom)); } // Triangle path to mask diff --git a/test_data/Kaylee Simmons/parley_line_breaking_and_font_fallback.png b/test_data/Kaylee Simmons/parley_line_breaking_and_font_fallback.png index c7b06fadb16f86d9653cf3f743491f29cfe99eec..d4dddad45a51fbc84d59ee14dcbb102144f345aa 100644 GIT binary patch literal 27031 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 From 859885db108e6a6e5d5a19cbf49fb223db218bb7 Mon Sep 17 00:00:00 2001 From: Kaylee Simmons Date: Fri, 20 Sep 2024 02:35:33 -0700 Subject: [PATCH 2/5] Move font_styles to its own file and add font installation instructions for windows --- README.md | 12 ++ src/test.rs | 16 +- src/test/font_styles.rs | 440 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 457 insertions(+), 11 deletions(-) create mode 100644 src/test/font_styles.rs diff --git a/README.md b/README.md index 4dba237..d518111 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,15 @@ effort: 4. Where possible, features of the renderer should be regression tested to ensure that changes do not change the quality of the rendering unless explicitly intended. + +## Dependencies + +The tests require the nerd fonts to be installed. Run the +following: + +### Windows +```powershell +scoop bucket add extras +scoop bucket add nerd-fonts +scoop install Monaspace-NF FiraCode-NF ProFont-NF CascadiaCode-NF Noto-NF +``` diff --git a/src/test.rs b/src/test.rs index 490828e..9d247d8 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,3 +1,5 @@ +mod font_styles; + use std::{env::temp_dir, fs::create_dir_all, path::PathBuf, thread}; use git2::Repository; @@ -6,23 +8,15 @@ use image::ImageReader; use lazy_static::lazy_static; use palette::Srgba; use parley::{ - style::{ - FontFamily, FontSettings, FontStack, FontStretch, FontStyle, FontWeight, StyleProperty, - }, - swash, - swash::{tag_from_bytes, Attributes, Setting, Stretch, Style, Tag, Weight}, + style::{FontFamily, FontSettings, FontStack, FontWeight, StyleProperty}, + swash::Setting, }; use rust_embed::RustEmbed; use crate::{ - offscreen_renderer::OffscreenRenderer, scene::Scene, scene::Synthesis, Layer, Path, Quad, - Shaper, Sprite, Texture, + offscreen_renderer::OffscreenRenderer, scene::Scene, Layer, Path, Quad, Shaper, Sprite, Texture, }; -const WGHT: Tag = tag_from_bytes(b"wght"); -const WDTH: Tag = tag_from_bytes(b"wdth"); -const SLNT: Tag = tag_from_bytes(b"slnt"); - #[derive(RustEmbed)] #[folder = "test_data/assets"] struct Assets; diff --git a/src/test/font_styles.rs b/src/test/font_styles.rs new file mode 100644 index 0000000..4daa164 --- /dev/null +++ b/src/test/font_styles.rs @@ -0,0 +1,440 @@ +use glamour::point2; +use palette::Srgba; +use parley::{ + style::{FontStack, FontStretch, FontStyle, FontWeight, StyleProperty}, + swash, + swash::{tag_from_bytes, Attributes, Setting, Stretch, Style, Tag, Weight}, +}; + +use crate::{scene::Scene, scene::Synthesis, Shaper}; + +const WGHT: Tag = tag_from_bytes(b"wght"); +const WDTH: Tag = tag_from_bytes(b"wdth"); +const SLNT: Tag = tag_from_bytes(b"slnt"); + +#[test] +fn font_styles() { + let mut scene = Scene::new(); + let mut shaper = Shaper::new(); + + let padding = 10.; + #[derive(Debug, PartialEq, Eq)] + struct Expected { + fullname: String, + attributes: Attributes, + synthesis: Synthesis, + } + let lines = vec![ + ( + "FiraCode Normal", + vec![StyleProperty::FontStack(FontStack::Source( + "FiraCode Nerd Font", + ))], + Expected { + fullname: "FiraCode Nerd Font Reg".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "FiraCode (Native) Bold", + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + Expected { + fullname: "FiraCode Nerd Font Bold".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "FiraCode (Faux) Italic", + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + Expected { + fullname: "FiraCode Nerd Font Reg".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 14.0.into(), + }, + }, + ), + ( + "FiraCode Oblique 5 degrees", + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(5.0))), + ], + Expected { + fullname: "FiraCode Nerd Font Reg".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 5.0.into(), + }, + }, + ), + ( + "FiraCode Synthetic Stretch Wide (Buggy)", + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStretch(FontStretch::EXPANDED), + ], + Expected { + // FIXME: Fontique does not support synthetic stretch + fullname: "FiraCode Nerd Font Reg".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "ProFontWindows Nerd Font", + vec![StyleProperty::FontStack(FontStack::Source( + "ProFontWindows Nerd Font", + ))], + Expected { + fullname: "ProFontWindows Nerd Font".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "ProFontWindows Nerd Font (Faux) Bold", + vec![ + StyleProperty::FontStack(FontStack::Source("ProFontWindows Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + Expected { + fullname: "ProFontWindows Nerd Font".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: true, + skew: 0.0.into(), + }, + }, + ), + ( + "CaskaydiaCove Nerd Font Italic", + vec![ + StyleProperty::FontStack(FontStack::Source("CaskaydiaCove Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + Expected { + fullname: "CaskaydiaCove NF Italic".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var", + vec![StyleProperty::FontStack(FontStack::Source( + "Monaspace Xenon Var", + ))], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var (Variadic) Bold", + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![crate::Setting { + tag: WGHT, + value: swash::Weight::BOLD.0.into(), + }], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var (Variadic) Italic (Buggy)", + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + // FIXME: This should be -11 + // See: https://github.com/linebender/parley/issues/94 + value: (14.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var Oblique -10 degrees", + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-10.0))), + ], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + value: (-10.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var Oblique 5 degreees = no italic", + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-5.0))), + ], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + value: (-5.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Monaspace Xenon Var Stretch=113 Weight = 637, Oblique -8 degrees", + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontWeight(FontWeight::new(637.0)), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-8.0))), + StyleProperty::FontStretch(FontStretch::from_percentage(113.0)), + ], + Expected { + fullname: "Monaspace Xenon Var Regular".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![ + crate::Setting { + tag: WDTH, + value: 113.0.into(), + }, + crate::Setting { + tag: WGHT, + value: 637.0.into(), + }, + crate::Setting { + tag: SLNT, + value: (-8.0).into(), + }, + ], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Normal", + vec![StyleProperty::FontStack(FontStack::Source( + "NotoSerif Nerd Font", + ))], + Expected { + fullname: "NotoSerif NF Reg".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Bold", + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + Expected { + fullname: "NotoSerif NF Bold".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Condensed", + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontStretch(FontStretch::CONDENSED), + ], + Expected { + fullname: "NotoSerif NF Cond Reg".into(), + attributes: Attributes::new(Stretch::CONDENSED, Weight::NORMAL, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Bold Condensed", + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + StyleProperty::FontStretch(FontStretch::CONDENSED), + ], + Expected { + fullname: "NotoSerif NF Cond Bold".into(), + attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Normal), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Italic", + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + Expected { + fullname: "NotoSerif NF Italic".into(), + attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ( + "Noto Serif Bold Condensed Italic", + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + StyleProperty::FontStretch(FontStretch::CONDENSED), + StyleProperty::FontStyle(FontStyle::Italic), + ], + Expected { + fullname: "NotoSerif NF Cond Bold Italic".into(), + attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Italic), + synthesis: Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + }, + ), + ]; + let layout = shaper.layout_within_with( + &lines + .iter() + .map(|line| line.0) + .collect::>() + .join("\n"), + 800., + |builder| { + builder.push_default(&StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); + builder.push_default(&StyleProperty::FontSize(16.)); + let mut start = 0; + for line in &lines { + let line_len = line.0.len(); + let range = start..start + line_len; + for prop in &line.1 { + builder.push(prop, range.clone()); + } + start += line_len + 1; + } + }, + ); + + let layout_width = layout.width(); + let layout_height = layout.height(); + scene.add_text_layout(&layout, point2!(padding, padding)); + + let current_layer = scene.layer(); + assert_eq!( + current_layer + .contents + .primitives + .last() + .unwrap() + .as_glyph_run_vec() + .unwrap() + .len(), + lines.len() + ); + for (index, line) in lines.iter().enumerate() { + let glyph_runs = current_layer + .contents + .primitives + .last() + .unwrap() + .as_glyph_run_vec() + .unwrap(); + let glyph_run = &glyph_runs[index]; + let font = scene.resources.fonts.get(&glyph_run.font_id).unwrap(); + let font_ref = font.as_swash_font_ref(glyph_run.font_index).unwrap(); + let fullname = font_ref + .localized_strings() + .find_by_id(swash::StringId::Full, None) + .map_or("".into(), |str| str.chars().collect::()); + let attributes = font_ref.attributes(); + let synthesis = glyph_run.synthesis.clone(); + let actual = Expected { + fullname, + attributes, + synthesis, + }; + assert_eq!(line.2, actual, "line number {index}"); + } +} From 6f006338ceaca546fa03e903e917e69ebb6c11de Mon Sep 17 00:00:00 2001 From: Kaylee Simmons Date: Fri, 20 Sep 2024 02:39:43 -0700 Subject: [PATCH 3/5] Ignore font_styles test for now --- src/test/font_styles.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/font_styles.rs b/src/test/font_styles.rs index 4daa164..ec2197c 100644 --- a/src/test/font_styles.rs +++ b/src/test/font_styles.rs @@ -13,6 +13,7 @@ const WDTH: Tag = tag_from_bytes(b"wdth"); const SLNT: Tag = tag_from_bytes(b"slnt"); #[test] +#[ignore = "Fails to load CaskaydiaCove Italic correctly on windows"] fn font_styles() { let mut scene = Scene::new(); let mut shaper = Shaper::new(); From 1ea5782b9ae271653ef34dd1e9b2af585c3e2575 Mon Sep 17 00:00:00 2001 From: Kaylee Simmons Date: Fri, 20 Sep 2024 14:35:00 -0700 Subject: [PATCH 4/5] Add install instructions for mac and linux --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index d518111..85f4db9 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,30 @@ scoop bucket add extras scoop bucket add nerd-fonts scoop install Monaspace-NF FiraCode-NF ProFont-NF CascadiaCode-NF Noto-NF ``` + +### Mac +```bash +brew install font-monaspace font-fira-code-nerd-font font-profont-nerd-font font-caskaydia-cove-nerd-font font-monaspace-nerd-font font-noto-nerd-font +``` +### Linux +```bash +FONT_DIR="${HOME}/.local/share/fonts" +mkdir -p "$FONT_DIR" + +for font in ${{ env.FONTS }}; do + ZIP_FILE="${font}${EXTENSION}" + if [[ "$font" == "Monaspace" ]]; then + DOWNLOAD_URL="https://github.com/githubnext/monaspace/releases/download/v1.101/monaspace-v1.101.zip" + else + DOWNLOAD_URL="https://github.com/ryanoasis/nerd-fonts/releases/download/${VERSION}/${ZIP_FILE}" + fi + echo "Downloading and installing '$font'..." + wget --quiet "$DOWNLOAD_URL" -O "$ZIP_FILE" + unzip -oq "$ZIP_FILE" -d "$FONT_DIR" + rm "$ZIP_FILE" + echo "'$font' installed successfully." +done + +# Refresh font cache +fc-cache -fv +``` From 84a8c5f4d655dfc02a90b258784279752044ada4 Mon Sep 17 00:00:00 2001 From: Kaylee Simmons Date: Fri, 20 Sep 2024 18:44:00 -0700 Subject: [PATCH 5/5] Update font_style tests to run individually using a helper function --- src/test/font_styles.rs | 832 +++++++++--------- .../Kaylee Simmons/firacode_faux_italic.png | Bin 0 -> 5148 bytes .../Kaylee Simmons/firacode_native_bold.png | Bin 0 -> 4918 bytes test_data/Kaylee Simmons/firacode_normal.png | Bin 0 -> 3023 bytes .../firacode_oblique_5_degrees.png | Bin 0 -> 6164 bytes .../firacode_synthetic_stretch_wide.png | Bin 0 -> 6028 bytes .../Kaylee Simmons/monaspace_xenon_var.png | Bin 0 -> 4764 bytes ..._xenon_var_oblique_5_degrees_no_italic.png | Bin 0 -> 11412 bytes ...ace_xenon_var_oblique_minus_10_degrees.png | Bin 0 -> 9838 bytes ...113_weight_637_oblique_minus_8_degrees.png | Bin 0 -> 18610 bytes .../monaspace_xenon_var_variadic_bold.png | Bin 0 -> 9521 bytes ...aspace_xenon_var_variadic_italic_buggy.png | Bin 0 -> 8249 bytes .../profontwindows_nerd_font_faux_bold.png | Bin 0 -> 4680 bytes 13 files changed, 418 insertions(+), 414 deletions(-) create mode 100644 test_data/Kaylee Simmons/firacode_faux_italic.png create mode 100644 test_data/Kaylee Simmons/firacode_native_bold.png create mode 100644 test_data/Kaylee Simmons/firacode_normal.png create mode 100644 test_data/Kaylee Simmons/firacode_oblique_5_degrees.png create mode 100644 test_data/Kaylee Simmons/firacode_synthetic_stretch_wide.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var_oblique_5_degrees_no_italic.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var_oblique_minus_10_degrees.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var_stretch_113_weight_637_oblique_minus_8_degrees.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var_variadic_bold.png create mode 100644 test_data/Kaylee Simmons/monaspace_xenon_var_variadic_italic_buggy.png create mode 100644 test_data/Kaylee Simmons/profontwindows_nerd_font_faux_bold.png diff --git a/src/test/font_styles.rs b/src/test/font_styles.rs index ec2197c..0c18312 100644 --- a/src/test/font_styles.rs +++ b/src/test/font_styles.rs @@ -3,439 +3,443 @@ use palette::Srgba; use parley::{ style::{FontStack, FontStretch, FontStyle, FontWeight, StyleProperty}, swash, - swash::{tag_from_bytes, Attributes, Setting, Stretch, Style, Tag, Weight}, + swash::{tag_from_bytes, Attributes, Stretch, Style, Tag, Weight}, }; +use super::assert_no_regressions; use crate::{scene::Scene, scene::Synthesis, Shaper}; const WGHT: Tag = tag_from_bytes(b"wght"); const WDTH: Tag = tag_from_bytes(b"wdth"); const SLNT: Tag = tag_from_bytes(b"slnt"); -#[test] -#[ignore = "Fails to load CaskaydiaCove Italic correctly on windows"] -fn font_styles() { +fn assert_attributes( + style_properties: Vec>, + text: &str, + expected_full_name: &'static str, + expected_attributes: Attributes, + expected_synthesis: Synthesis, +) { let mut scene = Scene::new(); let mut shaper = Shaper::new(); - let padding = 10.; - #[derive(Debug, PartialEq, Eq)] - struct Expected { - fullname: String, - attributes: Attributes, - synthesis: Synthesis, - } - let lines = vec![ - ( - "FiraCode Normal", - vec![StyleProperty::FontStack(FontStack::Source( - "FiraCode Nerd Font", - ))], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "FiraCode (Native) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "FiraCode Nerd Font Bold".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "FiraCode (Faux) Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 14.0.into(), - }, - }, - ), - ( - "FiraCode Oblique 5 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(5.0))), - ], - Expected { - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 5.0.into(), - }, - }, - ), - ( - "FiraCode Synthetic Stretch Wide (Buggy)", - vec![ - StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), - StyleProperty::FontStretch(FontStretch::EXPANDED), - ], - Expected { - // FIXME: Fontique does not support synthetic stretch - fullname: "FiraCode Nerd Font Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "ProFontWindows Nerd Font", - vec![StyleProperty::FontStack(FontStack::Source( - "ProFontWindows Nerd Font", - ))], - Expected { - fullname: "ProFontWindows Nerd Font".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "ProFontWindows Nerd Font (Faux) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("ProFontWindows Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "ProFontWindows Nerd Font".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: true, - skew: 0.0.into(), - }, - }, - ), - ( - "CaskaydiaCove Nerd Font Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("CaskaydiaCove Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "CaskaydiaCove NF Italic".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( + + let layout = shaper.layout_within_with(text, 800., |builder| { + builder.push_default(&StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); + builder.push_default(&StyleProperty::FontSize(16.)); + for prop in style_properties { + builder.push(&prop, 0..text.len()); + } + }); + + let layout_width = layout.width(); + let layout_height = layout.height(); + scene.add_text_layout(&layout, point2!(padding, padding)); + + let current_layer = scene.layer(); + + let glyph_run = ¤t_layer + .contents + .primitives + .last() + .unwrap() + .as_glyph_run_vec() + .unwrap()[0]; + let font = scene.resources.fonts.get(&glyph_run.font_id).unwrap(); + let font_ref = font.as_swash_font_ref(glyph_run.font_index).unwrap(); + let fullname = font_ref + .localized_strings() + .find_by_id(swash::StringId::Full, None) + .map_or("".into(), |str| str.chars().collect::()); + let attributes = font_ref.attributes(); + let synthesis = glyph_run.synthesis.clone(); + + assert_eq!(fullname, expected_full_name); + assert_eq!(attributes, expected_attributes); + assert_eq!(synthesis, expected_synthesis); + + assert_no_regressions( + (layout_width + padding * 2.) as u32, + (layout_height + padding * 2.) as u32, + scene, + ); +} + +#[test] +fn firacode_normal() { + assert_attributes( + vec![StyleProperty::FontStack(FontStack::Source( + "FiraCode Nerd Font", + ))], + "FiraCode Normal", + "FiraCode Nerd Font Reg".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn firacode_native_bold() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + "FiraCode (Native) Bold", + "FiraCode Nerd Font Bold".into(), + Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn firacode_faux_italic() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + "FiraCode (Faux) Italic", + "FiraCode Nerd Font Reg".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 14.0.into(), + }, + ); +} + +#[test] +fn firacode_oblique_5_degrees() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(5.0))), + ], + "FiraCode Oblique 5 degrees", + "FiraCode Nerd Font Reg".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 5.0.into(), + }, + ); +} + +#[test] +fn firacode_synthetic_stretch_wide() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("FiraCode Nerd Font")), + StyleProperty::FontStretch(FontStretch::EXPANDED), + ], + "FiraCode Synthetic Stretch Wide", + "FiraCode Nerd Font Reg".into(), + // FIXME: Fontique does not support synthetic stretch + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn profontwindows_nerd_font_faux_bold() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("ProFontWindows Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + "ProFontWindows Nerd Font (Faux) Bold", + "ProFontWindows Nerd Font".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: true, + skew: 0.0.into(), + }, + ); +} + +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn caskaydiacove_nerd_font_italic() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("CaskaydiaCove Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + "CaskaydiaCove Nerd Font Italic", + "CaskaydiaCove NF Italic".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var() { + assert_attributes( + vec![StyleProperty::FontStack(FontStack::Source( "Monaspace Xenon Var", - vec![StyleProperty::FontStack(FontStack::Source( - "Monaspace Xenon Var", - ))], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var (Variadic) Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![crate::Setting { - tag: WGHT, - value: swash::Weight::BOLD.0.into(), - }], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var (Variadic) Italic (Buggy)", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![crate::Setting { - tag: SLNT, - // FIXME: This should be -11 - // See: https://github.com/linebender/parley/issues/94 - value: (14.0).into(), - }], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Oblique -10 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-10.0))), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![crate::Setting { - tag: SLNT, - value: (-10.0).into(), - }], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Oblique 5 degreees = no italic", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-5.0))), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![crate::Setting { - tag: SLNT, - value: (-5.0).into(), - }], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Monaspace Xenon Var Stretch=113 Weight = 637, Oblique -8 degrees", - vec![ - StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), - StyleProperty::FontWeight(FontWeight::new(637.0)), - StyleProperty::FontStyle(FontStyle::Oblique(Some(-8.0))), - StyleProperty::FontStretch(FontStretch::from_percentage(113.0)), - ], - Expected { - fullname: "Monaspace Xenon Var Regular".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![ - crate::Setting { - tag: WDTH, - value: 113.0.into(), - }, - crate::Setting { - tag: WGHT, - value: 637.0.into(), - }, - crate::Setting { - tag: SLNT, - value: (-8.0).into(), - }, - ], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Normal", - vec![StyleProperty::FontStack(FontStack::Source( - "NotoSerif Nerd Font", - ))], - Expected { - fullname: "NotoSerif NF Reg".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Bold", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - ], - Expected { - fullname: "NotoSerif NF Bold".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), + ))], + "Monaspace Xenon Var", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var_variadic_bold() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + "Monaspace Xenon Var (Variadic) Bold", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![crate::Setting { + tag: WGHT, + value: swash::Weight::BOLD.0.into(), + }], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var_variadic_italic_buggy() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + "Monaspace Xenon Var (Variadic) Italic", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + // FIXME: This should be -11 + // See: https://github.com/linebender/parley/issues/94 + value: (14.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var_oblique_minus_10_degrees() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-10.0))), + ], + "Monaspace Xenon Var Oblique -10 degrees", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + value: (-10.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var_oblique_5_degrees_no_italic() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-5.0))), + ], + "Monaspace Xenon Var Oblique 5 degreees = no italic", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![crate::Setting { + tag: SLNT, + value: (-5.0).into(), + }], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +fn monaspace_xenon_var_stretch_113_weight_637_oblique_minus_8_degrees() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("Monaspace Xenon Var")), + StyleProperty::FontWeight(FontWeight::new(637.0)), + StyleProperty::FontStyle(FontStyle::Oblique(Some(-8.0))), + StyleProperty::FontStretch(FontStretch::from_percentage(113.0)), + ], + "Monaspace Xenon Var Stretch=113 Weight = 637, Oblique -8 degrees", + "Monaspace Xenon Var Regular".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![ + crate::Setting { + tag: WDTH, + value: 113.0.into(), }, - }, - ), - ( - "Noto Serif Condensed", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontStretch(FontStretch::CONDENSED), - ], - Expected { - fullname: "NotoSerif NF Cond Reg".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::NORMAL, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), + crate::Setting { + tag: WGHT, + value: 637.0.into(), }, - }, - ), - ( - "Noto Serif Bold Condensed", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - StyleProperty::FontStretch(FontStretch::CONDENSED), - ], - Expected { - fullname: "NotoSerif NF Cond Bold".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Normal), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), + crate::Setting { + tag: SLNT, + value: (-8.0).into(), }, - }, - ), - ( - "Noto Serif Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontStyle(FontStyle::Italic), ], - Expected { - fullname: "NotoSerif NF Italic".into(), - attributes: Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ( - "Noto Serif Bold Condensed Italic", - vec![ - StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), - StyleProperty::FontWeight(FontWeight::BOLD), - StyleProperty::FontStretch(FontStretch::CONDENSED), - StyleProperty::FontStyle(FontStyle::Italic), - ], - Expected { - fullname: "NotoSerif NF Cond Bold Italic".into(), - attributes: Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Italic), - synthesis: Synthesis { - vars: vec![], - embolden: false, - skew: 0.0.into(), - }, - }, - ), - ]; - let layout = shaper.layout_within_with( - &lines - .iter() - .map(|line| line.0) - .collect::>() - .join("\n"), - 800., - |builder| { - builder.push_default(&StyleProperty::Brush(Srgba::new(0., 0., 0., 1.))); - builder.push_default(&StyleProperty::FontSize(16.)); - let mut start = 0; - for line in &lines { - let line_len = line.0.len(); - let range = start..start + line_len; - for prop in &line.1 { - builder.push(prop, range.clone()); - } - start += line_len + 1; - } + embolden: false, + skew: 0.0.into(), }, ); +} - let layout_width = layout.width(); - let layout_height = layout.height(); - scene.add_text_layout(&layout, point2!(padding, padding)); +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_normal() { + assert_attributes( + vec![StyleProperty::FontStack(FontStack::Source( + "NotoSerif Nerd Font", + ))], + "Noto Serif Normal", + "NotoSerif NF Reg".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} - let current_layer = scene.layer(); - assert_eq!( - current_layer - .contents - .primitives - .last() - .unwrap() - .as_glyph_run_vec() - .unwrap() - .len(), - lines.len() +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_bold() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + ], + "Noto Serif Bold", + "NotoSerif NF Bold".into(), + Attributes::new(Stretch::NORMAL, Weight::BOLD, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_condensed() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontStretch(FontStretch::CONDENSED), + ], + "Noto Serif Condensed", + "NotoSerif NF Cond Reg".into(), + Attributes::new(Stretch::CONDENSED, Weight::NORMAL, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_bold_condensed() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + StyleProperty::FontStretch(FontStretch::CONDENSED), + ], + "Noto Serif Bold Condensed", + "NotoSerif NF Cond Bold".into(), + Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Normal), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_italic() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontStyle(FontStyle::Italic), + ], + "Noto Serif Italic", + "NotoSerif NF Italic".into(), + Attributes::new(Stretch::NORMAL, Weight::NORMAL, Style::Italic), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, + ); +} + +#[test] +#[cfg_attr(target_os = "windows", ignore = "Font not found on windows")] +fn notoserif_bold_condensed_italic() { + assert_attributes( + vec![ + StyleProperty::FontStack(FontStack::Source("NotoSerif Nerd Font")), + StyleProperty::FontWeight(FontWeight::BOLD), + StyleProperty::FontStretch(FontStretch::CONDENSED), + StyleProperty::FontStyle(FontStyle::Italic), + ], + "Noto Serif Bold Condensed Italic", + "NotoSerif NF Cond Bold Italic".into(), + Attributes::new(Stretch::CONDENSED, Weight::BOLD, Style::Italic), + Synthesis { + vars: vec![], + embolden: false, + skew: 0.0.into(), + }, ); - for (index, line) in lines.iter().enumerate() { - let glyph_runs = current_layer - .contents - .primitives - .last() - .unwrap() - .as_glyph_run_vec() - .unwrap(); - let glyph_run = &glyph_runs[index]; - let font = scene.resources.fonts.get(&glyph_run.font_id).unwrap(); - let font_ref = font.as_swash_font_ref(glyph_run.font_index).unwrap(); - let fullname = font_ref - .localized_strings() - .find_by_id(swash::StringId::Full, None) - .map_or("".into(), |str| str.chars().collect::()); - let attributes = font_ref.attributes(); - let synthesis = glyph_run.synthesis.clone(); - let actual = Expected { - fullname, - attributes, - synthesis, - }; - assert_eq!(line.2, actual, "line number {index}"); - } } diff --git a/test_data/Kaylee Simmons/firacode_faux_italic.png b/test_data/Kaylee Simmons/firacode_faux_italic.png new file mode 100644 index 0000000000000000000000000000000000000000..bb9b99791066f66a05ce1bb595c334ed5e1e0607 GIT binary patch literal 5148 zcmcIoZB!HIwho{mBBnws_8^QFE48SxMU5XJ(dw02s_Ct@IX%=wYmd~TM5Rgs$xIM6 zB88|_(IQ0aQCc|=J+=Z8GJGgOBSfVb6v*U@1O%CU5Hd+7lN);PI={N^TKC7@Yt77` zci#Q1y`TL)``v|~Y)y@v{+H<_5-D=?hZ{c)d`AP%f@z_F_o;85b&^QY#?2eof5r=X zr3*T}VDs4po1=7O*byirZmT|U&ao#o@MAG}dr>p_k_ z+|JtJgr}aX4y=VD-ev7L+~c49*&jbHnO5uJv^1kMp)>;WCgI%dZ?Hj*a4ww}#qu@2 zhR5(9MzPTlxTp#r53@rpJCZO5;>})lx7@!ksf|Uv=*C9WLdMG4)ernDqpjy4{&^13 znj=0^;@>hBG`^H^YQX}VEo#*F9;HK}Pl5GJ>>5)LrwjJCOe2cBf^z-RO;Kl09}BFq zAl5a_%^@l7eTR(EU|}ZU_TVi3%ll_!-Y1A*3F0;Keo1Xw3^2Je$FU&w4>>1iJICFd;@xNKi#N7_1lry zUj7_PM^kh^kp^`pu#M;Pbp$tpsO&rAs9yXs~x!+MWuw zRy!V-@e`g6gcI1_j4%9lvcn8`x|TIoLK2tvmnvHcgfG($rA>(T6UqM+F+KW3>$lKE zzT6mtlOA!+ZoU@~1Oqr(qIbeNQm+YmD+CxXWe)xZTJ`ciiFW3}X#eNo@)vc)8=NEh zV!o59h`eCKJmD8E#fLywfrqq#)Ngb2k85^WtU zH)&_Ne=);amv;$&NH)gN9o0L*WVL#=E)jHu(+uYruLtnH8^raUA`h}a!xmkCDdwtI zS(OYwnKnA8B?o|x1|zO8reT&0d(s^0XVrGY#&czPe&L0b zV=*Qf>vDxUHR>$(z%~28dCNp31fE==*!a~7JcZ#A*V!k4iK#&Y{)am6o!hY-NsQSr1#u=p%5>OYEp1^BX>Uecd8U9FBrmjhN7LuI%^ zd63-~HeLuH4HWIcs4qRc*{35C1gH#Of?`*ss%m&N(>@G%w$jE}ijeDRc*Ha!vMY#T z>tpK9$nY!8vnd^E>Xtld*9-G?iZ3MI=i!E4GB*f&Ra|=;bMEupqB2tvG`fgp$0d%7 zQa>T@>}ot@Olz9&%CjYB(=7$aS;YMuHH#q^m)DvmSPm0zS>z=n$iS;&+&^W=sTzf+ z(bn3Z+}bF3rgogJ62vja|Bk9Dgd25OBUX%FqC!(uBz3YLGX-8E}21@P4{pBaOcy;T#C30Sowgdnm#&$z2JhcE91ROMLh7t ztgNqrj|LH=tTMN-jz5}nwLJcQcHZ;In~ZYQCtkq;ySMOsSzgPBOUN6^YshIe0%}&!^Jz%fKRu{#lyFT0)t~9y(EG0P8MQ-p)4f`KaQcfZZ_I zQnze0naukU-p-{* zb)`g#`Zn>zOk$P--xeXstsq}XzodJTXpujNZJI5!wlw2c<^}=y5~$Szo7A@HD8Bd6 z9j@+r&6_B;NA{o;@{vW^cxGG>XCf2o%#^D$Hw64%;DG%#@_sMcHacHEFNijNy>#)B z+ABXi+@jp`2pHeluAfUD&tTG(neq{JbD=mJRt~JO#R~vui)0W?6sdD9EK8k&;5PW4 zmSV@$_$-AlA+<|x2n%Y7IHYN4kG1t3@PraIQP?e5_!o+EOtVh-8l{6vBaX1mLR3Vw z&=`N}R=uC37@3YjrWxZFPd=fdnLc^M@ZqWk6mB53J;sxi2uht5?Q*&e9lR z%~ao$Qp~Of|DMHrMGl(Iwav3_W!N(>$C7%bItzg<5|}cCDKh(cwB);FDfTjv-%-t& zy(+S~CZXT89eS{VW3LglM%e4ZtjT~YL{8*^bAQOJM^?R^K6m{v3A4eygS#O|0&gf* zPW^<`8>X-@D_axTPM>H$I5N@R33!joAN7IDZnpSJP82>57nMLYRsYl}WLQGH$G{Cg z8DpYZqhaS1tuu58+P%;ti~Z+- zaGbhlq>m0Z=y!1+W;fQf#4#qQH0-`MIFRoBkz;}U>su%jvqiitcw)Tp6%(J!_BPSu z4XY-VIustSPj~k)pDVS>m3MA+UepjXDy0nJQ=$Ato-b-{-W;{MTVw4&u?V)Yf*$X6cu(cE-W++Of z3AMtM$!1INv|4JqBEzRQZzg`rY9wp({L~8wc7T1MYOHNH{7N!MiY4^6ue{?HG2Xwo zAqW$vJt!A+Q0LlZ%_ZXfj$V#`QM|1ko$-jbYiTgYtAg58O#|K_jh*W>Wm{h`T;*T7PO{8X z`7dV4TUq`^)BqiLAff-%z7Vh%)5dF2V>RQ|0Kb*%dk5xA`C;1fZDfdF*%ytz4>&Ry z%JvPMvoYqvoQo3oZRu`fKn)#^0?4ym>l^@!>xTz1>RT9V4H>`3W#p&I?P5|oo))TG z>$m?xGdqzPtJ)k6EaPLj*DfB4AOCBm6mX9S*)JOrNsj+}nf~_z_KBxlYXIs@hNJva zE~av<>myyWx8g0`sQx{4`r<4d=xx>zFFB4I!1$(5;#-@V<6!)=tlZJHr0g+QeR`s{ z0==5|c=wwkRPb~MexEvUtYR|Ew>njV$I{^AP)$)-G}%Dil`W1jqm>H7fXuz{l}P4M9=V#Tij*1wk8^|ryyM$*uE6Zg;iIv4f_Fa#nAOs z+flr&CIRJjyZ$qaKSRAgm_AYkC}TK&zWkY2xHP>AIQ5a5lj4lx;xCX$P0CrzL?ZL9 zgq0`b9NkSe9(Q*q4k)XeG?bQGVq1TS2*|@L`t67ME_dUxv+$&p!$7>Z2D-OJlKbaM zlq9est%fT!Y6!<+Vd{U=zS{fE$Su+w%m>2~D)5 zSt5EE=(QFlX-C4~<1vtmIdyub2%-N&3K+o2Kbo{tzCZj{^0 zeKRicrn$V`O29fM00s&Gm9L9wZQ=OR1w5>0 z664$2iCdS;d6z>48e^96iOjpH`AzoeAgl`(yer}Rs3Bd}qo(g>d`J{eBhCd-CTV>? za(|)^-IBjk`CXZN=-+A~Zl)5pQogBL0o-iMPCl@W#d{dNvmdT-s0z76vC`p_j&Hui z4;RIaxqg0AuE}Uxfmn}on%z~trThPOQ2&i7(QjIWzhDVw@?u0({_k7xQ6}RDhr}Ou zzU>r}YxqLpErl$6yQq?<>E^BP3Sms7Gj+3M_W8}T z)y$yY8~q+r;v_9=w<1pNPgzFulwF zhXTPjx!47+Kbd|*_$I|2&-u6~6m|VbY1e@2q-5G~9S@Ac+K~pa3&fQ+1By>wr~E@q zu>Tel&d#ogs3=!u!LV+wccidU3dS6mvhII{6SAfGTEQEs)vNcfG4vCp>NHwiUu?f^ zH>4`yj4mPB`d5n7yke!*hk%7%LLc)-9ALE?ZdXzvPYrR?Lo=HzTdKEV12V*iQhfMX5*4)AcK z$+Om$%)!^odsKk+ak;jj9Pr)kN832QtOOc8#r(LTr(DRl^L#zZzAIa8oXpqF5Hq-lHY=?%Ip}4&Y&06F~o7fDY@aft1*9uW(_4sVR29@km46|q`t z(V2T(Xl&+9Q-jcysqK)`UncVIQ?YmG`T?z|3V)W<_A9yB*~}D<#X1@w;#2ux61)($ zIRRCoe2;xQf;IK$xmF&y7t$$`3M^%Vw+Z|luYx6rRM@s5Asjr6G&Xg7jB#Q?JbNlM zF@K+8G%TU8%J;k1(N8B1*Bb9Da5Aq&e-0r*pgCxLlV8I=04pja+p) z)TTb#WrdIDGkw?k_?-|oS39(UUfL@^UQKM6H@W+nXX{ed{IqYM74CfU{__ju%d1&F r@%q3m*AI4$CtOL(e_6iPMoEMn-kv9Lw){V6v>^%Bk!#l+N literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/firacode_native_bold.png b/test_data/Kaylee Simmons/firacode_native_bold.png new file mode 100644 index 0000000000000000000000000000000000000000..21e62c3ba149729c28980fdf11ca63a886196b0f GIT binary patch literal 4918 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 literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/firacode_oblique_5_degrees.png b/test_data/Kaylee Simmons/firacode_oblique_5_degrees.png new file mode 100644 index 0000000000000000000000000000000000000000..202228d5ea641221b1f79b8d642a3b80953759cc GIT binary patch literal 6164 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 TZ+npK2e!YHx$WxP*+>2hS!(j- literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/firacode_synthetic_stretch_wide.png b/test_data/Kaylee Simmons/firacode_synthetic_stretch_wide.png new file mode 100644 index 0000000000000000000000000000000000000000..d5cd0e53c33beb8bde56a33b81c8160d7bec584f GIT binary patch literal 6028 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 PJ1u?Hnw8a`Z8`LxJ&2^K literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/monaspace_xenon_var.png b/test_data/Kaylee Simmons/monaspace_xenon_var.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd04a4a154a8b925f89fe3846b23ad543931819 GIT binary patch literal 4764 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 literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/monaspace_xenon_var_oblique_5_degrees_no_italic.png b/test_data/Kaylee Simmons/monaspace_xenon_var_oblique_5_degrees_no_italic.png new file mode 100644 index 0000000000000000000000000000000000000000..731ee03057dc1299a9a15c2a120527e9227dd595 GIT binary patch literal 11412 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 QBX)eU>*G8BNImi20B|i>!~g&Q literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/monaspace_xenon_var_oblique_minus_10_degrees.png b/test_data/Kaylee Simmons/monaspace_xenon_var_oblique_minus_10_degrees.png new file mode 100644 index 0000000000000000000000000000000000000000..dbab42cf0853bffc9df1d568a91d1790f6bac64f GIT binary patch literal 9838 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≶XWRtTdxV|LA!7mj27#;)-{l4o9cNq6rXBe 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 R0nZ|0@O1TaS?83{1OS4k$`Jqn literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/monaspace_xenon_var_variadic_bold.png b/test_data/Kaylee Simmons/monaspace_xenon_var_variadic_bold.png new file mode 100644 index 0000000000000000000000000000000000000000..ee821425c348ea547a4b8281c44a86f7ccb13488 GIT binary patch literal 9521 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 literal 0 HcmV?d00001 diff --git a/test_data/Kaylee Simmons/monaspace_xenon_var_variadic_italic_buggy.png b/test_data/Kaylee Simmons/monaspace_xenon_var_variadic_italic_buggy.png new file mode 100644 index 0000000000000000000000000000000000000000..46eca02527a26947eb6d201b513138cbf8d027ab GIT binary patch literal 8249 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 literal 0 HcmV?d00001