diff options
Diffstat (limited to 'src/gui/text/qtextengine.cpp')
-rw-r--r-- | src/gui/text/qtextengine.cpp | 280 |
1 files changed, 165 insertions, 115 deletions
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index c6da4b8f4a..cb945b73ce 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -7,6 +7,7 @@ #include "qtextformat_p.h" #include "qtextengine_p.h" #include "qabstracttextdocumentlayout.h" +#include "qabstracttextdocumentlayout_p.h" #include "qtextlayout.h" #include "qtextboundaryfinder.h" #include <QtCore/private/qunicodetables_p.h> @@ -35,15 +36,10 @@ public: Itemizer(const QString &string, const QScriptAnalysis *analysis, QScriptItemArray &items) : m_string(string), m_analysis(analysis), - m_items(items), - m_splitter(nullptr) + m_items(items) { } - ~Itemizer() - { - delete m_splitter; - } - + ~Itemizer() = default; /// generate the script items /// The caps parameter is used to choose the algorithm of splitting text and assigning roles to the textitems void generate(int start, int length, QFont::Capitalization caps) @@ -100,8 +96,8 @@ private: return; if (!m_splitter) - m_splitter = new QTextBoundaryFinder(QTextBoundaryFinder::Word, - m_string.constData(), m_string.length(), + m_splitter = std::make_unique<QTextBoundaryFinder>(QTextBoundaryFinder::Word, + m_string.constData(), m_string.size(), /*buffer*/nullptr, /*buffer size*/0); m_splitter->setPosition(start); @@ -170,7 +166,7 @@ private: const QString &m_string; const QScriptAnalysis * const m_analysis; QScriptItemArray &m_items; - QTextBoundaryFinder *m_splitter; + std::unique_ptr<QTextBoundaryFinder> m_splitter; }; // ----------------------------------------------------------------------------------------------------- @@ -1395,8 +1391,7 @@ void QTextEngine::shapeText(int item) const } if (Q_UNLIKELY(!ensureSpace(itemLength))) { - Q_UNREACHABLE(); // ### report OOM error somehow - return; + Q_UNREACHABLE_RETURN(); // ### report OOM error somehow } QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading); @@ -1404,6 +1399,7 @@ void QTextEngine::shapeText(int item) const bool kerningEnabled; bool letterSpacingIsAbsolute; bool shapingEnabled = false; + QHash<QFont::Tag, quint32> features; QFixed letterSpacing, wordSpacing; #ifndef QT_NO_RAWFONT if (useRawFont) { @@ -1417,6 +1413,7 @@ void QTextEngine::shapeText(int item) const wordSpacing = QFixed::fromReal(font.wordSpacing()); letterSpacing = QFixed::fromReal(font.letterSpacing()); letterSpacingIsAbsolute = true; + features = font.d->features; } else #endif { @@ -1429,6 +1426,7 @@ void QTextEngine::shapeText(int item) const letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute; letterSpacing = font.d->letterSpacing; wordSpacing = font.d->wordSpacing; + features = font.d->features; if (letterSpacingIsAbsolute && letterSpacing.value()) letterSpacing *= font.d->dpi / qt_defaultDpiY(); @@ -1436,8 +1434,7 @@ void QTextEngine::shapeText(int item) const // split up the item into parts that come from different font engines // k * 3 entries, array[k] == index in string, array[k + 1] == index in glyphs, array[k + 2] == engine index - QList<uint> itemBoundaries; - itemBoundaries.reserve(24); + QVarLengthArray<uint, 24> itemBoundaries; QGlyphLayout initialGlyphs = availableGlyphs(&si); int nGlyphs = initialGlyphs.numGlyphs; @@ -1457,9 +1454,9 @@ void QTextEngine::shapeText(int item) const for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) { const uint engineIdx = initialGlyphs.glyphs[glyph_pos] >> 24; if (lastEngine != engineIdx) { - itemBoundaries.append(i); - itemBoundaries.append(glyph_pos); - itemBoundaries.append(engineIdx); + itemBoundaries.push_back(i); + itemBoundaries.push_back(glyph_pos); + itemBoundaries.push_back(engineIdx); if (engineIdx != 0) { QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); @@ -1475,14 +1472,21 @@ void QTextEngine::shapeText(int item) const ++i; } } else { - itemBoundaries.append(0); - itemBoundaries.append(0); - itemBoundaries.append(0); + itemBoundaries.push_back(0); + itemBoundaries.push_back(0); + itemBoundaries.push_back(0); } #if QT_CONFIG(harfbuzz) if (Q_LIKELY(shapingEnabled)) { - si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled, letterSpacing != 0); + si.num_glyphs = shapeTextWithHarfbuzzNG(si, + string, + itemLength, + fontEngine, + itemBoundaries, + kerningEnabled, + letterSpacing != 0, + features); } else #endif { @@ -1592,9 +1596,10 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, - const QList<uint> &itemBoundaries, + QSpan<uint> itemBoundaries, bool kerningEnabled, - bool hasLetterSpacing) const + bool hasLetterSpacing, + const QHash<QFont::Tag, quint32> &fontFeatures) const { uint glyphs_shaped = 0; @@ -1613,7 +1618,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, // ### TODO get_default_for_script? props.language = hb_language_get_default(); // use default language from locale - for (int k = 0; k < itemBoundaries.size(); k += 3) { + for (qsizetype k = 0; k < itemBoundaries.size(); k += 3) { const uint item_pos = itemBoundaries[k]; const uint item_length = (k + 4 < itemBoundaries.size() ? itemBoundaries[k + 3] : itemLength) - item_pos; const uint engineIdx = itemBoundaries[k + 2]; @@ -1648,14 +1653,24 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, || script == QChar::Script_Khmer || script == QChar::Script_Nko); bool dontLigate = hasLetterSpacing && !scriptRequiresOpenType; - const hb_feature_t features[5] = { - { HB_TAG('k','e','r','n'), !!kerningEnabled, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END }, - { HB_TAG('l','i','g','a'), false, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END }, - { HB_TAG('c','l','i','g'), false, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END }, - { HB_TAG('d','l','i','g'), false, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END }, - { HB_TAG('h','l','i','g'), false, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END } - }; - const int num_features = dontLigate ? 5 : 1; + + QHash<QFont::Tag, quint32> features; + features.insert(QFont::Tag("kern"), !!kerningEnabled); + if (dontLigate) { + features.insert(QFont::Tag("liga"), false); + features.insert(QFont::Tag("clig"), false); + features.insert(QFont::Tag("dlig"), false); + features.insert(QFont::Tag("hlig"), false); + } + features.insert(fontFeatures); + + QVarLengthArray<hb_feature_t, 16> featureArray; + for (auto it = features.constBegin(); it != features.constEnd(); ++it) { + featureArray.append({ it.key().value(), + it.value(), + HB_FEATURE_GLOBAL_START, + HB_FEATURE_GLOBAL_END }); + } // whitelist cross-platforms shapers only static const char *shaper_list[] = { @@ -1665,7 +1680,11 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, nullptr }; - bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, shaper_list); + bool shapedOk = hb_shape_full(hb_font, + buffer, + featureArray.constData(), + features.size(), + shaper_list); if (Q_UNLIKELY(!shapedOk)) { hb_buffer_destroy(buffer); return 0; @@ -1675,9 +1694,14 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, hb_buffer_reverse(buffer); } - const uint num_glyphs = hb_buffer_get_length(buffer); + uint num_glyphs = hb_buffer_get_length(buffer); + const bool has_glyphs = num_glyphs > 0; + // If Harfbuzz returns zero glyphs, we have to manually add a missing glyph + if (Q_UNLIKELY(!has_glyphs)) + num_glyphs = 1; + // ensure we have enough space for shaped glyphs and metrics - if (Q_UNLIKELY(num_glyphs == 0 || !ensureSpace(glyphs_shaped + num_glyphs))) { + if (Q_UNLIKELY(!ensureSpace(glyphs_shaped + num_glyphs))) { hb_buffer_destroy(buffer); return 0; } @@ -1685,35 +1709,44 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, // fetch the shaped glyphs and metrics QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs); ushort *log_clusters = logClusters(&si) + item_pos; - - hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, nullptr); - hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, nullptr); - uint str_pos = 0; - uint last_cluster = ~0u; - uint last_glyph_pos = glyphs_shaped; - for (uint i = 0; i < num_glyphs; ++i, ++infos, ++positions) { - g.glyphs[i] = infos->codepoint; - - g.advances[i] = QFixed::fromFixed(positions->x_advance); - g.offsets[i].x = QFixed::fromFixed(positions->x_offset); - g.offsets[i].y = QFixed::fromFixed(positions->y_offset); - - uint cluster = infos->cluster; - if (Q_LIKELY(last_cluster != cluster)) { - g.attributes[i].clusterStart = true; - - // fix up clusters so that the cluster indices will be monotonic - // and thus we never return out-of-order indices - while (last_cluster++ < cluster && str_pos < item_length) - log_clusters[str_pos++] = last_glyph_pos; - last_glyph_pos = i + glyphs_shaped; - last_cluster = cluster; - - applyVisibilityRules(string[item_pos + str_pos], &g, i, actualFontEngine); + if (Q_LIKELY(has_glyphs)) { + hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, nullptr); + hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, nullptr); + uint str_pos = 0; + uint last_cluster = ~0u; + uint last_glyph_pos = glyphs_shaped; + for (uint i = 0; i < num_glyphs; ++i, ++infos, ++positions) { + g.glyphs[i] = infos->codepoint; + + g.advances[i] = QFixed::fromFixed(positions->x_advance); + g.offsets[i].x = QFixed::fromFixed(positions->x_offset); + g.offsets[i].y = QFixed::fromFixed(positions->y_offset); + + uint cluster = infos->cluster; + if (Q_LIKELY(last_cluster != cluster)) { + g.attributes[i].clusterStart = true; + + // fix up clusters so that the cluster indices will be monotonic + // and thus we never return out-of-order indices + while (last_cluster++ < cluster && str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; + last_glyph_pos = i + glyphs_shaped; + last_cluster = cluster; + + applyVisibilityRules(string[item_pos + str_pos], &g, i, actualFontEngine); + } } + while (str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; + } else { // Harfbuzz did not return a glyph for the character, so we add a placeholder + g.glyphs[0] = 0; + g.advances[0] = QFixed{}; + g.offsets[0].x = QFixed{}; + g.offsets[0].y = QFixed{}; + g.attributes[0].clusterStart = true; + g.attributes[0].dontPrint = true; + log_clusters[0] = glyphs_shaped; } - while (str_pos < item_length) - log_clusters[str_pos++] = last_glyph_pos; if (Q_UNLIKELY(engineIdx != 0)) { for (quint32 i = 0; i < num_glyphs; ++i) @@ -1721,8 +1754,10 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, } if (!actualFontEngine->supportsHorizontalSubPixelPositions()) { - for (uint i = 0; i < num_glyphs; ++i) + for (uint i = 0; i < num_glyphs; ++i) { g.advances[i] = g.advances[i].round(); + g.offsets[i].x = g.offsets[i].x.round(); + } } glyphs_shaped += num_glyphs; @@ -1781,7 +1816,7 @@ const QCharAttributes *QTextEngine::attributes() const return (QCharAttributes *) layoutData->memory; itemize(); - if (! ensureSpace(layoutData->string.length())) + if (! ensureSpace(layoutData->string.size())) return nullptr; QVarLengthArray<QUnicodeTools::ScriptItem> scriptItems(layoutData->items.size()); @@ -1888,7 +1923,7 @@ void QTextEngine::itemize() const if (layoutData->items.size()) return; - int length = layoutData->string.length(); + int length = layoutData->string.size(); if (!length) return; @@ -1905,9 +1940,9 @@ void QTextEngine::itemize() const { QUnicodeTools::ScriptItemArray scriptItems; QUnicodeTools::initScripts(layoutData->string, &scriptItems); - for (int i = 0; i < scriptItems.length(); ++i) { + for (int i = 0; i < scriptItems.size(); ++i) { const auto &item = scriptItems.at(i); - int end = i < scriptItems.length() - 1 ? scriptItems.at(i + 1).position : length; + int end = i < scriptItems.size() - 1 ? scriptItems.at(i + 1).position : length; for (int j = item.position; j < end; ++j) analysis[j].script = item.script; } @@ -1918,7 +1953,17 @@ void QTextEngine::itemize() const while (uc < e) { switch (*uc) { case QChar::ObjectReplacementCharacter: - analysis->flags = QScriptAnalysis::Object; + { + const QTextDocumentPrivate *doc_p = QTextDocumentPrivate::get(block); + if (doc_p != nullptr + && doc_p->layout() != nullptr + && QAbstractTextDocumentLayoutPrivate::get(doc_p->layout()) != nullptr + && QAbstractTextDocumentLayoutPrivate::get(doc_p->layout())->hasHandlers()) { + analysis->flags = QScriptAnalysis::Object; + } else { + analysis->flags = QScriptAnalysis::None; + } + } break; case QChar::LineSeparator: analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; @@ -1970,7 +2015,7 @@ void QTextEngine::itemize() const const QTextFragmentData * const frag = it.value(); if (it == end || format != frag->format) { if (s && position >= preeditPosition) { - position += s->preeditText.length(); + position += s->preeditText.size(); preeditPosition = INT_MAX; } Q_ASSERT(position <= length); @@ -1979,7 +2024,7 @@ void QTextEngine::itemize() const ? formatCollection()->charFormat(format).fontCapitalization() : formatCollection()->defaultFont().capitalization(); if (s) { - for (const auto &range : qAsConst(s->formats)) { + for (const auto &range : std::as_const(s->formats)) { if (range.start + range.length <= prevPosition || range.start >= position) continue; if (range.format.hasProperty(QTextFormat::FontCapitalization)) { @@ -2399,7 +2444,7 @@ void QTextEngine::justify(const QScriptLine &line) if (!forceJustification) { int end = line.from + (int)line.length + line.trailingSpaces; - if (end == layoutData->string.length()) + if (end == layoutData->string.size()) return; // no justification at end of paragraph if (end && layoutData->items.at(findItem(end - 1)).analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) return; // no justification at the end of an explicitly separated line @@ -2605,18 +2650,20 @@ QTextEngine::LayoutData::LayoutData() haveCharAttributes = false; logClustersPtr = nullptr; available_glyphs = 0; + currentMaxWidth = 0; } -QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int _allocated) +QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, qsizetype _allocated) : string(str) { allocated = _allocated; - int space_charAttributes = int(sizeof(QCharAttributes) * string.length() / sizeof(void*) + 1); - int space_logClusters = int(sizeof(unsigned short) * string.length() / sizeof(void*) + 1); - available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded; + constexpr qsizetype voidSize = sizeof(void*); + qsizetype space_charAttributes = sizeof(QCharAttributes) * string.size() / voidSize + 1; + qsizetype space_logClusters = sizeof(unsigned short) * string.size() / voidSize + 1; + available_glyphs = (allocated - space_charAttributes - space_logClusters) * voidSize / QGlyphLayout::SpaceNeeded; - if (available_glyphs < str.length()) { + if (available_glyphs < str.size()) { // need to allocate on the heap allocated = 0; @@ -2629,7 +2676,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int logClustersPtr = (unsigned short *)(memory + space_charAttributes); void *m = memory + space_charAttributes + space_logClusters; - glyphLayout = QGlyphLayout(reinterpret_cast<char *>(m), str.length()); + glyphLayout = QGlyphLayout(reinterpret_cast<char *>(m), str.size()); glyphLayout.clear(); memset(memory, 0, space_charAttributes*sizeof(void *)); } @@ -2637,6 +2684,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int hasBidi = false; layoutState = LayoutEmpty; haveCharAttributes = false; + currentMaxWidth = 0; } QTextEngine::LayoutData::~LayoutData() @@ -2654,15 +2702,16 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs) return true; } - int space_charAttributes = int(sizeof(QCharAttributes) * string.length() / sizeof(void*) + 1); - int space_logClusters = int(sizeof(unsigned short) * string.length() / sizeof(void*) + 1); - int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2; + const qsizetype space_charAttributes = (sizeof(QCharAttributes) * string.size() / sizeof(void*) + 1); + const qsizetype space_logClusters = (sizeof(unsigned short) * string.size() / sizeof(void*) + 1); + const qsizetype space_glyphs = qsizetype(totalGlyphs) * QGlyphLayout::SpaceNeeded / sizeof(void *) + 2; - int newAllocated = space_charAttributes + space_glyphs + space_logClusters; - // These values can be negative if the length of string/glyphs causes overflow, + const qsizetype newAllocated = space_charAttributes + space_glyphs + space_logClusters; + // Check if the length of string/glyphs causes int overflow, // we can't layout such a long string all at once, so return false here to // indicate there is a failure - if (space_charAttributes < 0 || space_logClusters < 0 || space_glyphs < 0 || newAllocated < allocated) { + if (size_t(space_charAttributes) > INT_MAX || size_t(space_logClusters) > INT_MAX || totalGlyphs < 0 + || size_t(space_glyphs) > INT_MAX || size_t(newAllocated) > INT_MAX || newAllocated < allocated) { layoutState = LayoutFailed; return false; } @@ -2682,7 +2731,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs) logClustersPtr = (unsigned short *) m; m += space_logClusters; - const int space_preGlyphLayout = space_charAttributes + space_logClusters; + const qsizetype space_preGlyphLayout = space_charAttributes + space_logClusters; if (allocated < space_preGlyphLayout) memset(memory + allocated, 0, (space_preGlyphLayout - allocated)*sizeof(void *)); @@ -2722,6 +2771,7 @@ void QTextEngine::freeMemory() layoutData->hasBidi = false; layoutData->layoutState = LayoutEmpty; layoutData->haveCharAttributes = false; + layoutData->currentMaxWidth = 0; layoutData->items.clear(); } if (specialData) @@ -2745,10 +2795,10 @@ int QTextEngine::formatIndex(const QScriptItem *si) const return -1; int pos = si->position; if (specialData && si->position >= specialData->preeditPosition) { - if (si->position < specialData->preeditPosition + specialData->preeditText.length()) + if (si->position < specialData->preeditPosition + specialData->preeditText.size()) pos = qMax(qMin(block.length(), specialData->preeditPosition) - 1, 0); else - pos -= specialData->preeditText.length(); + pos -= specialData->preeditText.size(); } QTextDocumentPrivate::FragmentIterator it = p->find(block.position() + pos); return it.value()->format; @@ -2883,9 +2933,9 @@ void QTextEngine::indexFormats() */ static inline bool nextCharJoins(const QString &string, int pos) { - while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing) + while (pos < string.size() && string.at(pos).category() == QChar::Mark_NonSpacing) ++pos; - if (pos == string.length()) + if (pos == string.size()) return false; QChar::JoiningType joining = string.at(pos).joiningType(); return joining != QChar::Joining_None && joining != QChar::Joining_Transparent; @@ -2901,11 +2951,11 @@ static inline bool prevCharJoins(const QString &string, int pos) return joining == QChar::Joining_Dual || joining == QChar::Joining_Causing; } -static inline bool isRetainableControlCode(QChar c) +static constexpr bool isRetainableControlCode(char16_t c) noexcept { - return (c.unicode() >= 0x202a && c.unicode() <= 0x202e) // LRE, RLE, PDF, LRO, RLO - || (c.unicode() >= 0x200e && c.unicode() <= 0x200f) // LRM, RLM - || (c.unicode() >= 0x2066 && c.unicode() <= 0x2069); // LRI, RLI, FSI, PDI + return (c >= 0x202a && c <= 0x202e) // LRE, RLE, PDF, LRO, RLO + || (c >= 0x200e && c <= 0x200f) // LRM, RLM + || (c >= 0x2066 && c <= 0x2069); // LRI, RLI, FSI, PDI } static QString stringMidRetainingBidiCC(const QString &string, @@ -2918,14 +2968,14 @@ static QString stringMidRetainingBidiCC(const QString &string, { QString prefix; for (int i=subStringFrom; i<midStart; ++i) { - QChar c = string.at(i); + char16_t c = string.at(i).unicode(); if (isRetainableControlCode(c)) prefix += c; } QString suffix; for (int i=midStart + midLength; i<subStringTo; ++i) { - QChar c = string.at(i); + char16_t c = string.at(i).unicode(); if (isRetainableControlCode(c)) suffix += c; } @@ -2968,12 +3018,12 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, validate(); - const int to = count >= 0 && count <= layoutData->string.length() - from + const int to = count >= 0 && count <= layoutData->string.size() - from ? from + count - : layoutData->string.length(); + : layoutData->string.size(); if (mode == Qt::ElideNone - || this->width(from, layoutData->string.length()) <= width + || this->width(from, layoutData->string.size()) <= width || to - from <= 1) return layoutData->string.mid(from, from - to); @@ -2982,7 +3032,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, { QFontEngine *engine = fnt.d->engineForScript(QChar::Script_Common); - QChar ellipsisChar = u'\x2026'; + constexpr char16_t ellipsisChar = u'\x2026'; // We only want to use the ellipsis character if it is from the main // font (not one of the fallbacks), since using a fallback font @@ -2994,7 +3044,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, engine = multiEngine->engine(0); } - glyph_t glyph = engine->glyphIndex(ellipsisChar.unicode()); + glyph_t glyph = engine->glyphIndex(ellipsisChar); QGlyphLayout glyphs; glyphs.numGlyphs = 1; @@ -3014,7 +3064,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, ellipsisText = QStringLiteral("..."); } else { engine = fnt.d->engineForScript(QChar::Script_Common); - glyph = engine->glyphIndex(ellipsisChar.unicode()); + glyph = engine->glyphIndex(ellipsisChar); engine->recalcAdvances(&glyphs, { }); ellipsisText = ellipsisChar; } @@ -3040,7 +3090,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, pos = nextBreak; ++nextBreak; - while (nextBreak < layoutData->string.length() && !attributes[nextBreak].graphemeBoundary) + while (nextBreak < layoutData->string.size() && !attributes[nextBreak].graphemeBoundary) ++nextBreak; currentWidth += this->width(pos, nextBreak - pos); @@ -3092,7 +3142,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, QFixed width, int flags, rightPos = nextRightBreak; ++nextLeftBreak; - while (nextLeftBreak < layoutData->string.length() && !attributes[nextLeftBreak].graphemeBoundary) + while (nextLeftBreak < layoutData->string.size() && !attributes[nextLeftBreak].graphemeBoundary) ++nextLeftBreak; --nextRightBreak; @@ -3131,7 +3181,7 @@ void QTextEngine::setBoundary(int strPos) const QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const { - const QScriptItem &si = layoutData->items[item]; + const QScriptItem &si = layoutData->items.at(item); QFixed dpiScale = 1; if (QTextDocumentPrivate::get(block) != nullptr && QTextDocumentPrivate::get(block)->layout() != nullptr) { @@ -3165,15 +3215,15 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const } } } - for (const QTextOption::Tab &tabSpec : qAsConst(tabArray)) { + for (const QTextOption::Tab &tabSpec : std::as_const(tabArray)) { QFixed tab = QFixed::fromReal(tabSpec.position) * dpiScale; if (tab > x) { // this is the tab we need. - int tabSectionEnd = layoutData->string.length(); + int tabSectionEnd = layoutData->string.size(); if (tabSpec.type == QTextOption::RightTab || tabSpec.type == QTextOption::CenterTab) { // find next tab to calculate the width required. tab = QFixed::fromReal(tabSpec.position); - for (int i=item + 1; i < layoutData->items.count(); i++) { - const QScriptItem &item = layoutData->items[i]; + for (int i=item + 1; i < layoutData->items.size(); i++) { + const QScriptItem &item = layoutData->items.at(i); if (item.analysis.flags == QScriptAnalysis::TabOrObject) { // found it. tabSectionEnd = item.position; break; @@ -3187,7 +3237,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const if (tabSectionEnd > si.position) { QFixed length; // Calculate the length of text between this tab and the tabSectionEnd - for (int i=item; i < layoutData->items.count(); i++) { + for (int i=item; i < layoutData->items.size(); i++) { const QScriptItem &item = layoutData->items.at(i); if (item.position > tabSectionEnd || item.position <= si.position) continue; @@ -3259,7 +3309,7 @@ void QTextEngine::resolveFormats() const QTextFormatCollection *collection = formatCollection(); - QList<QTextCharFormat> resolvedFormats(layoutData->items.count()); + QList<QTextCharFormat> resolvedFormats(layoutData->items.size()); QVarLengthArray<int, 64> formatsSortedByStart; formatsSortedByStart.reserve(specialData->formats.size()); @@ -3277,7 +3327,7 @@ void QTextEngine::resolveFormats() const const int *startIt = formatsSortedByStart.constBegin(); const int *endIt = formatsSortedByEnd.constBegin(); - for (int i = 0; i < layoutData->items.count(); ++i) { + for (int i = 0; i < layoutData->items.size(); ++i) { const QScriptItem *si = &layoutData->items.at(i); int end = si->position + length(si); @@ -3453,8 +3503,8 @@ int QTextEngine::previousLogicalPosition(int oldPos) const { const QCharAttributes *attrs = attributes(); int len = block.isValid() ? block.length() - 1 - : layoutData->string.length(); - Q_ASSERT(len <= layoutData->string.length()); + : layoutData->string.size(); + Q_ASSERT(len <= layoutData->string.size()); if (!attrs || oldPos <= 0 || oldPos > len) return oldPos; @@ -3468,8 +3518,8 @@ int QTextEngine::nextLogicalPosition(int oldPos) const { const QCharAttributes *attrs = attributes(); int len = block.isValid() ? block.length() - 1 - : layoutData->string.length(); - Q_ASSERT(len <= layoutData->string.length()); + : layoutData->string.size(); + Q_ASSERT(len <= layoutData->string.size()); if (!attrs || oldPos < 0 || oldPos >= len) return oldPos; @@ -3483,7 +3533,7 @@ int QTextEngine::lineNumberForTextPosition(int pos) { if (!layoutData) itemize(); - if (pos == layoutData->string.length() && lines.size()) + if (pos == layoutData->string.size() && lines.size()) return lines.size() - 1; for (int i = 0; i < lines.size(); ++i) { const QScriptLine& line = lines[i]; |