From bc061e9abd092369ac5c2e7613dc6167a7d502ef Mon Sep 17 00:00:00 2001 From: Peter Duchovni Date: Thu, 28 Nov 2024 09:16:31 +1100 Subject: [PATCH] ChainedSequenceContexts support, otf_metrics tweaks --- doodle-formats/src/format/opentype.rs | 169 +++++++- generated/api_helper/otf_metrics.rs | 595 +++++++++++++++++++------- generated/sample_codegen.rs | 548 ++++++++++++++++++++++-- 3 files changed, 1118 insertions(+), 194 deletions(-) diff --git a/doodle-formats/src/format/opentype.rs b/doodle-formats/src/format/opentype.rs index 0d02b95f..f7636a35 100644 --- a/doodle-formats/src/format/opentype.rs +++ b/doodle-formats/src/format/opentype.rs @@ -384,9 +384,8 @@ pub fn main(module: &mut FormatModule, base: &BaseModule) -> FormatRef { const SHORT_OFFSET16: u16 = 0; const LONG_OFFSET32: u16 = 1; - let table_record = module.define_format_args( + let table_record = module.define_format( "opentype.table_record", - vec![START_ARG], record([ ("table_id", tag.call()), // should be ascending within the repetition "table_records" field in table_directory ("checksum", base.u32be()), @@ -2528,9 +2527,21 @@ pub fn main(module: &mut FormatModule, base: &BaseModule) -> FormatRef { match_variant( var("format"), [ - (Pattern::U16(1), "Format1", sequence_context_format1(var("table_start"))), - (Pattern::U16(2), "Format2", sequence_context_format2(var("table_start"))), - (Pattern::U16(3), "Format3", sequence_context_format3(var("table_start"))), + ( + Pattern::U16(1), + "Format1", + sequence_context_format1(var("table_start")), + ), + ( + Pattern::U16(2), + "Format2", + sequence_context_format2(var("table_start")), + ), + ( + Pattern::U16(3), + "Format3", + sequence_context_format3(var("table_start")), + ), (Pattern::Wildcard, "BadFormat", Format::Fail), ], ), @@ -2539,8 +2550,147 @@ pub fn main(module: &mut FormatModule, base: &BaseModule) -> FormatRef { ) }; let chained_sequence_context = { - /* STUB */ - module.define_format("opentype.common.chained_sequence_context", Format::EMPTY) + let rule_set = { + let chained_sequence_rule = record([ + ("backtrack_glyph_count", base.u16be()), + ( + "backtrack_sequence", + repeat_count(var("backtrack_glyph_count"), base.u16be()), + ), + ("input_glyph_count", base.u16be()), + ( + "input_sequence", + repeat_count(sub(var("input_glyph_count"), Expr::U16(1)), base.u16be()), + ), + ("lookahead_glyph_count", base.u16be()), + ( + "lookahead_sequence", + repeat_count(var("lookahead_glyph_count"), base.u16be()), + ), + ("seq_lookup_count", base.u16be()), + ( + "seq_lookup_records", + repeat_count(var("seq_lookup_count"), sequence_lookup_record.call()), + ), + ]); + record([ + ("table_start", pos32()), + ("chained_seq_rule_count", base.u16be()), + ( + "chained_seq_rules", + repeat_count(var("chained_seq_rule_count"), chained_sequence_rule), + ), + ]) + }; + let chained_sequence_context_format1 = |table_start: Expr| { + record([ + ( + "coverage", + offset16(table_start.clone(), coverage_table.call(), base), + ), + ("chained_seq_rule_set_count", base.u16be()), + ( + "chained_seq_rule_sets", + repeat_count( + var("chained_seq_rule_set_count"), + offset16(table_start, rule_set.clone(), base), + ), + ), + ]) + }; + let chained_sequence_context_format2 = |table_start: Expr| { + record([ + ( + "coverage", + offset16(table_start.clone(), coverage_table.call(), base), + ), + ( + "backtrack_class_def", + offset16(table_start.clone(), class_def.call(), base), + ), + ( + "input_class_def", + offset16(table_start.clone(), class_def.call(), base), + ), + ( + "lookahead_class_def", + offset16(table_start.clone(), class_def.call(), base), + ), + ("chained_class_seq_rule_set_count", base.u16be()), + ( + "chained_class_seq_rule_sets", + repeat_count( + var("chained_class_seq_rule_set_count"), + offset16(table_start, rule_set.clone(), base), + ), + ), + ]) + }; + let chained_sequence_context_format3 = |table_start: Expr| { + record([ + ("backtrack_glyph_count", base.u16be()), + ( + "backtrack_coverages", + repeat_count( + var("backtrack_glyph_count"), + offset16(table_start.clone(), coverage_table.call(), base), + ), + ), + ("input_glyph_count", base.u16be()), + ( + "input_coverages", + repeat_count( + var("input_glyph_count"), + offset16(table_start.clone(), coverage_table.call(), base), + ), + ), + ("lookahead_glyph_count", base.u16be()), + ( + "lookahead_coverages", + repeat_count( + var("lookahead_glyph_count"), + offset16(table_start, coverage_table.call(), base), + ), + ), + ("seq_lookup_count", base.u16be()), + ( + "seq_lookup_records", + repeat_count(var("seq_lookup_count"), sequence_lookup_record.call()), + ), + ]) + }; + module.define_format( + "opentype.common.chained_sequence_context", + record([ + ("table_start", pos32()), + ("format", base.u16be()), + // REVIEW - this is a GSUB-biased field-name, do we have a better field-name for this? + ( + "subst", + match_variant( + var("format"), + [ + ( + Pattern::U16(1), + "Format1", + chained_sequence_context_format1(var("table_start")), + ), + ( + Pattern::U16(2), + "Format2", + chained_sequence_context_format2(var("table_start")), + ), + ( + Pattern::U16(3), + "Format3", + chained_sequence_context_format3(var("table_start")), + ), + (Pattern::Wildcard, "BadFormat", Format::Fail), + ], + ), + ), + ]), + ) }; let layout_table = |tag: u32| { @@ -3108,10 +3258,7 @@ pub fn main(module: &mut FormatModule, base: &BaseModule) -> FormatRef { ("range_shift", base.u16be()), // TODO[validation] - should be (NumTables x 16) - searchRange ( "table_records", - repeat_count( - var("num_tables"), - table_record.call_args(vec![var("start")]), - ), + repeat_count(var("num_tables"), table_record.call()), ), ( "table_links", diff --git a/generated/api_helper/otf_metrics.rs b/generated/api_helper/otf_metrics.rs index e3c744a3..7bfbb9ec 100644 --- a/generated/api_helper/otf_metrics.rs +++ b/generated/api_helper/otf_metrics.rs @@ -140,8 +140,7 @@ trait TryPromote: Sized { fn try_promote(orig: &Original) -> Result; } -trait TryFromRef: Sized -{ +trait TryFromRef: Sized { type Error: std::error::Error; /// Fallibly convert from the GAT `Ref<'a>` defined on Original, into `Self`. @@ -208,8 +207,98 @@ impl Promote for T { orig.clone() } } + +/// Type-agnostic macro for dereferencing machine-generated Offset16 abstactions +/// into Option of the promotable dereference-value +macro_rules! promote_link { + () => { + (|offset| promote_opt(&offset.link)) + }; +} + // !SECTION +// SECTION - Generic (but niche-use-case) helper definitions +#[derive(Clone)] +#[repr(transparent)] +struct SemVec { + inner: Vec, + __proxy: std::marker::PhantomData, +} + +impl SemVec { + pub fn new() -> Self { + Self { + inner: Vec::new(), + __proxy: std::marker::PhantomData, + } + } + + pub fn with_capacity(cap: usize) -> Self { + Self { + inner: Vec::with_capacity(cap), + __proxy: std::marker::PhantomData, + } + } +} + +impl From> for SemVec { + fn from(v: Vec) -> Self { + Self { + inner: v, + __proxy: std::marker::PhantomData, + } + } +} + +impl FromIterator for SemVec { + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + Self { + inner: Vec::from_iter(iter), + __proxy: std::marker::PhantomData, + } + } +} + +impl std::fmt::Debug for SemVec +where + T: std::fmt::Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // REVIEW - consider whether we need this distinction when ChainedRule already discriminates on Sem + f.debug_tuple("ClassIds").field(&self.inner).finish() + } +} + +impl std::fmt::Debug for SemVec +where + T: std::fmt::Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // REVIEW - consider whether we need this distinction when ChainedRule already discriminates on Sem + f.debug_tuple("GlyphIds").field(&self.inner).finish() + } +} + +impl std::ops::Deref for SemVec { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +/// Marker type for indicating a SemVec (or any types above it) holds GlyphId-semantics u16 values +#[derive(Clone)] +struct GlyphId; +/// Marker type for indicating a SemVec (or any types above it) holds ClassId-semantics u16 values +#[derive(Clone)] +struct ClassId; + +// !SECTION /// Crate-private mirco-module for compile-time same-type assertions that can be chained pub(crate) mod refl { pub(crate) trait Refl { @@ -791,10 +880,7 @@ impl TryPromote for MarkGlyphSet { type ItemVariationStore = u32; impl TryPromote for GdefTableDataMetrics { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeGdefTableData) -> Result { Ok(match orig { @@ -802,10 +888,8 @@ impl TryPromote for GdefTableDataMetrics { OpentypeGdefTableData::Version1_2(opentype_gdef_table_data_Version1_2 { mark_glyph_sets_def, }) => { - GdefTableDataMetrics::MarkGlyphSetsDef( - try_promote_opt(&mark_glyph_sets_def.link)? - ) - }, + GdefTableDataMetrics::MarkGlyphSetsDef(try_promote_opt(&mark_glyph_sets_def.link)?) + } OpentypeGdefTableData::Version1_3(opentype_gdef_table_data_Version1_3 { item_var_store, }) => GdefTableDataMetrics::ItemVarStore(*item_var_store), @@ -926,7 +1010,7 @@ impl Promote for AttachList { attach_points: orig .attach_point_offsets .iter() - .map(|offset| promote_opt(&offset.link)) + .map(promote_link!()) .collect(), } } @@ -941,10 +1025,7 @@ struct LigCaretList { type OpentypeLigCaretList = opentype_gdef_table_lig_caret_list_link; impl TryPromote for LigCaretList { - type Error = ReflType< - TPErr, - UnknownValueError - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeLigCaretList) -> Result { let mut lig_glyphs = Vec::with_capacity(orig.lig_glyph_offsets.len()); @@ -966,10 +1047,7 @@ struct LigGlyph { type OpentypeLigGlyph = opentype_gdef_table_lig_caret_list_link_lig_glyph_offsets_link; impl TryPromote for LigGlyph { - type Error = ReflType< - TPErr, - UnknownValueError - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeLigGlyph) -> Result { let mut caret_values = Vec::with_capacity(orig.caret_values.len()); @@ -1120,10 +1198,7 @@ type OpentypeVariationIndexTable = opentype_common_device_or_variation_index_table_VariationIndexTable; impl TryPromote for DeviceOrVariationIndexTable { - type Error = ReflType< - TFRErr<(u16, Vec), DeltaValues>, - UnknownValueError, - >; + type Error = ReflType), DeltaValues>, UnknownValueError>; fn try_promote(orig: &OpentypeDeviceOrVariationIndexTable) -> Result { match orig { @@ -1131,7 +1206,7 @@ impl TryPromote for DeviceOrVariationIndexT start_size, end_size, delta_format, - ref delta_values + ref delta_values, }) => Ok(DeviceOrVariationIndexTable::DeviceTable(DeviceTable { start_size, end_size, @@ -1154,10 +1229,7 @@ impl TryPromote for DeviceOrVariationIndexT } impl TryPromote for CaretValue { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeCaretValueRaw) -> Result { Self::try_promote(&orig.data) @@ -1320,8 +1392,8 @@ impl TryPromote for LookupSubtable { OpentypeGsubLookupSubtable::SequenceContext(seq_ctx) => { LookupSubtable::SequenceContext(SequenceContext::promote(seq_ctx)) } - OpentypeGsubLookupSubtable::ChainedSequenceContext => { - LookupSubtable::ChainedSequenceContext + OpentypeGsubLookupSubtable::ChainedSequenceContext(chain_ctx) => { + LookupSubtable::ChainedSequenceContext(ChainedSequenceContext::promote(chain_ctx)) } OpentypeGsubLookupSubtable::SubstExtension => LookupSubtable::SubstExtension, OpentypeGsubLookupSubtable::ReverseChainSingleSubst => { @@ -1333,14 +1405,8 @@ impl TryPromote for LookupSubtable { impl TryPromote for LookupSubtable { type Error = ReflType< - ReflType< - TPErr, - TPErr, - >, - ReflType< - TPErr, - UnknownValueError, - >, + ReflType, TPErr>, + ReflType, UnknownValueError>, >; fn try_promote(orig: &OpentypeGposLookupSubtable) -> Result { @@ -1360,8 +1426,8 @@ impl TryPromote for LookupSubtable { OpentypeGposLookupSubtable::SequenceContext(seq_ctx) => { LookupSubtable::SequenceContext(SequenceContext::promote(seq_ctx)) } - OpentypeGposLookupSubtable::ChainedSequenceContext => { - LookupSubtable::ChainedSequenceContext + OpentypeGposLookupSubtable::ChainedSequenceContext(chain_ctx) => { + LookupSubtable::ChainedSequenceContext(ChainedSequenceContext::promote(chain_ctx)) } OpentypeGposLookupSubtable::PosExtension => LookupSubtable::PosExtension, }) @@ -1379,7 +1445,7 @@ enum LookupSubtable { PosExtension, SequenceContext(SequenceContext), - ChainedSequenceContext, + ChainedSequenceContext(ChainedSequenceContext), SingleSubst, MultipleSubst, @@ -1389,6 +1455,188 @@ enum LookupSubtable { ReverseChainSingleSubst, } +pub type OpentypeChainedSequenceContext = opentype_common_chained_sequence_context; +pub type OpentypeChainedSequenceContextInner = opentype_common_chained_sequence_context_subst; +pub type OpentypeChainedSequenceContextFormat1 = + opentype_common_chained_sequence_context_subst_Format1; +pub type OpentypeChainedSequenceContextFormat2 = + opentype_common_chained_sequence_context_subst_Format2; +pub type OpentypeChainedSequenceContextFormat3 = + opentype_common_chained_sequence_context_subst_Format3; + +pub type OpentypeChainedRuleSet = + opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link; +pub type OpentypeChainedRule = opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link_chained_seq_rules; + +impl Promote for ChainedRuleSet +where + ChainedRule: Promote, +{ + fn promote(orig: &OpentypeChainedRuleSet) -> Self { + promote_vec(&orig.chained_seq_rules) + } +} + +impl Promote for ChainedRule { + fn promote(orig: &OpentypeChainedRule) -> Self { + ChainedRule { + backtrack_glyph_count: orig.backtrack_glyph_count, + backtrack_sequence: orig.backtrack_sequence.clone().into(), + input_glyph_count: orig.input_glyph_count, + input_sequence: orig.input_sequence.clone().into(), + lookahead_glyph_count: orig.lookahead_glyph_count, + lookahead_sequence: orig.lookahead_sequence.clone().into(), + seq_lookup_records: promote_vec(&orig.seq_lookup_records), + } + } +} + +type ChainedRuleSet = Vec>; + +#[derive(Clone)] +struct ChainedRule { + backtrack_glyph_count: u16, // REVIEW - this field can be re-synthesized from backtrack_sequence.len() + backtrack_sequence: SemVec, + input_glyph_count: u16, // REVIEW - this field can be re-synthesized from input_sequence.len() + 1 + input_sequence: SemVec, // NOTE - unlike the other two sequence-arrays, this one is one shorter than its associated glyph_count field + lookahead_glyph_count: u16, // REVIEW - this field can be re-synthesized from lookahead_sequence.len() + lookahead_sequence: SemVec, + seq_lookup_records: Vec, +} + +impl std::fmt::Debug for ChainedRule { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // REVIEW - at the debug level, present a view of ChainedRule as if it were its own type `ChainedSequenceRule` + f.debug_struct("ChainedSequenceRule") + .field("backtrack_glyph_count", &self.backtrack_glyph_count) + .field("backtrack_sequence", &self.backtrack_sequence) + .field("input_glyph_count", &self.input_glyph_count) + .field("input_sequence", &self.input_sequence) + .field("lookahead_glyph_count", &self.lookahead_glyph_count) + .field("lookahead_sequence", &self.lookahead_sequence) + .field("seq_lookup_records", &self.seq_lookup_records) + .finish() + } +} + +impl std::fmt::Debug for ChainedRule { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // REVIEW - at the debug level, present a view of ChainedRule as if it were its own type `ChainedClassSequenceRule` + f.debug_struct("ChainedClassSequenceRule") + .field("backtrack_glyph_count", &self.backtrack_glyph_count) + .field("backtrack_sequence", &self.backtrack_sequence) + .field("input_glyph_count", &self.input_glyph_count) + .field("input_sequence", &self.input_sequence) + .field("lookahead_glyph_count", &self.lookahead_glyph_count) + .field("lookahead_sequence", &self.lookahead_sequence) + .field("seq_lookup_records", &self.seq_lookup_records) + .finish() + } +} + +impl Promote for ChainedSequenceContext { + fn promote(orig: &OpentypeChainedSequenceContext) -> Self { + Self::promote(&orig.subst) + } +} + +impl Promote for ChainedSequenceContext { + fn promote(orig: &OpentypeChainedSequenceContextInner) -> Self { + match orig { + OpentypeChainedSequenceContextInner::Format1(f1) => { + ChainedSequenceContext::Format1(ChainedSequenceContextFormat1::promote(f1)) + } + OpentypeChainedSequenceContextInner::Format2(f2) => { + ChainedSequenceContext::Format2(ChainedSequenceContextFormat2::promote(f2)) + } + OpentypeChainedSequenceContextInner::Format3(f3) => { + ChainedSequenceContext::Format3(ChainedSequenceContextFormat3::promote(f3)) + } + } + } +} + +#[derive(Debug, Clone)] +enum ChainedSequenceContext { + Format1(ChainedSequenceContextFormat1), + Format2(ChainedSequenceContextFormat2), + Format3(ChainedSequenceContextFormat3), +} + +impl Promote for ChainedSequenceContextFormat1 { + fn promote(orig: &OpentypeChainedSequenceContextFormat1) -> Self { + ChainedSequenceContextFormat1 { + coverage: promote_opt(&orig.coverage.link), + chained_seq_rule_sets: orig + .chained_seq_rule_sets + .iter() + .map(promote_link!()) + .collect(), + } + } +} + +#[derive(Debug, Clone)] +struct ChainedSequenceContextFormat1 { + coverage: Option, + chained_seq_rule_sets: Vec>>, +} + +impl Promote for ChainedSequenceContextFormat2 { + fn promote(orig: &OpentypeChainedSequenceContextFormat2) -> Self { + Self { + coverage: promote_opt(&orig.coverage.link), + backtrack_class_def: promote_opt(&orig.backtrack_class_def.link), + input_class_def: promote_opt(&orig.input_class_def.link), + lookahead_class_def: promote_opt(&orig.lookahead_class_def.link), + chained_class_seq_rule_sets: orig + .chained_class_seq_rule_sets + .iter() + .map(promote_link!()) + .collect(), + } + } +} + +#[derive(Debug, Clone)] +struct ChainedSequenceContextFormat2 { + coverage: Option, + backtrack_class_def: Option, + input_class_def: Option, + lookahead_class_def: Option, + chained_class_seq_rule_sets: Vec>>, +} + +impl Promote for ChainedSequenceContextFormat3 { + fn promote(orig: &OpentypeChainedSequenceContextFormat3) -> Self { + type OpentypeCoverageTableLink = + opentype_common_chained_sequence_context_subst_Format1_coverage; + let follow = |covs: &Vec| -> Vec> { + covs.iter().map(promote_link!()).collect() + }; + Self { + backtrack_glyph_count: orig.backtrack_glyph_count, + backtrack_coverages: follow(&orig.backtrack_coverages), + input_glyph_count: orig.input_glyph_count, + input_coverages: follow(&orig.input_coverages), + lookahead_glyph_count: orig.lookahead_glyph_count, + lookahead_coverages: follow(&orig.lookahead_coverages), + seq_lookup_records: promote_vec(&orig.seq_lookup_records), + } + } +} + +#[derive(Debug, Clone)] +struct ChainedSequenceContextFormat3 { + backtrack_glyph_count: u16, // REVIEW - this field can be re-synthesized from `backtrack_coverages.len()` + backtrack_coverages: Vec>, + input_glyph_count: u16, // REVIEW - this field can be re-synthesized from `input_coverages.len()` + input_coverages: Vec>, + lookahead_glyph_count: u16, // REVIEW - this field can be re-synthesized from `lookahead_coverages.len()` + lookahead_coverages: Vec>, + seq_lookup_records: Vec, +} + pub type OpentypeSequenceContext = opentype_common_sequence_context; pub type OpentypeSequenceContextInner = opentype_common_sequence_context_subst; pub type OpentypeSequenceContextFormat1 = opentype_common_sequence_context_subst_Format1; @@ -1530,7 +1778,7 @@ impl Promote for Rule { #[derive(Debug, Clone)] struct Rule { - glyph_count: u16, // REVIEW <- this field can be re-synthesized via `input_sequence.len() + 1` + glyph_count: u16, // REVIEW - this field can be re-synthesized via `input_sequence.len() + 1` input_sequence: Vec, seq_lookup_records: Vec, } @@ -1545,10 +1793,7 @@ pub type OpentypeCursivePosFormat1 = opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_CursivePos_subtable_Format1; impl TryPromote for CursivePos { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeCursivePos) -> Result { CursivePos::try_promote(&orig.subtable) @@ -1556,10 +1801,8 @@ impl TryPromote for CursivePos { } impl TryPromote for CursivePos { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = + ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeCursivePosSubtable) -> Result { match orig { @@ -1576,10 +1819,7 @@ enum CursivePos { } impl TryPromote for CursivePosFormat1 { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeCursivePosFormat1) -> Result { Ok(CursivePosFormat1 { @@ -1598,10 +1838,7 @@ struct CursivePosFormat1 { pub type OpentypeEntryExitRecord = opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_CursivePos_subtable_Format1_entry_exit_records; impl TryPromote for EntryExitRecord { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeEntryExitRecord) -> Result { Ok(EntryExitRecord { @@ -1625,10 +1862,7 @@ pub type OpentypeAnchorTableFormat2 = opentype_common_anchor_table_table_Format2 pub type OpentypeAnchorTableFormat3 = opentype_common_anchor_table_table_Format3; impl TryPromote for AnchorTable { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeAnchorTable) -> Result { AnchorTable::try_promote(&orig.table) @@ -1636,10 +1870,8 @@ impl TryPromote for AnchorTable { } impl TryPromote for AnchorTable { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = + ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeAnchorTableTable) -> Result { Ok(match orig { @@ -1734,10 +1966,7 @@ pub type OpentypePairPosFormat2 = opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_PairPos_subtable_Format2; impl TryPromote for PairPos { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypePairPos) -> Result { Self::try_promote(&orig.subtable) @@ -1772,10 +2001,7 @@ enum PairPos { } impl TryPromote for PairPosFormat1 { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypePairPosFormat1) -> Result { let mut pair_sets = Vec::with_capacity(orig.pair_sets.len()); @@ -1792,10 +2018,7 @@ impl TryPromote for PairPosFormat1 { } impl TryPromote for PairPosFormat2 { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypePairPosFormat2) -> Result { let mut store = Vec::with_capacity(orig.class1_count as usize * orig.class2_count as usize); @@ -1835,10 +2058,7 @@ type Class1RecordList = Wec; pub type OpentypeClass2Record = opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_PairPos_subtable_Format2_class1_records_class2_records; impl TryPromote for Class2Record { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeClass2Record) -> Result { Ok(Class2Record { @@ -1860,10 +2080,7 @@ pub type OpentypePairValueRecord = opentype_gpos_table_lookup_list_link_lookups_ type PairSet = Vec; impl TryPromote for PairSet { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypePairSet) -> Result { let mut accum = Vec::with_capacity(orig.pair_value_records.len()); @@ -1875,10 +2092,7 @@ impl TryPromote for PairSet { } impl TryPromote for PairValueRecord { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypePairValueRecord) -> Result { Ok(PairValueRecord { @@ -1907,10 +2121,7 @@ pub type OpentypeSinglePosFormat2 = opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_SinglePos_subtable_Format2; impl TryPromote for SinglePos { - type Error = ReflType< - TPErr, - UnknownValueError - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeSinglePos) -> Result { Self::try_promote(&orig.subtable) @@ -1945,10 +2156,7 @@ enum SinglePos { } impl TryPromote for SinglePosFormat1 { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeSinglePosFormat1) -> Result { Ok(SinglePosFormat1 { @@ -1959,10 +2167,7 @@ impl TryPromote for SinglePosFormat1 { } impl TryPromote for SinglePosFormat2 { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeSinglePosFormat2) -> Result { let mut value_records = Vec::with_capacity(orig.value_records.len()); @@ -2045,10 +2250,7 @@ pub type OpentypeGsubLookupTable = opentype_gsub_table_lookup_list_link_lookups_ impl TryPromote for LookupTable { type Error = - ReflType< - TPErr, - UnknownValueError, - >; + ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeGposLookupTable) -> Result { let mut subtables = Vec::with_capacity(orig.subtables.len()); @@ -2066,12 +2268,11 @@ impl TryPromote for LookupTable { } impl TryPromote for LookupTable { - type Error = - ReflType< - TPErr, - std::convert::Infallible, - // may easily become `UnknownValueError` but infallible for now - >; + type Error = ReflType< + TPErr, + std::convert::Infallible, + // may easily become `UnknownValueError` but infallible for now + >; fn try_promote(orig: &OpentypeGsubLookupTable) -> Result { let mut subtables = Vec::with_capacity(orig.subtables.len()); @@ -2119,10 +2320,7 @@ pub type OpentypeGposLookupList = opentype_gpos_table_lookup_list_link; pub type OpentypeGsubLookupList = opentype_gsub_table_lookup_list_link; impl TryPromote for LookupList { - type Error = ReflType< - TPErr, - UnknownValueError, - >; + type Error = ReflType, UnknownValueError>; fn try_promote(orig: &OpentypeGposLookupList) -> Result { let mut accum = Vec::with_capacity(orig.lookups.len()); @@ -2897,7 +3095,11 @@ fn show_lookup_table(table: &LookupTable, ctxt: Ctxt, conf: &Config) { } // ANCHOR[format-lookup-subtable] -fn format_lookup_subtable(subtable: &Option, show_lookup_type: bool, _conf: &Config) -> String { +fn format_lookup_subtable( + subtable: &Option, + show_lookup_type: bool, + _conf: &Config, +) -> String { // STUB - because the subtables are both partial (more variants exist) and abridged (existing variants are missing details), reimplement as necessary if let Some(subtable) = subtable { let (label, contents) = match subtable { @@ -3022,13 +3224,13 @@ fn format_lookup_subtable(subtable: &Option, show_lookup_type: b seq_rule_sets, }) => { if let Some(coverage_table) = coverage { - format!("SimpleGlyphs({})", format_coverage_table(coverage_table)) + format!("Glyphs({})", format_coverage_table(coverage_table)) } else { assert!( seq_rule_sets.is_empty(), "non-empty seq_rule_sets has no coverage table to correspond to" ); - format!("SimpleGlyphs[0]") + format!("Glyphs[0]") } } SequenceContext::Format2(SequenceContextFormat2 { @@ -3037,10 +3239,10 @@ fn format_lookup_subtable(subtable: &Option, show_lookup_type: b .. }) => { if let Some(coverage_table) = coverage { - format!("ClassBased({})", format_coverage_table(coverage_table)) + format!("Classes({})", format_coverage_table(coverage_table)) } else { assert!(class_seq_rule_sets.is_empty(), "non-empty class_seq_rule_sets has no coverage table to correspond to"); - format!("ClassBased[0]") + format!("Classes[0]") } } SequenceContext::Format3(SequenceContextFormat3 { @@ -3053,22 +3255,124 @@ fn format_lookup_subtable(subtable: &Option, show_lookup_type: b // FIXME - show_lookup_table calls this function through show_items_inline already, so we might want to reduce how many values we are willing to show proportionally let input_pattern = format_items_inline( coverage_tables, - |cov| if let Some(coverage_table) = cov { format_coverage_table(coverage_table) } else { String::from("[]") }, + |cov| { + if let Some(coverage_table) = cov { + format_coverage_table(coverage_table) + } else { + String::from("[]") + } + }, INLINE_INLINE_BOOKEND, - |n| format!("(..{n}..)") + |n| format!("(..{n}..)"), ); let seq_lookups = format_items_inline( seq_lookup_records, |seq_lookup| format_sequence_lookup(seq_lookup), INLINE_INLINE_BOOKEND, - |n| format!("(..{n}..)") + |n| format!("(..{n}..)"), ); format!("{input_pattern}=>{seq_lookups}") } }; ("SeqCtx", contents) } - LookupSubtable::ChainedSequenceContext => ("ChainSeqCtx", format!("(..)")), + LookupSubtable::ChainedSequenceContext(chain_ctx) => { + let contents = match chain_ctx { + ChainedSequenceContext::Format1(ChainedSequenceContextFormat1 { + coverage, + chained_seq_rule_sets, + }) => { + if let Some(coverage_table) = coverage { + // TODO - even if it means overly verbose output, this might be too little info to be useful compared to discriminant-only display + format!("ChainedGlyphs({})", format_coverage_table(coverage_table)) + } else { + assert!(chained_seq_rule_sets.is_empty(), "non-empty chained_seq_rule_sets has no coverage table to correspond to"); + format!("ChainedGlyphs[0]") + } + } + ChainedSequenceContext::Format2(ChainedSequenceContextFormat2 { + coverage, + chained_class_seq_rule_sets, + .. + }) => { + if let Some(coverage_table) = coverage { + // TODO - even if it means overly verbose output, this might be too little info to be useful compared to discriminant-only display + // REVIEW - consider what other details (e.g. class-def summary metrics) to show in implicitly- or explictly-verbose display format + format!("ChainedClasses({})", format_coverage_table(coverage_table)) + } else { + assert!(chained_class_seq_rule_sets.is_empty(), "non-empty chained_class_seq_rule_sets has no coverage table to correspond to"); + format!("ChainedClases[0]") + } + } + ChainedSequenceContext::Format3(ChainedSequenceContextFormat3 { + backtrack_coverages, + input_coverages, + lookahead_coverages, + seq_lookup_records, + .. + }) => { + // REVIEW - since we are already within an inline elision context, try to avoid taking up too much space per item, but this might not want to be a hardcoded value + const INLINE_INLINE_BOOKEND: usize = 1; + // FIXME - show_lookup_table calls this function through show_items_inline already, so we might want to reduce how many values we are willing to show proportionally + let backtrack_pattern = if backtrack_coverages.is_empty() { + String::new() + } else { + let tmp = format_items_inline( + backtrack_coverages, + |cov| { + if let Some(coverage_table) = cov { + format_coverage_table(coverage_table) + } else { + String::from("[]") + } + }, + INLINE_INLINE_BOOKEND, + |n| format!("(..{n}..)"), + ); + format!("(?<={tmp})") + }; + let input_pattern = format_items_inline( + input_coverages, + |cov| { + if let Some(coverage_table) = cov { + format_coverage_table(coverage_table) + } else { + String::from("[]") + } + }, + INLINE_INLINE_BOOKEND, + |n| format!("(..{n}..)"), + ); + let lookahead_pattern = if lookahead_coverages.is_empty() { + String::new() + } else { + let tmp = format_items_inline( + lookahead_coverages, + |cov| { + if let Some(coverage_table) = cov { + format_coverage_table(coverage_table) + } else { + String::from("[]") + } + }, + INLINE_INLINE_BOOKEND, + |n| format!("(..{n}..)"), + ); + format!("(?={tmp})") + }; + let seq_lookups = format_items_inline( + seq_lookup_records, + |seq_lookup| format_sequence_lookup(seq_lookup), + INLINE_INLINE_BOOKEND, + |n| format!("(..{n}..)"), + ); + format!( + "{backtrack_pattern}{input_pattern}{lookahead_pattern}=>{seq_lookups}" + ) + } + }; + ("ChainSeqCtx", contents) + } }; if show_lookup_type { format!("{label}{contents}") @@ -3394,26 +3698,26 @@ fn format_coverage_table(cov: &CoverageTable) -> String { match cov { CoverageTable::Format1 { ref glyph_array } => { let num_glyphs = glyph_array.len(); - let first_glyph = glyph_array.first().expect("empty glyph-array"); - let last_glyph = glyph_array.last().expect("empty glyph-array"); - format!("[{num_glyphs} glyphs in [{first_glyph},{last_glyph}]]") - } - CoverageTable::Format2 { ref range_records } => { - let num_glyphs: u16 = range_records - .iter() - .map(|rr| rr.end_glyph_id - rr.start_glyph_id + 1) - .sum(); - let num_ranges = range_records.len(); - let min_glyph = range_records - .first() - .expect("empty RangeRecord-array") - .start_glyph_id; - let max_glyph = range_records - .last() - .expect("empty RangeRecord-array") - .end_glyph_id; - format!("[{num_glyphs} glyphs ({num_ranges} ranges) in [{min_glyph},{max_glyph}]]") + match glyph_array.as_slice() { + &[] => format!("∅"), + &[id] => format!("[glyphId={id}]"), + &[first, .., last] => format!("[{num_glyphs} ∈ [{first},{last}]]"), + } } + CoverageTable::Format2 { ref range_records } => match range_records.as_slice() { + &[] => format!("∅"), + &[rr] => format!("[∀ glyphId ∈ [{},{}]]", rr.start_glyph_id, rr.end_glyph_id), + &[first, .., last] => { + let num_glyphs: u16 = range_records + .iter() + .map(|rr| rr.end_glyph_id - rr.start_glyph_id + 1) + .sum(); + let num_ranges = range_records.len(); + let min_glyph = first.start_glyph_id; + let max_glyph = last.end_glyph_id; + format!("[{num_ranges} ranges; {num_glyphs} ∈ [{min_glyph},{max_glyph}]]") + } + }, } } @@ -3603,8 +3907,7 @@ fn format_items_inline( show_fn: impl Fn(&T) -> String, bookend: usize, ellipsis: impl Fn(usize) -> String, -) -> String -{ +) -> String { // Allocate a buffer big enough to hold one string per item in the array, or enough items to show both bookends and one ellipsis-string let mut buffer = Vec::::with_capacity(Ord::min(items.len(), bookend * 2 + 1)); diff --git a/generated/sample_codegen.rs b/generated/sample_codegen.rs index 8e529f45..f7200f48 100644 --- a/generated/sample_codegen.rs +++ b/generated/sample_codegen.rs @@ -1849,7 +1849,7 @@ data: opentype_coverage_table_data } #[derive(Debug, Clone)] -pub struct opentype_common_sequence_context_subst_Format1_coverage { +pub struct opentype_common_chained_sequence_context_subst_Format1_coverage { offset: u16, link: Option } @@ -1869,7 +1869,7 @@ link: Option #[derive(Debug, Clone)] pub struct opentype_gdef_table_attach_list_link { table_start: u32, -coverage: opentype_common_sequence_context_subst_Format1_coverage, +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, glyph_count: u16, attach_point_offsets: Vec } @@ -1952,7 +1952,7 @@ link: Option #[derive(Debug, Clone)] pub struct opentype_gdef_table_lig_caret_list_link { table_start: u32, -coverage: opentype_common_sequence_context_subst_Format1_coverage, +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, lig_glyph_count: u16, lig_glyph_offsets: Vec } @@ -2104,6 +2104,76 @@ ignore_marks: bool, use_mark_filtering_set: bool } +#[derive(Debug, Copy, Clone)] +pub struct opentype_common_sequence_lookup { +sequence_index: u16, +lookup_list_index: u16 +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link_chained_seq_rules { +backtrack_glyph_count: u16, +backtrack_sequence: Vec, +input_glyph_count: u16, +input_sequence: Vec, +lookahead_glyph_count: u16, +lookahead_sequence: Vec, +seq_lookup_count: u16, +seq_lookup_records: Vec +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link { +table_start: u32, +chained_seq_rule_count: u16, +chained_seq_rules: Vec +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets { +offset: u16, +link: Option +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format1 { +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, +chained_seq_rule_set_count: u16, +chained_seq_rule_sets: Vec +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format2 { +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, +backtrack_class_def: opentype_gdef_table_glyph_class_def, +input_class_def: opentype_gdef_table_glyph_class_def, +lookahead_class_def: opentype_gdef_table_glyph_class_def, +chained_class_seq_rule_set_count: u16, +chained_class_seq_rule_sets: Vec +} + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context_subst_Format3 { +backtrack_glyph_count: u16, +backtrack_coverages: Vec, +input_glyph_count: u16, +input_coverages: Vec, +lookahead_glyph_count: u16, +lookahead_coverages: Vec, +seq_lookup_count: u16, +seq_lookup_records: Vec +} + +#[derive(Debug, Clone)] +pub enum opentype_common_chained_sequence_context_subst { Format1(opentype_common_chained_sequence_context_subst_Format1), Format2(opentype_common_chained_sequence_context_subst_Format2), Format3(opentype_common_chained_sequence_context_subst_Format3) } + +#[derive(Debug, Clone)] +pub struct opentype_common_chained_sequence_context { +table_start: u32, +format: u16, +subst: opentype_common_chained_sequence_context_subst +} + #[derive(Debug, Copy, Clone)] pub struct opentype_common_anchor_table_table_Format1 { x_coordinate: u16, @@ -2149,7 +2219,7 @@ exit_anchor: opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_Cu #[derive(Debug, Clone)] pub struct opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_CursivePos_subtable_Format1 { -coverage: opentype_common_sequence_context_subst_Format1_coverage, +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, entry_exit_count: u16, entry_exit_records: Vec } @@ -2210,7 +2280,7 @@ link: Option #[derive(Debug, Clone)] pub struct opentype_common_sequence_context_subst_Format1 { -coverage: opentype_common_sequence_context_subst_Format1_coverage, +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, seq_rule_set_count: u16, seq_rule_sets: Vec } #[derive(Debug, Clone)] pub struct opentype_common_sequence_context_subst_Format2 { -coverage: opentype_common_sequence_context_subst_Format1_coverage, +coverage: opentype_common_chained_sequence_context_subst_Format1_coverage, class_def: opentype_gdef_table_glyph_class_def, class_seq_rule_set_count: u16, class_seq_rule_sets: Vec @@ -2302,7 +2366,7 @@ class_seq_rule_sets: Vec, +coverage_tables: Vec, seq_lookup_records: Vec } @@ -2318,14 +2382,14 @@ subst: opentype_common_sequence_context_subst #[derive(Debug, Clone)] pub struct opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_SinglePos_subtable_Format1 { -coverage_offset: opentype_common_sequence_context_subst_Format1_coverage, +coverage_offset: opentype_common_chained_sequence_context_subst_Format1_coverage, value_format: opentype_common_value_format_flags, value_record: opentype_common_value_record } #[derive(Debug, Clone)] pub struct opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_SinglePos_subtable_Format2 { -coverage_offset: opentype_common_sequence_context_subst_Format1_coverage, +coverage_offset: opentype_common_chained_sequence_context_subst_Format1_coverage, value_format: opentype_common_value_format_flags, value_count: u16, value_records: Vec @@ -2342,7 +2406,7 @@ subtable: opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_Singl } #[derive(Debug, Clone)] -pub enum opentype_gpos_table_lookup_list_link_lookups_link_subtables_link { ChainedSequenceContext, CursivePos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_CursivePos), MarkBasePos, MarkLigPos, MarkMarkPos, PairPos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_PairPos), PosExtension, SequenceContext(opentype_common_sequence_context), SinglePos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_SinglePos) } +pub enum opentype_gpos_table_lookup_list_link_lookups_link_subtables_link { ChainedSequenceContext(opentype_common_chained_sequence_context), CursivePos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_CursivePos), MarkBasePos, MarkLigPos, MarkMarkPos, PairPos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_PairPos), PosExtension, SequenceContext(opentype_common_sequence_context), SinglePos(opentype_gpos_table_lookup_list_link_lookups_link_subtables_link_SinglePos) } #[derive(Debug, Clone)] pub struct opentype_gpos_table_lookup_list_link_lookups_link_subtables { @@ -2390,7 +2454,7 @@ lookup_list: opentype_gpos_table_lookup_list } #[derive(Debug, Clone)] -pub enum opentype_gsub_table_lookup_list_link_lookups_link_subtables_link { AlternateSubst, ChainedSequenceContext, LigatureSubst, MultipleSubst, ReverseChainSingleSubst, SequenceContext(opentype_common_sequence_context), SingleSubst, SubstExtension } +pub enum opentype_gsub_table_lookup_list_link_lookups_link_subtables_link { AlternateSubst, ChainedSequenceContext(opentype_common_chained_sequence_context), LigatureSubst, MultipleSubst, ReverseChainSingleSubst, SequenceContext(opentype_common_sequence_context), SingleSubst, SubstExtension } #[derive(Debug, Clone)] pub struct opentype_gsub_table_lookup_list_link_lookups_link_subtables { @@ -4570,7 +4634,7 @@ let range_shift = ((|| PResult::Ok((Decoder24(_input))?))())?; let table_records = ((|| PResult::Ok({ let mut accum = Vec::new(); for _ in 0..num_tables { -accum.push((Decoder_opentype_table_record(_input, start.clone()))?); +accum.push((Decoder_opentype_table_record(_input))?); } accum }))())?; @@ -4678,7 +4742,7 @@ let b = _input.read_byte()?; PResult::Ok(b) } -fn Decoder_opentype_table_record<'input>(_input: &mut Parser<'input>, start: u32) -> Result { +fn Decoder_opentype_table_record<'input>(_input: &mut Parser<'input>) -> Result { let table_id = ((|| PResult::Ok((Decoder50(_input))?))())?; let checksum = ((|| PResult::Ok((Decoder21(_input))?))())?; let offset = ((|| PResult::Ok((Decoder21(_input))?))())?; @@ -6375,7 +6439,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; let attach_point_offsets = ((|| PResult::Ok({ @@ -6470,7 +6534,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let lig_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; let lig_glyph_offsets = ((|| PResult::Ok({ @@ -6862,7 +6926,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let value_format = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; let value_record = ((|| PResult::Ok((Decoder_opentype_common_value_record(_input, table_start.clone(), value_format.clone()))?))())?; @@ -6895,7 +6959,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let value_format = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; let value_count = ((|| PResult::Ok((Decoder24(_input))?))())?; @@ -6952,7 +7016,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let value_format1 = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; let value_format2 = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; @@ -7043,7 +7107,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let value_format1 = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; let value_format2 = ((|| PResult::Ok((Decoder_opentype_common_value_format_flags(_input))?))())?; @@ -7171,7 +7235,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let entry_exit_count = ((|| PResult::Ok((Decoder24(_input))?))())?; let entry_exit_records = ((|| PResult::Ok({ @@ -7263,8 +7327,8 @@ opentype_gpos_table_lookup_list_link_lookups_link_subtables_link::SequenceContex }, 8u16 => { -let _ = (Decoder46(_input))?; -opentype_gpos_table_lookup_list_link_lookups_link_subtables_link::ChainedSequenceContext +let inner = (Decoder_opentype_common_chained_sequence_context(_input))?; +opentype_gpos_table_lookup_list_link_lookups_link_subtables_link::ChainedSequenceContext(inner) }, 9u16 => { @@ -7489,8 +7553,8 @@ opentype_gsub_table_lookup_list_link_lookups_link_subtables_link::SequenceContex }, 6u16 => { -let _ = (Decoder46(_input))?; -opentype_gsub_table_lookup_list_link_lookups_link_subtables_link::ChainedSequenceContext +let inner = (Decoder_opentype_common_chained_sequence_context(_input))?; +opentype_gsub_table_lookup_list_link_lookups_link_subtables_link::ChainedSequenceContext(inner) }, 7u16 => { @@ -7681,7 +7745,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let seq_rule_set_count = ((|| PResult::Ok((Decoder24(_input))?))())?; let seq_rule_sets = ((|| PResult::Ok({ @@ -7805,7 +7869,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }))())?; let class_def = ((|| PResult::Ok({ let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; @@ -7958,7 +8022,7 @@ false => { None } }))())?; -opentype_common_sequence_context_subst_Format1_coverage { offset, link } +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } }); } accum @@ -7982,8 +8046,418 @@ return Err(ParseError::FailToken); PResult::Ok(opentype_common_sequence_context { table_start, format, subst }) } -fn Decoder46<'input>(_input: &mut Parser<'input>) -> Result<(), ParseError> { -PResult::Ok(()) +fn Decoder_opentype_common_chained_sequence_context<'input>(_input: &mut Parser<'input>) -> Result { +let table_start = ((|| PResult::Ok({ +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}))())?; +let format = ((|| PResult::Ok((Decoder24(_input))?))())?; +let subst = ((|| PResult::Ok(match format { +1u16 => { +let inner = { +let coverage = ((|| PResult::Ok({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_coverage_table(_input))?; +((|val: opentype_coverage_table| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } +}))())?; +let chained_seq_rule_set_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let chained_seq_rule_sets = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..chained_seq_rule_set_count { +accum.push({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = { +let table_start = ((|| PResult::Ok({ +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}))())?; +let chained_seq_rule_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let chained_seq_rules = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..chained_seq_rule_count { +accum.push({ +let backtrack_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let backtrack_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..backtrack_glyph_count { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let input_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let input_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..try_sub!(input_glyph_count, 1u16) { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let lookahead_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let lookahead_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..lookahead_glyph_count { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let seq_lookup_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let seq_lookup_records = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..seq_lookup_count { +accum.push((Decoder_opentype_common_sequence_lookup(_input))?); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link_chained_seq_rules { backtrack_glyph_count, backtrack_sequence, input_glyph_count, input_sequence, lookahead_glyph_count, lookahead_sequence, seq_lookup_count, seq_lookup_records } +}); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link { table_start, chained_seq_rule_count, chained_seq_rules } +}; +((|val: opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets { offset, link } +}); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format1 { coverage, chained_seq_rule_set_count, chained_seq_rule_sets } +}; +opentype_common_chained_sequence_context_subst::Format1(inner) +}, + +2u16 => { +let inner = { +let coverage = ((|| PResult::Ok({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_coverage_table(_input))?; +((|val: opentype_coverage_table| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } +}))())?; +let backtrack_class_def = ((|| PResult::Ok({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_class_def(_input))?; +((|val: opentype_class_def| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_gdef_table_glyph_class_def { offset, link } +}))())?; +let input_class_def = ((|| PResult::Ok({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_class_def(_input))?; +((|val: opentype_class_def| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_gdef_table_glyph_class_def { offset, link } +}))())?; +let lookahead_class_def = ((|| PResult::Ok({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_class_def(_input))?; +((|val: opentype_class_def| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_gdef_table_glyph_class_def { offset, link } +}))())?; +let chained_class_seq_rule_set_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let chained_class_seq_rule_sets = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..chained_class_seq_rule_set_count { +accum.push({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = { +let table_start = ((|| PResult::Ok({ +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}))())?; +let chained_seq_rule_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let chained_seq_rules = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..chained_seq_rule_count { +accum.push({ +let backtrack_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let backtrack_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..backtrack_glyph_count { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let input_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let input_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..try_sub!(input_glyph_count, 1u16) { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let lookahead_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let lookahead_sequence = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..lookahead_glyph_count { +accum.push((Decoder24(_input))?); +} +accum +}))())?; +let seq_lookup_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let seq_lookup_records = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..seq_lookup_count { +accum.push((Decoder_opentype_common_sequence_lookup(_input))?); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link_chained_seq_rules { backtrack_glyph_count, backtrack_sequence, input_glyph_count, input_sequence, lookahead_glyph_count, lookahead_sequence, seq_lookup_count, seq_lookup_records } +}); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link { table_start, chained_seq_rule_count, chained_seq_rules } +}; +((|val: opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets_link| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_chained_seq_rule_sets { offset, link } +}); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format2 { coverage, backtrack_class_def, input_class_def, lookahead_class_def, chained_class_seq_rule_set_count, chained_class_seq_rule_sets } +}; +opentype_common_chained_sequence_context_subst::Format2(inner) +}, + +3u16 => { +let inner = { +let backtrack_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let backtrack_coverages = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..backtrack_glyph_count { +accum.push({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_coverage_table(_input))?; +((|val: opentype_coverage_table| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } +}); +} +accum +}))())?; +let input_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let input_coverages = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..input_glyph_count { +accum.push({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_coverage_table(_input))?; +((|val: opentype_coverage_table| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } +}); +} +accum +}))())?; +let lookahead_glyph_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let lookahead_coverages = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..lookahead_glyph_count { +accum.push({ +let offset = ((|| PResult::Ok((Decoder24(_input))?))())?; +let link = ((|| PResult::Ok(match offset != 0u16 { +true => { +let __here = { +let inner = _input.get_offset_u64(); +((|x: u64| PResult::Ok(x as u32))(inner))? +}; +_input.open_peek_context(); +_input.advance_by(try_sub!(table_start + (offset as u32), __here))?; +let ret = ((|| PResult::Ok({ +let inner = (Decoder_opentype_coverage_table(_input))?; +((|val: opentype_coverage_table| PResult::Ok(Some(val)))(inner))? +}))())?; +_input.close_peek_context()?; +ret +}, + +false => { +None +} +}))())?; +opentype_common_chained_sequence_context_subst_Format1_coverage { offset, link } +}); +} +accum +}))())?; +let seq_lookup_count = ((|| PResult::Ok((Decoder24(_input))?))())?; +let seq_lookup_records = ((|| PResult::Ok({ +let mut accum = Vec::new(); +for _ in 0..seq_lookup_count { +accum.push((Decoder_opentype_common_sequence_lookup(_input))?); +} +accum +}))())?; +opentype_common_chained_sequence_context_subst_Format3 { backtrack_glyph_count, backtrack_coverages, input_glyph_count, input_coverages, lookahead_glyph_count, lookahead_coverages, seq_lookup_count, seq_lookup_records } +}; +opentype_common_chained_sequence_context_subst::Format3(inner) +}, + +_ => { +return Err(ParseError::FailToken); +} +}))())?; +PResult::Ok(opentype_common_chained_sequence_context { table_start, format, subst }) } fn Decoder_opentype_coverage_table<'input>(_input: &mut Parser<'input>) -> Result {