📄 qscriptengine.cpp
字号:
const int availableGlyphs = item->num_glyphs; if (!item->font->stringToCMap(item->string->unicode()+item->from, item->length, item->glyphs, &item->num_glyphs, QFlag(item->flags))) return false; heuristicSetGlyphAttributes(item); openType->shape(item); return openType->positionAndAdd(item, availableGlyphs); }#endif enum { Dagesh = 0x5bc, ShinDot = 0x5c1, SinDot = 0x5c2, Patah = 0x5b7, Qamats = 0x5b8, Holam = 0x5b9, Rafe = 0x5bf }; unsigned short chars[512]; QChar *shapedChars = item->length > 256 ? (QChar *)::malloc(2*item->length * sizeof(QChar)) : (QChar *)chars; const QChar *uc = item->string->unicode() + item->from; unsigned short *logClusters = item->log_clusters; QGlyphLayout *glyphs = item->glyphs; *shapedChars = *uc; logClusters[0] = 0; int slen = 1; int cluster_start = 0; for (int i = 1; i < item->length; ++i) { ushort base = shapedChars[slen-1].unicode(); ushort shaped = 0; bool invalid = false; if (uc[i].unicode() == Dagesh) { if (base >= 0x5d0 && base <= 0x5ea && base != 0x5d7 && base != 0x5dd && base != 0x5df && base != 0x5e2 && base != 0x5e5) { shaped = base - 0x5d0 + 0xfb30; } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) { shaped = base + 2; } else { invalid = true; } } else if (uc[i].unicode() == ShinDot) { if (base == 0x05e9) shaped = 0xfb2a; else if (base == 0xfb49) shaped = 0xfb2c; else invalid = true; } else if (uc[i].unicode() == SinDot) { if (base == 0x05e9) shaped = 0xfb2b; else if (base == 0xfb49) shaped = 0xfb2d; else invalid = true; } else if (uc[i].unicode() == Patah) { if (base == 0x5d0) shaped = 0xfb2e; } else if (uc[i].unicode() == Qamats) { if (base == 0x5d0) shaped = 0xfb2f; } else if (uc[i].unicode() == Holam) { if (base == 0x5d5) shaped = 0xfb4b; } else if (uc[i].unicode() == Rafe) { if (base == 0x5d1) shaped = 0xfb4c; else if (base == 0x5db) shaped = 0xfb4d; else if (base == 0x5e4) shaped = 0xfb4e; } if (invalid) { shapedChars[slen] = 0x25cc; glyphs[slen].attributes.clusterStart = true; glyphs[slen].attributes.mark = false; glyphs[slen].attributes.combiningClass = 0; cluster_start = slen; ++slen; } if (shaped) { if (item->font->canRender((QChar *)&shaped, 1)) { shapedChars[slen-1] = QChar(shaped); } else shaped = 0; } if (!shaped) { shapedChars[slen] = uc[i]; if (::category(uc[i]) != QChar::Mark_NonSpacing) { glyphs[slen].attributes.clusterStart = true; glyphs[slen].attributes.mark = false; glyphs[slen].attributes.combiningClass = 0; glyphs[slen].attributes.dontPrint = qIsControlChar(uc[i].unicode()); cluster_start = slen; } else { glyphs[slen].attributes.clusterStart = false; glyphs[slen].attributes.mark = true; glyphs[slen].attributes.combiningClass = ::combiningClass(uc[i]); } ++slen; } logClusters[i] = cluster_start; } if (!item->font->stringToCMap(shapedChars, slen, glyphs, &item->num_glyphs, QFlag(item->flags))) { if (item->length > 256) ::free(shapedChars); return false; } for (int i = 0; i < item->num_glyphs; ++i) { if (glyphs[i].attributes.mark) { glyphs[i].advance.x = 0; } } qt_heuristicPosition(item); if (item->length > 256) ::free(shapedChars); return true;}#endif// these groups correspond to the groups defined in the Unicode standard.// Some of these groups are equal whith regards to both joining and line breaking behaviour,// and thus have the same enum value//// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as// I couldn't find any better document I'll hope for the best.enum ArabicGroup { // NonJoining ArabicNone, ArabicSpace, // Transparent Transparent, // Causing Center, Kashida, // Arabic // Dual Beh, Noon, Meem = Noon, Heh = Noon, KnottedHeh = Noon, HehGoal = Noon, SwashKaf = Noon, Yeh, Hah, Seen, Sad = Seen, Tah, Kaf = Tah, Gaf = Tah, Lam = Tah, Ain, Feh = Ain, Qaf = Ain, // Right Alef, Waw, Dal, TehMarbuta = Dal, Reh, HamzaOnHehGoal, YehWithTail = HamzaOnHehGoal, YehBarre = HamzaOnHehGoal, // Syriac // Dual Beth = Beh, Gamal = Ain, Heth = Noon, Teth = Hah, Yudh = Noon, Kaph = Noon, Lamadh = Lam, Mim = Noon, Nun = Noon, Semakh = Noon, FinalSemakh = Noon, SyriacE = Ain, Pe = Ain, ReversedPe = Hah, Qaph = Noon, Shin = Noon, Fe = Ain, // Right Alaph = Alef, Dalath = Dal, He = Dal, SyriacWaw = Waw, Zain = Alef, YudhHe = Waw, Sadhe = HamzaOnHehGoal, Taw = Dal, // Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1. Dummy = HamzaOnHehGoal, ArabicGroupsEnd};static const unsigned char arabic_group[0x150] = { ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, Alef, Alef, Waw, Alef, Yeh, Alef, Beh, TehMarbuta, Beh, Beh, Hah, Hah, Hah, Dal, Dal, Reh, Reh, Seen, Seen, Sad, Sad, Tah, Tah, Ain, Ain, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, // 0x640 Kashida, Feh, Qaf, Kaf, Lam, Meem, Noon, Heh, Waw, Yeh, Yeh, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, Beh, Qaf, Transparent, Alef, Alef, Alef, ArabicNone, Alef, Waw, Waw, Yeh, Beh, Beh, Beh, Beh, Beh, Beh, Beh, // 0x680 Beh, Hah, Hah, Hah, Hah, Hah, Hah, Hah, Dal, Dal, Dal, Dal, Dal, Dal, Dal, Dal, Dal, Reh, Reh, Reh, Reh, Reh, Reh, Reh, Reh, Reh, Seen, Seen, Seen, Sad, Sad, Tah, Ain, Feh, Feh, Feh, Feh, Feh, Feh, Qaf, Qaf, Gaf, SwashKaf, Gaf, Kaf, Kaf, Kaf, Gaf, Gaf, Gaf, Gaf, Gaf, Gaf, Lam, Lam, Lam, Lam, Noon, Noon, Noon, Noon, Noon, KnottedHeh, Hah, // 0x6c0 TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal, Waw, Waw, Waw, Waw, Waw, Waw, Waw, Waw, Yeh, YehWithTail, Yeh, Waw, Yeh, Yeh, YehBarre, YehBarre, ArabicNone, TehMarbuta, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, ArabicNone, ArabicNone, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, ArabicNone, ArabicNone, Transparent, Transparent, ArabicNone, Transparent, Transparent, Transparent, Transparent, Dal, Reh, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, Seen, Sad, Ain, ArabicNone, ArabicNone, KnottedHeh, // 0x700 ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, ArabicNone, Alaph, Transparent, Beth, Gamal, Gamal, Dalath, Dalath, He, SyriacWaw, Zain, Heth, Teth, Teth, Yudh, YudhHe, Kaph, Lamadh, Mim, Nun, Semakh, FinalSemakh, SyriacE, Pe, ReversedPe, Sadhe, Qaph, Dalath, Shin, Taw, Beth, Gamal, Dalath, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, Transparent, ArabicNone, ArabicNone, Zain, Kaph, Fe,};static inline ArabicGroup arabicGroup(unsigned short uc){ if (uc >= 0x0600 && uc < 0x750) return (ArabicGroup) arabic_group[uc-0x600]; else if (uc == 0x200d) return Center; else if (::category(uc) == QChar::Separator_Space) return ArabicSpace; else return ArabicNone;}/* Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on arabic). Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent). transparent joining is not encoded in QChar::joining(), but applies to all combining marks and format marks. Right join-causing: dual + center Left join-causing: dual + right + center Rules are as follows (for a string already in visual order, as we have it here): R1 Transparent characters do not affect joining behaviour. R2 A right joining character, that has a right join-causing char on the right will get form XRight (R3 A left joining character, that has a left join-causing char on the left will get form XLeft) Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on the right will get form XMedial R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left will get form XRight R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right will get form XLeft R7 Otherwise the character will get form XIsolated Additionally we have to do the minimal ligature support for lam-alef ligatures: L1 Transparent characters do not affect ligature behaviour. L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft) L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated) The state table below handles rules R1-R7.*/enum Joining { JNone, JCausing, JDual, JRight, JTransparent};static const Joining joining_for_group[ArabicGroupsEnd] = { // NonJoining JNone, // ArabicNone JNone, // ArabicSpace // Transparent JTransparent, // Transparent // Causing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -