diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 10b8ade117..e94fad8890 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -201,10 +201,9 @@ public: inline void insertProperty(qint32 key, const QVariant &value) { hashDirty = true; - if ((key >= QTextFormat::FirstFontProperty && key <= QTextFormat::LastFontProperty) - || key == QTextFormat::FontLetterSpacingType) { + if (key >= QTextFormat::FirstFontProperty && key <= QTextFormat::LastFontProperty) fontDirty = true; - } + for (int i = 0; i < props.count(); ++i) if (props.at(i).key == key) { props[i].value = value; @@ -218,10 +217,8 @@ public: for (int i = 0; i < props.count(); ++i) if (props.at(i).key == key) { hashDirty = true; - if ((key >= QTextFormat::FirstFontProperty && key <= QTextFormat::LastFontProperty) - || key == QTextFormat::FontLetterSpacingType) { + if (key >= QTextFormat::FirstFontProperty && key <= QTextFormat::LastFontProperty) fontDirty = true; - } props.remove(i); return; } @@ -444,7 +441,22 @@ void QTextFormatPrivate::recalcFont() const #ifndef QT_NO_DATASTREAM Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt) { - stream << fmt.format_type << fmt.properties(); + QMap properties = fmt.properties(); + if (stream.version() < QDataStream::Qt_6_0) { + auto it = properties.find(QTextFormat::FontLetterSpacingType); + if (it != properties.end()) { + properties[QTextFormat::OldFontLetterSpacingType] = it.value(); + properties.erase(it); + } + + it = properties.find(QTextFormat::FontStretch); + if (it != properties.end()) { + properties[QTextFormat::OldFontStretch] = it.value(); + properties.erase(it); + } + } + + stream << fmt.format_type << properties; return stream; } @@ -459,8 +471,14 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) fmt.d = new QTextFormatPrivate(); for (QMap::ConstIterator it = properties.constBegin(); - it != properties.constEnd(); ++it) - fmt.d->insertProperty(it.key(), it.value()); + it != properties.constEnd(); ++it) { + qint32 key = it.key(); + if (key == QTextFormat::OldFontLetterSpacingType) + key = QTextFormat::FontLetterSpacingType; + else if (key == QTextFormat::OldFontStretch) + key = QTextFormat::FontStretch; + fmt.d->insertProperty(key, it.value()); + } return stream; } @@ -620,6 +638,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value IsAnchor \value AnchorHref \value AnchorName + \omitvalue OldFontLetterSpacingType + \omitvalue OldFontStretch \value ObjectType List properties diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 28da0fe344..b4db18289e 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -184,16 +184,16 @@ public: // character properties FirstFontProperty = 0x1FE0, FontCapitalization = FirstFontProperty, - FontLetterSpacingType = 0x2033, FontLetterSpacing = 0x1FE1, FontWordSpacing = 0x1FE2, - FontStretch = 0x2034, FontStyleHint = 0x1FE3, FontStyleStrategy = 0x1FE4, FontKerning = 0x1FE5, FontHintingPreference = 0x1FE6, FontFamilies = 0x1FE7, FontStyleName = 0x1FE8, + FontLetterSpacingType = 0x1FE9, + FontStretch = 0x1FEA, FontFamily = 0x2000, FontPointSize = 0x2001, FontSizeAdjustment = 0x2002, @@ -207,7 +207,7 @@ public: FontPixelSize = 0x2009, LastFontProperty = FontPixelSize, - TextUnderlineColor = 0x2010, + TextUnderlineColor = 0x2020, TextVerticalAlignment = 0x2021, TextOutline = 0x2022, TextUnderlineStyle = 0x2023, @@ -216,6 +216,12 @@ public: IsAnchor = 0x2030, AnchorHref = 0x2031, AnchorName = 0x2032, + + // Included for backwards compatibility with old QDataStreams. + // Should not be referenced in user code. + OldFontLetterSpacingType = 0x2033, + OldFontStretch = 0x2034, + ObjectType = 0x2f00, // list properties diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp index 4ab80bdcfe..4e5ef7c555 100644 --- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp +++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp @@ -40,6 +40,10 @@ #include #include +#ifndef QT_NO_DATASTREAM +# include +#endif + class tst_QTextFormat : public QObject { Q_OBJECT @@ -61,6 +65,10 @@ private slots: void setFont_collection_data(); void setFont_collection(); void clearCollection(); + +#ifndef QT_NO_DATASTREAM + void dataStreamCompatibility(); +#endif }; /*! \internal @@ -677,5 +685,125 @@ void tst_QTextFormat::clearCollection() 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"