By moving the call to Load() up in SearchProvider::Start(), we are giving a chance...
[chromium-blink-merge.git] / third_party / harfbuzz / tests / shaping / main.cpp
blob28f8e07ea80264209616b7dce981349c078e0cfd
1 /*
2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * This is part of HarfBuzz, an OpenType Layout engine library.
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25 #include <QtTest/QtTest>
27 #include <ft2build.h>
28 #include FT_FREETYPE_H
29 #include FT_TRUETYPE_TABLES_H
31 #include <harfbuzz-shaper.h>
32 #include <harfbuzz-global.h>
33 #include <harfbuzz-gpos.h>
35 static FT_Library freetype;
37 static FT_Face loadFace(const char *name)
39 FT_Face face;
40 char path[256];
42 strcpy(path, SRCDIR);
43 strcat(path, "/fonts/");
44 strcat(path, name);
46 if (FT_New_Face(freetype, path, /*index*/0, &face))
47 return 0;
48 return face;
51 static HB_UChar32 getChar(const HB_UChar16 *string, hb_uint32 length, hb_uint32 &i)
53 HB_UChar32 ch;
54 if (HB_IsHighSurrogate(string[i])
55 && i < length - 1
56 && HB_IsLowSurrogate(string[i + 1])) {
57 ch = HB_SurrogateToUcs4(string[i], string[i + 1]);
58 ++i;
59 } else {
60 ch = string[i];
62 return ch;
65 static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool /*rightToLeft*/)
67 FT_Face face = (FT_Face)font->userData;
68 if (length > *numGlyphs)
69 return false;
71 int glyph_pos = 0;
72 for (hb_uint32 i = 0; i < length; ++i) {
73 glyphs[glyph_pos] = FT_Get_Char_Index(face, getChar(string, length, i));
74 ++glyph_pos;
77 *numGlyphs = glyph_pos;
79 return true;
82 static void hb_getAdvances(HB_Font /*font*/, const HB_Glyph * /*glyphs*/, hb_uint32 numGlyphs, HB_Fixed *advances, int /*flags*/)
84 for (hb_uint32 i = 0; i < numGlyphs; ++i)
85 advances[i] = 0; // ### not tested right now
88 static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 length)
90 FT_Face face = (FT_Face)font->userData;
92 for (hb_uint32 i = 0; i < length; ++i)
93 if (!FT_Get_Char_Index(face, getChar(string, length, i)))
94 return false;
96 return true;
99 static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
101 FT_Face face = (FT_Face)font;
102 FT_ULong ftlen = *length;
103 FT_Error error = 0;
105 if (!FT_IS_SFNT(face))
106 return HB_Err_Invalid_Argument;
108 error = FT_Load_Sfnt_Table(face, tableTag, 0, buffer, &ftlen);
109 *length = ftlen;
110 return (HB_Error)error;
113 HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
115 HB_Error error = HB_Err_Ok;
116 FT_Face face = (FT_Face)font->userData;
118 int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
120 if ((error = (HB_Error)FT_Load_Glyph(face, glyph, load_flags)))
121 return error;
123 if (face->glyph->format != ft_glyph_format_outline)
124 return (HB_Error)HB_Err_Invalid_SubTable;
126 *nPoints = face->glyph->outline.n_points;
127 if (!(*nPoints))
128 return HB_Err_Ok;
130 if (point > *nPoints)
131 return (HB_Error)HB_Err_Invalid_SubTable;
133 *xpos = face->glyph->outline.points[point].x;
134 *ypos = face->glyph->outline.points[point].y;
136 return HB_Err_Ok;
139 void hb_getGlyphMetrics(HB_Font, HB_Glyph, HB_GlyphMetrics *metrics)
141 // ###
142 metrics->x = metrics->y = metrics->width = metrics->height = metrics->xOffset = metrics->yOffset = 0;
145 HB_Fixed hb_getFontMetric(HB_Font, HB_FontMetric )
147 return 0; // ####
150 const HB_FontClass hb_fontClass = {
151 hb_stringToGlyphs, hb_getAdvances, hb_canRender,
152 hb_getPointInOutline, hb_getGlyphMetrics, hb_getFontMetric
156 //TESTED_CLASS=
157 //TESTED_FILES= gui/text/qscriptengine.cpp
159 class tst_QScriptEngine : public QObject
161 Q_OBJECT
163 public:
164 tst_QScriptEngine();
165 virtual ~tst_QScriptEngine();
168 public slots:
169 void initTestCase();
170 void cleanupTestCase();
171 private slots:
172 void greek();
174 void devanagari();
175 void bengali();
176 void gurmukhi();
177 // gujarati missing
178 void oriya();
179 void tamil();
180 void telugu();
181 void kannada();
182 void malayalam();
183 void sinhala();
185 void khmer();
186 void nko();
187 void linearB();
190 tst_QScriptEngine::tst_QScriptEngine()
194 tst_QScriptEngine::~tst_QScriptEngine()
198 void tst_QScriptEngine::initTestCase()
200 FT_Init_FreeType(&freetype);
203 void tst_QScriptEngine::cleanupTestCase()
205 FT_Done_FreeType(freetype);
208 class Shaper
210 public:
211 Shaper(FT_Face face, HB_Script script, const QString &str);
213 HB_FontRec hbFont;
214 HB_ShaperItem shaper_item;
215 QVarLengthArray<HB_Glyph> hb_glyphs;
216 QVarLengthArray<HB_GlyphAttributes> hb_attributes;
217 QVarLengthArray<HB_Fixed> hb_advances;
218 QVarLengthArray<HB_FixedPoint> hb_offsets;
219 QVarLengthArray<unsigned short> hb_logClusters;
223 Shaper::Shaper(FT_Face face, HB_Script script, const QString &str)
225 HB_Face hbFace = HB_NewFace(face, hb_getSFntTable);
227 hbFont.klass = &hb_fontClass;
228 hbFont.userData = face;
229 hbFont.x_ppem = face->size->metrics.x_ppem;
230 hbFont.y_ppem = face->size->metrics.y_ppem;
231 hbFont.x_scale = face->size->metrics.x_scale;
232 hbFont.y_scale = face->size->metrics.y_scale;
234 shaper_item.kerning_applied = false;
235 shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData());
236 shaper_item.stringLength = str.length();
237 shaper_item.item.script = script;
238 shaper_item.item.pos = 0;
239 shaper_item.item.length = shaper_item.stringLength;
240 shaper_item.item.bidiLevel = 0; // ###
241 shaper_item.shaperFlags = 0;
242 shaper_item.font = &hbFont;
243 shaper_item.face = hbFace;
244 shaper_item.num_glyphs = shaper_item.item.length;
245 shaper_item.glyphIndicesPresent = false;
246 shaper_item.initialGlyphCount = 0;
249 while (1) {
250 hb_glyphs.resize(shaper_item.num_glyphs);
251 hb_attributes.resize(shaper_item.num_glyphs);
252 hb_advances.resize(shaper_item.num_glyphs);
253 hb_offsets.resize(shaper_item.num_glyphs);
254 hb_logClusters.resize(shaper_item.num_glyphs);
256 memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph));
257 memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAttributes));
258 memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed));
259 memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint));
261 shaper_item.glyphs = hb_glyphs.data();
262 shaper_item.attributes = hb_attributes.data();
263 shaper_item.advances = hb_advances.data();
264 shaper_item.offsets = hb_offsets.data();
265 shaper_item.log_clusters = hb_logClusters.data();
267 if (HB_ShapeItem(&shaper_item))
268 break;
271 HB_FreeFace(hbFace);
275 static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
277 QString uc = QString().append(ch);
278 Shaper shaper(face, script, uc);
280 uc = uc.normalized(QString::NormalizationForm_D);
281 Shaper decomposed(face, script, uc);
283 if( shaper.shaper_item.num_glyphs != decomposed.shaper_item.num_glyphs )
284 goto error;
286 for (unsigned int i = 0; i < shaper.shaper_item.num_glyphs; ++i) {
287 if ((shaper.shaper_item.glyphs[i]&0xffffff) != (decomposed.shaper_item.glyphs[i]&0xffffff))
288 goto error;
290 return true;
291 error:
292 QString str = "";
293 int i = 0;
294 while (i < uc.length()) {
295 str += QString("%1 ").arg(uc[i].unicode(), 4, 16);
296 ++i;
298 qDebug("%s: decomposedShaping of char %4x failed\n decomposedString: %s\n nglyphs=%d, decomposed nglyphs %d",
299 face->family_name,
300 ch.unicode(), str.toLatin1().data(),
301 shaper.shaper_item.num_glyphs,
302 decomposed.shaper_item.num_glyphs);
304 str = "";
305 i = 0;
306 while (i < shaper.shaper_item.num_glyphs) {
307 str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
308 ++i;
310 qDebug(" composed glyph result = %s", str.toLatin1().constData());
311 str = "";
312 i = 0;
313 while (i < decomposed.shaper_item.num_glyphs) {
314 str += QString("%1 ").arg(decomposed.shaper_item.glyphs[i], 4, 16);
315 ++i;
317 qDebug(" decomposed glyph result = %s", str.toLatin1().constData());
318 return false;
321 struct ShapeTable {
322 unsigned short unicode[16];
323 unsigned short glyphs[16];
326 static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script)
328 Shaper shaper(face, script, QString::fromUtf16( s->unicode ));
330 hb_uint32 nglyphs = 0;
331 const unsigned short *g = s->glyphs;
332 while ( *g ) {
333 nglyphs++;
334 g++;
337 if( nglyphs != shaper.shaper_item.num_glyphs )
338 goto error;
340 for (hb_uint32 i = 0; i < nglyphs; ++i) {
341 if ((shaper.shaper_item.glyphs[i]&0xffffff) != s->glyphs[i])
342 goto error;
344 return true;
345 error:
346 QString str = "";
347 const unsigned short *uc = s->unicode;
348 while (*uc) {
349 str += QString("%1 ").arg(*uc, 4, 16);
350 ++uc;
352 qDebug("%s: shaping of string %s failed, nglyphs=%d, expected %d",
353 face->family_name,
354 str.toLatin1().constData(),
355 shaper.shaper_item.num_glyphs, nglyphs);
357 str = "";
358 hb_uint32 i = 0;
359 while (i < shaper.shaper_item.num_glyphs) {
360 str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
361 ++i;
363 qDebug(" glyph result = %s", str.toLatin1().constData());
364 return false;
368 void tst_QScriptEngine::greek()
370 FT_Face face = loadFace("DejaVuSans.ttf");
371 if (face) {
372 for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
373 QString str;
374 str.append(uc);
375 if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
376 //qDebug() << "skipping" << hex << uc;
377 continue;
379 if (uc == 0x1fc1 || uc == 0x1fed)
380 continue;
381 QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
383 FT_Done_Face(face);
384 } else {
385 QSKIP("couln't find DejaVu Sans", SkipAll);
389 face = loadFace("SBL_grk.ttf");
390 if (face) {
391 for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
392 QString str;
393 str.append(uc);
394 if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
395 //qDebug() << "skipping" << hex << uc;
396 continue;
398 if (uc == 0x1fc1 || uc == 0x1fed)
399 continue;
400 QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
404 const ShapeTable shape_table [] = {
405 { { 0x3b1, 0x300, 0x313, 0x0 },
406 { 0xb8, 0x3d3, 0x3c7, 0x0 } },
407 { { 0x3b1, 0x313, 0x300, 0x0 },
408 { 0xd4, 0x0 } },
410 { {0}, {0} }
414 const ShapeTable *s = shape_table;
415 while (s->unicode[0]) {
416 QVERIFY( shaping(face, s, HB_Script_Greek) );
417 ++s;
420 FT_Done_Face(face);
421 } else {
422 QSKIP("couln't find DejaVu Sans", SkipAll);
427 void tst_QScriptEngine::devanagari()
430 FT_Face face = loadFace("raghu.ttf");
431 if (face) {
432 const ShapeTable shape_table [] = {
433 // Ka
434 { { 0x0915, 0x0 },
435 { 0x0080, 0x0 } },
436 // Ka Halant
437 { { 0x0915, 0x094d, 0x0 },
438 { 0x0080, 0x0051, 0x0 } },
439 // Ka Halant Ka
440 { { 0x0915, 0x094d, 0x0915, 0x0 },
441 { 0x00c8, 0x0080, 0x0 } },
442 // Ka MatraI
443 { { 0x0915, 0x093f, 0x0 },
444 { 0x01d1, 0x0080, 0x0 } },
445 // Ra Halant Ka
446 { { 0x0930, 0x094d, 0x0915, 0x0 },
447 { 0x0080, 0x005b, 0x0 } },
448 // Ra Halant Ka MatraI
449 { { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
450 { 0x01d1, 0x0080, 0x005b, 0x0 } },
451 // MatraI
452 { { 0x093f, 0x0 },
453 { 0x01d4, 0x029c, 0x0 } },
454 // Ka Nukta
455 { { 0x0915, 0x093c, 0x0 },
456 { 0x00a4, 0x0 } },
457 // Ka Halant Ra
458 { { 0x0915, 0x094d, 0x0930, 0x0 },
459 { 0x0110, 0x0 } },
460 // Ka Halant Ra Halant Ka
461 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
462 { 0x0158, 0x0080, 0x0 } },
463 { { 0x0930, 0x094d, 0x200d, 0x0 },
464 { 0x00e2, 0x0 } },
465 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x200d, 0x0 },
466 { 0x0158, 0x0 } },
468 { {0}, {0} }
472 const ShapeTable *s = shape_table;
473 while (s->unicode[0]) {
474 QVERIFY( shaping(face, s, HB_Script_Devanagari) );
475 ++s;
478 FT_Done_Face(face);
479 } else {
480 QSKIP("couln't find raghu.ttf", SkipAll);
485 FT_Face face = loadFace("mangal.ttf");
486 if (face) {
487 const ShapeTable shape_table [] = {
488 // Ka
489 { { 0x0915, 0x0 },
490 { 0x0080, 0x0 } },
491 // Ka Halant
492 { { 0x0915, 0x094d, 0x0 },
493 { 0x0080, 0x0051, 0x0 } },
494 // Ka Halant Ka
495 { { 0x0915, 0x094d, 0x0915, 0x0 },
496 { 0x00c8, 0x0080, 0x0 } },
497 // Ka MatraI
498 { { 0x0915, 0x093f, 0x0 },
499 { 0x01d1, 0x0080, 0x0 } },
500 // Ra Halant Ka
501 { { 0x0930, 0x094d, 0x0915, 0x0 },
502 { 0x0080, 0x005b, 0x0 } },
503 // Ra Halant Ka MatraI
504 { { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
505 { 0x01d1, 0x0080, 0x005b, 0x0 } },
506 // MatraI
507 { { 0x093f, 0x0 },
508 { 0x01d4, 0x029c, 0x0 } },
509 // Ka Nukta
510 { { 0x0915, 0x093c, 0x0 },
511 { 0x00a4, 0x0 } },
512 // Ka Halant Ra
513 { { 0x0915, 0x094d, 0x0930, 0x0 },
514 { 0x0110, 0x0 } },
515 // Ka Halant Ra Halant Ka
516 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
517 { 0x0158, 0x0080, 0x0 } },
519 { { 0x92b, 0x94d, 0x930, 0x0 },
520 { 0x125, 0x0 } },
521 { { 0x92b, 0x93c, 0x94d, 0x930, 0x0 },
522 { 0x149, 0x0 } },
523 { {0}, {0} }
526 const ShapeTable *s = shape_table;
527 while (s->unicode[0]) {
528 QVERIFY( shaping(face, s, HB_Script_Devanagari) );
529 ++s;
532 FT_Done_Face(face);
533 } else {
534 QSKIP("couldn't find mangal.ttf", SkipAll);
539 void tst_QScriptEngine::bengali()
542 FT_Face face = loadFace("AkaashNormal.ttf");
543 if (face) {
544 const ShapeTable shape_table [] = {
545 // Ka
546 { { 0x0995, 0x0 },
547 { 0x0151, 0x0 } },
548 // Ka Halant
549 { { 0x0995, 0x09cd, 0x0 },
550 { 0x0151, 0x017d, 0x0 } },
551 // Ka Halant Ka
552 { { 0x0995, 0x09cd, 0x0995, 0x0 },
553 { 0x019b, 0x0 } },
554 // Ka MatraI
555 { { 0x0995, 0x09bf, 0x0 },
556 { 0x0173, 0x0151, 0x0 } },
557 // Ra Halant Ka
558 { { 0x09b0, 0x09cd, 0x0995, 0x0 },
559 { 0x0151, 0x0276, 0x0 } },
560 // Ra Halant Ka MatraI
561 { { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
562 { 0x0173, 0x0151, 0x0276, 0x0 } },
563 // Ka Nukta
564 { { 0x0995, 0x09bc, 0x0 },
565 { 0x0151, 0x0171, 0x0 } },
566 // Ka Halant Ra
567 { { 0x0995, 0x09cd, 0x09b0, 0x0 },
568 { 0x01f4, 0x0 } },
569 // Ka Halant Ra Halant Ka
570 { { 0x0995, 0x09cd, 0x09b0, 0x09cd, 0x0995, 0x0 },
571 { 0x025c, 0x0276, 0x0151, 0x0 } },
572 // Ya + Halant
573 { { 0x09af, 0x09cd, 0x0 },
574 { 0x016a, 0x017d, 0x0 } },
575 // Da Halant Ya -> Da Ya-Phala
576 { { 0x09a6, 0x09cd, 0x09af, 0x0 },
577 { 0x01e5, 0x0 } },
578 // A Halant Ya -> A Ya-phala
579 { { 0x0985, 0x09cd, 0x09af, 0x0 },
580 { 0x0145, 0x01cf, 0x0 } },
581 // Na Halant Ka
582 { { 0x09a8, 0x09cd, 0x0995, 0x0 },
583 { 0x026f, 0x0151, 0x0 } },
584 // Na Halant ZWNJ Ka
585 { { 0x09a8, 0x09cd, 0x200c, 0x0995, 0x0 },
586 { 0x0164, 0x017d, 0x0151, 0x0 } },
587 // Na Halant ZWJ Ka
588 { { 0x09a8, 0x09cd, 0x200d, 0x0995, 0x0 },
589 { 0x026f, 0x0151, 0x0 } },
590 // Ka Halant ZWNJ Ka
591 { { 0x0995, 0x09cd, 0x200c, 0x0995, 0x0 },
592 { 0x0151, 0x017d, 0x0151, 0x0 } },
593 // Ka Halant ZWJ Ka
594 { { 0x0995, 0x09cd, 0x200d, 0x0995, 0x0 },
595 { 0x025c, 0x0151, 0x0 } },
596 // Na Halant Ra
597 { { 0x09a8, 0x09cd, 0x09b0, 0x0 },
598 { 0x0207, 0x0 } },
599 // Na Halant ZWNJ Ra
600 { { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
601 { 0x0164, 0x017d, 0x016b, 0x0 } },
602 // Na Halant ZWJ Ra
603 { { 0x09a8, 0x09cd, 0x200d, 0x09b0, 0x0 },
604 { 0x026f, 0x016b, 0x0 } },
605 // Na Halant Ba
606 { { 0x09a8, 0x09cd, 0x09ac, 0x0 },
607 { 0x022f, 0x0 } },
608 // Na Halant ZWNJ Ba
609 { { 0x09a8, 0x09cd, 0x200c, 0x09ac, 0x0 },
610 { 0x0164, 0x017d, 0x0167, 0x0 } },
611 // Na Halant ZWJ Ba
612 { { 0x09a8, 0x09cd, 0x200d, 0x09ac, 0x0 },
613 { 0x026f, 0x0167, 0x0 } },
614 // Na Halant Dha
615 { { 0x09a8, 0x09cd, 0x09a7, 0x0 },
616 { 0x01d3, 0x0 } },
617 // Na Halant ZWNJ Dha
618 { { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
619 { 0x0164, 0x017d, 0x0163, 0x0 } },
620 // Na Halant ZWJ Dha
621 { { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
622 { 0x026f, 0x0163, 0x0 } },
623 // Ra Halant Ka MatraAU
624 { { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 },
625 { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } },
626 // Ra Halant Ba Halant Ba
627 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
628 { 0x0232, 0x0276, 0x0 } },
629 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 },
630 { 0x151, 0x276, 0x172, 0x143, 0x0 } },
631 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 },
632 { 0x151, 0x276, 0x172, 0x144, 0x0 } },
633 // test decomposed two parts matras
634 { { 0x995, 0x9c7, 0x9be, 0x0 },
635 { 0x179, 0x151, 0x172, 0x0 } },
636 { { 0x995, 0x9c7, 0x9d7, 0x0 },
637 { 0x179, 0x151, 0x17e, 0x0 } },
638 { { 0x9b0, 0x9cd, 0x9ad, 0x0 },
639 { 0x168, 0x276, 0x0 } },
640 { { 0x9f0, 0x9cd, 0x9ad, 0x0 },
641 { 0x168, 0x276, 0x0 } },
642 { { 0x9f1, 0x9cd, 0x9ad, 0x0 },
643 { 0x191, 0x17d, 0x168, 0x0 } },
645 { {0}, {0} }
649 const ShapeTable *s = shape_table;
650 while (s->unicode[0]) {
651 QVERIFY( shaping(face, s, HB_Script_Bengali) );
652 ++s;
655 FT_Done_Face(face);
656 } else {
657 QSKIP("couln't find AkaashNormal.ttf", SkipAll);
661 FT_Face face = loadFace("MuktiNarrow.ttf");
662 if (face) {
663 const ShapeTable shape_table [] = {
664 // Ka
665 { { 0x0995, 0x0 },
666 { 0x0073, 0x0 } },
667 // Ka Halant
668 { { 0x0995, 0x09cd, 0x0 },
669 { 0x00b9, 0x0 } },
670 // Ka Halant Ka
671 { { 0x0995, 0x09cd, 0x0995, 0x0 },
672 { 0x0109, 0x0 } },
673 // Ka MatraI
674 { { 0x0995, 0x09bf, 0x0 },
675 { 0x0095, 0x0073, 0x0 } },
676 // Ra Halant Ka
677 { { 0x09b0, 0x09cd, 0x0995, 0x0 },
678 { 0x0073, 0x00e1, 0x0 } },
679 // Ra Halant Ka MatraI
680 { { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
681 { 0x0095, 0x0073, 0x00e1, 0x0 } },
682 // MatraI
683 { { 0x09bf, 0x0 },
684 { 0x0095, 0x01c8, 0x0 } },
685 // Ka Nukta
686 { { 0x0995, 0x09bc, 0x0 },
687 { 0x0073, 0x0093, 0x0 } },
688 // Ka Halant Ra
689 { { 0x0995, 0x09cd, 0x09b0, 0x0 },
690 { 0x00e5, 0x0 } },
691 // Ka Halant Ra Halant Ka
692 { { 0x995, 0x9cd, 0x9b0, 0x9cd, 0x995, 0x0 },
693 { 0x234, 0x24e, 0x73, 0x0 } },
694 // Ya + Halant
695 { { 0x09af, 0x09cd, 0x0 },
696 { 0x00d2, 0x0 } },
697 // Da Halant Ya -> Da Ya-Phala
698 { { 0x09a6, 0x09cd, 0x09af, 0x0 },
699 { 0x0084, 0x00e2, 0x0 } },
700 // A Halant Ya -> A Ya-phala
701 { { 0x0985, 0x09cd, 0x09af, 0x0 },
702 { 0x0067, 0x00e2, 0x0 } },
703 // Na Halant Ka
704 { { 0x09a8, 0x09cd, 0x0995, 0x0 },
705 { 0x0188, 0x0 } },
706 // Na Halant ZWNJ Ka
707 { { 0x9a8, 0x9cd, 0x200c, 0x995, 0x0 },
708 { 0xcc, 0x73, 0x0 } },
709 // Na Halant ZWJ Ka
710 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
711 { 0x247, 0x73, 0x0 } },
712 // Ka Halant ZWNJ Ka
713 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
714 { 0x247, 0x73, 0x0 } },
715 // Ka Halant ZWJ Ka
716 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
717 { 0x247, 0x73, 0x0 } },
718 // Na Halant Ra
719 { { 0x09a8, 0x09cd, 0x09b0, 0x0 },
720 { 0x00f8, 0x0 } },
721 // Na Halant ZWNJ Ra
722 { { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
723 { 0xcc, 0x8d, 0x0 } },
724 // Na Halant ZWJ Ra
725 { { 0x9a8, 0x9cd, 0x200d, 0x9b0, 0x0 },
726 { 0x247, 0x8d, 0x0 } },
727 // Na Halant Ba
728 { { 0x09a8, 0x09cd, 0x09ac, 0x0 },
729 { 0x0139, 0x0 } },
730 // Na Halant ZWNJ Ba
731 { { 0x9a8, 0x9cd, 0x200c, 0x9ac, 0x0 },
732 { 0xcc, 0x89, 0x0 } },
733 // Na Halant ZWJ Ba
734 { { 0x9a8, 0x9cd, 0x200d, 0x9ac, 0x0 },
735 { 0x247, 0x89, 0x0 } },
736 // Na Halant Dha
737 { { 0x09a8, 0x09cd, 0x09a7, 0x0 },
738 { 0x0145, 0x0 } },
739 // Na Halant ZWNJ Dha
740 { { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
741 { 0xcc, 0x85, 0x0 } },
742 // Na Halant ZWJ Dha
743 { { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
744 { 0x247, 0x85, 0x0 } },
745 // Ra Halant Ka MatraAU
746 { { 0x9b0, 0x9cd, 0x995, 0x9cc, 0x0 },
747 { 0x232, 0x73, 0xe1, 0xa0, 0x0 } },
748 // Ra Halant Ba Halant Ba
749 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
750 { 0x013b, 0x00e1, 0x0 } },
752 { {0}, {0} }
756 const ShapeTable *s = shape_table;
757 while (s->unicode[0]) {
758 QVERIFY( shaping(face, s, HB_Script_Bengali) );
759 ++s;
762 FT_Done_Face(face);
763 } else {
764 QSKIP("couln't find MuktiNarrow.ttf", SkipAll);
768 FT_Face face = loadFace("LikhanNormal.ttf");
769 if (face) {
770 const ShapeTable shape_table [] = {
771 { { 0x09a8, 0x09cd, 0x09af, 0x0 },
772 { 0x01ca, 0x0 } },
773 { { 0x09b8, 0x09cd, 0x09af, 0x0 },
774 { 0x020e, 0x0 } },
775 { { 0x09b6, 0x09cd, 0x09af, 0x0 },
776 { 0x01f4, 0x0 } },
777 { { 0x09b7, 0x09cd, 0x09af, 0x0 },
778 { 0x01fe, 0x0 } },
779 { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 },
780 { 0x10b, 0x167, 0x0 } },
781 { { 0x9b0, 0x9cd, 0x9ad, 0x0 },
782 { 0xa1, 0x167, 0x0 } },
783 { { 0x9f0, 0x9cd, 0x9ad, 0x0 },
784 { 0xa1, 0x167, 0x0 } },
785 { { 0x9f1, 0x9cd, 0x9ad, 0x0 },
786 { 0x11c, 0xa1, 0x0 } },
788 { {0}, {0} }
792 const ShapeTable *s = shape_table;
793 while (s->unicode[0]) {
794 QVERIFY( shaping(face, s, HB_Script_Bengali) );
795 ++s;
798 FT_Done_Face(face);
799 } else {
800 QSKIP("couln't find LikhanNormal.ttf", SkipAll);
805 void tst_QScriptEngine::gurmukhi()
808 FT_Face face = loadFace("lohit_pa.ttf");
809 if (face) {
810 const ShapeTable shape_table [] = {
811 { { 0xA15, 0xA4D, 0xa39, 0x0 },
812 { 0x3b, 0x8b, 0x0 } },
813 { {0}, {0} }
817 const ShapeTable *s = shape_table;
818 while (s->unicode[0]) {
819 QVERIFY( shaping(face, s, HB_Script_Gurmukhi) );
820 ++s;
823 FT_Done_Face(face);
824 } else {
825 QSKIP("couln't find lohit.punjabi.1.1.ttf", SkipAll);
830 void tst_QScriptEngine::oriya()
833 FT_Face face = loadFace("utkalm.ttf");
834 if (face) {
835 const ShapeTable shape_table [] = {
836 { { 0xb15, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
837 { 0x150, 0x125, 0x0 } },
838 { { 0xb24, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
839 { 0x151, 0x120, 0x0 } },
840 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
841 { 0x152, 0x120, 0x0 } },
842 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 },
843 { 0x152, 0x120, 0x0 } },
844 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
845 { 0x176, 0x0 } },
846 { { 0xb38, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 },
847 { 0x177, 0x0 } },
848 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0xb4d, 0xb2f, 0x0 },
849 { 0x176, 0x124, 0x0 } },
850 { {0}, {0} }
854 const ShapeTable *s = shape_table;
855 while (s->unicode[0]) {
856 QVERIFY( shaping(face, s, HB_Script_Oriya) );
857 ++s;
860 FT_Done_Face(face);
861 } else {
862 QSKIP("couln't find utkalm.ttf", SkipAll);
868 void tst_QScriptEngine::tamil()
871 FT_Face face = loadFace("akruti1.ttf");
872 if (face) {
873 const ShapeTable shape_table [] = {
874 { { 0x0b95, 0x0bc2, 0x0 },
875 { 0x004e, 0x0 } },
876 { { 0x0bae, 0x0bc2, 0x0 },
877 { 0x009e, 0x0 } },
878 { { 0x0b9a, 0x0bc2, 0x0 },
879 { 0x0058, 0x0 } },
880 { { 0x0b99, 0x0bc2, 0x0 },
881 { 0x0053, 0x0 } },
882 { { 0x0bb0, 0x0bc2, 0x0 },
883 { 0x00a8, 0x0 } },
884 { { 0x0ba4, 0x0bc2, 0x0 },
885 { 0x008e, 0x0 } },
886 { { 0x0b9f, 0x0bc2, 0x0 },
887 { 0x0062, 0x0 } },
888 { { 0x0b95, 0x0bc6, 0x0 },
889 { 0x000a, 0x0031, 0x0 } },
890 { { 0x0b95, 0x0bca, 0x0 },
891 { 0x000a, 0x0031, 0x0007, 0x0 } },
892 { { 0x0b95, 0x0bc6, 0x0bbe, 0x0 },
893 { 0x000a, 0x0031, 0x007, 0x0 } },
894 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0 },
895 { 0x0049, 0x0 } },
896 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0bca, 0x0 },
897 { 0x000a, 0x0049, 0x007, 0x0 } },
898 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0bc6, 0x0bbe, 0x0 },
899 { 0x000a, 0x0049, 0x007, 0x0 } },
900 { { 0x0b9f, 0x0bbf, 0x0 },
901 { 0x005f, 0x0 } },
902 { { 0x0b9f, 0x0bc0, 0x0 },
903 { 0x0060, 0x0 } },
904 { { 0x0bb2, 0x0bc0, 0x0 },
905 { 0x00ab, 0x0 } },
906 { { 0x0bb2, 0x0bbf, 0x0 },
907 { 0x00aa, 0x0 } },
908 { { 0x0bb0, 0x0bcd, 0x0 },
909 { 0x00a4, 0x0 } },
910 { { 0x0bb0, 0x0bbf, 0x0 },
911 { 0x00a5, 0x0 } },
912 { { 0x0bb0, 0x0bc0, 0x0 },
913 { 0x00a6, 0x0 } },
914 { { 0x0b83, 0x0 },
915 { 0x0025, 0x0 } },
916 { { 0x0b83, 0x0b95, 0x0 },
917 { 0x0025, 0x0031, 0x0 } },
919 { {0}, {0} }
923 const ShapeTable *s = shape_table;
924 while (s->unicode[0]) {
925 QVERIFY( shaping(face, s, HB_Script_Tamil) );
926 ++s;
929 FT_Done_Face(face);
930 } else {
931 QSKIP("couln't find akruti1.ttf", SkipAll);
937 void tst_QScriptEngine::telugu()
940 FT_Face face = loadFace("Pothana2000.ttf");
941 if (face) {
942 const ShapeTable shape_table [] = {
943 { { 0xc15, 0xc4d, 0x0 },
944 { 0xbb, 0x0 } },
945 { { 0xc15, 0xc4d, 0xc37, 0x0 },
946 { 0x4b, 0x0 } },
947 { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0x0 },
948 { 0xe0, 0x0 } },
949 { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0xc23, 0x0 },
950 { 0x4b, 0x91, 0x0 } },
951 { { 0xc15, 0xc4d, 0xc30, 0x0 },
952 { 0x5a, 0xb2, 0x0 } },
953 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0x0 },
954 { 0xbb, 0xb2, 0x0 } },
955 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0x0 },
956 { 0x5a, 0xb2, 0x83, 0x0 } },
957 { { 0xc15, 0xc4d, 0xc30, 0xc3f, 0x0 },
958 { 0xe2, 0xb2, 0x0 } },
959 { { 0xc15, 0xc4d, 0xc15, 0xc48, 0x0 },
960 { 0xe6, 0xb3, 0x83, 0x0 } },
961 { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 },
962 { 0xe6, 0xb3, 0x9f, 0x0 } },
963 { { 0xc15, 0xc46, 0xc56, 0x0 },
964 { 0xe6, 0xb3, 0x0 } },
965 { {0}, {0} }
968 const ShapeTable *s = shape_table;
969 while (s->unicode[0]) {
970 QVERIFY( shaping(face, s, HB_Script_Telugu) );
971 ++s;
974 FT_Done_Face(face);
975 } else {
976 QSKIP("couln't find Pothana2000.ttf", SkipAll);
982 void tst_QScriptEngine::kannada()
985 FT_Face face = loadFace("Sampige.ttf");
986 if (face) {
987 const ShapeTable shape_table [] = {
988 { { 0x0ca8, 0x0ccd, 0x0ca8, 0x0 },
989 { 0x0049, 0x00ba, 0x0 } },
990 { { 0x0ca8, 0x0ccd, 0x0ca1, 0x0 },
991 { 0x0049, 0x00b3, 0x0 } },
992 { { 0x0caf, 0x0cc2, 0x0 },
993 { 0x004f, 0x005d, 0x0 } },
994 { { 0x0ce0, 0x0 },
995 { 0x006a, 0x0 } },
996 { { 0x0ce6, 0x0ce7, 0x0ce8, 0x0 },
997 { 0x006b, 0x006c, 0x006d, 0x0 } },
998 { { 0x0cb5, 0x0ccb, 0x0 },
999 { 0x015f, 0x0067, 0x0 } },
1000 { { 0x0cb0, 0x0ccd, 0x0cae, 0x0 },
1001 { 0x004e, 0x0082, 0x0 } },
1002 { { 0x0cb0, 0x0ccd, 0x0c95, 0x0 },
1003 { 0x0036, 0x0082, 0x0 } },
1004 { { 0x0c95, 0x0ccd, 0x0cb0, 0x0 },
1005 { 0x0036, 0x00c1, 0x0 } },
1006 { { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 },
1007 { 0x0050, 0x00a7, 0x0 } },
1008 { {0}, {0} }
1012 const ShapeTable *s = shape_table;
1013 while (s->unicode[0]) {
1014 QVERIFY( shaping(face, s, HB_Script_Kannada) );
1015 ++s;
1018 FT_Done_Face(face);
1019 } else {
1020 QSKIP("couln't find Sampige.ttf", SkipAll);
1024 FT_Face face = loadFace("tunga.ttf");
1025 if (face) {
1026 const ShapeTable shape_table [] = {
1027 { { 0x0cb7, 0x0cc6, 0x0 },
1028 { 0x00b0, 0x006c, 0x0 } },
1029 { { 0x0cb7, 0x0ccd, 0x0 },
1030 { 0x0163, 0x0 } },
1031 { { 0xc95, 0xcbf, 0xcd5, 0x0 },
1032 { 0x114, 0x73, 0x0 } },
1033 { { 0xc95, 0xcc6, 0xcd5, 0x0 },
1034 { 0x90, 0x6c, 0x73, 0x0 } },
1035 { { 0xc95, 0xcc6, 0xcd6, 0x0 },
1036 { 0x90, 0x6c, 0x74, 0x0 } },
1037 { { 0xc95, 0xcc6, 0xcc2, 0x0 },
1038 { 0x90, 0x6c, 0x69, 0x0 } },
1039 { { 0xc95, 0xcca, 0xcd5, 0x0 },
1040 { 0x90, 0x6c, 0x69, 0x73, 0x0 } },
1043 { {0}, {0} }
1047 const ShapeTable *s = shape_table;
1048 while (s->unicode[0]) {
1049 QVERIFY( shaping(face, s, HB_Script_Kannada) );
1050 ++s;
1053 FT_Done_Face(face);
1054 } else {
1055 QSKIP("couln't find tunga.ttf", SkipAll);
1062 void tst_QScriptEngine::malayalam()
1065 FT_Face face = loadFace("AkrutiMal2Normal.ttf");
1066 if (face) {
1067 const ShapeTable shape_table [] = {
1068 { { 0x0d15, 0x0d46, 0x0 },
1069 { 0x005e, 0x0034, 0x0 } },
1070 { { 0x0d15, 0x0d47, 0x0 },
1071 { 0x005f, 0x0034, 0x0 } },
1072 { { 0x0d15, 0x0d4b, 0x0 },
1073 { 0x005f, 0x0034, 0x0058, 0x0 } },
1074 { { 0x0d15, 0x0d48, 0x0 },
1075 { 0x0060, 0x0034, 0x0 } },
1076 { { 0x0d15, 0x0d4a, 0x0 },
1077 { 0x005e, 0x0034, 0x0058, 0x0 } },
1078 { { 0x0d30, 0x0d4d, 0x0d15, 0x0 },
1079 { 0x009e, 0x0034, 0x0 } },
1080 { { 0x0d15, 0x0d4d, 0x0d35, 0x0 },
1081 { 0x0034, 0x007a, 0x0 } },
1082 { { 0x0d15, 0x0d4d, 0x0d2f, 0x0 },
1083 { 0x0034, 0x00a2, 0x0 } },
1084 { { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 },
1085 { 0x0069, 0x0 } },
1086 { { 0x0d26, 0x0d4d, 0x0d26, 0x0 },
1087 { 0x0074, 0x0 } },
1088 { { 0x0d30, 0x0d4d, 0x0 },
1089 { 0x009e, 0x0 } },
1090 { { 0x0d30, 0x0d4d, 0x200c, 0x0 },
1091 { 0x009e, 0x0 } },
1092 { { 0x0d30, 0x0d4d, 0x200d, 0x0 },
1093 { 0x009e, 0x0 } },
1094 { { 0xd15, 0xd46, 0xd3e, 0x0 },
1095 { 0x5e, 0x34, 0x58, 0x0 } },
1096 { { 0xd15, 0xd47, 0xd3e, 0x0 },
1097 { 0x5f, 0x34, 0x58, 0x0 } },
1098 { { 0xd15, 0xd46, 0xd57, 0x0 },
1099 { 0x5e, 0x34, 0x65, 0x0 } },
1100 { { 0xd15, 0xd57, 0x0 },
1101 { 0x34, 0x65, 0x0 } },
1102 { { 0xd1f, 0xd4d, 0xd1f, 0xd41, 0xd4d, 0x0 },
1103 { 0x69, 0x5b, 0x64, 0x0 } },
1105 { {0}, {0} }
1109 const ShapeTable *s = shape_table;
1110 while (s->unicode[0]) {
1111 QVERIFY( shaping(face, s, HB_Script_Malayalam) );
1112 ++s;
1115 FT_Done_Face(face);
1116 } else {
1117 QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll);
1122 FT_Face face = loadFace("Rachana.ttf");
1123 if (face) {
1124 const ShapeTable shape_table [] = {
1125 { { 0xd37, 0xd4d, 0xd1f, 0xd4d, 0xd30, 0xd40, 0x0 },
1126 { 0x385, 0xa3, 0x0 } },
1127 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
1128 { 0x2ff, 0x0 } },
1129 { { 0xd33, 0xd4d, 0xd33, 0x0 },
1130 { 0x3f8, 0x0 } },
1131 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
1132 { 0x2ff, 0x0 } },
1133 { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 },
1134 { 0xf3, 0x350, 0x0 } },
1136 { {0}, {0} }
1140 const ShapeTable *s = shape_table;
1141 while (s->unicode[0]) {
1142 QVERIFY( shaping(face, s, HB_Script_Malayalam) );
1143 ++s;
1146 FT_Done_Face(face);
1147 } else {
1148 QSKIP("couln't find Rachana.ttf", SkipAll);
1154 void tst_QScriptEngine::sinhala()
1157 FT_Face face = loadFace("FM-MalithiUW46.ttf");
1158 if (face) {
1159 const ShapeTable shape_table [] = {
1160 { { 0xd9a, 0xdd9, 0xdcf, 0x0 },
1161 { 0x4a, 0x61, 0x42, 0x0 } },
1162 { { 0xd9a, 0xdd9, 0xddf, 0x0 },
1163 { 0x4a, 0x61, 0x50, 0x0 } },
1164 { { 0xd9a, 0xdd9, 0xdca, 0x0 },
1165 { 0x4a, 0x62, 0x0 } },
1166 { { 0xd9a, 0xddc, 0xdca, 0x0 },
1167 { 0x4a, 0x61, 0x42, 0x41, 0x0 } },
1168 { { 0xd9a, 0xdda, 0x0 },
1169 { 0x4a, 0x62, 0x0 } },
1170 { { 0xd9a, 0xddd, 0x0 },
1171 { 0x4a, 0x61, 0x42, 0x41, 0x0 } },
1172 { {0}, {0} }
1175 const ShapeTable *s = shape_table;
1176 while (s->unicode[0]) {
1177 QVERIFY( shaping(face, s, HB_Script_Sinhala) );
1178 ++s;
1181 FT_Done_Face(face);
1182 } else {
1183 QSKIP("couln't find FM-MalithiUW46.ttf", SkipAll);
1189 void tst_QScriptEngine::khmer()
1192 FT_Face face = loadFace("KhmerOS.ttf");
1193 if (face) {
1194 const ShapeTable shape_table [] = {
1195 { { 0x179a, 0x17cd, 0x0 },
1196 { 0x24c, 0x27f, 0x0 } },
1197 { { 0x179f, 0x17c5, 0x0 },
1198 { 0x273, 0x203, 0x0 } },
1199 { { 0x1790, 0x17d2, 0x1784, 0x17c3, 0x0 },
1200 { 0x275, 0x242, 0x182, 0x0 } },
1201 { { 0x179a, 0x0 },
1202 { 0x24c, 0x0 } },
1203 { { 0x1781, 0x17d2, 0x1798, 0x17c2, 0x0 },
1204 { 0x274, 0x233, 0x197, 0x0 } },
1205 { { 0x1798, 0x17b6, 0x0 },
1206 { 0x1cb, 0x0 } },
1207 { { 0x179a, 0x17b8, 0x0 },
1208 { 0x24c, 0x26a, 0x0 } },
1209 { { 0x1787, 0x17b6, 0x0 },
1210 { 0x1ba, 0x0 } },
1211 { { 0x1798, 0x17d2, 0x1796, 0x17bb, 0x0 },
1212 { 0x24a, 0x195, 0x26d, 0x0 } },
1213 { {0}, {0} }
1217 const ShapeTable *s = shape_table;
1218 while (s->unicode[0]) {
1219 QVERIFY( shaping(face, s, HB_Script_Khmer) );
1220 ++s;
1223 FT_Done_Face(face);
1224 } else {
1225 QSKIP("couln't find KhmerOS.ttf", SkipAll);
1230 void tst_QScriptEngine::nko()
1233 FT_Face face = loadFace("DejaVuSans.ttf");
1234 if (face) {
1235 const ShapeTable shape_table [] = {
1236 { { 0x7ca, 0x0 },
1237 { 0x5c1, 0x0 } },
1238 { { 0x7ca, 0x7ca, 0x0 },
1239 { 0x14db, 0x14d9, 0x0 } },
1240 { { 0x7ca, 0x7fa, 0x7ca, 0x0 },
1241 { 0x14db, 0x5ec, 0x14d9, 0x0 } },
1242 { { 0x7ca, 0x7f3, 0x7ca, 0x0 },
1243 { 0x14db, 0x5e7, 0x14d9, 0x0 } },
1244 { { 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0x0 },
1245 { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0x0 } },
1246 { {0}, {0} }
1250 const ShapeTable *s = shape_table;
1251 while (s->unicode[0]) {
1252 QVERIFY( shaping(face, s, HB_Script_Nko) );
1253 ++s;
1256 FT_Done_Face(face);
1257 } else {
1258 QSKIP("couln't find DejaVuSans.ttf", SkipAll);
1264 void tst_QScriptEngine::linearB()
1267 FT_Face face = loadFace("penuture.ttf");
1268 if (face) {
1269 const ShapeTable shape_table [] = {
1270 { { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03, 0 },
1271 { 0x5, 0x6, 0x7, 0 } },
1272 { {0}, {0} }
1276 const ShapeTable *s = shape_table;
1277 while (s->unicode[0]) {
1278 QVERIFY( shaping(face, s, HB_Script_Common) );
1279 ++s;
1282 FT_Done_Face(face);
1283 } else {
1284 QSKIP("couln't find PENUTURE.TTF", SkipAll);
1290 QTEST_MAIN(tst_QScriptEngine)
1291 #include "main.moc"