diff options
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r-- | src/gui/text/qtextengine.cpp | 63 |
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; |