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