mirror of
https://github.com/typst/typst
synced 2025-05-13 12:36:23 +08:00
Parse math fonts only once
This commit is contained in:
parent
acdde6d326
commit
018860da9c
17
src/font.rs
17
src/font.rs
@ -6,6 +6,8 @@ use std::fmt::{self, Debug, Formatter};
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use rex::font::MathFont;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ttf_parser::{name_id, GlyphId, PlatformId, Tag};
|
use ttf_parser::{name_id, GlyphId, PlatformId, Tag};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
@ -246,6 +248,8 @@ pub struct Face {
|
|||||||
ttf: rustybuzz::Face<'static>,
|
ttf: rustybuzz::Face<'static>,
|
||||||
/// The faces metrics.
|
/// The faces metrics.
|
||||||
metrics: FaceMetrics,
|
metrics: FaceMetrics,
|
||||||
|
/// The parsed ReX math font.
|
||||||
|
math: OnceCell<Option<MathFont>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Face {
|
impl Face {
|
||||||
@ -263,7 +267,13 @@ impl Face {
|
|||||||
let ttf = rustybuzz::Face::from_slice(slice, index)?;
|
let ttf = rustybuzz::Face::from_slice(slice, index)?;
|
||||||
let metrics = FaceMetrics::from_ttf(&ttf);
|
let metrics = FaceMetrics::from_ttf(&ttf);
|
||||||
|
|
||||||
Some(Self { buffer, index, ttf, metrics })
|
Some(Self {
|
||||||
|
buffer,
|
||||||
|
index,
|
||||||
|
ttf,
|
||||||
|
metrics,
|
||||||
|
math: OnceCell::new(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The underlying buffer.
|
/// The underlying buffer.
|
||||||
@ -293,6 +303,11 @@ impl Face {
|
|||||||
&self.metrics
|
&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.
|
/// Convert from font units to an em length.
|
||||||
pub fn to_em(&self, units: impl Into<f64>) -> Em {
|
pub fn to_em(&self, units: impl Into<f64>) -> Em {
|
||||||
Em::from_units(units, self.units_per_em())
|
Em::from_units(units, self.units_per_em())
|
||||||
|
@ -35,13 +35,13 @@ impl Layout for RexNode {
|
|||||||
.at(span)?;
|
.at(span)?;
|
||||||
|
|
||||||
// Prepare the font.
|
// Prepare the font.
|
||||||
let data = ctx.fonts.get(face_id).buffer();
|
let face = ctx.fonts.get(face_id);
|
||||||
let font = MathFont::parse(data)
|
let ctx = face
|
||||||
.map_err(|_| "failed to parse math font")
|
.math()
|
||||||
|
.and_then(FontContext::new)
|
||||||
|
.ok_or("font is not suitable for math")
|
||||||
.at(span)?;
|
.at(span)?;
|
||||||
|
|
||||||
let ctx = FontContext::new(&font).ok_or("failed to parse math font").at(span)?;
|
|
||||||
|
|
||||||
// Layout the formula.
|
// Layout the formula.
|
||||||
let em = styles.get(TextNode::SIZE);
|
let em = styles.get(TextNode::SIZE);
|
||||||
let style = if self.display { Style::Display } else { Style::Text };
|
let style = if self.display { Style::Display } else { Style::Text };
|
||||||
|
@ -15,6 +15,12 @@ $[ \sum_{k=0}^n k = \frac{n(n+1)}{2} ]$
|
|||||||
// Test that blackboard style looks nice.
|
// Test that blackboard style looks nice.
|
||||||
$[ f: \mathbb{N} \rightarrow \mathbb{R} ]$
|
$[ f: \mathbb{N} \rightarrow \mathbb{R} ]$
|
||||||
|
|
||||||
|
---
|
||||||
|
#set math(family: "IBM Plex Sans")
|
||||||
|
|
||||||
|
// Error: 1-4 font is not suitable for math
|
||||||
|
$a$
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 1-10 expected '}' found EOF
|
// Error: 1-10 expected '}' found EOF
|
||||||
$\sqrt{x$
|
$\sqrt{x$
|
||||||
|
Loading…
x
Reference in New Issue
Block a user