2 * Copyright (C) 2010 Google, Inc.
4 * This is part of HarfBuzz, a text shaping library.
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 * Google Author(s): Behdad Esfahbod
27 #include "hb-ot-shape-complex-private.hh"
32 * Bits used in the joining tables
38 JOINING_TYPE_C = JOINING_TYPE_D,
39 JOINING_GROUP_ALAPH = 3,
40 JOINING_GROUP_DALATH_RISH = 4,
41 NUM_STATE_MACHINE_COLS = 5,
43 /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */
46 JOINING_TYPE_X = 7, /* means: use general-category to choose between U or T. */
55 * Main joining-type table, covering U+0600..U+07FF.
56 * Includes Arabic, Syriac, and N'ko.
58 static const uint8_t arabic_syriac_nko_joining_types[0x0800 - 0x0600 + 1] =
61 * The following table is generated by running:
63 * ./gen-arabic-joining-table.py < ArabicShaping.txt
65 * on the ArabicShaping.txt file with the header:
67 * # ArabicShaping-6.0.0.txt
68 * # Date: 2010-04-30, 13:47:00 PDT [KW]
70 /* == Start of generated table == */
71 JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
72 JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
73 JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
74 JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
75 JOINING_TYPE_X, /* 0604 */
76 JOINING_TYPE_X, /* 0605 */
77 JOINING_TYPE_X, /* 0606 */
78 JOINING_TYPE_X, /* 0607 */
79 JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
80 JOINING_TYPE_X, /* 0609 */
81 JOINING_TYPE_X, /* 060A */
82 JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
83 JOINING_TYPE_X, /* 060C */
84 JOINING_TYPE_X, /* 060D */
85 JOINING_TYPE_X, /* 060E */
86 JOINING_TYPE_X, /* 060F */
87 JOINING_TYPE_X, /* 0610 */
88 JOINING_TYPE_X, /* 0611 */
89 JOINING_TYPE_X, /* 0612 */
90 JOINING_TYPE_X, /* 0613 */
91 JOINING_TYPE_X, /* 0614 */
92 JOINING_TYPE_X, /* 0615 */
93 JOINING_TYPE_X, /* 0616 */
94 JOINING_TYPE_X, /* 0617 */
95 JOINING_TYPE_X, /* 0618 */
96 JOINING_TYPE_X, /* 0619 */
97 JOINING_TYPE_X, /* 061A */
98 JOINING_TYPE_X, /* 061B */
99 JOINING_TYPE_X, /* 061C */
100 JOINING_TYPE_X, /* 061D */
101 JOINING_TYPE_X, /* 061E */
102 JOINING_TYPE_X, /* 061F */
103 JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
104 JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
105 JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
106 JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
107 JOINING_TYPE_R, /* 0624; HAMZA ON WAW; R; WAW */
108 JOINING_TYPE_R, /* 0625; HAMZA UNDER ALEF; R; ALEF */
109 JOINING_TYPE_D, /* 0626; HAMZA ON YEH; D; YEH */
110 JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
111 JOINING_TYPE_D, /* 0628; BEH; D; BEH */
112 JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
113 JOINING_TYPE_D, /* 062A; TEH; D; BEH */
114 JOINING_TYPE_D, /* 062B; THEH; D; BEH */
115 JOINING_TYPE_D, /* 062C; JEEM; D; HAH */
116 JOINING_TYPE_D, /* 062D; HAH; D; HAH */
117 JOINING_TYPE_D, /* 062E; KHAH; D; HAH */
118 JOINING_TYPE_R, /* 062F; DAL; R; DAL */
119 JOINING_TYPE_R, /* 0630; THAL; R; DAL */
120 JOINING_TYPE_R, /* 0631; REH; R; REH */
121 JOINING_TYPE_R, /* 0632; ZAIN; R; REH */
122 JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
123 JOINING_TYPE_D, /* 0634; SHEEN; D; SEEN */
124 JOINING_TYPE_D, /* 0635; SAD; D; SAD */
125 JOINING_TYPE_D, /* 0636; DAD; D; SAD */
126 JOINING_TYPE_D, /* 0637; TAH; D; TAH */
127 JOINING_TYPE_D, /* 0638; ZAH; D; TAH */
128 JOINING_TYPE_D, /* 0639; AIN; D; AIN */
129 JOINING_TYPE_D, /* 063A; GHAIN; D; AIN */
130 JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
131 JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
132 JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V; D; FARSI YEH */
133 JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
134 JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
135 JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
136 JOINING_TYPE_D, /* 0641; FEH; D; FEH */
137 JOINING_TYPE_D, /* 0642; QAF; D; QAF */
138 JOINING_TYPE_D, /* 0643; KAF; D; KAF */
139 JOINING_TYPE_D, /* 0644; LAM; D; LAM */
140 JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
141 JOINING_TYPE_D, /* 0646; NOON; D; NOON */
142 JOINING_TYPE_D, /* 0647; HEH; D; HEH */
143 JOINING_TYPE_R, /* 0648; WAW; R; WAW */
144 JOINING_TYPE_D, /* 0649; ALEF MAKSURA; D; YEH */
145 JOINING_TYPE_D, /* 064A; YEH; D; YEH */
146 JOINING_TYPE_X, /* 064B */
147 JOINING_TYPE_X, /* 064C */
148 JOINING_TYPE_X, /* 064D */
149 JOINING_TYPE_X, /* 064E */
150 JOINING_TYPE_X, /* 064F */
151 JOINING_TYPE_X, /* 0650 */
152 JOINING_TYPE_X, /* 0651 */
153 JOINING_TYPE_X, /* 0652 */
154 JOINING_TYPE_X, /* 0653 */
155 JOINING_TYPE_X, /* 0654 */
156 JOINING_TYPE_X, /* 0655 */
157 JOINING_TYPE_X, /* 0656 */
158 JOINING_TYPE_X, /* 0657 */
159 JOINING_TYPE_X, /* 0658 */
160 JOINING_TYPE_X, /* 0659 */
161 JOINING_TYPE_X, /* 065A */
162 JOINING_TYPE_X, /* 065B */
163 JOINING_TYPE_X, /* 065C */
164 JOINING_TYPE_X, /* 065D */
165 JOINING_TYPE_X, /* 065E */
166 JOINING_TYPE_X, /* 065F */
167 JOINING_TYPE_X, /* 0660 */
168 JOINING_TYPE_X, /* 0661 */
169 JOINING_TYPE_X, /* 0662 */
170 JOINING_TYPE_X, /* 0663 */
171 JOINING_TYPE_X, /* 0664 */
172 JOINING_TYPE_X, /* 0665 */
173 JOINING_TYPE_X, /* 0666 */
174 JOINING_TYPE_X, /* 0667 */
175 JOINING_TYPE_X, /* 0668 */
176 JOINING_TYPE_X, /* 0669 */
177 JOINING_TYPE_X, /* 066A */
178 JOINING_TYPE_X, /* 066B */
179 JOINING_TYPE_X, /* 066C */
180 JOINING_TYPE_X, /* 066D */
181 JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
182 JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
183 JOINING_TYPE_X, /* 0670 */
184 JOINING_TYPE_R, /* 0671; HAMZAT WASL ON ALEF; R; ALEF */
185 JOINING_TYPE_R, /* 0672; WAVY HAMZA ON ALEF; R; ALEF */
186 JOINING_TYPE_R, /* 0673; WAVY HAMZA UNDER ALEF; R; ALEF */
187 JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
188 JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
189 JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
190 JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA; R; WAW */
191 JOINING_TYPE_D, /* 0678; HIGH HAMZA YEH; D; YEH */
192 JOINING_TYPE_D, /* 0679; TEH WITH SMALL TAH; D; BEH */
193 JOINING_TYPE_D, /* 067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH */
194 JOINING_TYPE_D, /* 067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH */
195 JOINING_TYPE_D, /* 067C; TEH WITH RING; D; BEH */
196 JOINING_TYPE_D, /* 067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH */
197 JOINING_TYPE_D, /* 067E; TEH WITH 3 DOTS BELOW; D; BEH */
198 JOINING_TYPE_D, /* 067F; TEH WITH 4 DOTS ABOVE; D; BEH */
199 JOINING_TYPE_D, /* 0680; BEH WITH 4 DOTS BELOW; D; BEH */
200 JOINING_TYPE_D, /* 0681; HAMZA ON HAH; D; HAH */
201 JOINING_TYPE_D, /* 0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH */
202 JOINING_TYPE_D, /* 0683; HAH WITH MIDDLE 2 DOTS; D; HAH */
203 JOINING_TYPE_D, /* 0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH */
204 JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
205 JOINING_TYPE_D, /* 0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH */
206 JOINING_TYPE_D, /* 0687; HAH WITH MIDDLE 4 DOTS; D; HAH */
207 JOINING_TYPE_R, /* 0688; DAL WITH SMALL TAH; R; DAL */
208 JOINING_TYPE_R, /* 0689; DAL WITH RING; R; DAL */
209 JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
210 JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL */
211 JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
212 JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
213 JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
214 JOINING_TYPE_R, /* 068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL */
215 JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
216 JOINING_TYPE_R, /* 0691; REH WITH SMALL TAH; R; REH */
217 JOINING_TYPE_R, /* 0692; REH WITH SMALL V; R; REH */
218 JOINING_TYPE_R, /* 0693; REH WITH RING; R; REH */
219 JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
220 JOINING_TYPE_R, /* 0695; REH WITH SMALL V BELOW; R; REH */
221 JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH */
222 JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
223 JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
224 JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
225 JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
226 JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
227 JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
228 JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
229 JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
230 JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
231 JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
232 JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
233 JOINING_TYPE_D, /* 06A2; FEH WITH DOT MOVED BELOW; D; FEH */
234 JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
235 JOINING_TYPE_D, /* 06A4; FEH WITH 3 DOTS ABOVE; D; FEH */
236 JOINING_TYPE_D, /* 06A5; FEH WITH 3 DOTS BELOW; D; FEH */
237 JOINING_TYPE_D, /* 06A6; FEH WITH 4 DOTS ABOVE; D; FEH */
238 JOINING_TYPE_D, /* 06A7; QAF WITH DOT ABOVE; D; QAF */
239 JOINING_TYPE_D, /* 06A8; QAF WITH 3 DOTS ABOVE; D; QAF */
240 JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
241 JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
242 JOINING_TYPE_D, /* 06AB; KAF WITH RING; D; GAF */
243 JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
244 JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
245 JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
246 JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
247 JOINING_TYPE_D, /* 06B0; GAF WITH RING; D; GAF */
248 JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
249 JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
250 JOINING_TYPE_D, /* 06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF */
251 JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
252 JOINING_TYPE_D, /* 06B5; LAM WITH SMALL V; D; LAM */
253 JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
254 JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
255 JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
256 JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
257 JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
258 JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH SMALL TAH; D; NOON */
259 JOINING_TYPE_D, /* 06BC; NOON WITH RING; D; NOON */
260 JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
261 JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
262 JOINING_TYPE_D, /* 06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH */
263 JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
264 JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
265 JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
266 JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
267 JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
268 JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
269 JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
270 JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA; R; WAW */
271 JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
272 JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED SMALL V; R; WAW */
273 JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
274 JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
275 JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
276 JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
277 JOINING_TYPE_D, /* 06CE; FARSI YEH WITH SMALL V; D; FARSI YEH */
278 JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
279 JOINING_TYPE_D, /* 06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH */
280 JOINING_TYPE_D, /* 06D1; YEH WITH 3 DOTS BELOW; D; YEH */
281 JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
282 JOINING_TYPE_R, /* 06D3; HAMZA ON YEH BARREE; R; YEH BARREE */
283 JOINING_TYPE_X, /* 06D4 */
284 JOINING_TYPE_R, /* 06D5; AE; R; TEH MARBUTA */
285 JOINING_TYPE_X, /* 06D6 */
286 JOINING_TYPE_X, /* 06D7 */
287 JOINING_TYPE_X, /* 06D8 */
288 JOINING_TYPE_X, /* 06D9 */
289 JOINING_TYPE_X, /* 06DA */
290 JOINING_TYPE_X, /* 06DB */
291 JOINING_TYPE_X, /* 06DC */
292 JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
293 JOINING_TYPE_X, /* 06DE */
294 JOINING_TYPE_X, /* 06DF */
295 JOINING_TYPE_X, /* 06E0 */
296 JOINING_TYPE_X, /* 06E1 */
297 JOINING_TYPE_X, /* 06E2 */
298 JOINING_TYPE_X, /* 06E3 */
299 JOINING_TYPE_X, /* 06E4 */
300 JOINING_TYPE_X, /* 06E5 */
301 JOINING_TYPE_X, /* 06E6 */
302 JOINING_TYPE_X, /* 06E7 */
303 JOINING_TYPE_X, /* 06E8 */
304 JOINING_TYPE_X, /* 06E9 */
305 JOINING_TYPE_X, /* 06EA */
306 JOINING_TYPE_X, /* 06EB */
307 JOINING_TYPE_X, /* 06EC */
308 JOINING_TYPE_X, /* 06ED */
309 JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V; R; DAL */
310 JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V; R; REH */
311 JOINING_TYPE_X, /* 06F0 */
312 JOINING_TYPE_X, /* 06F1 */
313 JOINING_TYPE_X, /* 06F2 */
314 JOINING_TYPE_X, /* 06F3 */
315 JOINING_TYPE_X, /* 06F4 */
316 JOINING_TYPE_X, /* 06F5 */
317 JOINING_TYPE_X, /* 06F6 */
318 JOINING_TYPE_X, /* 06F7 */
319 JOINING_TYPE_X, /* 06F8 */
320 JOINING_TYPE_X, /* 06F9 */
321 JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
322 JOINING_TYPE_D, /* 06FB; DAD WITH DOT BELOW; D; SAD */
323 JOINING_TYPE_D, /* 06FC; GHAIN WITH DOT BELOW; D; AIN */
324 JOINING_TYPE_X, /* 06FD */
325 JOINING_TYPE_X, /* 06FE */
326 JOINING_TYPE_D, /* 06FF; HEH WITH INVERTED V; D; KNOTTED HEH */
327 JOINING_TYPE_X, /* 0700 */
328 JOINING_TYPE_X, /* 0701 */
329 JOINING_TYPE_X, /* 0702 */
330 JOINING_TYPE_X, /* 0703 */
331 JOINING_TYPE_X, /* 0704 */
332 JOINING_TYPE_X, /* 0705 */
333 JOINING_TYPE_X, /* 0706 */
334 JOINING_TYPE_X, /* 0707 */
335 JOINING_TYPE_X, /* 0708 */
336 JOINING_TYPE_X, /* 0709 */
337 JOINING_TYPE_X, /* 070A */
338 JOINING_TYPE_X, /* 070B */
339 JOINING_TYPE_X, /* 070C */
340 JOINING_TYPE_X, /* 070D */
341 JOINING_TYPE_X, /* 070E */
342 JOINING_TYPE_X, /* 070F */
343 JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
344 JOINING_TYPE_X, /* 0711 */
345 JOINING_TYPE_D, /* 0712; BETH; D; BETH */
346 JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
347 JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
348 JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
349 JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
350 JOINING_TYPE_R, /* 0717; HE; R; HE */
351 JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
352 JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
353 JOINING_TYPE_D, /* 071A; HETH; D; HETH */
354 JOINING_TYPE_D, /* 071B; TETH; D; TETH */
355 JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
356 JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
357 JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
358 JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
359 JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
360 JOINING_TYPE_D, /* 0721; MIM; D; MIM */
361 JOINING_TYPE_D, /* 0722; NUN; D; NUN */
362 JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
363 JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
364 JOINING_TYPE_D, /* 0725; E; D; E */
365 JOINING_TYPE_D, /* 0726; PE; D; PE */
366 JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
367 JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
368 JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
369 JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
370 JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
371 JOINING_TYPE_R, /* 072C; TAW; R; TAW */
372 JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
373 JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
374 JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
375 JOINING_TYPE_X, /* 0730 */
376 JOINING_TYPE_X, /* 0731 */
377 JOINING_TYPE_X, /* 0732 */
378 JOINING_TYPE_X, /* 0733 */
379 JOINING_TYPE_X, /* 0734 */
380 JOINING_TYPE_X, /* 0735 */
381 JOINING_TYPE_X, /* 0736 */
382 JOINING_TYPE_X, /* 0737 */
383 JOINING_TYPE_X, /* 0738 */
384 JOINING_TYPE_X, /* 0739 */
385 JOINING_TYPE_X, /* 073A */
386 JOINING_TYPE_X, /* 073B */
387 JOINING_TYPE_X, /* 073C */
388 JOINING_TYPE_X, /* 073D */
389 JOINING_TYPE_X, /* 073E */
390 JOINING_TYPE_X, /* 073F */
391 JOINING_TYPE_X, /* 0740 */
392 JOINING_TYPE_X, /* 0741 */
393 JOINING_TYPE_X, /* 0742 */
394 JOINING_TYPE_X, /* 0743 */
395 JOINING_TYPE_X, /* 0744 */
396 JOINING_TYPE_X, /* 0745 */
397 JOINING_TYPE_X, /* 0746 */
398 JOINING_TYPE_X, /* 0747 */
399 JOINING_TYPE_X, /* 0748 */
400 JOINING_TYPE_X, /* 0749 */
401 JOINING_TYPE_X, /* 074A */
402 JOINING_TYPE_X, /* 074B */
403 JOINING_TYPE_X, /* 074C */
404 JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
405 JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
406 JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
407 JOINING_TYPE_D, /* 0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH */
408 JOINING_TYPE_D, /* 0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH */
409 JOINING_TYPE_D, /* 0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH */
410 JOINING_TYPE_D, /* 0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH */
411 JOINING_TYPE_D, /* 0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
412 JOINING_TYPE_D, /* 0755; BEH WITH INVERTED SMALL V BELOW; D; BEH */
413 JOINING_TYPE_D, /* 0756; BEH WITH SMALL V; D; BEH */
414 JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
415 JOINING_TYPE_D, /* 0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH */
416 JOINING_TYPE_R, /* 0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL */
417 JOINING_TYPE_R, /* 075A; DAL WITH INVERTED SMALL V BELOW; R; DAL */
418 JOINING_TYPE_R, /* 075B; REH WITH STROKE; R; REH */
419 JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
420 JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
421 JOINING_TYPE_D, /* 075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN */
422 JOINING_TYPE_D, /* 075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN */
423 JOINING_TYPE_D, /* 0760; FEH WITH 2 DOTS BELOW; D; FEH */
424 JOINING_TYPE_D, /* 0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH */
425 JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
426 JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
427 JOINING_TYPE_D, /* 0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF */
428 JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
429 JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
430 JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
431 JOINING_TYPE_D, /* 0768; NOON WITH SMALL TAH; D; NOON */
432 JOINING_TYPE_D, /* 0769; NOON WITH SMALL V; D; NOON */
433 JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
434 JOINING_TYPE_R, /* 076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH */
435 JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
436 JOINING_TYPE_D, /* 076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN */
437 JOINING_TYPE_D, /* 076E; HAH WITH SMALL TAH BELOW; D; HAH */
438 JOINING_TYPE_D, /* 076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH */
439 JOINING_TYPE_D, /* 0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN */
440 JOINING_TYPE_R, /* 0771; REH WITH SMALL TAH AND 2 DOTS; R; REH */
441 JOINING_TYPE_D, /* 0772; HAH WITH SMALL TAH ABOVE; D; HAH */
442 JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
443 JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
444 JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
445 JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
446 JOINING_TYPE_D, /* 0777; YEH WITH DIGIT FOUR BELOW; D; YEH */
447 JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
448 JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
449 JOINING_TYPE_D, /* 077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
450 JOINING_TYPE_D, /* 077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
451 JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
452 JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
453 JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V; D; SEEN */
454 JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
455 JOINING_TYPE_X, /* 0780 */
456 JOINING_TYPE_X, /* 0781 */
457 JOINING_TYPE_X, /* 0782 */
458 JOINING_TYPE_X, /* 0783 */
459 JOINING_TYPE_X, /* 0784 */
460 JOINING_TYPE_X, /* 0785 */
461 JOINING_TYPE_X, /* 0786 */
462 JOINING_TYPE_X, /* 0787 */
463 JOINING_TYPE_X, /* 0788 */
464 JOINING_TYPE_X, /* 0789 */
465 JOINING_TYPE_X, /* 078A */
466 JOINING_TYPE_X, /* 078B */
467 JOINING_TYPE_X, /* 078C */
468 JOINING_TYPE_X, /* 078D */
469 JOINING_TYPE_X, /* 078E */
470 JOINING_TYPE_X, /* 078F */
471 JOINING_TYPE_X, /* 0790 */
472 JOINING_TYPE_X, /* 0791 */
473 JOINING_TYPE_X, /* 0792 */
474 JOINING_TYPE_X, /* 0793 */
475 JOINING_TYPE_X, /* 0794 */
476 JOINING_TYPE_X, /* 0795 */
477 JOINING_TYPE_X, /* 0796 */
478 JOINING_TYPE_X, /* 0797 */
479 JOINING_TYPE_X, /* 0798 */
480 JOINING_TYPE_X, /* 0799 */
481 JOINING_TYPE_X, /* 079A */
482 JOINING_TYPE_X, /* 079B */
483 JOINING_TYPE_X, /* 079C */
484 JOINING_TYPE_X, /* 079D */
485 JOINING_TYPE_X, /* 079E */
486 JOINING_TYPE_X, /* 079F */
487 JOINING_TYPE_X, /* 07A0 */
488 JOINING_TYPE_X, /* 07A1 */
489 JOINING_TYPE_X, /* 07A2 */
490 JOINING_TYPE_X, /* 07A3 */
491 JOINING_TYPE_X, /* 07A4 */
492 JOINING_TYPE_X, /* 07A5 */
493 JOINING_TYPE_X, /* 07A6 */
494 JOINING_TYPE_X, /* 07A7 */
495 JOINING_TYPE_X, /* 07A8 */
496 JOINING_TYPE_X, /* 07A9 */
497 JOINING_TYPE_X, /* 07AA */
498 JOINING_TYPE_X, /* 07AB */
499 JOINING_TYPE_X, /* 07AC */
500 JOINING_TYPE_X, /* 07AD */
501 JOINING_TYPE_X, /* 07AE */
502 JOINING_TYPE_X, /* 07AF */
503 JOINING_TYPE_X, /* 07B0 */
504 JOINING_TYPE_X, /* 07B1 */
505 JOINING_TYPE_X, /* 07B2 */
506 JOINING_TYPE_X, /* 07B3 */
507 JOINING_TYPE_X, /* 07B4 */
508 JOINING_TYPE_X, /* 07B5 */
509 JOINING_TYPE_X, /* 07B6 */
510 JOINING_TYPE_X, /* 07B7 */
511 JOINING_TYPE_X, /* 07B8 */
512 JOINING_TYPE_X, /* 07B9 */
513 JOINING_TYPE_X, /* 07BA */
514 JOINING_TYPE_X, /* 07BB */
515 JOINING_TYPE_X, /* 07BC */
516 JOINING_TYPE_X, /* 07BD */
517 JOINING_TYPE_X, /* 07BE */
518 JOINING_TYPE_X, /* 07BF */
519 JOINING_TYPE_X, /* 07C0 */
520 JOINING_TYPE_X, /* 07C1 */
521 JOINING_TYPE_X, /* 07C2 */
522 JOINING_TYPE_X, /* 07C3 */
523 JOINING_TYPE_X, /* 07C4 */
524 JOINING_TYPE_X, /* 07C5 */
525 JOINING_TYPE_X, /* 07C6 */
526 JOINING_TYPE_X, /* 07C7 */
527 JOINING_TYPE_X, /* 07C8 */
528 JOINING_TYPE_X, /* 07C9 */
529 JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
530 JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
531 JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
532 JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
533 JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
534 JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
535 JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
536 JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
537 JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
538 JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
539 JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
540 JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
541 JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
542 JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
543 JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
544 JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
545 JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
546 JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
547 JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
548 JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
549 JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
550 JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
551 JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
552 JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
553 JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
554 JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
555 JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
556 JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
557 JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
558 JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
559 JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
560 JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
561 JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
562 JOINING_TYPE_X, /* 07EB */
563 JOINING_TYPE_X, /* 07EC */
564 JOINING_TYPE_X, /* 07ED */
565 JOINING_TYPE_X, /* 07EE */
566 JOINING_TYPE_X, /* 07EF */
567 JOINING_TYPE_X, /* 07F0 */
568 JOINING_TYPE_X, /* 07F1 */
569 JOINING_TYPE_X, /* 07F2 */
570 JOINING_TYPE_X, /* 07F3 */
571 JOINING_TYPE_X, /* 07F4 */
572 JOINING_TYPE_X, /* 07F5 */
573 JOINING_TYPE_X, /* 07F6 */
574 JOINING_TYPE_X, /* 07F7 */
575 JOINING_TYPE_X, /* 07F8 */
576 JOINING_TYPE_X, /* 07F9 */
577 JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
578 JOINING_TYPE_X, /* 07FB */
579 JOINING_TYPE_X, /* 07FC */
580 JOINING_TYPE_X, /* 07FD */
581 JOINING_TYPE_X, /* 07FE */
582 JOINING_TYPE_X, /* 07FF */
583 /* == End of generated table == */
587 static unsigned int get_joining_type (hb_codepoint_t u, hb_category_t gen_cat)
589 /* TODO Macroize the magic bit operations */
591 if (likely ((u & ~(0x0600^0x07FF)) == 0x0600)) {
592 unsigned int j_type = arabic_syriac_nko_joining_types[u - 0x0600];
593 if (likely (j_type != JOINING_TYPE_X))
597 if (unlikely ((u & ~(0x200C^0x200D)) == 0x200C)) {
598 return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
601 return ((1<<gen_cat) & ((1<<HB_CATEGORY_NON_SPACING_MARK)|(1<<HB_CATEGORY_ENCLOSING_MARK)|(1<<HB_CATEGORY_FORMAT))) ?
602 JOINING_TYPE_T : JOINING_TYPE_U;
607 static const hb_tag_t arabic_syriac_features[] =
609 HB_TAG('i','n','i','t'),
610 HB_TAG('m','e','d','i'),
611 HB_TAG('f','i','n','a'),
612 HB_TAG('i','s','o','l'),
614 HB_TAG('m','e','d','2'),
615 HB_TAG('f','i','n','2'),
616 HB_TAG('f','i','n','3'),
621 /* Same order as the feature array */
635 COMMON_NUM_FEATURES = 4,
636 SYRIAC_NUM_FEATURES = 7,
637 TOTAL_NUM_FEATURES = NONE
640 static const struct arabic_state_table_entry {
645 } arabic_state_table[][NUM_STATE_MACHINE_COLS] =
647 /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
649 /* State 0: prev was U, not willing to join. */
650 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
652 /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
653 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
655 /* State 2: prev was D/ISOL, willing to join. */
656 { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
658 /* State 3: prev was D/FINA, willing to join. */
659 { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
661 /* State 4: prev was FINA ALAPH, not willing to join. */
662 { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
664 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
665 { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
667 /* State 6: prev was DALATH/RISH, not willing to join. */
668 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
674 _hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_plan_t *plan, const hb_segment_properties_t *props)
676 unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
677 for (unsigned int i = 0; i < num_features; i++)
678 plan->map.add_bool_feature (arabic_syriac_features[i], false);
682 _hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
684 unsigned int count = c->buffer->len;
685 unsigned int prev = 0, state = 0;
687 for (unsigned int i = 0; i < count; i++)
690 unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
692 if (unlikely (this_type == JOINING_TYPE_T))
695 const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
697 if (entry->prev_action != NONE)
698 c->buffer->info[prev].gproperty = entry->prev_action;
700 c->buffer->info[i].gproperty = entry->curr_action;
703 state = entry->next_state;
706 hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
707 unsigned int num_masks = c->buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
708 for (unsigned int i = 0; i < num_masks; i++)
709 mask_array[i] = c->plan->map.get_mask (arabic_syriac_features[i]);
711 for (unsigned int i = 0; i < count; i++)
712 c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];