Changeset 769 for trunk/src/3rdparty/harfbuzz
- Timestamp:
- Aug 2, 2010, 9:27:30 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.6.3 (added) merged: 768 /branches/vendor/nokia/qt/current merged: 767 /branches/vendor/nokia/qt/4.6.2 removed
- Property svn:mergeinfo changed
-
trunk/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
r561 r769 1108 1108 #ifndef NO_OPENTYPE 1109 1109 static const HB_OpenTypeFeature indic_features[] = { 1110 { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty }, 1110 1111 { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, 1111 1112 { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, … … 1116 1117 { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty }, 1117 1118 { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty }, 1119 { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty }, 1118 1120 { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty }, 1119 1121 { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty }, … … 1122 1124 { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty }, 1123 1125 { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty }, 1126 { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty }, 1124 1127 { 0, 0 } 1125 1128 }; … … 1149 1152 QString res; 1150 1153 properties = ~properties; 1154 if (properties & LocaProperty) 1155 res += "Loca "; 1151 1156 if (properties & CcmpProperty) 1152 1157 res += "Ccmp "; … … 1169 1174 if (properties & PostFormProperty) 1170 1175 res += "PostForm "; 1176 if (properties & ConjunctFormProperty) 1177 res += "PostForm "; 1171 1178 if (properties & VattuProperty) 1172 1179 res += "Vattu "; … … 1183 1190 if (properties & CligProperty) 1184 1191 res += "Clig "; 1192 if (properties & IndicCaltProperty) 1193 res += "Calt "; 1185 1194 return res; 1186 1195 } … … 1297 1306 int skipped = 0; 1298 1307 Position pos = Post; 1299 for (i = len-1; i > base; i--) {1308 for (i = len-1; i >= base; i--) { 1300 1309 if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada)) 1301 1310 continue; 1311 1312 if (i < len-1 && position[i] == Control && position[i+1] == Consonant) { 1313 base = i+1; 1314 break; 1315 } 1302 1316 1303 1317 Position charPosition = indic_position(uc[i]); … … 1546 1560 // features we should always apply 1547 1561 for (i = 0; i < len; ++i) 1548 properties[i] = ~(CcmpProperty 1562 properties[i] = ~(LocaProperty 1563 | CcmpProperty 1549 1564 | NuktaProperty 1550 1565 | VattuProperty 1566 | ConjunctFormProperty 1551 1567 | PreSubstProperty 1552 1568 | BelowSubstProperty … … 1554 1570 | PostSubstProperty 1555 1571 | HalantProperty 1572 | IndicCaltProperty 1556 1573 | PositioningProperties); 1557 1574 1575 // Loca always applies 1558 1576 // Ccmp always applies 1559 1577 // Init … … 1612 1630 // psts always applies 1613 1631 // halant always applies 1632 // calt always applies 1614 1633 1615 1634 #ifdef INDIC_DEBUG -
trunk/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h
r2 r769 58 58 59 59 typedef enum { 60 CcmpProperty = 0x1, 61 InitProperty = 0x2, 62 IsolProperty = 0x4, 63 FinaProperty = 0x8, 64 MediProperty = 0x10, 65 RligProperty = 0x20, 66 CaltProperty = 0x40, 67 LigaProperty = 0x80, 68 DligProperty = 0x100, 69 CswhProperty = 0x200, 70 MsetProperty = 0x400, 60 LocaProperty = 0x1, 61 CcmpProperty = 0x2, 62 InitProperty = 0x4, 63 IsolProperty = 0x8, 64 FinaProperty = 0x10, 65 MediProperty = 0x20, 66 RligProperty = 0x40, 67 CaltProperty = 0x80, 68 LigaProperty = 0x100, 69 DligProperty = 0x200, 70 CswhProperty = 0x400, 71 MsetProperty = 0x800, 71 72 72 73 /* used by indic and myanmar shaper */ 73 NuktaProperty = 0x4, 74 AkhantProperty = 0x8, 75 RephProperty = 0x10, 76 PreFormProperty = 0x20, 77 BelowFormProperty = 0x40, 78 AboveFormProperty = 0x80, 79 HalfFormProperty = 0x100, 80 PostFormProperty = 0x200, 81 VattuProperty = 0x400, 82 PreSubstProperty = 0x800, 83 BelowSubstProperty = 0x1000, 84 AboveSubstProperty = 0x2000, 85 PostSubstProperty = 0x4000, 86 HalantProperty = 0x8000, 87 CligProperty = 0x10000 74 NuktaProperty = 0x8, 75 AkhantProperty = 0x10, 76 RephProperty = 0x20, 77 PreFormProperty = 0x40, 78 BelowFormProperty = 0x80, 79 AboveFormProperty = 0x100, 80 HalfFormProperty = 0x200, 81 PostFormProperty = 0x400, 82 ConjunctFormProperty = 0x800, 83 VattuProperty = 0x1000, 84 PreSubstProperty = 0x2000, 85 BelowSubstProperty = 0x4000, 86 AboveSubstProperty = 0x8000, 87 PostSubstProperty = 0x10000, 88 HalantProperty = 0x20000, 89 CligProperty = 0x40000, 90 IndicCaltProperty = 0x80000 88 91 89 92 } HB_OpenTypeProperty; -
trunk/src/3rdparty/harfbuzz/tests/shaping/main.cpp
r561 r769 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 // ### … … 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 147 return 0; // #### … … 170 170 void cleanupTestCase(); 171 171 private slots: 172 void greek(); 173 172 174 void devanagari(); 173 175 void bengali(); … … 204 206 } 205 207 206 struct ShapeTable { 207 unsigned short unicode[16]; 208 unsigned short glyphs[16]; 208 class Shaper 209 { 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 209 221 }; 210 222 211 static bool shaping(FT_Face face, const ShapeTable *s, HB_Script script) 212 { 213 QString str = QString::fromUtf16( s->unicode ); 214 223 Shaper::Shaper(FT_Face face, HB_Script script, const QString &str) 224 { 215 225 HB_Face hbFace = HB_NewFace(face, hb_getSFntTable); 216 226 217 HB_FontRec hbFont;218 227 hbFont.klass = &hb_fontClass; 219 228 hbFont.userData = face; … … 223 232 hbFont.y_scale = face->size->metrics.y_scale; 224 233 225 HB_ShaperItem shaper_item;226 234 shaper_item.kerning_applied = false; 227 235 shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData()); … … 238 246 shaper_item.initialGlyphCount = 0; 239 247 240 QVarLengthArray<HB_Glyph> hb_glyphs(shaper_item.num_glyphs);241 QVarLengthArray<HB_GlyphAttributes> hb_attributes(shaper_item.num_glyphs);242 QVarLengthArray<HB_Fixed> hb_advances(shaper_item.num_glyphs);243 QVarLengthArray<HB_FixedPoint> hb_offsets(shaper_item.num_glyphs);244 QVarLengthArray<unsigned short> hb_logClusters(shaper_item.num_glyphs);245 248 246 249 while (1) { … … 264 267 if (HB_ShapeItem(&shaper_item)) 265 268 break; 266 267 269 } 268 270 269 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.glyphs[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 )); 270 329 271 330 hb_uint32 nglyphs = 0; … … 276 335 } 277 336 278 if( nglyphs != shaper _item.num_glyphs )337 if( nglyphs != shaper.shaper_item.num_glyphs ) 279 338 goto error; 280 339 281 340 for (hb_uint32 i = 0; i < nglyphs; ++i) { 282 if ((shaper_item.glyphs[i]&0xffffff) != s->glyphs[i])341 if ((shaper.shaper_item.glyphs[i]&0xffffff) != s->glyphs[i]) 283 342 goto error; 284 343 } 285 344 return true; 286 345 error: 287 str = "";346 QString str = ""; 288 347 const unsigned short *uc = s->unicode; 289 348 while (*uc) { … … 294 353 face->family_name, 295 354 str.toLatin1().constData(), 296 shaper _item.num_glyphs, nglyphs);355 shaper.shaper_item.num_glyphs, nglyphs); 297 356 298 357 str = ""; 299 358 hb_uint32 i = 0; 300 while (i < shaper _item.num_glyphs) {301 str += QString("%1 ").arg(shaper_item.glyphs[i], 4, 16);359 while (i < shaper.shaper_item.num_glyphs) { 360 str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16); 302 361 ++i; 303 362 } … … 305 364 return false; 306 365 } 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 307 426 308 427 void tst_QScriptEngine::devanagari() … … 1012 1131 { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, 1013 1132 { 0x2ff, 0x0 } }, 1133 { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 }, 1134 { 0xf3, 0x350, 0x0 } }, 1014 1135 1015 1136 { {0}, {0} }
Note:
See TracChangeset
for help on using the changeset viewer.