1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(default)]
9pub struct FontVariableAxisInfo {
10 pub tag: String,
11 pub min_bits: u32,
12 pub max_bits: u32,
13 pub default_bits: u32,
14}
15
16impl FontVariableAxisInfo {
17 pub fn min(&self) -> f32 {
18 f32::from_bits(self.min_bits)
19 }
20
21 pub fn max(&self) -> f32 {
22 f32::from_bits(self.max_bits)
23 }
24
25 pub fn default(&self) -> f32 {
26 f32::from_bits(self.default_bits)
27 }
28}
29
30#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(default)]
36pub struct FontCatalog {
37 pub families: Vec<String>,
38 pub revision: u64,
43}
44
45#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
51#[serde(default)]
52pub struct FontCatalogEntry {
53 pub family: String,
54 pub has_variable_axes: bool,
56 pub known_variable_axes: Vec<String>,
58 #[serde(default)]
62 pub variable_axes: Vec<FontVariableAxisInfo>,
63 pub is_monospace_candidate: bool,
65}
66
67#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(default)]
73pub struct FontCatalogMetadata {
74 pub entries: Vec<FontCatalogEntry>,
75 pub revision: u64,
77}
78
79#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
80pub enum BundledFontBaselineSource {
81 #[default]
82 None,
83 BundledProfile,
84}
85
86#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
94#[serde(default)]
95pub struct BundledFontBaselineSnapshot {
96 pub source: BundledFontBaselineSource,
97 pub profile_name: Option<String>,
98 pub asset_bundle: Option<String>,
99 pub asset_keys: Vec<String>,
100 pub provided_roles: Vec<String>,
101 pub guaranteed_generic_families: Vec<String>,
102}
103
104impl BundledFontBaselineSnapshot {
105 pub fn none() -> Self {
106 Self::default()
107 }
108
109 pub fn bundled_profile(
110 profile_name: impl Into<String>,
111 asset_bundle: impl Into<String>,
112 asset_keys: Vec<String>,
113 provided_roles: Vec<String>,
114 guaranteed_generic_families: Vec<String>,
115 ) -> Self {
116 Self {
117 source: BundledFontBaselineSource::BundledProfile,
118 profile_name: Some(profile_name.into()),
119 asset_bundle: Some(asset_bundle.into()),
120 asset_keys,
121 provided_roles,
122 guaranteed_generic_families,
123 }
124 }
125}
126
127#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
128pub enum RendererFontSourceLane {
129 #[default]
130 BundledStartup,
131 AssetRequest,
132}
133
134#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
135#[serde(default)]
136pub struct RendererFontSourceRecord {
137 pub source_lane: RendererFontSourceLane,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub asset_request: Option<fret_assets::AssetRequest>,
140 pub byte_hash: u64,
141 pub byte_len: u64,
142 pub added_face_count: u64,
143}
144
145impl RendererFontSourceRecord {
146 pub fn bundled_startup(
147 asset_request: fret_assets::AssetRequest,
148 byte_hash: u64,
149 byte_len: u64,
150 added_face_count: u64,
151 ) -> Self {
152 Self {
153 source_lane: RendererFontSourceLane::BundledStartup,
154 asset_request: Some(asset_request),
155 byte_hash,
156 byte_len,
157 added_face_count,
158 }
159 }
160
161 pub fn asset_request(
162 asset_request: fret_assets::AssetRequest,
163 byte_hash: u64,
164 byte_len: u64,
165 added_face_count: u64,
166 ) -> Self {
167 Self {
168 source_lane: RendererFontSourceLane::AssetRequest,
169 asset_request: Some(asset_request),
170 byte_hash,
171 byte_len,
172 added_face_count,
173 }
174 }
175}
176
177#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
187#[serde(default)]
188pub struct RendererFontEnvironmentSnapshot {
189 pub revision: u64,
190 #[serde(default, skip_serializing_if = "Option::is_none")]
191 pub text_font_stack_key: Option<u64>,
192 #[serde(default)]
193 pub sources: Vec<RendererFontSourceRecord>,
194}
195
196impl RendererFontEnvironmentSnapshot {
197 pub fn note_text_font_stack_key(&mut self, text_font_stack_key: u64) -> bool {
198 if self.text_font_stack_key == Some(text_font_stack_key) {
199 return false;
200 }
201
202 self.text_font_stack_key = Some(text_font_stack_key);
203 self.revision = self.revision.saturating_add(1);
204 true
205 }
206
207 pub fn extend_sources_unique(
208 &mut self,
209 sources: impl IntoIterator<Item = RendererFontSourceRecord>,
210 ) -> bool {
211 let mut changed = false;
212 for source in sources {
213 if self.sources.iter().any(|existing| existing == &source) {
214 continue;
215 }
216 self.sources.push(source);
217 changed = true;
218 }
219 changed
220 }
221}
222
223#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
228#[serde(default)]
229pub struct RendererSvgTextBridgeDiagnosticsSnapshot {
230 #[serde(default, skip_serializing_if = "Option::is_none")]
231 pub revision: Option<u64>,
232 #[serde(default)]
233 pub selection_misses: Vec<RendererSvgTextFontSelectionMissRecord>,
234 #[serde(default)]
235 pub fallback_records: Vec<RendererSvgTextFontFallbackRecord>,
236 #[serde(default)]
237 pub missing_glyphs: Vec<RendererSvgTextMissingGlyphRecord>,
238}
239
240#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
241pub struct RendererSvgTextFontSelectionMissRecord {
242 pub requested_families: Vec<String>,
243 pub weight: u16,
244 pub style: String,
245 pub stretch: String,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
249pub struct RendererSvgTextFontFallbackRecord {
250 pub text: String,
251 pub from_family: String,
252 pub to_family: String,
253}
254
255#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
256pub struct RendererSvgTextMissingGlyphRecord {
257 pub text: String,
258 pub resolved_family: String,
259}
260
261#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
266pub struct TextFontStackKey(pub u64);
267
268#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
274pub struct SystemFontRescanState {
275 pub in_flight: bool,
277 pub pending: bool,
279}