summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r--src/gui/text/qtextengine.cpp63
1 files changed, 58 insertions, 5 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 793ea4aa9e..9848898d66 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1755,12 +1755,19 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
font.setPixelSize((font.pixelSize() * 2) / 3);
scaledEngine = font.d->engineForScript(script);
}
- feCache.prevFontEngine = engine;
+
if (engine)
engine->ref.ref();
- feCache.prevScaledFontEngine = scaledEngine;
+ if (feCache.prevFontEngine)
+ releaseCachedFontEngine(feCache.prevFontEngine);
+ feCache.prevFontEngine = engine;
+
if (scaledEngine)
scaledEngine->ref.ref();
+ if (feCache.prevScaledFontEngine)
+ releaseCachedFontEngine(feCache.prevScaledFontEngine);
+ feCache.prevScaledFontEngine = scaledEngine;
+
feCache.prevScript = script;
feCache.prevPosition = si.position;
feCache.prevLength = length(&si);
@@ -1770,9 +1777,13 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
engine = feCache.prevFontEngine;
else {
engine = font.d->engineForScript(script);
- feCache.prevFontEngine = engine;
+
if (engine)
engine->ref.ref();
+ if (feCache.prevFontEngine)
+ releaseCachedFontEngine(feCache.prevFontEngine);
+ feCache.prevFontEngine = engine;
+
feCache.prevScript = script;
feCache.prevPosition = -1;
feCache.prevLength = -1;
@@ -2318,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();
@@ -2429,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;
@@ -2449,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;