Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcolor.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qcolor.h"
6#include "qcolor_p.h"
8#include "qfloat16.h"
9#include "qnamespace.h"
10#include "qdatastream.h"
11#include "qvariant.h"
12#include "qdebug.h"
13#include "private/qtools_p.h"
14
15#include <algorithm>
16#include <optional>
17
18#include <stdio.h>
19#include <limits.h>
20
22
23// QColor fits into QVariant's internal storage on 64bit systems.
24// It could also fit on 32bit systems, but we cannot make it happen in Qt6, due to BC.
25#if QT_VERSION >= QT_VERSION_CHECK(7,0,0) || QT_POINTER_SIZE > 4
26static_assert(sizeof(QColor) <= QVariant::Private::MaxInternalSize);
27#endif
28
29/*!
30 \internal
31 If s[0..n] is a valid hex number, returns its integer value,
32 otherwise returns -1.
33 */
34static inline int hex2int(const char *s, int n)
35{
36 if (n < 0)
37 return -1;
38 int result = 0;
39 for (; n > 0; --n) {
40 result = result * 16;
41 const int h = QtMiscUtils::fromHex(*s++);
42 if (h < 0)
43 return -1;
44 result += h;
45 }
46 return result;
47}
48
49static std::optional<QRgba64> get_hex_rgb(const char *name, size_t len)
50{
51 if (name[0] != '#')
52 return std::nullopt;
53 name++;
54 --len;
55 int a, r, g, b;
56 a = 65535;
57 if (len == 12) {
58 r = hex2int(name + 0, 4);
59 g = hex2int(name + 4, 4);
60 b = hex2int(name + 8, 4);
61 } else if (len == 9) {
62 r = hex2int(name + 0, 3);
63 g = hex2int(name + 3, 3);
64 b = hex2int(name + 6, 3);
65 if (r == -1 || g == -1 || b == -1)
66 return std::nullopt;
67 r = (r << 4) | (r >> 8);
68 g = (g << 4) | (g >> 8);
69 b = (b << 4) | (b >> 8);
70 } else if (len == 8) {
71 a = hex2int(name + 0, 2) * 0x101;
72 r = hex2int(name + 2, 2) * 0x101;
73 g = hex2int(name + 4, 2) * 0x101;
74 b = hex2int(name + 6, 2) * 0x101;
75 } else if (len == 6) {
76 r = hex2int(name + 0, 2) * 0x101;
77 g = hex2int(name + 2, 2) * 0x101;
78 b = hex2int(name + 4, 2) * 0x101;
79 } else if (len == 3) {
80 r = hex2int(name + 0, 1) * 0x1111;
81 g = hex2int(name + 1, 1) * 0x1111;
82 b = hex2int(name + 2, 1) * 0x1111;
83 } else {
84 r = g = b = -1;
85 }
86 if (uint(r) > 65535 || uint(g) > 65535 || uint(b) > 65535 || uint(a) > 65535)
87 return std::nullopt;
88 return qRgba64(r, g ,b, a);
89}
90
91std::optional<QRgb> qt_get_hex_rgb(const char *name)
92{
93 if (std::optional<QRgba64> rgba64 = get_hex_rgb(name, qstrlen(name)))
94 return rgba64->toArgb32();
95 return std::nullopt;
96}
97
98static std::optional<QRgba64> get_hex_rgb(const QChar *str, size_t len)
99{
100 if (len > 13)
101 return std::nullopt;
102 char tmp[16];
103 for (size_t i = 0; i < len; ++i)
104 tmp[i] = str[i].toLatin1();
105 tmp[len] = 0;
106 return get_hex_rgb(tmp, len);
107}
108
109static std::optional<QRgba64> get_hex_rgb(QAnyStringView name)
110{
111 return name.visit([] (auto name) {
112 return get_hex_rgb(name.data(), name.size());
113 });
114}
115
116#ifndef QT_NO_COLORNAMES
117
118/*
119 CSS color names = SVG 1.0 color names + transparent (rgba(0,0,0,0))
120*/
121
122#ifdef rgb
123# undef rgb
124#endif
125#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
126
127// keep this is in sync with QColorConstants
128static constexpr struct RGBData {
129 const char name[21];
130 uint value;
131} rgbTbl[] = {
132 { "aliceblue", rgb(240, 248, 255) },
133 { "antiquewhite", rgb(250, 235, 215) },
134 { "aqua", rgb( 0, 255, 255) },
135 { "aquamarine", rgb(127, 255, 212) },
136 { "azure", rgb(240, 255, 255) },
137 { "beige", rgb(245, 245, 220) },
138 { "bisque", rgb(255, 228, 196) },
139 { "black", rgb( 0, 0, 0) },
140 { "blanchedalmond", rgb(255, 235, 205) },
141 { "blue", rgb( 0, 0, 255) },
142 { "blueviolet", rgb(138, 43, 226) },
143 { "brown", rgb(165, 42, 42) },
144 { "burlywood", rgb(222, 184, 135) },
145 { "cadetblue", rgb( 95, 158, 160) },
146 { "chartreuse", rgb(127, 255, 0) },
147 { "chocolate", rgb(210, 105, 30) },
148 { "coral", rgb(255, 127, 80) },
149 { "cornflowerblue", rgb(100, 149, 237) },
150 { "cornsilk", rgb(255, 248, 220) },
151 { "crimson", rgb(220, 20, 60) },
152 { "cyan", rgb( 0, 255, 255) },
153 { "darkblue", rgb( 0, 0, 139) },
154 { "darkcyan", rgb( 0, 139, 139) },
155 { "darkgoldenrod", rgb(184, 134, 11) },
156 { "darkgray", rgb(169, 169, 169) },
157 { "darkgreen", rgb( 0, 100, 0) },
158 { "darkgrey", rgb(169, 169, 169) },
159 { "darkkhaki", rgb(189, 183, 107) },
160 { "darkmagenta", rgb(139, 0, 139) },
161 { "darkolivegreen", rgb( 85, 107, 47) },
162 { "darkorange", rgb(255, 140, 0) },
163 { "darkorchid", rgb(153, 50, 204) },
164 { "darkred", rgb(139, 0, 0) },
165 { "darksalmon", rgb(233, 150, 122) },
166 { "darkseagreen", rgb(143, 188, 143) },
167 { "darkslateblue", rgb( 72, 61, 139) },
168 { "darkslategray", rgb( 47, 79, 79) },
169 { "darkslategrey", rgb( 47, 79, 79) },
170 { "darkturquoise", rgb( 0, 206, 209) },
171 { "darkviolet", rgb(148, 0, 211) },
172 { "deeppink", rgb(255, 20, 147) },
173 { "deepskyblue", rgb( 0, 191, 255) },
174 { "dimgray", rgb(105, 105, 105) },
175 { "dimgrey", rgb(105, 105, 105) },
176 { "dodgerblue", rgb( 30, 144, 255) },
177 { "firebrick", rgb(178, 34, 34) },
178 { "floralwhite", rgb(255, 250, 240) },
179 { "forestgreen", rgb( 34, 139, 34) },
180 { "fuchsia", rgb(255, 0, 255) },
181 { "gainsboro", rgb(220, 220, 220) },
182 { "ghostwhite", rgb(248, 248, 255) },
183 { "gold", rgb(255, 215, 0) },
184 { "goldenrod", rgb(218, 165, 32) },
185 { "gray", rgb(128, 128, 128) },
186 { "green", rgb( 0, 128, 0) },
187 { "greenyellow", rgb(173, 255, 47) },
188 { "grey", rgb(128, 128, 128) },
189 { "honeydew", rgb(240, 255, 240) },
190 { "hotpink", rgb(255, 105, 180) },
191 { "indianred", rgb(205, 92, 92) },
192 { "indigo", rgb( 75, 0, 130) },
193 { "ivory", rgb(255, 255, 240) },
194 { "khaki", rgb(240, 230, 140) },
195 { "lavender", rgb(230, 230, 250) },
196 { "lavenderblush", rgb(255, 240, 245) },
197 { "lawngreen", rgb(124, 252, 0) },
198 { "lemonchiffon", rgb(255, 250, 205) },
199 { "lightblue", rgb(173, 216, 230) },
200 { "lightcoral", rgb(240, 128, 128) },
201 { "lightcyan", rgb(224, 255, 255) },
202 { "lightgoldenrodyellow", rgb(250, 250, 210) },
203 { "lightgray", rgb(211, 211, 211) },
204 { "lightgreen", rgb(144, 238, 144) },
205 { "lightgrey", rgb(211, 211, 211) },
206 { "lightpink", rgb(255, 182, 193) },
207 { "lightsalmon", rgb(255, 160, 122) },
208 { "lightseagreen", rgb( 32, 178, 170) },
209 { "lightskyblue", rgb(135, 206, 250) },
210 { "lightslategray", rgb(119, 136, 153) },
211 { "lightslategrey", rgb(119, 136, 153) },
212 { "lightsteelblue", rgb(176, 196, 222) },
213 { "lightyellow", rgb(255, 255, 224) },
214 { "lime", rgb( 0, 255, 0) },
215 { "limegreen", rgb( 50, 205, 50) },
216 { "linen", rgb(250, 240, 230) },
217 { "magenta", rgb(255, 0, 255) },
218 { "maroon", rgb(128, 0, 0) },
219 { "mediumaquamarine", rgb(102, 205, 170) },
220 { "mediumblue", rgb( 0, 0, 205) },
221 { "mediumorchid", rgb(186, 85, 211) },
222 { "mediumpurple", rgb(147, 112, 219) },
223 { "mediumseagreen", rgb( 60, 179, 113) },
224 { "mediumslateblue", rgb(123, 104, 238) },
225 { "mediumspringgreen", rgb( 0, 250, 154) },
226 { "mediumturquoise", rgb( 72, 209, 204) },
227 { "mediumvioletred", rgb(199, 21, 133) },
228 { "midnightblue", rgb( 25, 25, 112) },
229 { "mintcream", rgb(245, 255, 250) },
230 { "mistyrose", rgb(255, 228, 225) },
231 { "moccasin", rgb(255, 228, 181) },
232 { "navajowhite", rgb(255, 222, 173) },
233 { "navy", rgb( 0, 0, 128) },
234 { "oldlace", rgb(253, 245, 230) },
235 { "olive", rgb(128, 128, 0) },
236 { "olivedrab", rgb(107, 142, 35) },
237 { "orange", rgb(255, 165, 0) },
238 { "orangered", rgb(255, 69, 0) },
239 { "orchid", rgb(218, 112, 214) },
240 { "palegoldenrod", rgb(238, 232, 170) },
241 { "palegreen", rgb(152, 251, 152) },
242 { "paleturquoise", rgb(175, 238, 238) },
243 { "palevioletred", rgb(219, 112, 147) },
244 { "papayawhip", rgb(255, 239, 213) },
245 { "peachpuff", rgb(255, 218, 185) },
246 { "peru", rgb(205, 133, 63) },
247 { "pink", rgb(255, 192, 203) },
248 { "plum", rgb(221, 160, 221) },
249 { "powderblue", rgb(176, 224, 230) },
250 { "purple", rgb(128, 0, 128) },
251 { "red", rgb(255, 0, 0) },
252 { "rosybrown", rgb(188, 143, 143) },
253 { "royalblue", rgb( 65, 105, 225) },
254 { "saddlebrown", rgb(139, 69, 19) },
255 { "salmon", rgb(250, 128, 114) },
256 { "sandybrown", rgb(244, 164, 96) },
257 { "seagreen", rgb( 46, 139, 87) },
258 { "seashell", rgb(255, 245, 238) },
259 { "sienna", rgb(160, 82, 45) },
260 { "silver", rgb(192, 192, 192) },
261 { "skyblue", rgb(135, 206, 235) },
262 { "slateblue", rgb(106, 90, 205) },
263 { "slategray", rgb(112, 128, 144) },
264 { "slategrey", rgb(112, 128, 144) },
265 { "snow", rgb(255, 250, 250) },
266 { "springgreen", rgb( 0, 255, 127) },
267 { "steelblue", rgb( 70, 130, 180) },
268 { "tan", rgb(210, 180, 140) },
269 { "teal", rgb( 0, 128, 128) },
270 { "thistle", rgb(216, 191, 216) },
271 { "tomato", rgb(255, 99, 71) },
272 { "transparent", 0 },
273 { "turquoise", rgb( 64, 224, 208) },
274 { "violet", rgb(238, 130, 238) },
275 { "wheat", rgb(245, 222, 179) },
276 { "white", rgb(255, 255, 255) },
277 { "whitesmoke", rgb(245, 245, 245) },
278 { "yellow", rgb(255, 255, 0) },
279 { "yellowgreen", rgb(154, 205, 50) }
281
282static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData);
283
284static_assert([] {
285 for (auto e : rgbTbl) {
286 for (auto it = e.name; *it ; ++it) {
287 if (uchar(*it) > 127)
288 return false;
289 }
290 }
291 return true;
292 }(), "the lookup code expects color names to be US-ASCII-only");
293
294#undef rgb
295
296inline bool operator<(const char *name, const RGBData &data)
297{ return qstrcmp(name, data.name) < 0; }
298inline bool operator<(const RGBData &data, const char *name)
299{ return qstrcmp(data.name, name) < 0; }
300
301static std::optional<QRgb> get_named_rgb_no_space(const char *name_no_space)
302{
303 const RGBData *r = std::lower_bound(rgbTbl, rgbTbl + rgbTblSize, name_no_space);
304 if ((r != rgbTbl + rgbTblSize) && !(name_no_space < *r))
305 return r->value;
306 return std::nullopt;
307}
308
309namespace {
310// named colors are US-ASCII (enforced by static_assert above):
311static char to_char(char ch) noexcept { return ch; }
312static char to_char(QChar ch) noexcept { return ch.toLatin1(); }
313}
314
315static std::optional<QRgb> get_named_rgb(QAnyStringView name)
316{
317 if (name.size() > 255)
318 return std::nullopt;
319 char name_no_space[256];
320 int pos = 0;
321 name.visit([&pos, &name_no_space] (auto name) {
322 for (auto c : name) {
323 if (c != u'\t' && c != u' ')
324 name_no_space[pos++] = QtMiscUtils::toAsciiLower(to_char(c));
325 }
326 });
327 name_no_space[pos] = 0;
328
329 return get_named_rgb_no_space(name_no_space);
330}
331
332#endif // QT_NO_COLORNAMES
333
335{
336 QStringList lst;
337#ifndef QT_NO_COLORNAMES
338 lst.reserve(rgbTblSize);
339 for (int i = 0; i < rgbTblSize; i++)
340 lst << QLatin1StringView(rgbTbl[i].name);
341#endif
342 return lst;
343}
344
345/*!
346 \class QColor
347 \brief The QColor class provides colors based on RGB, HSV or CMYK values.
348
349 \ingroup painting
350 \ingroup appearance
351 \inmodule QtGui
352
353
354 A color is normally specified in terms of RGB (red, green, and
355 blue) components, but it is also possible to specify it in terms
356 of HSV (hue, saturation, and value) and CMYK (cyan, magenta,
357 yellow and black) components. In addition a color can be specified
358 using a color name. The color name can be any of the SVG 1.0 color
359 names.
360
361 \table
362 \header
363 \li RGB \li HSV \li CMYK
364 \row
365 \li \inlineimage qcolor-rgb.png
366 \li \inlineimage qcolor-hsv.png
367 \li \inlineimage qcolor-cmyk.png
368 \endtable
369
370 The QColor constructor creates the color based on RGB values. To
371 create a QColor based on either HSV or CMYK values, use the
372 toHsv() and toCmyk() functions respectively. These functions
373 return a copy of the color using the desired format. In addition
374 the static fromRgb(), fromHsv() and fromCmyk() functions create
375 colors from the specified values. Alternatively, a color can be
376 converted to any of the three formats using the convertTo()
377 function (returning a copy of the color in the desired format), or
378 any of the setRgb(), setHsv() and setCmyk() functions altering \e
379 this color's format. The spec() function tells how the color was
380 specified.
381
382 A color can be set by passing an RGB string (such as "#112233"),
383 or an ARGB string (such as "#ff112233") or a color name (such as "blue"),
384 to the fromString() function.
385 The color names are taken from the SVG 1.0 color names. The name()
386 function returns the name of the color in the format
387 "#RRGGBB". Colors can also be set using setRgb(), setHsv() and
388 setCmyk(). To get a lighter or darker color use the lighter() and
389 darker() functions respectively.
390
391 The isValid() function indicates whether a QColor is legal at
392 all. For example, a RGB color with RGB values out of range is
393 illegal. For performance reasons, QColor mostly disregards illegal
394 colors, and for that reason, the result of using an invalid color
395 is undefined.
396
397 The color components can be retrieved individually, e.g with
398 red(), hue() and cyan(). The values of the color components can
399 also be retrieved in one go using the getRgb(), getHsv() and
400 getCmyk() functions. Using the RGB color model, the color
401 components can in addition be accessed with rgb().
402
403 There are several related non-members: QRgb is a typdef for an
404 unsigned int representing the RGB value triplet (r, g, b). Note
405 that it also can hold a value for the alpha-channel (for more
406 information, see the \l {QColor#Alpha-Blended
407 Drawing}{Alpha-Blended Drawing} section). The qRed(), qBlue() and
408 qGreen() functions return the respective component of the given
409 QRgb value, while the qRgb() and qRgba() functions create and
410 return the QRgb triplet based on the given component
411 values. Finally, the qAlpha() function returns the alpha component
412 of the provided QRgb, and the qGray() function calculates and
413 return a gray value based on the given value.
414
415 QColor is platform and device independent.
416
417 For more information about painting in general, see the \l{Paint
418 System} documentation.
419
420 \section1 Integer vs. Floating Point Precision
421
422 QColor supports floating point precision and provides floating
423 point versions of all the color components functions,
424 e.g. getRgbF(), hueF() and fromCmykF(). Note that since the
425 components are stored using 16-bit integers, there might be minor
426 deviations between the values set using, for example, setRgbF()
427 and the values returned by the getRgbF() function due to rounding.
428
429 While the integer based functions take values in the range 0-255
430 (except hue() which must have values within the range 0-359),
431 the floating point functions accept values in the range 0.0 - 1.0.
432
433 \section1 Alpha-Blended Drawing
434
435 QColor also support alpha-blended outlining and filling. The
436 alpha channel of a color specifies the transparency effect, 0
437 represents a fully transparent color, while 255 represents a fully
438 opaque color. For example:
439
440 \snippet code/src_gui_painting_qcolor.cpp 0
441
442 The code above produces the following output:
443
444 \image alphafill.png {An image that contains four square sections,
445 with the colors purple, blue, red and white}
446
447 The alpha channel of a color can be retrieved and set using the
448 alpha() and setAlpha() functions if its value is an integer, and
449 alphaF() and setAlphaF() if its value is float. By
450 default, the alpha-channel is set to 255 (opaque). To retrieve and
451 set \e all the RGB color components (including the alpha-channel)
452 in one go, use the rgba() and setRgba() functions.
453
454 \section1 Predefined Colors
455
456 There are 20 predefined QColor objects in the \c{QColorConstants}
457 namespace, including black, white, primary and secondary colors,
458 darker versions of these colors, and three shades of gray.
459 Furthermore, the \c{QColorConstants::Svg} namespace defines QColor
460 objects for the standard \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}.
461
462 \image qt-colors.png Qt Colors
463
464 The \c{QColorConstants::Color0}, \c{QColorConstants::Color1} and
465 \c{QColorConstants::Transparent} colors are used for special
466 purposes.
467
468 \c{QColorConstants::Color0} (zero pixel value) and
469 \c{QColorConstants::Color1} (non-zero pixel value) are special
470 colors for drawing in QBitmaps. Painting with
471 \c{QColorConstants::Color0} sets the bitmap bits to 0 (transparent;
472 i.e., background), and painting with c{QColorConstants::Color1}
473 sets the bits to 1 (opaque; i.e., foreground).
474
475 \c{QColorConstants::Transparent} is used to indicate a transparent
476 pixel. When painting with this value, a pixel value will be used
477 that is appropriate for the underlying pixel format in use.
478
479 For historical reasons, the 20 predefined colors are also available
480 in the Qt::GlobalColor enumeration.
481
482 Finally, QColor recognizes a variety of color names (as strings);
483 the static colorNames() function returns a QStringList color names
484 that QColor knows about.
485
486 \section1 The Extended RGB Color Model
487
488 The extended RGB color model, also known as the scRGB color space,
489 is the same the RGB color model except it allows values under 0.0,
490 and over 1.0. This makes it possible to represent colors that would
491 otherwise be outside the range of the RGB colorspace but still use
492 the same values for colors inside the RGB colorspace.
493
494 \section1 The HSV Color Model
495
496 The RGB model is hardware-oriented. Its representation is close to
497 what most monitors show. In contrast, HSV represents color in a way
498 more suited to the human perception of color. For example, the
499 relationships "stronger than", "darker than", and "the opposite of"
500 are easily expressed in HSV but are much harder to express in RGB.
501
502 HSV, like RGB, has three components:
503
504 \list
505 \li H, for hue, is in the range 0 to 359 if the color is chromatic (not
506 gray), or meaningless if it is gray. It represents degrees on the
507 color wheel familiar to most people. Red is 0 (degrees), green is
508 120, and blue is 240.
509
510 \inlineimage qcolor-hue.png
511
512 \li S, for saturation, is in the range 0 to 255, and the bigger it is,
513 the stronger the color is. Grayish colors have saturation near 0; very
514 strong colors have saturation near 255.
515
516 \inlineimage qcolor-saturation.png
517
518 \li V, for value, is in the range 0 to 255 and represents lightness or
519 brightness of the color. 0 is black; 255 is as far from black as
520 possible.
521
522 \inlineimage qcolor-value.png
523 \endlist
524
525 Here are some examples: pure red is H=0, S=255, V=255; a dark red,
526 moving slightly towards the magenta, could be H=350 (equivalent to
527 -10), S=255, V=180; a grayish light red could have H about 0 (say
528 350-359 or 0-10), S about 50-100, and S=255.
529
530 Qt returns a hue value of -1 for achromatic colors. If you pass a
531 hue value that is too large, Qt forces it into range. Hue 360 or 720 is
532 treated as 0; hue 540 is treated as 180.
533
534 In addition to the standard HSV model, Qt provides an
535 alpha-channel to feature \l {QColor#Alpha-Blended
536 Drawing}{alpha-blended drawing}.
537
538 \section1 The HSL Color Model
539
540 HSL is similar to HSV, however instead of the Value parameter, HSL
541 specifies a Lightness parameter which maps somewhat differently to the
542 brightness of the color.
543
544 Similarly, the HSL saturation value is not in general the same as the HSV
545 saturation value for the same color. hslSaturation() provides the color's
546 HSL saturation value, while saturation() and hsvSaturation() provides the
547 HSV saturation value.
548
549 The hue value is defined to be the same in HSL and HSV.
550
551 \section1 The CMYK Color Model
552
553 While the RGB and HSV color models are used for display on
554 computer monitors, the CMYK model is used in the four-color
555 printing process of printing presses and some hard-copy
556 devices.
557
558 CMYK has four components, all in the range 0-255: cyan (C),
559 magenta (M), yellow (Y) and black (K). Cyan, magenta and yellow
560 are called subtractive colors; the CMYK color model creates color
561 by starting with a white surface and then subtracting color by
562 applying the appropriate components. While combining cyan, magenta
563 and yellow gives the color black, subtracting one or more will
564 yield any other color. When combined in various percentages, these
565 three colors can create the entire spectrum of colors.
566
567 Mixing 100 percent of cyan, magenta and yellow \e does produce
568 black, but the result is unsatisfactory since it wastes ink,
569 increases drying time, and gives a muddy colour when printing. For
570 that reason, black is added in professional printing to provide a
571 solid black tone; hence the term 'four color process'.
572
573 In addition to the standard CMYK model, Qt provides an
574 alpha-channel to feature \l {QColor#Alpha-Blended
575 Drawing}{alpha-blended drawing}.
576
577 \sa QPalette, QBrush, QColorConstants
578*/
579
580#define QCOLOR_INT_RANGE_CHECK(fn, var)
581 do {
582 if (var < 0 || var > 255) {
583 qWarning(#fn": invalid value %d", var);
584 var = qMax(0, qMin(var, 255));
585 }
586 } while (0)
587
588#define QCOLOR_REAL_RANGE_CHECK(fn, var)
589 do {
590 if (var < 0.0f || var > 1.0f) {
591 qWarning(#fn": invalid value %g", var);
592 var = qMax(0.0f, qMin(var, 1.0f));
593 }
594 } while (0)
595
596/*****************************************************************************
597 QColor member functions
598 *****************************************************************************/
599
600/*!
601 \enum QColor::Spec
602
603 The type of color specified, either RGB, extended RGB, HSV, CMYK or HSL.
604
605 \value Rgb
606 \value Hsv
607 \value Cmyk
608 \value Hsl
609 \value ExtendedRgb
610 \value Invalid
611
612 \sa spec(), convertTo()
613*/
614
615/*!
616 \enum QColor::NameFormat
617
618 How to format the output of the name() function
619
620 \value HexRgb #RRGGBB A "#" character followed by three two-digit hexadecimal numbers (i.e. \c{#RRGGBB}).
621 \value HexArgb #AARRGGBB A "#" character followed by four two-digit hexadecimal numbers (i.e. \c{#AARRGGBB}).
622
623 \sa name()
624*/
625
626/*!
627 \fn Spec QColor::spec() const
628
629 Returns how the color was specified.
630
631 \sa Spec, convertTo()
632*/
633
634
635/*!
636 \fn QColor::QColor()
637
638 Constructs an invalid color with the RGB value (0, 0, 0). An
639 invalid color is a color that is not properly set up for the
640 underlying window system.
641
642 The alpha value of an invalid color is unspecified.
643
644 \sa isValid()
645*/
646
647/*!
648 \overload
649
650 Constructs a new color with a color value of \a color.
651
652 \sa isValid(), {QColor#Predefined Colors}{Predefined Colors}
653 */
654QColor::QColor(Qt::GlobalColor color) noexcept
655{
656#define QRGB(r, g, b)
657 QRgb(((0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)))
658#define QRGBA(r, g, b, a)
659 QRgb(((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff))
660
661 static const QRgb global_colors[] = {
662 QRGB(255, 255, 255), // Qt::color0
663 QRGB( 0, 0, 0), // Qt::color1
664 QRGB( 0, 0, 0), // black
665 QRGB(255, 255, 255), // white
666 /*
667 * From the "The Palette Manager: How and Why" by Ron Gery,
668 * March 23, 1992, archived on MSDN:
669 *
670 * The Windows system palette is broken up into two
671 * sections, one with fixed colors and one with colors
672 * that can be changed by applications. The system palette
673 * predefines 20 entries; these colors are known as the
674 * static or reserved colors and consist of the 16 colors
675 * found in the Windows version 3.0 VGA driver and 4
676 * additional colors chosen for their visual appeal. The
677 * DEFAULT_PALETTE stock object is, as the name implies,
678 * the default palette selected into a device context (DC)
679 * and consists of these static colors. Applications can
680 * set the remaining 236 colors using the Palette Manager.
681 *
682 * The 20 reserved entries have indices in [0,9] and
683 * [246,255]. We reuse 17 of them.
684 */
685 QRGB(128, 128, 128), // index 248 medium gray
686 QRGB(160, 160, 164), // index 247 light gray
687 QRGB(192, 192, 192), // index 7 light gray
688 QRGB(255, 0, 0), // index 249 red
689 QRGB( 0, 255, 0), // index 250 green
690 QRGB( 0, 0, 255), // index 252 blue
691 QRGB( 0, 255, 255), // index 254 cyan
692 QRGB(255, 0, 255), // index 253 magenta
693 QRGB(255, 255, 0), // index 251 yellow
694 QRGB(128, 0, 0), // index 1 dark red
695 QRGB( 0, 128, 0), // index 2 dark green
696 QRGB( 0, 0, 128), // index 4 dark blue
697 QRGB( 0, 128, 128), // index 6 dark cyan
698 QRGB(128, 0, 128), // index 5 dark magenta
699 QRGB(128, 128, 0), // index 3 dark yellow
700 QRGBA(0, 0, 0, 0) // transparent
701 };
702#undef QRGB
703#undef QRGBA
704
705 setRgb(qRed(global_colors[color]),
706 qGreen(global_colors[color]),
707 qBlue(global_colors[color]),
708 qAlpha(global_colors[color]));
709}
710
711/*!
712 \fn QColor::QColor(int r, int g, int b, int a = 255)
713
714 Constructs a color with the RGB value \a r, \a g, \a b, and the
715 alpha-channel (transparency) value of \a a.
716
717 The color is left invalid if any of the arguments are invalid.
718
719 \sa setRgba(), isValid()
720*/
721
722/*!
723 Constructs a color with the value \a color. The alpha component is
724 ignored and set to solid.
725
726 \sa fromRgb(), isValid()
727*/
728
729QColor::QColor(QRgb color) noexcept
730{
731 cspec = Rgb;
732 ct.argb.alpha = 0xffff;
733 ct.argb.red = qRed(color) * 0x101;
734 ct.argb.green = qGreen(color) * 0x101;
735 ct.argb.blue = qBlue(color) * 0x101;
736 ct.argb.pad = 0;
737}
738
739/*!
740 \since 5.6
741
742 Constructs a color with the value \a rgba64.
743
744 \sa fromRgba64()
745*/
746
747QColor::QColor(QRgba64 rgba64) noexcept
748{
749 setRgba64(rgba64);
750}
751
752/*!
753 \internal
754
755 Constructs a color with the given \a spec.
756
757 This function is primarily present to avoid that QColor::Invalid
758 becomes a valid color by accident.
759*/
760
761QColor::QColor(Spec spec) noexcept
762{
763 switch (spec) {
764 case Invalid:
765 invalidate();
766 break;
767 case Rgb:
768 setRgb(0, 0, 0);
769 break;
770 case Hsv:
771 setHsv(0, 0, 0);
772 break;
773 case Cmyk:
774 setCmyk(0, 0, 0, 0);
775 break;
776 case Hsl:
777 setHsl(0, 0, 0, 0);
778 break;
779 case ExtendedRgb:
780 cspec = spec;
781 setRgbF(0, 0, 0, 0);
782 break;
783 }
784}
785
786// ### Qt 7: remove those after deprecating them for the last Qt 6 LTS release
787/*!
788 \fn QColor::QColor(const QString &name)
789
790 Constructs a named color in the same way as fromString() using
791 the given \a name.
792
793 The color is left invalid if the \a name cannot be parsed.
794
795 \sa fromString(), name(), isValid()
796*/
797
798/*!
799 \fn QColor::QColor(const char *name)
800
801 Constructs a named color in the same way as fromString() using
802 the given \a name.
803
804 \overload
805 \sa fromString(), name(), isValid()
806*/
807
808/*!
809 \fn QColor::QColor(QLatin1StringView name)
810
811 Constructs a named color in the same way as fromString() using
812 the given \a name.
813
814 \overload
815 \since 5.8
816 \sa fromString(), name(), isValid()
817*/
818
819/*!
820 \fn bool QColor::isValid() const
821
822 Returns \c true if the color is valid; otherwise returns \c false.
823*/
824
825/*!
826 \since 5.2
827
828 Returns the name of the color in the specified \a format.
829
830 \sa fromString(), NameFormat
831*/
832
833QString QColor::name(NameFormat format) const
834{
835 switch (format) {
836 case HexRgb:
837 return u'#' + QStringView{QString::number(rgba() | 0x1000000, 16)}.right(6);
838 case HexArgb:
839 // it's called rgba() but it does return AARRGGBB
840 return u'#' + QStringView{QString::number(rgba() | Q_INT64_C(0x100000000), 16)}.right(8);
841 }
842 return QString();
843}
844
845#if QT_DEPRECATED_SINCE(6, 6)
846/*!
847 \deprecated [6.6] Use fromString() instead.
848
849 Sets the RGB value of this QColor to \a name, which may be in one
850 of these formats:
851
852 \list
853 \li #RGB (each of R, G, and B is a single hex digit)
854 \li #RRGGBB
855 \li #AARRGGBB (Since 5.2)
856 \li #RRRGGGBBB
857 \li #RRRRGGGGBBBB
858 \li A name from the list of colors defined in the list of
859 \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}
860 provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
861 These color names work on all platforms. Note that these color names are \e not the
862 same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
863 refer to the same color.
864 \li \c transparent - representing the absence of a color.
865 \endlist
866
867 The color is invalid if \a name cannot be parsed.
868
869 \sa QColor(), name(), isValid()
870*/
871
872void QColor::setNamedColor(const QString &name)
873{
874 *this = fromString(qToAnyStringViewIgnoringNull(name));
875}
876
877/*!
878 \overload
879 \since 5.10
880 \deprecated [6.6] Use fromString() instead.
881*/
882
883void QColor::setNamedColor(QStringView name)
884{
885 *this = fromString(name);
886}
887
888/*!
889 \overload
890 \since 5.8
891 \deprecated [6.6] Use fromString() instead.
892*/
893
894void QColor::setNamedColor(QLatin1StringView name)
895{
896 *this = fromString(name);
897}
898
899/*!
900 \since 4.7
901
902 \deprecated [6.6] Use isValidColorName() instead.
903
904 Returns \c true if the \a name is a valid color name and can
905 be used to construct a valid QColor object, otherwise returns
906 false.
907
908 It uses the same algorithm used in fromString().
909
910 \sa fromString()
911*/
912bool QColor::isValidColor(const QString &name)
913{
914 return isValidColorName(qToAnyStringViewIgnoringNull(name));
915}
916
917/*!
918 \overload
919 \since 5.10
920 \deprecated [6.6] Use isValidColorName() instead.
921*/
922bool QColor::isValidColor(QStringView name) noexcept
923{
924 return isValidColorName(name);
925}
926
927/*!
928 \overload
929 \since 5.8
930 \deprecated [6.6] Use isValidColorName() instead.
931*/
932bool QColor::isValidColor(QLatin1StringView name) noexcept
933{
934 return isValidColorName(name);
935}
936#endif // QT_DEPRECATED_SINCE(6, 6)
937
938/*!
939 \since 6.4
940
941 Returns \c true if the \a name is a valid color name and can
942 be used to construct a valid QColor object, otherwise returns
943 false.
944
945 It uses the same algorithm used in fromString().
946
947 \sa fromString()
948*/
949bool QColor::isValidColorName(QAnyStringView name) noexcept
950{
951 return fromString(name).isValid();
952}
953
954/*!
955 \since 6.4
956
957 Returns an RGB QColor parsed from \a name, which may be in one
958 of these formats:
959
960 \list
961 \li #RGB (each of R, G, and B is a single hex digit)
962 \li #RRGGBB
963 \li #AARRGGBB (Since 5.2)
964 \li #RRRGGGBBB
965 \li #RRRRGGGGBBBB
966 \li A name from the list of colors defined in the list of
967 \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}
968 provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
969 These color names work on all platforms. Note that these color names are \e not the
970 same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
971 refer to the same color.
972 \li \c transparent - representing the absence of a color.
973 \endlist
974
975 Returns an invalid color if \a name cannot be parsed.
976
977 \sa isValidColorName()
978*/
979QColor QColor::fromString(QAnyStringView name) noexcept
980{
981 if (!name.size())
982 return {};
983
984 if (name.front() == u'#') {
985 if (std::optional<QRgba64> r = get_hex_rgb(name))
986 return QColor::fromRgba64(*r);
987#ifndef QT_NO_COLORNAMES
988 } else if (std::optional<QRgb> r = get_named_rgb(name)) {
989 return QColor::fromRgba(*r);
990#endif
991 }
992
993 return {};
994}
995
996/*!
997 Returns a QStringList containing the color names Qt knows about.
998
999 \sa {QColor#Predefined Colors}{Predefined Colors}
1000*/
1001QStringList QColor::colorNames()
1002{
1003 return get_colornames();
1004}
1005
1006/*!
1007 Sets the contents pointed to by \a h, \a s, \a v, and \a a, to the hue,
1008 saturation, value, and alpha-channel (transparency) components of the
1009 color's HSV value.
1010
1011 These components can be retrieved individually using the hueF(),
1012 saturationF(), valueF() and alphaF() functions.
1013
1014 \sa setHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1015*/
1016void QColor::getHsvF(float *h, float *s, float *v, float *a) const
1017{
1018 if (!h || !s || !v)
1019 return;
1020
1021 if (cspec != Invalid && cspec != Hsv) {
1022 toHsv().getHsvF(h, s, v, a);
1023 return;
1024 }
1025
1026 *h = ct.ahsv.hue == USHRT_MAX ? -1.0f : ct.ahsv.hue / 36000.0f;
1027 *s = ct.ahsv.saturation / float(USHRT_MAX);
1028 *v = ct.ahsv.value / float(USHRT_MAX);
1029
1030 if (a)
1031 *a = ct.ahsv.alpha / float(USHRT_MAX);
1032}
1033
1034/*!
1035 Sets the contents pointed to by \a h, \a s, \a v, and \a a, to the hue,
1036 saturation, value, and alpha-channel (transparency) components of the
1037 color's HSV value.
1038
1039 These components can be retrieved individually using the hue(),
1040 saturation(), value() and alpha() functions.
1041
1042 \sa setHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1043*/
1044void QColor::getHsv(int *h, int *s, int *v, int *a) const
1045{
1046 if (!h || !s || !v)
1047 return;
1048
1049 if (cspec != Invalid && cspec != Hsv) {
1050 toHsv().getHsv(h, s, v, a);
1051 return;
1052 }
1053
1054 *h = ct.ahsv.hue == USHRT_MAX ? -1 : ct.ahsv.hue / 100;
1055 *s = qt_div_257(ct.ahsv.saturation);
1056 *v = qt_div_257(ct.ahsv.value);
1057
1058 if (a)
1059 *a = qt_div_257(ct.ahsv.alpha);
1060}
1061
1062/*!
1063 Sets a HSV color value; \a h is the hue, \a s is the saturation, \a v is
1064 the value and \a a is the alpha component of the HSV color.
1065
1066 All the values must be in the range 0.0-1.0.
1067
1068 \sa getHsvF(), setHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1069*/
1070void QColor::setHsvF(float h, float s, float v, float a)
1071{
1072 if (((h < 0.0f || h > 1.0f) && h != -1.0f)
1073 || (s < 0.0f || s > 1.0f)
1074 || (v < 0.0f || v > 1.0f)
1075 || (a < 0.0f || a > 1.0f)) {
1076 qWarning("QColor::setHsvF: HSV parameters out of range");
1077 invalidate();
1078 return;
1079 }
1080
1081 cspec = Hsv;
1082 ct.ahsv.alpha = qRound(a * USHRT_MAX);
1083 ct.ahsv.hue = h == -1.0f ? USHRT_MAX : qRound(h * 36000.0f);
1084 ct.ahsv.saturation = qRound(s * USHRT_MAX);
1085 ct.ahsv.value = qRound(v * USHRT_MAX);
1086 ct.ahsv.pad = 0;
1087}
1088
1089/*!
1090 Sets a HSV color value; \a h is the hue, \a s is the saturation, \a v is
1091 the value and \a a is the alpha component of the HSV color.
1092
1093 The saturation, value and alpha-channel values must be in the range 0-255,
1094 and the hue value must be greater than -1.
1095
1096 \sa getHsv(), setHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
1097*/
1098void QColor::setHsv(int h, int s, int v, int a)
1099{
1100 if (h < -1 || (uint)s > 255 || (uint)v > 255 || (uint)a > 255) {
1101 qWarning("QColor::setHsv: HSV parameters out of range");
1102 invalidate();
1103 return;
1104 }
1105
1106 cspec = Hsv;
1107 ct.ahsv.alpha = a * 0x101;
1108 ct.ahsv.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
1109 ct.ahsv.saturation = s * 0x101;
1110 ct.ahsv.value = v * 0x101;
1111 ct.ahsv.pad = 0;
1112}
1113
1114/*!
1115 \since 4.6
1116
1117 Sets the contents pointed to by \a h, \a s, \a l, and \a a, to the hue,
1118 saturation, lightness, and alpha-channel (transparency) components of the
1119 color's HSL value.
1120
1121 These components can be retrieved individually using the hslHueF(),
1122 hslSaturationF(), lightnessF() and alphaF() functions.
1123
1124 \sa getHsl(), setHslF(), {QColor#The HSL Color Model}{The HSL Color Model}
1125*/
1126void QColor::getHslF(float *h, float *s, float *l, float *a) const
1127{
1128 if (!h || !s || !l)
1129 return;
1130
1131 if (cspec != Invalid && cspec != Hsl) {
1132 toHsl().getHslF(h, s, l, a);
1133 return;
1134 }
1135
1136 *h = ct.ahsl.hue == USHRT_MAX ? -1.0f : ct.ahsl.hue / 36000.0f;
1137 *s = ct.ahsl.saturation / float(USHRT_MAX);
1138 *l = ct.ahsl.lightness / float(USHRT_MAX);
1139
1140 if (a)
1141 *a = ct.ahsl.alpha / float(USHRT_MAX);
1142}
1143
1144/*!
1145 \since 4.6
1146
1147 Sets the contents pointed to by \a h, \a s, \a l, and \a a, to the hue,
1148 saturation, lightness, and alpha-channel (transparency) components of the
1149 color's HSL value.
1150
1151 These components can be retrieved individually using the hslHue(),
1152 hslSaturation(), lightness() and alpha() functions.
1153
1154 \sa getHslF(), setHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
1155*/
1156void QColor::getHsl(int *h, int *s, int *l, int *a) const
1157{
1158 if (!h || !s || !l)
1159 return;
1160
1161 if (cspec != Invalid && cspec != Hsl) {
1162 toHsl().getHsl(h, s, l, a);
1163 return;
1164 }
1165
1166 *h = ct.ahsl.hue == USHRT_MAX ? -1 : ct.ahsl.hue / 100;
1167 *s = qt_div_257(ct.ahsl.saturation);
1168 *l = qt_div_257(ct.ahsl.lightness);
1169
1170 if (a)
1171 *a = qt_div_257(ct.ahsl.alpha);
1172}
1173
1174/*!
1175 \since 4.6
1176
1177 Sets a HSL color lightness; \a h is the hue, \a s is the saturation, \a l is
1178 the lightness and \a a is the alpha component of the HSL color.
1179
1180 All the values must be in the range 0.0-1.0.
1181
1182 \sa getHslF(), setHsl()
1183*/
1184void QColor::setHslF(float h, float s, float l, float a)
1185{
1186 if (((h < 0.0f || h > 1.0f) && h != -1.0f)
1187 || (s < 0.0f || s > 1.0f)
1188 || (l < 0.0f || l > 1.0f)
1189 || (a < 0.0f || a > 1.0f)) {
1190 qWarning("QColor::setHslF: HSL parameters out of range");
1191 invalidate();
1192 return;
1193 }
1194
1195 cspec = Hsl;
1196 ct.ahsl.alpha = qRound(a * USHRT_MAX);
1197 ct.ahsl.hue = h == -1.0f ? USHRT_MAX : qRound(h * 36000.0f);
1198 ct.ahsl.saturation = qRound(s * USHRT_MAX);
1199 ct.ahsl.lightness = qRound(l * USHRT_MAX);
1200 ct.ahsl.pad = 0;
1201}
1202
1203/*!
1204 \since 4.6
1205
1206 Sets a HSL color value; \a h is the hue, \a s is the saturation, \a l is
1207 the lightness and \a a is the alpha component of the HSL color.
1208
1209 The saturation, value and alpha-channel values must be in the range 0-255,
1210 and the hue value must be greater than -1.
1211
1212 \sa getHsl(), setHslF()
1213*/
1214void QColor::setHsl(int h, int s, int l, int a)
1215{
1216 if (h < -1 || (uint)s > 255 || (uint)l > 255 || (uint)a > 255) {
1217 qWarning("QColor::setHsl: HSL parameters out of range");
1218 invalidate();
1219 return;
1220 }
1221
1222 cspec = Hsl;
1223 ct.ahsl.alpha = a * 0x101;
1224 ct.ahsl.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
1225 ct.ahsl.saturation = s * 0x101;
1226 ct.ahsl.lightness = l * 0x101;
1227 ct.ahsl.pad = 0;
1228}
1229
1230static inline qfloat16 &castF16(quint16 &v)
1231{
1232 // this works because qfloat16 internally is a quint16
1233 return *reinterpret_cast<qfloat16 *>(&v);
1234}
1235
1236static inline const qfloat16 &castF16(const quint16 &v)
1237{
1238 return *reinterpret_cast<const qfloat16 *>(&v);
1239}
1240
1241/*!
1242 Sets the contents pointed to by \a r, \a g, \a b, and \a a, to the red,
1243 green, blue, and alpha-channel (transparency) components of the color's
1244 RGB value.
1245
1246 These components can be retrieved individually using the redF(), greenF(),
1247 blueF() and alphaF() functions.
1248
1249 \sa rgb(), setRgb()
1250*/
1251void QColor::getRgbF(float *r, float *g, float *b, float *a) const
1252{
1253 if (!r || !g || !b)
1254 return;
1255
1256 if (cspec != Invalid && cspec != Rgb && cspec != ExtendedRgb) {
1257 toRgb().getRgbF(r, g, b, a);
1258 return;
1259 }
1260
1261 if (cspec == Rgb || cspec == Invalid) {
1262 *r = ct.argb.red / float(USHRT_MAX);
1263 *g = ct.argb.green / float(USHRT_MAX);
1264 *b = ct.argb.blue / float(USHRT_MAX);
1265 if (a)
1266 *a = ct.argb.alpha / float(USHRT_MAX);
1267 } else {
1268 *r = castF16(ct.argbExtended.redF16);
1269 *g = castF16(ct.argbExtended.greenF16);
1270 *b = castF16(ct.argbExtended.blueF16);
1271 if (a)
1272 *a = castF16(ct.argbExtended.alphaF16);
1273 }
1274}
1275
1276/*!
1277 Sets the contents pointed to by \a r, \a g, \a b, and \a a, to the red,
1278 green, blue, and alpha-channel (transparency) components of the color's
1279 RGB value.
1280
1281 These components can be retrieved individually using the red(), green(),
1282 blue() and alpha() functions.
1283
1284 \sa rgb(), setRgb()
1285*/
1286void QColor::getRgb(int *r, int *g, int *b, int *a) const
1287{
1288 if (!r || !g || !b)
1289 return;
1290
1291 if (cspec != Invalid && cspec != Rgb) {
1292 toRgb().getRgb(r, g, b, a);
1293 return;
1294 }
1295
1296 *r = qt_div_257(ct.argb.red);
1297 *g = qt_div_257(ct.argb.green);
1298 *b = qt_div_257(ct.argb.blue);
1299
1300 if (a)
1301 *a = qt_div_257(ct.argb.alpha);
1302}
1303
1304/*!
1305 \fn void QColor::setRgbF(float r, float g, float b, float a)
1306
1307 Sets the color channels of this color to \a r (red), \a g (green),
1308 \a b (blue) and \a a (alpha, transparency).
1309
1310 The alpha value must be in the range 0.0-1.0.
1311 If any of the other values are outside the range of 0.0-1.0 the
1312 color model will be set as \c ExtendedRgb.
1313
1314 \sa rgb(), getRgbF(), setRgb()
1315*/
1316void QColor::setRgbF(float r, float g, float b, float a)
1317{
1318 if (a < 0.0f || a > 1.0f) {
1319 qWarning("QColor::setRgbF: Alpha parameter is out of range");
1320 invalidate();
1321 return;
1322 }
1323 if (r < 0.0f || r > 1.0f ||
1324 g < 0.0f || g > 1.0f ||
1325 b < 0.0f || b > 1.0f || cspec == ExtendedRgb) {
1326 cspec = ExtendedRgb;
1327 castF16(ct.argbExtended.redF16) = qfloat16(r);
1328 castF16(ct.argbExtended.greenF16) = qfloat16(g);
1329 castF16(ct.argbExtended.blueF16) = qfloat16(b);
1330 castF16(ct.argbExtended.alphaF16) = qfloat16(a);
1331 ct.argbExtended.pad = 0;
1332 return;
1333 }
1334 cspec = Rgb;
1335 ct.argb.red = qRound(r * USHRT_MAX);
1336 ct.argb.green = qRound(g * USHRT_MAX);
1337 ct.argb.blue = qRound(b * USHRT_MAX);
1338 ct.argb.alpha = qRound(a * USHRT_MAX);
1339 ct.argb.pad = 0;
1340}
1341
1342/*!
1343 Sets the RGB value to \a r, \a g, \a b and the alpha value to \a a.
1344
1345 All the values must be in the range 0-255.
1346
1347 \sa rgb(), getRgb(), setRgbF()
1348*/
1349void QColor::setRgb(int r, int g, int b, int a)
1350{
1351 if (!isRgbaValid(r, g, b, a)) {
1352 qWarning("QColor::setRgb: RGB parameters out of range");
1353 invalidate();
1354 return;
1355 }
1356
1357 cspec = Rgb;
1358 ct.argb.alpha = a * 0x101;
1359 ct.argb.red = r * 0x101;
1360 ct.argb.green = g * 0x101;
1361 ct.argb.blue = b * 0x101;
1362 ct.argb.pad = 0;
1363}
1364
1365/*!
1366 \fn QRgb QColor::rgba() const
1367
1368 Returns the RGB value of the color, including its alpha.
1369
1370 For an invalid color, the alpha value of the returned color is unspecified.
1371
1372 \sa setRgba(), rgb(), rgba64()
1373*/
1374
1375QRgb QColor::rgba() const noexcept
1376{
1377 if (cspec != Invalid && cspec != Rgb)
1378 return toRgb().rgba();
1379 return qRgba(qt_div_257(ct.argb.red), qt_div_257(ct.argb.green), qt_div_257(ct.argb.blue), qt_div_257(ct.argb.alpha));
1380}
1381
1382/*!
1383 Sets the RGB value to \a rgba, including its alpha.
1384
1385 \sa rgba(), rgb(), setRgba64()
1386*/
1387void QColor::setRgba(QRgb rgba) noexcept
1388{
1389 cspec = Rgb;
1390 ct.argb.alpha = qAlpha(rgba) * 0x101;
1391 ct.argb.red = qRed(rgba) * 0x101;
1392 ct.argb.green = qGreen(rgba) * 0x101;
1393 ct.argb.blue = qBlue(rgba) * 0x101;
1394 ct.argb.pad = 0;
1395}
1396
1397/*!
1398 \since 5.6
1399
1400 Returns the RGB64 value of the color, including its alpha.
1401
1402 For an invalid color, the alpha value of the returned color is unspecified.
1403
1404 \sa setRgba64(), rgba(), rgb()
1405*/
1406
1407QRgba64 QColor::rgba64() const noexcept
1408{
1409 if (cspec != Invalid && cspec != Rgb)
1410 return toRgb().rgba64();
1411 return qRgba64(ct.argb.red, ct.argb.green, ct.argb.blue, ct.argb.alpha);
1412}
1413
1414/*!
1415 \since 5.6
1416
1417 Sets the RGB64 value to \a rgba, including its alpha.
1418
1419 \sa setRgba(), rgba64()
1420*/
1421void QColor::setRgba64(QRgba64 rgba) noexcept
1422{
1423 cspec = Rgb;
1424 ct.argb.alpha = rgba.alpha();
1425 ct.argb.red = rgba.red();
1426 ct.argb.green = rgba.green();
1427 ct.argb.blue = rgba.blue();
1428 ct.argb.pad = 0;
1429}
1430
1431/*!
1432 \fn QRgb QColor::rgb() const
1433
1434 Returns the RGB value of the color. The alpha value is opaque.
1435
1436 \sa getRgb(), rgba()
1437*/
1438QRgb QColor::rgb() const noexcept
1439{
1440 if (cspec != Invalid && cspec != Rgb)
1441 return toRgb().rgb();
1442 return qRgb(qt_div_257(ct.argb.red), qt_div_257(ct.argb.green), qt_div_257(ct.argb.blue));
1443}
1444
1445/*!
1446 \overload
1447
1448 Sets the RGB value to \a rgb. The alpha value is set to opaque.
1449*/
1450void QColor::setRgb(QRgb rgb) noexcept
1451{
1452 cspec = Rgb;
1453 ct.argb.alpha = 0xffff;
1454 ct.argb.red = qRed(rgb) * 0x101;
1455 ct.argb.green = qGreen(rgb) * 0x101;
1456 ct.argb.blue = qBlue(rgb) * 0x101;
1457 ct.argb.pad = 0;
1458}
1459
1460/*!
1461 Returns the alpha color component of this color.
1462
1463 \sa setAlpha(), alphaF(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
1464*/
1465int QColor::alpha() const noexcept
1466{
1467 if (cspec == ExtendedRgb)
1468 return qRound(float(castF16(ct.argbExtended.alphaF16)) * 255);
1469 return qt_div_257(ct.argb.alpha);
1470}
1471
1472
1473/*!
1474 Sets the alpha of this color to \a alpha. Integer alpha is specified in the
1475 range 0-255.
1476
1477 \sa alpha(), alphaF(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
1478*/
1479
1480void QColor::setAlpha(int alpha)
1481{
1482 QCOLOR_INT_RANGE_CHECK("QColor::setAlpha", alpha);
1483 if (cspec == ExtendedRgb) {
1484 constexpr float f = 1.0f / 255;
1485 castF16(ct.argbExtended.alphaF16) = qfloat16(alpha * f);
1486 return;
1487 }
1488 ct.argb.alpha = alpha * 0x101;
1489}
1490
1491/*!
1492 Returns the alpha color component of this color.
1493
1494 \sa setAlphaF(), alpha(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
1495*/
1496float QColor::alphaF() const noexcept
1497{
1498 if (cspec == ExtendedRgb)
1499 return castF16(ct.argbExtended.alphaF16);
1500 return ct.argb.alpha / float(USHRT_MAX);
1501}
1502
1503/*!
1504 Sets the alpha of this color to \a alpha. float alpha is specified in the
1505 range 0.0-1.0.
1506
1507 \sa alphaF(), alpha(), {QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing}
1508
1509*/
1510void QColor::setAlphaF(float alpha)
1511{
1512 QCOLOR_REAL_RANGE_CHECK("QColor::setAlphaF", alpha);
1513 if (cspec == ExtendedRgb) {
1514 castF16(ct.argbExtended.alphaF16) = qfloat16(alpha);
1515 return;
1516 }
1517 float tmp = alpha * USHRT_MAX;
1518 ct.argb.alpha = qRound(tmp);
1519}
1520
1521
1522/*!
1523 Returns the red color component of this color.
1524
1525 \sa setRed(), redF(), getRgb()
1526*/
1527int QColor::red() const noexcept
1528{
1529 if (cspec != Invalid && cspec != Rgb)
1530 return toRgb().red();
1531 return qt_div_257(ct.argb.red);
1532}
1533
1534/*!
1535 Sets the red color component of this color to \a red. Integer components
1536 are specified in the range 0-255.
1537
1538 \sa red(), redF(), setRgb()
1539*/
1540void QColor::setRed(int red)
1541{
1542 QCOLOR_INT_RANGE_CHECK("QColor::setRed", red);
1543 if (cspec != Rgb)
1544 setRgb(red, green(), blue(), alpha());
1545 else
1546 ct.argb.red = red * 0x101;
1547}
1548
1549/*!
1550 Returns the green color component of this color.
1551
1552 \sa setGreen(), greenF(), getRgb()
1553*/
1554int QColor::green() const noexcept
1555{
1556 if (cspec != Invalid && cspec != Rgb)
1557 return toRgb().green();
1558 return qt_div_257(ct.argb.green);
1559}
1560
1561/*!
1562 Sets the green color component of this color to \a green. Integer
1563 components are specified in the range 0-255.
1564
1565 \sa green(), greenF(), setRgb()
1566*/
1567void QColor::setGreen(int green)
1568{
1569 QCOLOR_INT_RANGE_CHECK("QColor::setGreen", green);
1570 if (cspec != Rgb)
1571 setRgb(red(), green, blue(), alpha());
1572 else
1573 ct.argb.green = green * 0x101;
1574}
1575
1576
1577/*!
1578 Returns the blue color component of this color.
1579
1580 \sa setBlue(), blueF(), getRgb()
1581*/
1582int QColor::blue() const noexcept
1583{
1584 if (cspec != Invalid && cspec != Rgb)
1585 return toRgb().blue();
1586 return qt_div_257(ct.argb.blue);
1587}
1588
1589
1590/*!
1591 Sets the blue color component of this color to \a blue. Integer components
1592 are specified in the range 0-255.
1593
1594 \sa blue(), blueF(), setRgb()
1595*/
1596void QColor::setBlue(int blue)
1597{
1598 QCOLOR_INT_RANGE_CHECK("QColor::setBlue", blue);
1599 if (cspec != Rgb)
1600 setRgb(red(), green(), blue, alpha());
1601 else
1602 ct.argb.blue = blue * 0x101;
1603}
1604
1605/*!
1606 Returns the red color component of this color.
1607
1608 \sa setRedF(), red(), getRgbF()
1609*/
1610float QColor::redF() const noexcept
1611{
1612 if (cspec == Rgb || cspec == Invalid)
1613 return ct.argb.red / float(USHRT_MAX);
1614 if (cspec == ExtendedRgb)
1615 return castF16(ct.argbExtended.redF16);
1616
1617 return toRgb().redF();
1618}
1619
1620
1621/*!
1622 Sets the red color component of this color to \a red. If \a red lies outside
1623 the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
1624
1625 \sa redF(), red(), setRgbF()
1626*/
1627void QColor::setRedF(float red)
1628{
1629 if (cspec == Rgb && red >= 0.0f && red <= 1.0f)
1630 ct.argb.red = qRound(red * USHRT_MAX);
1631 else if (cspec == ExtendedRgb)
1632 castF16(ct.argbExtended.redF16) = qfloat16(red);
1633 else
1634 setRgbF(red, greenF(), blueF(), alphaF());
1635}
1636
1637/*!
1638 Returns the green color component of this color.
1639
1640 \sa setGreenF(), green(), getRgbF()
1641*/
1642float QColor::greenF() const noexcept
1643{
1644 if (cspec == Rgb || cspec == Invalid)
1645 return ct.argb.green / float(USHRT_MAX);
1646 if (cspec == ExtendedRgb)
1647 return castF16(ct.argbExtended.greenF16);
1648
1649 return toRgb().greenF();
1650}
1651
1652
1653/*!
1654 Sets the green color component of this color to \a green. If \a green lies outside
1655 the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
1656
1657 \sa greenF(), green(), setRgbF()
1658*/
1659void QColor::setGreenF(float green)
1660{
1661 if (cspec == Rgb && green >= 0.0f && green <= 1.0f)
1662 ct.argb.green = qRound(green * USHRT_MAX);
1663 else if (cspec == ExtendedRgb)
1664 castF16(ct.argbExtended.greenF16) = qfloat16(green);
1665 else
1666 setRgbF(redF(), green, blueF(), alphaF());
1667}
1668
1669/*!
1670 Returns the blue color component of this color.
1671
1672 \sa setBlueF(), blue(), getRgbF()
1673*/
1674float QColor::blueF() const noexcept
1675{
1676 if (cspec == Rgb || cspec == Invalid)
1677 return ct.argb.blue / float(USHRT_MAX);
1678 if (cspec == ExtendedRgb)
1679 return castF16(ct.argbExtended.blueF16);
1680
1681 return toRgb().blueF();
1682}
1683
1684/*!
1685 Sets the blue color component of this color to \a blue. If \a blue lies outside
1686 the 0.0-1.0 range, the color model will be changed to \c ExtendedRgb.
1687 \sa blueF(), blue(), setRgbF()
1688*/
1689void QColor::setBlueF(float blue)
1690{
1691 if (cspec == Rgb && blue >= 0.0f && blue <= 1.0f)
1692 ct.argb.blue = qRound(blue * USHRT_MAX);
1693 else if (cspec == ExtendedRgb)
1694 castF16(ct.argbExtended.blueF16) = qfloat16(blue);
1695 else
1696 setRgbF(redF(), greenF(), blue, alphaF());
1697}
1698
1699/*!
1700 Returns the HSV hue color component of this color.
1701
1702 The color is implicitly converted to HSV.
1703
1704 \sa hsvHue(), hslHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1705*/
1706
1707int QColor::hue() const noexcept
1708{
1709 return hsvHue();
1710}
1711
1712/*!
1713 Returns the HSV hue color component of this color.
1714
1715 \sa hueF(), hslHue(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1716*/
1717int QColor::hsvHue() const noexcept
1718{
1719 if (cspec != Invalid && cspec != Hsv)
1720 return toHsv().hue();
1721 return ct.ahsv.hue == USHRT_MAX ? -1 : ct.ahsv.hue / 100;
1722}
1723
1724/*!
1725 Returns the HSV saturation color component of this color.
1726
1727 The color is implicitly converted to HSV.
1728
1729 \sa hsvSaturation(), hslSaturation(), saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color
1730 Model}
1731*/
1732
1733int QColor::saturation() const noexcept
1734{
1735 return hsvSaturation();
1736}
1737
1738/*!
1739 Returns the HSV saturation color component of this color.
1740
1741 \sa saturationF(), hslSaturation(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1742*/
1743int QColor::hsvSaturation() const noexcept
1744{
1745 if (cspec != Invalid && cspec != Hsv)
1746 return toHsv().saturation();
1747 return qt_div_257(ct.ahsv.saturation);
1748}
1749
1750/*!
1751 Returns the value color component of this color.
1752
1753 \sa valueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model}
1754*/
1755int QColor::value() const noexcept
1756{
1757 if (cspec != Invalid && cspec != Hsv)
1758 return toHsv().value();
1759 return qt_div_257(ct.ahsv.value);
1760}
1761
1762/*!
1763 Returns the HSV hue color component of this color.
1764
1765 The color is implicitly converted to HSV.
1766
1767 \sa hsvHueF(), hslHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
1768*/
1769float QColor::hueF() const noexcept
1770{
1771 return hsvHueF();
1772}
1773
1774/*!
1775 Returns the hue color component of this color.
1776
1777 \sa hue(), hslHueF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
1778 Model}
1779*/
1780float QColor::hsvHueF() const noexcept
1781{
1782 if (cspec != Invalid && cspec != Hsv)
1783 return toHsv().hueF();
1784 return ct.ahsv.hue == USHRT_MAX ? -1.0f : ct.ahsv.hue / 36000.0f;
1785}
1786
1787/*!
1788 Returns the HSV saturation color component of this color.
1789
1790 The color is implicitly converted to HSV.
1791
1792 \sa hsvSaturationF(), hslSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color
1793 Model}
1794*/
1795float QColor::saturationF() const noexcept
1796{
1797 return hsvSaturationF();
1798}
1799
1800/*!
1801 Returns the HSV saturation color component of this color.
1802
1803 \sa saturation(), hslSaturationF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
1804*/
1805float QColor::hsvSaturationF() const noexcept
1806{
1807 if (cspec != Invalid && cspec != Hsv)
1808 return toHsv().saturationF();
1809 return ct.ahsv.saturation / float(USHRT_MAX);
1810}
1811
1812/*!
1813 Returns the value color component of this color.
1814
1815 \sa value(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model}
1816*/
1817float QColor::valueF() const noexcept
1818{
1819 if (cspec != Invalid && cspec != Hsv)
1820 return toHsv().valueF();
1821 return ct.ahsv.value / float(USHRT_MAX);
1822}
1823
1824/*!
1825 \since 4.6
1826
1827 Returns the HSL hue color component of this color.
1828
1829 \sa hslHueF(), hsvHue(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
1830*/
1831int QColor::hslHue() const noexcept
1832{
1833 if (cspec != Invalid && cspec != Hsl)
1834 return toHsl().hslHue();
1835 return ct.ahsl.hue == USHRT_MAX ? -1 : ct.ahsl.hue / 100;
1836}
1837
1838/*!
1839 \since 4.6
1840
1841 Returns the HSL saturation color component of this color.
1842
1843 \sa hslSaturationF(), hsvSaturation(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model}
1844*/
1845int QColor::hslSaturation() const noexcept
1846{
1847 if (cspec != Invalid && cspec != Hsl)
1848 return toHsl().hslSaturation();
1849 return qt_div_257(ct.ahsl.saturation);
1850}
1851
1852/*!
1853 \since 4.6
1854
1855 Returns the lightness color component of this color.
1856
1857 \sa lightnessF(), getHsl()
1858*/
1859int QColor::lightness() const noexcept
1860{
1861 if (cspec != Invalid && cspec != Hsl)
1862 return toHsl().lightness();
1863 return qt_div_257(ct.ahsl.lightness);
1864}
1865
1866/*!
1867 \since 4.6
1868
1869 Returns the HSL hue color component of this color.
1870
1871 \sa hslHue(), hsvHueF(), getHslF()
1872*/
1873float QColor::hslHueF() const noexcept
1874{
1875 if (cspec != Invalid && cspec != Hsl)
1876 return toHsl().hslHueF();
1877 return ct.ahsl.hue == USHRT_MAX ? -1.0f : ct.ahsl.hue / 36000.0f;
1878}
1879
1880/*!
1881 \since 4.6
1882
1883 Returns the HSL saturation color component of this color.
1884
1885 \sa hslSaturation(), hsvSaturationF(), getHslF(), {QColor#The HSL Color Model}{The HSL Color Model}
1886*/
1887float QColor::hslSaturationF() const noexcept
1888{
1889 if (cspec != Invalid && cspec != Hsl)
1890 return toHsl().hslSaturationF();
1891 return ct.ahsl.saturation / float(USHRT_MAX);
1892}
1893
1894/*!
1895 \since 4.6
1896
1897 Returns the lightness color component of this color.
1898
1899 \sa value(), getHslF()
1900*/
1901float QColor::lightnessF() const noexcept
1902{
1903 if (cspec != Invalid && cspec != Hsl)
1904 return toHsl().lightnessF();
1905 return ct.ahsl.lightness / float(USHRT_MAX);
1906}
1907
1908/*!
1909 Returns the cyan color component of this color.
1910
1911 \sa cyanF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1912*/
1913int QColor::cyan() const noexcept
1914{
1915 if (cspec != Invalid && cspec != Cmyk)
1916 return toCmyk().cyan();
1917 return qt_div_257(ct.acmyk.cyan);
1918}
1919
1920/*!
1921 Returns the magenta color component of this color.
1922
1923 \sa magentaF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1924*/
1925int QColor::magenta() const noexcept
1926{
1927 if (cspec != Invalid && cspec != Cmyk)
1928 return toCmyk().magenta();
1929 return qt_div_257(ct.acmyk.magenta);
1930}
1931
1932/*!
1933 Returns the yellow color component of this color.
1934
1935 \sa yellowF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1936*/
1937int QColor::yellow() const noexcept
1938{
1939 if (cspec != Invalid && cspec != Cmyk)
1940 return toCmyk().yellow();
1941 return qt_div_257(ct.acmyk.yellow);
1942}
1943
1944/*!
1945 Returns the black color component of this color.
1946
1947 \sa blackF(), getCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1948
1949*/
1950int QColor::black() const noexcept
1951{
1952 if (cspec != Invalid && cspec != Cmyk)
1953 return toCmyk().black();
1954 return qt_div_257(ct.acmyk.black);
1955}
1956
1957/*!
1958 Returns the cyan color component of this color.
1959
1960 \sa cyan(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1961*/
1962float QColor::cyanF() const noexcept
1963{
1964 if (cspec != Invalid && cspec != Cmyk)
1965 return toCmyk().cyanF();
1966 return ct.acmyk.cyan / float(USHRT_MAX);
1967}
1968
1969/*!
1970 Returns the magenta color component of this color.
1971
1972 \sa magenta(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1973*/
1974float QColor::magentaF() const noexcept
1975{
1976 if (cspec != Invalid && cspec != Cmyk)
1977 return toCmyk().magentaF();
1978 return ct.acmyk.magenta / float(USHRT_MAX);
1979}
1980
1981/*!
1982 Returns the yellow color component of this color.
1983
1984 \sa yellow(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1985*/
1986float QColor::yellowF() const noexcept
1987{
1988 if (cspec != Invalid && cspec != Cmyk)
1989 return toCmyk().yellowF();
1990 return ct.acmyk.yellow / float(USHRT_MAX);
1991}
1992
1993/*!
1994 Returns the black color component of this color.
1995
1996 \sa black(), getCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
1997*/
1998float QColor::blackF() const noexcept
1999{
2000 if (cspec != Invalid && cspec != Cmyk)
2001 return toCmyk().blackF();
2002 return ct.acmyk.black / float(USHRT_MAX);
2003}
2004
2005/*!
2006 Create and returns an extended RGB QColor based on this color.
2007 \since 5.14
2008
2009 \sa toRgb, convertTo()
2010*/
2011QColor QColor::toExtendedRgb() const noexcept
2012{
2013 if (!isValid() || cspec == ExtendedRgb)
2014 return *this;
2015 if (cspec != Rgb)
2016 return toRgb().toExtendedRgb();
2017
2018 constexpr float f = 1.0f / USHRT_MAX;
2019 QColor color;
2020 color.cspec = ExtendedRgb;
2021 castF16(color.ct.argbExtended.alphaF16) = qfloat16(ct.argb.alpha * f);
2022 castF16(color.ct.argbExtended.redF16) = qfloat16(ct.argb.red * f);
2023 castF16(color.ct.argbExtended.greenF16) = qfloat16(ct.argb.green * f);
2024 castF16(color.ct.argbExtended.blueF16) = qfloat16(ct.argb.blue * f);
2025 color.ct.argbExtended.pad = 0;
2026 return color;
2027}
2028
2029/*!
2030 Create and returns an RGB QColor based on this color.
2031
2032 \sa fromRgb(), convertTo(), isValid()
2033*/
2034QColor QColor::toRgb() const noexcept
2035{
2036 if (!isValid() || cspec == Rgb)
2037 return *this;
2038
2039 QColor color;
2040 color.cspec = Rgb;
2041 if (cspec != ExtendedRgb)
2042 color.ct.argb.alpha = ct.argb.alpha;
2043 color.ct.argb.pad = 0;
2044
2045 switch (cspec) {
2046 case Hsv:
2047 {
2048 if (ct.ahsv.saturation == 0 || ct.ahsv.hue == USHRT_MAX) {
2049 // achromatic case
2050 color.ct.argb.red = color.ct.argb.green = color.ct.argb.blue = ct.ahsv.value;
2051 break;
2052 }
2053
2054 // chromatic case
2055 const float h = ct.ahsv.hue == 36000 ? 0.0f : ct.ahsv.hue / 6000.0f;
2056 const float s = ct.ahsv.saturation / float(USHRT_MAX);
2057 const float v = ct.ahsv.value / float(USHRT_MAX);
2058 const int i = int(h);
2059 const float f = h - i;
2060 const float p = v * (1.0f - s);
2061
2062 if (i & 1) {
2063 const float q = v * (1.0f - (s * f));
2064
2065 switch (i) {
2066 case 1:
2067 color.ct.argb.red = qRound(q * USHRT_MAX);
2068 color.ct.argb.green = qRound(v * USHRT_MAX);
2069 color.ct.argb.blue = qRound(p * USHRT_MAX);
2070 break;
2071 case 3:
2072 color.ct.argb.red = qRound(p * USHRT_MAX);
2073 color.ct.argb.green = qRound(q * USHRT_MAX);
2074 color.ct.argb.blue = qRound(v * USHRT_MAX);
2075 break;
2076 case 5:
2077 color.ct.argb.red = qRound(v * USHRT_MAX);
2078 color.ct.argb.green = qRound(p * USHRT_MAX);
2079 color.ct.argb.blue = qRound(q * USHRT_MAX);
2080 break;
2081 }
2082 } else {
2083 const float t = v * (1.0f - (s * (1.0f - f)));
2084
2085 switch (i) {
2086 case 0:
2087 color.ct.argb.red = qRound(v * USHRT_MAX);
2088 color.ct.argb.green = qRound(t * USHRT_MAX);
2089 color.ct.argb.blue = qRound(p * USHRT_MAX);
2090 break;
2091 case 2:
2092 color.ct.argb.red = qRound(p * USHRT_MAX);
2093 color.ct.argb.green = qRound(v * USHRT_MAX);
2094 color.ct.argb.blue = qRound(t * USHRT_MAX);
2095 break;
2096 case 4:
2097 color.ct.argb.red = qRound(t * USHRT_MAX);
2098 color.ct.argb.green = qRound(p * USHRT_MAX);
2099 color.ct.argb.blue = qRound(v * USHRT_MAX);
2100 break;
2101 }
2102 }
2103 break;
2104 }
2105 case Hsl:
2106 {
2107 if (ct.ahsl.saturation == 0 || ct.ahsl.hue == USHRT_MAX) {
2108 // achromatic case
2109 color.ct.argb.red = color.ct.argb.green = color.ct.argb.blue = ct.ahsl.lightness;
2110 } else if (ct.ahsl.lightness == 0) {
2111 // lightness 0
2112 color.ct.argb.red = color.ct.argb.green = color.ct.argb.blue = 0;
2113 } else {
2114 // chromatic case
2115 const float h = ct.ahsl.hue == 36000 ? 0.0f : ct.ahsl.hue / 36000.0f;
2116 const float s = ct.ahsl.saturation / float(USHRT_MAX);
2117 const float l = ct.ahsl.lightness / float(USHRT_MAX);
2118
2119 float temp2;
2120 if (l < 0.5f)
2121 temp2 = l * (1.0f + s);
2122 else
2123 temp2 = l + s - (l * s);
2124
2125 const float temp1 = (2.0f * l) - temp2;
2126 float temp3[3] = { h + (1.0f / 3.0f),
2127 h,
2128 h - (1.0f / 3.0f) };
2129
2130 for (int i = 0; i != 3; ++i) {
2131 if (temp3[i] < 0.0f)
2132 temp3[i] += 1.0f;
2133 else if (temp3[i] > 1.0f)
2134 temp3[i] -= 1.0f;
2135
2136 const float sixtemp3 = temp3[i] * 6.0f;
2137 if (sixtemp3 < 1.0f)
2138 color.ct.array[i+1] = qRound((temp1 + (temp2 - temp1) * sixtemp3) * USHRT_MAX);
2139 else if ((temp3[i] * 2.0f) < 1.0f)
2140 color.ct.array[i+1] = qRound(temp2 * USHRT_MAX);
2141 else if ((temp3[i] * 3.0f) < 2.0f)
2142 color.ct.array[i+1] = qRound((temp1 + (temp2 -temp1) * (2.0f /3.0f - temp3[i]) * 6.0f) * USHRT_MAX);
2143 else
2144 color.ct.array[i+1] = qRound(temp1 * USHRT_MAX);
2145 }
2146 color.ct.argb.red = color.ct.argb.red == 1 ? 0 : color.ct.argb.red;
2147 color.ct.argb.green = color.ct.argb.green == 1 ? 0 : color.ct.argb.green;
2148 color.ct.argb.blue = color.ct.argb.blue == 1 ? 0 : color.ct.argb.blue;
2149 }
2150 break;
2151 }
2152 case Cmyk:
2153 {
2154 const float c = ct.acmyk.cyan / float(USHRT_MAX);
2155 const float m = ct.acmyk.magenta / float(USHRT_MAX);
2156 const float y = ct.acmyk.yellow / float(USHRT_MAX);
2157 const float k = ct.acmyk.black / float(USHRT_MAX);
2158
2159 color.ct.argb.red = qRound((1.0f - (c * (1.0f - k) + k)) * USHRT_MAX);
2160 color.ct.argb.green = qRound((1.0f - (m * (1.0f - k) + k)) * USHRT_MAX);
2161 color.ct.argb.blue = qRound((1.0f - (y * (1.0f - k) + k)) * USHRT_MAX);
2162 break;
2163 }
2164 case ExtendedRgb:
2165 color.ct.argb.alpha = qRound(USHRT_MAX * float(castF16(ct.argbExtended.alphaF16)));
2166 color.ct.argb.red = qRound(USHRT_MAX * qBound(0.0f, float(castF16(ct.argbExtended.redF16)), 1.0f));
2167 color.ct.argb.green = qRound(USHRT_MAX * qBound(0.0f, float(castF16(ct.argbExtended.greenF16)), 1.0f));
2168 color.ct.argb.blue = qRound(USHRT_MAX * qBound(0.0f, float(castF16(ct.argbExtended.blueF16)), 1.0f));
2169 break;
2170 default:
2171 break;
2172 }
2173
2174 return color;
2175}
2176
2177/*!
2178 Creates and returns an HSV QColor based on this color.
2179
2180 \sa fromHsv(), convertTo(), isValid(), {QColor#The HSV Color Model}{The HSV Color Model}
2181*/
2182QColor QColor::toHsv() const noexcept
2183{
2184 if (!isValid() || cspec == Hsv)
2185 return *this;
2186
2187 if (cspec != Rgb)
2188 return toRgb().toHsv();
2189
2190 QColor color;
2191 color.cspec = Hsv;
2192 color.ct.ahsv.alpha = ct.argb.alpha;
2193 color.ct.ahsv.pad = 0;
2194
2195 const ushort r = ct.argb.red;
2196 const ushort g = ct.argb.green;
2197 const ushort b = ct.argb.blue;
2198
2199 // cf. https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
2200 const auto [min, max] = std::minmax({r, g, b});
2201 const auto value = max;
2202 color.ct.ahsv.value = value;
2203 if (max == min) {
2204 // achromatic case, hue is undefined
2205 color.ct.ahsv.hue = USHRT_MAX;
2206 color.ct.ahsv.saturation = 0;
2207 } else {
2208 // chromatic case
2209 const float chroma = max - min; // cannot overflow
2210 float hue;
2211 color.ct.ahsv.saturation = qRound((chroma / value) * USHRT_MAX);
2212 if (value == r) {
2213 hue = 0 + (g - b) / chroma;
2214 // hue = hue mod 6:
2215 if (hue < 0)
2216 hue += 6;
2217 } else if (value == g) {
2218 hue = 2 + (b - r) / chroma;
2219 } else {
2220 Q_ASSERT(value == b); // by construction, `value` is one of r, g, and b!
2221 hue = 4 + (r - g) / chroma;
2222 }
2223 color.ct.ahsv.hue = qRound(hue * (60 * 100));
2224 }
2225
2226 return color;
2227}
2228
2229/*!
2230 Creates and returns an HSL QColor based on this color.
2231
2232 \sa fromHsl(), convertTo(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
2233*/
2234QColor QColor::toHsl() const noexcept
2235{
2236 if (!isValid() || cspec == Hsl)
2237 return *this;
2238
2239 if (cspec != Rgb)
2240 return toRgb().toHsl();
2241
2242 QColor color;
2243 color.cspec = Hsl;
2244 color.ct.ahsl.alpha = ct.argb.alpha;
2245 color.ct.ahsl.pad = 0;
2246
2247 const ushort r = ct.argb.red;
2248 const ushort g = ct.argb.green;
2249 const ushort b = ct.argb.blue;
2250
2251 // cf. https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
2252 const auto [min, max] = std::minmax({r, g, b});
2253 const auto value = max;
2254 if (min == max) {
2255 // achromatic case, hue is undefined
2256 color.ct.ahsl.hue = USHRT_MAX;
2257 color.ct.ahsl.saturation = 0;
2258 color.ct.ahsl.lightness = value;
2259 } else {
2260 // chromatic case
2261 const float chroma = max - min;
2262 const float lightness = 0.5f * (uint{max} + min); // use uint to avoid overflow
2263 color.ct.ahsl.lightness = qRound(lightness);
2264 const float saturation = 0.5f * chroma / (std::min)(lightness, USHRT_MAX - lightness);
2265 color.ct.ahsl.saturation = qRound(saturation * USHRT_MAX);
2266 float hue;
2267 if (value == r) {
2268 hue = 0 + (g - b) / chroma;
2269 // hue = hue mod 6
2270 if (hue < 0)
2271 hue += 6;
2272 } else if (value == g) {
2273 hue = 2 + (b - r) / chroma;
2274 } else {
2275 Q_ASSERT(value == b); // by construction, `value` is one of r, g, and b!
2276 hue = 4 + (r - g) / chroma;
2277 }
2278 color.ct.ahsl.hue = qRound(hue * (60 * 100));
2279 }
2280
2281 return color;
2282}
2283
2284/*!
2285 Creates and returns a CMYK QColor based on this color.
2286
2287 \sa fromCmyk(), convertTo(), isValid(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2288*/
2289QColor QColor::toCmyk() const noexcept
2290{
2291 if (!isValid() || cspec == Cmyk)
2292 return *this;
2293 if (cspec != Rgb)
2294 return toRgb().toCmyk();
2295
2296 QColor color;
2297 color.cspec = Cmyk;
2298 color.ct.acmyk.alpha = ct.argb.alpha;
2299
2300 if (!ct.argb.red && !ct.argb.green && !ct.argb.blue) {
2301 // Avoid div-by-0 below
2302 color.ct.acmyk.cyan = 0;
2303 color.ct.acmyk.magenta = 0;
2304 color.ct.acmyk.yellow = 0;
2305 color.ct.acmyk.black = USHRT_MAX;
2306 } else {
2307 // rgb -> cmy
2308 const float r = ct.argb.red / float(USHRT_MAX);
2309 const float g = ct.argb.green / float(USHRT_MAX);
2310 const float b = ct.argb.blue / float(USHRT_MAX);
2311 float c = 1.0f - r;
2312 float m = 1.0f - g;
2313 float y = 1.0f - b;
2314
2315 // cmy -> cmyk
2316 const float k = qMin(c, qMin(m, y));
2317 c = (c - k) / (1.0f - k);
2318 m = (m - k) / (1.0f - k);
2319 y = (y - k) / (1.0f - k);
2320
2321 color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
2322 color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
2323 color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
2324 color.ct.acmyk.black = qRound(k * USHRT_MAX);
2325 }
2326
2327 return color;
2328}
2329
2330QColor QColor::convertTo(QColor::Spec colorSpec) const noexcept
2331{
2332 if (colorSpec == cspec)
2333 return *this;
2334 switch (colorSpec) {
2335 case Rgb:
2336 return toRgb();
2337 case ExtendedRgb:
2338 return toExtendedRgb();
2339 case Hsv:
2340 return toHsv();
2341 case Cmyk:
2342 return toCmyk();
2343 case Hsl:
2344 return toHsl();
2345 case Invalid:
2346 break;
2347 }
2348 return QColor(); // must be invalid
2349}
2350
2351
2352/*!
2353 Static convenience function that returns a QColor constructed from the
2354 given QRgb value \a rgb.
2355
2356 The alpha component of \a rgb is ignored (i.e. it is automatically set to
2357 255), use the fromRgba() function to include the alpha-channel specified by
2358 the given QRgb value.
2359
2360 \sa fromRgba(), fromRgbF(), toRgb(), isValid()
2361*/
2362
2363QColor QColor::fromRgb(QRgb rgb) noexcept
2364{
2365 return fromRgb(qRed(rgb), qGreen(rgb), qBlue(rgb));
2366}
2367
2368
2369/*!
2370 Static convenience function that returns a QColor constructed from the
2371 given QRgb value \a rgba.
2372
2373 Unlike the fromRgb() function, the alpha-channel specified by the given
2374 QRgb value is included.
2375
2376 \sa fromRgb(), fromRgba64(), isValid()
2377*/
2378
2379QColor QColor::fromRgba(QRgb rgba) noexcept
2380{
2381 return fromRgb(qRed(rgba), qGreen(rgba), qBlue(rgba), qAlpha(rgba));
2382}
2383
2384/*!
2385 Static convenience function that returns a QColor constructed from the RGB
2386 color values, \a r (red), \a g (green), \a b (blue), and \a a
2387 (alpha-channel, i.e. transparency).
2388
2389 All the values must be in the range 0-255.
2390
2391 \sa toRgb(), fromRgba64(), fromRgbF(), isValid()
2392*/
2393QColor QColor::fromRgb(int r, int g, int b, int a)
2394{
2395 if (!isRgbaValid(r, g, b, a)) {
2396 qWarning("QColor::fromRgb: RGB parameters out of range");
2397 return QColor();
2398 }
2399
2400 QColor color;
2401 color.cspec = Rgb;
2402 color.ct.argb.alpha = a * 0x101;
2403 color.ct.argb.red = r * 0x101;
2404 color.ct.argb.green = g * 0x101;
2405 color.ct.argb.blue = b * 0x101;
2406 color.ct.argb.pad = 0;
2407 return color;
2408}
2409
2410/*!
2411 Static convenience function that returns a QColor constructed from the RGB
2412 color values, \a r (red), \a g (green), \a b (blue), and \a a
2413 (alpha-channel, i.e. transparency).
2414
2415 The alpha value must be in the range 0.0-1.0.
2416 If any of the other values are outside the range of 0.0-1.0 the
2417 color model will be set as \c ExtendedRgb.
2418
2419 \sa fromRgb(), fromRgba64(), toRgb(), isValid()
2420*/
2421QColor QColor::fromRgbF(float r, float g, float b, float a)
2422{
2423 if (a < 0.0f || a > 1.0f) {
2424 qWarning("QColor::fromRgbF: Alpha parameter out of range");
2425 return QColor();
2426 }
2427
2428 if (r < 0.0f || r > 1.0f
2429 || g < 0.0f || g > 1.0f
2430 || b < 0.0f || b > 1.0f) {
2431 QColor color;
2432 color.cspec = ExtendedRgb;
2433 castF16(color.ct.argbExtended.alphaF16) = qfloat16(a);
2434 castF16(color.ct.argbExtended.redF16) = qfloat16(r);
2435 castF16(color.ct.argbExtended.greenF16) = qfloat16(g);
2436 castF16(color.ct.argbExtended.blueF16) = qfloat16(b);
2437 color.ct.argbExtended.pad = 0;
2438 return color;
2439 }
2440
2441 QColor color;
2442 color.cspec = Rgb;
2443 color.ct.argb.alpha = qRound(a * USHRT_MAX);
2444 color.ct.argb.red = qRound(r * USHRT_MAX);
2445 color.ct.argb.green = qRound(g * USHRT_MAX);
2446 color.ct.argb.blue = qRound(b * USHRT_MAX);
2447 color.ct.argb.pad = 0;
2448 return color;
2449}
2450
2451
2452/*!
2453 \since 5.6
2454
2455 Static convenience function that returns a QColor constructed from the RGBA64
2456 color values, \a r (red), \a g (green), \a b (blue), and \a a
2457 (alpha-channel, i.e. transparency).
2458
2459 \sa fromRgb(), fromRgbF(), toRgb(), isValid()
2460*/
2461QColor QColor::fromRgba64(ushort r, ushort g, ushort b, ushort a) noexcept
2462{
2463 QColor color;
2464 color.setRgba64(qRgba64(r, g, b, a));
2465 return color;
2466}
2467
2468/*!
2469 \since 5.6
2470
2471 Static convenience function that returns a QColor constructed from the
2472 given QRgba64 value \a rgba64.
2473
2474 \sa fromRgb(), fromRgbF(), toRgb(), isValid()
2475*/
2476QColor QColor::fromRgba64(QRgba64 rgba64) noexcept
2477{
2478 QColor color;
2479 color.setRgba64(rgba64);
2480 return color;
2481}
2482
2483/*!
2484 Static convenience function that returns a QColor constructed from the HSV
2485 color values, \a h (hue), \a s (saturation), \a v (value), and \a a
2486 (alpha-channel, i.e. transparency).
2487
2488 The value of \a s, \a v, and \a a must all be in the range 0-255; the value
2489 of \a h must be in the range 0-359.
2490
2491 \sa toHsv(), fromHsvF(), isValid(), {QColor#The HSV Color Model}{The HSV Color Model}
2492*/
2493QColor QColor::fromHsv(int h, int s, int v, int a)
2494{
2495 if (((h < 0 || h >= 360) && h != -1)
2496 || s < 0 || s > 255
2497 || v < 0 || v > 255
2498 || a < 0 || a > 255) {
2499 qWarning("QColor::fromHsv: HSV parameters out of range");
2500 return QColor();
2501 }
2502
2503 QColor color;
2504 color.cspec = Hsv;
2505 color.ct.ahsv.alpha = a * 0x101;
2506 color.ct.ahsv.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
2507 color.ct.ahsv.saturation = s * 0x101;
2508 color.ct.ahsv.value = v * 0x101;
2509 color.ct.ahsv.pad = 0;
2510 return color;
2511}
2512
2513/*!
2514 \overload
2515
2516 Static convenience function that returns a QColor constructed from the HSV
2517 color values, \a h (hue), \a s (saturation), \a v (value), and \a a
2518 (alpha-channel, i.e. transparency).
2519
2520 All the values must be in the range 0.0-1.0.
2521
2522 \sa toHsv(), fromHsv(), isValid(), {QColor#The HSV Color Model}{The HSV Color Model}
2523*/
2524QColor QColor::fromHsvF(float h, float s, float v, float a)
2525{
2526 if (((h < 0.0f || h > 1.0f) && h != -1.0f)
2527 || (s < 0.0f || s > 1.0f)
2528 || (v < 0.0f || v > 1.0f)
2529 || (a < 0.0f || a > 1.0f)) {
2530 qWarning("QColor::fromHsvF: HSV parameters out of range");
2531 return QColor();
2532 }
2533
2534 QColor color;
2535 color.cspec = Hsv;
2536 color.ct.ahsv.alpha = qRound(a * USHRT_MAX);
2537 color.ct.ahsv.hue = h == -1.0f ? USHRT_MAX : qRound(h * 36000.0f);
2538 color.ct.ahsv.saturation = qRound(s * USHRT_MAX);
2539 color.ct.ahsv.value = qRound(v * USHRT_MAX);
2540 color.ct.ahsv.pad = 0;
2541 return color;
2542}
2543
2544/*!
2545 \since 4.6
2546
2547 Static convenience function that returns a QColor constructed from the HSV
2548 color values, \a h (hue), \a s (saturation), \a l (lightness), and \a a
2549 (alpha-channel, i.e. transparency).
2550
2551 The value of \a s, \a l, and \a a must all be in the range 0-255; the value
2552 of \a h must be in the range 0-359.
2553
2554 \sa toHsl(), fromHslF(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
2555*/
2556QColor QColor::fromHsl(int h, int s, int l, int a)
2557{
2558 if (((h < 0 || h >= 360) && h != -1)
2559 || s < 0 || s > 255
2560 || l < 0 || l > 255
2561 || a < 0 || a > 255) {
2562 qWarning("QColor::fromHsl: HSL parameters out of range");
2563 return QColor();
2564 }
2565
2566 QColor color;
2567 color.cspec = Hsl;
2568 color.ct.ahsl.alpha = a * 0x101;
2569 color.ct.ahsl.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
2570 color.ct.ahsl.saturation = s * 0x101;
2571 color.ct.ahsl.lightness = l * 0x101;
2572 color.ct.ahsl.pad = 0;
2573 return color;
2574}
2575
2576/*!
2577 \overload
2578 \since 4.6
2579
2580 Static convenience function that returns a QColor constructed from the HSV
2581 color values, \a h (hue), \a s (saturation), \a l (lightness), and \a a
2582 (alpha-channel, i.e. transparency).
2583
2584 All the values must be in the range 0.0-1.0.
2585
2586 \sa toHsl(), fromHsl(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model}
2587*/
2588QColor QColor::fromHslF(float h, float s, float l, float a)
2589{
2590 if (((h < 0.0f || h > 1.0f) && h != -1.0f)
2591 || (s < 0.0f || s > 1.0f)
2592 || (l < 0.0f || l > 1.0f)
2593 || (a < 0.0f || a > 1.0f)) {
2594 qWarning("QColor::fromHslF: HSL parameters out of range");
2595 return QColor();
2596 }
2597
2598 QColor color;
2599 color.cspec = Hsl;
2600 color.ct.ahsl.alpha = qRound(a * USHRT_MAX);
2601 color.ct.ahsl.hue = (h == -1.0f) ? USHRT_MAX : qRound(h * 36000.0f);
2602 if (color.ct.ahsl.hue == 36000)
2603 color.ct.ahsl.hue = 0;
2604 color.ct.ahsl.saturation = qRound(s * USHRT_MAX);
2605 color.ct.ahsl.lightness = qRound(l * USHRT_MAX);
2606 color.ct.ahsl.pad = 0;
2607 return color;
2608}
2609
2610/*!
2611 Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
2612 cyan, magenta, yellow, black, and alpha-channel (transparency) components
2613 of the color's CMYK value.
2614
2615 These components can be retrieved individually using the cyan(), magenta(),
2616 yellow(), black() and alpha() functions.
2617
2618 \sa setCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2619*/
2620void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a) const
2621{
2622 if (!c || !m || !y || !k)
2623 return;
2624
2625 if (cspec != Invalid && cspec != Cmyk) {
2626 toCmyk().getCmyk(c, m, y, k, a);
2627 return;
2628 }
2629
2630 *c = qt_div_257(ct.acmyk.cyan);
2631 *m = qt_div_257(ct.acmyk.magenta);
2632 *y = qt_div_257(ct.acmyk.yellow);
2633 *k = qt_div_257(ct.acmyk.black);
2634
2635 if (a)
2636 *a = qt_div_257(ct.acmyk.alpha);
2637}
2638
2639/*!
2640 Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
2641 cyan, magenta, yellow, black, and alpha-channel (transparency) components
2642 of the color's CMYK value.
2643
2644 These components can be retrieved individually using the cyanF(),
2645 magentaF(), yellowF(), blackF() and alphaF() functions.
2646
2647 \sa setCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2648*/
2649void QColor::getCmykF(float *c, float *m, float *y, float *k, float *a) const
2650{
2651 if (!c || !m || !y || !k)
2652 return;
2653
2654 if (cspec != Invalid && cspec != Cmyk) {
2655 toCmyk().getCmykF(c, m, y, k, a);
2656 return;
2657 }
2658
2659 *c = ct.acmyk.cyan / float(USHRT_MAX);
2660 *m = ct.acmyk.magenta / float(USHRT_MAX);
2661 *y = ct.acmyk.yellow / float(USHRT_MAX);
2662 *k = ct.acmyk.black / float(USHRT_MAX);
2663
2664 if (a)
2665 *a = ct.acmyk.alpha / float(USHRT_MAX);
2666}
2667
2668/*!
2669 Sets the color to CMYK values, \a c (cyan), \a m (magenta), \a y (yellow),
2670 \a k (black), and \a a (alpha-channel, i.e. transparency).
2671
2672 All the values must be in the range 0-255.
2673
2674 \sa getCmyk(), setCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2675*/
2676void QColor::setCmyk(int c, int m, int y, int k, int a)
2677{
2678 if (c < 0 || c > 255
2679 || m < 0 || m > 255
2680 || y < 0 || y > 255
2681 || k < 0 || k > 255
2682 || a < 0 || a > 255) {
2683 qWarning("QColor::setCmyk: CMYK parameters out of range");
2684 invalidate();
2685 return;
2686 }
2687
2688 cspec = Cmyk;
2689 ct.acmyk.alpha = a * 0x101;
2690 ct.acmyk.cyan = c * 0x101;
2691 ct.acmyk.magenta = m * 0x101;
2692 ct.acmyk.yellow = y * 0x101;
2693 ct.acmyk.black = k * 0x101;
2694}
2695
2696/*!
2697 \overload
2698
2699 Sets the color to CMYK values, \a c (cyan), \a m (magenta), \a y (yellow),
2700 \a k (black), and \a a (alpha-channel, i.e. transparency).
2701
2702 All the values must be in the range 0.0-1.0.
2703
2704 \sa getCmykF(), setCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2705*/
2706void QColor::setCmykF(float c, float m, float y, float k, float a)
2707{
2708 if (c < 0.0f || c > 1.0f
2709 || m < 0.0f || m > 1.0f
2710 || y < 0.0f || y > 1.0f
2711 || k < 0.0f || k > 1.0f
2712 || a < 0.0f || a > 1.0f) {
2713 qWarning("QColor::setCmykF: CMYK parameters out of range");
2714 invalidate();
2715 return;
2716 }
2717
2718 cspec = Cmyk;
2719 ct.acmyk.alpha = qRound(a * USHRT_MAX);
2720 ct.acmyk.cyan = qRound(c * USHRT_MAX);
2721 ct.acmyk.magenta = qRound(m * USHRT_MAX);
2722 ct.acmyk.yellow = qRound(y * USHRT_MAX);
2723 ct.acmyk.black = qRound(k * USHRT_MAX);
2724}
2725
2726/*!
2727 Static convenience function that returns a QColor constructed from the
2728 given CMYK color values: \a c (cyan), \a m (magenta), \a y (yellow), \a k
2729 (black), and \a a (alpha-channel, i.e. transparency).
2730
2731 All the values must be in the range 0-255.
2732
2733 \sa toCmyk(), fromCmykF(), isValid(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2734*/
2735QColor QColor::fromCmyk(int c, int m, int y, int k, int a)
2736{
2737 if (c < 0 || c > 255
2738 || m < 0 || m > 255
2739 || y < 0 || y > 255
2740 || k < 0 || k > 255
2741 || a < 0 || a > 255) {
2742 qWarning("QColor::fromCmyk: CMYK parameters out of range");
2743 return QColor();
2744 }
2745
2746 QColor color;
2747 color.cspec = Cmyk;
2748 color.ct.acmyk.alpha = a * 0x101;
2749 color.ct.acmyk.cyan = c * 0x101;
2750 color.ct.acmyk.magenta = m * 0x101;
2751 color.ct.acmyk.yellow = y * 0x101;
2752 color.ct.acmyk.black = k * 0x101;
2753 return color;
2754}
2755
2756/*!
2757 \overload
2758
2759 Static convenience function that returns a QColor constructed from the
2760 given CMYK color values: \a c (cyan), \a m (magenta), \a y (yellow), \a k
2761 (black), and \a a (alpha-channel, i.e. transparency).
2762
2763 All the values must be in the range 0.0-1.0.
2764
2765 \sa toCmyk(), fromCmyk(), isValid(), {QColor#The CMYK Color Model}{The CMYK Color Model}
2766*/
2767QColor QColor::fromCmykF(float c, float m, float y, float k, float a)
2768{
2769 if (c < 0.0f || c > 1.0f
2770 || m < 0.0f || m > 1.0f
2771 || y < 0.0f || y > 1.0f
2772 || k < 0.0f || k > 1.0f
2773 || a < 0.0f || a > 1.0f) {
2774 qWarning("QColor::fromCmykF: CMYK parameters out of range");
2775 return QColor();
2776 }
2777
2778 QColor color;
2779 color.cspec = Cmyk;
2780 color.ct.acmyk.alpha = qRound(a * USHRT_MAX);
2781 color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
2782 color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
2783 color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
2784 color.ct.acmyk.black = qRound(k * USHRT_MAX);
2785 return color;
2786}
2787
2788/*!
2789 \fn QColor QColor::lighter(int factor) const
2790 \since 4.3
2791
2792 Returns a lighter (or darker) color, but does not change this object.
2793
2794 If the \a factor is greater than 100, this functions returns a lighter
2795 color. Setting \a factor to 150 returns a color that is 50% brighter. If
2796 the \a factor is less than 100, the return color is darker, but we
2797 recommend using the darker() function for this purpose. If the \a factor
2798 is 0 or negative, the return value is unspecified.
2799
2800 The function converts the current color to HSV, multiplies the value
2801 (V) component by \a factor and converts the color back to it's original
2802 color spec.
2803
2804 \sa darker(), isValid()
2805*/
2806QColor QColor::lighter(int factor) const noexcept
2807{
2808 if (factor <= 0) // invalid lightness factor
2809 return *this;
2810 else if (factor < 100) // makes color darker
2811 return darker(10000 / factor);
2812
2813 QColor hsv = toHsv();
2814 int s = hsv.ct.ahsv.saturation;
2815 uint v = hsv.ct.ahsv.value;
2816
2817 v = (factor*v)/100;
2818 if (v > USHRT_MAX) {
2819 // overflow... adjust saturation
2820 s -= v - USHRT_MAX;
2821 if (s < 0)
2822 s = 0;
2823 v = USHRT_MAX;
2824 }
2825
2826 hsv.ct.ahsv.saturation = s;
2827 hsv.ct.ahsv.value = v;
2828
2829 // convert back to same color spec as original color
2830 return hsv.convertTo(cspec);
2831}
2832
2833/*!
2834 \fn QColor QColor::darker(int factor) const
2835 \since 4.3
2836
2837 Returns a darker (or lighter) color, but does not change this object.
2838
2839 If the \a factor is greater than 100, this functions returns a darker
2840 color. Setting \a factor to 300 returns a color that has one-third the
2841 brightness. If the \a factor is less than 100, the return color is lighter,
2842 but we recommend using the lighter() function for this purpose. If the
2843 \a factor is 0 or negative, the return value is unspecified.
2844
2845 The function converts the current color to HSV, divides the value (V)
2846 component by \a factor and converts the color back to it's original
2847 color spec.
2848
2849 \sa lighter(), isValid()
2850*/
2851QColor QColor::darker(int factor) const noexcept
2852{
2853 if (factor <= 0) // invalid darkness factor
2854 return *this;
2855 else if (factor < 100) // makes color lighter
2856 return lighter(10000 / factor);
2857
2858 QColor hsv = toHsv();
2859 hsv.ct.ahsv.value = (hsv.ct.ahsv.value * 100) / factor;
2860
2861 // convert back to same color spec as original color
2862 return hsv.convertTo(cspec);
2863}
2864
2865/*! \overload
2866 Assigns a copy of \a color and returns a reference to this color.
2867 */
2868QColor &QColor::operator=(Qt::GlobalColor color) noexcept
2869{
2870 return operator=(QColor(color));
2871}
2872
2873/*!
2874 Returns \c true if this color has the same color specification and component values as \a color;
2875 otherwise returns \c false.
2876
2877 ExtendedRgb and Rgb specifications are considered matching in this context.
2878
2879 \sa spec()
2880*/
2881bool QColor::operator==(const QColor &color) const noexcept
2882{
2883 if ((cspec == ExtendedRgb || color.cspec == ExtendedRgb) &&
2884 (cspec == color.cspec || cspec == Rgb || color.cspec == Rgb)) {
2885 return qFuzzyCompare(alphaF(), color.alphaF())
2886 && qFuzzyCompare(redF(), color.redF())
2887 && qFuzzyCompare(greenF(), color.greenF())
2888 && qFuzzyCompare(blueF(), color.blueF());
2889 } else {
2890 return (cspec == color.cspec
2891 && ct.argb.alpha == color.ct.argb.alpha
2892 && (((cspec == QColor::Hsv || cspec == QColor::Hsl)
2893 && ((ct.ahsv.hue % 36000) == (color.ct.ahsv.hue % 36000)))
2894 || (ct.argb.red == color.ct.argb.red))
2895 && ct.argb.green == color.ct.argb.green
2896 && ct.argb.blue == color.ct.argb.blue
2897 && ct.argb.pad == color.ct.argb.pad);
2898 }
2899}
2900
2901/*!
2902 Returns \c true if this color has different color specification or component values from
2903 \a color; otherwise returns \c false.
2904
2905 ExtendedRgb and Rgb specifications are considered matching in this context.
2906
2907 \sa spec()
2908*/
2909bool QColor::operator!=(const QColor &color) const noexcept
2910{ return !operator==(color); }
2911
2912
2913/*!
2914 Returns the color as a QVariant
2915*/
2916QColor::operator QVariant() const
2917{
2918 return QVariant::fromValue(*this);
2919}
2920
2921/*! \internal
2922
2923 Marks the color as invalid and sets all components to zero (alpha is set
2924 to fully opaque for compatibility with Qt 3).
2925*/
2926void QColor::invalidate() noexcept
2927{
2928 cspec = Invalid;
2929 ct.argb.alpha = USHRT_MAX;
2930 ct.argb.red = 0;
2931 ct.argb.green = 0;
2932 ct.argb.blue = 0;
2933 ct.argb.pad = 0;
2934}
2935
2936/*****************************************************************************
2937 QColor stream functions
2938 *****************************************************************************/
2939
2940#ifndef QT_NO_DEBUG_STREAM
2941QDebug operator<<(QDebug dbg, const QColor &c)
2942{
2943 QDebugStateSaver saver(dbg);
2944 if (!c.isValid())
2945 dbg.nospace() << "QColor(Invalid)";
2946 else if (c.spec() == QColor::Rgb)
2947 dbg.nospace() << "QColor(ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ')';
2948 else if (c.spec() == QColor::ExtendedRgb)
2949 dbg.nospace() << "QColor(Ext. ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ')';
2950 else if (c.spec() == QColor::Hsv)
2951 dbg.nospace() << "QColor(AHSV " << c.alphaF() << ", " << c.hueF() << ", " << c.saturationF() << ", " << c.valueF() << ')';
2952 else if (c.spec() == QColor::Cmyk)
2953 dbg.nospace() << "QColor(ACMYK " << c.alphaF() << ", " << c.cyanF() << ", " << c.magentaF() << ", " << c.yellowF() << ", "
2954 << c.blackF()<< ')';
2955 else if (c.spec() == QColor::Hsl)
2956 dbg.nospace() << "QColor(AHSL " << c.alphaF() << ", " << c.hslHueF() << ", " << c.hslSaturationF() << ", " << c.lightnessF() << ')';
2957
2958 return dbg;
2959}
2960#endif
2961
2962#ifndef QT_NO_DATASTREAM
2963/*!
2964 \fn QDataStream &operator<<(QDataStream &stream, const QColor &color)
2965 \relates QColor
2966
2967 Writes the \a color to the \a stream.
2968
2969 \sa {Serializing Qt Data Types}
2970*/
2971QDataStream &operator<<(QDataStream &stream, const QColor &color)
2972{
2973 if (stream.version() < 7) {
2974 if (!color.isValid())
2975 return stream << quint32(0x49000000);
2976 quint32 p = (quint32)color.rgb();
2977 if (stream.version() == 1) // Swap red and blue
2978 p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
2979 return stream << p;
2980 }
2981
2982 qint8 s = color.cspec;
2983 quint16 a = color.ct.argb.alpha;
2984 quint16 r = color.ct.argb.red;
2985 quint16 g = color.ct.argb.green;
2986 quint16 b = color.ct.argb.blue;
2987 quint16 p = color.ct.argb.pad;
2988
2989 stream << s;
2990 stream << a;
2991 stream << r;
2992 stream << g;
2993 stream << b;
2994 stream << p;
2995
2996 return stream;
2997}
2998
2999/*!
3000 \fn QDataStream &operator>>(QDataStream &stream, QColor &color)
3001 \relates QColor
3002
3003 Reads the \a color from the \a stream.
3004
3005 \sa {Serializing Qt Data Types}
3006*/
3007QDataStream &operator>>(QDataStream &stream, QColor &color)
3008{
3009 if (stream.version() < 7) {
3010 quint32 p;
3011 stream >> p;
3012 if (p == 0x49000000) {
3013 color.invalidate();
3014 return stream;
3015 }
3016 if (stream.version() == 1) // Swap red and blue
3017 p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
3018 color.setRgb(p);
3019 return stream;
3020 }
3021
3022 qint8 s;
3023 quint16 a, r, g, b, p;
3024 stream >> s;
3025 stream >> a;
3026 stream >> r;
3027 stream >> g;
3028 stream >> b;
3029 stream >> p;
3030
3031 color.cspec = QColor::Spec(s);
3032 color.ct.argb.alpha = a;
3033 color.ct.argb.red = r;
3034 color.ct.argb.green = g;
3035 color.ct.argb.blue = b;
3036 color.ct.argb.pad = p;
3037
3038 return stream;
3039}
3040#endif // QT_NO_DATASTREAM
3041
3042// A table of precalculated results of 0x00ff00ff/alpha use by qUnpremultiply:
3043const uint qt_inv_premul_factor[256] = {
3044 0, 16711935, 8355967, 5570645, 4177983, 3342387, 2785322, 2387419,
3045 2088991, 1856881, 1671193, 1519266, 1392661, 1285533, 1193709, 1114129,
3046 1044495, 983055, 928440, 879575, 835596, 795806, 759633, 726605,
3047 696330, 668477, 642766, 618960, 596854, 576273, 557064, 539094,
3048 522247, 506422, 491527, 477483, 464220, 451673, 439787, 428511,
3049 417798, 407608, 397903, 388649, 379816, 371376, 363302, 355573,
3050 348165, 341059, 334238, 327685, 321383, 315319, 309480, 303853,
3051 298427, 293191, 288136, 283253, 278532, 273966, 269547, 265268,
3052 261123, 257106, 253211, 249431, 245763, 242201, 238741, 235379,
3053 232110, 228930, 225836, 222825, 219893, 217038, 214255, 211543,
3054 208899, 206320, 203804, 201348, 198951, 196611, 194324, 192091,
3055 189908, 187774, 185688, 183647, 181651, 179698, 177786, 175915,
3056 174082, 172287, 170529, 168807, 167119, 165464, 163842, 162251,
3057 160691, 159161, 157659, 156186, 154740, 153320, 151926, 150557,
3058 149213, 147893, 146595, 145321, 144068, 142837, 141626, 140436,
3059 139266, 138115, 136983, 135869, 134773, 133695, 132634, 131590,
3060 130561, 129549, 128553, 127572, 126605, 125653, 124715, 123792,
3061 122881, 121984, 121100, 120229, 119370, 118524, 117689, 116866,
3062 116055, 115254, 114465, 113686, 112918, 112160, 111412, 110675,
3063 109946, 109228, 108519, 107818, 107127, 106445, 105771, 105106,
3064 104449, 103800, 103160, 102527, 101902, 101284, 100674, 100071,
3065 99475, 98887, 98305, 97730, 97162, 96600, 96045, 95496,
3066 94954, 94417, 93887, 93362, 92844, 92331, 91823, 91322,
3067 90825, 90334, 89849, 89368, 88893, 88422, 87957, 87497,
3068 87041, 86590, 86143, 85702, 85264, 84832, 84403, 83979,
3069 83559, 83143, 82732, 82324, 81921, 81521, 81125, 80733,
3070 80345, 79961, 79580, 79203, 78829, 78459, 78093, 77729,
3071 77370, 77013, 76660, 76310, 75963, 75619, 75278, 74941,
3072 74606, 74275, 73946, 73620, 73297, 72977, 72660, 72346,
3073 72034, 71725, 71418, 71114, 70813, 70514, 70218, 69924,
3074 69633, 69344, 69057, 68773, 68491, 68211, 67934, 67659,
3075 67386, 67116, 66847, 66581, 66317, 66055, 65795, 65537
3076};
3077
3078/*****************************************************************************
3079 QColor global functions (documentation only)
3080 *****************************************************************************/
3081
3082/*!
3083 \fn int qRed(QRgb rgb)
3084 \relates QColor
3085
3086 Returns the red component of the ARGB quadruplet \a rgb.
3087
3088 \sa qRgb(), QColor::red()
3089*/
3090
3091/*!
3092 \fn int qGreen(QRgb rgb)
3093 \relates QColor
3094
3095 Returns the green component of the ARGB quadruplet \a rgb.
3096
3097 \sa qRgb(), QColor::green()
3098*/
3099
3100/*!
3101 \fn int qBlue(QRgb rgb)
3102 \relates QColor
3103
3104 Returns the blue component of the ARGB quadruplet \a rgb.
3105
3106 \sa qRgb(), QColor::blue()
3107*/
3108
3109/*!
3110 \fn int qAlpha(QRgb rgba)
3111 \relates QColor
3112
3113 Returns the alpha component of the ARGB quadruplet \a rgba.
3114
3115 \sa qRgb(), QColor::alpha()
3116*/
3117
3118/*!
3119 \fn QRgb qRgb(int r, int g, int b)
3120 \relates QColor
3121
3122 Returns the ARGB quadruplet (255, \a{r}, \a{g}, \a{b}).
3123
3124 \sa qRgba(), qRed(), qGreen(), qBlue(), qAlpha()
3125*/
3126
3127/*!
3128 \fn QRgb qRgba(int r, int g, int b, int a)
3129 \relates QColor
3130
3131 Returns the ARGB quadruplet (\a{a}, \a{r}, \a{g}, \a{b}).
3132
3133 \sa qRgb(), qRed(), qGreen(), qBlue(), qAlpha()
3134*/
3135
3136/*!
3137 \fn int qGray(int r, int g, int b)
3138 \relates QColor
3139
3140 Returns a gray value (0 to 255) from the (\a r, \a g, \a b)
3141 triplet.
3142
3143 The gray value is calculated using the formula (\a r * 11 + \a g * 16 +
3144 \a b * 5)/32.
3145*/
3146
3147/*!
3148 \fn int qGray(QRgb rgb)
3149 \overload
3150 \relates QColor
3151
3152 Returns a gray value (0 to 255) from the given ARGB quadruplet \a rgb.
3153
3154 The gray value is calculated using the formula (R * 11 + G * 16 + B * 5)/32;
3155 the alpha-channel is ignored.
3156*/
3157
3158/*!
3159 \fn QRgb qPremultiply(QRgb rgb)
3160 \since 5.3
3161 \relates QColor
3162
3163 Converts an unpremultiplied ARGB quadruplet \a rgb into a premultiplied ARGB quadruplet.
3164
3165 \sa qUnpremultiply()
3166*/
3167
3168/*!
3169 \fn QRgb qUnpremultiply(QRgb rgb)
3170 \since 5.3
3171 \relates QColor
3172
3173 Converts a premultiplied ARGB quadruplet \a rgb into an unpremultiplied ARGB quadruplet.
3174
3175 \sa qPremultiply()
3176*/
3177
3178/*!
3179 \fn QColor QColor::convertTo(Spec colorSpec) const
3180
3181 Creates a copy of \e this color in the format specified by \a colorSpec.
3182
3183 \sa spec(), toCmyk(), toHsv(), toRgb(), isValid()
3184*/
3185
3186/*!
3187 \typedef QRgb
3188 \relates QColor
3189
3190 An ARGB quadruplet on the format #AARRGGBB, equivalent to an unsigned int.
3191
3192 The type also holds a value for the alpha-channel. The default alpha
3193 channel is \c ff, i.e opaque. For more information, see the
3194 \l{QColor#Alpha-Blended Drawing}{Alpha-Blended Drawing} section.
3195
3196 Here are some examples of how QRgb values can be created:
3197
3198 \snippet code/src_gui_painting_qcolor.cpp QRgb
3199
3200 \sa qRgb(), qRgba(), QColor::rgb(), QColor::rgba()
3201*/
3202
3203/*!
3204 \namespace QColorConstants
3205 \inmodule QtGui
3206 \since 5.14
3207
3208 \brief The QColorConstants namespace contains QColor predefined constants.
3209
3210 These constants are usable everywhere a QColor object is expected:
3211
3212 \code
3213 painter.setBrush(QColorConstants::Svg::lightblue);
3214 \endcode
3215
3216 Their usage is much cheaper than e.g. passing a string to QColor's constructor,
3217 as they don't require any parsing of the string, and always result in a valid
3218 QColor object:
3219
3220 \badcode
3221 object.setColor(QColor("lightblue")); // expensive
3222 \endcode
3223
3224 \section1 Qt Colors
3225
3226 The following colors are defined in the \c{QColorConstants} namespace:
3227
3228 \include qt-colors.qdocinc
3229
3230 \section1 SVG Colors
3231
3232 The following table lists the available
3233 \l {http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG colors}.
3234 They are available in the \c{QColorConstants::Svg} inner namespace.
3235
3236 \include svg-colors.qdocinc
3237
3238 \sa QColor, Qt::GlobalColor
3239*/
3240
3241QT_END_NAMESPACE
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
Definition qfloat16.h:57
static QStringList get_colornames()
Definition qcolor.cpp:334
std::optional< QRgb > qt_get_hex_rgb(const char *name)
Definition qcolor.cpp:91
QDataStream & operator>>(QDataStream &stream, QColor &color)
Definition qcolor.cpp:3007
const uint qt_inv_premul_factor[256]
Definition qcolor.cpp:3043
static const qfloat16 & castF16(const quint16 &v)
Definition qcolor.cpp:1236
QT_BEGIN_NAMESPACE
Definition qcolor.cpp:26
#define rgb(r, g, b)
Definition qcolor.cpp:125
static std::optional< QRgb > get_named_rgb(QAnyStringView name)
Definition qcolor.cpp:315
static std::optional< QRgba64 > get_hex_rgb(QAnyStringView name)
Definition qcolor.cpp:109
static std::optional< QRgba64 > get_hex_rgb(const char *name, size_t len)
Definition qcolor.cpp:49
static std::optional< QRgb > get_named_rgb_no_space(const char *name_no_space)
Definition qcolor.cpp:301
static const int rgbTblSize
Definition qcolor.cpp:282
#define QCOLOR_INT_RANGE_CHECK(fn, var)
Definition qcolor.cpp:580
bool operator<(const RGBData &data, const char *name)
Definition qcolor.cpp:298
static qfloat16 & castF16(quint16 &v)
Definition qcolor.cpp:1230
static std::optional< QRgba64 > get_hex_rgb(const QChar *str, size_t len)
Definition qcolor.cpp:98
#define QRGBA(r, g, b, a)
QDebug operator<<(QDebug dbg, const QColor &c)
Definition qcolor.cpp:2941
#define QCOLOR_REAL_RANGE_CHECK(fn, var)
Definition qcolor.cpp:588
bool operator<(const char *name, const RGBData &data)
Definition qcolor.cpp:296
#define QRGB(r, g, b)
const char name[21]
Definition qcolor.cpp:129
uint value
Definition qcolor.cpp:130