1use super::ucd_table::ucd::*;
2use crate::hb::algs::*;
3use crate::Script;
4
5pub type Codepoint = u32;
6
7pub mod hb_unicode_funcs_t {
11 pub type space_t = u8;
12 pub const NOT_SPACE: u8 = 0;
13 pub const SPACE_EM: u8 = 1;
14 pub const SPACE_EM_2: u8 = 2;
15 pub const SPACE_EM_3: u8 = 3;
16 pub const SPACE_EM_4: u8 = 4;
17 pub const SPACE_EM_5: u8 = 5;
18 pub const SPACE_EM_6: u8 = 6;
19 pub const SPACE_EM_16: u8 = 16;
20 pub const SPACE_4_EM_18: u8 = 17; pub const SPACE: u8 = 18;
22 pub const SPACE_FIGURE: u8 = 19;
23 pub const SPACE_PUNCTUATION: u8 = 20;
24 pub const SPACE_NARROW: u8 = 21;
25}
26
27#[derive(Copy, Clone, PartialEq, Eq, Debug)]
28pub struct GeneralCategory(pub u8);
29
30#[allow(unused)]
31impl GeneralCategory {
32 pub const CONTROL: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_CONTROL as _);
33 pub const FORMAT: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_FORMAT as _);
34 pub const UNASSIGNED: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED as _);
35 pub const PRIVATE_USE: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE as _);
36 pub const SURROGATE: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_SURROGATE as _);
37 pub const LOWERCASE_LETTER: Self =
38 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER as _);
39 pub const MODIFIER_LETTER: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER as _);
40 pub const OTHER_LETTER: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER as _);
41 pub const TITLECASE_LETTER: Self =
42 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER as _);
43 pub const UPPERCASE_LETTER: Self =
44 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER as _);
45 pub const SPACING_MARK: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK as _);
46 pub const ENCLOSING_MARK: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK as _);
47 pub const NON_SPACING_MARK: Self =
48 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK as _);
49 pub const DECIMAL_NUMBER: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER as _);
50 pub const LETTER_NUMBER: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER as _);
51 pub const OTHER_NUMBER: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER as _);
52 pub const CONNECT_PUNCTUATION: Self =
53 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION as _);
54 pub const DASH_PUNCTUATION: Self =
55 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION as _);
56 pub const CLOSE_PUNCTUATION: Self =
57 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION as _);
58 pub const FINAL_PUNCTUATION: Self =
59 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION as _);
60 pub const INITIAL_PUNCTUATION: Self =
61 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION as _);
62 pub const OTHER_PUNCTUATION: Self =
63 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION as _);
64 pub const OPEN_PUNCTUATION: Self =
65 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION as _);
66 pub const CURRENCY_SYMBOL: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL as _);
67 pub const MODIFIER_SYMBOL: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL as _);
68 pub const MATH_SYMBOL: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL as _);
69 pub const OTHER_SYMBOL: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL as _);
70 pub const LINE_SEPARATOR: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR as _);
71 pub const PARAGRAPH_SEPARATOR: Self =
72 Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR as _);
73 pub const SPACE_SEPARATOR: Self = Self(hb_gc::HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR as _);
74}
75
76impl GeneralCategory {
77 pub fn to_u8(self) -> u8 {
78 self.0
79 }
80
81 pub fn is_mark(&self) -> bool {
82 matches!(
83 *self,
84 Self::SPACING_MARK | Self::ENCLOSING_MARK | Self::NON_SPACING_MARK
85 )
86 }
87
88 pub fn is_letter(&self) -> bool {
89 matches!(
90 *self,
91 Self::LOWERCASE_LETTER
92 | Self::MODIFIER_LETTER
93 | Self::OTHER_LETTER
94 | Self::TITLECASE_LETTER
95 | Self::UPPERCASE_LETTER
96 )
97 }
98}
99
100#[allow(dead_code)]
101pub mod combining_class {
102 pub const NotReordered: u8 = 0;
103 pub const Overlay: u8 = 1;
104 pub const Nukta: u8 = 7;
105 pub const KanaVoicing: u8 = 8;
106 pub const Virama: u8 = 9;
107
108 pub const CCC10: u8 = 10;
110 pub const CCC11: u8 = 11;
111 pub const CCC12: u8 = 12;
112 pub const CCC13: u8 = 13;
113 pub const CCC14: u8 = 14;
114 pub const CCC15: u8 = 15;
115 pub const CCC16: u8 = 16;
116 pub const CCC17: u8 = 17;
117 pub const CCC18: u8 = 18;
118 pub const CCC19: u8 = 19;
119 pub const CCC20: u8 = 20;
120 pub const CCC21: u8 = 21;
121 pub const CCC22: u8 = 22;
122 pub const CCC23: u8 = 23;
123 pub const CCC24: u8 = 24;
124 pub const CCC25: u8 = 25;
125 pub const CCC26: u8 = 26;
126
127 pub const CCC27: u8 = 27;
129 pub const CCC28: u8 = 28;
130 pub const CCC29: u8 = 29;
131 pub const CCC30: u8 = 30;
132 pub const CCC31: u8 = 31;
133 pub const CCC32: u8 = 32;
134 pub const CCC33: u8 = 33;
135 pub const CCC34: u8 = 34;
136 pub const CCC35: u8 = 35;
137
138 pub const CCC36: u8 = 36;
140
141 pub const CCC84: u8 = 84;
143 pub const CCC91: u8 = 91;
144
145 pub const CCC103: u8 = 103;
147 pub const CCC107: u8 = 107;
148
149 pub const CCC118: u8 = 118;
151 pub const CCC122: u8 = 122;
152
153 pub const CCC129: u8 = 129;
155 pub const CCC130: u8 = 130;
156 pub const CCC132: u8 = 132;
157
158 pub const AttachedBelowLeft: u8 = 200;
159 pub const AttachedBelow: u8 = 202;
160 pub const AttachedAbove: u8 = 214;
161 pub const AttachedAboveRight: u8 = 216;
162 pub const BelowLeft: u8 = 218;
163 pub const Below: u8 = 220;
164 pub const BelowRight: u8 = 222;
165 pub const Left: u8 = 224;
166 pub const Right: u8 = 226;
167 pub const AboveLeft: u8 = 228;
168 pub const Above: u8 = 230;
169 pub const AboveRight: u8 = 232;
170 pub const DoubleBelow: u8 = 233;
171 pub const DoubleAbove: u8 = 234;
172
173 pub const IotaSubscript: u8 = 240;
174
175 pub const Invalid: u8 = 255;
176}
177
178#[allow(dead_code)]
179pub mod modified_combining_class {
180 pub const CCC10: u8 = 22; pub const CCC11: u8 = 15; pub const CCC12: u8 = 16; pub const CCC13: u8 = 17; pub const CCC14: u8 = 23; pub const CCC15: u8 = 18; pub const CCC16: u8 = 19; pub const CCC17: u8 = 20; pub const CCC18: u8 = 21; pub const CCC19: u8 = 14; pub const CCC20: u8 = 24; pub const CCC21: u8 = 12; pub const CCC22: u8 = 25; pub const CCC23: u8 = 13; pub const CCC24: u8 = 10; pub const CCC25: u8 = 11; pub const CCC26: u8 = 26; pub const CCC27: u8 = 28; pub const CCC28: u8 = 29; pub const CCC29: u8 = 30; pub const CCC30: u8 = 31; pub const CCC31: u8 = 32; pub const CCC32: u8 = 33; pub const CCC33: u8 = 27; pub const CCC34: u8 = 34; pub const CCC35: u8 = 35; pub const CCC36: u8 = 36; pub const CCC84: u8 = 0; pub const CCC91: u8 = 0; pub const CCC103: u8 = 3; pub const CCC107: u8 = 107; pub const CCC118: u8 = 118; pub const CCC122: u8 = 122; pub const CCC129: u8 = 129; pub const CCC130: u8 = 132; pub const CCC132: u8 = 131; }
257
258#[rustfmt::skip]
259static MODIFIED_COMBINING_CLASS: &[u8; 256] = &[
260 combining_class::NotReordered,
261 combining_class::Overlay,
262 2, 3, 4, 5, 6,
263 combining_class::Nukta,
264 combining_class::KanaVoicing,
265 combining_class::Virama,
266
267 modified_combining_class::CCC10,
269 modified_combining_class::CCC11,
270 modified_combining_class::CCC12,
271 modified_combining_class::CCC13,
272 modified_combining_class::CCC14,
273 modified_combining_class::CCC15,
274 modified_combining_class::CCC16,
275 modified_combining_class::CCC17,
276 modified_combining_class::CCC18,
277 modified_combining_class::CCC19,
278 modified_combining_class::CCC20,
279 modified_combining_class::CCC21,
280 modified_combining_class::CCC22,
281 modified_combining_class::CCC23,
282 modified_combining_class::CCC24,
283 modified_combining_class::CCC25,
284 modified_combining_class::CCC26,
285
286 modified_combining_class::CCC27,
288 modified_combining_class::CCC28,
289 modified_combining_class::CCC29,
290 modified_combining_class::CCC30,
291 modified_combining_class::CCC31,
292 modified_combining_class::CCC32,
293 modified_combining_class::CCC33,
294 modified_combining_class::CCC34,
295 modified_combining_class::CCC35,
296
297 modified_combining_class::CCC36,
299
300 37, 38, 39,
301 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
302 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
303 80, 81, 82, 83,
304
305 modified_combining_class::CCC84,
307 85, 86, 87, 88, 89, 90,
308 modified_combining_class::CCC91,
309 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
310
311 modified_combining_class::CCC103,
313 104, 105, 106,
314 modified_combining_class::CCC107,
315 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
316
317 modified_combining_class::CCC118,
319 119, 120, 121,
320 modified_combining_class::CCC122,
321 123, 124, 125, 126, 127, 128,
322
323 modified_combining_class::CCC129,
325 modified_combining_class::CCC130,
326 131,
327 modified_combining_class::CCC132,
328 133, 134, 135, 136, 137, 138, 139,
329
330
331 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
332 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
333 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
334 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
335 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
336 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
337
338 combining_class::AttachedBelowLeft,
339 201,
340 combining_class::AttachedBelow,
341 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
342 combining_class::AttachedAbove,
343 215,
344 combining_class::AttachedAboveRight,
345 217,
346 combining_class::BelowLeft,
347 219,
348 combining_class::Below,
349 221,
350 combining_class::BelowRight,
351 223,
352 combining_class::Left,
353 225,
354 combining_class::Right,
355 227,
356 combining_class::AboveLeft,
357 229,
358 combining_class::Above,
359 231,
360 combining_class::AboveRight,
361 combining_class::DoubleBelow,
362 combining_class::DoubleAbove,
363 235, 236, 237, 238, 239,
364 combining_class::IotaSubscript,
365 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
366 combining_class::Invalid,
367];
368
369pub trait CharExt {
370 fn script(self) -> Script;
371 fn general_category(self) -> GeneralCategory;
372 fn space_fallback(self) -> hb_unicode_funcs_t::space_t;
373 fn combining_class(self) -> u8;
374 fn modified_combining_class(self) -> u8;
375 fn mirrored(self) -> Option<Codepoint>;
376 fn is_emoji_extended_pictographic(self) -> bool;
377 fn is_default_ignorable(self) -> bool;
378 fn is_variation_selector(self) -> bool;
379 fn vertical(self) -> Option<Codepoint>;
380}
381
382impl CharExt for Codepoint {
383 fn script(self) -> Script {
384 _hb_ucd_sc_map[_hb_ucd_sc(self as usize) as usize]
385 }
386
387 fn general_category(self) -> GeneralCategory {
388 GeneralCategory(_hb_ucd_gc(self as usize))
389 }
390
391 fn space_fallback(self) -> hb_unicode_funcs_t::space_t {
392 use hb_unicode_funcs_t::*;
393
394 match self {
396 0x0020 => SPACE, 0x00A0 => SPACE, 0x2000 => SPACE_EM_2, 0x2001 => SPACE_EM, 0x2002 => SPACE_EM_2, 0x2003 => SPACE_EM, 0x2004 => SPACE_EM_3, 0x2005 => SPACE_EM_4, 0x2006 => SPACE_EM_6, 0x2007 => SPACE_FIGURE, 0x2008 => SPACE_PUNCTUATION, 0x2009 => SPACE_EM_5, 0x200A => SPACE_EM_16, 0x202F => SPACE_NARROW, 0x205F => SPACE_4_EM_18, 0x3000 => SPACE_EM, _ => NOT_SPACE, }
414 }
415
416 fn combining_class(self) -> u8 {
417 _hb_ucd_ccc(self as usize)
418 }
419
420 fn modified_combining_class(self) -> u8 {
421 let u = self;
422
423 if u == 0x1A60 {
425 return 254;
426 }
427
428 if u == 0x0FC6 {
430 return 254;
431 }
432
433 if u == 0x0F39 {
435 return 127;
436 }
437
438 let k = u.combining_class();
439
440 MODIFIED_COMBINING_CLASS[k as usize]
441 }
442
443 fn mirrored(self) -> Option<Codepoint> {
444 let delta = _hb_ucd_bmg(self as usize);
445 if delta == 0 {
446 None
447 } else {
448 Some(((self as i32).wrapping_add(delta as i32)) as u32)
449 }
450 }
451
452 fn is_emoji_extended_pictographic(self) -> bool {
453 super::unicode_emoji_table::is_Extended_Pictographic(self)
454 }
455
456 fn is_default_ignorable(self) -> bool {
494 let ch = self;
495 let plane = ch >> 16;
496 if plane == 0 {
497 let page = ch >> 8;
499 match page {
500 0x00 => ch == 0x00AD,
501 0x03 => ch == 0x034F,
502 0x06 => ch == 0x061C,
503 0x17 => (0x17B4..=0x17B5).contains(&ch),
504 0x18 => (0x180B..=0x180E).contains(&ch),
505 0x20 => {
506 (0x200B..=0x200F).contains(&ch)
507 || (0x202A..=0x202E).contains(&ch)
508 || (0x2060..=0x206F).contains(&ch)
509 }
510 0xFE => (0xFE00..=0xFE0F).contains(&ch) || ch == 0xFEFF,
511 0xFF => (0xFFF0..=0xFFF8).contains(&ch),
512 _ => false,
513 }
514 } else {
515 match plane {
517 0x01 => (0x1D173..=0x1D17A).contains(&ch),
518 0x0E => (0xE0000..=0xE0FFF).contains(&ch),
519 _ => false,
520 }
521 }
522 }
523
524 fn is_variation_selector(self) -> bool {
525 (0x0FE00..=0x0FE0F).contains(&self) || (0xE0100..=0xE01EF).contains(&self) }
530
531 fn vertical(self) -> Option<Codepoint> {
532 Some(match self >> 8 {
533 0x20 => match self {
534 0x2013 => 0xfe32, 0x2014 => 0xfe31, 0x2025 => 0xfe30, 0x2026 => 0xfe19, _ => return None,
539 },
540 0x30 => match self {
541 0x3001 => 0xfe11, 0x3002 => 0xfe12, 0x3008 => 0xfe3f, 0x3009 => 0xfe40, 0x300a => 0xfe3d, 0x300b => 0xfe3e, 0x300c => 0xfe41, 0x300d => 0xfe42, 0x300e => 0xfe43, 0x300f => 0xfe44, 0x3010 => 0xfe3b, 0x3011 => 0xfe3c, 0x3014 => 0xfe39, 0x3015 => 0xfe3a, 0x3016 => 0xfe17, 0x3017 => 0xfe18, _ => return None,
558 },
559 0xfe => match self {
560 0xfe4f => 0xfe34, _ => return None,
562 },
563 0xff => match self {
564 0xff01 => 0xfe15, 0xff08 => 0xfe35, 0xff09 => 0xfe36, 0xff0c => 0xfe10, 0xff1a => 0xfe13, 0xff1b => 0xfe14, 0xff1f => 0xfe16, 0xff3b => 0xfe47, 0xff3d => 0xfe48, 0xff3f => 0xfe33, 0xff5b => 0xfe37, 0xff5d => 0xfe38, _ => return None,
577 },
578 _ => return None,
579 })
580 }
581}
582
583const S_BASE: u32 = 0xAC00;
584const L_BASE: u32 = 0x1100;
585const V_BASE: u32 = 0x1161;
586const T_BASE: u32 = 0x11A7;
587const L_COUNT: u32 = 19;
588const V_COUNT: u32 = 21;
589const T_COUNT: u32 = 28;
590const N_COUNT: u32 = V_COUNT * T_COUNT;
591const S_COUNT: u32 = L_COUNT * N_COUNT;
592
593pub fn compose(a: Codepoint, b: Codepoint) -> Option<Codepoint> {
594 if let Some(ab) = compose_hangul(a, b) {
596 return Some(ab);
597 }
598
599 let u: u32;
600
601 if (a & 0xFFFF_F800) == 0x0000 && (b & 0xFFFF_FF80) == 0x0300 {
602 let k = HB_CODEPOINT_ENCODE3_11_7_14(a, b, 0);
606 let v = _hb_ucd_dm2_u32_map
607 .binary_search_by(|probe| {
608 let key = probe & HB_CODEPOINT_ENCODE3_11_7_14(0x001F_FFFF, 0x001F_FFFF, 0);
609 key.cmp(&k)
610 })
611 .ok()
612 .map(|index| _hb_ucd_dm2_u32_map[index]);
613
614 if let Some(value) = v {
615 u = HB_CODEPOINT_DECODE3_11_7_14_3(value);
616 } else {
617 return None;
618 }
619 } else {
620 let k = HB_CODEPOINT_ENCODE3(a, b, 0);
623 let v = _hb_ucd_dm2_u64_map
624 .binary_search_by(|probe| {
625 let key = probe & HB_CODEPOINT_ENCODE3(0x001F_FFFF, 0x001F_FFFF, 0);
626 key.cmp(&k)
627 })
628 .ok()
629 .map(|index| _hb_ucd_dm2_u64_map[index]);
630
631 if let Some(value) = v {
632 u = HB_CODEPOINT_DECODE3_3(value);
633 } else {
634 return None;
635 }
636 }
637
638 if u == 0 {
639 None
640 } else {
641 Some(u)
642 }
643}
644
645fn compose_hangul(a: Codepoint, b: Codepoint) -> Option<Codepoint> {
646 let l = a;
647 let v = b;
648 if L_BASE <= l && l < (L_BASE + L_COUNT) && V_BASE <= v && v < (V_BASE + V_COUNT) {
649 let r = S_BASE + (l - L_BASE) * N_COUNT + (v - V_BASE) * T_COUNT;
650 Some(r)
651 } else if S_BASE <= l
652 && l <= (S_BASE + S_COUNT - T_COUNT)
653 && T_BASE <= v
654 && v < (T_BASE + T_COUNT)
655 && (l - S_BASE) % T_COUNT == 0
656 {
657 let r = l + (v - T_BASE);
658 Some(r)
659 } else {
660 None
661 }
662}
663
664pub fn decompose(ab: Codepoint) -> Option<(Codepoint, Codepoint)> {
665 if let Some((a, b)) = decompose_hangul(ab) {
666 return Some((a, b));
667 }
668
669 let mut i = _hb_ucd_dm(ab as usize) as usize;
670
671 if i == 0 {
673 return None;
674 }
675 i -= 1;
676
677 if i < _hb_ucd_dm1_p0_map.len() + _hb_ucd_dm1_p2_map.len() {
678 let a = if i < _hb_ucd_dm1_p0_map.len() {
679 _hb_ucd_dm1_p0_map[i] as u32
680 } else {
681 let j = i - _hb_ucd_dm1_p0_map.len();
682 0x20000 | _hb_ucd_dm1_p2_map[j] as u32
683 };
684 return Some((a, 0));
685 }
686
687 i -= _hb_ucd_dm1_p0_map.len() + _hb_ucd_dm1_p2_map.len();
688
689 if i < _hb_ucd_dm2_u32_map.len() {
690 let v = _hb_ucd_dm2_u32_map[i];
691 let a = HB_CODEPOINT_DECODE3_11_7_14_1(v);
692 let b = HB_CODEPOINT_DECODE3_11_7_14_2(v);
693 return Some((a, b));
694 }
695
696 i -= _hb_ucd_dm2_u32_map.len();
697
698 let v = _hb_ucd_dm2_u64_map[i];
699 let a = HB_CODEPOINT_DECODE3_1(v);
700 let b = HB_CODEPOINT_DECODE3_2(v);
701 Some((a, b))
702}
703
704pub fn decompose_hangul(ab: Codepoint) -> Option<(Codepoint, Codepoint)> {
705 let si = ab.wrapping_sub(S_BASE);
706 if si >= S_COUNT {
707 return None;
708 }
709
710 let (a, b) = if si % T_COUNT != 0 {
711 (S_BASE + (si / T_COUNT) * T_COUNT, T_BASE + (si % T_COUNT))
713 } else {
714 (L_BASE + (si / N_COUNT), V_BASE + (si % N_COUNT) / T_COUNT)
716 };
717 Some((a, b))
718}
719
720pub mod hb_gc {
721 pub const HB_UNICODE_GENERAL_CATEGORY_CONTROL: u32 = 0;
722 pub const HB_UNICODE_GENERAL_CATEGORY_FORMAT: u32 = 1;
723 pub const HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: u32 = 2;
724 pub const HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE: u32 = 3;
725 pub const HB_UNICODE_GENERAL_CATEGORY_SURROGATE: u32 = 4;
726 pub const HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER: u32 = 5;
727 pub const HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER: u32 = 6;
728 pub const HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: u32 = 7;
729 pub const HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER: u32 = 8;
730 pub const HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER: u32 = 9;
731 pub const HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: u32 = 10;
732 pub const HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: u32 = 11;
733 pub const HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: u32 = 12;
734 pub const HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER: u32 = 13;
735 pub const HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER: u32 = 14;
736 pub const HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER: u32 = 15;
737 pub const HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: u32 = 16;
738 pub const HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: u32 = 17;
739 pub const HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: u32 = 18;
740 pub const HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: u32 = 19;
741 pub const HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: u32 = 20;
742 pub const HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: u32 = 21;
743 pub const HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: u32 = 22;
744 pub const HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: u32 = 23;
745 pub const HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: u32 = 24;
746 pub const HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: u32 = 25;
747 pub const HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: u32 = 26;
748 pub const HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: u32 = 27;
749 pub const HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: u32 = 28;
750 pub const HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR: u32 = 29;
751}