From 1ad41e99bd0426f203b23fa5bbbaf070402d1fad Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Sun, 28 Dec 2014 01:11:09 +0100 Subject: [PATCH 2/2] add qSetSubpixelBlendBackgroundColor Signed-off-by: Matej Knopp --- src/gui/painting/qdrawhelper.cpp | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 9c1b2e7..8b47965 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6171,10 +6171,95 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, } } +static quint32 qSubPixelBlendBackgroundColor = 0; + +// Allows specifying target background collor for subpixel blends to empty surface +void Q_GUI_EXPORT qSetSubpixelBlendBackgroundColor(quint32 color) +{ + qSubPixelBlendBackgroundColor = color; +} + static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uchar *gamma, const uchar *invgamma) { // Do a gray alphablend... int da = qAlpha(*dst); + + if (da == 0 && qSubPixelBlendBackgroundColor != 0) + { + int dr = qRed(qSubPixelBlendBackgroundColor); + int dg = qGreen(qSubPixelBlendBackgroundColor); + int db = qBlue(qSubPixelBlendBackgroundColor); + + int mr = qRed(coverage); + int mg = qGreen(coverage); + int mb = qBlue(coverage); + +#if 0 + int a = qGray(coverage); +#else + // qGray is probably the proper way to do this, but the code below seems to give better results + int a = qMax(mr, mg); + a = qMax(a, mb); +#endif + dr = gamma[dr]; + dg = gamma[dg]; + db = gamma[db]; + + int nr = qt_div_255((sr - dr) * mr) + dr; + int ng = qt_div_255((sg - dg) * mg) + dg; + int nb = qt_div_255((sb - db) * mb) + db; + + nr = invgamma[nr]; + ng = invgamma[ng]; + nb = invgamma[nb]; + + *dst = qRgba(qt_div_255(nr * a), qt_div_255(ng * a), qt_div_255(nb * a), a); + return; + } + else if (da < 255 && qSubPixelBlendBackgroundColor != 0) + { + // Blend destination color to "fake" destination color + int da = qAlpha(*dst); + int ida = 255 - da; + + int dr = qRed(*dst) + qt_div_255(qRed(qSubPixelBlendBackgroundColor) * ida); + int dg = qGreen(*dst) + qt_div_255(qGreen(qSubPixelBlendBackgroundColor) * ida); + int db = qBlue(*dst) + qt_div_255(qBlue(qSubPixelBlendBackgroundColor) * ida); + + // Do subpixel blending + + int mr = qRed(coverage); + int mg = qGreen(coverage); + int mb = qBlue(coverage); + +#if 0 + int a = qGray(coverage); +#else + // qGray is probably the proper way to do this, but the code below seems to give better results + int a = qMax(mr, mg); + a = qMax(a, mb); +#endif + dr = gamma[dr]; + dg = gamma[dg]; + db = gamma[db]; + + int nr = qt_div_255((sr - dr) * mr) + dr; + int ng = qt_div_255((sg - dg) * mg) + dg; + int nb = qt_div_255((sb - db) * mb) + db; + + nr = invgamma[nr]; + ng = invgamma[ng]; + nb = invgamma[nb]; + + // Blend the result to actual destination + int ia = 255 - a; + *dst = qRgba(qt_div_255(nr * a) + qt_div_255(qRed(*dst) * ia), + qt_div_255(ng * a) + qt_div_255(qGreen(*dst) * ia), + qt_div_255(nb * a) + qt_div_255(qBlue(*dst) * ia), + da + qt_div_255(a * ida)); + return; + } + int dr = qRed(*dst); int dg = qGreen(*dst); int db = qBlue(*dst); -- 1.9.3 (Apple Git-50)