1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8pub use read_fonts::tables::layout::{DeltaFormat, FeatureLookupsFlags};
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() > to_usize(u16::MAX) {
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 ReadArgs for ScriptList {
62 type Args = ();
63}
64
65impl<'a> FontRead<'a> for ScriptList {
66 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
67 <read_fonts::tables::layout::ScriptList as FontRead>::read(data).map(|x| x.to_owned_table())
68 }
69}
70
71#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub struct ScriptRecord {
75 pub script_tag: Tag,
77 pub script: OffsetMarker<Script>,
79}
80
81impl ScriptRecord {
82 pub fn new(script_tag: Tag, script: Script) -> Self {
84 Self {
85 script_tag,
86 script: script.into(),
87 }
88 }
89}
90
91impl FontWrite for ScriptRecord {
92 fn write_into(&self, writer: &mut TableWriter) {
93 self.script_tag.write_into(writer);
94 self.script.write_into(writer);
95 }
96 fn table_type(&self) -> TableType {
97 TableType::Named("ScriptRecord")
98 }
99}
100
101impl Validate for ScriptRecord {
102 fn validate_impl(&self, ctx: &mut ValidationCtx) {
103 ctx.in_table("ScriptRecord", |ctx| {
104 ctx.in_field("script", |ctx| {
105 self.script.validate_impl(ctx);
106 });
107 })
108 }
109}
110
111impl FromObjRef<read_fonts::tables::layout::ScriptRecord> for ScriptRecord {
112 fn from_obj_ref(obj: &read_fonts::tables::layout::ScriptRecord, offset_data: FontData) -> Self {
113 ScriptRecord {
114 script_tag: obj.script_tag(),
115 script: obj.script(offset_data).to_owned_table(),
116 }
117 }
118}
119
120#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
122#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
123pub struct Script {
124 pub default_lang_sys: NullableOffsetMarker<LangSys>,
127 pub lang_sys_records: Vec<LangSysRecord>,
129}
130
131impl Script {
132 pub fn new(default_lang_sys: Option<LangSys>, lang_sys_records: Vec<LangSysRecord>) -> Self {
134 Self {
135 default_lang_sys: default_lang_sys.into(),
136 lang_sys_records,
137 }
138 }
139}
140
141impl FontWrite for Script {
142 #[allow(clippy::unnecessary_cast)]
143 fn write_into(&self, writer: &mut TableWriter) {
144 self.default_lang_sys.write_into(writer);
145 (u16::try_from(array_len(&self.lang_sys_records)).unwrap()).write_into(writer);
146 self.lang_sys_records.write_into(writer);
147 }
148 fn table_type(&self) -> TableType {
149 TableType::Named("Script")
150 }
151}
152
153impl Validate for Script {
154 fn validate_impl(&self, ctx: &mut ValidationCtx) {
155 ctx.in_table("Script", |ctx| {
156 ctx.in_field("default_lang_sys", |ctx| {
157 self.default_lang_sys.validate_impl(ctx);
158 });
159 ctx.in_field("lang_sys_records", |ctx| {
160 if self.lang_sys_records.len() > to_usize(u16::MAX) {
161 ctx.report("array exceeds max length");
162 }
163 self.lang_sys_records.validate_impl(ctx);
164 });
165 })
166 }
167}
168
169impl<'a> FromObjRef<read_fonts::tables::layout::Script<'a>> for Script {
170 fn from_obj_ref(obj: &read_fonts::tables::layout::Script<'a>, _: FontData) -> Self {
171 let offset_data = obj.offset_data();
172 Script {
173 default_lang_sys: obj.default_lang_sys().to_owned_table(),
174 lang_sys_records: obj.lang_sys_records().to_owned_obj(offset_data),
175 }
176 }
177}
178
179#[allow(clippy::needless_lifetimes)]
180impl<'a> FromTableRef<read_fonts::tables::layout::Script<'a>> for Script {}
181
182impl ReadArgs for Script {
183 type Args = ();
184}
185
186impl<'a> FontRead<'a> for Script {
187 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
188 <read_fonts::tables::layout::Script as FontRead>::read(data).map(|x| x.to_owned_table())
189 }
190}
191
192#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
193#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
194pub struct LangSysRecord {
195 pub lang_sys_tag: Tag,
197 pub lang_sys: OffsetMarker<LangSys>,
199}
200
201impl LangSysRecord {
202 pub fn new(lang_sys_tag: Tag, lang_sys: LangSys) -> Self {
204 Self {
205 lang_sys_tag,
206 lang_sys: lang_sys.into(),
207 }
208 }
209}
210
211impl FontWrite for LangSysRecord {
212 fn write_into(&self, writer: &mut TableWriter) {
213 self.lang_sys_tag.write_into(writer);
214 self.lang_sys.write_into(writer);
215 }
216 fn table_type(&self) -> TableType {
217 TableType::Named("LangSysRecord")
218 }
219}
220
221impl Validate for LangSysRecord {
222 fn validate_impl(&self, ctx: &mut ValidationCtx) {
223 ctx.in_table("LangSysRecord", |ctx| {
224 ctx.in_field("lang_sys", |ctx| {
225 self.lang_sys.validate_impl(ctx);
226 });
227 })
228 }
229}
230
231impl FromObjRef<read_fonts::tables::layout::LangSysRecord> for LangSysRecord {
232 fn from_obj_ref(
233 obj: &read_fonts::tables::layout::LangSysRecord,
234 offset_data: FontData,
235 ) -> Self {
236 LangSysRecord {
237 lang_sys_tag: obj.lang_sys_tag(),
238 lang_sys: obj.lang_sys(offset_data).to_owned_table(),
239 }
240 }
241}
242
243#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
245#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
246pub struct LangSys {
247 pub required_feature_index: u16,
250 pub feature_indices: Vec<u16>,
252}
253
254impl Default for LangSys {
255 fn default() -> Self {
256 Self {
257 required_feature_index: 0xFFFF,
258 feature_indices: Default::default(),
259 }
260 }
261}
262
263impl LangSys {
264 pub fn new(feature_indices: Vec<u16>) -> Self {
266 Self {
267 feature_indices,
268 ..Default::default()
269 }
270 }
271}
272
273impl FontWrite for LangSys {
274 #[allow(clippy::unnecessary_cast)]
275 fn write_into(&self, writer: &mut TableWriter) {
276 (0 as u16).write_into(writer);
277 self.required_feature_index.write_into(writer);
278 (u16::try_from(array_len(&self.feature_indices)).unwrap()).write_into(writer);
279 self.feature_indices.write_into(writer);
280 }
281 fn table_type(&self) -> TableType {
282 TableType::Named("LangSys")
283 }
284}
285
286impl Validate for LangSys {
287 fn validate_impl(&self, ctx: &mut ValidationCtx) {
288 ctx.in_table("LangSys", |ctx| {
289 ctx.in_field("feature_indices", |ctx| {
290 if self.feature_indices.len() > to_usize(u16::MAX) {
291 ctx.report("array exceeds max length");
292 }
293 });
294 })
295 }
296}
297
298impl<'a> FromObjRef<read_fonts::tables::layout::LangSys<'a>> for LangSys {
299 fn from_obj_ref(obj: &read_fonts::tables::layout::LangSys<'a>, _: FontData) -> Self {
300 let offset_data = obj.offset_data();
301 LangSys {
302 required_feature_index: obj.required_feature_index(),
303 feature_indices: obj.feature_indices().to_owned_obj(offset_data),
304 }
305 }
306}
307
308#[allow(clippy::needless_lifetimes)]
309impl<'a> FromTableRef<read_fonts::tables::layout::LangSys<'a>> for LangSys {}
310
311impl ReadArgs for LangSys {
312 type Args = ();
313}
314
315impl<'a> FontRead<'a> for LangSys {
316 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
317 <read_fonts::tables::layout::LangSys as FontRead>::read(data).map(|x| x.to_owned_table())
318 }
319}
320
321#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
323#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
324pub struct FeatureList {
325 pub feature_records: Vec<FeatureRecord>,
328}
329
330impl FeatureList {
331 pub fn new(feature_records: Vec<FeatureRecord>) -> Self {
333 Self { feature_records }
334 }
335}
336
337impl FontWrite for FeatureList {
338 #[allow(clippy::unnecessary_cast)]
339 fn write_into(&self, writer: &mut TableWriter) {
340 (u16::try_from(array_len(&self.feature_records)).unwrap()).write_into(writer);
341 self.feature_records.write_into(writer);
342 }
343 fn table_type(&self) -> TableType {
344 TableType::Named("FeatureList")
345 }
346}
347
348impl Validate for FeatureList {
349 fn validate_impl(&self, ctx: &mut ValidationCtx) {
350 ctx.in_table("FeatureList", |ctx| {
351 ctx.in_field("feature_records", |ctx| {
352 if self.feature_records.len() > to_usize(u16::MAX) {
353 ctx.report("array exceeds max length");
354 }
355 self.feature_records.validate_impl(ctx);
356 });
357 })
358 }
359}
360
361impl<'a> FromObjRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList {
362 fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureList<'a>, _: FontData) -> Self {
363 let offset_data = obj.offset_data();
364 FeatureList {
365 feature_records: obj.feature_records().to_owned_obj(offset_data),
366 }
367 }
368}
369
370#[allow(clippy::needless_lifetimes)]
371impl<'a> FromTableRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList {}
372
373impl ReadArgs for FeatureList {
374 type Args = ();
375}
376
377impl<'a> FontRead<'a> for FeatureList {
378 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
379 <read_fonts::tables::layout::FeatureList as FontRead>::read(data)
380 .map(|x| x.to_owned_table())
381 }
382}
383
384#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
386#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
387pub struct FeatureRecord {
388 pub feature_tag: Tag,
390 pub feature: OffsetMarker<Feature>,
392}
393
394impl FeatureRecord {
395 pub fn new(feature_tag: Tag, feature: Feature) -> Self {
397 Self {
398 feature_tag,
399 feature: feature.into(),
400 }
401 }
402}
403
404impl FontWrite for FeatureRecord {
405 fn write_into(&self, writer: &mut TableWriter) {
406 self.feature_tag.write_into(writer);
407 self.feature.write_into(writer);
408 }
409 fn table_type(&self) -> TableType {
410 TableType::Named("FeatureRecord")
411 }
412}
413
414impl Validate for FeatureRecord {
415 fn validate_impl(&self, ctx: &mut ValidationCtx) {
416 ctx.in_table("FeatureRecord", |ctx| {
417 ctx.in_field("feature", |ctx| {
418 self.feature.validate_impl(ctx);
419 });
420 })
421 }
422}
423
424impl FromObjRef<read_fonts::tables::layout::FeatureRecord> for FeatureRecord {
425 fn from_obj_ref(
426 obj: &read_fonts::tables::layout::FeatureRecord,
427 offset_data: FontData,
428 ) -> Self {
429 FeatureRecord {
430 feature_tag: obj.feature_tag(),
431 feature: obj.feature(offset_data).to_owned_table(),
432 }
433 }
434}
435
436#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
438#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
439pub struct Feature {
440 pub feature_params: NullableOffsetMarker<FeatureParams>,
442 pub lookup_list_indices: Vec<u16>,
445}
446
447impl Feature {
448 pub fn new(feature_params: Option<FeatureParams>, lookup_list_indices: Vec<u16>) -> Self {
450 Self {
451 feature_params: feature_params.into(),
452 lookup_list_indices,
453 }
454 }
455}
456
457impl FontWrite for Feature {
458 #[allow(clippy::unnecessary_cast)]
459 fn write_into(&self, writer: &mut TableWriter) {
460 self.feature_params.write_into(writer);
461 (u16::try_from(array_len(&self.lookup_list_indices)).unwrap()).write_into(writer);
462 self.lookup_list_indices.write_into(writer);
463 }
464 fn table_type(&self) -> TableType {
465 TableType::Named("Feature")
466 }
467}
468
469impl Validate for Feature {
470 fn validate_impl(&self, ctx: &mut ValidationCtx) {
471 ctx.in_table("Feature", |ctx| {
472 ctx.in_field("feature_params", |ctx| {
473 self.feature_params.validate_impl(ctx);
474 });
475 ctx.in_field("lookup_list_indices", |ctx| {
476 if self.lookup_list_indices.len() > to_usize(u16::MAX) {
477 ctx.report("array exceeds max length");
478 }
479 });
480 })
481 }
482}
483
484impl<'a> FromObjRef<read_fonts::tables::layout::Feature<'a>> for Feature {
485 fn from_obj_ref(obj: &read_fonts::tables::layout::Feature<'a>, _: FontData) -> Self {
486 let offset_data = obj.offset_data();
487 Feature {
488 feature_params: obj.feature_params().to_owned_table(),
489 lookup_list_indices: obj.lookup_list_indices().to_owned_obj(offset_data),
490 }
491 }
492}
493
494#[allow(clippy::needless_lifetimes)]
495impl<'a> FromTableRef<read_fonts::tables::layout::Feature<'a>> for Feature {}
496
497#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
499#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
500pub struct LookupList<T> {
501 pub lookups: Vec<OffsetMarker<T>>,
504}
505
506impl<T: Default> LookupList<T> {
507 pub fn new(lookups: Vec<T>) -> Self {
509 Self {
510 lookups: lookups.into_iter().map(Into::into).collect(),
511 }
512 }
513}
514
515impl<T: FontWrite> FontWrite for LookupList<T> {
516 #[allow(clippy::unnecessary_cast)]
517 fn write_into(&self, writer: &mut TableWriter) {
518 (u16::try_from(array_len(&self.lookups)).unwrap()).write_into(writer);
519 self.lookups.write_into(writer);
520 }
521 fn table_type(&self) -> TableType {
522 TableType::Named("LookupList")
523 }
524}
525
526impl<T: Validate> Validate for LookupList<T> {
527 fn validate_impl(&self, ctx: &mut ValidationCtx) {
528 ctx.in_table("LookupList", |ctx| {
529 ctx.in_field("lookups", |ctx| {
530 if self.lookups.len() > to_usize(u16::MAX) {
531 ctx.report("array exceeds max length");
532 }
533 self.lookups.validate_impl(ctx);
534 });
535 })
536 }
537}
538
539impl<'a, T, U> FromObjRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T>
540where
541 U: FontRead<'a, Args = ()>,
542 T: FromTableRef<U> + Default + 'static,
543{
544 fn from_obj_ref(obj: &read_fonts::tables::layout::LookupList<'a, U>, _: FontData) -> Self {
545 LookupList {
546 lookups: obj.lookups().to_owned_table(),
547 }
548 }
549}
550
551#[allow(clippy::needless_lifetimes)]
552impl<'a, T, U> FromTableRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T>
553where
554 U: FontRead<'a, Args = ()>,
555 T: FromTableRef<U> + Default + 'static,
556{
557}
558
559#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
561#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
562pub struct Lookup<T> {
563 pub lookup_flag: LookupFlag,
565 pub subtables: Vec<OffsetMarker<T>>,
568 pub mark_filtering_set: Option<u16>,
572}
573
574impl<T: Default> Lookup<T> {
575 pub fn new(lookup_flag: LookupFlag, subtables: Vec<T>) -> Self {
577 Self {
578 lookup_flag,
579 subtables: subtables.into_iter().map(Into::into).collect(),
580 ..Default::default()
581 }
582 }
583}
584
585impl<T: Validate> Validate for Lookup<T> {
586 fn validate_impl(&self, ctx: &mut ValidationCtx) {
587 ctx.in_table("Lookup", |ctx| {
588 ctx.in_field("subtables", |ctx| {
589 if self.subtables.len() > to_usize(u16::MAX) {
590 ctx.report("array exceeds max length");
591 }
592 self.subtables.validate_impl(ctx);
593 });
594 ctx.in_field("mark_filtering_set", |ctx| {
595 if !(self
596 .lookup_flag
597 .contains(LookupFlag::USE_MARK_FILTERING_SET))
598 && self.mark_filtering_set.is_some()
599 {
600 ctx.report("'mark_filtering_set' is present but USE_MARK_FILTERING_SET not set")
601 }
602 if (self
603 .lookup_flag
604 .contains(LookupFlag::USE_MARK_FILTERING_SET))
605 && self.mark_filtering_set.is_none()
606 {
607 ctx.report("USE_MARK_FILTERING_SET is set but 'mark_filtering_set' is None")
608 }
609 });
610 })
611 }
612}
613
614impl<'a, T, U> FromObjRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T>
615where
616 U: FontRead<'a, Args = ()>,
617 T: FromTableRef<U> + Default + 'static,
618{
619 fn from_obj_ref(obj: &read_fonts::tables::layout::Lookup<'a, U>, _: FontData) -> Self {
620 Lookup {
621 lookup_flag: obj.lookup_flag(),
622 subtables: obj.subtables().to_owned_table(),
623 mark_filtering_set: obj.mark_filtering_set(),
624 }
625 }
626}
627
628#[allow(clippy::needless_lifetimes)]
629impl<'a, T, U> FromTableRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T>
630where
631 U: FontRead<'a, Args = ()>,
632 T: FromTableRef<U> + Default + 'static,
633{
634}
635
636#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
638#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
639pub struct CoverageFormat1 {
640 pub glyph_array: Vec<GlyphId16>,
642}
643
644impl CoverageFormat1 {
645 pub fn new(glyph_array: Vec<GlyphId16>) -> Self {
647 Self { glyph_array }
648 }
649}
650
651impl FontWrite for CoverageFormat1 {
652 #[allow(clippy::unnecessary_cast)]
653 fn write_into(&self, writer: &mut TableWriter) {
654 (1 as u16).write_into(writer);
655 (u16::try_from(array_len(&self.glyph_array)).unwrap()).write_into(writer);
656 self.glyph_array.write_into(writer);
657 }
658 fn table_type(&self) -> TableType {
659 TableType::Named("CoverageFormat1")
660 }
661}
662
663impl Validate for CoverageFormat1 {
664 fn validate_impl(&self, ctx: &mut ValidationCtx) {
665 ctx.in_table("CoverageFormat1", |ctx| {
666 ctx.in_field("glyph_array", |ctx| {
667 if self.glyph_array.len() > to_usize(u16::MAX) {
668 ctx.report("array exceeds max length");
669 }
670 });
671 })
672 }
673}
674
675impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 {
676 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat1<'a>, _: FontData) -> Self {
677 let offset_data = obj.offset_data();
678 CoverageFormat1 {
679 glyph_array: obj.glyph_array().to_owned_obj(offset_data),
680 }
681 }
682}
683
684#[allow(clippy::needless_lifetimes)]
685impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 {}
686
687impl ReadArgs for CoverageFormat1 {
688 type Args = ();
689}
690
691impl<'a> FontRead<'a> for CoverageFormat1 {
692 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
693 <read_fonts::tables::layout::CoverageFormat1 as FontRead>::read(data)
694 .map(|x| x.to_owned_table())
695 }
696}
697
698#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
700#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
701pub struct CoverageFormat2 {
702 pub range_records: Vec<RangeRecord>,
704}
705
706impl CoverageFormat2 {
707 pub fn new(range_records: Vec<RangeRecord>) -> Self {
709 Self { range_records }
710 }
711}
712
713impl FontWrite for CoverageFormat2 {
714 #[allow(clippy::unnecessary_cast)]
715 fn write_into(&self, writer: &mut TableWriter) {
716 (2 as u16).write_into(writer);
717 (u16::try_from(array_len(&self.range_records)).unwrap()).write_into(writer);
718 self.range_records.write_into(writer);
719 }
720 fn table_type(&self) -> TableType {
721 TableType::Named("CoverageFormat2")
722 }
723}
724
725impl Validate for CoverageFormat2 {
726 fn validate_impl(&self, ctx: &mut ValidationCtx) {
727 ctx.in_table("CoverageFormat2", |ctx| {
728 ctx.in_field("range_records", |ctx| {
729 if self.range_records.len() > to_usize(u16::MAX) {
730 ctx.report("array exceeds max length");
731 }
732 self.range_records.validate_impl(ctx);
733 });
734 })
735 }
736}
737
738impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 {
739 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat2<'a>, _: FontData) -> Self {
740 let offset_data = obj.offset_data();
741 CoverageFormat2 {
742 range_records: obj.range_records().to_owned_obj(offset_data),
743 }
744 }
745}
746
747#[allow(clippy::needless_lifetimes)]
748impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 {}
749
750impl ReadArgs for CoverageFormat2 {
751 type Args = ();
752}
753
754impl<'a> FontRead<'a> for CoverageFormat2 {
755 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
756 <read_fonts::tables::layout::CoverageFormat2 as FontRead>::read(data)
757 .map(|x| x.to_owned_table())
758 }
759}
760
761#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
763#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
764pub struct RangeRecord {
765 pub start_glyph_id: GlyphId16,
767 pub end_glyph_id: GlyphId16,
769 pub start_coverage_index: u16,
771}
772
773impl RangeRecord {
774 pub fn new(
776 start_glyph_id: GlyphId16,
777 end_glyph_id: GlyphId16,
778 start_coverage_index: u16,
779 ) -> Self {
780 Self {
781 start_glyph_id,
782 end_glyph_id,
783 start_coverage_index,
784 }
785 }
786}
787
788impl FontWrite for RangeRecord {
789 fn write_into(&self, writer: &mut TableWriter) {
790 self.start_glyph_id.write_into(writer);
791 self.end_glyph_id.write_into(writer);
792 self.start_coverage_index.write_into(writer);
793 }
794 fn table_type(&self) -> TableType {
795 TableType::Named("RangeRecord")
796 }
797}
798
799impl Validate for RangeRecord {
800 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
801}
802
803impl FromObjRef<read_fonts::tables::layout::RangeRecord> for RangeRecord {
804 fn from_obj_ref(obj: &read_fonts::tables::layout::RangeRecord, _: FontData) -> Self {
805 RangeRecord {
806 start_glyph_id: obj.start_glyph_id(),
807 end_glyph_id: obj.end_glyph_id(),
808 start_coverage_index: obj.start_coverage_index(),
809 }
810 }
811}
812
813#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
815#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
816pub enum CoverageTable {
817 Format1(CoverageFormat1),
818 Format2(CoverageFormat2),
819 Format3(CoverageFormat3),
820 Format4(CoverageFormat4),
821}
822
823impl CoverageTable {
824 pub fn format_1(glyph_array: Vec<GlyphId16>) -> Self {
826 Self::Format1(CoverageFormat1::new(glyph_array))
827 }
828
829 pub fn format_2(range_records: Vec<RangeRecord>) -> Self {
831 Self::Format2(CoverageFormat2::new(range_records))
832 }
833
834 pub fn format_3(glyph_array: Vec<GlyphId24>) -> Self {
836 Self::Format3(CoverageFormat3::new(glyph_array))
837 }
838
839 pub fn format_4(range_records: Vec<RangeRecord2>) -> Self {
841 Self::Format4(CoverageFormat4::new(range_records))
842 }
843}
844
845impl Default for CoverageTable {
846 fn default() -> Self {
847 Self::Format1(Default::default())
848 }
849}
850
851impl FontWrite for CoverageTable {
852 fn write_into(&self, writer: &mut TableWriter) {
853 match self {
854 Self::Format1(item) => item.write_into(writer),
855 Self::Format2(item) => item.write_into(writer),
856 Self::Format3(item) => item.write_into(writer),
857 Self::Format4(item) => item.write_into(writer),
858 }
859 }
860 fn table_type(&self) -> TableType {
861 match self {
862 Self::Format1(item) => item.table_type(),
863 Self::Format2(item) => item.table_type(),
864 Self::Format3(item) => item.table_type(),
865 Self::Format4(item) => item.table_type(),
866 }
867 }
868}
869
870impl Validate for CoverageTable {
871 fn validate_impl(&self, ctx: &mut ValidationCtx) {
872 match self {
873 Self::Format1(item) => item.validate_impl(ctx),
874 Self::Format2(item) => item.validate_impl(ctx),
875 Self::Format3(item) => item.validate_impl(ctx),
876 Self::Format4(item) => item.validate_impl(ctx),
877 }
878 }
879}
880
881impl FromObjRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable {
882 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageTable, _: FontData) -> Self {
883 use read_fonts::tables::layout::CoverageTable as ObjRefType;
884 match obj {
885 ObjRefType::Format1(item) => CoverageTable::Format1(item.to_owned_table()),
886 ObjRefType::Format2(item) => CoverageTable::Format2(item.to_owned_table()),
887 ObjRefType::Format3(item) => CoverageTable::Format3(item.to_owned_table()),
888 ObjRefType::Format4(item) => CoverageTable::Format4(item.to_owned_table()),
889 }
890 }
891}
892
893impl FromTableRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable {}
894
895impl ReadArgs for CoverageTable {
896 type Args = ();
897}
898
899impl<'a> FontRead<'a> for CoverageTable {
900 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
901 <read_fonts::tables::layout::CoverageTable as FontRead>::read(data)
902 .map(|x| x.to_owned_table())
903 }
904}
905
906impl From<CoverageFormat1> for CoverageTable {
907 fn from(src: CoverageFormat1) -> CoverageTable {
908 CoverageTable::Format1(src)
909 }
910}
911
912impl From<CoverageFormat2> for CoverageTable {
913 fn from(src: CoverageFormat2) -> CoverageTable {
914 CoverageTable::Format2(src)
915 }
916}
917
918impl From<CoverageFormat3> for CoverageTable {
919 fn from(src: CoverageFormat3) -> CoverageTable {
920 CoverageTable::Format3(src)
921 }
922}
923
924impl From<CoverageFormat4> for CoverageTable {
925 fn from(src: CoverageFormat4) -> CoverageTable {
926 CoverageTable::Format4(src)
927 }
928}
929
930#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
932#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
933pub struct ClassDefFormat1 {
934 pub start_glyph_id: GlyphId16,
936 pub class_value_array: Vec<u16>,
938}
939
940impl ClassDefFormat1 {
941 pub fn new(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self {
943 Self {
944 start_glyph_id,
945 class_value_array,
946 }
947 }
948}
949
950impl FontWrite for ClassDefFormat1 {
951 #[allow(clippy::unnecessary_cast)]
952 fn write_into(&self, writer: &mut TableWriter) {
953 (1 as u16).write_into(writer);
954 self.start_glyph_id.write_into(writer);
955 (u16::try_from(array_len(&self.class_value_array)).unwrap()).write_into(writer);
956 self.class_value_array.write_into(writer);
957 }
958 fn table_type(&self) -> TableType {
959 TableType::Named("ClassDefFormat1")
960 }
961}
962
963impl Validate for ClassDefFormat1 {
964 fn validate_impl(&self, ctx: &mut ValidationCtx) {
965 ctx.in_table("ClassDefFormat1", |ctx| {
966 ctx.in_field("class_value_array", |ctx| {
967 if self.class_value_array.len() > to_usize(u16::MAX) {
968 ctx.report("array exceeds max length");
969 }
970 });
971 })
972 }
973}
974
975impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 {
976 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat1<'a>, _: FontData) -> Self {
977 let offset_data = obj.offset_data();
978 ClassDefFormat1 {
979 start_glyph_id: obj.start_glyph_id(),
980 class_value_array: obj.class_value_array().to_owned_obj(offset_data),
981 }
982 }
983}
984
985#[allow(clippy::needless_lifetimes)]
986impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 {}
987
988impl ReadArgs for ClassDefFormat1 {
989 type Args = ();
990}
991
992impl<'a> FontRead<'a> for ClassDefFormat1 {
993 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
994 <read_fonts::tables::layout::ClassDefFormat1 as FontRead>::read(data)
995 .map(|x| x.to_owned_table())
996 }
997}
998
999#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1001#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1002pub struct ClassDefFormat2 {
1003 pub class_range_records: Vec<ClassRangeRecord>,
1005}
1006
1007impl ClassDefFormat2 {
1008 pub fn new(class_range_records: Vec<ClassRangeRecord>) -> Self {
1010 Self {
1011 class_range_records,
1012 }
1013 }
1014}
1015
1016impl FontWrite for ClassDefFormat2 {
1017 #[allow(clippy::unnecessary_cast)]
1018 fn write_into(&self, writer: &mut TableWriter) {
1019 (2 as u16).write_into(writer);
1020 (u16::try_from(array_len(&self.class_range_records)).unwrap()).write_into(writer);
1021 self.class_range_records.write_into(writer);
1022 }
1023 fn table_type(&self) -> TableType {
1024 TableType::Named("ClassDefFormat2")
1025 }
1026}
1027
1028impl Validate for ClassDefFormat2 {
1029 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1030 ctx.in_table("ClassDefFormat2", |ctx| {
1031 ctx.in_field("class_range_records", |ctx| {
1032 if self.class_range_records.len() > to_usize(u16::MAX) {
1033 ctx.report("array exceeds max length");
1034 }
1035 self.class_range_records.validate_impl(ctx);
1036 });
1037 })
1038 }
1039}
1040
1041impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 {
1042 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat2<'a>, _: FontData) -> Self {
1043 let offset_data = obj.offset_data();
1044 ClassDefFormat2 {
1045 class_range_records: obj.class_range_records().to_owned_obj(offset_data),
1046 }
1047 }
1048}
1049
1050#[allow(clippy::needless_lifetimes)]
1051impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 {}
1052
1053impl ReadArgs for ClassDefFormat2 {
1054 type Args = ();
1055}
1056
1057impl<'a> FontRead<'a> for ClassDefFormat2 {
1058 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1059 <read_fonts::tables::layout::ClassDefFormat2 as FontRead>::read(data)
1060 .map(|x| x.to_owned_table())
1061 }
1062}
1063
1064#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1066#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1067pub struct ClassRangeRecord {
1068 pub start_glyph_id: GlyphId16,
1070 pub end_glyph_id: GlyphId16,
1072 pub class: u16,
1074}
1075
1076impl ClassRangeRecord {
1077 pub fn new(start_glyph_id: GlyphId16, end_glyph_id: GlyphId16, class: u16) -> Self {
1079 Self {
1080 start_glyph_id,
1081 end_glyph_id,
1082 class,
1083 }
1084 }
1085}
1086
1087impl FontWrite for ClassRangeRecord {
1088 fn write_into(&self, writer: &mut TableWriter) {
1089 self.start_glyph_id.write_into(writer);
1090 self.end_glyph_id.write_into(writer);
1091 self.class.write_into(writer);
1092 }
1093 fn table_type(&self) -> TableType {
1094 TableType::Named("ClassRangeRecord")
1095 }
1096}
1097
1098impl Validate for ClassRangeRecord {
1099 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1100 ctx.in_table("ClassRangeRecord", |ctx| {
1101 ctx.in_field("start_glyph_id", |ctx| {
1102 self.validate_glyph_range(ctx);
1103 });
1104 })
1105 }
1106}
1107
1108impl FromObjRef<read_fonts::tables::layout::ClassRangeRecord> for ClassRangeRecord {
1109 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassRangeRecord, _: FontData) -> Self {
1110 ClassRangeRecord {
1111 start_glyph_id: obj.start_glyph_id(),
1112 end_glyph_id: obj.end_glyph_id(),
1113 class: obj.class(),
1114 }
1115 }
1116}
1117
1118#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1120#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1121pub enum ClassDef {
1122 Format1(ClassDefFormat1),
1123 Format2(ClassDefFormat2),
1124 Format3(ClassDefFormat3),
1125 Format4(ClassDefFormat4),
1126}
1127
1128impl ClassDef {
1129 pub fn format_1(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self {
1131 Self::Format1(ClassDefFormat1::new(start_glyph_id, class_value_array))
1132 }
1133
1134 pub fn format_2(class_range_records: Vec<ClassRangeRecord>) -> Self {
1136 Self::Format2(ClassDefFormat2::new(class_range_records))
1137 }
1138
1139 pub fn format_3(start_glyph_id: GlyphId24, class_value_array: Vec<Uint24>) -> Self {
1141 Self::Format3(ClassDefFormat3::new(start_glyph_id, class_value_array))
1142 }
1143
1144 pub fn format_4(class_range_records: Vec<ClassRangeRecord2>) -> Self {
1146 Self::Format4(ClassDefFormat4::new(class_range_records))
1147 }
1148}
1149
1150impl Default for ClassDef {
1151 fn default() -> Self {
1152 Self::Format1(Default::default())
1153 }
1154}
1155
1156impl FontWrite for ClassDef {
1157 fn write_into(&self, writer: &mut TableWriter) {
1158 match self {
1159 Self::Format1(item) => item.write_into(writer),
1160 Self::Format2(item) => item.write_into(writer),
1161 Self::Format3(item) => item.write_into(writer),
1162 Self::Format4(item) => item.write_into(writer),
1163 }
1164 }
1165 fn table_type(&self) -> TableType {
1166 match self {
1167 Self::Format1(item) => item.table_type(),
1168 Self::Format2(item) => item.table_type(),
1169 Self::Format3(item) => item.table_type(),
1170 Self::Format4(item) => item.table_type(),
1171 }
1172 }
1173}
1174
1175impl Validate for ClassDef {
1176 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1177 match self {
1178 Self::Format1(item) => item.validate_impl(ctx),
1179 Self::Format2(item) => item.validate_impl(ctx),
1180 Self::Format3(item) => item.validate_impl(ctx),
1181 Self::Format4(item) => item.validate_impl(ctx),
1182 }
1183 }
1184}
1185
1186impl FromObjRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef {
1187 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDef, _: FontData) -> Self {
1188 use read_fonts::tables::layout::ClassDef as ObjRefType;
1189 match obj {
1190 ObjRefType::Format1(item) => ClassDef::Format1(item.to_owned_table()),
1191 ObjRefType::Format2(item) => ClassDef::Format2(item.to_owned_table()),
1192 ObjRefType::Format3(item) => ClassDef::Format3(item.to_owned_table()),
1193 ObjRefType::Format4(item) => ClassDef::Format4(item.to_owned_table()),
1194 }
1195 }
1196}
1197
1198impl FromTableRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef {}
1199
1200impl ReadArgs for ClassDef {
1201 type Args = ();
1202}
1203
1204impl<'a> FontRead<'a> for ClassDef {
1205 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1206 <read_fonts::tables::layout::ClassDef as FontRead>::read(data).map(|x| x.to_owned_table())
1207 }
1208}
1209
1210impl From<ClassDefFormat1> for ClassDef {
1211 fn from(src: ClassDefFormat1) -> ClassDef {
1212 ClassDef::Format1(src)
1213 }
1214}
1215
1216impl From<ClassDefFormat2> for ClassDef {
1217 fn from(src: ClassDefFormat2) -> ClassDef {
1218 ClassDef::Format2(src)
1219 }
1220}
1221
1222impl From<ClassDefFormat3> for ClassDef {
1223 fn from(src: ClassDefFormat3) -> ClassDef {
1224 ClassDef::Format3(src)
1225 }
1226}
1227
1228impl From<ClassDefFormat4> for ClassDef {
1229 fn from(src: ClassDefFormat4) -> ClassDef {
1230 ClassDef::Format4(src)
1231 }
1232}
1233
1234#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1236#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1237pub struct SequenceLookupRecord {
1238 pub sequence_index: u16,
1240 pub lookup_list_index: u16,
1242}
1243
1244impl SequenceLookupRecord {
1245 pub fn new(sequence_index: u16, lookup_list_index: u16) -> Self {
1247 Self {
1248 sequence_index,
1249 lookup_list_index,
1250 }
1251 }
1252}
1253
1254impl FontWrite for SequenceLookupRecord {
1255 fn write_into(&self, writer: &mut TableWriter) {
1256 self.sequence_index.write_into(writer);
1257 self.lookup_list_index.write_into(writer);
1258 }
1259 fn table_type(&self) -> TableType {
1260 TableType::Named("SequenceLookupRecord")
1261 }
1262}
1263
1264impl Validate for SequenceLookupRecord {
1265 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1266}
1267
1268impl FromObjRef<read_fonts::tables::layout::SequenceLookupRecord> for SequenceLookupRecord {
1269 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceLookupRecord, _: FontData) -> Self {
1270 SequenceLookupRecord {
1271 sequence_index: obj.sequence_index(),
1272 lookup_list_index: obj.lookup_list_index(),
1273 }
1274 }
1275}
1276
1277#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1279#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1280pub struct SequenceContextFormat1 {
1281 pub coverage: OffsetMarker<CoverageTable>,
1284 pub seq_rule_sets: Vec<NullableOffsetMarker<SequenceRuleSet>>,
1287}
1288
1289impl SequenceContextFormat1 {
1290 pub fn new(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self {
1292 Self {
1293 coverage: coverage.into(),
1294 seq_rule_sets: seq_rule_sets.into_iter().map(Into::into).collect(),
1295 }
1296 }
1297}
1298
1299impl FontWrite for SequenceContextFormat1 {
1300 #[allow(clippy::unnecessary_cast)]
1301 fn write_into(&self, writer: &mut TableWriter) {
1302 (1 as u16).write_into(writer);
1303 self.coverage.write_into(writer);
1304 (u16::try_from(array_len(&self.seq_rule_sets)).unwrap()).write_into(writer);
1305 self.seq_rule_sets.write_into(writer);
1306 }
1307 fn table_type(&self) -> TableType {
1308 TableType::Named("SequenceContextFormat1")
1309 }
1310}
1311
1312impl Validate for SequenceContextFormat1 {
1313 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1314 ctx.in_table("SequenceContextFormat1", |ctx| {
1315 ctx.in_field("coverage", |ctx| {
1316 self.coverage.validate_impl(ctx);
1317 });
1318 ctx.in_field("seq_rule_sets", |ctx| {
1319 if self.seq_rule_sets.len() > to_usize(u16::MAX) {
1320 ctx.report("array exceeds max length");
1321 }
1322 self.seq_rule_sets.validate_impl(ctx);
1323 });
1324 })
1325 }
1326}
1327
1328impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat1<'a>>
1329 for SequenceContextFormat1
1330{
1331 fn from_obj_ref(
1332 obj: &read_fonts::tables::layout::SequenceContextFormat1<'a>,
1333 _: FontData,
1334 ) -> Self {
1335 SequenceContextFormat1 {
1336 coverage: obj.coverage().to_owned_table(),
1337 seq_rule_sets: obj.seq_rule_sets().to_owned_table(),
1338 }
1339 }
1340}
1341
1342#[allow(clippy::needless_lifetimes)]
1343impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat1<'a>>
1344 for SequenceContextFormat1
1345{
1346}
1347
1348impl ReadArgs for SequenceContextFormat1 {
1349 type Args = ();
1350}
1351
1352impl<'a> FontRead<'a> for SequenceContextFormat1 {
1353 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1354 <read_fonts::tables::layout::SequenceContextFormat1 as FontRead>::read(data)
1355 .map(|x| x.to_owned_table())
1356 }
1357}
1358
1359#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1362pub struct SequenceRuleSet {
1363 pub seq_rules: Vec<OffsetMarker<SequenceRule>>,
1366}
1367
1368impl SequenceRuleSet {
1369 pub fn new(seq_rules: Vec<SequenceRule>) -> Self {
1371 Self {
1372 seq_rules: seq_rules.into_iter().map(Into::into).collect(),
1373 }
1374 }
1375}
1376
1377impl FontWrite for SequenceRuleSet {
1378 #[allow(clippy::unnecessary_cast)]
1379 fn write_into(&self, writer: &mut TableWriter) {
1380 (u16::try_from(array_len(&self.seq_rules)).unwrap()).write_into(writer);
1381 self.seq_rules.write_into(writer);
1382 }
1383 fn table_type(&self) -> TableType {
1384 TableType::Named("SequenceRuleSet")
1385 }
1386}
1387
1388impl Validate for SequenceRuleSet {
1389 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1390 ctx.in_table("SequenceRuleSet", |ctx| {
1391 ctx.in_field("seq_rules", |ctx| {
1392 if self.seq_rules.len() > to_usize(u16::MAX) {
1393 ctx.report("array exceeds max length");
1394 }
1395 self.seq_rules.validate_impl(ctx);
1396 });
1397 })
1398 }
1399}
1400
1401impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet {
1402 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRuleSet<'a>, _: FontData) -> Self {
1403 SequenceRuleSet {
1404 seq_rules: obj.seq_rules().to_owned_table(),
1405 }
1406 }
1407}
1408
1409#[allow(clippy::needless_lifetimes)]
1410impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet {}
1411
1412impl ReadArgs for SequenceRuleSet {
1413 type Args = ();
1414}
1415
1416impl<'a> FontRead<'a> for SequenceRuleSet {
1417 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1418 <read_fonts::tables::layout::SequenceRuleSet as FontRead>::read(data)
1419 .map(|x| x.to_owned_table())
1420 }
1421}
1422
1423#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1425#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1426pub struct SequenceRule {
1427 pub input_sequence: Vec<GlyphId16>,
1429 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1431}
1432
1433impl SequenceRule {
1434 pub fn new(
1436 input_sequence: Vec<GlyphId16>,
1437 seq_lookup_records: Vec<SequenceLookupRecord>,
1438 ) -> Self {
1439 Self {
1440 input_sequence,
1441 seq_lookup_records,
1442 }
1443 }
1444}
1445
1446impl FontWrite for SequenceRule {
1447 #[allow(clippy::unnecessary_cast)]
1448 fn write_into(&self, writer: &mut TableWriter) {
1449 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
1450 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1451 self.input_sequence.write_into(writer);
1452 self.seq_lookup_records.write_into(writer);
1453 }
1454 fn table_type(&self) -> TableType {
1455 TableType::Named("SequenceRule")
1456 }
1457}
1458
1459impl Validate for SequenceRule {
1460 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1461 ctx.in_table("SequenceRule", |ctx| {
1462 ctx.in_field("seq_lookup_records", |ctx| {
1463 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
1464 ctx.report("array exceeds max length");
1465 }
1466 self.seq_lookup_records.validate_impl(ctx);
1467 });
1468 })
1469 }
1470}
1471
1472impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule {
1473 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRule<'a>, _: FontData) -> Self {
1474 let offset_data = obj.offset_data();
1475 SequenceRule {
1476 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
1477 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1478 }
1479 }
1480}
1481
1482#[allow(clippy::needless_lifetimes)]
1483impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule {}
1484
1485impl ReadArgs for SequenceRule {
1486 type Args = ();
1487}
1488
1489impl<'a> FontRead<'a> for SequenceRule {
1490 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1491 <read_fonts::tables::layout::SequenceRule as FontRead>::read(data)
1492 .map(|x| x.to_owned_table())
1493 }
1494}
1495
1496#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1498#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1499pub struct SequenceContextFormat2 {
1500 pub coverage: OffsetMarker<CoverageTable>,
1503 pub class_def: OffsetMarker<ClassDef>,
1506 pub class_seq_rule_sets: Vec<NullableOffsetMarker<ClassSequenceRuleSet>>,
1509}
1510
1511impl SequenceContextFormat2 {
1512 pub fn new(
1514 coverage: CoverageTable,
1515 class_def: ClassDef,
1516 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>,
1517 ) -> Self {
1518 Self {
1519 coverage: coverage.into(),
1520 class_def: class_def.into(),
1521 class_seq_rule_sets: class_seq_rule_sets.into_iter().map(Into::into).collect(),
1522 }
1523 }
1524}
1525
1526impl FontWrite for SequenceContextFormat2 {
1527 #[allow(clippy::unnecessary_cast)]
1528 fn write_into(&self, writer: &mut TableWriter) {
1529 (2 as u16).write_into(writer);
1530 self.coverage.write_into(writer);
1531 self.class_def.write_into(writer);
1532 (u16::try_from(array_len(&self.class_seq_rule_sets)).unwrap()).write_into(writer);
1533 self.class_seq_rule_sets.write_into(writer);
1534 }
1535 fn table_type(&self) -> TableType {
1536 TableType::Named("SequenceContextFormat2")
1537 }
1538}
1539
1540impl Validate for SequenceContextFormat2 {
1541 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1542 ctx.in_table("SequenceContextFormat2", |ctx| {
1543 ctx.in_field("coverage", |ctx| {
1544 self.coverage.validate_impl(ctx);
1545 });
1546 ctx.in_field("class_def", |ctx| {
1547 self.class_def.validate_impl(ctx);
1548 });
1549 ctx.in_field("class_seq_rule_sets", |ctx| {
1550 if self.class_seq_rule_sets.len() > to_usize(u16::MAX) {
1551 ctx.report("array exceeds max length");
1552 }
1553 self.class_seq_rule_sets.validate_impl(ctx);
1554 });
1555 })
1556 }
1557}
1558
1559impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat2<'a>>
1560 for SequenceContextFormat2
1561{
1562 fn from_obj_ref(
1563 obj: &read_fonts::tables::layout::SequenceContextFormat2<'a>,
1564 _: FontData,
1565 ) -> Self {
1566 SequenceContextFormat2 {
1567 coverage: obj.coverage().to_owned_table(),
1568 class_def: obj.class_def().to_owned_table(),
1569 class_seq_rule_sets: obj.class_seq_rule_sets().to_owned_table(),
1570 }
1571 }
1572}
1573
1574#[allow(clippy::needless_lifetimes)]
1575impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat2<'a>>
1576 for SequenceContextFormat2
1577{
1578}
1579
1580impl ReadArgs for SequenceContextFormat2 {
1581 type Args = ();
1582}
1583
1584impl<'a> FontRead<'a> for SequenceContextFormat2 {
1585 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1586 <read_fonts::tables::layout::SequenceContextFormat2 as FontRead>::read(data)
1587 .map(|x| x.to_owned_table())
1588 }
1589}
1590
1591#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1593#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1594pub struct ClassSequenceRuleSet {
1595 pub class_seq_rules: Vec<OffsetMarker<ClassSequenceRule>>,
1598}
1599
1600impl ClassSequenceRuleSet {
1601 pub fn new(class_seq_rules: Vec<ClassSequenceRule>) -> Self {
1603 Self {
1604 class_seq_rules: class_seq_rules.into_iter().map(Into::into).collect(),
1605 }
1606 }
1607}
1608
1609impl FontWrite for ClassSequenceRuleSet {
1610 #[allow(clippy::unnecessary_cast)]
1611 fn write_into(&self, writer: &mut TableWriter) {
1612 (u16::try_from(array_len(&self.class_seq_rules)).unwrap()).write_into(writer);
1613 self.class_seq_rules.write_into(writer);
1614 }
1615 fn table_type(&self) -> TableType {
1616 TableType::Named("ClassSequenceRuleSet")
1617 }
1618}
1619
1620impl Validate for ClassSequenceRuleSet {
1621 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1622 ctx.in_table("ClassSequenceRuleSet", |ctx| {
1623 ctx.in_field("class_seq_rules", |ctx| {
1624 if self.class_seq_rules.len() > to_usize(u16::MAX) {
1625 ctx.report("array exceeds max length");
1626 }
1627 self.class_seq_rules.validate_impl(ctx);
1628 });
1629 })
1630 }
1631}
1632
1633impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>> for ClassSequenceRuleSet {
1634 fn from_obj_ref(
1635 obj: &read_fonts::tables::layout::ClassSequenceRuleSet<'a>,
1636 _: FontData,
1637 ) -> Self {
1638 ClassSequenceRuleSet {
1639 class_seq_rules: obj.class_seq_rules().to_owned_table(),
1640 }
1641 }
1642}
1643
1644#[allow(clippy::needless_lifetimes)]
1645impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>>
1646 for ClassSequenceRuleSet
1647{
1648}
1649
1650impl ReadArgs for ClassSequenceRuleSet {
1651 type Args = ();
1652}
1653
1654impl<'a> FontRead<'a> for ClassSequenceRuleSet {
1655 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1656 <read_fonts::tables::layout::ClassSequenceRuleSet as FontRead>::read(data)
1657 .map(|x| x.to_owned_table())
1658 }
1659}
1660
1661#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1663#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1664pub struct ClassSequenceRule {
1665 pub input_sequence: Vec<u16>,
1668 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1670}
1671
1672impl ClassSequenceRule {
1673 pub fn new(input_sequence: Vec<u16>, seq_lookup_records: Vec<SequenceLookupRecord>) -> Self {
1675 Self {
1676 input_sequence,
1677 seq_lookup_records,
1678 }
1679 }
1680}
1681
1682impl FontWrite for ClassSequenceRule {
1683 #[allow(clippy::unnecessary_cast)]
1684 fn write_into(&self, writer: &mut TableWriter) {
1685 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
1686 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1687 self.input_sequence.write_into(writer);
1688 self.seq_lookup_records.write_into(writer);
1689 }
1690 fn table_type(&self) -> TableType {
1691 TableType::Named("ClassSequenceRule")
1692 }
1693}
1694
1695impl Validate for ClassSequenceRule {
1696 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1697 ctx.in_table("ClassSequenceRule", |ctx| {
1698 ctx.in_field("seq_lookup_records", |ctx| {
1699 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
1700 ctx.report("array exceeds max length");
1701 }
1702 self.seq_lookup_records.validate_impl(ctx);
1703 });
1704 })
1705 }
1706}
1707
1708impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule {
1709 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassSequenceRule<'a>, _: FontData) -> Self {
1710 let offset_data = obj.offset_data();
1711 ClassSequenceRule {
1712 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
1713 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1714 }
1715 }
1716}
1717
1718#[allow(clippy::needless_lifetimes)]
1719impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule {}
1720
1721impl ReadArgs for ClassSequenceRule {
1722 type Args = ();
1723}
1724
1725impl<'a> FontRead<'a> for ClassSequenceRule {
1726 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1727 <read_fonts::tables::layout::ClassSequenceRule as FontRead>::read(data)
1728 .map(|x| x.to_owned_table())
1729 }
1730}
1731
1732#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1734#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1735pub struct SequenceContextFormat3 {
1736 pub coverages: Vec<OffsetMarker<CoverageTable>>,
1739 pub seq_lookup_records: Vec<SequenceLookupRecord>,
1741}
1742
1743impl SequenceContextFormat3 {
1744 pub fn new(
1746 coverages: Vec<CoverageTable>,
1747 seq_lookup_records: Vec<SequenceLookupRecord>,
1748 ) -> Self {
1749 Self {
1750 coverages: coverages.into_iter().map(Into::into).collect(),
1751 seq_lookup_records,
1752 }
1753 }
1754}
1755
1756impl FontWrite for SequenceContextFormat3 {
1757 #[allow(clippy::unnecessary_cast)]
1758 fn write_into(&self, writer: &mut TableWriter) {
1759 (3 as u16).write_into(writer);
1760 (u16::try_from(array_len(&self.coverages)).unwrap()).write_into(writer);
1761 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
1762 self.coverages.write_into(writer);
1763 self.seq_lookup_records.write_into(writer);
1764 }
1765 fn table_type(&self) -> TableType {
1766 TableType::Named("SequenceContextFormat3")
1767 }
1768}
1769
1770impl Validate for SequenceContextFormat3 {
1771 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1772 ctx.in_table("SequenceContextFormat3", |ctx| {
1773 ctx.in_field("coverages", |ctx| {
1774 if self.coverages.len() > to_usize(u16::MAX) {
1775 ctx.report("array exceeds max length");
1776 }
1777 self.coverages.validate_impl(ctx);
1778 });
1779 ctx.in_field("seq_lookup_records", |ctx| {
1780 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
1781 ctx.report("array exceeds max length");
1782 }
1783 self.seq_lookup_records.validate_impl(ctx);
1784 });
1785 })
1786 }
1787}
1788
1789impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat3<'a>>
1790 for SequenceContextFormat3
1791{
1792 fn from_obj_ref(
1793 obj: &read_fonts::tables::layout::SequenceContextFormat3<'a>,
1794 _: FontData,
1795 ) -> Self {
1796 let offset_data = obj.offset_data();
1797 SequenceContextFormat3 {
1798 coverages: obj.coverages().to_owned_table(),
1799 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
1800 }
1801 }
1802}
1803
1804#[allow(clippy::needless_lifetimes)]
1805impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat3<'a>>
1806 for SequenceContextFormat3
1807{
1808}
1809
1810impl ReadArgs for SequenceContextFormat3 {
1811 type Args = ();
1812}
1813
1814impl<'a> FontRead<'a> for SequenceContextFormat3 {
1815 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1816 <read_fonts::tables::layout::SequenceContextFormat3 as FontRead>::read(data)
1817 .map(|x| x.to_owned_table())
1818 }
1819}
1820
1821#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1822#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1823pub enum SequenceContext {
1824 Format1(SequenceContextFormat1),
1825 Format2(SequenceContextFormat2),
1826 Format3(SequenceContextFormat3),
1827 Format4(SequenceContextFormat4),
1828 Format5(SequenceContextFormat5),
1829 Format6(SequenceContextFormat6),
1830}
1831
1832impl SequenceContext {
1833 pub fn format_1(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self {
1835 Self::Format1(SequenceContextFormat1::new(coverage, seq_rule_sets))
1836 }
1837
1838 pub fn format_2(
1840 coverage: CoverageTable,
1841 class_def: ClassDef,
1842 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>,
1843 ) -> Self {
1844 Self::Format2(SequenceContextFormat2::new(
1845 coverage,
1846 class_def,
1847 class_seq_rule_sets,
1848 ))
1849 }
1850
1851 pub fn format_3(
1853 coverages: Vec<CoverageTable>,
1854 seq_lookup_records: Vec<SequenceLookupRecord>,
1855 ) -> Self {
1856 Self::Format3(SequenceContextFormat3::new(coverages, seq_lookup_records))
1857 }
1858
1859 pub fn format_4(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet2>>) -> Self {
1861 Self::Format4(SequenceContextFormat4::new(coverage, seq_rule_sets))
1862 }
1863
1864 pub fn format_5(
1866 coverage: CoverageTable,
1867 class_def: ClassDef,
1868 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet2>>,
1869 ) -> Self {
1870 Self::Format5(SequenceContextFormat5::new(
1871 coverage,
1872 class_def,
1873 class_seq_rule_sets,
1874 ))
1875 }
1876
1877 pub fn format_6(
1879 coverages: Vec<CoverageTable>,
1880 seq_lookup_records: Vec<SequenceLookupRecord>,
1881 ) -> Self {
1882 Self::Format6(SequenceContextFormat6::new(coverages, seq_lookup_records))
1883 }
1884}
1885
1886impl Default for SequenceContext {
1887 fn default() -> Self {
1888 Self::Format1(Default::default())
1889 }
1890}
1891
1892impl FontWrite for SequenceContext {
1893 fn write_into(&self, writer: &mut TableWriter) {
1894 match self {
1895 Self::Format1(item) => item.write_into(writer),
1896 Self::Format2(item) => item.write_into(writer),
1897 Self::Format3(item) => item.write_into(writer),
1898 Self::Format4(item) => item.write_into(writer),
1899 Self::Format5(item) => item.write_into(writer),
1900 Self::Format6(item) => item.write_into(writer),
1901 }
1902 }
1903 fn table_type(&self) -> TableType {
1904 match self {
1905 Self::Format1(item) => item.table_type(),
1906 Self::Format2(item) => item.table_type(),
1907 Self::Format3(item) => item.table_type(),
1908 Self::Format4(item) => item.table_type(),
1909 Self::Format5(item) => item.table_type(),
1910 Self::Format6(item) => item.table_type(),
1911 }
1912 }
1913}
1914
1915impl Validate for SequenceContext {
1916 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1917 match self {
1918 Self::Format1(item) => item.validate_impl(ctx),
1919 Self::Format2(item) => item.validate_impl(ctx),
1920 Self::Format3(item) => item.validate_impl(ctx),
1921 Self::Format4(item) => item.validate_impl(ctx),
1922 Self::Format5(item) => item.validate_impl(ctx),
1923 Self::Format6(item) => item.validate_impl(ctx),
1924 }
1925 }
1926}
1927
1928impl FromObjRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext {
1929 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceContext, _: FontData) -> Self {
1930 use read_fonts::tables::layout::SequenceContext as ObjRefType;
1931 match obj {
1932 ObjRefType::Format1(item) => SequenceContext::Format1(item.to_owned_table()),
1933 ObjRefType::Format2(item) => SequenceContext::Format2(item.to_owned_table()),
1934 ObjRefType::Format3(item) => SequenceContext::Format3(item.to_owned_table()),
1935 ObjRefType::Format4(item) => SequenceContext::Format4(item.to_owned_table()),
1936 ObjRefType::Format5(item) => SequenceContext::Format5(item.to_owned_table()),
1937 ObjRefType::Format6(item) => SequenceContext::Format6(item.to_owned_table()),
1938 }
1939 }
1940}
1941
1942impl FromTableRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext {}
1943
1944impl ReadArgs for SequenceContext {
1945 type Args = ();
1946}
1947
1948impl<'a> FontRead<'a> for SequenceContext {
1949 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1950 <read_fonts::tables::layout::SequenceContext as FontRead>::read(data)
1951 .map(|x| x.to_owned_table())
1952 }
1953}
1954
1955impl From<SequenceContextFormat1> for SequenceContext {
1956 fn from(src: SequenceContextFormat1) -> SequenceContext {
1957 SequenceContext::Format1(src)
1958 }
1959}
1960
1961impl From<SequenceContextFormat2> for SequenceContext {
1962 fn from(src: SequenceContextFormat2) -> SequenceContext {
1963 SequenceContext::Format2(src)
1964 }
1965}
1966
1967impl From<SequenceContextFormat3> for SequenceContext {
1968 fn from(src: SequenceContextFormat3) -> SequenceContext {
1969 SequenceContext::Format3(src)
1970 }
1971}
1972
1973impl From<SequenceContextFormat4> for SequenceContext {
1974 fn from(src: SequenceContextFormat4) -> SequenceContext {
1975 SequenceContext::Format4(src)
1976 }
1977}
1978
1979impl From<SequenceContextFormat5> for SequenceContext {
1980 fn from(src: SequenceContextFormat5) -> SequenceContext {
1981 SequenceContext::Format5(src)
1982 }
1983}
1984
1985impl From<SequenceContextFormat6> for SequenceContext {
1986 fn from(src: SequenceContextFormat6) -> SequenceContext {
1987 SequenceContext::Format6(src)
1988 }
1989}
1990
1991#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1993#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1994pub struct ChainedSequenceContextFormat1 {
1995 pub coverage: OffsetMarker<CoverageTable>,
1998 pub chained_seq_rule_sets: Vec<NullableOffsetMarker<ChainedSequenceRuleSet>>,
2001}
2002
2003impl ChainedSequenceContextFormat1 {
2004 pub fn new(
2006 coverage: CoverageTable,
2007 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>,
2008 ) -> Self {
2009 Self {
2010 coverage: coverage.into(),
2011 chained_seq_rule_sets: chained_seq_rule_sets.into_iter().map(Into::into).collect(),
2012 }
2013 }
2014}
2015
2016impl FontWrite for ChainedSequenceContextFormat1 {
2017 #[allow(clippy::unnecessary_cast)]
2018 fn write_into(&self, writer: &mut TableWriter) {
2019 (1 as u16).write_into(writer);
2020 self.coverage.write_into(writer);
2021 (u16::try_from(array_len(&self.chained_seq_rule_sets)).unwrap()).write_into(writer);
2022 self.chained_seq_rule_sets.write_into(writer);
2023 }
2024 fn table_type(&self) -> TableType {
2025 TableType::Named("ChainedSequenceContextFormat1")
2026 }
2027}
2028
2029impl Validate for ChainedSequenceContextFormat1 {
2030 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2031 ctx.in_table("ChainedSequenceContextFormat1", |ctx| {
2032 ctx.in_field("coverage", |ctx| {
2033 self.coverage.validate_impl(ctx);
2034 });
2035 ctx.in_field("chained_seq_rule_sets", |ctx| {
2036 if self.chained_seq_rule_sets.len() > to_usize(u16::MAX) {
2037 ctx.report("array exceeds max length");
2038 }
2039 self.chained_seq_rule_sets.validate_impl(ctx);
2040 });
2041 })
2042 }
2043}
2044
2045impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>>
2046 for ChainedSequenceContextFormat1
2047{
2048 fn from_obj_ref(
2049 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>,
2050 _: FontData,
2051 ) -> Self {
2052 ChainedSequenceContextFormat1 {
2053 coverage: obj.coverage().to_owned_table(),
2054 chained_seq_rule_sets: obj.chained_seq_rule_sets().to_owned_table(),
2055 }
2056 }
2057}
2058
2059#[allow(clippy::needless_lifetimes)]
2060impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>>
2061 for ChainedSequenceContextFormat1
2062{
2063}
2064
2065impl ReadArgs for ChainedSequenceContextFormat1 {
2066 type Args = ();
2067}
2068
2069impl<'a> FontRead<'a> for ChainedSequenceContextFormat1 {
2070 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2071 <read_fonts::tables::layout::ChainedSequenceContextFormat1 as FontRead>::read(data)
2072 .map(|x| x.to_owned_table())
2073 }
2074}
2075
2076#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2078#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2079pub struct ChainedSequenceRuleSet {
2080 pub chained_seq_rules: Vec<OffsetMarker<ChainedSequenceRule>>,
2083}
2084
2085impl ChainedSequenceRuleSet {
2086 pub fn new(chained_seq_rules: Vec<ChainedSequenceRule>) -> Self {
2088 Self {
2089 chained_seq_rules: chained_seq_rules.into_iter().map(Into::into).collect(),
2090 }
2091 }
2092}
2093
2094impl FontWrite for ChainedSequenceRuleSet {
2095 #[allow(clippy::unnecessary_cast)]
2096 fn write_into(&self, writer: &mut TableWriter) {
2097 (u16::try_from(array_len(&self.chained_seq_rules)).unwrap()).write_into(writer);
2098 self.chained_seq_rules.write_into(writer);
2099 }
2100 fn table_type(&self) -> TableType {
2101 TableType::Named("ChainedSequenceRuleSet")
2102 }
2103}
2104
2105impl Validate for ChainedSequenceRuleSet {
2106 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2107 ctx.in_table("ChainedSequenceRuleSet", |ctx| {
2108 ctx.in_field("chained_seq_rules", |ctx| {
2109 if self.chained_seq_rules.len() > to_usize(u16::MAX) {
2110 ctx.report("array exceeds max length");
2111 }
2112 self.chained_seq_rules.validate_impl(ctx);
2113 });
2114 })
2115 }
2116}
2117
2118impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>>
2119 for ChainedSequenceRuleSet
2120{
2121 fn from_obj_ref(
2122 obj: &read_fonts::tables::layout::ChainedSequenceRuleSet<'a>,
2123 _: FontData,
2124 ) -> Self {
2125 ChainedSequenceRuleSet {
2126 chained_seq_rules: obj.chained_seq_rules().to_owned_table(),
2127 }
2128 }
2129}
2130
2131#[allow(clippy::needless_lifetimes)]
2132impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>>
2133 for ChainedSequenceRuleSet
2134{
2135}
2136
2137impl ReadArgs for ChainedSequenceRuleSet {
2138 type Args = ();
2139}
2140
2141impl<'a> FontRead<'a> for ChainedSequenceRuleSet {
2142 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2143 <read_fonts::tables::layout::ChainedSequenceRuleSet as FontRead>::read(data)
2144 .map(|x| x.to_owned_table())
2145 }
2146}
2147
2148#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2150#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2151pub struct ChainedSequenceRule {
2152 pub backtrack_sequence: Vec<GlyphId16>,
2154 pub input_sequence: Vec<GlyphId16>,
2156 pub lookahead_sequence: Vec<GlyphId16>,
2158 pub seq_lookup_records: Vec<SequenceLookupRecord>,
2160}
2161
2162impl ChainedSequenceRule {
2163 pub fn new(
2165 backtrack_sequence: Vec<GlyphId16>,
2166 input_sequence: Vec<GlyphId16>,
2167 lookahead_sequence: Vec<GlyphId16>,
2168 seq_lookup_records: Vec<SequenceLookupRecord>,
2169 ) -> Self {
2170 Self {
2171 backtrack_sequence,
2172 input_sequence,
2173 lookahead_sequence,
2174 seq_lookup_records,
2175 }
2176 }
2177}
2178
2179impl FontWrite for ChainedSequenceRule {
2180 #[allow(clippy::unnecessary_cast)]
2181 fn write_into(&self, writer: &mut TableWriter) {
2182 (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer);
2183 self.backtrack_sequence.write_into(writer);
2184 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
2185 self.input_sequence.write_into(writer);
2186 (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer);
2187 self.lookahead_sequence.write_into(writer);
2188 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
2189 self.seq_lookup_records.write_into(writer);
2190 }
2191 fn table_type(&self) -> TableType {
2192 TableType::Named("ChainedSequenceRule")
2193 }
2194}
2195
2196impl Validate for ChainedSequenceRule {
2197 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2198 ctx.in_table("ChainedSequenceRule", |ctx| {
2199 ctx.in_field("backtrack_sequence", |ctx| {
2200 if self.backtrack_sequence.len() > to_usize(u16::MAX) {
2201 ctx.report("array exceeds max length");
2202 }
2203 });
2204 ctx.in_field("lookahead_sequence", |ctx| {
2205 if self.lookahead_sequence.len() > to_usize(u16::MAX) {
2206 ctx.report("array exceeds max length");
2207 }
2208 });
2209 ctx.in_field("seq_lookup_records", |ctx| {
2210 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
2211 ctx.report("array exceeds max length");
2212 }
2213 self.seq_lookup_records.validate_impl(ctx);
2214 });
2215 })
2216 }
2217}
2218
2219impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule {
2220 fn from_obj_ref(
2221 obj: &read_fonts::tables::layout::ChainedSequenceRule<'a>,
2222 _: FontData,
2223 ) -> Self {
2224 let offset_data = obj.offset_data();
2225 ChainedSequenceRule {
2226 backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data),
2227 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
2228 lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data),
2229 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2230 }
2231 }
2232}
2233
2234#[allow(clippy::needless_lifetimes)]
2235impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule {}
2236
2237impl ReadArgs for ChainedSequenceRule {
2238 type Args = ();
2239}
2240
2241impl<'a> FontRead<'a> for ChainedSequenceRule {
2242 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2243 <read_fonts::tables::layout::ChainedSequenceRule as FontRead>::read(data)
2244 .map(|x| x.to_owned_table())
2245 }
2246}
2247
2248#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2251pub struct ChainedSequenceContextFormat2 {
2252 pub coverage: OffsetMarker<CoverageTable>,
2255 pub backtrack_class_def: OffsetMarker<ClassDef>,
2258 pub input_class_def: OffsetMarker<ClassDef>,
2261 pub lookahead_class_def: OffsetMarker<ClassDef>,
2264 pub chained_class_seq_rule_sets: Vec<NullableOffsetMarker<ChainedClassSequenceRuleSet>>,
2267}
2268
2269impl ChainedSequenceContextFormat2 {
2270 pub fn new(
2272 coverage: CoverageTable,
2273 backtrack_class_def: ClassDef,
2274 input_class_def: ClassDef,
2275 lookahead_class_def: ClassDef,
2276 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>,
2277 ) -> Self {
2278 Self {
2279 coverage: coverage.into(),
2280 backtrack_class_def: backtrack_class_def.into(),
2281 input_class_def: input_class_def.into(),
2282 lookahead_class_def: lookahead_class_def.into(),
2283 chained_class_seq_rule_sets: chained_class_seq_rule_sets
2284 .into_iter()
2285 .map(Into::into)
2286 .collect(),
2287 }
2288 }
2289}
2290
2291impl FontWrite for ChainedSequenceContextFormat2 {
2292 #[allow(clippy::unnecessary_cast)]
2293 fn write_into(&self, writer: &mut TableWriter) {
2294 (2 as u16).write_into(writer);
2295 self.coverage.write_into(writer);
2296 self.backtrack_class_def.write_into(writer);
2297 self.input_class_def.write_into(writer);
2298 self.lookahead_class_def.write_into(writer);
2299 (u16::try_from(array_len(&self.chained_class_seq_rule_sets)).unwrap()).write_into(writer);
2300 self.chained_class_seq_rule_sets.write_into(writer);
2301 }
2302 fn table_type(&self) -> TableType {
2303 TableType::Named("ChainedSequenceContextFormat2")
2304 }
2305}
2306
2307impl Validate for ChainedSequenceContextFormat2 {
2308 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2309 ctx.in_table("ChainedSequenceContextFormat2", |ctx| {
2310 ctx.in_field("coverage", |ctx| {
2311 self.coverage.validate_impl(ctx);
2312 });
2313 ctx.in_field("backtrack_class_def", |ctx| {
2314 self.backtrack_class_def.validate_impl(ctx);
2315 });
2316 ctx.in_field("input_class_def", |ctx| {
2317 self.input_class_def.validate_impl(ctx);
2318 });
2319 ctx.in_field("lookahead_class_def", |ctx| {
2320 self.lookahead_class_def.validate_impl(ctx);
2321 });
2322 ctx.in_field("chained_class_seq_rule_sets", |ctx| {
2323 if self.chained_class_seq_rule_sets.len() > to_usize(u16::MAX) {
2324 ctx.report("array exceeds max length");
2325 }
2326 self.chained_class_seq_rule_sets.validate_impl(ctx);
2327 });
2328 })
2329 }
2330}
2331
2332impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>>
2333 for ChainedSequenceContextFormat2
2334{
2335 fn from_obj_ref(
2336 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>,
2337 _: FontData,
2338 ) -> Self {
2339 ChainedSequenceContextFormat2 {
2340 coverage: obj.coverage().to_owned_table(),
2341 backtrack_class_def: obj.backtrack_class_def().to_owned_table(),
2342 input_class_def: obj.input_class_def().to_owned_table(),
2343 lookahead_class_def: obj.lookahead_class_def().to_owned_table(),
2344 chained_class_seq_rule_sets: obj.chained_class_seq_rule_sets().to_owned_table(),
2345 }
2346 }
2347}
2348
2349#[allow(clippy::needless_lifetimes)]
2350impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>>
2351 for ChainedSequenceContextFormat2
2352{
2353}
2354
2355impl ReadArgs for ChainedSequenceContextFormat2 {
2356 type Args = ();
2357}
2358
2359impl<'a> FontRead<'a> for ChainedSequenceContextFormat2 {
2360 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2361 <read_fonts::tables::layout::ChainedSequenceContextFormat2 as FontRead>::read(data)
2362 .map(|x| x.to_owned_table())
2363 }
2364}
2365
2366#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2368#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2369pub struct ChainedClassSequenceRuleSet {
2370 pub chained_class_seq_rules: Vec<OffsetMarker<ChainedClassSequenceRule>>,
2373}
2374
2375impl ChainedClassSequenceRuleSet {
2376 pub fn new(chained_class_seq_rules: Vec<ChainedClassSequenceRule>) -> Self {
2378 Self {
2379 chained_class_seq_rules: chained_class_seq_rules
2380 .into_iter()
2381 .map(Into::into)
2382 .collect(),
2383 }
2384 }
2385}
2386
2387impl FontWrite for ChainedClassSequenceRuleSet {
2388 #[allow(clippy::unnecessary_cast)]
2389 fn write_into(&self, writer: &mut TableWriter) {
2390 (u16::try_from(array_len(&self.chained_class_seq_rules)).unwrap()).write_into(writer);
2391 self.chained_class_seq_rules.write_into(writer);
2392 }
2393 fn table_type(&self) -> TableType {
2394 TableType::Named("ChainedClassSequenceRuleSet")
2395 }
2396}
2397
2398impl Validate for ChainedClassSequenceRuleSet {
2399 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2400 ctx.in_table("ChainedClassSequenceRuleSet", |ctx| {
2401 ctx.in_field("chained_class_seq_rules", |ctx| {
2402 if self.chained_class_seq_rules.len() > to_usize(u16::MAX) {
2403 ctx.report("array exceeds max length");
2404 }
2405 self.chained_class_seq_rules.validate_impl(ctx);
2406 });
2407 })
2408 }
2409}
2410
2411impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>>
2412 for ChainedClassSequenceRuleSet
2413{
2414 fn from_obj_ref(
2415 obj: &read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>,
2416 _: FontData,
2417 ) -> Self {
2418 ChainedClassSequenceRuleSet {
2419 chained_class_seq_rules: obj.chained_class_seq_rules().to_owned_table(),
2420 }
2421 }
2422}
2423
2424#[allow(clippy::needless_lifetimes)]
2425impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>>
2426 for ChainedClassSequenceRuleSet
2427{
2428}
2429
2430impl ReadArgs for ChainedClassSequenceRuleSet {
2431 type Args = ();
2432}
2433
2434impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet {
2435 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2436 <read_fonts::tables::layout::ChainedClassSequenceRuleSet as FontRead>::read(data)
2437 .map(|x| x.to_owned_table())
2438 }
2439}
2440
2441#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2443#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2444pub struct ChainedClassSequenceRule {
2445 pub backtrack_sequence: Vec<u16>,
2447 pub input_sequence: Vec<u16>,
2450 pub lookahead_sequence: Vec<u16>,
2452 pub seq_lookup_records: Vec<SequenceLookupRecord>,
2454}
2455
2456impl ChainedClassSequenceRule {
2457 pub fn new(
2459 backtrack_sequence: Vec<u16>,
2460 input_sequence: Vec<u16>,
2461 lookahead_sequence: Vec<u16>,
2462 seq_lookup_records: Vec<SequenceLookupRecord>,
2463 ) -> Self {
2464 Self {
2465 backtrack_sequence,
2466 input_sequence,
2467 lookahead_sequence,
2468 seq_lookup_records,
2469 }
2470 }
2471}
2472
2473impl FontWrite for ChainedClassSequenceRule {
2474 #[allow(clippy::unnecessary_cast)]
2475 fn write_into(&self, writer: &mut TableWriter) {
2476 (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer);
2477 self.backtrack_sequence.write_into(writer);
2478 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
2479 self.input_sequence.write_into(writer);
2480 (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer);
2481 self.lookahead_sequence.write_into(writer);
2482 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
2483 self.seq_lookup_records.write_into(writer);
2484 }
2485 fn table_type(&self) -> TableType {
2486 TableType::Named("ChainedClassSequenceRule")
2487 }
2488}
2489
2490impl Validate for ChainedClassSequenceRule {
2491 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2492 ctx.in_table("ChainedClassSequenceRule", |ctx| {
2493 ctx.in_field("backtrack_sequence", |ctx| {
2494 if self.backtrack_sequence.len() > to_usize(u16::MAX) {
2495 ctx.report("array exceeds max length");
2496 }
2497 });
2498 ctx.in_field("lookahead_sequence", |ctx| {
2499 if self.lookahead_sequence.len() > to_usize(u16::MAX) {
2500 ctx.report("array exceeds max length");
2501 }
2502 });
2503 ctx.in_field("seq_lookup_records", |ctx| {
2504 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
2505 ctx.report("array exceeds max length");
2506 }
2507 self.seq_lookup_records.validate_impl(ctx);
2508 });
2509 })
2510 }
2511}
2512
2513impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>>
2514 for ChainedClassSequenceRule
2515{
2516 fn from_obj_ref(
2517 obj: &read_fonts::tables::layout::ChainedClassSequenceRule<'a>,
2518 _: FontData,
2519 ) -> Self {
2520 let offset_data = obj.offset_data();
2521 ChainedClassSequenceRule {
2522 backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data),
2523 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
2524 lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data),
2525 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2526 }
2527 }
2528}
2529
2530#[allow(clippy::needless_lifetimes)]
2531impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>>
2532 for ChainedClassSequenceRule
2533{
2534}
2535
2536impl ReadArgs for ChainedClassSequenceRule {
2537 type Args = ();
2538}
2539
2540impl<'a> FontRead<'a> for ChainedClassSequenceRule {
2541 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2542 <read_fonts::tables::layout::ChainedClassSequenceRule as FontRead>::read(data)
2543 .map(|x| x.to_owned_table())
2544 }
2545}
2546
2547#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2549#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2550pub struct ChainedSequenceContextFormat3 {
2551 pub backtrack_coverages: Vec<OffsetMarker<CoverageTable>>,
2553 pub input_coverages: Vec<OffsetMarker<CoverageTable>>,
2555 pub lookahead_coverages: Vec<OffsetMarker<CoverageTable>>,
2557 pub seq_lookup_records: Vec<SequenceLookupRecord>,
2559}
2560
2561impl ChainedSequenceContextFormat3 {
2562 pub fn new(
2564 backtrack_coverages: Vec<CoverageTable>,
2565 input_coverages: Vec<CoverageTable>,
2566 lookahead_coverages: Vec<CoverageTable>,
2567 seq_lookup_records: Vec<SequenceLookupRecord>,
2568 ) -> Self {
2569 Self {
2570 backtrack_coverages: backtrack_coverages.into_iter().map(Into::into).collect(),
2571 input_coverages: input_coverages.into_iter().map(Into::into).collect(),
2572 lookahead_coverages: lookahead_coverages.into_iter().map(Into::into).collect(),
2573 seq_lookup_records,
2574 }
2575 }
2576}
2577
2578impl FontWrite for ChainedSequenceContextFormat3 {
2579 #[allow(clippy::unnecessary_cast)]
2580 fn write_into(&self, writer: &mut TableWriter) {
2581 (3 as u16).write_into(writer);
2582 (u16::try_from(array_len(&self.backtrack_coverages)).unwrap()).write_into(writer);
2583 self.backtrack_coverages.write_into(writer);
2584 (u16::try_from(array_len(&self.input_coverages)).unwrap()).write_into(writer);
2585 self.input_coverages.write_into(writer);
2586 (u16::try_from(array_len(&self.lookahead_coverages)).unwrap()).write_into(writer);
2587 self.lookahead_coverages.write_into(writer);
2588 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
2589 self.seq_lookup_records.write_into(writer);
2590 }
2591 fn table_type(&self) -> TableType {
2592 TableType::Named("ChainedSequenceContextFormat3")
2593 }
2594}
2595
2596impl Validate for ChainedSequenceContextFormat3 {
2597 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2598 ctx.in_table("ChainedSequenceContextFormat3", |ctx| {
2599 ctx.in_field("backtrack_coverages", |ctx| {
2600 if self.backtrack_coverages.len() > to_usize(u16::MAX) {
2601 ctx.report("array exceeds max length");
2602 }
2603 self.backtrack_coverages.validate_impl(ctx);
2604 });
2605 ctx.in_field("input_coverages", |ctx| {
2606 if self.input_coverages.len() > to_usize(u16::MAX) {
2607 ctx.report("array exceeds max length");
2608 }
2609 self.input_coverages.validate_impl(ctx);
2610 });
2611 ctx.in_field("lookahead_coverages", |ctx| {
2612 if self.lookahead_coverages.len() > to_usize(u16::MAX) {
2613 ctx.report("array exceeds max length");
2614 }
2615 self.lookahead_coverages.validate_impl(ctx);
2616 });
2617 ctx.in_field("seq_lookup_records", |ctx| {
2618 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
2619 ctx.report("array exceeds max length");
2620 }
2621 self.seq_lookup_records.validate_impl(ctx);
2622 });
2623 })
2624 }
2625}
2626
2627impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>>
2628 for ChainedSequenceContextFormat3
2629{
2630 fn from_obj_ref(
2631 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>,
2632 _: FontData,
2633 ) -> Self {
2634 let offset_data = obj.offset_data();
2635 ChainedSequenceContextFormat3 {
2636 backtrack_coverages: obj.backtrack_coverages().to_owned_table(),
2637 input_coverages: obj.input_coverages().to_owned_table(),
2638 lookahead_coverages: obj.lookahead_coverages().to_owned_table(),
2639 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
2640 }
2641 }
2642}
2643
2644#[allow(clippy::needless_lifetimes)]
2645impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>>
2646 for ChainedSequenceContextFormat3
2647{
2648}
2649
2650impl ReadArgs for ChainedSequenceContextFormat3 {
2651 type Args = ();
2652}
2653
2654impl<'a> FontRead<'a> for ChainedSequenceContextFormat3 {
2655 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2656 <read_fonts::tables::layout::ChainedSequenceContextFormat3 as FontRead>::read(data)
2657 .map(|x| x.to_owned_table())
2658 }
2659}
2660
2661#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2662#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2663pub enum ChainedSequenceContext {
2664 Format1(ChainedSequenceContextFormat1),
2665 Format2(ChainedSequenceContextFormat2),
2666 Format3(ChainedSequenceContextFormat3),
2667 Format4(ChainedSequenceContextFormat4),
2668 Format5(ChainedSequenceContextFormat5),
2669}
2670
2671impl ChainedSequenceContext {
2672 pub fn format_1(
2674 coverage: CoverageTable,
2675 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>,
2676 ) -> Self {
2677 Self::Format1(ChainedSequenceContextFormat1::new(
2678 coverage,
2679 chained_seq_rule_sets,
2680 ))
2681 }
2682
2683 pub fn format_2(
2685 coverage: CoverageTable,
2686 backtrack_class_def: ClassDef,
2687 input_class_def: ClassDef,
2688 lookahead_class_def: ClassDef,
2689 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>,
2690 ) -> Self {
2691 Self::Format2(ChainedSequenceContextFormat2::new(
2692 coverage,
2693 backtrack_class_def,
2694 input_class_def,
2695 lookahead_class_def,
2696 chained_class_seq_rule_sets,
2697 ))
2698 }
2699
2700 pub fn format_3(
2702 backtrack_coverages: Vec<CoverageTable>,
2703 input_coverages: Vec<CoverageTable>,
2704 lookahead_coverages: Vec<CoverageTable>,
2705 seq_lookup_records: Vec<SequenceLookupRecord>,
2706 ) -> Self {
2707 Self::Format3(ChainedSequenceContextFormat3::new(
2708 backtrack_coverages,
2709 input_coverages,
2710 lookahead_coverages,
2711 seq_lookup_records,
2712 ))
2713 }
2714
2715 pub fn format_4(
2717 coverage: CoverageTable,
2718 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet2>>,
2719 ) -> Self {
2720 Self::Format4(ChainedSequenceContextFormat4::new(
2721 coverage,
2722 chained_seq_rule_sets,
2723 ))
2724 }
2725
2726 pub fn format_5(
2728 coverage: CoverageTable,
2729 backtrack_class_def: ClassDef,
2730 input_class_def: ClassDef,
2731 lookahead_class_def: ClassDef,
2732 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet2>>,
2733 ) -> Self {
2734 Self::Format5(ChainedSequenceContextFormat5::new(
2735 coverage,
2736 backtrack_class_def,
2737 input_class_def,
2738 lookahead_class_def,
2739 chained_class_seq_rule_sets,
2740 ))
2741 }
2742}
2743
2744impl Default for ChainedSequenceContext {
2745 fn default() -> Self {
2746 Self::Format1(Default::default())
2747 }
2748}
2749
2750impl FontWrite for ChainedSequenceContext {
2751 fn write_into(&self, writer: &mut TableWriter) {
2752 match self {
2753 Self::Format1(item) => item.write_into(writer),
2754 Self::Format2(item) => item.write_into(writer),
2755 Self::Format3(item) => item.write_into(writer),
2756 Self::Format4(item) => item.write_into(writer),
2757 Self::Format5(item) => item.write_into(writer),
2758 }
2759 }
2760 fn table_type(&self) -> TableType {
2761 match self {
2762 Self::Format1(item) => item.table_type(),
2763 Self::Format2(item) => item.table_type(),
2764 Self::Format3(item) => item.table_type(),
2765 Self::Format4(item) => item.table_type(),
2766 Self::Format5(item) => item.table_type(),
2767 }
2768 }
2769}
2770
2771impl Validate for ChainedSequenceContext {
2772 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2773 match self {
2774 Self::Format1(item) => item.validate_impl(ctx),
2775 Self::Format2(item) => item.validate_impl(ctx),
2776 Self::Format3(item) => item.validate_impl(ctx),
2777 Self::Format4(item) => item.validate_impl(ctx),
2778 Self::Format5(item) => item.validate_impl(ctx),
2779 }
2780 }
2781}
2782
2783impl FromObjRef<read_fonts::tables::layout::ChainedSequenceContext<'_>> for ChainedSequenceContext {
2784 fn from_obj_ref(obj: &read_fonts::tables::layout::ChainedSequenceContext, _: FontData) -> Self {
2785 use read_fonts::tables::layout::ChainedSequenceContext as ObjRefType;
2786 match obj {
2787 ObjRefType::Format1(item) => ChainedSequenceContext::Format1(item.to_owned_table()),
2788 ObjRefType::Format2(item) => ChainedSequenceContext::Format2(item.to_owned_table()),
2789 ObjRefType::Format3(item) => ChainedSequenceContext::Format3(item.to_owned_table()),
2790 ObjRefType::Format4(item) => ChainedSequenceContext::Format4(item.to_owned_table()),
2791 ObjRefType::Format5(item) => ChainedSequenceContext::Format5(item.to_owned_table()),
2792 }
2793 }
2794}
2795
2796impl FromTableRef<read_fonts::tables::layout::ChainedSequenceContext<'_>>
2797 for ChainedSequenceContext
2798{
2799}
2800
2801impl ReadArgs for ChainedSequenceContext {
2802 type Args = ();
2803}
2804
2805impl<'a> FontRead<'a> for ChainedSequenceContext {
2806 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2807 <read_fonts::tables::layout::ChainedSequenceContext as FontRead>::read(data)
2808 .map(|x| x.to_owned_table())
2809 }
2810}
2811
2812impl From<ChainedSequenceContextFormat1> for ChainedSequenceContext {
2813 fn from(src: ChainedSequenceContextFormat1) -> ChainedSequenceContext {
2814 ChainedSequenceContext::Format1(src)
2815 }
2816}
2817
2818impl From<ChainedSequenceContextFormat2> for ChainedSequenceContext {
2819 fn from(src: ChainedSequenceContextFormat2) -> ChainedSequenceContext {
2820 ChainedSequenceContext::Format2(src)
2821 }
2822}
2823
2824impl From<ChainedSequenceContextFormat3> for ChainedSequenceContext {
2825 fn from(src: ChainedSequenceContextFormat3) -> ChainedSequenceContext {
2826 ChainedSequenceContext::Format3(src)
2827 }
2828}
2829
2830impl From<ChainedSequenceContextFormat4> for ChainedSequenceContext {
2831 fn from(src: ChainedSequenceContextFormat4) -> ChainedSequenceContext {
2832 ChainedSequenceContext::Format4(src)
2833 }
2834}
2835
2836impl From<ChainedSequenceContextFormat5> for ChainedSequenceContext {
2837 fn from(src: ChainedSequenceContextFormat5) -> ChainedSequenceContext {
2838 ChainedSequenceContext::Format5(src)
2839 }
2840}
2841
2842impl FontWrite for DeltaFormat {
2843 fn write_into(&self, writer: &mut TableWriter) {
2844 let val = *self as u16;
2845 writer.write_slice(&val.to_be_bytes())
2846 }
2847}
2848
2849#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2851#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2852pub struct Device {
2853 pub start_size: u16,
2855 pub end_size: u16,
2857 pub delta_format: DeltaFormat,
2859 pub delta_value: Vec<u16>,
2861}
2862
2863impl FontWrite for Device {
2864 fn write_into(&self, writer: &mut TableWriter) {
2865 self.start_size.write_into(writer);
2866 self.end_size.write_into(writer);
2867 self.delta_format.write_into(writer);
2868 self.delta_value.write_into(writer);
2869 }
2870 fn table_type(&self) -> TableType {
2871 TableType::Named("Device")
2872 }
2873}
2874
2875impl Validate for Device {
2876 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2877}
2878
2879impl<'a> FromObjRef<read_fonts::tables::layout::Device<'a>> for Device {
2880 fn from_obj_ref(obj: &read_fonts::tables::layout::Device<'a>, _: FontData) -> Self {
2881 let offset_data = obj.offset_data();
2882 Device {
2883 start_size: obj.start_size(),
2884 end_size: obj.end_size(),
2885 delta_format: obj.delta_format(),
2886 delta_value: obj.delta_value().to_owned_obj(offset_data),
2887 }
2888 }
2889}
2890
2891#[allow(clippy::needless_lifetimes)]
2892impl<'a> FromTableRef<read_fonts::tables::layout::Device<'a>> for Device {}
2893
2894impl ReadArgs for Device {
2895 type Args = ();
2896}
2897
2898impl<'a> FontRead<'a> for Device {
2899 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2900 <read_fonts::tables::layout::Device as FontRead>::read(data).map(|x| x.to_owned_table())
2901 }
2902}
2903
2904#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2906#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2907pub struct VariationIndex {
2908 pub delta_set_outer_index: u16,
2911 pub delta_set_inner_index: u16,
2914}
2915
2916impl VariationIndex {
2917 pub fn new(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self {
2919 Self {
2920 delta_set_outer_index,
2921 delta_set_inner_index,
2922 }
2923 }
2924}
2925
2926impl FontWrite for VariationIndex {
2927 #[allow(clippy::unnecessary_cast)]
2928 fn write_into(&self, writer: &mut TableWriter) {
2929 self.delta_set_outer_index.write_into(writer);
2930 self.delta_set_inner_index.write_into(writer);
2931 (DeltaFormat::VariationIndex as DeltaFormat).write_into(writer);
2932 }
2933 fn table_type(&self) -> TableType {
2934 TableType::Named("VariationIndex")
2935 }
2936}
2937
2938impl Validate for VariationIndex {
2939 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2940}
2941
2942impl<'a> FromObjRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex {
2943 fn from_obj_ref(obj: &read_fonts::tables::layout::VariationIndex<'a>, _: FontData) -> Self {
2944 VariationIndex {
2945 delta_set_outer_index: obj.delta_set_outer_index(),
2946 delta_set_inner_index: obj.delta_set_inner_index(),
2947 }
2948 }
2949}
2950
2951#[allow(clippy::needless_lifetimes)]
2952impl<'a> FromTableRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex {}
2953
2954impl ReadArgs for VariationIndex {
2955 type Args = ();
2956}
2957
2958impl<'a> FontRead<'a> for VariationIndex {
2959 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2960 <read_fonts::tables::layout::VariationIndex as FontRead>::read(data)
2961 .map(|x| x.to_owned_table())
2962 }
2963}
2964
2965#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
2976#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2977pub struct PendingVariationIndex {
2978 pub delta_set_id: u32,
2980}
2981
2982impl PendingVariationIndex {
2983 pub fn new(delta_set_id: u32) -> Self {
2985 Self { delta_set_id }
2986 }
2987}
2988
2989impl Validate for PendingVariationIndex {
2990 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2991}
2992
2993#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2995#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2996pub enum DeviceOrVariationIndex {
2997 Device(Device),
2998 VariationIndex(VariationIndex),
2999 PendingVariationIndex(PendingVariationIndex),
3000}
3001
3002impl DeviceOrVariationIndex {
3003 pub fn variation_index(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self {
3005 Self::VariationIndex(VariationIndex::new(
3006 delta_set_outer_index,
3007 delta_set_inner_index,
3008 ))
3009 }
3010
3011 pub fn pending_variation_index(delta_set_id: u32) -> Self {
3013 Self::PendingVariationIndex(PendingVariationIndex::new(delta_set_id))
3014 }
3015}
3016
3017impl Default for DeviceOrVariationIndex {
3018 fn default() -> Self {
3019 Self::Device(Default::default())
3020 }
3021}
3022
3023impl FontWrite for DeviceOrVariationIndex {
3024 fn write_into(&self, writer: &mut TableWriter) {
3025 match self {
3026 Self::Device(item) => item.write_into(writer),
3027 Self::VariationIndex(item) => item.write_into(writer),
3028 Self::PendingVariationIndex(item) => item.write_into(writer),
3029 }
3030 }
3031 fn table_type(&self) -> TableType {
3032 match self {
3033 Self::Device(item) => item.table_type(),
3034 Self::VariationIndex(item) => item.table_type(),
3035 Self::PendingVariationIndex(item) => item.table_type(),
3036 }
3037 }
3038}
3039
3040impl Validate for DeviceOrVariationIndex {
3041 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3042 match self {
3043 Self::Device(item) => item.validate_impl(ctx),
3044 Self::VariationIndex(item) => item.validate_impl(ctx),
3045 Self::PendingVariationIndex(item) => item.validate_impl(ctx),
3046 }
3047 }
3048}
3049
3050impl FromObjRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>> for DeviceOrVariationIndex {
3051 fn from_obj_ref(obj: &read_fonts::tables::layout::DeviceOrVariationIndex, _: FontData) -> Self {
3052 use read_fonts::tables::layout::DeviceOrVariationIndex as ObjRefType;
3053 match obj {
3054 ObjRefType::Device(item) => DeviceOrVariationIndex::Device(item.to_owned_table()),
3055 ObjRefType::VariationIndex(item) => {
3056 DeviceOrVariationIndex::VariationIndex(item.to_owned_table())
3057 }
3058 }
3059 }
3060}
3061
3062impl FromTableRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>>
3063 for DeviceOrVariationIndex
3064{
3065}
3066
3067impl ReadArgs for DeviceOrVariationIndex {
3068 type Args = ();
3069}
3070
3071impl<'a> FontRead<'a> for DeviceOrVariationIndex {
3072 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3073 <read_fonts::tables::layout::DeviceOrVariationIndex as FontRead>::read(data)
3074 .map(|x| x.to_owned_table())
3075 }
3076}
3077
3078impl From<Device> for DeviceOrVariationIndex {
3079 fn from(src: Device) -> DeviceOrVariationIndex {
3080 DeviceOrVariationIndex::Device(src)
3081 }
3082}
3083
3084impl From<VariationIndex> for DeviceOrVariationIndex {
3085 fn from(src: VariationIndex) -> DeviceOrVariationIndex {
3086 DeviceOrVariationIndex::VariationIndex(src)
3087 }
3088}
3089
3090impl From<PendingVariationIndex> for DeviceOrVariationIndex {
3091 fn from(src: PendingVariationIndex) -> DeviceOrVariationIndex {
3092 DeviceOrVariationIndex::PendingVariationIndex(src)
3093 }
3094}
3095
3096#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3099#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3100pub struct FeatureVariations {
3101 pub feature_variation_records: Vec<FeatureVariationRecord>,
3103 pub lookup_variation_records: Option<Vec<LookupVariationRecord>>,
3105}
3106
3107impl FeatureVariations {
3108 pub fn new(feature_variation_records: Vec<FeatureVariationRecord>) -> Self {
3110 Self {
3111 feature_variation_records,
3112 ..Default::default()
3113 }
3114 }
3115}
3116
3117impl FontWrite for FeatureVariations {
3118 #[allow(clippy::unnecessary_cast)]
3119 fn write_into(&self, writer: &mut TableWriter) {
3120 let version = self.compute_version() as MajorMinor;
3121 version.write_into(writer);
3122 (u32::try_from(array_len(&self.feature_variation_records)).unwrap()).write_into(writer);
3123 self.feature_variation_records.write_into(writer);
3124 version.compatible((1u16, 1u16)).then(|| {
3125 (u32::try_from(array_len(&self.lookup_variation_records)).unwrap()).write_into(writer)
3126 });
3127 version.compatible((1u16, 1u16)).then(|| {
3128 self.lookup_variation_records
3129 .as_ref()
3130 .expect("missing conditional field should have failed validation")
3131 .write_into(writer)
3132 });
3133 }
3134 fn table_type(&self) -> TableType {
3135 TableType::Named("FeatureVariations")
3136 }
3137}
3138
3139impl Validate for FeatureVariations {
3140 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3141 ctx.in_table("FeatureVariations", |ctx| {
3142 let version: MajorMinor = self.compute_version();
3143 ctx.in_field("feature_variation_records", |ctx| {
3144 if self.feature_variation_records.len() > to_usize(u32::MAX) {
3145 ctx.report("array exceeds max length");
3146 }
3147 self.feature_variation_records.validate_impl(ctx);
3148 });
3149 ctx.in_field("lookup_variation_records", |ctx| {
3150 if version.compatible((1u16, 1u16)) && self.lookup_variation_records.is_none() {
3151 ctx.report(format!("field must be present for version {version}"));
3152 }
3153 if self.lookup_variation_records.is_some()
3154 && self.lookup_variation_records.as_ref().unwrap().len() > to_usize(u32::MAX)
3155 {
3156 ctx.report("array exceeds max length");
3157 }
3158 self.lookup_variation_records.validate_impl(ctx);
3159 });
3160 self.validate_lookup_variations(ctx);
3161 })
3162 }
3163}
3164
3165impl<'a> FromObjRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations {
3166 fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureVariations<'a>, _: FontData) -> Self {
3167 let offset_data = obj.offset_data();
3168 FeatureVariations {
3169 feature_variation_records: obj.feature_variation_records().to_owned_obj(offset_data),
3170 lookup_variation_records: obj.lookup_variation_records().to_owned_obj(offset_data),
3171 }
3172 }
3173}
3174
3175#[allow(clippy::needless_lifetimes)]
3176impl<'a> FromTableRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations {}
3177
3178impl ReadArgs for FeatureVariations {
3179 type Args = ();
3180}
3181
3182impl<'a> FontRead<'a> for FeatureVariations {
3183 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3184 <read_fonts::tables::layout::FeatureVariations as FontRead>::read(data)
3185 .map(|x| x.to_owned_table())
3186 }
3187}
3188
3189#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3192pub struct FeatureVariationRecord {
3193 pub condition_set: NullableOffsetMarker<ConditionSet, WIDTH_32>,
3196 pub feature_table_substitution: NullableOffsetMarker<FeatureTableSubstitution, WIDTH_32>,
3199}
3200
3201impl FeatureVariationRecord {
3202 pub fn new(
3204 condition_set: Option<ConditionSet>,
3205 feature_table_substitution: Option<FeatureTableSubstitution>,
3206 ) -> Self {
3207 Self {
3208 condition_set: condition_set.into(),
3209 feature_table_substitution: feature_table_substitution.into(),
3210 }
3211 }
3212}
3213
3214impl FontWrite for FeatureVariationRecord {
3215 fn write_into(&self, writer: &mut TableWriter) {
3216 self.condition_set.write_into(writer);
3217 self.feature_table_substitution.write_into(writer);
3218 }
3219 fn table_type(&self) -> TableType {
3220 TableType::Named("FeatureVariationRecord")
3221 }
3222}
3223
3224impl Validate for FeatureVariationRecord {
3225 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3226 ctx.in_table("FeatureVariationRecord", |ctx| {
3227 ctx.in_field("condition_set", |ctx| {
3228 self.condition_set.validate_impl(ctx);
3229 });
3230 ctx.in_field("feature_table_substitution", |ctx| {
3231 self.feature_table_substitution.validate_impl(ctx);
3232 });
3233 })
3234 }
3235}
3236
3237impl FromObjRef<read_fonts::tables::layout::FeatureVariationRecord> for FeatureVariationRecord {
3238 fn from_obj_ref(
3239 obj: &read_fonts::tables::layout::FeatureVariationRecord,
3240 offset_data: FontData,
3241 ) -> Self {
3242 FeatureVariationRecord {
3243 condition_set: obj.condition_set(offset_data).to_owned_table(),
3244 feature_table_substitution: obj
3245 .feature_table_substitution(offset_data)
3246 .to_owned_table(),
3247 }
3248 }
3249}
3250
3251#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3253#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3254pub struct LookupVariationRecord {
3255 pub feature_index: u16,
3256 pub feature_lookups: OffsetMarker<FeatureLookups, WIDTH_32>,
3258}
3259
3260impl LookupVariationRecord {
3261 pub fn new(feature_index: u16, feature_lookups: FeatureLookups) -> Self {
3263 Self {
3264 feature_index,
3265 feature_lookups: feature_lookups.into(),
3266 }
3267 }
3268}
3269
3270impl FontWrite for LookupVariationRecord {
3271 fn write_into(&self, writer: &mut TableWriter) {
3272 self.feature_index.write_into(writer);
3273 self.feature_lookups.write_into(writer);
3274 }
3275 fn table_type(&self) -> TableType {
3276 TableType::Named("LookupVariationRecord")
3277 }
3278}
3279
3280impl Validate for LookupVariationRecord {
3281 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3282 ctx.in_table("LookupVariationRecord", |ctx| {
3283 ctx.in_field("feature_lookups", |ctx| {
3284 self.feature_lookups.validate_impl(ctx);
3285 });
3286 })
3287 }
3288}
3289
3290impl FromObjRef<read_fonts::tables::layout::LookupVariationRecord> for LookupVariationRecord {
3291 fn from_obj_ref(
3292 obj: &read_fonts::tables::layout::LookupVariationRecord,
3293 offset_data: FontData,
3294 ) -> Self {
3295 LookupVariationRecord {
3296 feature_index: obj.feature_index(),
3297 feature_lookups: obj.feature_lookups(offset_data).to_owned_table(),
3298 }
3299 }
3300}
3301
3302#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3304#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3305pub struct FeatureLookups {
3306 pub flags: FeatureLookupsFlags,
3307 pub lookup_condition_records: Vec<LookupConditionRecord>,
3308}
3309
3310impl FeatureLookups {
3311 pub fn new(
3313 flags: FeatureLookupsFlags,
3314 lookup_condition_records: Vec<LookupConditionRecord>,
3315 ) -> Self {
3316 Self {
3317 flags,
3318 lookup_condition_records,
3319 }
3320 }
3321}
3322
3323impl FontWrite for FeatureLookups {
3324 #[allow(clippy::unnecessary_cast)]
3325 fn write_into(&self, writer: &mut TableWriter) {
3326 (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer);
3327 self.flags.write_into(writer);
3328 (u32::try_from(array_len(&self.lookup_condition_records)).unwrap()).write_into(writer);
3329 self.lookup_condition_records.write_into(writer);
3330 }
3331 fn table_type(&self) -> TableType {
3332 TableType::Named("FeatureLookups")
3333 }
3334}
3335
3336impl Validate for FeatureLookups {
3337 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3338 ctx.in_table("FeatureLookups", |ctx| {
3339 ctx.in_field("lookup_condition_records", |ctx| {
3340 if self.lookup_condition_records.len() > to_usize(u32::MAX) {
3341 ctx.report("array exceeds max length");
3342 }
3343 self.lookup_condition_records.validate_impl(ctx);
3344 });
3345 })
3346 }
3347}
3348
3349impl<'a> FromObjRef<read_fonts::tables::layout::FeatureLookups<'a>> for FeatureLookups {
3350 fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureLookups<'a>, _: FontData) -> Self {
3351 let offset_data = obj.offset_data();
3352 FeatureLookups {
3353 flags: obj.flags(),
3354 lookup_condition_records: obj.lookup_condition_records().to_owned_obj(offset_data),
3355 }
3356 }
3357}
3358
3359#[allow(clippy::needless_lifetimes)]
3360impl<'a> FromTableRef<read_fonts::tables::layout::FeatureLookups<'a>> for FeatureLookups {}
3361
3362impl ReadArgs for FeatureLookups {
3363 type Args = ();
3364}
3365
3366impl<'a> FontRead<'a> for FeatureLookups {
3367 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3368 <read_fonts::tables::layout::FeatureLookups as FontRead>::read(data)
3369 .map(|x| x.to_owned_table())
3370 }
3371}
3372
3373impl FontWrite for FeatureLookupsFlags {
3374 fn write_into(&self, writer: &mut TableWriter) {
3375 writer.write_slice(&self.bits().to_be_bytes())
3376 }
3377}
3378
3379#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3381#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3382pub struct LookupConditionRecord {
3383 pub condition: NullableOffsetMarker<Condition, WIDTH_32>,
3385 pub lookup_index_list: OffsetMarker<LookupIndexList, WIDTH_32>,
3387}
3388
3389impl LookupConditionRecord {
3390 pub fn new(condition: Option<Condition>, lookup_index_list: LookupIndexList) -> Self {
3392 Self {
3393 condition: condition.into(),
3394 lookup_index_list: lookup_index_list.into(),
3395 }
3396 }
3397}
3398
3399impl FontWrite for LookupConditionRecord {
3400 fn write_into(&self, writer: &mut TableWriter) {
3401 self.condition.write_into(writer);
3402 self.lookup_index_list.write_into(writer);
3403 }
3404 fn table_type(&self) -> TableType {
3405 TableType::Named("LookupConditionRecord")
3406 }
3407}
3408
3409impl Validate for LookupConditionRecord {
3410 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3411 ctx.in_table("LookupConditionRecord", |ctx| {
3412 ctx.in_field("condition", |ctx| {
3413 self.condition.validate_impl(ctx);
3414 });
3415 ctx.in_field("lookup_index_list", |ctx| {
3416 self.lookup_index_list.validate_impl(ctx);
3417 });
3418 })
3419 }
3420}
3421
3422impl FromObjRef<read_fonts::tables::layout::LookupConditionRecord> for LookupConditionRecord {
3423 fn from_obj_ref(
3424 obj: &read_fonts::tables::layout::LookupConditionRecord,
3425 offset_data: FontData,
3426 ) -> Self {
3427 LookupConditionRecord {
3428 condition: obj.condition(offset_data).to_owned_table(),
3429 lookup_index_list: obj.lookup_index_list(offset_data).to_owned_table(),
3430 }
3431 }
3432}
3433
3434#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3436#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3437pub struct LookupIndexList {
3438 pub lookup_indices: Vec<u16>,
3439}
3440
3441impl LookupIndexList {
3442 pub fn new(lookup_indices: Vec<u16>) -> Self {
3444 Self { lookup_indices }
3445 }
3446}
3447
3448impl FontWrite for LookupIndexList {
3449 #[allow(clippy::unnecessary_cast)]
3450 fn write_into(&self, writer: &mut TableWriter) {
3451 (u16::try_from(array_len(&self.lookup_indices)).unwrap()).write_into(writer);
3452 self.lookup_indices.write_into(writer);
3453 }
3454 fn table_type(&self) -> TableType {
3455 TableType::Named("LookupIndexList")
3456 }
3457}
3458
3459impl Validate for LookupIndexList {
3460 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3461 ctx.in_table("LookupIndexList", |ctx| {
3462 ctx.in_field("lookup_indices", |ctx| {
3463 if self.lookup_indices.len() > to_usize(u16::MAX) {
3464 ctx.report("array exceeds max length");
3465 }
3466 });
3467 })
3468 }
3469}
3470
3471impl<'a> FromObjRef<read_fonts::tables::layout::LookupIndexList<'a>> for LookupIndexList {
3472 fn from_obj_ref(obj: &read_fonts::tables::layout::LookupIndexList<'a>, _: FontData) -> Self {
3473 let offset_data = obj.offset_data();
3474 LookupIndexList {
3475 lookup_indices: obj.lookup_indices().to_owned_obj(offset_data),
3476 }
3477 }
3478}
3479
3480#[allow(clippy::needless_lifetimes)]
3481impl<'a> FromTableRef<read_fonts::tables::layout::LookupIndexList<'a>> for LookupIndexList {}
3482
3483impl ReadArgs for LookupIndexList {
3484 type Args = ();
3485}
3486
3487impl<'a> FontRead<'a> for LookupIndexList {
3488 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3489 <read_fonts::tables::layout::LookupIndexList as FontRead>::read(data)
3490 .map(|x| x.to_owned_table())
3491 }
3492}
3493
3494#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3496#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3497pub struct ConditionSet {
3498 pub conditions: Vec<OffsetMarker<Condition, WIDTH_32>>,
3501}
3502
3503impl ConditionSet {
3504 pub fn new(conditions: Vec<Condition>) -> Self {
3506 Self {
3507 conditions: conditions.into_iter().map(Into::into).collect(),
3508 }
3509 }
3510}
3511
3512impl FontWrite for ConditionSet {
3513 #[allow(clippy::unnecessary_cast)]
3514 fn write_into(&self, writer: &mut TableWriter) {
3515 (u16::try_from(array_len(&self.conditions)).unwrap()).write_into(writer);
3516 self.conditions.write_into(writer);
3517 }
3518 fn table_type(&self) -> TableType {
3519 TableType::Named("ConditionSet")
3520 }
3521}
3522
3523impl Validate for ConditionSet {
3524 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3525 ctx.in_table("ConditionSet", |ctx| {
3526 ctx.in_field("conditions", |ctx| {
3527 if self.conditions.len() > to_usize(u16::MAX) {
3528 ctx.report("array exceeds max length");
3529 }
3530 self.conditions.validate_impl(ctx);
3531 });
3532 })
3533 }
3534}
3535
3536impl<'a> FromObjRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet {
3537 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionSet<'a>, _: FontData) -> Self {
3538 ConditionSet {
3539 conditions: obj.conditions().to_owned_table(),
3540 }
3541 }
3542}
3543
3544#[allow(clippy::needless_lifetimes)]
3545impl<'a> FromTableRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet {}
3546
3547impl ReadArgs for ConditionSet {
3548 type Args = ();
3549}
3550
3551impl<'a> FontRead<'a> for ConditionSet {
3552 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3553 <read_fonts::tables::layout::ConditionSet as FontRead>::read(data)
3554 .map(|x| x.to_owned_table())
3555 }
3556}
3557
3558#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
3562#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3563pub enum Condition {
3564 Format1AxisRange(ConditionFormat1),
3565 Format2VariableValue(ConditionFormat2),
3566 Format3And(ConditionFormat3),
3567 Format4Or(ConditionFormat4),
3568 Format5Negate(ConditionFormat5),
3569}
3570
3571impl Condition {
3572 pub fn format_1_axis_range(
3574 axis_index: u16,
3575 filter_range_min_value: F2Dot14,
3576 filter_range_max_value: F2Dot14,
3577 ) -> Self {
3578 Self::Format1AxisRange(ConditionFormat1::new(
3579 axis_index,
3580 filter_range_min_value,
3581 filter_range_max_value,
3582 ))
3583 }
3584
3585 pub fn format_2_variable_value(default_value: i16, var_index: u32) -> Self {
3587 Self::Format2VariableValue(ConditionFormat2::new(default_value, var_index))
3588 }
3589
3590 pub fn format_3_and(condition_count: u8, conditions: Vec<Condition>) -> Self {
3592 Self::Format3And(ConditionFormat3::new(condition_count, conditions))
3593 }
3594
3595 pub fn format_4_or(condition_count: u8, conditions: Vec<Condition>) -> Self {
3597 Self::Format4Or(ConditionFormat4::new(condition_count, conditions))
3598 }
3599
3600 pub fn format_5_negate(condition: Condition) -> Self {
3602 Self::Format5Negate(ConditionFormat5::new(condition))
3603 }
3604}
3605
3606impl Default for Condition {
3607 fn default() -> Self {
3608 Self::Format1AxisRange(Default::default())
3609 }
3610}
3611
3612impl FontWrite for Condition {
3613 fn write_into(&self, writer: &mut TableWriter) {
3614 match self {
3615 Self::Format1AxisRange(item) => item.write_into(writer),
3616 Self::Format2VariableValue(item) => item.write_into(writer),
3617 Self::Format3And(item) => item.write_into(writer),
3618 Self::Format4Or(item) => item.write_into(writer),
3619 Self::Format5Negate(item) => item.write_into(writer),
3620 }
3621 }
3622 fn table_type(&self) -> TableType {
3623 match self {
3624 Self::Format1AxisRange(item) => item.table_type(),
3625 Self::Format2VariableValue(item) => item.table_type(),
3626 Self::Format3And(item) => item.table_type(),
3627 Self::Format4Or(item) => item.table_type(),
3628 Self::Format5Negate(item) => item.table_type(),
3629 }
3630 }
3631}
3632
3633impl Validate for Condition {
3634 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3635 match self {
3636 Self::Format1AxisRange(item) => item.validate_impl(ctx),
3637 Self::Format2VariableValue(item) => item.validate_impl(ctx),
3638 Self::Format3And(item) => item.validate_impl(ctx),
3639 Self::Format4Or(item) => item.validate_impl(ctx),
3640 Self::Format5Negate(item) => item.validate_impl(ctx),
3641 }
3642 }
3643}
3644
3645impl FromObjRef<read_fonts::tables::layout::Condition<'_>> for Condition {
3646 fn from_obj_ref(obj: &read_fonts::tables::layout::Condition, _: FontData) -> Self {
3647 use read_fonts::tables::layout::Condition as ObjRefType;
3648 match obj {
3649 ObjRefType::Format1AxisRange(item) => {
3650 Condition::Format1AxisRange(item.to_owned_table())
3651 }
3652 ObjRefType::Format2VariableValue(item) => {
3653 Condition::Format2VariableValue(item.to_owned_table())
3654 }
3655 ObjRefType::Format3And(item) => Condition::Format3And(item.to_owned_table()),
3656 ObjRefType::Format4Or(item) => Condition::Format4Or(item.to_owned_table()),
3657 ObjRefType::Format5Negate(item) => Condition::Format5Negate(item.to_owned_table()),
3658 }
3659 }
3660}
3661
3662impl FromTableRef<read_fonts::tables::layout::Condition<'_>> for Condition {}
3663
3664impl ReadArgs for Condition {
3665 type Args = ();
3666}
3667
3668impl<'a> FontRead<'a> for Condition {
3669 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3670 <read_fonts::tables::layout::Condition as FontRead>::read(data).map(|x| x.to_owned_table())
3671 }
3672}
3673
3674impl From<ConditionFormat1> for Condition {
3675 fn from(src: ConditionFormat1) -> Condition {
3676 Condition::Format1AxisRange(src)
3677 }
3678}
3679
3680impl From<ConditionFormat2> for Condition {
3681 fn from(src: ConditionFormat2) -> Condition {
3682 Condition::Format2VariableValue(src)
3683 }
3684}
3685
3686impl From<ConditionFormat3> for Condition {
3687 fn from(src: ConditionFormat3) -> Condition {
3688 Condition::Format3And(src)
3689 }
3690}
3691
3692impl From<ConditionFormat4> for Condition {
3693 fn from(src: ConditionFormat4) -> Condition {
3694 Condition::Format4Or(src)
3695 }
3696}
3697
3698impl From<ConditionFormat5> for Condition {
3699 fn from(src: ConditionFormat5) -> Condition {
3700 Condition::Format5Negate(src)
3701 }
3702}
3703
3704#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3706#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3707pub struct ConditionFormat1 {
3708 pub axis_index: u16,
3711 pub filter_range_min_value: F2Dot14,
3714 pub filter_range_max_value: F2Dot14,
3717}
3718
3719impl ConditionFormat1 {
3720 pub fn new(
3722 axis_index: u16,
3723 filter_range_min_value: F2Dot14,
3724 filter_range_max_value: F2Dot14,
3725 ) -> Self {
3726 Self {
3727 axis_index,
3728 filter_range_min_value,
3729 filter_range_max_value,
3730 }
3731 }
3732}
3733
3734impl FontWrite for ConditionFormat1 {
3735 #[allow(clippy::unnecessary_cast)]
3736 fn write_into(&self, writer: &mut TableWriter) {
3737 (1 as u16).write_into(writer);
3738 self.axis_index.write_into(writer);
3739 self.filter_range_min_value.write_into(writer);
3740 self.filter_range_max_value.write_into(writer);
3741 }
3742 fn table_type(&self) -> TableType {
3743 TableType::Named("ConditionFormat1")
3744 }
3745}
3746
3747impl Validate for ConditionFormat1 {
3748 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3749}
3750
3751impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 {
3752 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat1<'a>, _: FontData) -> Self {
3753 ConditionFormat1 {
3754 axis_index: obj.axis_index(),
3755 filter_range_min_value: obj.filter_range_min_value(),
3756 filter_range_max_value: obj.filter_range_max_value(),
3757 }
3758 }
3759}
3760
3761#[allow(clippy::needless_lifetimes)]
3762impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 {}
3763
3764impl ReadArgs for ConditionFormat1 {
3765 type Args = ();
3766}
3767
3768impl<'a> FontRead<'a> for ConditionFormat1 {
3769 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3770 <read_fonts::tables::layout::ConditionFormat1 as FontRead>::read(data)
3771 .map(|x| x.to_owned_table())
3772 }
3773}
3774
3775#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3777#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3778pub struct ConditionFormat2 {
3779 pub default_value: i16,
3781 pub var_index: u32,
3783}
3784
3785impl ConditionFormat2 {
3786 pub fn new(default_value: i16, var_index: u32) -> Self {
3788 Self {
3789 default_value,
3790 var_index,
3791 }
3792 }
3793}
3794
3795impl FontWrite for ConditionFormat2 {
3796 #[allow(clippy::unnecessary_cast)]
3797 fn write_into(&self, writer: &mut TableWriter) {
3798 (2 as u16).write_into(writer);
3799 self.default_value.write_into(writer);
3800 self.var_index.write_into(writer);
3801 }
3802 fn table_type(&self) -> TableType {
3803 TableType::Named("ConditionFormat2")
3804 }
3805}
3806
3807impl Validate for ConditionFormat2 {
3808 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
3809}
3810
3811impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 {
3812 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat2<'a>, _: FontData) -> Self {
3813 ConditionFormat2 {
3814 default_value: obj.default_value(),
3815 var_index: obj.var_index(),
3816 }
3817 }
3818}
3819
3820#[allow(clippy::needless_lifetimes)]
3821impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 {}
3822
3823impl ReadArgs for ConditionFormat2 {
3824 type Args = ();
3825}
3826
3827impl<'a> FontRead<'a> for ConditionFormat2 {
3828 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3829 <read_fonts::tables::layout::ConditionFormat2 as FontRead>::read(data)
3830 .map(|x| x.to_owned_table())
3831 }
3832}
3833
3834#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3836#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3837pub struct ConditionFormat3 {
3838 pub condition_count: u8,
3840 pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>,
3842}
3843
3844impl ConditionFormat3 {
3845 pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self {
3847 Self {
3848 condition_count,
3849 conditions: conditions.into_iter().map(Into::into).collect(),
3850 }
3851 }
3852}
3853
3854impl FontWrite for ConditionFormat3 {
3855 #[allow(clippy::unnecessary_cast)]
3856 fn write_into(&self, writer: &mut TableWriter) {
3857 (3 as u16).write_into(writer);
3858 self.condition_count.write_into(writer);
3859 self.conditions.write_into(writer);
3860 }
3861 fn table_type(&self) -> TableType {
3862 TableType::Named("ConditionFormat3")
3863 }
3864}
3865
3866impl Validate for ConditionFormat3 {
3867 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3868 ctx.in_table("ConditionFormat3", |ctx| {
3869 ctx.in_field("conditions", |ctx| {
3870 if self.conditions.len() > to_usize(u8::MAX) {
3871 ctx.report("array exceeds max length");
3872 }
3873 self.conditions.validate_impl(ctx);
3874 });
3875 })
3876 }
3877}
3878
3879impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 {
3880 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat3<'a>, _: FontData) -> Self {
3881 ConditionFormat3 {
3882 condition_count: obj.condition_count(),
3883 conditions: obj.conditions().to_owned_table(),
3884 }
3885 }
3886}
3887
3888#[allow(clippy::needless_lifetimes)]
3889impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 {}
3890
3891impl ReadArgs for ConditionFormat3 {
3892 type Args = ();
3893}
3894
3895impl<'a> FontRead<'a> for ConditionFormat3 {
3896 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3897 <read_fonts::tables::layout::ConditionFormat3 as FontRead>::read(data)
3898 .map(|x| x.to_owned_table())
3899 }
3900}
3901
3902#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3904#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3905pub struct ConditionFormat4 {
3906 pub condition_count: u8,
3908 pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>,
3910}
3911
3912impl ConditionFormat4 {
3913 pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self {
3915 Self {
3916 condition_count,
3917 conditions: conditions.into_iter().map(Into::into).collect(),
3918 }
3919 }
3920}
3921
3922impl FontWrite for ConditionFormat4 {
3923 #[allow(clippy::unnecessary_cast)]
3924 fn write_into(&self, writer: &mut TableWriter) {
3925 (4 as u16).write_into(writer);
3926 self.condition_count.write_into(writer);
3927 self.conditions.write_into(writer);
3928 }
3929 fn table_type(&self) -> TableType {
3930 TableType::Named("ConditionFormat4")
3931 }
3932}
3933
3934impl Validate for ConditionFormat4 {
3935 fn validate_impl(&self, ctx: &mut ValidationCtx) {
3936 ctx.in_table("ConditionFormat4", |ctx| {
3937 ctx.in_field("conditions", |ctx| {
3938 if self.conditions.len() > to_usize(u8::MAX) {
3939 ctx.report("array exceeds max length");
3940 }
3941 self.conditions.validate_impl(ctx);
3942 });
3943 })
3944 }
3945}
3946
3947impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 {
3948 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat4<'a>, _: FontData) -> Self {
3949 ConditionFormat4 {
3950 condition_count: obj.condition_count(),
3951 conditions: obj.conditions().to_owned_table(),
3952 }
3953 }
3954}
3955
3956#[allow(clippy::needless_lifetimes)]
3957impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 {}
3958
3959impl ReadArgs for ConditionFormat4 {
3960 type Args = ();
3961}
3962
3963impl<'a> FontRead<'a> for ConditionFormat4 {
3964 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
3965 <read_fonts::tables::layout::ConditionFormat4 as FontRead>::read(data)
3966 .map(|x| x.to_owned_table())
3967 }
3968}
3969
3970#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
3972#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3973pub struct ConditionFormat5 {
3974 pub condition: OffsetMarker<Condition, WIDTH_24>,
3976}
3977
3978impl ConditionFormat5 {
3979 pub fn new(condition: Condition) -> Self {
3981 Self {
3982 condition: condition.into(),
3983 }
3984 }
3985}
3986
3987impl FontWrite for ConditionFormat5 {
3988 #[allow(clippy::unnecessary_cast)]
3989 fn write_into(&self, writer: &mut TableWriter) {
3990 (5 as u16).write_into(writer);
3991 self.condition.write_into(writer);
3992 }
3993 fn table_type(&self) -> TableType {
3994 TableType::Named("ConditionFormat5")
3995 }
3996}
3997
3998impl Validate for ConditionFormat5 {
3999 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4000 ctx.in_table("ConditionFormat5", |ctx| {
4001 ctx.in_field("condition", |ctx| {
4002 self.condition.validate_impl(ctx);
4003 });
4004 })
4005 }
4006}
4007
4008impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 {
4009 fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat5<'a>, _: FontData) -> Self {
4010 ConditionFormat5 {
4011 condition: obj.condition().to_owned_table(),
4012 }
4013 }
4014}
4015
4016#[allow(clippy::needless_lifetimes)]
4017impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 {}
4018
4019impl ReadArgs for ConditionFormat5 {
4020 type Args = ();
4021}
4022
4023impl<'a> FontRead<'a> for ConditionFormat5 {
4024 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4025 <read_fonts::tables::layout::ConditionFormat5 as FontRead>::read(data)
4026 .map(|x| x.to_owned_table())
4027 }
4028}
4029
4030#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4032#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4033pub struct FeatureTableSubstitution {
4034 pub substitutions: Vec<FeatureTableSubstitutionRecord>,
4036}
4037
4038impl FeatureTableSubstitution {
4039 pub fn new(substitutions: Vec<FeatureTableSubstitutionRecord>) -> Self {
4041 Self { substitutions }
4042 }
4043}
4044
4045impl FontWrite for FeatureTableSubstitution {
4046 #[allow(clippy::unnecessary_cast)]
4047 fn write_into(&self, writer: &mut TableWriter) {
4048 (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer);
4049 (u16::try_from(array_len(&self.substitutions)).unwrap()).write_into(writer);
4050 self.substitutions.write_into(writer);
4051 }
4052 fn table_type(&self) -> TableType {
4053 TableType::Named("FeatureTableSubstitution")
4054 }
4055}
4056
4057impl Validate for FeatureTableSubstitution {
4058 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4059 ctx.in_table("FeatureTableSubstitution", |ctx| {
4060 ctx.in_field("substitutions", |ctx| {
4061 if self.substitutions.len() > to_usize(u16::MAX) {
4062 ctx.report("array exceeds max length");
4063 }
4064 self.substitutions.validate_impl(ctx);
4065 });
4066 })
4067 }
4068}
4069
4070impl<'a> FromObjRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>>
4071 for FeatureTableSubstitution
4072{
4073 fn from_obj_ref(
4074 obj: &read_fonts::tables::layout::FeatureTableSubstitution<'a>,
4075 _: FontData,
4076 ) -> Self {
4077 let offset_data = obj.offset_data();
4078 FeatureTableSubstitution {
4079 substitutions: obj.substitutions().to_owned_obj(offset_data),
4080 }
4081 }
4082}
4083
4084#[allow(clippy::needless_lifetimes)]
4085impl<'a> FromTableRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>>
4086 for FeatureTableSubstitution
4087{
4088}
4089
4090impl ReadArgs for FeatureTableSubstitution {
4091 type Args = ();
4092}
4093
4094impl<'a> FontRead<'a> for FeatureTableSubstitution {
4095 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4096 <read_fonts::tables::layout::FeatureTableSubstitution as FontRead>::read(data)
4097 .map(|x| x.to_owned_table())
4098 }
4099}
4100
4101#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4103#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4104pub struct FeatureTableSubstitutionRecord {
4105 pub feature_index: u16,
4107 pub alternate_feature: OffsetMarker<Feature, WIDTH_32>,
4110}
4111
4112impl FeatureTableSubstitutionRecord {
4113 pub fn new(feature_index: u16, alternate_feature: Feature) -> Self {
4115 Self {
4116 feature_index,
4117 alternate_feature: alternate_feature.into(),
4118 }
4119 }
4120}
4121
4122impl FontWrite for FeatureTableSubstitutionRecord {
4123 fn write_into(&self, writer: &mut TableWriter) {
4124 self.feature_index.write_into(writer);
4125 self.alternate_feature.write_into(writer);
4126 }
4127 fn table_type(&self) -> TableType {
4128 TableType::Named("FeatureTableSubstitutionRecord")
4129 }
4130}
4131
4132impl Validate for FeatureTableSubstitutionRecord {
4133 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4134 ctx.in_table("FeatureTableSubstitutionRecord", |ctx| {
4135 ctx.in_field("alternate_feature", |ctx| {
4136 self.alternate_feature.validate_impl(ctx);
4137 });
4138 })
4139 }
4140}
4141
4142impl FromObjRef<read_fonts::tables::layout::FeatureTableSubstitutionRecord>
4143 for FeatureTableSubstitutionRecord
4144{
4145 fn from_obj_ref(
4146 obj: &read_fonts::tables::layout::FeatureTableSubstitutionRecord,
4147 offset_data: FontData,
4148 ) -> Self {
4149 FeatureTableSubstitutionRecord {
4150 feature_index: obj.feature_index(),
4151 alternate_feature: obj.alternate_feature(offset_data).to_owned_table(),
4152 }
4153 }
4154}
4155
4156#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4158pub struct SizeParams {
4159 pub design_size: u16,
4164 pub identifier: u16,
4171 pub name_entry: u16,
4182 pub range_start: u16,
4188 pub range_end: u16,
4189}
4190
4191impl SizeParams {
4192 pub fn new(
4194 design_size: u16,
4195 identifier: u16,
4196 name_entry: u16,
4197 range_start: u16,
4198 range_end: u16,
4199 ) -> Self {
4200 Self {
4201 design_size,
4202 identifier,
4203 name_entry,
4204 range_start,
4205 range_end,
4206 }
4207 }
4208}
4209
4210impl FontWrite for SizeParams {
4211 fn write_into(&self, writer: &mut TableWriter) {
4212 self.design_size.write_into(writer);
4213 self.identifier.write_into(writer);
4214 self.name_entry.write_into(writer);
4215 self.range_start.write_into(writer);
4216 self.range_end.write_into(writer);
4217 }
4218 fn table_type(&self) -> TableType {
4219 TableType::Named("SizeParams")
4220 }
4221}
4222
4223impl Validate for SizeParams {
4224 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
4225}
4226
4227impl<'a> FromObjRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams {
4228 fn from_obj_ref(obj: &read_fonts::tables::layout::SizeParams<'a>, _: FontData) -> Self {
4229 SizeParams {
4230 design_size: obj.design_size(),
4231 identifier: obj.identifier(),
4232 name_entry: obj.name_entry(),
4233 range_start: obj.range_start(),
4234 range_end: obj.range_end(),
4235 }
4236 }
4237}
4238
4239#[allow(clippy::needless_lifetimes)]
4240impl<'a> FromTableRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams {}
4241
4242impl ReadArgs for SizeParams {
4243 type Args = ();
4244}
4245
4246impl<'a> FontRead<'a> for SizeParams {
4247 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4248 <read_fonts::tables::layout::SizeParams as FontRead>::read(data).map(|x| x.to_owned_table())
4249 }
4250}
4251
4252#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4253#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4254pub struct StylisticSetParams {
4255 pub ui_name_id: NameId,
4265}
4266
4267impl StylisticSetParams {
4268 pub fn new(ui_name_id: NameId) -> Self {
4270 Self { ui_name_id }
4271 }
4272}
4273
4274impl FontWrite for StylisticSetParams {
4275 #[allow(clippy::unnecessary_cast)]
4276 fn write_into(&self, writer: &mut TableWriter) {
4277 (0 as u16).write_into(writer);
4278 self.ui_name_id.write_into(writer);
4279 }
4280 fn table_type(&self) -> TableType {
4281 TableType::Named("StylisticSetParams")
4282 }
4283}
4284
4285impl Validate for StylisticSetParams {
4286 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
4287}
4288
4289impl<'a> FromObjRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams {
4290 fn from_obj_ref(obj: &read_fonts::tables::layout::StylisticSetParams<'a>, _: FontData) -> Self {
4291 StylisticSetParams {
4292 ui_name_id: obj.ui_name_id(),
4293 }
4294 }
4295}
4296
4297#[allow(clippy::needless_lifetimes)]
4298impl<'a> FromTableRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams {}
4299
4300impl ReadArgs for StylisticSetParams {
4301 type Args = ();
4302}
4303
4304impl<'a> FontRead<'a> for StylisticSetParams {
4305 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4306 <read_fonts::tables::layout::StylisticSetParams as FontRead>::read(data)
4307 .map(|x| x.to_owned_table())
4308 }
4309}
4310
4311#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4313#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4314pub struct CharacterVariantParams {
4315 pub feat_ui_label_name_id: NameId,
4319 pub feat_ui_tooltip_text_name_id: NameId,
4323 pub sample_text_name_id: NameId,
4326 pub num_named_parameters: u16,
4328 pub first_param_ui_label_name_id: NameId,
4332 pub character: Vec<Uint24>,
4335}
4336
4337impl CharacterVariantParams {
4338 pub fn new(
4340 feat_ui_label_name_id: NameId,
4341 feat_ui_tooltip_text_name_id: NameId,
4342 sample_text_name_id: NameId,
4343 num_named_parameters: u16,
4344 first_param_ui_label_name_id: NameId,
4345 character: Vec<Uint24>,
4346 ) -> Self {
4347 Self {
4348 feat_ui_label_name_id,
4349 feat_ui_tooltip_text_name_id,
4350 sample_text_name_id,
4351 num_named_parameters,
4352 first_param_ui_label_name_id,
4353 character,
4354 }
4355 }
4356}
4357
4358impl FontWrite for CharacterVariantParams {
4359 #[allow(clippy::unnecessary_cast)]
4360 fn write_into(&self, writer: &mut TableWriter) {
4361 (0 as u16).write_into(writer);
4362 self.feat_ui_label_name_id.write_into(writer);
4363 self.feat_ui_tooltip_text_name_id.write_into(writer);
4364 self.sample_text_name_id.write_into(writer);
4365 self.num_named_parameters.write_into(writer);
4366 self.first_param_ui_label_name_id.write_into(writer);
4367 (u16::try_from(array_len(&self.character)).unwrap()).write_into(writer);
4368 self.character.write_into(writer);
4369 }
4370 fn table_type(&self) -> TableType {
4371 TableType::Named("CharacterVariantParams")
4372 }
4373}
4374
4375impl Validate for CharacterVariantParams {
4376 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4377 ctx.in_table("CharacterVariantParams", |ctx| {
4378 ctx.in_field("character", |ctx| {
4379 if self.character.len() > to_usize(u16::MAX) {
4380 ctx.report("array exceeds max length");
4381 }
4382 });
4383 })
4384 }
4385}
4386
4387impl<'a> FromObjRef<read_fonts::tables::layout::CharacterVariantParams<'a>>
4388 for CharacterVariantParams
4389{
4390 fn from_obj_ref(
4391 obj: &read_fonts::tables::layout::CharacterVariantParams<'a>,
4392 _: FontData,
4393 ) -> Self {
4394 let offset_data = obj.offset_data();
4395 CharacterVariantParams {
4396 feat_ui_label_name_id: obj.feat_ui_label_name_id(),
4397 feat_ui_tooltip_text_name_id: obj.feat_ui_tooltip_text_name_id(),
4398 sample_text_name_id: obj.sample_text_name_id(),
4399 num_named_parameters: obj.num_named_parameters(),
4400 first_param_ui_label_name_id: obj.first_param_ui_label_name_id(),
4401 character: obj.character().to_owned_obj(offset_data),
4402 }
4403 }
4404}
4405
4406#[allow(clippy::needless_lifetimes)]
4407impl<'a> FromTableRef<read_fonts::tables::layout::CharacterVariantParams<'a>>
4408 for CharacterVariantParams
4409{
4410}
4411
4412impl ReadArgs for CharacterVariantParams {
4413 type Args = ();
4414}
4415
4416impl<'a> FontRead<'a> for CharacterVariantParams {
4417 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4418 <read_fonts::tables::layout::CharacterVariantParams as FontRead>::read(data)
4419 .map(|x| x.to_owned_table())
4420 }
4421}
4422
4423#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4425#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4426pub struct CoverageFormat3 {
4427 pub glyph_array: Vec<GlyphId24>,
4429}
4430
4431impl CoverageFormat3 {
4432 pub fn new(glyph_array: Vec<GlyphId24>) -> Self {
4434 Self { glyph_array }
4435 }
4436}
4437
4438impl FontWrite for CoverageFormat3 {
4439 #[allow(clippy::unnecessary_cast)]
4440 fn write_into(&self, writer: &mut TableWriter) {
4441 (3 as u16).write_into(writer);
4442 (Uint24::try_from(array_len(&self.glyph_array)).unwrap()).write_into(writer);
4443 self.glyph_array.write_into(writer);
4444 }
4445 fn table_type(&self) -> TableType {
4446 TableType::Named("CoverageFormat3")
4447 }
4448}
4449
4450impl Validate for CoverageFormat3 {
4451 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4452 ctx.in_table("CoverageFormat3", |ctx| {
4453 ctx.in_field("glyph_array", |ctx| {
4454 if self.glyph_array.len() > to_usize(Uint24::MAX) {
4455 ctx.report("array exceeds max length");
4456 }
4457 });
4458 })
4459 }
4460}
4461
4462impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat3<'a>> for CoverageFormat3 {
4463 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat3<'a>, _: FontData) -> Self {
4464 let offset_data = obj.offset_data();
4465 CoverageFormat3 {
4466 glyph_array: obj.glyph_array().to_owned_obj(offset_data),
4467 }
4468 }
4469}
4470
4471#[allow(clippy::needless_lifetimes)]
4472impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat3<'a>> for CoverageFormat3 {}
4473
4474impl ReadArgs for CoverageFormat3 {
4475 type Args = ();
4476}
4477
4478impl<'a> FontRead<'a> for CoverageFormat3 {
4479 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4480 <read_fonts::tables::layout::CoverageFormat3 as FontRead>::read(data)
4481 .map(|x| x.to_owned_table())
4482 }
4483}
4484
4485#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4487#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4488pub struct CoverageFormat4 {
4489 pub range_records: Vec<RangeRecord2>,
4491}
4492
4493impl CoverageFormat4 {
4494 pub fn new(range_records: Vec<RangeRecord2>) -> Self {
4496 Self { range_records }
4497 }
4498}
4499
4500impl FontWrite for CoverageFormat4 {
4501 #[allow(clippy::unnecessary_cast)]
4502 fn write_into(&self, writer: &mut TableWriter) {
4503 (4 as u16).write_into(writer);
4504 (Uint24::try_from(array_len(&self.range_records)).unwrap()).write_into(writer);
4505 self.range_records.write_into(writer);
4506 }
4507 fn table_type(&self) -> TableType {
4508 TableType::Named("CoverageFormat4")
4509 }
4510}
4511
4512impl Validate for CoverageFormat4 {
4513 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4514 ctx.in_table("CoverageFormat4", |ctx| {
4515 ctx.in_field("range_records", |ctx| {
4516 if self.range_records.len() > to_usize(Uint24::MAX) {
4517 ctx.report("array exceeds max length");
4518 }
4519 self.range_records.validate_impl(ctx);
4520 });
4521 })
4522 }
4523}
4524
4525impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat4<'a>> for CoverageFormat4 {
4526 fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat4<'a>, _: FontData) -> Self {
4527 let offset_data = obj.offset_data();
4528 CoverageFormat4 {
4529 range_records: obj.range_records().to_owned_obj(offset_data),
4530 }
4531 }
4532}
4533
4534#[allow(clippy::needless_lifetimes)]
4535impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat4<'a>> for CoverageFormat4 {}
4536
4537impl ReadArgs for CoverageFormat4 {
4538 type Args = ();
4539}
4540
4541impl<'a> FontRead<'a> for CoverageFormat4 {
4542 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4543 <read_fonts::tables::layout::CoverageFormat4 as FontRead>::read(data)
4544 .map(|x| x.to_owned_table())
4545 }
4546}
4547
4548#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4550#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4551pub struct RangeRecord2 {
4552 pub start_glyph_id: GlyphId24,
4554 pub end_glyph_id: GlyphId24,
4556 pub start_coverage_index: Uint24,
4558}
4559
4560impl RangeRecord2 {
4561 pub fn new(
4563 start_glyph_id: GlyphId24,
4564 end_glyph_id: GlyphId24,
4565 start_coverage_index: Uint24,
4566 ) -> Self {
4567 Self {
4568 start_glyph_id,
4569 end_glyph_id,
4570 start_coverage_index,
4571 }
4572 }
4573}
4574
4575impl FontWrite for RangeRecord2 {
4576 fn write_into(&self, writer: &mut TableWriter) {
4577 self.start_glyph_id.write_into(writer);
4578 self.end_glyph_id.write_into(writer);
4579 self.start_coverage_index.write_into(writer);
4580 }
4581 fn table_type(&self) -> TableType {
4582 TableType::Named("RangeRecord2")
4583 }
4584}
4585
4586impl Validate for RangeRecord2 {
4587 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
4588}
4589
4590impl FromObjRef<read_fonts::tables::layout::RangeRecord2> for RangeRecord2 {
4591 fn from_obj_ref(obj: &read_fonts::tables::layout::RangeRecord2, _: FontData) -> Self {
4592 RangeRecord2 {
4593 start_glyph_id: obj.start_glyph_id(),
4594 end_glyph_id: obj.end_glyph_id(),
4595 start_coverage_index: obj.start_coverage_index(),
4596 }
4597 }
4598}
4599
4600#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4602#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4603pub struct ClassDefFormat3 {
4604 pub start_glyph_id: GlyphId24,
4606 pub class_value_array: Vec<Uint24>,
4608}
4609
4610impl ClassDefFormat3 {
4611 pub fn new(start_glyph_id: GlyphId24, class_value_array: Vec<Uint24>) -> Self {
4613 Self {
4614 start_glyph_id,
4615 class_value_array,
4616 }
4617 }
4618}
4619
4620impl FontWrite for ClassDefFormat3 {
4621 #[allow(clippy::unnecessary_cast)]
4622 fn write_into(&self, writer: &mut TableWriter) {
4623 (3 as u16).write_into(writer);
4624 self.start_glyph_id.write_into(writer);
4625 (Uint24::try_from(array_len(&self.class_value_array)).unwrap()).write_into(writer);
4626 self.class_value_array.write_into(writer);
4627 }
4628 fn table_type(&self) -> TableType {
4629 TableType::Named("ClassDefFormat3")
4630 }
4631}
4632
4633impl Validate for ClassDefFormat3 {
4634 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4635 ctx.in_table("ClassDefFormat3", |ctx| {
4636 ctx.in_field("class_value_array", |ctx| {
4637 if self.class_value_array.len() > to_usize(Uint24::MAX) {
4638 ctx.report("array exceeds max length");
4639 }
4640 });
4641 })
4642 }
4643}
4644
4645impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat3<'a>> for ClassDefFormat3 {
4646 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat3<'a>, _: FontData) -> Self {
4647 let offset_data = obj.offset_data();
4648 ClassDefFormat3 {
4649 start_glyph_id: obj.start_glyph_id(),
4650 class_value_array: obj.class_value_array().to_owned_obj(offset_data),
4651 }
4652 }
4653}
4654
4655#[allow(clippy::needless_lifetimes)]
4656impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat3<'a>> for ClassDefFormat3 {}
4657
4658impl ReadArgs for ClassDefFormat3 {
4659 type Args = ();
4660}
4661
4662impl<'a> FontRead<'a> for ClassDefFormat3 {
4663 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4664 <read_fonts::tables::layout::ClassDefFormat3 as FontRead>::read(data)
4665 .map(|x| x.to_owned_table())
4666 }
4667}
4668
4669#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4671#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4672pub struct ClassDefFormat4 {
4673 pub class_range_records: Vec<ClassRangeRecord2>,
4675}
4676
4677impl ClassDefFormat4 {
4678 pub fn new(class_range_records: Vec<ClassRangeRecord2>) -> Self {
4680 Self {
4681 class_range_records,
4682 }
4683 }
4684}
4685
4686impl FontWrite for ClassDefFormat4 {
4687 #[allow(clippy::unnecessary_cast)]
4688 fn write_into(&self, writer: &mut TableWriter) {
4689 (4 as u16).write_into(writer);
4690 (Uint24::try_from(array_len(&self.class_range_records)).unwrap()).write_into(writer);
4691 self.class_range_records.write_into(writer);
4692 }
4693 fn table_type(&self) -> TableType {
4694 TableType::Named("ClassDefFormat4")
4695 }
4696}
4697
4698impl Validate for ClassDefFormat4 {
4699 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4700 ctx.in_table("ClassDefFormat4", |ctx| {
4701 ctx.in_field("class_range_records", |ctx| {
4702 if self.class_range_records.len() > to_usize(Uint24::MAX) {
4703 ctx.report("array exceeds max length");
4704 }
4705 self.class_range_records.validate_impl(ctx);
4706 });
4707 })
4708 }
4709}
4710
4711impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat4<'a>> for ClassDefFormat4 {
4712 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat4<'a>, _: FontData) -> Self {
4713 let offset_data = obj.offset_data();
4714 ClassDefFormat4 {
4715 class_range_records: obj.class_range_records().to_owned_obj(offset_data),
4716 }
4717 }
4718}
4719
4720#[allow(clippy::needless_lifetimes)]
4721impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat4<'a>> for ClassDefFormat4 {}
4722
4723impl ReadArgs for ClassDefFormat4 {
4724 type Args = ();
4725}
4726
4727impl<'a> FontRead<'a> for ClassDefFormat4 {
4728 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4729 <read_fonts::tables::layout::ClassDefFormat4 as FontRead>::read(data)
4730 .map(|x| x.to_owned_table())
4731 }
4732}
4733
4734#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4736#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4737pub struct ClassRangeRecord2 {
4738 pub start_glyph_id: GlyphId24,
4740 pub end_glyph_id: GlyphId24,
4742 pub class: u16,
4744}
4745
4746impl ClassRangeRecord2 {
4747 pub fn new(start_glyph_id: GlyphId24, end_glyph_id: GlyphId24, class: u16) -> Self {
4749 Self {
4750 start_glyph_id,
4751 end_glyph_id,
4752 class,
4753 }
4754 }
4755}
4756
4757impl FontWrite for ClassRangeRecord2 {
4758 fn write_into(&self, writer: &mut TableWriter) {
4759 self.start_glyph_id.write_into(writer);
4760 self.end_glyph_id.write_into(writer);
4761 self.class.write_into(writer);
4762 }
4763 fn table_type(&self) -> TableType {
4764 TableType::Named("ClassRangeRecord2")
4765 }
4766}
4767
4768impl Validate for ClassRangeRecord2 {
4769 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4770 ctx.in_table("ClassRangeRecord2", |ctx| {
4771 ctx.in_field("start_glyph_id", |ctx| {
4772 self.validate_glyph_range(ctx);
4773 });
4774 })
4775 }
4776}
4777
4778impl FromObjRef<read_fonts::tables::layout::ClassRangeRecord2> for ClassRangeRecord2 {
4779 fn from_obj_ref(obj: &read_fonts::tables::layout::ClassRangeRecord2, _: FontData) -> Self {
4780 ClassRangeRecord2 {
4781 start_glyph_id: obj.start_glyph_id(),
4782 end_glyph_id: obj.end_glyph_id(),
4783 class: obj.class(),
4784 }
4785 }
4786}
4787
4788#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4790#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4791pub struct SequenceContextFormat4 {
4792 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
4795 pub seq_rule_sets: Vec<NullableOffsetMarker<SequenceRuleSet2, WIDTH_24>>,
4798}
4799
4800impl SequenceContextFormat4 {
4801 pub fn new(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet2>>) -> Self {
4803 Self {
4804 coverage: coverage.into(),
4805 seq_rule_sets: seq_rule_sets.into_iter().map(Into::into).collect(),
4806 }
4807 }
4808}
4809
4810impl FontWrite for SequenceContextFormat4 {
4811 #[allow(clippy::unnecessary_cast)]
4812 fn write_into(&self, writer: &mut TableWriter) {
4813 (4 as u16).write_into(writer);
4814 self.coverage.write_into(writer);
4815 (Uint24::try_from(array_len(&self.seq_rule_sets)).unwrap()).write_into(writer);
4816 self.seq_rule_sets.write_into(writer);
4817 }
4818 fn table_type(&self) -> TableType {
4819 TableType::Named("SequenceContextFormat4")
4820 }
4821}
4822
4823impl Validate for SequenceContextFormat4 {
4824 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4825 ctx.in_table("SequenceContextFormat4", |ctx| {
4826 ctx.in_field("coverage", |ctx| {
4827 self.coverage.validate_impl(ctx);
4828 });
4829 ctx.in_field("seq_rule_sets", |ctx| {
4830 if self.seq_rule_sets.len() > to_usize(Uint24::MAX) {
4831 ctx.report("array exceeds max length");
4832 }
4833 self.seq_rule_sets.validate_impl(ctx);
4834 });
4835 })
4836 }
4837}
4838
4839impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat4<'a>>
4840 for SequenceContextFormat4
4841{
4842 fn from_obj_ref(
4843 obj: &read_fonts::tables::layout::SequenceContextFormat4<'a>,
4844 _: FontData,
4845 ) -> Self {
4846 SequenceContextFormat4 {
4847 coverage: obj.coverage().to_owned_table(),
4848 seq_rule_sets: obj.seq_rule_sets().to_owned_table(),
4849 }
4850 }
4851}
4852
4853#[allow(clippy::needless_lifetimes)]
4854impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat4<'a>>
4855 for SequenceContextFormat4
4856{
4857}
4858
4859impl ReadArgs for SequenceContextFormat4 {
4860 type Args = ();
4861}
4862
4863impl<'a> FontRead<'a> for SequenceContextFormat4 {
4864 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4865 <read_fonts::tables::layout::SequenceContextFormat4 as FontRead>::read(data)
4866 .map(|x| x.to_owned_table())
4867 }
4868}
4869
4870#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4872#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4873pub struct SequenceRuleSet2 {
4874 pub seq_rules: Vec<OffsetMarker<SequenceRule2>>,
4877}
4878
4879impl SequenceRuleSet2 {
4880 pub fn new(seq_rules: Vec<SequenceRule2>) -> Self {
4882 Self {
4883 seq_rules: seq_rules.into_iter().map(Into::into).collect(),
4884 }
4885 }
4886}
4887
4888impl FontWrite for SequenceRuleSet2 {
4889 #[allow(clippy::unnecessary_cast)]
4890 fn write_into(&self, writer: &mut TableWriter) {
4891 (u16::try_from(array_len(&self.seq_rules)).unwrap()).write_into(writer);
4892 self.seq_rules.write_into(writer);
4893 }
4894 fn table_type(&self) -> TableType {
4895 TableType::Named("SequenceRuleSet2")
4896 }
4897}
4898
4899impl Validate for SequenceRuleSet2 {
4900 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4901 ctx.in_table("SequenceRuleSet2", |ctx| {
4902 ctx.in_field("seq_rules", |ctx| {
4903 if self.seq_rules.len() > to_usize(u16::MAX) {
4904 ctx.report("array exceeds max length");
4905 }
4906 self.seq_rules.validate_impl(ctx);
4907 });
4908 })
4909 }
4910}
4911
4912impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRuleSet2<'a>> for SequenceRuleSet2 {
4913 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRuleSet2<'a>, _: FontData) -> Self {
4914 SequenceRuleSet2 {
4915 seq_rules: obj.seq_rules().to_owned_table(),
4916 }
4917 }
4918}
4919
4920#[allow(clippy::needless_lifetimes)]
4921impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRuleSet2<'a>> for SequenceRuleSet2 {}
4922
4923impl ReadArgs for SequenceRuleSet2 {
4924 type Args = ();
4925}
4926
4927impl<'a> FontRead<'a> for SequenceRuleSet2 {
4928 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
4929 <read_fonts::tables::layout::SequenceRuleSet2 as FontRead>::read(data)
4930 .map(|x| x.to_owned_table())
4931 }
4932}
4933
4934#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
4936#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4937pub struct SequenceRule2 {
4938 pub input_sequence: Vec<GlyphId24>,
4940 pub seq_lookup_records: Vec<SequenceLookupRecord>,
4942}
4943
4944impl SequenceRule2 {
4945 pub fn new(
4947 input_sequence: Vec<GlyphId24>,
4948 seq_lookup_records: Vec<SequenceLookupRecord>,
4949 ) -> Self {
4950 Self {
4951 input_sequence,
4952 seq_lookup_records,
4953 }
4954 }
4955}
4956
4957impl FontWrite for SequenceRule2 {
4958 #[allow(clippy::unnecessary_cast)]
4959 fn write_into(&self, writer: &mut TableWriter) {
4960 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
4961 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
4962 self.input_sequence.write_into(writer);
4963 self.seq_lookup_records.write_into(writer);
4964 }
4965 fn table_type(&self) -> TableType {
4966 TableType::Named("SequenceRule2")
4967 }
4968}
4969
4970impl Validate for SequenceRule2 {
4971 fn validate_impl(&self, ctx: &mut ValidationCtx) {
4972 ctx.in_table("SequenceRule2", |ctx| {
4973 ctx.in_field("seq_lookup_records", |ctx| {
4974 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
4975 ctx.report("array exceeds max length");
4976 }
4977 self.seq_lookup_records.validate_impl(ctx);
4978 });
4979 })
4980 }
4981}
4982
4983impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRule2<'a>> for SequenceRule2 {
4984 fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRule2<'a>, _: FontData) -> Self {
4985 let offset_data = obj.offset_data();
4986 SequenceRule2 {
4987 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
4988 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
4989 }
4990 }
4991}
4992
4993#[allow(clippy::needless_lifetimes)]
4994impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRule2<'a>> for SequenceRule2 {}
4995
4996impl ReadArgs for SequenceRule2 {
4997 type Args = ();
4998}
4999
5000impl<'a> FontRead<'a> for SequenceRule2 {
5001 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5002 <read_fonts::tables::layout::SequenceRule2 as FontRead>::read(data)
5003 .map(|x| x.to_owned_table())
5004 }
5005}
5006
5007#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5009#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5010pub struct SequenceContextFormat5 {
5011 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
5014 pub class_def: OffsetMarker<ClassDef, WIDTH_32>,
5017 pub class_seq_rule_sets: Vec<NullableOffsetMarker<ClassSequenceRuleSet2, WIDTH_24>>,
5020}
5021
5022impl SequenceContextFormat5 {
5023 pub fn new(
5025 coverage: CoverageTable,
5026 class_def: ClassDef,
5027 class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet2>>,
5028 ) -> Self {
5029 Self {
5030 coverage: coverage.into(),
5031 class_def: class_def.into(),
5032 class_seq_rule_sets: class_seq_rule_sets.into_iter().map(Into::into).collect(),
5033 }
5034 }
5035}
5036
5037impl FontWrite for SequenceContextFormat5 {
5038 #[allow(clippy::unnecessary_cast)]
5039 fn write_into(&self, writer: &mut TableWriter) {
5040 (5 as u16).write_into(writer);
5041 self.coverage.write_into(writer);
5042 self.class_def.write_into(writer);
5043 (Uint24::try_from(array_len(&self.class_seq_rule_sets)).unwrap()).write_into(writer);
5044 self.class_seq_rule_sets.write_into(writer);
5045 }
5046 fn table_type(&self) -> TableType {
5047 TableType::Named("SequenceContextFormat5")
5048 }
5049}
5050
5051impl Validate for SequenceContextFormat5 {
5052 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5053 ctx.in_table("SequenceContextFormat5", |ctx| {
5054 ctx.in_field("coverage", |ctx| {
5055 self.coverage.validate_impl(ctx);
5056 });
5057 ctx.in_field("class_def", |ctx| {
5058 self.class_def.validate_impl(ctx);
5059 });
5060 ctx.in_field("class_seq_rule_sets", |ctx| {
5061 if self.class_seq_rule_sets.len() > to_usize(Uint24::MAX) {
5062 ctx.report("array exceeds max length");
5063 }
5064 self.class_seq_rule_sets.validate_impl(ctx);
5065 });
5066 })
5067 }
5068}
5069
5070impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat5<'a>>
5071 for SequenceContextFormat5
5072{
5073 fn from_obj_ref(
5074 obj: &read_fonts::tables::layout::SequenceContextFormat5<'a>,
5075 _: FontData,
5076 ) -> Self {
5077 SequenceContextFormat5 {
5078 coverage: obj.coverage().to_owned_table(),
5079 class_def: obj.class_def().to_owned_table(),
5080 class_seq_rule_sets: obj.class_seq_rule_sets().to_owned_table(),
5081 }
5082 }
5083}
5084
5085#[allow(clippy::needless_lifetimes)]
5086impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat5<'a>>
5087 for SequenceContextFormat5
5088{
5089}
5090
5091impl ReadArgs for SequenceContextFormat5 {
5092 type Args = ();
5093}
5094
5095impl<'a> FontRead<'a> for SequenceContextFormat5 {
5096 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5097 <read_fonts::tables::layout::SequenceContextFormat5 as FontRead>::read(data)
5098 .map(|x| x.to_owned_table())
5099 }
5100}
5101
5102#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5105pub struct ClassSequenceRuleSet2 {
5106 pub class_seq_rules: Vec<OffsetMarker<ClassSequenceRule, WIDTH_24>>,
5109}
5110
5111impl ClassSequenceRuleSet2 {
5112 pub fn new(class_seq_rules: Vec<ClassSequenceRule>) -> Self {
5114 Self {
5115 class_seq_rules: class_seq_rules.into_iter().map(Into::into).collect(),
5116 }
5117 }
5118}
5119
5120impl FontWrite for ClassSequenceRuleSet2 {
5121 #[allow(clippy::unnecessary_cast)]
5122 fn write_into(&self, writer: &mut TableWriter) {
5123 (u16::try_from(array_len(&self.class_seq_rules)).unwrap()).write_into(writer);
5124 self.class_seq_rules.write_into(writer);
5125 }
5126 fn table_type(&self) -> TableType {
5127 TableType::Named("ClassSequenceRuleSet2")
5128 }
5129}
5130
5131impl Validate for ClassSequenceRuleSet2 {
5132 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5133 ctx.in_table("ClassSequenceRuleSet2", |ctx| {
5134 ctx.in_field("class_seq_rules", |ctx| {
5135 if self.class_seq_rules.len() > to_usize(u16::MAX) {
5136 ctx.report("array exceeds max length");
5137 }
5138 self.class_seq_rules.validate_impl(ctx);
5139 });
5140 })
5141 }
5142}
5143
5144impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRuleSet2<'a>>
5145 for ClassSequenceRuleSet2
5146{
5147 fn from_obj_ref(
5148 obj: &read_fonts::tables::layout::ClassSequenceRuleSet2<'a>,
5149 _: FontData,
5150 ) -> Self {
5151 ClassSequenceRuleSet2 {
5152 class_seq_rules: obj.class_seq_rules().to_owned_table(),
5153 }
5154 }
5155}
5156
5157#[allow(clippy::needless_lifetimes)]
5158impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRuleSet2<'a>>
5159 for ClassSequenceRuleSet2
5160{
5161}
5162
5163impl ReadArgs for ClassSequenceRuleSet2 {
5164 type Args = ();
5165}
5166
5167impl<'a> FontRead<'a> for ClassSequenceRuleSet2 {
5168 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5169 <read_fonts::tables::layout::ClassSequenceRuleSet2 as FontRead>::read(data)
5170 .map(|x| x.to_owned_table())
5171 }
5172}
5173
5174#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5176#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5177pub struct SequenceContextFormat6 {
5178 pub coverages: Vec<OffsetMarker<CoverageTable, WIDTH_24>>,
5181 pub seq_lookup_records: Vec<SequenceLookupRecord>,
5183}
5184
5185impl SequenceContextFormat6 {
5186 pub fn new(
5188 coverages: Vec<CoverageTable>,
5189 seq_lookup_records: Vec<SequenceLookupRecord>,
5190 ) -> Self {
5191 Self {
5192 coverages: coverages.into_iter().map(Into::into).collect(),
5193 seq_lookup_records,
5194 }
5195 }
5196}
5197
5198impl FontWrite for SequenceContextFormat6 {
5199 #[allow(clippy::unnecessary_cast)]
5200 fn write_into(&self, writer: &mut TableWriter) {
5201 (6 as u16).write_into(writer);
5202 (u16::try_from(array_len(&self.coverages)).unwrap()).write_into(writer);
5203 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
5204 self.coverages.write_into(writer);
5205 self.seq_lookup_records.write_into(writer);
5206 }
5207 fn table_type(&self) -> TableType {
5208 TableType::Named("SequenceContextFormat6")
5209 }
5210}
5211
5212impl Validate for SequenceContextFormat6 {
5213 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5214 ctx.in_table("SequenceContextFormat6", |ctx| {
5215 ctx.in_field("coverages", |ctx| {
5216 if self.coverages.len() > to_usize(u16::MAX) {
5217 ctx.report("array exceeds max length");
5218 }
5219 self.coverages.validate_impl(ctx);
5220 });
5221 ctx.in_field("seq_lookup_records", |ctx| {
5222 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
5223 ctx.report("array exceeds max length");
5224 }
5225 self.seq_lookup_records.validate_impl(ctx);
5226 });
5227 })
5228 }
5229}
5230
5231impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat6<'a>>
5232 for SequenceContextFormat6
5233{
5234 fn from_obj_ref(
5235 obj: &read_fonts::tables::layout::SequenceContextFormat6<'a>,
5236 _: FontData,
5237 ) -> Self {
5238 let offset_data = obj.offset_data();
5239 SequenceContextFormat6 {
5240 coverages: obj.coverages().to_owned_table(),
5241 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
5242 }
5243 }
5244}
5245
5246#[allow(clippy::needless_lifetimes)]
5247impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat6<'a>>
5248 for SequenceContextFormat6
5249{
5250}
5251
5252impl ReadArgs for SequenceContextFormat6 {
5253 type Args = ();
5254}
5255
5256impl<'a> FontRead<'a> for SequenceContextFormat6 {
5257 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5258 <read_fonts::tables::layout::SequenceContextFormat6 as FontRead>::read(data)
5259 .map(|x| x.to_owned_table())
5260 }
5261}
5262
5263#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5265#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5266pub struct ChainedSequenceContextFormat4 {
5267 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
5270 pub chained_seq_rule_sets: Vec<NullableOffsetMarker<ChainedSequenceRuleSet2, WIDTH_24>>,
5273}
5274
5275impl ChainedSequenceContextFormat4 {
5276 pub fn new(
5278 coverage: CoverageTable,
5279 chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet2>>,
5280 ) -> Self {
5281 Self {
5282 coverage: coverage.into(),
5283 chained_seq_rule_sets: chained_seq_rule_sets.into_iter().map(Into::into).collect(),
5284 }
5285 }
5286}
5287
5288impl FontWrite for ChainedSequenceContextFormat4 {
5289 #[allow(clippy::unnecessary_cast)]
5290 fn write_into(&self, writer: &mut TableWriter) {
5291 (4 as u16).write_into(writer);
5292 self.coverage.write_into(writer);
5293 (Uint24::try_from(array_len(&self.chained_seq_rule_sets)).unwrap()).write_into(writer);
5294 self.chained_seq_rule_sets.write_into(writer);
5295 }
5296 fn table_type(&self) -> TableType {
5297 TableType::Named("ChainedSequenceContextFormat4")
5298 }
5299}
5300
5301impl Validate for ChainedSequenceContextFormat4 {
5302 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5303 ctx.in_table("ChainedSequenceContextFormat4", |ctx| {
5304 ctx.in_field("coverage", |ctx| {
5305 self.coverage.validate_impl(ctx);
5306 });
5307 ctx.in_field("chained_seq_rule_sets", |ctx| {
5308 if self.chained_seq_rule_sets.len() > to_usize(Uint24::MAX) {
5309 ctx.report("array exceeds max length");
5310 }
5311 self.chained_seq_rule_sets.validate_impl(ctx);
5312 });
5313 })
5314 }
5315}
5316
5317impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat4<'a>>
5318 for ChainedSequenceContextFormat4
5319{
5320 fn from_obj_ref(
5321 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat4<'a>,
5322 _: FontData,
5323 ) -> Self {
5324 ChainedSequenceContextFormat4 {
5325 coverage: obj.coverage().to_owned_table(),
5326 chained_seq_rule_sets: obj.chained_seq_rule_sets().to_owned_table(),
5327 }
5328 }
5329}
5330
5331#[allow(clippy::needless_lifetimes)]
5332impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat4<'a>>
5333 for ChainedSequenceContextFormat4
5334{
5335}
5336
5337impl ReadArgs for ChainedSequenceContextFormat4 {
5338 type Args = ();
5339}
5340
5341impl<'a> FontRead<'a> for ChainedSequenceContextFormat4 {
5342 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5343 <read_fonts::tables::layout::ChainedSequenceContextFormat4 as FontRead>::read(data)
5344 .map(|x| x.to_owned_table())
5345 }
5346}
5347
5348#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5350#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5351pub struct ChainedSequenceRuleSet2 {
5352 pub chained_seq_rules: Vec<OffsetMarker<ChainedSequenceRule2, WIDTH_24>>,
5355}
5356
5357impl ChainedSequenceRuleSet2 {
5358 pub fn new(chained_seq_rules: Vec<ChainedSequenceRule2>) -> Self {
5360 Self {
5361 chained_seq_rules: chained_seq_rules.into_iter().map(Into::into).collect(),
5362 }
5363 }
5364}
5365
5366impl FontWrite for ChainedSequenceRuleSet2 {
5367 #[allow(clippy::unnecessary_cast)]
5368 fn write_into(&self, writer: &mut TableWriter) {
5369 (u16::try_from(array_len(&self.chained_seq_rules)).unwrap()).write_into(writer);
5370 self.chained_seq_rules.write_into(writer);
5371 }
5372 fn table_type(&self) -> TableType {
5373 TableType::Named("ChainedSequenceRuleSet2")
5374 }
5375}
5376
5377impl Validate for ChainedSequenceRuleSet2 {
5378 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5379 ctx.in_table("ChainedSequenceRuleSet2", |ctx| {
5380 ctx.in_field("chained_seq_rules", |ctx| {
5381 if self.chained_seq_rules.len() > to_usize(u16::MAX) {
5382 ctx.report("array exceeds max length");
5383 }
5384 self.chained_seq_rules.validate_impl(ctx);
5385 });
5386 })
5387 }
5388}
5389
5390impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRuleSet2<'a>>
5391 for ChainedSequenceRuleSet2
5392{
5393 fn from_obj_ref(
5394 obj: &read_fonts::tables::layout::ChainedSequenceRuleSet2<'a>,
5395 _: FontData,
5396 ) -> Self {
5397 ChainedSequenceRuleSet2 {
5398 chained_seq_rules: obj.chained_seq_rules().to_owned_table(),
5399 }
5400 }
5401}
5402
5403#[allow(clippy::needless_lifetimes)]
5404impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRuleSet2<'a>>
5405 for ChainedSequenceRuleSet2
5406{
5407}
5408
5409impl ReadArgs for ChainedSequenceRuleSet2 {
5410 type Args = ();
5411}
5412
5413impl<'a> FontRead<'a> for ChainedSequenceRuleSet2 {
5414 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5415 <read_fonts::tables::layout::ChainedSequenceRuleSet2 as FontRead>::read(data)
5416 .map(|x| x.to_owned_table())
5417 }
5418}
5419
5420#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5422#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5423pub struct ChainedSequenceRule2 {
5424 pub backtrack_sequence: Vec<GlyphId24>,
5426 pub input_sequence: Vec<GlyphId24>,
5428 pub lookahead_sequence: Vec<GlyphId24>,
5430 pub seq_lookup_records: Vec<SequenceLookupRecord>,
5432}
5433
5434impl ChainedSequenceRule2 {
5435 pub fn new(
5437 backtrack_sequence: Vec<GlyphId24>,
5438 input_sequence: Vec<GlyphId24>,
5439 lookahead_sequence: Vec<GlyphId24>,
5440 seq_lookup_records: Vec<SequenceLookupRecord>,
5441 ) -> Self {
5442 Self {
5443 backtrack_sequence,
5444 input_sequence,
5445 lookahead_sequence,
5446 seq_lookup_records,
5447 }
5448 }
5449}
5450
5451impl FontWrite for ChainedSequenceRule2 {
5452 #[allow(clippy::unnecessary_cast)]
5453 fn write_into(&self, writer: &mut TableWriter) {
5454 (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer);
5455 self.backtrack_sequence.write_into(writer);
5456 (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer);
5457 self.input_sequence.write_into(writer);
5458 (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer);
5459 self.lookahead_sequence.write_into(writer);
5460 (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer);
5461 self.seq_lookup_records.write_into(writer);
5462 }
5463 fn table_type(&self) -> TableType {
5464 TableType::Named("ChainedSequenceRule2")
5465 }
5466}
5467
5468impl Validate for ChainedSequenceRule2 {
5469 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5470 ctx.in_table("ChainedSequenceRule2", |ctx| {
5471 ctx.in_field("backtrack_sequence", |ctx| {
5472 if self.backtrack_sequence.len() > to_usize(u16::MAX) {
5473 ctx.report("array exceeds max length");
5474 }
5475 });
5476 ctx.in_field("lookahead_sequence", |ctx| {
5477 if self.lookahead_sequence.len() > to_usize(u16::MAX) {
5478 ctx.report("array exceeds max length");
5479 }
5480 });
5481 ctx.in_field("seq_lookup_records", |ctx| {
5482 if self.seq_lookup_records.len() > to_usize(u16::MAX) {
5483 ctx.report("array exceeds max length");
5484 }
5485 self.seq_lookup_records.validate_impl(ctx);
5486 });
5487 })
5488 }
5489}
5490
5491impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRule2<'a>> for ChainedSequenceRule2 {
5492 fn from_obj_ref(
5493 obj: &read_fonts::tables::layout::ChainedSequenceRule2<'a>,
5494 _: FontData,
5495 ) -> Self {
5496 let offset_data = obj.offset_data();
5497 ChainedSequenceRule2 {
5498 backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data),
5499 input_sequence: obj.input_sequence().to_owned_obj(offset_data),
5500 lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data),
5501 seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data),
5502 }
5503 }
5504}
5505
5506#[allow(clippy::needless_lifetimes)]
5507impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRule2<'a>>
5508 for ChainedSequenceRule2
5509{
5510}
5511
5512impl ReadArgs for ChainedSequenceRule2 {
5513 type Args = ();
5514}
5515
5516impl<'a> FontRead<'a> for ChainedSequenceRule2 {
5517 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5518 <read_fonts::tables::layout::ChainedSequenceRule2 as FontRead>::read(data)
5519 .map(|x| x.to_owned_table())
5520 }
5521}
5522
5523#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5525#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5526pub struct ChainedSequenceContextFormat5 {
5527 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
5530 pub backtrack_class_def: OffsetMarker<ClassDef, WIDTH_32>,
5533 pub input_class_def: OffsetMarker<ClassDef, WIDTH_32>,
5536 pub lookahead_class_def: OffsetMarker<ClassDef, WIDTH_32>,
5539 pub chained_class_seq_rule_sets:
5542 Vec<NullableOffsetMarker<ChainedClassSequenceRuleSet2, WIDTH_24>>,
5543}
5544
5545impl ChainedSequenceContextFormat5 {
5546 pub fn new(
5548 coverage: CoverageTable,
5549 backtrack_class_def: ClassDef,
5550 input_class_def: ClassDef,
5551 lookahead_class_def: ClassDef,
5552 chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet2>>,
5553 ) -> Self {
5554 Self {
5555 coverage: coverage.into(),
5556 backtrack_class_def: backtrack_class_def.into(),
5557 input_class_def: input_class_def.into(),
5558 lookahead_class_def: lookahead_class_def.into(),
5559 chained_class_seq_rule_sets: chained_class_seq_rule_sets
5560 .into_iter()
5561 .map(Into::into)
5562 .collect(),
5563 }
5564 }
5565}
5566
5567impl FontWrite for ChainedSequenceContextFormat5 {
5568 #[allow(clippy::unnecessary_cast)]
5569 fn write_into(&self, writer: &mut TableWriter) {
5570 (5 as u16).write_into(writer);
5571 self.coverage.write_into(writer);
5572 self.backtrack_class_def.write_into(writer);
5573 self.input_class_def.write_into(writer);
5574 self.lookahead_class_def.write_into(writer);
5575 (u16::try_from(array_len(&self.chained_class_seq_rule_sets)).unwrap()).write_into(writer);
5576 self.chained_class_seq_rule_sets.write_into(writer);
5577 }
5578 fn table_type(&self) -> TableType {
5579 TableType::Named("ChainedSequenceContextFormat5")
5580 }
5581}
5582
5583impl Validate for ChainedSequenceContextFormat5 {
5584 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5585 ctx.in_table("ChainedSequenceContextFormat5", |ctx| {
5586 ctx.in_field("coverage", |ctx| {
5587 self.coverage.validate_impl(ctx);
5588 });
5589 ctx.in_field("backtrack_class_def", |ctx| {
5590 self.backtrack_class_def.validate_impl(ctx);
5591 });
5592 ctx.in_field("input_class_def", |ctx| {
5593 self.input_class_def.validate_impl(ctx);
5594 });
5595 ctx.in_field("lookahead_class_def", |ctx| {
5596 self.lookahead_class_def.validate_impl(ctx);
5597 });
5598 ctx.in_field("chained_class_seq_rule_sets", |ctx| {
5599 if self.chained_class_seq_rule_sets.len() > to_usize(u16::MAX) {
5600 ctx.report("array exceeds max length");
5601 }
5602 self.chained_class_seq_rule_sets.validate_impl(ctx);
5603 });
5604 })
5605 }
5606}
5607
5608impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat5<'a>>
5609 for ChainedSequenceContextFormat5
5610{
5611 fn from_obj_ref(
5612 obj: &read_fonts::tables::layout::ChainedSequenceContextFormat5<'a>,
5613 _: FontData,
5614 ) -> Self {
5615 ChainedSequenceContextFormat5 {
5616 coverage: obj.coverage().to_owned_table(),
5617 backtrack_class_def: obj.backtrack_class_def().to_owned_table(),
5618 input_class_def: obj.input_class_def().to_owned_table(),
5619 lookahead_class_def: obj.lookahead_class_def().to_owned_table(),
5620 chained_class_seq_rule_sets: obj.chained_class_seq_rule_sets().to_owned_table(),
5621 }
5622 }
5623}
5624
5625#[allow(clippy::needless_lifetimes)]
5626impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat5<'a>>
5627 for ChainedSequenceContextFormat5
5628{
5629}
5630
5631impl ReadArgs for ChainedSequenceContextFormat5 {
5632 type Args = ();
5633}
5634
5635impl<'a> FontRead<'a> for ChainedSequenceContextFormat5 {
5636 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5637 <read_fonts::tables::layout::ChainedSequenceContextFormat5 as FontRead>::read(data)
5638 .map(|x| x.to_owned_table())
5639 }
5640}
5641
5642#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5644#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5645pub struct ChainedClassSequenceRuleSet2 {
5646 pub chained_class_seq_rules: Vec<OffsetMarker<ChainedClassSequenceRule, WIDTH_24>>,
5649}
5650
5651impl ChainedClassSequenceRuleSet2 {
5652 pub fn new(chained_class_seq_rules: Vec<ChainedClassSequenceRule>) -> Self {
5654 Self {
5655 chained_class_seq_rules: chained_class_seq_rules
5656 .into_iter()
5657 .map(Into::into)
5658 .collect(),
5659 }
5660 }
5661}
5662
5663impl FontWrite for ChainedClassSequenceRuleSet2 {
5664 #[allow(clippy::unnecessary_cast)]
5665 fn write_into(&self, writer: &mut TableWriter) {
5666 (u16::try_from(array_len(&self.chained_class_seq_rules)).unwrap()).write_into(writer);
5667 self.chained_class_seq_rules.write_into(writer);
5668 }
5669 fn table_type(&self) -> TableType {
5670 TableType::Named("ChainedClassSequenceRuleSet2")
5671 }
5672}
5673
5674impl Validate for ChainedClassSequenceRuleSet2 {
5675 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5676 ctx.in_table("ChainedClassSequenceRuleSet2", |ctx| {
5677 ctx.in_field("chained_class_seq_rules", |ctx| {
5678 if self.chained_class_seq_rules.len() > to_usize(u16::MAX) {
5679 ctx.report("array exceeds max length");
5680 }
5681 self.chained_class_seq_rules.validate_impl(ctx);
5682 });
5683 })
5684 }
5685}
5686
5687impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet2<'a>>
5688 for ChainedClassSequenceRuleSet2
5689{
5690 fn from_obj_ref(
5691 obj: &read_fonts::tables::layout::ChainedClassSequenceRuleSet2<'a>,
5692 _: FontData,
5693 ) -> Self {
5694 ChainedClassSequenceRuleSet2 {
5695 chained_class_seq_rules: obj.chained_class_seq_rules().to_owned_table(),
5696 }
5697 }
5698}
5699
5700#[allow(clippy::needless_lifetimes)]
5701impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet2<'a>>
5702 for ChainedClassSequenceRuleSet2
5703{
5704}
5705
5706impl ReadArgs for ChainedClassSequenceRuleSet2 {
5707 type Args = ();
5708}
5709
5710impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet2 {
5711 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
5712 <read_fonts::tables::layout::ChainedClassSequenceRuleSet2 as FontRead>::read(data)
5713 .map(|x| x.to_owned_table())
5714 }
5715}
5716
5717#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
5719#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5720pub struct LookupList2<T> {
5721 pub lookups: Vec<OffsetMarker<T, WIDTH_32>>,
5724}
5725
5726impl<T: Default> LookupList2<T> {
5727 pub fn new(lookups: Vec<T>) -> Self {
5729 Self {
5730 lookups: lookups.into_iter().map(Into::into).collect(),
5731 }
5732 }
5733}
5734
5735impl<T: FontWrite> FontWrite for LookupList2<T> {
5736 #[allow(clippy::unnecessary_cast)]
5737 fn write_into(&self, writer: &mut TableWriter) {
5738 (u16::try_from(array_len(&self.lookups)).unwrap()).write_into(writer);
5739 self.lookups.write_into(writer);
5740 }
5741 fn table_type(&self) -> TableType {
5742 TableType::Named("LookupList2")
5743 }
5744}
5745
5746impl<T: Validate> Validate for LookupList2<T> {
5747 fn validate_impl(&self, ctx: &mut ValidationCtx) {
5748 ctx.in_table("LookupList2", |ctx| {
5749 ctx.in_field("lookups", |ctx| {
5750 if self.lookups.len() > to_usize(u16::MAX) {
5751 ctx.report("array exceeds max length");
5752 }
5753 self.lookups.validate_impl(ctx);
5754 });
5755 })
5756 }
5757}
5758
5759impl<'a, T, U> FromObjRef<read_fonts::tables::layout::LookupList2<'a, U>> for LookupList2<T>
5760where
5761 U: FontRead<'a, Args = ()>,
5762 T: FromTableRef<U> + Default + 'static,
5763{
5764 fn from_obj_ref(obj: &read_fonts::tables::layout::LookupList2<'a, U>, _: FontData) -> Self {
5765 LookupList2 {
5766 lookups: obj.lookups().to_owned_table(),
5767 }
5768 }
5769}
5770
5771#[allow(clippy::needless_lifetimes)]
5772impl<'a, T, U> FromTableRef<read_fonts::tables::layout::LookupList2<'a, U>> for LookupList2<T>
5773where
5774 U: FontRead<'a, Args = ()>,
5775 T: FromTableRef<U> + Default + 'static,
5776{
5777}