From a512c9c2f79309b76d84e4f56eef233064592ef0 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 21 Nov 2016 14:00:45 -0800 Subject: QPixmap: move mask functions into QPlatformPixmap These used to be in QPixmapData in Qt4, allowing platforms to override mask handling. Useful when native 32-bit ARGB might not be available. Change-Id: I1fcb77222ee4bc4705a8b4c614c9d5c3938c47ba Reviewed-by: Lars Knoll --- src/gui/image/qplatformpixmap.cpp | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'src/gui/image/qplatformpixmap.cpp') diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp index 00c21a5f54..b123afb4db 100644 --- a/src/gui/image/qplatformpixmap.cpp +++ b/src/gui/image/qplatformpixmap.cpp @@ -160,6 +160,82 @@ bool QPlatformPixmap::scroll(int dx, int dy, const QRect &rect) return false; } +QBitmap QPlatformPixmap::mask() const +{ + if (!hasAlphaChannel()) + return QBitmap(); + + const QImage img = toImage(); + bool shouldConvert = (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied); + const QImage image = (shouldConvert ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); + const int w = image.width(); + const int h = image.height(); + + QImage mask(w, h, QImage::Format_MonoLSB); + if (mask.isNull()) // allocation failed + return QBitmap(); + + mask.setColorCount(2); + mask.setColor(0, QColor(Qt::color0).rgba()); + mask.setColor(1, QColor(Qt::color1).rgba()); + + const int bpl = mask.bytesPerLine(); + + for (int y = 0; y < h; ++y) { + const QRgb *src = reinterpret_cast(image.scanLine(y)); + uchar *dest = mask.scanLine(y); + memset(dest, 0, bpl); + for (int x = 0; x < w; ++x) { + if (qAlpha(*src) > 0) + dest[x >> 3] |= (1 << (x & 7)); + ++src; + } + } + + return QBitmap::fromImage(mask); +} + +void QPlatformPixmap::setMask(const QBitmap &mask) +{ + QImage image = toImage(); + if (mask.size().isEmpty()) { + if (image.depth() != 1) { // hw: ???? + image = image.convertToFormat(QImage::Format_RGB32); + } + } else { + const int w = image.width(); + const int h = image.height(); + + switch (image.depth()) { + case 1: { + const QImage imageMask = mask.toImage().convertToFormat(image.format()); + for (int y = 0; y < h; ++y) { + const uchar *mscan = imageMask.scanLine(y); + uchar *tscan = image.scanLine(y); + int bytesPerLine = image.bytesPerLine(); + for (int i = 0; i < bytesPerLine; ++i) + tscan[i] &= mscan[i]; + } + break; + } + default: { + const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + for (int y = 0; y < h; ++y) { + const uchar *mscan = imageMask.scanLine(y); + QRgb *tscan = (QRgb *)image.scanLine(y); + for (int x = 0; x < w; ++x) { + if (!(mscan[x>>3] & (1 << (x&7)))) + tscan[x] = 0; + } + } + break; + } + } + } + fromImage(image, Qt::AutoColor); +} + QPixmap QPlatformPixmap::transformed(const QTransform &matrix, Qt::TransformationMode mode) const { -- cgit v1.2.3