diff options
author | Friedemann Kleint <Friedemann.Kleint@digia.com> | 2013-08-27 11:16:33 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-27 12:33:11 +0200 |
commit | 637901270b9342d3804342ae301dc0569efe7fb5 (patch) | |
tree | 3a8bf2ea6733d6c8719492037122cb3ddce5738d /tests | |
parent | 24d3c5cec95af74124e10dcee4d017200325c748 (diff) |
Add test for the Windows QPixmap conversion functions.
Re-add the part of the QPixmap-tests dealing with the conversion
functions.
Change-Id: I49af7adb0b16e8b380061058815284d15c21c6ed
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/qpixmap/data/icon_32bpp.ico | bin | 0 -> 285478 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_32bpp_16x16.png | bin | 0 -> 754 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_32bpp_256x256.png | bin | 0 -> 16269 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_32bpp_32x32.png | bin | 0 -> 1745 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_32bpp_48x48.png | bin | 0 -> 2618 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_8bpp.ico | bin | 0 -> 7406 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_8bpp_16x16.png | bin | 0 -> 1454 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_8bpp_32x32.png | bin | 0 -> 1721 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/data/icon_8bpp_48x48.png | bin | 0 -> 1967 bytes | |||
-rw-r--r-- | tests/auto/qpixmap/qpixmap.pro | 4 | ||||
-rw-r--r-- | tests/auto/qpixmap/tst_qpixmap.cpp | 295 |
12 files changed, 301 insertions, 1 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index abf8bfe..b50613c 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs SUBDIRS += \ - qwinthumbnailtoolbar + qwinthumbnailtoolbar \ + qpixmap diff --git a/tests/auto/qpixmap/data/icon_32bpp.ico b/tests/auto/qpixmap/data/icon_32bpp.ico Binary files differnew file mode 100644 index 0000000..dbb55cd --- /dev/null +++ b/tests/auto/qpixmap/data/icon_32bpp.ico diff --git a/tests/auto/qpixmap/data/icon_32bpp_16x16.png b/tests/auto/qpixmap/data/icon_32bpp_16x16.png Binary files differnew file mode 100644 index 0000000..f23f398 --- /dev/null +++ b/tests/auto/qpixmap/data/icon_32bpp_16x16.png diff --git a/tests/auto/qpixmap/data/icon_32bpp_256x256.png b/tests/auto/qpixmap/data/icon_32bpp_256x256.png Binary files differnew file mode 100644 index 0000000..293f1c5 --- /dev/null +++ b/tests/auto/qpixmap/data/icon_32bpp_256x256.png diff --git a/tests/auto/qpixmap/data/icon_32bpp_32x32.png b/tests/auto/qpixmap/data/icon_32bpp_32x32.png Binary files differnew file mode 100644 index 0000000..bfdb1fe --- /dev/null +++ b/tests/auto/qpixmap/data/icon_32bpp_32x32.png diff --git a/tests/auto/qpixmap/data/icon_32bpp_48x48.png b/tests/auto/qpixmap/data/icon_32bpp_48x48.png Binary files differnew file mode 100644 index 0000000..7dd2d13 --- /dev/null +++ b/tests/auto/qpixmap/data/icon_32bpp_48x48.png diff --git a/tests/auto/qpixmap/data/icon_8bpp.ico b/tests/auto/qpixmap/data/icon_8bpp.ico Binary files differnew file mode 100644 index 0000000..4341a33 --- /dev/null +++ b/tests/auto/qpixmap/data/icon_8bpp.ico diff --git a/tests/auto/qpixmap/data/icon_8bpp_16x16.png b/tests/auto/qpixmap/data/icon_8bpp_16x16.png Binary files differnew file mode 100644 index 0000000..e9a995e --- /dev/null +++ b/tests/auto/qpixmap/data/icon_8bpp_16x16.png diff --git a/tests/auto/qpixmap/data/icon_8bpp_32x32.png b/tests/auto/qpixmap/data/icon_8bpp_32x32.png Binary files differnew file mode 100644 index 0000000..41ef57f --- /dev/null +++ b/tests/auto/qpixmap/data/icon_8bpp_32x32.png diff --git a/tests/auto/qpixmap/data/icon_8bpp_48x48.png b/tests/auto/qpixmap/data/icon_8bpp_48x48.png Binary files differnew file mode 100644 index 0000000..35d60d1 --- /dev/null +++ b/tests/auto/qpixmap/data/icon_8bpp_48x48.png diff --git a/tests/auto/qpixmap/qpixmap.pro b/tests/auto/qpixmap/qpixmap.pro new file mode 100644 index 0000000..7c35cdf --- /dev/null +++ b/tests/auto/qpixmap/qpixmap.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qpixmap +QT += gui testlib winextras +SOURCES += tst_qpixmap.cpp diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp new file mode 100644 index 0000000..2cc1da0 --- /dev/null +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/qt_windows.h> +#include <QtCore/QFileInfo> +#include <QtGui/QPixmap> +#include <QtGui/QImage> +#include <QtWinExtras/QWinFunctions> + +class tst_QPixmap : public QObject +{ + Q_OBJECT + +public: + tst_QPixmap() : m_dataDirectory(QFINDTESTDATA("data")) {} + +private slots: + void initTestCase(); + + void toHBITMAP_data(); + void toHBITMAP(); + void fromHBITMAP_data(); + void fromHBITMAP(); + + void toHICON_data(); + void toHICON(); + void fromHICON_data(); + void fromHICON(); + +private: + const QString m_dataDirectory; +}; + +void tst_QPixmap::initTestCase() +{ + QVERIFY(!m_dataDirectory.isEmpty()); +} + +void tst_QPixmap::toHBITMAP_data() +{ + QTest::addColumn<int>("red"); + QTest::addColumn<int>("green"); + QTest::addColumn<int>("blue"); + + QTest::newRow("red") << 255 << 0 << 0; + QTest::newRow("green") << 0 << 255 << 0; + QTest::newRow("blue") << 0 << 0 << 255; +} + +void tst_QPixmap::toHBITMAP() +{ + QFETCH(int, red); + QFETCH(int, green); + QFETCH(int, blue); + + QPixmap pm(100, 100); + pm.fill(QColor(red, green, blue)); + + const HBITMAP bitmap = QWinExtras::toHBITMAP(pm); + + QVERIFY(bitmap != 0); + + // Verify size + BITMAP bitmapInfo; + memset(&bitmapInfo, 0, sizeof(BITMAP)); + + QVERIFY(GetObject(bitmap, sizeof(BITMAP), &bitmapInfo)); + + QCOMPARE(100, (int) bitmapInfo.bmWidth); + QCOMPARE(100, (int) bitmapInfo.bmHeight); + + const HDC displayDc = GetDC(0); + const HDC bitmapDc = CreateCompatibleDC(displayDc); + + const HBITMAP nullBitmap = (HBITMAP) SelectObject(bitmapDc, bitmap); + + const COLORREF pixel = GetPixel(bitmapDc, 0, 0); + QCOMPARE((int)GetRValue(pixel), red); + QCOMPARE((int)GetGValue(pixel), green); + QCOMPARE((int)GetBValue(pixel), blue); + + // Clean up + SelectObject(bitmapDc, nullBitmap); + DeleteObject(bitmap); + DeleteDC(bitmapDc); + ReleaseDC(0, displayDc); +} + +void tst_QPixmap::fromHBITMAP_data() +{ + toHBITMAP_data(); +} + +void tst_QPixmap::fromHBITMAP() +{ + QFETCH(int, red); + QFETCH(int, green); + QFETCH(int, blue); + + const HDC displayDc = GetDC(0); + const HDC bitmapDc = CreateCompatibleDC(displayDc); + const HBITMAP bitmap = CreateCompatibleBitmap(displayDc, 100, 100); + SelectObject(bitmapDc, bitmap); + + SelectObject(bitmapDc, GetStockObject(NULL_PEN)); + const HGDIOBJ oldBrush = SelectObject(bitmapDc, CreateSolidBrush(RGB(red, green, blue))); + Rectangle(bitmapDc, 0, 0, 100, 100); + + const QPixmap pixmap = QWinExtras::fromHBITMAP(bitmap); + QCOMPARE(pixmap.width(), 100); + QCOMPARE(pixmap.height(), 100); + + const QImage image = pixmap.toImage(); + const QRgb pixel = image.pixel(0, 0); + QCOMPARE(qRed(pixel), red); + QCOMPARE(qGreen(pixel), green); + QCOMPARE(qBlue(pixel), blue); + + DeleteObject(SelectObject(bitmapDc, oldBrush)); + DeleteObject(SelectObject(bitmapDc, bitmap)); + DeleteDC(bitmapDc); + ReleaseDC(0, displayDc); +} + +static bool compareImages(const QImage &actual, const QImage &expected, + QByteArray *errorMessage) +{ + if (actual.size() != expected.size()) { + QString s; + QDebug(&s) << "Size mismatch, actual: " << actual.size() << " expected: " << expected.size(); + *errorMessage = s.toLocal8Bit(); + return false; + } + if (actual.format() != expected.format()) { + *errorMessage = QByteArrayLiteral("Format mismatch, actual: ") + + QByteArray::number(actual.format()) + + QByteArrayLiteral(", expected: ") + QByteArray::number(expected.format()); + return false; + } + + static const int fuzz = 1; + + for (int y = 0; y < actual.height(); ++y) { + for (int x = 0; x < expected.width(); ++x) { + const QRgb actualRgb = actual.pixel(x, y); + const QRgb expectedRgb = expected.pixel(x, y); + const bool pixelMatches = + qAbs(qRed(actualRgb) - qRed(expectedRgb)) <= fuzz + && qAbs(qGreen(actualRgb) - qGreen(expectedRgb)) <= fuzz + && qAbs(qBlue(actualRgb) - qBlue(expectedRgb)) <= fuzz + && qAbs(qAlpha(actualRgb) - qAlpha(expectedRgb)) <= fuzz; + if (!pixelMatches) { + QString s; + QDebug(&s) << "Pixmal mismatch at " << x << ',' << y << " actual: " + << QColor(actualRgb) << " expected: " << QColor(expectedRgb); + *errorMessage = s.toLocal8Bit(); + return false; + } + } + } + return true; +} + +static inline QString pngFileName(const QString &image, int width, int height) +{ + return image + QLatin1Char('_') + QString::number(width) + + QLatin1Char('x') + QString::number(height) + QStringLiteral(".png"); +} + +void tst_QPixmap::toHICON_data() +{ + QTest::addColumn<QString>("image"); + QTest::addColumn<int>("width"); + QTest::addColumn<int>("height"); + + QTest::newRow("32bpp_16x16") << m_dataDirectory + QStringLiteral("/icon_32bpp") << 16 << 16; + QTest::newRow("32bpp_32x32") << m_dataDirectory + QStringLiteral("/icon_32bpp") << 32 << 32; + QTest::newRow("32bpp_48x48") << m_dataDirectory + QStringLiteral("/icon_32bpp") << 48 << 48; + QTest::newRow("32bpp_256x256") << m_dataDirectory + QStringLiteral("/icon_32bpp") << 256 << 256; + + QTest::newRow("8bpp_16x16") << m_dataDirectory + QStringLiteral("/icon_8bpp") << 16 << 16; + QTest::newRow("8bpp_32x32") << m_dataDirectory + QStringLiteral("/icon_8bpp") << 32 << 32; + QTest::newRow("8bpp_48x48") << m_dataDirectory + QStringLiteral("/icon_8bpp") << 48 << 48; +} + +void tst_QPixmap::toHICON() +{ + QFETCH(int, width); + QFETCH(int, height); + QFETCH(QString, image); + + QPixmap empty(width, height); + empty.fill(Qt::transparent); + + const HDC displayDc = GetDC(0); + const HDC bitmapDc = CreateCompatibleDC(displayDc); + const HBITMAP bitmap = QWinExtras::toHBITMAP(empty, QWinExtras::HBitmapAlpha); + SelectObject(bitmapDc, bitmap); + + const QString imageFileName = pngFileName(image, width, height); + QVERIFY2(QFileInfo(imageFileName).exists(), qPrintable(imageFileName)); + + const QImage imageFromFile = QImage(imageFileName).convertToFormat(QImage::Format_ARGB32_Premultiplied); + QVERIFY(!imageFromFile.isNull()); + + const HICON icon = QWinExtras::toHICON(QPixmap::fromImage(imageFromFile)); + + DrawIconEx(bitmapDc, 0, 0, icon, width, height, 0, 0, DI_NORMAL); + + DestroyIcon(icon); + DeleteDC(bitmapDc); + + const QImage imageFromHICON = QWinExtras::fromHBITMAP(bitmap, QWinExtras::HBitmapAlpha).toImage(); + QVERIFY(!imageFromHICON.isNull()); + + ReleaseDC(0, displayDc); + + // fuzzy comparison must be used, as the pixel values change slightly during conversion + // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere + QByteArray errorMessage; + QVERIFY2(compareImages(imageFromHICON, imageFromFile, &errorMessage), errorMessage.constData()); +} + +void tst_QPixmap::fromHICON_data() +{ + toHICON_data(); +} + +void tst_QPixmap::fromHICON() +{ + QFETCH(int, width); + QFETCH(int, height); + QFETCH(QString, image); + + const QString iconFileName = image + QStringLiteral(".ico"); + QVERIFY2(QFileInfo(iconFileName).exists(), qPrintable(iconFileName)); + + const HICON icon = (HICON)LoadImage(0, (wchar_t*)(iconFileName).utf16(), IMAGE_ICON, width, height, LR_LOADFROMFILE); + const QImage imageFromHICON = QWinExtras::fromHICON(icon).toImage(); + DestroyIcon(icon); + + const QString imageFileName = pngFileName(image, width, height); + QVERIFY2(QFileInfo(imageFileName).exists(), qPrintable(imageFileName)); + + const QImage imageFromFile = QImage(imageFileName).convertToFormat(QImage::Format_ARGB32_Premultiplied); + QVERIFY(!imageFromFile.isNull()); + + // fuzzy comparison must be used, as the pixel values change slightly during conversion + // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere + QByteArray errorMessage; + QVERIFY2(compareImages(imageFromHICON, imageFromFile, &errorMessage), errorMessage.constData()); +} + +QTEST_MAIN(tst_QPixmap) + +#include "tst_qpixmap.moc" |