summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/image/qimage_conversions.cpp17
-rw-r--r--src/gui/kernel/qguiapplication.cpp33
-rw-r--r--src/gui/kernel/qguiapplication_p.h8
-rw-r--r--src/gui/painting/painting.pri3
-rw-r--r--src/gui/painting/qcolorprofile.cpp (renamed from src/gui/painting/qgammatables.cpp)47
-rw-r--r--src/gui/painting/qcolorprofile_p.h157
-rw-r--r--src/gui/painting/qdrawhelper.cpp146
-rw-r--r--src/gui/painting/qdrawhelper_p.h12
8 files changed, 278 insertions, 145 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index c646ee96b4..d685d50d49 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -39,6 +39,7 @@
#include <private/qdrawhelper_p.h>
#include <private/qguiapplication_p.h>
+#include <private/qcolorprofile_p.h>
#include <private/qsimd_p.h>
#include <private/qimage_p.h>
#include <qendian.h>
@@ -82,23 +83,17 @@ const uchar *qt_get_bitflip_array()
void qGamma_correct_back_to_linear_cs(QImage *image)
{
- const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
- if (!tables)
+ const QColorProfile *cp = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
+ if (!cp)
return;
- const uchar *gamma = tables->qt_pow_rgb_gamma;
// gamma correct the pixels back to linear color space...
int h = image->height();
int w = image->width();
for (int y=0; y<h; ++y) {
- uint *pixels = (uint *) image->scanLine(y);
- for (int x=0; x<w; ++x) {
- uint p = pixels[x];
- uint r = gamma[qRed(p)];
- uint g = gamma[qGreen(p)];
- uint b = gamma[qBlue(p)];
- pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
- }
+ QRgb *pixels = reinterpret_cast<QRgb *>(image->scanLine(y));
+ for (int x=0; x<w; ++x)
+ pixels[x] = cp->toLinear(pixels[x]);
}
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index ccb392f968..e0eff166a8 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -68,8 +68,8 @@
#include <qpalette.h>
#include <qscreen.h>
#include "qsessionmanager.h"
+#include <private/qcolorprofile_p.h>
#include <private/qscreen_p.h>
-#include <private/qdrawhelper_p.h>
#include <QtGui/qgenericpluginfactory.h>
#include <QtGui/qstylehints.h>
@@ -1530,7 +1530,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
platform_theme = 0;
delete platform_integration;
platform_integration = 0;
- delete m_gammaTables.load();
+ delete m_a8ColorProfile.load();
+ delete m_a32ColorProfile.load();
window_list.clear();
}
@@ -3683,14 +3684,30 @@ void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag)
}
#endif
-const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables()
+const QColorProfile *QGuiApplicationPrivate::colorProfileForA8Text()
{
- QDrawHelperGammaTables *result = m_gammaTables.load();
+#ifdef Q_OS_WIN
+ QColorProfile *result = m_a8ColorProfile.load();
if (!result){
- QDrawHelperGammaTables *tables = new QDrawHelperGammaTables(fontSmoothingGamma);
- if (!m_gammaTables.testAndSetRelease(0, tables))
- delete tables;
- result = m_gammaTables.load();
+ QColorProfile *cs = QColorProfile::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering
+ if (!m_a8ColorProfile.testAndSetRelease(0, cs))
+ delete cs;
+ result = m_a8ColorProfile.load();
+ }
+ return result;
+#else
+ return colorProfileForA32Text();
+#endif
+}
+
+const QColorProfile *QGuiApplicationPrivate::colorProfileForA32Text()
+{
+ QColorProfile *result = m_a32ColorProfile.load();
+ if (!result){
+ QColorProfile *cs = QColorProfile::fromGamma(fontSmoothingGamma);
+ if (!m_a32ColorProfile.testAndSetRelease(0, cs))
+ delete cs;
+ result = m_a32ColorProfile.load();
}
return result;
}
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index e1a35e048c..996ea748b0 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -66,10 +66,10 @@
QT_BEGIN_NAMESPACE
+class QColorProfile;
class QPlatformIntegration;
class QPlatformTheme;
class QPlatformDragQtResponse;
-struct QDrawHelperGammaTables;
#ifndef QT_NO_DRAGANDDROP
class QDrag;
#endif // QT_NO_DRAGANDDROP
@@ -292,7 +292,8 @@ public:
static QInputDeviceManager *inputDeviceManager();
- const QDrawHelperGammaTables *gammaTables();
+ const QColorProfile *colorProfileForA8Text();
+ const QColorProfile *colorProfileForA32Text();
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
@@ -316,7 +317,8 @@ private:
static QGuiApplicationPrivate *self;
static QTouchDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
- QAtomicPointer<QDrawHelperGammaTables> m_gammaTables;
+ QAtomicPointer<QColorProfile> m_a8ColorProfile;
+ QAtomicPointer<QColorProfile> m_a32ColorProfile;
bool ownGlobalShareContext;
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 86e35c39f8..63e345545c 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -8,6 +8,7 @@ HEADERS += \
painting/qbrush.h \
painting/qcolor.h \
painting/qcolor_p.h \
+ painting/qcolorprofile_p.h \
painting/qcosmeticstroker_p.h \
painting/qdatabuffer_p.h \
painting/qdrawhelper_p.h \
@@ -63,11 +64,11 @@ SOURCES += \
painting/qblittable.cpp \
painting/qbrush.cpp \
painting/qcolor.cpp \
+ painting/qcolorprofile.cpp \
painting/qcompositionfunctions.cpp \
painting/qcosmeticstroker.cpp \
painting/qdrawhelper.cpp \
painting/qemulationpaintengine.cpp \
- painting/qgammatables.cpp \
painting/qgrayraster.c \
painting/qimagescale.cpp \
painting/qmatrix.cpp \
diff --git a/src/gui/painting/qgammatables.cpp b/src/gui/painting/qcolorprofile.cpp
index 1d76f7ee3c..3b7b0a248b 100644
--- a/src/gui/painting/qgammatables.cpp
+++ b/src/gui/painting/qcolorprofile.cpp
@@ -37,28 +37,51 @@
**
****************************************************************************/
-#include <private/qdrawhelper_p.h>
+#include "qcolorprofile_p.h"
+#include <qmath.h>
QT_BEGIN_NAMESPACE
+QColorProfile *QColorProfile::fromGamma(qreal gamma)
+{
+ QColorProfile *cp = new QColorProfile;
+
+ for (int i = 0; i <= (255 * 16); ++i) {
+ cp->m_toLinear[i] = ushort(qRound(qPow(i / qreal(255 * 16), gamma) * (255 * 256)));
+ cp->m_fromLinear[i] = ushort(qRound(qPow(i / qreal(255 * 16), qreal(1) / gamma) * (255 * 256)));
+ }
+
+ return cp;
+}
-QDrawHelperGammaTables::QDrawHelperGammaTables(qreal smoothing)
+static qreal srgbToLinear(qreal v)
{
- const qreal gray_gamma = 2.31;
- for (int i=0; i<256; ++i)
- qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
- for (int i=0; i<2048; ++i)
- qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255));
+ const qreal a = 0.055;
+ if (v <= qreal(0.04045))
+ return v / qreal(12.92);
+ else
+ return qPow((v + a) / (qreal(1) + a), qreal(2.4));
+}
- refresh(smoothing);
+static qreal linearToSrgb(qreal v)
+{
+ const qreal a = 0.055;
+ if (v <= qreal(0.0031308))
+ return v * qreal(12.92);
+ else
+ return (qreal(1) + a) * qPow(v, qreal(1.0 / 2.4)) - a;
}
-void QDrawHelperGammaTables::refresh(qreal smoothing)
+QColorProfile *QColorProfile::fromSRgb()
{
- for (int i=0; i<256; ++i) {
- qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
- qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
+ QColorProfile *cp = new QColorProfile;
+
+ for (int i = 0; i <= (255 * 16); ++i) {
+ cp->m_toLinear[i] = ushort(qRound(srgbToLinear(i / qreal(255 * 16)) * (255 * 256)));
+ cp->m_fromLinear[i] = ushort(qRound(linearToSrgb(i / qreal(255 * 16)) * (255 * 256)));
}
+
+ return cp;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qcolorprofile_p.h b/src/gui/painting/qcolorprofile_p.h
new file mode 100644
index 0000000000..ca1786ee6d
--- /dev/null
+++ b/src/gui/painting/qcolorprofile_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORPROFILE_P_H
+#define QCOLORPROFILE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/qrgb.h>
+#include <QtGui/qrgba64.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QColorProfile
+{
+public:
+ static QColorProfile *fromGamma(qreal gamma);
+ static QColorProfile *fromSRgb();
+
+ // The following methods all convert opaque or unpremultiplied colors:
+
+ QRgba64 toLinear64(QRgb rgb32) const
+ {
+ ushort r = m_toLinear[qRed(rgb32) << 4];
+ ushort g = m_toLinear[qGreen(rgb32) << 4];
+ ushort b = m_toLinear[qBlue(rgb32) << 4];
+ r = r + (r >> 8);
+ g = g + (g >> 8);
+ b = b + (b >> 8);
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ }
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+ uchar r = (m_toLinear[qRed(rgb32) << 4] + 0x80) >> 8;
+ uchar g = (m_toLinear[qGreen(rgb32) << 4] + 0x80) >> 8;
+ uchar b = (m_toLinear[qBlue(rgb32) << 4] + 0x80) >> 8;
+ return qRgba(r, g, b, qAlpha(rgb32));
+ }
+
+ QRgba64 toLinear(QRgba64 rgb64) const
+ {
+ ushort r = rgb64.red();
+ ushort g = rgb64.green();
+ ushort b = rgb64.blue();
+ r = r - (r >> 8);
+ g = g - (g >> 8);
+ b = b - (b >> 8);
+ r = m_toLinear[r >> 4];
+ g = m_toLinear[g >> 4];
+ b = m_toLinear[b >> 4];
+ r = r + (r >> 8);
+ g = g + (g >> 8);
+ b = b + (b >> 8);
+ return QRgba64::fromRgba64(r, g, b, rgb64.alpha());
+ }
+
+ QRgb fromLinear64(QRgba64 rgb64) const
+ {
+ ushort r = rgb64.red();
+ ushort g = rgb64.green();
+ ushort b = rgb64.blue();
+ r = r - (r >> 8);
+ g = g - (g >> 8);
+ b = b - (b >> 8);
+ r = (m_fromLinear[r >> 4] + 0x80) >> 8;
+ g = (m_fromLinear[g >> 4] + 0x80) >> 8;
+ b = (m_fromLinear[b >> 4] + 0x80) >> 8;
+ return qRgba(r, g, b, rgb64.alpha8());
+ }
+
+ QRgb fromLinear(QRgb rgb32) const
+ {
+ uchar r = (m_fromLinear[qRed(rgb32) << 4] + 0x80) >> 8;
+ uchar g = (m_fromLinear[qGreen(rgb32) << 4] + 0x80) >> 8;
+ uchar b = (m_fromLinear[qBlue(rgb32) << 4] + 0x80) >> 8;
+ return qRgba(r, g, b, qAlpha(rgb32));
+ }
+
+ QRgba64 fromLinear(QRgba64 rgb64) const
+ {
+ ushort r = rgb64.red();
+ ushort g = rgb64.green();
+ ushort b = rgb64.blue();
+ r = r - (r >> 8);
+ g = g - (g >> 8);
+ b = b - (b >> 8);
+ r = m_fromLinear[r >> 4];
+ g = m_fromLinear[g >> 4];
+ b = m_fromLinear[b >> 4];
+ r = r + (r >> 8);
+ g = g + (g >> 8);
+ b = b + (b >> 8);
+ return QRgba64::fromRgba64(r, g, b, rgb64.alpha());
+ }
+
+private:
+ QColorProfile() { }
+
+ // We translate to 0-65280 (255*256) instead to 0-65535 to make simple
+ // shifting an accurate conversion.
+ // We translate from 0-4080 (255*16) for the same speed up, and to keep
+ // the tables small enough to fit in most inner caches.
+ ushort m_toLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
+ ushort m_fromLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOLORPROFILE_P_H
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index fe1ff6603d..bd853ad934 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -43,6 +43,7 @@
#include <qstylehints.h>
#include <qguiapplication.h>
#include <qatomic.h>
+#include <private/qcolorprofile_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qpaintengine_raster_p.h>
#include <private/qpainter_p.h>
@@ -5508,80 +5509,35 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
}
}
-static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uchar *gamma, const uchar *invgamma)
+static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorProfile *colorProfile)
{
- // Do a gray alphablend...
- int da = qAlpha(*dst);
- int dr = qRed(*dst);
- int dg = qGreen(*dst);
- int db = qBlue(*dst);
+ // Do a gammacorrected RGB alphablend...
+ const int mr = qRed(coverage);
+ const int mg = qGreen(coverage);
+ const int mb = qBlue(coverage);
- if (da != 255
- ) {
+ const QRgba64 dlinear = colorProfile->toLinear64(*dst);
- int a = qGray(coverage);
- sr = qt_div_255(invgamma[sr] * a);
- sg = qt_div_255(invgamma[sg] * a);
- sb = qt_div_255(invgamma[sb] * a);
+ QRgba64 blend;
+ blend.setAlpha(65535);
+ blend.setRed (qt_div_255(slinear.red() * mr + dlinear.red() * (255 - mr)));
+ blend.setGreen(qt_div_255(slinear.green() * mg + dlinear.green() * (255 - mg)));
+ blend.setBlue (qt_div_255(slinear.blue() * mb + dlinear.blue() * (255 - mb)));
- int ia = 255 - a;
- dr = qt_div_255(dr * ia);
- dg = qt_div_255(dg * ia);
- db = qt_div_255(db * ia);
-
- *dst = ((a + qt_div_255((255 - a) * da)) << 24)
- | ((sr + dr) << 16)
- | ((sg + dg) << 8)
- | ((sb + db));
- return;
- }
-
- int mr = qRed(coverage);
- int mg = qGreen(coverage);
- int mb = qBlue(coverage);
-
- dr = gamma[dr];
- dg = gamma[dg];
- db = gamma[db];
-
- int nr = qt_div_255(sr * mr + dr * (255 - mr));
- int ng = qt_div_255(sg * mg + dg * (255 - mg));
- int nb = qt_div_255(sb * mb + db * (255 - mb));
-
- nr = invgamma[nr];
- ng = invgamma[ng];
- nb = invgamma[nb];
-
- *dst = qRgb(nr, ng, nb);
+ *dst = colorProfile->fromLinear64(blend);
}
-#if defined(Q_OS_WIN)
Q_GUI_EXPORT bool qt_needs_a8_gamma_correction = false;
-static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uint *gamma, const uchar *invgamma)
+static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorProfile *colorProfile)
{
// Do a gammacorrected gray alphablend...
- int dr = qRed(*dst);
- int dg = qGreen(*dst);
- int db = qBlue(*dst);
-
- dr = gamma[dr];
- dg = gamma[dg];
- db = gamma[db];
-
- int alpha = coverage;
- int ialpha = 255 - alpha;
- int nr = qt_div_255(sr * alpha + dr * ialpha);
- int ng = qt_div_255(sg * alpha + dg * ialpha);
- int nb = qt_div_255(sb * alpha + db * ialpha);
+ const QRgba64 dlinear = colorProfile->toLinear64(*dst);
- nr = invgamma[nr];
- ng = invgamma[ng];
- nb = invgamma[nb];
+ QRgba64 blend = interpolate255(slinear, coverage, dlinear, 255 - coverage);
- *dst = qRgb(nr, ng, nb);
+ *dst = colorProfile->fromLinear64(blend);
}
-#endif
static void qt_alphamapblit_uint32(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
@@ -5592,21 +5548,14 @@ static void qt_alphamapblit_uint32(QRasterBuffer *rasterBuffer,
const quint32 c = color;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32);
-#if defined(Q_OS_WIN)
- const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
- if (!tables)
+ const QColorProfile *colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
+ if (!colorProfile)
return;
- const uint *gamma = tables->qt_pow_gamma;
- const uchar *invgamma = tables->qt_pow_invgamma;
-
- int sr = gamma[qRed(color)];
- int sg = gamma[qGreen(color)];
- int sb = gamma[qBlue(color)];
+ const QRgba64 slinear = colorProfile->toLinear64(c);
bool opaque_src = (qAlpha(color) == 255);
bool doGrayBlendPixel = opaque_src && qt_needs_a8_gamma_correction;
-#endif
if (!clip) {
quint32 *dest = reinterpret_cast<quint32*>(rasterBuffer->scanLine(y)) + x;
@@ -5619,13 +5568,9 @@ static void qt_alphamapblit_uint32(QRasterBuffer *rasterBuffer,
} else if (coverage == 255) {
dest[i] = c;
} else {
-#if defined(Q_OS_WIN)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
- && qAlpha(dest[i]) == 255) {
- grayBlendPixel(dest+i, coverage, sr, sg, sb, gamma, invgamma);
- } else
-#endif
- {
+ if (doGrayBlendPixel && qAlpha(dest[i]) == 255) {
+ grayBlendPixel(dest+i, coverage, slinear, colorProfile);
+ } else {
int ialpha = 255 - coverage;
dest[i] = INTERPOLATE_PIXEL_255(c, coverage, dest[i], ialpha);
}
@@ -5660,13 +5605,9 @@ static void qt_alphamapblit_uint32(QRasterBuffer *rasterBuffer,
} else if (coverage == 255) {
dest[xp] = c;
} else {
-#if defined(Q_OS_WIN)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
- && qAlpha(dest[xp]) == 255) {
- grayBlendPixel(dest+xp, coverage, sr, sg, sb, gamma, invgamma);
- } else
-#endif
- {
+ if (doGrayBlendPixel && qAlpha(dest[xp]) == 255) {
+ grayBlendPixel(dest+xp, coverage, slinear, colorProfile);
+ } else {
int ialpha = 255 - coverage;
dest[xp] = INTERPOLATE_PIXEL_255(c, coverage, dest[xp], ialpha);
}
@@ -5700,6 +5641,11 @@ static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
}
#endif
+inline static int qRgbAvg(QRgb rgb)
+{
+ return (qRed(rgb) * 5 + qGreen(rgb) * 6 + qBlue(rgb) * 5) / 16;
+}
+
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uint *src, int mapWidth, int mapHeight, int srcStride,
@@ -5707,21 +5653,13 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
{
const quint32 c = color.toArgb32();
- int sr = qRed(c);
- int sg = qGreen(c);
- int sb = qBlue(c);
int sa = qAlpha(c);
- const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
- if (!tables)
+ const QColorProfile *colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
+ if (!colorProfile)
return;
- const uchar *gamma = tables->qt_pow_rgb_gamma;
- const uchar *invgamma = tables->qt_pow_rgb_invgamma;
-
- sr = gamma[sr];
- sg = gamma[sg];
- sb = gamma[sb];
+ const QRgba64 slinear = colorProfile->toLinear64(c);
if (sa == 0)
return;
@@ -5735,7 +5673,13 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
if (coverage == 0xffffffff) {
dst[i] = c;
} else if (coverage != 0xff000000) {
- rgbBlendPixel(dst+i, coverage, sr, sg, sb, gamma, invgamma);
+ if (dst[i] >= 0xff000000) {
+ rgbBlendPixel(dst+i, coverage, slinear, colorProfile);
+ } else {
+ // Give up and do a naive blend.
+ const int a = qRgbAvg(coverage);
+ dst[i] = INTERPOLATE_PIXEL_255(c, a, dst[i], 255 - a);
+ }
}
}
@@ -5765,7 +5709,13 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
if (coverage == 0xffffffff) {
dst[xp] = c;
} else if (coverage != 0xff000000) {
- rgbBlendPixel(dst+xp, coverage, sr, sg, sb, gamma, invgamma);
+ if (dst[xp] >= 0xff000000) {
+ rgbBlendPixel(dst+xp, coverage, slinear, colorProfile);
+ } else {
+ // Give up and do a naive blend.
+ const int a = qRgbAvg(coverage);
+ dst[xp] = INTERPOLATE_PIXEL_255(c, a, dst[xp], 255 - coverage);
+ }
}
}
} // for (i -> line.count)
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index e537c343bb..f28b2821d6 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -345,18 +345,6 @@ struct QSpanData
void adjustSpanMethods();
};
-struct QDrawHelperGammaTables
-{
- explicit QDrawHelperGammaTables(qreal smoothing);
-
- void refresh(qreal smoothing);
-
- uchar qt_pow_rgb_gamma[256];
- uchar qt_pow_rgb_invgamma[256];
- uint qt_pow_gamma[256];
- uchar qt_pow_invgamma[2048];
-};
-
static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
{
if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) {