From 0169edf6fd136415a1eb4b68b7d5384a843ca335 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 23 May 2017 15:46:30 +0200 Subject: Implement remaining porter-duff compositions for rgb64 Gets rid of debug output when they are used, which is more common now that we use it for unpremultiplied ARGB32. Task-number: QTBUG-60549 Change-Id: I14b2eb34d1d08612916e2b69b188f33dbe1b525c Reviewed-by: Eirik Aavitsland --- src/gui/painting/qcompositionfunctions.cpp | 792 ++++++++++++++++++++++++++++- 1 file changed, 777 insertions(+), 15 deletions(-) (limited to 'src/gui/painting/qcompositionfunctions.cpp') diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp index 6d2cb9aadb..ee05f810f1 100644 --- a/src/gui/painting/qcompositionfunctions.cpp +++ b/src/gui/painting/qcompositionfunctions.cpp @@ -855,6 +855,10 @@ struct QFullCoverage { { *dest = src; } + inline void store(QRgba64 *dest, const QRgba64 src) const + { + *dest = src; + } }; struct QPartialCoverage { @@ -868,6 +872,10 @@ struct QPartialCoverage { { *dest = INTERPOLATE_PIXEL_255(src, ca, *dest, ica); } + inline void store(QRgba64 *dest, const QRgba64 src) const + { + *dest = interpolate255(src, ca, *dest, ica); + } private: const uint ca; @@ -879,6 +887,11 @@ static inline int mix_alpha(int da, int sa) return 255 - ((255 - sa) * (255 - da) >> 8); } +static inline uint mix_alpha_rgb64(uint da, uint sa) +{ + return 65535 - ((65535 - sa) * (65535 - da) >> 16); +} + /* Dca' = Sca.Da + Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa) = Sca + Dca @@ -897,17 +910,6 @@ 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) @@ -986,6 +988,11 @@ static inline int multiply_op(int dst, int src, int da, int sa) return qt_div_255(src * dst + src * (255 - da) + dst * (255 - sa)); } +static inline uint multiply_op_rgb64(uint dst, uint src, uint da, uint sa) +{ + return qt_div_65535(src * dst + src * (65535 - da) + dst * (65535 - sa)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1011,6 +1018,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) multiply_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1019,6 +1049,14 @@ void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, ui comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Multiply_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1042,6 +1080,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_REST } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) multiply_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Multiply(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1050,6 +1109,14 @@ void QT_FASTCALL comp_func_Multiply(uint *Q_DECL_RESTRICT dest, const uint *Q_DE comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Multiply_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Multiply_impl(dest, src, length, QFullCoverage()); + else + comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* Dca' = (Sca.Da + Dca.Sa - Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) = Sca + Dca - Sca.Dca @@ -1079,6 +1146,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, i } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) 65535 - qt_div_65535((65535-a) * (65535-b)) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1087,6 +1177,14 @@ void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Screen_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Screen_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1110,6 +1208,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRI } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) 65535 - (((65535-a) * (65535-b)) >> 16) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1118,6 +1237,14 @@ void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Screen_rgb64(QRgba64 *dest, const QRgba64 *src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Screen_impl(dest, src, length, QFullCoverage()); + else + comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* if 2.Dca < Da Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) @@ -1133,6 +1260,15 @@ static inline int overlay_op(int dst, int src, int da, int sa) return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp); } +static inline uint overlay_op_rgb64(uint dst, uint src, uint da, uint sa) +{ + const uint temp = src * (65535 - da) + dst * (65535 - sa); + if (2 * dst < da) + return qt_div_65535(2 * src * dst + temp); + else + return qt_div_65535(sa * da - 2 * (da - dst) * (sa - src) + temp); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1158,6 +1294,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) overlay_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1166,6 +1325,14 @@ void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uin comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Overlay_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1189,6 +1356,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTR } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) overlay_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Overlay(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1197,6 +1385,14 @@ void QT_FASTCALL comp_func_Overlay(uint *Q_DECL_RESTRICT dest, const uint *Q_DEC comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Overlay_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Overlay_impl(dest, src, length, QFullCoverage()); + else + comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) Da' = Sa + Da - Sa.Da @@ -1206,6 +1402,11 @@ static inline int darken_op(int dst, int src, int da, int sa) return qt_div_255(qMin(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa)); } +static inline uint darken_op_rgb64(uint dst, uint src, uint da, uint sa) +{ + return qt_div_65535(qMin(src * da, dst * sa) + src * (65535 - da) + dst * (65535 - sa)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1231,6 +1432,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, i } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) darken_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1239,6 +1463,14 @@ void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Darken_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Darken_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1262,6 +1494,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRI } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) darken_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Darken(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1270,6 +1523,14 @@ void QT_FASTCALL comp_func_Darken(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Darken_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Darken_impl(dest, src, length, QFullCoverage()); + else + comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) Da' = Sa + Da - Sa.Da @@ -1279,6 +1540,11 @@ static inline int lighten_op(int dst, int src, int da, int sa) return qt_div_255(qMax(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa)); } +static inline uint lighten_op_rgb64(uint dst, uint src, uint da, uint sa) +{ + return qt_div_65535(qMax(src * da, dst * sa) + src * (65535 - da) + dst * (65535 - sa)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1304,6 +1570,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) lighten_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1312,6 +1601,14 @@ void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uin comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Lighten_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1335,6 +1632,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTR } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) lighten_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Lighten(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1343,6 +1661,14 @@ void QT_FASTCALL comp_func_Lighten(uint *Q_DECL_RESTRICT dest, const uint *Q_DEC comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Lighten_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Lighten_impl(dest, src, length, QFullCoverage()); + else + comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* if Sca.Da + Dca.Sa >= Sa.Da Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) @@ -1362,6 +1688,19 @@ static inline int color_dodge_op(int dst, int src, int da, int sa) return qt_div_255(255 * dst_sa / (255 - 255 * src / sa) + temp); } +static inline uint color_dodge_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa) +{ + const qint64 sa_da = sa * da; + const qint64 dst_sa = dst * sa; + const qint64 src_da = src * da; + + const qint64 temp = src * (65535 - da) + dst * (65535 - sa); + if (src_da + dst_sa >= sa_da) + return qt_div_65535(sa_da + temp); + else + return qt_div_65535(65535 * dst_sa / (65535 - 65535 * src / sa) + temp); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1387,6 +1726,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *des } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a,b) color_dodge_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1395,6 +1757,14 @@ void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_ColorDodge_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1418,6 +1788,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RE } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) color_dodge_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_ColorDodge(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1426,6 +1817,14 @@ void QT_FASTCALL comp_func_ColorDodge(uint *Q_DECL_RESTRICT dest, const uint *Q_ comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_ColorDodge_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_ColorDodge_impl(dest, src, length, QFullCoverage()); + else + comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* if Sca.Da + Dca.Sa <= Sa.Da Dca' = Sca.(1 - Da) + Dca.(1 - Sa) @@ -1445,6 +1844,19 @@ static inline int color_burn_op(int dst, int src, int da, int sa) return qt_div_255(sa * (src_da + dst_sa - sa_da) / src + temp); } +static inline uint color_burn_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa) +{ + const qint64 src_da = src * da; + const qint64 dst_sa = dst * sa; + const qint64 sa_da = sa * da; + + const qint64 temp = src * (65535 - da) + dst * (65535 - sa); + + if (src == 0 || src_da + dst_sa <= sa_da) + return qt_div_65535(temp); + return qt_div_65535(sa * (src_da + dst_sa - sa_da) / src + temp); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1470,6 +1882,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) color_burn_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1478,6 +1913,14 @@ void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, u comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_ColorBurn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1501,6 +1944,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RES } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) color_burn_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_ColorBurn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1509,6 +1973,14 @@ void QT_FASTCALL comp_func_ColorBurn(uint *Q_DECL_RESTRICT dest, const uint *Q_D comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_ColorBurn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_ColorBurn_impl(dest, src, length, QFullCoverage()); + else + comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* if 2.Sca < Sa Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) @@ -1525,6 +1997,16 @@ static inline uint hardlight_op(int dst, int src, int da, int sa) return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp); } +static inline uint hardlight_op_rgb64(uint dst, uint src, uint da, uint sa) +{ + const uint temp = src * (65535 - da) + dst * (65535 - sa); + + if (2 * src < sa) + return qt_div_65535(2 * src * dst + temp); + else + return qt_div_65535(sa * da - 2 * (da - dst) * (sa - src) + temp); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1550,6 +2032,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) hardlight_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1558,6 +2063,14 @@ void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, u comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_HardLight_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1581,6 +2094,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RES } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) hardlight_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_HardLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1589,6 +2123,14 @@ void QT_FASTCALL comp_func_HardLight(uint *Q_DECL_RESTRICT dest, const uint *Q_D comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_HardLight_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_HardLight_impl(dest, src, length, QFullCoverage()); + else + comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* if 2.Sca <= Sa Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa) @@ -1612,6 +2154,22 @@ static inline int soft_light_op(int dst, int src, int da, int sa) } } +static inline uint soft_light_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa) +{ + const qint64 src2 = src << 1; + const qint64 dst_np = da != 0 ? (65535 * dst) / da : 0; + const qint64 temp = (src * (65535 - da) + dst * (65535 - sa)) * 65535; + const qint64 factor = qint64(65535) * 65535; + + if (src2 < sa) + return (dst * (sa * 65535 + (src2 - sa) * (65535 - dst_np)) + temp) / factor; + else if (4 * dst <= da) + return (dst * sa * 65535 + da * (src2 - sa) * ((((16 * dst_np - 12 * 65535) * dst_np + 3 * factor) * dst_np) / factor) + temp) / factor; + else { + return (dst * sa * 65535 + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 65535))) - dst_np) + temp) / factor; + } +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1637,6 +2195,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) soft_light_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1645,6 +2226,14 @@ void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, u comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_SoftLight_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1668,6 +2257,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RES } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) soft_light_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_SoftLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1676,6 +2286,14 @@ void QT_FASTCALL comp_func_SoftLight(uint *Q_DECL_RESTRICT dest, const uint *Q_D comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_SoftLight_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_SoftLight_impl(dest, src, length, QFullCoverage()); + else + comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* Dca' = abs(Dca.Sa - Sca.Da) + Sca.(1 - Da) + Dca.(1 - Sa) = Sca + Dca - 2.min(Sca.Da, Dca.Sa) @@ -1685,6 +2303,11 @@ static inline int difference_op(int dst, int src, int da, int sa) return src + dst - qt_div_255(2 * qMin(src * da, dst * sa)); } +static inline uint difference_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa) +{ + return src + dst - qt_div_65535(2 * qMin(src * da, dst * sa)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage) { @@ -1710,6 +2333,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *des } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) difference_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1718,6 +2364,14 @@ void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Difference_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Difference_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1741,6 +2395,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RE } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) difference_op_rgb64(a, b, da, sa) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Difference(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1749,6 +2424,14 @@ void QT_FASTCALL comp_func_Difference(uint *Q_DECL_RESTRICT dest, const uint *Q_ comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Difference_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Difference_impl(dest, src, length, QFullCoverage()); + else + comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + /* Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) */ @@ -1777,6 +2460,30 @@ Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_imp } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +{ + uint sa = color.alpha(); + uint sr = color.red(); + uint sg = color.green(); + uint sb = color.blue(); + + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + uint da = d.alpha(); + +#define OP(a, b) (a + b - qt_div_65535(2*(qint64(a)*b))) + uint r = OP( d.red(), sr); + uint b = OP( d.blue(), sb); + uint g = OP(d.green(), sg); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + + void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha) { if (const_alpha == 255) @@ -1785,6 +2492,14 @@ void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, u comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_solid_Exclusion_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage()); + else + comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha)); +} + template Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { @@ -1808,6 +2523,27 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RES } } +template +Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +{ + for (int i = 0; i < length; ++i) { + QRgba64 d = dest[i]; + QRgba64 s = src[i]; + + uint da = d.alpha(); + uint sa = s.alpha(); + +#define OP(a, b) (a + b - ((qint64(a)*b) >> 15)) + uint r = OP( d.red(), s.red()); + uint b = OP( d.blue(), s.blue()); + uint g = OP(d.green(), s.green()); + uint a = mix_alpha_rgb64(da, sa); +#undef OP + + coverage.store(&dest[i], qRgba64(r, g, b, a)); + } +} + void QT_FASTCALL comp_func_Exclusion(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha) { if (const_alpha == 255) @@ -1816,6 +2552,14 @@ void QT_FASTCALL comp_func_Exclusion(uint *Q_DECL_RESTRICT dest, const uint *Q_D comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha)); } +void QT_FASTCALL comp_func_Exclusion_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha) +{ + if (const_alpha == 255) + comp_func_Exclusion_impl(dest, src, length, QFullCoverage()); + else + comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha)); +} + void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, int length, uint color, @@ -2177,8 +2921,17 @@ CompositionFunctionSolid64 qt_functionForModeSolid64_C[] = { 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, + comp_func_solid_Multiply_rgb64, + comp_func_solid_Screen_rgb64, + comp_func_solid_Overlay_rgb64, + comp_func_solid_Darken_rgb64, + comp_func_solid_Lighten_rgb64, + comp_func_solid_ColorDodge_rgb64, + comp_func_solid_ColorBurn_rgb64, + comp_func_solid_HardLight_rgb64, + comp_func_solid_SoftLight_rgb64, + comp_func_solid_Difference_rgb64, + comp_func_solid_Exclusion_rgb64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -2238,8 +2991,17 @@ CompositionFunction64 qt_functionForMode64_C[] = { comp_func_DestinationAtop_rgb64, comp_func_XOR_rgb64, comp_func_Plus_rgb64, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + comp_func_Multiply_rgb64, + comp_func_Screen_rgb64, + comp_func_Overlay_rgb64, + comp_func_Darken_rgb64, + comp_func_Lighten_rgb64, + comp_func_ColorDodge_rgb64, + comp_func_ColorBurn_rgb64, + comp_func_HardLight_rgb64, + comp_func_SoftLight_rgb64, + comp_func_Difference_rgb64, + comp_func_Exclusion_rgb64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -- cgit v1.2.3