summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-04-06 16:28:13 (GMT)
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-08-11 17:14:51 (GMT)
commite0059d1d01a7c1d76ed86cccf8253d0ebd18f575 (patch)
treea3753a0b0913ba95406083368c96cf9b1e1e3dda
parent1693931ac92a6a7d98eb28acda371f2d7c9c6dc2 (diff)
downloadQt-e0059d1d01a7c1d76ed86cccf8253d0ebd18f575.zip
Qt-e0059d1d01a7c1d76ed86cccf8253d0ebd18f575.tar.gz
Qt-e0059d1d01a7c1d76ed86cccf8253d0ebd18f575.tar.bz2
Handle multi-length strings in the low-level formatting code
Patch originally from Oswald on Jira QT-10, with few a modifications. If a string contains multiple variants sorted by decreasing length, separated by \x9c, it will try to paint the longest variant which fits into the bounding box. Reviewed-by: Oswald Buddenhagen Task-Number: QT-10
-rw-r--r--src/gui/painting/qpainter.cpp34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 8192fb7..c3fc14b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -7486,12 +7486,14 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
int *underlinePositions = underlinePositionStack;
QFontMetricsF fm(fnt);
-
QString text = str;
+ int offset = 0;
+start_lenghtVariant:
+ bool hasMoreLenghtVariants = false;
// compatible behaviour to the old implementation. Replace
// tabs by spaces
- QChar *chr = text.data();
- const QChar *end = chr + str.length();
+ 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'))) {
@@ -7502,12 +7504,17 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
++maxUnderlines;
} else if (*chr == QLatin1Char('\t')) {
has_tab = true;
+ } else if (*chr == QChar(ushort(0x9c))) {
+ // string with multiple length variants
+ end = chr;
+ hasMoreLenghtVariants = true;
+ break;
}
++chr;
}
if (has_tab) {
if (!expandtabs) {
- chr = text.data();
+ chr = text.data() + offset;
while (chr != end) {
if (*chr == QLatin1Char('\t'))
*chr = QLatin1Char(' ');
@@ -7518,12 +7525,13 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
}
}
+ QChar *cout = end;
if (hidemnmemonic || showmnemonic) {
if (maxUnderlines > 32)
underlinePositions = new int[maxUnderlines];
- QChar *cout = text.data();
+ cout = text.data() + offset;
QChar *cin = cout;
- int l = str.length();
+ int l = end - cout;
while (l) {
if (*cin == QLatin1Char('&')) {
++cin;
@@ -7538,9 +7546,6 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
++cin;
--l;
}
- int newlen = cout - text.unicode();
- if (newlen != text.length())
- text.resize(newlen);
}
// no need to do extra work for underlines if we don't paint
@@ -7551,13 +7556,12 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
qreal height = 0;
qreal width = 0;
- QStackTextEngine engine(text, fnt);
+ QString finalText = text.mid(offset, cout - (text.data() + offset));
+ QStackTextEngine engine(finalText, fnt);
if (option) {
engine.option = *option;
}
-
-
engine.option.setTextDirection(layout_direction);
if (tf & Qt::AlignJustify)
engine.option.setAlignment(Qt::AlignJustify);
@@ -7573,7 +7577,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
textLayout.setCacheEnabled(true);
textLayout.engine()->underlinePositions = underlinePositions;
- if (text.isEmpty()) {
+ if (finalText.isEmpty()) {
height = fm.height();
width = 0;
tf |= Qt::TextDontPrint;
@@ -7638,6 +7642,10 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
}
}
QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
+ if (hasMoreLenghtVariants && !r.contains(bounds)) {
+ offset = end - text.data() + 1;
+ goto start_lenghtVariant;
+ }
if (brect)
*brect = bounds;