📄 qscriptengine.cpp
字号:
return (ArabicGroup) arabic_group[uc-0x600]; else if (uc == 0x200d) return Center; else if (QChar::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 JCausing, // Center JCausing, // Kashida // Dual JDual, // Beh JDual, // Noon JDual, // Yeh JDual, // Hah JDual, // Seen JDual, // Tah JDual, // Ain // Right JRight, // Alef JRight, // Waw JRight, // Dal JRight, // Reh JRight // HamzaOnHehGoal};struct JoiningPair { QArabicShape form1; QArabicShape form2;};static const JoiningPair joining_table[5][4] =// None, Causing, Dual, Right{ { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, // XIsolated { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, // XFinal { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, // XInitial { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, // XMedial { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, // XCausing};/*According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp1. Find the priority of the connecting opportunities in each word2. Add expansion at the highest priority connection opportunity3. If more than one connection opportunity have the same highest value, use the opportunity closest to the end of the word.Following is a chart that provides the priority for connectionopportunities and where expansion occurs. The character group namesare those in table 6.6 of the UNICODE 2.0 book.PrioritY Glyph Condition Kashida LocationArabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida automatic kashida.Arabic_Seen Seen, Sad Connecting to the next character. After the character. (Initial or medial form).Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form of these characters.Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form Kaf and Gaf of these characters.Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial BaaArabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of these characters.Arabic_Normal Other connecting Connecting to previous character. Before the final form characters of these characters.This seems to imply that we have at most one kashida point per arabic word.*/void qt_getArabicProperties(const unsigned short *chars, int len, QArabicProperties *properties){// qDebug("arabicSyriacOpenTypeShape: properties:"); int lastPos = 0; int lastGroup = ArabicNone; ArabicGroup group = arabicGroup(chars[0]); Joining j = joining_for_group[group]; QArabicShape shape = joining_table[XIsolated][j].form2; properties[0].justification = QGlyphLayout::NoJustification; for (int i = 1; i < len; ++i) { // #### fix handling for spaces and punktuation properties[i].justification = QGlyphLayout::NoJustification; group = arabicGroup(chars[i]); j = joining_for_group[group]; if (j == JTransparent) { properties[i].shape = XIsolated; continue; } properties[lastPos].shape = joining_table[shape][j].form1; shape = joining_table[shape][j].form2; switch(lastGroup) { case Seen: if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial) properties[i-1].justification = QGlyphLayout::Arabic_Seen; break; case Hah: if (properties[lastPos].shape == XFinal) properties[lastPos-1].justification = QGlyphLayout::Arabic_HaaDal; break; case Alef: if (properties[lastPos].shape == XFinal) properties[lastPos-1].justification = QGlyphLayout::Arabic_Alef; break; case Ain: if (properties[lastPos].shape == XFinal) properties[lastPos-1].justification = QGlyphLayout::Arabic_Waw; break; case Noon: if (properties[lastPos].shape == XFinal) properties[lastPos-1].justification = QGlyphLayout::Arabic_Normal; break; case ArabicNone: break; default: Q_ASSERT(false); } lastGroup = ArabicNone; switch(group) { case ArabicNone: case Transparent: // ### Center should probably be treated as transparent when it comes to justification. case Center: break; case ArabicSpace: properties[i].justification = QGlyphLayout::Arabic_Space; break; case Kashida: properties[i].justification = QGlyphLayout::Arabic_Kashida; break; case Seen: lastGroup = Seen; break; case Hah: case Dal: lastGroup = Hah; break; case Alef: case Tah: lastGroup = Alef; break; case Yeh: case Reh: if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh) properties[lastPos-1].justification = QGlyphLayout::Arabic_BaRa; break; case Ain: case Waw: lastGroup = Ain; break; case Noon: case Beh: case HamzaOnHehGoal: lastGroup = Noon; break; case ArabicGroupsEnd: Q_ASSERT(false); } lastPos = i; } properties[lastPos].shape = joining_table[shape][JNone].form1;// for (int i = 0; i < len; ++i)// qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);}// The unicode to unicode shaping codec.// does only presentation forms B at the moment, but that should be enough for// simple displaystatic const ushort arabicUnicodeMapping[256][2] = { // base of shaped forms, and number-1 of them (0 for non shaping, // 1 for right binding and 3 for dual binding // These are just the glyphs available in Unicode, // some characters are in R class, but have no glyphs in Unicode. { 0x0600, 0 }, // 0x0600 { 0x0601, 0 }, // 0x0601 { 0x0602, 0 }, // 0x0602 { 0x0603, 0 }, // 0x0603 { 0x0604, 0 }, // 0x0604 { 0x0605, 0 }, // 0x0605 { 0x0606, 0 }, // 0x0606 { 0x0607, 0 }, // 0x0607 { 0x0608, 0 }, // 0x0608 { 0x0609, 0 }, // 0x0609 { 0x060A, 0 }, // 0x060A { 0x060B, 0 }, // 0x060B { 0x060C, 0 }, // 0x060C { 0x060D, 0 }, // 0x060D { 0x060E, 0 }, // 0x060E { 0x060F, 0 }, // 0x060F { 0x0610, 0 }, // 0x0610 { 0x0611, 0 }, // 0x0611 { 0x0612, 0 }, // 0x0612 { 0x0613, 0 }, // 0x0613 { 0x0614, 0 }, // 0x0614 { 0x0615, 0 }, // 0x0615 { 0x0616, 0 }, // 0x0616 { 0x0617, 0 }, // 0x0617 { 0x0618, 0 }, // 0x0618 { 0x0619, 0 }, // 0x0619 { 0x061A, 0 }, // 0x061A { 0x061B, 0 }, // 0x061B { 0x061C, 0 }, // 0x061C { 0x061D, 0 }, // 0x061D { 0x061E, 0 }, // 0x061E { 0x061F, 0 }, // 0x061F { 0x0620, 0 }, // 0x0620 { 0xFE80, 0 }, // 0x0621 HAMZA { 0xFE81, 1 }, // 0x0622 R ALEF WITH MADDA ABOVE { 0xFE83, 1 }, // 0x0623 R ALEF WITH HAMZA ABOVE { 0xFE85, 1 }, // 0x0624 R WAW WITH HAMZA ABOVE { 0xFE87, 1 }, // 0x0625 R ALEF WITH HAMZA BELOW { 0xFE89, 3 }, // 0x0626 D YEH WITH HAMZA ABOVE { 0xFE8D, 1 }, // 0x0627 R ALEF { 0xFE8F, 3 }, // 0x0628 D BEH { 0xFE93, 1 }, // 0x0629 R TEH MARBUTA { 0xFE95, 3 }, // 0x062A D TEH { 0xFE99, 3 }, // 0x062B D THEH { 0xFE9D, 3 }, // 0x062C D JEEM { 0xFEA1, 3 }, // 0x062D D HAH { 0xFEA5, 3 }, // 0x062E D KHAH { 0xFEA9, 1 }, // 0x062F R DAL { 0xFEAB, 1 }, // 0x0630 R THAL { 0xFEAD, 1 }, // 0x0631 R REH { 0xFEAF, 1 }, // 0x0632 R ZAIN { 0xFEB1, 3 }, // 0x0633 D SEEN { 0xFEB5, 3 }, // 0x0634 D SHEEN { 0xFEB9, 3 }, // 0x0635 D SAD { 0xFEBD, 3 }, // 0x0636 D DAD { 0xFEC1, 3 }, // 0x0637 D TAH { 0xFEC5, 3 }, // 0x0638 D ZAH { 0xFEC9, 3 }, // 0x0639 D AIN { 0xFECD, 3 }, // 0x063A D GHAIN { 0x063B, 0 }, // 0x063B { 0x063C, 0 }, // 0x063C { 0x063D, 0 }, // 0x063D { 0x063E, 0 }, // 0x063E { 0x063F, 0 }, // 0x063F { 0x0640, 0 }, // 0x0640 C TATWEEL // ### Join Causing, only one glyph { 0xFED1, 3 }, // 0x0641 D FEH { 0xFED5, 3 }, // 0x0642 D QAF { 0xFED9, 3 }, // 0x0643 D KAF { 0xFEDD, 3 }, // 0x0644 D LAM { 0xFEE1, 3 }, // 0x0645 D MEEM { 0xFEE5, 3 }, // 0x0646 D NOON { 0xFEE9, 3 }, // 0x0647 D HEH { 0xFEED, 1 }, // 0x0648 R WAW { 0x0649, 3 }, // 0x0649 ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code. { 0xFEF1, 3 }, // 0x064A D YEH { 0x064B, 0 }, // 0x064B { 0x064C, 0 }, // 0x064C { 0x064D, 0 }, // 0x064D { 0x064E, 0 }, // 0x064E { 0x064F, 0 }, // 0x064F { 0x0650, 0 }, // 0x0650 { 0x0651, 0 }, // 0x0651 { 0x0652, 0 }, // 0x0652 { 0x0653, 0 }, // 0x0653 { 0x0654, 0 }, // 0x0654 { 0x0655, 0 }, // 0x0655 { 0x0656, 0 }, // 0x0656 { 0x0657, 0 }, // 0x0657 { 0x0658, 0 }, // 0x0658 { 0x0659, 0 }, // 0x0659 { 0x065A, 0 }, // 0x065A { 0x065B, 0 }, // 0x065B { 0x065C, 0 }, // 0x065C { 0x065D, 0 }, // 0x065D { 0x065E, 0 }, // 0x065E { 0x065F, 0 }, // 0x065F { 0x0660, 0 }, // 0x0660 { 0x0661, 0 }, // 0x0661 { 0x0662, 0 }, // 0x0662 { 0x0663, 0 }, // 0x0663 { 0x0664, 0 }, // 0x0664 { 0x0665, 0 }, // 0x0665 { 0x0666, 0 }, // 0x0666 { 0x0667, 0 }, // 0x0667 { 0x0668, 0 }, // 0x0668 { 0x0669, 0 }, // 0x0669 { 0x066A, 0 }, // 0x066A { 0x066B, 0 }, // 0x066B { 0x066C, 0 }, // 0x066C { 0x066D, 0 }, // 0x066D { 0x066E, 0 }, // 0x066E { 0x066F, 0 }, // 0x066F { 0x0670, 0 }, // 0x0670
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -