1 | /* == Start of generated functions == */ |
---|---|
2 | /* |
3 | * The following functions are generated by running: |
4 | * |
5 | * ./gen-vowel-constraints.py use Scripts.txt |
6 | * |
7 | * on files with these headers: |
8 | * |
9 | * # Copied from https://docs.microsoft.com/en-us/typography/script-development/use |
10 | * # On October 23, 2018; with documentd dated 02/07/2018. |
11 | * |
12 | * # Scripts-11.0.0.txt |
13 | * # Date: 2018-02-21, 05:34:31 GMT |
14 | */ |
15 | |
16 | #include "hb-ot-shape-complex-vowel-constraints.hh" |
17 | |
18 | static void |
19 | _output_dotted_circle (hb_buffer_t *buffer) |
20 | { |
21 | hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu); |
22 | _hb_glyph_info_reset_continuation (&dottedcircle); |
23 | } |
24 | |
25 | static void |
26 | _output_with_dotted_circle (hb_buffer_t *buffer) |
27 | { |
28 | _output_dotted_circle (buffer); |
29 | buffer->next_glyph (); |
30 | } |
31 | |
32 | void |
33 | _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, |
34 | hb_buffer_t *buffer, |
35 | hb_font_t *font HB_UNUSED) |
36 | { |
37 | /* UGLY UGLY UGLY business of adding dotted-circle in the middle of |
38 | * vowel-sequences that look like another vowel. Data for each script |
39 | * collected from the USE script development spec. |
40 | * |
41 | * https://github.com/harfbuzz/harfbuzz/issues/1019 |
42 | */ |
43 | bool processed = false; |
44 | buffer->clear_output (); |
45 | unsigned int count = buffer->len; |
46 | switch ((unsigned) buffer->props.script) |
47 | { |
48 | case HB_SCRIPT_DEVANAGARI: |
49 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
50 | { |
51 | bool matched = false; |
52 | switch (buffer->cur ().codepoint) |
53 | { |
54 | case 0x0905u: |
55 | switch (buffer->cur (1).codepoint) |
56 | { |
57 | case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u: |
58 | case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu: |
59 | case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u: |
60 | matched = true; |
61 | break; |
62 | } |
63 | break; |
64 | case 0x0906u: |
65 | switch (buffer->cur (1).codepoint) |
66 | { |
67 | case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u: |
68 | case 0x0948u: |
69 | matched = true; |
70 | break; |
71 | } |
72 | break; |
73 | case 0x0909u: |
74 | matched = 0x0941u == buffer->cur (1).codepoint; |
75 | break; |
76 | case 0x090Fu: |
77 | switch (buffer->cur (1).codepoint) |
78 | { |
79 | case 0x0945u: case 0x0946u: case 0x0947u: |
80 | matched = true; |
81 | break; |
82 | } |
83 | break; |
84 | case 0x0930u: |
85 | if (0x094Du == buffer->cur (1).codepoint && |
86 | buffer->idx + 2 < count && |
87 | 0x0907u == buffer->cur (2).codepoint) |
88 | { |
89 | buffer->next_glyph (); |
90 | buffer->next_glyph (); |
91 | _output_dotted_circle (buffer); |
92 | } |
93 | break; |
94 | } |
95 | buffer->next_glyph (); |
96 | if (matched) _output_with_dotted_circle (buffer); |
97 | } |
98 | processed = true; |
99 | break; |
100 | |
101 | case HB_SCRIPT_BENGALI: |
102 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
103 | { |
104 | bool matched = false; |
105 | switch (buffer->cur ().codepoint) |
106 | { |
107 | case 0x0985u: |
108 | matched = 0x09BEu == buffer->cur (1).codepoint; |
109 | break; |
110 | case 0x098Bu: |
111 | matched = 0x09C3u == buffer->cur (1).codepoint; |
112 | break; |
113 | case 0x098Cu: |
114 | matched = 0x09E2u == buffer->cur (1).codepoint; |
115 | break; |
116 | } |
117 | buffer->next_glyph (); |
118 | if (matched) _output_with_dotted_circle (buffer); |
119 | } |
120 | processed = true; |
121 | break; |
122 | |
123 | case HB_SCRIPT_GURMUKHI: |
124 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
125 | { |
126 | bool matched = false; |
127 | switch (buffer->cur ().codepoint) |
128 | { |
129 | case 0x0A05u: |
130 | switch (buffer->cur (1).codepoint) |
131 | { |
132 | case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu: |
133 | matched = true; |
134 | break; |
135 | } |
136 | break; |
137 | case 0x0A72u: |
138 | switch (buffer->cur (1).codepoint) |
139 | { |
140 | case 0x0A3Fu: case 0x0A40u: case 0x0A47u: |
141 | matched = true; |
142 | break; |
143 | } |
144 | break; |
145 | case 0x0A73u: |
146 | switch (buffer->cur (1).codepoint) |
147 | { |
148 | case 0x0A41u: case 0x0A42u: case 0x0A4Bu: |
149 | matched = true; |
150 | break; |
151 | } |
152 | break; |
153 | } |
154 | buffer->next_glyph (); |
155 | if (matched) _output_with_dotted_circle (buffer); |
156 | } |
157 | processed = true; |
158 | break; |
159 | |
160 | case HB_SCRIPT_GUJARATI: |
161 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
162 | { |
163 | bool matched = false; |
164 | switch (buffer->cur ().codepoint) |
165 | { |
166 | case 0x0A85u: |
167 | switch (buffer->cur (1).codepoint) |
168 | { |
169 | case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u: |
170 | case 0x0AC9u: case 0x0ACBu: case 0x0ACCu: |
171 | matched = true; |
172 | break; |
173 | } |
174 | break; |
175 | case 0x0AC5u: |
176 | matched = 0x0ABEu == buffer->cur (1).codepoint; |
177 | break; |
178 | } |
179 | buffer->next_glyph (); |
180 | if (matched) _output_with_dotted_circle (buffer); |
181 | } |
182 | processed = true; |
183 | break; |
184 | |
185 | case HB_SCRIPT_ORIYA: |
186 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
187 | { |
188 | bool matched = false; |
189 | switch (buffer->cur ().codepoint) |
190 | { |
191 | case 0x0B05u: |
192 | matched = 0x0B3Eu == buffer->cur (1).codepoint; |
193 | break; |
194 | case 0x0B0Fu: case 0x0B13u: |
195 | matched = 0x0B57u == buffer->cur (1).codepoint; |
196 | break; |
197 | } |
198 | buffer->next_glyph (); |
199 | if (matched) _output_with_dotted_circle (buffer); |
200 | } |
201 | processed = true; |
202 | break; |
203 | |
204 | case HB_SCRIPT_TELUGU: |
205 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
206 | { |
207 | bool matched = false; |
208 | switch (buffer->cur ().codepoint) |
209 | { |
210 | case 0x0C12u: |
211 | switch (buffer->cur (1).codepoint) |
212 | { |
213 | case 0x0C4Cu: case 0x0C55u: |
214 | matched = true; |
215 | break; |
216 | } |
217 | break; |
218 | case 0x0C3Fu: case 0x0C46u: case 0x0C4Au: |
219 | matched = 0x0C55u == buffer->cur (1).codepoint; |
220 | break; |
221 | } |
222 | buffer->next_glyph (); |
223 | if (matched) _output_with_dotted_circle (buffer); |
224 | } |
225 | processed = true; |
226 | break; |
227 | |
228 | case HB_SCRIPT_KANNADA: |
229 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
230 | { |
231 | bool matched = false; |
232 | switch (buffer->cur ().codepoint) |
233 | { |
234 | case 0x0C89u: case 0x0C8Bu: |
235 | matched = 0x0CBEu == buffer->cur (1).codepoint; |
236 | break; |
237 | case 0x0C92u: |
238 | matched = 0x0CCCu == buffer->cur (1).codepoint; |
239 | break; |
240 | } |
241 | buffer->next_glyph (); |
242 | if (matched) _output_with_dotted_circle (buffer); |
243 | } |
244 | processed = true; |
245 | break; |
246 | |
247 | case HB_SCRIPT_MALAYALAM: |
248 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
249 | { |
250 | bool matched = false; |
251 | switch (buffer->cur ().codepoint) |
252 | { |
253 | case 0x0D07u: case 0x0D09u: |
254 | matched = 0x0D57u == buffer->cur (1).codepoint; |
255 | break; |
256 | case 0x0D0Eu: |
257 | matched = 0x0D46u == buffer->cur (1).codepoint; |
258 | break; |
259 | case 0x0D12u: |
260 | switch (buffer->cur (1).codepoint) |
261 | { |
262 | case 0x0D3Eu: case 0x0D57u: |
263 | matched = true; |
264 | break; |
265 | } |
266 | break; |
267 | } |
268 | buffer->next_glyph (); |
269 | if (matched) _output_with_dotted_circle (buffer); |
270 | } |
271 | processed = true; |
272 | break; |
273 | |
274 | case HB_SCRIPT_SINHALA: |
275 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
276 | { |
277 | bool matched = false; |
278 | switch (buffer->cur ().codepoint) |
279 | { |
280 | case 0x0D85u: |
281 | switch (buffer->cur (1).codepoint) |
282 | { |
283 | case 0x0DCFu: case 0x0DD0u: case 0x0DD1u: |
284 | matched = true; |
285 | break; |
286 | } |
287 | break; |
288 | case 0x0D8Bu: case 0x0D8Fu: case 0x0D94u: |
289 | matched = 0x0DDFu == buffer->cur (1).codepoint; |
290 | break; |
291 | case 0x0D8Du: |
292 | matched = 0x0DD8u == buffer->cur (1).codepoint; |
293 | break; |
294 | case 0x0D91u: |
295 | switch (buffer->cur (1).codepoint) |
296 | { |
297 | case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu: |
298 | case 0x0DDDu: |
299 | matched = true; |
300 | break; |
301 | } |
302 | break; |
303 | } |
304 | buffer->next_glyph (); |
305 | if (matched) _output_with_dotted_circle (buffer); |
306 | } |
307 | processed = true; |
308 | break; |
309 | |
310 | case HB_SCRIPT_BRAHMI: |
311 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
312 | { |
313 | bool matched = false; |
314 | switch (buffer->cur ().codepoint) |
315 | { |
316 | case 0x11005u: |
317 | matched = 0x11038u == buffer->cur (1).codepoint; |
318 | break; |
319 | case 0x1100Bu: |
320 | matched = 0x1103Eu == buffer->cur (1).codepoint; |
321 | break; |
322 | case 0x1100Fu: |
323 | matched = 0x11042u == buffer->cur (1).codepoint; |
324 | break; |
325 | } |
326 | buffer->next_glyph (); |
327 | if (matched) _output_with_dotted_circle (buffer); |
328 | } |
329 | processed = true; |
330 | break; |
331 | |
332 | case HB_SCRIPT_KHUDAWADI: |
333 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
334 | { |
335 | bool matched = false; |
336 | switch (buffer->cur ().codepoint) |
337 | { |
338 | case 0x112B0u: |
339 | switch (buffer->cur (1).codepoint) |
340 | { |
341 | case 0x112E0u: case 0x112E5u: case 0x112E6u: case 0x112E7u: |
342 | case 0x112E8u: |
343 | matched = true; |
344 | break; |
345 | } |
346 | break; |
347 | } |
348 | buffer->next_glyph (); |
349 | if (matched) _output_with_dotted_circle (buffer); |
350 | } |
351 | processed = true; |
352 | break; |
353 | |
354 | case HB_SCRIPT_TIRHUTA: |
355 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
356 | { |
357 | bool matched = false; |
358 | switch (buffer->cur ().codepoint) |
359 | { |
360 | case 0x11481u: |
361 | matched = 0x114B0u == buffer->cur (1).codepoint; |
362 | break; |
363 | case 0x1148Bu: case 0x1148Du: |
364 | matched = 0x114BAu == buffer->cur (1).codepoint; |
365 | break; |
366 | case 0x114AAu: |
367 | switch (buffer->cur (1).codepoint) |
368 | { |
369 | case 0x114B5u: case 0x114B6u: |
370 | matched = true; |
371 | break; |
372 | } |
373 | break; |
374 | } |
375 | buffer->next_glyph (); |
376 | if (matched) _output_with_dotted_circle (buffer); |
377 | } |
378 | processed = true; |
379 | break; |
380 | |
381 | case HB_SCRIPT_MODI: |
382 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
383 | { |
384 | bool matched = false; |
385 | switch (buffer->cur ().codepoint) |
386 | { |
387 | case 0x11600u: case 0x11601u: |
388 | switch (buffer->cur (1).codepoint) |
389 | { |
390 | case 0x11639u: case 0x1163Au: |
391 | matched = true; |
392 | break; |
393 | } |
394 | break; |
395 | } |
396 | buffer->next_glyph (); |
397 | if (matched) _output_with_dotted_circle (buffer); |
398 | } |
399 | processed = true; |
400 | break; |
401 | |
402 | case HB_SCRIPT_TAKRI: |
403 | for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) |
404 | { |
405 | bool matched = false; |
406 | switch (buffer->cur ().codepoint) |
407 | { |
408 | case 0x11680u: |
409 | switch (buffer->cur (1).codepoint) |
410 | { |
411 | case 0x116ADu: case 0x116B4u: case 0x116B5u: |
412 | matched = true; |
413 | break; |
414 | } |
415 | break; |
416 | case 0x11686u: |
417 | matched = 0x116B2u == buffer->cur (1).codepoint; |
418 | break; |
419 | } |
420 | buffer->next_glyph (); |
421 | if (matched) _output_with_dotted_circle (buffer); |
422 | } |
423 | processed = true; |
424 | break; |
425 | |
426 | default: |
427 | break; |
428 | } |
429 | if (processed) |
430 | { |
431 | if (buffer->idx < count) |
432 | buffer->next_glyph (); |
433 | buffer->swap_buffers (); |
434 | } |
435 | } |
436 | |
437 | /* == End of generated functions == */ |
438 |