QtBase  v6.3.1
tst_qpicture.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 
30 #include <QTest>
31 #include <QBuffer>
32 
33 #include <qpicture.h>
34 #include <qpainter.h>
35 #include <qimage.h>
36 #include <qpaintengine.h>
37 #include <qguiapplication.h>
38 #include <qscreen.h>
39 #include <limits.h>
40 
41 #ifndef QT_NO_PICTURE
42 
43 class tst_QPicture : public QObject
44 {
45  Q_OBJECT
46 
47 public:
48  tst_QPicture();
49 
50 private slots:
51  void devType();
52  void paintingActive();
53  void boundingRect();
54  void swap();
55  void serialization();
56  void save_restore();
57  void boundaryValues_data();
58  void boundaryValues();
59 };
60 
62 {
63 }
64 
65 void tst_QPicture::devType()
66 {
67  QPicture p;
68  QCOMPARE( p.devType(), (int)QInternal::Picture );
69 }
70 
71 void tst_QPicture::paintingActive()
72 {
73  // actually implemented in QPainter but QPicture is a good
74  // example of an external paint device
75  QPicture p;
76  QVERIFY( !p.paintingActive() );
77  QPainter pt( &p );
78  QVERIFY( p.paintingActive() );
79  pt.end();
80  QVERIFY( !p.paintingActive() );
81 }
82 
83 void tst_QPicture::boundingRect()
84 {
85  QPicture p1;
86  // default value
87  QVERIFY( !p1.boundingRect().isValid() );
88 
89  QRect r1( 20, 30, 5, 15 );
90  p1.setBoundingRect( r1 );
91  QCOMPARE( p1.boundingRect(), r1 );
92  p1.setBoundingRect(QRect());
93 
94  QPainter pt( &p1 );
95  pt.drawLine( 10, 20, 110, 80 );
96  pt.end();
97 
98  // assignment and copy constructor
99  QRect r2( 10, 20, 100, 60 );
100  QCOMPARE( p1.boundingRect(), r2 );
101  QPicture p2( p1 );
102  QCOMPARE( p2.boundingRect(), r2 );
103  QPicture p3;
104  p3 = p1;
105  QCOMPARE( p3.boundingRect(), r2 );
106 
107  {
108  QPicture p4;
109  QPainter p(&p4);
110  p.drawLine(0, 0, 5, 0);
111  p.drawLine(0, 0, 0, 5);
112  p.end();
113 
114  QRect r3(0, 0, 5, 5);
115  QCOMPARE(p4.boundingRect(), r3);
116  }
117 }
118 
119 void tst_QPicture::swap()
120 {
121  QPicture p1, p2;
122  QPainter(&p1).drawLine(0, 0, 5, 5);
123  QPainter(&p2).drawLine(0, 3, 3, 0);
124  QCOMPARE(p1.boundingRect(), QRect(0,0,5,5));
125  QCOMPARE(p2.boundingRect(), QRect(0,0,3,3));
126  p1.swap(p2);
127  QCOMPARE(p1.boundingRect(), QRect(0,0,3,3));
128  QCOMPARE(p2.boundingRect(), QRect(0,0,5,5));
129 }
130 
133 
135  {
137 
138  QBuffer buffer;
140  stream.setDevice(&buffer);
141  stream.setVersion(version);
142  stream << picture;
143  buffer.close();
144 
146  QPicture readpicture;
147  stream >> readpicture;
148  QVERIFY2(memcmp(picture.data(), readpicture.data(), picture.size()) == 0,
149  qPrintable(QString::fromLatin1("Picture data does not compare equal for QDataStream version %1").arg(version)));
150 }
151 
152 class PaintEngine : public QPaintEngine
153 {
154 public:
156  bool begin(QPaintDevice *) override { return true; }
157  bool end() override { return true; }
158  void updateState(const QPaintEngineState &) override {}
159  void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) override {}
160  Type type() const override { return Raster; }
161 
162  QFont font() { return state->font(); }
163 };
164 
165 class Picture : public QPicture
166 {
167 public:
168  Picture() : QPicture() {}
169  QPaintEngine *paintEngine() const override { return (QPaintEngine*)&mPaintEngine; }
170 private:
171  PaintEngine mPaintEngine;
172 };
173 
174 void tst_QPicture::serialization()
175 {
177  const int thisVersion = stream.version();
178 
179  for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) {
180  const QDataStream::Version versionEnum = static_cast<QDataStream::Version>(version);
181 
182  {
183  // streaming of null pictures
184  ensureSerializesCorrectly(QPicture(), versionEnum);
185  }
186  {
187  // picture with a simple line, checking bitwise equality
190  painter.drawLine(10, 20, 30, 40);
191  ensureSerializesCorrectly(picture, versionEnum);
192  }
193  }
194 
195  {
196  // Test features that were added after Qt 4.5, as that was hard-coded as the major
197  // version for a while, which was incorrect. In this case, we'll test font hints.
200  QFont font;
201  font.setStyleName("Blah");
205  painter.drawText(20, 20, "Hello");
206  painter.end();
207 
208  Picture customPicture;
209  painter.begin(&customPicture);
210  picture.play(&painter);
211  const QFont actualFont = ((PaintEngine*)customPicture.paintEngine())->font();
212  painter.end();
213  QCOMPARE(actualFont.styleName(), QStringLiteral("Blah"));
215  }
216 }
217 
218 static QRectF scaleRect(const QRectF &rect, qreal xf, qreal yf)
219 {
220  return QRectF(rect.left() * xf, rect.top() * yf, rect.width() * xf, rect.height() * yf);
221 }
222 
223 static void paintStuff(QPainter *p)
224 {
226  // Calculate factors from the screen resolution against QPicture's 96DPI
227  // (enforced by Qt::AA_Use96Dpi as set by QTEST_MAIN).
228  const qreal xf = qreal(p->device()->logicalDpiX()) / screen->logicalDotsPerInchX();
229  const qreal yf = qreal(p->device()->logicalDpiY()) / screen->logicalDotsPerInchY();
230  p->drawRect(scaleRect(QRectF(100, 100, 100, 100), xf, yf));
231  p->save();
232  p->translate(10 * xf, 10 * yf);
233  p->restore();
234  p->drawRect(scaleRect(QRectF(100, 100, 100, 100), xf, yf));
235 }
236 
237 /* See task: 41469
238  Problem is that the state is not properly restored if the basestate of
239  the painter is different when the picture data was created compared to
240  the base state of the painter when it is played back.
241  */
242 void tst_QPicture::save_restore()
243 {
244  QPicture pic;
245  QPainter p;
246  p.begin(&pic);
247  paintStuff(&p);
248  p.end();
249 
250  QPixmap pix1(300, 300);
251  pix1.fill(Qt::white);
252  p.begin(&pix1);
253  p.drawPicture(50, 50, pic);
254  p.end();
255 
256  QPixmap pix2(300, 300);
257  pix2.fill(Qt::white);
258  p.begin(&pix2);
259  p.translate(50, 50);
260  paintStuff(&p);
261  p.end();
262 
263  QVERIFY( pix1.toImage() == pix2.toImage() );
264 }
265 
266 void tst_QPicture::boundaryValues_data()
267 {
268  QTest::addColumn<int>("x");
269  QTest::addColumn<int>("y");
270  QTest::newRow("max x") << INT_MAX << 50;
271  QTest::newRow("max y") << 50 << INT_MAX;
272  QTest::newRow("max x and y") << INT_MAX << INT_MAX;
273 
274  QTest::newRow("min x") << INT_MIN << 50;
275  QTest::newRow("min y") << 50 << INT_MIN;
276  QTest::newRow("min x and y") << INT_MIN << INT_MIN;
277 
278  QTest::newRow("min x, max y") << INT_MIN << INT_MAX;
279  QTest::newRow("max x, min y") << INT_MAX << INT_MIN;
280 }
281 
282 void tst_QPicture::boundaryValues()
283 {
285 
288 
289  QFETCH(int, x);
290  QFETCH(int, y);
292 
293  painter.end();
294 }
295 
297 #include "tst_qpicture.moc"
298 
299 #endif // QT_NO_PICTURE
void updateState(const QPaintEngineState &) override
bool begin(QPaintDevice *) override
bool end() override
void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) override
Type type() const override
QPaintEngine * paintEngine() const override
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:52
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
The QFont class specifies a query for a font used for drawing text.
Definition: qfont.h:56
QString styleName() const
Definition: qfont.cpp:864
HintingPreference hintingPreference() const
Definition: qfont.cpp:995
void setHintingPreference(HintingPreference hintingPreference)
Definition: qfont.cpp:978
@ PreferFullHinting
Definition: qfont.h:92
void setStyleName(const QString &)
Definition: qfont.cpp:882
QScreen * primaryScreen
the primary (or default) screen of the application.
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:87
QPaintEngineState * state
Definition: qpaintengine.h:234
The QPaintEngineState class provides information about the active paint engine's current state....
Definition: qpaintengine.h:268
QFont font() const
Definition: qpainter.cpp:7686
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
void drawPoint(const QPointF &pt)
Definition: qpainter.h:580
void drawLine(const QLineF &line)
Definition: qpainter.h:477
bool begin(QPaintDevice *)
Definition: qpainter.cpp:1709
void setFont(const QFont &f)
Definition: qpainter.cpp:3866
void drawText(const QPointF &p, const QString &s)
Definition: qpainter.cpp:5444
bool end()
Definition: qpainter.cpp:1877
The QPicture class is a paint device that records and replays QPainter commands.
Definition: qpicture.h:55
const char * data() const
Definition: qpicture.cpp:226
QRect boundingRect() const
Definition: qpicture.cpp:332
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
void swap(QPixmap &other) noexcept
Definition: qpixmap.h:79
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition: qscreen.h:68
qreal logicalDotsPerInchY
the number of logical dots or pixels per inch in the vertical direction
Definition: qscreen.h:93
qreal logicalDotsPerInchX
the number of logical dots or pixels per inch in the horizontal direction
Definition: qscreen.h:92
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
QPixmap p2
QPixmap p1
[0]
QCOMPARE(spy.count(), 1)
rect
[4]
int const char * version
Definition: zlib.h:814
auto it unsigned count const
Definition: hb-iter.hh:848
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
@ white
Definition: qnamespace.h:62
void
Definition: png.h:1080
EGLStreamKHR stream
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define Q_DECLARE_METATYPE(TYPE)
Definition: qmetatype.h:1417
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint buffer
GLint y
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
SSL_CTX int(*) void arg)
#define QStringLiteral(str)
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define QVERIFY2(statement, description)
Definition: qtestcase.h:76
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define slots
Definition: qtmetamacros.h:76
QScreen * screen
[1]
Definition: main.cpp:76
QRect r1(100, 200, 11, 16)
[0]
QRect r2(QPoint(100, 200), QSize(11, 16))
QPainter painter(this)
[7]
Definition: moc.h:48
void ensureSerializesCorrectly(const QPicture &picture, QDataStream::Version version)