QAbstractItemView: fix rendering centered/right aligned item text
Commit 5712c62d1c
introduced a regression
for item texts which were aligned right or horizontally centered. The
layoutRect was calculated wrong and started below zero and later the
correct x offset could not be calculated since QTextLine::x() does not
return a calculated value.
Fix it by first calculating the complete string and pass it completely
to QTextLayout::draw() instead trying to draw the single lines on our
own - QTextLayout has a better working algorithm so no need to reinvent
the wheel here.
[ChangeLog][QtWidgets][ItemViews] Fixed a regression with wrongly drawn
centered/right aligned item texts
Fixes: QTBUG-34133
Fixes: QTBUG-56759
Fixes: QTBUG-72805
Fixes: QTBUG-72869
Change-Id: I0ed521c3a9d35446d190ac22aa9f2374814fd278
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
7511697efe
commit
25133a1b77
@ -943,17 +943,20 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
|
||||
const QRectF boundingRect = textLayout.boundingRect();
|
||||
const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
|
||||
boundingRect.size().toSize(), textRect);
|
||||
const QPointF position = layoutRect.topLeft();
|
||||
const int lineCount = textLayout.lineCount();
|
||||
QPointF paintPosition = QPointF(textRect.x(), layoutRect.top());
|
||||
|
||||
QString newText;
|
||||
qreal height = 0;
|
||||
const int lineCount = textLayout.lineCount();
|
||||
for (int i = 0; i < lineCount; ++i) {
|
||||
const QTextLine line = textLayout.lineAt(i);
|
||||
height += line.height();
|
||||
|
||||
// above visible rect
|
||||
if (height + layoutRect.top() <= textRect.top())
|
||||
if (height + layoutRect.top() <= textRect.top()) {
|
||||
paintPosition.ry() += line.height();
|
||||
continue;
|
||||
}
|
||||
|
||||
const int start = line.textStart();
|
||||
const int length = line.textLength();
|
||||
@ -968,26 +971,33 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
|
||||
elideLastVisibleLine = true;
|
||||
}
|
||||
|
||||
if (drawElided || elideLastVisibleLine) {
|
||||
QString text = textLayout.text().mid(start, length);
|
||||
if (elideLastVisibleLine)
|
||||
if (drawElided || elideLastVisibleLine) {
|
||||
if (elideLastVisibleLine) {
|
||||
if (text.endsWith(QChar::LineSeparator))
|
||||
text.chop(1);
|
||||
text += QChar(0x2026);
|
||||
}
|
||||
const QStackTextEngine engine(text, option->font);
|
||||
const QString elidedText = engine.elidedText(option->textElideMode, textRect.width());
|
||||
const QPointF pos(position.x() + line.x(),
|
||||
position.y() + line.y() + line.ascent());
|
||||
p->save();
|
||||
p->setFont(option->font);
|
||||
p->drawText(pos, elidedText);
|
||||
p->restore();
|
||||
newText += engine.elidedText(option->textElideMode, textRect.width());
|
||||
// sometimes drawElided is true but no eliding is done so the text ends
|
||||
// with QChar::LineSeparator - don't add another one. This happened with
|
||||
// arabic text in the testcase for QTBUG-72805
|
||||
if (i < lineCount - 1 &&
|
||||
!newText.endsWith(QChar::LineSeparator))
|
||||
newText += QChar::LineSeparator;
|
||||
} else {
|
||||
line.draw(p, position);
|
||||
newText += text;
|
||||
}
|
||||
|
||||
// below visible text, can stop
|
||||
if (height + layoutRect.top() >= textRect.bottom())
|
||||
break;
|
||||
}
|
||||
|
||||
textLayout.setText(newText);
|
||||
viewItemTextLayout(textLayout, textRect.width());
|
||||
textLayout.draw(p, paintPosition);
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
Loading…
Reference in New Issue
Block a user