1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Gsub {
12 pub script_list: NullableOffsetMarker<ScriptList>,
14 pub feature_list: NullableOffsetMarker<FeatureList>,
16 pub lookup_list: NullableOffsetMarker<OriginalSubstitutionLookupList>,
18 pub feature_variations: NullableOffsetMarker<FeatureVariations, WIDTH_32>,
21 pub script_list2: NullableOffsetMarker<ScriptList, WIDTH_32>,
23 pub feature_list2: NullableOffsetMarker<FeatureList, WIDTH_32>,
25 pub lookup_list2: NullableOffsetMarker<SubstitutionLookupList2, WIDTH_32>,
27}
28
29impl Default for Gsub {
30 fn default() -> Self {
31 Self {
32 script_list: Some(Default::default()).into(),
33 feature_list: Some(Default::default()).into(),
34 lookup_list: Some(Default::default()).into(),
35 feature_variations: Default::default(),
36 script_list2: Default::default(),
37 feature_list2: Default::default(),
38 lookup_list2: Default::default(),
39 }
40 }
41}
42
43impl FontWrite for Gsub {
44 #[allow(clippy::unnecessary_cast)]
45 fn write_into(&self, writer: &mut TableWriter) {
46 let version = self.compute_version() as MajorMinor;
47 version.write_into(writer);
48 self.script_list.write_into(writer);
49 self.feature_list.write_into(writer);
50 self.lookup_list.write_into(writer);
51 version
52 .compatible((1u16, 1u16))
53 .then(|| self.feature_variations.write_into(writer));
54 version
55 .compatible((1u16, 2u16))
56 .then(|| self.script_list2.write_into(writer));
57 version
58 .compatible((1u16, 2u16))
59 .then(|| self.feature_list2.write_into(writer));
60 version
61 .compatible((1u16, 2u16))
62 .then(|| self.lookup_list2.write_into(writer));
63 }
64 fn table_type(&self) -> TableType {
65 TableType::TopLevel(Gsub::TAG)
66 }
67}
68
69impl Validate for Gsub {
70 fn validate_impl(&self, ctx: &mut ValidationCtx) {
71 ctx.in_table("Gsub", |ctx| {
72 ctx.in_field("script_list", |ctx| {
73 self.script_list.validate_impl(ctx);
74 });
75 ctx.in_field("feature_list", |ctx| {
76 self.feature_list.validate_impl(ctx);
77 });
78 ctx.in_field("lookup_list", |ctx| {
79 self.lookup_list.validate_impl(ctx);
80 });
81 ctx.in_field("feature_variations", |ctx| {
82 self.feature_variations.validate_impl(ctx);
83 });
84 ctx.in_field("script_list2", |ctx| {
85 self.script_list2.validate_impl(ctx);
86 });
87 ctx.in_field("feature_list2", |ctx| {
88 self.feature_list2.validate_impl(ctx);
89 });
90 ctx.in_field("lookup_list2", |ctx| {
91 self.lookup_list2.validate_impl(ctx);
92 });
93 })
94 }
95}
96
97impl TopLevelTable for Gsub {
98 const TAG: Tag = Tag::new(b"GSUB");
99}
100
101impl<'a> FromObjRef<read_fonts::tables::gsub::Gsub<'a>> for Gsub {
102 fn from_obj_ref(obj: &read_fonts::tables::gsub::Gsub<'a>, _: FontData) -> Self {
103 Gsub {
104 script_list: obj.original_script_list().to_owned_table(),
105 feature_list: obj.original_feature_list().to_owned_table(),
106 lookup_list: obj.original_lookup_list().to_owned_table(),
107 feature_variations: obj.feature_variations().to_owned_table(),
108 script_list2: obj.script_list2().to_owned_table(),
109 feature_list2: obj.feature_list2().to_owned_table(),
110 lookup_list2: obj.lookup_list2().to_owned_table(),
111 }
112 }
113}
114
115#[allow(clippy::needless_lifetimes)]
116impl<'a> FromTableRef<read_fonts::tables::gsub::Gsub<'a>> for Gsub {}
117
118impl ReadArgs for Gsub {
119 type Args = ();
120}
121
122impl<'a> FontRead<'a> for Gsub {
123 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
124 <read_fonts::tables::gsub::Gsub as FontRead>::read(data).map(|x| x.to_owned_table())
125 }
126}
127
128#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
130#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
131pub enum SubstitutionLookup {
132 Single(Lookup<SingleSubst>),
133 Multiple(Lookup<MultipleSubst>),
134 Alternate(Lookup<AlternateSubst>),
135 Ligature(Lookup<LigatureSubst>),
136 Contextual(Lookup<SubstitutionSequenceContext>),
137 ChainContextual(Lookup<SubstitutionChainContext>),
138 Extension(Lookup<ExtensionSubtable>),
139 Reverse(Lookup<ReverseChainSingleSubst>),
140}
141
142impl Default for SubstitutionLookup {
143 fn default() -> Self {
144 Self::Single(Default::default())
145 }
146}
147
148impl FontWrite for SubstitutionLookup {
149 fn write_into(&self, writer: &mut TableWriter) {
150 match self {
151 Self::Single(table) => table.write_into(writer),
152 Self::Multiple(table) => table.write_into(writer),
153 Self::Alternate(table) => table.write_into(writer),
154 Self::Ligature(table) => table.write_into(writer),
155 Self::Contextual(table) => table.write_into(writer),
156 Self::ChainContextual(table) => table.write_into(writer),
157 Self::Extension(table) => table.write_into(writer),
158 Self::Reverse(table) => table.write_into(writer),
159 }
160 }
161 fn table_type(&self) -> TableType {
162 match self {
163 Self::Single(table) => table.table_type(),
164 Self::Multiple(table) => table.table_type(),
165 Self::Alternate(table) => table.table_type(),
166 Self::Ligature(table) => table.table_type(),
167 Self::Contextual(table) => table.table_type(),
168 Self::ChainContextual(table) => table.table_type(),
169 Self::Extension(table) => table.table_type(),
170 Self::Reverse(table) => table.table_type(),
171 }
172 }
173}
174
175impl Validate for SubstitutionLookup {
176 fn validate_impl(&self, ctx: &mut ValidationCtx) {
177 match self {
178 Self::Single(table) => table.validate_impl(ctx),
179 Self::Multiple(table) => table.validate_impl(ctx),
180 Self::Alternate(table) => table.validate_impl(ctx),
181 Self::Ligature(table) => table.validate_impl(ctx),
182 Self::Contextual(table) => table.validate_impl(ctx),
183 Self::ChainContextual(table) => table.validate_impl(ctx),
184 Self::Extension(table) => table.validate_impl(ctx),
185 Self::Reverse(table) => table.validate_impl(ctx),
186 }
187 }
188}
189
190impl FromObjRef<read_fonts::tables::gsub::SubstitutionLookup<'_>> for SubstitutionLookup {
191 fn from_obj_ref(
192 from: &read_fonts::tables::gsub::SubstitutionLookup<'_>,
193 data: FontData,
194 ) -> Self {
195 match from {
196 read_fonts::tables::gsub::SubstitutionLookup::Single(table) => {
197 Self::Single(table.to_owned_obj(data))
198 }
199 read_fonts::tables::gsub::SubstitutionLookup::Multiple(table) => {
200 Self::Multiple(table.to_owned_obj(data))
201 }
202 read_fonts::tables::gsub::SubstitutionLookup::Alternate(table) => {
203 Self::Alternate(table.to_owned_obj(data))
204 }
205 read_fonts::tables::gsub::SubstitutionLookup::Ligature(table) => {
206 Self::Ligature(table.to_owned_obj(data))
207 }
208 read_fonts::tables::gsub::SubstitutionLookup::Contextual(table) => {
209 Self::Contextual(table.to_owned_obj(data))
210 }
211 read_fonts::tables::gsub::SubstitutionLookup::ChainContextual(table) => {
212 Self::ChainContextual(table.to_owned_obj(data))
213 }
214 read_fonts::tables::gsub::SubstitutionLookup::Extension(table) => {
215 Self::Extension(table.to_owned_obj(data))
216 }
217 read_fonts::tables::gsub::SubstitutionLookup::Reverse(table) => {
218 Self::Reverse(table.to_owned_obj(data))
219 }
220 }
221 }
222}
223
224impl FromTableRef<read_fonts::tables::gsub::SubstitutionLookup<'_>> for SubstitutionLookup {}
225
226impl From<Lookup<SingleSubst>> for SubstitutionLookup {
227 fn from(src: Lookup<SingleSubst>) -> SubstitutionLookup {
228 SubstitutionLookup::Single(src)
229 }
230}
231
232impl From<Lookup<MultipleSubst>> for SubstitutionLookup {
233 fn from(src: Lookup<MultipleSubst>) -> SubstitutionLookup {
234 SubstitutionLookup::Multiple(src)
235 }
236}
237
238impl From<Lookup<AlternateSubst>> for SubstitutionLookup {
239 fn from(src: Lookup<AlternateSubst>) -> SubstitutionLookup {
240 SubstitutionLookup::Alternate(src)
241 }
242}
243
244impl From<Lookup<LigatureSubst>> for SubstitutionLookup {
245 fn from(src: Lookup<LigatureSubst>) -> SubstitutionLookup {
246 SubstitutionLookup::Ligature(src)
247 }
248}
249
250impl From<Lookup<SubstitutionSequenceContext>> for SubstitutionLookup {
251 fn from(src: Lookup<SubstitutionSequenceContext>) -> SubstitutionLookup {
252 SubstitutionLookup::Contextual(src)
253 }
254}
255
256impl From<Lookup<SubstitutionChainContext>> for SubstitutionLookup {
257 fn from(src: Lookup<SubstitutionChainContext>) -> SubstitutionLookup {
258 SubstitutionLookup::ChainContextual(src)
259 }
260}
261
262impl From<Lookup<ExtensionSubtable>> for SubstitutionLookup {
263 fn from(src: Lookup<ExtensionSubtable>) -> SubstitutionLookup {
264 SubstitutionLookup::Extension(src)
265 }
266}
267
268impl From<Lookup<ReverseChainSingleSubst>> for SubstitutionLookup {
269 fn from(src: Lookup<ReverseChainSingleSubst>) -> SubstitutionLookup {
270 SubstitutionLookup::Reverse(src)
271 }
272}
273
274#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
276#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
277pub enum SingleSubst {
278 Format1(SingleSubstFormat1),
279 Format2(SingleSubstFormat2),
280 Format3(SingleSubstFormat3),
281 Format4(SingleSubstFormat4),
282}
283
284impl SingleSubst {
285 pub fn format_1(coverage: CoverageTable, delta_glyph_id: i16) -> Self {
287 Self::Format1(SingleSubstFormat1::new(coverage, delta_glyph_id))
288 }
289
290 pub fn format_2(coverage: CoverageTable, substitute_glyph_ids: Vec<GlyphId16>) -> Self {
292 Self::Format2(SingleSubstFormat2::new(coverage, substitute_glyph_ids))
293 }
294
295 pub fn format_3(coverage: CoverageTable, delta_glyph_id: Int24) -> Self {
297 Self::Format3(SingleSubstFormat3::new(coverage, delta_glyph_id))
298 }
299
300 pub fn format_4(coverage: CoverageTable, substitute_glyph_ids: Vec<GlyphId24>) -> Self {
302 Self::Format4(SingleSubstFormat4::new(coverage, substitute_glyph_ids))
303 }
304}
305
306impl Default for SingleSubst {
307 fn default() -> Self {
308 Self::Format1(Default::default())
309 }
310}
311
312impl FontWrite for SingleSubst {
313 fn write_into(&self, writer: &mut TableWriter) {
314 match self {
315 Self::Format1(item) => item.write_into(writer),
316 Self::Format2(item) => item.write_into(writer),
317 Self::Format3(item) => item.write_into(writer),
318 Self::Format4(item) => item.write_into(writer),
319 }
320 }
321 fn table_type(&self) -> TableType {
322 match self {
323 Self::Format1(item) => item.table_type(),
324 Self::Format2(item) => item.table_type(),
325 Self::Format3(item) => item.table_type(),
326 Self::Format4(item) => item.table_type(),
327 }
328 }
329}
330
331impl Validate for SingleSubst {
332 fn validate_impl(&self, ctx: &mut ValidationCtx) {
333 match self {
334 Self::Format1(item) => item.validate_impl(ctx),
335 Self::Format2(item) => item.validate_impl(ctx),
336 Self::Format3(item) => item.validate_impl(ctx),
337 Self::Format4(item) => item.validate_impl(ctx),
338 }
339 }
340}
341
342impl FromObjRef<read_fonts::tables::gsub::SingleSubst<'_>> for SingleSubst {
343 fn from_obj_ref(obj: &read_fonts::tables::gsub::SingleSubst, _: FontData) -> Self {
344 use read_fonts::tables::gsub::SingleSubst as ObjRefType;
345 match obj {
346 ObjRefType::Format1(item) => SingleSubst::Format1(item.to_owned_table()),
347 ObjRefType::Format2(item) => SingleSubst::Format2(item.to_owned_table()),
348 ObjRefType::Format3(item) => SingleSubst::Format3(item.to_owned_table()),
349 ObjRefType::Format4(item) => SingleSubst::Format4(item.to_owned_table()),
350 }
351 }
352}
353
354impl FromTableRef<read_fonts::tables::gsub::SingleSubst<'_>> for SingleSubst {}
355
356impl ReadArgs for SingleSubst {
357 type Args = ();
358}
359
360impl<'a> FontRead<'a> for SingleSubst {
361 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
362 <read_fonts::tables::gsub::SingleSubst as FontRead>::read(data).map(|x| x.to_owned_table())
363 }
364}
365
366impl From<SingleSubstFormat1> for SingleSubst {
367 fn from(src: SingleSubstFormat1) -> SingleSubst {
368 SingleSubst::Format1(src)
369 }
370}
371
372impl From<SingleSubstFormat2> for SingleSubst {
373 fn from(src: SingleSubstFormat2) -> SingleSubst {
374 SingleSubst::Format2(src)
375 }
376}
377
378impl From<SingleSubstFormat3> for SingleSubst {
379 fn from(src: SingleSubstFormat3) -> SingleSubst {
380 SingleSubst::Format3(src)
381 }
382}
383
384impl From<SingleSubstFormat4> for SingleSubst {
385 fn from(src: SingleSubstFormat4) -> SingleSubst {
386 SingleSubst::Format4(src)
387 }
388}
389
390#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
392#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
393pub struct SingleSubstFormat1 {
394 pub coverage: OffsetMarker<CoverageTable>,
397 pub delta_glyph_id: i16,
399}
400
401impl SingleSubstFormat1 {
402 pub fn new(coverage: CoverageTable, delta_glyph_id: i16) -> Self {
404 Self {
405 coverage: coverage.into(),
406 delta_glyph_id,
407 }
408 }
409}
410
411impl FontWrite for SingleSubstFormat1 {
412 #[allow(clippy::unnecessary_cast)]
413 fn write_into(&self, writer: &mut TableWriter) {
414 (1 as u16).write_into(writer);
415 self.coverage.write_into(writer);
416 self.delta_glyph_id.write_into(writer);
417 }
418 fn table_type(&self) -> TableType {
419 TableType::Named("SingleSubstFormat1")
420 }
421}
422
423impl Validate for SingleSubstFormat1 {
424 fn validate_impl(&self, ctx: &mut ValidationCtx) {
425 ctx.in_table("SingleSubstFormat1", |ctx| {
426 ctx.in_field("coverage", |ctx| {
427 self.coverage.validate_impl(ctx);
428 });
429 })
430 }
431}
432
433impl<'a> FromObjRef<read_fonts::tables::gsub::SingleSubstFormat1<'a>> for SingleSubstFormat1 {
434 fn from_obj_ref(obj: &read_fonts::tables::gsub::SingleSubstFormat1<'a>, _: FontData) -> Self {
435 SingleSubstFormat1 {
436 coverage: obj.coverage().to_owned_table(),
437 delta_glyph_id: obj.delta_glyph_id(),
438 }
439 }
440}
441
442#[allow(clippy::needless_lifetimes)]
443impl<'a> FromTableRef<read_fonts::tables::gsub::SingleSubstFormat1<'a>> for SingleSubstFormat1 {}
444
445impl ReadArgs for SingleSubstFormat1 {
446 type Args = ();
447}
448
449impl<'a> FontRead<'a> for SingleSubstFormat1 {
450 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
451 <read_fonts::tables::gsub::SingleSubstFormat1 as FontRead>::read(data)
452 .map(|x| x.to_owned_table())
453 }
454}
455
456#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
458#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
459pub struct SingleSubstFormat2 {
460 pub coverage: OffsetMarker<CoverageTable>,
463 pub substitute_glyph_ids: Vec<GlyphId16>,
465}
466
467impl SingleSubstFormat2 {
468 pub fn new(coverage: CoverageTable, substitute_glyph_ids: Vec<GlyphId16>) -> Self {
470 Self {
471 coverage: coverage.into(),
472 substitute_glyph_ids,
473 }
474 }
475}
476
477impl FontWrite for SingleSubstFormat2 {
478 #[allow(clippy::unnecessary_cast)]
479 fn write_into(&self, writer: &mut TableWriter) {
480 (2 as u16).write_into(writer);
481 self.coverage.write_into(writer);
482 (u16::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
483 self.substitute_glyph_ids.write_into(writer);
484 }
485 fn table_type(&self) -> TableType {
486 TableType::Named("SingleSubstFormat2")
487 }
488}
489
490impl Validate for SingleSubstFormat2 {
491 fn validate_impl(&self, ctx: &mut ValidationCtx) {
492 ctx.in_table("SingleSubstFormat2", |ctx| {
493 ctx.in_field("coverage", |ctx| {
494 self.coverage.validate_impl(ctx);
495 });
496 ctx.in_field("substitute_glyph_ids", |ctx| {
497 if self.substitute_glyph_ids.len() > to_usize(u16::MAX) {
498 ctx.report("array exceeds max length");
499 }
500 });
501 })
502 }
503}
504
505impl<'a> FromObjRef<read_fonts::tables::gsub::SingleSubstFormat2<'a>> for SingleSubstFormat2 {
506 fn from_obj_ref(obj: &read_fonts::tables::gsub::SingleSubstFormat2<'a>, _: FontData) -> Self {
507 let offset_data = obj.offset_data();
508 SingleSubstFormat2 {
509 coverage: obj.coverage().to_owned_table(),
510 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
511 }
512 }
513}
514
515#[allow(clippy::needless_lifetimes)]
516impl<'a> FromTableRef<read_fonts::tables::gsub::SingleSubstFormat2<'a>> for SingleSubstFormat2 {}
517
518impl ReadArgs for SingleSubstFormat2 {
519 type Args = ();
520}
521
522impl<'a> FontRead<'a> for SingleSubstFormat2 {
523 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
524 <read_fonts::tables::gsub::SingleSubstFormat2 as FontRead>::read(data)
525 .map(|x| x.to_owned_table())
526 }
527}
528
529#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
531#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
532pub struct MultipleSubstFormat1 {
533 pub coverage: OffsetMarker<CoverageTable>,
536 pub sequences: Vec<OffsetMarker<Sequence>>,
539}
540
541impl MultipleSubstFormat1 {
542 pub fn new(coverage: CoverageTable, sequences: Vec<Sequence>) -> Self {
544 Self {
545 coverage: coverage.into(),
546 sequences: sequences.into_iter().map(Into::into).collect(),
547 }
548 }
549}
550
551impl FontWrite for MultipleSubstFormat1 {
552 #[allow(clippy::unnecessary_cast)]
553 fn write_into(&self, writer: &mut TableWriter) {
554 (1 as u16).write_into(writer);
555 self.coverage.write_into(writer);
556 (u16::try_from(array_len(&self.sequences)).unwrap()).write_into(writer);
557 self.sequences.write_into(writer);
558 }
559 fn table_type(&self) -> TableType {
560 TableType::Named("MultipleSubstFormat1")
561 }
562}
563
564impl Validate for MultipleSubstFormat1 {
565 fn validate_impl(&self, ctx: &mut ValidationCtx) {
566 ctx.in_table("MultipleSubstFormat1", |ctx| {
567 ctx.in_field("coverage", |ctx| {
568 self.coverage.validate_impl(ctx);
569 });
570 ctx.in_field("sequences", |ctx| {
571 if self.sequences.len() > to_usize(u16::MAX) {
572 ctx.report("array exceeds max length");
573 }
574 self.sequences.validate_impl(ctx);
575 });
576 })
577 }
578}
579
580impl<'a> FromObjRef<read_fonts::tables::gsub::MultipleSubstFormat1<'a>> for MultipleSubstFormat1 {
581 fn from_obj_ref(obj: &read_fonts::tables::gsub::MultipleSubstFormat1<'a>, _: FontData) -> Self {
582 MultipleSubstFormat1 {
583 coverage: obj.coverage().to_owned_table(),
584 sequences: obj.sequences().to_owned_table(),
585 }
586 }
587}
588
589#[allow(clippy::needless_lifetimes)]
590impl<'a> FromTableRef<read_fonts::tables::gsub::MultipleSubstFormat1<'a>> for MultipleSubstFormat1 {}
591
592impl ReadArgs for MultipleSubstFormat1 {
593 type Args = ();
594}
595
596impl<'a> FontRead<'a> for MultipleSubstFormat1 {
597 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
598 <read_fonts::tables::gsub::MultipleSubstFormat1 as FontRead>::read(data)
599 .map(|x| x.to_owned_table())
600 }
601}
602
603#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
605#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
606pub struct Sequence {
607 pub substitute_glyph_ids: Vec<GlyphId16>,
609}
610
611impl Sequence {
612 pub fn new(substitute_glyph_ids: Vec<GlyphId16>) -> Self {
614 Self {
615 substitute_glyph_ids,
616 }
617 }
618}
619
620impl FontWrite for Sequence {
621 #[allow(clippy::unnecessary_cast)]
622 fn write_into(&self, writer: &mut TableWriter) {
623 (u16::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
624 self.substitute_glyph_ids.write_into(writer);
625 }
626 fn table_type(&self) -> TableType {
627 TableType::Named("Sequence")
628 }
629}
630
631impl Validate for Sequence {
632 fn validate_impl(&self, ctx: &mut ValidationCtx) {
633 ctx.in_table("Sequence", |ctx| {
634 ctx.in_field("substitute_glyph_ids", |ctx| {
635 if self.substitute_glyph_ids.len() > to_usize(u16::MAX) {
636 ctx.report("array exceeds max length");
637 }
638 });
639 })
640 }
641}
642
643impl<'a> FromObjRef<read_fonts::tables::gsub::Sequence<'a>> for Sequence {
644 fn from_obj_ref(obj: &read_fonts::tables::gsub::Sequence<'a>, _: FontData) -> Self {
645 let offset_data = obj.offset_data();
646 Sequence {
647 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
648 }
649 }
650}
651
652#[allow(clippy::needless_lifetimes)]
653impl<'a> FromTableRef<read_fonts::tables::gsub::Sequence<'a>> for Sequence {}
654
655impl ReadArgs for Sequence {
656 type Args = ();
657}
658
659impl<'a> FontRead<'a> for Sequence {
660 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
661 <read_fonts::tables::gsub::Sequence as FontRead>::read(data).map(|x| x.to_owned_table())
662 }
663}
664
665#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
667#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
668pub struct AlternateSubstFormat1 {
669 pub coverage: OffsetMarker<CoverageTable>,
672 pub alternate_sets: Vec<OffsetMarker<AlternateSet>>,
675}
676
677impl AlternateSubstFormat1 {
678 pub fn new(coverage: CoverageTable, alternate_sets: Vec<AlternateSet>) -> Self {
680 Self {
681 coverage: coverage.into(),
682 alternate_sets: alternate_sets.into_iter().map(Into::into).collect(),
683 }
684 }
685}
686
687impl FontWrite for AlternateSubstFormat1 {
688 #[allow(clippy::unnecessary_cast)]
689 fn write_into(&self, writer: &mut TableWriter) {
690 (1 as u16).write_into(writer);
691 self.coverage.write_into(writer);
692 (u16::try_from(array_len(&self.alternate_sets)).unwrap()).write_into(writer);
693 self.alternate_sets.write_into(writer);
694 }
695 fn table_type(&self) -> TableType {
696 TableType::Named("AlternateSubstFormat1")
697 }
698}
699
700impl Validate for AlternateSubstFormat1 {
701 fn validate_impl(&self, ctx: &mut ValidationCtx) {
702 ctx.in_table("AlternateSubstFormat1", |ctx| {
703 ctx.in_field("coverage", |ctx| {
704 self.coverage.validate_impl(ctx);
705 });
706 ctx.in_field("alternate_sets", |ctx| {
707 if self.alternate_sets.len() > to_usize(u16::MAX) {
708 ctx.report("array exceeds max length");
709 }
710 self.alternate_sets.validate_impl(ctx);
711 });
712 })
713 }
714}
715
716impl<'a> FromObjRef<read_fonts::tables::gsub::AlternateSubstFormat1<'a>> for AlternateSubstFormat1 {
717 fn from_obj_ref(
718 obj: &read_fonts::tables::gsub::AlternateSubstFormat1<'a>,
719 _: FontData,
720 ) -> Self {
721 AlternateSubstFormat1 {
722 coverage: obj.coverage().to_owned_table(),
723 alternate_sets: obj.alternate_sets().to_owned_table(),
724 }
725 }
726}
727
728#[allow(clippy::needless_lifetimes)]
729impl<'a> FromTableRef<read_fonts::tables::gsub::AlternateSubstFormat1<'a>>
730 for AlternateSubstFormat1
731{
732}
733
734impl ReadArgs for AlternateSubstFormat1 {
735 type Args = ();
736}
737
738impl<'a> FontRead<'a> for AlternateSubstFormat1 {
739 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
740 <read_fonts::tables::gsub::AlternateSubstFormat1 as FontRead>::read(data)
741 .map(|x| x.to_owned_table())
742 }
743}
744
745#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
747#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
748pub struct AlternateSet {
749 pub alternate_glyph_ids: Vec<GlyphId16>,
751}
752
753impl AlternateSet {
754 pub fn new(alternate_glyph_ids: Vec<GlyphId16>) -> Self {
756 Self {
757 alternate_glyph_ids,
758 }
759 }
760}
761
762impl FontWrite for AlternateSet {
763 #[allow(clippy::unnecessary_cast)]
764 fn write_into(&self, writer: &mut TableWriter) {
765 (u16::try_from(array_len(&self.alternate_glyph_ids)).unwrap()).write_into(writer);
766 self.alternate_glyph_ids.write_into(writer);
767 }
768 fn table_type(&self) -> TableType {
769 TableType::Named("AlternateSet")
770 }
771}
772
773impl Validate for AlternateSet {
774 fn validate_impl(&self, ctx: &mut ValidationCtx) {
775 ctx.in_table("AlternateSet", |ctx| {
776 ctx.in_field("alternate_glyph_ids", |ctx| {
777 if self.alternate_glyph_ids.len() > to_usize(u16::MAX) {
778 ctx.report("array exceeds max length");
779 }
780 });
781 })
782 }
783}
784
785impl<'a> FromObjRef<read_fonts::tables::gsub::AlternateSet<'a>> for AlternateSet {
786 fn from_obj_ref(obj: &read_fonts::tables::gsub::AlternateSet<'a>, _: FontData) -> Self {
787 let offset_data = obj.offset_data();
788 AlternateSet {
789 alternate_glyph_ids: obj.alternate_glyph_ids().to_owned_obj(offset_data),
790 }
791 }
792}
793
794#[allow(clippy::needless_lifetimes)]
795impl<'a> FromTableRef<read_fonts::tables::gsub::AlternateSet<'a>> for AlternateSet {}
796
797impl ReadArgs for AlternateSet {
798 type Args = ();
799}
800
801impl<'a> FontRead<'a> for AlternateSet {
802 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
803 <read_fonts::tables::gsub::AlternateSet as FontRead>::read(data).map(|x| x.to_owned_table())
804 }
805}
806
807#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
809#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
810pub struct LigatureSubstFormat1 {
811 pub coverage: OffsetMarker<CoverageTable>,
814 pub ligature_sets: Vec<OffsetMarker<LigatureSet>>,
817}
818
819impl LigatureSubstFormat1 {
820 pub fn new(coverage: CoverageTable, ligature_sets: Vec<LigatureSet>) -> Self {
822 Self {
823 coverage: coverage.into(),
824 ligature_sets: ligature_sets.into_iter().map(Into::into).collect(),
825 }
826 }
827}
828
829impl FontWrite for LigatureSubstFormat1 {
830 #[allow(clippy::unnecessary_cast)]
831 fn write_into(&self, writer: &mut TableWriter) {
832 (1 as u16).write_into(writer);
833 self.coverage.write_into(writer);
834 (u16::try_from(array_len(&self.ligature_sets)).unwrap()).write_into(writer);
835 self.ligature_sets.write_into(writer);
836 }
837 fn table_type(&self) -> TableType {
838 TableType::Named("LigatureSubstFormat1")
839 }
840}
841
842impl Validate for LigatureSubstFormat1 {
843 fn validate_impl(&self, ctx: &mut ValidationCtx) {
844 ctx.in_table("LigatureSubstFormat1", |ctx| {
845 ctx.in_field("coverage", |ctx| {
846 self.coverage.validate_impl(ctx);
847 });
848 ctx.in_field("ligature_sets", |ctx| {
849 if self.ligature_sets.len() > to_usize(u16::MAX) {
850 ctx.report("array exceeds max length");
851 }
852 self.ligature_sets.validate_impl(ctx);
853 });
854 })
855 }
856}
857
858impl<'a> FromObjRef<read_fonts::tables::gsub::LigatureSubstFormat1<'a>> for LigatureSubstFormat1 {
859 fn from_obj_ref(obj: &read_fonts::tables::gsub::LigatureSubstFormat1<'a>, _: FontData) -> Self {
860 LigatureSubstFormat1 {
861 coverage: obj.coverage().to_owned_table(),
862 ligature_sets: obj.ligature_sets().to_owned_table(),
863 }
864 }
865}
866
867#[allow(clippy::needless_lifetimes)]
868impl<'a> FromTableRef<read_fonts::tables::gsub::LigatureSubstFormat1<'a>> for LigatureSubstFormat1 {}
869
870impl ReadArgs for LigatureSubstFormat1 {
871 type Args = ();
872}
873
874impl<'a> FontRead<'a> for LigatureSubstFormat1 {
875 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
876 <read_fonts::tables::gsub::LigatureSubstFormat1 as FontRead>::read(data)
877 .map(|x| x.to_owned_table())
878 }
879}
880
881#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
883#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
884pub struct LigatureSet {
885 pub ligatures: Vec<OffsetMarker<Ligature>>,
888}
889
890impl LigatureSet {
891 pub fn new(ligatures: Vec<Ligature>) -> Self {
893 Self {
894 ligatures: ligatures.into_iter().map(Into::into).collect(),
895 }
896 }
897}
898
899impl FontWrite for LigatureSet {
900 #[allow(clippy::unnecessary_cast)]
901 fn write_into(&self, writer: &mut TableWriter) {
902 (u16::try_from(array_len(&self.ligatures)).unwrap()).write_into(writer);
903 self.ligatures.write_into(writer);
904 }
905 fn table_type(&self) -> TableType {
906 TableType::Named("LigatureSet")
907 }
908}
909
910impl Validate for LigatureSet {
911 fn validate_impl(&self, ctx: &mut ValidationCtx) {
912 ctx.in_table("LigatureSet", |ctx| {
913 ctx.in_field("ligatures", |ctx| {
914 if self.ligatures.len() > to_usize(u16::MAX) {
915 ctx.report("array exceeds max length");
916 }
917 self.ligatures.validate_impl(ctx);
918 });
919 })
920 }
921}
922
923impl<'a> FromObjRef<read_fonts::tables::gsub::LigatureSet<'a>> for LigatureSet {
924 fn from_obj_ref(obj: &read_fonts::tables::gsub::LigatureSet<'a>, _: FontData) -> Self {
925 LigatureSet {
926 ligatures: obj.ligatures().to_owned_table(),
927 }
928 }
929}
930
931#[allow(clippy::needless_lifetimes)]
932impl<'a> FromTableRef<read_fonts::tables::gsub::LigatureSet<'a>> for LigatureSet {}
933
934impl ReadArgs for LigatureSet {
935 type Args = ();
936}
937
938impl<'a> FontRead<'a> for LigatureSet {
939 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
940 <read_fonts::tables::gsub::LigatureSet as FontRead>::read(data).map(|x| x.to_owned_table())
941 }
942}
943
944#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
946#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
947pub struct Ligature {
948 pub ligature_glyph: GlyphId16,
950 pub component_glyph_ids: Vec<GlyphId16>,
953}
954
955impl Ligature {
956 pub fn new(ligature_glyph: GlyphId16, component_glyph_ids: Vec<GlyphId16>) -> Self {
958 Self {
959 ligature_glyph,
960 component_glyph_ids,
961 }
962 }
963}
964
965impl FontWrite for Ligature {
966 #[allow(clippy::unnecessary_cast)]
967 fn write_into(&self, writer: &mut TableWriter) {
968 self.ligature_glyph.write_into(writer);
969 (u16::try_from(plus_one(&self.component_glyph_ids.len())).unwrap()).write_into(writer);
970 self.component_glyph_ids.write_into(writer);
971 }
972 fn table_type(&self) -> TableType {
973 TableType::Named("Ligature")
974 }
975}
976
977impl Validate for Ligature {
978 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
979}
980
981impl<'a> FromObjRef<read_fonts::tables::gsub::Ligature<'a>> for Ligature {
982 fn from_obj_ref(obj: &read_fonts::tables::gsub::Ligature<'a>, _: FontData) -> Self {
983 let offset_data = obj.offset_data();
984 Ligature {
985 ligature_glyph: obj.ligature_glyph(),
986 component_glyph_ids: obj.component_glyph_ids().to_owned_obj(offset_data),
987 }
988 }
989}
990
991#[allow(clippy::needless_lifetimes)]
992impl<'a> FromTableRef<read_fonts::tables::gsub::Ligature<'a>> for Ligature {}
993
994impl ReadArgs for Ligature {
995 type Args = ();
996}
997
998impl<'a> FontRead<'a> for Ligature {
999 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1000 <read_fonts::tables::gsub::Ligature as FontRead>::read(data).map(|x| x.to_owned_table())
1001 }
1002}
1003
1004#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1006#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1007pub struct ExtensionSubstFormat1<T> {
1008 pub extension_lookup_type: u16,
1011 pub extension: OffsetMarker<T, WIDTH_32>,
1015}
1016
1017impl<T: Default> ExtensionSubstFormat1<T> {
1018 pub fn new(extension_lookup_type: u16, extension: T) -> Self {
1020 Self {
1021 extension_lookup_type,
1022 extension: extension.into(),
1023 }
1024 }
1025}
1026
1027impl<T: Validate> Validate for ExtensionSubstFormat1<T> {
1028 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1029 ctx.in_table("ExtensionSubstFormat1", |ctx| {
1030 ctx.in_field("extension", |ctx| {
1031 self.extension.validate_impl(ctx);
1032 });
1033 })
1034 }
1035}
1036
1037impl<'a, T, U> FromObjRef<read_fonts::tables::gsub::ExtensionSubstFormat1<'a, U>>
1038 for ExtensionSubstFormat1<T>
1039where
1040 U: FontRead<'a, Args = ()>,
1041 T: FromTableRef<U> + Default + 'static,
1042{
1043 fn from_obj_ref(
1044 obj: &read_fonts::tables::gsub::ExtensionSubstFormat1<'a, U>,
1045 _: FontData,
1046 ) -> Self {
1047 ExtensionSubstFormat1 {
1048 extension_lookup_type: obj.extension_lookup_type(),
1049 extension: obj.extension().to_owned_table(),
1050 }
1051 }
1052}
1053
1054#[allow(clippy::needless_lifetimes)]
1055impl<'a, T, U> FromTableRef<read_fonts::tables::gsub::ExtensionSubstFormat1<'a, U>>
1056 for ExtensionSubstFormat1<T>
1057where
1058 U: FontRead<'a, Args = ()>,
1059 T: FromTableRef<U> + Default + 'static,
1060{
1061}
1062
1063#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1065#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1066pub enum ExtensionSubtable {
1067 Single(ExtensionSubstFormat1<SingleSubst>),
1068 Multiple(ExtensionSubstFormat1<MultipleSubst>),
1069 Alternate(ExtensionSubstFormat1<AlternateSubst>),
1070 Ligature(ExtensionSubstFormat1<LigatureSubst>),
1071 Contextual(ExtensionSubstFormat1<SubstitutionSequenceContext>),
1072 ChainContextual(ExtensionSubstFormat1<SubstitutionChainContext>),
1073 Reverse(ExtensionSubstFormat1<ReverseChainSingleSubst>),
1074}
1075
1076impl Default for ExtensionSubtable {
1077 fn default() -> Self {
1078 Self::Single(Default::default())
1079 }
1080}
1081
1082impl FontWrite for ExtensionSubtable {
1083 fn write_into(&self, writer: &mut TableWriter) {
1084 match self {
1085 Self::Single(table) => table.write_into(writer),
1086 Self::Multiple(table) => table.write_into(writer),
1087 Self::Alternate(table) => table.write_into(writer),
1088 Self::Ligature(table) => table.write_into(writer),
1089 Self::Contextual(table) => table.write_into(writer),
1090 Self::ChainContextual(table) => table.write_into(writer),
1091 Self::Reverse(table) => table.write_into(writer),
1092 }
1093 }
1094 fn table_type(&self) -> TableType {
1095 match self {
1096 Self::Single(table) => table.table_type(),
1097 Self::Multiple(table) => table.table_type(),
1098 Self::Alternate(table) => table.table_type(),
1099 Self::Ligature(table) => table.table_type(),
1100 Self::Contextual(table) => table.table_type(),
1101 Self::ChainContextual(table) => table.table_type(),
1102 Self::Reverse(table) => table.table_type(),
1103 }
1104 }
1105}
1106
1107impl Validate for ExtensionSubtable {
1108 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1109 match self {
1110 Self::Single(table) => table.validate_impl(ctx),
1111 Self::Multiple(table) => table.validate_impl(ctx),
1112 Self::Alternate(table) => table.validate_impl(ctx),
1113 Self::Ligature(table) => table.validate_impl(ctx),
1114 Self::Contextual(table) => table.validate_impl(ctx),
1115 Self::ChainContextual(table) => table.validate_impl(ctx),
1116 Self::Reverse(table) => table.validate_impl(ctx),
1117 }
1118 }
1119}
1120
1121impl FromObjRef<read_fonts::tables::gsub::ExtensionSubtable<'_>> for ExtensionSubtable {
1122 fn from_obj_ref(
1123 from: &read_fonts::tables::gsub::ExtensionSubtable<'_>,
1124 data: FontData,
1125 ) -> Self {
1126 match from {
1127 read_fonts::tables::gsub::ExtensionSubtable::Single(table) => {
1128 Self::Single(table.to_owned_obj(data))
1129 }
1130 read_fonts::tables::gsub::ExtensionSubtable::Multiple(table) => {
1131 Self::Multiple(table.to_owned_obj(data))
1132 }
1133 read_fonts::tables::gsub::ExtensionSubtable::Alternate(table) => {
1134 Self::Alternate(table.to_owned_obj(data))
1135 }
1136 read_fonts::tables::gsub::ExtensionSubtable::Ligature(table) => {
1137 Self::Ligature(table.to_owned_obj(data))
1138 }
1139 read_fonts::tables::gsub::ExtensionSubtable::Contextual(table) => {
1140 Self::Contextual(table.to_owned_obj(data))
1141 }
1142 read_fonts::tables::gsub::ExtensionSubtable::ChainContextual(table) => {
1143 Self::ChainContextual(table.to_owned_obj(data))
1144 }
1145 read_fonts::tables::gsub::ExtensionSubtable::Reverse(table) => {
1146 Self::Reverse(table.to_owned_obj(data))
1147 }
1148 }
1149 }
1150}
1151
1152impl FromTableRef<read_fonts::tables::gsub::ExtensionSubtable<'_>> for ExtensionSubtable {}
1153
1154impl From<ExtensionSubstFormat1<SingleSubst>> for ExtensionSubtable {
1155 fn from(src: ExtensionSubstFormat1<SingleSubst>) -> ExtensionSubtable {
1156 ExtensionSubtable::Single(src)
1157 }
1158}
1159
1160impl From<ExtensionSubstFormat1<MultipleSubst>> for ExtensionSubtable {
1161 fn from(src: ExtensionSubstFormat1<MultipleSubst>) -> ExtensionSubtable {
1162 ExtensionSubtable::Multiple(src)
1163 }
1164}
1165
1166impl From<ExtensionSubstFormat1<AlternateSubst>> for ExtensionSubtable {
1167 fn from(src: ExtensionSubstFormat1<AlternateSubst>) -> ExtensionSubtable {
1168 ExtensionSubtable::Alternate(src)
1169 }
1170}
1171
1172impl From<ExtensionSubstFormat1<LigatureSubst>> for ExtensionSubtable {
1173 fn from(src: ExtensionSubstFormat1<LigatureSubst>) -> ExtensionSubtable {
1174 ExtensionSubtable::Ligature(src)
1175 }
1176}
1177
1178impl From<ExtensionSubstFormat1<SubstitutionSequenceContext>> for ExtensionSubtable {
1179 fn from(src: ExtensionSubstFormat1<SubstitutionSequenceContext>) -> ExtensionSubtable {
1180 ExtensionSubtable::Contextual(src)
1181 }
1182}
1183
1184impl From<ExtensionSubstFormat1<SubstitutionChainContext>> for ExtensionSubtable {
1185 fn from(src: ExtensionSubstFormat1<SubstitutionChainContext>) -> ExtensionSubtable {
1186 ExtensionSubtable::ChainContextual(src)
1187 }
1188}
1189
1190impl From<ExtensionSubstFormat1<ReverseChainSingleSubst>> for ExtensionSubtable {
1191 fn from(src: ExtensionSubstFormat1<ReverseChainSingleSubst>) -> ExtensionSubtable {
1192 ExtensionSubtable::Reverse(src)
1193 }
1194}
1195
1196#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1198#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1199pub struct ReverseChainSingleSubstFormat1 {
1200 pub coverage: OffsetMarker<CoverageTable>,
1203 pub backtrack_coverages: Vec<OffsetMarker<CoverageTable>>,
1206 pub lookahead_coverages: Vec<OffsetMarker<CoverageTable>>,
1209 pub substitute_glyph_ids: Vec<GlyphId16>,
1211}
1212
1213impl ReverseChainSingleSubstFormat1 {
1214 pub fn new(
1216 coverage: CoverageTable,
1217 backtrack_coverages: Vec<CoverageTable>,
1218 lookahead_coverages: Vec<CoverageTable>,
1219 substitute_glyph_ids: Vec<GlyphId16>,
1220 ) -> Self {
1221 Self {
1222 coverage: coverage.into(),
1223 backtrack_coverages: backtrack_coverages.into_iter().map(Into::into).collect(),
1224 lookahead_coverages: lookahead_coverages.into_iter().map(Into::into).collect(),
1225 substitute_glyph_ids,
1226 }
1227 }
1228}
1229
1230impl FontWrite for ReverseChainSingleSubstFormat1 {
1231 #[allow(clippy::unnecessary_cast)]
1232 fn write_into(&self, writer: &mut TableWriter) {
1233 (1 as u16).write_into(writer);
1234 self.coverage.write_into(writer);
1235 (u16::try_from(array_len(&self.backtrack_coverages)).unwrap()).write_into(writer);
1236 self.backtrack_coverages.write_into(writer);
1237 (u16::try_from(array_len(&self.lookahead_coverages)).unwrap()).write_into(writer);
1238 self.lookahead_coverages.write_into(writer);
1239 (u16::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
1240 self.substitute_glyph_ids.write_into(writer);
1241 }
1242 fn table_type(&self) -> TableType {
1243 TableType::Named("ReverseChainSingleSubstFormat1")
1244 }
1245}
1246
1247impl Validate for ReverseChainSingleSubstFormat1 {
1248 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1249 ctx.in_table("ReverseChainSingleSubstFormat1", |ctx| {
1250 ctx.in_field("coverage", |ctx| {
1251 self.coverage.validate_impl(ctx);
1252 });
1253 ctx.in_field("backtrack_coverages", |ctx| {
1254 if self.backtrack_coverages.len() > to_usize(u16::MAX) {
1255 ctx.report("array exceeds max length");
1256 }
1257 self.backtrack_coverages.validate_impl(ctx);
1258 });
1259 ctx.in_field("lookahead_coverages", |ctx| {
1260 if self.lookahead_coverages.len() > to_usize(u16::MAX) {
1261 ctx.report("array exceeds max length");
1262 }
1263 self.lookahead_coverages.validate_impl(ctx);
1264 });
1265 ctx.in_field("substitute_glyph_ids", |ctx| {
1266 if self.substitute_glyph_ids.len() > to_usize(u16::MAX) {
1267 ctx.report("array exceeds max length");
1268 }
1269 });
1270 })
1271 }
1272}
1273
1274impl<'a> FromObjRef<read_fonts::tables::gsub::ReverseChainSingleSubstFormat1<'a>>
1275 for ReverseChainSingleSubstFormat1
1276{
1277 fn from_obj_ref(
1278 obj: &read_fonts::tables::gsub::ReverseChainSingleSubstFormat1<'a>,
1279 _: FontData,
1280 ) -> Self {
1281 let offset_data = obj.offset_data();
1282 ReverseChainSingleSubstFormat1 {
1283 coverage: obj.coverage().to_owned_table(),
1284 backtrack_coverages: obj.backtrack_coverages().to_owned_table(),
1285 lookahead_coverages: obj.lookahead_coverages().to_owned_table(),
1286 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
1287 }
1288 }
1289}
1290
1291#[allow(clippy::needless_lifetimes)]
1292impl<'a> FromTableRef<read_fonts::tables::gsub::ReverseChainSingleSubstFormat1<'a>>
1293 for ReverseChainSingleSubstFormat1
1294{
1295}
1296
1297impl ReadArgs for ReverseChainSingleSubstFormat1 {
1298 type Args = ();
1299}
1300
1301impl<'a> FontRead<'a> for ReverseChainSingleSubstFormat1 {
1302 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1303 <read_fonts::tables::gsub::ReverseChainSingleSubstFormat1 as FontRead>::read(data)
1304 .map(|x| x.to_owned_table())
1305 }
1306}
1307
1308#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1310#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1311pub struct SingleSubstFormat3 {
1312 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1315 pub delta_glyph_id: Int24,
1317}
1318
1319impl SingleSubstFormat3 {
1320 pub fn new(coverage: CoverageTable, delta_glyph_id: Int24) -> Self {
1322 Self {
1323 coverage: coverage.into(),
1324 delta_glyph_id,
1325 }
1326 }
1327}
1328
1329impl FontWrite for SingleSubstFormat3 {
1330 #[allow(clippy::unnecessary_cast)]
1331 fn write_into(&self, writer: &mut TableWriter) {
1332 (3 as u16).write_into(writer);
1333 self.coverage.write_into(writer);
1334 self.delta_glyph_id.write_into(writer);
1335 }
1336 fn table_type(&self) -> TableType {
1337 TableType::Named("SingleSubstFormat3")
1338 }
1339}
1340
1341impl Validate for SingleSubstFormat3 {
1342 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1343 ctx.in_table("SingleSubstFormat3", |ctx| {
1344 ctx.in_field("coverage", |ctx| {
1345 self.coverage.validate_impl(ctx);
1346 });
1347 })
1348 }
1349}
1350
1351impl<'a> FromObjRef<read_fonts::tables::gsub::SingleSubstFormat3<'a>> for SingleSubstFormat3 {
1352 fn from_obj_ref(obj: &read_fonts::tables::gsub::SingleSubstFormat3<'a>, _: FontData) -> Self {
1353 SingleSubstFormat3 {
1354 coverage: obj.coverage().to_owned_table(),
1355 delta_glyph_id: obj.delta_glyph_id(),
1356 }
1357 }
1358}
1359
1360#[allow(clippy::needless_lifetimes)]
1361impl<'a> FromTableRef<read_fonts::tables::gsub::SingleSubstFormat3<'a>> for SingleSubstFormat3 {}
1362
1363impl ReadArgs for SingleSubstFormat3 {
1364 type Args = ();
1365}
1366
1367impl<'a> FontRead<'a> for SingleSubstFormat3 {
1368 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1369 <read_fonts::tables::gsub::SingleSubstFormat3 as FontRead>::read(data)
1370 .map(|x| x.to_owned_table())
1371 }
1372}
1373
1374#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1376#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1377pub struct SingleSubstFormat4 {
1378 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1381 pub substitute_glyph_ids: Vec<GlyphId24>,
1383}
1384
1385impl SingleSubstFormat4 {
1386 pub fn new(coverage: CoverageTable, substitute_glyph_ids: Vec<GlyphId24>) -> Self {
1388 Self {
1389 coverage: coverage.into(),
1390 substitute_glyph_ids,
1391 }
1392 }
1393}
1394
1395impl FontWrite for SingleSubstFormat4 {
1396 #[allow(clippy::unnecessary_cast)]
1397 fn write_into(&self, writer: &mut TableWriter) {
1398 (4 as u16).write_into(writer);
1399 self.coverage.write_into(writer);
1400 (Uint24::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
1401 self.substitute_glyph_ids.write_into(writer);
1402 }
1403 fn table_type(&self) -> TableType {
1404 TableType::Named("SingleSubstFormat4")
1405 }
1406}
1407
1408impl Validate for SingleSubstFormat4 {
1409 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1410 ctx.in_table("SingleSubstFormat4", |ctx| {
1411 ctx.in_field("coverage", |ctx| {
1412 self.coverage.validate_impl(ctx);
1413 });
1414 ctx.in_field("substitute_glyph_ids", |ctx| {
1415 if self.substitute_glyph_ids.len() > to_usize(Uint24::MAX) {
1416 ctx.report("array exceeds max length");
1417 }
1418 });
1419 })
1420 }
1421}
1422
1423impl<'a> FromObjRef<read_fonts::tables::gsub::SingleSubstFormat4<'a>> for SingleSubstFormat4 {
1424 fn from_obj_ref(obj: &read_fonts::tables::gsub::SingleSubstFormat4<'a>, _: FontData) -> Self {
1425 let offset_data = obj.offset_data();
1426 SingleSubstFormat4 {
1427 coverage: obj.coverage().to_owned_table(),
1428 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
1429 }
1430 }
1431}
1432
1433#[allow(clippy::needless_lifetimes)]
1434impl<'a> FromTableRef<read_fonts::tables::gsub::SingleSubstFormat4<'a>> for SingleSubstFormat4 {}
1435
1436impl ReadArgs for SingleSubstFormat4 {
1437 type Args = ();
1438}
1439
1440impl<'a> FontRead<'a> for SingleSubstFormat4 {
1441 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1442 <read_fonts::tables::gsub::SingleSubstFormat4 as FontRead>::read(data)
1443 .map(|x| x.to_owned_table())
1444 }
1445}
1446
1447#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1449#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1450pub struct MultipleSubstFormat2 {
1451 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1454 pub sequences: Vec<OffsetMarker<Sequence2, WIDTH_24>>,
1457}
1458
1459impl MultipleSubstFormat2 {
1460 pub fn new(coverage: CoverageTable, sequences: Vec<Sequence2>) -> Self {
1462 Self {
1463 coverage: coverage.into(),
1464 sequences: sequences.into_iter().map(Into::into).collect(),
1465 }
1466 }
1467}
1468
1469impl FontWrite for MultipleSubstFormat2 {
1470 #[allow(clippy::unnecessary_cast)]
1471 fn write_into(&self, writer: &mut TableWriter) {
1472 (2 as u16).write_into(writer);
1473 self.coverage.write_into(writer);
1474 (Uint24::try_from(array_len(&self.sequences)).unwrap()).write_into(writer);
1475 self.sequences.write_into(writer);
1476 }
1477 fn table_type(&self) -> TableType {
1478 TableType::Named("MultipleSubstFormat2")
1479 }
1480}
1481
1482impl Validate for MultipleSubstFormat2 {
1483 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1484 ctx.in_table("MultipleSubstFormat2", |ctx| {
1485 ctx.in_field("coverage", |ctx| {
1486 self.coverage.validate_impl(ctx);
1487 });
1488 ctx.in_field("sequences", |ctx| {
1489 if self.sequences.len() > to_usize(Uint24::MAX) {
1490 ctx.report("array exceeds max length");
1491 }
1492 self.sequences.validate_impl(ctx);
1493 });
1494 })
1495 }
1496}
1497
1498impl<'a> FromObjRef<read_fonts::tables::gsub::MultipleSubstFormat2<'a>> for MultipleSubstFormat2 {
1499 fn from_obj_ref(obj: &read_fonts::tables::gsub::MultipleSubstFormat2<'a>, _: FontData) -> Self {
1500 MultipleSubstFormat2 {
1501 coverage: obj.coverage().to_owned_table(),
1502 sequences: obj.sequences().to_owned_table(),
1503 }
1504 }
1505}
1506
1507#[allow(clippy::needless_lifetimes)]
1508impl<'a> FromTableRef<read_fonts::tables::gsub::MultipleSubstFormat2<'a>> for MultipleSubstFormat2 {}
1509
1510impl ReadArgs for MultipleSubstFormat2 {
1511 type Args = ();
1512}
1513
1514impl<'a> FontRead<'a> for MultipleSubstFormat2 {
1515 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1516 <read_fonts::tables::gsub::MultipleSubstFormat2 as FontRead>::read(data)
1517 .map(|x| x.to_owned_table())
1518 }
1519}
1520
1521#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1523#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1524pub struct AlternateSubstFormat2 {
1525 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1528 pub alternate_sets: Vec<OffsetMarker<AlternateSet2, WIDTH_24>>,
1531}
1532
1533impl AlternateSubstFormat2 {
1534 pub fn new(coverage: CoverageTable, alternate_sets: Vec<AlternateSet2>) -> Self {
1536 Self {
1537 coverage: coverage.into(),
1538 alternate_sets: alternate_sets.into_iter().map(Into::into).collect(),
1539 }
1540 }
1541}
1542
1543impl FontWrite for AlternateSubstFormat2 {
1544 #[allow(clippy::unnecessary_cast)]
1545 fn write_into(&self, writer: &mut TableWriter) {
1546 (2 as u16).write_into(writer);
1547 self.coverage.write_into(writer);
1548 (Uint24::try_from(array_len(&self.alternate_sets)).unwrap()).write_into(writer);
1549 self.alternate_sets.write_into(writer);
1550 }
1551 fn table_type(&self) -> TableType {
1552 TableType::Named("AlternateSubstFormat2")
1553 }
1554}
1555
1556impl Validate for AlternateSubstFormat2 {
1557 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1558 ctx.in_table("AlternateSubstFormat2", |ctx| {
1559 ctx.in_field("coverage", |ctx| {
1560 self.coverage.validate_impl(ctx);
1561 });
1562 ctx.in_field("alternate_sets", |ctx| {
1563 if self.alternate_sets.len() > to_usize(Uint24::MAX) {
1564 ctx.report("array exceeds max length");
1565 }
1566 self.alternate_sets.validate_impl(ctx);
1567 });
1568 })
1569 }
1570}
1571
1572impl<'a> FromObjRef<read_fonts::tables::gsub::AlternateSubstFormat2<'a>> for AlternateSubstFormat2 {
1573 fn from_obj_ref(
1574 obj: &read_fonts::tables::gsub::AlternateSubstFormat2<'a>,
1575 _: FontData,
1576 ) -> Self {
1577 AlternateSubstFormat2 {
1578 coverage: obj.coverage().to_owned_table(),
1579 alternate_sets: obj.alternate_sets().to_owned_table(),
1580 }
1581 }
1582}
1583
1584#[allow(clippy::needless_lifetimes)]
1585impl<'a> FromTableRef<read_fonts::tables::gsub::AlternateSubstFormat2<'a>>
1586 for AlternateSubstFormat2
1587{
1588}
1589
1590impl ReadArgs for AlternateSubstFormat2 {
1591 type Args = ();
1592}
1593
1594impl<'a> FontRead<'a> for AlternateSubstFormat2 {
1595 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1596 <read_fonts::tables::gsub::AlternateSubstFormat2 as FontRead>::read(data)
1597 .map(|x| x.to_owned_table())
1598 }
1599}
1600
1601#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1603#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1604pub struct LigatureSubstFormat2 {
1605 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1608 pub ligature_sets: Vec<OffsetMarker<LigatureSet2, WIDTH_24>>,
1611}
1612
1613impl LigatureSubstFormat2 {
1614 pub fn new(coverage: CoverageTable, ligature_sets: Vec<LigatureSet2>) -> Self {
1616 Self {
1617 coverage: coverage.into(),
1618 ligature_sets: ligature_sets.into_iter().map(Into::into).collect(),
1619 }
1620 }
1621}
1622
1623impl FontWrite for LigatureSubstFormat2 {
1624 #[allow(clippy::unnecessary_cast)]
1625 fn write_into(&self, writer: &mut TableWriter) {
1626 (2 as u16).write_into(writer);
1627 self.coverage.write_into(writer);
1628 (Uint24::try_from(array_len(&self.ligature_sets)).unwrap()).write_into(writer);
1629 self.ligature_sets.write_into(writer);
1630 }
1631 fn table_type(&self) -> TableType {
1632 TableType::Named("LigatureSubstFormat2")
1633 }
1634}
1635
1636impl Validate for LigatureSubstFormat2 {
1637 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1638 ctx.in_table("LigatureSubstFormat2", |ctx| {
1639 ctx.in_field("coverage", |ctx| {
1640 self.coverage.validate_impl(ctx);
1641 });
1642 ctx.in_field("ligature_sets", |ctx| {
1643 if self.ligature_sets.len() > to_usize(Uint24::MAX) {
1644 ctx.report("array exceeds max length");
1645 }
1646 self.ligature_sets.validate_impl(ctx);
1647 });
1648 })
1649 }
1650}
1651
1652impl<'a> FromObjRef<read_fonts::tables::gsub::LigatureSubstFormat2<'a>> for LigatureSubstFormat2 {
1653 fn from_obj_ref(obj: &read_fonts::tables::gsub::LigatureSubstFormat2<'a>, _: FontData) -> Self {
1654 LigatureSubstFormat2 {
1655 coverage: obj.coverage().to_owned_table(),
1656 ligature_sets: obj.ligature_sets().to_owned_table(),
1657 }
1658 }
1659}
1660
1661#[allow(clippy::needless_lifetimes)]
1662impl<'a> FromTableRef<read_fonts::tables::gsub::LigatureSubstFormat2<'a>> for LigatureSubstFormat2 {}
1663
1664impl ReadArgs for LigatureSubstFormat2 {
1665 type Args = ();
1666}
1667
1668impl<'a> FontRead<'a> for LigatureSubstFormat2 {
1669 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1670 <read_fonts::tables::gsub::LigatureSubstFormat2 as FontRead>::read(data)
1671 .map(|x| x.to_owned_table())
1672 }
1673}
1674
1675#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1677#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1678pub struct ReverseChainSingleSubstFormat2 {
1679 pub coverage: OffsetMarker<CoverageTable, WIDTH_32>,
1682 pub backtrack_coverages: Vec<OffsetMarker<CoverageTable, WIDTH_24>>,
1685 pub lookahead_coverages: Vec<OffsetMarker<CoverageTable, WIDTH_24>>,
1688 pub substitute_glyph_ids: Vec<GlyphId24>,
1690}
1691
1692impl ReverseChainSingleSubstFormat2 {
1693 pub fn new(
1695 coverage: CoverageTable,
1696 backtrack_coverages: Vec<CoverageTable>,
1697 lookahead_coverages: Vec<CoverageTable>,
1698 substitute_glyph_ids: Vec<GlyphId24>,
1699 ) -> Self {
1700 Self {
1701 coverage: coverage.into(),
1702 backtrack_coverages: backtrack_coverages.into_iter().map(Into::into).collect(),
1703 lookahead_coverages: lookahead_coverages.into_iter().map(Into::into).collect(),
1704 substitute_glyph_ids,
1705 }
1706 }
1707}
1708
1709impl FontWrite for ReverseChainSingleSubstFormat2 {
1710 #[allow(clippy::unnecessary_cast)]
1711 fn write_into(&self, writer: &mut TableWriter) {
1712 (2 as u16).write_into(writer);
1713 self.coverage.write_into(writer);
1714 (u16::try_from(array_len(&self.backtrack_coverages)).unwrap()).write_into(writer);
1715 self.backtrack_coverages.write_into(writer);
1716 (u16::try_from(array_len(&self.lookahead_coverages)).unwrap()).write_into(writer);
1717 self.lookahead_coverages.write_into(writer);
1718 (Uint24::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
1719 self.substitute_glyph_ids.write_into(writer);
1720 }
1721 fn table_type(&self) -> TableType {
1722 TableType::Named("ReverseChainSingleSubstFormat2")
1723 }
1724}
1725
1726impl Validate for ReverseChainSingleSubstFormat2 {
1727 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1728 ctx.in_table("ReverseChainSingleSubstFormat2", |ctx| {
1729 ctx.in_field("coverage", |ctx| {
1730 self.coverage.validate_impl(ctx);
1731 });
1732 ctx.in_field("backtrack_coverages", |ctx| {
1733 if self.backtrack_coverages.len() > to_usize(u16::MAX) {
1734 ctx.report("array exceeds max length");
1735 }
1736 self.backtrack_coverages.validate_impl(ctx);
1737 });
1738 ctx.in_field("lookahead_coverages", |ctx| {
1739 if self.lookahead_coverages.len() > to_usize(u16::MAX) {
1740 ctx.report("array exceeds max length");
1741 }
1742 self.lookahead_coverages.validate_impl(ctx);
1743 });
1744 ctx.in_field("substitute_glyph_ids", |ctx| {
1745 if self.substitute_glyph_ids.len() > to_usize(Uint24::MAX) {
1746 ctx.report("array exceeds max length");
1747 }
1748 });
1749 })
1750 }
1751}
1752
1753impl<'a> FromObjRef<read_fonts::tables::gsub::ReverseChainSingleSubstFormat2<'a>>
1754 for ReverseChainSingleSubstFormat2
1755{
1756 fn from_obj_ref(
1757 obj: &read_fonts::tables::gsub::ReverseChainSingleSubstFormat2<'a>,
1758 _: FontData,
1759 ) -> Self {
1760 let offset_data = obj.offset_data();
1761 ReverseChainSingleSubstFormat2 {
1762 coverage: obj.coverage().to_owned_table(),
1763 backtrack_coverages: obj.backtrack_coverages().to_owned_table(),
1764 lookahead_coverages: obj.lookahead_coverages().to_owned_table(),
1765 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
1766 }
1767 }
1768}
1769
1770#[allow(clippy::needless_lifetimes)]
1771impl<'a> FromTableRef<read_fonts::tables::gsub::ReverseChainSingleSubstFormat2<'a>>
1772 for ReverseChainSingleSubstFormat2
1773{
1774}
1775
1776impl ReadArgs for ReverseChainSingleSubstFormat2 {
1777 type Args = ();
1778}
1779
1780impl<'a> FontRead<'a> for ReverseChainSingleSubstFormat2 {
1781 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1782 <read_fonts::tables::gsub::ReverseChainSingleSubstFormat2 as FontRead>::read(data)
1783 .map(|x| x.to_owned_table())
1784 }
1785}
1786
1787#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1789#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1790pub struct Sequence2 {
1791 pub substitute_glyph_ids: Vec<GlyphId24>,
1793}
1794
1795impl Sequence2 {
1796 pub fn new(substitute_glyph_ids: Vec<GlyphId24>) -> Self {
1798 Self {
1799 substitute_glyph_ids,
1800 }
1801 }
1802}
1803
1804impl FontWrite for Sequence2 {
1805 #[allow(clippy::unnecessary_cast)]
1806 fn write_into(&self, writer: &mut TableWriter) {
1807 (u16::try_from(array_len(&self.substitute_glyph_ids)).unwrap()).write_into(writer);
1808 self.substitute_glyph_ids.write_into(writer);
1809 }
1810 fn table_type(&self) -> TableType {
1811 TableType::Named("Sequence2")
1812 }
1813}
1814
1815impl Validate for Sequence2 {
1816 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1817 ctx.in_table("Sequence2", |ctx| {
1818 ctx.in_field("substitute_glyph_ids", |ctx| {
1819 if self.substitute_glyph_ids.len() > to_usize(u16::MAX) {
1820 ctx.report("array exceeds max length");
1821 }
1822 });
1823 })
1824 }
1825}
1826
1827impl<'a> FromObjRef<read_fonts::tables::gsub::Sequence2<'a>> for Sequence2 {
1828 fn from_obj_ref(obj: &read_fonts::tables::gsub::Sequence2<'a>, _: FontData) -> Self {
1829 let offset_data = obj.offset_data();
1830 Sequence2 {
1831 substitute_glyph_ids: obj.substitute_glyph_ids().to_owned_obj(offset_data),
1832 }
1833 }
1834}
1835
1836#[allow(clippy::needless_lifetimes)]
1837impl<'a> FromTableRef<read_fonts::tables::gsub::Sequence2<'a>> for Sequence2 {}
1838
1839impl ReadArgs for Sequence2 {
1840 type Args = ();
1841}
1842
1843impl<'a> FontRead<'a> for Sequence2 {
1844 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1845 <read_fonts::tables::gsub::Sequence2 as FontRead>::read(data).map(|x| x.to_owned_table())
1846 }
1847}
1848
1849#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1851#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1852pub struct AlternateSet2 {
1853 pub alternate_glyph_ids: Vec<GlyphId24>,
1855}
1856
1857impl AlternateSet2 {
1858 pub fn new(alternate_glyph_ids: Vec<GlyphId24>) -> Self {
1860 Self {
1861 alternate_glyph_ids,
1862 }
1863 }
1864}
1865
1866impl FontWrite for AlternateSet2 {
1867 #[allow(clippy::unnecessary_cast)]
1868 fn write_into(&self, writer: &mut TableWriter) {
1869 (u16::try_from(array_len(&self.alternate_glyph_ids)).unwrap()).write_into(writer);
1870 self.alternate_glyph_ids.write_into(writer);
1871 }
1872 fn table_type(&self) -> TableType {
1873 TableType::Named("AlternateSet2")
1874 }
1875}
1876
1877impl Validate for AlternateSet2 {
1878 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1879 ctx.in_table("AlternateSet2", |ctx| {
1880 ctx.in_field("alternate_glyph_ids", |ctx| {
1881 if self.alternate_glyph_ids.len() > to_usize(u16::MAX) {
1882 ctx.report("array exceeds max length");
1883 }
1884 });
1885 })
1886 }
1887}
1888
1889impl<'a> FromObjRef<read_fonts::tables::gsub::AlternateSet2<'a>> for AlternateSet2 {
1890 fn from_obj_ref(obj: &read_fonts::tables::gsub::AlternateSet2<'a>, _: FontData) -> Self {
1891 let offset_data = obj.offset_data();
1892 AlternateSet2 {
1893 alternate_glyph_ids: obj.alternate_glyph_ids().to_owned_obj(offset_data),
1894 }
1895 }
1896}
1897
1898#[allow(clippy::needless_lifetimes)]
1899impl<'a> FromTableRef<read_fonts::tables::gsub::AlternateSet2<'a>> for AlternateSet2 {}
1900
1901impl ReadArgs for AlternateSet2 {
1902 type Args = ();
1903}
1904
1905impl<'a> FontRead<'a> for AlternateSet2 {
1906 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1907 <read_fonts::tables::gsub::AlternateSet2 as FontRead>::read(data)
1908 .map(|x| x.to_owned_table())
1909 }
1910}
1911
1912#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1914#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1915pub struct LigatureSet2 {
1916 pub ligatures: Vec<OffsetMarker<Ligature2, WIDTH_24>>,
1919}
1920
1921impl LigatureSet2 {
1922 pub fn new(ligatures: Vec<Ligature2>) -> Self {
1924 Self {
1925 ligatures: ligatures.into_iter().map(Into::into).collect(),
1926 }
1927 }
1928}
1929
1930impl FontWrite for LigatureSet2 {
1931 #[allow(clippy::unnecessary_cast)]
1932 fn write_into(&self, writer: &mut TableWriter) {
1933 (u16::try_from(array_len(&self.ligatures)).unwrap()).write_into(writer);
1934 self.ligatures.write_into(writer);
1935 }
1936 fn table_type(&self) -> TableType {
1937 TableType::Named("LigatureSet2")
1938 }
1939}
1940
1941impl Validate for LigatureSet2 {
1942 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1943 ctx.in_table("LigatureSet2", |ctx| {
1944 ctx.in_field("ligatures", |ctx| {
1945 if self.ligatures.len() > to_usize(u16::MAX) {
1946 ctx.report("array exceeds max length");
1947 }
1948 self.ligatures.validate_impl(ctx);
1949 });
1950 })
1951 }
1952}
1953
1954impl<'a> FromObjRef<read_fonts::tables::gsub::LigatureSet2<'a>> for LigatureSet2 {
1955 fn from_obj_ref(obj: &read_fonts::tables::gsub::LigatureSet2<'a>, _: FontData) -> Self {
1956 LigatureSet2 {
1957 ligatures: obj.ligatures().to_owned_table(),
1958 }
1959 }
1960}
1961
1962#[allow(clippy::needless_lifetimes)]
1963impl<'a> FromTableRef<read_fonts::tables::gsub::LigatureSet2<'a>> for LigatureSet2 {}
1964
1965impl ReadArgs for LigatureSet2 {
1966 type Args = ();
1967}
1968
1969impl<'a> FontRead<'a> for LigatureSet2 {
1970 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
1971 <read_fonts::tables::gsub::LigatureSet2 as FontRead>::read(data).map(|x| x.to_owned_table())
1972 }
1973}
1974
1975#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1977#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1978pub struct Ligature2 {
1979 pub ligature_glyph: GlyphId24,
1981 pub component_glyph_ids: Vec<GlyphId24>,
1984}
1985
1986impl Ligature2 {
1987 pub fn new(ligature_glyph: GlyphId24, component_glyph_ids: Vec<GlyphId24>) -> Self {
1989 Self {
1990 ligature_glyph,
1991 component_glyph_ids,
1992 }
1993 }
1994}
1995
1996impl FontWrite for Ligature2 {
1997 #[allow(clippy::unnecessary_cast)]
1998 fn write_into(&self, writer: &mut TableWriter) {
1999 self.ligature_glyph.write_into(writer);
2000 (u16::try_from(plus_one(&self.component_glyph_ids.len())).unwrap()).write_into(writer);
2001 self.component_glyph_ids.write_into(writer);
2002 }
2003 fn table_type(&self) -> TableType {
2004 TableType::Named("Ligature2")
2005 }
2006}
2007
2008impl Validate for Ligature2 {
2009 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
2010}
2011
2012impl<'a> FromObjRef<read_fonts::tables::gsub::Ligature2<'a>> for Ligature2 {
2013 fn from_obj_ref(obj: &read_fonts::tables::gsub::Ligature2<'a>, _: FontData) -> Self {
2014 let offset_data = obj.offset_data();
2015 Ligature2 {
2016 ligature_glyph: obj.ligature_glyph(),
2017 component_glyph_ids: obj.component_glyph_ids().to_owned_obj(offset_data),
2018 }
2019 }
2020}
2021
2022#[allow(clippy::needless_lifetimes)]
2023impl<'a> FromTableRef<read_fonts::tables::gsub::Ligature2<'a>> for Ligature2 {}
2024
2025impl ReadArgs for Ligature2 {
2026 type Args = ();
2027}
2028
2029impl<'a> FontRead<'a> for Ligature2 {
2030 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2031 <read_fonts::tables::gsub::Ligature2 as FontRead>::read(data).map(|x| x.to_owned_table())
2032 }
2033}
2034
2035#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2037#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2038pub enum MultipleSubst {
2039 Format1(MultipleSubstFormat1),
2040 Format2(MultipleSubstFormat2),
2041}
2042
2043impl MultipleSubst {
2044 pub fn format_1(coverage: CoverageTable, sequences: Vec<Sequence>) -> Self {
2046 Self::Format1(MultipleSubstFormat1::new(coverage, sequences))
2047 }
2048
2049 pub fn format_2(coverage: CoverageTable, sequences: Vec<Sequence2>) -> Self {
2051 Self::Format2(MultipleSubstFormat2::new(coverage, sequences))
2052 }
2053}
2054
2055impl Default for MultipleSubst {
2056 fn default() -> Self {
2057 Self::Format1(Default::default())
2058 }
2059}
2060
2061impl FontWrite for MultipleSubst {
2062 fn write_into(&self, writer: &mut TableWriter) {
2063 match self {
2064 Self::Format1(item) => item.write_into(writer),
2065 Self::Format2(item) => item.write_into(writer),
2066 }
2067 }
2068 fn table_type(&self) -> TableType {
2069 match self {
2070 Self::Format1(item) => item.table_type(),
2071 Self::Format2(item) => item.table_type(),
2072 }
2073 }
2074}
2075
2076impl Validate for MultipleSubst {
2077 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2078 match self {
2079 Self::Format1(item) => item.validate_impl(ctx),
2080 Self::Format2(item) => item.validate_impl(ctx),
2081 }
2082 }
2083}
2084
2085impl FromObjRef<read_fonts::tables::gsub::MultipleSubst<'_>> for MultipleSubst {
2086 fn from_obj_ref(obj: &read_fonts::tables::gsub::MultipleSubst, _: FontData) -> Self {
2087 use read_fonts::tables::gsub::MultipleSubst as ObjRefType;
2088 match obj {
2089 ObjRefType::Format1(item) => MultipleSubst::Format1(item.to_owned_table()),
2090 ObjRefType::Format2(item) => MultipleSubst::Format2(item.to_owned_table()),
2091 }
2092 }
2093}
2094
2095impl FromTableRef<read_fonts::tables::gsub::MultipleSubst<'_>> for MultipleSubst {}
2096
2097impl ReadArgs for MultipleSubst {
2098 type Args = ();
2099}
2100
2101impl<'a> FontRead<'a> for MultipleSubst {
2102 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2103 <read_fonts::tables::gsub::MultipleSubst as FontRead>::read(data)
2104 .map(|x| x.to_owned_table())
2105 }
2106}
2107
2108impl From<MultipleSubstFormat1> for MultipleSubst {
2109 fn from(src: MultipleSubstFormat1) -> MultipleSubst {
2110 MultipleSubst::Format1(src)
2111 }
2112}
2113
2114impl From<MultipleSubstFormat2> for MultipleSubst {
2115 fn from(src: MultipleSubstFormat2) -> MultipleSubst {
2116 MultipleSubst::Format2(src)
2117 }
2118}
2119
2120#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2122#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2123pub enum AlternateSubst {
2124 Format1(AlternateSubstFormat1),
2125 Format2(AlternateSubstFormat2),
2126}
2127
2128impl AlternateSubst {
2129 pub fn format_1(coverage: CoverageTable, alternate_sets: Vec<AlternateSet>) -> Self {
2131 Self::Format1(AlternateSubstFormat1::new(coverage, alternate_sets))
2132 }
2133
2134 pub fn format_2(coverage: CoverageTable, alternate_sets: Vec<AlternateSet2>) -> Self {
2136 Self::Format2(AlternateSubstFormat2::new(coverage, alternate_sets))
2137 }
2138}
2139
2140impl Default for AlternateSubst {
2141 fn default() -> Self {
2142 Self::Format1(Default::default())
2143 }
2144}
2145
2146impl FontWrite for AlternateSubst {
2147 fn write_into(&self, writer: &mut TableWriter) {
2148 match self {
2149 Self::Format1(item) => item.write_into(writer),
2150 Self::Format2(item) => item.write_into(writer),
2151 }
2152 }
2153 fn table_type(&self) -> TableType {
2154 match self {
2155 Self::Format1(item) => item.table_type(),
2156 Self::Format2(item) => item.table_type(),
2157 }
2158 }
2159}
2160
2161impl Validate for AlternateSubst {
2162 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2163 match self {
2164 Self::Format1(item) => item.validate_impl(ctx),
2165 Self::Format2(item) => item.validate_impl(ctx),
2166 }
2167 }
2168}
2169
2170impl FromObjRef<read_fonts::tables::gsub::AlternateSubst<'_>> for AlternateSubst {
2171 fn from_obj_ref(obj: &read_fonts::tables::gsub::AlternateSubst, _: FontData) -> Self {
2172 use read_fonts::tables::gsub::AlternateSubst as ObjRefType;
2173 match obj {
2174 ObjRefType::Format1(item) => AlternateSubst::Format1(item.to_owned_table()),
2175 ObjRefType::Format2(item) => AlternateSubst::Format2(item.to_owned_table()),
2176 }
2177 }
2178}
2179
2180impl FromTableRef<read_fonts::tables::gsub::AlternateSubst<'_>> for AlternateSubst {}
2181
2182impl ReadArgs for AlternateSubst {
2183 type Args = ();
2184}
2185
2186impl<'a> FontRead<'a> for AlternateSubst {
2187 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2188 <read_fonts::tables::gsub::AlternateSubst as FontRead>::read(data)
2189 .map(|x| x.to_owned_table())
2190 }
2191}
2192
2193impl From<AlternateSubstFormat1> for AlternateSubst {
2194 fn from(src: AlternateSubstFormat1) -> AlternateSubst {
2195 AlternateSubst::Format1(src)
2196 }
2197}
2198
2199impl From<AlternateSubstFormat2> for AlternateSubst {
2200 fn from(src: AlternateSubstFormat2) -> AlternateSubst {
2201 AlternateSubst::Format2(src)
2202 }
2203}
2204
2205#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2207#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2208pub enum LigatureSubst {
2209 Format1(LigatureSubstFormat1),
2210 Format2(LigatureSubstFormat2),
2211}
2212
2213impl LigatureSubst {
2214 pub fn format_1(coverage: CoverageTable, ligature_sets: Vec<LigatureSet>) -> Self {
2216 Self::Format1(LigatureSubstFormat1::new(coverage, ligature_sets))
2217 }
2218
2219 pub fn format_2(coverage: CoverageTable, ligature_sets: Vec<LigatureSet2>) -> Self {
2221 Self::Format2(LigatureSubstFormat2::new(coverage, ligature_sets))
2222 }
2223}
2224
2225impl Default for LigatureSubst {
2226 fn default() -> Self {
2227 Self::Format1(Default::default())
2228 }
2229}
2230
2231impl FontWrite for LigatureSubst {
2232 fn write_into(&self, writer: &mut TableWriter) {
2233 match self {
2234 Self::Format1(item) => item.write_into(writer),
2235 Self::Format2(item) => item.write_into(writer),
2236 }
2237 }
2238 fn table_type(&self) -> TableType {
2239 match self {
2240 Self::Format1(item) => item.table_type(),
2241 Self::Format2(item) => item.table_type(),
2242 }
2243 }
2244}
2245
2246impl Validate for LigatureSubst {
2247 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2248 match self {
2249 Self::Format1(item) => item.validate_impl(ctx),
2250 Self::Format2(item) => item.validate_impl(ctx),
2251 }
2252 }
2253}
2254
2255impl FromObjRef<read_fonts::tables::gsub::LigatureSubst<'_>> for LigatureSubst {
2256 fn from_obj_ref(obj: &read_fonts::tables::gsub::LigatureSubst, _: FontData) -> Self {
2257 use read_fonts::tables::gsub::LigatureSubst as ObjRefType;
2258 match obj {
2259 ObjRefType::Format1(item) => LigatureSubst::Format1(item.to_owned_table()),
2260 ObjRefType::Format2(item) => LigatureSubst::Format2(item.to_owned_table()),
2261 }
2262 }
2263}
2264
2265impl FromTableRef<read_fonts::tables::gsub::LigatureSubst<'_>> for LigatureSubst {}
2266
2267impl ReadArgs for LigatureSubst {
2268 type Args = ();
2269}
2270
2271impl<'a> FontRead<'a> for LigatureSubst {
2272 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2273 <read_fonts::tables::gsub::LigatureSubst as FontRead>::read(data)
2274 .map(|x| x.to_owned_table())
2275 }
2276}
2277
2278impl From<LigatureSubstFormat1> for LigatureSubst {
2279 fn from(src: LigatureSubstFormat1) -> LigatureSubst {
2280 LigatureSubst::Format1(src)
2281 }
2282}
2283
2284impl From<LigatureSubstFormat2> for LigatureSubst {
2285 fn from(src: LigatureSubstFormat2) -> LigatureSubst {
2286 LigatureSubst::Format2(src)
2287 }
2288}
2289
2290#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2292#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2293pub enum ReverseChainSingleSubst {
2294 Format1(ReverseChainSingleSubstFormat1),
2295 Format2(ReverseChainSingleSubstFormat2),
2296}
2297
2298impl ReverseChainSingleSubst {
2299 pub fn format_1(
2301 coverage: CoverageTable,
2302 backtrack_coverages: Vec<CoverageTable>,
2303 lookahead_coverages: Vec<CoverageTable>,
2304 substitute_glyph_ids: Vec<GlyphId16>,
2305 ) -> Self {
2306 Self::Format1(ReverseChainSingleSubstFormat1::new(
2307 coverage,
2308 backtrack_coverages,
2309 lookahead_coverages,
2310 substitute_glyph_ids,
2311 ))
2312 }
2313
2314 pub fn format_2(
2316 coverage: CoverageTable,
2317 backtrack_coverages: Vec<CoverageTable>,
2318 lookahead_coverages: Vec<CoverageTable>,
2319 substitute_glyph_ids: Vec<GlyphId24>,
2320 ) -> Self {
2321 Self::Format2(ReverseChainSingleSubstFormat2::new(
2322 coverage,
2323 backtrack_coverages,
2324 lookahead_coverages,
2325 substitute_glyph_ids,
2326 ))
2327 }
2328}
2329
2330impl Default for ReverseChainSingleSubst {
2331 fn default() -> Self {
2332 Self::Format1(Default::default())
2333 }
2334}
2335
2336impl FontWrite for ReverseChainSingleSubst {
2337 fn write_into(&self, writer: &mut TableWriter) {
2338 match self {
2339 Self::Format1(item) => item.write_into(writer),
2340 Self::Format2(item) => item.write_into(writer),
2341 }
2342 }
2343 fn table_type(&self) -> TableType {
2344 match self {
2345 Self::Format1(item) => item.table_type(),
2346 Self::Format2(item) => item.table_type(),
2347 }
2348 }
2349}
2350
2351impl Validate for ReverseChainSingleSubst {
2352 fn validate_impl(&self, ctx: &mut ValidationCtx) {
2353 match self {
2354 Self::Format1(item) => item.validate_impl(ctx),
2355 Self::Format2(item) => item.validate_impl(ctx),
2356 }
2357 }
2358}
2359
2360impl FromObjRef<read_fonts::tables::gsub::ReverseChainSingleSubst<'_>> for ReverseChainSingleSubst {
2361 fn from_obj_ref(obj: &read_fonts::tables::gsub::ReverseChainSingleSubst, _: FontData) -> Self {
2362 use read_fonts::tables::gsub::ReverseChainSingleSubst as ObjRefType;
2363 match obj {
2364 ObjRefType::Format1(item) => ReverseChainSingleSubst::Format1(item.to_owned_table()),
2365 ObjRefType::Format2(item) => ReverseChainSingleSubst::Format2(item.to_owned_table()),
2366 }
2367 }
2368}
2369
2370impl FromTableRef<read_fonts::tables::gsub::ReverseChainSingleSubst<'_>>
2371 for ReverseChainSingleSubst
2372{
2373}
2374
2375impl ReadArgs for ReverseChainSingleSubst {
2376 type Args = ();
2377}
2378
2379impl<'a> FontRead<'a> for ReverseChainSingleSubst {
2380 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
2381 <read_fonts::tables::gsub::ReverseChainSingleSubst as FontRead>::read(data)
2382 .map(|x| x.to_owned_table())
2383 }
2384}
2385
2386impl From<ReverseChainSingleSubstFormat1> for ReverseChainSingleSubst {
2387 fn from(src: ReverseChainSingleSubstFormat1) -> ReverseChainSingleSubst {
2388 ReverseChainSingleSubst::Format1(src)
2389 }
2390}
2391
2392impl From<ReverseChainSingleSubstFormat2> for ReverseChainSingleSubst {
2393 fn from(src: ReverseChainSingleSubstFormat2) -> ReverseChainSingleSubst {
2394 ReverseChainSingleSubst::Format2(src)
2395 }
2396}