summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qcolor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qcolor.cpp')
-rw-r--r--src/gui/painting/qcolor.cpp438
1 files changed, 301 insertions, 137 deletions
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 07202f5b1c..8780cce223 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -39,6 +39,7 @@
#include "qcolor.h"
#include "qcolor_p.h"
+#include "qfloat16.h"
#include "qnamespace.h"
#include "qdatastream.h"
#include "qvariant.h"
@@ -146,6 +147,7 @@ static bool get_hex_rgb(const QChar *str, size_t len, QRgba64 *rgb)
#endif
#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
+// keep this is in sync with QColorConstants
static const struct RGBData {
const char name[21];
uint value;
@@ -474,25 +476,43 @@ static QStringList get_colornames()
\section1 Predefined Colors
- There are 20 predefined QColors described by the Qt::GlobalColor enum,
- including black, white, primary and secondary colors, darker versions
- of these colors and three shades of gray. QColor also recognizes a
- variety of color names; the static colorNames() function returns a
- QStringList color names that QColor knows about.
+ There are 20 predefined QColor objects in the \c{QColorConstants}
+ namespace, including black, white, primary and secondary colors,
+ darker versions of these colors, and three shades of gray.
+ Furthermore, the \c{QColorConstants::Svg} namespace defines QColor
+ objects for the standard \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}.
\image qt-colors.png Qt Colors
- Additionally, the Qt::color0, Qt::color1 and Qt::transparent colors
- are used for special purposes.
+ The \c{QColorConstants::Color0}, \c{QColorConstants::Color1} and
+ \c{QColorConstants::Transparent} colors are used for special
+ purposes.
- Qt::color0 (zero pixel value) and Qt::color1 (non-zero pixel value)
- are special colors for drawing in QBitmaps. Painting with Qt::color0
- sets the bitmap bits to 0 (transparent; i.e., background), and painting
- with Qt::color1 sets the bits to 1 (opaque; i.e., foreground).
+ \c{QColorConstants::Color0} (zero pixel value) and
+ \c{QColorConstants::Color1} (non-zero pixel value) are special
+ colors for drawing in QBitmaps. Painting with
+ \c{QColorConstants::Color0} sets the bitmap bits to 0 (transparent;
+ i.e., background), and painting with c{QColorConstants::Color1}
+ sets the bits to 1 (opaque; i.e., foreground).
- Qt::transparent is used to indicate a transparent pixel. When painting
- with this value, a pixel value will be used that is appropriate for the
- underlying pixel format in use.
+ \c{QColorConstants::Transparent} is used to indicate a transparent
+ pixel. When painting with this value, a pixel value will be used
+ that is appropriate for the underlying pixel format in use.
+
+ For historical reasons, the 20 predefined colors are also available
+ in the Qt::GlobalColor enumeration.
+
+ Finally, QColor recognizes a variety of color names (as strings);
+ the static colorNames() function returns a QStringList color names
+ that QColor knows about.
+
+ \section1 The Extended RGB Color Model
+
+ The extended RGB color model, also known as the scRGB color space,
+ is the same the RGB color model except it allows values under 0.0,
+ and over 1.0. This makes it possible to represent colors that would
+ otherwise be outside the range of the RGB colorspace but still use
+ the same values for colors inside the RGB colorspace.
\section1 The HSV Color Model
@@ -577,7 +597,7 @@ static QStringList get_colornames()
alpha-channel to feature \l {QColor#Alpha-Blended
Drawing}{alpha-blended drawing}.
- \sa QPalette, QBrush
+ \sa QPalette, QBrush, QColorConstants
*/
#define QCOLOR_INT_RANGE_CHECK(fn, var) \
@@ -603,12 +623,13 @@ static QStringList get_colornames()
/*!
\enum QColor::Spec
- The type of color specified, either RGB, HSV, CMYK or HSL.
+ The type of color specified, either RGB, extended RGB, HSV, CMYK or HSL.
\value Rgb
\value Hsv
\value Cmyk
\value Hsl
+ \value ExtendedRgb
\value Invalid
\sa spec(), convertTo()
@@ -653,7 +674,7 @@ static QStringList get_colornames()
\sa isValid(), {QColor#Predefined Colors}{Predefined Colors}
*/
-QColor::QColor(Qt::GlobalColor color) Q_DECL_NOTHROW
+QColor::QColor(Qt::GlobalColor color) noexcept
{
#define QRGB(r, g, b) \
QRgb(((0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)))
@@ -728,7 +749,7 @@ QColor::QColor(Qt::GlobalColor color) Q_DECL_NOTHROW
\sa fromRgb(), isValid()
*/
-QColor::QColor(QRgb color) Q_DECL_NOTHROW
+QColor::QColor(QRgb color) noexcept
{
cspec = Rgb;
ct.argb.alpha = 0xffff;
@@ -746,7 +767,7 @@ QColor::QColor(QRgb color) Q_DECL_NOTHROW
\sa fromRgba64()
*/
-QColor::QColor(QRgba64 rgba64) Q_DECL_NOTHROW
+QColor::QColor(QRgba64 rgba64) noexcept
{
setRgba64(rgba64);
}
@@ -760,7 +781,7 @@ QColor::QColor(QRgba64 rgba64) Q_DECL_NOTHROW
becomes a valid color by accident.
*/
-QColor::QColor(Spec spec) Q_DECL_NOTHROW
+QColor::QColor(Spec spec) noexcept
{
switch (spec) {
case Invalid:
@@ -778,6 +799,10 @@ QColor::QColor(Spec spec) Q_DECL_NOTHROW
case Hsl:
setHsl(0, 0, 0, 0);
break;
+ case ExtendedRgb:
+ cspec = spec;
+ setRgbF(0, 0, 0, 0);
+ break;
}
}
@@ -872,7 +897,8 @@ QString QColor::name(NameFormat format) const
\li #AARRGGBB (Since 5.2)
\li #RRRGGGBBB
\li #RRRRGGGGBBBB
- \li A name from the list of colors defined in the list of \l{http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG color keyword names}
+ \li A name from the list of colors defined in the list of
+ \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}
provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
These color names work on all platforms. Note that these color names are \e not the
same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
@@ -933,7 +959,7 @@ bool QColor::isValidColor(const QString &name)
\overload
\since 5.10
*/
-bool QColor::isValidColor(QStringView name) Q_DECL_NOTHROW
+bool QColor::isValidColor(QStringView name) noexcept
{
return name.size() && QColor().setColorFromString(name);
}
@@ -942,7 +968,7 @@ bool QColor::isValidColor(QStringView name) Q_DECL_NOTHROW
\overload
\since 5.8
*/
-bool QColor::isValidColor(QLatin1String name) Q_DECL_NOTHROW
+bool QColor::isValidColor(QLatin1String name) noexcept
{
return name.size() && QColor().setColorFromString(name);
}
@@ -1211,6 +1237,17 @@ void QColor::setHsl(int h, int s, int l, int a)
ct.ahsl.pad = 0;
}
+static inline qfloat16 &castF16(quint16 &v)
+{
+ // this works because qfloat16 internally is a quint16
+ return *reinterpret_cast<qfloat16 *>(&v);
+}
+
+static inline const qfloat16 &castF16(const quint16 &v)
+{
+ return *reinterpret_cast<const qfloat16 *>(&v);
+}
+
/*!
Sets the contents pointed to by \a r, \a g, \a b, and \a a, to the red,
green, blue, and alpha-channel (transparency) components of the color's
@@ -1226,18 +1263,27 @@ void QColor::getRgbF(qreal *r, qreal *g, qreal *b, qreal *a) const
if (!r || !g || !b)
return;
- if (cspec != Invalid && cspec != Rgb) {
+ if (cspec == Invalid)
+ return;
+
+ if (cspec != Rgb && cspec != ExtendedRgb) {
toRgb().getRgbF(r, g, b, a);
return;
}
- *r = ct.argb.red / qreal(USHRT_MAX);
- *g = ct.argb.green / qreal(USHRT_MAX);
- *b = ct.argb.blue / qreal(USHRT_MAX);
-
- if (a)
- *a = ct.argb.alpha / qreal(USHRT_MAX);
-
+ if (cspec == Rgb) {
+ *r = ct.argb.red / qreal(USHRT_MAX);
+ *g = ct.argb.green / qreal(USHRT_MAX);
+ *b = ct.argb.blue / qreal(USHRT_MAX);
+ if (a)
+ *a = ct.argb.alpha / qreal(USHRT_MAX);
+ } else {
+ *r = castF16(ct.argbExtended.redF16);
+ *g = castF16(ct.argbExtended.greenF16);
+ *b = castF16(ct.argbExtended.blueF16);
+ if (a)
+ *a = castF16(ct.argbExtended.alphaF16);
+ }
}
/*!
@@ -1274,26 +1320,35 @@ void QColor::getRgb(int *r, int *g, int *b, int *a) const
Sets the color channels of this color to \a r (red), \a g (green),
\a b (blue) and \a a (alpha, transparency).
- All values must be in the range 0.0-1.0.
+ The alpha value must be in the range 0.0-1.0.
+ If any of the other values are outside the range of 0.0-1.0 the
+ color model will be set as \c ExtendedRgb.
\sa rgb(), getRgbF(), setRgb()
*/
void QColor::setRgbF(qreal r, qreal g, qreal b, qreal a)
{
- if (r < qreal(0.0) || r > qreal(1.0)
- || g < qreal(0.0) || g > qreal(1.0)
- || b < qreal(0.0) || b > qreal(1.0)
- || a < qreal(0.0) || a > qreal(1.0)) {
- qWarning("QColor::setRgbF: RGB parameters out of range");
+ if (a < qreal(0.0) || a > qreal(1.0)) {
+ qWarning("QColor::setRgbF: Alpha parameter is out of range");
invalidate();
return;
}
-
+ if (r < qreal(0.0) || r > qreal(1.0) ||
+ g < qreal(0.0) || g > qreal(1.0) ||
+ b < qreal(0.0) || b > qreal(1.0) || cspec == ExtendedRgb) {
+ cspec = ExtendedRgb;
+ castF16(ct.argbExtended.redF16) = qfloat16(r);
+ castF16(ct.argbExtended.greenF16) = qfloat16(g);
+ castF16(ct.argbExtended.blueF16) = qfloat16(b);
+ castF16(ct.argbExtended.alphaF16) = qfloat16(a);
+ ct.argbExtended.pad = 0;
+ return;
+ }
cspec = Rgb;
- ct.argb.alpha = qRound(a * USHRT_MAX);
ct.argb.red = qRound(r * USHRT_MAX);
ct.argb.green = qRound(g * USHRT_MAX);
ct.argb.blue = qRound(b * USHRT_MAX);
+ ct.argb.alpha = qRound(a * USHRT_MAX);
ct.argb.pad = 0;
}
@@ -1306,7 +1361,7 @@ void QColor::setRgbF(qreal r, qreal g, qreal b, qreal a)
*/
void QColor::setRgb(int r, int g, int b, int a)
{
- if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255 || (uint)a > 255) {
+ if (!isRgbaValid(r, g, b, a)) {
qWarning("QColor::setRgb: RGB parameters out of range");
invalidate();
return;
@@ -1330,7 +1385,7 @@ void QColor::setRgb(int r, int g, int b, int a)
\sa setRgba(), rgb(), rgba64()
*/
-QRgb QColor::rgba() const Q_DECL_NOTHROW
+QRgb QColor::rgba() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().rgba();
@@ -1342,7 +1397,7 @@ QRgb QColor::rgba() const Q_DECL_NOTHROW
\sa rgba(), rgb(), setRgba64()
*/
-void QColor::setRgba(QRgb rgba) Q_DECL_NOTHROW
+void QColor::setRgba(QRgb rgba) noexcept
{
cspec = Rgb;
ct.argb.alpha = qAlpha(rgba) * 0x101;
@@ -1362,7 +1417,7 @@ void QColor::setRgba(QRgb rgba) Q_DECL_NOTHROW
\sa setRgba64(), rgba(), rgb()
*/
-QRgba64 QColor::rgba64() const Q_DECL_NOTHROW
+QRgba64 QColor::rgba64() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().rgba64();
@@ -1376,7 +1431,7 @@ QRgba64 QColor::rgba64() const Q_DECL_NOTHROW
\sa setRgba(), rgba64()
*/
-void QColor::setRgba64(QRgba64 rgba) Q_DECL_NOTHROW
+void QColor::setRgba64(QRgba64 rgba) noexcept
{
cspec = Rgb;
ct.argb.alpha = rgba.alpha();
@@ -1393,7 +1448,7 @@ void QColor::setRgba64(QRgba64 rgba) Q_DECL_NOTHROW
\sa getRgb(), rgba()
*/
-QRgb QColor::rgb() const Q_DECL_NOTHROW
+QRgb QColor::rgb() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().rgb();
@@ -1405,7 +1460,7 @@ QRgb QColor::rgb() const Q_DECL_NOTHROW
Sets the RGB value to \a rgb. The alpha value is set to opaque.
*/
-void QColor::setRgb(QRgb rgb) Q_DECL_NOTHROW
+void QColor::setRgb(QRgb rgb) noexcept
{
cspec = Rgb;
ct.argb.alpha = 0xffff;
@@ -1420,8 +1475,12 @@ void QColor::setRgb(QRgb rgb) Q_DECL_NOTHROW
\sa setAlpha(), alphaF(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
*/
-int QColor::alpha() const Q_DECL_NOTHROW
-{ return ct.argb.alpha >> 8; }
+int QColor::alpha() const noexcept
+{
+ if (cspec == ExtendedRgb)
+ return qRound(qreal(castF16(ct.argbExtended.alphaF16)) * 255);
+ return ct.argb.alpha >> 8;
+}
/*!
@@ -1434,6 +1493,11 @@ int QColor::alpha() const Q_DECL_NOTHROW
void QColor::setAlpha(int alpha)
{
QCOLOR_INT_RANGE_CHECK("QColor::setAlpha", alpha);
+ if (cspec == ExtendedRgb) {
+ constexpr qreal f = qreal(1.0) / 255;
+ castF16(ct.argbExtended.alphaF16) = alpha * f;
+ return;
+ }
ct.argb.alpha = alpha * 0x101;
}
@@ -1442,8 +1506,12 @@ void QColor::setAlpha(int alpha)
\sa setAlphaF(), alpha(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
*/
-qreal QColor::alphaF() const Q_DECL_NOTHROW
-{ return ct.argb.alpha / qreal(USHRT_MAX); }
+qreal QColor::alphaF() const noexcept
+{
+ if (cspec == ExtendedRgb)
+ return castF16(ct.argbExtended.alphaF16);
+ return ct.argb.alpha / qreal(USHRT_MAX);
+}
/*!
Sets the alpha of this color to \a alpha. qreal alpha is specified in the
@@ -1455,6 +1523,10 @@ qreal QColor::alphaF() const Q_DECL_NOTHROW
void QColor::setAlphaF(qreal alpha)
{
QCOLOR_REAL_RANGE_CHECK("QColor::setAlphaF", alpha);
+ if (cspec == ExtendedRgb) {
+ castF16(ct.argbExtended.alphaF16) = alpha;
+ return;
+ }
qreal tmp = alpha * USHRT_MAX;
ct.argb.alpha = qRound(tmp);
}
@@ -1465,7 +1537,7 @@ void QColor::setAlphaF(qreal alpha)
\sa setRed(), redF(), getRgb()
*/
-int QColor::red() const Q_DECL_NOTHROW
+int QColor::red() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().red();
@@ -1492,7 +1564,7 @@ void QColor::setRed(int red)
\sa setGreen(), greenF(), getRgb()
*/
-int QColor::green() const Q_DECL_NOTHROW
+int QColor::green() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().green();
@@ -1520,7 +1592,7 @@ void QColor::setGreen(int green)
\sa setBlue(), blueF(), getRgb()
*/
-int QColor::blue() const Q_DECL_NOTHROW
+int QColor::blue() const noexcept
{
if (cspec != Invalid && cspec != Rgb)
return toRgb().blue();
@@ -1548,27 +1620,31 @@ void QColor::setBlue(int blue)
\sa setRedF(), red(), getRgbF()
*/
-qreal QColor::redF() const Q_DECL_NOTHROW
+qreal QColor::redF() const noexcept
{
- if (cspec != Invalid && cspec != Rgb)
- return toRgb().redF();
- return ct.argb.red / qreal(USHRT_MAX);
+ if (cspec == Rgb || cspec == Invalid)
+ return ct.argb.red / qreal(USHRT_MAX);
+ if (cspec == ExtendedRgb)
+ return castF16(ct.argbExtended.redF16);
+
+ return toRgb().redF();
}
/*!
- Sets the red color component of this color to \a red. Float components
- are specified in the range 0.0-1.0.
+ Sets the red color component of this color to \a red. If \a red lies outside
+ the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
\sa redF(), red(), setRgbF()
*/
void QColor::setRedF(qreal red)
{
- QCOLOR_REAL_RANGE_CHECK("QColor::setRedF", red);
- if (cspec != Rgb)
- setRgbF(red, greenF(), blueF(), alphaF());
- else
+ if (cspec == Rgb && red >= qreal(0.0) && red <= qreal(1.0))
ct.argb.red = qRound(red * USHRT_MAX);
+ else if (cspec == ExtendedRgb)
+ castF16(ct.argbExtended.redF16) = red;
+ else
+ setRgbF(red, greenF(), blueF(), alphaF());
}
/*!
@@ -1576,27 +1652,31 @@ void QColor::setRedF(qreal red)
\sa setGreenF(), green(), getRgbF()
*/
-qreal QColor::greenF() const Q_DECL_NOTHROW
+qreal QColor::greenF() const noexcept
{
- if (cspec != Invalid && cspec != Rgb)
- return toRgb().greenF();
- return ct.argb.green / qreal(USHRT_MAX);
+ if (cspec == Rgb || cspec == Invalid)
+ return ct.argb.green / qreal(USHRT_MAX);
+ if (cspec == ExtendedRgb)
+ return castF16(ct.argbExtended.greenF16);
+
+ return toRgb().greenF();
}
/*!
- Sets the green color component of this color to \a green. Float components
- are specified in the range 0.0-1.0.
+ Sets the green color component of this color to \a green. If \a green lies outside
+ the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
\sa greenF(), green(), setRgbF()
*/
void QColor::setGreenF(qreal green)
{
- QCOLOR_REAL_RANGE_CHECK("QColor::setGreenF", green);
- if (cspec != Rgb)
- setRgbF(redF(), green, blueF(), alphaF());
- else
+ if (cspec == Rgb && green >= qreal(0.0) && green <= qreal(1.0))
ct.argb.green = qRound(green * USHRT_MAX);
+ else if (cspec == ExtendedRgb)
+ castF16(ct.argbExtended.greenF16) = green;
+ else
+ setRgbF(redF(), green, blueF(), alphaF());
}
/*!
@@ -1604,26 +1684,29 @@ void QColor::setGreenF(qreal green)
\sa setBlueF(), blue(), getRgbF()
*/
-qreal QColor::blueF() const Q_DECL_NOTHROW
+qreal QColor::blueF() const noexcept
{
- if (cspec != Invalid && cspec != Rgb)
- return toRgb().blueF();
- return ct.argb.blue / qreal(USHRT_MAX);
+ if (cspec == Rgb || cspec == Invalid)
+ return ct.argb.blue / qreal(USHRT_MAX);
+ if (cspec == ExtendedRgb)
+ return castF16(ct.argbExtended.blueF16);
+
+ return toRgb().blueF();
}
/*!
- Sets the blue color component of this color to \a blue. Float components
- are specified in the range 0.0-1.0.
-
+ Sets the blue color component of this color to \a blue. If \a blue lies outside
+ the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
\sa blueF(), blue(), setRgbF()
*/
void QColor::setBlueF(qreal blue)
{
- QCOLOR_REAL_RANGE_CHECK("QColor::setBlueF", blue);
- if (cspec != Rgb)
- setRgbF(redF(), greenF(), blue, alphaF());
- else
+ if (cspec == Rgb && blue >= qreal(0.0) && blue <= qreal(1.0))
ct.argb.blue = qRound(blue * USHRT_MAX);
+ else if (cspec == ExtendedRgb)
+ castF16(ct.argbExtended.blueF16) = blue;
+ else
+ setRgbF(redF(), greenF(), blue, alphaF());
}
/*!
@@ -1634,7 +1717,7 @@ void QColor::setBlueF(qreal blue)
\sa hsvHue(), hslHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-int QColor::hue() const Q_DECL_NOTHROW
+int QColor::hue() const noexcept
{
return hsvHue();
}
@@ -1644,7 +1727,7 @@ int QColor::hue() const Q_DECL_NOTHROW
\sa hueF(), hslHue(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-int QColor::hsvHue() const Q_DECL_NOTHROW
+int QColor::hsvHue() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().hue();
@@ -1660,7 +1743,7 @@ int QColor::hsvHue() const Q_DECL_NOTHROW
Model}
*/
-int QColor::saturation() const Q_DECL_NOTHROW
+int QColor::saturation() const noexcept
{
return hsvSaturation();
}
@@ -1670,7 +1753,7 @@ int QColor::saturation() const Q_DECL_NOTHROW
\sa saturationF(), hslSaturation(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-int QColor::hsvSaturation() const Q_DECL_NOTHROW
+int QColor::hsvSaturation() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().saturation();
@@ -1682,7 +1765,7 @@ int QColor::hsvSaturation() const Q_DECL_NOTHROW
\sa valueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-int QColor::value() const Q_DECL_NOTHROW
+int QColor::value() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().value();
@@ -1696,7 +1779,7 @@ int QColor::value() const Q_DECL_NOTHROW
\sa hsvHueF(), hslHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-qreal QColor::hueF() const Q_DECL_NOTHROW
+qreal QColor::hueF() const noexcept
{
return hsvHueF();
}
@@ -1707,7 +1790,7 @@ qreal QColor::hueF() const Q_DECL_NOTHROW
\sa hue(), hslHueF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
Model}
*/
-qreal QColor::hsvHueF() const Q_DECL_NOTHROW
+qreal QColor::hsvHueF() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().hueF();
@@ -1722,7 +1805,7 @@ qreal QColor::hsvHueF() const Q_DECL_NOTHROW
\sa hsvSaturationF(), hslSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
Model}
*/
-qreal QColor::saturationF() const Q_DECL_NOTHROW
+qreal QColor::saturationF() const noexcept
{
return hsvSaturationF();
}
@@ -1732,7 +1815,7 @@ qreal QColor::saturationF() const Q_DECL_NOTHROW
\sa saturation(), hslSaturationF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-qreal QColor::hsvSaturationF() const Q_DECL_NOTHROW
+qreal QColor::hsvSaturationF() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().saturationF();
@@ -1744,7 +1827,7 @@ qreal QColor::hsvSaturationF() const Q_DECL_NOTHROW
\sa value(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-qreal QColor::valueF() const Q_DECL_NOTHROW
+qreal QColor::valueF() const noexcept
{
if (cspec != Invalid && cspec != Hsv)
return toHsv().valueF();
@@ -1758,7 +1841,7 @@ qreal QColor::valueF() const Q_DECL_NOTHROW
\sa hslHueF(), hsvHue(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
-int QColor::hslHue() const Q_DECL_NOTHROW
+int QColor::hslHue() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().hslHue();
@@ -1772,7 +1855,7 @@ int QColor::hslHue() const Q_DECL_NOTHROW
\sa hslSaturationF(), hsvSaturation(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
-int QColor::hslSaturation() const Q_DECL_NOTHROW
+int QColor::hslSaturation() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().hslSaturation();
@@ -1786,7 +1869,7 @@ int QColor::hslSaturation() const Q_DECL_NOTHROW
\sa lightnessF(), getHsl()
*/
-int QColor::lightness() const Q_DECL_NOTHROW
+int QColor::lightness() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().lightness();
@@ -1800,7 +1883,7 @@ int QColor::lightness() const Q_DECL_NOTHROW
\sa hslHue(), hsvHueF(), getHslF()
*/
-qreal QColor::hslHueF() const Q_DECL_NOTHROW
+qreal QColor::hslHueF() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().hslHueF();
@@ -1814,7 +1897,7 @@ qreal QColor::hslHueF() const Q_DECL_NOTHROW
\sa hslSaturation(), hsvSaturationF(), getHslF(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
-qreal QColor::hslSaturationF() const Q_DECL_NOTHROW
+qreal QColor::hslSaturationF() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().hslSaturationF();
@@ -1828,7 +1911,7 @@ qreal QColor::hslSaturationF() const Q_DECL_NOTHROW
\sa value(), getHslF()
*/
-qreal QColor::lightnessF() const Q_DECL_NOTHROW
+qreal QColor::lightnessF() const noexcept
{
if (cspec != Invalid && cspec != Hsl)
return toHsl().lightnessF();
@@ -1840,7 +1923,7 @@ qreal QColor::lightnessF() const Q_DECL_NOTHROW
\sa cyanF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-int QColor::cyan() const Q_DECL_NOTHROW
+int QColor::cyan() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().cyan();
@@ -1852,7 +1935,7 @@ int QColor::cyan() const Q_DECL_NOTHROW
\sa magentaF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-int QColor::magenta() const Q_DECL_NOTHROW
+int QColor::magenta() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().magenta();
@@ -1864,7 +1947,7 @@ int QColor::magenta() const Q_DECL_NOTHROW
\sa yellowF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-int QColor::yellow() const Q_DECL_NOTHROW
+int QColor::yellow() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().yellow();
@@ -1877,7 +1960,7 @@ int QColor::yellow() const Q_DECL_NOTHROW
\sa blackF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-int QColor::black() const Q_DECL_NOTHROW
+int QColor::black() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().black();
@@ -1889,7 +1972,7 @@ int QColor::black() const Q_DECL_NOTHROW
\sa cyan(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-qreal QColor::cyanF() const Q_DECL_NOTHROW
+qreal QColor::cyanF() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().cyanF();
@@ -1901,7 +1984,7 @@ qreal QColor::cyanF() const Q_DECL_NOTHROW
\sa magenta(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-qreal QColor::magentaF() const Q_DECL_NOTHROW
+qreal QColor::magentaF() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().magentaF();
@@ -1913,7 +1996,7 @@ qreal QColor::magentaF() const Q_DECL_NOTHROW
\sa yellow(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-qreal QColor::yellowF() const Q_DECL_NOTHROW
+qreal QColor::yellowF() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().yellowF();
@@ -1925,7 +2008,7 @@ qreal QColor::yellowF() const Q_DECL_NOTHROW
\sa black(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-qreal QColor::blackF() const Q_DECL_NOTHROW
+qreal QColor::blackF() const noexcept
{
if (cspec != Invalid && cspec != Cmyk)
return toCmyk().blackF();
@@ -1933,18 +2016,43 @@ qreal QColor::blackF() const Q_DECL_NOTHROW
}
/*!
+ Create and returns an extended RGB QColor based on this color.
+ \since 5.14
+
+ \sa toRgb, convertTo()
+*/
+QColor QColor::toExtendedRgb() const noexcept
+{
+ if (!isValid() || cspec == ExtendedRgb)
+ return *this;
+ if (cspec != Rgb)
+ return toRgb().toExtendedRgb();
+
+ constexpr qreal f = qreal(1.0) / USHRT_MAX;
+ QColor color;
+ color.cspec = ExtendedRgb;
+ castF16(color.ct.argbExtended.alphaF16) = qfloat16(ct.argb.alpha * f);
+ castF16(color.ct.argbExtended.redF16) = qfloat16(ct.argb.red * f);
+ castF16(color.ct.argbExtended.greenF16) = qfloat16(ct.argb.green * f);
+ castF16(color.ct.argbExtended.blueF16) = qfloat16(ct.argb.blue * f);
+ color.ct.argbExtended.pad = 0;
+ return color;
+}
+
+/*!
Create and returns an RGB QColor based on this color.
\sa fromRgb(), convertTo(), isValid()
*/
-QColor QColor::toRgb() const Q_DECL_NOTHROW
+QColor QColor::toRgb() const noexcept
{
if (!isValid() || cspec == Rgb)
return *this;
QColor color;
color.cspec = Rgb;
- color.ct.argb.alpha = ct.argb.alpha;
+ if (cspec != ExtendedRgb)
+ color.ct.argb.alpha = ct.argb.alpha;
color.ct.argb.pad = 0;
switch (cspec) {
@@ -2066,6 +2174,12 @@ QColor QColor::toRgb() const Q_DECL_NOTHROW
color.ct.argb.blue = qRound((qreal(1.0) - (y * (qreal(1.0) - k) + k)) * USHRT_MAX);
break;
}
+ case ExtendedRgb:
+ color.ct.argb.alpha = qRound(USHRT_MAX * qreal(castF16(ct.argbExtended.alphaF16)));
+ color.ct.argb.red = qRound(USHRT_MAX * qBound(qreal(0.0), qreal(castF16(ct.argbExtended.redF16)), qreal(1.0)));
+ color.ct.argb.green = qRound(USHRT_MAX * qBound(qreal(0.0), qreal(castF16(ct.argbExtended.greenF16)), qreal(1.0)));
+ color.ct.argb.blue = qRound(USHRT_MAX * qBound(qreal(0.0), qreal(castF16(ct.argbExtended.blueF16)), qreal(1.0)));
+ break;
default:
break;
}
@@ -2083,7 +2197,7 @@ QColor QColor::toRgb() const Q_DECL_NOTHROW
\sa fromHsv(), convertTo(), isValid(), {QColor#The HSV Color Model}{The HSV Color Model}
*/
-QColor QColor::toHsv() const Q_DECL_NOTHROW
+QColor QColor::toHsv() const noexcept
{
if (!isValid() || cspec == Hsv)
return *this;
@@ -2134,7 +2248,7 @@ QColor QColor::toHsv() const Q_DECL_NOTHROW
\sa fromHsl(), convertTo(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
*/
-QColor QColor::toHsl() const Q_DECL_NOTHROW
+QColor QColor::toHsl() const noexcept
{
if (!isValid() || cspec == Hsl)
return *this;
@@ -2190,7 +2304,7 @@ QColor QColor::toHsl() const Q_DECL_NOTHROW
\sa fromCmyk(), convertTo(), isValid(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-QColor QColor::toCmyk() const Q_DECL_NOTHROW
+QColor QColor::toCmyk() const noexcept
{
if (!isValid() || cspec == Cmyk)
return *this;
@@ -2231,13 +2345,15 @@ QColor QColor::toCmyk() const Q_DECL_NOTHROW
return color;
}
-QColor QColor::convertTo(QColor::Spec colorSpec) const Q_DECL_NOTHROW
+QColor QColor::convertTo(QColor::Spec colorSpec) const noexcept
{
if (colorSpec == cspec)
return *this;
switch (colorSpec) {
case Rgb:
return toRgb();
+ case ExtendedRgb:
+ return toExtendedRgb();
case Hsv:
return toHsv();
case Cmyk:
@@ -2262,7 +2378,7 @@ QColor QColor::convertTo(QColor::Spec colorSpec) const Q_DECL_NOTHROW
\sa fromRgba(), fromRgbF(), toRgb(), isValid()
*/
-QColor QColor::fromRgb(QRgb rgb) Q_DECL_NOTHROW
+QColor QColor::fromRgb(QRgb rgb) noexcept
{
return fromRgb(qRed(rgb), qGreen(rgb), qBlue(rgb));
}
@@ -2278,7 +2394,7 @@ QColor QColor::fromRgb(QRgb rgb) Q_DECL_NOTHROW
\sa fromRgb(), fromRgba64(), isValid()
*/
-QColor QColor::fromRgba(QRgb rgba) Q_DECL_NOTHROW
+QColor QColor::fromRgba(QRgb rgba) noexcept
{
return fromRgb(qRed(rgba), qGreen(rgba), qBlue(rgba), qAlpha(rgba));
}
@@ -2294,10 +2410,7 @@ QColor QColor::fromRgba(QRgb rgba) Q_DECL_NOTHROW
*/
QColor QColor::fromRgb(int r, int g, int b, int a)
{
- if (r < 0 || r > 255
- || g < 0 || g > 255
- || b < 0 || b > 255
- || a < 0 || a > 255) {
+ if (!isRgbaValid(r, g, b, a)) {
qWarning("QColor::fromRgb: RGB parameters out of range");
return QColor();
}
@@ -2317,20 +2430,32 @@ QColor QColor::fromRgb(int r, int g, int b, int a)
color values, \a r (red), \a g (green), \a b (blue), and \a a
(alpha-channel, i.e. transparency).
- All the values must be in the range 0.0-1.0.
+ The alpha value must be in the range 0.0-1.0.
+ If any of the other values are outside the range of 0.0-1.0 the
+ color model will be set as \c ExtendedRgb.
\sa fromRgb(), fromRgba64(), toRgb(), isValid()
*/
QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
{
- if (r < qreal(0.0) || r > qreal(1.0)
- || g < qreal(0.0) || g > qreal(1.0)
- || b < qreal(0.0) || b > qreal(1.0)
- || a < qreal(0.0) || a > qreal(1.0)) {
- qWarning("QColor::fromRgbF: RGB parameters out of range");
+ if (a < qreal(0.0) || a > qreal(1.0)) {
+ qWarning("QColor::fromRgbF: Alpha parameter out of range");
return QColor();
}
+ if (r < qreal(0.0) || r > qreal(1.0)
+ || g < qreal(0.0) || g > qreal(1.0)
+ || b < qreal(0.0) || b > qreal(1.0)) {
+ QColor color;
+ color.cspec = ExtendedRgb;
+ castF16(color.ct.argbExtended.alphaF16) = qfloat16(a);
+ castF16(color.ct.argbExtended.redF16) = qfloat16(r);
+ castF16(color.ct.argbExtended.greenF16) = qfloat16(g);
+ castF16(color.ct.argbExtended.blueF16) = qfloat16(b);
+ color.ct.argbExtended.pad = 0;
+ return color;
+ }
+
QColor color;
color.cspec = Rgb;
color.ct.argb.alpha = qRound(a * USHRT_MAX);
@@ -2351,7 +2476,7 @@ QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
\sa fromRgb(), fromRgbF(), toRgb(), isValid()
*/
-QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a) Q_DECL_NOTHROW
+QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a) noexcept
{
QColor color;
color.setRgba64(qRgba64(r, g, b, a));
@@ -2366,7 +2491,7 @@ QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a) Q_DECL_NOTHROW
\sa fromRgb(), fromRgbF(), toRgb(), isValid()
*/
-QColor QColor::fromRgba64(QRgba64 rgba64) Q_DECL_NOTHROW
+QColor QColor::fromRgba64(QRgba64 rgba64) noexcept
{
QColor color;
color.setRgba64(rgba64);
@@ -2714,7 +2839,7 @@ QColor QColor::fromCmykF(qreal c, qreal m, qreal y, qreal k, qreal a)
\sa darker(), isValid()
*/
-QColor QColor::lighter(int factor) const Q_DECL_NOTHROW
+QColor QColor::lighter(int factor) const noexcept
{
if (factor <= 0) // invalid lightness factor
return *this;
@@ -2759,7 +2884,7 @@ QColor QColor::lighter(int factor) const Q_DECL_NOTHROW
\sa lighter(), isValid()
*/
-QColor QColor::darker(int factor) const Q_DECL_NOTHROW
+QColor QColor::darker(int factor) const noexcept
{
if (factor <= 0) // invalid darkness factor
return *this;
@@ -2779,7 +2904,7 @@ QColor QColor::darker(int factor) const Q_DECL_NOTHROW
Use lighter(\a factor) instead.
*/
-QColor QColor::light(int factor) const Q_DECL_NOTHROW
+QColor QColor::light(int factor) const noexcept
{
return lighter(factor);
}
@@ -2789,7 +2914,7 @@ QColor QColor::light(int factor) const Q_DECL_NOTHROW
Use darker(\a factor) instead.
*/
-QColor QColor::dark(int factor) const Q_DECL_NOTHROW
+QColor QColor::dark(int factor) const noexcept
{
return darker(factor);
}
@@ -2799,7 +2924,7 @@ QColor QColor::dark(int factor) const Q_DECL_NOTHROW
/*!
Assigns a copy of \a color to this color, and returns a reference to it.
*/
-QColor &QColor::operator=(const QColor &color) Q_DECL_NOTHROW
+QColor &QColor::operator=(const QColor &color) noexcept
{
cspec = color.cspec;
ct.argb = color.ct.argb;
@@ -2810,7 +2935,7 @@ QColor &QColor::operator=(const QColor &color) Q_DECL_NOTHROW
/*! \overload
Assigns a copy of \a color and returns a reference to this color.
*/
-QColor &QColor::operator=(Qt::GlobalColor color) Q_DECL_NOTHROW
+QColor &QColor::operator=(Qt::GlobalColor color) noexcept
{
return operator=(QColor(color));
}
@@ -2819,7 +2944,7 @@ QColor &QColor::operator=(Qt::GlobalColor color) Q_DECL_NOTHROW
Returns \c true if this color has the same RGB and alpha values as \a color;
otherwise returns \c false.
*/
-bool QColor::operator==(const QColor &color) const Q_DECL_NOTHROW
+bool QColor::operator==(const QColor &color) const noexcept
{
if (cspec == Hsl && cspec == color.cspec) {
return (ct.argb.alpha == color.ct.argb.alpha
@@ -2846,7 +2971,7 @@ bool QColor::operator==(const QColor &color) const Q_DECL_NOTHROW
Returns \c true if this color has a different RGB and alpha values from
\a color; otherwise returns \c false.
*/
-bool QColor::operator!=(const QColor &color) const Q_DECL_NOTHROW
+bool QColor::operator!=(const QColor &color) const noexcept
{ return !operator==(color); }
@@ -2863,7 +2988,7 @@ QColor::operator QVariant() const
Marks the color as invalid and sets all components to zero (alpha is set
to fully opaque for compatibility with Qt 3).
*/
-void QColor::invalidate() Q_DECL_NOTHROW
+void QColor::invalidate() noexcept
{
cspec = Invalid;
ct.argb.alpha = USHRT_MAX;
@@ -2885,6 +3010,8 @@ QDebug operator<<(QDebug dbg, const QColor &c)
dbg.nospace() << "QColor(Invalid)";
else if (c.spec() == QColor::Rgb)
dbg.nospace() << "QColor(ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ')';
+ else if (c.spec() == QColor::ExtendedRgb)
+ dbg.nospace() << "QColor(Ext. ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ')';
else if (c.spec() == QColor::Hsv)
dbg.nospace() << "QColor(AHSV " << c.alphaF() << ", " << c.hueF() << ", " << c.saturationF() << ", " << c.valueF() << ')';
else if (c.spec() == QColor::Cmyk)
@@ -3134,4 +3261,41 @@ const uint qt_inv_premul_factor[256] = {
\sa QColor::rgb(), QColor::rgba()
*/
+/*!
+ \namespace QColorConstants
+ \inmodule QtGui
+
+ \brief The QColorConstants namespace contains QColor predefined constants.
+
+ These constants are usable everywhere a QColor object is expected:
+
+ \code
+ painter.setBrush(QColorConstants::Svg::lightblue);
+ \endcode
+
+ Their usage is much cheaper than e.g. passing a string to QColor's constructor,
+ as they don't require any parsing of the string, and always result in a valid
+ QColor object:
+
+ \badcode
+ object.setColor(QColor("lightblue")); // expensive
+ \endcode
+
+ \section1 Qt Colors
+
+ The following colors are defined in the \c{QColorConstants} namespace:
+
+ \include qt-colors.qdocinc
+
+ \section1 SVG Colors
+
+ The following table lists the available
+ \l {http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG colors}.
+ They are available in the \c{QColorConstants::Svg} inner namespace.
+
+ \include svg-colors.qdocinc
+
+ \sa QColor, Qt::GlobalColor
+*/
+
QT_END_NAMESPACE