diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-04-06 15:13:20 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-04-06 15:13:20 +0200 |
| commit | 464a6ff75e198253ba4128d4820e9ad09458a22d (patch) | |
| tree | dd9f5e0760c5fa08cd142f00308073f6506362cb /src/font.rs | |
| parent | de20a21a584a90da682a64e9a79cd18a95195b70 (diff) | |
Deduplicate ttf-parser and rustybuzz face 🥞
Diffstat (limited to 'src/font.rs')
| -rw-r--r-- | src/font.rs | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/src/font.rs b/src/font.rs index a816ed06..1ac8fea3 100644 --- a/src/font.rs +++ b/src/font.rs @@ -10,8 +10,7 @@ use crate::geom::Length; pub struct FaceBuf { data: Box<[u8]>, index: u32, - ttf: ttf_parser::Face<'static>, - buzz: rustybuzz::Face<'static>, + inner: rustybuzz::Face<'static>, units_per_em: f64, ascender: f64, cap_height: f64, @@ -30,23 +29,16 @@ impl FaceBuf { self.index } - /// Get a reference to the underlying ttf-parser face. - pub fn ttf(&self) -> &ttf_parser::Face<'_> { + /// Get a reference to the underlying ttf-parser/rustybuzz face. + pub fn ttf(&self) -> &rustybuzz::Face<'_> { // We can't implement Deref because that would leak the internal 'static // lifetime. - &self.ttf + &self.inner } - /// Get a reference to the underlying rustybuzz face. - pub fn buzz(&self) -> &rustybuzz::Face<'_> { - // We can't implement Deref because that would leak the internal 'static - // lifetime. - &self.buzz - } - - /// Look up a vertical metric at a given font size. - pub fn vertical_metric(&self, size: Length, metric: VerticalFontMetric) -> Length { - self.convert(size, match metric { + /// Look up a vertical metric. + pub fn vertical_metric(&self, metric: VerticalFontMetric) -> EmLength { + self.convert(match metric { VerticalFontMetric::Ascender => self.ascender, VerticalFontMetric::CapHeight => self.cap_height, VerticalFontMetric::XHeight => self.x_height, @@ -55,9 +47,9 @@ impl FaceBuf { }) } - /// Convert from font units to a length at a given font size. - pub fn convert(&self, size: Length, units: impl Into<f64>) -> Length { - units.into() / self.units_per_em * size + /// Convert from font units to an em length length. + pub fn convert(&self, units: impl Into<f64>) -> EmLength { + EmLength(units.into() / self.units_per_em) } } @@ -70,21 +62,19 @@ impl FaceFromVec for FaceBuf { let slice: &'static [u8] = unsafe { std::slice::from_raw_parts(data.as_ptr(), data.len()) }; - let ttf = ttf_parser::Face::from_slice(slice, index).ok()?; - let buzz = rustybuzz::Face::from_slice(slice, index)?; + let inner = rustybuzz::Face::from_slice(slice, index)?; // Look up some metrics we may need often. - let units_per_em = ttf.units_per_em().unwrap_or(1000); - let ascender = ttf.typographic_ascender().unwrap_or(ttf.ascender()); - let cap_height = ttf.capital_height().filter(|&h| h > 0).unwrap_or(ascender); - let x_height = ttf.x_height().filter(|&h| h > 0).unwrap_or(ascender); - let descender = ttf.typographic_descender().unwrap_or(ttf.descender()); + let units_per_em = inner.units_per_em(); + let ascender = inner.typographic_ascender().unwrap_or(inner.ascender()); + let cap_height = inner.capital_height().filter(|&h| h > 0).unwrap_or(ascender); + let x_height = inner.x_height().filter(|&h| h > 0).unwrap_or(ascender); + let descender = inner.typographic_descender().unwrap_or(inner.descender()); Some(Self { data, index, - ttf, - buzz, + inner, units_per_em: f64::from(units_per_em), ascender: f64::from(ascender), cap_height: f64::from(cap_height), @@ -94,6 +84,22 @@ impl FaceFromVec for FaceBuf { } } +/// A length in resolved em units. +#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd)] +pub struct EmLength(f64); + +impl EmLength { + /// Convert to a length at the given font size. + pub fn scale(self, size: Length) -> Length { + self.0 * size + } + + /// Get the number of em units. + pub fn get(self) -> f64 { + self.0 + } +} + /// Identifies a vertical metric of a font. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] pub enum VerticalFontMetric { |
