rustybuzz/hb/
ot_shaper.rs1use alloc::boxed::Box;
2use core::any::Any;
3
4use super::buffer::*;
5use super::common::TagExt;
6use super::ot_shape::*;
7use super::ot_shape_normalize::*;
8use super::ot_shape_plan::hb_ot_shape_plan_t;
9use super::{hb_font_t, hb_tag_t, script, Direction, Script};
10
11impl hb_glyph_info_t {
12 pub(crate) fn ot_shaper_var_u8_category(&self) -> u8 {
13 let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
14 v[2]
15 }
16
17 pub(crate) fn set_ot_shaper_var_u8_category(&mut self, c: u8) {
18 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
19 v[2] = c;
20 }
21
22 pub(crate) fn ot_shaper_var_u8_auxiliary(&self) -> u8 {
23 let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
24 v[3]
25 }
26
27 pub(crate) fn set_ot_shaper_var_u8_auxiliary(&mut self, c: u8) {
28 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
29 v[3] = c;
30 }
31}
32
33pub const MAX_COMBINING_MARKS: usize = 32;
34
35pub type hb_ot_shape_zero_width_marks_type_t = u32;
36pub const HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: u32 = 0;
37pub const HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: u32 = 1;
38pub const HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: u32 = 2;
39
40pub type DecomposeFn = fn(&hb_ot_shape_normalize_context_t, char) -> Option<(char, char)>;
41pub type ComposeFn = fn(&hb_ot_shape_normalize_context_t, char, char) -> Option<char>;
42
43pub const DEFAULT_SHAPER: hb_ot_shaper_t = hb_ot_shaper_t {
44 collect_features: None,
45 override_features: None,
46 create_data: None,
47 preprocess_text: None,
48 postprocess_glyphs: None,
49 normalization_preference: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,
50 decompose: None,
51 compose: None,
52 setup_masks: None,
53 gpos_tag: None,
54 reorder_marks: None,
55 zero_width_marks: HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
56 fallback_position: true,
57};
58
59pub struct hb_ot_shaper_t {
60 pub collect_features: Option<fn(&mut hb_ot_shape_planner_t)>,
63
64 pub override_features: Option<fn(&mut hb_ot_shape_planner_t)>,
68
69 pub create_data: Option<fn(&hb_ot_shape_plan_t) -> Box<dyn Any + Send + Sync>>,
72
73 pub preprocess_text: Option<fn(&hb_ot_shape_plan_t, &hb_font_t, &mut hb_buffer_t)>,
76
77 pub postprocess_glyphs: Option<fn(&hb_ot_shape_plan_t, &hb_font_t, &mut hb_buffer_t)>,
80
81 pub normalization_preference: hb_ot_shape_normalization_mode_t,
83
84 pub decompose: Option<DecomposeFn>,
86
87 pub compose: Option<ComposeFn>,
89
90 pub setup_masks: Option<fn(&hb_ot_shape_plan_t, &hb_font_t, &mut hb_buffer_t)>,
94
95 pub gpos_tag: Option<hb_tag_t>,
98
99 pub reorder_marks: Option<fn(&hb_ot_shape_plan_t, &mut hb_buffer_t, usize, usize)>,
102
103 pub zero_width_marks: hb_ot_shape_zero_width_marks_type_t,
105
106 pub fallback_position: bool,
108}
109
110pub const DUMBER_SHAPER: hb_ot_shaper_t = hb_ot_shaper_t {
113 collect_features: None,
114 override_features: None,
115 create_data: None,
116 preprocess_text: None,
117 postprocess_glyphs: None,
118 normalization_preference: HB_OT_SHAPE_NORMALIZATION_MODE_AUTO,
119 decompose: None,
120 compose: None,
121 setup_masks: None,
122 gpos_tag: None,
123 reorder_marks: None,
124 zero_width_marks: HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
125 fallback_position: false,
126};
127
128pub fn hb_ot_shape_complex_categorize(
129 script: Script,
130 direction: Direction,
131 gsub_script: Option<hb_tag_t>,
132) -> &'static hb_ot_shaper_t {
133 match script {
134 script::ARABIC
136
137 | script::SYRIAC => {
139 if (gsub_script != Some(hb_tag_t::default_script()) || script == script::ARABIC)
146 && direction.is_horizontal()
147 {
148 &crate::hb::ot_shaper_arabic::ARABIC_SHAPER
149 } else {
150 &DEFAULT_SHAPER
151 }
152 }
153
154 script::THAI
156 | script::LAO => &crate::hb::ot_shaper_thai::THAI_SHAPER,
157
158 script::HANGUL => &crate::hb::ot_shaper_hangul::HANGUL_SHAPER,
160
161 script::HEBREW => &crate::hb::ot_shaper_hebrew::HEBREW_SHAPER,
163
164 script::BENGALI
166 | script::DEVANAGARI
167 | script::GUJARATI
168 | script::GURMUKHI
169 | script::KANNADA
170 | script::MALAYALAM
171 | script::ORIYA
172 | script::TAMIL
173 | script::TELUGU => {
174 if gsub_script == Some(hb_tag_t::default_script()) ||
180 gsub_script == Some(hb_tag_t::from_bytes(b"latn")) {
181 &DEFAULT_SHAPER
182 } else if gsub_script.map_or(false, |tag| tag.to_bytes()[3] == b'3') {
183 &crate::hb::ot_shaper_use::UNIVERSAL_SHAPER
184 } else {
185 &crate::hb::ot_shaper_indic::INDIC_SHAPER
186 }
187 }
188
189 script::KHMER => &crate::hb::ot_shaper_khmer::KHMER_SHAPER,
190
191 script::MYANMAR => {
192 if gsub_script == Some(hb_tag_t::default_script()) ||
200 gsub_script == Some(hb_tag_t::from_bytes(b"latn")) ||
201 gsub_script == Some(hb_tag_t::from_bytes(b"mymr"))
202 {
203 &DEFAULT_SHAPER
204 } else {
205 &crate::hb::ot_shaper_myanmar::MYANMAR_SHAPER
206 }
207 }
208
209 script::MYANMAR_ZAWGYI => &crate::hb::ot_shaper_myanmar::MYANMAR_ZAWGYI_SHAPER,
211
212 script::TIBETAN
214
215 | script::MONGOLIAN
217 | script::SINHALA
218
219 | script::BUHID
221 | script::HANUNOO
222 | script::TAGALOG
223 | script::TAGBANWA
224
225 | script::LIMBU
227 | script::TAI_LE
228
229 | script::BUGINESE
231 | script::KHAROSHTHI
232 | script::SYLOTI_NAGRI
233 | script::TIFINAGH
234
235 | script::BALINESE
237 | script::NKO
238 | script::PHAGS_PA
239
240 | script::CHAM
242 | script::KAYAH_LI
243 | script::LEPCHA
244 | script::REJANG
245 | script::SAURASHTRA
246 | script::SUNDANESE
247
248 | script::EGYPTIAN_HIEROGLYPHS
250 | script::JAVANESE
251 | script::KAITHI
252 | script::MEETEI_MAYEK
253 | script::TAI_THAM
254 | script::TAI_VIET
255
256 | script::BATAK
258 | script::BRAHMI
259 | script::MANDAIC
260
261 | script::CHAKMA
263 | script::MIAO
264 | script::SHARADA
265 | script::TAKRI
266
267 | script::DUPLOYAN
269 | script::GRANTHA
270 | script::KHOJKI
271 | script::KHUDAWADI
272 | script::MAHAJANI
273 | script::MANICHAEAN
274 | script::MODI
275 | script::PAHAWH_HMONG
276 | script::PSALTER_PAHLAVI
277 | script::SIDDHAM
278 | script::TIRHUTA
279
280 | script::AHOM
282 | script::MULTANI
283
284 | script::ADLAM
286 | script::BHAIKSUKI
287 | script::MARCHEN
288 | script::NEWA
289
290 | script::MASARAM_GONDI
292 | script::SOYOMBO
293 | script::ZANABAZAR_SQUARE
294
295 | script::DOGRA
297 | script::GUNJALA_GONDI
298 | script::HANIFI_ROHINGYA
299 | script::MAKASAR
300 | script::MEDEFAIDRIN
301 | script::OLD_SOGDIAN
302 | script::SOGDIAN
303
304 | script::ELYMAIC
306 | script::NANDINAGARI
307 | script::NYIAKENG_PUACHUE_HMONG
308 | script::WANCHO
309
310 | script::CHORASMIAN
312 | script::DIVES_AKURU
313 | script::KHITAN_SMALL_SCRIPT
314 | script::YEZIDI
315
316 | script::CYPRO_MINOAN
318 | script::OLD_UYGHUR
319 | script::TANGSA
320 | script::TOTO
321 | script::VITHKUQI
322
323 | script::KAWI
325 | script::NAG_MUNDARI
326
327 | script::GARAY
329 | script::GURUNG_KHEMA
330 | script::KIRAT_RAI
331 | script::OL_ONAL
332 | script::SUNUWAR
333 | script::TODHRI
334 | script::TULU_TIGALARI
335
336 => {
337 if gsub_script == Some(hb_tag_t::default_script()) ||
343 gsub_script == Some(hb_tag_t::from_bytes(b"latn")) {
344 &DEFAULT_SHAPER
345 } else {
346 &crate::hb::ot_shaper_use::UNIVERSAL_SHAPER
347 }
348 }
349
350 _ => &DEFAULT_SHAPER
351 }
352}