|
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_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 |
|
82 static 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 |
|
88 static 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 |
|
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_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 |
|
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->xOffset = 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_GlyphAttributes)); |
|
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" |