1 /* -*-c-*- */
2 /* Copyright (C) 2003 Marcus Lundblad */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see: <http://www.gnu.org/licenses/>
15 */
16
17 #include "config.h"
18
19 #include <stdio.h>
20 #include <X11/Xlib.h>
21 #include "fvwmlib.h"
22 #include "CombineChars.h"
23
24 /* ---------------------------- local types -------------------------------- */
25
26 typedef struct char_combclass
27 {
28 unsigned short key;
29 int combclass;
30 } char_combclass_t;
31
32
33 typedef struct char_comb
34 {
35 unsigned short key;
36 unsigned short first;
37 unsigned short second;
38 } char_comb_t;
39
40 /* ---------------------------- static variables --------------------------- */
41
42 /* would like to use the Unicode replacement character here, but that would
43 result in expanding incoming UTF-8 strings when garbage characters occurs */
44 /* so for the time being use '?' */
45 static unsigned short REPLACEMENT_CHARACTER = 0x3f;
46
47 /* maps characters to combination classes (not in list => 0) */
48 /* parsed from UnicodeData-3.2.0.txt */
49 static const char_combclass_t combclass_table[] =
50 {
51 { 0x0300, 230},
52 { 0x0301, 230},
53 { 0x0302, 230},
54 { 0x0303, 230},
55 { 0x0304, 230},
56 { 0x0305, 230},
57 { 0x0306, 230},
58 { 0x0307, 230},
59 { 0x0308, 230},
60 { 0x0309, 230},
61 { 0x030A, 230},
62 { 0x030B, 230},
63 { 0x030C, 230},
64 { 0x030D, 230},
65 { 0x030E, 230},
66 { 0x030F, 230},
67 { 0x0310, 230},
68 { 0x0311, 230},
69 { 0x0312, 230},
70 { 0x0313, 230},
71 { 0x0314, 230},
72 { 0x0315, 232},
73 { 0x0316, 220},
74 { 0x0317, 220},
75 { 0x0318, 220},
76 { 0x0319, 220},
77 { 0x031A, 232},
78 { 0x031B, 216},
79 { 0x031C, 220},
80 { 0x031D, 220},
81 { 0x031E, 220},
82 { 0x031F, 220},
83 { 0x0320, 220},
84 { 0x0321, 202},
85 { 0x0322, 202},
86 { 0x0323, 220},
87 { 0x0324, 220},
88 { 0x0325, 220},
89 { 0x0326, 220},
90 { 0x0327, 202},
91 { 0x0328, 202},
92 { 0x0329, 220},
93 { 0x032A, 220},
94 { 0x032B, 220},
95 { 0x032C, 220},
96 { 0x032D, 220},
97 { 0x032E, 220},
98 { 0x032F, 220},
99 { 0x0330, 220},
100 { 0x0331, 220},
101 { 0x0332, 220},
102 { 0x0333, 220},
103 { 0x0334, 1},
104 { 0x0335, 1},
105 { 0x0336, 1},
106 { 0x0337, 1},
107 { 0x0338, 1},
108 { 0x0339, 220},
109 { 0x033A, 220},
110 { 0x033B, 220},
111 { 0x033C, 220},
112 { 0x033D, 230},
113 { 0x033E, 230},
114 { 0x033F, 230},
115 { 0x0340, 230},
116 { 0x0341, 230},
117 { 0x0342, 230},
118 { 0x0343, 230},
119 { 0x0344, 230},
120 { 0x0345, 240},
121 { 0x0346, 230},
122 { 0x0347, 220},
123 { 0x0348, 220},
124 { 0x0349, 220},
125 { 0x034A, 230},
126 { 0x034B, 230},
127 { 0x034C, 230},
128 { 0x034D, 220},
129 { 0x034E, 220},
130 { 0x034F, -1 },
131 { 0x0360, 234},
132 { 0x0361, 234},
133 { 0x0362, 233},
134 { 0x0363, 230},
135 { 0x0364, 230},
136 { 0x0365, 230},
137 { 0x0366, 230},
138 { 0x0367, 230},
139 { 0x0368, 230},
140 { 0x0369, 230},
141 { 0x036A, 230},
142 { 0x036B, 230},
143 { 0x036C, 230},
144 { 0x036D, 230},
145 { 0x036E, 230},
146 { 0x036F, 230},
147 { 0x0483, 230},
148 { 0x0484, 230},
149 { 0x0485, 230},
150 { 0x0486, 230},
151 { 0x0488, -3 },
152 { 0x0489, -3 },
153 { 0x0591, 220},
154 { 0x0592, 230},
155 { 0x0593, 230},
156 { 0x0594, 230},
157 { 0x0595, 230},
158 { 0x0596, 220},
159 { 0x0597, 230},
160 { 0x0598, 230},
161 { 0x0599, 230},
162 { 0x059A, 222},
163 { 0x059B, 220},
164 { 0x059C, 230},
165 { 0x059D, 230},
166 { 0x059E, 230},
167 { 0x059F, 230},
168 { 0x05A0, 230},
169 { 0x05A1, 230},
170 { 0x05A3, 220},
171 { 0x05A4, 220},
172 { 0x05A5, 220},
173 { 0x05A6, 220},
174 { 0x05A7, 220},
175 { 0x05A8, 230},
176 { 0x05A9, 230},
177 { 0x05AA, 220},
178 { 0x05AB, 230},
179 { 0x05AC, 230},
180 { 0x05AD, 222},
181 { 0x05AE, 228},
182 { 0x05AF, 230},
183 { 0x05B0, 10},
184 { 0x05B1, 11},
185 { 0x05B2, 12},
186 { 0x05B3, 13},
187 { 0x05B4, 14},
188 { 0x05B5, 15},
189 { 0x05B6, 16},
190 { 0x05B7, 17},
191 { 0x05B8, 18},
192 { 0x05B9, 19},
193 { 0x05BB, 20},
194 { 0x05BC, 21},
195 { 0x05BD, 22},
196 { 0x05BF, 23},
197 { 0x05C1, 24},
198 { 0x05C2, 25},
199 { 0x05C4, 230},
200 { 0x064B, 27},
201 { 0x064C, 28},
202 { 0x064D, 29},
203 { 0x064E, 30},
204 { 0x064F, 31},
205 { 0x0650, 32},
206 { 0x0651, 33},
207 { 0x0652, 34},
208 { 0x0653, 230},
209 { 0x0654, 230},
210 { 0x0655, 220},
211 { 0x0670, 35},
212 { 0x06D6, 230},
213 { 0x06D7, 230},
214 { 0x06D8, 230},
215 { 0x06D9, 230},
216 { 0x06DA, 230},
217 { 0x06DB, 230},
218 { 0x06DC, 230},
219 { 0x06DE, -3 },
220 { 0x06DF, 230},
221 { 0x06E0, 230},
222 { 0x06E1, 230},
223 { 0x06E2, 230},
224 { 0x06E3, 220},
225 { 0x06E4, 230},
226 { 0x06E7, 230},
227 { 0x06E8, 230},
228 { 0x06EA, 220},
229 { 0x06EB, 230},
230 { 0x06EC, 230},
231 { 0x06ED, 220},
232 { 0x0711, 36},
233 { 0x0730, 230},
234 { 0x0731, 220},
235 { 0x0732, 230},
236 { 0x0733, 230},
237 { 0x0734, 220},
238 { 0x0735, 230},
239 { 0x0736, 230},
240 { 0x0737, 220},
241 { 0x0738, 220},
242 { 0x0739, 220},
243 { 0x073A, 230},
244 { 0x073B, 220},
245 { 0x073C, 220},
246 { 0x073D, 230},
247 { 0x073E, 220},
248 { 0x073F, 230},
249 { 0x0740, 230},
250 { 0x0741, 230},
251 { 0x0742, 220},
252 { 0x0743, 230},
253 { 0x0744, 220},
254 { 0x0745, 230},
255 { 0x0746, 220},
256 { 0x0747, 230},
257 { 0x0748, 220},
258 { 0x0749, 230},
259 { 0x074A, 230},
260 { 0x07A6, -1 },
261 { 0x07A7, -1 },
262 { 0x07A8, -1 },
263 { 0x07A9, -1 },
264 { 0x07AA, -1 },
265 { 0x07AB, -1 },
266 { 0x07AC, -1 },
267 { 0x07AD, -1 },
268 { 0x07AE, -1 },
269 { 0x07AF, -1 },
270 { 0x07B0, -1 },
271 { 0x0901, -1 },
272 { 0x0902, -1 },
273 { 0x0903, -2 },
274 { 0x093C, 7},
275 { 0x093E, -2 },
276 { 0x093F, -2 },
277 { 0x0940, -2 },
278 { 0x0941, -1 },
279 { 0x0942, -1 },
280 { 0x0943, -1 },
281 { 0x0944, -1 },
282 { 0x0945, -1 },
283 { 0x0946, -1 },
284 { 0x0947, -1 },
285 { 0x0948, -1 },
286 { 0x0949, -2 },
287 { 0x094A, -2 },
288 { 0x094B, -2 },
289 { 0x094C, -2 },
290 { 0x094D, 9},
291 { 0x0951, 230},
292 { 0x0952, 220},
293 { 0x0953, 230},
294 { 0x0954, 230},
295 { 0x0962, -1 },
296 { 0x0963, -1 },
297 { 0x0981, -1 },
298 { 0x0982, -2 },
299 { 0x0983, -2 },
300 { 0x09BC, 7},
301 { 0x09BE, -2 },
302 { 0x09BF, -2 },
303 { 0x09C0, -2 },
304 { 0x09C1, -1 },
305 { 0x09C2, -1 },
306 { 0x09C3, -1 },
307 { 0x09C4, -1 },
308 { 0x09C7, -2 },
309 { 0x09C8, -2 },
310 { 0x09CB, -2 },
311 { 0x09CC, -2 },
312 { 0x09CD, 9},
313 { 0x09D7, -2 },
314 { 0x09E2, -1 },
315 { 0x09E3, -1 },
316 { 0x0A02, -1 },
317 { 0x0A3C, 7},
318 { 0x0A3E, -2 },
319 { 0x0A3F, -2 },
320 { 0x0A40, -2 },
321 { 0x0A41, -1 },
322 { 0x0A42, -1 },
323 { 0x0A47, -1 },
324 { 0x0A48, -1 },
325 { 0x0A4B, -1 },
326 { 0x0A4C, -1 },
327 { 0x0A4D, 9},
328 { 0x0A70, -1 },
329 { 0x0A71, -1 },
330 { 0x0A81, -1 },
331 { 0x0A82, -1 },
332 { 0x0A83, -2 },
333 { 0x0ABC, 7},
334 { 0x0ABE, -2 },
335 { 0x0ABF, -2 },
336 { 0x0AC0, -2 },
337 { 0x0AC1, -1 },
338 { 0x0AC2, -1 },
339 { 0x0AC3, -1 },
340 { 0x0AC4, -1 },
341 { 0x0AC5, -1 },
342 { 0x0AC7, -1 },
343 { 0x0AC8, -1 },
344 { 0x0AC9, -2 },
345 { 0x0ACB, -2 },
346 { 0x0ACC, -2 },
347 { 0x0ACD, 9},
348 { 0x0B01, -1 },
349 { 0x0B02, -2 },
350 { 0x0B03, -2 },
351 { 0x0B3C, 7},
352 { 0x0B3E, -2 },
353 { 0x0B3F, -1 },
354 { 0x0B40, -2 },
355 { 0x0B41, -1 },
356 { 0x0B42, -1 },
357 { 0x0B43, -1 },
358 { 0x0B47, -2 },
359 { 0x0B48, -2 },
360 { 0x0B4B, -2 },
361 { 0x0B4C, -2 },
362 { 0x0B4D, 9},
363 { 0x0B56, -1 },
364 { 0x0B57, -2 },
365 { 0x0B82, -1 },
366 { 0x0BBE, -2 },
367 { 0x0BBF, -2 },
368 { 0x0BC0, -1 },
369 { 0x0BC1, -2 },
370 { 0x0BC2, -2 },
371 { 0x0BC6, -2 },
372 { 0x0BC7, -2 },
373 { 0x0BC8, -2 },
374 { 0x0BCA, -2 },
375 { 0x0BCB, -2 },
376 { 0x0BCC, -2 },
377 { 0x0BCD, 9},
378 { 0x0BD7, -2 },
379 { 0x0C01, -2 },
380 { 0x0C02, -2 },
381 { 0x0C03, -2 },
382 { 0x0C3E, -1 },
383 { 0x0C3F, -1 },
384 { 0x0C40, -1 },
385 { 0x0C41, -2 },
386 { 0x0C42, -2 },
387 { 0x0C43, -2 },
388 { 0x0C44, -2 },
389 { 0x0C46, -1 },
390 { 0x0C47, -1 },
391 { 0x0C48, -1 },
392 { 0x0C4A, -1 },
393 { 0x0C4B, -1 },
394 { 0x0C4C, -1 },
395 { 0x0C4D, 9},
396 { 0x0C55, 84},
397 { 0x0C56, 91},
398 { 0x0C82, -2 },
399 { 0x0C83, -2 },
400 { 0x0CBE, -2 },
401 { 0x0CBF, -1 },
402 { 0x0CC0, -2 },
403 { 0x0CC1, -2 },
404 { 0x0CC2, -2 },
405 { 0x0CC3, -2 },
406 { 0x0CC4, -2 },
407 { 0x0CC6, -1 },
408 { 0x0CC7, -2 },
409 { 0x0CC8, -2 },
410 { 0x0CCA, -2 },
411 { 0x0CCB, -2 },
412 { 0x0CCC, -1 },
413 { 0x0CCD, 9},
414 { 0x0CD5, -2 },
415 { 0x0CD6, -2 },
416 { 0x0D02, -2 },
417 { 0x0D03, -2 },
418 { 0x0D3E, -2 },
419 { 0x0D3F, -2 },
420 { 0x0D40, -2 },
421 { 0x0D41, -1 },
422 { 0x0D42, -1 },
423 { 0x0D43, -1 },
424 { 0x0D46, -2 },
425 { 0x0D47, -2 },
426 { 0x0D48, -2 },
427 { 0x0D4A, -2 },
428 { 0x0D4B, -2 },
429 { 0x0D4C, -2 },
430 { 0x0D4D, 9},
431 { 0x0D57, -2 },
432 { 0x0D82, -2 },
433 { 0x0D83, -2 },
434 { 0x0DCA, 9},
435 { 0x0DCF, -2 },
436 { 0x0DD0, -2 },
437 { 0x0DD1, -2 },
438 { 0x0DD2, -1 },
439 { 0x0DD3, -1 },
440 { 0x0DD4, -1 },
441 { 0x0DD6, -1 },
442 { 0x0DD8, -2 },
443 { 0x0DD9, -2 },
444 { 0x0DDA, -2 },
445 { 0x0DDB, -2 },
446 { 0x0DDC, -2 },
447 { 0x0DDD, -2 },
448 { 0x0DDE, -2 },
449 { 0x0DDF, -2 },
450 { 0x0DF2, -2 },
451 { 0x0DF3, -2 },
452 { 0x0E31, -1 },
453 { 0x0E34, -1 },
454 { 0x0E35, -1 },
455 { 0x0E36, -1 },
456 { 0x0E37, -1 },
457 { 0x0E38, 103},
458 { 0x0E39, 103},
459 { 0x0E3A, 9},
460 { 0x0E47, -1 },
461 { 0x0E48, 107},
462 { 0x0E49, 107},
463 { 0x0E4A, 107},
464 { 0x0E4B, 107},
465 { 0x0E4C, -1 },
466 { 0x0E4D, -1 },
467 { 0x0E4E, -1 },
468 { 0x0EB1, -1 },
469 { 0x0EB4, -1 },
470 { 0x0EB5, -1 },
471 { 0x0EB6, -1 },
472 { 0x0EB7, -1 },
473 { 0x0EB8, 118},
474 { 0x0EB9, 118},
475 { 0x0EBB, -1 },
476 { 0x0EBC, -1 },
477 { 0x0EC8, 122},
478 { 0x0EC9, 122},
479 { 0x0ECA, 122},
480 { 0x0ECB, 122},
481 { 0x0ECC, -1 },
482 { 0x0ECD, -1 },
483 { 0x0F18, 220},
484 { 0x0F19, 220},
485 { 0x0F35, 220},
486 { 0x0F37, 220},
487 { 0x0F39, 216},
488 { 0x0F3E, -2 },
489 { 0x0F3F, -2 },
490 { 0x0F71, 129},
491 { 0x0F72, 130},
492 { 0x0F73, -1 },
493 { 0x0F74, 132},
494 { 0x0F75, -1 },
495 { 0x0F76, -1 },
496 { 0x0F77, -1 },
497 { 0x0F78, -1 },
498 { 0x0F79, -1 },
499 { 0x0F7A, 130},
500 { 0x0F7B, 130},
501 { 0x0F7C, 130},
502 { 0x0F7D, 130},
503 { 0x0F7E, -1 },
504 { 0x0F7F, -2 },
505 { 0x0F80, 130},
506 { 0x0F81, -1 },
507 { 0x0F82, 230},
508 { 0x0F83, 230},
509 { 0x0F84, 9},
510 { 0x0F86, 230},
511 { 0x0F87, 230},
512 { 0x0F90, -1 },
513 { 0x0F91, -1 },
514 { 0x0F92, -1 },
515 { 0x0F93, -1 },
516 { 0x0F94, -1 },
517 { 0x0F95, -1 },
518 { 0x0F96, -1 },
519 { 0x0F97, -1 },
520 { 0x0F99, -1 },
521 { 0x0F9A, -1 },
522 { 0x0F9B, -1 },
523 { 0x0F9C, -1 },
524 { 0x0F9D, -1 },
525 { 0x0F9E, -1 },
526 { 0x0F9F, -1 },
527 { 0x0FA0, -1 },
528 { 0x0FA1, -1 },
529 { 0x0FA2, -1 },
530 { 0x0FA3, -1 },
531 { 0x0FA4, -1 },
532 { 0x0FA5, -1 },
533 { 0x0FA6, -1 },
534 { 0x0FA7, -1 },
535 { 0x0FA8, -1 },
536 { 0x0FA9, -1 },
537 { 0x0FAA, -1 },
538 { 0x0FAB, -1 },
539 { 0x0FAC, -1 },
540 { 0x0FAD, -1 },
541 { 0x0FAE, -1 },
542 { 0x0FAF, -1 },
543 { 0x0FB0, -1 },
544 { 0x0FB1, -1 },
545 { 0x0FB2, -1 },
546 { 0x0FB3, -1 },
547 { 0x0FB4, -1 },
548 { 0x0FB5, -1 },
549 { 0x0FB6, -1 },
550 { 0x0FB7, -1 },
551 { 0x0FB8, -1 },
552 { 0x0FB9, -1 },
553 { 0x0FBA, -1 },
554 { 0x0FBB, -1 },
555 { 0x0FBC, -1 },
556 { 0x0FC6, 220},
557 { 0x102C, -2 },
558 { 0x102D, -1 },
559 { 0x102E, -1 },
560 { 0x102F, -1 },
561 { 0x1030, -1 },
562 { 0x1031, -2 },
563 { 0x1032, -1 },
564 { 0x1036, -1 },
565 { 0x1037, 7},
566 { 0x1038, -2 },
567 { 0x1039, 9},
568 { 0x1056, -2 },
569 { 0x1057, -2 },
570 { 0x1058, -1 },
571 { 0x1059, -1 },
572 { 0x1712, -1 },
573 { 0x1713, -1 },
574 { 0x1714, 9},
575 { 0x1732, -1 },
576 { 0x1733, -1 },
577 { 0x1734, 9},
578 { 0x1752, -1 },
579 { 0x1753, -1 },
580 { 0x1772, -1 },
581 { 0x1773, -1 },
582 { 0x17B4, -2 },
583 { 0x17B5, -2 },
584 { 0x17B6, -2 },
585 { 0x17B7, -1 },
586 { 0x17B8, -1 },
587 { 0x17B9, -1 },
588 { 0x17BA, -1 },
589 { 0x17BB, -1 },
590 { 0x17BC, -1 },
591 { 0x17BD, -1 },
592 { 0x17BE, -2 },
593 { 0x17BF, -2 },
594 { 0x17C0, -2 },
595 { 0x17C1, -2 },
596 { 0x17C2, -2 },
597 { 0x17C3, -2 },
598 { 0x17C4, -2 },
599 { 0x17C5, -2 },
600 { 0x17C6, -1 },
601 { 0x17C7, -2 },
602 { 0x17C8, -2 },
603 { 0x17C9, -1 },
604 { 0x17CA, -1 },
605 { 0x17CB, -1 },
606 { 0x17CC, -1 },
607 { 0x17CD, -1 },
608 { 0x17CE, -1 },
609 { 0x17CF, -1 },
610 { 0x17D0, -1 },
611 { 0x17D1, -1 },
612 { 0x17D2, 9},
613 { 0x17D3, -1 },
614 { 0x180B, -1 },
615 { 0x180C, -1 },
616 { 0x180D, -1 },
617 { 0x18A9, 228},
618 { 0x20D0, 230},
619 { 0x20D1, 230},
620 { 0x20D2, 1},
621 { 0x20D3, 1},
622 { 0x20D4, 230},
623 { 0x20D5, 230},
624 { 0x20D6, 230},
625 { 0x20D7, 230},
626 { 0x20D8, 1},
627 { 0x20D9, 1},
628 { 0x20DA, 1},
629 { 0x20DB, 230},
630 { 0x20DC, 230},
631 { 0x20DD, -3 },
632 { 0x20DE, -3 },
633 { 0x20DF, -3 },
634 { 0x20E0, -3 },
635 { 0x20E1, 230},
636 { 0x20E2, -3 },
637 { 0x20E3, -3 },
638 { 0x20E4, -3 },
639 { 0x20E5, 1},
640 { 0x20E6, 1},
641 { 0x20E7, 230},
642 { 0x20E8, 220},
643 { 0x20E9, 230},
644 { 0x20EA, 1},
645 { 0x302A, 218},
646 { 0x302B, 228},
647 { 0x302C, 232},
648 { 0x302D, 222},
649 { 0x302E, 224},
650 { 0x302F, 224},
651 { 0x3099, 8},
652 { 0x309A, 8},
653 { 0xFB1E, 26},
654 { 0xFE00, -1 },
655 { 0xFE01, -1 },
656 { 0xFE02, -1 },
657 { 0xFE03, -1 },
658 { 0xFE04, -1 },
659 { 0xFE05, -1 },
660 { 0xFE06, -1 },
661 { 0xFE07, -1 },
662 { 0xFE08, -1 },
663 { 0xFE09, -1 },
664 { 0xFE0A, -1 },
665 { 0xFE0B, -1 },
666 { 0xFE0C, -1 },
667 { 0xFE0D, -1 },
668 { 0xFE0E, -1 },
669 { 0xFE0F, -1 },
670 { 0xFE20, 230},
671 { 0xFE21, 230},
672 { 0xFE22, 230},
673 { 0xFE23, 230},
674 /*{ 0x1D165, 216},
675 { 0x1D166, 216},
676 { 0x1D167, 1},
677 { 0x1D168, 1},
678 { 0x1D169, 1},
679 { 0x1D16D, 226},
680 { 0x1D16E, 216},
681 { 0x1D16F, 216},
682 { 0x1D170, 216},
683 { 0x1D171, 216},
684 { 0x1D172, 216},
685 { 0x1D17B, 220},
686 { 0x1D17C, 220},
687 { 0x1D17D, 220},
688 { 0x1D17E, 220},
689 { 0x1D17F, 220},
690 { 0x1D180, 220},
691 { 0x1D181, 220},
692 { 0x1D182, 220},
693 { 0x1D185, 230},
694 { 0x1D186, 230},
695 { 0x1D187, 230},
696 { 0x1D188, 230},
697 { 0x1D189, 230},
698 { 0x1D18A, 220},
699 { 0x1D18B, 220},
700 { 0x1D1AA, 230},
701 { 0x1D1AB, 230},
702 { 0x1D1AC, 230},
703 { 0x1D1AD, 230},*/
704 };
705
706 /* maps characters to decompositions */
707 /* parsed from UnicodeData-3.2.0.txt */
708 static const char_comb_t comb_table[] =
709 {
710 { 0x00C0, 0x0041, 0x0300 },
711 { 0x00C1, 0x0041, 0x0301 },
712 { 0x00C2, 0x0041, 0x0302 },
713 { 0x00C3, 0x0041, 0x0303 },
714 { 0x00C4, 0x0041, 0x0308 },
715 { 0x00C5, 0x0041, 0x030A },
716 { 0x00C7, 0x0043, 0x0327 },
717 { 0x00C8, 0x0045, 0x0300 },
718 { 0x00C9, 0x0045, 0x0301 },
719 { 0x00CA, 0x0045, 0x0302 },
720 { 0x00CB, 0x0045, 0x0308 },
721 { 0x00CC, 0x0049, 0x0300 },
722 { 0x00CD, 0x0049, 0x0301 },
723 { 0x00CE, 0x0049, 0x0302 },
724 { 0x00CF, 0x0049, 0x0308 },
725 { 0x00D1, 0x004E, 0x0303 },
726 { 0x00D2, 0x004F, 0x0300 },
727 { 0x00D3, 0x004F, 0x0301 },
728 { 0x00D4, 0x004F, 0x0302 },
729 { 0x00D5, 0x004F, 0x0303 },
730 { 0x00D6, 0x004F, 0x0308 },
731 { 0x00D9, 0x0055, 0x0300 },
732 { 0x00DA, 0x0055, 0x0301 },
733 { 0x00DB, 0x0055, 0x0302 },
734 { 0x00DC, 0x0055, 0x0308 },
735 { 0x00DD, 0x0059, 0x0301 },
736 { 0x00E0, 0x0061, 0x0300 },
737 { 0x00E1, 0x0061, 0x0301 },
738 { 0x00E2, 0x0061, 0x0302 },
739 { 0x00E3, 0x0061, 0x0303 },
740 { 0x00E4, 0x0061, 0x0308 },
741 { 0x00E5, 0x0061, 0x030A },
742 { 0x00E7, 0x0063, 0x0327 },
743 { 0x00E8, 0x0065, 0x0300 },
744 { 0x00E9, 0x0065, 0x0301 },
745 { 0x00EA, 0x0065, 0x0302 },
746 { 0x00EB, 0x0065, 0x0308 },
747 { 0x00EC, 0x0069, 0x0300 },
748 { 0x00ED, 0x0069, 0x0301 },
749 { 0x00EE, 0x0069, 0x0302 },
750 { 0x00EF, 0x0069, 0x0308 },
751 { 0x00F1, 0x006E, 0x0303 },
752 { 0x00F2, 0x006F, 0x0300 },
753 { 0x00F3, 0x006F, 0x0301 },
754 { 0x00F4, 0x006F, 0x0302 },
755 { 0x00F5, 0x006F, 0x0303 },
756 { 0x00F6, 0x006F, 0x0308 },
757 { 0x00F9, 0x0075, 0x0300 },
758 { 0x00FA, 0x0075, 0x0301 },
759 { 0x00FB, 0x0075, 0x0302 },
760 { 0x00FC, 0x0075, 0x0308 },
761 { 0x00FD, 0x0079, 0x0301 },
762 { 0x00FF, 0x0079, 0x0308 },
763 { 0x0100, 0x0041, 0x0304 },
764 { 0x0101, 0x0061, 0x0304 },
765 { 0x0102, 0x0041, 0x0306 },
766 { 0x0103, 0x0061, 0x0306 },
767 { 0x0104, 0x0041, 0x0328 },
768 { 0x0105, 0x0061, 0x0328 },
769 { 0x0106, 0x0043, 0x0301 },
770 { 0x0107, 0x0063, 0x0301 },
771 { 0x0108, 0x0043, 0x0302 },
772 { 0x0109, 0x0063, 0x0302 },
773 { 0x010A, 0x0043, 0x0307 },
774 { 0x010B, 0x0063, 0x0307 },
775 { 0x010C, 0x0043, 0x030C },
776 { 0x010D, 0x0063, 0x030C },
777 { 0x010E, 0x0044, 0x030C },
778 { 0x010F, 0x0064, 0x030C },
779 { 0x0112, 0x0045, 0x0304 },
780 { 0x0113, 0x0065, 0x0304 },
781 { 0x0114, 0x0045, 0x0306 },
782 { 0x0115, 0x0065, 0x0306 },
783 { 0x0116, 0x0045, 0x0307 },
784 { 0x0117, 0x0065, 0x0307 },
785 { 0x0118, 0x0045, 0x0328 },
786 { 0x0119, 0x0065, 0x0328 },
787 { 0x011A, 0x0045, 0x030C },
788 { 0x011B, 0x0065, 0x030C },
789 { 0x011C, 0x0047, 0x0302 },
790 { 0x011D, 0x0067, 0x0302 },
791 { 0x011E, 0x0047, 0x0306 },
792 { 0x011F, 0x0067, 0x0306 },
793 { 0x0120, 0x0047, 0x0307 },
794 { 0x0121, 0x0067, 0x0307 },
795 { 0x0122, 0x0047, 0x0327 },
796 { 0x0123, 0x0067, 0x0327 },
797 { 0x0124, 0x0048, 0x0302 },
798 { 0x0125, 0x0068, 0x0302 },
799 { 0x0128, 0x0049, 0x0303 },
800 { 0x0129, 0x0069, 0x0303 },
801 { 0x012A, 0x0049, 0x0304 },
802 { 0x012B, 0x0069, 0x0304 },
803 { 0x012C, 0x0049, 0x0306 },
804 { 0x012D, 0x0069, 0x0306 },
805 { 0x012E, 0x0049, 0x0328 },
806 { 0x012F, 0x0069, 0x0328 },
807 { 0x0130, 0x0049, 0x0307 },
808 { 0x0134, 0x004A, 0x0302 },
809 { 0x0135, 0x006A, 0x0302 },
810 { 0x0136, 0x004B, 0x0327 },
811 { 0x0137, 0x006B, 0x0327 },
812 { 0x0139, 0x004C, 0x0301 },
813 { 0x013A, 0x006C, 0x0301 },
814 { 0x013B, 0x004C, 0x0327 },
815 { 0x013C, 0x006C, 0x0327 },
816 { 0x013D, 0x004C, 0x030C },
817 { 0x013E, 0x006C, 0x030C },
818 { 0x0143, 0x004E, 0x0301 },
819 { 0x0144, 0x006E, 0x0301 },
820 { 0x0145, 0x004E, 0x0327 },
821 { 0x0146, 0x006E, 0x0327 },
822 { 0x0147, 0x004E, 0x030C },
823 { 0x0148, 0x006E, 0x030C },
824 { 0x014C, 0x004F, 0x0304 },
825 { 0x014D, 0x006F, 0x0304 },
826 { 0x014E, 0x004F, 0x0306 },
827 { 0x014F, 0x006F, 0x0306 },
828 { 0x0150, 0x004F, 0x030B },
829 { 0x0151, 0x006F, 0x030B },
830 { 0x0154, 0x0052, 0x0301 },
831 { 0x0155, 0x0072, 0x0301 },
832 { 0x0156, 0x0052, 0x0327 },
833 { 0x0157, 0x0072, 0x0327 },
834 { 0x0158, 0x0052, 0x030C },
835 { 0x0159, 0x0072, 0x030C },
836 { 0x015A, 0x0053, 0x0301 },
837 { 0x015B, 0x0073, 0x0301 },
838 { 0x015C, 0x0053, 0x0302 },
839 { 0x015D, 0x0073, 0x0302 },
840 { 0x015E, 0x0053, 0x0327 },
841 { 0x015F, 0x0073, 0x0327 },
842 { 0x0160, 0x0053, 0x030C },
843 { 0x0161, 0x0073, 0x030C },
844 { 0x0162, 0x0054, 0x0327 },
845 { 0x0163, 0x0074, 0x0327 },
846 { 0x0164, 0x0054, 0x030C },
847 { 0x0165, 0x0074, 0x030C },
848 { 0x0168, 0x0055, 0x0303 },
849 { 0x0169, 0x0075, 0x0303 },
850 { 0x016A, 0x0055, 0x0304 },
851 { 0x016B, 0x0075, 0x0304 },
852 { 0x016C, 0x0055, 0x0306 },
853 { 0x016D, 0x0075, 0x0306 },
854 { 0x016E, 0x0055, 0x030A },
855 { 0x016F, 0x0075, 0x030A },
856 { 0x0170, 0x0055, 0x030B },
857 { 0x0171, 0x0075, 0x030B },
858 { 0x0172, 0x0055, 0x0328 },
859 { 0x0173, 0x0075, 0x0328 },
860 { 0x0174, 0x0057, 0x0302 },
861 { 0x0175, 0x0077, 0x0302 },
862 { 0x0176, 0x0059, 0x0302 },
863 { 0x0177, 0x0079, 0x0302 },
864 { 0x0178, 0x0059, 0x0308 },
865 { 0x0179, 0x005A, 0x0301 },
866 { 0x017A, 0x007A, 0x0301 },
867 { 0x017B, 0x005A, 0x0307 },
868 { 0x017C, 0x007A, 0x0307 },
869 { 0x017D, 0x005A, 0x030C },
870 { 0x017E, 0x007A, 0x030C },
871 { 0x01A0, 0x004F, 0x031B },
872 { 0x01A1, 0x006F, 0x031B },
873 { 0x01AF, 0x0055, 0x031B },
874 { 0x01B0, 0x0075, 0x031B },
875 { 0x01CD, 0x0041, 0x030C },
876 { 0x01CE, 0x0061, 0x030C },
877 { 0x01CF, 0x0049, 0x030C },
878 { 0x01D0, 0x0069, 0x030C },
879 { 0x01D1, 0x004F, 0x030C },
880 { 0x01D2, 0x006F, 0x030C },
881 { 0x01D3, 0x0055, 0x030C },
882 { 0x01D4, 0x0075, 0x030C },
883 { 0x01D5, 0x00DC, 0x0304 },
884 { 0x01D6, 0x00FC, 0x0304 },
885 { 0x01D7, 0x00DC, 0x0301 },
886 { 0x01D8, 0x00FC, 0x0301 },
887 { 0x01D9, 0x00DC, 0x030C },
888 { 0x01DA, 0x00FC, 0x030C },
889 { 0x01DB, 0x00DC, 0x0300 },
890 { 0x01DC, 0x00FC, 0x0300 },
891 { 0x01DE, 0x00C4, 0x0304 },
892 { 0x01DF, 0x00E4, 0x0304 },
893 { 0x01E0, 0x0226, 0x0304 },
894 { 0x01E1, 0x0227, 0x0304 },
895 { 0x01E2, 0x00C6, 0x0304 },
896 { 0x01E3, 0x00E6, 0x0304 },
897 { 0x01E6, 0x0047, 0x030C },
898 { 0x01E7, 0x0067, 0x030C },
899 { 0x01E8, 0x004B, 0x030C },
900 { 0x01E9, 0x006B, 0x030C },
901 { 0x01EA, 0x004F, 0x0328 },
902 { 0x01EB, 0x006F, 0x0328 },
903 { 0x01EC, 0x01EA, 0x0304 },
904 { 0x01ED, 0x01EB, 0x0304 },
905 { 0x01EE, 0x01B7, 0x030C },
906 { 0x01EF, 0x0292, 0x030C },
907 { 0x01F0, 0x006A, 0x030C },
908 { 0x01F4, 0x0047, 0x0301 },
909 { 0x01F5, 0x0067, 0x0301 },
910 { 0x01F8, 0x004E, 0x0300 },
911 { 0x01F9, 0x006E, 0x0300 },
912 { 0x01FA, 0x00C5, 0x0301 },
913 { 0x01FB, 0x00E5, 0x0301 },
914 { 0x01FC, 0x00C6, 0x0301 },
915 { 0x01FD, 0x00E6, 0x0301 },
916 { 0x01FE, 0x00D8, 0x0301 },
917 { 0x01FF, 0x00F8, 0x0301 },
918 { 0x0200, 0x0041, 0x030F },
919 { 0x0201, 0x0061, 0x030F },
920 { 0x0202, 0x0041, 0x0311 },
921 { 0x0203, 0x0061, 0x0311 },
922 { 0x0204, 0x0045, 0x030F },
923 { 0x0205, 0x0065, 0x030F },
924 { 0x0206, 0x0045, 0x0311 },
925 { 0x0207, 0x0065, 0x0311 },
926 { 0x0208, 0x0049, 0x030F },
927 { 0x0209, 0x0069, 0x030F },
928 { 0x020A, 0x0049, 0x0311 },
929 { 0x020B, 0x0069, 0x0311 },
930 { 0x020C, 0x004F, 0x030F },
931 { 0x020D, 0x006F, 0x030F },
932 { 0x020E, 0x004F, 0x0311 },
933 { 0x020F, 0x006F, 0x0311 },
934 { 0x0210, 0x0052, 0x030F },
935 { 0x0211, 0x0072, 0x030F },
936 { 0x0212, 0x0052, 0x0311 },
937 { 0x0213, 0x0072, 0x0311 },
938 { 0x0214, 0x0055, 0x030F },
939 { 0x0215, 0x0075, 0x030F },
940 { 0x0216, 0x0055, 0x0311 },
941 { 0x0217, 0x0075, 0x0311 },
942 { 0x0218, 0x0053, 0x0326 },
943 { 0x0219, 0x0073, 0x0326 },
944 { 0x021A, 0x0054, 0x0326 },
945 { 0x021B, 0x0074, 0x0326 },
946 { 0x021E, 0x0048, 0x030C },
947 { 0x021F, 0x0068, 0x030C },
948 { 0x0226, 0x0041, 0x0307 },
949 { 0x0227, 0x0061, 0x0307 },
950 { 0x0228, 0x0045, 0x0327 },
951 { 0x0229, 0x0065, 0x0327 },
952 { 0x022A, 0x00D6, 0x0304 },
953 { 0x022B, 0x00F6, 0x0304 },
954 { 0x022C, 0x00D5, 0x0304 },
955 { 0x022D, 0x00F5, 0x0304 },
956 { 0x022E, 0x004F, 0x0307 },
957 { 0x022F, 0x006F, 0x0307 },
958 { 0x0230, 0x022E, 0x0304 },
959 { 0x0231, 0x022F, 0x0304 },
960 { 0x0232, 0x0059, 0x0304 },
961 { 0x0233, 0x0079, 0x0304 },
962 { 0x0344, 0x0308, 0x0301 },
963 { 0x0385, 0x00A8, 0x0301 },
964 { 0x0386, 0x0391, 0x0301 },
965 { 0x0388, 0x0395, 0x0301 },
966 { 0x0389, 0x0397, 0x0301 },
967 { 0x038A, 0x0399, 0x0301 },
968 { 0x038C, 0x039F, 0x0301 },
969 { 0x038E, 0x03A5, 0x0301 },
970 { 0x038F, 0x03A9, 0x0301 },
971 { 0x0390, 0x03CA, 0x0301 },
972 { 0x03AA, 0x0399, 0x0308 },
973 { 0x03AB, 0x03A5, 0x0308 },
974 { 0x03AC, 0x03B1, 0x0301 },
975 { 0x03AD, 0x03B5, 0x0301 },
976 { 0x03AE, 0x03B7, 0x0301 },
977 { 0x03AF, 0x03B9, 0x0301 },
978 { 0x03B0, 0x03CB, 0x0301 },
979 { 0x03CA, 0x03B9, 0x0308 },
980 { 0x03CB, 0x03C5, 0x0308 },
981 { 0x03CC, 0x03BF, 0x0301 },
982 { 0x03CD, 0x03C5, 0x0301 },
983 { 0x03CE, 0x03C9, 0x0301 },
984 { 0x03D3, 0x03D2, 0x0301 },
985 { 0x03D4, 0x03D2, 0x0308 },
986 { 0x0400, 0x0415, 0x0300 },
987 { 0x0401, 0x0415, 0x0308 },
988 { 0x0403, 0x0413, 0x0301 },
989 { 0x0407, 0x0406, 0x0308 },
990 { 0x040C, 0x041A, 0x0301 },
991 { 0x040D, 0x0418, 0x0300 },
992 { 0x040E, 0x0423, 0x0306 },
993 { 0x0419, 0x0418, 0x0306 },
994 { 0x0439, 0x0438, 0x0306 },
995 { 0x0450, 0x0435, 0x0300 },
996 { 0x0451, 0x0435, 0x0308 },
997 { 0x0453, 0x0433, 0x0301 },
998 { 0x0457, 0x0456, 0x0308 },
999 { 0x045C, 0x043A, 0x0301 },
1000 { 0x045D, 0x0438, 0x0300 },
1001 { 0x045E, 0x0443, 0x0306 },
1002 { 0x0476, 0x0474, 0x030F },
1003 { 0x0477, 0x0475, 0x030F },
1004 { 0x04C1, 0x0416, 0x0306 },
1005 { 0x04C2, 0x0436, 0x0306 },
1006 { 0x04D0, 0x0410, 0x0306 },
1007 { 0x04D1, 0x0430, 0x0306 },
1008 { 0x04D2, 0x0410, 0x0308 },
1009 { 0x04D3, 0x0430, 0x0308 },
1010 { 0x04D6, 0x0415, 0x0306 },
1011 { 0x04D7, 0x0435, 0x0306 },
1012 { 0x04DA, 0x04D8, 0x0308 },
1013 { 0x04DB, 0x04D9, 0x0308 },
1014 { 0x04DC, 0x0416, 0x0308 },
1015 { 0x04DD, 0x0436, 0x0308 },
1016 { 0x04DE, 0x0417, 0x0308 },
1017 { 0x04DF, 0x0437, 0x0308 },
1018 { 0x04E2, 0x0418, 0x0304 },
1019 { 0x04E3, 0x0438, 0x0304 },
1020 { 0x04E4, 0x0418, 0x0308 },
1021 { 0x04E5, 0x0438, 0x0308 },
1022 { 0x04E6, 0x041E, 0x0308 },
1023 { 0x04E7, 0x043E, 0x0308 },
1024 { 0x04EA, 0x04E8, 0x0308 },
1025 { 0x04EB, 0x04E9, 0x0308 },
1026 { 0x04EC, 0x042D, 0x0308 },
1027 { 0x04ED, 0x044D, 0x0308 },
1028 { 0x04EE, 0x0423, 0x0304 },
1029 { 0x04EF, 0x0443, 0x0304 },
1030 { 0x04F0, 0x0423, 0x0308 },
1031 { 0x04F1, 0x0443, 0x0308 },
1032 { 0x04F2, 0x0423, 0x030B },
1033 { 0x04F3, 0x0443, 0x030B },
1034 { 0x04F4, 0x0427, 0x0308 },
1035 { 0x04F5, 0x0447, 0x0308 },
1036 { 0x04F8, 0x042B, 0x0308 },
1037 { 0x04F9, 0x044B, 0x0308 },
1038 { 0x0622, 0x0627, 0x0653 },
1039 { 0x0623, 0x0627, 0x0654 },
1040 { 0x0624, 0x0648, 0x0654 },
1041 { 0x0625, 0x0627, 0x0655 },
1042 { 0x0626, 0x064A, 0x0654 },
1043 { 0x06C0, 0x06D5, 0x0654 },
1044 { 0x06C2, 0x06C1, 0x0654 },
1045 { 0x06D3, 0x06D2, 0x0654 },
1046 { 0x0929, 0x0928, 0x093C },
1047 { 0x0931, 0x0930, 0x093C },
1048 { 0x0934, 0x0933, 0x093C },
1049 { 0x0958, 0x0915, 0x093C },
1050 { 0x0959, 0x0916, 0x093C },
1051 { 0x095A, 0x0917, 0x093C },
1052 { 0x095B, 0x091C, 0x093C },
1053 { 0x095C, 0x0921, 0x093C },
1054 { 0x095D, 0x0922, 0x093C },
1055 { 0x095E, 0x092B, 0x093C },
1056 { 0x095F, 0x092F, 0x093C },
1057 { 0x09CB, 0x09C7, 0x09BE },
1058 { 0x09CC, 0x09C7, 0x09D7 },
1059 { 0x09DC, 0x09A1, 0x09BC },
1060 { 0x09DD, 0x09A2, 0x09BC },
1061 { 0x09DF, 0x09AF, 0x09BC },
1062 { 0x0A33, 0x0A32, 0x0A3C },
1063 { 0x0A36, 0x0A38, 0x0A3C },
1064 { 0x0A59, 0x0A16, 0x0A3C },
1065 { 0x0A5A, 0x0A17, 0x0A3C },
1066 { 0x0A5B, 0x0A1C, 0x0A3C },
1067 { 0x0A5E, 0x0A2B, 0x0A3C },
1068 { 0x0B48, 0x0B47, 0x0B56 },
1069 { 0x0B4B, 0x0B47, 0x0B3E },
1070 { 0x0B4C, 0x0B47, 0x0B57 },
1071 { 0x0B5C, 0x0B21, 0x0B3C },
1072 { 0x0B5D, 0x0B22, 0x0B3C },
1073 { 0x0B94, 0x0B92, 0x0BD7 },
1074 { 0x0BCA, 0x0BC6, 0x0BBE },
1075 { 0x0BCB, 0x0BC7, 0x0BBE },
1076 { 0x0BCC, 0x0BC6, 0x0BD7 },
1077 { 0x0C48, 0x0C46, 0x0C56 },
1078 { 0x0CC0, 0x0CBF, 0x0CD5 },
1079 { 0x0CC7, 0x0CC6, 0x0CD5 },
1080 { 0x0CC8, 0x0CC6, 0x0CD6 },
1081 { 0x0CCA, 0x0CC6, 0x0CC2 },
1082 { 0x0CCB, 0x0CCA, 0x0CD5 },
1083 { 0x0D4A, 0x0D46, 0x0D3E },
1084 { 0x0D4B, 0x0D47, 0x0D3E },
1085 { 0x0D4C, 0x0D46, 0x0D57 },
1086 { 0x0DDA, 0x0DD9, 0x0DCA },
1087 { 0x0DDC, 0x0DD9, 0x0DCF },
1088 { 0x0DDD, 0x0DDC, 0x0DCA },
1089 { 0x0DDE, 0x0DD9, 0x0DDF },
1090 { 0x0F43, 0x0F42, 0x0FB7 },
1091 { 0x0F4D, 0x0F4C, 0x0FB7 },
1092 { 0x0F52, 0x0F51, 0x0FB7 },
1093 { 0x0F57, 0x0F56, 0x0FB7 },
1094 { 0x0F5C, 0x0F5B, 0x0FB7 },
1095 { 0x0F69, 0x0F40, 0x0FB5 },
1096 { 0x0F73, 0x0F71, 0x0F72 },
1097 { 0x0F75, 0x0F71, 0x0F74 },
1098 { 0x0F76, 0x0FB2, 0x0F80 },
1099 { 0x0F78, 0x0FB3, 0x0F80 },
1100 { 0x0F81, 0x0F71, 0x0F80 },
1101 { 0x0F93, 0x0F92, 0x0FB7 },
1102 { 0x0F9D, 0x0F9C, 0x0FB7 },
1103 { 0x0FA2, 0x0FA1, 0x0FB7 },
1104 { 0x0FA7, 0x0FA6, 0x0FB7 },
1105 { 0x0FAC, 0x0FAB, 0x0FB7 },
1106 { 0x0FB9, 0x0F90, 0x0FB5 },
1107 { 0x1026, 0x1025, 0x102E },
1108 { 0x1E00, 0x0041, 0x0325 },
1109 { 0x1E01, 0x0061, 0x0325 },
1110 { 0x1E02, 0x0042, 0x0307 },
1111 { 0x1E03, 0x0062, 0x0307 },
1112 { 0x1E04, 0x0042, 0x0323 },
1113 { 0x1E05, 0x0062, 0x0323 },
1114 { 0x1E06, 0x0042, 0x0331 },
1115 { 0x1E07, 0x0062, 0x0331 },
1116 { 0x1E08, 0x00C7, 0x0301 },
1117 { 0x1E09, 0x00E7, 0x0301 },
1118 { 0x1E0A, 0x0044, 0x0307 },
1119 { 0x1E0B, 0x0064, 0x0307 },
1120 { 0x1E0C, 0x0044, 0x0323 },
1121 { 0x1E0D, 0x0064, 0x0323 },
1122 { 0x1E0E, 0x0044, 0x0331 },
1123 { 0x1E0F, 0x0064, 0x0331 },
1124 { 0x1E10, 0x0044, 0x0327 },
1125 { 0x1E11, 0x0064, 0x0327 },
1126 { 0x1E12, 0x0044, 0x032D },
1127 { 0x1E13, 0x0064, 0x032D },
1128 { 0x1E14, 0x0112, 0x0300 },
1129 { 0x1E15, 0x0113, 0x0300 },
1130 { 0x1E16, 0x0112, 0x0301 },
1131 { 0x1E17, 0x0113, 0x0301 },
1132 { 0x1E18, 0x0045, 0x032D },
1133 { 0x1E19, 0x0065, 0x032D },
1134 { 0x1E1A, 0x0045, 0x0330 },
1135 { 0x1E1B, 0x0065, 0x0330 },
1136 { 0x1E1C, 0x0228, 0x0306 },
1137 { 0x1E1D, 0x0229, 0x0306 },
1138 { 0x1E1E, 0x0046, 0x0307 },
1139 { 0x1E1F, 0x0066, 0x0307 },
1140 { 0x1E20, 0x0047, 0x0304 },
1141 { 0x1E21, 0x0067, 0x0304 },
1142 { 0x1E22, 0x0048, 0x0307 },
1143 { 0x1E23, 0x0068, 0x0307 },
1144 { 0x1E24, 0x0048, 0x0323 },
1145 { 0x1E25, 0x0068, 0x0323 },
1146 { 0x1E26, 0x0048, 0x0308 },
1147 { 0x1E27, 0x0068, 0x0308 },
1148 { 0x1E28, 0x0048, 0x0327 },
1149 { 0x1E29, 0x0068, 0x0327 },
1150 { 0x1E2A, 0x0048, 0x032E },
1151 { 0x1E2B, 0x0068, 0x032E },
1152 { 0x1E2C, 0x0049, 0x0330 },
1153 { 0x1E2D, 0x0069, 0x0330 },
1154 { 0x1E2E, 0x00CF, 0x0301 },
1155 { 0x1E2F, 0x00EF, 0x0301 },
1156 { 0x1E30, 0x004B, 0x0301 },
1157 { 0x1E31, 0x006B, 0x0301 },
1158 { 0x1E32, 0x004B, 0x0323 },
1159 { 0x1E33, 0x006B, 0x0323 },
1160 { 0x1E34, 0x004B, 0x0331 },
1161 { 0x1E35, 0x006B, 0x0331 },
1162 { 0x1E36, 0x004C, 0x0323 },
1163 { 0x1E37, 0x006C, 0x0323 },
1164 { 0x1E38, 0x1E36, 0x0304 },
1165 { 0x1E39, 0x1E37, 0x0304 },
1166 { 0x1E3A, 0x004C, 0x0331 },
1167 { 0x1E3B, 0x006C, 0x0331 },
1168 { 0x1E3C, 0x004C, 0x032D },
1169 { 0x1E3D, 0x006C, 0x032D },
1170 { 0x1E3E, 0x004D, 0x0301 },
1171 { 0x1E3F, 0x006D, 0x0301 },
1172 { 0x1E40, 0x004D, 0x0307 },
1173 { 0x1E41, 0x006D, 0x0307 },
1174 { 0x1E42, 0x004D, 0x0323 },
1175 { 0x1E43, 0x006D, 0x0323 },
1176 { 0x1E44, 0x004E, 0x0307 },
1177 { 0x1E45, 0x006E, 0x0307 },
1178 { 0x1E46, 0x004E, 0x0323 },
1179 { 0x1E47, 0x006E, 0x0323 },
1180 { 0x1E48, 0x004E, 0x0331 },
1181 { 0x1E49, 0x006E, 0x0331 },
1182 { 0x1E4A, 0x004E, 0x032D },
1183 { 0x1E4B, 0x006E, 0x032D },
1184 { 0x1E4C, 0x00D5, 0x0301 },
1185 { 0x1E4D, 0x00F5, 0x0301 },
1186 { 0x1E4E, 0x00D5, 0x0308 },
1187 { 0x1E4F, 0x00F5, 0x0308 },
1188 { 0x1E50, 0x014C, 0x0300 },
1189 { 0x1E51, 0x014D, 0x0300 },
1190 { 0x1E52, 0x014C, 0x0301 },
1191 { 0x1E53, 0x014D, 0x0301 },
1192 { 0x1E54, 0x0050, 0x0301 },
1193 { 0x1E55, 0x0070, 0x0301 },
1194 { 0x1E56, 0x0050, 0x0307 },
1195 { 0x1E57, 0x0070, 0x0307 },
1196 { 0x1E58, 0x0052, 0x0307 },
1197 { 0x1E59, 0x0072, 0x0307 },
1198 { 0x1E5A, 0x0052, 0x0323 },
1199 { 0x1E5B, 0x0072, 0x0323 },
1200 { 0x1E5C, 0x1E5A, 0x0304 },
1201 { 0x1E5D, 0x1E5B, 0x0304 },
1202 { 0x1E5E, 0x0052, 0x0331 },
1203 { 0x1E5F, 0x0072, 0x0331 },
1204 { 0x1E60, 0x0053, 0x0307 },
1205 { 0x1E61, 0x0073, 0x0307 },
1206 { 0x1E62, 0x0053, 0x0323 },
1207 { 0x1E63, 0x0073, 0x0323 },
1208 { 0x1E64, 0x015A, 0x0307 },
1209 { 0x1E65, 0x015B, 0x0307 },
1210 { 0x1E66, 0x0160, 0x0307 },
1211 { 0x1E67, 0x0161, 0x0307 },
1212 { 0x1E68, 0x1E62, 0x0307 },
1213 { 0x1E69, 0x1E63, 0x0307 },
1214 { 0x1E6A, 0x0054, 0x0307 },
1215 { 0x1E6B, 0x0074, 0x0307 },
1216 { 0x1E6C, 0x0054, 0x0323 },
1217 { 0x1E6D, 0x0074, 0x0323 },
1218 { 0x1E6E, 0x0054, 0x0331 },
1219 { 0x1E6F, 0x0074, 0x0331 },
1220 { 0x1E70, 0x0054, 0x032D },
1221 { 0x1E71, 0x0074, 0x032D },
1222 { 0x1E72, 0x0055, 0x0324 },
1223 { 0x1E73, 0x0075, 0x0324 },
1224 { 0x1E74, 0x0055, 0x0330 },
1225 { 0x1E75, 0x0075, 0x0330 },
1226 { 0x1E76, 0x0055, 0x032D },
1227 { 0x1E77, 0x0075, 0x032D },
1228 { 0x1E78, 0x0168, 0x0301 },
1229 { 0x1E79, 0x0169, 0x0301 },
1230 { 0x1E7A, 0x016A, 0x0308 },
1231 { 0x1E7B, 0x016B, 0x0308 },
1232 { 0x1E7C, 0x0056, 0x0303 },
1233 { 0x1E7D, 0x0076, 0x0303 },
1234 { 0x1E7E, 0x0056, 0x0323 },
1235 { 0x1E7F, 0x0076, 0x0323 },
1236 { 0x1E80, 0x0057, 0x0300 },
1237 { 0x1E81, 0x0077, 0x0300 },
1238 { 0x1E82, 0x0057, 0x0301 },
1239 { 0x1E83, 0x0077, 0x0301 },
1240 { 0x1E84, 0x0057, 0x0308 },
1241 { 0x1E85, 0x0077, 0x0308 },
1242 { 0x1E86, 0x0057, 0x0307 },
1243 { 0x1E87, 0x0077, 0x0307 },
1244 { 0x1E88, 0x0057, 0x0323 },
1245 { 0x1E89, 0x0077, 0x0323 },
1246 { 0x1E8A, 0x0058, 0x0307 },
1247 { 0x1E8B, 0x0078, 0x0307 },
1248 { 0x1E8C, 0x0058, 0x0308 },
1249 { 0x1E8D, 0x0078, 0x0308 },
1250 { 0x1E8E, 0x0059, 0x0307 },
1251 { 0x1E8F, 0x0079, 0x0307 },
1252 { 0x1E90, 0x005A, 0x0302 },
1253 { 0x1E91, 0x007A, 0x0302 },
1254 { 0x1E92, 0x005A, 0x0323 },
1255 { 0x1E93, 0x007A, 0x0323 },
1256 { 0x1E94, 0x005A, 0x0331 },
1257 { 0x1E95, 0x007A, 0x0331 },
1258 { 0x1E96, 0x0068, 0x0331 },
1259 { 0x1E97, 0x0074, 0x0308 },
1260 { 0x1E98, 0x0077, 0x030A },
1261 { 0x1E99, 0x0079, 0x030A },
1262 { 0x1E9B, 0x017F, 0x0307 },
1263 { 0x1EA0, 0x0041, 0x0323 },
1264 { 0x1EA1, 0x0061, 0x0323 },
1265 { 0x1EA2, 0x0041, 0x0309 },
1266 { 0x1EA3, 0x0061, 0x0309 },
1267 { 0x1EA4, 0x00C2, 0x0301 },
1268 { 0x1EA5, 0x00E2, 0x0301 },
1269 { 0x1EA6, 0x00C2, 0x0300 },
1270 { 0x1EA7, 0x00E2, 0x0300 },
1271 { 0x1EA8, 0x00C2, 0x0309 },
1272 { 0x1EA9, 0x00E2, 0x0309 },
1273 { 0x1EAA, 0x00C2, 0x0303 },
1274 { 0x1EAB, 0x00E2, 0x0303 },
1275 { 0x1EAC, 0x1EA0, 0x0302 },
1276 { 0x1EAD, 0x1EA1, 0x0302 },
1277 { 0x1EAE, 0x0102, 0x0301 },
1278 { 0x1EAF, 0x0103, 0x0301 },
1279 { 0x1EB0, 0x0102, 0x0300 },
1280 { 0x1EB1, 0x0103, 0x0300 },
1281 { 0x1EB2, 0x0102, 0x0309 },
1282 { 0x1EB3, 0x0103, 0x0309 },
1283 { 0x1EB4, 0x0102, 0x0303 },
1284 { 0x1EB5, 0x0103, 0x0303 },
1285 { 0x1EB6, 0x1EA0, 0x0306 },
1286 { 0x1EB7, 0x1EA1, 0x0306 },
1287 { 0x1EB8, 0x0045, 0x0323 },
1288 { 0x1EB9, 0x0065, 0x0323 },
1289 { 0x1EBA, 0x0045, 0x0309 },
1290 { 0x1EBB, 0x0065, 0x0309 },
1291 { 0x1EBC, 0x0045, 0x0303 },
1292 { 0x1EBD, 0x0065, 0x0303 },
1293 { 0x1EBE, 0x00CA, 0x0301 },
1294 { 0x1EBF, 0x00EA, 0x0301 },
1295 { 0x1EC0, 0x00CA, 0x0300 },
1296 { 0x1EC1, 0x00EA, 0x0300 },
1297 { 0x1EC2, 0x00CA, 0x0309 },
1298 { 0x1EC3, 0x00EA, 0x0309 },
1299 { 0x1EC4, 0x00CA, 0x0303 },
1300 { 0x1EC5, 0x00EA, 0x0303 },
1301 { 0x1EC6, 0x1EB8, 0x0302 },
1302 { 0x1EC7, 0x1EB9, 0x0302 },
1303 { 0x1EC8, 0x0049, 0x0309 },
1304 { 0x1EC9, 0x0069, 0x0309 },
1305 { 0x1ECA, 0x0049, 0x0323 },
1306 { 0x1ECB, 0x0069, 0x0323 },
1307 { 0x1ECC, 0x004F, 0x0323 },
1308 { 0x1ECD, 0x006F, 0x0323 },
1309 { 0x1ECE, 0x004F, 0x0309 },
1310 { 0x1ECF, 0x006F, 0x0309 },
1311 { 0x1ED0, 0x00D4, 0x0301 },
1312 { 0x1ED1, 0x00F4, 0x0301 },
1313 { 0x1ED2, 0x00D4, 0x0300 },
1314 { 0x1ED3, 0x00F4, 0x0300 },
1315 { 0x1ED4, 0x00D4, 0x0309 },
1316 { 0x1ED5, 0x00F4, 0x0309 },
1317 { 0x1ED6, 0x00D4, 0x0303 },
1318 { 0x1ED7, 0x00F4, 0x0303 },
1319 { 0x1ED8, 0x1ECC, 0x0302 },
1320 { 0x1ED9, 0x1ECD, 0x0302 },
1321 { 0x1EDA, 0x01A0, 0x0301 },
1322 { 0x1EDB, 0x01A1, 0x0301 },
1323 { 0x1EDC, 0x01A0, 0x0300 },
1324 { 0x1EDD, 0x01A1, 0x0300 },
1325 { 0x1EDE, 0x01A0, 0x0309 },
1326 { 0x1EDF, 0x01A1, 0x0309 },
1327 { 0x1EE0, 0x01A0, 0x0303 },
1328 { 0x1EE1, 0x01A1, 0x0303 },
1329 { 0x1EE2, 0x01A0, 0x0323 },
1330 { 0x1EE3, 0x01A1, 0x0323 },
1331 { 0x1EE4, 0x0055, 0x0323 },
1332 { 0x1EE5, 0x0075, 0x0323 },
1333 { 0x1EE6, 0x0055, 0x0309 },
1334 { 0x1EE7, 0x0075, 0x0309 },
1335 { 0x1EE8, 0x01AF, 0x0301 },
1336 { 0x1EE9, 0x01B0, 0x0301 },
1337 { 0x1EEA, 0x01AF, 0x0300 },
1338 { 0x1EEB, 0x01B0, 0x0300 },
1339 { 0x1EEC, 0x01AF, 0x0309 },
1340 { 0x1EED, 0x01B0, 0x0309 },
1341 { 0x1EEE, 0x01AF, 0x0303 },
1342 { 0x1EEF, 0x01B0, 0x0303 },
1343 { 0x1EF0, 0x01AF, 0x0323 },
1344 { 0x1EF1, 0x01B0, 0x0323 },
1345 { 0x1EF2, 0x0059, 0x0300 },
1346 { 0x1EF3, 0x0079, 0x0300 },
1347 { 0x1EF4, 0x0059, 0x0323 },
1348 { 0x1EF5, 0x0079, 0x0323 },
1349 { 0x1EF6, 0x0059, 0x0309 },
1350 { 0x1EF7, 0x0079, 0x0309 },
1351 { 0x1EF8, 0x0059, 0x0303 },
1352 { 0x1EF9, 0x0079, 0x0303 },
1353 { 0x1F00, 0x03B1, 0x0313 },
1354 { 0x1F01, 0x03B1, 0x0314 },
1355 { 0x1F02, 0x1F00, 0x0300 },
1356 { 0x1F03, 0x1F01, 0x0300 },
1357 { 0x1F04, 0x1F00, 0x0301 },
1358 { 0x1F05, 0x1F01, 0x0301 },
1359 { 0x1F06, 0x1F00, 0x0342 },
1360 { 0x1F07, 0x1F01, 0x0342 },
1361 { 0x1F08, 0x0391, 0x0313 },
1362 { 0x1F09, 0x0391, 0x0314 },
1363 { 0x1F0A, 0x1F08, 0x0300 },
1364 { 0x1F0B, 0x1F09, 0x0300 },
1365 { 0x1F0C, 0x1F08, 0x0301 },
1366 { 0x1F0D, 0x1F09, 0x0301 },
1367 { 0x1F0E, 0x1F08, 0x0342 },
1368 { 0x1F0F, 0x1F09, 0x0342 },
1369 { 0x1F10, 0x03B5, 0x0313 },
1370 { 0x1F11, 0x03B5, 0x0314 },
1371 { 0x1F12, 0x1F10, 0x0300 },
1372 { 0x1F13, 0x1F11, 0x0300 },
1373 { 0x1F14, 0x1F10, 0x0301 },
1374 { 0x1F15, 0x1F11, 0x0301 },
1375 { 0x1F18, 0x0395, 0x0313 },
1376 { 0x1F19, 0x0395, 0x0314 },
1377 { 0x1F1A, 0x1F18, 0x0300 },
1378 { 0x1F1B, 0x1F19, 0x0300 },
1379 { 0x1F1C, 0x1F18, 0x0301 },
1380 { 0x1F1D, 0x1F19, 0x0301 },
1381 { 0x1F20, 0x03B7, 0x0313 },
1382 { 0x1F21, 0x03B7, 0x0314 },
1383 { 0x1F22, 0x1F20, 0x0300 },
1384 { 0x1F23, 0x1F21, 0x0300 },
1385 { 0x1F24, 0x1F20, 0x0301 },
1386 { 0x1F25, 0x1F21, 0x0301 },
1387 { 0x1F26, 0x1F20, 0x0342 },
1388 { 0x1F27, 0x1F21, 0x0342 },
1389 { 0x1F28, 0x0397, 0x0313 },
1390 { 0x1F29, 0x0397, 0x0314 },
1391 { 0x1F2A, 0x1F28, 0x0300 },
1392 { 0x1F2B, 0x1F29, 0x0300 },
1393 { 0x1F2C, 0x1F28, 0x0301 },
1394 { 0x1F2D, 0x1F29, 0x0301 },
1395 { 0x1F2E, 0x1F28, 0x0342 },
1396 { 0x1F2F, 0x1F29, 0x0342 },
1397 { 0x1F30, 0x03B9, 0x0313 },
1398 { 0x1F31, 0x03B9, 0x0314 },
1399 { 0x1F32, 0x1F30, 0x0300 },
1400 { 0x1F33, 0x1F31, 0x0300 },
1401 { 0x1F34, 0x1F30, 0x0301 },
1402 { 0x1F35, 0x1F31, 0x0301 },
1403 { 0x1F36, 0x1F30, 0x0342 },
1404 { 0x1F37, 0x1F31, 0x0342 },
1405 { 0x1F38, 0x0399, 0x0313 },
1406 { 0x1F39, 0x0399, 0x0314 },
1407 { 0x1F3A, 0x1F38, 0x0300 },
1408 { 0x1F3B, 0x1F39, 0x0300 },
1409 { 0x1F3C, 0x1F38, 0x0301 },
1410 { 0x1F3D, 0x1F39, 0x0301 },
1411 { 0x1F3E, 0x1F38, 0x0342 },
1412 { 0x1F3F, 0x1F39, 0x0342 },
1413 { 0x1F40, 0x03BF, 0x0313 },
1414 { 0x1F41, 0x03BF, 0x0314 },
1415 { 0x1F42, 0x1F40, 0x0300 },
1416 { 0x1F43, 0x1F41, 0x0300 },
1417 { 0x1F44, 0x1F40, 0x0301 },
1418 { 0x1F45, 0x1F41, 0x0301 },
1419 { 0x1F48, 0x039F, 0x0313 },
1420 { 0x1F49, 0x039F, 0x0314 },
1421 { 0x1F4A, 0x1F48, 0x0300 },
1422 { 0x1F4B, 0x1F49, 0x0300 },
1423 { 0x1F4C, 0x1F48, 0x0301 },
1424 { 0x1F4D, 0x1F49, 0x0301 },
1425 { 0x1F50, 0x03C5, 0x0313 },
1426 { 0x1F51, 0x03C5, 0x0314 },
1427 { 0x1F52, 0x1F50, 0x0300 },
1428 { 0x1F53, 0x1F51, 0x0300 },
1429 { 0x1F54, 0x1F50, 0x0301 },
1430 { 0x1F55, 0x1F51, 0x0301 },
1431 { 0x1F56, 0x1F50, 0x0342 },
1432 { 0x1F57, 0x1F51, 0x0342 },
1433 { 0x1F59, 0x03A5, 0x0314 },
1434 { 0x1F5B, 0x1F59, 0x0300 },
1435 { 0x1F5D, 0x1F59, 0x0301 },
1436 { 0x1F5F, 0x1F59, 0x0342 },
1437 { 0x1F60, 0x03C9, 0x0313 },
1438 { 0x1F61, 0x03C9, 0x0314 },
1439 { 0x1F62, 0x1F60, 0x0300 },
1440 { 0x1F63, 0x1F61, 0x0300 },
1441 { 0x1F64, 0x1F60, 0x0301 },
1442 { 0x1F65, 0x1F61, 0x0301 },
1443 { 0x1F66, 0x1F60, 0x0342 },
1444 { 0x1F67, 0x1F61, 0x0342 },
1445 { 0x1F68, 0x03A9, 0x0313 },
1446 { 0x1F69, 0x03A9, 0x0314 },
1447 { 0x1F6A, 0x1F68, 0x0300 },
1448 { 0x1F6B, 0x1F69, 0x0300 },
1449 { 0x1F6C, 0x1F68, 0x0301 },
1450 { 0x1F6D, 0x1F69, 0x0301 },
1451 { 0x1F6E, 0x1F68, 0x0342 },
1452 { 0x1F6F, 0x1F69, 0x0342 },
1453 { 0x1F70, 0x03B1, 0x0300 },
1454 { 0x1F72, 0x03B5, 0x0300 },
1455 { 0x1F74, 0x03B7, 0x0300 },
1456 { 0x1F76, 0x03B9, 0x0300 },
1457 { 0x1F78, 0x03BF, 0x0300 },
1458 { 0x1F7A, 0x03C5, 0x0300 },
1459 { 0x1F7C, 0x03C9, 0x0300 },
1460 { 0x1F80, 0x1F00, 0x0345 },
1461 { 0x1F81, 0x1F01, 0x0345 },
1462 { 0x1F82, 0x1F02, 0x0345 },
1463 { 0x1F83, 0x1F03, 0x0345 },
1464 { 0x1F84, 0x1F04, 0x0345 },
1465 { 0x1F85, 0x1F05, 0x0345 },
1466 { 0x1F86, 0x1F06, 0x0345 },
1467 { 0x1F87, 0x1F07, 0x0345 },
1468 { 0x1F88, 0x1F08, 0x0345 },
1469 { 0x1F89, 0x1F09, 0x0345 },
1470 { 0x1F8A, 0x1F0A, 0x0345 },
1471 { 0x1F8B, 0x1F0B, 0x0345 },
1472 { 0x1F8C, 0x1F0C, 0x0345 },
1473 { 0x1F8D, 0x1F0D, 0x0345 },
1474 { 0x1F8E, 0x1F0E, 0x0345 },
1475 { 0x1F8F, 0x1F0F, 0x0345 },
1476 { 0x1F90, 0x1F20, 0x0345 },
1477 { 0x1F91, 0x1F21, 0x0345 },
1478 { 0x1F92, 0x1F22, 0x0345 },
1479 { 0x1F93, 0x1F23, 0x0345 },
1480 { 0x1F94, 0x1F24, 0x0345 },
1481 { 0x1F95, 0x1F25, 0x0345 },
1482 { 0x1F96, 0x1F26, 0x0345 },
1483 { 0x1F97, 0x1F27, 0x0345 },
1484 { 0x1F98, 0x1F28, 0x0345 },
1485 { 0x1F99, 0x1F29, 0x0345 },
1486 { 0x1F9A, 0x1F2A, 0x0345 },
1487 { 0x1F9B, 0x1F2B, 0x0345 },
1488 { 0x1F9C, 0x1F2C, 0x0345 },
1489 { 0x1F9D, 0x1F2D, 0x0345 },
1490 { 0x1F9E, 0x1F2E, 0x0345 },
1491 { 0x1F9F, 0x1F2F, 0x0345 },
1492 { 0x1FA0, 0x1F60, 0x0345 },
1493 { 0x1FA1, 0x1F61, 0x0345 },
1494 { 0x1FA2, 0x1F62, 0x0345 },
1495 { 0x1FA3, 0x1F63, 0x0345 },
1496 { 0x1FA4, 0x1F64, 0x0345 },
1497 { 0x1FA5, 0x1F65, 0x0345 },
1498 { 0x1FA6, 0x1F66, 0x0345 },
1499 { 0x1FA7, 0x1F67, 0x0345 },
1500 { 0x1FA8, 0x1F68, 0x0345 },
1501 { 0x1FA9, 0x1F69, 0x0345 },
1502 { 0x1FAA, 0x1F6A, 0x0345 },
1503 { 0x1FAB, 0x1F6B, 0x0345 },
1504 { 0x1FAC, 0x1F6C, 0x0345 },
1505 { 0x1FAD, 0x1F6D, 0x0345 },
1506 { 0x1FAE, 0x1F6E, 0x0345 },
1507 { 0x1FAF, 0x1F6F, 0x0345 },
1508 { 0x1FB0, 0x03B1, 0x0306 },
1509 { 0x1FB1, 0x03B1, 0x0304 },
1510 { 0x1FB2, 0x1F70, 0x0345 },
1511 { 0x1FB3, 0x03B1, 0x0345 },
1512 { 0x1FB4, 0x03AC, 0x0345 },
1513 { 0x1FB6, 0x03B1, 0x0342 },
1514 { 0x1FB7, 0x1FB6, 0x0345 },
1515 { 0x1FB8, 0x0391, 0x0306 },
1516 { 0x1FB9, 0x0391, 0x0304 },
1517 { 0x1FBA, 0x0391, 0x0300 },
1518 { 0x1FBC, 0x0391, 0x0345 },
1519 { 0x1FC1, 0x00A8, 0x0342 },
1520 { 0x1FC2, 0x1F74, 0x0345 },
1521 { 0x1FC3, 0x03B7, 0x0345 },
1522 { 0x1FC4, 0x03AE, 0x0345 },
1523 { 0x1FC6, 0x03B7, 0x0342 },
1524 { 0x1FC7, 0x1FC6, 0x0345 },
1525 { 0x1FC8, 0x0395, 0x0300 },
1526 { 0x1FCA, 0x0397, 0x0300 },
1527 { 0x1FCC, 0x0397, 0x0345 },
1528 { 0x1FCD, 0x1FBF, 0x0300 },
1529 { 0x1FCE, 0x1FBF, 0x0301 },
1530 { 0x1FCF, 0x1FBF, 0x0342 },
1531 { 0x1FD0, 0x03B9, 0x0306 },
1532 { 0x1FD1, 0x03B9, 0x0304 },
1533 { 0x1FD2, 0x03CA, 0x0300 },
1534 { 0x1FD6, 0x03B9, 0x0342 },
1535 { 0x1FD7, 0x03CA, 0x0342 },
1536 { 0x1FD8, 0x0399, 0x0306 },
1537 { 0x1FD9, 0x0399, 0x0304 },
1538 { 0x1FDA, 0x0399, 0x0300 },
1539 { 0x1FDD, 0x1FFE, 0x0300 },
1540 { 0x1FDE, 0x1FFE, 0x0301 },
1541 { 0x1FDF, 0x1FFE, 0x0342 },
1542 { 0x1FE0, 0x03C5, 0x0306 },
1543 { 0x1FE1, 0x03C5, 0x0304 },
1544 { 0x1FE2, 0x03CB, 0x0300 },
1545 { 0x1FE4, 0x03C1, 0x0313 },
1546 { 0x1FE5, 0x03C1, 0x0314 },
1547 { 0x1FE6, 0x03C5, 0x0342 },
1548 { 0x1FE7, 0x03CB, 0x0342 },
1549 { 0x1FE8, 0x03A5, 0x0306 },
1550 { 0x1FE9, 0x03A5, 0x0304 },
1551 { 0x1FEA, 0x03A5, 0x0300 },
1552 { 0x1FEC, 0x03A1, 0x0314 },
1553 { 0x1FED, 0x00A8, 0x0300 },
1554 { 0x1FF2, 0x1F7C, 0x0345 },
1555 { 0x1FF3, 0x03C9, 0x0345 },
1556 { 0x1FF4, 0x03CE, 0x0345 },
1557 { 0x1FF6, 0x03C9, 0x0342 },
1558 { 0x1FF7, 0x1FF6, 0x0345 },
1559 { 0x1FF8, 0x039F, 0x0300 },
1560 { 0x1FFA, 0x03A9, 0x0300 },
1561 { 0x1FFC, 0x03A9, 0x0345 },
1562 { 0x219A, 0x2190, 0x0338 },
1563 { 0x219B, 0x2192, 0x0338 },
1564 { 0x21AE, 0x2194, 0x0338 },
1565 { 0x21CD, 0x21D0, 0x0338 },
1566 { 0x21CE, 0x21D4, 0x0338 },
1567 { 0x21CF, 0x21D2, 0x0338 },
1568 { 0x2204, 0x2203, 0x0338 },
1569 { 0x2209, 0x2208, 0x0338 },
1570 { 0x220C, 0x220B, 0x0338 },
1571 { 0x2224, 0x2223, 0x0338 },
1572 { 0x2226, 0x2225, 0x0338 },
1573 { 0x2241, 0x223C, 0x0338 },
1574 { 0x2244, 0x2243, 0x0338 },
1575 { 0x2247, 0x2245, 0x0338 },
1576 { 0x2249, 0x2248, 0x0338 },
1577 { 0x2260, 0x003D, 0x0338 },
1578 { 0x2262, 0x2261, 0x0338 },
1579 { 0x226D, 0x224D, 0x0338 },
1580 { 0x226E, 0x003C, 0x0338 },
1581 { 0x226F, 0x003E, 0x0338 },
1582 { 0x2270, 0x2264, 0x0338 },
1583 { 0x2271, 0x2265, 0x0338 },
1584 { 0x2274, 0x2272, 0x0338 },
1585 { 0x2275, 0x2273, 0x0338 },
1586 { 0x2278, 0x2276, 0x0338 },
1587 { 0x2279, 0x2277, 0x0338 },
1588 { 0x2280, 0x227A, 0x0338 },
1589 { 0x2281, 0x227B, 0x0338 },
1590 { 0x2284, 0x2282, 0x0338 },
1591 { 0x2285, 0x2283, 0x0338 },
1592 { 0x2288, 0x2286, 0x0338 },
1593 { 0x2289, 0x2287, 0x0338 },
1594 { 0x22AC, 0x22A2, 0x0338 },
1595 { 0x22AD, 0x22A8, 0x0338 },
1596 { 0x22AE, 0x22A9, 0x0338 },
1597 { 0x22AF, 0x22AB, 0x0338 },
1598 { 0x22E0, 0x227C, 0x0338 },
1599 { 0x22E1, 0x227D, 0x0338 },
1600 { 0x22E2, 0x2291, 0x0338 },
1601 { 0x22E3, 0x2292, 0x0338 },
1602 { 0x22EA, 0x22B2, 0x0338 },
1603 { 0x22EB, 0x22B3, 0x0338 },
1604 { 0x22EC, 0x22B4, 0x0338 },
1605 { 0x22ED, 0x22B5, 0x0338 },
1606 { 0x2ADC, 0x2ADD, 0x0338 },
1607 { 0x304C, 0x304B, 0x3099 },
1608 { 0x304E, 0x304D, 0x3099 },
1609 { 0x3050, 0x304F, 0x3099 },
1610 { 0x3052, 0x3051, 0x3099 },
1611 { 0x3054, 0x3053, 0x3099 },
1612 { 0x3056, 0x3055, 0x3099 },
1613 { 0x3058, 0x3057, 0x3099 },
1614 { 0x305A, 0x3059, 0x3099 },
1615 { 0x305C, 0x305B, 0x3099 },
1616 { 0x305E, 0x305D, 0x3099 },
1617 { 0x3060, 0x305F, 0x3099 },
1618 { 0x3062, 0x3061, 0x3099 },
1619 { 0x3065, 0x3064, 0x3099 },
1620 { 0x3067, 0x3066, 0x3099 },
1621 { 0x3069, 0x3068, 0x3099 },
1622 { 0x3070, 0x306F, 0x3099 },
1623 { 0x3071, 0x306F, 0x309A },
1624 { 0x3073, 0x3072, 0x3099 },
1625 { 0x3074, 0x3072, 0x309A },
1626 { 0x3076, 0x3075, 0x3099 },
1627 { 0x3077, 0x3075, 0x309A },
1628 { 0x3079, 0x3078, 0x3099 },
1629 { 0x307A, 0x3078, 0x309A },
1630 { 0x307C, 0x307B, 0x3099 },
1631 { 0x307D, 0x307B, 0x309A },
1632 { 0x3094, 0x3046, 0x3099 },
1633 { 0x309E, 0x309D, 0x3099 },
1634 { 0x30AC, 0x30AB, 0x3099 },
1635 { 0x30AE, 0x30AD, 0x3099 },
1636 { 0x30B0, 0x30AF, 0x3099 },
1637 { 0x30B2, 0x30B1, 0x3099 },
1638 { 0x30B4, 0x30B3, 0x3099 },
1639 { 0x30B6, 0x30B5, 0x3099 },
1640 { 0x30B8, 0x30B7, 0x3099 },
1641 { 0x30BA, 0x30B9, 0x3099 },
1642 { 0x30BC, 0x30BB, 0x3099 },
1643 { 0x30BE, 0x30BD, 0x3099 },
1644 { 0x30C0, 0x30BF, 0x3099 },
1645 { 0x30C2, 0x30C1, 0x3099 },
1646 { 0x30C5, 0x30C4, 0x3099 },
1647 { 0x30C7, 0x30C6, 0x3099 },
1648 { 0x30C9, 0x30C8, 0x3099 },
1649 { 0x30D0, 0x30CF, 0x3099 },
1650 { 0x30D1, 0x30CF, 0x309A },
1651 { 0x30D3, 0x30D2, 0x3099 },
1652 { 0x30D4, 0x30D2, 0x309A },
1653 { 0x30D6, 0x30D5, 0x3099 },
1654 { 0x30D7, 0x30D5, 0x309A },
1655 { 0x30D9, 0x30D8, 0x3099 },
1656 { 0x30DA, 0x30D8, 0x309A },
1657 { 0x30DC, 0x30DB, 0x3099 },
1658 { 0x30DD, 0x30DB, 0x309A },
1659 { 0x30F4, 0x30A6, 0x3099 },
1660 { 0x30F7, 0x30EF, 0x3099 },
1661 { 0x30F8, 0x30F0, 0x3099 },
1662 { 0x30F9, 0x30F1, 0x3099 },
1663 { 0x30FA, 0x30F2, 0x3099 },
1664 { 0x30FE, 0x30FD, 0x3099 },
1665 { 0xFB1D, 0x05D9, 0x05B4 },
1666 { 0xFB1F, 0x05F2, 0x05B7 },
1667 { 0xFB2A, 0x05E9, 0x05C1 },
1668 { 0xFB2B, 0x05E9, 0x05C2 },
1669 { 0xFB2C, 0xFB49, 0x05C1 },
1670 { 0xFB2D, 0xFB49, 0x05C2 },
1671 { 0xFB2E, 0x05D0, 0x05B7 },
1672 { 0xFB2F, 0x05D0, 0x05B8 },
1673 { 0xFB30, 0x05D0, 0x05BC },
1674 { 0xFB31, 0x05D1, 0x05BC },
1675 { 0xFB32, 0x05D2, 0x05BC },
1676 { 0xFB33, 0x05D3, 0x05BC },
1677 { 0xFB34, 0x05D4, 0x05BC },
1678 { 0xFB35, 0x05D5, 0x05BC },
1679 { 0xFB36, 0x05D6, 0x05BC },
1680 { 0xFB38, 0x05D8, 0x05BC },
1681 { 0xFB39, 0x05D9, 0x05BC },
1682 { 0xFB3A, 0x05DA, 0x05BC },
1683 { 0xFB3B, 0x05DB, 0x05BC },
1684 { 0xFB3C, 0x05DC, 0x05BC },
1685 { 0xFB3E, 0x05DE, 0x05BC },
1686 { 0xFB40, 0x05E0, 0x05BC },
1687 { 0xFB41, 0x05E1, 0x05BC },
1688 { 0xFB43, 0x05E3, 0x05BC },
1689 { 0xFB44, 0x05E4, 0x05BC },
1690 { 0xFB46, 0x05E6, 0x05BC },
1691 { 0xFB47, 0x05E7, 0x05BC },
1692 { 0xFB48, 0x05E8, 0x05BC },
1693 { 0xFB49, 0x05E9, 0x05BC },
1694 { 0xFB4A, 0x05EA, 0x05BC },
1695 { 0xFB4B, 0x05D5, 0x05B9 },
1696 { 0xFB4C, 0x05D1, 0x05BF },
1697 { 0xFB4D, 0x05DB, 0x05BF },
1698 { 0xFB4E, 0x05E4, 0x05BF },
1699 /* out of range of unsigned short... */
1700 #if 0
1701 { 0x1D15E, 0x1D157, 0x1D165 },
1702 { 0x1D15F, 0x1D158, 0x1D165 },
1703 { 0x1D160, 0x1D15F, 0x1D16E },
1704 { 0x1D161, 0x1D15F, 0x1D16F },
1705 { 0x1D162, 0x1D15F, 0x1D170 },
1706 { 0x1D163, 0x1D15F, 0x1D171 },
1707 { 0x1D164, 0x1D15F, 0x1D172 },
1708 { 0x1D1BB, 0x1D1B9, 0x1D165 },
1709 { 0x1D1BC, 0x1D1BA, 0x1D165 },
1710 { 0x1D1BD, 0x1D1BB, 0x1D16E },
1711 { 0x1D1BE, 0x1D1BC, 0x1D16E },
1712 { 0x1D1BF, 0x1D1BB, 0x1D16F },
1713 { 0x1D1C0, 0x1D1BC, 0x1D16F },
1714 #endif
1715 /* special hack, treat Arabic ligatures as combining characters */
1716 /* combine them to the isolated presentation form, then let
1717 * the shaping and joining take care of it */
1718 { 0xFEF5, 0x0644, 0x0622 }, /* LAM_ALEF_MADDA */
1719 { 0xFEF7, 0x0644, 0x0623 }, /* LAM_ALEF_HAMZA_ABOVE */
1720 { 0xFEF9, 0x0644, 0x0625 }, /* LAM_ALEF_HAMZA_BELOW */
1721 { 0xFEFB, 0x0644, 0x0627 }, /* LAM_ALEF */
1722 };
1723
1724 /* -------------------------- local functions ------------------------------ */
1725
1726
1727 /* look-up functions, maybe theese should use binary search?
1728 would require a duplicate of comb_table to reverse map... */
1729 static int
get_combining_class(unsigned short ch)1730 get_combining_class(unsigned short ch)
1731 {
1732 int count;
1733 int table_size = sizeof(combclass_table) / sizeof(combclass_table[0]);
1734
1735 for (count = 0; count < table_size; count++)
1736 {
1737 if (combclass_table[count].key == ch)
1738 {
1739 return combclass_table[count].combclass;
1740 }
1741 }
1742
1743 return 0;
1744 }
1745
1746 static const char_comb_t*
get_comb_entry_decomposed(unsigned short ch)1747 get_comb_entry_decomposed(unsigned short ch)
1748 {
1749 int count;
1750 int table_size = sizeof(comb_table) / sizeof(comb_table[0]);
1751
1752 for (count = 0; count < table_size; count++)
1753 {
1754 if (comb_table[count].key == ch)
1755 {
1756 return &comb_table[count];
1757 }
1758 }
1759
1760 return NULL;
1761 }
1762
1763 static unsigned short
get_comb_entry_composed(unsigned short first,unsigned short second)1764 get_comb_entry_composed(unsigned short first, unsigned short second)
1765 {
1766 int count;
1767 int table_size = sizeof(comb_table) / sizeof(comb_table[0]);
1768
1769 for (count = 0; count < table_size; count++)
1770 {
1771 if (comb_table[count].first == first &&
1772 comb_table[count].second == second)
1773 {
1774 return comb_table[count].key;
1775 }
1776 }
1777
1778 return (unsigned short) 0;
1779 }
1780
1781 static int
convert_to_ucs2(const unsigned char * str_utf8,unsigned short * str_ucs2,int len)1782 convert_to_ucs2(
1783 const unsigned char *str_utf8, unsigned short *str_ucs2, int len)
1784 {
1785 int in_pos = 0;
1786 int out_pos = 0;
1787 while (in_pos < len)
1788 {
1789 if (str_utf8[in_pos] <= 0x7f)
1790 {
1791 str_ucs2[out_pos] =
1792 (unsigned short)str_utf8[in_pos];
1793 in_pos++;
1794 }
1795 else
1796 {
1797 if ((str_utf8[in_pos] & 0300) != 0300)
1798 {
1799 /* out of sync */
1800 str_ucs2[out_pos] = REPLACEMENT_CHARACTER;
1801 in_pos++;
1802 }
1803 else if (in_pos < len-1 && str_utf8[in_pos] <= 0xdf &&
1804 str_utf8[in_pos + 1] <= 0xbf &&
1805 str_utf8[in_pos + 1] >= 0x80)
1806 {
1807 str_ucs2[out_pos] =
1808 ((str_utf8[in_pos] & 0x1f) << 6) +
1809 (str_utf8[in_pos+1] & 0x3f);
1810 /* check for overlong sequence */
1811 if(str_ucs2[out_pos] < 0x80)
1812 str_ucs2[out_pos] =
1813 REPLACEMENT_CHARACTER;
1814 in_pos += 2;
1815 }
1816 else if (in_pos < len-2 && str_utf8[in_pos] <= 0xef &&
1817 str_utf8[in_pos + 1] <= 0xbf &&
1818 str_utf8[in_pos + 1] >= 0x80 &&
1819 str_utf8[in_pos + 2] <= 0xbf &&
1820 str_utf8[in_pos + 2] >= 0x80)
1821 {
1822 str_ucs2[out_pos] =
1823 ((str_utf8[in_pos] & 0x0f) << 12) +
1824 ((str_utf8[in_pos+1] & 0x3f) << 6) +
1825 (str_utf8[in_pos+2] & 0x3f);
1826 /* check for overlong sequence */
1827 if(str_ucs2[out_pos] < 0x800)
1828 str_ucs2[out_pos] =
1829 REPLACEMENT_CHARACTER;
1830 in_pos += 3;
1831 }
1832 else
1833 {
1834 /* incomplete sequence */
1835 str_ucs2[out_pos] = REPLACEMENT_CHARACTER;
1836 in_pos++;
1837 }
1838 }
1839 out_pos++;
1840 }
1841 return out_pos;
1842 }
1843
1844 static int
convert_to_utf8(const unsigned short * str_ucs2,unsigned char * str_utf8,int len)1845 convert_to_utf8(
1846 const unsigned short *str_ucs2, unsigned char *str_utf8, int len)
1847 {
1848 int in_pos = 0;
1849 int out_pos = 0;
1850
1851 for (in_pos = 0 ; in_pos < len ; in_pos++)
1852 {
1853 if (str_ucs2[in_pos] <= 0x7f)
1854 {
1855 str_utf8[out_pos] = str_ucs2[in_pos];
1856 out_pos++;
1857 }
1858 else if (str_ucs2[in_pos] <= 0x7ff)
1859 {
1860 str_utf8[out_pos] =
1861 (str_ucs2[in_pos] >> 6) | 0xc0;
1862 str_utf8[out_pos+1] =
1863 (str_ucs2[in_pos] & 0x3f) | 0x80;
1864 out_pos += 2;
1865 }
1866 else
1867 {
1868 str_utf8[out_pos] =
1869 (str_ucs2[in_pos] >> 12) | 0xe0;
1870 str_utf8[out_pos+1] =
1871 ((str_ucs2[in_pos] & 0xfff) >> 6) | 0x80;
1872 str_utf8[out_pos+2] =
1873 (str_ucs2[in_pos] & 0x3f) | 0x80;
1874 out_pos += 3;
1875 }
1876 /* this doesn't handle values outside UCS2 (16-bit) */
1877 }
1878 return out_pos;
1879 }
1880
1881
1882 /* main procedure:
1883 takes a pointer to a string (UTF-8)
1884 first decomposes string, then rearrange combining characters, the
1885 combines them back.
1886 Result is stored in original string (can never be "expanded" from
1887 original size), new length is returned
1888 */
1889
1890
1891 int
CombineChars(unsigned char * str_visual,int len,superimpose_char_t ** comb_chars,int ** l_to_v)1892 CombineChars(
1893 unsigned char *str_visual, int len, superimpose_char_t **comb_chars,
1894 int **l_to_v)
1895 {
1896 int i,j,k; /* counters */
1897 unsigned short *source;
1898 unsigned short *dest;
1899 int *source_v_to_l;
1900 int *dest_v_to_l;
1901 int str_len;
1902 int in_str_len;
1903 int out_str_len;
1904 int comp_str_len = 0;
1905 Bool has_changed;
1906
1907 /* if input has zero length, return immediatly */
1908 if (len == 0)
1909 {
1910 return 0;
1911 }
1912
1913 /* decompose composed characters */
1914 source = (unsigned short *)safemalloc(
1915 (len + 1) * sizeof(unsigned short));
1916 /* convert from UTF-8-encoded text to internal 16-bit encoding */
1917 str_len = convert_to_ucs2(str_visual,source,len);
1918 in_str_len = str_len;
1919 /* we don't really need to NULL-terminate source, since we
1920 have string length */
1921
1922 /* be pessimistic, assume all characters are decomposed */
1923 dest = (unsigned short *)safemalloc(
1924 (str_len + 1) * 2 * sizeof(unsigned short));
1925 /* use theese to keep track of the mapping of characters from
1926 logical to visual */
1927 source_v_to_l = (int *)safemalloc(str_len * sizeof(int));
1928 dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int));
1929 /* setup initial mapping 1-to-1 */
1930 for(i = 0 ; i < str_len ; i++)
1931 {
1932 source_v_to_l[i] = i;
1933 }
1934 do
1935 {
1936 has_changed = False;
1937 for (i = 0, j = 0; i < str_len; i++)
1938 {
1939 const char_comb_t *decomp =
1940 get_comb_entry_decomposed(source[i]);
1941 /* current character is decomposable */
1942 if (decomp)
1943 {
1944 dest[j] = decomp->first;
1945 dest[j+1] = decomp->second;
1946 dest_v_to_l[j] = source_v_to_l[i];
1947 dest_v_to_l[j+1] = source_v_to_l[i];
1948 j += 2;
1949 has_changed = True;
1950 }
1951 else /* leave it as is */
1952 {
1953 dest[j] = source[i];
1954 dest_v_to_l[j] = source_v_to_l[i];
1955 j++;
1956 }
1957 }
1958
1959 /* now swap */
1960 free(source);
1961 free(source_v_to_l);
1962 source = dest;
1963 source_v_to_l = dest_v_to_l;
1964 str_len = j;
1965 dest = (unsigned short *)safemalloc(
1966 (str_len + 1) * 2 * sizeof(unsigned short));
1967 dest_v_to_l = (int *)safemalloc(str_len * 2 * sizeof(int));
1968 } while (has_changed);
1969 /* source now holds decomposed string (got swapped before exiting
1970 loop, str_len holds string length */
1971 /* we reuse dest for composing, can use existing string lengths
1972 since it will only get shorter */
1973 /* source_v_to_l holds the mapping from positions in decomposed
1974 string to original string */
1975
1976 /* rearrange combining characters */
1977 do
1978 {
1979 has_changed = False;
1980 for (i = 0; i < str_len - 1; i++)
1981 {
1982 /* swap if combining-class(c1) > combining-class(c2)
1983 and combining-class(c2) != 0 */
1984 /* use negative values for marks that have combining
1985 class 0, but should be taken out for drawing
1986 superimposed */
1987 int c1 = get_combining_class(source[i]);
1988 int c2 = get_combining_class(source[i+1]);
1989 if (c1 > c2 && c2 > 0)
1990 {
1991 unsigned short temp = source[i];
1992 int temp_v_to_l = source_v_to_l[i];
1993 source[i] = source[i+1];
1994 source[i+1] = temp;
1995 source_v_to_l[i] = source_v_to_l[i+1];
1996 source_v_to_l[i+1] = temp_v_to_l;
1997 has_changed = True;
1998 }
1999 }
2000 } while (has_changed);
2001
2002 /* compose */
2003 do
2004 {
2005 unsigned short *temp;
2006 int *temp_v_to_l;
2007 Bool last_changed = False;
2008 has_changed = False;
2009
2010 for (i = 0, j = 0; i < str_len - 1; j++)
2011 {
2012 unsigned short composed =
2013 get_comb_entry_composed(source[i],
2014 source[i+1]);
2015 dest_v_to_l[j] = source_v_to_l[i];
2016 if (composed != 0)
2017 {
2018 dest[j] = composed;
2019 /* if the last character was "absorbed" */
2020 if (i == str_len - 2)
2021 {
2022 last_changed = True;
2023 }
2024 i += 2;
2025 has_changed = True;
2026 }
2027 else
2028 {
2029 dest[j] = source[i];
2030 i++;
2031 }
2032 }
2033 temp = dest;
2034 dest = source;
2035 source = temp;
2036 temp_v_to_l = dest_v_to_l;
2037 dest_v_to_l = source_v_to_l;
2038 source_v_to_l = temp_v_to_l;
2039 /* fixup the last character, the loop above goes to second
2040 last, since it needs to look at 2 consecutive,
2041 if the last character is a non-combining character */
2042 /* since we have an immediate return on zero length, this works
2043 otherwise this would introduce crap here */
2044 if (!last_changed)
2045 {
2046 source[j] = dest[i];
2047 source_v_to_l[j] = dest_v_to_l[i];
2048 str_len = j+1;
2049 }
2050 else
2051 {
2052 str_len = j;
2053 }
2054 } while (has_changed);
2055
2056 /* source contains composed string */
2057
2058 /* gather "uncomposed" combining characters here for rendering
2059 over normal characters later */
2060 comp_str_len = 0;
2061 if (comb_chars != NULL)
2062 {
2063 /* calculate number of combining characters left */
2064 for (i = 0 ; i < str_len ; i++)
2065 {
2066 if (get_combining_class(source[i]) != 0)
2067 {
2068 comp_str_len++;
2069 }
2070 }
2071 /* allocate storage for combining characters */
2072 *comb_chars = (superimpose_char_t *)
2073 safemalloc((comp_str_len + 1) *
2074 sizeof(superimpose_char_t));
2075 }
2076 for (i = 0,j = 0,k = 0 ; i < str_len ; i++)
2077 {
2078 /* if character is non-combining,
2079 just copy it over to output */
2080 /* if first character is a combing character, just output
2081 it as if it where a base character */
2082 if (get_combining_class(source[i]) == 0)
2083 {
2084 dest[j] = source[i];
2085 dest_v_to_l[j] = source_v_to_l[i];
2086 j++;
2087 }
2088 else
2089 {
2090 if (comb_chars != NULL)
2091 {
2092 /* store composing character as associated
2093 with last base charcter */
2094 (*comb_chars)[k].position = j == 0 ? 0 : j-1;
2095 (*comb_chars)[k].c.byte1 = source[i] >> 8;
2096 (*comb_chars)[k].c.byte2 = source[i] & 0xff;
2097 k++;
2098 }
2099 }
2100 }
2101 /* terminate */
2102 if (comb_chars != NULL)
2103 {
2104 (*comb_chars)[comp_str_len].position = 0;
2105 (*comb_chars)[comp_str_len].c.byte1 = 0;
2106 (*comb_chars)[comp_str_len].c.byte2 = 0;
2107 }
2108 str_len = convert_to_utf8(dest,str_visual,j);
2109 out_str_len = j;
2110 str_visual[str_len] = 0;
2111
2112 if(l_to_v != NULL)
2113 {
2114 *l_to_v = (int *)safemalloc((in_str_len + 1) * sizeof(int));
2115 /* map the visual to logical mapping obtained above into
2116 a logical to visual mapping */
2117 /* setup the final mapping from logical to visual positions */
2118 /* if no base characters out, all positions map to zero,
2119 because there we have combining chars in that case */
2120 if(out_str_len == 0)
2121 {
2122 for(i = 0 ; i < in_str_len ; i++)
2123 {
2124 (*l_to_v)[i] = 0;
2125 }
2126 }
2127 for(i = 0, j = 0 ; i < out_str_len ; i++)
2128 {
2129 /* for each element in mapping from visual string
2130 insert "backtracked" references from logical
2131 string by inserting consequitive entries, as many
2132 as the step in the mapping from visual to logical
2133 */
2134 int step = (i == out_str_len - 1) ?
2135 in_str_len - j :
2136 dest_v_to_l[i+1] - dest_v_to_l[i];
2137 for(k = 0 ; k < step ; k++, j++)
2138 {
2139 (*l_to_v)[j] = i;
2140 }
2141 }
2142 /* terminated it with -1, to avoid have to send around
2143 lenghts */
2144 (*l_to_v)[in_str_len] = -1;
2145 }
2146
2147 /* clean up */
2148 free(source);
2149 free(dest);
2150 free(source_v_to_l);
2151 free(dest_v_to_l);
2152
2153 return str_len;
2154 }
2155