diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-24 19:30:09 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-24 19:30:09 +0200 |
| commit | 018860da9c72df846d80051a1408b3e632fbaaf6 (patch) | |
| tree | f499a4908cd59b087b107015789a606b370fd1fd /src | |
| parent | acdde6d3266d4158241c2e62aa88a1185a3016fd (diff) | |
Parse math fonts only once
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.rs | 17 | ||||
| -rw-r--r-- | src/library/math/rex.rs | 10 |
2 files changed, 21 insertions, 6 deletions
diff --git a/src/font.rs b/src/font.rs index ce1c48f8..9280ff8d 100644 --- a/src/font.rs +++ b/src/font.rs @@ -6,6 +6,8 @@ use std::fmt::{self, Debug, Formatter}; use std::path::{Path, PathBuf}; use std::sync::Arc; +use once_cell::sync::OnceCell; +use rex::font::MathFont; use serde::{Deserialize, Serialize}; use ttf_parser::{name_id, GlyphId, PlatformId, Tag}; use unicode_segmentation::UnicodeSegmentation; @@ -246,6 +248,8 @@ pub struct Face { ttf: rustybuzz::Face<'static>, /// The faces metrics. metrics: FaceMetrics, + /// The parsed ReX math font. + math: OnceCell<Option<MathFont>>, } impl Face { @@ -263,7 +267,13 @@ impl Face { let ttf = rustybuzz::Face::from_slice(slice, index)?; let metrics = FaceMetrics::from_ttf(&ttf); - Some(Self { buffer, index, ttf, metrics }) + Some(Self { + buffer, + index, + ttf, + metrics, + math: OnceCell::new(), + }) } /// The underlying buffer. @@ -293,6 +303,11 @@ impl Face { &self.metrics } + /// Access the math font, if any. + pub fn math(&self) -> Option<&MathFont> { + self.math.get_or_init(|| MathFont::parse(self.buffer()).ok()).as_ref() + } + /// Convert from font units to an em length. pub fn to_em(&self, units: impl Into<f64>) -> Em { Em::from_units(units, self.units_per_em()) diff --git a/src/library/math/rex.rs b/src/library/math/rex.rs index addf56b6..0268fb9c 100644 --- a/src/library/math/rex.rs +++ b/src/library/math/rex.rs @@ -35,13 +35,13 @@ impl Layout for RexNode { .at(span)?; // Prepare the font. - let data = ctx.fonts.get(face_id).buffer(); - let font = MathFont::parse(data) - .map_err(|_| "failed to parse math font") + let face = ctx.fonts.get(face_id); + let ctx = face + .math() + .and_then(FontContext::new) + .ok_or("font is not suitable for math") .at(span)?; - let ctx = FontContext::new(&font).ok_or("failed to parse math font").at(span)?; - // Layout the formula. let em = styles.get(TextNode::SIZE); let style = if self.display { Style::Display } else { Style::Text }; |
