Avoid unneccessarily long text scans

Limit the scans to the processed length.

Fixes: QTBUG-109838
Change-Id: If4b19bf6f97d788d0a227af3a80962bef26016fd
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 7c84550f3bfdf93cb8a071e6bb23d54d57109e84)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Allan Sandfeld Jensen 2023-01-05 15:23:25 +01:00 committed by Qt Cherry-pick Bot
parent a765c10436
commit 802dfb1879

View File

@ -473,6 +473,8 @@ int QFontMetrics::rightBearing(QChar ch) const
return qRound(rb); return qRound(rb);
} }
static constexpr QLatin1Char s_variableLengthStringSeparator('\x9c');
/*! /*!
Returns the horizontal advance in pixels of the first \a len characters of \a 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 text. If \a len is negative (the default), the entire string is
@ -487,9 +489,11 @@ int QFontMetrics::rightBearing(QChar ch) const
*/ */
int QFontMetrics::horizontalAdvance(const QString &text, int len) 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) { if (pos != -1) {
len = (len < 0) ? pos : qMin(pos, len); len = pos;
} else if (len < 0) { } else if (len < 0) {
len = text.size(); len = text.size();
} }
@ -512,11 +516,11 @@ int QFontMetrics::horizontalAdvance(const QString &text, int len) const
*/ */
int QFontMetrics::horizontalAdvance(const QString &text, const QTextOption &option) const int QFontMetrics::horizontalAdvance(const QString &text, const QTextOption &option) const
{ {
int pos = text.indexOf(QLatin1Char('\x9c')); int pos = text.indexOf(s_variableLengthStringSeparator);
int len = -1; int len = -1;
if (pos != -1) { if (pos != -1) {
len = (len < 0) ? pos : qMin(pos, len); len = pos;
} else if (len < 0) { } else {
len = text.size(); len = text.size();
} }
if (len == 0) if (len == 0)
@ -876,13 +880,13 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in
QString _text = text; QString _text = text;
if (!(flags & Qt::TextLongestVariant)) { if (!(flags & Qt::TextLongestVariant)) {
int posA = 0; int posA = 0;
int posB = _text.indexOf(QLatin1Char('\x9c')); int posB = _text.indexOf(s_variableLengthStringSeparator);
while (posB >= 0) { while (posB >= 0) {
QString portion = _text.mid(posA, posB - posA); QString portion = _text.mid(posA, posB - posA);
if (size(flags, portion).width() <= width) if (size(flags, portion).width() <= width)
return portion; return portion;
posA = posB + 1; posA = posB + 1;
posB = _text.indexOf(QLatin1Char('\x9c'), posA); posB = _text.indexOf(s_variableLengthStringSeparator, posA);
} }
_text = _text.mid(posA); _text = _text.mid(posA);
} }
@ -1398,9 +1402,11 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
*/ */
qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) 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) if (pos != -1)
length = (length < 0) ? pos : qMin(pos, length); length = pos;
else if (length < 0) else if (length < 0)
length = text.size(); length = text.size();
@ -1424,11 +1430,11 @@ qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
*/ */
qreal QFontMetricsF::horizontalAdvance(const QString &text, const QTextOption &option) const qreal QFontMetricsF::horizontalAdvance(const QString &text, const QTextOption &option) const
{ {
int pos = text.indexOf(QLatin1Char('\x9c')); int pos = text.indexOf(s_variableLengthStringSeparator);
int length = -1; int length = -1;
if (pos != -1) if (pos != -1)
length = (length < 0) ? pos : qMin(pos, length); length = pos;
else if (length < 0) else
length = text.size(); length = text.size();
if (length == 0) if (length == 0)
@ -1793,13 +1799,13 @@ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, q
QString _text = text; QString _text = text;
if (!(flags & Qt::TextLongestVariant)) { if (!(flags & Qt::TextLongestVariant)) {
int posA = 0; int posA = 0;
int posB = _text.indexOf(QLatin1Char('\x9c')); int posB = _text.indexOf(s_variableLengthStringSeparator);
while (posB >= 0) { while (posB >= 0) {
QString portion = _text.mid(posA, posB - posA); QString portion = _text.mid(posA, posB - posA);
if (size(flags, portion).width() <= width) if (size(flags, portion).width() <= width)
return portion; return portion;
posA = posB + 1; posA = posB + 1;
posB = _text.indexOf(QLatin1Char('\x9c'), posA); posB = _text.indexOf(s_variableLengthStringSeparator, posA);
} }
_text = _text.mid(posA); _text = _text.mid(posA);
} }