summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-02-07 12:44:03 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-03-10 10:58:03 +0100
commit761197e9d29f233dabb45d8adbed56725870348a (patch)
treeb591391ac15f50e41cca8ac09b700659f21dc229
parent1ef8470c805faf39e95ee8652cf473c231471eef (diff)
Fix distribution of font properties in QTextFormat
The area reserved for font properties was too small for the properties we needed, and as a result font properties were added outside of the area and special-cased (in the case of FontLetterSpacingType) or ignored (in the case of FontStretch) by conditions that check if the property is within the designated area. We reorganize the enum values now that we can, and allocate some more space for the font properties area. Fixes: QTBUG-65345 Change-Id: I8121ff7f72102d8022c6a6d2f8ed9c35dcdbb321 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/gui/text/qtextformat.cpp38
-rw-r--r--src/gui/text/qtextformat.h12
-rw-r--r--tests/auto/gui/text/qtextformat/tst_qtextformat.cpp128
3 files changed, 166 insertions, 12 deletions
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<int, QVariant> 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<qint32, QVariant>::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 <qtextlayout.h>
#include <qabstracttextdocumentlayout.h>
+#ifndef QT_NO_DATASTREAM
+# include <qdatastream.h>
+#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<int, QVariant> 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<int, QVariant> 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<qint32, QVariant> 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<int, QVariant> 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<qint32, QVariant> 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"