Introduce QRgba64 structure for 64bit RGBA values
This structure is meant to replace QRgb where higher precision is needed. Change-Id: I49d441e2133371a8b91c2e6af0c137bcc5fcb9ed Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
This commit is contained in:
parent
395e205f2f
commit
e2c91dd77b
@ -43,6 +43,7 @@ HEADERS += \
|
|||||||
painting/qrasterizer_p.h \
|
painting/qrasterizer_p.h \
|
||||||
painting/qregion.h \
|
painting/qregion.h \
|
||||||
painting/qrgb.h \
|
painting/qrgb.h \
|
||||||
|
painting/qrgba64.h \
|
||||||
painting/qstroker_p.h \
|
painting/qstroker_p.h \
|
||||||
painting/qtextureglyphcache_p.h \
|
painting/qtextureglyphcache_p.h \
|
||||||
painting/qtransform.h \
|
painting/qtransform.h \
|
||||||
|
@ -416,6 +416,18 @@ QColor::QColor(QRgb color)
|
|||||||
ct.argb.pad = 0;
|
ct.argb.pad = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Constructs a color with the value \a rgba64.
|
||||||
|
|
||||||
|
\sa fromRgba64()
|
||||||
|
*/
|
||||||
|
|
||||||
|
QColor::QColor(QRgba64 rgba64)
|
||||||
|
{
|
||||||
|
setRgba64(rgba64);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
@ -941,7 +953,7 @@ void QColor::setRgb(int r, int g, int b, int a)
|
|||||||
|
|
||||||
For an invalid color, the alpha value of the returned color is unspecified.
|
For an invalid color, the alpha value of the returned color is unspecified.
|
||||||
|
|
||||||
\sa setRgba(), rgb()
|
\sa setRgba(), rgb(), rgba64()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QRgb QColor::rgba() const
|
QRgb QColor::rgba() const
|
||||||
@ -954,7 +966,7 @@ QRgb QColor::rgba() const
|
|||||||
/*!
|
/*!
|
||||||
Sets the RGB value to \a rgba, including its alpha.
|
Sets the RGB value to \a rgba, including its alpha.
|
||||||
|
|
||||||
\sa rgba(), rgb()
|
\sa rgba(), rgb(), setRgba64()
|
||||||
*/
|
*/
|
||||||
void QColor::setRgba(QRgb rgba)
|
void QColor::setRgba(QRgb rgba)
|
||||||
{
|
{
|
||||||
@ -966,6 +978,40 @@ void QColor::setRgba(QRgb rgba)
|
|||||||
ct.argb.pad = 0;
|
ct.argb.pad = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Returns the RGB64 value of the color, including its alpha.
|
||||||
|
|
||||||
|
For an invalid color, the alpha value of the returned color is unspecified.
|
||||||
|
|
||||||
|
\sa setRgba64(), rgba(), rgb()
|
||||||
|
*/
|
||||||
|
|
||||||
|
QRgba64 QColor::rgba64() const
|
||||||
|
{
|
||||||
|
if (cspec != Invalid && cspec != Rgb)
|
||||||
|
return toRgb().rgba64();
|
||||||
|
return qRgba64(ct.argb.red, ct.argb.green, ct.argb.blue, ct.argb.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Sets the RGB64 value to \a rgba, including its alpha.
|
||||||
|
|
||||||
|
\sa \setRgba(), rgba64()
|
||||||
|
*/
|
||||||
|
void QColor::setRgba64(QRgba64 rgba)
|
||||||
|
{
|
||||||
|
cspec = Rgb;
|
||||||
|
ct.argb.alpha = rgba.alpha();
|
||||||
|
ct.argb.red = rgba.red();
|
||||||
|
ct.argb.green = rgba.green();
|
||||||
|
ct.argb.blue = rgba.blue();
|
||||||
|
ct.argb.pad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QRgb QColor::rgb() const
|
\fn QRgb QColor::rgb() const
|
||||||
|
|
||||||
@ -1850,7 +1896,7 @@ QColor QColor::fromRgb(QRgb rgb)
|
|||||||
Unlike the fromRgb() function, the alpha-channel specified by the given
|
Unlike the fromRgb() function, the alpha-channel specified by the given
|
||||||
QRgb value is included.
|
QRgb value is included.
|
||||||
|
|
||||||
\sa fromRgb(), isValid()
|
\sa fromRgb(), fromRgba64(), isValid()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QColor QColor::fromRgba(QRgb rgba)
|
QColor QColor::fromRgba(QRgb rgba)
|
||||||
@ -1865,7 +1911,7 @@ QColor QColor::fromRgba(QRgb rgba)
|
|||||||
|
|
||||||
All the values must be in the range 0-255.
|
All the values must be in the range 0-255.
|
||||||
|
|
||||||
\sa toRgb(), fromRgbF(), isValid()
|
\sa toRgb(), fromRgba64(), fromRgbF(), isValid()
|
||||||
*/
|
*/
|
||||||
QColor QColor::fromRgb(int r, int g, int b, int a)
|
QColor QColor::fromRgb(int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
@ -1894,7 +1940,7 @@ QColor QColor::fromRgb(int r, int g, int b, int a)
|
|||||||
|
|
||||||
All the values must be in the range 0.0-1.0.
|
All the values must be in the range 0.0-1.0.
|
||||||
|
|
||||||
\sa fromRgb(), toRgb(), isValid()
|
\sa fromRgb(), fromRgba64(), toRgb(), isValid()
|
||||||
*/
|
*/
|
||||||
QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
|
QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
|
||||||
{
|
{
|
||||||
@ -1916,6 +1962,38 @@ QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Static convenience function that returns a QColor constructed from the RGBA64
|
||||||
|
color values, \a r (red), \a g (green), \a b (blue), and \a a
|
||||||
|
(alpha-channel, i.e. transparency).
|
||||||
|
|
||||||
|
\sa fromRgb(), fromRgbF(), toRgb(), isValid()
|
||||||
|
*/
|
||||||
|
QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a)
|
||||||
|
{
|
||||||
|
QColor color;
|
||||||
|
color.setRgba64(qRgba64(r, g, b, a));
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Static convenience function that returns a QColor constructed from the
|
||||||
|
given QRgba64 value \a rgba64.
|
||||||
|
|
||||||
|
\sa fromRgb(), fromRgbF(), toRgb(), isValid()
|
||||||
|
*/
|
||||||
|
QColor QColor::fromRgba64(QRgba64 rgba64)
|
||||||
|
{
|
||||||
|
QColor color;
|
||||||
|
color.setRgba64(rgba64);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Static convenience function that returns a QColor constructed from the HSV
|
Static convenience function that returns a QColor constructed from the HSV
|
||||||
color values, \a h (hue), \a s (saturation), \a v (value), and \a a
|
color values, \a h (hue), \a s (saturation), \a v (value), and \a a
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <QtGui/qrgb.h>
|
#include <QtGui/qrgb.h>
|
||||||
#include <QtCore/qnamespace.h>
|
#include <QtCore/qnamespace.h>
|
||||||
#include <QtCore/qstringlist.h>
|
#include <QtCore/qstringlist.h>
|
||||||
|
#include <QtGui/qrgba64.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ public:
|
|||||||
QColor(Qt::GlobalColor color);
|
QColor(Qt::GlobalColor color);
|
||||||
QColor(int r, int g, int b, int a = 255);
|
QColor(int r, int g, int b, int a = 255);
|
||||||
QColor(QRgb rgb);
|
QColor(QRgb rgb);
|
||||||
|
QColor(QRgba64 rgba64);
|
||||||
QColor(const QString& name);
|
QColor(const QString& name);
|
||||||
QColor(const char *name);
|
QColor(const char *name);
|
||||||
QColor(const QColor &color); // ### Qt 6: remove, the trivial one is fine.
|
QColor(const QColor &color); // ### Qt 6: remove, the trivial one is fine.
|
||||||
@ -109,6 +111,9 @@ public:
|
|||||||
QRgb rgba() const;
|
QRgb rgba() const;
|
||||||
void setRgba(QRgb rgba);
|
void setRgba(QRgb rgba);
|
||||||
|
|
||||||
|
QRgba64 rgba64() const;
|
||||||
|
void setRgba64(QRgba64 rgba);
|
||||||
|
|
||||||
QRgb rgb() const;
|
QRgb rgb() const;
|
||||||
void setRgb(QRgb rgb);
|
void setRgb(QRgb rgb);
|
||||||
|
|
||||||
@ -173,6 +178,9 @@ public:
|
|||||||
static QColor fromRgb(int r, int g, int b, int a = 255);
|
static QColor fromRgb(int r, int g, int b, int a = 255);
|
||||||
static QColor fromRgbF(qreal r, qreal g, qreal b, qreal a = 1.0);
|
static QColor fromRgbF(qreal r, qreal g, qreal b, qreal a = 1.0);
|
||||||
|
|
||||||
|
static QColor fromRgba64(ushort r, ushort g, ushort b, ushort a = USHRT_MAX);
|
||||||
|
static QColor fromRgba64(QRgba64 rgba);
|
||||||
|
|
||||||
static QColor fromHsv(int h, int s, int v, int a = 255);
|
static QColor fromHsv(int h, int s, int v, int a = 255);
|
||||||
static QColor fromHsvF(qreal h, qreal s, qreal v, qreal a = 1.0);
|
static QColor fromHsvF(qreal h, qreal s, qreal v, qreal a = 1.0);
|
||||||
|
|
||||||
|
186
src/gui/painting/qrgba64.h
Normal file
186
src/gui/painting/qrgba64.h
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL21$
|
||||||
|
** 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 http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://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 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** As a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QRGBA64_H
|
||||||
|
#define QRGBA64_H
|
||||||
|
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/qprocessordetection.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QRgba64 {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
quint16 red;
|
||||||
|
quint16 green;
|
||||||
|
quint16 blue;
|
||||||
|
quint16 alpha;
|
||||||
|
} c;
|
||||||
|
quint64 rgba;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// No constructors are allowed, since this needs to be usable in a union in no-c++11 mode.
|
||||||
|
// When c++11 is mandatory, we can add all but a copy constructor.
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
|
||||||
|
{
|
||||||
|
QRgba64 rgba64;
|
||||||
|
rgba64.c.red = red;
|
||||||
|
rgba64.c.green = green;
|
||||||
|
rgba64.c.blue = blue;
|
||||||
|
rgba64.c.alpha = alpha;
|
||||||
|
return rgba64;
|
||||||
|
}
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint64 c)
|
||||||
|
{
|
||||||
|
QRgba64 rgba64;
|
||||||
|
rgba64.rgba = c;
|
||||||
|
return rgba64;
|
||||||
|
}
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
|
||||||
|
{
|
||||||
|
QRgba64 rgb64 = fromRgba64(red, green, blue, alpha);
|
||||||
|
// Expand the range so that 0x00 maps to 0x0000 and 0xff maps to 0xffff.
|
||||||
|
rgb64.rgba |= rgb64.rgba << 8;
|
||||||
|
return rgb64;
|
||||||
|
}
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromArgb32(uint rgb)
|
||||||
|
{
|
||||||
|
return fromRgba(rgb >> 16, rgb >> 8, rgb, rgb >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_CONSTEXPR quint16 red() const { return c.red; }
|
||||||
|
Q_DECL_CONSTEXPR quint16 green() const { return c.green; }
|
||||||
|
Q_DECL_CONSTEXPR quint16 blue() const { return c.blue; }
|
||||||
|
Q_DECL_CONSTEXPR quint16 alpha() const { return c.alpha; }
|
||||||
|
void setRed(quint16 _red) { c.red = _red; }
|
||||||
|
void setGreen(quint16 _green) { c.green = _green; }
|
||||||
|
void setBlue(quint16 _blue) { c.blue = _blue; }
|
||||||
|
void setAlpha(quint16 _alpha) { c.alpha = _alpha; }
|
||||||
|
|
||||||
|
Q_DECL_CONSTEXPR quint8 red8() const { return div_257(c.red); }
|
||||||
|
Q_DECL_CONSTEXPR quint8 green8() const { return div_257(c.green); }
|
||||||
|
Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(c.blue); }
|
||||||
|
Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(c.alpha); }
|
||||||
|
Q_DECL_CONSTEXPR uint toArgb32() const
|
||||||
|
{
|
||||||
|
return (alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8();
|
||||||
|
}
|
||||||
|
Q_DECL_CONSTEXPR ushort toRgb16() const
|
||||||
|
{
|
||||||
|
return (c.red & 0xf800) | ((c.green >> 10) << 5) | (c.blue >> 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const
|
||||||
|
{
|
||||||
|
const quint32 a = c.alpha;
|
||||||
|
const quint16 r = div_65535(c.red * a);
|
||||||
|
const quint16 g = div_65535(c.green * a);
|
||||||
|
const quint16 b = div_65535(c.blue * a);
|
||||||
|
return fromRgba64(r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied() const
|
||||||
|
{
|
||||||
|
#if Q_PROCESSOR_WORDSIZE < 8
|
||||||
|
return unpremultiplied_32bit();
|
||||||
|
#else
|
||||||
|
return unpremultiplied_64bit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_CONSTEXPR operator quint64() const
|
||||||
|
{
|
||||||
|
return rgba;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Q_DECL_CONSTEXPR uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
|
||||||
|
static Q_DECL_CONSTEXPR uint div_257(uint x) { return div_257_floor(x + 128); }
|
||||||
|
static Q_DECL_CONSTEXPR uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_32bit() const
|
||||||
|
{
|
||||||
|
if (c.alpha == 0xffff || c.alpha == 0)
|
||||||
|
return *this;
|
||||||
|
const quint16 r = (quint32(c.red) * 0xffff + c.alpha/2) / c.alpha;
|
||||||
|
const quint16 g = (quint32(c.green) * 0xffff + c.alpha/2) / c.alpha;
|
||||||
|
const quint16 b = (quint32(c.blue) * 0xffff + c.alpha/2) / c.alpha;
|
||||||
|
return fromRgba64(r, g, b, c.alpha);
|
||||||
|
}
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_64bit() const
|
||||||
|
{
|
||||||
|
if (c.alpha == 0xffff || c.alpha == 0)
|
||||||
|
return *this;
|
||||||
|
const quint64 fa = (Q_UINT64_C(0xffff00008000) + c.alpha/2) / c.alpha;
|
||||||
|
const quint16 r = (c.red * fa + 0x80000000) >> 32;
|
||||||
|
const quint16 g = (c.green * fa + 0x80000000) >> 32;
|
||||||
|
const quint16 b = (c.blue * fa + 0x80000000) >> 32;
|
||||||
|
return fromRgba64(r, g, b, c.alpha);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
|
||||||
|
{
|
||||||
|
return QRgba64::fromRgba64(r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qRgba64(quint64 c)
|
||||||
|
{
|
||||||
|
return QRgba64::fromRgba64(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qPremultiply(QRgba64 c)
|
||||||
|
{
|
||||||
|
return c.premultiplied();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECL_RELAXED_CONSTEXPR inline QRgba64 qUnpremultiply(QRgba64 c)
|
||||||
|
{
|
||||||
|
return c.unpremultiplied();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Q_DECL_CONSTEXPR uint qRed(QRgba64 rgb)
|
||||||
|
{ return rgb.red8(); }
|
||||||
|
|
||||||
|
inline Q_DECL_CONSTEXPR uint qGreen(QRgba64 rgb)
|
||||||
|
{ return rgb.green8(); }
|
||||||
|
|
||||||
|
inline Q_DECL_CONSTEXPR uint qBlue(QRgba64 rgb)
|
||||||
|
{ return rgb.blue8(); }
|
||||||
|
|
||||||
|
inline Q_DECL_CONSTEXPR uint qAlpha(QRgba64 rgb)
|
||||||
|
{ return rgb.alpha8(); }
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QRGBA64_H
|
241
src/gui/painting/qrgba64.qdoc
Normal file
241
src/gui/painting/qrgba64.qdoc
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the documentation of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:FDL$
|
||||||
|
** 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 http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Free Documentation License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Free
|
||||||
|
** Documentation License version 1.3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file included in the packaging of
|
||||||
|
** this file. Please review the following information to ensure
|
||||||
|
** the GNU Free Documentation License version 1.3 requirements
|
||||||
|
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QRgba64
|
||||||
|
\brief The QRgba64 struct contains a 64-bit RGB color.
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
\ingroup painting
|
||||||
|
\inmodule QtGui
|
||||||
|
|
||||||
|
QRgba64 is a 64-bit data-structure containing four 16-bit color channels: Red, green, blue and alpha.
|
||||||
|
|
||||||
|
QRgba64 can be used a replacement for QRgb when higher precision is needed. In particular a
|
||||||
|
premultiplied QRgba64 can operate on unpremultipled QRgb without loss of precision except
|
||||||
|
for alpha 0.
|
||||||
|
|
||||||
|
\sa QRgb, QColor
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn static QRgba64 QRgba64::fromRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
|
||||||
|
|
||||||
|
Returns the QRgba64 quadruplet (\a{r}, \a{g}, \a{b}, \a{a}).
|
||||||
|
|
||||||
|
\sa fromRgba()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn static QRgba64 QRgba64::fromRgba64(quint64 c)
|
||||||
|
|
||||||
|
Returns \a c as a QRgba64 struct.
|
||||||
|
|
||||||
|
\sa fromArgb32()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn static QRgba64 QRgba64::fromRgba(quint8 red, quint8 green, quint8 blue, quint8 alpha)
|
||||||
|
|
||||||
|
Constructs a QRgba64 value from the four 8-bit color channels \a red, \a green, \a blue and \a alpha.
|
||||||
|
|
||||||
|
\sa fromArgb32()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn static QRgba64 QRgba64::fromArgb32(uint rgb)
|
||||||
|
|
||||||
|
Constructs a QRgba64 value from the 32bit ARGB value \a rgb.
|
||||||
|
|
||||||
|
\sa fromRgba()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint16 QRgba64::red() const
|
||||||
|
|
||||||
|
Returns the 16-bit red color component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint16 QRgba64::green() const
|
||||||
|
|
||||||
|
Returns the 16-bit green color component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint16 QRgba64::blue() const
|
||||||
|
|
||||||
|
Returns the 16-bit blue color component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint16 QRgba64::alpha() const
|
||||||
|
|
||||||
|
Returns the 16-bit alpha channel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint8 QRgba64::red8() const
|
||||||
|
|
||||||
|
Returns the red color component as an 8-bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint8 QRgba64::green8() const
|
||||||
|
|
||||||
|
Returns the green color component as an 8-bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint8 QRgba64::blue8() const
|
||||||
|
|
||||||
|
Returns the blue color component as an 8-bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn quint8 QRgba64::alpha8() const
|
||||||
|
|
||||||
|
Returns the alpha channel as an 8-bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn uint QRgba64::toArgb32() const
|
||||||
|
|
||||||
|
Returns the color as a 32-bit ARGB value.
|
||||||
|
|
||||||
|
\sa fromArgb32()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn ushort QRgba64::toRgb16() const
|
||||||
|
|
||||||
|
Returns the color as a 16-bit RGB value.
|
||||||
|
|
||||||
|
\sa toArgb32()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 QRgba64::premultiplied() const
|
||||||
|
|
||||||
|
Returns the color with the alpha premultiplied.
|
||||||
|
|
||||||
|
\sa unpremultiplied()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 QRgba64::unpremultiplied() const
|
||||||
|
|
||||||
|
Returns the color with the alpha unpremultiplied.
|
||||||
|
|
||||||
|
\sa premultiplied()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64::operator quint64() const
|
||||||
|
|
||||||
|
Returns the color as a 64bit unsigned integer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 qRgba64(quint16 r, quint16 g, quint16 b, quint16 a)
|
||||||
|
\relates QColor
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Returns the QRgba64 quadruplet (\a{r}, \a{g}, \a{b}, \a{a}).
|
||||||
|
|
||||||
|
\sa qRgba()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 qRgba64(quint64 c)
|
||||||
|
\relates QColor
|
||||||
|
\since 5.6
|
||||||
|
|
||||||
|
Returns \a c as a QRgba64 struct.
|
||||||
|
|
||||||
|
\sa qRgba()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 qPremultiply(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Converts an unpremultiplied QRgba64 quadruplet \a rgba64 into a premultiplied QRgba64 quadruplet.
|
||||||
|
|
||||||
|
\sa QRgba64::premultiplied(), qUnpremultiply()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QRgba64 qUnpremultiply(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Converts a premultiplied QRgba64 quadruplet \a rgba64 into an unpremultiplied QRgba64 quadruplet.
|
||||||
|
|
||||||
|
\sa QRgba64::unpremultiplied(), qPremultiply()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn uint qRed(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Returns the red component of \a rgba64 as an 8-bit value.
|
||||||
|
|
||||||
|
\sa QRgba64::red8(), QColor::red()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn uint qGreen(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Returns the green component of \a rgba64 as an 8-bit value.
|
||||||
|
|
||||||
|
\sa QRgba64::green8(), QColor::green()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn uint qBlue(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Returns the blue component of \a rgba64 as an 8-bit value.
|
||||||
|
|
||||||
|
\sa QRgba64::blue8(), QColor::blue()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn uint qAlpha(QRgba64 rgba64)
|
||||||
|
\since 5.6
|
||||||
|
\relates QColor
|
||||||
|
|
||||||
|
Returns the alpha component of \a rgba64 as an 8-bit value.
|
||||||
|
|
||||||
|
\sa QRgba64::alpha8(), QColor::alpha()
|
||||||
|
*/
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include <qcolor.h>
|
#include <qcolor.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
#include <qrgba64.h>
|
||||||
#include <private/qdrawingprimitive_sse2_p.h>
|
#include <private/qdrawingprimitive_sse2_p.h>
|
||||||
|
|
||||||
class tst_QColor : public QObject
|
class tst_QColor : public QObject
|
||||||
@ -105,6 +106,9 @@ private slots:
|
|||||||
|
|
||||||
void premultiply();
|
void premultiply();
|
||||||
void unpremultiply_sse4();
|
void unpremultiply_sse4();
|
||||||
|
void qrgba64();
|
||||||
|
void qrgba64Premultiply();
|
||||||
|
void qrgba64Equivalence();
|
||||||
|
|
||||||
#ifdef Q_DEAD_CODE_FROM_QT4_X11
|
#ifdef Q_DEAD_CODE_FROM_QT4_X11
|
||||||
void setallowX11ColorNames();
|
void setallowX11ColorNames();
|
||||||
@ -1455,7 +1459,7 @@ void tst_QColor::unpremultiply_sse4()
|
|||||||
for (uint a = 0; a < 256; a++) {
|
for (uint a = 0; a < 256; a++) {
|
||||||
for (uint c = 0; c <= a; c++) {
|
for (uint c = 0; c <= a; c++) {
|
||||||
QRgb p = qRgba(c, a-c, c, a);
|
QRgb p = qRgba(c, a-c, c, a);
|
||||||
QCOMPARE(qUnpremultiply(p), qUnpremultiply_sse4(p));
|
QCOMPARE(qUnpremultiply_sse4(p), qUnpremultiply(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1464,5 +1468,84 @@ void tst_QColor::unpremultiply_sse4()
|
|||||||
QSKIP("SSE4 not supported on this CPU.");
|
QSKIP("SSE4 not supported on this CPU.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QColor::qrgba64()
|
||||||
|
{
|
||||||
|
QRgba64 rgb64 = QRgba64::fromRgba(0x22, 0x33, 0x44, 0xff);
|
||||||
|
QCOMPARE(rgb64.red(), quint16(0x2222));
|
||||||
|
QCOMPARE(rgb64.green(), quint16(0x3333));
|
||||||
|
QCOMPARE(rgb64.blue(), quint16(0x4444));
|
||||||
|
QCOMPARE(rgb64.alpha(), quint16(0xffff));
|
||||||
|
|
||||||
|
QColor c(rgb64);
|
||||||
|
QCOMPARE(c.red(), 0x22);
|
||||||
|
QCOMPARE(c.green(), 0x33);
|
||||||
|
QCOMPARE(c.blue(), 0x44);
|
||||||
|
|
||||||
|
QCOMPARE(c.rgba64(), rgb64);
|
||||||
|
|
||||||
|
QColor c2 = QColor::fromRgb(0x22, 0x33, 0x44, 0xff);
|
||||||
|
QCOMPARE(c, c2);
|
||||||
|
QCOMPARE(c2.rgba64(), rgb64);
|
||||||
|
|
||||||
|
rgb64.setAlpha(0x8000);
|
||||||
|
rgb64.setGreen(0x8844);
|
||||||
|
rgb64 = rgb64.premultiplied();
|
||||||
|
QCOMPARE(rgb64.red(), quint16(0x1111));
|
||||||
|
QCOMPARE(rgb64.blue(), quint16(0x2222));
|
||||||
|
QCOMPARE(rgb64.green(), quint16(0x4422));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QColor::qrgba64Premultiply()
|
||||||
|
{
|
||||||
|
// Tests that qPremultiply(qUnpremultiply(rgba64)) returns rgba64.
|
||||||
|
for (uint a = 0; a < 0x10000; a+=7) {
|
||||||
|
const uint step = std::max(a/1024, 1u);
|
||||||
|
for (uint c = 0; c <= a; c+=step) {
|
||||||
|
QRgba64 p = qRgba64(c, a-c, a-c/2, a);
|
||||||
|
QRgba64 pp = qPremultiply(qUnpremultiply(p));
|
||||||
|
QCOMPARE(pp, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QColor::qrgba64Equivalence()
|
||||||
|
{
|
||||||
|
// Any ARGB32 converted back and forth.
|
||||||
|
for (uint a = 0; a < 256; a++) {
|
||||||
|
for (uint c = 0; c < 256; c++) {
|
||||||
|
QRgb p1 = qRgba(c, 255-c, 255-c, a);
|
||||||
|
QRgba64 p64 = QRgba64::fromArgb32(p1);
|
||||||
|
QCOMPARE(p64.toArgb32(), p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Any unpremultiplied ARGB32 value premultipled in RGB64 (except alpha 0).
|
||||||
|
for (uint a = 1; a < 256; a++) {
|
||||||
|
for (uint c = 0; c < 256; c++) {
|
||||||
|
QRgb p1 = qRgba(c, 255-c, 255-c, a);
|
||||||
|
QRgb pp1 = qPremultiply(p1);
|
||||||
|
QRgba64 pp64 = qPremultiply(QRgba64::fromArgb32(p1));
|
||||||
|
QRgb pp2 = pp64.toArgb32();
|
||||||
|
// 64bit premultiplied is more accurate than 32bit, so allow slight difference.
|
||||||
|
QCOMPARE(qAlpha(pp2), qAlpha(pp1));
|
||||||
|
QVERIFY(qAbs(qRed(pp2)-qRed(pp1)) <= 1);
|
||||||
|
QVERIFY(qAbs(qGreen(pp2)-qGreen(pp1)) <= 1);
|
||||||
|
QVERIFY(qAbs(qBlue(pp2)-qBlue(pp1)) <= 1);
|
||||||
|
// But verify the added accuracy means we can return to accurate unpremultiplied ARGB32.
|
||||||
|
QRgba64 pu64 = qUnpremultiply(pp64);
|
||||||
|
QRgb p2 = pu64.toArgb32();
|
||||||
|
QCOMPARE(p2, p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Any premultiplied ARGB32 value unpremultipled in RGB64.
|
||||||
|
for (uint a = 0; a < 256; a++) {
|
||||||
|
for (uint c = 0; c <= a; c++) {
|
||||||
|
QRgb pp = qRgba(c, a-c, a-c, a);
|
||||||
|
QRgb pu = qUnpremultiply(pp);
|
||||||
|
QRgba64 pu64 = qUnpremultiply(QRgba64::fromArgb32(pp));
|
||||||
|
QCOMPARE(pu64.toArgb32(), pu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QColor)
|
QTEST_MAIN(tst_QColor)
|
||||||
#include "tst_qcolor.moc"
|
#include "tst_qcolor.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user