summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qdrawhelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qdrawhelper.cpp')
-rw-r--r--src/gui/painting/qdrawhelper.cpp187
1 files changed, 95 insertions, 92 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index edb363ac69..3d06a27d8e 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -5658,44 +5658,60 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
{
if (coverage == 0) {
// nothing
- } else if (coverage == 255) {
- *dst = src;
- } else if (!colorProfile) {
- *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
+ } else if (coverage == 255 || !colorProfile) {
+ blend_pixel(*dst, src, coverage);
+ } else if (*dst < 0xff000000) {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
+ blend_pixel(*dst, src, coverage);
+ } else if (src >= 0xff000000) {
+ grayBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
- if (*dst >= 0xff000000) {
- grayBlendPixel(dst, coverage, srcLinear, colorProfile);
- } else {
- // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
- *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
- }
+ // First do naive blend with text-color
+ QRgb s = *dst;
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ grayBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile);
}
}
#if QT_CONFIG(raster_64bit)
+
+static inline void grayBlendPixel(QRgba64 &dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
+{
+ // Do a gammacorrected gray alphablend...
+ QRgba64 dstColor = dst;
+ if (colorProfile) {
+ if (dstColor.isOpaque())
+ dstColor = colorProfile->toLinear(dstColor);
+ else if (!dstColor.isTransparent())
+ dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
+ }
+
+ blend_pixel(dstColor, srcLinear, coverage);
+
+ if (colorProfile) {
+ if (dstColor.isOpaque())
+ dstColor = colorProfile->fromLinear(dstColor);
+ else if (!dstColor.isTransparent())
+ dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
+ }
+ dst = dstColor;
+}
+
static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
} else if (coverage == 255) {
- dest[x] = src;
+ blend_pixel(dest[x], src);
+ } else if (src.isOpaque()) {
+ grayBlendPixel(dest[x], coverage, srcLinear, colorProfile);
} else {
- QRgba64 dstColor = dest[x];
- if (colorProfile) {
- if (dstColor.isOpaque())
- dstColor = colorProfile->toLinear(dstColor);
- else if (!dstColor.isTransparent())
- dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
- }
-
- dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - coverage);
- if (colorProfile) {
- if (dstColor.isOpaque())
- dstColor = colorProfile->fromLinear(dstColor);
- else if (!dstColor.isTransparent())
- dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
- }
- dest[x] = dstColor;
+ // First do naive blend with text-color
+ QRgba64 s = dest[x];
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ grayBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile);
}
}
@@ -5714,12 +5730,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@@ -5792,12 +5804,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@@ -5872,7 +5880,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
int mapWidth, int mapHeight, int mapStride,
const QClipData *clip, bool useGammaCorrection)
{
- if (useGammaCorrection) {
+ if (useGammaCorrection || !color.isOpaque()) {
qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection);
return;
}
@@ -5931,12 +5939,8 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
if (!clip) {
quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
@@ -6031,48 +6035,59 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
#endif
}
-#if QT_CONFIG(raster_64bit)
-static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
+static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
- } else if (coverage == 0xffffffff) {
- dest[x] = src;
+ } else if (coverage == 0xffffffff && qAlpha(src) == 255) {
+ blend_pixel(*dst, src);
+ } else if (!colorProfile) {
+ *dst = rgbBlend(*dst, src, coverage);
+ } else if (*dst < 0xff000000) {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
+ blend_pixel(*dst, src, qRgbAvg(coverage));
+ } else if (srcLinear.isOpaque()) {
+ rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
} else {
- QRgba64 dstColor = dest[x];
- if (dstColor.isOpaque()) {
- if (colorProfile)
- dstColor = colorProfile->toLinear(dstColor);
- dstColor = rgbBlend(dstColor, srcLinear, coverage);
- if (colorProfile)
- dstColor = colorProfile->fromLinear(dstColor);
- dest[x] = dstColor;
- } else {
- // Do a gray alphablend.
- alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
- }
+ // First do naive blend with text-color
+ QRgb s = *dst;
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ rgbBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile);
}
}
-#endif
-static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
+#if QT_CONFIG(raster_64bit)
+static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+{
+ // Do a gammacorrected RGB alphablend...
+ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+ dst = colorProfile ? colorProfile->fromLinear(blend) : blend;
+}
+
+static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
} else if (coverage == 0xffffffff) {
- *dst = src;
- } else if (*dst < 0xff000000) {
- // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
- const int a = qRgbAvg(coverage);
- *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a);
- } else if (!colorProfile) {
- *dst = rgbBlend(*dst, src, coverage);
- } else {
- rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
+ blend_pixel(dest[x], src);
+ } else if (!dest[x].isOpaque()) {
+ // Do a gray alphablend.
+ alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
+ } else if (src.isOpaque()) {
+ rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile);
+ } else {
+ // First do naive blend with text-color
+ QRgba64 s = dest[x];
+ blend_pixel(s, src);
+ // Then gamma-corrected blend with glyph shape
+ rgbBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile);
}
}
-#if QT_CONFIG(raster_64bit)
static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride,
@@ -6087,12 +6102,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
alignas(8) QRgba64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
@@ -6164,12 +6175,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
quint32 buffer[BufferSize];
const DestFetchProc destFetch = destFetchProc[rasterBuffer->format];
@@ -6242,12 +6249,8 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
QRgba64 srcColor = color;
- if (colorProfile) {
- if (color.isOpaque())
- srcColor = colorProfile->toLinear(srcColor);
- else
- srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
- }
+ if (colorProfile && color.isOpaque())
+ srcColor = colorProfile->toLinear(srcColor);
if (!clip) {
quint32 *dst = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;