summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qchar.cpp63
-rw-r--r--src/corelib/tools/qchar.h28
-rw-r--r--src/corelib/tools/qstring.h12
-rw-r--r--src/gui/text/qtextengine.cpp8
-rw-r--r--tests/auto/corelib/tools/qchar/tst_qchar.cpp42
-rw-r--r--util/unicode/main.cpp62
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"