summaryrefslogtreecommitdiff
path: root/src/font.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-04-06 15:13:20 +0200
committerLaurenz <laurmaedje@gmail.com>2021-04-06 15:13:20 +0200
commit464a6ff75e198253ba4128d4820e9ad09458a22d (patch)
treedd9f5e0760c5fa08cd142f00308073f6506362cb /src/font.rs
parentde20a21a584a90da682a64e9a79cd18a95195b70 (diff)
Deduplicate ttf-parser and rustybuzz face 🥞
Diffstat (limited to 'src/font.rs')
-rw-r--r--src/font.rs60
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 {