summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2012-04-19 13:36:59 +0200
committerQt by Nokia <qt-info@nokia.com>2012-04-20 10:29:14 +0200
commitca5918c8b8e0d4388b574cb019e6b770e7342884 (patch)
treef1db9f30bf7a12dd9bb6988724b16d22a581ddec /src/gui
parent528cb10d5395692d9dd1975e51faca636d87c9e7 (diff)
Retain bidirectional marks when eliding text
When the text contains unicode markers for bidirectional text, these will not affect the width of the text, but they might affects its layout. Thus, we need to retain these markers in the elided text to avoid the layout of the string changing when its allocated width changes. Task-number: QTBUG-3768 Change-Id: I3866c32cd1dcd5fff2b8fa5b25ae89e551531a97 Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/text/qtextengine.cpp46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index ec7dc57314..9848898d66 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2329,6 +2329,42 @@ static inline bool prevCharJoins(const QString &string, int pos)
return (joining == QChar::Dual || joining == QChar::Center);
}
+static bool isRetainableControlCode(const QChar &c)
+{
+ return (c.unicode() == 0x202a // LRE
+ || c.unicode() == 0x202b // LRE
+ || c.unicode() == 0x202c // PDF
+ || c.unicode() == 0x202d // LRO
+ || c.unicode() == 0x202e // RLO
+ || c.unicode() == 0x200e // LRM
+ || c.unicode() == 0x200f); // RLM
+}
+
+static QString stringMidRetainingBidiCC(const QString &string,
+ const QString &ellidePrefix,
+ const QString &ellideSuffix,
+ int subStringFrom,
+ int subStringTo,
+ int midStart,
+ int midLength)
+{
+ QString prefix;
+ for (int i=subStringFrom; i<midStart; ++i) {
+ QChar c = string.at(i);
+ if (isRetainableControlCode(c))
+ prefix += c;
+ }
+
+ QString suffix;
+ for (int i=midStart + midLength; i<subStringTo; ++i) {
+ QChar c = string.at(i);
+ if (isRetainableControlCode(c))
+ suffix += c;
+ }
+
+ return prefix + ellidePrefix + string.mid(midStart, midLength) + ellideSuffix + suffix;
+}
+
QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags, int from, int count) const
{
// qDebug() << "elidedText; available width" << width.toReal() << "text width:" << this->width(0, layoutData->string.length()).toReal();
@@ -2440,7 +2476,10 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (nextCharJoins(layoutData->string, pos))
ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
- return layoutData->string.mid(from, pos - from) + ellipsisText;
+ return stringMidRetainingBidiCC(layoutData->string,
+ QString(), ellipsisText,
+ from, to,
+ from, pos - from);
} else if (mode == Qt::ElideLeft) {
QFixed currentWidth;
int pos;
@@ -2460,7 +2499,10 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (prevCharJoins(layoutData->string, pos))
ellipsisText.append(QChar(0x200d) /* ZWJ */);
- return ellipsisText + layoutData->string.mid(pos, to - pos);
+ return stringMidRetainingBidiCC(layoutData->string,
+ ellipsisText, QString(),
+ from, to,
+ pos, to - pos);
} else if (mode == Qt::ElideMiddle) {
QFixed leftWidth;
QFixed rightWidth;