OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
3 * | 3 * |
4 * This is part of HarfBuzz, an OpenType Layout engine library. | 4 * This is part of HarfBuzz, an OpenType Layout engine library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 | 129 |
130 if (point > *nPoints) | 130 if (point > *nPoints) |
131 return (HB_Error)HB_Err_Invalid_SubTable; | 131 return (HB_Error)HB_Err_Invalid_SubTable; |
132 | 132 |
133 *xpos = face->glyph->outline.points[point].x; | 133 *xpos = face->glyph->outline.points[point].x; |
134 *ypos = face->glyph->outline.points[point].y; | 134 *ypos = face->glyph->outline.points[point].y; |
135 | 135 |
136 return HB_Err_Ok; | 136 return HB_Err_Ok; |
137 } | 137 } |
138 | 138 |
139 void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics) | 139 void hb_getGlyphMetrics(HB_Font, HB_Glyph, HB_GlyphMetrics *metrics) |
140 { | 140 { |
141 // ### | 141 // ### |
142 metrics->x = metrics->y = metrics->width = metrics->height = metrics->xOffse
t = metrics->yOffset = 0; | 142 metrics->x = metrics->y = metrics->width = metrics->height = metrics->xOffse
t = metrics->yOffset = 0; |
143 } | 143 } |
144 | 144 |
145 HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric) | 145 HB_Fixed hb_getFontMetric(HB_Font, HB_FontMetric ) |
146 { | 146 { |
147 return 0; // #### | 147 return 0; // #### |
148 } | 148 } |
149 | 149 |
150 const HB_FontClass hb_fontClass = { | 150 const HB_FontClass hb_fontClass = { |
151 hb_stringToGlyphs, hb_getAdvances, hb_canRender, | 151 hb_stringToGlyphs, hb_getAdvances, hb_canRender, |
152 hb_getPointInOutline, hb_getGlyphMetrics, hb_getFontMetric | 152 hb_getPointInOutline, hb_getGlyphMetrics, hb_getFontMetric |
153 }; | 153 }; |
154 | 154 |
155 | 155 |
156 //TESTED_CLASS= | 156 //TESTED_CLASS= |
157 //TESTED_FILES= gui/text/qscriptengine.cpp | 157 //TESTED_FILES= gui/text/qscriptengine.cpp |
158 | 158 |
159 class tst_QScriptEngine : public QObject | 159 class tst_QScriptEngine : public QObject |
160 { | 160 { |
161 Q_OBJECT | 161 Q_OBJECT |
162 | 162 |
163 public: | 163 public: |
164 tst_QScriptEngine(); | 164 tst_QScriptEngine(); |
165 virtual ~tst_QScriptEngine(); | 165 virtual ~tst_QScriptEngine(); |
166 | 166 |
167 | 167 |
168 public slots: | 168 public slots: |
169 void initTestCase(); | 169 void initTestCase(); |
170 void cleanupTestCase(); | 170 void cleanupTestCase(); |
171 private slots: | 171 private slots: |
| 172 void greek(); |
| 173 |
172 void devanagari(); | 174 void devanagari(); |
173 void bengali(); | 175 void bengali(); |
174 void gurmukhi(); | 176 void gurmukhi(); |
175 // gujarati missing | 177 // gujarati missing |
176 void oriya(); | 178 void oriya(); |
177 void tamil(); | 179 void tamil(); |
178 void telugu(); | 180 void telugu(); |
179 void kannada(); | 181 void kannada(); |
180 void malayalam(); | 182 void malayalam(); |
181 // sinhala missing | 183 void sinhala(); |
182 | 184 |
183 void khmer(); | 185 void khmer(); |
| 186 void nko(); |
184 void linearB(); | 187 void linearB(); |
185 }; | 188 }; |
186 | 189 |
187 tst_QScriptEngine::tst_QScriptEngine() | 190 tst_QScriptEngine::tst_QScriptEngine() |
188 { | 191 { |
189 } | 192 } |
190 | 193 |
191 tst_QScriptEngine::~tst_QScriptEngine() | 194 tst_QScriptEngine::~tst_QScriptEngine() |
192 { | 195 { |
193 } | 196 } |
194 | 197 |
195 void tst_QScriptEngine::initTestCase() | 198 void tst_QScriptEngine::initTestCase() |
196 { | 199 { |
197 FT_Init_FreeType(&freetype); | 200 FT_Init_FreeType(&freetype); |
198 } | 201 } |
199 | 202 |
200 void tst_QScriptEngine::cleanupTestCase() | 203 void tst_QScriptEngine::cleanupTestCase() |
201 { | 204 { |
202 FT_Done_FreeType(freetype); | 205 FT_Done_FreeType(freetype); |
203 } | 206 } |
204 | 207 |
205 struct ShapeTable { | 208 class Shaper |
206 unsigned short unicode[16]; | 209 { |
207 unsigned short glyphs[16]; | 210 public: |
| 211 Shaper(FT_Face face, HB_Script script, const QString &str); |
| 212 |
| 213 HB_FontRec hbFont; |
| 214 HB_ShaperItem shaper_item; |
| 215 QVarLengthArray<HB_Glyph> hb_glyphs; |
| 216 QVarLengthArray<HB_GlyphAttributes> hb_attributes; |
| 217 QVarLengthArray<HB_Fixed> hb_advances; |
| 218 QVarLengthArray<HB_FixedPoint> hb_offsets; |
| 219 QVarLengthArray<unsigned short> hb_logClusters; |
| 220 |
208 }; | 221 }; |
209 | 222 |
210 static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script) | 223 Shaper::Shaper(FT_Face face, HB_Script script, const QString &str) |
211 { | 224 { |
212 QString str = QString::fromUtf16( s->unicode ); | |
213 | |
214 HB_Face hbFace = HB_NewFace(face, hb_getSFntTable); | 225 HB_Face hbFace = HB_NewFace(face, hb_getSFntTable); |
215 | 226 |
216 HB_FontRec hbFont; | |
217 hbFont.klass = &hb_fontClass; | 227 hbFont.klass = &hb_fontClass; |
218 hbFont.userData = face; | 228 hbFont.userData = face; |
219 hbFont.x_ppem = face->size->metrics.x_ppem; | 229 hbFont.x_ppem = face->size->metrics.x_ppem; |
220 hbFont.y_ppem = face->size->metrics.y_ppem; | 230 hbFont.y_ppem = face->size->metrics.y_ppem; |
221 hbFont.x_scale = face->size->metrics.x_scale; | 231 hbFont.x_scale = face->size->metrics.x_scale; |
222 hbFont.y_scale = face->size->metrics.y_scale; | 232 hbFont.y_scale = face->size->metrics.y_scale; |
223 | 233 |
224 HB_ShaperItem shaper_item; | |
225 shaper_item.kerning_applied = false; | 234 shaper_item.kerning_applied = false; |
226 shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData()); | 235 shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData()); |
227 shaper_item.stringLength = str.length(); | 236 shaper_item.stringLength = str.length(); |
228 shaper_item.item.script = script; | 237 shaper_item.item.script = script; |
229 shaper_item.item.pos = 0; | 238 shaper_item.item.pos = 0; |
230 shaper_item.item.length = shaper_item.stringLength; | 239 shaper_item.item.length = shaper_item.stringLength; |
231 shaper_item.item.bidiLevel = 0; // ### | 240 shaper_item.item.bidiLevel = 0; // ### |
232 shaper_item.shaperFlags = 0; | 241 shaper_item.shaperFlags = 0; |
233 shaper_item.font = &hbFont; | 242 shaper_item.font = &hbFont; |
234 shaper_item.face = hbFace; | 243 shaper_item.face = hbFace; |
235 shaper_item.num_glyphs = shaper_item.item.length; | 244 shaper_item.num_glyphs = shaper_item.item.length; |
236 shaper_item.glyphIndicesPresent = false; | 245 shaper_item.glyphIndicesPresent = false; |
237 shaper_item.initialGlyphCount = 0; | 246 shaper_item.initialGlyphCount = 0; |
238 | 247 |
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 | 248 |
245 while (1) { | 249 while (1) { |
246 hb_glyphs.resize(shaper_item.num_glyphs); | 250 hb_glyphs.resize(shaper_item.num_glyphs); |
247 hb_attributes.resize(shaper_item.num_glyphs); | 251 hb_attributes.resize(shaper_item.num_glyphs); |
248 hb_advances.resize(shaper_item.num_glyphs); | 252 hb_advances.resize(shaper_item.num_glyphs); |
249 hb_offsets.resize(shaper_item.num_glyphs); | 253 hb_offsets.resize(shaper_item.num_glyphs); |
250 hb_logClusters.resize(shaper_item.num_glyphs); | 254 hb_logClusters.resize(shaper_item.num_glyphs); |
251 | 255 |
252 memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph)); | 256 memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph)); |
253 memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAt
tributes)); | 257 memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAt
tributes)); |
254 memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed)); | 258 memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed)); |
255 memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint)); | 259 memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint)); |
256 | 260 |
257 shaper_item.glyphs = hb_glyphs.data(); | 261 shaper_item.glyphs = hb_glyphs.data(); |
258 shaper_item.attributes = hb_attributes.data(); | 262 shaper_item.attributes = hb_attributes.data(); |
259 shaper_item.advances = hb_advances.data(); | 263 shaper_item.advances = hb_advances.data(); |
260 shaper_item.offsets = hb_offsets.data(); | 264 shaper_item.offsets = hb_offsets.data(); |
261 shaper_item.log_clusters = hb_logClusters.data(); | 265 shaper_item.log_clusters = hb_logClusters.data(); |
262 | 266 |
263 if (HB_ShapeItem(&shaper_item)) | 267 if (HB_ShapeItem(&shaper_item)) |
264 break; | 268 break; |
265 | |
266 } | 269 } |
267 | 270 |
268 HB_FreeFace(hbFace); | 271 HB_FreeFace(hbFace); |
| 272 } |
| 273 |
| 274 |
| 275 static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch) |
| 276 { |
| 277 QString uc = QString().append(ch); |
| 278 Shaper shaper(face, script, uc); |
| 279 |
| 280 uc = uc.normalized(QString::NormalizationForm_D); |
| 281 Shaper decomposed(face, script, uc); |
| 282 |
| 283 if( shaper.shaper_item.num_glyphs != decomposed.shaper_item.num_glyphs ) |
| 284 goto error; |
| 285 |
| 286 for (unsigned int i = 0; i < shaper.shaper_item.num_glyphs; ++i) { |
| 287 if ((shaper.shaper_item.glyphs[i]&0xffffff) != (decomposed.shaper_item.g
lyphs[i]&0xffffff)) |
| 288 goto error; |
| 289 } |
| 290 return true; |
| 291 error: |
| 292 QString str = ""; |
| 293 int i = 0; |
| 294 while (i < uc.length()) { |
| 295 str += QString("%1 ").arg(uc[i].unicode(), 4, 16); |
| 296 ++i; |
| 297 } |
| 298 qDebug("%s: decomposedShaping of char %4x failed\n decomposedString: %s\n
nglyphs=%d, decomposed nglyphs %d", |
| 299 face->family_name, |
| 300 ch.unicode(), str.toLatin1().data(), |
| 301 shaper.shaper_item.num_glyphs, |
| 302 decomposed.shaper_item.num_glyphs); |
| 303 |
| 304 str = ""; |
| 305 i = 0; |
| 306 while (i < shaper.shaper_item.num_glyphs) { |
| 307 str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16); |
| 308 ++i; |
| 309 } |
| 310 qDebug(" composed glyph result = %s", str.toLatin1().constData()); |
| 311 str = ""; |
| 312 i = 0; |
| 313 while (i < decomposed.shaper_item.num_glyphs) { |
| 314 str += QString("%1 ").arg(decomposed.shaper_item.glyphs[i], 4, 16); |
| 315 ++i; |
| 316 } |
| 317 qDebug(" decomposed glyph result = %s", str.toLatin1().constData()); |
| 318 return false; |
| 319 } |
| 320 |
| 321 struct ShapeTable { |
| 322 unsigned short unicode[16]; |
| 323 unsigned short glyphs[16]; |
| 324 }; |
| 325 |
| 326 static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script) |
| 327 { |
| 328 Shaper shaper(face, script, QString::fromUtf16( s->unicode )); |
269 | 329 |
270 hb_uint32 nglyphs = 0; | 330 hb_uint32 nglyphs = 0; |
271 const unsigned short *g = s->glyphs; | 331 const unsigned short *g = s->glyphs; |
272 while ( *g ) { | 332 while ( *g ) { |
273 nglyphs++; | 333 nglyphs++; |
274 g++; | 334 g++; |
275 } | 335 } |
276 | 336 |
277 if( nglyphs != shaper_item.num_glyphs ) | 337 if( nglyphs != shaper.shaper_item.num_glyphs ) |
278 goto error; | 338 goto error; |
279 | 339 |
280 for (hb_uint32 i = 0; i < nglyphs; ++i) { | 340 for (hb_uint32 i = 0; i < nglyphs; ++i) { |
281 » if ((shaper_item.glyphs[i]&0xffffff) != s->glyphs[i]) | 341 if ((shaper.shaper_item.glyphs[i]&0xffffff) != s->glyphs[i]) |
282 goto error; | 342 goto error; |
283 } | 343 } |
284 return true; | 344 return true; |
285 error: | 345 error: |
286 str = ""; | 346 QString str = ""; |
287 const unsigned short *uc = s->unicode; | 347 const unsigned short *uc = s->unicode; |
288 while (*uc) { | 348 while (*uc) { |
289 str += QString("%1 ").arg(*uc, 4, 16); | 349 str += QString("%1 ").arg(*uc, 4, 16); |
290 ++uc; | 350 ++uc; |
291 } | 351 } |
292 qDebug("%s: shaping of string %s failed, nglyphs=%d, expected %d", | 352 qDebug("%s: shaping of string %s failed, nglyphs=%d, expected %d", |
293 face->family_name, | 353 face->family_name, |
294 str.toLatin1().constData(), | 354 str.toLatin1().constData(), |
295 shaper_item.num_glyphs, nglyphs); | 355 shaper.shaper_item.num_glyphs, nglyphs); |
296 | 356 |
297 str = ""; | 357 str = ""; |
298 hb_uint32 i = 0; | 358 hb_uint32 i = 0; |
299 while (i < shaper_item.num_glyphs) { | 359 while (i < shaper.shaper_item.num_glyphs) { |
300 » str += QString("%1 ").arg(shaper_item.glyphs[i], 4, 16); | 360 str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16); |
301 ++i; | 361 ++i; |
302 } | 362 } |
303 qDebug(" glyph result = %s", str.toLatin1().constData()); | 363 qDebug(" glyph result = %s", str.toLatin1().constData()); |
304 return false; | 364 return false; |
305 } | 365 } |
306 | 366 |
| 367 |
| 368 void tst_QScriptEngine::greek() |
| 369 { |
| 370 FT_Face face = loadFace("DejaVuSans.ttf"); |
| 371 if (face) { |
| 372 for (int uc = 0x1f00; uc <= 0x1fff; ++uc) { |
| 373 QString str; |
| 374 str.append(uc); |
| 375 if (str.normalized(QString::NormalizationForm_D).normalized(QString:
:NormalizationForm_C) != str) { |
| 376 //qDebug() << "skipping" << hex << uc; |
| 377 continue; |
| 378 } |
| 379 if (uc == 0x1fc1 || uc == 0x1fed) |
| 380 continue; |
| 381 QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) ); |
| 382 } |
| 383 FT_Done_Face(face); |
| 384 } else { |
| 385 QSKIP("couln't find DejaVu Sans", SkipAll); |
| 386 } |
| 387 |
| 388 |
| 389 face = loadFace("SBL_grk.ttf"); |
| 390 if (face) { |
| 391 for (int uc = 0x1f00; uc <= 0x1fff; ++uc) { |
| 392 QString str; |
| 393 str.append(uc); |
| 394 if (str.normalized(QString::NormalizationForm_D).normalized(QString:
:NormalizationForm_C) != str) { |
| 395 //qDebug() << "skipping" << hex << uc; |
| 396 continue; |
| 397 } |
| 398 if (uc == 0x1fc1 || uc == 0x1fed) |
| 399 continue; |
| 400 QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) ); |
| 401 |
| 402 } |
| 403 |
| 404 const ShapeTable shape_table [] = { |
| 405 { { 0x3b1, 0x300, 0x313, 0x0 }, |
| 406 { 0xb8, 0x3d3, 0x3c7, 0x0 } }, |
| 407 { { 0x3b1, 0x313, 0x300, 0x0 }, |
| 408 { 0xd4, 0x0 } }, |
| 409 |
| 410 { {0}, {0} } |
| 411 }; |
| 412 |
| 413 |
| 414 const ShapeTable *s = shape_table; |
| 415 while (s->unicode[0]) { |
| 416 QVERIFY( shaping(face, s, HB_Script_Greek) ); |
| 417 ++s; |
| 418 } |
| 419 |
| 420 FT_Done_Face(face); |
| 421 } else { |
| 422 QSKIP("couln't find DejaVu Sans", SkipAll); |
| 423 } |
| 424 } |
| 425 |
| 426 |
307 void tst_QScriptEngine::devanagari() | 427 void tst_QScriptEngine::devanagari() |
308 { | 428 { |
309 { | 429 { |
310 FT_Face face = loadFace("raghu.ttf"); | 430 FT_Face face = loadFace("raghu.ttf"); |
311 if (face) { | 431 if (face) { |
312 const ShapeTable shape_table [] = { | 432 const ShapeTable shape_table [] = { |
313 // Ka | 433 // Ka |
314 { { 0x0915, 0x0 }, | 434 { { 0x0915, 0x0 }, |
315 { 0x0080, 0x0 } }, | 435 { 0x0080, 0x0 } }, |
316 // Ka Halant | 436 // Ka Halant |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 // Ra Halant Ka MatraAU | 623 // Ra Halant Ka MatraAU |
504 { { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 }, | 624 { { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 }, |
505 { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } }, | 625 { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } }, |
506 // Ra Halant Ba Halant Ba | 626 // Ra Halant Ba Halant Ba |
507 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 }, | 627 { { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 }, |
508 { 0x0232, 0x0276, 0x0 } }, | 628 { 0x0232, 0x0276, 0x0 } }, |
509 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 }, | 629 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 }, |
510 { 0x151, 0x276, 0x172, 0x143, 0x0 } }, | 630 { 0x151, 0x276, 0x172, 0x143, 0x0 } }, |
511 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 }, | 631 { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 }, |
512 { 0x151, 0x276, 0x172, 0x144, 0x0 } }, | 632 { 0x151, 0x276, 0x172, 0x144, 0x0 } }, |
| 633 // test decomposed two parts matras |
| 634 { { 0x995, 0x9c7, 0x9be, 0x0 }, |
| 635 { 0x179, 0x151, 0x172, 0x0 } }, |
| 636 { { 0x995, 0x9c7, 0x9d7, 0x0 }, |
| 637 { 0x179, 0x151, 0x17e, 0x0 } }, |
| 638 { { 0x9b0, 0x9cd, 0x9ad, 0x0 }, |
| 639 { 0x168, 0x276, 0x0 } }, |
| 640 { { 0x9f0, 0x9cd, 0x9ad, 0x0 }, |
| 641 { 0x168, 0x276, 0x0 } }, |
| 642 { { 0x9f1, 0x9cd, 0x9ad, 0x0 }, |
| 643 { 0x191, 0x17d, 0x168, 0x0 } }, |
513 | 644 |
514 { {0}, {0} } | 645 { {0}, {0} } |
515 }; | 646 }; |
516 | 647 |
517 | 648 |
518 const ShapeTable *s = shape_table; | 649 const ShapeTable *s = shape_table; |
519 while (s->unicode[0]) { | 650 while (s->unicode[0]) { |
520 QVERIFY( shaping(face, s, HB_Script_Bengali) ); | 651 QVERIFY( shaping(face, s, HB_Script_Bengali) ); |
521 ++s; | 652 ++s; |
522 } | 653 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 FT_Done_Face(face); | 762 FT_Done_Face(face); |
632 } else { | 763 } else { |
633 QSKIP("couln't find MuktiNarrow.ttf", SkipAll); | 764 QSKIP("couln't find MuktiNarrow.ttf", SkipAll); |
634 } | 765 } |
635 } | 766 } |
636 { | 767 { |
637 FT_Face face = loadFace("LikhanNormal.ttf"); | 768 FT_Face face = loadFace("LikhanNormal.ttf"); |
638 if (face) { | 769 if (face) { |
639 const ShapeTable shape_table [] = { | 770 const ShapeTable shape_table [] = { |
640 { { 0x09a8, 0x09cd, 0x09af, 0x0 }, | 771 { { 0x09a8, 0x09cd, 0x09af, 0x0 }, |
641 » » { 0x0192, 0x0 } }, | 772 { 0x01ca, 0x0 } }, |
642 { { 0x09b8, 0x09cd, 0x09af, 0x0 }, | 773 { { 0x09b8, 0x09cd, 0x09af, 0x0 }, |
643 » » { 0x01d6, 0x0 } }, | 774 { 0x020e, 0x0 } }, |
644 { { 0x09b6, 0x09cd, 0x09af, 0x0 }, | 775 { { 0x09b6, 0x09cd, 0x09af, 0x0 }, |
645 » » { 0x01bc, 0x0 } }, | 776 { 0x01f4, 0x0 } }, |
646 { { 0x09b7, 0x09cd, 0x09af, 0x0 }, | 777 { { 0x09b7, 0x09cd, 0x09af, 0x0 }, |
647 » » { 0x01c6, 0x0 } }, | 778 { 0x01fe, 0x0 } }, |
648 { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 }, | 779 { { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 }, |
649 » » { 0xd3, 0x12f, 0x0 } }, | 780 { 0x10b, 0x167, 0x0 } }, |
| 781 { { 0x9b0, 0x9cd, 0x9ad, 0x0 }, |
| 782 { 0xa1, 0x167, 0x0 } }, |
| 783 { { 0x9f0, 0x9cd, 0x9ad, 0x0 }, |
| 784 { 0xa1, 0x167, 0x0 } }, |
| 785 { { 0x9f1, 0x9cd, 0x9ad, 0x0 }, |
| 786 { 0x11c, 0xa1, 0x0 } }, |
650 | 787 |
651 { {0}, {0} } | 788 { {0}, {0} } |
652 }; | 789 }; |
653 | 790 |
654 | 791 |
655 const ShapeTable *s = shape_table; | 792 const ShapeTable *s = shape_table; |
656 while (s->unicode[0]) { | 793 while (s->unicode[0]) { |
657 QVERIFY( shaping(face, s, HB_Script_Bengali) ); | 794 QVERIFY( shaping(face, s, HB_Script_Bengali) ); |
658 ++s; | 795 ++s; |
659 } | 796 } |
660 | 797 |
661 FT_Done_Face(face); | 798 FT_Done_Face(face); |
662 } else { | 799 } else { |
663 QSKIP("couln't find LikhanNormal.ttf", SkipAll); | 800 QSKIP("couln't find LikhanNormal.ttf", SkipAll); |
664 } | 801 } |
665 } | 802 } |
666 } | 803 } |
667 | 804 |
668 void tst_QScriptEngine::gurmukhi() | 805 void tst_QScriptEngine::gurmukhi() |
669 { | 806 { |
670 { | 807 { |
671 FT_Face face = loadFace("lohit.punjabi.1.1.ttf"); | 808 FT_Face face = loadFace("lohit_pa.ttf"); |
672 if (face) { | 809 if (face) { |
673 const ShapeTable shape_table [] = { | 810 const ShapeTable shape_table [] = { |
674 { { 0xA15, 0xA4D, 0xa39, 0x0 }, | 811 { { 0xA15, 0xA4D, 0xa39, 0x0 }, |
675 { 0x3b, 0x8b, 0x0 } }, | 812 { 0x3b, 0x8b, 0x0 } }, |
676 { {0}, {0} } | 813 { {0}, {0} } |
677 }; | 814 }; |
678 | 815 |
679 | 816 |
680 const ShapeTable *s = shape_table; | 817 const ShapeTable *s = shape_table; |
681 while (s->unicode[0]) { | 818 while (s->unicode[0]) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0x0 }, | 953 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0x0 }, |
817 { 0xbb, 0xb2, 0x0 } }, | 954 { 0xbb, 0xb2, 0x0 } }, |
818 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0x0 }, | 955 { { 0xc15, 0xc4d, 0xc30, 0xc4d, 0xc15, 0x0 }, |
819 { 0x5a, 0xb2, 0x83, 0x0 } }, | 956 { 0x5a, 0xb2, 0x83, 0x0 } }, |
820 { { 0xc15, 0xc4d, 0xc30, 0xc3f, 0x0 }, | 957 { { 0xc15, 0xc4d, 0xc30, 0xc3f, 0x0 }, |
821 { 0xe2, 0xb2, 0x0 } }, | 958 { 0xe2, 0xb2, 0x0 } }, |
822 { { 0xc15, 0xc4d, 0xc15, 0xc48, 0x0 }, | 959 { { 0xc15, 0xc4d, 0xc15, 0xc48, 0x0 }, |
823 { 0xe6, 0xb3, 0x83, 0x0 } }, | 960 { 0xe6, 0xb3, 0x83, 0x0 } }, |
824 { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 }, | 961 { { 0xc15, 0xc4d, 0xc30, 0xc48, 0x0 }, |
825 { 0xe6, 0xb3, 0x9f, 0x0 } }, | 962 { 0xe6, 0xb3, 0x9f, 0x0 } }, |
826 » » { {0}, {0} } | 963 { { 0xc15, 0xc46, 0xc56, 0x0 }, |
827 | 964 { 0xe6, 0xb3, 0x0 } }, |
| 965 { {0}, {0} } |
828 }; | 966 }; |
829 | 967 |
830 const ShapeTable *s = shape_table; | 968 const ShapeTable *s = shape_table; |
831 while (s->unicode[0]) { | 969 while (s->unicode[0]) { |
832 QVERIFY( shaping(face, s, HB_Script_Telugu) ); | 970 QVERIFY( shaping(face, s, HB_Script_Telugu) ); |
833 ++s; | 971 ++s; |
834 } | 972 } |
835 | 973 |
836 FT_Done_Face(face); | 974 FT_Done_Face(face); |
837 } else { | 975 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
860 { { 0x0cb5, 0x0ccb, 0x0 }, | 998 { { 0x0cb5, 0x0ccb, 0x0 }, |
861 { 0x015f, 0x0067, 0x0 } }, | 999 { 0x015f, 0x0067, 0x0 } }, |
862 { { 0x0cb0, 0x0ccd, 0x0cae, 0x0 }, | 1000 { { 0x0cb0, 0x0ccd, 0x0cae, 0x0 }, |
863 { 0x004e, 0x0082, 0x0 } }, | 1001 { 0x004e, 0x0082, 0x0 } }, |
864 { { 0x0cb0, 0x0ccd, 0x0c95, 0x0 }, | 1002 { { 0x0cb0, 0x0ccd, 0x0c95, 0x0 }, |
865 { 0x0036, 0x0082, 0x0 } }, | 1003 { 0x0036, 0x0082, 0x0 } }, |
866 { { 0x0c95, 0x0ccd, 0x0cb0, 0x0 }, | 1004 { { 0x0c95, 0x0ccd, 0x0cb0, 0x0 }, |
867 { 0x0036, 0x00c1, 0x0 } }, | 1005 { 0x0036, 0x00c1, 0x0 } }, |
868 { { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 }, | 1006 { { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 }, |
869 { 0x0050, 0x00a7, 0x0 } }, | 1007 { 0x0050, 0x00a7, 0x0 } }, |
870 | |
871 { {0}, {0} } | 1008 { {0}, {0} } |
872 }; | 1009 }; |
873 | 1010 |
874 | 1011 |
875 const ShapeTable *s = shape_table; | 1012 const ShapeTable *s = shape_table; |
876 while (s->unicode[0]) { | 1013 while (s->unicode[0]) { |
877 QVERIFY( shaping(face, s, HB_Script_Kannada) ); | 1014 QVERIFY( shaping(face, s, HB_Script_Kannada) ); |
878 ++s; | 1015 ++s; |
879 } | 1016 } |
880 | 1017 |
881 FT_Done_Face(face); | 1018 FT_Done_Face(face); |
882 } else { | 1019 } else { |
883 QSKIP("couln't find Sampige.ttf", SkipAll); | 1020 QSKIP("couln't find Sampige.ttf", SkipAll); |
884 } | 1021 } |
885 } | 1022 } |
886 { | 1023 { |
887 FT_Face face = loadFace("tunga.ttf"); | 1024 FT_Face face = loadFace("tunga.ttf"); |
888 if (face) { | 1025 if (face) { |
889 const ShapeTable shape_table [] = { | 1026 const ShapeTable shape_table [] = { |
890 { { 0x0cb7, 0x0cc6, 0x0 }, | 1027 { { 0x0cb7, 0x0cc6, 0x0 }, |
891 { 0x00b0, 0x006c, 0x0 } }, | 1028 { 0x00b0, 0x006c, 0x0 } }, |
892 { { 0x0cb7, 0x0ccd, 0x0 }, | 1029 { { 0x0cb7, 0x0ccd, 0x0 }, |
893 { 0x0163, 0x0 } }, | 1030 { 0x0163, 0x0 } }, |
| 1031 { { 0xc95, 0xcbf, 0xcd5, 0x0 }, |
| 1032 { 0x114, 0x73, 0x0 } }, |
| 1033 { { 0xc95, 0xcc6, 0xcd5, 0x0 }, |
| 1034 { 0x90, 0x6c, 0x73, 0x0 } }, |
| 1035 { { 0xc95, 0xcc6, 0xcd6, 0x0 }, |
| 1036 { 0x90, 0x6c, 0x74, 0x0 } }, |
| 1037 { { 0xc95, 0xcc6, 0xcc2, 0x0 }, |
| 1038 { 0x90, 0x6c, 0x69, 0x0 } }, |
| 1039 { { 0xc95, 0xcca, 0xcd5, 0x0 }, |
| 1040 { 0x90, 0x6c, 0x69, 0x73, 0x0 } }, |
| 1041 |
894 | 1042 |
895 { {0}, {0} } | 1043 { {0}, {0} } |
896 }; | 1044 }; |
897 | 1045 |
898 | 1046 |
899 const ShapeTable *s = shape_table; | 1047 const ShapeTable *s = shape_table; |
900 while (s->unicode[0]) { | 1048 while (s->unicode[0]) { |
901 QVERIFY( shaping(face, s, HB_Script_Kannada) ); | 1049 QVERIFY( shaping(face, s, HB_Script_Kannada) ); |
902 ++s; | 1050 ++s; |
903 } | 1051 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 { { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 }, | 1084 { { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 }, |
937 { 0x0069, 0x0 } }, | 1085 { 0x0069, 0x0 } }, |
938 { { 0x0d26, 0x0d4d, 0x0d26, 0x0 }, | 1086 { { 0x0d26, 0x0d4d, 0x0d26, 0x0 }, |
939 { 0x0074, 0x0 } }, | 1087 { 0x0074, 0x0 } }, |
940 { { 0x0d30, 0x0d4d, 0x0 }, | 1088 { { 0x0d30, 0x0d4d, 0x0 }, |
941 { 0x009e, 0x0 } }, | 1089 { 0x009e, 0x0 } }, |
942 { { 0x0d30, 0x0d4d, 0x200c, 0x0 }, | 1090 { { 0x0d30, 0x0d4d, 0x200c, 0x0 }, |
943 { 0x009e, 0x0 } }, | 1091 { 0x009e, 0x0 } }, |
944 { { 0x0d30, 0x0d4d, 0x200d, 0x0 }, | 1092 { { 0x0d30, 0x0d4d, 0x200d, 0x0 }, |
945 { 0x009e, 0x0 } }, | 1093 { 0x009e, 0x0 } }, |
946 | 1094 { { 0xd15, 0xd46, 0xd3e, 0x0 }, |
| 1095 { 0x5e, 0x34, 0x58, 0x0 } }, |
| 1096 { { 0xd15, 0xd47, 0xd3e, 0x0 }, |
| 1097 { 0x5f, 0x34, 0x58, 0x0 } }, |
| 1098 { { 0xd15, 0xd46, 0xd57, 0x0 }, |
| 1099 { 0x5e, 0x34, 0x65, 0x0 } }, |
| 1100 { { 0xd15, 0xd57, 0x0 }, |
| 1101 { 0x34, 0x65, 0x0 } }, |
| 1102 { { 0xd1f, 0xd4d, 0xd1f, 0xd41, 0xd4d, 0x0 }, |
| 1103 { 0x69, 0x5b, 0x64, 0x0 } }, |
947 | 1104 |
948 { {0}, {0} } | 1105 { {0}, {0} } |
949 }; | 1106 }; |
950 | 1107 |
951 | 1108 |
952 const ShapeTable *s = shape_table; | 1109 const ShapeTable *s = shape_table; |
953 while (s->unicode[0]) { | 1110 while (s->unicode[0]) { |
954 QVERIFY( shaping(face, s, HB_Script_Malayalam) ); | 1111 QVERIFY( shaping(face, s, HB_Script_Malayalam) ); |
955 ++s; | 1112 ++s; |
956 } | 1113 } |
957 | 1114 |
958 FT_Done_Face(face); | 1115 FT_Done_Face(face); |
959 } else { | 1116 } else { |
960 QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll); | 1117 QSKIP("couln't find AkrutiMal2Normal.ttf", SkipAll); |
961 } | 1118 } |
962 } | 1119 } |
| 1120 |
| 1121 { |
| 1122 FT_Face face = loadFace("Rachana.ttf"); |
| 1123 if (face) { |
| 1124 const ShapeTable shape_table [] = { |
| 1125 { { 0xd37, 0xd4d, 0xd1f, 0xd4d, 0xd30, 0xd40, 0x0 }, |
| 1126 { 0x385, 0xa3, 0x0 } }, |
| 1127 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, |
| 1128 { 0x2ff, 0x0 } }, |
| 1129 { { 0xd33, 0xd4d, 0xd33, 0x0 }, |
| 1130 { 0x3f8, 0x0 } }, |
| 1131 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, |
| 1132 { 0x2ff, 0x0 } }, |
| 1133 { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 }, |
| 1134 { 0xf3, 0x350, 0x0 } }, |
| 1135 |
| 1136 { {0}, {0} } |
| 1137 }; |
| 1138 |
| 1139 |
| 1140 const ShapeTable *s = shape_table; |
| 1141 while (s->unicode[0]) { |
| 1142 QVERIFY( shaping(face, s, HB_Script_Malayalam) ); |
| 1143 ++s; |
| 1144 } |
| 1145 |
| 1146 FT_Done_Face(face); |
| 1147 } else { |
| 1148 QSKIP("couln't find Rachana.ttf", SkipAll); |
| 1149 } |
| 1150 } |
| 1151 |
| 1152 } |
| 1153 |
| 1154 void tst_QScriptEngine::sinhala() |
| 1155 { |
| 1156 { |
| 1157 FT_Face face = loadFace("FM-MalithiUW46.ttf"); |
| 1158 if (face) { |
| 1159 const ShapeTable shape_table [] = { |
| 1160 { { 0xd9a, 0xdd9, 0xdcf, 0x0 }, |
| 1161 { 0x4a, 0x61, 0x42, 0x0 } }, |
| 1162 { { 0xd9a, 0xdd9, 0xddf, 0x0 }, |
| 1163 { 0x4a, 0x61, 0x50, 0x0 } }, |
| 1164 { { 0xd9a, 0xdd9, 0xdca, 0x0 }, |
| 1165 { 0x4a, 0x62, 0x0 } }, |
| 1166 { { 0xd9a, 0xddc, 0xdca, 0x0 }, |
| 1167 { 0x4a, 0x61, 0x42, 0x41, 0x0 } }, |
| 1168 { { 0xd9a, 0xdda, 0x0 }, |
| 1169 { 0x4a, 0x62, 0x0 } }, |
| 1170 { { 0xd9a, 0xddd, 0x0 }, |
| 1171 { 0x4a, 0x61, 0x42, 0x41, 0x0 } }, |
| 1172 { {0}, {0} } |
| 1173 }; |
| 1174 |
| 1175 const ShapeTable *s = shape_table; |
| 1176 while (s->unicode[0]) { |
| 1177 QVERIFY( shaping(face, s, HB_Script_Sinhala) ); |
| 1178 ++s; |
| 1179 } |
| 1180 |
| 1181 FT_Done_Face(face); |
| 1182 } else { |
| 1183 QSKIP("couln't find FM-MalithiUW46.ttf", SkipAll); |
| 1184 } |
| 1185 } |
963 } | 1186 } |
964 | 1187 |
965 | 1188 |
966 | |
967 void tst_QScriptEngine::khmer() | 1189 void tst_QScriptEngine::khmer() |
968 { | 1190 { |
969 { | 1191 { |
970 FT_Face face = loadFace("KhmerOS.ttf"); | 1192 FT_Face face = loadFace("KhmerOS.ttf"); |
971 if (face) { | 1193 if (face) { |
972 const ShapeTable shape_table [] = { | 1194 const ShapeTable shape_table [] = { |
973 { { 0x179a, 0x17cd, 0x0 }, | 1195 { { 0x179a, 0x17cd, 0x0 }, |
974 { 0x24c, 0x27f, 0x0 } }, | 1196 { 0x24c, 0x27f, 0x0 } }, |
975 { { 0x179f, 0x17c5, 0x0 }, | 1197 { { 0x179f, 0x17c5, 0x0 }, |
976 { 0x273, 0x203, 0x0 } }, | 1198 { 0x273, 0x203, 0x0 } }, |
(...skipping 21 matching lines...) Expand all Loading... |
998 ++s; | 1220 ++s; |
999 } | 1221 } |
1000 | 1222 |
1001 FT_Done_Face(face); | 1223 FT_Done_Face(face); |
1002 } else { | 1224 } else { |
1003 QSKIP("couln't find KhmerOS.ttf", SkipAll); | 1225 QSKIP("couln't find KhmerOS.ttf", SkipAll); |
1004 } | 1226 } |
1005 } | 1227 } |
1006 } | 1228 } |
1007 | 1229 |
| 1230 void tst_QScriptEngine::nko() |
| 1231 { |
| 1232 { |
| 1233 FT_Face face = loadFace("DejaVuSans.ttf"); |
| 1234 if (face) { |
| 1235 const ShapeTable shape_table [] = { |
| 1236 { { 0x7ca, 0x0 }, |
| 1237 { 0x5c1, 0x0 } }, |
| 1238 { { 0x7ca, 0x7ca, 0x0 }, |
| 1239 { 0x14db, 0x14d9, 0x0 } }, |
| 1240 { { 0x7ca, 0x7fa, 0x7ca, 0x0 }, |
| 1241 { 0x14db, 0x5ec, 0x14d9, 0x0 } }, |
| 1242 { { 0x7ca, 0x7f3, 0x7ca, 0x0 }, |
| 1243 { 0x14db, 0x5e7, 0x14d9, 0x0 } }, |
| 1244 { { 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0x0 }, |
| 1245 { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0x0 } }, |
| 1246 { {0}, {0} } |
| 1247 }; |
| 1248 |
| 1249 |
| 1250 const ShapeTable *s = shape_table; |
| 1251 while (s->unicode[0]) { |
| 1252 QVERIFY( shaping(face, s, HB_Script_Nko) ); |
| 1253 ++s; |
| 1254 } |
| 1255 |
| 1256 FT_Done_Face(face); |
| 1257 } else { |
| 1258 QSKIP("couln't find DejaVuSans.ttf", SkipAll); |
| 1259 } |
| 1260 } |
| 1261 } |
| 1262 |
| 1263 |
1008 void tst_QScriptEngine::linearB() | 1264 void tst_QScriptEngine::linearB() |
1009 { | 1265 { |
1010 { | 1266 { |
1011 FT_Face face = loadFace("PENUTURE.TTF"); | 1267 FT_Face face = loadFace("penuture.ttf"); |
1012 if (face) { | 1268 if (face) { |
1013 const ShapeTable shape_table [] = { | 1269 const ShapeTable shape_table [] = { |
1014 { { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03, 0 }, | 1270 { { 0xd800, 0xdc01, 0xd800, 0xdc02, 0xd800, 0xdc03, 0 }, |
1015 { 0x5, 0x6, 0x7, 0 } }, | 1271 { 0x5, 0x6, 0x7, 0 } }, |
1016 { {0}, {0} } | 1272 { {0}, {0} } |
1017 }; | 1273 }; |
1018 | 1274 |
1019 | 1275 |
1020 const ShapeTable *s = shape_table; | 1276 const ShapeTable *s = shape_table; |
1021 while (s->unicode[0]) { | 1277 while (s->unicode[0]) { |
1022 QVERIFY( shaping(face, s, HB_Script_Common) ); | 1278 QVERIFY( shaping(face, s, HB_Script_Common) ); |
1023 ++s; | 1279 ++s; |
1024 } | 1280 } |
1025 | 1281 |
1026 FT_Done_Face(face); | 1282 FT_Done_Face(face); |
1027 } else { | 1283 } else { |
1028 QSKIP("couln't find PENUTURE.TTF", SkipAll); | 1284 QSKIP("couln't find PENUTURE.TTF", SkipAll); |
1029 } | 1285 } |
1030 } | 1286 } |
1031 } | 1287 } |
1032 | 1288 |
1033 | 1289 |
1034 QTEST_MAIN(tst_QScriptEngine) | 1290 QTEST_MAIN(tst_QScriptEngine) |
1035 #include "main.moc" | 1291 #include "main.moc" |
OLD | NEW |