1pub mod layout;
2pub mod layout_common;
3pub mod layout_kerx_table;
4pub mod layout_morx_table;
5pub mod layout_trak_table;
6pub mod map;
7
8use crate::hb::aat::layout_kerx_table::KerxSubtableCache;
9use crate::hb::aat::layout_morx_table::MorxSubtableCache;
10use crate::hb::kerning::KernSubtableCache;
11use crate::hb::ot::OtTables;
12use crate::hb::tables::TableRanges;
13use alloc::vec::Vec;
14use read_fonts::{
15 tables::{ankr::Ankr, feat::Feat, kern::Kern, kerx::Kerx, morx::Morx, trak::Trak},
16 FontRef, TableProvider,
17};
18
19#[derive(Default)]
20pub struct AatCache {
21 pub morx: Vec<MorxSubtableCache>,
22 pub kern: Vec<KernSubtableCache>,
23 pub kerx: Vec<KerxSubtableCache>,
24}
25
26impl AatCache {
27 #[allow(unused)]
28 pub fn new<'a>(font: &impl TableProvider<'a>) -> Self {
29 let mut cache = Self::default();
30 let num_glyphs = font
31 .maxp()
32 .map(|maxp| maxp.num_glyphs() as u32)
33 .unwrap_or_default();
34 if let Ok(morx) = font.morx() {
35 let chains = morx.chains();
36 for chain in morx.chains().iter() {
37 let Ok(chain) = chain else {
38 continue;
39 };
40 for subtable in chain.subtables().iter() {
41 let Ok(subtable) = subtable else {
42 continue;
43 };
44 cache
45 .morx
46 .push(MorxSubtableCache::new(&subtable, num_glyphs));
47 }
48 }
49 }
50 if let Ok(kern) = font.kern() {
51 for subtable in kern.subtables() {
52 let Ok(subtable) = subtable else {
53 continue;
54 };
55 cache
56 .kern
57 .push(KernSubtableCache::new(&subtable, num_glyphs));
58 }
59 }
60 if let Ok(kerx) = font.kerx() {
61 for subtable in kerx.subtables().iter() {
62 let Ok(subtable) = subtable else {
63 continue;
64 };
65 cache
66 .kerx
67 .push(KerxSubtableCache::new(&subtable, num_glyphs));
68 }
69 }
70 cache
71 }
72}
73
74#[derive(Clone, Default)]
75pub struct AatTables<'a> {
76 pub morx: Option<(Morx<'a>, &'a [MorxSubtableCache])>,
77 pub ankr: Option<Ankr<'a>>,
78 pub kern: Option<(Kern<'a>, &'a [KernSubtableCache])>,
79 pub kerx: Option<(Kerx<'a>, &'a [KerxSubtableCache])>,
80 pub trak: Option<Trak<'a>>,
81 pub feat: Option<Feat<'a>>,
82}
83
84use crate::hb::algs::HB_CODEPOINT_ENCODE3 as encode3;
85
86fn is_morx_blocklisted(morx_len: u32, gsub_len: u32, gdef_len: u32) -> bool {
89 const BLOCKLIST: &[u64] = &[
90 encode3(19892, 2794, 340),
92 ];
93 let key = encode3(morx_len, gsub_len, gdef_len);
94 BLOCKLIST.contains(&key)
95}
96
97impl<'a> AatTables<'a> {
98 pub fn new(font: &FontRef<'a>, cache: &'a AatCache, table_ranges: &TableRanges) -> Self {
99 let morx = if is_morx_blocklisted(
100 table_ranges.morx.len(),
101 table_ranges.gsub.len(),
102 table_ranges.gdef.len(),
103 ) {
104 None
105 } else {
106 table_ranges
107 .morx
108 .resolve_table(font)
109 .map(|table| (table, cache.morx.as_slice()))
110 };
111 let ankr = table_ranges.ankr.resolve_table(font);
112 let kern = table_ranges
113 .kern
114 .resolve_table(font)
115 .map(|table| (table, cache.kern.as_slice()));
116 let kerx = table_ranges
117 .kerx
118 .resolve_table(font)
119 .map(|table| (table, cache.kerx.as_slice()));
120 let trak = table_ranges.trak.resolve_table(font);
121 let feat = table_ranges.feat.resolve_table(font);
122 Self {
123 morx,
124 ankr,
125 kern,
126 kerx,
127 trak,
128 feat,
129 }
130 }
131
132 pub fn from_tables(
133 font: &impl TableProvider<'a>,
134 ot_tables: &OtTables,
135 cache: &'a AatCache,
136 ) -> Self {
137 let morx = if let Ok(morx) = font.morx() {
138 let gsub_len = ot_tables
139 .gsub
140 .as_ref()
141 .map_or(0, |table| table.table.offset_data().len() as u32);
142 let gdef_len = ot_tables
143 .gdef
144 .table
145 .as_ref()
146 .map_or(0, |table| table.offset_data().len() as u32);
147 if is_morx_blocklisted(morx.offset_data().len() as u32, gsub_len, gdef_len) {
148 None
149 } else {
150 Some((morx, cache.morx.as_slice()))
151 }
152 } else {
153 None
154 };
155 let ankr = font.ankr().ok();
156 let kern = font.kern().ok().map(|table| (table, cache.kern.as_slice()));
157 let kerx = font.kerx().ok().map(|table| (table, cache.kerx.as_slice()));
158 let trak = font.trak().ok();
159 let feat = font.feat().ok();
160 Self {
161 morx,
162 ankr,
163 kern,
164 kerx,
165 trak,
166 feat,
167 }
168 }
169}