OLD | NEW |
| (Empty) |
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 | |
35 static FT_Library freetype; | |
36 | |
37 static 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 | |
51 static 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 | |
65 static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint
32 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 | |
82 static void hb_getAdvances(HB_Font /*font*/, const HB_Glyph * /*glyphs*/, hb_uin
t32 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 | |
88 static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 le
ngth) | |
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 | |
99 static 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 | |
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) | |
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_HINTI
NG : 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 | |
139 void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics) | |
140 { | |
141 // ### | |
142 metrics->x = metrics->y = metrics->width = metrics->height = metrics->xOffse
t = metrics->yOffset = 0; | |
143 } | |
144 | |
145 HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric) | |
146 { | |
147 return 0; // #### | |
148 } | |
149 | |
150 const 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 | |
159 class tst_QScriptEngine : public QObject | |
160 { | |
161 Q_OBJECT | |
162 | |
163 public: | |
164 tst_QScriptEngine(); | |
165 virtual ~tst_QScriptEngine(); | |
166 | |
167 | |
168 public slots: | |
169 void initTestCase(); | |
170 void cleanupTestCase(); | |
171 private 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 // sinhala missing | |
182 | |
183 void khmer(); | |
184 void linearB(); | |
185 }; | |
186 | |
187 tst_QScriptEngine::tst_QScriptEngine() | |
188 { | |
189 } | |
190 | |
191 tst_QScriptEngine::~tst_QScriptEngine() | |
192 { | |
193 } | |
194 | |
195 void tst_QScriptEngine::initTestCase() | |
196 { | |
197 FT_Init_FreeType(&freetype); | |
198 } | |
199 | |
200 void tst_QScriptEngine::cleanupTestCase() | |
201 { | |
202 FT_Done_FreeType(freetype); | |
203 } | |
204 | |
205 struct ShapeTable { | |
206 unsigned short unicode[16]; | |
207 unsigned short glyphs[16]; | |
208 }; | |
209 | |
210 static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script) | |
211 { | |
212 QString str = QString::fromUtf16( s->unicode ); | |
213 | |
214 HB_Face hbFace = HB_NewFace(face, hb_getSFntTable); | |
215 | |
216 HB_FontRec hbFont; | |
217 hbFont.klass = &hb_fontClass; | |
218 hbFont.userData = face; | |
219 hbFont.x_ppem = face->size->metrics.x_ppem; | |
220 hbFont.y_ppem = face->size->metrics.y_ppem; | |
221 hbFont.x_scale = face->size->metrics.x_scale; | |
222 hbFont.y_scale = face->size->metrics.y_scale; | |
223 | |
224 HB_ShaperItem shaper_item; | |
225 shaper_item.kerning_applied = false; | |
226 shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData()); | |
227 shaper_item.stringLength = str.length(); | |
228 shaper_item.item.script = script; | |
229 shaper_item.item.pos = 0; | |
230 shaper_item.item.length = shaper_item.stringLength; | |
231 shaper_item.item.bidiLevel = 0; // ### | |
232 shaper_item.shaperFlags = 0; | |
233 shaper_item.font = &hbFont; | |
234 shaper_item.face = hbFace; | |
235 shaper_item.num_glyphs = shaper_item.item.length; | |
236 shaper_item.glyphIndicesPresent = false; | |
237 shaper_item.initialGlyphCount = 0; | |
238 | |
239 QVarLengthArray<HB_Glyph> hb_glyphs(shaper_item.num_glyphs); | |
240 QVarLengthArray<HB_GlyphAttributes> hb_attributes(shaper_item.num_glyphs); | |
241 QVarLengthArray<HB_Fixed> hb_advances(shaper_item.num_glyphs); | |
242 QVarLengthArray<HB_FixedPoint> hb_offsets(shaper_item.num_glyphs); | |
243 QVarLengthArray<unsigned short> hb_logClusters(shaper_item.num_glyphs); | |
244 | |
245 while (1) { | |
246 hb_glyphs.resize(shaper_item.num_glyphs); | |
247 hb_attributes.resize(shaper_item.num_glyphs); | |
248 hb_advances.resize(shaper_item.num_glyphs); | |
249 hb_offsets.resize(shaper_item.num_glyphs); | |
250 hb_logClusters.resize(shaper_item.num_glyphs); | |
251 | |
252 memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph)); | |
253 memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAt
tributes)); | |
254 memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed)); | |
255 memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint)); | |
256 | |
257 shaper_item.glyphs = hb_glyphs.data(); | |
258 shaper_item.attributes = hb_attributes.data(); | |
259 shaper_item.advances = hb_advances.data(); | |
260 shaper_item.offsets = hb_offsets.data(); | |
261 shaper_item.log_clusters = hb_logClusters.data(); | |
262 | |
263 if (HB_ShapeItem(&shaper_item)) | |
264 break; | |
265 | |
266 } | |
267 | |
268 HB_FreeFace(hbFace); | |
269 | |
270 hb_uint32 nglyphs = 0; | |
271 const unsigned short *g = s->glyphs; | |
272 while ( *g ) { | |
273 nglyphs++; | |
274 g++; | |
275 } | |
276 | |
277 if( nglyphs != shaper_item.num_glyphs ) | |
278 goto error; | |
279 | |
280 for (hb_uint32 i = 0; i < nglyphs; ++i) { | |
281 if ((shaper_item.glyphs[i]&0xffffff) != s->glyphs[i]) | |
282 goto error; | |
283 } | |
284 return true; | |
285 error: | |
286 str = ""; | |
287 const unsigned short *uc = s->unicode; | |
288 while (*uc) { | |
289 str += QString("%1 ").arg(*uc, 4, 16); | |
290 ++uc; | |
291 } | |
292 qDebug("%s: shaping of string %s failed, nglyphs=%d, expected %d", | |
293 face->family_name, | |
294 str.toLatin1().constData(), | |
295 shaper_item.num_glyphs, nglyphs); | |
296 | |
297 str = ""; | |
298 hb_uint32 i = 0; | |
299 while (i < shaper_item.num_glyphs) { | |
300 str += QString("%1 ").arg(shaper_item.glyphs[i], 4, 16); | |
301 ++i; | |
302 } | |
303 qDebug(" glyph result = %s", str.toLatin1().constData()); | |
304 return false; | |
305 } | |
306 | |
307 void tst_QScriptEngine::devanagari() | |
308 { | |
309 { | |
310 FT_Face face = loadFace("raghu.ttf"); | |
311 if (face) { | |
312 const ShapeTable shape_table [] = { | |
313 // Ka | |
314 { { 0x0915, 0x0 }, | |
315 { 0x0080, 0x0 } }, | |
316 // Ka Halant | |
317 { { 0x0915, 0x094d, 0x0 }, | |
318 { 0x0080, 0x0051, 0x0 } }, | |
319 // Ka Halant Ka | |
320 { { 0x0915, 0x094d, 0x0915, 0x0 }, | |
321 { 0x00c8, 0x0080, 0x0 } }, | |
322 // Ka MatraI | |
323 { { 0x0915, 0x093f, 0x0 }, | |
324 { 0x01d1, 0x0080, 0x0 } }, | |
325 // Ra Halant Ka | |
326 { { 0x0930, 0x094d, 0x0915, 0x0 }, | |
327 { 0x0080, 0x005b, 0x0 } }, | |
328 // Ra Halant Ka MatraI | |
329 { { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 }, | |
330 { 0x01d1, 0x0080, 0x005b, 0x0 } }, | |
331 // MatraI | |
332 { { 0x093f, 0x0 }, | |
333 { 0x01d4, 0x029c, 0x0 } }, | |
334 // Ka Nukta | |
335 { { 0x0915, 0x093c, 0x0 }, | |
336 { 0x00a4, 0x0 } }, | |
337 // Ka Halant Ra | |
338 { { 0x0915, 0x094d, 0x0930, 0x0 }, | |
339 { 0x0110, 0x0 } }, | |
340 // Ka Halant Ra Halant Ka | |
341 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 }, | |
342 { 0x0158, 0x0080, 0x0 } }, | |
343 { { 0x0930, 0x094d, 0x200d, 0x0 }, | |
344 { 0x00e2, 0x0 } }, | |
345 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x200d, 0x0 }, | |
346 { 0x0158, 0x0 } }, | |
347 | |
348 { {0}, {0} } | |
349 }; | |
350 | |
351 | |
352 const ShapeTable *s = shape_table; | |
353 while (s->unicode[0]) { | |
354 QVERIFY( shaping(face, s, HB_Script_Devanagari) ); | |
355 ++s; | |
356 } | |
357 | |
358 FT_Done_Face(face); | |
359 } else { | |
360 QSKIP("couln't find raghu.ttf", SkipAll); | |
361 } | |
362 } | |
363 | |
364 { | |
365 FT_Face face = loadFace("mangal.ttf"); | |
366 if (face) { | |
367 const ShapeTable shape_table [] = { | |
368 // Ka | |
369 { { 0x0915, 0x0 }, | |
370 { 0x0080, 0x0 } }, | |
371 // Ka Halant | |
372 { { 0x0915, 0x094d, 0x0 }, | |
373 { 0x0080, 0x0051, 0x0 } }, | |
374 // Ka Halant Ka | |
375 { { 0x0915, 0x094d, 0x0915, 0x0 }, | |
376 { 0x00c8, 0x0080, 0x0 } }, | |
377 // Ka MatraI | |
378 { { 0x0915, 0x093f, 0x0 }, | |
379 { 0x01d1, 0x0080, 0x0 } }, | |
380 // Ra Halant Ka | |
381 { { 0x0930, 0x094d, 0x0915, 0x0 }, | |
382 { 0x0080, 0x005b, 0x0 } }, | |
383 // Ra Halant Ka MatraI | |
384 { { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 }, | |
385 { 0x01d1, 0x0080, 0x005b, 0x0 } }, | |
386 // MatraI | |
387 { { 0x093f, 0x0 }, | |
388 { 0x01d4, 0x029c, 0x0 } }, | |
389 // Ka Nukta | |
390 { { 0x0915, 0x093c, 0x0 }, | |
391 { 0x00a4, 0x0 } }, | |
392 // Ka Halant Ra | |
393 { { 0x0915, 0x094d, 0x0930, 0x0 }, | |
394 { 0x0110, 0x0 } }, | |
395 // Ka Halant Ra Halant Ka | |
396 { { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 }, | |
397 { 0x0158, 0x0080, 0x0 } }, | |
398 | |
399 { { 0x92b, 0x94d, 0x930, 0x0 }, | |
400 { 0x125, 0x0 } }, | |
401 { { 0x92b, 0x93c, 0x94d, 0x930, 0x0 }, | |
402 { 0x149, 0x0 } }, | |
403 { {0}, {0} } | |
404 }; | |
405 | |
406 const ShapeTable *s = shape_table; | |
407 while (s->unicode[0]) { | |
408 QVERIFY( shaping(face, s, HB_Script_Devanagari) ); | |
409 ++s; | |
410 } | |
411 | |
412 FT_Done_Face(face); | |
413 } else { | |
414 QSKIP("couldn't find mangal.ttf", SkipAll); | |
415 } | |
416 } | |
417 } | |
418 | |
419 void tst_QScriptEngine::bengali() | |
420 { | |
421 { | |
422 FT_Face face = loadFace("AkaashNormal.ttf"); | |
423 if (face) { | |
424 const ShapeTable shape_table [] = { | |
425 // Ka | |
426 { { 0x0995, 0x0 }, | |
427 { 0x0151, 0x0 } }, | |
428 // Ka Halant | |
429 { { 0x0995, 0x09cd, 0x0 }, | |
430 { 0x0151, 0x017d, 0x0 } }, | |
431 // Ka Halant Ka | |
432 { { 0x0995, 0x09cd, 0x0995, 0x0 }, | |
433 { 0x019b, 0x0 } }, | |
434 // Ka MatraI | |
435 { { 0x0995, 0x09bf, 0x0 }, | |
436 { 0x0173, 0x0151, 0x0 } }, | |
437 // Ra Halant Ka | |
438 { { 0x09b0, 0x09cd, 0x0995, 0x0 }, | |
439 { 0x0151, 0x0276, 0x0 } }, | |
440 // Ra Halant Ka MatraI | |
441 { { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 }, | |
442 { 0x0173, 0x0151, 0x0276, 0x0 } }, | |
443 // Ka Nukta | |
444 { { 0x0995, 0x09bc, 0x0 }, | |
445 { 0x0151, 0x0171, 0x0 } }, | |
446 // Ka Halant Ra | |
447 { { 0x0995, 0x09cd, 0x09b0, 0x0 }, | |
448 { 0x01f4, 0x0 } }, | |
449 // Ka Halant Ra Halant Ka | |
450 { { 0x0995, 0x09cd, 0x09b0, 0x09cd, 0x0995, 0x0 }, | |
451 { 0x025c, 0x0276, 0x0151, 0x0 } }, | |
452 // Ya + Halant | |
453 { { 0x09af, 0x09cd, 0x0 }, | |
454 { 0x016a, 0x017d, 0x0 } }, | |
455 // Da Halant Ya -> Da Ya-Phala | |
456 { { 0x09a6, 0x09cd, 0x09af, 0x0 }, | |
457 { 0x01e5, 0x0 } }, | |
458 // A Halant Ya -> A Ya-phala | |
459 { { 0x0985, 0x09cd, 0x09af, 0x0 }, | |
460 { 0x0145, 0x01cf, 0x0 } }, | |
461 // Na Halant Ka | |
462 { { 0x09a8, 0x09cd, 0x0995, 0x0 }, | |
463 { 0x026f, 0x0151, 0x0 } }, | |
464 // Na Halant ZWNJ Ka | |
465 { { 0x09a8, 0x09cd, 0x200c, 0x0995, 0x0 }, | |
466 { 0x0164, 0x017d, 0x0151, 0x0 } }, | |
467 // Na Halant ZWJ Ka | |
468 { { 0x09a8, 0x09cd, 0x200d, 0x0995, 0x0 }, | |
469 { 0x026f, 0x0151, 0x0 } }, | |
470 // Ka Halant ZWNJ Ka | |
471 { { 0x0995, 0x09cd, 0x200c, 0x0995, 0x0 }, | |
472 { 0x0151, 0x017d, 0x0151, 0x0 } }, | |
473 // Ka Halant ZWJ Ka | |
474 { { 0x0995, 0x09cd, 0x200d, 0x0995, 0x0 }, | |
475 { 0x025c, 0x0151, 0x0 } }, | |
476 // Na Halant Ra | |
477 { { 0x09a8, 0x09cd, 0x09b0, 0x0 }, | |
478 { 0x0207, 0x0 } }, | |
479 // Na Halant ZWNJ Ra | |
480 { { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 }, | |
481 { 0x0164, 0x017d, 0x016b, 0x0 } }, | |
482 // Na Halant ZWJ Ra | |
483 { { 0x09a8, 0x09cd, 0x200d, 0x09b0, 0x0 }, | |
484 { 0x026f, 0x016b, 0x0 } }, | |
485 // Na Halant Ba | |
486 { { 0x09a8, 0x09cd, 0x09ac, 0x0 }, | |
487 { 0x022f, 0x0 } }, | |
488 // Na Halant ZWNJ Ba | |
489 { { 0x09a8, 0x09cd, 0x200c, 0x09ac, 0x0 }, | |
490 { 0x0164, 0x017d, 0x0167, 0x0 } }, | |
491 // Na Halant ZWJ Ba | |
492 { { 0x09a8, 0x09cd, 0x200d, 0x09ac, 0x0 }, | |
493 { 0x026f, 0x0167, 0x0 } }, | |
494 // Na Halant Dha | |
495 { { 0x09a8, 0x09cd, 0x09a7, 0x0 }, | |
496 { 0x01d3, 0x0 } }, | |
497 // Na Halant ZWNJ Dha | |
498 { { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 }, | |
499 { 0x0164, 0x017d, 0x0163, 0x0 } }, | |
500 // Na Halant ZWJ Dha | |
501 { { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 }, | |
502 { 0x026f, 0x0163, 0x0 } }, | |
503 // Ra Halant Ka MatraAU | |
504 { { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 }, | |
505 { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } }, | |
506 // Ra Halant Ba Halant Ba | |
507 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 }, | |
508 { 0x0232, 0x0276, 0x0 } }, | |
509 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 }, | |
510 { 0x151, 0x276, 0x172, 0x143, 0x0 } }, | |
511 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 }, | |
512 { 0x151, 0x276, 0x172, 0x144, 0x0 } }, | |
513 | |
514 { {0}, {0} } | |
515 }; | |
516 | |
517 | |
518 const ShapeTable *s = shape_table; | |
519 while (s->unicode[0]) { | |
520 QVERIFY( shaping(face, s, HB_Script_Bengali) ); | |
521 ++s; | |
522 } | |
523 | |
524 FT_Done_Face(face); | |
525 } else { | |
526 QSKIP("couln't find AkaashNormal.ttf", SkipAll); | |
527 } | |
528 } | |
529 { | |
530 FT_Face face = loadFace("MuktiNarrow.ttf"); | |
531 if (face) { | |
532 const ShapeTable shape_table [] = { | |
533 // Ka | |
534 { { 0x0995, 0x0 }, | |
535 { 0x0073, 0x0 } }, | |
536 // Ka Halant | |
537 { { 0x0995, 0x09cd, 0x0 }, | |
538 { 0x00b9, 0x0 } }, | |
539 // Ka Halant Ka | |
540 { { 0x0995, 0x09cd, 0x0995, 0x0 }, | |
541 { 0x0109, 0x0 } }, | |
542 // Ka MatraI | |
543 { { 0x0995, 0x09bf, 0x0 }, | |
544 { 0x0095, 0x0073, 0x0 } }, | |
545 // Ra Halant Ka | |
546 { { 0x09b0, 0x09cd, 0x0995, 0x0 }, | |
547 { 0x0073, 0x00e1, 0x0 } }, | |
548 // Ra Halant Ka MatraI | |
549 { { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 }, | |
550 { 0x0095, 0x0073, 0x00e1, 0x0 } }, | |
551 // MatraI | |
552 { { 0x09bf, 0x0 }, | |
553 { 0x0095, 0x01c8, 0x0 } }, | |
554 // Ka Nukta | |
555 { { 0x0995, 0x09bc, 0x0 }, | |
556 { 0x0073, 0x0093, 0x0 } }, | |
557 // Ka Halant Ra | |
558 { { 0x0995, 0x09cd, 0x09b0, 0x0 }, | |
559 { 0x00e5, 0x0 } }, | |
560 // Ka Halant Ra Halant Ka | |
561 { { 0x995, 0x9cd, 0x9b0, 0x9cd, 0x995, 0x0 }, | |
562 { 0x234, 0x24e, 0x73, 0x0 } }, | |
563 // Ya + Halant | |
564 { { 0x09af, 0x09cd, 0x0 }, | |
565 { 0x00d2, 0x0 } }, | |
566 // Da Halant Ya -> Da Ya-Phala | |
567 { { 0x09a6, 0x09cd, 0x09af, 0x0 }, | |
568 { 0x0084, 0x00e2, 0x0 } }, | |
569 // A Halant Ya -> A Ya-phala | |
570 { { 0x0985, 0x09cd, 0x09af, 0x0 }, | |
571 { 0x0067, 0x00e2, 0x0 } }, | |
572 // Na Halant Ka | |
573 { { 0x09a8, 0x09cd, 0x0995, 0x0 }, | |
574 { 0x0188, 0x0 } }, | |
575 // Na Halant ZWNJ Ka | |
576 { { 0x9a8, 0x9cd, 0x200c, 0x995, 0x0 }, | |
577 { 0xcc, 0x73, 0x0 } }, | |
578 // Na Halant ZWJ Ka | |
579 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 }, | |
580 { 0x247, 0x73, 0x0 } }, | |
581 // Ka Halant ZWNJ Ka | |
582 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 }, | |
583 { 0x247, 0x73, 0x0 } }, | |
584 // Ka Halant ZWJ Ka | |
585 { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 }, | |
586 { 0x247, 0x73, 0x0 } }, | |
587 // Na Halant Ra | |
588 { { 0x09a8, 0x09cd, 0x09b0, 0x0 }, | |
589 { 0x00f8, 0x0 } }, | |
590 // Na Halant ZWNJ Ra | |
591 { { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 }, | |
592 { 0xcc, 0x8d, 0x0 } }, | |
593 // Na Halant ZWJ Ra | |
594 { { 0x9a8, 0x9cd, 0x200d, 0x9b0, 0x0 }, | |
595 { 0x247, 0x8d, 0x0 } }, | |
596 // Na Halant Ba | |
597 { { 0x09a8, 0x09cd, 0x09ac, 0x0 }, | |
598 { 0x0139, 0x0 } }, | |
599 // Na Halant ZWNJ Ba | |
600 { { 0x9a8, 0x9cd, 0x200c, 0x9ac, 0x0 }, | |
601 { 0xcc, 0x89, 0x0 } }, | |
602 // Na Halant ZWJ Ba | |
603 { { 0x9a8, 0x9cd, 0x200d, 0x9ac, 0x0 }, | |
604 { 0x247, 0x89, 0x0 } }, | |
605 // Na Halant Dha | |
606 { { 0x09a8, 0x09cd, 0x09a7, 0x0 }, | |
607 { 0x0145, 0x0 } }, | |
608 // Na Halant ZWNJ Dha | |
609 { { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 }, | |
610 { 0xcc, 0x85, 0x0 } }, | |
611 // Na Halant ZWJ Dha | |
612 { { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 }, | |
613 { 0x247, 0x85, 0x0 } }, | |
614 // Ra Halant Ka MatraAU | |
615 { { 0x9b0, 0x9cd, 0x995, 0x9cc, 0x0 }, | |
616 { 0x232, 0x73, 0xe1, 0xa0, 0x0 } }, | |
617 // Ra Halant Ba Halant Ba | |
618 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 }, | |
619 { 0x013b, 0x00e1, 0x0 } }, | |
620 | |
621 { {0}, {0} } | |
622 }; | |
623 | |
624 | |
625 const ShapeTable *s = shape_table; | |
626 while (s->unicode[0]) { | |
627 QVERIFY( shaping(face, s, HB_Script_Bengali) ); | |
628 ++s; | |
629 } | |
630 | |
631 FT_Done_Face(face); | |
632 } else { | |
633 QSKIP("couln't find MuktiNarrow.ttf", SkipAll); | |
634 } | |
635 } | |
636 { | |
637 FT_Face face = loadFace("LikhanNormal.ttf"); | |
638 if (face) { | |
639 const ShapeTable shape_table [] = { | |
640 { { 0x09a8, 0x09cd, 0x09af, 0x0 }, | |
641 { 0x0192, 0x0 } }, | |
642 { { 0x09b8, 0x09cd, 0x09af, 0x0 }, | |
643 { 0x01d6, 0x0 } }, | |
644 { { 0x09b6, 0x09cd, 0x09af, 0x0 }, | |
645 { 0x01bc, 0x0 } }, | |
646 { { 0x09b7, 0x09cd, 0x09af, 0x0 }, | |
647 { 0x01c6, 0x0 } }, | |
648 { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 }, | |
649 { 0xd3, 0x12f, 0x0 } }, | |
650 | |
651 { {0}, {0} } | |
652 }; | |
653 | |
654 | |
655 const ShapeTable *s = shape_table; | |
656 while (s->unicode[0]) { | |
657 QVERIFY( shaping(face, s, HB_Script_Bengali) ); | |
658 ++s; | |
659 } | |
660 | |
661 FT_Done_Face(face); | |
662 } else { | |
663 QSKIP("couln't find LikhanNormal.ttf", SkipAll); | |
664 } | |
665 } | |
666 } | |
667 | |
668 void tst_QScriptEngine::gurmukhi() | |
669 { | |
670 { | |
671 FT_Face face = loadFace("lohit.punjabi.1.1.ttf"); | |
672 if (face) { | |
673 const ShapeTable shape_table [] = { | |
674 { { 0xA15, 0xA4D, 0xa39, 0x0 }, | |
675 { 0x3b, 0x8b, 0x0 } }, | |
676 { {0}, {0} } | |
677 }; | |
678 | |
679 | |
680 const ShapeTable *s = shape_table; | |
681 while (s->unicode[0]) { | |
682 QVERIFY( shaping(face, s, HB_Script_Gurmukhi) ); | |
683 ++s; | |
684 } | |
685 | |
686 FT_Done_Face(face); | |
687 } else { | |
688 QSKIP("couln't find lohit.punjabi.1.1.ttf", SkipAll); | |
689 } | |
690 } | |
691 } | |
692 | |
693 void tst_QScriptEngine::oriya() | |
694 { | |
695 { | |
696 FT_Face face = loadFace("utkalm.ttf"); | |
697 if (face) { | |
698 const ShapeTable shape_table [] = { | |
699 { { 0xb15, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 }, | |
700 { 0x150, 0x125, 0x0 } }, | |
701 { { 0xb24, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 }, | |
702 { 0x151, 0x120, 0x0 } }, | |
703 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 }, | |
704 { 0x152, 0x120, 0x0 } }, | |
705 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb2c, 0x0 }, | |
706 { 0x152, 0x120, 0x0 } }, | |
707 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 }, | |
708 { 0x176, 0x0 } }, | |
709 { { 0xb38, 0xb4d, 0xb24, 0xb4d, 0xb30, 0x0 }, | |
710 { 0x177, 0x0 } }, | |
711 { { 0xb28, 0xb4d, 0xb24, 0xb4d, 0xb30, 0xb4d, 0xb2f, 0x0 }, | |
712 { 0x176, 0x124, 0x0 } }, | |
713 { {0}, {0} } | |
714 | |
715 }; | |
716 | |
717 const ShapeTable *s = shape_table; | |
718 while (s->unicode[0]) { | |
719 QVERIFY( shaping(face, s, HB_Script_Oriya) ); | |
720 ++s; | |
721 } | |
722 | |
723 FT_Done_Face(face); | |
724 } else { | |
725 QSKIP("couln't find utkalm.ttf", SkipAll); | |
726 } | |
727 } | |
728 } | |
729 | |
730 | |
731 void tst_QScriptEngine::tamil() | |
732 { | |
733 { | |
734 FT_Face face = loadFace("akruti1.ttf"); | |
735 if (face) { | |
736 const ShapeTable shape_table [] = { | |
737 { { 0x0b95, 0x0bc2, 0x0 }, | |
738 { 0x004e, 0x0 } }, | |
739 { { 0x0bae, 0x0bc2, 0x0 }, | |
740 { 0x009e, 0x0 } }, | |
741 { { 0x0b9a, 0x0bc2, 0x0 }, | |
742 { 0x0058, 0x0 } }, | |
743 { { 0x0b99, 0x0bc2, 0x0 }, | |
744 { 0x0053, 0x0 } }, | |
745 { { 0x0bb0, 0x0bc2, 0x0 }, | |
746 { 0x00a8, 0x0 } }, | |
747 { { 0x0ba4, 0x0bc2, 0x0 }, | |
748 { 0x008e, 0x0 } }, | |
749 { { 0x0b9f, 0x0bc2, 0x0 }, | |
750 { 0x0062, 0x0 } }, | |
751 { { 0x0b95, 0x0bc6, 0x0 }, | |
752 { 0x000a, 0x0031, 0x0 } }, | |
753 { { 0x0b95, 0x0bca, 0x0 }, | |
754 { 0x000a, 0x0031, 0x0007, 0x0 } }, | |
755 { { 0x0b95, 0x0bc6, 0x0bbe, 0x0 }, | |
756 { 0x000a, 0x0031, 0x007, 0x0 } }, | |
757 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0 }, | |
758 { 0x0049, 0x0 } }, | |
759 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0bca, 0x0 }, | |
760 { 0x000a, 0x0049, 0x007, 0x0 } }, | |
761 { { 0x0b95, 0x0bcd, 0x0bb7, 0x0bc6, 0x0bbe, 0x0 }, | |
762 { 0x000a, 0x0049, 0x007, 0x0 } }, | |
763 { { 0x0b9f, 0x0bbf, 0x0 }, | |
764 { 0x005f, 0x0 } }, | |
765 { { 0x0b9f, 0x0bc0, 0x0 }, | |
766 { 0x0060, 0x0 } }, | |
767 { { 0x0bb2, 0x0bc0, 0x0 }, | |
768 { 0x00ab, 0x0 } }, | |
769 { { 0x0bb2, 0x0bbf, 0x0 }, | |
770 { 0x00aa, 0x0 } }, | |
771 { { 0x0bb0, 0x0bcd, 0x0 }, | |
772 { 0x00a4, 0x0 } }, | |
773 { { 0x0bb0, 0x0bbf, 0x0 }, | |
774 { 0x00a5, 0x0 } }, | |
775 { { 0x0bb0, 0x0bc0, 0x0 }, | |
776 { 0x00a6, 0x0 } }, | |
777 { { 0x0b83, 0x0 }, | |
778 { 0x0025, 0x0 } }, | |
779 { { 0x0b83, 0x0b95, 0x0 }, | |
780 { 0x0025, 0x0031, 0x0 } }, | |
781 | |
782 { {0}, {0} } | |
783 }; | |
784 | |
785 | |
786 const ShapeTable *s = shape_table; | |
787 while (s->unicode[0]) { | |
788 QVERIFY( shaping(face, s, HB_Script_Tamil) ); | |
789 ++s; | |
790 } | |
791 | |
792 FT_Done_Face(face); | |
793 } else { | |
794 QSKIP("couln't find akruti1.ttf", SkipAll); | |
795 } | |
796 } | |
797 } | |
798 | |
799 | |
800 void tst_QScriptEngine::telugu() | |
801 { | |
802 { | |
803 FT_Face face = loadFace("Pothana2000.ttf"); | |
804 if (face) { | |
805 const ShapeTable shape_table [] = { | |
806 { { 0xc15, 0xc4d, 0x0 }, | |
807 { 0xbb, 0x0 } }, | |
808 { { 0xc15, 0xc4d, 0xc37, 0x0 }, | |
809 { 0x4b, 0x0 } }, | |
810 { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0x0 }, | |
811 { 0xe0, 0x0 } }, | |
812 { { 0xc15, 0xc4d, 0xc37, 0xc4d, 0xc23, 0x0 }, | |
813 { 0x4b, 0x91, 0x0 } }, | |
814 { { 0xc15, 0xc4d, 0xc30, 0x0 }, | |
815 { 0x5a, 0xb2, 0x0 } }, | |
816 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0x0 }, | |
817 { 0xbb, 0xb2, 0x0 } }, | |
818 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0x0 }, | |
819 { 0x5a, 0xb2, 0x83, 0x0 } }, | |
820 { { 0xc15, 0xc4d, 0xc30, 0xc3f, 0x0 }, | |
821 { 0xe2, 0xb2, 0x0 } }, | |
822 { { 0xc15, 0xc4d, 0xc15, 0xc48, 0x0 }, | |
823 { 0xe6, 0xb3, 0x83, 0x0 } }, | |
824 { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 }, | |
825 { 0xe6, 0xb3, 0x9f, 0x0 } }, | |
826 { {0}, {0} } | |
827 | |
828 }; | |
829 | |
830 const ShapeTable *s = shape_table; | |
831 while (s->unicode[0]) { | |
832 QVERIFY( shaping(face, s, HB_Script_Telugu) ); | |
833 ++s; | |
834 } | |
835 | |
836 FT_Done_Face(face); | |
837 } else { | |
838 QSKIP("couln't find Pothana2000.ttf", SkipAll); | |
839 } | |
840 } | |
841 } | |
842 | |
843 | |
844 void tst_QScriptEngine::kannada() | |
845 { | |
846 { | |
847 FT_Face face = loadFace("Sampige.ttf"); | |
848 if (face) { | |
849 const ShapeTable shape_table [] = { | |
850 { { 0x0ca8, 0x0ccd, 0x0ca8, 0x0 }, | |
851 { 0x0049, 0x00ba, 0x0 } }, | |
852 { { 0x0ca8, 0x0ccd, 0x0ca1, 0x0 }, | |
853 { 0x0049, 0x00b3, 0x0 } }, | |
854 { { 0x0caf, 0x0cc2, 0x0 }, | |
855 { 0x004f, 0x005d, 0x0 } }, | |
856 { { 0x0ce0, 0x0 }, | |
857 { 0x006a, 0x0 } }, | |
858 { { 0x0ce6, 0x0ce7, 0x0ce8, 0x0 }, | |
859 { 0x006b, 0x006c, 0x006d, 0x0 } }, | |
860 { { 0x0cb5, 0x0ccb, 0x0 }, | |
861 { 0x015f, 0x0067, 0x0 } }, | |
862 { { 0x0cb0, 0x0ccd, 0x0cae, 0x0 }, | |
863 { 0x004e, 0x0082, 0x0 } }, | |
864 { { 0x0cb0, 0x0ccd, 0x0c95, 0x0 }, | |
865 { 0x0036, 0x0082, 0x0 } }, | |
866 { { 0x0c95, 0x0ccd, 0x0cb0, 0x0 }, | |
867 { 0x0036, 0x00c1, 0x0 } }, | |
868 { { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 }, | |
869 { 0x0050, 0x00a7, 0x0 } }, | |
870 | |
871 { {0}, {0} } | |
872 }; | |
873 | |
874 | |
875 const ShapeTable *s = shape_table; | |
876 while (s->unicode[0]) { | |
877 QVERIFY( shaping(face, s, HB_Script_Kannada) ); | |
878 ++s; | |
879 } | |
880 | |
881 FT_Done_Face(face); | |
882 } else { | |
883 QSKIP("couln't find Sampige.ttf", SkipAll); | |
884 } | |
885 } | |
886 { | |
887 FT_Face face = loadFace("tunga.ttf"); | |
888 if (face) { | |
889 const ShapeTable shape_table [] = { | |
890 { { 0x0cb7, 0x0cc6, 0x0 }, | |
891 { 0x00b0, 0x006c, 0x0 } }, | |
892 { { 0x0cb7, 0x0ccd, 0x0 }, | |
893 { 0x0163, 0x0 } }, | |
894 | |
895 { {0}, {0} } | |
896 }; | |
897 | |
898 | |
899 const ShapeTable *s = shape_table; | |
900 while (s->unicode[0]) { | |
901 QVERIFY( shaping(face, s, HB_Script_Kannada) ); | |
902 ++s; | |
903 } | |
904 | |
905 FT_Done_Face(face); | |
906 } else { | |
907 QSKIP("couln't find tunga.ttf", SkipAll); | |
908 } | |
909 } | |
910 } | |
911 | |
912 | |
913 | |
914 void tst_QScriptEngine::malayalam() | |
915 { | |
916 { | |
917 FT_Face face = loadFace("AkrutiMal2Normal.ttf"); | |
918 if (face) { | |
919 const ShapeTable shape_table [] = { | |
920 { { 0x0d15, 0x0d46, 0x0 }, | |
921 { 0x005e, 0x0034, 0x0 } }, | |
922 { { 0x0d15, 0x0d47, 0x0 }, | |
923 { 0x005f, 0x0034, 0x0 } }, | |
924 { { 0x0d15, 0x0d4b, 0x0 }, | |
925 { 0x005f, 0x0034, 0x0058, 0x0 } }, | |
926 { { 0x0d15, 0x0d48, 0x0 }, | |
927 { 0x0060, 0x0034, 0x0 } }, | |
928 { { 0x0d15, 0x0d4a, 0x0 }, | |
929 { 0x005e, 0x0034, 0x0058, 0x0 } }, | |
930 { { 0x0d30, 0x0d4d, 0x0d15, 0x0 }, | |
931 { 0x009e, 0x0034, 0x0 } }, | |
932 { { 0x0d15, 0x0d4d, 0x0d35, 0x0 }, | |
933 { 0x0034, 0x007a, 0x0 } }, | |
934 { { 0x0d15, 0x0d4d, 0x0d2f, 0x0 }, | |
935 { 0x0034, 0x00a2, 0x0 } }, | |
936 { { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 }, | |
937 { 0x0069, 0x0 } }, | |
938 { { 0x0d26, 0x0d4d, 0x0d26, 0x0 }, | |
939 { 0x0074, 0x0 } }, | |
940 { { 0x0d30, 0x0d4d, 0x0 }, | |
941 { 0x009e, 0x0 } }, | |
942 { { 0x0d30, 0x0d4d, 0x200c, 0x0 }, | |
943 { 0x009e, 0x0 } }, | |
944 { { 0x0d30, 0x0d4d, 0x200d, 0x0 }, | |
945 { 0x009e, 0x0 } }, | |
946 | |
947 | |
948 { {0}, {0} } | |
949 }; | |
950 | |
951 | |
952 const ShapeTable *s = shape_table; | |
953 while (s->unicode[0]) { | |
954 QVERIFY( shaping(face, s, HB_Script_Malayalam) ); | |
955 ++s; | |
956 } | |
957 | |
958 FT_Done_Face(face); | |
959 } else { | |
960 QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll); | |
961 } | |
962 } | |
963 } | |
964 | |
965 | |
966 | |
967 void tst_QScriptEngine::khmer() | |
968 { | |
969 { | |
970 FT_Face face = loadFace("KhmerOS.ttf"); | |
971 if (face) { | |
972 const ShapeTable shape_table [] = { | |
973 { { 0x179a, 0x17cd, 0x0 }, | |
974 { 0x24c, 0x27f, 0x0 } }, | |
975 { { 0x179f, 0x17c5, 0x0 }, | |
976 { 0x273, 0x203, 0x0 } }, | |
977 { { 0x1790, 0x17d2, 0x1784, 0x17c3, 0x0 }, | |
978 { 0x275, 0x242, 0x182, 0x0 } }, | |
979 { { 0x179a, 0x0 }, | |
980 { 0x24c, 0x0 } }, | |
981 { { 0x1781, 0x17d2, 0x1798, 0x17c2, 0x0 }, | |
982 { 0x274, 0x233, 0x197, 0x0 } }, | |
983 { { 0x1798, 0x17b6, 0x0 }, | |
984 { 0x1cb, 0x0 } }, | |
985 { { 0x179a, 0x17b8, 0x0 }, | |
986 { 0x24c, 0x26a, 0x0 } }, | |
987 { { 0x1787, 0x17b6, 0x0 }, | |
988 { 0x1ba, 0x0 } }, | |
989 { { 0x1798, 0x17d2, 0x1796, 0x17bb, 0x0 }, | |
990 { 0x24a, 0x195, 0x26d, 0x0 } }, | |
991 { {0}, {0} } | |
992 }; | |
993 | |
994 | |
995 const ShapeTable *s = shape_table; | |
996 while (s->unicode[0]) { | |
997 QVERIFY( shaping(face, s, HB_Script_Khmer) ); | |
998 ++s; | |
999 } | |
1000 | |
1001 FT_Done_Face(face); | |
1002 } else { | |
1003 QSKIP("couln't find KhmerOS.ttf", SkipAll); | |
1004 } | |
1005 } | |
1006 } | |
1007 | |
1008 void tst_QScriptEngine::linearB() | |
1009 { | |
1010 { | |
1011 FT_Face face = loadFace("PENUTURE.TTF"); | |
1012 if (face) { | |
1013 const ShapeTable shape_table [] = { | |
1014 { { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03, 0 }, | |
1015 { 0x5, 0x6, 0x7, 0 } }, | |
1016 { {0}, {0} } | |
1017 }; | |
1018 | |
1019 | |
1020 const ShapeTable *s = shape_table; | |
1021 while (s->unicode[0]) { | |
1022 QVERIFY( shaping(face, s, HB_Script_Common) ); | |
1023 ++s; | |
1024 } | |
1025 | |
1026 FT_Done_Face(face); | |
1027 } else { | |
1028 QSKIP("couln't find PENUTURE.TTF", SkipAll); | |
1029 } | |
1030 } | |
1031 } | |
1032 | |
1033 | |
1034 QTEST_MAIN(tst_QScriptEngine) | |
1035 #include "main.moc" | |
OLD | NEW |