From 8a38899c98b4f9829b2d1f21c8fee66d254d20c6 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 14 Nov 2021 14:53:01 +0100 Subject: [PATCH] Tidying --- src/diag.rs | 1 - src/eval/value.rs | 8 ------ src/font.rs | 27 +++++++++++++------ src/library/text.rs | 64 ++++++++++++++++++++------------------------- src/source.rs | 10 +++---- src/style/mod.rs | 8 +++--- 6 files changed, 57 insertions(+), 61 deletions(-) diff --git a/src/diag.rs b/src/diag.rs index d284687ed..f0efa500d 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -7,7 +7,6 @@ use serde::{Deserialize, Serialize}; use crate::syntax::{Span, Spanned}; /// Early-return with a vec-boxed [`Error`]. -#[macro_export] macro_rules! bail { ($span:expr, $message:expr $(,)?) => { return Err($crate::diag::Error::boxed($span, $message,)) diff --git a/src/eval/value.rs b/src/eval/value.rs index 2c6167a48..804f8d55a 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -72,14 +72,6 @@ impl Value { } } - /// Check whether the value is castable into a specific type. - pub fn is(&self) -> bool - where - T: Cast, - { - T::is(self) - } - /// Try to cast the value into a specific type. pub fn cast(self) -> StrResult where diff --git a/src/font.rs b/src/font.rs index 378115e49..6b76eda6b 100644 --- a/src/font.rs +++ b/src/font.rs @@ -149,31 +149,48 @@ impl FontStore { pub fn families(&self) -> impl Iterator + '_ { // Since the keys are lowercased, we instead use the family field of the // first face's info. + let faces = self.loader.faces(); self.families .values() - .map(move |id| self.loader.faces()[id[0].0 as usize].family.as_str()) + .map(move |id| faces[id[0].0 as usize].family.as_str()) } } /// A font face. pub struct Face { + /// The raw face data, possibly shared with other faces from the same + /// collection. Must stay alive put, because `ttf` points into it using + /// unsafe code. buffer: Rc>, + /// The face's index in the collection (zero if not a collection). index: u32, + /// The underlying ttf-parser/rustybuzz face. ttf: rustybuzz::Face<'static>, - units_per_em: f64, + /// How many font units represent one em unit. + pub units_per_em: f64, + /// The distance from the baseline to the typographic ascender. pub ascender: Em, + /// The approximate height of uppercase letters. pub cap_height: Em, + /// The approximate height of non-ascending lowercase letters. pub x_height: Em, + /// The distance from the baseline to the typographic descender. pub descender: Em, + /// Recommended metrics for a strikethrough line. pub strikethrough: LineMetrics, + /// Recommended metrics for an underline. pub underline: LineMetrics, + /// Recommended metrics for an overline. pub overline: LineMetrics, } /// Metrics for a decorative line. #[derive(Debug, Copy, Clone)] pub struct LineMetrics { + /// The thickness of the line. pub strength: Em, + /// The vertical offset of the line from the baseline. Positive goes + /// upwards, negative downwards. pub position: Em, } @@ -190,7 +207,6 @@ impl Face { unsafe { std::slice::from_raw_parts(buffer.as_ptr(), buffer.len()) }; let ttf = rustybuzz::Face::from_slice(slice, index)?; - let units_per_em = f64::from(ttf.units_per_em()); let to_em = |units| Em::from_units(units, units_per_em); @@ -252,11 +268,6 @@ impl Face { &self.ttf } - /// Get the number of units per em. - pub fn units_per_em(&self) -> f64 { - self.units_per_em - } - /// Convert from font units to an em length. pub fn to_em(&self, units: impl Into) -> Em { Em::from_units(units, self.units_per_em) diff --git a/src/library/text.rs b/src/library/text.rs index 924723b4e..4cf94bdee 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -2,11 +2,12 @@ use std::borrow::Cow; use std::convert::TryInto; use std::ops::Range; -use rustybuzz::{Feature, Tag, UnicodeBuffer}; +use rustybuzz::{Feature, UnicodeBuffer}; +use ttf_parser::Tag; use super::prelude::*; use crate::font::{ - Face, FaceId, FontFamily, FontStretch, FontStyle, FontVariant, FontWeight, + Face, FaceId, FontFamily, FontStore, FontStretch, FontStyle, FontVariant, FontWeight, VerticalFontMetric, }; use crate::geom::{Dir, Em, Length, Point, Size}; @@ -19,7 +20,7 @@ use crate::util::SliceExt; pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult { struct FontDef(Rc>); struct FamilyDef(Rc>); - struct FeatureList(Vec<(String, u32)>); + struct FeatureList(Vec<(Tag, u32)>); struct StylisticSet(Option); castable! { @@ -134,21 +135,23 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult { castable! { FeatureList: "array of strings or dictionary mapping tags to integers", - Value::Array(values) => Self(values - .into_iter() - .filter_map(|v| v.cast().ok()) - .map(|string: Str| (string.to_lowercase(), 1)) - .collect()), - Value::Dict(values) => Self(values - .into_iter() - .filter_map(|(k, v)| { - if let Ok(value) = v.cast::() { - Some((k.to_lowercase(), value as u32)) - } else { - None - } - }) - .collect()), + Value::Array(values) => Self( + values + .into_iter() + .filter_map(|v| v.cast().ok()) + .map(|string: Str| (Tag::from_bytes_lossy(string.as_bytes()), 1)) + .collect() + ), + Value::Dict(values) => Self( + values + .into_iter() + .filter_map(|(k, v)| { + let tag = Tag::from_bytes_lossy(k.as_bytes()); + let num = v.cast::().ok()?.try_into().ok()?; + Some((tag, num)) + }) + .collect() + ), } let list = args.named("family")?.or_else(|| { @@ -266,11 +269,10 @@ pub fn shape<'a>( let mut glyphs = vec![]; if !text.is_empty() { shape_segment( - ctx, + ctx.fonts, &mut glyphs, 0, text, - style.size, style.variant(), style.families(), None, @@ -452,11 +454,10 @@ enum Side { /// Shape text with font fallback using the `families` iterator. fn shape_segment<'a>( - ctx: &mut LayoutContext, + fonts: &mut FontStore, glyphs: &mut Vec, base: usize, text: &str, - size: Length, variant: FontVariant, mut families: impl Iterator + Clone, mut first_face: Option, @@ -468,7 +469,7 @@ fn shape_segment<'a>( // Try to load the next available font family. match families.next() { Some(family) => { - if let Some(id) = ctx.fonts.select(family, variant) { + if let Some(id) = fonts.select(family, variant) { break (id, true); } } @@ -495,7 +496,7 @@ fn shape_segment<'a>( }); // Shape! - let mut face = ctx.fonts.get(face_id); + let mut face = fonts.get(face_id); let buffer = rustybuzz::shape(face.ttf(), tags, buffer); let infos = buffer.glyph_infos(); let pos = buffer.glyph_positions(); @@ -545,11 +546,9 @@ fn shape_segment<'a>( // Glyphs: E C _ _ A // Clusters: 8 6 4 2 0 // k=2 i=3 - let ltr = dir.is_positive(); let first = if ltr { k } else { i }; let start = infos[first].cluster as usize; - let last = if ltr { i.checked_add(1) } else { k.checked_sub(1) }; let end = last .and_then(|last| infos.get(last)) @@ -560,11 +559,10 @@ fn shape_segment<'a>( // Recursively shape the tofu sequence with the next family. shape_segment( - ctx, + fonts, glyphs, base + range.start, &text[range], - size, variant, families.clone(), first_face, @@ -572,7 +570,7 @@ fn shape_segment<'a>( tags, ); - face = ctx.fonts.get(face_id); + face = fonts.get(face_id); } i += 1; @@ -687,12 +685,8 @@ fn tags(features: &FontFeatures) -> Vec { feat(b"frac", 1); } - for (tag, value) in features.raw.iter() { - tags.push(Feature::new( - Tag::from_bytes_lossy(tag.as_bytes()), - *value, - .., - )) + for &(tag, value) in features.raw.iter() { + tags.push(Feature::new(tag, value, ..)) } tags diff --git a/src/source.rs b/src/source.rs index 85f48491a..e692ac94d 100644 --- a/src/source.rs +++ b/src/source.rs @@ -144,6 +144,11 @@ impl SourceFile { } } + /// Create a source file without a real id and path, usually for testing. + pub fn detached(src: impl Into) -> Self { + Self::new(SourceId(0), Path::new(""), src.into()) + } + /// The file's abstract syntax tree. pub fn ast(&self) -> TypResult { let red = RedNode::from_root(self.root.clone(), self.id); @@ -155,11 +160,6 @@ impl SourceFile { } } - /// Create a source file without a real id and path, usually for testing. - pub fn detached(src: impl Into) -> Self { - Self::new(SourceId(0), Path::new(""), src.into()) - } - /// The id of the source file. pub fn id(&self) -> SourceId { self.id diff --git a/src/style/mod.rs b/src/style/mod.rs index 4b1d2837a..dccc75436 100644 --- a/src/style/mod.rs +++ b/src/style/mod.rs @@ -6,9 +6,9 @@ pub use paper::*; use std::rc::Rc; -use crate::font::{ - FontFamily, FontStretch, FontStyle, FontVariant, FontWeight, VerticalFontMetric, -}; +use ttf_parser::Tag; + +use crate::font::*; use crate::geom::*; /// Defines a set of properties a template can be instantiated with. @@ -275,7 +275,7 @@ pub struct FontFeatures { /// Configuration of numbers features. pub numbers: NumberFeatures, /// Raw OpenType features to apply. - pub raw: Vec<(String, u32)>, + pub raw: Vec<(Tag, u32)>, } impl Default for FontFeatures {