diff options
author | David Schulz <david.schulz@qt.io> | 2019-11-28 13:03:32 +0100 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2020-02-10 14:09:38 +0000 |
commit | e85d6b363bd039c4407bbf5367cce0efdd559945 (patch) | |
tree | 4c997d75bed34e5fc100eb1ae411fb70eb034420 | |
parent | c522ceb7dd678df063db930288c9d269ee464e13 (diff) | |
download | qt-creator-e85d6b363bd039c4407bbf5367cce0efdd559945.tar.gz |
Editor: Improve splitting format range performance
Instead of copying the list and move some items individualy from
one list to the other use Utils::partition.
Fixes: QTCREATORBUG-23281
Change-Id: Iaf9430c041aa916feecf9214303ba30f17290ba8
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r-- | src/plugins/texteditor/syntaxhighlighter.cpp | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp index b28ac1ee18..bfa0f85a86 100644 --- a/src/plugins/texteditor/syntaxhighlighter.cpp +++ b/src/plugins/texteditor/syntaxhighlighter.cpp @@ -78,13 +78,13 @@ public: bool noAutomaticHighlighting = false; }; -static bool adjustRange(QTextLayout::FormatRange &range, int from, int charsRemoved, int charsAdded) { - +static bool adjustRange(QTextLayout::FormatRange &range, int from, int charsDelta) +{ if (range.start >= from) { - range.start += charsAdded - charsRemoved; + range.start += charsDelta; return true; } else if (range.start + range.length > from) { - range.length += charsAdded - charsRemoved; + range.length += charsDelta; return true; } return false; @@ -105,32 +105,24 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in QTextLayout *layout = currentBlock.layout(); - QVector<QTextLayout::FormatRange> ranges = layout->formats(); - - bool doAdjustRange = currentBlock.contains(from); - - QVector<QTextLayout::FormatRange> old_ranges; + QVector<QTextLayout::FormatRange> ranges; + QVector<QTextLayout::FormatRange> oldRanges; + std::tie(ranges, oldRanges) + = Utils::partition(layout->formats(), [](const QTextLayout::FormatRange &range) { + return range.format.property(QTextFormat::UserProperty).toBool(); + }); - if (!ranges.isEmpty()) { - auto it = ranges.begin(); - while (it != ranges.end()) { - if (it->format.property(QTextFormat::UserProperty).toBool()) { - if (doAdjustRange) - formatsChanged = adjustRange(*it, from - currentBlock.position(), charsRemoved, charsAdded) - || formatsChanged; - ++it; - } else { - old_ranges.append(*it); - it = ranges.erase(it); - } - } + if (currentBlock.contains(from)) { + const int charsDelta = charsAdded - charsRemoved; + for (QTextLayout::FormatRange &range : ranges) + formatsChanged |= adjustRange(range, from - currentBlock.position(), charsDelta); } QTextCharFormat emptyFormat; QTextLayout::FormatRange r; - QVector<QTextLayout::FormatRange> new_ranges; + QVector<QTextLayout::FormatRange> newRanges; int i = 0; while (i < formatChanges.count()) { @@ -148,19 +140,19 @@ void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, in r.length = i - r.start; - new_ranges << r; + newRanges << r; } - formatsChanged = formatsChanged || (new_ranges.size() != old_ranges.size()); + formatsChanged = formatsChanged || (newRanges.size() != oldRanges.size()); - for (int i = 0; !formatsChanged && i < new_ranges.size(); ++i) { - const QTextLayout::FormatRange &o = old_ranges.at(i); - const QTextLayout::FormatRange &n = new_ranges.at(i); + for (int i = 0; !formatsChanged && i < newRanges.size(); ++i) { + const QTextLayout::FormatRange &o = oldRanges.at(i); + const QTextLayout::FormatRange &n = newRanges.at(i); formatsChanged = (o.start != n.start || o.length != n.length || o.format != n.format); } if (formatsChanged) { - ranges.append(new_ranges); + ranges.append(newRanges); layout->setFormats(ranges); doc->markContentsDirty(currentBlock.position(), currentBlock.length()); } |