diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2014-01-26 02:42:37 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-29 23:19:47 +0100 |
commit | b80fcbdba62ec2324fa9ad29cbc5ac1d9a9fe8a2 (patch) | |
tree | 97a78ec35d3e66e0f2539490d8e112322adde7ce | |
parent | b04d87b2263fd5d9b2b57799098a2eb5a3c91dfc (diff) |
Introduce QChar::JoiningType enum and QChar::joiningType() method
This aimed to disctinct joining types "L", "T", and "U" from just "U".
Unicode 6.3.0 has introduced a character with joining type "L" and
Unicode 7.0 will add a few more characters of joining type "L", so
we'll have to deal with it anyways.
[ChangeLog][QtCore][QChar] Added JoiningType enum and joiningType()
method that deprecates the old QChar::Joining enum and joining() method.
Change-Id: I4be3a3f745d944e689feb9b62d4ca86d1cf371b0
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/tools/qchar.cpp | 63 | ||||
-rw-r--r-- | src/corelib/tools/qchar.h | 28 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 12 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 8 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qchar/tst_qchar.cpp | 42 | ||||
-rw-r--r-- | util/unicode/main.cpp | 62 |
6 files changed, 159 insertions, 56 deletions
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index f7f425d594..eb59cc719f 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -127,9 +127,9 @@ QT_BEGIN_NAMESPACE Separator_* or an exceptional code point from Other_Control category). QChar also provides direction(), which indicates the "natural" - writing direction of this character. The joining() function + writing direction of this character. The joiningType() function indicates how the character joins with it's neighbors (needed - mostly for Arabic) and finally hasMirrored(), which indicates + mostly for Arabic or Syriac) and finally hasMirrored(), which indicates whether the character needs to be mirrored when it is printed in it's "unnatural" writing direction. @@ -458,7 +458,29 @@ QT_BEGIN_NAMESPACE */ /*! + \enum QChar::JoiningType + since 5.3 + + This enum type defines the Unicode joining type attributes. See the + \l{http://www.unicode.org/}{Unicode Standard} for a description of the values. + + In order to conform to C/C++ naming conventions "Joining_" is prepended + to the codes used in the Unicode Standard. + + \value Joining_None + \value Joining_Causing + \value Joining_Dual + \value Joining_Right + \value Joining_Left + \value Joining_Transparent + + \sa joiningType() +*/ + +#if QT_DEPRECATED_SINCE(5, 3) +/*! \enum QChar::Joining + \deprecated in 5.3, use JoiningType instead. This enum type defines the Unicode joining attributes. See the \l{http://www.unicode.org/}{Unicode Standard} for a description @@ -471,6 +493,7 @@ QT_BEGIN_NAMESPACE \sa joining() */ +#endif /*! \enum QChar::CombiningClass @@ -1053,7 +1076,32 @@ QChar::Direction QChar::direction(uint ucs4) } /*! + \fn QChar::JoiningType QChar::joiningType() const + \since 5.3 + + Returns information about the joining type attributes of the character + (needed for certain languages such as Arabic or Syriac). +*/ + +/*! + \overload + \since 5.3 + + Returns information about the joining type attributes of the UCS-4-encoded + character specified by \a ucs4 + (needed for certain languages such as Arabic or Syriac). +*/ +QChar::JoiningType QChar::joiningType(uint ucs4) +{ + if (ucs4 > LastValidCodePoint) + return QChar::Joining_None; + return QChar::JoiningType(qGetProp(ucs4)->joining); +} + +#if QT_DEPRECATED_SINCE(5, 3) +/*! \fn QChar::Joining QChar::joining() const + \deprecated in 5.3, use joiningType() instead. Returns information about the joining properties of the character (needed for certain languages such as Arabic). @@ -1061,6 +1109,8 @@ QChar::Direction QChar::direction(uint ucs4) /*! \overload + \deprecated in 5.3, use joiningType() instead. + Returns information about the joining properties of the UCS-4-encoded character specified by \a ucs4 (needed for certain languages such as Arabic). */ @@ -1068,8 +1118,15 @@ QChar::Joining QChar::joining(uint ucs4) { if (ucs4 > LastValidCodePoint) return QChar::OtherJoining; - return (QChar::Joining) qGetProp(ucs4)->joining; + switch (qGetProp(ucs4)->joining) { + case QChar::Joining_Causing: return QChar::Center; + case QChar::Joining_Dual: return QChar::Dual; + case QChar::Joining_Right: return QChar::Right; + default: break; + } + return QChar::OtherJoining; } +#endif /*! \fn bool QChar::hasMirrored() const diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 82ff337341..266effb66a 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -288,10 +288,21 @@ public: Fraction }; + enum JoiningType { + Joining_None, + Joining_Causing, + Joining_Dual, + Joining_Right, + Joining_Left, + Joining_Transparent + }; + +#if QT_DEPRECATED_SINCE(5, 3) enum Joining { OtherJoining, Dual, Right, Center }; +#endif enum CombiningClass { @@ -340,7 +351,17 @@ public: inline Category category() const { return QChar::category(ucs); } inline Direction direction() const { return QChar::direction(ucs); } - inline Joining joining() const { return QChar::joining(ucs); } + inline JoiningType joiningType() const { return QChar::joiningType(ucs); } +#if QT_DEPRECATED_SINCE(5, 3) + QT_DEPRECATED inline Joining joining() const { + switch (QChar::joiningType(ucs)) { + case QChar::Joining_Causing: return QChar::Center; + case QChar::Joining_Dual: return QChar::Dual; + case QChar::Joining_Right: return QChar::Right; + default: return QChar::OtherJoining; + } + } +#endif inline unsigned char combiningClass() const { return QChar::combiningClass(ucs); } inline QChar mirroredChar() const { return QChar::mirroredChar(ucs); } @@ -427,7 +448,10 @@ public: static Category QT_FASTCALL category(uint ucs4); static Direction QT_FASTCALL direction(uint ucs4); - static Joining QT_FASTCALL joining(uint ucs4); + static JoiningType QT_FASTCALL joiningType(uint ucs4); +#if QT_DEPRECATED_SINCE(5, 3) + QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4); +#endif static unsigned char QT_FASTCALL combiningClass(uint ucs4); static uint QT_FASTCALL mirroredChar(uint ucs4); diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 01ddf669f5..4432759b03 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -908,7 +908,17 @@ public: QChar::Category category() const { return QChar(*this).category(); } QChar::Direction direction() const { return QChar(*this).direction(); } - QChar::Joining joining() const { return QChar(*this).joining(); } + QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); } +#if QT_DEPRECATED_SINCE(5, 3) + QT_DEPRECATED QChar::Joining joining() const { + switch (QChar(*this).joiningType()) { + case QChar::Joining_Causing: return QChar::Center; + case QChar::Joining_Dual: return QChar::Dual; + case QChar::Joining_Right: return QChar::Right; + default: return QChar::OtherJoining; + } + } +#endif bool hasMirrored() const { return QChar(*this).hasMirrored(); } QChar mirroredChar() const { return QChar(*this).mirroredChar(); } QString decomposition() const { return QChar(*this).decomposition(); } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 109b7e600f..6c985e2eac 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2537,8 +2537,8 @@ static inline bool nextCharJoins(const QString &string, int pos) ++pos; if (pos == string.length()) return false; - // ### U+A872 has joining type L - return string.at(pos) == QChar(0xA872) || string.at(pos).joining() != QChar::OtherJoining; + QChar::JoiningType joining = string.at(pos).joiningType(); + return joining != QChar::Joining_None && joining != QChar::Joining_Transparent; } static inline bool prevCharJoins(const QString &string, int pos) @@ -2547,8 +2547,8 @@ static inline bool prevCharJoins(const QString &string, int pos) --pos; if (pos == 0) return false; - QChar::Joining joining = string.at(pos - 1).joining(); - return (joining == QChar::Dual || joining == QChar::Center); + QChar::JoiningType joining = string.at(pos - 1).joiningType(); + return joining == QChar::Joining_Dual || joining == QChar::Joining_Causing; } static inline bool isRetainableControlCode(QChar c) diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp index 80b4162156..81409eb866 100644 --- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp +++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp @@ -74,7 +74,7 @@ private slots: void isSpaceSpecial(); void category(); void direction(); - void joining(); + void joiningType(); void combiningClass(); void digitValue(); void mirroredChar(); @@ -483,30 +483,32 @@ void tst_QChar::direction() QVERIFY(QChar::direction(0x2FA17u) == QChar::DirL); } -void tst_QChar::joining() +void tst_QChar::joiningType() { - QVERIFY(QChar('a').joining() == QChar::OtherJoining); - QVERIFY(QChar('0').joining() == QChar::OtherJoining); - QVERIFY(QChar((ushort)0x627).joining() == QChar::Right); - QVERIFY(QChar((ushort)0x5d0).joining() == QChar::OtherJoining); + QVERIFY(QChar('a').joiningType() == QChar::Joining_None); + QVERIFY(QChar('0').joiningType() == QChar::Joining_None); + QVERIFY(QChar((ushort)0x0627).joiningType() == QChar::Joining_Right); + QVERIFY(QChar((ushort)0x05d0).joiningType() == QChar::Joining_None); + QVERIFY(QChar((ushort)0x00ad).joiningType() == QChar::Joining_Transparent); - QVERIFY(QChar::joining((ushort)'a') == QChar::OtherJoining); - QVERIFY(QChar::joining((ushort)'0') == QChar::OtherJoining); - QVERIFY(QChar::joining((ushort)0x627) == QChar::Right); - QVERIFY(QChar::joining((ushort)0x5d0) == QChar::OtherJoining); + QVERIFY(QChar::joiningType((ushort)'a') == QChar::Joining_None); + QVERIFY(QChar::joiningType((ushort)'0') == QChar::Joining_None); + QVERIFY(QChar::joiningType((ushort)0x0627) == QChar::Joining_Right); + QVERIFY(QChar::joiningType((ushort)0x05d0) == QChar::Joining_None); + QVERIFY(QChar::joiningType((ushort)0x00ad) == QChar::Joining_Transparent); - QVERIFY(QChar::joining((uint)'a') == QChar::OtherJoining); - QVERIFY(QChar::joining((uint)'0') == QChar::OtherJoining); - QVERIFY(QChar::joining((uint)0x627) == QChar::Right); - QVERIFY(QChar::joining((uint)0x5d0) == QChar::OtherJoining); + QVERIFY(QChar::joiningType((uint)'a') == QChar::Joining_None); + QVERIFY(QChar::joiningType((uint)'0') == QChar::Joining_None); + QVERIFY(QChar::joiningType((uint)0x0627) == QChar::Joining_Right); + QVERIFY(QChar::joiningType((uint)0x05d0) == QChar::Joining_None); + QVERIFY(QChar::joiningType((uint)0x00ad) == QChar::Joining_Transparent); - QVERIFY(QChar::joining(0xE01DAu) == QChar::OtherJoining); - QVERIFY(QChar::joining(0xf0000u) == QChar::OtherJoining); - QVERIFY(QChar::joining(0xE0030u) == QChar::OtherJoining); - QVERIFY(QChar::joining(0x2FA17u) == QChar::OtherJoining); + QVERIFY(QChar::joiningType(0xE01DAu) == QChar::Joining_Transparent); + QVERIFY(QChar::joiningType(0xf0000u) == QChar::Joining_None); + QVERIFY(QChar::joiningType(0xE0030u) == QChar::Joining_Transparent); + QVERIFY(QChar::joiningType(0x2FA17u) == QChar::Joining_None); - // ### U+A872 has joining type L - QVERIFY(QChar::joining((uint)0xA872) == QChar::OtherJoining); + QVERIFY(QChar::joiningType((uint)0xA872) == QChar::Joining_Left); } void tst_QChar::combiningClass() diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index 59b95ad924..4f941d0eb3 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -246,30 +246,30 @@ static void initDirectionMap() } -enum Joining { +enum JoiningType { Joining_None, - Joining_Left, Joining_Causing, Joining_Dual, Joining_Right, + Joining_Left, Joining_Transparent , Joining_Unassigned }; -static QHash<QByteArray, Joining> joining_map; +static QHash<QByteArray, JoiningType> joining_map; static void initJoiningMap() { struct JoiningList { - Joining joining; + JoiningType joining; const char *name; } joinings[] = { { Joining_None, "U" }, - { Joining_Left, "L" }, { Joining_Causing, "C" }, { Joining_Dual, "D" }, { Joining_Right, "R" }, + { Joining_Left, "L" }, { Joining_Transparent, "T" }, { Joining_Unassigned, 0 } }; @@ -719,8 +719,8 @@ static const char *property_string = " ushort category : 8; /* 5 used */\n" " ushort direction : 8; /* 5 used */\n" " ushort combiningClass : 8;\n" - " ushort joining : 2;\n" - " signed short digitValue : 6; /* 5 used */\n" + " ushort joining : 3;\n" + " signed short digitValue : 5; /* 5 used */\n" " signed short mirrorDiff : 16;\n" " signed short lowerCaseDiff : 16;\n" " signed short upperCaseDiff : 16;\n" @@ -792,7 +792,7 @@ struct PropertyFlags { QChar::Category category : 5; QChar::Direction direction : 5; // from ArabicShaping.txt - QChar::Joining joining : 2; + QChar::JoiningType joining : 3; // from DerivedAge.txt QChar::UnicodeVersion age : 4; int digitValue; @@ -944,7 +944,7 @@ struct UnicodeData { mirroredChar = 0; decompositionType = QChar::NoDecomposition; - p.joining = QChar::OtherJoining; + p.joining = QChar::Joining_None; p.age = QChar::Unicode_Unassigned; p.mirrorDiff = 0; p.digitValue = -1; @@ -1171,7 +1171,7 @@ static void readUnicodeData() if (d[0].contains('<')) { data.decompositionType = decompositionMap.value(d[0], QChar::NoDecomposition); if (data.decompositionType == QChar::NoDecomposition) - qFatal("unassigned decomposition type: %s", d[0].constData()); + qFatal("unhandled decomposition type: %s", d[0].constData()); d.takeFirst(); } else { data.decompositionType = QChar::Canonical; @@ -1261,24 +1261,34 @@ static void readArabicShaping() int codepoint = l[0].toInt(&ok, 16); Q_ASSERT(ok); - Joining joining = joining_map.value(l[2].trimmed(), Joining_Unassigned); - if (joining == Joining_Unassigned) - qFatal("unassigned or unhandled joining value: %s", l[2].constData()); + UnicodeData &d = UnicodeData::valueRef(codepoint); + JoiningType joining = joining_map.value(l[2].trimmed(), Joining_Unassigned); + switch (joining) { + case Joining_Unassigned: + qFatal("%x: unassigned or unhandled joining type: %s", codepoint, l[2].constData()); + break; + case Joining_Transparent: + if (d.p.category != QChar::Mark_NonSpacing && d.p.category != QChar::Mark_Enclosing && d.p.category != QChar::Other_Format) { + qFatal("%x: joining type '%s' was met; the current implementation needs to be revised!", + codepoint, l[2].constData()); + } + // fall through - if (joining == Joining_Left) { - qWarning("ACHTUNG!!! joining type '%s' has been met for U+%X; the current implementation needs to be revised!", - l[2].trimmed().constData(), codepoint); + default: + d.p.joining = QChar::JoiningType(joining); + break; } + } + // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U: + // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T. + // - All others not explicitly listed have joining type U. + for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) { UnicodeData &d = UnicodeData::valueRef(codepoint); - if (joining == Joining_Right) - d.p.joining = QChar::Right; - else if (joining == Joining_Dual) - d.p.joining = QChar::Dual; - else if (joining == Joining_Causing) - d.p.joining = QChar::Center; - else - d.p.joining = QChar::OtherJoining; + if (d.p.joining == QChar::Joining_None) { + if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format) + d.p.joining = QChar::Joining_Transparent; + } } } @@ -2332,10 +2342,10 @@ static QByteArray createPropertyInfo() // " ushort combiningClass : 8;\n" out += QByteArray::number( p.combiningClass ); out += ", "; -// " ushort joining : 2;\n" +// " ushort joining : 3;\n" out += QByteArray::number( p.joining ); out += ", "; -// " signed short digitValue : 6; /* 5 used */\n" +// " signed short digitValue : 5; /* 5 used */\n" out += QByteArray::number( p.digitValue ); out += ", "; // " signed short mirrorDiff : 16;\n" |