1
pub mod arabic;
2
pub mod indic;
3
pub mod khmer;
4
pub mod mongolian;
5
pub mod myanmar;
6
mod syllable;
7
pub mod syriac;
8
pub mod thai_lao;
9
pub mod tibetan;
10

            
11
use crate::glyph_position::TextDirection;
12
use crate::gsub::{GlyphOrigin, RawGlyph};
13
use crate::scripts::syllable::SyllableChar;
14
use crate::tag;
15
use crate::unicode::mcc::sort_by_modified_combining_class;
16

            
17
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
18
pub enum ScriptType {
19
    Arabic,
20
    Default,
21
    Indic,
22
    Khmer,
23
    Mongolian,
24
    Myanmar,
25
    Syriac,
26
    ThaiLao,
27
    Tibetan,
28
}
29

            
30
impl From<u32> for ScriptType {
31
49248
    fn from(script_tag: u32) -> Self {
32
49248
        match script_tag {
33
            tag::ARAB => ScriptType::Arabic,
34
49248
            tag::LATN => ScriptType::Default,
35
            tag::CYRL => ScriptType::Default,
36
            tag::GREK => ScriptType::Default,
37
            tag::DEVA => ScriptType::Indic,
38
            tag::BENG => ScriptType::Indic,
39
            tag::GURU => ScriptType::Indic,
40
            tag::GUJR => ScriptType::Indic,
41
            tag::ORYA => ScriptType::Indic,
42
            tag::TAML => ScriptType::Indic,
43
            tag::TELU => ScriptType::Indic,
44
            tag::KNDA => ScriptType::Indic,
45
            tag::MLYM => ScriptType::Indic,
46
            tag::SINH => ScriptType::Indic,
47
            tag::KHMR => ScriptType::Khmer,
48
            tag::MONG => ScriptType::Mongolian,
49
            tag::MYMR => ScriptType::Myanmar,
50
            tag::MYM2 => ScriptType::Myanmar,
51
            tag::SYRC => ScriptType::Syriac,
52
            tag::THAI => ScriptType::ThaiLao,
53
            tag::LAO => ScriptType::ThaiLao,
54
            tag::TIBT => ScriptType::Tibetan,
55
            _ => ScriptType::Default,
56
        }
57
49248
    }
58
}
59

            
60
impl<T> SyllableChar for RawGlyph<T> {
61
    fn char(&self) -> char {
62
        match self.glyph_origin {
63
            GlyphOrigin::Char(ch) => ch,
64
            GlyphOrigin::Direct => panic!("unexpected glyph origin"),
65
        }
66
    }
67
}
68

            
69
pub fn preprocess_text(cs: &mut Vec<char>, script_tag: u32) {
70
    match ScriptType::from(script_tag) {
71
        ScriptType::Arabic => arabic::reorder_marks(cs),
72
        ScriptType::Default => sort_by_modified_combining_class(cs),
73
        ScriptType::Indic => indic::preprocess_indic(cs, script_tag),
74
        ScriptType::Khmer => khmer::preprocess_khmer(cs),
75
        ScriptType::Mongolian => sort_by_modified_combining_class(cs),
76
        ScriptType::Myanmar => {}
77
        ScriptType::Syriac => arabic::reorder_marks(cs),
78
        ScriptType::ThaiLao => thai_lao::reorder_marks(cs),
79
        ScriptType::Tibetan => tibetan::preprocess_tibetan(cs),
80
    }
81
}
82

            
83
mod rtl_tags {
84
    use crate::tag;
85

            
86
    // Unicode 1.1
87
    pub const ARAB: u32 = tag!(b"arab"); // Arabic
88
    pub const HEBR: u32 = tag!(b"hebr"); // Hebrew
89

            
90
    // Unicode 3.0
91
    pub const SYRC: u32 = tag!(b"syrc"); // Syriac
92
    pub const THAA: u32 = tag!(b"thaa"); // Thaana
93

            
94
    // Unicode 4.0
95
    pub const CPRT: u32 = tag!(b"cprt"); // Cypriot Syllabary
96

            
97
    // Unicode 4.1
98
    pub const KHAR: u32 = tag!(b"khar"); // Kharosthi
99

            
100
    // Unicode 5.0
101
    pub const PHNX: u32 = tag!(b"phnx"); // Phoenician
102
    pub const NKO: u32 = tag!(b"nko "); // N'Ko
103

            
104
    // Unicode 5.1
105
    pub const LYDI: u32 = tag!(b"lydi"); // Lydian
106

            
107
    // Unicode 5.2
108
    pub const AVST: u32 = tag!(b"avst"); // Avestan
109
    pub const ARMI: u32 = tag!(b"armi"); // Imperial Aramaic
110
    pub const PHLI: u32 = tag!(b"phli"); // Inscriptional Pahlavi
111
    pub const PRTI: u32 = tag!(b"prti"); // Inscriptional Parthian
112
    pub const SARB: u32 = tag!(b"sarb"); // Old South Arabian
113
    pub const ORKH: u32 = tag!(b"orkh"); // Old Turkic, Orkhon Runic
114
    pub const SAMR: u32 = tag!(b"samr"); // Samaritan
115

            
116
    // Unicode 6.0
117
    pub const MAND: u32 = tag!(b"mand"); // Mandaic, Mandaean
118

            
119
    // Unicode 6.1
120
    pub const MERC: u32 = tag!(b"merc"); // Meroitic Cursive
121
    pub const MERO: u32 = tag!(b"mero"); // Meroitic Hieroglyphs
122

            
123
    // Unicode 7.0
124
    pub const MANI: u32 = tag!(b"mani"); // Manichaean
125
    pub const MEND: u32 = tag!(b"mend"); // Mende Kikakui
126
    pub const NBAT: u32 = tag!(b"nbat"); // Nabataean
127
    pub const NARB: u32 = tag!(b"narb"); // Old North Arabian
128
    pub const PALM: u32 = tag!(b"palm"); // Palmyrene
129
    pub const PHLP: u32 = tag!(b"phlp"); // Psalter Pahlavi
130

            
131
    // Unicode 8.0
132
    pub const HATR: u32 = tag!(b"hatr"); // Hatran
133

            
134
    // Unicode 9.0
135
    pub const ADLM: u32 = tag!(b"adlm"); // Adlam
136

            
137
    // Unicode 11.0
138
    pub const ROHG: u32 = tag!(b"rohg"); // Hanifi Rohingya
139
    pub const SOGO: u32 = tag!(b"sogo"); // Old Sogdian
140
    pub const SOGD: u32 = tag!(b"sogd"); // Sogdian
141

            
142
    // Unicode 12.0
143
    pub const ELYM: u32 = tag!(b"elym"); // Elymaic
144

            
145
    // Unicode 13.0
146
    pub const CHRS: u32 = tag!(b"chrs"); // Chorasmian
147
    pub const YEZI: u32 = tag!(b"yezi"); // Yezidi
148

            
149
    // Unicode 14.0
150
    pub const OUGR: u32 = tag!(b"ougr"); // Old Uyghur
151

            
152
    // Unicode 16.0
153
    pub const GARA: u32 = tag!(b"gara"); // Garay
154
}
155

            
156
8316
pub fn horizontal_text_direction(script: u32) -> TextDirection {
157
    use rtl_tags as rtl;
158

            
159
    // Derived from https://github.com/harfbuzz/harfbuzz/blob/bdee8658c68cf400e266c91039d741b5047c2519/src/hb-common.cc#L556-L644
160
    // License: MIT
161
    // Copyright (c) 2009, 2010 Red Hat, Inc.
162
    // Copyright (c) 2011, 2012 Google, Inc.
163
8316
    match script {
164
        // Unicode 1.1
165
        | rtl::ARAB // Arabic
166
        | rtl::HEBR // Hebrew
167

            
168
        // Unicode 3.0
169
        | rtl::SYRC // Syriac
170
        | rtl::THAA // Thaana
171

            
172
        // Unicode 4.0
173
        | rtl::CPRT // Cypriot Syllabary
174

            
175
        // Unicode 4.1
176
        | rtl::KHAR // Kharosthi
177

            
178
        // Unicode 5.0
179
        | rtl::PHNX // Phoenician
180
        | rtl::NKO  // N'Ko
181

            
182
        // Unicode 5.1
183
        | rtl::LYDI // Lydian
184

            
185
        // Unicode 5.2
186
        | rtl::AVST // Avestan
187
        | rtl::ARMI // Imperial Aramaic
188
        | rtl::PHLI // Inscriptional Pahlavi
189
        | rtl::PRTI // Inscriptional Parthian
190
        | rtl::SARB // Old South Arabian
191
        | rtl::ORKH // Old Turkic, Orkhon Runic
192
        | rtl::SAMR // Samaritan
193

            
194
        // Unicode 6.0
195
        | rtl::MAND // Mandaic, Mandaean
196

            
197
        // Unicode 6.1
198
        | rtl::MERC // Meroitic Cursive
199
        | rtl::MERO // Meroitic Hieroglyphs
200

            
201
        // Unicode 7.0
202
        | rtl::MANI // Manichaean
203
        | rtl::MEND // Mende Kikakui
204
        | rtl::NBAT // Nabataean
205
        | rtl::NARB // Old North Arabian
206
        | rtl::PALM // Palmyrene
207
        | rtl::PHLP // Psalter Pahlavi
208

            
209
        // Unicode 8.0
210
        | rtl::HATR // Hatran
211

            
212
        // Unicode 9.0
213
        | rtl::ADLM // Adlam
214

            
215
        // Unicode 11.0
216
        | rtl::ROHG // Hanifi Rohingya
217
        | rtl::SOGO // Old Sogdian
218
        | rtl::SOGD // Sogdian
219

            
220
        // Unicode 12.0
221
        | rtl::ELYM // Elymaic
222

            
223
        // Unicode 13.0
224
        | rtl::CHRS // Chorasmian
225
        | rtl::YEZI // Yezidi
226

            
227
        // Unicode 14.0
228
        | rtl::OUGR // Old Uyghur
229

            
230
        // Unicode 16.0
231
1026
        | rtl::GARA => TextDirection::RightToLeft, // Garay
232

            
233
7290
        _ => TextDirection::LeftToRight,
234
    }
235
8316
}