Serialize QPicture using the latest QDataStream version.

The QDataStream version with which QPicture was previously serialized
with was hard-coded to 11 (Qt 4.5). This prevents features of
serializable types used by QPicture from being serialized if they
were added after Qt 4.5; namely features of QFont like
HintingPreference.

[ChangeLog][QtGui][QPicture] QPicture now serializes its data properly
by also accounting for QDataStream versions greater than Qt 4.5.

Task-number: QTBUG-20578

Change-Id: Idd27682b187f4d4a3695c52bbf68e84853c024a8
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
Mitch Curtis 2014-03-31 18:05:32 +02:00 committed by The Qt Project
parent 463d58325c
commit 78f6d144d6
2 changed files with 84 additions and 25 deletions

View File

@ -118,7 +118,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
*/
const char *qt_mfhdr_tag = "QPIC"; // header tag
static const quint16 mfhdr_maj = 11; // major version #
static const quint16 mfhdr_maj = QDataStream::Qt_DefaultCompiledVersion; // major version #
static const quint16 mfhdr_min = 0; // minor version #
/*!

View File

@ -45,6 +45,7 @@
#include <qpicture.h>
#include <qpainter.h>
#include <qimage.h>
#include <qpaintengine.h>
#ifndef QT_NO_WIDGETS
#include <qdesktopwidget.h>
#include <qapplication.h>
@ -64,7 +65,7 @@ private slots:
void paintingActive();
void boundingRect();
void swap();
void operator_lt_lt();
void serialization();
#ifndef QT_NO_WIDGETS
void save_restore();
@ -169,36 +170,94 @@ void tst_QPicture::swap()
QCOMPARE(p2.boundingRect(), QRect(0,0,5,5));
}
// operator<< and operator>>
void tst_QPicture::operator_lt_lt()
Q_DECLARE_METATYPE(QDataStream::Version)
Q_DECLARE_METATYPE(QPicture)
void ensureSerializesCorrectly(const QPicture &picture, QDataStream::Version version)
{
// streaming of null pictures
{
QPicture pic1, pic2;
QByteArray ba( 100, 0 );
QDataStream str1( &ba, QIODevice::WriteOnly );
str1 << pic1;
QDataStream str2( &ba, QIODevice::ReadOnly );
str2 >> pic2;
QVERIFY( pic2.isNull() );
QDataStream stream;
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
stream.setDevice(&buffer);
stream.setVersion(version);
stream << picture;
buffer.close();
buffer.open(QIODevice::ReadOnly);
QPicture readpicture;
stream >> readpicture;
QVERIFY2(memcmp(picture.data(), readpicture.data(), picture.size()) == 0,
qPrintable(QString::fromLatin1("Picture data does not compare equal for QDataStream version %1").arg(version)));
}
// picture with a simple line, checking bitwise equality
class PaintEngine : public QPaintEngine
{
QPicture pic1, pic2;
QPainter p( &pic1 );
p.drawLine( 10, 20, 30, 40 );
p.end();
QByteArray ba( 10 * pic1.size(), 0 );
QDataStream str1( &ba, QIODevice::WriteOnly );
str1 << pic1;
QDataStream str2( &ba, QIODevice::ReadOnly );
str2 >> pic2;
QCOMPARE( pic1.size(), pic2.size() );
QVERIFY( memcmp( pic1.data(), pic2.data(), pic1.size() ) == 0 );
public:
PaintEngine() : QPaintEngine() {}
bool begin(QPaintDevice *) { return true; }
bool end() { return true; }
void updateState(const QPaintEngineState &) {}
void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {}
Type type() const { return Raster; }
QFont font() { return state->font(); }
};
class Picture : public QPicture
{
public:
Picture() : QPicture() {}
QPaintEngine *paintEngine() const { return (QPaintEngine*)&mPaintEngine; }
private:
PaintEngine mPaintEngine;
};
void tst_QPicture::serialization()
{
QDataStream stream;
const int thisVersion = stream.version();
for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) {
const QDataStream::Version versionEnum = static_cast<QDataStream::Version>(version);
{
// streaming of null pictures
ensureSerializesCorrectly(QPicture(), versionEnum);
}
{
// picture with a simple line, checking bitwise equality
QPicture picture;
QPainter painter(&picture);
painter.drawLine(10, 20, 30, 40);
ensureSerializesCorrectly(picture, versionEnum);
}
}
{
// Test features that were added after Qt 4.5, as that was hard-coded as the major
// version for a while, which was incorrect. In this case, we'll test font hints.
QPicture picture;
QPainter painter;
QFont font;
font.setStyleName("Blah");
font.setHintingPreference(QFont::PreferFullHinting);
painter.begin(&picture);
painter.setFont(font);
painter.drawText(20, 20, "Hello");
painter.end();
Picture customPicture;
painter.begin(&customPicture);
picture.play(&painter);
const QFont actualFont = ((PaintEngine*)customPicture.paintEngine())->font();
painter.end();
QCOMPARE(actualFont.styleName(), QStringLiteral("Blah"));
QCOMPARE(actualFont.hintingPreference(), QFont::PreferFullHinting);
}
}
#ifndef QT_NO_WIDGETS
static QPointF scalePoint(const QPointF &point, QPaintDevice *sourceDevice, QPaintDevice *destDevice)
{