summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-05-24 19:30:09 +0200
committerLaurenz <laurmaedje@gmail.com>2022-05-24 19:30:09 +0200
commit018860da9c72df846d80051a1408b3e632fbaaf6 (patch)
treef499a4908cd59b087b107015789a606b370fd1fd /src
parentacdde6d3266d4158241c2e62aa88a1185a3016fd (diff)
Parse math fonts only once
Diffstat (limited to 'src')
-rw-r--r--src/font.rs17
-rw-r--r--src/library/math/rex.rs10
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 };