ttf_parser/ggg/
chained_context.rs1use super::{ClassDefinition, Coverage, SequenceLookupRecord};
2use crate::parser::{FromSlice, LazyArray16, LazyOffsetArray16, Offset, Offset16, Stream};
3
4#[allow(missing_docs)]
7#[derive(Clone, Copy, Debug)]
8pub enum ChainedContextLookup<'a> {
9 Format1 {
11 coverage: Coverage<'a>,
12 sets: ChainedSequenceRuleSets<'a>,
13 },
14 Format2 {
16 coverage: Coverage<'a>,
17 backtrack_classes: ClassDefinition<'a>,
18 input_classes: ClassDefinition<'a>,
19 lookahead_classes: ClassDefinition<'a>,
20 sets: ChainedSequenceRuleSets<'a>,
21 },
22 Format3 {
24 coverage: Coverage<'a>,
25 backtrack_coverages: LazyOffsetArray16<'a, Coverage<'a>>,
26 input_coverages: LazyOffsetArray16<'a, Coverage<'a>>,
27 lookahead_coverages: LazyOffsetArray16<'a, Coverage<'a>>,
28 lookups: LazyArray16<'a, SequenceLookupRecord>,
29 },
30}
31
32impl<'a> ChainedContextLookup<'a> {
33 pub(crate) fn parse(data: &'a [u8]) -> Option<Self> {
34 let mut s = Stream::new(data);
35 match s.read::<u16>()? {
36 1 => {
37 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
38 let count = s.read::<u16>()?;
39 let offsets = s.read_array16(count)?;
40 Some(Self::Format1 {
41 coverage,
42 sets: ChainedSequenceRuleSets::new(data, offsets),
43 })
44 }
45 2 => {
46 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
47
48 let mut parse_func = || match s.read::<Option<Offset16>>()? {
49 Some(offset) => Some(ClassDefinition::parse(data.get(offset.to_usize()..)?)?),
50 None => Some(ClassDefinition::Empty),
51 };
52
53 let backtrack_classes = parse_func()?;
54 let input_classes = parse_func()?;
55 let lookahead_classes = parse_func()?;
56
57 let count = s.read::<u16>()?;
58 let offsets = s.read_array16(count)?;
59 Some(Self::Format2 {
60 coverage,
61 backtrack_classes,
62 input_classes,
63 lookahead_classes,
64 sets: LazyOffsetArray16::new(data, offsets),
65 })
66 }
67 3 => {
68 let backtrack_count = s.read::<u16>()?;
69 let backtrack_coverages = s.read_array16(backtrack_count)?;
70 let input_count = s.read::<u16>()?;
71 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
72 let input_coverages = s.read_array16(input_count.checked_sub(1)?)?;
73 let lookahead_count = s.read::<u16>()?;
74 let lookahead_coverages = s.read_array16(lookahead_count)?;
75 let lookup_count = s.read::<u16>()?;
76 let lookups = s.read_array16(lookup_count)?;
77 Some(Self::Format3 {
78 coverage,
79 backtrack_coverages: LazyOffsetArray16::new(data, backtrack_coverages),
80 input_coverages: LazyOffsetArray16::new(data, input_coverages),
81 lookahead_coverages: LazyOffsetArray16::new(data, lookahead_coverages),
82 lookups,
83 })
84 }
85 _ => None,
86 }
87 }
88
89 #[inline]
91 pub fn coverage(&self) -> Coverage<'a> {
92 match self {
93 Self::Format1 { coverage, .. } => *coverage,
94 Self::Format2 { coverage, .. } => *coverage,
95 Self::Format3 { coverage, .. } => *coverage,
96 }
97 }
98}
99
100pub type ChainedSequenceRuleSets<'a> = LazyOffsetArray16<'a, ChainedSequenceRuleSet<'a>>;
102
103pub type ChainedSequenceRuleSet<'a> = LazyOffsetArray16<'a, ChainedSequenceRule<'a>>;
105
106impl<'a> FromSlice<'a> for ChainedSequenceRuleSet<'a> {
107 fn parse(data: &'a [u8]) -> Option<Self> {
108 Self::parse(data)
109 }
110}
111
112#[allow(missing_docs)]
114#[derive(Clone, Copy, Debug)]
115pub struct ChainedSequenceRule<'a> {
116 pub backtrack: LazyArray16<'a, u16>,
118 pub input: LazyArray16<'a, u16>,
119 pub lookahead: LazyArray16<'a, u16>,
121 pub lookups: LazyArray16<'a, SequenceLookupRecord>,
122}
123
124impl<'a> FromSlice<'a> for ChainedSequenceRule<'a> {
125 fn parse(data: &'a [u8]) -> Option<Self> {
126 let mut s = Stream::new(data);
127 let backtrack_count = s.read::<u16>()?;
128 let backtrack = s.read_array16(backtrack_count)?;
129 let input_count = s.read::<u16>()?;
130 let input = s.read_array16(input_count.checked_sub(1)?)?;
131 let lookahead_count = s.read::<u16>()?;
132 let lookahead = s.read_array16(lookahead_count)?;
133 let lookup_count = s.read::<u16>()?;
134 let lookups = s.read_array16(lookup_count)?;
135 Some(Self {
136 backtrack,
137 input,
138 lookahead,
139 lookups,
140 })
141 }
142}