e3b55616e2
Change-Id: I852f016fcb619a9e634deee6efb1fe7930d974c8 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
1024 lines
30 KiB
C++
1024 lines
30 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include <QtTest/QtTest>
|
|
#include <QtGui/QGuiApplication>
|
|
#include <QtGui/QPainter>
|
|
#include <QtGui/QImage>
|
|
|
|
#include <qstatictext.h>
|
|
#include <qpaintengine.h>
|
|
|
|
#ifdef QT_BUILD_INTERNAL
|
|
#include <private/qstatictext_p.h>
|
|
#endif
|
|
|
|
// #define DEBUG_SAVE_IMAGE
|
|
|
|
static inline QImage blankSquare()
|
|
{
|
|
// a "blank" square; we compare against in our testfunctions to verify
|
|
// that we have actually painted something
|
|
QPixmap pm(1000, 1000);
|
|
pm.fill(Qt::white);
|
|
return pm.toImage();
|
|
}
|
|
|
|
class tst_QStaticText: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
tst_QStaticText() : m_whiteSquare(blankSquare()) {}
|
|
|
|
private slots:
|
|
void constructionAndDestruction();
|
|
void drawToPoint_data();
|
|
void drawToPoint();
|
|
void drawToRect_data();
|
|
void drawToRect();
|
|
void compareToDrawText_data();
|
|
void compareToDrawText();
|
|
void setFont();
|
|
void setTextWidth();
|
|
void prepareToCorrectData();
|
|
void prepareToWrongData();
|
|
|
|
void copyConstructor();
|
|
|
|
void translatedPainter();
|
|
void rotatedPainter();
|
|
void scaledPainter();
|
|
void projectedPainter();
|
|
#if 0
|
|
void rotatedScaledAndTranslatedPainter_data();
|
|
void rotatedScaledAndTranslatedPainter();
|
|
#endif
|
|
void transformationChanged();
|
|
|
|
void plainTextVsRichText();
|
|
|
|
void setPenPlainText_data();
|
|
void setPenPlainText();
|
|
void setPenRichText();
|
|
void richTextOverridesPen();
|
|
|
|
void drawStruckOutText();
|
|
void drawOverlinedText();
|
|
void drawUnderlinedText();
|
|
|
|
void unprintableCharacter_qtbug12614();
|
|
|
|
#ifdef QT_BUILD_INTERNAL
|
|
void underlinedColor_qtbug20159();
|
|
void textDocumentColor();
|
|
#endif
|
|
|
|
void multiLine();
|
|
|
|
void size_qtbug65836();
|
|
|
|
private:
|
|
bool supportsTransformations() const;
|
|
|
|
const QImage m_whiteSquare;
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(QImage::Format);
|
|
|
|
void tst_QStaticText::constructionAndDestruction()
|
|
{
|
|
QStaticText text("My text");
|
|
}
|
|
|
|
void tst_QStaticText::copyConstructor()
|
|
{
|
|
QStaticText text(QLatin1String("My text"));
|
|
|
|
QTextOption textOption(Qt::AlignRight);
|
|
text.setTextOption(textOption);
|
|
|
|
text.setPerformanceHint(QStaticText::AggressiveCaching);
|
|
text.setTextWidth(123.456);
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
QStaticText copiedText(text);
|
|
copiedText.setText(QLatin1String("Other text"));
|
|
|
|
QCOMPARE(copiedText.textOption().alignment(), Qt::AlignRight);
|
|
QCOMPARE(copiedText.performanceHint(), QStaticText::AggressiveCaching);
|
|
QCOMPARE(copiedText.textWidth(), 123.456);
|
|
QCOMPARE(copiedText.textFormat(), Qt::PlainText);
|
|
|
|
QStaticText otherCopiedText(copiedText);
|
|
otherCopiedText.setTextWidth(789);
|
|
|
|
QCOMPARE(otherCopiedText.text(), QString::fromLatin1("Other text"));
|
|
}
|
|
|
|
Q_DECLARE_METATYPE(QStaticText::PerformanceHint)
|
|
void tst_QStaticText::drawToPoint_data()
|
|
{
|
|
QTest::addColumn<QStaticText::PerformanceHint>("performanceHint");
|
|
|
|
QTest::newRow("Moderate caching") << QStaticText::ModerateCaching;
|
|
QTest::newRow("Aggressive caching") << QStaticText::AggressiveCaching;
|
|
}
|
|
|
|
void tst_QStaticText::drawToPoint()
|
|
{
|
|
QFETCH(QStaticText::PerformanceHint, performanceHint);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
text.setPerformanceHint(performanceHint);
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::drawToRect_data()
|
|
{
|
|
QTest::addColumn<QStaticText::PerformanceHint>("performanceHint");
|
|
|
|
QTest::newRow("Moderate caching") << QStaticText::ModerateCaching;
|
|
QTest::newRow("Aggressive caching") << QStaticText::AggressiveCaching;
|
|
}
|
|
|
|
void tst_QStaticText::drawToRect()
|
|
{
|
|
QFETCH(QStaticText::PerformanceHint, performanceHint);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.drawText(QRectF(11, 12, 10, 500), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextWidth(10),
|
|
p.setClipRect(QRectF(11, 12, 10, 500));
|
|
text.setPerformanceHint(performanceHint);
|
|
text.setTextFormat(Qt::PlainText);
|
|
p.drawStaticText(QPointF(11, 12), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("drawToRect_imageDrawText.png");
|
|
imageDrawStaticText.save("drawToRect_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
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(10),
|
|
p.setClipRect(QRectF(11, 12, 30, 500));
|
|
text.setTextFormat(Qt::PlainText);
|
|
p.drawStaticText(QPointF(11, 12), text);
|
|
}
|
|
|
|
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(10),
|
|
p.setClipRect(QRectF(11, 12, 30, 500));
|
|
text.setTextFormat(Qt::RichText);
|
|
p.drawStaticText(QPointF(11, 12), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("compareToDrawText_imageDrawText.png");
|
|
imageDrawStaticText.save("compareToDrawText_imageDrawStaticPlainText.png");
|
|
imageDrawStaticText.save("compareToDrawText_imageDrawStaticRichText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticPlainText, imageDrawText);
|
|
QCOMPARE(imageDrawStaticRichText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::prepareToCorrectData()
|
|
{
|
|
QTransform transform;
|
|
transform.scale(2.0, 2.0);
|
|
transform.translate(100, 10);
|
|
transform.rotate(90, Qt::ZAxis);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.setTransform(transform);
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.setTransform(transform);
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.prepare(transform, p.font());
|
|
text.setTextFormat(Qt::PlainText);
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("prepareToCorrectData_imageDrawText.png");
|
|
imageDrawStaticText.save("prepareToCorrectData_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
|
|
if (!supportsTransformations())
|
|
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::prepareToWrongData()
|
|
{
|
|
QTransform transform;
|
|
transform.scale(2.0, 2.0);
|
|
transform.rotate(90, Qt::ZAxis);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.prepare(transform, p.font());
|
|
text.setTextFormat(Qt::PlainText);
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
|
|
void tst_QStaticText::setFont()
|
|
{
|
|
QFont font = QGuiApplication::font();
|
|
font.setBold(true);
|
|
font.setPointSize(28);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
|
|
p.setFont(font);
|
|
p.drawText(QRectF(11, 120, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
|
|
QStaticText text;
|
|
text.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(0, 0, text);
|
|
|
|
p.setFont(font);
|
|
p.drawStaticText(11, 120, text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("setFont_imageDrawText.png");
|
|
imageDrawStaticText.save("setFont_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::setTextWidth()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.drawText(QRectF(11, 12, 10, 500), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextWidth(10);
|
|
p.setClipRect(QRectF(11, 12, 10, 500));
|
|
p.drawStaticText(QPointF(11, 12), text);
|
|
}
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::translatedPainter()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.translate(100, 200);
|
|
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.translate(100, 200);
|
|
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
bool tst_QStaticText::supportsTransformations() const
|
|
{
|
|
QPixmap pm(10, 10);
|
|
QPainter p(&pm);
|
|
return p.paintEngine()->type() != QPaintEngine::OpenGL;
|
|
}
|
|
|
|
void tst_QStaticText::rotatedPainter()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.rotate(30.0);
|
|
p.drawText(QRectF(0, 0, 1000, 100), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
QPainter p(&imageDrawStaticText);
|
|
p.rotate(30.0);
|
|
p.drawStaticText(QPoint(0, 0), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("rotatedPainter_imageDrawText.png");
|
|
imageDrawStaticText.save("rotatedPainter_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
|
|
#ifdef Q_OS_ANDROID
|
|
QEXPECT_FAIL("", "QTBUG-69218", Continue);
|
|
#endif
|
|
if (!supportsTransformations())
|
|
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::scaledPainter()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.scale(2.0, 0.2);
|
|
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.scale(2.0, 0.2);
|
|
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
|
|
if (!supportsTransformations())
|
|
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::projectedPainter()
|
|
{
|
|
QTransform transform;
|
|
transform.rotate(90, Qt::XAxis);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.setTransform(transform);
|
|
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.setTransform(transform);
|
|
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
#if 0
|
|
void tst_QStaticText::rotatedScaledAndTranslatedPainter_data()
|
|
{
|
|
QTest::addColumn<qreal>("offset");
|
|
|
|
for (int i=0; i<100; ++i) {
|
|
qreal offset = 300 + i / 100.;
|
|
QTest::newRow(QByteArray::number(offset).constData()) << offset;
|
|
}
|
|
}
|
|
|
|
void tst_QStaticText::rotatedScaledAndTranslatedPainter()
|
|
{
|
|
QFETCH(qreal, offset);
|
|
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.translate(offset, 0);
|
|
p.rotate(45.0);
|
|
p.scale(2.0, 2.0);
|
|
p.translate(100, 200);
|
|
|
|
p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.translate(offset, 0);
|
|
p.rotate(45.0);
|
|
p.scale(2.0, 2.0);
|
|
p.translate(100, 200);
|
|
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("rotatedScaledAndPainter_imageDrawText.png");
|
|
imageDrawStaticText.save("rotatedScaledAndPainter_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
|
|
if (!supportsTransformations())
|
|
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
#endif
|
|
|
|
void tst_QStaticText::transformationChanged()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
imageDrawText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.rotate(33.0);
|
|
p.scale(0.5, 0.7);
|
|
|
|
p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
|
|
p.scale(2.0, 2.5);
|
|
p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
}
|
|
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
p.rotate(33.0);
|
|
p.scale(0.5, 0.7);
|
|
|
|
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
|
text.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(QPointF(0, 0), text);
|
|
|
|
p.scale(2.0, 2.5);
|
|
p.drawStaticText(QPointF(0, 0), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("transformationChanged_imageDrawText.png");
|
|
imageDrawStaticText.save("transformationChanged_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
|
|
#ifdef Q_OS_ANDROID
|
|
QEXPECT_FAIL("", "QTBUG-69220", Continue);
|
|
#endif
|
|
if (!supportsTransformations())
|
|
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
|
|
QCOMPARE(imageDrawStaticText, imageDrawText);
|
|
}
|
|
|
|
void tst_QStaticText::plainTextVsRichText()
|
|
{
|
|
QPixmap imagePlainText(1000, 1000);
|
|
imagePlainText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imagePlainText);
|
|
|
|
QStaticText staticText;
|
|
staticText.setText("FOObar");
|
|
staticText.setTextFormat(Qt::PlainText);
|
|
|
|
p.drawStaticText(10, 10, staticText);
|
|
}
|
|
|
|
QPixmap imageRichText(1000, 1000);
|
|
imageRichText.fill(Qt::white);
|
|
{
|
|
QPainter p(&imageRichText);
|
|
|
|
QStaticText staticText;
|
|
staticText.setText("<html><body>FOObar</body></html>");
|
|
staticText.setTextFormat(Qt::RichText);
|
|
|
|
p.drawStaticText(10, 10, staticText);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imagePlainText.save("plainTextVsRichText_imagePlainText.png");
|
|
imageRichText.save("plainTextVsRichText_imageRichText.png");
|
|
#endif
|
|
|
|
QVERIFY(imagePlainText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imagePlainText, imageRichText);
|
|
}
|
|
|
|
static bool checkPixels(const QImage &image,
|
|
Qt::GlobalColor expectedColor1, Qt::GlobalColor expectedColor2,
|
|
QByteArray *errorMessage)
|
|
{
|
|
const QRgb expectedRgb1 = QColor(expectedColor1).rgba();
|
|
const QRgb expectedRgb2 = QColor(expectedColor2).rgba();
|
|
|
|
for (int x = 0, w = image.width(); x < w; ++x) {
|
|
for (int y = 0, h = image.height(); y < h; ++y) {
|
|
const QRgb pixel = image.pixel(x, y);
|
|
if (pixel != expectedRgb1 && pixel != expectedRgb2) {
|
|
QString message;
|
|
QDebug(&message) << "Color mismatch in image" << image
|
|
<< "at" << x << ',' << y << ':' << Qt::showbase << Qt::hex << pixel
|
|
<< "(expected: " << expectedRgb1 << ',' << expectedRgb2 << ')';
|
|
*errorMessage = message.toLocal8Bit();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void tst_QStaticText::setPenPlainText_data()
|
|
{
|
|
QTest::addColumn<QImage::Format>("format");
|
|
|
|
QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied;
|
|
QTest::newRow("rgb32") << QImage::Format_RGB32;
|
|
QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied;
|
|
QTest::newRow("rgbx8888") << QImage::Format_RGBX8888;
|
|
}
|
|
|
|
void tst_QStaticText::setPenPlainText()
|
|
{
|
|
QFETCH(QImage::Format, format);
|
|
|
|
QFont font = QGuiApplication::font();
|
|
font.setStyleStrategy(QFont::NoAntialias);
|
|
|
|
QFontMetricsF fm(font);
|
|
QImage image(qCeil(fm.horizontalAdvance("XXXXX")), qCeil(fm.height()), format);
|
|
image.fill(Qt::white);
|
|
{
|
|
QPainter p(&image);
|
|
p.setFont(font);
|
|
p.setPen(Qt::yellow);
|
|
|
|
QStaticText staticText("XXXXX");
|
|
staticText.setTextFormat(Qt::PlainText);
|
|
p.drawStaticText(0, 0, staticText);
|
|
}
|
|
|
|
QByteArray errorMessage;
|
|
QVERIFY2(checkPixels(image, Qt::yellow, Qt::white, &errorMessage),
|
|
errorMessage.constData());
|
|
}
|
|
|
|
void tst_QStaticText::setPenRichText()
|
|
{
|
|
QFont font = QGuiApplication::font();
|
|
font.setStyleStrategy(QFont::NoAntialias);
|
|
|
|
QFontMetricsF fm(font);
|
|
QPixmap image(qCeil(fm.horizontalAdvance("XXXXX")), qCeil(fm.height()));
|
|
image.fill(Qt::white);
|
|
{
|
|
QPainter p(&image);
|
|
p.setFont(font);
|
|
p.setPen(Qt::green);
|
|
|
|
QStaticText staticText;
|
|
staticText.setText("<html><body>XXXXX</body></html>");
|
|
staticText.setTextFormat(Qt::RichText);
|
|
p.drawStaticText(0, 0, staticText);
|
|
}
|
|
|
|
QByteArray errorMessage;
|
|
QVERIFY2(checkPixels(image.toImage(), Qt::green, Qt::white, &errorMessage),
|
|
errorMessage.constData());
|
|
}
|
|
|
|
void tst_QStaticText::richTextOverridesPen()
|
|
{
|
|
QFont font = QGuiApplication::font();
|
|
font.setStyleStrategy(QFont::NoAntialias);
|
|
|
|
QFontMetricsF fm(font);
|
|
QPixmap image(qCeil(fm.horizontalAdvance("XXXXX")), qCeil(fm.height()));
|
|
image.fill(Qt::white);
|
|
{
|
|
QPainter p(&image);
|
|
p.setFont(font);
|
|
p.setPen(Qt::green);
|
|
|
|
QStaticText staticText;
|
|
staticText.setText("<html><body><font color=\"#ff0000\">XXXXX</font></body></html>");
|
|
staticText.setTextFormat(Qt::RichText);
|
|
p.drawStaticText(0, 0, staticText);
|
|
}
|
|
|
|
QByteArray errorMessage;
|
|
QVERIFY2(checkPixels(image.toImage(), Qt::red, Qt::white, &errorMessage),
|
|
errorMessage.constData());
|
|
}
|
|
|
|
void tst_QStaticText::drawStruckOutText()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
|
|
imageDrawText.fill(Qt::white);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
|
|
QString s = QString::fromLatin1("Foobar");
|
|
|
|
QFont font;
|
|
font.setStrikeOut(true);
|
|
font.setStyleStrategy(QFont::ForceIntegerMetrics);
|
|
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.setFont(font);
|
|
p.drawText(QPointF(50, 50), s);
|
|
}
|
|
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text = QStaticText(s);
|
|
p.setFont(font);
|
|
p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("drawStruckOutText_imageDrawText.png");
|
|
imageDrawStaticText.save("drawStruckOutText_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawText, imageDrawStaticText);
|
|
}
|
|
|
|
void tst_QStaticText::drawOverlinedText()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
|
|
imageDrawText.fill(Qt::white);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
|
|
QString s = QString::fromLatin1("Foobar");
|
|
|
|
QFont font;
|
|
font.setOverline(true);
|
|
font.setStyleStrategy(QFont::ForceIntegerMetrics);
|
|
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.setFont(font);
|
|
p.drawText(QPointF(50, 50), s);
|
|
}
|
|
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text = QStaticText(s);
|
|
p.setFont(font);
|
|
p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("drawOverlinedText_imageDrawText.png");
|
|
imageDrawStaticText.save("drawOverlinedText_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QVERIFY(imageDrawText.toImage() != m_whiteSquare);
|
|
QCOMPARE(imageDrawText, imageDrawStaticText);
|
|
}
|
|
|
|
void tst_QStaticText::drawUnderlinedText()
|
|
{
|
|
QPixmap imageDrawText(1000, 1000);
|
|
QPixmap imageDrawStaticText(1000, 1000);
|
|
|
|
imageDrawText.fill(Qt::white);
|
|
imageDrawStaticText.fill(Qt::white);
|
|
|
|
QString s = QString::fromLatin1("Foobar");
|
|
|
|
QFont font;
|
|
font.setUnderline(true);
|
|
font.setStyleStrategy(QFont::ForceIntegerMetrics);
|
|
|
|
{
|
|
QPainter p(&imageDrawText);
|
|
p.setFont(font);
|
|
p.drawText(QPointF(50, 50), s);
|
|
}
|
|
|
|
{
|
|
QPainter p(&imageDrawStaticText);
|
|
QStaticText text = QStaticText(s);
|
|
p.setFont(font);
|
|
p.drawStaticText(QPointF(50, 50 - QFontMetricsF(p.font()).ascent()), text);
|
|
}
|
|
|
|
#if defined(DEBUG_SAVE_IMAGE)
|
|
imageDrawText.save("drawUnderlinedText_imageDrawText.png");
|
|
imageDrawStaticText.save("drawUnderlinedText_imageDrawStaticText.png");
|
|
#endif
|
|
|
|
QCOMPARE(imageDrawText, imageDrawStaticText);
|
|
}
|
|
|
|
void tst_QStaticText::unprintableCharacter_qtbug12614()
|
|
{
|
|
QString s(QChar(0x200B)); // U+200B, ZERO WIDTH SPACE
|
|
|
|
QStaticText staticText(s);
|
|
|
|
QVERIFY(staticText.size().isValid()); // Force layout. Should not crash.
|
|
}
|
|
|
|
#ifdef QT_BUILD_INTERNAL
|
|
void tst_QStaticText::underlinedColor_qtbug20159()
|
|
{
|
|
QString multiScriptText;
|
|
multiScriptText += QChar(0x0410); // Cyrillic 'A'
|
|
multiScriptText += QLatin1Char('A');
|
|
|
|
QStaticText staticText(multiScriptText);
|
|
|
|
QFont font;
|
|
font.setUnderline(true);
|
|
|
|
staticText.prepare(QTransform(), font);
|
|
|
|
QStaticTextPrivate *d = QStaticTextPrivate::get(&staticText);
|
|
QCOMPARE(d->itemCount, 2);
|
|
|
|
// The pen should not be marked as dirty when drawing the underline
|
|
QVERIFY(!d->items[0].color.isValid());
|
|
QVERIFY(!d->items[1].color.isValid());
|
|
}
|
|
|
|
void tst_QStaticText::textDocumentColor()
|
|
{
|
|
QStaticText staticText("A<font color=\"red\">B</font>");
|
|
staticText.setTextFormat(Qt::RichText);
|
|
staticText.prepare();
|
|
|
|
QStaticTextPrivate *d = QStaticTextPrivate::get(&staticText);
|
|
QCOMPARE(d->itemCount, 2);
|
|
|
|
// The pen should not be marked as dirty when drawing the underline
|
|
QVERIFY(!d->items[0].color.isValid());
|
|
QVERIFY(d->items[1].color.isValid());
|
|
|
|
QCOMPARE(d->items[1].color, QColor(Qt::red));
|
|
}
|
|
#endif
|
|
|
|
class TestPaintEngine: public QPaintEngine
|
|
{
|
|
public:
|
|
void drawTextItem(const QPointF &p, const QTextItem &) override
|
|
{
|
|
differentVerticalPositions.insert(qRound(p.y()));
|
|
}
|
|
|
|
void updateState(const QPaintEngineState &) override {}
|
|
|
|
void drawPolygon(const QPointF *, int , PolygonDrawMode ) override {}
|
|
|
|
bool begin(QPaintDevice *) override { return true; }
|
|
bool end() override { return true; }
|
|
void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) override {}
|
|
Type type() const override
|
|
{
|
|
return User;
|
|
}
|
|
|
|
QSet<int> differentVerticalPositions;
|
|
};
|
|
|
|
class TestPixmap: public QPixmap
|
|
{
|
|
public:
|
|
TestPixmap(int w, int h) : QPixmap(w, h), testPaintEngine(new TestPaintEngine) {}
|
|
~TestPixmap() { delete testPaintEngine; }
|
|
|
|
QPaintEngine *paintEngine() const
|
|
{
|
|
return testPaintEngine;
|
|
}
|
|
|
|
TestPaintEngine *testPaintEngine;
|
|
};
|
|
|
|
void tst_QStaticText::multiLine()
|
|
{
|
|
TestPixmap pixmap(100, 100);
|
|
|
|
TestPaintEngine *paintEngine = pixmap.testPaintEngine;
|
|
|
|
{
|
|
QPainter p(&pixmap);
|
|
QStaticText text;
|
|
text.setText(QLatin1String("line 1") + QChar(QChar::LineSeparator) + QLatin1String("line 2"));
|
|
p.drawStaticText(0, 0, text);
|
|
}
|
|
|
|
QCOMPARE(paintEngine->differentVerticalPositions.size(), 2);
|
|
}
|
|
|
|
void tst_QStaticText::size_qtbug65836()
|
|
{
|
|
const QString text = QLatin1String("Lorem ipsum dolor sit amet, "
|
|
"consectetur adipiscing elit.");
|
|
QFont font("Courier");
|
|
font.setPixelSize(15);
|
|
|
|
{
|
|
QStaticText st1(text);
|
|
st1.setTextFormat(Qt::PlainText);
|
|
st1.prepare(QTransform(), font);
|
|
|
|
QStaticText st2(text);
|
|
st2.setTextFormat(Qt::RichText);
|
|
QTextOption opt;
|
|
opt.setWrapMode(QTextOption::NoWrap);
|
|
st2.setTextOption(opt);
|
|
st2.prepare(QTransform(), font);
|
|
|
|
QCOMPARE(st1.size(), st2.size());
|
|
}
|
|
|
|
{
|
|
QStaticText st1(text);
|
|
st1.setTextFormat(Qt::PlainText);
|
|
st1.setTextWidth(10.0);
|
|
st1.prepare(QTransform(), font);
|
|
|
|
QStaticText st2(text);
|
|
st2.setTextFormat(Qt::RichText);
|
|
st2.setTextWidth(10.0);
|
|
st2.prepare(QTransform(), font);
|
|
|
|
QCOMPARE(st1.size(), st2.size());
|
|
}
|
|
}
|
|
|
|
QTEST_MAIN(tst_QStaticText)
|
|
#include "tst_qstatictext.moc"
|