| 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 |