macOS: Share code for resolving CGImage bitmapInfor for a QImage

Removes assumptions about QImage format in a few places.

Change-Id: I515701be53190429a48956c31986fa0804806406
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Tor Arne Vestbø 2018-11-25 14:09:00 +01:00
parent 5fd6f4d882
commit 09e3457541
4 changed files with 41 additions and 47 deletions

View File

@ -40,6 +40,7 @@
#include "qimage.h"
#include <private/qcore_mac_p.h>
#include <private/qcoregraphics_p.h>
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
@ -98,32 +99,10 @@ CGImageRef QImage::toCGImage() const
if (isNull())
return nil;
// Determine the target native format
uint cgflags = kCGImageAlphaNone;
switch (format()) {
case QImage::Format_ARGB32:
cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGBA8888_Premultiplied:
cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888:
cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBX8888:
cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_ARGB32_Premultiplied:
cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
default: break;
}
CGBitmapInfo bitmapInfo = qt_mac_bitmapInfoForImage(*this);
// Format not supported: return nil CGImageRef
if (cgflags == kCGImageAlphaNone)
if (bitmapInfo == kCGImageAlphaNone)
return nil;
// Create a data provider that owns a copy of the QImage and references the image data.
@ -140,7 +119,7 @@ CGImageRef QImage::toCGImage() const
const bool shouldInterpolate = false;
return CGImageCreate(width(), height(), bitsPerComponent, bitsPerPixel,
this->bytesPerLine(), colorSpace, cgflags, dataProvider,
this->bytesPerLine(), colorSpace, bitmapInfo, dataProvider,
decode, shouldInterpolate, kCGRenderingIntentDefault);
}

View File

@ -51,6 +51,33 @@ QT_BEGIN_NAMESPACE
// ---------------------- Images ----------------------
CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image)
{
CGBitmapInfo bitmapInfo = kCGImageAlphaNone;
switch (image.format()) {
case QImage::Format_ARGB32:
bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGBA8888_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888:
bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBX8888:
bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_ARGB32_Premultiplied:
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
default: break;
}
return bitmapInfo;
}
CGImageRef qt_mac_toCGImage(const QImage &inImage)
{
CGImageRef cgImage = inImage.toCGImage();
@ -362,13 +389,10 @@ QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0)
if (!image)
return; // Context type not supported.
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint flags = kCGImageAlphaPremultipliedFirst;
flags |= kCGBitmapByteOrder32Host;
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8,
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
context = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorSpace, flags);
CFRelease(colorSpace);
CGContextTranslateCTM(context, 0, image->height());
const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
@ -396,16 +420,10 @@ QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint flags = kCGImageAlphaPremultipliedFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
flags |= kCGBitmapByteOrder32Host;
#endif
const QImage *image = static_cast<const QImage *>(paintEngine->paintDevice());
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(),
8, image->bytesPerLine(), colorSpace, flags);
CFRelease(colorSpace);
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8,
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
// Invert y axis
CGContextTranslateCTM(context, 0, image->height());

View File

@ -64,6 +64,8 @@
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image);
#ifdef HAVE_APPKIT
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm);
Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize = 0);

View File

@ -45,7 +45,7 @@
#include <QtCore/qsettings.h>
#endif
#include <QtCore/qoperatingsystemversion.h>
#include <private/qcoregraphics_p.h>
#include <private/qimage_p.h>
#include <cmath>
@ -647,14 +647,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
im.fill(0); // Faster than Qt::black
QCFType<CGColorSpaceRef> colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
cgflags |= kCGBitmapByteOrder32Host;
#endif
QCFType<CGContextRef> ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
8, im.bytesPerLine(), colorspace,
cgflags);
qt_mac_bitmapInfoForImage(im));
Q_ASSERT(ctx);
CGContextSetFontSize(ctx, fontDef.pixelSize);
const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold) && !(fontDef.styleStrategy & QFont::NoAntialias);