/**************************************************************************** ** ** 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 #include #include #include #include #include #ifndef QT_NO_DATASTREAM # include #endif class tst_QTextFormat : public QObject { Q_OBJECT private slots: void getSetCheck(); void defaultAlignment(); void testQTextCharFormat() const; void testUnderlinePropertyPrecedence(); void toFormat(); void resolveFont(); void testLetterSpacing(); void testFontStretch(); void getSetTabs(); void testTabsUsed(); void testFontStyleSetters(); void setFont_data(); void setFont(); void setFont_collection_data(); void setFont_collection(); void clearCollection(); #ifndef QT_NO_DATASTREAM void dataStreamCompatibility(); #endif }; /*! \internal This (used to) trigger a crash in: QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) which is most easily produced through QSettings. */ void tst_QTextFormat::testQTextCharFormat() const { QSettings settings("test", "test"); QTextCharFormat test; settings.value("test", test); } // Testing get/set functions void tst_QTextFormat::getSetCheck() { QTextFormat obj1; // int QTextFormat::objectIndex() // void QTextFormat::setObjectIndex(int) obj1.setObjectIndex(0); QCOMPARE(0, obj1.objectIndex()); obj1.setObjectIndex(INT_MIN); QCOMPARE(INT_MIN, obj1.objectIndex()); obj1.setObjectIndex(INT_MAX); QCOMPARE(INT_MAX, obj1.objectIndex()); } void tst_QTextFormat::defaultAlignment() { QTextBlockFormat fmt; QVERIFY(!fmt.hasProperty(QTextFormat::BlockAlignment)); QCOMPARE(fmt.intProperty(QTextFormat::BlockAlignment), 0); QCOMPARE(fmt.alignment(), Qt::AlignLeft); } void tst_QTextFormat::testUnderlinePropertyPrecedence() { QTextCharFormat format; // use normal accessors and check internal state format.setUnderlineStyle(QTextCharFormat::NoUnderline); QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), false); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).toInt(), 0); format = QTextCharFormat(); format.setUnderlineStyle(QTextCharFormat::SingleUnderline); QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), true); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).toInt(), 1); format = QTextCharFormat(); format.setUnderlineStyle(QTextCharFormat::DotLine); QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), false); QCOMPARE(format.property(QTextFormat::FontUnderline).toBool(), false); QVERIFY(format.property(QTextFormat::TextUnderlineStyle).toInt() > 0); // override accessors and use setProperty to create a false state. // then check font() format = QTextCharFormat(); format.setProperty(QTextCharFormat::FontUnderline, true); QCOMPARE(format.property(QTextFormat::FontUnderline).isNull(), false); QCOMPARE(format.property(QTextFormat::TextUnderlineStyle).isNull(), true); QCOMPARE(format.fontUnderline(), true); QCOMPARE(format.font().underline(), true); format = QTextCharFormat(); // create conflict. Should use the new property format.setProperty(QTextCharFormat::TextUnderlineStyle, QTextCharFormat::SingleUnderline); format.setProperty(QTextCharFormat::FontUnderline, false); QCOMPARE(format.fontUnderline(), true); QCOMPARE(format.font().underline(), true); format = QTextCharFormat(); // create conflict. Should use the new property format.setProperty(QTextCharFormat::TextUnderlineStyle, QTextCharFormat::NoUnderline); format.setProperty(QTextCharFormat::FontUnderline, true); QCOMPARE(format.fontUnderline(), false); QCOMPARE(format.font().underline(), false); // do it again, but reverse the ordering (we use a QVector internally, so test a LOT ;) // create conflict. Should use the new property format.setProperty(QTextCharFormat::FontUnderline, false); format.setProperty(QTextCharFormat::TextUnderlineStyle, QTextCharFormat::SingleUnderline); QCOMPARE(format.fontUnderline(), true); QCOMPARE(format.font().underline(), true); format = QTextCharFormat(); // create conflict. Should use the new property format.setProperty(QTextCharFormat::FontUnderline, true); format.setProperty(QTextCharFormat::TextUnderlineStyle, QTextCharFormat::NoUnderline); QCOMPARE(format.fontUnderline(), false); QCOMPARE(format.font().underline(), false); } void tst_QTextFormat::toFormat() { { QTextFormat fmt = QTextFrameFormat(); QCOMPARE(fmt.toFrameFormat().type(), int(QTextFormat::FrameFormat)); } { QTextFormat fmt = QTextTableFormat(); QCOMPARE(fmt.toTableFormat().type(), int(QTextFormat::FrameFormat)); QCOMPARE(fmt.toTableFormat().objectType(), int(QTextFormat::TableObject)); } { QTextFormat fmt = QTextBlockFormat(); QCOMPARE(fmt.toBlockFormat().type(), int(QTextFormat::BlockFormat)); } { QTextFormat fmt = QTextCharFormat(); QCOMPARE(fmt.toCharFormat().type(), int(QTextFormat::CharFormat)); } { QTextFormat fmt = QTextListFormat(); QCOMPARE(fmt.toListFormat().type(), int(QTextFormat::ListFormat)); } } void tst_QTextFormat::resolveFont() { QTextDocument doc; QTextCharFormat fmt; fmt.setProperty(QTextFormat::ForegroundBrush, QColor(Qt::blue)); QCOMPARE(fmt.property(QTextFormat::ForegroundBrush).userType(), qMetaTypeId()); QCOMPARE(fmt.property(QTextFormat::ForegroundBrush).value(), QColor(Qt::blue)); fmt.setProperty(QTextFormat::FontItalic, true); QTextCursor(&doc).insertText("Test", fmt); QVector formats = doc.allFormats(); QCOMPARE(formats.count(), 3); QCOMPARE(formats.at(2).type(), int(QTextFormat::CharFormat)); fmt = formats.at(2).toCharFormat(); QVERIFY(!fmt.font().underline()); QVERIFY(fmt.hasProperty(QTextFormat::ForegroundBrush)); QFont f; f.setUnderline(true); doc.setDefaultFont(f); formats = doc.allFormats(); fmt = formats.at(2).toCharFormat(); QVERIFY(fmt.font().underline()); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); // verify that deleting a non-existent property does not affect the font resolving QVERIFY(!fmt.hasProperty(QTextFormat::BackgroundBrush)); fmt.clearProperty(QTextFormat::BackgroundBrush); QVERIFY(!fmt.hasProperty(QTextFormat::BackgroundBrush)); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); QVERIFY(fmt.font().underline()); // verify that deleting an existent but font _unrelated_ property does not affect the font resolving QVERIFY(fmt.hasProperty(QTextFormat::ForegroundBrush)); fmt.clearProperty(QTextFormat::ForegroundBrush); QVERIFY(!fmt.hasProperty(QTextFormat::ForegroundBrush)); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); QVERIFY(fmt.font().underline()); // verify that removing a font property _does_ clear the resolving QVERIFY(fmt.hasProperty(QTextFormat::FontItalic)); fmt.clearProperty(QTextFormat::FontItalic); QVERIFY(!fmt.hasProperty(QTextFormat::FontItalic)); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); QVERIFY(!fmt.font().underline()); QVERIFY(!fmt.font().italic()); // reset fmt = formats.at(2).toCharFormat(); QVERIFY(fmt.font().underline()); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); // verify that _setting_ an unrelated property does _not_ affect the resolving QVERIFY(!fmt.hasProperty(QTextFormat::IsAnchor)); fmt.setProperty(QTextFormat::IsAnchor, true); QVERIFY(fmt.hasProperty(QTextFormat::IsAnchor)); QVERIFY(fmt.font().underline()); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); // verify that setting a _related_ font property does affect the resolving // QVERIFY(!fmt.hasProperty(QTextFormat::FontStrikeOut)); fmt.setProperty(QTextFormat::FontStrikeOut, true); QVERIFY(fmt.hasProperty(QTextFormat::FontStrikeOut)); QVERIFY(!fmt.font().underline()); QVERIFY(!fmt.hasProperty(QTextFormat::FontUnderline)); QVERIFY(fmt.font().strikeOut()); } void tst_QTextFormat::testLetterSpacing() { QTextCharFormat format; QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacing), false); QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacingType), false); format.setFontLetterSpacingType(QFont::AbsoluteSpacing); QCOMPARE(format.font().letterSpacingType(), QFont::AbsoluteSpacing); format.setFontLetterSpacing(10.0); QCOMPARE(format.font().letterSpacing(), 10.0); QCOMPARE(format.hasProperty(QTextFormat::FontLetterSpacing), true); QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 10.0); QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::AbsoluteSpacing)); format.setFontLetterSpacingType(QFont::PercentageSpacing); QCOMPARE(format.font().letterSpacingType(), QFont::PercentageSpacing); format.setFontLetterSpacing(110.0); QCOMPARE(format.font().letterSpacing(), 110.0); QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 110.0); QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::PercentageSpacing)); format.setFontLetterSpacingType(QFont::AbsoluteSpacing); QCOMPARE(format.font().letterSpacingType(), QFont::AbsoluteSpacing); format.setFontLetterSpacing(10.0); QCOMPARE(format.font().letterSpacing(), 10.0); QCOMPARE(format.property(QTextFormat::FontLetterSpacingType).toInt(), int(QFont::AbsoluteSpacing)); QCOMPARE(format.property(QTextFormat::FontLetterSpacing).toDouble(), 10.0); } void tst_QTextFormat::testFontStretch() { QTextCharFormat format; QCOMPARE(format.hasProperty(QTextFormat::FontStretch), false); format.setFontStretch(130.0); QCOMPARE(format.property(QTextFormat::FontStretch).toInt(), 130); } void tst_QTextFormat::getSetTabs() { class Comparator { public: Comparator(const QList &tabs, const QList &tabs2) { QCOMPARE(tabs.count(), tabs2.count()); for(int i=0; i < tabs.count(); i++) { QTextOption::Tab t1 = tabs[i]; QTextOption::Tab t2 = tabs2[i]; QCOMPARE(t1.position, t2.position); QCOMPARE(t1.type, t2.type); QCOMPARE(t1.delimiter, t2.delimiter); } } }; QList tabs; QTextBlockFormat format; format.setTabPositions(tabs); Comparator c1(tabs, format.tabPositions()); QTextOption::Tab tab1; tab1.position = 1234; tabs.append(tab1); format.setTabPositions(tabs); Comparator c2(tabs, format.tabPositions()); QTextOption::Tab tab2(3456, QTextOption::RightTab, QChar('x')); tabs.append(tab2); format.setTabPositions(tabs); Comparator c3(tabs, format.tabPositions()); } void tst_QTextFormat::testTabsUsed() { QTextDocument doc; QTextCursor cursor(&doc); QList tabs; QTextBlockFormat format; QTextOption::Tab tab; tab.position = 100; tabs.append(tab); format.setTabPositions(tabs); cursor.mergeBlockFormat(format); cursor.insertText("foo\tbar"); //doc.setPageSize(QSizeF(200, 200)); doc.documentLayout()->pageCount(); // force layout; QTextBlock block = doc.begin(); QTextLayout *layout = block.layout(); QVERIFY(layout); QCOMPARE(layout->lineCount(), 1); QTextLine line = layout->lineAt(0); QCOMPARE(line.cursorToX(4), 100.); QTextOption option = layout->textOption(); QCOMPARE(option.tabs().count(), tabs.count()); } void tst_QTextFormat::testFontStyleSetters() { QTextCharFormat format; // test the setters format.setFontStyleHint(QFont::Serif); QCOMPARE(format.font().styleHint(), QFont::Serif); QCOMPARE(format.font().styleStrategy(), QFont::PreferDefault); format.setFontStyleStrategy(QFont::PreferOutline); QCOMPARE(format.font().styleStrategy(), QFont::PreferOutline); // test setting properties through setFont() QFont font; font.setStyleHint(QFont::SansSerif, QFont::PreferAntialias); format.setFont(font); QCOMPARE(format.font().styleHint(), QFont::SansSerif); QCOMPARE(format.font().styleStrategy(), QFont::PreferAntialias); // test kerning format.setFontKerning(false); QCOMPARE(format.font().kerning(), false); format.setFontKerning(true); QCOMPARE(format.font().kerning(), true); font.setKerning(false); format.setFont(font); QCOMPARE(format.font().kerning(), false); } Q_DECLARE_METATYPE(QTextCharFormat) void tst_QTextFormat::setFont_data() { QTest::addColumn("format1"); QTest::addColumn("format2"); QTest::addColumn("overrideAll"); QTextCharFormat format1; format1.setFontStyleHint(QFont::Serif); format1.setFontStyleStrategy(QFont::PreferOutline); format1.setFontCapitalization(QFont::AllUppercase); format1.setFontKerning(true); { QTest::newRow("noop|override") << format1 << format1 << true; QTest::newRow("noop|inherit") << format1 << format1 << false; } { QTextCharFormat format2; format2.setFontStyleHint(QFont::SansSerif); format2.setFontStyleStrategy(QFont::PreferAntialias); format2.setFontCapitalization(QFont::MixedCase); format2.setFontKerning(false); QTest::newRow("coverage|override") << format1 << format2 << true; QTest::newRow("coverage|inherit") << format1 << format2 << false; } { QTextCharFormat format2; format2.setFontStyleHint(QFont::SansSerif); format2.setFontStyleStrategy(QFont::PreferAntialias); QTest::newRow("partial|override") << format1 << format2 << true; QTest::newRow("partial|inherit") << format1 << format2 << false; } } void tst_QTextFormat::setFont() { QFETCH(QTextCharFormat, format1); QFETCH(QTextCharFormat, format2); QFETCH(bool, overrideAll); QTextCharFormat f; f.merge(format1); QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); QCOMPARE(f.fontKerning(), format1.fontKerning()); QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); f.merge(format2); QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); if (format2.hasProperty(QTextFormat::FontStyleHint)) QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint()); else QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint()); if (format2.hasProperty(QTextFormat::FontStyleStrategy)) QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy()); else QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy()); if (format2.hasProperty(QTextFormat::FontCapitalization)) QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization()); else QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization()); if (format2.hasProperty(QTextFormat::FontKerning)) QCOMPARE(f.font().kerning(), format2.fontKerning()); else QCOMPARE(f.font().kerning(), format1.fontKerning()); QFont font1 = format1.font(); QFont font2 = format2.font(); f = QTextCharFormat(); { QTextCharFormat tmp; tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll : QTextCharFormat::FontPropertiesSpecifiedOnly); f.merge(tmp); } QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); QCOMPARE(f.fontKerning(), format1.fontKerning()); QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); { QTextCharFormat tmp; tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll : QTextCharFormat::FontPropertiesSpecifiedOnly); f.merge(tmp); } QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); if (overrideAll || (font2.resolve() & QFont::StyleHintResolved)) QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint()); else QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint()); if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved)) QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy()); else QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy()); if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved)) QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization()); else QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization()); if (overrideAll || (font2.resolve() & QFont::KerningResolved)) QCOMPARE(f.font().kerning(), font2.kerning()); else QCOMPARE(f.font().kerning(), font1.kerning()); } void tst_QTextFormat::setFont_collection_data() { setFont_data(); } void tst_QTextFormat::setFont_collection() { QFETCH(QTextCharFormat, format1); QFETCH(QTextCharFormat, format2); QFETCH(bool, overrideAll); QFont font1 = format1.font(); QFont font2 = format2.font(); { QTextFormatCollection collection; collection.setDefaultFont(font1); int formatIndex = collection.indexForFormat(format1); QTextCharFormat f = collection.charFormat(formatIndex); QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); QCOMPARE(f.fontKerning(), format1.fontKerning()); QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); } { QTextFormatCollection collection; collection.setDefaultFont(font1); int formatIndex = collection.indexForFormat(format2); QTextCharFormat f = collection.charFormat(formatIndex); if (format2.hasProperty(QTextFormat::FontStyleHint)) QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint()); else QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint()); if (format2.hasProperty(QTextFormat::FontStyleStrategy)) QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy()); else QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy()); if (format2.hasProperty(QTextFormat::FontCapitalization)) QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization()); else QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization()); if (format2.hasProperty(QTextFormat::FontKerning)) QCOMPARE(f.font().kerning(), format2.fontKerning()); else QCOMPARE(f.font().kerning(), format1.fontKerning()); } { QTextFormatCollection collection; collection.setDefaultFont(font1); QTextCharFormat tmp; tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll : QTextCharFormat::FontPropertiesSpecifiedOnly); int formatIndex = collection.indexForFormat(tmp); QTextCharFormat f = collection.charFormat(formatIndex); QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint()); QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy()); QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization()); QCOMPARE(f.fontKerning(), format1.fontKerning()); QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint()); QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy()); QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization()); QCOMPARE(f.font().kerning(), f.fontKerning()); } { QTextFormatCollection collection; collection.setDefaultFont(font1); QTextCharFormat tmp; tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll : QTextCharFormat::FontPropertiesSpecifiedOnly); int formatIndex = collection.indexForFormat(tmp); QTextCharFormat f = collection.charFormat(formatIndex); if (overrideAll || (font2.resolve() & QFont::StyleHintResolved)) QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint()); else QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint()); if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved)) QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy()); else QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy()); if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved)) QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization()); else QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization()); if (overrideAll || (font2.resolve() & QFont::KerningResolved)) QCOMPARE(f.font().kerning(), font2.kerning()); else QCOMPARE(f.font().kerning(), font1.kerning()); } } void tst_QTextFormat::clearCollection() { QTextFormatCollection collection; QFont f; f.setUnderline(true); collection.setDefaultFont(f); QTextCharFormat charFormat; charFormat.setFontStyleHint(QFont::SansSerif); int formatIndex = collection.indexForFormat(charFormat); QCOMPARE(formatIndex, 0); QTextCharFormat charFormat2; charFormat2.setUnderlineStyle(QTextCharFormat::SingleUnderline); int formatIndex2 = collection.indexForFormat(charFormat2); QCOMPARE(formatIndex2, 1); QCOMPARE(collection.formats.count(), 2); QCOMPARE(collection.hashes.count(), 2); QCOMPARE(collection.defaultFont(), f); collection.clear(); QCOMPARE(collection.formats.count(), 0); QCOMPARE(collection.hashes.count(), 0); QCOMPARE(collection.indexForFormat(charFormat2), 0); QCOMPARE(collection.formats.count(), 1); QCOMPARE(collection.hashes.count(), 1); QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont } #ifndef QT_NO_DATASTREAM void tst_QTextFormat::dataStreamCompatibility() { // Make sure that we are still compatible with the old values of QTextFormat::FontLetterSpacingType // and QTextFormat::FontStretch, when used with earlier QDataStream versions QTextCharFormat format; format.setFontStretch(42); format.setFontLetterSpacingType(QFont::AbsoluteSpacing); // Sanity check { QMap properties = format.properties(); QVERIFY(properties.contains(QTextFormat::FontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::FontStretch)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); } QByteArray memory; // Current stream version { { QBuffer buffer(&memory); buffer.open(QIODevice::WriteOnly); QDataStream stream(&buffer); stream << format; } { QBuffer buffer(&memory); buffer.open(QIODevice::ReadOnly); QDataStream stream(&buffer); QTextFormat other; stream >> other; { QMap properties = other.properties(); QVERIFY(properties.contains(QTextFormat::FontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::FontStretch)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); } } { QBuffer buffer(&memory); buffer.open(QIODevice::ReadOnly); QDataStream stream(&buffer); quint32 type; stream >> type; QMap properties; stream >> properties; QVERIFY(properties.contains(QTextFormat::FontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::FontStretch)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); } } // Qt 5.15 stream version memory.clear(); { { QBuffer buffer(&memory); buffer.open(QIODevice::WriteOnly); QDataStream stream(&buffer); stream.setVersion(QDataStream::Qt_5_15); stream << format; } { QBuffer buffer(&memory); buffer.open(QIODevice::ReadOnly); QDataStream stream(&buffer); stream.setVersion(QDataStream::Qt_5_15); QTextFormat other; stream >> other; { QMap properties = other.properties(); QVERIFY(properties.contains(QTextFormat::FontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::FontStretch)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); } } { QBuffer buffer(&memory); buffer.open(QIODevice::ReadOnly); QDataStream stream(&buffer); stream.setVersion(QDataStream::Qt_5_15); quint32 type; stream >> type; // Verify that old data stream still has the compatibility values QMap properties; stream >> properties; QVERIFY(!properties.contains(QTextFormat::FontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::FontStretch)); QVERIFY(properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::OldFontStretch)); } } } #endif // QT_NO_DATASTREAM QTEST_MAIN(tst_QTextFormat) #include "tst_qtextformat.moc"