From 5c7d2d1d6772b1d7e808aa37659ce5654f0862da Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 10 Apr 2015 15:34:23 +0200 Subject: Add support for more composition modes in rgb64 rendering Change-Id: I3bacecbabdf2d7b2de1acd86ab9383e69924a390 Reviewed-by: Gunnar Sletta --- src/gui/painting/qdrawhelper.cpp | 271 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 267 insertions(+), 4 deletions(-) (limited to 'src/gui/painting/qdrawhelper.cpp') diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index b2992a138e..2dab2ba859 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3029,6 +3029,23 @@ void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, ui } } +void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(color, dest[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + color = multiplyAlpha65535(color, ca); + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + dest[i] = interpolate65535(color, d.alpha(), d, cia); + } + } +} + void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3048,6 +3065,23 @@ void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DE } } +void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(src[i], dest[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = multiplyAlpha65535(src[i], ca); + dest[i] = interpolate65535(s, d.alpha(), d, cia); + } + } +} + /* result = d * sa dest = d * sa * ca + d * cia @@ -3066,6 +3100,17 @@ void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint colo } } +void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + uint a = color.alpha(); + uint ca64k = const_alpha * 257; + if (const_alpha != 255) + a = qt_div_65535(a * ca64k) + 65535 - ca64k; + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(dest[i], a); + } +} + void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3084,6 +3129,22 @@ void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint } } +void QT_FASTCALL comp_func_DestinationIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(dest[i], src[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + for (int i = 0; i < length; ++i) { + uint a = qt_div_65535(src[i].alpha() * ca) + cia; + dest[i] = multiplyAlpha65535(dest[i], a); + } + } +} + /* result = s * dia dest = s * dia * ca + d * cia @@ -3108,6 +3169,23 @@ void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, u } } +void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(color, 65535 - dest[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + color = multiplyAlpha65535(color, ca); + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + dest[i] = interpolate65535(color, 65535 - d.alpha(), d, cia); + } + } +} + void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3127,6 +3205,23 @@ void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_D } } +void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(src[i], 65535 - dest[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = multiplyAlpha65535(src[i], ca); + dest[i] = interpolate65535(s, 65535 - d.alpha(), d, cia); + } + } +} + /* result = d * sia dest = d * sia * ca + d * cia @@ -3144,6 +3239,17 @@ void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint col } } +void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + uint a = 65535 - color.alpha(); + uint ca64k = const_alpha * 257; + if (const_alpha != 255) + a = qt_div_65535(a * ca64k) + 65535 - ca64k; + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(dest[i], a); + } +} + void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3162,6 +3268,22 @@ void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint } } +void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = multiplyAlpha65535(dest[i], 65535 - src[i].alpha()); + } + } else { + uint ca = const_alpha * 257; + uint cia = 65535 - ca; + for (int i = 0; i < length; ++i) { + uint a = qt_div_65535((65535 - src[i].alpha()) * ca) + cia; + dest[i] = multiplyAlpha65535(dest[i], a); + } + } +} + /* result = s*da + d*sia dest = s*da*ca + d*sia*ca + d *cia @@ -3181,6 +3303,16 @@ void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, } } +void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha != 255) + color = multiplyAlpha255(color, const_alpha); + uint sia = 65535 - color.alpha(); + for (int i = 0; i < length; ++i) { + dest[i] = interpolate65535(color, dest[i].alpha(), dest[i], sia); + } +} + void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3201,6 +3333,23 @@ void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_ } } +void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + QRgba64 s = src[i]; + QRgba64 d = dest[i]; + dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha()); + } + } else { + for (int i = 0; i < length; ++i) { + QRgba64 s = multiplyAlpha255(src[i], const_alpha); + QRgba64 d = dest[i]; + dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha()); + } + } +} + /* result = d*sa + s*dia dest = d*sa*ca + s*dia*ca + d *cia @@ -3221,6 +3370,19 @@ void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint co } } +void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + uint a = color.alpha(); + if (const_alpha != 255) { + color = multiplyAlpha255(color, const_alpha); + a = color.alpha() + 65535 - (const_alpha * 257); + } + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + dest[i] = interpolate65535(d, a, color, 65535 - d.alpha()); + } +} + void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3243,6 +3405,26 @@ void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uin } } +void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + QRgba64 s = src[i]; + QRgba64 d = dest[i]; + dest[i] = interpolate65535(d, s.alpha(), s, 65535 - d.alpha()); + } + } else { + int ca = const_alpha * 257; + int cia = 65535 - ca; + for (int i = 0; i < length; ++i) { + QRgba64 s = multiplyAlpha65535(src[i], ca); + QRgba64 d = dest[i]; + uint a = s.alpha() + cia; + dest[i] = interpolate65535(d, a, s, 65535 - d.alpha()); + } + } +} + /* result = d*sia + s*dia dest = d*sia*ca + s*dia*ca + d *cia @@ -3263,6 +3445,17 @@ void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint co } } +void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha != 255) + color = multiplyAlpha255(color, const_alpha); + uint sia = 65535 - color.alpha(); + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + dest[i] = interpolate65535(color, 65535 - d.alpha(), d, sia); + } +} + void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) @@ -3283,6 +3476,23 @@ void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RE } } +void QT_FASTCALL comp_func_XOR_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha()); + } + } else { + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = multiplyAlpha255(src[i], const_alpha); + dest[i] = interpolate65535(s, 65535 - d.alpha(), d, 65535 - s.alpha()); + } + } +} + struct QFullCoverage { inline void store(uint *dest, const uint src) const { @@ -3330,6 +3540,17 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl_rgb64(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + QRgba64 s = color; + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + d = comp_func_Plus_one_pixel(d, s); + coverage.store(&dest[i], d); + } +} + void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -3338,6 +3559,20 @@ void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint c comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = addWithSaturation(dest[i], color); + } + } else { + for (int i = 0; i < length; ++i) { + QRgba64 d = addWithSaturation(dest[i], color); + dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha); + } + } +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -3361,6 +3596,20 @@ void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_R comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Plus_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + for (int i = 0; i < length; ++i) { + dest[i] = addWithSaturation(dest[i], src[i]); + } + } else { + for (int i = 0; i < length; ++i) { + QRgba64 d = addWithSaturation(dest[i], src[i]); + dest[i] = interpolate255(d, const_alpha, dest[i], 255 - const_alpha); + } + } +} + /* Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) */ @@ -4552,8 +4801,15 @@ static CompositionFunctionSolid64 functionForModeSolid64_C[] = { comp_func_solid_Clear_rgb64, comp_func_solid_Source_rgb64, comp_func_solid_Destination_rgb64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + comp_func_solid_SourceIn_rgb64, + comp_func_solid_DestinationIn_rgb64, + comp_func_solid_SourceOut_rgb64, + comp_func_solid_DestinationOut_rgb64, + comp_func_solid_SourceAtop_rgb64, + comp_func_solid_DestinationAtop_rgb64, + comp_func_solid_XOR_rgb64, + comp_func_solid_Plus_rgb64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -4609,8 +4865,15 @@ static CompositionFunction64 functionForMode64_C[] = { comp_func_Clear_rgb64, comp_func_Source_rgb64, comp_func_Destination_rgb64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + comp_func_SourceIn_rgb64, + comp_func_DestinationIn_rgb64, + comp_func_SourceOut_rgb64, + comp_func_DestinationOut_rgb64, + comp_func_SourceAtop_rgb64, + comp_func_DestinationAtop_rgb64, + comp_func_XOR_rgb64, + comp_func_Plus_rgb64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -- cgit v1.2.3