diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-05-04 14:41:42 +0200 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2017-05-08 18:04:12 +0000 |
commit | ab059940aad327b7dbe7ef22cfd061061feb6e0e (patch) | |
tree | 64625a3786abe900e7ccb780c198d1fc36f47a5a /src | |
parent | cab9bc8fba8f48be0e469a7097cd4914a4f617d9 (diff) | |
download | qtbase-ab059940aad327b7dbe7ef22cfd061061feb6e0e.tar.gz |
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')
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 66 |
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; |