1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! Font metric data storage
//! This file contains font metric data and measurements for KaTeX
//! Generated from the original JavaScript fontMetricsData.js using phf macros
use crate::{ParseError, font_metrics::MetricMap, namespace::KeyMap, types::ParseErrorKind};
/// Font metrics for a single character
/// The array contains: [depth, height, italic, skew, width]
#[derive(Debug, Clone, Copy)]
pub struct CharacterMetrics {
/// Depth of the character
pub depth: f64,
/// Height of the character
pub height: f64,
/// Italic correction
pub italic: f64,
/// Skew of the character
pub skew: f64,
/// Width of the character
pub width: f64,
}
impl CharacterMetrics {
/// Create a new FontMetrics instance
#[must_use]
pub const fn new(depth: f64, height: f64, italic: f64, skew: f64, width: f64) -> Self {
Self {
depth,
height,
italic,
skew,
width,
}
}
}
// Include the generated phf maps from the build script
include!(concat!(env!("OUT_DIR"), "/font_metrics_data_phf.rs"));
/// Main font metrics data structure
#[derive(Default)]
pub struct FontMetricsData {
/// Custom font metrics added at runtime
pub custom: KeyMap<String, MetricMap>,
}
impl FontMetricsData {
/// Get metrics for a specific character in a font family
pub fn get_metric(
&self,
font_family: &str,
char_code: u32,
) -> Result<Option<&CharacterMetrics>, ParseError> {
if let Some(metrics) = FONT_METRICS_INDEX.get(font_family) {
return Ok(metrics.get(&char_code));
}
if let Some(custom_metrics) = self.custom.get(font_family) {
return Ok(custom_metrics.get(&char_code));
}
Err(ParseError::new(ParseErrorKind::FontMetricsNotFound {
font_family: font_family.to_owned(),
}))
}
/// Create a new FontMetricsData instance with optional custom metrics
pub fn add_custom_metrics(
&mut self,
font_family: String,
char_code: u32,
metrics: CharacterMetrics,
) {
self.custom
.entry(font_family)
.or_default()
.insert(char_code, metrics);
}
}