Fix deserializing Qt 5.x fonts through QDataStream

In Qt 5, fonts had both singular family and plural families properties,
and both were stored separately when streaming through QDataStream. The
families list was treated as an extension of family in this case, and
the primary font family was always the singular family property.

In Qt 6, it has been merged into one and family() is now just a
convenience for families().at(0).

But when reading files generated with Qt 5, we would ignore the fact
that these were previously separated. We would first read the family
entry into the families list, and then we would later overwrite this
with  an empty families list.

Instead, we detect streams created with Qt 5.15 or lower and make sure
we append the families list instead of overwriting it in this case. In
addition, we need to make sure we split up the list again when
outputting to Qt 5.x.

This adds a file generated with QDataStream in Qt 5.15 to the test to
verify.

[ChangeLog][Fonts] Fixed a problem deserializing the family of fonts
that had been serialized using QDataStream in Qt 5.

Pick-to: 6.2
Fixes: QTBUG-97995
Change-Id: Id3c6e13fc2375685643caee5f8e3009c00918ccb
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
bb10
Eskil Abrahamsen Blomfeldt 2021-11-12 08:14:25 +01:00
parent 4bee9cdc0a
commit 71faedc5b4
5 changed files with 50 additions and 3 deletions

View File

@ -2387,8 +2387,12 @@ QDataStream &operator<<(QDataStream &s, const QFont &font)
s << (quint8)font.d->request.hintingPreference;
if (s.version() >= QDataStream::Qt_5_6)
s << (quint8)font.d->capital;
if (s.version() >= QDataStream::Qt_5_13)
s << font.d->request.families;
if (s.version() >= QDataStream::Qt_5_13) {
if (s.version() < QDataStream::Qt_6_0)
s << font.d->request.families.mid(1);
else
s << font.d->request.families;
}
return s;
}
@ -2498,7 +2502,10 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
if (s.version() >= QDataStream::Qt_5_13) {
QStringList value;
s >> value;
font.d->request.families = value;
if (s.version() < QDataStream::Qt_6_0)
font.d->request.families.append(value);
else
font.d->request.families = value;
}
return s;
}

View File

@ -16,6 +16,7 @@ qt_internal_add_test(tst_qfont
# Resources:
set(testfont_resource_files
"datastream.515"
"weirdfont.otf"
)

Binary file not shown.

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>weirdfont.otf</file>
<file>datastream.515</file>
</qresource>
</RCC>

View File

@ -62,6 +62,7 @@ private slots:
void insertAndRemoveSubstitutions();
void serialize_data();
void serialize();
void deserializeQt515();
void styleName();
void defaultFamily_data();
@ -511,6 +512,43 @@ void tst_QFont::serialize()
}
}
void tst_QFont::deserializeQt515()
{
QFile file;
file.setFileName(QFINDTESTDATA("datastream.515"));
QVERIFY(file.open(QIODevice::ReadOnly));
QFont font;
{
QDataStream stream(&file);
stream.setVersion(QDataStream::Qt_5_15);
stream >> font;
}
QCOMPARE(font.family(), QStringLiteral("FirstFamily"));
QCOMPARE(font.families().size(), 3);
QCOMPARE(font.families().at(0), QStringLiteral("FirstFamily"));
QCOMPARE(font.families().at(1), QStringLiteral("OtherFamily1"));
QCOMPARE(font.families().at(2), QStringLiteral("OtherFamily2"));
QCOMPARE(font.pointSize(), 12);
QVERIFY(file.reset());
QByteArray fileContent = file.readAll();
QByteArray serializedContent;
{
QBuffer buffer(&serializedContent);
QVERIFY(buffer.open(QIODevice::WriteOnly));
QDataStream stream(&buffer);
stream.setVersion(QDataStream::Qt_5_15);
stream << font;
}
QCOMPARE(serializedContent, fileContent);
file.close();
}
void tst_QFont::styleName()
{
#if !defined(Q_OS_MAC)