/src/fontations/write-fonts/generated/generated_ift.rs
Line | Count | Source |
1 | | // THIS FILE IS AUTOGENERATED. |
2 | | // Any changes to this file will be overwritten. |
3 | | // For more information about how codegen works, see font-codegen/README.md |
4 | | |
5 | | #[allow(unused_imports)] |
6 | | use crate::codegen_prelude::*; |
7 | | |
8 | | pub use read_fonts::tables::ift::{ |
9 | | EntryFormatFlags, GlyphKeyedFlags, PatchMapFieldPresenceFlags, TablePatchFlags, |
10 | | }; |
11 | | |
12 | | impl FontWrite for PatchMapFieldPresenceFlags { |
13 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
14 | 0 | writer.write_slice(&self.bits().to_be_bytes()) |
15 | 0 | } |
16 | | } |
17 | | |
18 | | /// [Patch Map Table](https://w3c.github.io/IFT/Overview.html#patch-map-table) |
19 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
20 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
21 | | pub struct IftPatchMap { |
22 | | /// Format identifier: format = 2 |
23 | | pub format: u8, |
24 | | pub field_flags: PatchMapFieldPresenceFlags, |
25 | | /// Unique ID that identifies compatible patches. |
26 | | pub compatibility_id: CompatibilityId, |
27 | | /// Patch format number for patches referenced by this mapping. |
28 | | pub default_patch_format: u8, |
29 | | pub entry_count: Uint24, |
30 | | pub entries: OffsetMarker<MappingEntries, WIDTH_32>, |
31 | | pub entry_id_string_data: NullableOffsetMarker<IdStringData, WIDTH_32>, |
32 | | pub url_template_length: u16, |
33 | | pub url_template: Vec<u8>, |
34 | | pub cff_charstrings_offset: Option<u32>, |
35 | | pub cff2_charstrings_offset: Option<u32>, |
36 | | } |
37 | | |
38 | | impl IftPatchMap { |
39 | | /// Construct a new `IftPatchMap` |
40 | | #[allow(clippy::too_many_arguments)] |
41 | 0 | pub fn new( |
42 | 0 | format: u8, |
43 | 0 | field_flags: PatchMapFieldPresenceFlags, |
44 | 0 | compatibility_id: CompatibilityId, |
45 | 0 | default_patch_format: u8, |
46 | 0 | entry_count: Uint24, |
47 | 0 | entries: MappingEntries, |
48 | 0 | entry_id_string_data: Option<IdStringData>, |
49 | 0 | url_template_length: u16, |
50 | 0 | url_template: Vec<u8>, |
51 | 0 | ) -> Self { |
52 | 0 | Self { |
53 | 0 | format, |
54 | 0 | field_flags, |
55 | 0 | compatibility_id, |
56 | 0 | default_patch_format, |
57 | 0 | entry_count, |
58 | 0 | entries: entries.into(), |
59 | 0 | entry_id_string_data: entry_id_string_data.into(), |
60 | 0 | url_template_length, |
61 | 0 | url_template, |
62 | 0 | ..Default::default() |
63 | 0 | } |
64 | 0 | } |
65 | | } |
66 | | |
67 | | impl FontWrite for IftPatchMap { |
68 | | #[allow(clippy::unnecessary_cast)] |
69 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
70 | 0 | self.format.write_into(writer); |
71 | 0 | (0 as u8).write_into(writer); |
72 | 0 | (0 as u8).write_into(writer); |
73 | 0 | (0 as u8).write_into(writer); |
74 | 0 | self.field_flags.write_into(writer); |
75 | 0 | self.compatibility_id.write_into(writer); |
76 | 0 | self.default_patch_format.write_into(writer); |
77 | 0 | self.entry_count.write_into(writer); |
78 | 0 | self.entries.write_into(writer); |
79 | 0 | self.entry_id_string_data.write_into(writer); |
80 | 0 | self.url_template_length.write_into(writer); |
81 | 0 | self.url_template.write_into(writer); |
82 | 0 | self.field_flags |
83 | 0 | .contains(PatchMapFieldPresenceFlags::CFF_CHARSTRINGS_OFFSET) |
84 | 0 | .then(|| { |
85 | 0 | self.cff_charstrings_offset |
86 | 0 | .as_ref() |
87 | 0 | .expect("missing conditional field should have failed validation") |
88 | 0 | .write_into(writer) |
89 | 0 | }); |
90 | 0 | self.field_flags |
91 | 0 | .contains(PatchMapFieldPresenceFlags::CFF2_CHARSTRINGS_OFFSET) |
92 | 0 | .then(|| { |
93 | 0 | self.cff2_charstrings_offset |
94 | 0 | .as_ref() |
95 | 0 | .expect("missing conditional field should have failed validation") |
96 | 0 | .write_into(writer) |
97 | 0 | }); |
98 | 0 | } |
99 | 0 | fn table_type(&self) -> TableType { |
100 | 0 | TableType::Named("IftPatchMap") |
101 | 0 | } |
102 | | } |
103 | | |
104 | | impl Validate for IftPatchMap { |
105 | 0 | fn validate_impl(&self, ctx: &mut ValidationCtx) { |
106 | 0 | ctx.in_table("IftPatchMap", |ctx| { |
107 | 0 | ctx.in_field("entries", |ctx| { |
108 | 0 | self.entries.validate_impl(ctx); |
109 | 0 | }); |
110 | 0 | ctx.in_field("entry_id_string_data", |ctx| { |
111 | 0 | self.entry_id_string_data.validate_impl(ctx); |
112 | 0 | }); |
113 | 0 | ctx.in_field("url_template", |ctx| { |
114 | 0 | if self.url_template.len() > to_usize(u16::MAX) { |
115 | 0 | ctx.report("array exceeds max length"); |
116 | 0 | } |
117 | 0 | }); |
118 | 0 | ctx.in_field("cff_charstrings_offset", |ctx| { |
119 | 0 | if !(self |
120 | 0 | .field_flags |
121 | 0 | .contains(PatchMapFieldPresenceFlags::CFF_CHARSTRINGS_OFFSET)) |
122 | 0 | && self.cff_charstrings_offset.is_some() |
123 | | { |
124 | 0 | ctx.report( |
125 | | "'cff_charstrings_offset' is present but CFF_CHARSTRINGS_OFFSET not set", |
126 | | ) |
127 | 0 | } |
128 | 0 | if (self |
129 | 0 | .field_flags |
130 | 0 | .contains(PatchMapFieldPresenceFlags::CFF_CHARSTRINGS_OFFSET)) |
131 | 0 | && self.cff_charstrings_offset.is_none() |
132 | | { |
133 | 0 | ctx.report("CFF_CHARSTRINGS_OFFSET is set but 'cff_charstrings_offset' is None") |
134 | 0 | } |
135 | 0 | }); |
136 | 0 | ctx.in_field("cff2_charstrings_offset", |ctx| { |
137 | 0 | if !(self |
138 | 0 | .field_flags |
139 | 0 | .contains(PatchMapFieldPresenceFlags::CFF2_CHARSTRINGS_OFFSET)) |
140 | 0 | && self.cff2_charstrings_offset.is_some() |
141 | | { |
142 | 0 | ctx.report( |
143 | | "'cff2_charstrings_offset' is present but CFF2_CHARSTRINGS_OFFSET not set", |
144 | | ) |
145 | 0 | } |
146 | 0 | if (self |
147 | 0 | .field_flags |
148 | 0 | .contains(PatchMapFieldPresenceFlags::CFF2_CHARSTRINGS_OFFSET)) |
149 | 0 | && self.cff2_charstrings_offset.is_none() |
150 | | { |
151 | 0 | ctx.report( |
152 | | "CFF2_CHARSTRINGS_OFFSET is set but 'cff2_charstrings_offset' is None", |
153 | | ) |
154 | 0 | } |
155 | 0 | }); |
156 | 0 | }) |
157 | 0 | } |
158 | | } |
159 | | |
160 | | impl<'a> FromObjRef<read_fonts::tables::ift::IftPatchMap<'a>> for IftPatchMap { |
161 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::IftPatchMap<'a>, _: FontData) -> Self { |
162 | 0 | let offset_data = obj.offset_data(); |
163 | 0 | IftPatchMap { |
164 | 0 | format: obj.format(), |
165 | 0 | field_flags: obj.field_flags(), |
166 | 0 | compatibility_id: obj.compatibility_id(), |
167 | 0 | default_patch_format: obj.default_patch_format(), |
168 | 0 | entry_count: obj.entry_count(), |
169 | 0 | entries: obj.entries().to_owned_table(), |
170 | 0 | entry_id_string_data: obj.entry_id_string_data().to_owned_table(), |
171 | 0 | url_template_length: obj.url_template_length(), |
172 | 0 | url_template: obj.url_template().to_owned_obj(offset_data), |
173 | 0 | cff_charstrings_offset: obj.cff_charstrings_offset(), |
174 | 0 | cff2_charstrings_offset: obj.cff2_charstrings_offset(), |
175 | 0 | } |
176 | 0 | } |
177 | | } |
178 | | |
179 | | #[allow(clippy::needless_lifetimes)] |
180 | | impl<'a> FromTableRef<read_fonts::tables::ift::IftPatchMap<'a>> for IftPatchMap {} |
181 | | |
182 | | impl ReadArgs for IftPatchMap { |
183 | | type Args = (); |
184 | | } |
185 | | |
186 | | impl<'a> FontRead<'a> for IftPatchMap { |
187 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
188 | 0 | <read_fonts::tables::ift::IftPatchMap as FontRead>::read(data).map(|x| x.to_owned_table()) |
189 | 0 | } |
190 | | } |
191 | | |
192 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
193 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
194 | | pub struct MappingEntries { |
195 | | pub entry_data: Vec<u8>, |
196 | | } |
197 | | |
198 | | impl MappingEntries { |
199 | | /// Construct a new `MappingEntries` |
200 | 0 | pub fn new(entry_data: Vec<u8>) -> Self { |
201 | 0 | Self { entry_data } |
202 | 0 | } |
203 | | } |
204 | | |
205 | | impl FontWrite for MappingEntries { |
206 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
207 | 0 | self.entry_data.write_into(writer); |
208 | 0 | } |
209 | 0 | fn table_type(&self) -> TableType { |
210 | 0 | TableType::Named("MappingEntries") |
211 | 0 | } |
212 | | } |
213 | | |
214 | | impl Validate for MappingEntries { |
215 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
216 | | } |
217 | | |
218 | | impl<'a> FromObjRef<read_fonts::tables::ift::MappingEntries<'a>> for MappingEntries { |
219 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::MappingEntries<'a>, _: FontData) -> Self { |
220 | 0 | let offset_data = obj.offset_data(); |
221 | 0 | MappingEntries { |
222 | 0 | entry_data: obj.entry_data().to_owned_obj(offset_data), |
223 | 0 | } |
224 | 0 | } |
225 | | } |
226 | | |
227 | | #[allow(clippy::needless_lifetimes)] |
228 | | impl<'a> FromTableRef<read_fonts::tables::ift::MappingEntries<'a>> for MappingEntries {} |
229 | | |
230 | | impl ReadArgs for MappingEntries { |
231 | | type Args = (); |
232 | | } |
233 | | |
234 | | impl<'a> FontRead<'a> for MappingEntries { |
235 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
236 | 0 | <read_fonts::tables::ift::MappingEntries as FontRead>::read(data) |
237 | 0 | .map(|x| x.to_owned_table()) |
238 | 0 | } |
239 | | } |
240 | | |
241 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
242 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
243 | | pub struct EntryData { |
244 | | pub format_flags: EntryFormatFlags, |
245 | | pub feature_count: Option<u8>, |
246 | | pub feature_tags: Option<Vec<Tag>>, |
247 | | pub design_space_count: Option<u16>, |
248 | | pub design_space_segments: Option<Vec<DesignSpaceSegment>>, |
249 | | pub child_indices: Option<Vec<Uint24>>, |
250 | | pub trailing_data: Vec<u8>, |
251 | | } |
252 | | |
253 | | impl EntryData { |
254 | | /// Construct a new `EntryData` |
255 | 0 | pub fn new(format_flags: EntryFormatFlags, trailing_data: Vec<u8>) -> Self { |
256 | 0 | Self { |
257 | 0 | format_flags, |
258 | 0 | trailing_data, |
259 | 0 | ..Default::default() |
260 | 0 | } |
261 | 0 | } |
262 | | } |
263 | | |
264 | | impl FontWrite for EntryData { |
265 | | #[allow(clippy::unnecessary_cast)] |
266 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
267 | 0 | self.format_flags.write_into(writer); |
268 | 0 | self.format_flags |
269 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE) |
270 | 0 | .then(|| { |
271 | 0 | self.feature_count |
272 | 0 | .as_ref() |
273 | 0 | .expect("missing conditional field should have failed validation") |
274 | 0 | .write_into(writer) |
275 | 0 | }); |
276 | 0 | self.format_flags |
277 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE) |
278 | 0 | .then(|| { |
279 | 0 | self.feature_tags |
280 | 0 | .as_ref() |
281 | 0 | .expect("missing conditional field should have failed validation") |
282 | 0 | .write_into(writer) |
283 | 0 | }); |
284 | 0 | self.format_flags |
285 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE) |
286 | 0 | .then(|| { |
287 | 0 | self.design_space_count |
288 | 0 | .as_ref() |
289 | 0 | .expect("missing conditional field should have failed validation") |
290 | 0 | .write_into(writer) |
291 | 0 | }); |
292 | 0 | self.format_flags |
293 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE) |
294 | 0 | .then(|| { |
295 | 0 | self.design_space_segments |
296 | 0 | .as_ref() |
297 | 0 | .expect("missing conditional field should have failed validation") |
298 | 0 | .write_into(writer) |
299 | 0 | }); |
300 | 0 | self.format_flags |
301 | 0 | .contains(EntryFormatFlags::CHILD_INDICES) |
302 | 0 | .then(|| { |
303 | 0 | self.child_indices |
304 | 0 | .as_ref() |
305 | 0 | .expect("missing conditional field should have failed validation") |
306 | 0 | .write_into(writer) |
307 | 0 | }); |
308 | 0 | self.trailing_data.write_into(writer); |
309 | 0 | } |
310 | 0 | fn table_type(&self) -> TableType { |
311 | 0 | TableType::Named("EntryData") |
312 | 0 | } |
313 | | } |
314 | | |
315 | | impl Validate for EntryData { |
316 | 0 | fn validate_impl(&self, ctx: &mut ValidationCtx) { |
317 | 0 | ctx.in_table("EntryData", |ctx| { |
318 | 0 | ctx.in_field("feature_count", |ctx| { |
319 | 0 | if !(self |
320 | 0 | .format_flags |
321 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
322 | 0 | && self.feature_count.is_some() |
323 | | { |
324 | 0 | ctx.report("'feature_count' is present but FEATURES_AND_DESIGN_SPACE not set") |
325 | 0 | } |
326 | 0 | if (self |
327 | 0 | .format_flags |
328 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
329 | 0 | && self.feature_count.is_none() |
330 | | { |
331 | 0 | ctx.report("FEATURES_AND_DESIGN_SPACE is set but 'feature_count' is None") |
332 | 0 | } |
333 | 0 | }); |
334 | 0 | ctx.in_field("feature_tags", |ctx| { |
335 | 0 | if !(self |
336 | 0 | .format_flags |
337 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
338 | 0 | && self.feature_tags.is_some() |
339 | | { |
340 | 0 | ctx.report("'feature_tags' is present but FEATURES_AND_DESIGN_SPACE not set") |
341 | 0 | } |
342 | 0 | if (self |
343 | 0 | .format_flags |
344 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
345 | 0 | && self.feature_tags.is_none() |
346 | | { |
347 | 0 | ctx.report("FEATURES_AND_DESIGN_SPACE is set but 'feature_tags' is None") |
348 | 0 | } |
349 | 0 | if self.feature_tags.is_some() |
350 | 0 | && self.feature_tags.as_ref().unwrap().len() > to_usize(u8::MAX) |
351 | 0 | { |
352 | 0 | ctx.report("array exceeds max length"); |
353 | 0 | } |
354 | 0 | }); |
355 | 0 | ctx.in_field("design_space_count", |ctx| { |
356 | 0 | if !(self |
357 | 0 | .format_flags |
358 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
359 | 0 | && self.design_space_count.is_some() |
360 | | { |
361 | 0 | ctx.report( |
362 | | "'design_space_count' is present but FEATURES_AND_DESIGN_SPACE not set", |
363 | | ) |
364 | 0 | } |
365 | 0 | if (self |
366 | 0 | .format_flags |
367 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
368 | 0 | && self.design_space_count.is_none() |
369 | | { |
370 | 0 | ctx.report("FEATURES_AND_DESIGN_SPACE is set but 'design_space_count' is None") |
371 | 0 | } |
372 | 0 | }); |
373 | 0 | ctx.in_field("design_space_segments", |ctx| { |
374 | 0 | if !(self |
375 | 0 | .format_flags |
376 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
377 | 0 | && self.design_space_segments.is_some() |
378 | | { |
379 | 0 | ctx.report( |
380 | | "'design_space_segments' is present but FEATURES_AND_DESIGN_SPACE not set", |
381 | | ) |
382 | 0 | } |
383 | 0 | if (self |
384 | 0 | .format_flags |
385 | 0 | .contains(EntryFormatFlags::FEATURES_AND_DESIGN_SPACE)) |
386 | 0 | && self.design_space_segments.is_none() |
387 | | { |
388 | 0 | ctx.report( |
389 | | "FEATURES_AND_DESIGN_SPACE is set but 'design_space_segments' is None", |
390 | | ) |
391 | 0 | } |
392 | 0 | if self.design_space_segments.is_some() |
393 | 0 | && self.design_space_segments.as_ref().unwrap().len() > to_usize(u16::MAX) |
394 | 0 | { |
395 | 0 | ctx.report("array exceeds max length"); |
396 | 0 | } |
397 | 0 | self.design_space_segments.validate_impl(ctx); |
398 | 0 | }); |
399 | 0 | ctx.in_field("child_indices", |ctx| { |
400 | 0 | if !(self.format_flags.contains(EntryFormatFlags::CHILD_INDICES)) |
401 | 0 | && self.child_indices.is_some() |
402 | | { |
403 | 0 | ctx.report("'child_indices' is present but CHILD_INDICES not set") |
404 | 0 | } |
405 | 0 | if (self.format_flags.contains(EntryFormatFlags::CHILD_INDICES)) |
406 | 0 | && self.child_indices.is_none() |
407 | | { |
408 | 0 | ctx.report("CHILD_INDICES is set but 'child_indices' is None") |
409 | 0 | } |
410 | 0 | }); |
411 | 0 | }) |
412 | 0 | } |
413 | | } |
414 | | |
415 | | impl<'a> FromObjRef<read_fonts::tables::ift::EntryData<'a>> for EntryData { |
416 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::EntryData<'a>, _: FontData) -> Self { |
417 | 0 | let offset_data = obj.offset_data(); |
418 | 0 | EntryData { |
419 | 0 | format_flags: obj.format_flags(), |
420 | 0 | feature_count: obj.feature_count(), |
421 | 0 | feature_tags: obj.feature_tags().to_owned_obj(offset_data), |
422 | 0 | design_space_count: obj.design_space_count(), |
423 | 0 | design_space_segments: obj.design_space_segments().to_owned_obj(offset_data), |
424 | 0 | child_indices: obj.child_indices().to_owned_obj(offset_data), |
425 | 0 | trailing_data: obj.trailing_data().to_owned_obj(offset_data), |
426 | 0 | } |
427 | 0 | } |
428 | | } |
429 | | |
430 | | #[allow(clippy::needless_lifetimes)] |
431 | | impl<'a> FromTableRef<read_fonts::tables::ift::EntryData<'a>> for EntryData {} |
432 | | |
433 | | impl ReadArgs for EntryData { |
434 | | type Args = (); |
435 | | } |
436 | | |
437 | | impl<'a> FontRead<'a> for EntryData { |
438 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
439 | 0 | <read_fonts::tables::ift::EntryData as FontRead>::read(data).map(|x| x.to_owned_table()) |
440 | 0 | } |
441 | | } |
442 | | |
443 | | impl FontWrite for EntryFormatFlags { |
444 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
445 | 0 | writer.write_slice(&self.bits().to_be_bytes()) |
446 | 0 | } |
447 | | } |
448 | | |
449 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
450 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
451 | | pub struct DesignSpaceSegment { |
452 | | pub axis_tag: Tag, |
453 | | pub start: Fixed, |
454 | | pub end: Fixed, |
455 | | } |
456 | | |
457 | | impl DesignSpaceSegment { |
458 | | /// Construct a new `DesignSpaceSegment` |
459 | 0 | pub fn new(axis_tag: Tag, start: Fixed, end: Fixed) -> Self { |
460 | 0 | Self { |
461 | 0 | axis_tag, |
462 | 0 | start, |
463 | 0 | end, |
464 | 0 | } |
465 | 0 | } |
466 | | } |
467 | | |
468 | | impl FontWrite for DesignSpaceSegment { |
469 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
470 | 0 | self.axis_tag.write_into(writer); |
471 | 0 | self.start.write_into(writer); |
472 | 0 | self.end.write_into(writer); |
473 | 0 | } |
474 | 0 | fn table_type(&self) -> TableType { |
475 | 0 | TableType::Named("DesignSpaceSegment") |
476 | 0 | } |
477 | | } |
478 | | |
479 | | impl Validate for DesignSpaceSegment { |
480 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
481 | | } |
482 | | |
483 | | impl FromObjRef<read_fonts::tables::ift::DesignSpaceSegment> for DesignSpaceSegment { |
484 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::DesignSpaceSegment, _: FontData) -> Self { |
485 | 0 | DesignSpaceSegment { |
486 | 0 | axis_tag: obj.axis_tag(), |
487 | 0 | start: obj.start(), |
488 | 0 | end: obj.end(), |
489 | 0 | } |
490 | 0 | } |
491 | | } |
492 | | |
493 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
494 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
495 | | pub struct IdStringData { |
496 | | pub id_data: Vec<u8>, |
497 | | } |
498 | | |
499 | | impl IdStringData { |
500 | | /// Construct a new `IdStringData` |
501 | 0 | pub fn new(id_data: Vec<u8>) -> Self { |
502 | 0 | Self { id_data } |
503 | 0 | } |
504 | | } |
505 | | |
506 | | impl FontWrite for IdStringData { |
507 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
508 | 0 | self.id_data.write_into(writer); |
509 | 0 | } |
510 | 0 | fn table_type(&self) -> TableType { |
511 | 0 | TableType::Named("IdStringData") |
512 | 0 | } |
513 | | } |
514 | | |
515 | | impl Validate for IdStringData { |
516 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
517 | | } |
518 | | |
519 | | impl<'a> FromObjRef<read_fonts::tables::ift::IdStringData<'a>> for IdStringData { |
520 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::IdStringData<'a>, _: FontData) -> Self { |
521 | 0 | let offset_data = obj.offset_data(); |
522 | 0 | IdStringData { |
523 | 0 | id_data: obj.id_data().to_owned_obj(offset_data), |
524 | 0 | } |
525 | 0 | } |
526 | | } |
527 | | |
528 | | #[allow(clippy::needless_lifetimes)] |
529 | | impl<'a> FromTableRef<read_fonts::tables::ift::IdStringData<'a>> for IdStringData {} |
530 | | |
531 | | impl ReadArgs for IdStringData { |
532 | | type Args = (); |
533 | | } |
534 | | |
535 | | impl<'a> FontRead<'a> for IdStringData { |
536 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
537 | 0 | <read_fonts::tables::ift::IdStringData as FontRead>::read(data).map(|x| x.to_owned_table()) |
538 | 0 | } |
539 | | } |
540 | | |
541 | | /// [Table Keyed Patch](https://w3c.github.io/IFT/Overview.html#table-keyed) |
542 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
543 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
544 | | pub struct TableKeyedPatch { |
545 | | pub format: Tag, |
546 | | /// Unique ID that identifies compatible patches. |
547 | | pub compatibility_id: CompatibilityId, |
548 | | pub patches_count: u16, |
549 | | pub patches: Vec<OffsetMarker<TablePatch, WIDTH_32>>, |
550 | | } |
551 | | |
552 | | impl TableKeyedPatch { |
553 | | /// Construct a new `TableKeyedPatch` |
554 | 0 | pub fn new( |
555 | 0 | format: Tag, |
556 | 0 | compatibility_id: CompatibilityId, |
557 | 0 | patches_count: u16, |
558 | 0 | patches: Vec<TablePatch>, |
559 | 0 | ) -> Self { |
560 | 0 | Self { |
561 | 0 | format, |
562 | 0 | compatibility_id, |
563 | 0 | patches_count, |
564 | 0 | patches: patches.into_iter().map(Into::into).collect(), |
565 | 0 | } |
566 | 0 | } |
567 | | } |
568 | | |
569 | | impl FontWrite for TableKeyedPatch { |
570 | | #[allow(clippy::unnecessary_cast)] |
571 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
572 | 0 | self.format.write_into(writer); |
573 | 0 | (0 as u32).write_into(writer); |
574 | 0 | self.compatibility_id.write_into(writer); |
575 | 0 | self.patches_count.write_into(writer); |
576 | 0 | self.patches.write_into(writer); |
577 | 0 | } |
578 | 0 | fn table_type(&self) -> TableType { |
579 | 0 | TableType::Named("TableKeyedPatch") |
580 | 0 | } |
581 | | } |
582 | | |
583 | | impl Validate for TableKeyedPatch { |
584 | 0 | fn validate_impl(&self, ctx: &mut ValidationCtx) { |
585 | 0 | ctx.in_table("TableKeyedPatch", |ctx| { |
586 | 0 | ctx.in_field("patches", |ctx| { |
587 | 0 | self.patches.validate_impl(ctx); |
588 | 0 | }); |
589 | 0 | }) |
590 | 0 | } |
591 | | } |
592 | | |
593 | | impl<'a> FromObjRef<read_fonts::tables::ift::TableKeyedPatch<'a>> for TableKeyedPatch { |
594 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::TableKeyedPatch<'a>, _: FontData) -> Self { |
595 | 0 | TableKeyedPatch { |
596 | 0 | format: obj.format(), |
597 | 0 | compatibility_id: obj.compatibility_id(), |
598 | 0 | patches_count: obj.patches_count(), |
599 | 0 | patches: obj.patches().to_owned_table(), |
600 | 0 | } |
601 | 0 | } |
602 | | } |
603 | | |
604 | | #[allow(clippy::needless_lifetimes)] |
605 | | impl<'a> FromTableRef<read_fonts::tables::ift::TableKeyedPatch<'a>> for TableKeyedPatch {} |
606 | | |
607 | | impl ReadArgs for TableKeyedPatch { |
608 | | type Args = (); |
609 | | } |
610 | | |
611 | | impl<'a> FontRead<'a> for TableKeyedPatch { |
612 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
613 | 0 | <read_fonts::tables::ift::TableKeyedPatch as FontRead>::read(data) |
614 | 0 | .map(|x| x.to_owned_table()) |
615 | 0 | } |
616 | | } |
617 | | |
618 | | /// [TablePatch](https://w3c.github.io/IFT/Overview.html#tablepatch) |
619 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
620 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
621 | | pub struct TablePatch { |
622 | | pub tag: Tag, |
623 | | pub flags: TablePatchFlags, |
624 | | pub max_uncompressed_length: u32, |
625 | | pub brotli_stream: Vec<u8>, |
626 | | } |
627 | | |
628 | | impl TablePatch { |
629 | | /// Construct a new `TablePatch` |
630 | 0 | pub fn new( |
631 | 0 | tag: Tag, |
632 | 0 | flags: TablePatchFlags, |
633 | 0 | max_uncompressed_length: u32, |
634 | 0 | brotli_stream: Vec<u8>, |
635 | 0 | ) -> Self { |
636 | 0 | Self { |
637 | 0 | tag, |
638 | 0 | flags, |
639 | 0 | max_uncompressed_length, |
640 | 0 | brotli_stream, |
641 | 0 | } |
642 | 0 | } |
643 | | } |
644 | | |
645 | | impl FontWrite for TablePatch { |
646 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
647 | 0 | self.tag.write_into(writer); |
648 | 0 | self.flags.write_into(writer); |
649 | 0 | self.max_uncompressed_length.write_into(writer); |
650 | 0 | self.brotli_stream.write_into(writer); |
651 | 0 | } |
652 | 0 | fn table_type(&self) -> TableType { |
653 | 0 | TableType::Named("TablePatch") |
654 | 0 | } |
655 | | } |
656 | | |
657 | | impl Validate for TablePatch { |
658 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
659 | | } |
660 | | |
661 | | impl<'a> FromObjRef<read_fonts::tables::ift::TablePatch<'a>> for TablePatch { |
662 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::TablePatch<'a>, _: FontData) -> Self { |
663 | 0 | let offset_data = obj.offset_data(); |
664 | 0 | TablePatch { |
665 | 0 | tag: obj.tag(), |
666 | 0 | flags: obj.flags(), |
667 | 0 | max_uncompressed_length: obj.max_uncompressed_length(), |
668 | 0 | brotli_stream: obj.brotli_stream().to_owned_obj(offset_data), |
669 | 0 | } |
670 | 0 | } |
671 | | } |
672 | | |
673 | | #[allow(clippy::needless_lifetimes)] |
674 | | impl<'a> FromTableRef<read_fonts::tables::ift::TablePatch<'a>> for TablePatch {} |
675 | | |
676 | | impl ReadArgs for TablePatch { |
677 | | type Args = (); |
678 | | } |
679 | | |
680 | | impl<'a> FontRead<'a> for TablePatch { |
681 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
682 | 0 | <read_fonts::tables::ift::TablePatch as FontRead>::read(data).map(|x| x.to_owned_table()) |
683 | 0 | } |
684 | | } |
685 | | |
686 | | impl FontWrite for TablePatchFlags { |
687 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
688 | 0 | writer.write_slice(&self.bits().to_be_bytes()) |
689 | 0 | } |
690 | | } |
691 | | |
692 | | /// [Glyph Keyed Patch](https://w3c.github.io/IFT/Overview.html#glyph-keyed) |
693 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
694 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
695 | | pub struct GlyphKeyedPatch { |
696 | | pub format: Tag, |
697 | | pub flags: GlyphKeyedFlags, |
698 | | pub compatibility_id: CompatibilityId, |
699 | | pub max_uncompressed_length: u32, |
700 | | pub brotli_stream: Vec<u8>, |
701 | | } |
702 | | |
703 | | impl GlyphKeyedPatch { |
704 | | /// Construct a new `GlyphKeyedPatch` |
705 | 0 | pub fn new( |
706 | 0 | format: Tag, |
707 | 0 | flags: GlyphKeyedFlags, |
708 | 0 | compatibility_id: CompatibilityId, |
709 | 0 | max_uncompressed_length: u32, |
710 | 0 | brotli_stream: Vec<u8>, |
711 | 0 | ) -> Self { |
712 | 0 | Self { |
713 | 0 | format, |
714 | 0 | flags, |
715 | 0 | compatibility_id, |
716 | 0 | max_uncompressed_length, |
717 | 0 | brotli_stream, |
718 | 0 | } |
719 | 0 | } |
720 | | } |
721 | | |
722 | | impl FontWrite for GlyphKeyedPatch { |
723 | | #[allow(clippy::unnecessary_cast)] |
724 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
725 | 0 | self.format.write_into(writer); |
726 | 0 | (0 as u32).write_into(writer); |
727 | 0 | self.flags.write_into(writer); |
728 | 0 | self.compatibility_id.write_into(writer); |
729 | 0 | self.max_uncompressed_length.write_into(writer); |
730 | 0 | self.brotli_stream.write_into(writer); |
731 | 0 | } |
732 | 0 | fn table_type(&self) -> TableType { |
733 | 0 | TableType::Named("GlyphKeyedPatch") |
734 | 0 | } |
735 | | } |
736 | | |
737 | | impl Validate for GlyphKeyedPatch { |
738 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
739 | | } |
740 | | |
741 | | impl<'a> FromObjRef<read_fonts::tables::ift::GlyphKeyedPatch<'a>> for GlyphKeyedPatch { |
742 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::GlyphKeyedPatch<'a>, _: FontData) -> Self { |
743 | 0 | let offset_data = obj.offset_data(); |
744 | 0 | GlyphKeyedPatch { |
745 | 0 | format: obj.format(), |
746 | 0 | flags: obj.flags(), |
747 | 0 | compatibility_id: obj.compatibility_id(), |
748 | 0 | max_uncompressed_length: obj.max_uncompressed_length(), |
749 | 0 | brotli_stream: obj.brotli_stream().to_owned_obj(offset_data), |
750 | 0 | } |
751 | 0 | } |
752 | | } |
753 | | |
754 | | #[allow(clippy::needless_lifetimes)] |
755 | | impl<'a> FromTableRef<read_fonts::tables::ift::GlyphKeyedPatch<'a>> for GlyphKeyedPatch {} |
756 | | |
757 | | impl ReadArgs for GlyphKeyedPatch { |
758 | | type Args = (); |
759 | | } |
760 | | |
761 | | impl<'a> FontRead<'a> for GlyphKeyedPatch { |
762 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
763 | 0 | <read_fonts::tables::ift::GlyphKeyedPatch as FontRead>::read(data) |
764 | 0 | .map(|x| x.to_owned_table()) |
765 | 0 | } |
766 | | } |
767 | | |
768 | | impl FontWrite for GlyphKeyedFlags { |
769 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
770 | 0 | writer.write_slice(&self.bits().to_be_bytes()) |
771 | 0 | } |
772 | | } |
773 | | |
774 | | /// [GlyphPatches](https://w3c.github.io/IFT/Overview.html#glyphpatches) |
775 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
776 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
777 | | pub struct GlyphPatches { |
778 | | pub glyph_count: u32, |
779 | | pub table_count: u8, |
780 | | pub tables: Vec<Tag>, |
781 | | pub glyph_data: Vec<OffsetMarker<GlyphData, WIDTH_32>>, |
782 | | } |
783 | | |
784 | | impl GlyphPatches { |
785 | | /// Construct a new `GlyphPatches` |
786 | 0 | pub fn new( |
787 | 0 | glyph_count: u32, |
788 | 0 | table_count: u8, |
789 | 0 | tables: Vec<Tag>, |
790 | 0 | glyph_data: Vec<GlyphData>, |
791 | 0 | ) -> Self { |
792 | 0 | Self { |
793 | 0 | glyph_count, |
794 | 0 | table_count, |
795 | 0 | tables, |
796 | 0 | glyph_data: glyph_data.into_iter().map(Into::into).collect(), |
797 | 0 | } |
798 | 0 | } |
799 | | } |
800 | | |
801 | | impl FontWrite for GlyphPatches { |
802 | | #[allow(clippy::unnecessary_cast)] |
803 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
804 | 0 | self.glyph_count.write_into(writer); |
805 | 0 | self.table_count.write_into(writer); |
806 | 0 | self.tables.write_into(writer); |
807 | 0 | self.glyph_data.write_into(writer); |
808 | 0 | } |
809 | 0 | fn table_type(&self) -> TableType { |
810 | 0 | TableType::Named("GlyphPatches") |
811 | 0 | } |
812 | | } |
813 | | |
814 | | impl Validate for GlyphPatches { |
815 | 0 | fn validate_impl(&self, ctx: &mut ValidationCtx) { |
816 | 0 | ctx.in_table("GlyphPatches", |ctx| { |
817 | 0 | ctx.in_field("tables", |ctx| { |
818 | 0 | if self.tables.len() > to_usize(u8::MAX) { |
819 | 0 | ctx.report("array exceeds max length"); |
820 | 0 | } |
821 | 0 | }); |
822 | 0 | ctx.in_field("glyph_data", |ctx| { |
823 | 0 | self.glyph_data.validate_impl(ctx); |
824 | 0 | }); |
825 | 0 | }) |
826 | 0 | } |
827 | | } |
828 | | |
829 | | impl<'a> FromObjRef<read_fonts::tables::ift::GlyphPatches<'a>> for GlyphPatches { |
830 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::GlyphPatches<'a>, _: FontData) -> Self { |
831 | 0 | let offset_data = obj.offset_data(); |
832 | 0 | GlyphPatches { |
833 | 0 | glyph_count: obj.glyph_count(), |
834 | 0 | table_count: obj.table_count(), |
835 | 0 | tables: obj.tables().to_owned_obj(offset_data), |
836 | 0 | glyph_data: obj.glyph_data().to_owned_table(), |
837 | 0 | } |
838 | 0 | } |
839 | | } |
840 | | |
841 | | #[allow(clippy::needless_lifetimes)] |
842 | | impl<'a> FromTableRef<read_fonts::tables::ift::GlyphPatches<'a>> for GlyphPatches {} |
843 | | |
844 | | #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
845 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
846 | | pub struct GlyphData { |
847 | | pub data: Vec<u8>, |
848 | | } |
849 | | |
850 | | impl GlyphData { |
851 | | /// Construct a new `GlyphData` |
852 | 0 | pub fn new(data: Vec<u8>) -> Self { |
853 | 0 | Self { data } |
854 | 0 | } |
855 | | } |
856 | | |
857 | | impl FontWrite for GlyphData { |
858 | 0 | fn write_into(&self, writer: &mut TableWriter) { |
859 | 0 | self.data.write_into(writer); |
860 | 0 | } |
861 | 0 | fn table_type(&self) -> TableType { |
862 | 0 | TableType::Named("GlyphData") |
863 | 0 | } |
864 | | } |
865 | | |
866 | | impl Validate for GlyphData { |
867 | 0 | fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
868 | | } |
869 | | |
870 | | impl<'a> FromObjRef<read_fonts::tables::ift::GlyphData<'a>> for GlyphData { |
871 | 0 | fn from_obj_ref(obj: &read_fonts::tables::ift::GlyphData<'a>, _: FontData) -> Self { |
872 | 0 | let offset_data = obj.offset_data(); |
873 | 0 | GlyphData { |
874 | 0 | data: obj.data().to_owned_obj(offset_data), |
875 | 0 | } |
876 | 0 | } |
877 | | } |
878 | | |
879 | | #[allow(clippy::needless_lifetimes)] |
880 | | impl<'a> FromTableRef<read_fonts::tables::ift::GlyphData<'a>> for GlyphData {} |
881 | | |
882 | | impl ReadArgs for GlyphData { |
883 | | type Args = (); |
884 | | } |
885 | | |
886 | | impl<'a> FontRead<'a> for GlyphData { |
887 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
888 | 0 | <read_fonts::tables::ift::GlyphData as FontRead>::read(data).map(|x| x.to_owned_table()) |
889 | 0 | } |
890 | | } |