source: trunk/src/3rdparty/harfbuzz/tests/shaping/main.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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