/**************************************************************************** ** ** 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 #include #include #include #include #include #ifdef QT_BUILD_INTERNAL #include #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("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("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("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; 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); 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("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); 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("FOObar"); 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 << ':' << showbase << hex << pixel << "(expected: " << expectedRgb1 << ',' << expectedRgb2 << ')'; *errorMessage = message.toLocal8Bit(); return false; } } } return true; } void tst_QStaticText::setPenPlainText_data() { QTest::addColumn("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("XXXXX"); 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("XXXXX"); 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("AB"); 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 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"