From 4d3daea33f7f2750303a62a97c342ea880f75644 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 5 Jan 2023 15:23:25 +0100 Subject: [PATCH] Avoid unneccessarily long text scans Limit the scans to the processed length. Fixes: QTBUG-109838 Change-Id: If4b19bf6f97d788d0a227af3a80962bef26016fd Reviewed-by: Eirik Aavitsland Reviewed-by: Marc Mutz (cherry picked from commit 7c84550f3bfdf93cb8a071e6bb23d54d57109e84) --- src/gui/text/qfontmetrics.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 42c17ced584..e8b447955ed 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -509,6 +509,8 @@ int QFontMetrics::rightBearing(QChar ch) const return qRound(rb); } +static constexpr QLatin1Char s_variableLengthStringSeparator('\x9c'); + /*! Returns the horizontal advance in pixels of the first \a len characters of \a text. If \a len is negative (the default), the entire string is @@ -523,9 +525,11 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::horizontalAdvance(const QString &text, int len) const { - int pos = text.indexOf(QLatin1Char('\x9c')); + int pos = (len >= 0) + ? QStringView(text).left(len).indexOf(s_variableLengthStringSeparator) + : text.indexOf(s_variableLengthStringSeparator); if (pos != -1) { - len = (len < 0) ? pos : qMin(pos, len); + len = pos; } else if (len < 0) { len = text.length(); } @@ -819,13 +823,13 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in QString _text = text; if (!(flags & Qt::TextLongestVariant)) { int posA = 0; - int posB = _text.indexOf(QLatin1Char('\x9c')); + int posB = _text.indexOf(s_variableLengthStringSeparator); while (posB >= 0) { QString portion = _text.mid(posA, posB - posA); if (size(flags, portion).width() <= width) return portion; posA = posB + 1; - posB = _text.indexOf(QLatin1Char('\x9c'), posA); + posB = _text.indexOf(s_variableLengthStringSeparator, posA); } _text = _text.mid(posA); } @@ -1341,9 +1345,11 @@ qreal QFontMetricsF::rightBearing(QChar ch) const */ qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const { - int pos = text.indexOf(QLatin1Char('\x9c')); + int pos = (length >= 0) + ? QStringView(text).left(length).indexOf(s_variableLengthStringSeparator) + : text.indexOf(s_variableLengthStringSeparator); if (pos != -1) - length = (length < 0) ? pos : qMin(pos, length); + length = pos; else if (length < 0) length = text.length(); @@ -1641,13 +1647,13 @@ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, q QString _text = text; if (!(flags & Qt::TextLongestVariant)) { int posA = 0; - int posB = _text.indexOf(QLatin1Char('\x9c')); + int posB = _text.indexOf(s_variableLengthStringSeparator); while (posB >= 0) { QString portion = _text.mid(posA, posB - posA); if (size(flags, portion).width() <= width) return portion; posA = posB + 1; - posB = _text.indexOf(QLatin1Char('\x9c'), posA); + posB = _text.indexOf(s_variableLengthStringSeparator, posA); } _text = _text.mid(posA); }