summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qdrawhelper.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-05-04 14:41:42 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2017-05-08 18:04:12 +0000
commitab059940aad327b7dbe7ef22cfd061061feb6e0e (patch)
tree64625a3786abe900e7ccb780c198d1fc36f47a5a /src/gui/painting/qdrawhelper.cpp
parentcab9bc8fba8f48be0e469a7097cd4914a4f617d9 (diff)
Revert gamma-corrected handling of transparent destination buffer
Due to the text blend routines being used by ARGB32 and due to another bug on invalid premultiplied buffers, we need to keep using the naive blend on non-opaque pixels for now. Task-number: QTBUG-60562 Task-number: QTBUG-60571 Change-Id: Idfbb2c2e24dd840189c4fbed4e167f03bbc6ca8d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/gui/painting/qdrawhelper.cpp')
-rw-r--r--src/gui/painting/qdrawhelper.cpp66
1 files changed, 29 insertions, 37 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index b2e762a391..cb3e7523a8 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -5710,17 +5710,11 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, co
static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorProfile *colorProfile)
{
// Do a gammacorrected gray alphablend...
- QRgba64 dstLinear = QRgba64::fromArgb32(*dst);
+ const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
- if (colorProfile && !dstLinear.isTransparent())
- dstLinear = colorProfile->fromLinear(dstLinear.unpremultiplied()).premultiplied();
+ QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
- dstLinear = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
-
- if (colorProfile && !dstLinear.isTransparent())
- dstLinear = colorProfile->fromLinear(dstLinear.unpremultiplied()).premultiplied();
-
- *dst = toArgb32(dstLinear);
+ *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile)
@@ -5730,7 +5724,12 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
} else if (coverage == 255) {
*dst = src;
} else {
- grayBlendPixel(dst, coverage, srcLinear, colorProfile);
+ 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);
+ }
}
}
@@ -5818,14 +5817,25 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co
dstColor = colorProfile->fromLinear(dstColor);
dest[x] = dstColor;
} else {
- // Give up and do a gray alphablend.
- if (colorProfile && !dstColor.isTransparent())
- dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
+ // Do a gray alphablend.
+ alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
+ }
+ }
+}
+
+static inline void alphargbblend_argb32(quint32 *dst, uint coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile)
+{
+ if (coverage == 0xff000000) {
+ // nothing
+ } else if (coverage == 0xffffffff) {
+ *dst = src;
+ } else {
+ if (*dst >= 0xff000000) {
+ rgbBlendPixel(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
const int a = qRgbAvg(coverage);
- dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - a);
- if (colorProfile && !dstColor.isTransparent())
- dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
- dest[x] = dstColor;
+ *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a);
}
}
}
@@ -5930,16 +5940,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
while (mapHeight--) {
for (int i = 0; i < mapWidth; ++i) {
const uint coverage = src[i];
- if (coverage == 0xffffffff) {
- dst[i] = c;
- } else if (coverage != 0xff000000) {
- if (dst[i] >= 0xff000000) {
- rgbBlendPixel(dst + i, coverage, srcColor, colorProfile);
- } else {
- // Give up and do a gray blend.
- grayBlendPixel(dst + i, qRgbAvg(coverage), srcColor, colorProfile);
- }
- }
+ alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
}
dst += destStride;
@@ -5965,16 +5966,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
for (int xp=start; xp<end; ++xp) {
const uint coverage = src[xp - x];
- if (coverage == 0xffffffff) {
- dst[xp] = c;
- } else if (coverage != 0xff000000) {
- if (dst[xp] >= 0xff000000) {
- rgbBlendPixel(dst + xp, coverage, srcColor, colorProfile);
- } else {
- // Give up and do a gray blend.
- grayBlendPixel(dst + xp, qRgbAvg(coverage), srcColor, colorProfile);
- }
- }
+ alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
}
} // for (i -> line.count)
src += srcStride;