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