[test] Add Indic tests from harfbuzz.old
[framework/uifw/harfbuzz.git] / test / test-shape-complex.c
1 /*
2  * Copyright © 2011  Google, Inc.
3  * Copyright © 2008  Nokia Corporation and/or its subsidiary(-ies)
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Google Author(s): Behdad Esfahbod
26  */
27
28 #include "hb-test.h"
29
30 /* Unit tests for complex text shaping */
31
32 /*
33  * This test provides a framework to test aspects of hb_shape() that are
34  * font-dependent.  Please add tests for any feature that fits that
35  * description.
36  */
37
38 #ifdef HAVE_FREETYPE
39 #include <hb-ft.h>
40 #endif
41
42 typedef struct
43 {
44   char           comments[64];
45   hb_codepoint_t characters[16];
46   hb_codepoint_t glyphs[16];
47 } test_t;
48
49 typedef struct
50 {
51   const char *font_file;
52   unsigned int face_index;
53   const test_t tests[];
54 } test_set_t;
55
56
57 #if 0
58 static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
59 {
60     QString uc = QString().append(ch);
61     Shaper shaper(face, script, uc);
62
63     uc = uc.normalized(QString::NormalizationForm_D);
64     Shaper decomposed(face, script, uc);
65
66     if( shaper.shaper_item.num_glyphs != decomposed.shaper_item.num_glyphs )
67         goto error;
68
69     for (unsigned int i = 0; i < shaper.shaper_item.num_glyphs; ++i) {
70         if ((shaper.shaper_item.glyphs[i]&0xffffff) != (decomposed.shaper_item.glyphs[i]&0xffffff))
71             goto error;
72     }
73     return true;
74  error:
75     QString str = "";
76     int i = 0;
77     while (i < uc.length()) {
78         str += QString("%1 ").arg(uc[i].unicode(), 4, 16);
79         ++i;
80     }
81     qDebug("%s: decomposedShaping of char %4x failed\n    decomposedString: %s\n   nglyphs=%d, decomposed nglyphs %d",
82            face->family_name,
83            ch.unicode(), str.toLatin1().data(),
84            shaper.shaper_item.num_glyphs,
85            decomposed.shaper_item.num_glyphs);
86
87     str = "";
88     i = 0;
89     while (i < shaper.shaper_item.num_glyphs) {
90         str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
91         ++i;
92     }
93     qDebug("    composed glyph result   = %s", str.toLatin1().constData());
94     str = "";
95     i = 0;
96     while (i < decomposed.shaper_item.num_glyphs) {
97         str += QString("%1 ").arg(decomposed.shaper_item.glyphs[i], 4, 16);
98         ++i;
99     }
100     qDebug("    decomposed glyph result = %s", str.toLatin1().constData());
101     return false;
102 }
103
104 struct shape_test_t {
105     unsigned short unicode[16];
106     unsigned short glyphs[16];
107 };
108
109 void tst_QScriptEngine::greek()
110 {
111   "DejaVuSans.ttf",
112     if (face) {
113         for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
114             QString str;
115             str.append(uc);
116             if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
117                 /* qDebug() << "skipping" << hex << uc; */
118                 continue;
119             }
120             if (uc == 0x1fc1 || uc == 0x1fed)
121                 continue;
122             QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
123         }
124         FT_Done_Face(face);
125     } else {
126         QSKIP("couln't find DejaVu Sans", SkipAll);
127     }
128
129
130     face = loadFace("SBL_grk.ttf");
131     if (face) {
132         for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
133             QString str;
134             str.append(uc);
135             if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
136                 /* qDebug() << "skipping" << hex << uc; */
137                 continue;
138             }
139             if (uc == 0x1fc1 || uc == 0x1fed)
140                 continue;
141             QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
142
143         }
144
145     };
146 }
147 #endif
148
149 static const test_set_t tests_greek = {
150   "DejaVuSans.ttf", 0,
151   {
152     { "",
153       { 0x3b1, 0x300, 0x313, 0 },
154       { 0xb8, 0x3d3, 0x3c7, 0 }
155     },
156     { "",
157       { 0x3b1, 0x313, 0x300, 0 },
158       { 0xd4, 0 }
159     },
160     {{0}}
161   }
162 };
163
164 static const test_set_t tests_devanagari_1 = {
165   "raghu.ttf", 0,
166   {
167     { "Ka",
168       { 0x0915, 0 },
169       { 0x0080, 0 }
170     },
171     { "Ka Halant",
172       { 0x0915, 0x094d, 0 },
173       { 0x0080, 0x0051, 0 }
174     },
175     { "Ka Halant Ka",
176       { 0x0915, 0x094d, 0x0915, 0 },
177       { 0x00c8, 0x0080, 0 }
178     },
179     { "Ka MatraI",
180       { 0x0915, 0x093f, 0 },
181       { 0x01d1, 0x0080, 0 }
182     },
183     { "Ra Halant Ka",
184       { 0x0930, 0x094d, 0x0915, 0 },
185       { 0x0080, 0x005b, 0 }
186     },
187     { "Ra Halant Ka MatraI",
188       { 0x0930, 0x094d, 0x0915, 0x093f, 0 },
189       { 0x01d1, 0x0080, 0x005b, 0 }
190     },
191     { "MatraI",
192       { 0x093f, 0 },
193       { 0x01d4, 0x029c, 0 }
194     },
195     { "Ka Nukta",
196       { 0x0915, 0x093c, 0 },
197       { 0x00a4, 0 }
198     },
199     { "Ka Halant Ra",
200       { 0x0915, 0x094d, 0x0930, 0 },
201       { 0x0110, 0 }
202     },
203     { "Ka Halant Ra Halant Ka",
204       { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0 },
205       { 0x0158, 0x0080, 0 }
206     },
207     { "",
208       { 0x0930, 0x094d, 0x200d, 0 },
209       { 0x00e2, 0 }
210     },
211     { "",
212       { 0x0915, 0x094d, 0x0930, 0x094d, 0x200d, 0 },
213       { 0x0158, 0 }
214     },
215     {{0}}
216   }
217 };
218
219 static const test_set_t tests_devanagari_2 = {
220   "mangal.ttf", 0,
221   {
222     { "Ka",
223       { 0x0915, 0 },
224       { 0x0080, 0 }
225     },
226     { "Ka Halant",
227       { 0x0915, 0x094d, 0 },
228       { 0x0080, 0x0051, 0 }
229     },
230     { "Ka Halant Ka",
231       { 0x0915, 0x094d, 0x0915, 0 },
232       { 0x00c8, 0x0080, 0 }
233     },
234     { "Ka MatraI",
235       { 0x0915, 0x093f, 0 },
236       { 0x01d1, 0x0080, 0 }
237     },
238     { "Ra Halant Ka",
239       { 0x0930, 0x094d, 0x0915, 0 },
240       { 0x0080, 0x005b, 0 }
241     },
242     { "Ra Halant Ka MatraI",
243       { 0x0930, 0x094d, 0x0915, 0x093f, 0 },
244       { 0x01d1, 0x0080, 0x005b, 0 }
245     },
246     { "MatraI",
247       { 0x093f, 0 },
248       { 0x01d4, 0x029c, 0 }
249     },
250     { "Ka Nukta",
251       { 0x0915, 0x093c, 0 },
252       { 0x00a4, 0 }
253     },
254     { "Ka Halant Ra",
255       { 0x0915, 0x094d, 0x0930, 0 },
256       { 0x0110, 0 }
257     },
258     { "Ka Halant Ra Halant Ka",
259       { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0 },
260       { 0x0158, 0x0080, 0 }
261     },
262     { "",
263       { 0x92b, 0x94d, 0x930, 0 },
264       { 0x125, 0 }
265     },
266     { "",
267       { 0x92b, 0x93c, 0x94d, 0x930, 0 },
268       { 0x149, 0 }
269     },
270     {{0}}
271   }
272 };
273
274 static const test_set_t tests_bengali_1 = {
275   "AkaashNormal.ttf", 0,
276   {
277     { "Ka",
278       { 0x0995, 0 },
279       { 0x0151, 0 }
280     },
281     { "Ka Halant",
282       { 0x0995, 0x09cd, 0 },
283       { 0x0151, 0x017d, 0 }
284     },
285     { "Ka Halant Ka",
286       { 0x0995, 0x09cd, 0x0995, 0 },
287       { 0x019b, 0 }
288     },
289     { "Ka MatraI",
290       { 0x0995, 0x09bf, 0 },
291       { 0x0173, 0x0151, 0 }
292     },
293     { "Ra Halant Ka",
294       { 0x09b0, 0x09cd, 0x0995, 0 },
295       { 0x0151, 0x0276, 0 }
296     },
297     { "Ra Halant Ka MatraI",
298       { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0 },
299       { 0x0173, 0x0151, 0x0276, 0 }
300     },
301     { "Ka Nukta",
302       { 0x0995, 0x09bc, 0 },
303       { 0x0151, 0x0171, 0 }
304     },
305     { "Ka Halant Ra",
306       { 0x0995, 0x09cd, 0x09b0, 0 },
307       { 0x01f4, 0 }
308     },
309     { "Ka Halant Ra Halant Ka",
310       { 0x0995, 0x09cd, 0x09b0, 0x09cd, 0x0995, 0 },
311       { 0x025c, 0x0276, 0x0151, 0 }
312     },
313     { "Ya + Halant",
314       { 0x09af, 0x09cd, 0 },
315       { 0x016a, 0x017d, 0 }
316     },
317     { "Da Halant Ya -> Da Ya-Phala",
318       { 0x09a6, 0x09cd, 0x09af, 0 },
319       { 0x01e5, 0 }
320     },
321     { "A Halant Ya -> A Ya-phala",
322       { 0x0985, 0x09cd, 0x09af, 0 },
323       { 0x0145, 0x01cf, 0 }
324     },
325     { "Na Halant Ka",
326       { 0x09a8, 0x09cd, 0x0995, 0 },
327       { 0x026f, 0x0151, 0 }
328     },
329     { "Na Halant ZWNJ Ka",
330       { 0x09a8, 0x09cd, 0x200c, 0x0995, 0 },
331       { 0x0164, 0x017d, 0x0151, 0 }
332     },
333     { "Na Halant ZWJ Ka",
334       { 0x09a8, 0x09cd, 0x200d, 0x0995, 0 },
335       { 0x026f, 0x0151, 0 }
336     },
337     { "Ka Halant ZWNJ Ka",
338       { 0x0995, 0x09cd, 0x200c, 0x0995, 0 },
339       { 0x0151, 0x017d, 0x0151, 0 }
340     },
341     { "Ka Halant ZWJ Ka",
342       { 0x0995, 0x09cd, 0x200d, 0x0995, 0 },
343       { 0x025c, 0x0151, 0 }
344     },
345     { "Na Halant Ra",
346       { 0x09a8, 0x09cd, 0x09b0, 0 },
347       { 0x0207, 0 }
348     },
349     { "Na Halant ZWNJ Ra",
350       { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0 },
351       { 0x0164, 0x017d, 0x016b, 0 }
352     },
353     { "Na Halant ZWJ Ra",
354       { 0x09a8, 0x09cd, 0x200d, 0x09b0, 0 },
355       { 0x026f, 0x016b, 0 }
356     },
357     { "Na Halant Ba",
358       { 0x09a8, 0x09cd, 0x09ac, 0 },
359       { 0x022f, 0 }
360     },
361     { "Na Halant ZWNJ Ba",
362       { 0x09a8, 0x09cd, 0x200c, 0x09ac, 0 },
363       { 0x0164, 0x017d, 0x0167, 0 }
364     },
365     { "Na Halant ZWJ Ba",
366       { 0x09a8, 0x09cd, 0x200d, 0x09ac, 0 },
367       { 0x026f, 0x0167, 0 }
368     },
369     { "Na Halant Dha",
370       { 0x09a8, 0x09cd, 0x09a7, 0 },
371       { 0x01d3, 0 }
372     },
373     { "Na Halant ZWNJ Dha",
374       { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0 },
375       { 0x0164, 0x017d, 0x0163, 0 }
376     },
377     { "Na Halant ZWJ Dha",
378       { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0 },
379       { 0x026f, 0x0163, 0 }
380     },
381     { "Ra Halant Ka MatraAU",
382       { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0 },
383       { 0x0179, 0x0151, 0x0276, 0x017e, 0 }
384     },
385     { "Ra Halant Ba Halant Ba",
386       { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0 },
387       { 0x0232, 0x0276, 0 }
388     },
389     { "",
390       { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0 },
391       { 0x151, 0x276, 0x172, 0x143, 0 }
392     },
393     { "",
394       { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0 },
395       { 0x151, 0x276, 0x172, 0x144, 0 }
396     },
397     /*  Test decomposed two part matras */
398     { "",
399       { 0x995, 0x9c7, 0x9be, 0 },
400       { 0x179, 0x151, 0x172, 0 }
401     },
402     { "",
403       { 0x995, 0x9c7, 0x9d7, 0 },
404       { 0x179, 0x151, 0x17e, 0 }
405     },
406     { "",
407       { 0x9b0, 0x9cd, 0x9ad, 0 },
408       { 0x168, 0x276, 0 }
409     },
410     { "",
411       { 0x9f0, 0x9cd, 0x9ad, 0 },
412       { 0x168, 0x276, 0 }
413     },
414     { "",
415       { 0x9f1, 0x9cd, 0x9ad, 0 },
416       { 0x191, 0x17d, 0x168, 0 }
417     },
418     {{0}}
419   }
420 };
421
422 static const test_set_t tests_bengali_2 = {
423   "MuktiNarrow.ttf", 0,
424   {
425     { "Ka",
426       { 0x0995, 0 },
427       { 0x0073, 0 }
428     },
429     { "Ka Halant",
430       { 0x0995, 0x09cd, 0 },
431       { 0x00b9, 0 }
432     },
433     { "Ka Halant Ka",
434       { 0x0995, 0x09cd, 0x0995, 0 },
435       { 0x0109, 0 }
436     },
437     { "Ka MatraI",
438       { 0x0995, 0x09bf, 0 },
439       { 0x0095, 0x0073, 0 }
440     },
441     { "Ra Halant Ka",
442       { 0x09b0, 0x09cd, 0x0995, 0 },
443       { 0x0073, 0x00e1, 0 }
444     },
445     { "Ra Halant Ka MatraI",
446       { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0 },
447       { 0x0095, 0x0073, 0x00e1, 0 }
448     },
449     { "MatraI",
450       { 0x09bf, 0 },
451       { 0x0095, 0x01c8, 0 }
452     },
453     { "Ka Nukta",
454       { 0x0995, 0x09bc, 0 },
455       { 0x0073, 0x0093, 0 }
456     },
457     { "Ka Halant Ra",
458       { 0x0995, 0x09cd, 0x09b0, 0 },
459       { 0x00e5, 0 }
460     },
461     { "Ka Halant Ra Halant Ka",
462       { 0x995, 0x9cd, 0x9b0, 0x9cd, 0x995, 0 },
463       { 0x234, 0x24e, 0x73, 0 }
464     },
465     { "Ya + Halant",
466       { 0x09af, 0x09cd, 0 },
467       { 0x00d2, 0 }
468     },
469     { "Da Halant Ya -> Da Ya-Phala",
470       { 0x09a6, 0x09cd, 0x09af, 0 },
471       { 0x0084, 0x00e2, 0 }
472     },
473     { "A Halant Ya -> A Ya-phala",
474       { 0x0985, 0x09cd, 0x09af, 0 },
475       { 0x0067, 0x00e2, 0 }
476     },
477     { "Na Halant Ka",
478       { 0x09a8, 0x09cd, 0x0995, 0 },
479       { 0x0188, 0 }
480     },
481     { "Na Halant ZWNJ Ka",
482       { 0x9a8, 0x9cd, 0x200c, 0x995, 0 },
483       { 0xcc, 0x73, 0 }
484     },
485     { "Na Halant ZWJ Ka",
486       { 0x9a8, 0x9cd, 0x200d, 0x995, 0 },
487       { 0x247, 0x73, 0 }
488     },
489     { "Ka Halant ZWNJ Ka",
490       { 0x9a8, 0x9cd, 0x200d, 0x995, 0 },
491       { 0x247, 0x73, 0 }
492     },
493     { "Ka Halant ZWJ Ka",
494       { 0x9a8, 0x9cd, 0x200d, 0x995, 0 },
495       { 0x247, 0x73, 0 }
496     },
497     { "Na Halant Ra",
498       { 0x09a8, 0x09cd, 0x09b0, 0 },
499       { 0x00f8, 0 }
500     },
501     { "Na Halant ZWNJ Ra",
502       { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0 },
503       { 0xcc, 0x8d, 0 }
504     },
505     { "Na Halant ZWJ Ra",
506       { 0x9a8, 0x9cd, 0x200d, 0x9b0, 0 },
507       { 0x247, 0x8d, 0 }
508     },
509     { "Na Halant Ba",
510       { 0x09a8, 0x09cd, 0x09ac, 0 },
511       { 0x0139, 0 }
512     },
513     { "Na Halant ZWNJ Ba",
514       { 0x9a8, 0x9cd, 0x200c, 0x9ac, 0 },
515       { 0xcc, 0x89, 0 }
516     },
517     { "Na Halant ZWJ Ba",
518       { 0x9a8, 0x9cd, 0x200d, 0x9ac, 0 },
519       { 0x247, 0x89, 0 }
520     },
521     { "Na Halant Dha",
522       { 0x09a8, 0x09cd, 0x09a7, 0 },
523       { 0x0145, 0 }
524     },
525     { "Na Halant ZWNJ Dha",
526       { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0 },
527       { 0xcc, 0x85, 0 }
528     },
529     { "Na Halant ZWJ Dha",
530       { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0 },
531       { 0x247, 0x85, 0 }
532     },
533     { "Ra Halant Ka MatraAU",
534       { 0x9b0, 0x9cd, 0x995, 0x9cc, 0 },
535       { 0x232, 0x73, 0xe1, 0xa0, 0 }
536     },
537     { "Ra Halant Ba Halant Ba",
538       { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0 },
539       { 0x013b, 0x00e1, 0 }
540     },
541     {{0}}
542   }
543 };
544
545 static const test_set_t tests_bengali_3 = {
546   "LikhanNormal.ttf", 0,
547   {
548     { "",
549       { 0x09a8, 0x09cd, 0x09af, 0 },
550       { 0x01ca, 0 }
551     },
552     { "",
553       { 0x09b8, 0x09cd, 0x09af, 0 },
554       { 0x020e, 0 }
555     },
556     { "",
557       { 0x09b6, 0x09cd, 0x09af, 0 },
558       { 0x01f4, 0 }
559     },
560     { "",
561       { 0x09b7, 0x09cd, 0x09af, 0 },
562       { 0x01fe, 0 }
563     },
564     { "",
565       { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0 },
566       { 0x10b, 0x167, 0 }
567     },
568     { "",
569       { 0x9b0, 0x9cd, 0x9ad, 0 },
570       { 0xa1, 0x167, 0 }
571     },
572     { "",
573       { 0x9f0, 0x9cd, 0x9ad, 0 },
574       { 0xa1, 0x167, 0 }
575     },
576     { "",
577       { 0x9f1, 0x9cd, 0x9ad, 0 },
578       { 0x11c, 0xa1, 0 }
579     },
580     {{0}}
581   }
582 };
583
584 static const test_set_t tests_gurmukhi = {
585   "lohit_pa.ttf", 0,
586   {
587     { "",
588       { 0xA15, 0xA4D, 0xa39, 0 },
589       { 0x3b, 0x8b, 0 }
590     },
591     {{0}}
592   }
593 };
594
595 static const test_set_t tests_oriya = {
596   "utkalm.ttf", 0,
597   {
598     { "",
599       { 0xb15, 0xb4d, 0xb24, 0xb4d, 0xb30, 0 },
600       { 0x150, 0x125, 0 }
601     },
602     { "",
603       { 0xb24, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0 },
604       { 0x151, 0x120, 0 }
605     },
606     { "",
607       { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0 },
608       { 0x152, 0x120, 0 }
609     },
610     { "",
611       { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0 },
612       { 0x152, 0x120, 0 }
613     },
614     { "",
615       { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0 },
616       { 0x176, 0 }
617     },
618     { "",
619       { 0xb38, 0xb4d, 0xb24, 0xb4d, 0xb30, 0 },
620       { 0x177, 0 }
621     },
622     { "",
623       { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0xb4d, 0xb2f, 0 },
624       { 0x176, 0x124, 0 }
625     },
626     {{0}}
627   }
628 };
629
630 static const test_set_t tests_tamil = {
631   "akruti1.ttf", 0,
632   {
633     { "",
634       { 0x0b95, 0x0bc2, 0 },
635       { 0x004e, 0 }
636     },
637     { "",
638       { 0x0bae, 0x0bc2, 0 },
639       { 0x009e, 0 }
640     },
641     { "",
642       { 0x0b9a, 0x0bc2, 0 },
643       { 0x0058, 0 }
644     },
645     { "",
646       { 0x0b99, 0x0bc2, 0 },
647       { 0x0053, 0 }
648     },
649     { "",
650       { 0x0bb0, 0x0bc2, 0 },
651       { 0x00a8, 0 }
652     },
653     { "",
654       { 0x0ba4, 0x0bc2, 0 },
655       { 0x008e, 0 }
656     },
657     { "",
658       { 0x0b9f, 0x0bc2, 0 },
659       { 0x0062, 0 }
660     },
661     { "",
662       { 0x0b95, 0x0bc6, 0 },
663       { 0x000a, 0x0031, 0 }
664     },
665     { "",
666       { 0x0b95, 0x0bca, 0 },
667       { 0x000a, 0x0031, 0x0007, 0 }
668     },
669     { "",
670       { 0x0b95, 0x0bc6, 0x0bbe, 0 },
671       { 0x000a, 0x0031, 0x007, 0 }
672     },
673     { "",
674       { 0x0b95, 0x0bcd, 0x0bb7, 0 },
675       { 0x0049, 0 }
676     },
677     { "",
678       { 0x0b95, 0x0bcd, 0x0bb7, 0x0bca, 0 },
679       { 0x000a, 0x0049, 0x007, 0 }
680     },
681     { "",
682       { 0x0b95, 0x0bcd, 0x0bb7, 0x0bc6, 0x0bbe, 0 },
683       { 0x000a, 0x0049, 0x007, 0 }
684     },
685     { "",
686       { 0x0b9f, 0x0bbf, 0 },
687       { 0x005f, 0 }
688     },
689     { "",
690       { 0x0b9f, 0x0bc0, 0 },
691       { 0x0060, 0 }
692     },
693     { "",
694       { 0x0bb2, 0x0bc0, 0 },
695       { 0x00ab, 0 }
696     },
697     { "",
698       { 0x0bb2, 0x0bbf, 0 },
699       { 0x00aa, 0 }
700     },
701     { "",
702       { 0x0bb0, 0x0bcd, 0 },
703       { 0x00a4, 0 }
704     },
705     { "",
706       { 0x0bb0, 0x0bbf, 0 },
707       { 0x00a5, 0 }
708     },
709     { "",
710       { 0x0bb0, 0x0bc0, 0 },
711       { 0x00a6, 0 }
712     },
713     { "",
714       { 0x0b83, 0 },
715       { 0x0025, 0 }
716     },
717     { "",
718       { 0x0b83, 0x0b95, 0 },
719       { 0x0025, 0x0031, 0 }
720     },
721     {{0}}
722   }
723 };
724
725 static const test_set_t tests_telugu = {
726   "Pothana2000.ttf", 0,
727   {
728     { "",
729       { 0xc15, 0xc4d, 0 },
730       { 0xbb, 0 }
731     },
732     { "",
733       { 0xc15, 0xc4d, 0xc37, 0 },
734       { 0x4b, 0 }
735     },
736     { "",
737       { 0xc15, 0xc4d, 0xc37, 0xc4d, 0 },
738       { 0xe0, 0 }
739     },
740     { "",
741       { 0xc15, 0xc4d, 0xc37, 0xc4d, 0xc23, 0 },
742       { 0x4b, 0x91, 0 }
743     },
744     { "",
745       { 0xc15, 0xc4d, 0xc30, 0 },
746       { 0x5a, 0xb2, 0 }
747     },
748     { "",
749       { 0xc15, 0xc4d, 0xc30, 0xc4d, 0 },
750       { 0xbb, 0xb2, 0 }
751     },
752     { "",
753       { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0 },
754       { 0x5a, 0xb2, 0x83, 0 }
755     },
756     { "",
757       { 0xc15, 0xc4d, 0xc30, 0xc3f, 0 },
758       { 0xe2, 0xb2, 0 }
759     },
760     { "",
761       { 0xc15, 0xc4d, 0xc15, 0xc48, 0 },
762       { 0xe6, 0xb3, 0x83, 0 }
763     },
764     { "",
765       { 0xc15, 0xc4d, 0xc30, 0xc48, 0 },
766       { 0xe6, 0xb3, 0x9f, 0 }
767     },
768     { "",
769       { 0xc15, 0xc46, 0xc56, 0 },
770       { 0xe6, 0xb3, 0 }
771     },
772     {{0}}
773   }
774 };
775
776 static const test_set_t tests_kannada_1 = {
777   "Sampige.ttf", 0,
778   {
779     { "",
780       { 0x0ca8, 0x0ccd, 0x0ca8, 0 },
781       { 0x0049, 0x00ba, 0 }
782     },
783     { "",
784       { 0x0ca8, 0x0ccd, 0x0ca1, 0 },
785       { 0x0049, 0x00b3, 0 }
786     },
787     { "",
788       { 0x0caf, 0x0cc2, 0 },
789       { 0x004f, 0x005d, 0 }
790     },
791     { "",
792       { 0x0ce0, 0 },
793       { 0x006a, 0 }
794     },
795     { "",
796       { 0x0ce6, 0x0ce7, 0x0ce8, 0 },
797       { 0x006b, 0x006c, 0x006d, 0 }
798     },
799     { "",
800       { 0x0cb5, 0x0ccb, 0 },
801       { 0x015f, 0x0067, 0 }
802     },
803     { "",
804       { 0x0cb0, 0x0ccd, 0x0cae, 0 },
805       { 0x004e, 0x0082, 0 }
806     },
807     { "",
808       { 0x0cb0, 0x0ccd, 0x0c95, 0 },
809       { 0x0036, 0x0082, 0 }
810     },
811     { "",
812       { 0x0c95, 0x0ccd, 0x0cb0, 0 },
813       { 0x0036, 0x00c1, 0 }
814     },
815     { "",
816       { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0 },
817       { 0x0050, 0x00a7, 0 }
818     },
819     {{0}}
820   }
821 };
822
823 static const test_set_t tests_kannada_2 = {
824   "tunga.ttf", 0,
825   {
826     { "",
827       { 0x0cb7, 0x0cc6, 0 },
828       { 0x00b0, 0x006c, 0 }
829     },
830     { "",
831       { 0x0cb7, 0x0ccd, 0 },
832       { 0x0163, 0 }
833     },
834     { "",
835       { 0xc95, 0xcbf, 0xcd5, 0 },
836       { 0x114, 0x73, 0 }
837     },
838     { "",
839       { 0xc95, 0xcc6, 0xcd5, 0 },
840       { 0x90, 0x6c, 0x73, 0 }
841     },
842     { "",
843       { 0xc95, 0xcc6, 0xcd6, 0 },
844       { 0x90, 0x6c, 0x74, 0 }
845     },
846     { "",
847       { 0xc95, 0xcc6, 0xcc2, 0 },
848       { 0x90, 0x6c, 0x69, 0 }
849     },
850     { "",
851       { 0xc95, 0xcca, 0xcd5, 0 },
852       { 0x90, 0x6c, 0x69, 0x73, 0 }
853     },
854     {{0}}
855   }
856 };
857
858 static const test_set_t tests_malayalam_1 = {
859   "AkrutiMal2Normal.ttf", 0,
860   {
861     { "",
862       { 0x0d15, 0x0d46, 0 },
863       { 0x005e, 0x0034, 0 }
864     },
865     { "",
866       { 0x0d15, 0x0d47, 0 },
867       { 0x005f, 0x0034, 0 }
868     },
869     { "",
870       { 0x0d15, 0x0d4b, 0 },
871       { 0x005f, 0x0034, 0x0058, 0 }
872     },
873     { "",
874       { 0x0d15, 0x0d48, 0 },
875       { 0x0060, 0x0034, 0 }
876     },
877     { "",
878       { 0x0d15, 0x0d4a, 0 },
879       { 0x005e, 0x0034, 0x0058, 0 }
880     },
881     { "",
882       { 0x0d30, 0x0d4d, 0x0d15, 0 },
883       { 0x009e, 0x0034, 0 }
884     },
885     { "",
886       { 0x0d15, 0x0d4d, 0x0d35, 0 },
887       { 0x0034, 0x007a, 0 }
888     },
889     { "",
890       { 0x0d15, 0x0d4d, 0x0d2f, 0 },
891       { 0x0034, 0x00a2, 0 }
892     },
893     { "",
894       { 0x0d1f, 0x0d4d, 0x0d1f, 0 },
895       { 0x0069, 0 }
896     },
897     { "",
898       { 0x0d26, 0x0d4d, 0x0d26, 0 },
899       { 0x0074, 0 }
900     },
901     { "",
902       { 0x0d30, 0x0d4d, 0 },
903       { 0x009e, 0 }
904     },
905     { "",
906       { 0x0d30, 0x0d4d, 0x200c, 0 },
907       { 0x009e, 0 }
908     },
909     { "",
910       { 0x0d30, 0x0d4d, 0x200d, 0 },
911       { 0x009e, 0 }
912     },
913     { "",
914       { 0xd15, 0xd46, 0xd3e, 0 },
915       { 0x5e, 0x34, 0x58, 0 }
916     },
917     { "",
918       { 0xd15, 0xd47, 0xd3e, 0 },
919       { 0x5f, 0x34, 0x58, 0 }
920     },
921     { "",
922       { 0xd15, 0xd46, 0xd57, 0 },
923       { 0x5e, 0x34, 0x65, 0 }
924     },
925     { "",
926       { 0xd15, 0xd57, 0 },
927       { 0x34, 0x65, 0 }
928     },
929     { "",
930       { 0xd1f, 0xd4d, 0xd1f, 0xd41, 0xd4d, 0 },
931       { 0x69, 0x5b, 0x64, 0 }
932     },
933
934     {{0}}
935   }
936 };
937
938 static const test_set_t tests_malayalam_2 = {
939   "Rachana.ttf", 0,
940   {
941     { "",
942       { 0xd37, 0xd4d, 0xd1f, 0xd4d, 0xd30, 0xd40, 0 },
943       { 0x385, 0xa3, 0 }
944     },
945     { "",
946       { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0 },
947       { 0x2ff, 0 }
948     },
949     { "",
950       { 0xd33, 0xd4d, 0xd33, 0 },
951       { 0x3f8, 0 }
952     },
953     { "",
954       { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0 },
955       { 0x2ff, 0 }
956     },
957     { "",
958       { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0 },
959       { 0xf3, 0x350, 0 }
960     },
961
962     {{0}}
963   }
964 };
965
966 static const test_set_t tests_sinhala = {
967   "FM-MalithiUW46.ttf", 0,
968   {
969     { "",
970       { 0xd9a, 0xdd9, 0xdcf, 0 },
971       { 0x4a, 0x61, 0x42, 0 }
972     },
973     { "",
974       { 0xd9a, 0xdd9, 0xddf, 0 },
975       { 0x4a, 0x61, 0x50, 0 }
976     },
977     { "",
978       { 0xd9a, 0xdd9, 0xdca, 0 },
979       { 0x4a, 0x62, 0 }
980     },
981     { "",
982       { 0xd9a, 0xddc, 0xdca, 0 },
983       { 0x4a, 0x61, 0x42, 0x41, 0 }
984     },
985     { "",
986       { 0xd9a, 0xdda, 0 },
987       { 0x4a, 0x62, 0 }
988     },
989     { "",
990       { 0xd9a, 0xddd, 0 },
991       { 0x4a, 0x61, 0x42, 0x41, 0 }
992     },
993     {{0}}
994   }
995 };
996
997 static const test_set_t tests_khmer = {
998   "KhmerOS.ttf", 0,
999   {
1000     { "",
1001       { 0x179a, 0x17cd, 0 },
1002       { 0x24c, 0x27f, 0 }
1003     },
1004     { "",
1005       { 0x179f, 0x17c5, 0 },
1006       { 0x273, 0x203, 0 }
1007     },
1008     { "",
1009       { 0x1790, 0x17d2, 0x1784, 0x17c3, 0 },
1010       { 0x275, 0x242, 0x182, 0 }
1011     },
1012     { "",
1013       { 0x179a, 0 },
1014       { 0x24c, 0 }
1015     },
1016     { "",
1017       { 0x1781, 0x17d2, 0x1798, 0x17c2, 0 },
1018       { 0x274, 0x233, 0x197, 0 }
1019     },
1020     { "",
1021       { 0x1798, 0x17b6, 0 },
1022       { 0x1cb, 0 }
1023     },
1024     { "",
1025       { 0x179a, 0x17b8, 0 },
1026       { 0x24c, 0x26a, 0 }
1027     },
1028     { "",
1029       { 0x1787, 0x17b6, 0 },
1030       { 0x1ba, 0 }
1031     },
1032     { "",
1033       { 0x1798, 0x17d2, 0x1796, 0x17bb, 0 },
1034       { 0x24a, 0x195, 0x26d, 0 }
1035     },
1036     {{0}}
1037   }
1038 };
1039
1040 static const test_set_t tests_nko = {
1041   "DejaVuSans.ttf", 0,
1042   {
1043     { "",
1044       { 0x7ca, 0 },
1045       { 0x5c1, 0 }
1046     },
1047     { "",
1048       { 0x7ca, 0x7ca, 0 },
1049       { 0x14db, 0x14d9, 0 }
1050     },
1051     { "",
1052       { 0x7ca, 0x7fa, 0x7ca, 0 },
1053       { 0x14db, 0x5ec, 0x14d9, 0 }
1054     },
1055     { "",
1056       { 0x7ca, 0x7f3, 0x7ca, 0 },
1057       { 0x14db, 0x5e7, 0x14d9, 0 }
1058     },
1059     { "",
1060       { 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0 },
1061       { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0 }
1062     },
1063     {{0}}
1064   }
1065 };
1066
1067 static const test_set_t tests_linearb = {
1068   "penuture.ttf", 0,
1069   {
1070     { "",
1071       { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03,  0 },
1072       { 0x5, 0x6, 0x7, 0 },
1073     },
1074     {{0}}
1075   }
1076 };
1077
1078
1079
1080 typedef struct {
1081   FT_Library ft_library;
1082   FT_Face ft_face;
1083   hb_font_t *font;
1084 } ft_fixture_t;
1085
1086 static void
1087 ft_fixture_init (ft_fixture_t *f, gconstpointer user_data)
1088 {
1089   const test_set_t *test = user_data;
1090   char *font_file = g_strdup_printf ("%s/fonts/%s", srcdir (), test->font_file);
1091
1092   FT_Init_FreeType (&f->ft_library);
1093
1094   if (FT_New_Face (f->ft_library, font_file, test->face_index, &f->ft_face))
1095     g_test_message ("Font file %s not found.  Skipping test.", font_file);
1096   else
1097     f->font = hb_ft_font_create (f->ft_face, NULL);
1098
1099   g_free (font_file);
1100 }
1101
1102 static void
1103 ft_fixture_finish (ft_fixture_t *f, gconstpointer user_data)
1104 {
1105   hb_font_destroy (f->font);
1106
1107   FT_Done_Face (f->ft_face);
1108   FT_Done_FreeType (f->ft_library);
1109 }
1110
1111 static void
1112 test_shape_complex (ft_fixture_t *f, gconstpointer user_data)
1113 {
1114   const test_set_t *test_set = user_data;
1115   const test_t *test;
1116
1117   if (!f->font)
1118     return; /* Skip test */
1119
1120   for (test = test_set->tests; test->characters[0]; test++) {
1121     hb_buffer_t *buffer;
1122     unsigned int i, len, expected_len;
1123     hb_glyph_info_t *glyphs;
1124
1125     if (test->comments[0])
1126       g_test_message ("Test comments: %s", test->comments);
1127
1128     buffer =  hb_buffer_create (0);
1129     for (len = 0; test->characters[len]; len++) ;
1130     hb_buffer_add_utf32 (buffer, test->characters, len, 0, len);
1131
1132     hb_shape (f->font, buffer, NULL, 0);
1133
1134     for (len = 0; test->glyphs[len]; len++) ;
1135     expected_len = len;
1136
1137     glyphs = hb_buffer_get_glyph_infos (buffer, &len);
1138     g_assert_cmpint (len, ==, expected_len);
1139     for (i = 0; i < len; i++)
1140       g_assert_cmphex (glyphs[i].codepoint, ==, test->glyphs[i]);
1141
1142     hb_buffer_destroy (buffer);
1143   }
1144 }
1145
1146
1147
1148
1149 int
1150 main (int argc, char **argv)
1151 {
1152   hb_test_init (&argc, &argv);
1153
1154 #define TEST_SET(name) hb_test_add_fixture_flavor (ft_fixture, (const void *) &tests_##name, #name, test_shape_complex)
1155
1156   TEST_SET (greek);
1157
1158   TEST_SET (devanagari_1);
1159   TEST_SET (devanagari_2);
1160   TEST_SET (bengali_1);
1161   TEST_SET (bengali_2);
1162   TEST_SET (bengali_3);
1163   TEST_SET (gurmukhi);
1164   TEST_SET (oriya);
1165   TEST_SET (tamil);
1166   TEST_SET (telugu);
1167   TEST_SET (kannada_1);
1168   TEST_SET (kannada_2);
1169   TEST_SET (malayalam_1);
1170   TEST_SET (malayalam_2);
1171   TEST_SET (sinhala);
1172
1173   TEST_SET (khmer);
1174
1175   TEST_SET (nko);
1176   TEST_SET (linearb);
1177
1178   return hb_test_run();
1179 }