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 <lars.knoll@qt.io>
This commit is contained in:
parent
208c71768c
commit
a512c9c2f7
@ -596,44 +596,7 @@ void QPixmap::setMask(const QBitmap &mask)
|
||||
return;
|
||||
|
||||
detach();
|
||||
|
||||
QImage image = data->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
data->fromImage(image, Qt::AutoColor);
|
||||
data->setMask(mask);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1496,37 +1459,7 @@ QPaintEngine *QPixmap::paintEngine() const
|
||||
*/
|
||||
QBitmap QPixmap::mask() const
|
||||
{
|
||||
if (!data || !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<const QRgb*>(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);
|
||||
return data ? data->mask() : QBitmap();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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<const QRgb*>(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
|
||||
{
|
||||
|
@ -99,6 +99,9 @@ public:
|
||||
virtual int metric(QPaintDevice::PaintDeviceMetric metric) const = 0;
|
||||
virtual void fill(const QColor &color) = 0;
|
||||
|
||||
virtual QBitmap mask() const;
|
||||
virtual void setMask(const QBitmap &mask);
|
||||
|
||||
virtual bool hasAlphaChannel() const = 0;
|
||||
virtual QPixmap transformed(const QTransform &matrix,
|
||||
Qt::TransformationMode mode) const;
|
||||
|
Loading…
Reference in New Issue
Block a user