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