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