summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-09-04 10:05:41 (GMT)
committerLars Knoll <lars.knoll@nokia.com>2009-09-04 10:09:13 (GMT)
commit19a65fca4af242269b354f82212556f88eb03eaa (patch)
tree5dd09a55f7aa2aabacc6747bcdcddcaaf850b4ef
parent41b52eb4ad4f19221577059ce1447121e757b112 (diff)
downloadQt-19a65fca4af242269b354f82212556f88eb03eaa.zip
Qt-19a65fca4af242269b354f82212556f88eb03eaa.tar.gz
Qt-19a65fca4af242269b354f82212556f88eb03eaa.tar.bz2
fix text eliding for arabic and syriac
Arabic and Syriac are connected scripts where the letter shape changes depending on the context. Text eliding should not affect that letter shape if the truncation happens in the middle of a word. The patch ensures that by adding a Unicode ZWJ character between the text and the eliding in case the character would connect in the full string. Reviewed-by: Simon Hausmann
-rw-r--r--src/gui/text/qtextengine.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 2b84c6c..ba9145e 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2245,6 +2245,28 @@ void QTextEngine::indexAdditionalFormats()
}
}
+/* These two helper functions are used to determine whether we need to insert a ZWJ character
+ between the text that gets truncated and the ellipsis. This is important to get
+ correctly shaped results for arabic text.
+*/
+static bool nextCharJoins(const QString &string, int pos)
+{
+ while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing)
+ ++pos;
+ if (pos == string.length())
+ return false;
+ return string.at(pos).joining() != QChar::OtherJoining;
+}
+
+static bool prevCharJoins(const QString &string, int pos)
+{
+ while (pos > 0 && string.at(pos - 1).category() == QChar::Mark_NonSpacing)
+ --pos;
+ if (pos == 0)
+ return false;
+ return (string.at(pos - 1).joining() == QChar::Dual || string.at(pos - 1).joining() == QChar::Center);
+}
+
QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags) const
{
// qDebug() << "elidedText; available width" << width.toReal() << "text width:" << this->width(0, layoutData->string.length()).toReal();
@@ -2345,6 +2367,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
} while (nextBreak < layoutData->string.length()
&& currentWidth < availableWidth);
+ if (nextCharJoins(layoutData->string, pos))
+ ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
+
return layoutData->string.left(pos) + ellipsisText;
} else if (mode == Qt::ElideLeft) {
QFixed currentWidth;
@@ -2362,6 +2387,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
} while (nextBreak > 0
&& currentWidth < availableWidth);
+ if (prevCharJoins(layoutData->string, pos))
+ ellipsisText.append(QChar(0x200d) /* ZWJ */);
+
return ellipsisText + layoutData->string.mid(pos);
} else if (mode == Qt::ElideMiddle) {
QFixed leftWidth;
@@ -2391,6 +2419,11 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
&& nextRightBreak > 0
&& leftWidth + rightWidth < availableWidth);
+ if (nextCharJoins(layoutData->string, leftPos))
+ ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
+ if (prevCharJoins(layoutData->string, rightPos))
+ ellipsisText.append(QChar(0x200d) /* ZWJ */);
+
return layoutData->string.left(leftPos) + ellipsisText + layoutData->string.mid(rightPos);
}