summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qdrawhelper_p.h
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-05-06 14:23:57 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-03 12:01:26 +0000
commit8f760808e0fe0fe6dd89d561f118b19ed8085e7a (patch)
tree8cc259b6098d83b91b6ec8ac22745546947860c7 /src/gui/painting/qdrawhelper_p.h
parent754efa57d89c62d1796e01b407e9222e67450f52 (diff)
Fix premul conversion from ARGB32 to A2RGB30 formats.
When a premultiplied alpha changes value because it is rounded to fewer bits the premultiplied colors may need to be recalculated with the new value. Otherwise the color will both be wrong and potentially invalid. Change-Id: I9ec74a22aac73cd7ffab04e180cf2bf35bb4c315 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/gui/painting/qdrawhelper_p.h')
-rw-r--r--src/gui/painting/qdrawhelper_p.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 66ef5949d9..73ff21812a 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -847,9 +847,25 @@ template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb);
template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c);
+// A combined unpremultiply and premultiply with new simplified alpha.
+// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30).
+template<unsigned int Shift>
+inline QRgb qRepremultiply(QRgb p)
+{
+ const uint alpha = qAlpha(p);
+ if (alpha == 255 || alpha == 0)
+ return p;
+ p = qUnpremultiply(p);
+ Q_CONSTEXPR uint mult = 255 / (255 >> Shift);
+ const uint newAlpha = mult * (alpha >> Shift);
+ p = (p & ~0xff000000) | (newAlpha<<24);
+ return qPremultiply(p);
+}
+
template<>
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
{
+ c = qRepremultiply<6>(c);
return (c & 0xc0000000)
| (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000))
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))
@@ -859,6 +875,7 @@ inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
template<>
inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c)
{
+ c = qRepremultiply<6>(c);
return (c & 0xc0000000)
| (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000))
| (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00))