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