1use hashbrown::HashSet;
2use ttf_parser::Face;
3
4pub fn load_gsub(face: &Face, indices_to_load: &mut HashSet<u16>) {
5 if let Some(subtable) = face.tables().gsub {
6 use ttf_parser::gsub::SubstitutionSubtable;
7 for lookup in subtable.lookups {
8 for table in lookup.subtables.into_iter::<SubstitutionSubtable>() {
9 match table {
10 SubstitutionSubtable::Single(ss) => {
11 use ttf_parser::gsub::SingleSubstitution;
12 use ttf_parser::opentype_layout::Coverage;
13 match ss {
14 SingleSubstitution::Format1 {
15 coverage,
16 delta,
17 } => match coverage {
18 Coverage::Format1 {
19 glyphs,
20 } => {
21 for glyph in glyphs {
22 indices_to_load.insert((glyph.0 as i32 + delta as i32) as u16);
23 }
24 }
25 Coverage::Format2 {
26 records,
27 } => {
28 for record in records {
29 for id in record.start.0..record.end.0 {
30 indices_to_load.insert((id as i32 + delta as i32) as u16);
31 }
32 }
33 }
34 },
35 SingleSubstitution::Format2 {
36 coverage: _,
37 substitutes,
38 } => {
39 for g in substitutes {
40 indices_to_load.insert(g.0);
41 }
42 }
43 }
44 }
45 SubstitutionSubtable::Multiple(ms) => {
46 for seq in ms.sequences {
47 for g in seq.substitutes {
48 indices_to_load.insert(g.0);
49 }
50 }
51 }
52 SubstitutionSubtable::Alternate(als) => {
53 for alt in als.alternate_sets {
54 for g in alt.alternates {
55 indices_to_load.insert(g.0);
56 }
57 }
58 }
59 SubstitutionSubtable::Ligature(ls) => ls.ligature_sets.into_iter().for_each(|ls| {
60 for l in ls {
61 indices_to_load.insert(l.glyph.0);
62 }
63 }),
64 SubstitutionSubtable::ReverseChainSingle(rcsl) => {
65 for g in rcsl.substitutes {
66 indices_to_load.insert(g.0);
67 }
68 }
69 _ => {}
70 }
71 }
72 }
73 }
74}
75