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 <QtTest/QtTest> |
31 | #include <qpixmap.h> |
32 | #include <qbitmap.h> |
33 | #include <qimage.h> |
34 | #include <qimagereader.h> |
35 | #ifndef QT_NO_WIDGETS |
36 | #include <qdesktopwidget.h> |
37 | #include <qsplashscreen.h> |
38 | #endif |
39 | #include <qpaintengine.h> |
40 | |
41 | #include <qpa/qplatformpixmap.h> |
42 | #include <qpa/qplatformintegration.h> |
43 | #include <private/qguiapplication_p.h> |
44 | #include <private/qdrawhelper_p.h> |
45 | |
46 | #include <QSet> |
47 | |
48 | #ifdef Q_OS_WIN |
49 | #include <windows.h> |
50 | #endif |
51 | |
52 | |
53 | Q_DECLARE_METATYPE(QImage::Format) |
54 | |
55 | class tst_QPixmap : public QObject |
56 | { |
57 | Q_OBJECT |
58 | |
59 | public: |
60 | tst_QPixmap(); |
61 | |
62 | public slots: |
63 | void initTestCase(); |
64 | void cleanupTestCase(); |
65 | |
66 | private slots: |
67 | void swap(); |
68 | |
69 | void fromImage_data(); |
70 | void fromImage(); |
71 | |
72 | void fromUninitializedImage_data(); |
73 | void fromUninitializedImage(); |
74 | |
75 | void convertFromImage_data(); |
76 | void convertFromImage(); |
77 | void convertFromImageShouldDetach(); |
78 | |
79 | void testMetrics(); |
80 | |
81 | void scroll_data(); |
82 | void scroll(); |
83 | |
84 | void fill_data(); |
85 | void fill(); |
86 | void fill_transparent(); |
87 | |
88 | void createMaskFromColor(); |
89 | |
90 | void mask(); |
91 | void bitmapMask(); |
92 | void bitmapFromImageRvalue(); |
93 | void setGetMask_data(); |
94 | void setGetMask(); |
95 | void cacheKey(); |
96 | void drawBitmap(); |
97 | void isNull(); |
98 | void task_246446(); |
99 | void task_51271(); |
100 | |
101 | void convertFromImageNoDetach(); |
102 | void convertFromImageNoDetach2(); |
103 | void convertFromImageDetach(); |
104 | void convertFromImageCacheKey(); |
105 | |
106 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
107 | void toWinHBITMAP_data(); |
108 | void toWinHBITMAP(); |
109 | void fromWinHBITMAP_data(); |
110 | void fromWinHBITMAP(); |
111 | |
112 | void toWinHICON_data(); |
113 | void toWinHICON(); |
114 | void fromWinHICON_data(); |
115 | void fromWinHICON(); |
116 | #endif |
117 | |
118 | void onlyNullPixmapsOutsideGuiThread(); |
119 | void refUnref(); |
120 | |
121 | void copy(); |
122 | void deepCopyPreservesDpr(); |
123 | void fillPreservesDpr(); |
124 | void dprPassthrough(); |
125 | void depthOfNullObjects(); |
126 | |
127 | void transformed(); |
128 | void transformed2(); |
129 | |
130 | void fromImage_crash(); |
131 | |
132 | void load(); |
133 | void loadFromData(); |
134 | #if !defined(QT_NO_DATASTREAM) |
135 | void loadFromDataStream(); |
136 | #endif |
137 | |
138 | void fromData(); |
139 | void loadFromDataNullValues(); |
140 | |
141 | void loadFromDataImage_data(); |
142 | void loadFromDataImage(); |
143 | |
144 | void fromImageReader_data(); |
145 | void fromImageReader(); |
146 | |
147 | void fromImageReaderAnimatedGif_data(); |
148 | void fromImageReaderAnimatedGif(); |
149 | |
150 | void preserveDepth(); |
151 | #ifndef QT_NO_WIDGETS |
152 | void splash_crash(); |
153 | #endif |
154 | |
155 | void toImageDeepCopy(); |
156 | |
157 | void loadAsBitmapOrPixmap(); |
158 | |
159 | void scaled_QTBUG19157(); |
160 | void detachOnLoad_QTBUG29639(); |
161 | |
162 | void copyOnNonAlignedBoundary(); |
163 | void devicePixelRatio(); |
164 | |
165 | private: |
166 | const QString m_prefix; |
167 | const QString m_convertFromImage; |
168 | const QString m_loadFromData; |
169 | const QTemporaryDir m_tempDir; |
170 | }; |
171 | |
172 | static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) |
173 | { |
174 | QImage expectedImage = expected.toImage().convertToFormat(f: QImage::Format_RGB32); |
175 | QImage actualImage = actual.toImage().convertToFormat(f: QImage::Format_RGB32); |
176 | |
177 | if (expectedImage.size() != actualImage.size()) { |
178 | qWarning(msg: "Image size comparison failed: expected: %dx%d, got %dx%d" , |
179 | expectedImage.size().width(), expectedImage.size().height(), |
180 | actualImage.size().width(), actualImage.size().height()); |
181 | return false; |
182 | } |
183 | |
184 | const int size = actual.width() * actual.height(); |
185 | const int threshold = QPixmap::defaultDepth() == 16 ? 10 : 2; |
186 | |
187 | QRgb *a = (QRgb *)actualImage.bits(); |
188 | QRgb *e = (QRgb *)expectedImage.bits(); |
189 | for (int i = 0; i < size; ++i) { |
190 | const QColor ca(a[i]); |
191 | const QColor ce(e[i]); |
192 | if (qAbs(t: ca.red() - ce.red()) > threshold |
193 | || qAbs(t: ca.green() - ce.green()) > threshold |
194 | || qAbs(t: ca.blue() - ce.blue()) > threshold) { |
195 | qWarning(msg: "Color mismatch at pixel #%d: Expected: %d,%d,%d, got %d,%d,%d" , |
196 | i, ce.red(), ce.green(), ce.blue(), ca.red(), ca.green(), ca.blue()); |
197 | return false; |
198 | } |
199 | } |
200 | |
201 | return true; |
202 | } |
203 | |
204 | |
205 | tst_QPixmap::tst_QPixmap() |
206 | : m_prefix(QFINDTESTDATA("images/" )) |
207 | , m_convertFromImage(QFINDTESTDATA("convertFromImage" )) |
208 | , m_loadFromData(QFINDTESTDATA("loadFromData" )) |
209 | { |
210 | } |
211 | |
212 | void tst_QPixmap::initTestCase() |
213 | { |
214 | QVERIFY(!m_prefix.isEmpty()); |
215 | QVERIFY(!m_convertFromImage.isEmpty()); |
216 | QVERIFY(!m_loadFromData.isEmpty()); |
217 | QVERIFY2(m_tempDir.isValid(), qPrintable(m_tempDir.errorString())); |
218 | } |
219 | |
220 | void tst_QPixmap::cleanupTestCase() |
221 | { |
222 | } |
223 | |
224 | void tst_QPixmap::swap() |
225 | { |
226 | QPixmap p1( 16, 16 ), p2( 32, 32 ); |
227 | p1.fill( fillColor: Qt::white ); |
228 | p2.fill( fillColor: Qt::black ); |
229 | const qint64 p1k = p1.cacheKey(); |
230 | const qint64 p2k = p2.cacheKey(); |
231 | p1.swap(other&: p2); |
232 | QCOMPARE(p1.cacheKey(), p2k); |
233 | QCOMPARE(p1.size(), QSize(32,32)); |
234 | QCOMPARE(p2.cacheKey(), p1k); |
235 | QCOMPARE(p2.size(), QSize(16,16)); |
236 | } |
237 | |
238 | void tst_QPixmap::fromImage_data() |
239 | { |
240 | bool is16bit = false; |
241 | if (QPixmap::defaultDepth() == 16) |
242 | is16bit = true; |
243 | |
244 | QTest::addColumn<QImage::Format>(name: "format" ); |
245 | |
246 | QTest::newRow(dataTag: "Format_Mono" ) << QImage::Format_Mono; |
247 | QTest::newRow(dataTag: "Format_MonoLSB" ) << QImage::Format_MonoLSB; |
248 | // QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; |
249 | if (!is16bit) |
250 | QTest::newRow(dataTag: "Format_RGB32" ) << QImage::Format_RGB32; |
251 | QTest::newRow(dataTag: "Format_ARGB32" ) << QImage::Format_ARGB32; |
252 | QTest::newRow(dataTag: "Format_ARGB32_Premultiplied" ) << QImage::Format_ARGB32_Premultiplied; |
253 | if (!is16bit) |
254 | QTest::newRow(dataTag: "Format_RGB16" ) << QImage::Format_RGB16; |
255 | } |
256 | |
257 | void tst_QPixmap::fromImage() |
258 | { |
259 | QFETCH(QImage::Format, format); |
260 | |
261 | QImage image(37, 16, format); |
262 | |
263 | if (image.colorCount() == 2) { |
264 | image.setColor(i: 0, c: QColor(Qt::color0).rgba()); |
265 | image.setColor(i: 1, c: QColor(Qt::color1).rgba()); |
266 | } |
267 | image.fill(pixel: 0x7f7f7f7f); |
268 | |
269 | const QPixmap pixmap = QPixmap::fromImage(image); |
270 | const QImage result = pixmap.toImage(); |
271 | image = image.convertToFormat(f: result.format()); |
272 | QCOMPARE(result, image); |
273 | } |
274 | |
275 | |
276 | void tst_QPixmap::fromUninitializedImage_data() |
277 | { |
278 | QTest::addColumn<QImage::Format>(name: "format" ); |
279 | |
280 | QTest::newRow(dataTag: "Format_Mono" ) << QImage::Format_Mono; |
281 | QTest::newRow(dataTag: "Format_MonoLSB" ) << QImage::Format_MonoLSB; |
282 | QTest::newRow(dataTag: "Format_Indexed8" ) << QImage::Format_Indexed8; |
283 | QTest::newRow(dataTag: "Format_RGB32" ) << QImage::Format_RGB32; |
284 | QTest::newRow(dataTag: "Format_ARGB32" ) << QImage::Format_ARGB32; |
285 | QTest::newRow(dataTag: "Format_ARGB32_Premultiplied" ) << QImage::Format_ARGB32_Premultiplied; |
286 | QTest::newRow(dataTag: "Format_RGB16" ) << QImage::Format_RGB16; |
287 | } |
288 | |
289 | void tst_QPixmap::fromUninitializedImage() |
290 | { |
291 | QFETCH(QImage::Format, format); |
292 | |
293 | QImage image(100, 100, format); |
294 | QPixmap pix = QPixmap::fromImage(image); |
295 | |
296 | // it simply shouldn't crash... |
297 | QVERIFY(true); |
298 | |
299 | } |
300 | |
301 | void tst_QPixmap::convertFromImage_data() |
302 | { |
303 | QTest::addColumn<QImage>(name: "img1" ); |
304 | QTest::addColumn<QImage>(name: "img2" ); |
305 | |
306 | { |
307 | QImage img1; |
308 | QImage img2; |
309 | QVERIFY(img1.load(m_convertFromImage + "/task31722_0/img1.png" )); |
310 | QVERIFY(img2.load(m_convertFromImage + "/task31722_0/img2.png" )); |
311 | QVERIFY(img1.load(m_convertFromImage + "/task31722_0/img1.png" )); |
312 | QVERIFY(img2.load(m_convertFromImage + "/task31722_0/img2.png" )); |
313 | QTest::newRow(dataTag: "Task 31722 0" ) << img1 << img2; |
314 | } |
315 | { |
316 | QImage img1; |
317 | QImage img2; |
318 | QVERIFY(img1.load(m_convertFromImage + "/task31722_1/img1.png" )); |
319 | QVERIFY(img2.load(m_convertFromImage + "/task31722_1/img2.png" )); |
320 | QTest::newRow(dataTag: "Task 31722 1" ) << img1 << img2; |
321 | } |
322 | } |
323 | |
324 | void tst_QPixmap::convertFromImage() |
325 | { |
326 | QFETCH(QImage, img1); |
327 | QFETCH(QImage, img2); |
328 | |
329 | QPixmap pix = QPixmap::fromImage(image: img1); |
330 | pix = QPixmap::fromImage(image: img2); |
331 | |
332 | QPixmap res = QPixmap::fromImage(image: img2); |
333 | QCOMPARE(pix, res); |
334 | } |
335 | |
336 | void tst_QPixmap::convertFromImageShouldDetach() |
337 | { |
338 | QImage img1; |
339 | QImage img2; |
340 | QVERIFY(img1.load(m_convertFromImage + "/task31722_0/img1.png" )); |
341 | QVERIFY(img2.load(m_convertFromImage + "/task31722_0/img2.png" )); |
342 | QPixmap pix = QPixmap::fromImage(image: img1); |
343 | QPixmap pix1 = pix; |
344 | pix.convertFromImage(img: img2); |
345 | QCOMPARE(pix, QPixmap::fromImage(img2)); |
346 | QCOMPARE(pix1, QPixmap::fromImage(img1)); // unchanged |
347 | } |
348 | |
349 | void tst_QPixmap::scroll_data() |
350 | { |
351 | QTest::addColumn<QImage>(name: "input" ); |
352 | QTest::addColumn<int>(name: "dx" ); |
353 | QTest::addColumn<int>(name: "dy" ); |
354 | QTest::addColumn<QRect>(name: "rect" ); |
355 | QTest::addColumn<QRegion>(name: "exposed" ); |
356 | QTest::addColumn<bool>(name: "newPix" ); |
357 | |
358 | QImage input(":/images/designer.png" ); |
359 | |
360 | // Noop tests |
361 | QTest::newRow(dataTag: "null" ) << QImage() << 0 << 0 << QRect() << QRegion() << false; |
362 | QTest::newRow(dataTag: "dx_0_dy_0_null" ) << input << 0 << 0 << QRect() << QRegion() << false; |
363 | QTest::newRow(dataTag: "dx_1_dy_0_null" ) << input << 1 << 0 << QRect() << QRegion() << false; |
364 | QTest::newRow(dataTag: "dx_0_dy_1_null" ) << input << 0 << 1 << QRect() << QRegion() << false; |
365 | QTest::newRow(dataTag: "dx_0_dy_0_x_y_w_h" ) << input << 0 << 0 << input.rect() << QRegion() << false; |
366 | |
367 | QRegion r; |
368 | // Scroll whole pixmap |
369 | r = QRegion(); r += QRect(0, 0, 128, 10); |
370 | QTest::newRow(dataTag: "dx_0_dy_10_x_y_w_h" ) << input << 0 << 10 << input.rect() << r << true; |
371 | r = QRegion(); r += QRect(0, 0, 10, 128); |
372 | QTest::newRow(dataTag: "dx_10_dy_0_x_y_w_h" ) << input << 10 << 0 << input.rect() << r << true; |
373 | r = QRegion(); r += QRect(0, 0, 128, 10); r += QRect(0, 10, 10, 118); |
374 | QTest::newRow(dataTag: "dx_10_dy_10_x_y_w_h" ) << input << 10 << 10 << input.rect() << r << true; |
375 | r = QRegion(); r += QRect(118, 0, 10, 128); |
376 | QTest::newRow(dataTag: "dx_-10_dy_0_x_y_w_h" ) << input << -10 << 0 << input.rect() << r << true; |
377 | r = QRegion(); r += QRect(0, 118, 128, 10); |
378 | QTest::newRow(dataTag: "dx_0_dy_-10_x_y_w_h" ) << input << 0 << -10 << input.rect() << r << true; |
379 | r = QRegion(); r += QRect(118, 0, 10, 118); r += QRect(0, 118, 128, 10); |
380 | QTest::newRow(dataTag: "dx_-10_dy_-10_x_y_w_h" ) << input << -10 << -10 << input.rect() << r << true; |
381 | |
382 | // Scroll part of pixmap |
383 | QTest::newRow(dataTag: "dx_0_dy_0_50_50_100_100" ) << input << 0 << 0 << QRect(50, 50, 100, 100) << QRegion() << false; |
384 | r = QRegion(); r += QRect(50, 50, 10, 78); |
385 | QTest::newRow(dataTag: "dx_10_dy_0_50_50_100_100" ) << input << 10 << 0 << QRect(50, 50, 100, 100) << r << true; |
386 | r = QRegion(); r += QRect(50, 50, 78, 10); |
387 | QTest::newRow(dataTag: "dx_0_dy_10_50_50_100_100" ) << input << 0 << 10 << QRect(50, 50, 100, 100) << r << true; |
388 | r = QRegion(); r += QRect(50, 50, 78, 10); r += QRect(50, 60, 10, 68); |
389 | QTest::newRow(dataTag: "dx_10_dy_10_50_50_100_100" ) << input << 10 << 10 << QRect(50, 50, 100, 100) << r << true; |
390 | r = QRegion(); r += QRect(118, 50, 10, 78); |
391 | QTest::newRow(dataTag: "dx_-10_dy_0_50_50_100_100" ) << input << -10 << 0 << QRect(50, 50, 100, 100) << r << true; |
392 | r = QRegion(); r += QRect(50, 118, 78, 10); |
393 | QTest::newRow(dataTag: "dx_0_dy_-10_50_50_100_100" ) << input << 0 << -10 << QRect(50, 50, 100, 100) << r << true; |
394 | r = QRegion(); r += QRect(118, 50, 10, 68); r += QRect(50, 118, 78, 10); |
395 | QTest::newRow(dataTag: "dx_-10_dy_-10_50_50_100_100" ) << input << -10 << -10 << QRect(50, 50, 100, 100) << r << true; |
396 | |
397 | // Scroll away the whole pixmap |
398 | r = input.rect(); |
399 | QTest::newRow(dataTag: "dx_128_dy_0_x_y_w_h" ) << input << 128 << 0 << input.rect() << r << false; |
400 | QTest::newRow(dataTag: "dx_0_dy_128_x_y_w_h" ) << input << 0 << 128 << input.rect() << r << false; |
401 | QTest::newRow(dataTag: "dx_128_dy_128_x_y_w_h" ) << input << 128 << 128 << input.rect() << r << false; |
402 | QTest::newRow(dataTag: "dx_-128_dy_0_x_y_w_h" ) << input << -128 << 0 << input.rect() << r << false; |
403 | QTest::newRow(dataTag: "dx_0_dy_-128_x_y_w_h" ) << input << 0 << -128 << input.rect() << r << false; |
404 | QTest::newRow(dataTag: "dx_-128_dy_-128_x_y_w_h" ) << input << -128 << -128 << input.rect() << r << false; |
405 | |
406 | // Scroll away part of the pixmap |
407 | r = QRegion(); r += QRect(64, 64, 64, 64); |
408 | QTest::newRow(dataTag: "dx_128_dy_128_64_64_128_128" ) << input << 128 << 128 << QRect(64, 64, 128, 128) << r << false; |
409 | } |
410 | |
411 | void tst_QPixmap::scroll() |
412 | { |
413 | QFETCH(QImage, input); |
414 | QFETCH(int, dx); |
415 | QFETCH(int, dy); |
416 | QFETCH(QRect, rect); |
417 | QFETCH(QRegion, exposed); |
418 | QFETCH(bool, newPix); |
419 | |
420 | QPixmap pixmap = QPixmap::fromImage(image: input); |
421 | QRegion exp; |
422 | qint64 oldKey = pixmap.cacheKey(); |
423 | pixmap.scroll(dx, dy, rect, exposed: &exp); |
424 | if (!newPix) |
425 | QCOMPARE(pixmap.cacheKey(), oldKey); |
426 | else |
427 | QVERIFY(pixmap.cacheKey() != oldKey); |
428 | |
429 | const QString fileName = QLatin1String(":/images/" ) + QLatin1String(QTest::currentDataTag()) |
430 | + QLatin1String(".png" ); |
431 | QPixmap output(fileName); |
432 | QCOMPARE(input.isNull(), output.isNull()); |
433 | QVERIFY(lenientCompare(pixmap, output)); |
434 | QCOMPARE(exp, exposed); |
435 | } |
436 | |
437 | void tst_QPixmap::fill_data() |
438 | { |
439 | QTest::addColumn<uint>(name: "pixel" ); |
440 | QTest::addColumn<bool>(name: "syscolor" ); |
441 | QTest::addColumn<bool>(name: "bitmap" ); |
442 | for (int color = Qt::black; color < Qt::darkYellow; ++color) |
443 | QTest::newRow(dataTag: ("syscolor_" + QByteArray::number(color)).constData()) |
444 | << uint(color) << true << false; |
445 | |
446 | QPixmap pixmap(1, 1); |
447 | QTest::newRow(dataTag: "alpha_7f_red" ) << 0x7fff0000u << false << false; |
448 | QTest::newRow(dataTag: "alpha_3f_blue" ) << 0x3f0000ffu << false << false; |
449 | QTest::newRow(dataTag: "alpha_b7_green" ) << 0xbf00ff00u << false << false; |
450 | QTest::newRow(dataTag: "alpha_7f_white" ) << 0x7fffffffu << false << false; |
451 | QTest::newRow(dataTag: "alpha_3f_white" ) << 0x3fffffffu << false << false; |
452 | QTest::newRow(dataTag: "alpha_b7_white" ) << 0xb7ffffffu << false << false; |
453 | QTest::newRow(dataTag: "alpha_7f_black" ) << 0x7f000000u << false << false; |
454 | QTest::newRow(dataTag: "alpha_3f_black" ) << 0x3f000000u << false << false; |
455 | QTest::newRow(dataTag: "alpha_b7_black" ) << 0xbf000000u << false << false; |
456 | |
457 | QTest::newRow(dataTag: "bitmap_color0" ) << uint(Qt::color0) << true << true; |
458 | QTest::newRow(dataTag: "bitmap_color1" ) << uint(Qt::color1) << true << true; |
459 | } |
460 | |
461 | void tst_QPixmap::fill() |
462 | { |
463 | QFETCH(uint, pixel); |
464 | QFETCH(bool, syscolor); |
465 | QFETCH(bool, bitmap); |
466 | |
467 | QColor color; |
468 | |
469 | if (syscolor) |
470 | color = QColor(Qt::GlobalColor(pixel)); |
471 | else |
472 | color = QColor(qRed(rgb: pixel), qGreen(rgb: pixel), qBlue(rgb: pixel), qAlpha(rgb: pixel)); |
473 | |
474 | QColor compareColor = color; |
475 | if (bitmap && syscolor) { |
476 | // special case color0 and color1 for bitmaps. |
477 | if (pixel == Qt::color0) |
478 | compareColor.setRgb(r: 255, g: 255, b: 255); |
479 | else |
480 | compareColor.setRgb(r: 0, g: 0, b: 0); |
481 | } |
482 | |
483 | QPixmap pm; |
484 | |
485 | if (bitmap) |
486 | pm = QBitmap(400, 400); |
487 | else |
488 | pm = QPixmap(400, 400); |
489 | |
490 | pm.fill(fillColor: color); |
491 | if (syscolor && !bitmap && pm.depth() < 24) { |
492 | QSKIP("Test does not work on displays without true color" ); |
493 | } |
494 | |
495 | QImage image = pm.toImage(); |
496 | if (bitmap && syscolor) { |
497 | int pixelindex = (pixel == Qt::color0) ? 0 : 1; |
498 | QCOMPARE(image.pixelIndex(0,0), pixelindex); |
499 | } |
500 | QImage::Format format = compareColor.alpha() != 255 |
501 | ? QImage::Format_ARGB32 |
502 | : QImage::Format_RGB32; |
503 | image = image.convertToFormat(f: format); |
504 | |
505 | |
506 | QImage shouldBe(400, 400, format); |
507 | shouldBe.fill(pixel: compareColor.rgba()); |
508 | |
509 | QCOMPARE(image, shouldBe); |
510 | } |
511 | |
512 | void tst_QPixmap::fill_transparent() |
513 | { |
514 | QPixmap pixmap(10, 10); |
515 | pixmap.fill(fillColor: Qt::transparent); |
516 | QVERIFY(pixmap.hasAlphaChannel()); |
517 | } |
518 | |
519 | void tst_QPixmap::mask() |
520 | { |
521 | QPixmap pm(100, 100); |
522 | QBitmap bm(100, 100); |
523 | |
524 | pm.fill(); |
525 | bm.fill(); |
526 | |
527 | QVERIFY(!pm.isNull()); |
528 | QVERIFY(!bm.isNull()); |
529 | if (!pm.hasAlphaChannel()) { |
530 | // This would fail if the default pixmap format is |
531 | // argb32_premultiplied. The mask will be all 1's. |
532 | // Therefore this is skipped when the alpha channel is present. |
533 | QVERIFY(pm.mask().isNull()); |
534 | } |
535 | |
536 | QImage img = bm.toImage(); |
537 | QVERIFY(img.format() == QImage::Format_MonoLSB |
538 | || img.format() == QImage::Format_Mono); |
539 | |
540 | pm.setMask(bm); |
541 | QVERIFY(!pm.mask().isNull()); |
542 | |
543 | bm = QBitmap(); |
544 | // Invalid format here, since isNull() == true |
545 | QVERIFY(bm.toImage().isNull()); |
546 | QCOMPARE(bm.toImage().format(), QImage::Format_Invalid); |
547 | pm.setMask(bm); |
548 | QVERIFY(pm.mask().isNull()); |
549 | |
550 | bm = QBitmap(100, 100); |
551 | bm.fill(); |
552 | pm.setMask(bm); |
553 | QVERIFY(!pm.mask().isNull()); |
554 | } |
555 | |
556 | void tst_QPixmap::bitmapMask() |
557 | { |
558 | QImage image(3, 3, QImage::Format_Mono); |
559 | image.setColor(i: 0, c: Qt::color0); |
560 | image.setColor(i: 1, c: Qt::color1); |
561 | image.fill(color: Qt::color0); |
562 | image.setPixel(x: 1, y: 1, index_or_rgb: Qt::color1); |
563 | image.setPixel(x: 0, y: 0, index_or_rgb: Qt::color1); |
564 | |
565 | QImage image_mask(3, 3, QImage::Format_Mono); |
566 | image_mask.setColor(i: 0, c: Qt::color0); |
567 | image_mask.setColor(i: 1, c: Qt::color1); |
568 | image_mask.fill(color: Qt::color0); |
569 | image_mask.setPixel(x: 1, y: 1, index_or_rgb: Qt::color1); |
570 | image_mask.setPixel(x: 2, y: 0, index_or_rgb: Qt::color1); |
571 | |
572 | QBitmap pm = QBitmap::fromImage(image); |
573 | QBitmap pm_mask = QBitmap::fromImage(image: image_mask); |
574 | pm.setMask(pm_mask); |
575 | |
576 | image = pm.toImage(); |
577 | image.setColor(i: 0, c: Qt::color0); |
578 | image.setColor(i: 1, c: Qt::color1); |
579 | image_mask = pm_mask.toImage(); |
580 | image_mask.setColor(i: 0, c: Qt::color0); |
581 | image_mask.setColor(i: 1, c: Qt::color1); |
582 | |
583 | QVERIFY(!image.pixel(0, 0)); |
584 | QVERIFY(!image.pixel(2, 0)); |
585 | QVERIFY(image.pixel(1, 1)); |
586 | } |
587 | |
588 | void tst_QPixmap::bitmapFromImageRvalue() |
589 | { |
590 | auto makeImage = [](){ |
591 | QImage image(3, 3, QImage::Format_MonoLSB); |
592 | image.setColor(i: 0, c: Qt::color0); |
593 | image.setColor(i: 1, c: Qt::color1); |
594 | image.fill(color: Qt::color0); |
595 | image.setPixel(x: 1, y: 1, index_or_rgb: Qt::color1); |
596 | image.setPixel(x: 0, y: 0, index_or_rgb: Qt::color1); |
597 | return image; |
598 | }; |
599 | |
600 | auto image1 = makeImage(); |
601 | auto image2 = makeImage(); |
602 | auto bitmap1 = QBitmap::fromImage(image: image1); |
603 | auto bitmap2 = QBitmap::fromImage(image: std::move(image2)); |
604 | QCOMPARE(bitmap1.toImage(), bitmap2.toImage()); |
605 | QVERIFY(!image1.isNull()); |
606 | QVERIFY(image2.isNull()); |
607 | } |
608 | |
609 | void tst_QPixmap::setGetMask_data() |
610 | { |
611 | QTest::addColumn<QPixmap>(name: "pixmap" ); |
612 | QTest::addColumn<QBitmap>(name: "mask" ); |
613 | QTest::addColumn<QBitmap>(name: "expected" ); |
614 | |
615 | QPixmap pixmap(10, 10); |
616 | QBitmap mask(10, 10); |
617 | QPainter p; |
618 | |
619 | p.begin(&pixmap); |
620 | p.fillRect(x: 0, y: 0, w: 10, h: 10, b: QColor(Qt::black)); |
621 | p.end(); |
622 | |
623 | QTest::newRow(dataTag: "nullmask 0" ) << QPixmap() << QBitmap() << QBitmap(); |
624 | QTest::newRow(dataTag: "nullmask 1" ) << pixmap << QBitmap() << QBitmap(); |
625 | mask.clear(); |
626 | QTest::newRow(dataTag: "nullmask 2" ) << pixmap << mask << mask; |
627 | QTest::newRow(dataTag: "nullmask 3" ) << QPixmap(QBitmap()) << QBitmap() << QBitmap(); |
628 | |
629 | p.begin(&mask); |
630 | p.fillRect(x: 1, y: 1, w: 5, h: 5, b: QColor(Qt::color1)); |
631 | p.end(); |
632 | QTest::newRow(dataTag: "simple mask 0" ) << pixmap << mask << mask; |
633 | } |
634 | |
635 | void tst_QPixmap::setGetMask() |
636 | { |
637 | QFETCH(QPixmap, pixmap); |
638 | QFETCH(QBitmap, mask); |
639 | QFETCH(QBitmap, expected); |
640 | |
641 | pixmap.setMask(mask); |
642 | QBitmap result = pixmap.mask(); |
643 | |
644 | QImage resultImage = result.toImage(); |
645 | QImage expectedImage = expected.toImage(); |
646 | QCOMPARE(resultImage.convertToFormat(expectedImage.format()), |
647 | expectedImage); |
648 | } |
649 | |
650 | void tst_QPixmap::testMetrics() |
651 | { |
652 | QPixmap pixmap(100, 100); |
653 | |
654 | QCOMPARE(pixmap.width(), 100); |
655 | QCOMPARE(pixmap.height(), 100); |
656 | QVERIFY(pixmap.depth() >= QPixmap::defaultDepth()); |
657 | |
658 | QBitmap bitmap(100, 100); |
659 | |
660 | QCOMPARE(bitmap.width(), 100); |
661 | QCOMPARE(bitmap.height(), 100); |
662 | QCOMPARE(bitmap.depth(), 1); |
663 | |
664 | QPixmap null; |
665 | |
666 | QCOMPARE(null.size().width(), null.width()); |
667 | QCOMPARE(null.size().height(), null.height()); |
668 | } |
669 | |
670 | void tst_QPixmap::createMaskFromColor() |
671 | { |
672 | QImage image(3, 3, QImage::Format_Indexed8); |
673 | image.setColorCount(10); |
674 | image.setColor(i: 0, c: 0xffffffff); |
675 | image.setColor(i: 1, c: 0xff000000); |
676 | image.setColor(i: 2, c: 0xffff0000); |
677 | image.setColor(i: 3, c: 0xff0000ff); |
678 | image.fill(pixel: 0); |
679 | image.setPixel(x: 1, y: 0, index_or_rgb: 1); |
680 | image.setPixel(x: 0, y: 1, index_or_rgb: 2); |
681 | image.setPixel(x: 1, y: 1, index_or_rgb: 3); |
682 | |
683 | QImage im_mask = image.createMaskFromColor(color: 0xffff0000); |
684 | QCOMPARE((uint) im_mask.pixel(0, 1), QColor(Qt::color0).rgba()); |
685 | QCOMPARE((uint) im_mask.pixel(0, 1), QColor(Qt::color0).rgba()); |
686 | |
687 | QPixmap pixmap = QPixmap::fromImage(image); |
688 | QBitmap mask = pixmap.createMaskFromColor(maskColor: Qt::red); |
689 | QBitmap inv_mask = pixmap.createMaskFromColor(maskColor: Qt::red, mode: Qt::MaskOutColor); |
690 | QCOMPARE((uint) mask.toImage().pixel(0, 1), QColor(Qt::color0).rgba()); |
691 | QCOMPARE((uint) inv_mask.toImage().pixel(0, 1), QColor(Qt::color1).rgba()); |
692 | } |
693 | |
694 | |
695 | void tst_QPixmap::cacheKey() |
696 | { |
697 | QPixmap pixmap1(1, 1); |
698 | QPixmap pixmap2(1, 1); |
699 | qint64 pixmap1_key = pixmap1.cacheKey(); |
700 | |
701 | QVERIFY(pixmap1.cacheKey() != pixmap2.cacheKey()); |
702 | |
703 | pixmap2 = pixmap1; |
704 | QCOMPARE(pixmap2.cacheKey(), pixmap1.cacheKey()); |
705 | |
706 | pixmap2.detach(); |
707 | QVERIFY(pixmap2.cacheKey() != pixmap1.cacheKey()); |
708 | QCOMPARE(pixmap1.cacheKey(), pixmap1_key); |
709 | } |
710 | |
711 | // Test drawing a bitmap on a pixmap. |
712 | void tst_QPixmap::drawBitmap() |
713 | { |
714 | QBitmap bitmap(10,10); |
715 | bitmap.fill(fillColor: Qt::color1); |
716 | |
717 | QPixmap pixmap(10,10); |
718 | QPainter painter2(&pixmap); |
719 | painter2.fillRect(x: 0,y: 0,w: 10,h: 10, b: QBrush(Qt::green)); |
720 | painter2.setPen(Qt::red); |
721 | painter2.drawPixmap(x: 0,y: 0,w: 10,h: 10, pm: bitmap); |
722 | painter2.end(); |
723 | |
724 | QPixmap expected(10, 10); |
725 | expected.fill(fillColor: Qt::red); |
726 | |
727 | QVERIFY(lenientCompare(pixmap, expected)); |
728 | } |
729 | |
730 | void tst_QPixmap::isNull() |
731 | { |
732 | { |
733 | QPixmap pixmap(1,1); |
734 | QVERIFY(!pixmap.isNull()); |
735 | } |
736 | { |
737 | QPixmap pixmap(0,0); |
738 | QVERIFY(pixmap.isNull()); |
739 | } |
740 | |
741 | { |
742 | QPixmap pixmap(0,1); |
743 | QVERIFY(pixmap.isNull()); |
744 | } |
745 | { |
746 | QPixmap pixmap(1,0); |
747 | QVERIFY(pixmap.isNull()); |
748 | } |
749 | { |
750 | QPixmap pixmap(-1,-1); |
751 | QVERIFY(pixmap.isNull()); |
752 | } |
753 | { |
754 | QPixmap pixmap(-1,5); |
755 | QVERIFY(pixmap.isNull()); |
756 | } |
757 | } |
758 | |
759 | void tst_QPixmap::convertFromImageNoDetach() |
760 | { |
761 | QPixmap randomPixmap(10, 10); |
762 | if (randomPixmap.handle()->classId() != QPlatformPixmap::RasterClass) |
763 | QSKIP("Test only valid for raster pixmaps" ); |
764 | |
765 | //first get the screen format |
766 | QImage::Format screenFormat = randomPixmap.toImage().format(); |
767 | QVERIFY(screenFormat != QImage::Format_Invalid); |
768 | |
769 | QImage orig(100,100, screenFormat); |
770 | |
771 | QPixmap pix = QPixmap::fromImage(image: orig); |
772 | QImage copy = pix.toImage(); |
773 | |
774 | QCOMPARE(copy.format(), screenFormat); |
775 | |
776 | const QImage constOrig = orig; |
777 | const QImage constCopy = copy; |
778 | QCOMPARE(constOrig.bits(), constCopy.bits()); |
779 | } |
780 | |
781 | void tst_QPixmap::convertFromImageNoDetach2() |
782 | { |
783 | QPixmap randomPixmap(10, 10); |
784 | if (randomPixmap.handle()->classId() != QPlatformPixmap::RasterClass) |
785 | QSKIP("Test only valid for raster pixmaps" ); |
786 | |
787 | //first get the screen format |
788 | QImage::Format screenFormat = randomPixmap.toImage().format(); |
789 | QVERIFY(screenFormat != QImage::Format_Invalid); |
790 | if (screenFormat != QImage::Format_RGB32 && |
791 | screenFormat != QImage::Format_ARGB32_Premultiplied) |
792 | QSKIP("Test only valid for platforms with RGB32 pixmaps" ); |
793 | |
794 | QImage orig(100,100, QImage::Format_ARGB32_Premultiplied); |
795 | orig.fill(color: Qt::white); |
796 | |
797 | const uchar *origBits = orig.constBits(); |
798 | |
799 | QPixmap pix = QPixmap::fromImage(image: std::move(orig)); |
800 | QImage copy = pix.toImage(); |
801 | |
802 | QVERIFY(!copy.hasAlphaChannel()); |
803 | QCOMPARE(copy.format(), QImage::Format_RGB32); |
804 | |
805 | QCOMPARE(origBits, copy.constBits()); |
806 | } |
807 | |
808 | void tst_QPixmap::convertFromImageDetach() |
809 | { |
810 | QImage img(10,10, QImage::Format_RGB32); |
811 | img.fill(pixel: 0); |
812 | QVERIFY(!img.isNull()); |
813 | QPixmap p = QPixmap::fromImage(image: img); |
814 | QVERIFY(p.isDetached()); |
815 | QPixmap copy = p; |
816 | QVERIFY(!copy.isDetached()); |
817 | QVERIFY(!p.isDetached()); |
818 | img.fill(pixel: 1); |
819 | p = QPixmap::fromImage(image: img); |
820 | QVERIFY(copy.isDetached()); |
821 | } |
822 | |
823 | void tst_QPixmap::convertFromImageCacheKey() |
824 | { |
825 | QPixmap randomPixmap(10, 10); |
826 | if (randomPixmap.handle()->classId() != QPlatformPixmap::RasterClass) |
827 | QSKIP("Test only valid for raster pixmaps" ); |
828 | |
829 | //first get the screen format |
830 | QImage::Format screenFormat = randomPixmap.toImage().format(); |
831 | QVERIFY(screenFormat != QImage::Format_Invalid); |
832 | |
833 | QImage orig(100,100, screenFormat); |
834 | orig.fill(pixel: 0); |
835 | |
836 | QPixmap pix = QPixmap::fromImage(image: orig); |
837 | QImage copy = pix.toImage(); |
838 | |
839 | QCOMPARE(copy.format(), screenFormat); |
840 | |
841 | QCOMPARE(orig.cacheKey(), pix.cacheKey()); |
842 | QCOMPARE(copy.cacheKey(), pix.cacheKey()); |
843 | } |
844 | |
845 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
846 | |
847 | QT_BEGIN_NAMESPACE |
848 | Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); |
849 | Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); |
850 | Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); |
851 | Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p); |
852 | Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h); |
853 | Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); |
854 | QT_END_NAMESPACE |
855 | |
856 | void tst_QPixmap::toWinHBITMAP_data() |
857 | { |
858 | QTest::addColumn<int>("red" ); |
859 | QTest::addColumn<int>("green" ); |
860 | QTest::addColumn<int>("blue" ); |
861 | |
862 | QTest::newRow("red" ) << 255 << 0 << 0; |
863 | QTest::newRow("green" ) << 0 << 255 << 0; |
864 | QTest::newRow("blue" ) << 0 << 0 << 255; |
865 | } |
866 | |
867 | void tst_QPixmap::toWinHBITMAP() |
868 | { |
869 | QFETCH(int, red); |
870 | QFETCH(int, green); |
871 | QFETCH(int, blue); |
872 | |
873 | QPixmap pm(100, 100); |
874 | pm.fill(QColor(red, green, blue)); |
875 | |
876 | HBITMAP bitmap = qt_pixmapToWinHBITMAP(pm); |
877 | |
878 | QVERIFY(bitmap != 0); |
879 | |
880 | // Verify size |
881 | BITMAP bitmap_info; |
882 | memset(&bitmap_info, 0, sizeof(BITMAP)); |
883 | |
884 | int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info); |
885 | QVERIFY(res); |
886 | |
887 | QCOMPARE(100, (int) bitmap_info.bmWidth); |
888 | QCOMPARE(100, (int) bitmap_info.bmHeight); |
889 | |
890 | HDC display_dc = GetDC(0); |
891 | HDC bitmap_dc = CreateCompatibleDC(display_dc); |
892 | |
893 | HBITMAP null_bitmap = (HBITMAP) SelectObject(bitmap_dc, bitmap); |
894 | |
895 | COLORREF pixel = GetPixel(bitmap_dc, 0, 0); |
896 | QCOMPARE((int)GetRValue(pixel), red); |
897 | QCOMPARE((int)GetGValue(pixel), green); |
898 | QCOMPARE((int)GetBValue(pixel), blue); |
899 | |
900 | // Clean up |
901 | SelectObject(bitmap_dc, null_bitmap); |
902 | DeleteObject(bitmap); |
903 | DeleteDC(bitmap_dc); |
904 | ReleaseDC(0, display_dc); |
905 | |
906 | } |
907 | |
908 | void tst_QPixmap::fromWinHBITMAP_data() |
909 | { |
910 | toWinHBITMAP_data(); |
911 | } |
912 | |
913 | void tst_QPixmap::fromWinHBITMAP() |
914 | { |
915 | QFETCH(int, red); |
916 | QFETCH(int, green); |
917 | QFETCH(int, blue); |
918 | |
919 | HDC display_dc = GetDC(0); |
920 | HDC bitmap_dc = CreateCompatibleDC(display_dc); |
921 | HBITMAP bitmap = CreateCompatibleBitmap(display_dc, 100, 100); |
922 | SelectObject(bitmap_dc, bitmap); |
923 | |
924 | SelectObject(bitmap_dc, GetStockObject(NULL_PEN)); |
925 | HGDIOBJ old_brush = SelectObject(bitmap_dc, CreateSolidBrush(RGB(red, green, blue))); |
926 | Rectangle(bitmap_dc, 0, 0, 100, 100); |
927 | |
928 | QPixmap pixmap = qt_pixmapFromWinHBITMAP(bitmap); |
929 | QCOMPARE(pixmap.width(), 100); |
930 | QCOMPARE(pixmap.height(), 100); |
931 | |
932 | QImage image = pixmap.toImage(); |
933 | QRgb pixel = image.pixel(0, 0); |
934 | QCOMPARE(qRed(pixel), red); |
935 | QCOMPARE(qGreen(pixel), green); |
936 | QCOMPARE(qBlue(pixel), blue); |
937 | |
938 | DeleteObject(SelectObject(bitmap_dc, old_brush)); |
939 | DeleteObject(SelectObject(bitmap_dc, bitmap)); |
940 | DeleteDC(bitmap_dc); |
941 | ReleaseDC(0, display_dc); |
942 | } |
943 | |
944 | static bool compareImages(const QImage &actualImage, const QImage &expectedImage) |
945 | { |
946 | if (actualImage.width() != expectedImage.width() |
947 | || actualImage.height() != expectedImage.height()) { |
948 | qWarning("Image size comparison failed: expected: %dx%d, got %dx%d" , |
949 | expectedImage.size().width(), expectedImage.size().height(), |
950 | actualImage.size().width(), actualImage.size().height()); |
951 | return false; |
952 | } |
953 | if (actualImage.format() != expectedImage.format()) { |
954 | qWarning("Image format comparison failed: expected: %d, got %d" , |
955 | expectedImage.format(), actualImage.format()); |
956 | return false; |
957 | } |
958 | |
959 | static const int fuzz = 1; |
960 | |
961 | for (int y = 0; y < actualImage.height(); ++y) { |
962 | for (int x = 0; x < expectedImage.width(); ++x) { |
963 | const QRgb p1 = actualImage.pixel(x, y); |
964 | const QRgb p2 = expectedImage.pixel(x, y); |
965 | |
966 | if (qAbs(qRed(p1) - qRed(p2)) > fuzz |
967 | || qAbs(qGreen(p1) - qGreen(p2)) > fuzz |
968 | || qAbs(qBlue(p1) - qBlue(p2)) > fuzz |
969 | || qAbs(qAlpha(p1) - qAlpha(p2)) > fuzz) { |
970 | qWarning("Color mismatch at pixel %d,%d: Expected: 0x%x. got 0x%x" , |
971 | x, y, p2, p1); |
972 | return false; |
973 | } |
974 | } |
975 | } |
976 | return true; |
977 | } |
978 | |
979 | void tst_QPixmap::toWinHICON_data() |
980 | { |
981 | QTest::addColumn<QString>("image" ); |
982 | QTest::addColumn<int>("width" ); |
983 | QTest::addColumn<int>("height" ); |
984 | |
985 | const QString prefix = QFINDTESTDATA("convertFromToHICON" ); |
986 | |
987 | QTest::newRow("32bpp_16x16" ) << prefix + QLatin1String("/icon_32bpp" ) << 16 << 16; |
988 | QTest::newRow("32bpp_32x32" ) << prefix + QLatin1String("/icon_32bpp" ) << 32 << 32; |
989 | QTest::newRow("32bpp_48x48" ) << prefix + QLatin1String("/icon_32bpp" ) << 48 << 48; |
990 | QTest::newRow("32bpp_256x256" ) << prefix + QLatin1String("/icon_32bpp" ) << 256 << 256; |
991 | |
992 | QTest::newRow("8bpp_16x16" ) << prefix + QLatin1String("/icon_8bpp" ) << 16 << 16; |
993 | QTest::newRow("8bpp_32x32" ) << prefix + QLatin1String("/icon_8bpp" ) << 32 << 32; |
994 | QTest::newRow("8bpp_48x48" ) << prefix + QLatin1String("/icon_8bpp" ) << 48 << 48; |
995 | } |
996 | |
997 | void tst_QPixmap::toWinHICON() |
998 | { |
999 | enum { Alpha = 2 }; |
1000 | |
1001 | QFETCH(int, width); |
1002 | QFETCH(int, height); |
1003 | QFETCH(QString, image); |
1004 | |
1005 | QPixmap empty(width, height); |
1006 | empty.fill(Qt::transparent); |
1007 | |
1008 | HDC display_dc = GetDC(0); |
1009 | HDC bitmap_dc = CreateCompatibleDC(display_dc); |
1010 | HBITMAP bitmap = qt_pixmapToWinHBITMAP(empty, Alpha); |
1011 | SelectObject(bitmap_dc, bitmap); |
1012 | |
1013 | const QString fileName = image + QLatin1Char('_') + QString::number(width) + QLatin1Char('x') |
1014 | + QString::number(height) + QLatin1String(".png" ); |
1015 | QImage imageFromFile(fileName); |
1016 | imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied); |
1017 | |
1018 | HICON icon = qt_pixmapToWinHICON(QPixmap::fromImage(imageFromFile)); |
1019 | |
1020 | DrawIconEx(bitmap_dc, 0, 0, icon, width, height, 0, 0, DI_NORMAL); |
1021 | |
1022 | DestroyIcon(icon); |
1023 | DeleteDC(bitmap_dc); |
1024 | |
1025 | QImage imageFromHICON = qt_pixmapFromWinHBITMAP(bitmap, Alpha).toImage(); |
1026 | |
1027 | ReleaseDC(0, display_dc); |
1028 | |
1029 | // fuzzy comparison must be used, as the pixel values change slightly during conversion |
1030 | // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere |
1031 | |
1032 | QVERIFY(compareImages(imageFromHICON, imageFromFile)); |
1033 | } |
1034 | |
1035 | void tst_QPixmap::fromWinHICON_data() |
1036 | { |
1037 | toWinHICON_data(); |
1038 | } |
1039 | |
1040 | void tst_QPixmap::fromWinHICON() |
1041 | { |
1042 | QFETCH(int, width); |
1043 | QFETCH(int, height); |
1044 | QFETCH(QString, image); |
1045 | |
1046 | HICON icon = (HICON)LoadImage(0, (wchar_t*)(image + QLatin1String(".ico" )).utf16(), IMAGE_ICON, width, height, LR_LOADFROMFILE); |
1047 | QImage imageFromHICON = qt_pixmapFromWinHICON(icon).toImage(); |
1048 | DestroyIcon(icon); |
1049 | |
1050 | const QString fileName = image + QLatin1Char('_') + QString::number(width) + QLatin1Char('x') |
1051 | + QString::number(height) + QLatin1String(".png" ); |
1052 | QImage imageFromFile(fileName); |
1053 | imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied); |
1054 | |
1055 | // fuzzy comparison must be used, as the pixel values change slightly during conversion |
1056 | // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere |
1057 | |
1058 | QVERIFY(compareImages(imageFromHICON, imageFromFile)); |
1059 | } |
1060 | |
1061 | #endif // Q_OS_WIN && !Q_OS_WINRT |
1062 | |
1063 | void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() |
1064 | { |
1065 | class Thread : public QThread |
1066 | { |
1067 | public: |
1068 | void run() |
1069 | { |
1070 | QTest::ignoreMessage(type: QtWarningMsg, |
1071 | message: "QPixmap: It is not safe to use pixmaps outside the GUI thread" ); |
1072 | QPixmap pixmap; |
1073 | QVERIFY(pixmap.isNull()); |
1074 | |
1075 | QTest::ignoreMessage(type: QtWarningMsg, |
1076 | message: "QPixmap: It is not safe to use pixmaps outside the GUI thread" ); |
1077 | QPixmap pixmap1(100, 100); |
1078 | QVERIFY(pixmap1.isNull()); |
1079 | |
1080 | QTest::ignoreMessage(type: QtWarningMsg, |
1081 | message: "QPixmap: It is not safe to use pixmaps outside the GUI thread" ); |
1082 | QPixmap pixmap2(pixmap1); |
1083 | QVERIFY(pixmap2.isNull()); |
1084 | } |
1085 | }; |
1086 | if (QGuiApplicationPrivate::platform_integration->hasCapability(cap: QPlatformIntegration::ThreadedPixmaps)) |
1087 | QSKIP("This platform supports threaded pixmaps." ); |
1088 | |
1089 | Thread thread; |
1090 | thread.start(); |
1091 | thread.wait(); |
1092 | } |
1093 | |
1094 | void tst_QPixmap::refUnref() |
1095 | { |
1096 | // Simple ref/unref |
1097 | { |
1098 | QPixmap p; |
1099 | } |
1100 | { |
1101 | QBitmap b; |
1102 | } |
1103 | |
1104 | // Get a copy of a pixmap that goes out of scope |
1105 | { |
1106 | QPixmap b; |
1107 | { |
1108 | QPixmap a(10, 10); |
1109 | a.fill(fillColor: Qt::color0); |
1110 | b = a; |
1111 | } |
1112 | } |
1113 | { |
1114 | QBitmap mask; |
1115 | { |
1116 | QBitmap bitmap(10, 10); |
1117 | bitmap.fill(fillColor: Qt::color1); |
1118 | mask = bitmap.mask(); |
1119 | } |
1120 | mask.fill(fillColor: Qt::color0); |
1121 | } |
1122 | |
1123 | } |
1124 | |
1125 | void tst_QPixmap::copy() |
1126 | { |
1127 | QPixmap src(32, 32); |
1128 | { |
1129 | QPainter p(&src); |
1130 | p.fillRect(x: 0, y: 0, w: 32, h: 32, c: Qt::red); |
1131 | p.fillRect(x: 10, y: 10, w: 10, h: 10, c: Qt::blue); |
1132 | } |
1133 | |
1134 | QPixmap dest = src.copy(ax: 10, ay: 10, awidth: 10, aheight: 10); |
1135 | |
1136 | QPixmap expected(10, 10); |
1137 | expected.fill(fillColor: Qt::blue); |
1138 | QVERIFY(lenientCompare(dest, expected)); |
1139 | |
1140 | QPixmap trans; |
1141 | trans.fill(fillColor: Qt::transparent); |
1142 | |
1143 | QPixmap transCopy = trans.copy(); |
1144 | QCOMPARE(trans, transCopy); |
1145 | } |
1146 | |
1147 | // QTBUG-58653: Force a deep copy of a pixmap by |
1148 | // having a QPainter and check whether DevicePixelRatio is preserved |
1149 | void tst_QPixmap::deepCopyPreservesDpr() |
1150 | { |
1151 | const qreal dpr = 2; |
1152 | QPixmap src(32, 32); |
1153 | src.setDevicePixelRatio(dpr); |
1154 | src.fill(fillColor: Qt::red); |
1155 | QPainter painter(&src); |
1156 | const QPixmap dest = src.copy(); |
1157 | QCOMPARE(dest.devicePixelRatio(), dpr); |
1158 | } |
1159 | |
1160 | // Check that the DPR is preserved after doing a fill after an |
1161 | // assigned copy of the QPixmap |
1162 | void tst_QPixmap::fillPreservesDpr() |
1163 | { |
1164 | const qreal dpr = 2; |
1165 | QPixmap src(32, 32); |
1166 | src.setDevicePixelRatio(dpr); |
1167 | src.fill(fillColor: Qt::red); |
1168 | QPixmap dest = src; |
1169 | dest.fill(fillColor: Qt::blue); |
1170 | QCOMPARE(dest.devicePixelRatio(), dpr); |
1171 | } |
1172 | |
1173 | void tst_QPixmap::dprPassthrough() |
1174 | { |
1175 | const qreal dpr = 2; |
1176 | QPixmap src(32, 32); |
1177 | src.setDevicePixelRatio(dpr); |
1178 | src.fill(fillColor: Qt::transparent); |
1179 | QCOMPARE(src.devicePixelRatio(), dpr); |
1180 | |
1181 | QImage img = src.toImage(); |
1182 | QCOMPARE(img.devicePixelRatio(), dpr); |
1183 | |
1184 | QPixmap pm(1, 1); |
1185 | pm.convertFromImage(img); |
1186 | QCOMPARE(pm.devicePixelRatio(), dpr); |
1187 | |
1188 | QBitmap heuristicMask = src.createHeuristicMask(); |
1189 | QCOMPARE(heuristicMask.devicePixelRatio(), dpr); |
1190 | |
1191 | QBitmap maskFromColor = src.createMaskFromColor(maskColor: Qt::white); |
1192 | QCOMPARE(maskFromColor.devicePixelRatio(), dpr); |
1193 | |
1194 | QBitmap mask = src.mask(); |
1195 | QCOMPARE(mask.devicePixelRatio(), dpr); |
1196 | |
1197 | QPixmap scaled = src.scaled(w: 16, h: 16); |
1198 | QCOMPARE(scaled.devicePixelRatio(), dpr); |
1199 | |
1200 | QTransform t; |
1201 | t.rotate(a: 90); |
1202 | QPixmap transformed = src.transformed(t); |
1203 | QCOMPARE(transformed.devicePixelRatio(), dpr); |
1204 | } |
1205 | |
1206 | void tst_QPixmap::depthOfNullObjects() |
1207 | { |
1208 | QBitmap b1; |
1209 | QCOMPARE(b1.depth(), 0); |
1210 | QPixmap p4; |
1211 | QCOMPARE(p4.depth(), 0); |
1212 | } |
1213 | |
1214 | void tst_QPixmap::transformed() |
1215 | { |
1216 | QPixmap p1(20, 10); |
1217 | p1.fill(fillColor: Qt::red); |
1218 | { |
1219 | QPainter p(&p1); |
1220 | p.drawRect(x: 0, y: 0, w: p1.width() - 1, h: p1.height() - 1); |
1221 | } |
1222 | |
1223 | QPixmap p2(10, 20); |
1224 | { |
1225 | QPainter p(&p2); |
1226 | p.rotate(a: 90); |
1227 | p.drawPixmap(x: 0, y: -p1.height(), pm: p1); |
1228 | } |
1229 | |
1230 | QPixmap p3(20, 10); |
1231 | { |
1232 | QPainter p(&p3); |
1233 | p.rotate(a: 180); |
1234 | p.drawPixmap(x: -p1.width(), y: -p1.height(), pm: p1); |
1235 | } |
1236 | |
1237 | QPixmap p4(10, 20); |
1238 | { |
1239 | QPainter p(&p4); |
1240 | p.rotate(a: 270); |
1241 | p.drawPixmap(x: -p1.width(), y: 0, pm: p1); |
1242 | } |
1243 | |
1244 | QPixmap p1_90 = p1.transformed(QTransform().rotate(a: 90)); |
1245 | QPixmap p1_180 = p1.transformed(QTransform().rotate(a: 180)); |
1246 | QPixmap p1_270 = p1.transformed(QTransform().rotate(a: 270)); |
1247 | |
1248 | QVERIFY(lenientCompare(p1_90, p2)); |
1249 | QVERIFY(lenientCompare(p1_180, p3)); |
1250 | QVERIFY(lenientCompare(p1_270, p4)); |
1251 | } |
1252 | |
1253 | void tst_QPixmap::transformed2() |
1254 | { |
1255 | QPixmap pm(3, 3); |
1256 | pm.fill(fillColor: Qt::red); |
1257 | QPainter p(&pm); |
1258 | p.fillRect(x: 0, y: 0, w: 3, h: 3, b: QBrush(Qt::Dense4Pattern)); |
1259 | p.end(); |
1260 | |
1261 | QTransform transform; |
1262 | transform.rotate(a: -90); |
1263 | transform.scale(sx: 3, sy: 3); |
1264 | |
1265 | QPixmap actual = pm.transformed(transform); |
1266 | |
1267 | QPixmap expected(9, 9); |
1268 | expected.fill(fillColor: Qt::red); |
1269 | p.begin(&expected); |
1270 | p.setBrush(Qt::black); |
1271 | p.setPen(Qt::NoPen); |
1272 | p.drawRect(x: 3, y: 0, w: 3, h: 3); |
1273 | p.drawRect(x: 0, y: 3, w: 3, h: 3); |
1274 | p.drawRect(x: 6, y: 3, w: 3, h: 3); |
1275 | p.drawRect(x: 3, y: 6, w: 3, h: 3); |
1276 | p.end(); |
1277 | |
1278 | QVERIFY(lenientCompare(actual, expected)); |
1279 | } |
1280 | |
1281 | void tst_QPixmap::load() |
1282 | { |
1283 | const QString filePath = m_prefix + QLatin1String("designer.png" ); |
1284 | |
1285 | QPixmap dest(filePath); |
1286 | QVERIFY(!dest.isNull()); |
1287 | QVERIFY(!dest.load("image_that_does_not_exist.png" )); |
1288 | QVERIFY(dest.isNull()); |
1289 | QVERIFY(dest.load(filePath)); |
1290 | QVERIFY(!dest.isNull()); |
1291 | } |
1292 | |
1293 | void tst_QPixmap::loadFromData() |
1294 | { |
1295 | const QString filePath = m_prefix + QLatin1String("designer.png" ); |
1296 | |
1297 | QPixmap original(filePath); |
1298 | QVERIFY(!original.isNull()); |
1299 | |
1300 | QByteArray ba; |
1301 | { |
1302 | QBuffer buf(&ba); |
1303 | QVERIFY(buf.open(QIODevice::WriteOnly)); |
1304 | QVERIFY(original.save(&buf, "BMP" )); |
1305 | } |
1306 | QVERIFY(!ba.isEmpty()); |
1307 | |
1308 | QPixmap dest; |
1309 | QVERIFY(dest.loadFromData(ba, "BMP" )); |
1310 | QVERIFY(!dest.isNull()); |
1311 | |
1312 | QCOMPARE(original, dest); |
1313 | |
1314 | QVERIFY(!dest.loadFromData(QByteArray())); |
1315 | QVERIFY(dest.isNull()); |
1316 | } |
1317 | |
1318 | #if !defined(QT_NO_DATASTREAM) |
1319 | void tst_QPixmap::loadFromDataStream() |
1320 | { |
1321 | const QString filePath = m_prefix + QLatin1String("designer.png" ); |
1322 | |
1323 | QPixmap original(filePath); |
1324 | QVERIFY(!original.isNull()); |
1325 | |
1326 | QByteArray ba; |
1327 | { |
1328 | QDataStream s(&ba, QIODevice::WriteOnly); |
1329 | s << original; |
1330 | } |
1331 | QVERIFY(!ba.isEmpty()); |
1332 | |
1333 | QPixmap dest; |
1334 | { |
1335 | QDataStream s(&ba, QIODevice::ReadOnly); |
1336 | s >> dest; |
1337 | } |
1338 | QVERIFY(!dest.isNull()); |
1339 | |
1340 | QCOMPARE(original, dest); |
1341 | |
1342 | { |
1343 | ba.clear(); |
1344 | QDataStream s(&ba, QIODevice::ReadOnly); |
1345 | s >> dest; |
1346 | } |
1347 | QVERIFY(dest.isNull()); |
1348 | } |
1349 | #endif // QT_NO_DATASTREAM |
1350 | |
1351 | void tst_QPixmap::fromImage_crash() |
1352 | { |
1353 | QImage *img = new QImage(64, 64, QImage::Format_ARGB32_Premultiplied); |
1354 | |
1355 | QPixmap pm = QPixmap::fromImage(image: *img); |
1356 | QPainter painter(&pm); |
1357 | |
1358 | delete img; |
1359 | } |
1360 | |
1361 | #ifndef QT_NO_WIDGETS |
1362 | //This is testing QPlatformPixmap::createCompatiblePlatformPixmap - see QTBUG-5977 |
1363 | void tst_QPixmap::splash_crash() |
1364 | { |
1365 | QPixmap pix; |
1366 | pix = QPixmap(":/images/designer.png" ); |
1367 | QSplashScreen splash(pix); |
1368 | splash.show(); |
1369 | QCoreApplication::processEvents(); |
1370 | splash.close(); |
1371 | } |
1372 | #endif |
1373 | |
1374 | void tst_QPixmap::fromData() |
1375 | { |
1376 | unsigned char bits[] = { 0xaa, 0x55 }; |
1377 | |
1378 | QBitmap bm = QBitmap::fromData(size: QSize(8, 2), bits); |
1379 | QImage img = bm.toImage(); |
1380 | |
1381 | QSet<QRgb> colors; |
1382 | for (int y = 0; y < img.height(); ++y) |
1383 | for (int x = 0; x < img.width(); ++x) |
1384 | colors << img.pixel(x, y); |
1385 | |
1386 | QCOMPARE(colors.size(), 2); |
1387 | |
1388 | QCOMPARE(img.pixel(0, 0), QRgb(0xffffffff)); |
1389 | QCOMPARE(img.pixel(0, 1), QRgb(0xff000000)); |
1390 | } |
1391 | |
1392 | void tst_QPixmap::loadFromDataNullValues() |
1393 | { |
1394 | { |
1395 | QPixmap pixmap; |
1396 | pixmap.loadFromData(buf: QByteArray()); |
1397 | QVERIFY(pixmap.isNull()); |
1398 | } |
1399 | { |
1400 | QPixmap pixmap; |
1401 | pixmap.loadFromData(buf: 0, len: 123); |
1402 | QVERIFY(pixmap.isNull()); |
1403 | } |
1404 | { |
1405 | QPixmap pixmap; |
1406 | const uchar bla[] = "bla" ; |
1407 | pixmap.loadFromData(buf: bla, len: 0); |
1408 | QVERIFY(pixmap.isNull()); |
1409 | } |
1410 | } |
1411 | |
1412 | void tst_QPixmap::loadFromDataImage_data() |
1413 | { |
1414 | QTest::addColumn<QString>(name: "imagePath" ); |
1415 | |
1416 | QTest::newRow(dataTag: "designer_argb32.png" ) << m_loadFromData + "/designer_argb32.png" ; |
1417 | // When no extension is provided we try all extensions that has been registered by image providers |
1418 | QTest::newRow(dataTag: "designer_argb32" ) << m_loadFromData + "/designer_argb32.png" ; |
1419 | QTest::newRow(dataTag: "designer_indexed8_no_alpha.png" ) << m_loadFromData + "/designer_indexed8_no_alpha.png" ; |
1420 | QTest::newRow(dataTag: "designer_indexed8_with_alpha.png" ) << m_loadFromData + "/designer_indexed8_with_alpha.png" ; |
1421 | QTest::newRow(dataTag: "designer_rgb32.png" ) << m_loadFromData + "/designer_rgb32.png" ; |
1422 | QTest::newRow(dataTag: "designer_indexed8_no_alpha.gif" ) << m_loadFromData + "/designer_indexed8_no_alpha.gif" ; |
1423 | QTest::newRow(dataTag: "designer_indexed8_with_alpha.gif" ) << m_loadFromData + "/designer_indexed8_with_alpha.gif" ; |
1424 | QTest::newRow(dataTag: "designer_rgb32.jpg" ) << m_loadFromData + "/designer_rgb32.jpg" ; |
1425 | } |
1426 | |
1427 | void tst_QPixmap::loadFromDataImage() |
1428 | { |
1429 | QFETCH(QString, imagePath); |
1430 | |
1431 | QImage imageRef(imagePath); |
1432 | QPixmap pixmapWithCopy = QPixmap::fromImage(image: imageRef); |
1433 | |
1434 | QFile file(imagePath); |
1435 | file.open(flags: QIODevice::ReadOnly); |
1436 | QByteArray rawData = file.readAll(); |
1437 | |
1438 | QPixmap directLoadingPixmap; |
1439 | directLoadingPixmap.loadFromData(buf: rawData); |
1440 | |
1441 | QCOMPARE(pixmapWithCopy, directLoadingPixmap); |
1442 | } |
1443 | |
1444 | void tst_QPixmap::fromImageReader_data() |
1445 | { |
1446 | QTest::addColumn<QString>(name: "imagePath" ); |
1447 | |
1448 | QTest::newRow(dataTag: "designer_argb32.png" ) << m_loadFromData + "/designer_argb32.png" ; |
1449 | QTest::newRow(dataTag: "designer_indexed8_no_alpha.png" ) << m_loadFromData + "/designer_indexed8_no_alpha.png" ; |
1450 | QTest::newRow(dataTag: "designer_indexed8_with_alpha.png" ) << m_loadFromData + "/designer_indexed8_with_alpha.png" ; |
1451 | QTest::newRow(dataTag: "designer_rgb32.png" ) << m_loadFromData + "/designer_rgb32.png" ; |
1452 | QTest::newRow(dataTag: "designer_indexed8_no_alpha.gif" ) << m_loadFromData + "/designer_indexed8_no_alpha.gif" ; |
1453 | QTest::newRow(dataTag: "designer_indexed8_with_alpha.gif" ) << m_loadFromData + "/designer_indexed8_with_alpha.gif" ; |
1454 | QTest::newRow(dataTag: "designer_rgb32.jpg" ) << m_loadFromData + "/designer_rgb32.jpg" ; |
1455 | QTest::newRow(dataTag: "designer_indexed8_with_alpha_animated" ) << m_loadFromData + "/designer_indexed8_with_alpha_animated.gif" ; |
1456 | QTest::newRow(dataTag: "designer_indexed8_no_alpha_animated" ) << m_loadFromData + "/designer_indexed8_no_alpha_animated.gif" ; |
1457 | } |
1458 | |
1459 | void tst_QPixmap::fromImageReader() |
1460 | { |
1461 | QFETCH(QString, imagePath); |
1462 | |
1463 | QImage imageRef(imagePath); |
1464 | QPixmap pixmapWithCopy = QPixmap::fromImage(image: imageRef); |
1465 | |
1466 | QImageReader imageReader(imagePath); |
1467 | |
1468 | QPixmap directLoadingPixmap = QPixmap::fromImageReader(imageReader: &imageReader); |
1469 | |
1470 | QCOMPARE(pixmapWithCopy, directLoadingPixmap); |
1471 | } |
1472 | |
1473 | void tst_QPixmap::fromImageReaderAnimatedGif_data() |
1474 | { |
1475 | QTest::addColumn<QString>(name: "imagePath" ); |
1476 | QTest::newRow(dataTag: "gif with alpha" ) << QString::fromLatin1(str: "/designer_indexed8_with_alpha_animated.gif" ); |
1477 | QTest::newRow(dataTag: "gif without alpha" ) << QString::fromLatin1(str: "/designer_indexed8_no_alpha_animated.gif" ); |
1478 | } |
1479 | |
1480 | void tst_QPixmap::fromImageReaderAnimatedGif() |
1481 | { |
1482 | QFETCH(QString, imagePath); |
1483 | |
1484 | const QString path = m_loadFromData + imagePath; |
1485 | |
1486 | QImageReader referenceReader(path); |
1487 | QImageReader pixmapReader(path); |
1488 | |
1489 | QVERIFY(referenceReader.canRead()); |
1490 | QVERIFY(referenceReader.imageCount() > 1); |
1491 | |
1492 | for (int i = 0; i < referenceReader.imageCount(); ++i) { |
1493 | QImage refImage = referenceReader.read(); |
1494 | QPixmap refPixmap = QPixmap::fromImage(image: refImage); |
1495 | |
1496 | QPixmap directLoadingPixmap = QPixmap::fromImageReader(imageReader: &pixmapReader); |
1497 | QCOMPARE(refPixmap, directLoadingPixmap); |
1498 | } |
1499 | } |
1500 | |
1501 | void tst_QPixmap::task_246446() |
1502 | { |
1503 | // This crashed without the bugfix in 246446 |
1504 | QPixmap pm(10, 10); |
1505 | pm.fill(fillColor: Qt::transparent); // force 32-bit depth |
1506 | QBitmap bm; |
1507 | pm.setMask(bm); |
1508 | { |
1509 | QPixmap pm2(pm); |
1510 | } |
1511 | QCOMPARE(pm.width(), 10); |
1512 | QVERIFY(pm.mask().isNull()); |
1513 | } |
1514 | |
1515 | void tst_QPixmap::task_51271() |
1516 | { |
1517 | QPixmap pm; |
1518 | QBitmap bm; |
1519 | QVERIFY(!pm.isQBitmap()); // Should not crash ! |
1520 | QVERIFY(bm.isQBitmap()); |
1521 | } |
1522 | |
1523 | void tst_QPixmap::preserveDepth() |
1524 | { |
1525 | QPixmap target(64, 64); |
1526 | target.fill(fillColor: Qt::transparent); |
1527 | |
1528 | QPixmap source(64, 64); |
1529 | source.fill(fillColor: Qt::white); |
1530 | |
1531 | int depth = source.depth(); |
1532 | |
1533 | QPainter painter(&target); |
1534 | painter.setBrush(source); |
1535 | painter.drawRect(r: target.rect()); |
1536 | painter.end(); |
1537 | |
1538 | QCOMPARE(depth, source.depth()); |
1539 | } |
1540 | |
1541 | void tst_QPixmap::loadAsBitmapOrPixmap() |
1542 | { |
1543 | QImage tmp(10, 10, QImage::Format_RGB32); |
1544 | tmp.save(fileName: m_tempDir.path() + "/temp_image.png" ); |
1545 | |
1546 | bool ok; |
1547 | |
1548 | // Check that we can load the pixmap as a pixmap and that it then turns into a pixmap |
1549 | QPixmap pixmap(m_tempDir.path() + "/temp_image.png" ); |
1550 | QVERIFY(!pixmap.isNull()); |
1551 | QVERIFY(pixmap.depth() > 1); |
1552 | QVERIFY(!pixmap.isQBitmap()); |
1553 | |
1554 | pixmap = QPixmap(); |
1555 | ok = pixmap.load(fileName: m_tempDir.path() + "/temp_image.png" ); |
1556 | QVERIFY(ok); |
1557 | QVERIFY(!pixmap.isNull()); |
1558 | QVERIFY(pixmap.depth() > 1); |
1559 | QVERIFY(!pixmap.isQBitmap()); |
1560 | |
1561 | //now we can try to load it without an extension |
1562 | pixmap = QPixmap(); |
1563 | ok = pixmap.load(fileName: m_tempDir.path() + "/temp_image" ); |
1564 | QVERIFY(ok); |
1565 | QVERIFY(!pixmap.isNull()); |
1566 | QVERIFY(pixmap.depth() > 1); |
1567 | QVERIFY(!pixmap.isQBitmap()); |
1568 | |
1569 | // The do the same check for bitmaps.. |
1570 | QBitmap bitmap(m_tempDir.path() + "/temp_image.png" ); |
1571 | QVERIFY(!bitmap.isNull()); |
1572 | QCOMPARE(bitmap.depth(), 1); |
1573 | QVERIFY(bitmap.isQBitmap()); |
1574 | |
1575 | bitmap = QBitmap(); |
1576 | ok = bitmap.load(fileName: m_tempDir.path() + "/temp_image.png" ); |
1577 | QVERIFY(ok); |
1578 | QVERIFY(!bitmap.isNull()); |
1579 | QCOMPARE(bitmap.depth(), 1); |
1580 | QVERIFY(bitmap.isQBitmap()); |
1581 | |
1582 | // check that a QBitmap stays a QBitmap even when loading fails: |
1583 | ok = bitmap.load(fileName: QString()); |
1584 | QVERIFY(!ok); |
1585 | QVERIFY(bitmap.isNull()); |
1586 | QVERIFY(bitmap.isQBitmap()); |
1587 | |
1588 | ok = bitmap.load(fileName: "does not exist" ); |
1589 | QVERIFY(!ok); |
1590 | QVERIFY(bitmap.isNull()); |
1591 | QVERIFY(bitmap.isQBitmap()); |
1592 | |
1593 | ok = bitmap.load(fileName: "does not exist.png" ); |
1594 | QVERIFY(!ok); |
1595 | QVERIFY(bitmap.isNull()); |
1596 | QVERIFY(bitmap.isQBitmap()); |
1597 | |
1598 | QTemporaryFile garbage; |
1599 | QVERIFY(garbage.open()); |
1600 | const QString garbagePath = garbage.fileName(); |
1601 | garbage.write(data: reinterpret_cast<const char *>(&garbage), len: sizeof garbage); |
1602 | garbage.close(); |
1603 | |
1604 | ok = bitmap.load(fileName: garbagePath); |
1605 | QVERIFY(!ok); |
1606 | QVERIFY(bitmap.isNull()); |
1607 | QVERIFY(bitmap.isQBitmap()); |
1608 | } |
1609 | |
1610 | void tst_QPixmap::toImageDeepCopy() |
1611 | { |
1612 | QPixmap pixmap(64, 64); |
1613 | pixmap.fill(fillColor: Qt::white); |
1614 | |
1615 | QPainter painter(&pixmap); |
1616 | QImage first = pixmap.toImage(); |
1617 | |
1618 | painter.setBrush(Qt::black); |
1619 | painter.drawEllipse(r: pixmap.rect()); |
1620 | |
1621 | QImage second = pixmap.toImage(); |
1622 | |
1623 | QVERIFY(first != second); |
1624 | } |
1625 | |
1626 | void tst_QPixmap::scaled_QTBUG19157() |
1627 | { |
1628 | QPixmap foo(5000, 1); |
1629 | foo = foo.scaled(w: 1024, h: 1024, aspectMode: Qt::KeepAspectRatio); |
1630 | QVERIFY(!foo.isNull()); |
1631 | } |
1632 | |
1633 | void tst_QPixmap::detachOnLoad_QTBUG29639() |
1634 | { |
1635 | QPixmap a; |
1636 | a.load(fileName: m_convertFromImage + "/task31722_0/img1.png" ); |
1637 | a.load(fileName: m_convertFromImage + "/task31722_0/img2.png" ); |
1638 | |
1639 | QPixmap b; |
1640 | b.load(fileName: m_convertFromImage + "/task31722_0/img1.png" ); |
1641 | |
1642 | QVERIFY(a.toImage() != b.toImage()); |
1643 | } |
1644 | |
1645 | void tst_QPixmap::copyOnNonAlignedBoundary() |
1646 | { |
1647 | QImage img(8, 2, QImage::Format_RGB16); |
1648 | |
1649 | QPixmap pm1 = QPixmap::fromImage(image: img, flags: Qt::NoFormatConversion); |
1650 | QPixmap pm2 = pm1.copy(rect: QRect(5, 0, 3, 2)); // When copying second line: 2 bytes too many are read which might cause an access violation. |
1651 | } |
1652 | |
1653 | // test pixmap devicePixelRatio setting and detaching |
1654 | void tst_QPixmap::devicePixelRatio() |
1655 | { |
1656 | // create pixmap |
1657 | QPixmap a(64, 64); |
1658 | a.fill(fillColor: Qt::white); |
1659 | QCOMPARE(a.devicePixelRatio(), qreal(1.0)); |
1660 | QCOMPARE(a.isDetached(), true); |
1661 | |
1662 | // copy pixmap |
1663 | QPixmap b = a; |
1664 | QCOMPARE(b.devicePixelRatio(), qreal(1.0)); |
1665 | QCOMPARE(a.isDetached(), false); |
1666 | QCOMPARE(b.isDetached(), false); |
1667 | |
1668 | // set devicePixelRatio to the current value: does not detach |
1669 | a.setDevicePixelRatio(qreal(1.0)); |
1670 | QCOMPARE(a.isDetached(), false); |
1671 | QCOMPARE(b.isDetached(), false); |
1672 | |
1673 | // set devicePixelRatio to a new value: may detach (currently |
1674 | // does, but we may want to avoid the data copy the future) |
1675 | a.setDevicePixelRatio(qreal(2.0)); |
1676 | QCOMPARE(a.devicePixelRatio(), qreal(2.0)); |
1677 | QCOMPARE(b.devicePixelRatio(), qreal(1.0)); |
1678 | } |
1679 | |
1680 | QTEST_MAIN(tst_QPixmap) |
1681 | #include "tst_qpixmap.moc" |
1682 | |