diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2009-09-04 12:00:01 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2009-09-04 13:50:33 (GMT) |
commit | 1a60fb9506519210edcbfb3fbc400a67a6d26a41 (patch) | |
tree | 617cd54d145332ea251a5a822028d4e8f6ef6aa3 /src/gui/painting/qpainter.cpp | |
parent | f7be6402e089aefd445a5ab98912ff5aea511cea (diff) | |
download | Qt-1a60fb9506519210edcbfb3fbc400a67a6d26a41.zip Qt-1a60fb9506519210edcbfb3fbc400a67a6d26a41.tar.gz Qt-1a60fb9506519210edcbfb3fbc400a67a6d26a41.tar.bz2 |
Optimize qt_format_text test operations: try not to detach
Second try.
This is a fixed version of the one reverted in commit 25014061b8de
The difference is that it does
text[offset] = QChar::LineSeparator;
instead of
chr = QChar::LineSeparator;
Reviewed-by: Eskil
Diffstat (limited to 'src/gui/painting/qpainter.cpp')
-rw-r--r-- | src/gui/painting/qpainter.cpp | 68 |
1 files changed, 28 insertions, 40 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a6bea76..263e53e 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7545,10 +7545,9 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, if (!painter) tf |= Qt::TextDontPrint; - int maxUnderlines = 0; + uint maxUnderlines = 0; int numUnderlines = 0; - int underlinePositionStack[32]; - int *underlinePositions = underlinePositionStack; + QVarLengthArray<int, 32> underlinePositions(1); QFontMetricsF fm(fnt); QString text = str; @@ -7557,54 +7556,46 @@ start_lengthVariant: bool hasMoreLengthVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces - QChar *chr = text.data() + offset; - QChar *end = text.data() + text.length(); bool has_tab = false; - while (chr != end) { - if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { - *chr = QLatin1Char(' '); - } else if (*chr == QLatin1Char('\n')) { - *chr = QChar::LineSeparator; - } else if (*chr == QLatin1Char('&')) { + int old_offset = offset; + for (; offset < text.length(); offset++) { + QChar chr = text.at(offset); + if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) { + text[offset] = QLatin1Char(' '); + } else if (chr == QLatin1Char('\n')) { + text[offset] = QChar::LineSeparator; + } else if (chr == QLatin1Char('&')) { ++maxUnderlines; - } else if (*chr == QLatin1Char('\t')) { + } else if (chr == QLatin1Char('\t')) { + if (!expandtabs) { + text[offset] = QLatin1Char(' '); + } else if (!tabarraylen && !tabstops) { + tabstops = qRound(fm.width(QLatin1Char('x'))*8); + } has_tab = true; - } else if (*chr == QChar(ushort(0x9c))) { + } else if (chr == QChar(ushort(0x9c))) { // string with multiple length variants - end = chr; hasMoreLengthVariants = true; break; } - ++chr; - } - if (has_tab) { - if (!expandtabs) { - chr = text.data() + offset; - while (chr != end) { - if (*chr == QLatin1Char('\t')) - *chr = QLatin1Char(' '); - ++chr; - } - } else if (!tabarraylen && !tabstops) { - tabstops = qRound(fm.width(QLatin1Char('x'))*8); - } } - QChar *cout = end; - if (hidemnmemonic || showmnemonic) { - if (maxUnderlines > 32) - underlinePositions = new int[maxUnderlines]; - cout = text.data() + offset; + int length = offset - old_offset; + if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { + underlinePositions.resize(maxUnderlines + 1); + + QChar *cout = text.data() + old_offset; QChar *cin = cout; - int l = end - cout; + int l = length; while (l) { if (*cin == QLatin1Char('&')) { ++cin; + --length; --l; if (!l) break; if (*cin != QLatin1Char('&') && !hidemnmemonic) - underlinePositions[numUnderlines++] = cout - text.unicode(); + underlinePositions[numUnderlines++] = cout - text.data() - old_offset; } *cout = *cin; ++cout; @@ -7621,7 +7612,7 @@ start_lengthVariant: qreal height = 0; qreal width = 0; - QString finalText = text.mid(offset, cout - (text.data() + offset)); + QString finalText = text.mid(old_offset, length); QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; @@ -7640,7 +7631,7 @@ start_lengthVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.engine()->underlinePositions = underlinePositions; + textLayout.engine()->underlinePositions = underlinePositions.data(); if (finalText.isEmpty()) { height = fm.height(); @@ -7709,7 +7700,7 @@ start_lengthVariant: QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { - offset = end - text.data() + 1; + offset++; goto start_lengthVariant; } if (brect) @@ -7738,9 +7729,6 @@ start_lengthVariant: painter->restore(); } } - - if (underlinePositions != underlinePositionStack) - delete [] underlinePositions; } /*! |