Improve bounding rect of QStaticText with Qt::PlainText

The bounding rect was not including positive leading of the last line. This
patch solves it by changing using QTextLine's setLeadingIncluded, and adds
handling of negative leading to keep rendering unchanged in that case.

Change-Id: I4d18b81892184bb85cd7949a5dc3fb9cfa270a26
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2018-01-25 11:13:19 +01:00
parent dfa434a979
commit bd74b624d5
2 changed files with 72 additions and 4 deletions

View File

@ -39,6 +39,7 @@
#include "qstatictext.h"
#include "qstatictext_p.h"
#include <qmath.h>
#include <private/qtextengine_p.h>
#include <private/qfontengine_p.h>
#include <qabstracttextdocumentlayout.h>
@ -611,22 +612,22 @@ void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p,
textLayout.setTextOption(textOption);
textLayout.setCacheEnabled(true);
qreal leading = QFontMetricsF(font).leading();
qreal height = -leading;
qreal height = 0;
textLayout.beginLayout();
while (1) {
QTextLine line = textLayout.createLine();
if (!line.isValid())
break;
line.setLeadingIncluded(true);
if (textWidth >= 0.0)
line.setLineWidth(textWidth);
else
line.setLineWidth(QFIXED_MAX);
height += leading;
line.setPosition(QPointF(0.0, height));
height += line.height();
if (line.leading() < 0)
height += qCeil(line.leading());
}
textLayout.endLayout();

View File

@ -61,6 +61,8 @@ private slots:
void drawToPoint();
void drawToRect_data();
void drawToRect();
void compareToDrawText_data();
void compareToDrawText();
void setFont();
void setTextWidth();
void prepareToCorrectData();
@ -212,6 +214,71 @@ void tst_QStaticText::drawToRect()
QCOMPARE(imageDrawStaticText, imageDrawText);
}
void tst_QStaticText::compareToDrawText_data()
{
QTest::addColumn<QFont>("font");
QTest::newRow("default") << QFont();
QFont sansserif; sansserif.setStyleHint(QFont::SansSerif);
QFont serif; serif.setStyleHint(QFont::Serif);
QFont monospace; monospace.setStyleHint(QFont::Monospace);
QTest::newRow("sans-serif") << QFont(sansserif.defaultFamily());
QTest::newRow("serif") << QFont(serif.defaultFamily());
QTest::newRow("monospace") << QFont(monospace.defaultFamily());
}
void tst_QStaticText::compareToDrawText()
{
QFETCH(QFont, font);
QPixmap imageDrawText(1000, 1000);
imageDrawText.fill(Qt::white);
{
QPainter p(&imageDrawText);
p.setFont(font);
p.drawText(QRectF(11, 12, 30, 500), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
}
QPixmap imageDrawStaticPlainText(1000, 1000);
imageDrawStaticPlainText.fill(Qt::white);
{
QPainter p(&imageDrawStaticPlainText);
p.setFont(font);
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextWidth(30),
p.setClipRect(QRectF(11, 12, 30, 500));
text.setTextFormat(Qt::PlainText);
p.drawStaticText(QPointF(11, 12), text);
}
#if defined(DEBUG_SAVE_IMAGE)
imageDrawText.save("compareToDrawText_imageDrawText.png");
imageDrawStaticPlainText.save("compareToDrawText_imageDrawStaticPlainText.png");
#endif
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
QCOMPARE(imageDrawStaticPlainText, imageDrawText);
// Rich text rendering does not take negative leading into account.
#if 0
QPixmap imageDrawStaticRichText(1000, 1000);
imageDrawStaticRichText.fill(Qt::white);
{
QPainter p(&imageDrawStaticRichText);
p.setFont(font);
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextWidth(30),
p.setClipRect(QRectF(11, 12, 30, 500));
text.setTextFormat(Qt::RichText);
p.drawStaticText(QPointF(11, 12), text);
}
#if defined(DEBUG_SAVE_IMAGE)
imageDrawStaticRichText.save("compareToDrawText_imageDrawStaticRichText.png");
#endif
QCOMPARE(imageDrawStaticRichText, imageDrawText);
#endif
}
void tst_QStaticText::prepareToCorrectData()
{
QTransform transform;