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)
This commit is contained in:
Allan Sandfeld Jensen 2023-01-05 15:23:25 +01:00
parent 72de1af9e9
commit 4d3daea33f

View File

@ -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);
}