1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8pub use read_fonts::tables::layout::DeltaFormat;
9
10#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct ScriptList {
14 pub script_records: Vec<ScriptRecord>,
16}
17
18impl ScriptList {
19 pub fn new(script_records: Vec<ScriptRecord>) -> Self {
21 Self { script_records }
22 }
23}
24
25impl FontWrite for ScriptList {
26 #[allow(clippy::unnecessary_cast)]
27 fn write_into(&self, writer: &mut TableWriter) {
28 (u16::try_from(array_len(&self.script_records)).unwrap()).write_into(writer);
29 self.script_records.write_into(writer);
30 }
31 fn table_type(&self) -> TableType {
32 TableType::Named("ScriptList")
33 }
34}
35
36impl Validate for ScriptList {
37 fn validate_impl(&self, ctx: &mut ValidationCtx) {
38 ctx.in_table("ScriptList", |ctx| {
39 ctx.in_field("script_records", |ctx| {
40 if self.script_records.len() > (u16::MAX as usize) {
41 ctx.report("array exceeds max length");
42 }
43 self.script_records.validate_impl(ctx);
44 });
45 })
46 }
47}
48
49impl<'a> FromObjRef<read_fonts::tables::layout::ScriptList<'a>> for ScriptList {
50 fn from_obj_ref(obj: &read_fonts::tables::layout::ScriptList<'a>, _: FontData) -> Self {
51 let offset_data = obj.offset_data();
52 ScriptList {
53 script_records: obj.script_records().to_owned_obj(offset_data),
54 }
55 }
56}
57
58#[allow(clippy::needless_lifetimes)]
59impl<'a> FromTableRef<read_fonts::tables::layout::ScriptList<'a>> for ScriptList {}
60
61impl<'a> FontRead<'a> for ScriptList {
62 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
63 <read_fonts::tables::layout::ScriptList as FontRead>::read(data).map(|x| x.to_owned_table())
64 }
65}
66
67#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
69#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
70pub struct ScriptRecord {
71 pub script_tag: Tag,
73 pub script: OffsetMarker<Script>,
75}
76
77impl ScriptRecord {
78 pub fn new(script_tag: Tag, script: Script) -> Self {
80 Self {
81 script_tag,
82 script: script.into(),
83 }
84 }
85}
86
87impl FontWrite for ScriptRecord {
88 fn write_into(&self, writer: &mut TableWriter) {
89 self.script_tag.write_into(writer);
90 self.script.write_into(writer);
91 }
92 fn table_type(&self) -> TableType {
93 TableType::Named("ScriptRecord")
94 }
95}
96
97impl Validate for ScriptRecord {
98 fn validate_impl(&self, ctx: &mut ValidationCtx) {
99 ctx.in_table("ScriptRecord", |ctx| {
100 ctx.in_field("script", |ctx| {
101 self.script.validate_impl(ctx);
102 });
103 })
104 }
105}
106
107impl FromObjRef<read_fonts::tables::layout::ScriptRecord> for ScriptRecord {
108 fn from_obj_ref(obj: &read_fonts::tables::layout::ScriptRecord, offset_data: FontData) -> Self {
109 ScriptRecord {
110 script_tag: obj.script_tag(),
111 script: obj.script(offset_data).to_owned_table(),
112 }
113 }
114}
115
116#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119pub struct Script {
120 pub default_lang_sys: NullableOffsetMarker<LangSys>,
123 pub lang_sys_records: Vec<LangSysRecord>,
125}
126
127impl Script {
128 pub fn new(default_lang_sys: Option<LangSys>, lang_sys_records: Vec<LangSysRecord>) -> Self {
130 Self {
131 default_lang_sys: default_lang_sys.into(),
132 lang_sys_records,
133 }
134 }
135}
136
137impl FontWrite for Script {
138 #[allow(clippy::unnecessary_cast)]
139 fn write_into(&self, writer: &mut TableWriter) {
140 self.default_lang_sys.write_into(writer);
141 (u16::try_from(array_len(&self.lang_sys_records)).unwrap()).write_into(writer);
142 self.lang_sys_records.write_into(writer);
143 }
144 fn table_type(&self) -> TableType {
145 TableType::Named("Script")
146 }
147}
148
149impl Validate for Script {
150 fn validate_impl(&self, ctx: &mut ValidationCtx) {
151 ctx.in_table("Script", |ctx| {
152 ctx.in_field("default_lang_sys", |ctx| {
153 self.default_lang_sys.validate_impl(ctx);
154 });
155 ctx.in_field("lang_sys_records", |ctx| {
156 if self.lang_sys_records.len() > (u16::MAX as usize) {
157 ctx.report("array exceeds max length");
158 }
159 self.lang_sys_records.validate_impl(ctx);
160 });
161 })
162 }
163}
164
165impl<'a> FromObjRef<read_fonts::tables::layout::Script<'a>> for Script {
166 fn from_obj_ref(obj: &read_fonts::tables::layout::Script<'a>, _: FontData) -> Self {
167 let offset_data = obj.offset_data();
168 Script {
169 default_lang_sys: obj.default_lang_sys().to_owned_table(),
170 lang_sys_records: obj.lang_sys_records().to_owned_obj(offset_data),
171 }
172 }
173}
174
175#[allow(clippy::needless_lifetimes)]
176impl<'a> FromTableRef<read_fonts::tables::layout::Script<'a>> for Script {}
177
178impl<'a> FontRead<'a> for Script {
179 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
180 <read_fonts::tables::layout::Script as FontRead>::read(data).map(|x| x.to_owned_table())
181 }
182}
183
184#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
186pub struct LangSysRecord {
187 pub lang_sys_tag: Tag,
189 pub lang_sys: OffsetMarker<LangSys>,
191}
192
193impl LangSysRecord {
194 pub fn new(lang_sys_tag: Tag, lang_sys: LangSys) -> Self {
196 Self {
197 lang_sys_tag,
198 lang_sys: lang_sys.into(),
199 }
200 }
201}
202
203impl FontWrite for LangSysRecord {
204 fn write_into(&self, writer: &mut TableWriter) {
205 self.lang_sys_tag.write_into(writer);
206 self.lang_sys.write_into(writer);
207 }
208 fn table_type(&self) -> TableType {
209 TableType::Named("LangSysRecord")
210 }
211}
212
213impl Validate for LangSysRecord {
214 fn validate_impl(&self, ctx: &mut ValidationCtx) {
215 ctx.in_table("LangSysRecord", |ctx| {
216 ctx.in_field("lang_sys", |ctx| {
217 self.lang_sys.validate_impl(ctx);
218 });
219 })
220 }
221}
222
223impl FromObjRef<read_fonts::tables::layout::LangSysRecord> for LangSysRecord {
224 fn from_obj_ref(
225 obj: &read_fonts::tables::layout::LangSysRecord,
226 offset_data: FontData,
227 ) -> Self {
228 LangSysRecord {
229 lang_sys_tag: obj.lang_sys_tag(),
230 lang_sys: obj.lang_sys(offset_data).to_owned_table(),
231 }
232 }
233}
234
235#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
237#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
238pub struct LangSys {
239 pub required_feature_index: u16,
242 pub feature_indices: Vec<u16>,
244}
245
246impl Default for LangSys {
247 fn default() -> Self {
248 Self {
249 required_feature_index: 0xFFFF,
250 feature_indices: Default::default(),
251 }
252 }
253}
254
255impl LangSys {
256 pub fn new(feature_indices: Vec<u16>) -> Self {
258 Self {
259 feature_indices,
260 ..Default::default()
261 }
262 }
263}
264
265impl FontWrite for LangSys {
266 #[allow(clippy::unnecessary_cast)]
267 fn write_into(&self, writer: &mut TableWriter) {
268 (0 as u16).write_into(writer);
269 self.required_feature_index.write_into(writer);
270 (u16::try_from(array_len(&self.feature_indices)).unwrap()).write_into(writer);
271 self.feature_indices.write_into(writer);
272 }
273 fn table_type(&self) -> TableType {
274 TableType::Named("LangSys")
275 }
276}
277
278impl Validate for LangSys {
279 fn validate_impl(&self, ctx: &mut ValidationCtx) {
280 ctx.in_table("LangSys", |ctx| {
281 ctx.in_field("feature_indices", |ctx| {
282 if self.feature_indices.len() > (u16::MAX as usize) {
283 ctx.report("array exceeds max length");
284 }
285 });
286 })
287 }
288}
289
290impl<'a> FromObjRef<read_fonts::tables::layout::LangSys<'a>> for LangSys {
291 fn from_obj_ref(obj: &read_fonts::tables::layout::LangSys<'a>, _: FontData) -> Self {
292 let offset_data = obj.offset_data();
293 LangSys {
294 required_feature_index: obj.required_feature_index(),
295 feature_indices: obj.feature_indices().to_owned_obj(offset_data),
296 }
297 }
298}
299
300#[allow(clippy::needless_lifetimes)]
301impl<'a> FromTableRef<read_fonts::tables::layout::LangSys<'a>> for LangSys {}
302
303impl<'a> FontRead<'a> for LangSys {
304 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
305 <read_fonts::tables::layout::LangSys as FontRead>::read(data).map(|x| x.to_owned_table())
306 }
307}
308
309#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
311#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
312pub struct FeatureList {
313 pub feature_records: Vec<FeatureRecord>,
316}
317
318impl FeatureList {
319 pub fn new(feature_records: Vec<FeatureRecord>) -> Self {
321 Self { feature_records }
322 }
323}
324
325impl FontWrite for FeatureList {
326 #[allow(clippy::unnecessary_cast)]
327 fn write_into(&self, writer: &mut TableWriter) {
328 (u16::try_from(array_len(&self.feature_records)).unwrap()).write_into(writer);
329 self.feature_records.write_into(writer);
330 }
331 fn table_type(&self) -> TableType {
332 TableType::Named("FeatureList")
333 }
334}
335
336impl Validate for FeatureList {
337 fn validate_impl(&self, ctx: &mut ValidationCtx) {
338 ctx.in_table("FeatureList", |ctx| {
339 ctx.in_field("feature_records", |ctx| {
340 if self.feature_records.len() > (u16::MAX as usize) {
341 ctx.report("array exceeds max length");
342 }
343 self.feature_records.validate_impl(ctx);
344 });
345 })
346 }
347}
348
349impl<'a> FromObjRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList {
350 fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureList<'a>, _: FontData) -> Self {
351 let offset_data = obj.offset_data();
352 FeatureList {
353 feature_records: obj.feature_records().to_owned_obj(offset_data),
354 }
355 }
356}
357
358#[allow(clippy::needless_lifetimes)]
359impl<'a> FromTableRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList {}
360
361impl<'a> FontRead<'a> for FeatureList {
362 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
363 <read_fonts::tables::layout::FeatureList as FontRead>::read(data)
364 .map(|x| x.to_owned_table())
365 }
366}
367
368#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
370#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
371pub struct FeatureRecord {
372 pub feature_tag: Tag,
374 pub feature: OffsetMarker<Feature>,
376}
377
378impl FeatureRecord {
379 pub fn new(feature_tag: Tag, feature: Feature) -> Self {
381 Self {
382 feature_tag,
383 feature: feature.into(),
384 }
385 }
386}
387
388impl FontWrite for FeatureRecord {
389 fn write_into(&self, writer: &mut TableWriter) {
390 self.feature_tag.write_into(writer);
391 self.feature.write_into(writer);
392 }
393 fn table_type(&self) -> TableType {
394 TableType::Named("FeatureRecord")
395 }
396}
397
398impl Validate for FeatureRecord {
399 fn validate_impl(&self, ctx: &mut ValidationCtx) {
400 ctx.in_table("FeatureRecord", |ctx| {
401 ctx.in_field("feature", |ctx| {
402 self.feature.validate_impl(ctx);
403 });
404 })
405 }
406}
407
408impl FromObjRef<read_fonts::tables::layout::FeatureRecord> for FeatureRecord {
409 fn from_obj_ref(
410 obj: &read_fonts::tables::layout::FeatureRecord,
411 offset_data: FontData,
412 ) -> Self {
413 FeatureRecord {
414 feature_tag: obj.feature_tag(),
415 feature: obj.feature(offset_data).to_owned_table(),
416 }
417 }
418}
419
420#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
422#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
423pub struct Feature {
424 pub feature_params: NullableOffsetMarker<FeatureParams>,
426 pub lookup_list_indices: Vec<u16>,
429}
430
431impl Feature {
432 pub fn new(feature_params: Option<FeatureParams>, lookup_list_indices: Vec<u16>) -> Self {
434 Self {
435 feature_params: feature_params.into(),
436 lookup_list_indices,
437 }
438 }
439}
440
441impl FontWrite for Feature {
442 #[allow(clippy::unnecessary_cast)]
443 fn write_into(&self, writer: &mut TableWriter) {
444 self.feature_params.write_into(writer);
445 (u16::try_from(array_len(&self.lookup_list_indices)).unwrap()).write_into(writer);
446 self.lookup_list_indices.write_into(writer);
447 }
448 fn table_type(&self) -> TableType {
449 TableType::Named("Feature")
450 }
451}
452
453impl Validate for Feature {
454 fn validate_impl(&self, ctx: &mut ValidationCtx) {
455 ctx.in_table("Feature", |ctx| {
456 ctx.in_field("feature_params", |ctx| {
457 self.feature_params.validate_impl(ctx);
458 });
459 ctx.in_field("lookup_list_indices", |ctx| {
460 if self.lookup_list_indices.len() > (u16::MAX as usize) {
461 ctx.report("array exceeds max length");
462 }
463 });
464 })
465 }
466}
467
468impl<'a> FromObjRef<read_fonts::tables::layout::Feature<'a>> for Feature {
469 fn from_obj_ref(obj: &read_fonts::tables::layout::Feature<'a>, _: FontData) -> Self {
470 let offset_data = obj.offset_data();
471 Feature {
472 feature_params: obj.feature_params().to_owned_table(),
473 lookup_list_indices: obj.lookup_list_indices().to_owned_obj(offset_data),
474 }
475 }
476}
477
478#[allow(clippy::needless_lifetimes)]
479impl<'a> FromTableRef<read_fonts::tables::layout::Feature<'a>> for Feature {}
480
481#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
483#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
484pub struct LookupList<T> {
485 pub lookups: Vec<OffsetMarker<T>>,
488}
489
490impl<T: Default> LookupList<T> {
491 pub fn new(lookups: Vec<T>) -> Self {
493 Self {
494 lookups: lookups.into_iter().map(Into::into).collect(),
495 }
496 }
497}
498
499impl<T: FontWrite> FontWrite for LookupList<T> {
500 #[allow(clippy::unnecessary_cast)]
501 fn write_into(&self, writer: &mut TableWriter) {
502 (u16::try_from(array_len(&self.lookups)).unwrap()).write_into(writer);
503 self.lookups.write_into(writer);
504 }
505 fn table_type(&self) -> TableType {
506 TableType::Named("LookupList")
507 }
508}
509
510impl<T: Validate> Validate for LookupList<T> {
511 fn validate_impl(&self, ctx: &mut ValidationCtx) {
512 ctx.in_table("LookupList", |ctx| {
513 ctx.in_field("lookups", |ctx| {
514 if self.lookups.len() > (u16::MAX as usize) {
515 ctx.report("array exceeds max length");
516 }
517 self.lookups.validate_impl(ctx);
518 });
519 })
520 }
521}
522
523impl<'a, T, U> FromObjRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T>
524where
525 U: FontRead<'a>,
526 T: FromTableRef<U> + Default + 'static,
527{
528 fn from_obj_ref(obj: &read_fonts::tables::layout::LookupList<'a, U>, _: FontData) -> Self {
529 LookupList {
530 lookups: obj.lookups().to_owned_table(),
531 }
532 }
533}
534
535#[allow(clippy::needless_lifetimes)]
536impl<'a, T, U> FromTableRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T>
537where
538 U: FontRead<'a>,
539 T: FromTableRef<U> + Default + 'static,
540{
541}
542
543#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
545#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
546pub struct Lookup<T> {
547 pub lookup_flag: LookupFlag,
549 pub subtables: Vec<OffsetMarker<T>>,
552 pub mark_filtering_set: Option<u16>,
556}
557
558impl<T: Default> Lookup<T> {
559 pub fn new(lookup_flag: LookupFlag, subtables: Vec<T>) -> Self {
561 Self {
562 lookup_flag,
563 subtables: subtables.into_iter().map(Into::into).collect(),
564 ..Default::default()
565 }
566 }
567}
568
569impl<T: Validate> Validate for Lookup<T> {
570 fn validate_impl(&self, ctx: &mut ValidationCtx) {
571 ctx.in_table("Lookup", |ctx| {
572 let lookup_flag = self.lookup_flag;
573 ctx.in_field("subtables", |ctx| {
574 if self.subtables.len() > (u16::MAX as usize) {
575 ctx.report("array exceeds max length");
576 }
577 self.subtables.validate_impl(ctx);
578 });
579 ctx.in_field("mark_filtering_set", |ctx| {
580 if !(lookup_flag.contains(LookupFlag::USE_MARK_FILTERING_SET))
581 && self.mark_filtering_set.is_some()
582 {
583 ctx.report("'mark_filtering_set' is present but USE_MARK_FILTERING_SET not set")
584 }
585 if (lookup_flag.contains(LookupFlag::USE_MARK_FILTERING_SET))
586 && self.mark_filtering_set.is_none()
587 {
588 ctx.report("USE_MARK_FILTERING_SET is set but 'mark_filtering_set' is None")
589 }
590 });
591 })
592 }
593}
594
595impl<'a, T, U> FromObjRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T>
596where
597 U: FontRead<'a>,
598 T: FromTableRef<U> + Default + 'static,
599{
600 fn from_obj_ref(obj: &read_fonts::tables::layout::Lookup<'a, U>, _: FontData) -> Self {
601 Lookup {
602 lookup_flag: obj.lookup_flag(),
603 subtables: obj.subtables().to_owned_table(),
604 mark_filtering_set: obj.mark_filtering_set(),
605 }
606 }
607}
608
609#[allow(clippy::needless_lifetimes)]
610impl<'a, T, U> FromTableRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T>
611where
612 U: FontRead<'a>,
613 T: FromTableRef<U> + Default + 'static,
614{
615}
616
617#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
619#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
620pub struct CoverageFormat1 {
621 pub glyph_array: Vec<GlyphId16>,
623}
624
625impl CoverageFormat1 {
626 pub fn new(glyph_array: Vec<GlyphId16>) -> Self {
628 Self { glyph_array }
629 }
630}
631
632impl FontWrite for CoverageFormat1 {
633 #[allow(clippy::unnecessary_cast)]
634 fn write_into(&self, writer: &mut TableWriter) {
635 (1 as u16).write_into(writer);
636 (u16::try_from(array_len(&self.glyph_array)).unwrap()).write_into(writer);
637 self.glyph_array.write_into(writer);
638 }
639 fn table_type(&self) -> TableType {
640 TableType::Named("CoverageFormat1")
641 }
642}
643
644impl Validate for CoverageFormat1 {
645 fn validate_impl(&self, ctx: &mut ValidationCtx) {
646 ctx.in_table("CoverageFormat1", |ctx| {
647 ctx.in_field("glyph_array", |ctx| {
648 if self.glyph_array.len() > (u16::MAX as usize) {
649 ctx.report("array exceeds max length");
650 }
651 });
652 })
653 }
654}
655
656impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 {
657 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat1<'a>, _: FontData) -> Self {
658 let offset_data = obj.offset_data();
659 CoverageFormat1 {
660 glyph_array: obj.glyph_array().to_owned_obj(offset_data),
661 }
662 }
663}
664
665#[allow(clippy::needless_lifetimes)]
666impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 {}
667
668impl<'a> FontRead<'a> for CoverageFormat1 {
669 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
670 <read_fonts::tables::layout::CoverageFormat1 as FontRead>::read(data)
671 .map(|x| x.to_owned_table())
672 }
673}
674
675#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
677#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
678pub struct CoverageFormat2 {
679 pub range_records: Vec<RangeRecord>,
681}
682
683impl CoverageFormat2 {
684 pub fn new(range_records: Vec<RangeRecord>) -> Self {
686 Self { range_records }
687 }
688}
689
690impl FontWrite for CoverageFormat2 {
691 #[allow(clippy::unnecessary_cast)]
692 fn write_into(&self, writer: &mut TableWriter) {
693 (2 as u16).write_into(writer);
694 (u16::try_from(array_len(&self.range_records)).unwrap()).write_into(writer);
695 self.range_records.write_into(writer);
696 }
697 fn table_type(&self) -> TableType {
698 TableType::Named("CoverageFormat2")
699 }
700}
701
702impl Validate for CoverageFormat2 {
703 fn validate_impl(&self, ctx: &mut ValidationCtx) {
704 ctx.in_table("CoverageFormat2", |ctx| {
705 ctx.in_field("range_records", |ctx| {
706 if self.range_records.len() > (u16::MAX as usize) {
707 ctx.report("array exceeds max length");
708 }
709 self.range_records.validate_impl(ctx);
710 });
711 })
712 }
713}
714
715impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 {
716 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat2<'a>, _: FontData) -> Self {
717 let offset_data = obj.offset_data();
718 CoverageFormat2 {
719 range_records: obj.range_records().to_owned_obj(offset_data),
720 }
721 }
722}
723
724#[allow(clippy::needless_lifetimes)]
725impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 {}
726
727impl<'a> FontRead<'a> for CoverageFormat2 {
728 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
729 <read_fonts::tables::layout::CoverageFormat2 as FontRead>::read(data)
730 .map(|x| x.to_owned_table())
731 }
732}
733
734#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
736#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
737pub struct RangeRecord {
738 pub start_glyph_id: GlyphId16,
740 pub end_glyph_id: GlyphId16,
742 pub start_coverage_index: u16,
744}
745
746impl RangeRecord {
747 pub fn new(
749 start_glyph_id: GlyphId16,
750 end_glyph_id: GlyphId16,
751 start_coverage_index: u16,
752 ) -> Self {
753 Self {
754 start_glyph_id,
755 end_glyph_id,
756 start_coverage_index,
757 }
758 }
759}
760
761impl FontWrite for RangeRecord {
762 fn write_into(&self, writer: &mut TableWriter) {
763 self.start_glyph_id.write_into(writer);
764 self.end_glyph_id.write_into(writer);
765 self.start_coverage_index.write_into(writer);
766 }
767 fn table_type(&self) -> TableType {
768 TableType::Named("RangeRecord")
769 }
770}
771
772impl Validate for RangeRecord {
773 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
774}
775
776impl FromObjRef<read_fonts::tables::layout::RangeRecord> for RangeRecord {
777 fn from_obj_ref(obj: &read_fonts::tables::layout::RangeRecord, _: FontData) -> Self {
778 RangeRecord {
779 start_glyph_id: obj.start_glyph_id(),
780 end_glyph_id: obj.end_glyph_id(),
781 start_coverage_index: obj.start_coverage_index(),
782 }
783 }
784}
785
786#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
788#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
789pub enum CoverageTable {
790 Format1(CoverageFormat1),
791 Format2(CoverageFormat2),
792}
793
794impl CoverageTable {
795 pub fn format_1(glyph_array: Vec<GlyphId16>) -> Self {
797 Self::Format1(CoverageFormat1::new(glyph_array))
798 }
799
800 pub fn format_2(range_records: Vec<RangeRecord>) -> Self {
802 Self::Format2(CoverageFormat2::new(range_records))
803 }
804}
805
806impl Default for CoverageTable {
807 fn default() -> Self {
808 Self::Format1(Default::default())
809 }
810}
811
812impl FontWrite for CoverageTable {
813 fn write_into(&self, writer: &mut TableWriter) {
814 match self {
815 Self::Format1(item) => item.write_into(writer),
816 Self::Format2(item) => item.write_into(writer),
817 }
818 }
819 fn table_type(&self) -> TableType {
820 match self {
821 Self::Format1(item) => item.table_type(),
822 Self::Format2(item) => item.table_type(),
823 }
824 }
825}
826
827impl Validate for CoverageTable {
828 fn validate_impl(&self, ctx: &mut ValidationCtx) {
829 match self {
830 Self::Format1(item) => item.validate_impl(ctx),
831 Self::Format2(item) => item.validate_impl(ctx),
832 }
833 }
834}
835
836impl FromObjRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable {
837 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageTable, _: FontData) -> Self {
838 use read_fonts::tables::layout::CoverageTable as ObjRefType;
839 match obj {
840 ObjRefType::Format1(item) => CoverageTable::Format1(item.to_owned_table()),
841 ObjRefType::Format2(item) => CoverageTable::Format2(item.to_owned_table()),
842 }
843 }
844}
845
846impl FromTableRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable {}
847
848impl<'a> FontRead<'a> for CoverageTable {
849 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
850 <read_fonts::tables::layout::CoverageTable as FontRead>::read(data)
851 .map(|x| x.to_owned_table())
852 }
853}
854
855impl From<CoverageFormat1> for CoverageTable {
856 fn from(src: CoverageFormat1) -> CoverageTable {
857 CoverageTable::Format1(src)
858 }
859}
860
861impl From<CoverageFormat2> for CoverageTable {
862 fn from(src: CoverageFormat2) -> CoverageTable {
863 CoverageTable::Format2(src)
864 }
865}
866
867#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
869#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
870pub struct ClassDefFormat1 {
871 pub start_glyph_id: GlyphId16,
873 pub class_value_array: Vec<u16>,
875}
876
877impl ClassDefFormat1 {
878 pub fn new(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self {
880 Self {
881 start_glyph_id,
882 class_value_array,
883 }
884 }
885}
886
887impl FontWrite for ClassDefFormat1 {
888 #[allow(clippy::unnecessary_cast)]
889 fn write_into(&self, writer: &mut TableWriter) {
890 (1 as u16).write_into(writer);
891 self.start_glyph_id.write_into(writer);
892 (u16::try_from(array_len(&self.class_value_array)).unwrap()).write_into(writer);
893 self.class_value_array.write_into(writer);
894 }
895 fn table_type(&self) -> TableType {
896 TableType::Named("ClassDefFormat1")
897 }
898}
899
900impl Validate for ClassDefFormat1 {
901 fn validate_impl(&self, ctx: &mut ValidationCtx) {
902 ctx.in_table("ClassDefFormat1", |ctx| {
903 ctx.in_field("class_value_array", |ctx| {
904 if self.class_value_array.len() > (u16::MAX as usize) {
905 ctx.report("array exceeds max length");
906 }
907 });
908 })
909 }
910}
911
912impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 {
913 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat1<'a>, _: FontData) -> Self {
914 let offset_data = obj.offset_data();
915 ClassDefFormat1 {
916 start_glyph_id: obj.start_glyph_id(),
917 class_value_array: obj.class_value_array().to_owned_obj(offset_data),
918 }
919 }
920}
921
922#[allow(clippy::needless_lifetimes)]
923impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 {}
924
925impl<'a> FontRead<'a> for ClassDefFormat1 {
926 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
927 <read_fonts::tables::layout::ClassDefFormat1 as FontRead>::read(data)
928 .map(|x| x.to_owned_table())
929 }
930}
931
932#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
934#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
935pub struct ClassDefFormat2 {
936 pub class_range_records: Vec<ClassRangeRecord>,
938}
939
940impl ClassDefFormat2 {
941 pub fn new(class_range_records: Vec<ClassRangeRecord>) -> Self {
943 Self {
944 class_range_records,
945 }
946 }
947}
948
949impl FontWrite for ClassDefFormat2 {
950 #[allow(clippy::unnecessary_cast)]
951 fn write_into(&self, writer: &mut TableWriter) {
952 (2 as u16).write_into(writer);
953 (u16::try_from(array_len(&self.class_range_records)).unwrap()).write_into(writer);
954 self.class_range_records.write_into(writer);
955 }
956 fn table_type(&self) -> TableType {
957 TableType::Named("ClassDefFormat2")
958 }
959}
960
961impl Validate for ClassDefFormat2 {
962 fn validate_impl(&self, ctx: &mut ValidationCtx) {
963 ctx.in_table("ClassDefFormat2", |ctx| {
964 ctx.in_field("class_range_records", |ctx| {
965 if self.class_range_records.len() > (u16::MAX as usize) {
966 ctx.report("array exceeds max length");
967 }
968 self.class_range_records.validate_impl(ctx);
969 });
970 })
971 }
972}
973
974impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 {
975 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat2<'a>, _: FontData) -> Self {
976 let offset_data = obj.offset_data();
977 ClassDefFormat2 {
978 class_range_records: obj.class_range_records().to_owned_obj(offset_data),
979 }
980 }
981}
982
983#[allow(clippy::needless_lifetimes)]
984impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 {}
985
986impl<'a> FontRead<'a> for ClassDefFormat2 {
987 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
988 <read_fonts::tables::layout::ClassDefFormat2 as FontRead>::read(data)
989 .map(|x| x.to_owned_table())
990 }
991}
992
993#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
995#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
996pub struct ClassRangeRecord {
997 pub start_glyph_id: GlyphId16,
999 pub end_glyph_id: GlyphId16,
1001 pub class: u16,
1003}
1004
1005impl ClassRangeRecord {
1006 pub fn new(start_glyph_id: GlyphId16, end_glyph_id: GlyphId16, class: u16) -> Self {
1008 Self {
1009 start_glyph_id,
1010 end_glyph_id,
1011 class,
1012 }
1013 }
1014}
1015
1016impl FontWrite for ClassRangeRecord {
1017 fn write_into(&self, writer: &mut TableWriter) {
1018 self.start_glyph_id.write_into(writer);
1019 self.end_glyph_id.write_into(writer);
1020 self.class.write_into(writer);
1021 }
1022 fn table_type(&self) -> TableType {
1023 TableType::Named("ClassRangeRecord")
1024 }
1025}
1026
1027impl Validate for ClassRangeRecord {
1028 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1029 ctx.in_table("ClassRangeRecord", |ctx| {
1030 ctx.in_field("start_glyph_id", |ctx| {
1031 self.validate_glyph_range(ctx);
1032 });
1033 })
1034 }
1035}
1036
1037impl FromObjRef<read_fonts::tables::layout::ClassRangeRecord> for ClassRangeRecord {
1038 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassRangeRecord, _: FontData) -> Self {
1039 ClassRangeRecord {
1040 start_glyph_id: obj.start_glyph_id(),
1041 end_glyph_id: obj.end_glyph_id(),
1042 class: obj.class(),
1043 }
1044 }
1045}
1046
1047#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1049#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1050pub enum ClassDef {
1051 Format1(ClassDefFormat1),
1052 Format2(ClassDefFormat2),
1053}
1054
1055impl ClassDef {
1056 pub fn format_1(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self {
1058 Self::Format1(ClassDefFormat1::new(start_glyph_id, class_value_array))
1059 }
1060
1061 pub fn format_2(class_range_records: Vec<ClassRangeRecord>) -> Self {
1063 Self::Format2(ClassDefFormat2::new(class_range_records))
1064 }
1065}
1066
1067impl Default for ClassDef {
1068 fn default() -> Self {
1069 Self::Format1(Default::default())
1070 }
1071}
1072
1073impl FontWrite for ClassDef {
1074 fn write_into(&self, writer: &mut TableWriter) {
1075 match self {
1076 Self::Format1(item) => item.write_into(writer),
1077 Self::Format2(item) => item.write_into(writer),
1078 }
1079 }
1080 fn table_type(&self) -> TableType {
1081 match self {
1082 Self::Format1(item) => item.table_type(),
1083 Self::Format2(item) => item.table_type(),
1084 }
1085 }
1086}
1087
1088impl Validate for ClassDef {
1089 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1090 match self {
1091 Self::Format1(item) => item.validate_impl(ctx),
1092 Self::Format2(item) => item.validate_impl(ctx),
1093 }
1094 }
1095}
1096
1097impl FromObjRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef {
1098 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDef, _: FontData) -> Self {
1099 use read_fonts::tables::layout::ClassDef as ObjRefType;
1100 match obj {
1101 ObjRefType::Format1(item) => ClassDef::Format1(item.to_owned_table()),
1102 ObjRefType::Format2(item) => ClassDef::Format2(item.to_owned_table()),
1103 }
1104 }
1105}
1106
1107impl FromTableRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef {}
1108
1109impl<'a> FontRead<'a> for ClassDef {
1110 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1111 <read_fonts::tables::layout::ClassDef as FontRead>::read(data).map(|x| x.to_owned_table())
1112 }
1113}
1114
1115impl From<ClassDefFormat1> for ClassDef {
1116 fn from(src: ClassDefFormat1) -> ClassDef {
1117 ClassDef::Format1(src)
1118 }
1119}
1120
1121impl From<ClassDefFormat2> for ClassDef {
1122 fn from(src: ClassDefFormat2) -> ClassDef {
1123 ClassDef::Format2(src)
1124 }
1125}
1126
1127#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1129#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1130pub struct SequenceLookupRecord {
1131 pub sequence_index: u16,
1133 pub lookup_list_index: u16,
1135}
1136
1137impl SequenceLookupRecord {
1138 pub fn new(sequence_index: u16, lookup_list_index: u16) -> Self {
1140 Self {
1141 sequence_index,
1142 lookup_list_index,
1143 }
1144 }
1145}
1146
1147impl FontWrite for SequenceLookupRecord {
1148 fn write_into(&self, writer: &mut TableWriter) {
1149 self.sequence_index.write_into(writer);
1150 self.lookup_list_index.write_into(writer);
1151 }
1152 fn table_type(&self) -> TableType {
1153 TableType::Named("SequenceLookupRecord")
1154 }
1155}
1156
1157impl Validate for SequenceLookupRecord {
1158 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1159}
1160
1161impl FromObjRef<read_fonts::tables::layout::SequenceLookupRecord> for SequenceLookupRecord {
1162 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceLookupRecord, _: FontData) -> Self {
1163 SequenceLookupRecord {
1164 sequence_index: obj.sequence_index(),
1165 lookup_list_index: obj.lookup_list_index(),
1166 }
1167 }
1168}
1169
1170#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1172#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1173pub struct SequenceContextFormat1 {
1174 pub coverage: OffsetMarker<CoverageTable>,
1177 pub seq_rule_sets: Vec<NullableOffsetMarker<SequenceRuleSet>>,
1180}
1181
1182impl SequenceContextFormat1 {
1183 pub fn new(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self {
1185 Self {
1186 coverage: coverage.into(),
1187 seq_rule_sets: seq_rule_sets.into_iter().map(Into::into).collect(),
1188 }
1189 }
1190}
1191
1192impl FontWrite for SequenceContextFormat1 {
1193 #[allow(clippy::unnecessary_cast)]
1194 fn write_into(&self, writer: &mut TableWriter) {
1195 (1 as u16).write_into(writer);
1196 self.coverage.write_into(writer);
1197 (u16::try_from(array_len(&self.seq_rule_sets)).unwrap()).write_into(writer);
1198 self.seq_rule_sets.write_into(writer);
1199 }
1200 fn table_type(&self) -> TableType {
1201 TableType::Named("SequenceContextFormat1")
1202 }
1203}
1204
1205impl Validate for SequenceContextFormat1 {
1206 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1207 ctx.in_table("SequenceContextFormat1", |ctx| {
1208 ctx.in_field("coverage", |ctx| {
1209 self.coverage.validate_impl(ctx);
1210 });
1211 ctx.in_field("seq_rule_sets", |ctx| {
1212 if self.seq_rule_sets.len() > (u16::MAX as usize) {
1213 ctx.report("array exceeds max length");
1214 }
1215 self.seq_rule_sets.validate_impl(ctx);
1216 });
1217 })
1218 }
1219}
1220
1221impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat1<'a>>
1222 for SequenceContextFormat1
1223{
1224 fn from_obj_ref(
1225 obj: &read_fonts::tables::layout::SequenceContextFormat1<'a>,
1226 _: FontData,
1227 ) -> Self {
1228 SequenceContextFormat1 {
1229 coverage: obj.coverage().to_owned_table(),
1230 seq_rule_sets: obj.seq_rule_sets().to_owned_table(),
1231 }
1232 }
1233}
1234
1235#[allow(clippy::needless_lifetimes)]
1236impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat1<'a>>
1237 for SequenceContextFormat1
1238{
1239}
1240
1241impl<'a> FontRead<'a> for SequenceContextFormat1 {
1242 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1243 <read_fonts::tables::layout::SequenceContextFormat1 as FontRead>::read(data)
1244 .map(|x| x.to_owned_table())
1245 }
1246}
1247
1248#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1251pub struct SequenceRuleSet {
1252 pub seq_rules: Vec<OffsetMarker<SequenceRule>>,
1255}
1256
1257impl SequenceRuleSet {
1258 pub fn new(seq_rules: Vec<SequenceRule>) -> Self {
1260 Self {
1261 seq_rules: seq_rules.into_iter().map(Into::into).collect(),
1262 }
1263 }
1264}
1265
1266impl FontWrite for SequenceRuleSet {
1267 #[allow(clippy::unnecessary_cast)]
1268 fn write_into(&self, writer: &mut TableWriter) {
1269 (u16::try_from(array_len(&self.seq_rules)).unwrap()).write_into(writer);
1270 self.seq_rules.write_into(writer);
1271 }
1272 fn table_type(&self) -> TableType {
1273 TableType::Named("SequenceRuleSet")
1274 }
1275}
1276
1277impl Validate for SequenceRuleSet {
1278 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1279 ctx.in_table("SequenceRuleSet", |ctx| {
1280 ctx.in_field("seq_rules", |ctx| {
1281 if self.seq_rules.len() > (u16::MAX as usize) {
1282 ctx.report("array exceeds max length");
1283 }
1284 self.seq_rules.validate_impl(ctx);
1285 });
1286 })
1287 }
1288}
1289
1290impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet {
1291 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRuleSet<'a>, _: FontData) -> Self {
1292 SequenceRuleSet {
1293 seq_rules: obj.seq_rules().to_owned_table(),
1294 }
1295 }
1296}
1297
1298#[allow(clippy::needless_lifetimes)]
1299impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet {}
1300
1301impl<'a> FontRead<'a> for SequenceRuleSet {
1302 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1303 <read_fonts::tables::layout::SequenceRuleSet as FontRead>::read(data)
1304 .map(|x| x.to_owned_table())
1305 }
1306}
1307
1308#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1310#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1311pub struct SequenceRule {
1312 pub input_sequence: Vec<GlyphId16>,
1314 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1316}
1317
1318impl SequenceRule {
1319 pub fn new(
1321 input_sequence: Vec<GlyphId16>,
1322 seq_lookup_records: Vec<SequenceLookupRecord>,
1323 ) -> Self {
1324 Self {
1325 input_sequence,
1326 seq_lookup_records,
1327 }
1328 }
1329}
1330
1331impl FontWrite for SequenceRule {
1332 #[allow(clippy::unnecessary_cast)]
1333 fn write_into(&self, writer: &mut TableWriter) {
1334 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
1335 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1336 self.input_sequence.write_into(writer);
1337 self.seq_lookup_records.write_into(writer);
1338 }
1339 fn table_type(&self) -> TableType {
1340 TableType::Named("SequenceRule")
1341 }
1342}
1343
1344impl Validate for SequenceRule {
1345 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1346 ctx.in_table("SequenceRule", |ctx| {
1347 ctx.in_field("seq_lookup_records", |ctx| {
1348 if self.seq_lookup_records.len() > (u16::MAX as usize) {
1349 ctx.report("array exceeds max length");
1350 }
1351 self.seq_lookup_records.validate_impl(ctx);
1352 });
1353 })
1354 }
1355}
1356
1357impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule {
1358 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRule<'a>, _: FontData) -> Self {
1359 let offset_data = obj.offset_data();
1360 SequenceRule {
1361 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
1362 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1363 }
1364 }
1365}
1366
1367#[allow(clippy::needless_lifetimes)]
1368impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule {}
1369
1370impl<'a> FontRead<'a> for SequenceRule {
1371 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1372 <read_fonts::tables::layout::SequenceRule as FontRead>::read(data)
1373 .map(|x| x.to_owned_table())
1374 }
1375}
1376
1377#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1379#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1380pub struct SequenceContextFormat2 {
1381 pub coverage: OffsetMarker<CoverageTable>,
1384 pub class_def: OffsetMarker<ClassDef>,
1387 pub class_seq_rule_sets: Vec<NullableOffsetMarker<ClassSequenceRuleSet>>,
1390}
1391
1392impl SequenceContextFormat2 {
1393 pub fn new(
1395 coverage: CoverageTable,
1396 class_def: ClassDef,
1397 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>,
1398 ) -> Self {
1399 Self {
1400 coverage: coverage.into(),
1401 class_def: class_def.into(),
1402 class_seq_rule_sets: class_seq_rule_sets.into_iter().map(Into::into).collect(),
1403 }
1404 }
1405}
1406
1407impl FontWrite for SequenceContextFormat2 {
1408 #[allow(clippy::unnecessary_cast)]
1409 fn write_into(&self, writer: &mut TableWriter) {
1410 (2 as u16).write_into(writer);
1411 self.coverage.write_into(writer);
1412 self.class_def.write_into(writer);
1413 (u16::try_from(array_len(&self.class_seq_rule_sets)).unwrap()).write_into(writer);
1414 self.class_seq_rule_sets.write_into(writer);
1415 }
1416 fn table_type(&self) -> TableType {
1417 TableType::Named("SequenceContextFormat2")
1418 }
1419}
1420
1421impl Validate for SequenceContextFormat2 {
1422 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1423 ctx.in_table("SequenceContextFormat2", |ctx| {
1424 ctx.in_field("coverage", |ctx| {
1425 self.coverage.validate_impl(ctx);
1426 });
1427 ctx.in_field("class_def", |ctx| {
1428 self.class_def.validate_impl(ctx);
1429 });
1430 ctx.in_field("class_seq_rule_sets", |ctx| {
1431 if self.class_seq_rule_sets.len() > (u16::MAX as usize) {
1432 ctx.report("array exceeds max length");
1433 }
1434 self.class_seq_rule_sets.validate_impl(ctx);
1435 });
1436 })
1437 }
1438}
1439
1440impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat2<'a>>
1441 for SequenceContextFormat2
1442{
1443 fn from_obj_ref(
1444 obj: &read_fonts::tables::layout::SequenceContextFormat2<'a>,
1445 _: FontData,
1446 ) -> Self {
1447 SequenceContextFormat2 {
1448 coverage: obj.coverage().to_owned_table(),
1449 class_def: obj.class_def().to_owned_table(),
1450 class_seq_rule_sets: obj.class_seq_rule_sets().to_owned_table(),
1451 }
1452 }
1453}
1454
1455#[allow(clippy::needless_lifetimes)]
1456impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat2<'a>>
1457 for SequenceContextFormat2
1458{
1459}
1460
1461impl<'a> FontRead<'a> for SequenceContextFormat2 {
1462 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1463 <read_fonts::tables::layout::SequenceContextFormat2 as FontRead>::read(data)
1464 .map(|x| x.to_owned_table())
1465 }
1466}
1467
1468#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1470#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1471pub struct ClassSequenceRuleSet {
1472 pub class_seq_rules: Vec<OffsetMarker<ClassSequenceRule>>,
1475}
1476
1477impl ClassSequenceRuleSet {
1478 pub fn new(class_seq_rules: Vec<ClassSequenceRule>) -> Self {
1480 Self {
1481 class_seq_rules: class_seq_rules.into_iter().map(Into::into).collect(),
1482 }
1483 }
1484}
1485
1486impl FontWrite for ClassSequenceRuleSet {
1487 #[allow(clippy::unnecessary_cast)]
1488 fn write_into(&self, writer: &mut TableWriter) {
1489 (u16::try_from(array_len(&self.class_seq_rules)).unwrap()).write_into(writer);
1490 self.class_seq_rules.write_into(writer);
1491 }
1492 fn table_type(&self) -> TableType {
1493 TableType::Named("ClassSequenceRuleSet")
1494 }
1495}
1496
1497impl Validate for ClassSequenceRuleSet {
1498 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1499 ctx.in_table("ClassSequenceRuleSet", |ctx| {
1500 ctx.in_field("class_seq_rules", |ctx| {
1501 if self.class_seq_rules.len() > (u16::MAX as usize) {
1502 ctx.report("array exceeds max length");
1503 }
1504 self.class_seq_rules.validate_impl(ctx);
1505 });
1506 })
1507 }
1508}
1509
1510impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>> for ClassSequenceRuleSet {
1511 fn from_obj_ref(
1512 obj: &read_fonts::tables::layout::ClassSequenceRuleSet<'a>,
1513 _: FontData,
1514 ) -> Self {
1515 ClassSequenceRuleSet {
1516 class_seq_rules: obj.class_seq_rules().to_owned_table(),
1517 }
1518 }
1519}
1520
1521#[allow(clippy::needless_lifetimes)]
1522impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>>
1523 for ClassSequenceRuleSet
1524{
1525}
1526
1527impl<'a> FontRead<'a> for ClassSequenceRuleSet {
1528 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1529 <read_fonts::tables::layout::ClassSequenceRuleSet as FontRead>::read(data)
1530 .map(|x| x.to_owned_table())
1531 }
1532}
1533
1534#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1536#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1537pub struct ClassSequenceRule {
1538 pub input_sequence: Vec<u16>,
1541 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1543}
1544
1545impl ClassSequenceRule {
1546 pub fn new(input_sequence: Vec<u16>, seq_lookup_records: Vec<SequenceLookupRecord>) -> Self {
1548 Self {
1549 input_sequence,
1550 seq_lookup_records,
1551 }
1552 }
1553}
1554
1555impl FontWrite for ClassSequenceRule {
1556 #[allow(clippy::unnecessary_cast)]
1557 fn write_into(&self, writer: &mut TableWriter) {
1558 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
1559 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1560 self.input_sequence.write_into(writer);
1561 self.seq_lookup_records.write_into(writer);
1562 }
1563 fn table_type(&self) -> TableType {
1564 TableType::Named("ClassSequenceRule")
1565 }
1566}
1567
1568impl Validate for ClassSequenceRule {
1569 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1570 ctx.in_table("ClassSequenceRule", |ctx| {
1571 ctx.in_field("seq_lookup_records", |ctx| {
1572 if self.seq_lookup_records.len() > (u16::MAX as usize) {
1573 ctx.report("array exceeds max length");
1574 }
1575 self.seq_lookup_records.validate_impl(ctx);
1576 });
1577 })
1578 }
1579}
1580
1581impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule {
1582 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassSequenceRule<'a>, _: FontData) -> Self {
1583 let offset_data = obj.offset_data();
1584 ClassSequenceRule {
1585 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
1586 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1587 }
1588 }
1589}
1590
1591#[allow(clippy::needless_lifetimes)]
1592impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule {}
1593
1594impl<'a> FontRead<'a> for ClassSequenceRule {
1595 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1596 <read_fonts::tables::layout::ClassSequenceRule as FontRead>::read(data)
1597 .map(|x| x.to_owned_table())
1598 }
1599}
1600
1601#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1603#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1604pub struct SequenceContextFormat3 {
1605 pub coverages: Vec<OffsetMarker<CoverageTable>>,
1608 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1610}
1611
1612impl SequenceContextFormat3 {
1613 pub fn new(
1615 coverages: Vec<CoverageTable>,
1616 seq_lookup_records: Vec<SequenceLookupRecord>,
1617 ) -> Self {
1618 Self {
1619 coverages: coverages.into_iter().map(Into::into).collect(),
1620 seq_lookup_records,
1621 }
1622 }
1623}
1624
1625impl FontWrite for SequenceContextFormat3 {
1626 #[allow(clippy::unnecessary_cast)]
1627 fn write_into(&self, writer: &mut TableWriter) {
1628 (3 as u16).write_into(writer);
1629 (u16::try_from(array_len(&self.coverages)).unwrap()).write_into(writer);
1630 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1631 self.coverages.write_into(writer);
1632 self.seq_lookup_records.write_into(writer);
1633 }
1634 fn table_type(&self) -> TableType {
1635 TableType::Named("SequenceContextFormat3")
1636 }
1637}
1638
1639impl Validate for SequenceContextFormat3 {
1640 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1641 ctx.in_table("SequenceContextFormat3", |ctx| {
1642 ctx.in_field("coverages", |ctx| {
1643 if self.coverages.len() > (u16::MAX as usize) {
1644 ctx.report("array exceeds max length");
1645 }
1646 self.coverages.validate_impl(ctx);
1647 });
1648 ctx.in_field("seq_lookup_records", |ctx| {
1649 if self.seq_lookup_records.len() > (u16::MAX as usize) {
1650 ctx.report("array exceeds max length");
1651 }
1652 self.seq_lookup_records.validate_impl(ctx);
1653 });
1654 })
1655 }
1656}
1657
1658impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat3<'a>>
1659 for SequenceContextFormat3
1660{
1661 fn from_obj_ref(
1662 obj: &read_fonts::tables::layout::SequenceContextFormat3<'a>,
1663 _: FontData,
1664 ) -> Self {
1665 let offset_data = obj.offset_data();
1666 SequenceContextFormat3 {
1667 coverages: obj.coverages().to_owned_table(),
1668 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1669 }
1670 }
1671}
1672
1673#[allow(clippy::needless_lifetimes)]
1674impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat3<'a>>
1675 for SequenceContextFormat3
1676{
1677}
1678
1679impl<'a> FontRead<'a> for SequenceContextFormat3 {
1680 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1681 <read_fonts::tables::layout::SequenceContextFormat3 as FontRead>::read(data)
1682 .map(|x| x.to_owned_table())
1683 }
1684}
1685
1686#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1687#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1688pub enum SequenceContext {
1689 Format1(SequenceContextFormat1),
1690 Format2(SequenceContextFormat2),
1691 Format3(SequenceContextFormat3),
1692}
1693
1694impl SequenceContext {
1695 pub fn format_1(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self {
1697 Self::Format1(SequenceContextFormat1::new(coverage, seq_rule_sets))
1698 }
1699
1700 pub fn format_2(
1702 coverage: CoverageTable,
1703 class_def: ClassDef,
1704 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>,
1705 ) -> Self {
1706 Self::Format2(SequenceContextFormat2::new(
1707 coverage,
1708 class_def,
1709 class_seq_rule_sets,
1710 ))
1711 }
1712
1713 pub fn format_3(
1715 coverages: Vec<CoverageTable>,
1716 seq_lookup_records: Vec<SequenceLookupRecord>,
1717 ) -> Self {
1718 Self::Format3(SequenceContextFormat3::new(coverages, seq_lookup_records))
1719 }
1720}
1721
1722impl Default for SequenceContext {
1723 fn default() -> Self {
1724 Self::Format1(Default::default())
1725 }
1726}
1727
1728impl FontWrite for SequenceContext {
1729 fn write_into(&self, writer: &mut TableWriter) {
1730 match self {
1731 Self::Format1(item) => item.write_into(writer),
1732 Self::Format2(item) => item.write_into(writer),
1733 Self::Format3(item) => item.write_into(writer),
1734 }
1735 }
1736 fn table_type(&self) -> TableType {
1737 match self {
1738 Self::Format1(item) => item.table_type(),
1739 Self::Format2(item) => item.table_type(),
1740 Self::Format3(item) => item.table_type(),
1741 }
1742 }
1743}
1744
1745impl Validate for SequenceContext {
1746 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1747 match self {
1748 Self::Format1(item) => item.validate_impl(ctx),
1749 Self::Format2(item) => item.validate_impl(ctx),
1750 Self::Format3(item) => item.validate_impl(ctx),
1751 }
1752 }
1753}
1754
1755impl FromObjRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext {
1756 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceContext, _: FontData) -> Self {
1757 use read_fonts::tables::layout::SequenceContext as ObjRefType;
1758 match obj {
1759 ObjRefType::Format1(item) => SequenceContext::Format1(item.to_owned_table()),
1760 ObjRefType::Format2(item) => SequenceContext::Format2(item.to_owned_table()),
1761 ObjRefType::Format3(item) => SequenceContext::Format3(item.to_owned_table()),
1762 }
1763 }
1764}
1765
1766impl FromTableRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext {}
1767
1768impl<'a> FontRead<'a> for SequenceContext {
1769 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1770 <read_fonts::tables::layout::SequenceContext as FontRead>::read(data)
1771 .map(|x| x.to_owned_table())
1772 }
1773}
1774
1775impl From<SequenceContextFormat1> for SequenceContext {
1776 fn from(src: SequenceContextFormat1) -> SequenceContext {
1777 SequenceContext::Format1(src)
1778 }
1779}
1780
1781impl From<SequenceContextFormat2> for SequenceContext {
1782 fn from(src: SequenceContextFormat2) -> SequenceContext {
1783 SequenceContext::Format2(src)
1784 }
1785}
1786
1787impl From<SequenceContextFormat3> for SequenceContext {
1788 fn from(src: SequenceContextFormat3) -> SequenceContext {
1789 SequenceContext::Format3(src)
1790 }
1791}
1792
1793#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1795#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1796pub struct ChainedSequenceContextFormat1 {
1797 pub coverage: OffsetMarker<CoverageTable>,
1800 pub chained_seq_rule_sets: Vec<NullableOffsetMarker<ChainedSequenceRuleSet>>,
1803}
1804
1805impl ChainedSequenceContextFormat1 {
1806 pub fn new(
1808 coverage: CoverageTable,
1809 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>,
1810 ) -> Self {
1811 Self {
1812 coverage: coverage.into(),
1813 chained_seq_rule_sets: chained_seq_rule_sets.into_iter().map(Into::into).collect(),
1814 }
1815 }
1816}
1817
1818impl FontWrite for ChainedSequenceContextFormat1 {
1819 #[allow(clippy::unnecessary_cast)]
1820 fn write_into(&self, writer: &mut TableWriter) {
1821 (1 as u16).write_into(writer);
1822 self.coverage.write_into(writer);
1823 (u16::try_from(array_len(&self.chained_seq_rule_sets)).unwrap()).write_into(writer);
1824 self.chained_seq_rule_sets.write_into(writer);
1825 }
1826 fn table_type(&self) -> TableType {
1827 TableType::Named("ChainedSequenceContextFormat1")
1828 }
1829}
1830
1831impl Validate for ChainedSequenceContextFormat1 {
1832 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1833 ctx.in_table("ChainedSequenceContextFormat1", |ctx| {
1834 ctx.in_field("coverage", |ctx| {
1835 self.coverage.validate_impl(ctx);
1836 });
1837 ctx.in_field("chained_seq_rule_sets", |ctx| {
1838 if self.chained_seq_rule_sets.len() > (u16::MAX as usize) {
1839 ctx.report("array exceeds max length");
1840 }
1841 self.chained_seq_rule_sets.validate_impl(ctx);
1842 });
1843 })
1844 }
1845}
1846
1847impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>>
1848 for ChainedSequenceContextFormat1
1849{
1850 fn from_obj_ref(
1851 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>,
1852 _: FontData,
1853 ) -> Self {
1854 ChainedSequenceContextFormat1 {
1855 coverage: obj.coverage().to_owned_table(),
1856 chained_seq_rule_sets: obj.chained_seq_rule_sets().to_owned_table(),
1857 }
1858 }
1859}
1860
1861#[allow(clippy::needless_lifetimes)]
1862impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>>
1863 for ChainedSequenceContextFormat1
1864{
1865}
1866
1867impl<'a> FontRead<'a> for ChainedSequenceContextFormat1 {
1868 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1869 <read_fonts::tables::layout::ChainedSequenceContextFormat1 as FontRead>::read(data)
1870 .map(|x| x.to_owned_table())
1871 }
1872}
1873
1874#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1876#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1877pub struct ChainedSequenceRuleSet {
1878 pub chained_seq_rules: Vec<OffsetMarker<ChainedSequenceRule>>,
1881}
1882
1883impl ChainedSequenceRuleSet {
1884 pub fn new(chained_seq_rules: Vec<ChainedSequenceRule>) -> Self {
1886 Self {
1887 chained_seq_rules: chained_seq_rules.into_iter().map(Into::into).collect(),
1888 }
1889 }
1890}
1891
1892impl FontWrite for ChainedSequenceRuleSet {
1893 #[allow(clippy::unnecessary_cast)]
1894 fn write_into(&self, writer: &mut TableWriter) {
1895 (u16::try_from(array_len(&self.chained_seq_rules)).unwrap()).write_into(writer);
1896 self.chained_seq_rules.write_into(writer);
1897 }
1898 fn table_type(&self) -> TableType {
1899 TableType::Named("ChainedSequenceRuleSet")
1900 }
1901}
1902
1903impl Validate for ChainedSequenceRuleSet {
1904 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1905 ctx.in_table("ChainedSequenceRuleSet", |ctx| {
1906 ctx.in_field("chained_seq_rules", |ctx| {
1907 if self.chained_seq_rules.len() > (u16::MAX as usize) {
1908 ctx.report("array exceeds max length");
1909 }
1910 self.chained_seq_rules.validate_impl(ctx);
1911 });
1912 })
1913 }
1914}
1915
1916impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>>
1917 for ChainedSequenceRuleSet
1918{
1919 fn from_obj_ref(
1920 obj: &read_fonts::tables::layout::ChainedSequenceRuleSet<'a>,
1921 _: FontData,
1922 ) -> Self {
1923 ChainedSequenceRuleSet {
1924 chained_seq_rules: obj.chained_seq_rules().to_owned_table(),
1925 }
1926 }
1927}
1928
1929#[allow(clippy::needless_lifetimes)]
1930impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>>
1931 for ChainedSequenceRuleSet
1932{
1933}
1934
1935impl<'a> FontRead<'a> for ChainedSequenceRuleSet {
1936 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1937 <read_fonts::tables::layout::ChainedSequenceRuleSet as FontRead>::read(data)
1938 .map(|x| x.to_owned_table())
1939 }
1940}
1941
1942#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1944#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1945pub struct ChainedSequenceRule {
1946 pub backtrack_sequence: Vec<GlyphId16>,
1948 pub input_sequence: Vec<GlyphId16>,
1950 pub lookahead_sequence: Vec<GlyphId16>,
1952 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1954}
1955
1956impl ChainedSequenceRule {
1957 pub fn new(
1959 backtrack_sequence: Vec<GlyphId16>,
1960 input_sequence: Vec<GlyphId16>,
1961 lookahead_sequence: Vec<GlyphId16>,
1962 seq_lookup_records: Vec<SequenceLookupRecord>,
1963 ) -> Self {
1964 Self {
1965 backtrack_sequence,
1966 input_sequence,
1967 lookahead_sequence,
1968 seq_lookup_records,
1969 }
1970 }
1971}
1972
1973impl FontWrite for ChainedSequenceRule {
1974 #[allow(clippy::unnecessary_cast)]
1975 fn write_into(&self, writer: &mut TableWriter) {
1976 (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer);
1977 self.backtrack_sequence.write_into(writer);
1978 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
1979 self.input_sequence.write_into(writer);
1980 (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer);
1981 self.lookahead_sequence.write_into(writer);
1982 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1983 self.seq_lookup_records.write_into(writer);
1984 }
1985 fn table_type(&self) -> TableType {
1986 TableType::Named("ChainedSequenceRule")
1987 }
1988}
1989
1990impl Validate for ChainedSequenceRule {
1991 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1992 ctx.in_table("ChainedSequenceRule", |ctx| {
1993 ctx.in_field("backtrack_sequence", |ctx| {
1994 if self.backtrack_sequence.len() > (u16::MAX as usize) {
1995 ctx.report("array exceeds max length");
1996 }
1997 });
1998 ctx.in_field("lookahead_sequence", |ctx| {
1999 if self.lookahead_sequence.len() > (u16::MAX as usize) {
2000 ctx.report("array exceeds max length");
2001 }
2002 });
2003 ctx.in_field("seq_lookup_records", |ctx| {
2004 if self.seq_lookup_records.len() > (u16::MAX as usize) {
2005 ctx.report("array exceeds max length");
2006 }
2007 self.seq_lookup_records.validate_impl(ctx);
2008 });
2009 })
2010 }
2011}
2012
2013impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule {
2014 fn from_obj_ref(
2015 obj: &read_fonts::tables::layout::ChainedSequenceRule<'a>,
2016 _: FontData,
2017 ) -> Self {
2018 let offset_data = obj.offset_data();
2019 ChainedSequenceRule {
2020 backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data),
2021 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
2022 lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data),
2023 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2024 }
2025 }
2026}
2027
2028#[allow(clippy::needless_lifetimes)]
2029impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule {}
2030
2031impl<'a> FontRead<'a> for ChainedSequenceRule {
2032 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2033 <read_fonts::tables::layout::ChainedSequenceRule as FontRead>::read(data)
2034 .map(|x| x.to_owned_table())
2035 }
2036}
2037
2038#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2040#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2041pub struct ChainedSequenceContextFormat2 {
2042 pub coverage: OffsetMarker<CoverageTable>,
2045 pub backtrack_class_def: OffsetMarker<ClassDef>,
2048 pub input_class_def: OffsetMarker<ClassDef>,
2051 pub lookahead_class_def: OffsetMarker<ClassDef>,
2054 pub chained_class_seq_rule_sets: Vec<NullableOffsetMarker<ChainedClassSequenceRuleSet>>,
2057}
2058
2059impl ChainedSequenceContextFormat2 {
2060 pub fn new(
2062 coverage: CoverageTable,
2063 backtrack_class_def: ClassDef,
2064 input_class_def: ClassDef,
2065 lookahead_class_def: ClassDef,
2066 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>,
2067 ) -> Self {
2068 Self {
2069 coverage: coverage.into(),
2070 backtrack_class_def: backtrack_class_def.into(),
2071 input_class_def: input_class_def.into(),
2072 lookahead_class_def: lookahead_class_def.into(),
2073 chained_class_seq_rule_sets: chained_class_seq_rule_sets
2074 .into_iter()
2075 .map(Into::into)
2076 .collect(),
2077 }
2078 }
2079}
2080
2081impl FontWrite for ChainedSequenceContextFormat2 {
2082 #[allow(clippy::unnecessary_cast)]
2083 fn write_into(&self, writer: &mut TableWriter) {
2084 (2 as u16).write_into(writer);
2085 self.coverage.write_into(writer);
2086 self.backtrack_class_def.write_into(writer);
2087 self.input_class_def.write_into(writer);
2088 self.lookahead_class_def.write_into(writer);
2089 (u16::try_from(array_len(&self.chained_class_seq_rule_sets)).unwrap()).write_into(writer);
2090 self.chained_class_seq_rule_sets.write_into(writer);
2091 }
2092 fn table_type(&self) -> TableType {
2093 TableType::Named("ChainedSequenceContextFormat2")
2094 }
2095}
2096
2097impl Validate for ChainedSequenceContextFormat2 {
2098 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2099 ctx.in_table("ChainedSequenceContextFormat2", |ctx| {
2100 ctx.in_field("coverage", |ctx| {
2101 self.coverage.validate_impl(ctx);
2102 });
2103 ctx.in_field("backtrack_class_def", |ctx| {
2104 self.backtrack_class_def.validate_impl(ctx);
2105 });
2106 ctx.in_field("input_class_def", |ctx| {
2107 self.input_class_def.validate_impl(ctx);
2108 });
2109 ctx.in_field("lookahead_class_def", |ctx| {
2110 self.lookahead_class_def.validate_impl(ctx);
2111 });
2112 ctx.in_field("chained_class_seq_rule_sets", |ctx| {
2113 if self.chained_class_seq_rule_sets.len() > (u16::MAX as usize) {
2114 ctx.report("array exceeds max length");
2115 }
2116 self.chained_class_seq_rule_sets.validate_impl(ctx);
2117 });
2118 })
2119 }
2120}
2121
2122impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>>
2123 for ChainedSequenceContextFormat2
2124{
2125 fn from_obj_ref(
2126 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>,
2127 _: FontData,
2128 ) -> Self {
2129 ChainedSequenceContextFormat2 {
2130 coverage: obj.coverage().to_owned_table(),
2131 backtrack_class_def: obj.backtrack_class_def().to_owned_table(),
2132 input_class_def: obj.input_class_def().to_owned_table(),
2133 lookahead_class_def: obj.lookahead_class_def().to_owned_table(),
2134 chained_class_seq_rule_sets: obj.chained_class_seq_rule_sets().to_owned_table(),
2135 }
2136 }
2137}
2138
2139#[allow(clippy::needless_lifetimes)]
2140impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>>
2141 for ChainedSequenceContextFormat2
2142{
2143}
2144
2145impl<'a> FontRead<'a> for ChainedSequenceContextFormat2 {
2146 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2147 <read_fonts::tables::layout::ChainedSequenceContextFormat2 as FontRead>::read(data)
2148 .map(|x| x.to_owned_table())
2149 }
2150}
2151
2152#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2154#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2155pub struct ChainedClassSequenceRuleSet {
2156 pub chained_class_seq_rules: Vec<OffsetMarker<ChainedClassSequenceRule>>,
2159}
2160
2161impl ChainedClassSequenceRuleSet {
2162 pub fn new(chained_class_seq_rules: Vec<ChainedClassSequenceRule>) -> Self {
2164 Self {
2165 chained_class_seq_rules: chained_class_seq_rules
2166 .into_iter()
2167 .map(Into::into)
2168 .collect(),
2169 }
2170 }
2171}
2172
2173impl FontWrite for ChainedClassSequenceRuleSet {
2174 #[allow(clippy::unnecessary_cast)]
2175 fn write_into(&self, writer: &mut TableWriter) {
2176 (u16::try_from(array_len(&self.chained_class_seq_rules)).unwrap()).write_into(writer);
2177 self.chained_class_seq_rules.write_into(writer);
2178 }
2179 fn table_type(&self) -> TableType {
2180 TableType::Named("ChainedClassSequenceRuleSet")
2181 }
2182}
2183
2184impl Validate for ChainedClassSequenceRuleSet {
2185 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2186 ctx.in_table("ChainedClassSequenceRuleSet", |ctx| {
2187 ctx.in_field("chained_class_seq_rules", |ctx| {
2188 if self.chained_class_seq_rules.len() > (u16::MAX as usize) {
2189 ctx.report("array exceeds max length");
2190 }
2191 self.chained_class_seq_rules.validate_impl(ctx);
2192 });
2193 })
2194 }
2195}
2196
2197impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>>
2198 for ChainedClassSequenceRuleSet
2199{
2200 fn from_obj_ref(
2201 obj: &read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>,
2202 _: FontData,
2203 ) -> Self {
2204 ChainedClassSequenceRuleSet {
2205 chained_class_seq_rules: obj.chained_class_seq_rules().to_owned_table(),
2206 }
2207 }
2208}
2209
2210#[allow(clippy::needless_lifetimes)]
2211impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>>
2212 for ChainedClassSequenceRuleSet
2213{
2214}
2215
2216impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet {
2217 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2218 <read_fonts::tables::layout::ChainedClassSequenceRuleSet as FontRead>::read(data)
2219 .map(|x| x.to_owned_table())
2220 }
2221}
2222
2223#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2225#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2226pub struct ChainedClassSequenceRule {
2227 pub backtrack_sequence: Vec<u16>,
2229 pub input_sequence: Vec<u16>,
2232 pub lookahead_sequence: Vec<u16>,
2234 pub seq_lookup_records: Vec<SequenceLookupRecord>,
2236}
2237
2238impl ChainedClassSequenceRule {
2239 pub fn new(
2241 backtrack_sequence: Vec<u16>,
2242 input_sequence: Vec<u16>,
2243 lookahead_sequence: Vec<u16>,
2244 seq_lookup_records: Vec<SequenceLookupRecord>,
2245 ) -> Self {
2246 Self {
2247 backtrack_sequence,
2248 input_sequence,
2249 lookahead_sequence,
2250 seq_lookup_records,
2251 }
2252 }
2253}
2254
2255impl FontWrite for ChainedClassSequenceRule {
2256 #[allow(clippy::unnecessary_cast)]
2257 fn write_into(&self, writer: &mut TableWriter) {
2258 (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer);
2259 self.backtrack_sequence.write_into(writer);
2260 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
2261 self.input_sequence.write_into(writer);
2262 (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer);
2263 self.lookahead_sequence.write_into(writer);
2264 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
2265 self.seq_lookup_records.write_into(writer);
2266 }
2267 fn table_type(&self) -> TableType {
2268 TableType::Named("ChainedClassSequenceRule")
2269 }
2270}
2271
2272impl Validate for ChainedClassSequenceRule {
2273 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2274 ctx.in_table("ChainedClassSequenceRule", |ctx| {
2275 ctx.in_field("backtrack_sequence", |ctx| {
2276 if self.backtrack_sequence.len() > (u16::MAX as usize) {
2277 ctx.report("array exceeds max length");
2278 }
2279 });
2280 ctx.in_field("lookahead_sequence", |ctx| {
2281 if self.lookahead_sequence.len() > (u16::MAX as usize) {
2282 ctx.report("array exceeds max length");
2283 }
2284 });
2285 ctx.in_field("seq_lookup_records", |ctx| {
2286 if self.seq_lookup_records.len() > (u16::MAX as usize) {
2287 ctx.report("array exceeds max length");
2288 }
2289 self.seq_lookup_records.validate_impl(ctx);
2290 });
2291 })
2292 }
2293}
2294
2295impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>>
2296 for ChainedClassSequenceRule
2297{
2298 fn from_obj_ref(
2299 obj: &read_fonts::tables::layout::ChainedClassSequenceRule<'a>,
2300 _: FontData,
2301 ) -> Self {
2302 let offset_data = obj.offset_data();
2303 ChainedClassSequenceRule {
2304 backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data),
2305 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
2306 lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data),
2307 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2308 }
2309 }
2310}
2311
2312#[allow(clippy::needless_lifetimes)]
2313impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>>
2314 for ChainedClassSequenceRule
2315{
2316}
2317
2318impl<'a> FontRead<'a> for ChainedClassSequenceRule {
2319 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2320 <read_fonts::tables::layout::ChainedClassSequenceRule as FontRead>::read(data)
2321 .map(|x| x.to_owned_table())
2322 }
2323}
2324
2325#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2327#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2328pub struct ChainedSequenceContextFormat3 {
2329 pub backtrack_coverages: Vec<OffsetMarker<CoverageTable>>,
2331 pub input_coverages: Vec<OffsetMarker<CoverageTable>>,
2333 pub lookahead_coverages: Vec<OffsetMarker<CoverageTable>>,
2335 pub seq_lookup_records: Vec<SequenceLookupRecord>,
2337}
2338
2339impl ChainedSequenceContextFormat3 {
2340 pub fn new(
2342 backtrack_coverages: Vec<CoverageTable>,
2343 input_coverages: Vec<CoverageTable>,
2344 lookahead_coverages: Vec<CoverageTable>,
2345 seq_lookup_records: Vec<SequenceLookupRecord>,
2346 ) -> Self {
2347 Self {
2348 backtrack_coverages: backtrack_coverages.into_iter().map(Into::into).collect(),
2349 input_coverages: input_coverages.into_iter().map(Into::into).collect(),
2350 lookahead_coverages: lookahead_coverages.into_iter().map(Into::into).collect(),
2351 seq_lookup_records,
2352 }
2353 }
2354}
2355
2356impl FontWrite for ChainedSequenceContextFormat3 {
2357 #[allow(clippy::unnecessary_cast)]
2358 fn write_into(&self, writer: &mut TableWriter) {
2359 (3 as u16).write_into(writer);
2360 (u16::try_from(array_len(&self.backtrack_coverages)).unwrap()).write_into(writer);
2361 self.backtrack_coverages.write_into(writer);
2362 (u16::try_from(array_len(&self.input_coverages)).unwrap()).write_into(writer);
2363 self.input_coverages.write_into(writer);
2364 (u16::try_from(array_len(&self.lookahead_coverages)).unwrap()).write_into(writer);
2365 self.lookahead_coverages.write_into(writer);
2366 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
2367 self.seq_lookup_records.write_into(writer);
2368 }
2369 fn table_type(&self) -> TableType {
2370 TableType::Named("ChainedSequenceContextFormat3")
2371 }
2372}
2373
2374impl Validate for ChainedSequenceContextFormat3 {
2375 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2376 ctx.in_table("ChainedSequenceContextFormat3", |ctx| {
2377 ctx.in_field("backtrack_coverages", |ctx| {
2378 if self.backtrack_coverages.len() > (u16::MAX as usize) {
2379 ctx.report("array exceeds max length");
2380 }
2381 self.backtrack_coverages.validate_impl(ctx);
2382 });
2383 ctx.in_field("input_coverages", |ctx| {
2384 if self.input_coverages.len() > (u16::MAX as usize) {
2385 ctx.report("array exceeds max length");
2386 }
2387 self.input_coverages.validate_impl(ctx);
2388 });
2389 ctx.in_field("lookahead_coverages", |ctx| {
2390 if self.lookahead_coverages.len() > (u16::MAX as usize) {
2391 ctx.report("array exceeds max length");
2392 }
2393 self.lookahead_coverages.validate_impl(ctx);
2394 });
2395 ctx.in_field("seq_lookup_records", |ctx| {
2396 if self.seq_lookup_records.len() > (u16::MAX as usize) {
2397 ctx.report("array exceeds max length");
2398 }
2399 self.seq_lookup_records.validate_impl(ctx);
2400 });
2401 })
2402 }
2403}
2404
2405impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>>
2406 for ChainedSequenceContextFormat3
2407{
2408 fn from_obj_ref(
2409 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>,
2410 _: FontData,
2411 ) -> Self {
2412 let offset_data = obj.offset_data();
2413 ChainedSequenceContextFormat3 {
2414 backtrack_coverages: obj.backtrack_coverages().to_owned_table(),
2415 input_coverages: obj.input_coverages().to_owned_table(),
2416 lookahead_coverages: obj.lookahead_coverages().to_owned_table(),
2417 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2418 }
2419 }
2420}
2421
2422#[allow(clippy::needless_lifetimes)]
2423impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>>
2424 for ChainedSequenceContextFormat3
2425{
2426}
2427
2428impl<'a> FontRead<'a> for ChainedSequenceContextFormat3 {
2429 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2430 <read_fonts::tables::layout::ChainedSequenceContextFormat3 as FontRead>::read(data)
2431 .map(|x| x.to_owned_table())
2432 }
2433}
2434
2435#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2436#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2437pub enum ChainedSequenceContext {
2438 Format1(ChainedSequenceContextFormat1),
2439 Format2(ChainedSequenceContextFormat2),
2440 Format3(ChainedSequenceContextFormat3),
2441}
2442
2443impl ChainedSequenceContext {
2444 pub fn format_1(
2446 coverage: CoverageTable,
2447 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>,
2448 ) -> Self {
2449 Self::Format1(ChainedSequenceContextFormat1::new(
2450 coverage,
2451 chained_seq_rule_sets,
2452 ))
2453 }
2454
2455 pub fn format_2(
2457 coverage: CoverageTable,
2458 backtrack_class_def: ClassDef,
2459 input_class_def: ClassDef,
2460 lookahead_class_def: ClassDef,
2461 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>,
2462 ) -> Self {
2463 Self::Format2(ChainedSequenceContextFormat2::new(
2464 coverage,
2465 backtrack_class_def,
2466 input_class_def,
2467 lookahead_class_def,
2468 chained_class_seq_rule_sets,
2469 ))
2470 }
2471
2472 pub fn format_3(
2474 backtrack_coverages: Vec<CoverageTable>,
2475 input_coverages: Vec<CoverageTable>,
2476 lookahead_coverages: Vec<CoverageTable>,
2477 seq_lookup_records: Vec<SequenceLookupRecord>,
2478 ) -> Self {
2479 Self::Format3(ChainedSequenceContextFormat3::new(
2480 backtrack_coverages,
2481 input_coverages,
2482 lookahead_coverages,
2483 seq_lookup_records,
2484 ))
2485 }
2486}
2487
2488impl Default for ChainedSequenceContext {
2489 fn default() -> Self {
2490 Self::Format1(Default::default())
2491 }
2492}
2493
2494impl FontWrite for ChainedSequenceContext {
2495 fn write_into(&self, writer: &mut TableWriter) {
2496 match self {
2497 Self::Format1(item) => item.write_into(writer),
2498 Self::Format2(item) => item.write_into(writer),
2499 Self::Format3(item) => item.write_into(writer),
2500 }
2501 }
2502 fn table_type(&self) -> TableType {
2503 match self {
2504 Self::Format1(item) => item.table_type(),
2505 Self::Format2(item) => item.table_type(),
2506 Self::Format3(item) => item.table_type(),
2507 }
2508 }
2509}
2510
2511impl Validate for ChainedSequenceContext {
2512 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2513 match self {
2514 Self::Format1(item) => item.validate_impl(ctx),
2515 Self::Format2(item) => item.validate_impl(ctx),
2516 Self::Format3(item) => item.validate_impl(ctx),
2517 }
2518 }
2519}
2520
2521impl FromObjRef<read_fonts::tables::layout::ChainedSequenceContext<'_>> for ChainedSequenceContext {
2522 fn from_obj_ref(obj: &read_fonts::tables::layout::ChainedSequenceContext, _: FontData) -> Self {
2523 use read_fonts::tables::layout::ChainedSequenceContext as ObjRefType;
2524 match obj {
2525 ObjRefType::Format1(item) => ChainedSequenceContext::Format1(item.to_owned_table()),
2526 ObjRefType::Format2(item) => ChainedSequenceContext::Format2(item.to_owned_table()),
2527 ObjRefType::Format3(item) => ChainedSequenceContext::Format3(item.to_owned_table()),
2528 }
2529 }
2530}
2531
2532impl FromTableRef<read_fonts::tables::layout::ChainedSequenceContext<'_>>
2533 for ChainedSequenceContext
2534{
2535}
2536
2537impl<'a> FontRead<'a> for ChainedSequenceContext {
2538 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2539 <read_fonts::tables::layout::ChainedSequenceContext as FontRead>::read(data)
2540 .map(|x| x.to_owned_table())
2541 }
2542}
2543
2544impl From<ChainedSequenceContextFormat1> for ChainedSequenceContext {
2545 fn from(src: ChainedSequenceContextFormat1) -> ChainedSequenceContext {
2546 ChainedSequenceContext::Format1(src)
2547 }
2548}
2549
2550impl From<ChainedSequenceContextFormat2> for ChainedSequenceContext {
2551 fn from(src: ChainedSequenceContextFormat2) -> ChainedSequenceContext {
2552 ChainedSequenceContext::Format2(src)
2553 }
2554}
2555
2556impl From<ChainedSequenceContextFormat3> for ChainedSequenceContext {
2557 fn from(src: ChainedSequenceContextFormat3) -> ChainedSequenceContext {
2558 ChainedSequenceContext::Format3(src)
2559 }
2560}
2561
2562impl FontWrite for DeltaFormat {
2563 fn write_into(&self, writer: &mut TableWriter) {
2564 let val = *self as u16;
2565 writer.write_slice(&val.to_be_bytes())
2566 }
2567}
2568
2569#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2571#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2572pub struct Device {
2573 pub start_size: u16,
2575 pub end_size: u16,
2577 pub delta_format: DeltaFormat,
2579 pub delta_value: Vec<u16>,
2581}
2582
2583impl FontWrite for Device {
2584 fn write_into(&self, writer: &mut TableWriter) {
2585 self.start_size.write_into(writer);
2586 self.end_size.write_into(writer);
2587 self.delta_format.write_into(writer);
2588 self.delta_value.write_into(writer);
2589 }
2590 fn table_type(&self) -> TableType {
2591 TableType::Named("Device")
2592 }
2593}
2594
2595impl Validate for Device {
2596 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2597}
2598
2599impl<'a> FromObjRef<read_fonts::tables::layout::Device<'a>> for Device {
2600 fn from_obj_ref(obj: &read_fonts::tables::layout::Device<'a>, _: FontData) -> Self {
2601 let offset_data = obj.offset_data();
2602 Device {
2603 start_size: obj.start_size(),
2604 end_size: obj.end_size(),
2605 delta_format: obj.delta_format(),
2606 delta_value: obj.delta_value().to_owned_obj(offset_data),
2607 }
2608 }
2609}
2610
2611#[allow(clippy::needless_lifetimes)]
2612impl<'a> FromTableRef<read_fonts::tables::layout::Device<'a>> for Device {}
2613
2614impl<'a> FontRead<'a> for Device {
2615 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2616 <read_fonts::tables::layout::Device as FontRead>::read(data).map(|x| x.to_owned_table())
2617 }
2618}
2619
2620#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2622#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2623pub struct VariationIndex {
2624 pub delta_set_outer_index: u16,
2627 pub delta_set_inner_index: u16,
2630}
2631
2632impl VariationIndex {
2633 pub fn new(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self {
2635 Self {
2636 delta_set_outer_index,
2637 delta_set_inner_index,
2638 }
2639 }
2640}
2641
2642impl FontWrite for VariationIndex {
2643 #[allow(clippy::unnecessary_cast)]
2644 fn write_into(&self, writer: &mut TableWriter) {
2645 self.delta_set_outer_index.write_into(writer);
2646 self.delta_set_inner_index.write_into(writer);
2647 (DeltaFormat::VariationIndex as DeltaFormat).write_into(writer);
2648 }
2649 fn table_type(&self) -> TableType {
2650 TableType::Named("VariationIndex")
2651 }
2652}
2653
2654impl Validate for VariationIndex {
2655 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2656}
2657
2658impl<'a> FromObjRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex {
2659 fn from_obj_ref(obj: &read_fonts::tables::layout::VariationIndex<'a>, _: FontData) -> Self {
2660 VariationIndex {
2661 delta_set_outer_index: obj.delta_set_outer_index(),
2662 delta_set_inner_index: obj.delta_set_inner_index(),
2663 }
2664 }
2665}
2666
2667#[allow(clippy::needless_lifetimes)]
2668impl<'a> FromTableRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex {}
2669
2670impl<'a> FontRead<'a> for VariationIndex {
2671 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2672 <read_fonts::tables::layout::VariationIndex as FontRead>::read(data)
2673 .map(|x| x.to_owned_table())
2674 }
2675}
2676
2677#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2688#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2689pub struct PendingVariationIndex {
2690 pub delta_set_id: u32,
2692}
2693
2694impl PendingVariationIndex {
2695 pub fn new(delta_set_id: u32) -> Self {
2697 Self { delta_set_id }
2698 }
2699}
2700
2701impl Validate for PendingVariationIndex {
2702 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2703}
2704
2705#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2707#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2708pub enum DeviceOrVariationIndex {
2709 Device(Device),
2710 VariationIndex(VariationIndex),
2711 PendingVariationIndex(PendingVariationIndex),
2712}
2713
2714impl DeviceOrVariationIndex {
2715 pub fn variation_index(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self {
2717 Self::VariationIndex(VariationIndex::new(
2718 delta_set_outer_index,
2719 delta_set_inner_index,
2720 ))
2721 }
2722
2723 pub fn pending_variation_index(delta_set_id: u32) -> Self {
2725 Self::PendingVariationIndex(PendingVariationIndex::new(delta_set_id))
2726 }
2727}
2728
2729impl Default for DeviceOrVariationIndex {
2730 fn default() -> Self {
2731 Self::Device(Default::default())
2732 }
2733}
2734
2735impl FontWrite for DeviceOrVariationIndex {
2736 fn write_into(&self, writer: &mut TableWriter) {
2737 match self {
2738 Self::Device(item) => item.write_into(writer),
2739 Self::VariationIndex(item) => item.write_into(writer),
2740 Self::PendingVariationIndex(item) => item.write_into(writer),
2741 }
2742 }
2743 fn table_type(&self) -> TableType {
2744 match self {
2745 Self::Device(item) => item.table_type(),
2746 Self::VariationIndex(item) => item.table_type(),
2747 Self::PendingVariationIndex(item) => item.table_type(),
2748 }
2749 }
2750}
2751
2752impl Validate for DeviceOrVariationIndex {
2753 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2754 match self {
2755 Self::Device(item) => item.validate_impl(ctx),
2756 Self::VariationIndex(item) => item.validate_impl(ctx),
2757 Self::PendingVariationIndex(item) => item.validate_impl(ctx),
2758 }
2759 }
2760}
2761
2762impl FromObjRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>> for DeviceOrVariationIndex {
2763 fn from_obj_ref(obj: &read_fonts::tables::layout::DeviceOrVariationIndex, _: FontData) -> Self {
2764 use read_fonts::tables::layout::DeviceOrVariationIndex as ObjRefType;
2765 match obj {
2766 ObjRefType::Device(item) => DeviceOrVariationIndex::Device(item.to_owned_table()),
2767 ObjRefType::VariationIndex(item) => {
2768 DeviceOrVariationIndex::VariationIndex(item.to_owned_table())
2769 }
2770 }
2771 }
2772}
2773
2774impl FromTableRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>>
2775 for DeviceOrVariationIndex
2776{
2777}
2778
2779impl<'a> FontRead<'a> for DeviceOrVariationIndex {
2780 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2781 <read_fonts::tables::layout::DeviceOrVariationIndex as FontRead>::read(data)
2782 .map(|x| x.to_owned_table())
2783 }
2784}
2785
2786impl From<Device> for DeviceOrVariationIndex {
2787 fn from(src: Device) -> DeviceOrVariationIndex {
2788 DeviceOrVariationIndex::Device(src)
2789 }
2790}
2791
2792impl From<VariationIndex> for DeviceOrVariationIndex {
2793 fn from(src: VariationIndex) -> DeviceOrVariationIndex {
2794 DeviceOrVariationIndex::VariationIndex(src)
2795 }
2796}
2797
2798impl From<PendingVariationIndex> for DeviceOrVariationIndex {
2799 fn from(src: PendingVariationIndex) -> DeviceOrVariationIndex {
2800 DeviceOrVariationIndex::PendingVariationIndex(src)
2801 }
2802}
2803
2804#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2806#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2807pub struct FeatureVariations {
2808 pub feature_variation_records: Vec<FeatureVariationRecord>,
2810}
2811
2812impl FeatureVariations {
2813 pub fn new(feature_variation_records: Vec<FeatureVariationRecord>) -> Self {
2815 Self {
2816 feature_variation_records,
2817 }
2818 }
2819}
2820
2821impl FontWrite for FeatureVariations {
2822 #[allow(clippy::unnecessary_cast)]
2823 fn write_into(&self, writer: &mut TableWriter) {
2824 (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer);
2825 (u32::try_from(array_len(&self.feature_variation_records)).unwrap()).write_into(writer);
2826 self.feature_variation_records.write_into(writer);
2827 }
2828 fn table_type(&self) -> TableType {
2829 TableType::Named("FeatureVariations")
2830 }
2831}
2832
2833impl Validate for FeatureVariations {
2834 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2835 ctx.in_table("FeatureVariations", |ctx| {
2836 ctx.in_field("feature_variation_records", |ctx| {
2837 if self.feature_variation_records.len() > (u32::MAX as usize) {
2838 ctx.report("array exceeds max length");
2839 }
2840 self.feature_variation_records.validate_impl(ctx);
2841 });
2842 })
2843 }
2844}
2845
2846impl<'a> FromObjRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations {
2847 fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureVariations<'a>, _: FontData) -> Self {
2848 let offset_data = obj.offset_data();
2849 FeatureVariations {
2850 feature_variation_records: obj.feature_variation_records().to_owned_obj(offset_data),
2851 }
2852 }
2853}
2854
2855#[allow(clippy::needless_lifetimes)]
2856impl<'a> FromTableRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations {}
2857
2858impl<'a> FontRead<'a> for FeatureVariations {
2859 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2860 <read_fonts::tables::layout::FeatureVariations as FontRead>::read(data)
2861 .map(|x| x.to_owned_table())
2862 }
2863}
2864
2865#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2867#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2868pub struct FeatureVariationRecord {
2869 pub condition_set: NullableOffsetMarker<ConditionSet, WIDTH_32>,
2872 pub feature_table_substitution: NullableOffsetMarker<FeatureTableSubstitution, WIDTH_32>,
2875}
2876
2877impl FeatureVariationRecord {
2878 pub fn new(
2880 condition_set: Option<ConditionSet>,
2881 feature_table_substitution: Option<FeatureTableSubstitution>,
2882 ) -> Self {
2883 Self {
2884 condition_set: condition_set.into(),
2885 feature_table_substitution: feature_table_substitution.into(),
2886 }
2887 }
2888}
2889
2890impl FontWrite for FeatureVariationRecord {
2891 fn write_into(&self, writer: &mut TableWriter) {
2892 self.condition_set.write_into(writer);
2893 self.feature_table_substitution.write_into(writer);
2894 }
2895 fn table_type(&self) -> TableType {
2896 TableType::Named("FeatureVariationRecord")
2897 }
2898}
2899
2900impl Validate for FeatureVariationRecord {
2901 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2902 ctx.in_table("FeatureVariationRecord", |ctx| {
2903 ctx.in_field("condition_set", |ctx| {
2904 self.condition_set.validate_impl(ctx);
2905 });
2906 ctx.in_field("feature_table_substitution", |ctx| {
2907 self.feature_table_substitution.validate_impl(ctx);
2908 });
2909 })
2910 }
2911}
2912
2913impl FromObjRef<read_fonts::tables::layout::FeatureVariationRecord> for FeatureVariationRecord {
2914 fn from_obj_ref(
2915 obj: &read_fonts::tables::layout::FeatureVariationRecord,
2916 offset_data: FontData,
2917 ) -> Self {
2918 FeatureVariationRecord {
2919 condition_set: obj.condition_set(offset_data).to_owned_table(),
2920 feature_table_substitution: obj
2921 .feature_table_substitution(offset_data)
2922 .to_owned_table(),
2923 }
2924 }
2925}
2926
2927#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2929#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2930pub struct ConditionSet {
2931 pub conditions: Vec<OffsetMarker<Condition, WIDTH_32>>,
2934}
2935
2936impl ConditionSet {
2937 pub fn new(conditions: Vec<Condition>) -> Self {
2939 Self {
2940 conditions: conditions.into_iter().map(Into::into).collect(),
2941 }
2942 }
2943}
2944
2945impl FontWrite for ConditionSet {
2946 #[allow(clippy::unnecessary_cast)]
2947 fn write_into(&self, writer: &mut TableWriter) {
2948 (u16::try_from(array_len(&self.conditions)).unwrap()).write_into(writer);
2949 self.conditions.write_into(writer);
2950 }
2951 fn table_type(&self) -> TableType {
2952 TableType::Named("ConditionSet")
2953 }
2954}
2955
2956impl Validate for ConditionSet {
2957 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2958 ctx.in_table("ConditionSet", |ctx| {
2959 ctx.in_field("conditions", |ctx| {
2960 if self.conditions.len() > (u16::MAX as usize) {
2961 ctx.report("array exceeds max length");
2962 }
2963 self.conditions.validate_impl(ctx);
2964 });
2965 })
2966 }
2967}
2968
2969impl<'a> FromObjRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet {
2970 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionSet<'a>, _: FontData) -> Self {
2971 ConditionSet {
2972 conditions: obj.conditions().to_owned_table(),
2973 }
2974 }
2975}
2976
2977#[allow(clippy::needless_lifetimes)]
2978impl<'a> FromTableRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet {}
2979
2980impl<'a> FontRead<'a> for ConditionSet {
2981 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
2982 <read_fonts::tables::layout::ConditionSet as FontRead>::read(data)
2983 .map(|x| x.to_owned_table())
2984 }
2985}
2986
2987#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2992#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2993pub enum Condition {
2994 Format1AxisRange(ConditionFormat1),
2995 Format2VariableValue(ConditionFormat2),
2996 Format3And(ConditionFormat3),
2997 Format4Or(ConditionFormat4),
2998 Format5Negate(ConditionFormat5),
2999}
3000
3001impl Condition {
3002 pub fn format_1_axis_range(
3004 axis_index: u16,
3005 filter_range_min_value: F2Dot14,
3006 filter_range_max_value: F2Dot14,
3007 ) -> Self {
3008 Self::Format1AxisRange(ConditionFormat1::new(
3009 axis_index,
3010 filter_range_min_value,
3011 filter_range_max_value,
3012 ))
3013 }
3014
3015 pub fn format_2_variable_value(default_value: i16, var_index: u32) -> Self {
3017 Self::Format2VariableValue(ConditionFormat2::new(default_value, var_index))
3018 }
3019
3020 pub fn format_3_and(condition_count: u8, conditions: Vec<Condition>) -> Self {
3022 Self::Format3And(ConditionFormat3::new(condition_count, conditions))
3023 }
3024
3025 pub fn format_4_or(condition_count: u8, conditions: Vec<Condition>) -> Self {
3027 Self::Format4Or(ConditionFormat4::new(condition_count, conditions))
3028 }
3029
3030 pub fn format_5_negate(condition: Condition) -> Self {
3032 Self::Format5Negate(ConditionFormat5::new(condition))
3033 }
3034}
3035
3036impl Default for Condition {
3037 fn default() -> Self {
3038 Self::Format1AxisRange(Default::default())
3039 }
3040}
3041
3042impl FontWrite for Condition {
3043 fn write_into(&self, writer: &mut TableWriter) {
3044 match self {
3045 Self::Format1AxisRange(item) => item.write_into(writer),
3046 Self::Format2VariableValue(item) => item.write_into(writer),
3047 Self::Format3And(item) => item.write_into(writer),
3048 Self::Format4Or(item) => item.write_into(writer),
3049 Self::Format5Negate(item) => item.write_into(writer),
3050 }
3051 }
3052 fn table_type(&self) -> TableType {
3053 match self {
3054 Self::Format1AxisRange(item) => item.table_type(),
3055 Self::Format2VariableValue(item) => item.table_type(),
3056 Self::Format3And(item) => item.table_type(),
3057 Self::Format4Or(item) => item.table_type(),
3058 Self::Format5Negate(item) => item.table_type(),
3059 }
3060 }
3061}
3062
3063impl Validate for Condition {
3064 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3065 match self {
3066 Self::Format1AxisRange(item) => item.validate_impl(ctx),
3067 Self::Format2VariableValue(item) => item.validate_impl(ctx),
3068 Self::Format3And(item) => item.validate_impl(ctx),
3069 Self::Format4Or(item) => item.validate_impl(ctx),
3070 Self::Format5Negate(item) => item.validate_impl(ctx),
3071 }
3072 }
3073}
3074
3075impl FromObjRef<read_fonts::tables::layout::Condition<'_>> for Condition {
3076 fn from_obj_ref(obj: &read_fonts::tables::layout::Condition, _: FontData) -> Self {
3077 use read_fonts::tables::layout::Condition as ObjRefType;
3078 match obj {
3079 ObjRefType::Format1AxisRange(item) => {
3080 Condition::Format1AxisRange(item.to_owned_table())
3081 }
3082 ObjRefType::Format2VariableValue(item) => {
3083 Condition::Format2VariableValue(item.to_owned_table())
3084 }
3085 ObjRefType::Format3And(item) => Condition::Format3And(item.to_owned_table()),
3086 ObjRefType::Format4Or(item) => Condition::Format4Or(item.to_owned_table()),
3087 ObjRefType::Format5Negate(item) => Condition::Format5Negate(item.to_owned_table()),
3088 }
3089 }
3090}
3091
3092impl FromTableRef<read_fonts::tables::layout::Condition<'_>> for Condition {}
3093
3094impl<'a> FontRead<'a> for Condition {
3095 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3096 <read_fonts::tables::layout::Condition as FontRead>::read(data).map(|x| x.to_owned_table())
3097 }
3098}
3099
3100impl From<ConditionFormat1> for Condition {
3101 fn from(src: ConditionFormat1) -> Condition {
3102 Condition::Format1AxisRange(src)
3103 }
3104}
3105
3106impl From<ConditionFormat2> for Condition {
3107 fn from(src: ConditionFormat2) -> Condition {
3108 Condition::Format2VariableValue(src)
3109 }
3110}
3111
3112impl From<ConditionFormat3> for Condition {
3113 fn from(src: ConditionFormat3) -> Condition {
3114 Condition::Format3And(src)
3115 }
3116}
3117
3118impl From<ConditionFormat4> for Condition {
3119 fn from(src: ConditionFormat4) -> Condition {
3120 Condition::Format4Or(src)
3121 }
3122}
3123
3124impl From<ConditionFormat5> for Condition {
3125 fn from(src: ConditionFormat5) -> Condition {
3126 Condition::Format5Negate(src)
3127 }
3128}
3129
3130#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3133pub struct ConditionFormat1 {
3134 pub axis_index: u16,
3137 pub filter_range_min_value: F2Dot14,
3140 pub filter_range_max_value: F2Dot14,
3143}
3144
3145impl ConditionFormat1 {
3146 pub fn new(
3148 axis_index: u16,
3149 filter_range_min_value: F2Dot14,
3150 filter_range_max_value: F2Dot14,
3151 ) -> Self {
3152 Self {
3153 axis_index,
3154 filter_range_min_value,
3155 filter_range_max_value,
3156 }
3157 }
3158}
3159
3160impl FontWrite for ConditionFormat1 {
3161 #[allow(clippy::unnecessary_cast)]
3162 fn write_into(&self, writer: &mut TableWriter) {
3163 (1 as u16).write_into(writer);
3164 self.axis_index.write_into(writer);
3165 self.filter_range_min_value.write_into(writer);
3166 self.filter_range_max_value.write_into(writer);
3167 }
3168 fn table_type(&self) -> TableType {
3169 TableType::Named("ConditionFormat1")
3170 }
3171}
3172
3173impl Validate for ConditionFormat1 {
3174 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3175}
3176
3177impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 {
3178 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat1<'a>, _: FontData) -> Self {
3179 ConditionFormat1 {
3180 axis_index: obj.axis_index(),
3181 filter_range_min_value: obj.filter_range_min_value(),
3182 filter_range_max_value: obj.filter_range_max_value(),
3183 }
3184 }
3185}
3186
3187#[allow(clippy::needless_lifetimes)]
3188impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 {}
3189
3190impl<'a> FontRead<'a> for ConditionFormat1 {
3191 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3192 <read_fonts::tables::layout::ConditionFormat1 as FontRead>::read(data)
3193 .map(|x| x.to_owned_table())
3194 }
3195}
3196
3197#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3199#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3200pub struct ConditionFormat2 {
3201 pub default_value: i16,
3203 pub var_index: u32,
3205}
3206
3207impl ConditionFormat2 {
3208 pub fn new(default_value: i16, var_index: u32) -> Self {
3210 Self {
3211 default_value,
3212 var_index,
3213 }
3214 }
3215}
3216
3217impl FontWrite for ConditionFormat2 {
3218 #[allow(clippy::unnecessary_cast)]
3219 fn write_into(&self, writer: &mut TableWriter) {
3220 (2 as u16).write_into(writer);
3221 self.default_value.write_into(writer);
3222 self.var_index.write_into(writer);
3223 }
3224 fn table_type(&self) -> TableType {
3225 TableType::Named("ConditionFormat2")
3226 }
3227}
3228
3229impl Validate for ConditionFormat2 {
3230 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3231}
3232
3233impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 {
3234 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat2<'a>, _: FontData) -> Self {
3235 ConditionFormat2 {
3236 default_value: obj.default_value(),
3237 var_index: obj.var_index(),
3238 }
3239 }
3240}
3241
3242#[allow(clippy::needless_lifetimes)]
3243impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 {}
3244
3245impl<'a> FontRead<'a> for ConditionFormat2 {
3246 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3247 <read_fonts::tables::layout::ConditionFormat2 as FontRead>::read(data)
3248 .map(|x| x.to_owned_table())
3249 }
3250}
3251
3252#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3254#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3255pub struct ConditionFormat3 {
3256 pub condition_count: u8,
3258 pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>,
3260}
3261
3262impl ConditionFormat3 {
3263 pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self {
3265 Self {
3266 condition_count,
3267 conditions: conditions.into_iter().map(Into::into).collect(),
3268 }
3269 }
3270}
3271
3272impl FontWrite for ConditionFormat3 {
3273 #[allow(clippy::unnecessary_cast)]
3274 fn write_into(&self, writer: &mut TableWriter) {
3275 (3 as u16).write_into(writer);
3276 self.condition_count.write_into(writer);
3277 self.conditions.write_into(writer);
3278 }
3279 fn table_type(&self) -> TableType {
3280 TableType::Named("ConditionFormat3")
3281 }
3282}
3283
3284impl Validate for ConditionFormat3 {
3285 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3286 ctx.in_table("ConditionFormat3", |ctx| {
3287 ctx.in_field("conditions", |ctx| {
3288 if self.conditions.len() > (u8::MAX as usize) {
3289 ctx.report("array exceeds max length");
3290 }
3291 self.conditions.validate_impl(ctx);
3292 });
3293 })
3294 }
3295}
3296
3297impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 {
3298 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat3<'a>, _: FontData) -> Self {
3299 ConditionFormat3 {
3300 condition_count: obj.condition_count(),
3301 conditions: obj.conditions().to_owned_table(),
3302 }
3303 }
3304}
3305
3306#[allow(clippy::needless_lifetimes)]
3307impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 {}
3308
3309impl<'a> FontRead<'a> for ConditionFormat3 {
3310 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3311 <read_fonts::tables::layout::ConditionFormat3 as FontRead>::read(data)
3312 .map(|x| x.to_owned_table())
3313 }
3314}
3315
3316#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3318#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3319pub struct ConditionFormat4 {
3320 pub condition_count: u8,
3322 pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>,
3324}
3325
3326impl ConditionFormat4 {
3327 pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self {
3329 Self {
3330 condition_count,
3331 conditions: conditions.into_iter().map(Into::into).collect(),
3332 }
3333 }
3334}
3335
3336impl FontWrite for ConditionFormat4 {
3337 #[allow(clippy::unnecessary_cast)]
3338 fn write_into(&self, writer: &mut TableWriter) {
3339 (4 as u16).write_into(writer);
3340 self.condition_count.write_into(writer);
3341 self.conditions.write_into(writer);
3342 }
3343 fn table_type(&self) -> TableType {
3344 TableType::Named("ConditionFormat4")
3345 }
3346}
3347
3348impl Validate for ConditionFormat4 {
3349 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3350 ctx.in_table("ConditionFormat4", |ctx| {
3351 ctx.in_field("conditions", |ctx| {
3352 if self.conditions.len() > (u8::MAX as usize) {
3353 ctx.report("array exceeds max length");
3354 }
3355 self.conditions.validate_impl(ctx);
3356 });
3357 })
3358 }
3359}
3360
3361impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 {
3362 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat4<'a>, _: FontData) -> Self {
3363 ConditionFormat4 {
3364 condition_count: obj.condition_count(),
3365 conditions: obj.conditions().to_owned_table(),
3366 }
3367 }
3368}
3369
3370#[allow(clippy::needless_lifetimes)]
3371impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 {}
3372
3373impl<'a> FontRead<'a> for ConditionFormat4 {
3374 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3375 <read_fonts::tables::layout::ConditionFormat4 as FontRead>::read(data)
3376 .map(|x| x.to_owned_table())
3377 }
3378}
3379
3380#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3382#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3383pub struct ConditionFormat5 {
3384 pub condition: OffsetMarker<Condition, WIDTH_24>,
3386}
3387
3388impl ConditionFormat5 {
3389 pub fn new(condition: Condition) -> Self {
3391 Self {
3392 condition: condition.into(),
3393 }
3394 }
3395}
3396
3397impl FontWrite for ConditionFormat5 {
3398 #[allow(clippy::unnecessary_cast)]
3399 fn write_into(&self, writer: &mut TableWriter) {
3400 (5 as u16).write_into(writer);
3401 self.condition.write_into(writer);
3402 }
3403 fn table_type(&self) -> TableType {
3404 TableType::Named("ConditionFormat5")
3405 }
3406}
3407
3408impl Validate for ConditionFormat5 {
3409 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3410 ctx.in_table("ConditionFormat5", |ctx| {
3411 ctx.in_field("condition", |ctx| {
3412 self.condition.validate_impl(ctx);
3413 });
3414 })
3415 }
3416}
3417
3418impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 {
3419 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat5<'a>, _: FontData) -> Self {
3420 ConditionFormat5 {
3421 condition: obj.condition().to_owned_table(),
3422 }
3423 }
3424}
3425
3426#[allow(clippy::needless_lifetimes)]
3427impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 {}
3428
3429impl<'a> FontRead<'a> for ConditionFormat5 {
3430 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3431 <read_fonts::tables::layout::ConditionFormat5 as FontRead>::read(data)
3432 .map(|x| x.to_owned_table())
3433 }
3434}
3435
3436#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3438#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3439pub struct FeatureTableSubstitution {
3440 pub substitutions: Vec<FeatureTableSubstitutionRecord>,
3442}
3443
3444impl FeatureTableSubstitution {
3445 pub fn new(substitutions: Vec<FeatureTableSubstitutionRecord>) -> Self {
3447 Self { substitutions }
3448 }
3449}
3450
3451impl FontWrite for FeatureTableSubstitution {
3452 #[allow(clippy::unnecessary_cast)]
3453 fn write_into(&self, writer: &mut TableWriter) {
3454 (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer);
3455 (u16::try_from(array_len(&self.substitutions)).unwrap()).write_into(writer);
3456 self.substitutions.write_into(writer);
3457 }
3458 fn table_type(&self) -> TableType {
3459 TableType::Named("FeatureTableSubstitution")
3460 }
3461}
3462
3463impl Validate for FeatureTableSubstitution {
3464 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3465 ctx.in_table("FeatureTableSubstitution", |ctx| {
3466 ctx.in_field("substitutions", |ctx| {
3467 if self.substitutions.len() > (u16::MAX as usize) {
3468 ctx.report("array exceeds max length");
3469 }
3470 self.substitutions.validate_impl(ctx);
3471 });
3472 })
3473 }
3474}
3475
3476impl<'a> FromObjRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>>
3477 for FeatureTableSubstitution
3478{
3479 fn from_obj_ref(
3480 obj: &read_fonts::tables::layout::FeatureTableSubstitution<'a>,
3481 _: FontData,
3482 ) -> Self {
3483 let offset_data = obj.offset_data();
3484 FeatureTableSubstitution {
3485 substitutions: obj.substitutions().to_owned_obj(offset_data),
3486 }
3487 }
3488}
3489
3490#[allow(clippy::needless_lifetimes)]
3491impl<'a> FromTableRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>>
3492 for FeatureTableSubstitution
3493{
3494}
3495
3496impl<'a> FontRead<'a> for FeatureTableSubstitution {
3497 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3498 <read_fonts::tables::layout::FeatureTableSubstitution as FontRead>::read(data)
3499 .map(|x| x.to_owned_table())
3500 }
3501}
3502
3503#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3505#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3506pub struct FeatureTableSubstitutionRecord {
3507 pub feature_index: u16,
3509 pub alternate_feature: OffsetMarker<Feature, WIDTH_32>,
3512}
3513
3514impl FeatureTableSubstitutionRecord {
3515 pub fn new(feature_index: u16, alternate_feature: Feature) -> Self {
3517 Self {
3518 feature_index,
3519 alternate_feature: alternate_feature.into(),
3520 }
3521 }
3522}
3523
3524impl FontWrite for FeatureTableSubstitutionRecord {
3525 fn write_into(&self, writer: &mut TableWriter) {
3526 self.feature_index.write_into(writer);
3527 self.alternate_feature.write_into(writer);
3528 }
3529 fn table_type(&self) -> TableType {
3530 TableType::Named("FeatureTableSubstitutionRecord")
3531 }
3532}
3533
3534impl Validate for FeatureTableSubstitutionRecord {
3535 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3536 ctx.in_table("FeatureTableSubstitutionRecord", |ctx| {
3537 ctx.in_field("alternate_feature", |ctx| {
3538 self.alternate_feature.validate_impl(ctx);
3539 });
3540 })
3541 }
3542}
3543
3544impl FromObjRef<read_fonts::tables::layout::FeatureTableSubstitutionRecord>
3545 for FeatureTableSubstitutionRecord
3546{
3547 fn from_obj_ref(
3548 obj: &read_fonts::tables::layout::FeatureTableSubstitutionRecord,
3549 offset_data: FontData,
3550 ) -> Self {
3551 FeatureTableSubstitutionRecord {
3552 feature_index: obj.feature_index(),
3553 alternate_feature: obj.alternate_feature(offset_data).to_owned_table(),
3554 }
3555 }
3556}
3557
3558#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3559#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3560pub struct SizeParams {
3561 pub design_size: u16,
3566 pub identifier: u16,
3573 pub name_entry: u16,
3584 pub range_start: u16,
3590 pub range_end: u16,
3591}
3592
3593impl SizeParams {
3594 pub fn new(
3596 design_size: u16,
3597 identifier: u16,
3598 name_entry: u16,
3599 range_start: u16,
3600 range_end: u16,
3601 ) -> Self {
3602 Self {
3603 design_size,
3604 identifier,
3605 name_entry,
3606 range_start,
3607 range_end,
3608 }
3609 }
3610}
3611
3612impl FontWrite for SizeParams {
3613 fn write_into(&self, writer: &mut TableWriter) {
3614 self.design_size.write_into(writer);
3615 self.identifier.write_into(writer);
3616 self.name_entry.write_into(writer);
3617 self.range_start.write_into(writer);
3618 self.range_end.write_into(writer);
3619 }
3620 fn table_type(&self) -> TableType {
3621 TableType::Named("SizeParams")
3622 }
3623}
3624
3625impl Validate for SizeParams {
3626 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3627}
3628
3629impl<'a> FromObjRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams {
3630 fn from_obj_ref(obj: &read_fonts::tables::layout::SizeParams<'a>, _: FontData) -> Self {
3631 SizeParams {
3632 design_size: obj.design_size(),
3633 identifier: obj.identifier(),
3634 name_entry: obj.name_entry(),
3635 range_start: obj.range_start(),
3636 range_end: obj.range_end(),
3637 }
3638 }
3639}
3640
3641#[allow(clippy::needless_lifetimes)]
3642impl<'a> FromTableRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams {}
3643
3644impl<'a> FontRead<'a> for SizeParams {
3645 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3646 <read_fonts::tables::layout::SizeParams as FontRead>::read(data).map(|x| x.to_owned_table())
3647 }
3648}
3649
3650#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3651#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3652pub struct StylisticSetParams {
3653 pub ui_name_id: NameId,
3663}
3664
3665impl StylisticSetParams {
3666 pub fn new(ui_name_id: NameId) -> Self {
3668 Self { ui_name_id }
3669 }
3670}
3671
3672impl FontWrite for StylisticSetParams {
3673 #[allow(clippy::unnecessary_cast)]
3674 fn write_into(&self, writer: &mut TableWriter) {
3675 (0 as u16).write_into(writer);
3676 self.ui_name_id.write_into(writer);
3677 }
3678 fn table_type(&self) -> TableType {
3679 TableType::Named("StylisticSetParams")
3680 }
3681}
3682
3683impl Validate for StylisticSetParams {
3684 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3685}
3686
3687impl<'a> FromObjRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams {
3688 fn from_obj_ref(obj: &read_fonts::tables::layout::StylisticSetParams<'a>, _: FontData) -> Self {
3689 StylisticSetParams {
3690 ui_name_id: obj.ui_name_id(),
3691 }
3692 }
3693}
3694
3695#[allow(clippy::needless_lifetimes)]
3696impl<'a> FromTableRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams {}
3697
3698impl<'a> FontRead<'a> for StylisticSetParams {
3699 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3700 <read_fonts::tables::layout::StylisticSetParams as FontRead>::read(data)
3701 .map(|x| x.to_owned_table())
3702 }
3703}
3704
3705#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3707#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3708pub struct CharacterVariantParams {
3709 pub feat_ui_label_name_id: NameId,
3713 pub feat_ui_tooltip_text_name_id: NameId,
3717 pub sample_text_name_id: NameId,
3720 pub num_named_parameters: u16,
3722 pub first_param_ui_label_name_id: NameId,
3726 pub character: Vec<Uint24>,
3729}
3730
3731impl CharacterVariantParams {
3732 pub fn new(
3734 feat_ui_label_name_id: NameId,
3735 feat_ui_tooltip_text_name_id: NameId,
3736 sample_text_name_id: NameId,
3737 num_named_parameters: u16,
3738 first_param_ui_label_name_id: NameId,
3739 character: Vec<Uint24>,
3740 ) -> Self {
3741 Self {
3742 feat_ui_label_name_id,
3743 feat_ui_tooltip_text_name_id,
3744 sample_text_name_id,
3745 num_named_parameters,
3746 first_param_ui_label_name_id,
3747 character,
3748 }
3749 }
3750}
3751
3752impl FontWrite for CharacterVariantParams {
3753 #[allow(clippy::unnecessary_cast)]
3754 fn write_into(&self, writer: &mut TableWriter) {
3755 (0 as u16).write_into(writer);
3756 self.feat_ui_label_name_id.write_into(writer);
3757 self.feat_ui_tooltip_text_name_id.write_into(writer);
3758 self.sample_text_name_id.write_into(writer);
3759 self.num_named_parameters.write_into(writer);
3760 self.first_param_ui_label_name_id.write_into(writer);
3761 (u16::try_from(array_len(&self.character)).unwrap()).write_into(writer);
3762 self.character.write_into(writer);
3763 }
3764 fn table_type(&self) -> TableType {
3765 TableType::Named("CharacterVariantParams")
3766 }
3767}
3768
3769impl Validate for CharacterVariantParams {
3770 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3771 ctx.in_table("CharacterVariantParams", |ctx| {
3772 ctx.in_field("character", |ctx| {
3773 if self.character.len() > (u16::MAX as usize) {
3774 ctx.report("array exceeds max length");
3775 }
3776 });
3777 })
3778 }
3779}
3780
3781impl<'a> FromObjRef<read_fonts::tables::layout::CharacterVariantParams<'a>>
3782 for CharacterVariantParams
3783{
3784 fn from_obj_ref(
3785 obj: &read_fonts::tables::layout::CharacterVariantParams<'a>,
3786 _: FontData,
3787 ) -> Self {
3788 let offset_data = obj.offset_data();
3789 CharacterVariantParams {
3790 feat_ui_label_name_id: obj.feat_ui_label_name_id(),
3791 feat_ui_tooltip_text_name_id: obj.feat_ui_tooltip_text_name_id(),
3792 sample_text_name_id: obj.sample_text_name_id(),
3793 num_named_parameters: obj.num_named_parameters(),
3794 first_param_ui_label_name_id: obj.first_param_ui_label_name_id(),
3795 character: obj.character().to_owned_obj(offset_data),
3796 }
3797 }
3798}
3799
3800#[allow(clippy::needless_lifetimes)]
3801impl<'a> FromTableRef<read_fonts::tables::layout::CharacterVariantParams<'a>>
3802 for CharacterVariantParams
3803{
3804}
3805
3806impl<'a> FontRead<'a> for CharacterVariantParams {
3807 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
3808 <read_fonts::tables::layout::CharacterVariantParams as FontRead>::read(data)
3809 .map(|x| x.to_owned_table())
3810 }
3811}