00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qcolor.h"
00025 #include "qcolor_p.h"
00026 #include "qnamespace.h"
00027 #include "qcolormap.h"
00028 #include "qdatastream.h"
00029 #include "qvariant.h"
00030 #include "qdebug.h"
00031
00032 #include <math.h>
00033 #include <stdio.h>
00034 #include <limits.h>
00035
00036
00249 #define QCOLOR_INT_RANGE_CHECK(fn, var) \
00250 do { \
00251 if (var < 0 || var > 255) { \
00252 qWarning(#fn": invalid value %d", var); \
00253 var = qMax(0, qMin(var, 255)); \
00254 } \
00255 } while (0)
00256
00257 #define QCOLOR_REAL_RANGE_CHECK(fn, var) \
00258 do { \
00259 if (var < qreal(0.0) || var > qreal(1.0)) { \
00260 qWarning(#fn": invalid value %g", var); \
00261 var = qMax(qreal(0.0), qMin(var, qreal(1.0))); \
00262 } \
00263 } while (0)
00264
00265
00266
00267
00268
00310 QColor::QColor(Qt::GlobalColor color)
00311 {
00312 #define QRGB(r, g, b) \
00313 QRgb(((0xff << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)))
00314 #define QRGBA(r, g, b, a) \
00315 QRgb(((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff))
00316
00317 static const QRgb global_colors[] = {
00318 QRGB(255, 255, 255),
00319 QRGB( 0, 0, 0),
00320 QRGB( 0, 0, 0),
00321 QRGB(255, 255, 255),
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 QRGB(128, 128, 128),
00342 QRGB(160, 160, 164),
00343 QRGB(192, 192, 192),
00344 QRGB(255, 0, 0),
00345 QRGB( 0, 255, 0),
00346 QRGB( 0, 0, 255),
00347 QRGB( 0, 255, 255),
00348 QRGB(255, 0, 255),
00349 QRGB(255, 255, 0),
00350 QRGB(128, 0, 0),
00351 QRGB( 0, 128, 0),
00352 QRGB( 0, 0, 128),
00353 QRGB( 0, 128, 128),
00354 QRGB(128, 0, 128),
00355 QRGB(128, 128, 0),
00356 QRGBA(0, 0, 0, 0)
00357 };
00358 #undef QRGB
00359 #undef QRGBA
00360
00361 setRgb(qRed(global_colors[color]),
00362 qGreen(global_colors[color]),
00363 qBlue(global_colors[color]),
00364 qAlpha(global_colors[color]));
00365 }
00366
00385 QColor::QColor(QRgb color)
00386 {
00387 cspec = Rgb;
00388 ct.argb.alpha = 0xffff;
00389 ct.argb.red = qRed(color) * 0x101;
00390 ct.argb.green = qGreen(color) * 0x101;
00391 ct.argb.blue = qBlue(color) * 0x101;
00392 ct.argb.pad = 0;
00393 }
00394
00395
00405 QColor::QColor(Spec spec)
00406 {
00407 switch (spec) {
00408 case Invalid:
00409 invalidate();
00410 break;
00411 case Rgb:
00412 setRgb(0, 0, 0);
00413 break;
00414 case Hsv:
00415 setHsv(0, 0, 0);
00416 break;
00417 case Cmyk:
00418 setCmyk(0, 0, 0, 0);
00419 break;
00420 }
00421 }
00422
00466 QString QColor::name() const
00467 {
00468 QString s;
00469 s.sprintf("#%02x%02x%02x", red(), green(), blue());
00470 return s;
00471 }
00472
00493 void QColor::setNamedColor(const QString &name)
00494 {
00495 if (name.isEmpty()) {
00496 invalidate();
00497 return;
00498 }
00499
00500 QByteArray n = name.toLatin1();
00501 if (n.startsWith('#')) {
00502 QRgb rgb;
00503 if (qt_get_hex_rgb(n, &rgb)) {
00504 setRgb(rgb);
00505 } else {
00506 qWarning("QColor::setNamedColor: Could not parse color '%s'", n.constData());
00507 invalidate();
00508 }
00509 return;
00510 }
00511
00512 QRgb rgb;
00513 if (qt_get_named_rgb(n, &rgb)) {
00514 setRgb(rgb);
00515 } else {
00516 qWarning("QColor::setNamedColor: Unknown color name '%s'", n.constData());
00517 invalidate();
00518 }
00519 }
00520
00526 QStringList QColor::colorNames()
00527 {
00528 return qt_get_colornames();
00529 }
00530
00541 void QColor::getHsvF(qreal *h, qreal *s, qreal *v, qreal *a) const
00542 {
00543 if (!h || !s || !v)
00544 return;
00545
00546 if (cspec != Invalid && cspec != Hsv) {
00547 toHsv().getHsvF(h, s, v, a);
00548 return;
00549 }
00550
00551 *h = ct.ahsv.hue == USHRT_MAX ? -1.0 : ct.ahsv.hue / 36000.0;
00552 *s = ct.ahsv.saturation / qreal(USHRT_MAX);
00553 *v = ct.ahsv.value / qreal(USHRT_MAX);
00554
00555 if (a)
00556 *a = ct.ahsv.alpha / qreal(USHRT_MAX);
00557 }
00558
00569 void QColor::getHsv(int *h, int *s, int *v, int *a) const
00570 {
00571 if (!h || !s || !v)
00572 return;
00573
00574 if (cspec != Invalid && cspec != Hsv) {
00575 toHsv().getHsv(h, s, v, a);
00576 return;
00577 }
00578
00579 *h = ct.ahsv.hue == USHRT_MAX ? -1 : ct.ahsv.hue / 100;
00580 *s = ct.ahsv.saturation >> 8;
00581 *v = ct.ahsv.value >> 8;
00582
00583 if (a)
00584 *a = ct.ahsv.alpha >> 8;
00585 }
00586
00597 void QColor::setHsvF(qreal h, qreal s, qreal v, qreal a)
00598 {
00599 if (((h < 0.0 || h > 1.0) && h != -1.0)
00600 || (s < 0.0 || s > 1.0)
00601 || (v < 0.0 || v > 1.0)
00602 || (a < 0.0 || a > 1.0)) {
00603 qWarning("QColor::setHsvF: HSV parameters out of range");
00604 return;
00605 }
00606
00607 cspec = Hsv;
00608 ct.ahsv.alpha = qRound(a * USHRT_MAX);
00609 ct.ahsv.hue = h == -1.0 ? USHRT_MAX : qRound(h * 36000);
00610 ct.ahsv.saturation = qRound(s * USHRT_MAX);
00611 ct.ahsv.value = qRound(v * USHRT_MAX);
00612 ct.ahsv.pad = 0;
00613 }
00614
00626 void QColor::setHsv(int h, int s, int v, int a)
00627 {
00628 if (h < -1 || (uint)s > 255 || (uint)v > 255 || (uint)a > 255) {
00629 qWarning("QColor::setHsv: HSV parameters out of range");
00630 invalidate();
00631 return;
00632 }
00633
00634 cspec = Hsv;
00635 ct.ahsv.alpha = a * 0x101;
00636 ct.ahsv.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
00637 ct.ahsv.saturation = s * 0x101;
00638 ct.ahsv.value = v * 0x101;
00639 ct.ahsv.pad = 0;
00640 }
00641
00652 void QColor::getRgbF(qreal *r, qreal *g, qreal *b, qreal *a) const
00653 {
00654 if (!r || !g || !b)
00655 return;
00656
00657 if (cspec != Invalid && cspec != Rgb) {
00658 toRgb().getRgbF(r, g, b, a);
00659 return;
00660 }
00661
00662 *r = ct.argb.red / qreal(USHRT_MAX);
00663 *g = ct.argb.green / qreal(USHRT_MAX);
00664 *b = ct.argb.blue / qreal(USHRT_MAX);
00665
00666 if (a)
00667 *a = ct.argb.alpha / qreal(USHRT_MAX);
00668
00669 }
00670
00681 void QColor::getRgb(int *r, int *g, int *b, int *a) const
00682 {
00683 if (!r || !g || !b)
00684 return;
00685
00686 if (cspec != Invalid && cspec != Rgb) {
00687 toRgb().getRgb(r, g, b, a);
00688 return;
00689 }
00690
00691 *r = ct.argb.red >> 8;
00692 *g = ct.argb.green >> 8;
00693 *b = ct.argb.blue >> 8;
00694
00695 if (a)
00696 *a = ct.argb.alpha >> 8;
00697 }
00698
00716 void QColor::setRgbF(qreal r, qreal g, qreal b, qreal a)
00717 {
00718 if (r < 0.0 || r > 1.0
00719 || g < 0.0 || g > 1.0
00720 || b < 0.0 || b > 1.0
00721 || a < 0.0 || a > 1.0) {
00722 qWarning("QColor::setRgbF: RGB parameters out of range");
00723 invalidate();
00724 return;
00725 }
00726
00727 cspec = Rgb;
00728 ct.argb.alpha = qRound(a * USHRT_MAX);
00729 ct.argb.red = qRound(r * USHRT_MAX);
00730 ct.argb.green = qRound(g * USHRT_MAX);
00731 ct.argb.blue = qRound(b * USHRT_MAX);
00732 ct.argb.pad = 0;
00733 }
00734
00743 void QColor::setRgb(int r, int g, int b, int a)
00744 {
00745 if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255 || (uint)a > 255) {
00746 qWarning("QColor::setRgb: RGB parameters out of range");
00747 invalidate();
00748 return;
00749 }
00750
00751 cspec = Rgb;
00752 ct.argb.alpha = a * 0x101;
00753 ct.argb.red = r * 0x101;
00754 ct.argb.green = g * 0x101;
00755 ct.argb.blue = b * 0x101;
00756 ct.argb.pad = 0;
00757 }
00758
00778 QRgb QColor::rgba() const
00779 {
00780 if (cspec != Invalid && cspec != Rgb)
00781 return toRgb().rgba();
00782 return qRgba(ct.argb.red >> 8, ct.argb.green >> 8, ct.argb.blue >> 8, ct.argb.alpha >> 8);
00783 }
00784
00791 void QColor::setRgba(QRgb rgba)
00792 {
00793 cspec = Rgb;
00794 ct.argb.alpha = qAlpha(rgba) * 0x101;
00795 ct.argb.red = qRed(rgba) * 0x101;
00796 ct.argb.green = qGreen(rgba) * 0x101;
00797 ct.argb.blue = qBlue(rgba) * 0x101;
00798 ct.argb.pad = 0;
00799 }
00800
00808 QRgb QColor::rgb() const
00809 {
00810 if (cspec != Invalid && cspec != Rgb)
00811 return toRgb().rgb();
00812 return qRgb(ct.argb.red >> 8, ct.argb.green >> 8, ct.argb.blue >> 8);
00813 }
00814
00820 void QColor::setRgb(QRgb rgb)
00821 {
00822 cspec = Rgb;
00823 ct.argb.alpha = 0xffff;
00824 ct.argb.red = qRed(rgb) * 0x101;
00825 ct.argb.green = qGreen(rgb) * 0x101;
00826 ct.argb.blue = qBlue(rgb) * 0x101;
00827 ct.argb.pad = 0;
00828 }
00829
00836 int QColor::alpha() const
00837 { return ct.argb.alpha >> 8; }
00838
00839
00848 void QColor::setAlpha(int alpha)
00849 {
00850 QCOLOR_INT_RANGE_CHECK("QColor::setAlpha", alpha);
00851 ct.argb.alpha = alpha * 0x101;
00852 }
00853
00860 qreal QColor::alphaF() const
00861 { return ct.argb.alpha / qreal(USHRT_MAX); }
00862
00871 void QColor::setAlphaF(qreal alpha)
00872 {
00873 QCOLOR_REAL_RANGE_CHECK("QColor::setAlphaF", alpha);
00874 qreal tmp = alpha * USHRT_MAX;
00875 ct.argb.alpha = qRound(tmp);
00876 }
00877
00878
00884 int QColor::red() const
00885 {
00886 if (cspec != Invalid && cspec != Rgb)
00887 return toRgb().red();
00888 return ct.argb.red >> 8;
00889 }
00890
00897 void QColor::setRed(int red)
00898 {
00899 QCOLOR_INT_RANGE_CHECK("QColor::setRed", red);
00900 if (cspec != Rgb)
00901 setRgb(red, green(), blue(), alpha());
00902 else
00903 ct.argb.red = red * 0x101;
00904 }
00905
00911 int QColor::green() const
00912 {
00913 if (cspec != Invalid && cspec != Rgb)
00914 return toRgb().green();
00915 return ct.argb.green >> 8;
00916 }
00917
00924 void QColor::setGreen(int green)
00925 {
00926 QCOLOR_INT_RANGE_CHECK("QColor::setGreen", green);
00927 if (cspec != Rgb)
00928 setRgb(red(), green, blue(), alpha());
00929 else
00930 ct.argb.green = green * 0x101;
00931 }
00932
00933
00939 int QColor::blue() const
00940 {
00941 if (cspec != Invalid && cspec != Rgb)
00942 return toRgb().blue();
00943 return ct.argb.blue >> 8;
00944 }
00945
00946
00953 void QColor::setBlue(int blue)
00954 {
00955 QCOLOR_INT_RANGE_CHECK("QColor::setBlue", blue);
00956 if (cspec != Rgb)
00957 setRgb(red(), green(), blue, alpha());
00958 else
00959 ct.argb.blue = blue * 0x101;
00960 }
00961
00967 qreal QColor::redF() const
00968 {
00969 if (cspec != Invalid && cspec != Rgb)
00970 return toRgb().redF();
00971 return ct.argb.red / qreal(USHRT_MAX);
00972 }
00973
00974
00981 void QColor::setRedF(qreal red)
00982 {
00983 QCOLOR_REAL_RANGE_CHECK("QColor::setRedF", red);
00984 if (cspec != Rgb)
00985 setRgbF(red, greenF(), blueF(), alphaF());
00986 else
00987 ct.argb.red = qRound(red * USHRT_MAX);
00988 }
00989
00995 qreal QColor::greenF() const
00996 {
00997 if (cspec != Invalid && cspec != Rgb)
00998 return toRgb().greenF();
00999 return ct.argb.green / qreal(USHRT_MAX);
01000 }
01001
01002
01009 void QColor::setGreenF(qreal green)
01010 {
01011 QCOLOR_REAL_RANGE_CHECK("QColor::setGreenF", green);
01012 if (cspec != Rgb)
01013 setRgbF(redF(), green, blueF(), alphaF());
01014 else
01015 ct.argb.green = qRound(green * USHRT_MAX);
01016 }
01017
01023 qreal QColor::blueF() const
01024 {
01025 if (cspec != Invalid && cspec != Rgb)
01026 return toRgb().blueF();
01027 return ct.argb.blue / qreal(USHRT_MAX);
01028 }
01029
01036 void QColor::setBlueF(qreal blue)
01037 {
01038 QCOLOR_REAL_RANGE_CHECK("QColor::setBlueF", blue);
01039 if (cspec != Rgb)
01040 setRgbF(redF(), greenF(), blue, alphaF());
01041 else
01042 ct.argb.blue = qRound(blue * USHRT_MAX);
01043 }
01044
01051 int QColor::hue() const
01052 {
01053 if (cspec != Invalid && cspec != Hsv)
01054 return toHsv().hue();
01055 return ct.ahsv.hue == USHRT_MAX ? -1 : ct.ahsv.hue / 100;
01056 }
01057
01064 int QColor::saturation() const
01065 {
01066 if (cspec != Invalid && cspec != Hsv)
01067 return toHsv().saturation();
01068 return ct.ahsv.saturation >> 8;
01069 }
01070
01077 int QColor::value() const
01078 {
01079 if (cspec != Invalid && cspec != Hsv)
01080 return toHsv().value();
01081 return ct.ahsv.value >> 8;
01082 }
01083
01090 qreal QColor::hueF() const
01091 {
01092 if (cspec != Invalid && cspec != Hsv)
01093 return toHsv().hueF();
01094 return ct.ahsv.hue == USHRT_MAX ? -1.0 : ct.ahsv.hue / 36000.0;
01095 }
01096
01103 qreal QColor::saturationF() const
01104 {
01105 if (cspec != Invalid && cspec != Hsv)
01106 return toHsv().saturationF();
01107 return ct.ahsv.saturation / qreal(USHRT_MAX);
01108 }
01109
01116 qreal QColor::valueF() const
01117 {
01118 if (cspec != Invalid && cspec != Hsv)
01119 return toHsv().valueF();
01120 return ct.ahsv.value / qreal(USHRT_MAX);
01121 }
01122
01129 int QColor::cyan() const
01130 {
01131 if (cspec != Invalid && cspec != Cmyk)
01132 return toCmyk().cyan();
01133 return ct.acmyk.cyan >> 8;
01134 }
01135
01142 int QColor::magenta() const
01143 {
01144 if (cspec != Invalid && cspec != Cmyk)
01145 return toCmyk().magenta();
01146 return ct.acmyk.magenta >> 8;
01147 }
01148
01155 int QColor::yellow() const
01156 {
01157 if (cspec != Invalid && cspec != Cmyk)
01158 return toCmyk().yellow();
01159 return ct.acmyk.yellow >> 8;
01160 }
01161
01169 int QColor::black() const
01170 {
01171 if (cspec != Invalid && cspec != Cmyk)
01172 return toCmyk().black();
01173 return ct.acmyk.black >> 8;
01174 }
01175
01182 qreal QColor::cyanF() const
01183 {
01184 if (cspec != Invalid && cspec != Cmyk)
01185 return toCmyk().cyanF();
01186 return ct.acmyk.cyan / qreal(USHRT_MAX);
01187 }
01188
01195 qreal QColor::magentaF() const
01196 {
01197 if (cspec != Invalid && cspec != Cmyk)
01198 return toCmyk().magentaF();
01199 return ct.acmyk.magenta / qreal(USHRT_MAX);
01200 }
01201
01208 qreal QColor::yellowF() const
01209 {
01210 if (cspec != Invalid && cspec != Cmyk)
01211 return toCmyk().yellowF();
01212 return ct.acmyk.yellow / qreal(USHRT_MAX);
01213 }
01214
01221 qreal QColor::blackF() const
01222 {
01223 if (cspec != Invalid && cspec != Cmyk)
01224 return toCmyk().blackF();
01225 return ct.acmyk.black / qreal(USHRT_MAX);
01226 }
01227
01233 QColor QColor::toRgb() const
01234 {
01235 if (!isValid() || cspec == Rgb)
01236 return *this;
01237
01238 QColor color;
01239 color.cspec = Rgb;
01240 color.ct.argb.alpha = ct.argb.alpha;
01241 color.ct.argb.pad = 0;
01242
01243 switch (cspec) {
01244 case Hsv:
01245 {
01246 if (ct.ahsv.saturation == 0 || ct.ahsv.hue == USHRT_MAX) {
01247
01248 color.ct.argb.red = color.ct.argb.green = color.ct.argb.blue = ct.ahsv.value;
01249 break;
01250 }
01251
01252
01253 const qreal h = ct.ahsv.hue / 6000.;
01254 const qreal s = ct.ahsv.saturation / qreal(USHRT_MAX);
01255 const qreal v = ct.ahsv.value / qreal(USHRT_MAX);
01256 const int i = int(h);
01257 const qreal f = h - i;
01258 const qreal p = v * (1.0 - s);
01259
01260 if (i & 1) {
01261 const qreal q = v * (1.0 - (s * f));
01262
01263 switch (i) {
01264 case 1:
01265 color.ct.argb.red = qRound(q * USHRT_MAX);
01266 color.ct.argb.green = qRound(v * USHRT_MAX);
01267 color.ct.argb.blue = qRound(p * USHRT_MAX);
01268 break;
01269 case 3:
01270 color.ct.argb.red = qRound(p * USHRT_MAX);
01271 color.ct.argb.green = qRound(q * USHRT_MAX);
01272 color.ct.argb.blue = qRound(v * USHRT_MAX);
01273 break;
01274 case 5:
01275 color.ct.argb.red = qRound(v * USHRT_MAX);
01276 color.ct.argb.green = qRound(p * USHRT_MAX);
01277 color.ct.argb.blue = qRound(q * USHRT_MAX);
01278 break;
01279 }
01280 } else {
01281 const qreal t = v * (1.0 - (s * (1.0 - f)));
01282
01283 switch (i) {
01284 case 0:
01285 color.ct.argb.red = qRound(v * USHRT_MAX);
01286 color.ct.argb.green = qRound(t * USHRT_MAX);
01287 color.ct.argb.blue = qRound(p * USHRT_MAX);
01288 break;
01289 case 2:
01290 color.ct.argb.red = qRound(p * USHRT_MAX);
01291 color.ct.argb.green = qRound(v * USHRT_MAX);
01292 color.ct.argb.blue = qRound(t * USHRT_MAX);
01293 break;
01294 case 4:
01295 color.ct.argb.red = qRound(t * USHRT_MAX);
01296 color.ct.argb.green = qRound(p * USHRT_MAX);
01297 color.ct.argb.blue = qRound(v * USHRT_MAX);
01298 break;
01299 }
01300 }
01301 break;
01302 }
01303 case Cmyk:
01304 {
01305 const qreal c = ct.acmyk.cyan / qreal(USHRT_MAX);
01306 const qreal m = ct.acmyk.magenta / qreal(USHRT_MAX);
01307 const qreal y = ct.acmyk.yellow / qreal(USHRT_MAX);
01308 const qreal k = ct.acmyk.black / qreal(USHRT_MAX);
01309
01310 color.ct.argb.red = qRound((1.0 - (c * (1.0 - k) + k)) * USHRT_MAX);
01311 color.ct.argb.green = qRound((1.0 - (m * (1.0 - k) + k)) * USHRT_MAX);
01312 color.ct.argb.blue = qRound((1.0 - (y * (1.0 - k) + k)) * USHRT_MAX);
01313 break;
01314 }
01315 default:
01316 break;
01317 }
01318
01319 return color;
01320 }
01321
01322
01323 #define Q_MAX_3(a, b, c) ( ( a > b && a > c) ? a : (b > c ? b : c) )
01324 #define Q_MIN_3(a, b, c) ( ( a < b && a < c) ? a : (b < c ? b : c) )
01325
01326
01333 QColor QColor::toHsv() const
01334 {
01335 if (!isValid())
01336 return *this;
01337
01338 if (cspec != Rgb)
01339 return toRgb().toHsv();
01340
01341 QColor color;
01342 color.cspec = Hsv;
01343 color.ct.ahsv.alpha = ct.argb.alpha;
01344 color.ct.ahsv.pad = 0;
01345
01346 const qreal r = ct.argb.red / qreal(USHRT_MAX);
01347 const qreal g = ct.argb.green / qreal(USHRT_MAX);
01348 const qreal b = ct.argb.blue / qreal(USHRT_MAX);
01349 const qreal max = Q_MAX_3(r, g, b);
01350 const qreal min = Q_MIN_3(r, g, b);
01351 const qreal delta = max - min;
01352 color.ct.ahsv.value = qRound(max * USHRT_MAX);
01353 if (delta == 0.0) {
01354
01355 color.ct.ahsv.hue = USHRT_MAX;
01356 color.ct.ahsv.saturation = 0;
01357 } else {
01358
01359 qreal hue = 0;
01360 color.ct.ahsv.saturation = qRound((delta / max) * USHRT_MAX);
01361 if (r == max) {
01362 hue = ((g - b) /delta);
01363 } else if (g == max) {
01364 hue = (2.0 + (b - r) / delta);
01365 } else if (b == max) {
01366 hue = (4.0 + (r - g) / delta);
01367 } else {
01368 Q_ASSERT_X(false, "QColor::toHsv", "internal error");
01369 }
01370 hue *= 60.0;
01371 if (hue < 0.0)
01372 hue += 360.0;
01373 color.ct.ahsv.hue = qRound(hue * 100);
01374 }
01375
01376 return color;
01377 }
01378
01385 QColor QColor::toCmyk() const
01386 {
01387 if (!isValid())
01388 return *this;
01389 if (cspec != Rgb)
01390 return toRgb().toCmyk();
01391
01392 QColor color;
01393 color.cspec = Cmyk;
01394 color.ct.acmyk.alpha = ct.argb.alpha;
01395
01396
01397 const qreal r = ct.argb.red / qreal(USHRT_MAX);
01398 const qreal g = ct.argb.green / qreal(USHRT_MAX);
01399 const qreal b = ct.argb.blue / qreal(USHRT_MAX);
01400 qreal c = 1.0 - r;
01401 qreal m = 1.0 - g;
01402 qreal y = 1.0 - b;
01403
01404
01405 const qreal k = qMin(c, qMin(m, y));
01406
01407 if (!qFuzzyCompare(k,1)) {
01408 c = (c - k) / (1.0 - k);
01409 m = (m - k) / (1.0 - k);
01410 y = (y - k) / (1.0 - k);
01411 }
01412
01413 color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
01414 color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
01415 color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
01416 color.ct.acmyk.black = qRound(k * USHRT_MAX);
01417
01418 return color;
01419 }
01420
01421 QColor QColor::convertTo(QColor::Spec colorSpec) const
01422 {
01423 if (colorSpec == cspec)
01424 return *this;
01425 switch (colorSpec) {
01426 case Rgb:
01427 return toRgb();
01428 case Hsv:
01429 return toHsv();
01430 case Cmyk:
01431 return toCmyk();
01432 case Invalid:
01433 break;
01434 }
01435 return QColor();
01436 }
01437
01438
01450 QColor QColor::fromRgb(QRgb rgb)
01451 {
01452 return fromRgb(qRed(rgb), qGreen(rgb), qBlue(rgb));
01453 }
01454
01455
01466 QColor QColor::fromRgba(QRgb rgba)
01467 {
01468 return fromRgb(qRed(rgba), qGreen(rgba), qBlue(rgba), qAlpha(rgba));
01469 }
01470
01480 QColor QColor::fromRgb(int r, int g, int b, int a)
01481 {
01482 if (r < 0 || r > 255
01483 || g < 0 || g > 255
01484 || b < 0 || b > 255
01485 || a < 0 || a > 255) {
01486 qWarning("QColor::fromRgb: RGB parameters out of range");
01487 return QColor();
01488 }
01489
01490 QColor color;
01491 color.cspec = Rgb;
01492 color.ct.argb.alpha = a * 0x101;
01493 color.ct.argb.red = r * 0x101;
01494 color.ct.argb.green = g * 0x101;
01495 color.ct.argb.blue = b * 0x101;
01496 color.ct.argb.pad = 0;
01497 return color;
01498 }
01499
01509 QColor QColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
01510 {
01511 if (r < 0.0 || r > 1.0
01512 || g < 0.0 || g > 1.0
01513 || b < 0.0 || b > 1.0
01514 || a < 0.0 || a > 1.0) {
01515 qWarning("QColor::fromRgbF: RGB parameters out of range");
01516 return QColor();
01517 }
01518
01519 QColor color;
01520 color.cspec = Rgb;
01521 color.ct.argb.alpha = qRound(a * USHRT_MAX);
01522 color.ct.argb.red = qRound(r * USHRT_MAX);
01523 color.ct.argb.green = qRound(g * USHRT_MAX);
01524 color.ct.argb.blue = qRound(b * USHRT_MAX);
01525 color.ct.argb.pad = 0;
01526 return color;
01527 }
01528
01540 QColor QColor::fromHsv(int h, int s, int v, int a)
01541 {
01542 if (((h < 0 || h >= 360) && h != -1)
01543 || s < 0 || s > 255
01544 || v < 0 || v > 255
01545 || a < 0 || a > 255) {
01546 qWarning("QColor::fromHsv: HSV parameters out of range");
01547 return QColor();
01548 }
01549
01550 QColor color;
01551 color.cspec = Hsv;
01552 color.ct.ahsv.alpha = a * 0x101;
01553 color.ct.ahsv.hue = h == -1 ? USHRT_MAX : (h % 360) * 100;
01554 color.ct.ahsv.saturation = s * 0x101;
01555 color.ct.ahsv.value = v * 0x101;
01556 color.ct.ahsv.pad = 0;
01557 return color;
01558 }
01559
01572 QColor QColor::fromHsvF(qreal h, qreal s, qreal v, qreal a)
01573 {
01574 if (((h < 0.0 || h > 1.0) && h != -1.0)
01575 || (s < 0.0 || s > 1.0)
01576 || (v < 0.0 || v > 1.0)
01577 || (a < 0.0 || a > 1.0)) {
01578 qWarning("QColor::fromHsvF: HSV parameters out of range");
01579 return QColor();
01580 }
01581
01582 QColor color;
01583 color.cspec = Hsv;
01584 color.ct.ahsv.alpha = qRound(a * USHRT_MAX);
01585 color.ct.ahsv.hue = h == -1.0 ? USHRT_MAX : qRound(h * 36000);
01586 color.ct.ahsv.saturation = qRound(s * USHRT_MAX);
01587 color.ct.ahsv.value = qRound(v * USHRT_MAX);
01588 color.ct.ahsv.pad = 0;
01589 return color;
01590 }
01591
01602 void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
01603 {
01604 if (!c || !m || !y || !k)
01605 return;
01606
01607 if (cspec != Invalid && cspec != Cmyk) {
01608 toCmyk().getCmyk(c, m, y, k, a);
01609 return;
01610 }
01611
01612 *c = ct.acmyk.cyan >> 8;
01613 *m = ct.acmyk.magenta >> 8;
01614 *y = ct.acmyk.yellow >> 8;
01615 *k = ct.acmyk.black >> 8;
01616
01617 if (a)
01618 *a = ct.acmyk.alpha >> 8;
01619 }
01620
01631 void QColor::getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a)
01632 {
01633 if (!c || !m || !y || !k)
01634 return;
01635
01636 if (cspec != Invalid && cspec != Cmyk) {
01637 toCmyk().getCmykF(c, m, y, k, a);
01638 return;
01639 }
01640
01641 *c = ct.acmyk.cyan / qreal(USHRT_MAX);
01642 *m = ct.acmyk.magenta / qreal(USHRT_MAX);
01643 *y = ct.acmyk.yellow / qreal(USHRT_MAX);
01644 *k = ct.acmyk.black / qreal(USHRT_MAX);
01645
01646 if (a)
01647 *a = ct.acmyk.alpha / qreal(USHRT_MAX);
01648 }
01649
01659 void QColor::setCmyk(int c, int m, int y, int k, int a)
01660 {
01661 if (c < 0 || c > 255
01662 || m < 0 || m > 255
01663 || y < 0 || y > 255
01664 || k < 0 || k > 255
01665 || a < 0 || a > 255) {
01666 qWarning("QColor::setCmyk: CMYK parameters out of range");
01667 return;
01668 }
01669
01670 cspec = Cmyk;
01671 ct.acmyk.alpha = a * 0x101;
01672 ct.acmyk.cyan = c * 0x101;
01673 ct.acmyk.magenta = m * 0x101;
01674 ct.acmyk.yellow = y * 0x101;
01675 ct.acmyk.black = k * 0x101;
01676 }
01677
01689 void QColor::setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a)
01690 {
01691 if (c < 0.0 || c > 1.0
01692 || m < 0.0 || m > 1.0
01693 || y < 0.0 || y > 1.0
01694 || k < 0.0 || k > 1.0
01695 || a < 0.0 || a > 1.0) {
01696 qWarning("QColor::setCmykF: CMYK parameters out of range");
01697 return;
01698 }
01699
01700 cspec = Cmyk;
01701 ct.acmyk.alpha = qRound(a * USHRT_MAX);
01702 ct.acmyk.cyan = qRound(c * USHRT_MAX);
01703 ct.acmyk.magenta = qRound(m * USHRT_MAX);
01704 ct.acmyk.yellow = qRound(y * USHRT_MAX);
01705 ct.acmyk.black = qRound(k * USHRT_MAX);
01706 }
01707
01719 QColor QColor::fromCmyk(int c, int m, int y, int k, int a)
01720 {
01721 if (c < 0 || c > 255
01722 || m < 0 || m > 255
01723 || y < 0 || y > 255
01724 || k < 0 || k > 255
01725 || a < 0 || a > 255) {
01726 qWarning("QColor::fromCmyk: CMYK parameters out of range");
01727 return QColor();
01728 }
01729
01730 QColor color;
01731 color.cspec = Cmyk;
01732 color.ct.acmyk.alpha = a * 0x101;
01733 color.ct.acmyk.cyan = c * 0x101;
01734 color.ct.acmyk.magenta = m * 0x101;
01735 color.ct.acmyk.yellow = y * 0x101;
01736 color.ct.acmyk.black = k * 0x101;
01737 return color;
01738 }
01739
01753 QColor QColor::fromCmykF(qreal c, qreal m, qreal y, qreal k, qreal a)
01754 {
01755 if (c < 0.0 || c > 1.0
01756 || m < 0.0 || m > 1.0
01757 || y < 0.0 || y > 1.0
01758 || k < 0.0 || k > 1.0
01759 || a < 0.0 || a > 1.0) {
01760 qWarning("QColor::fromCmykF: CMYK parameters out of range");
01761 return QColor();
01762 }
01763
01764 QColor color;
01765 color.cspec = Cmyk;
01766 color.ct.acmyk.alpha = qRound(a * USHRT_MAX);
01767 color.ct.acmyk.cyan = qRound(c * USHRT_MAX);
01768 color.ct.acmyk.magenta = qRound(m * USHRT_MAX);
01769 color.ct.acmyk.yellow = qRound(y * USHRT_MAX);
01770 color.ct.acmyk.black = qRound(k * USHRT_MAX);
01771 return color;
01772 }
01773
01791 QColor QColor::light(int factor) const
01792 {
01793 if (factor <= 0)
01794 return *this;
01795 else if (factor < 100)
01796 return dark(10000/factor);
01797
01798 QColor hsv = toHsv();
01799 int s = hsv.ct.ahsv.saturation;
01800 int v = hsv.ct.ahsv.value;
01801
01802 v = (factor*v)/100;
01803 if (v > USHRT_MAX) {
01804
01805 s -= v - USHRT_MAX;
01806 if (s < 0)
01807 s = 0;
01808 v = USHRT_MAX;
01809 }
01810
01811 hsv.ct.ahsv.saturation = s;
01812 hsv.ct.ahsv.value = v;
01813
01814
01815 return hsv.convertTo(cspec);
01816 }
01817
01835 QColor QColor::dark(int factor) const
01836 {
01837 if (factor <= 0)
01838 return *this;
01839 else if (factor < 100)
01840 return light(10000/factor);
01841
01842 QColor hsv = toHsv();
01843 hsv.ct.ahsv.value = (hsv.ct.ahsv.value * 100) / factor;
01844
01845
01846 return hsv.convertTo(cspec);
01847 }
01848
01853 QColor &QColor::operator=(const QColor &color)
01854 {
01855 cspec = color.cspec;
01856 ct.argb = color.ct.argb;
01857 return *this;
01858 }
01859
01863 QColor &QColor::operator=(Qt::GlobalColor color)
01864 {
01865 return operator=(QColor(color));
01866 }
01867
01872 bool QColor::operator==(const QColor &color) const
01873 {
01874 return (cspec == color.cspec
01875 && ct.argb.alpha == color.ct.argb.alpha
01876 && ct.argb.red == color.ct.argb.red
01877 && ct.argb.green == color.ct.argb.green
01878 && ct.argb.blue == color.ct.argb.blue
01879 && ct.argb.pad == color.ct.argb.pad);
01880 }
01881
01886 bool QColor::operator!=(const QColor &color) const
01887 { return !operator==(color); }
01888
01889
01893 QColor::operator QVariant() const
01894 {
01895 return QVariant(QVariant::Color, this);
01896 }
01897
01903 void QColor::invalidate()
01904 {
01905 cspec = Invalid;
01906 ct.argb.alpha = USHRT_MAX;
01907 ct.argb.red = 0;
01908 ct.argb.green = 0;
01909 ct.argb.blue = 0;
01910 ct.argb.pad = 0;
01911 }
01912
01913 #ifdef QT3_SUPPORT
01914
01929 uint QColor::pixel(int screen) const
01930 {
01931 QColormap cmap = QColormap::instance(screen);
01932 return cmap.pixel(*this);
01933 }
01934
01935 #endif // QT3_SUPPORT
01936
01937
01938
01939
01940
01941 #ifndef QT_NO_DEBUG_STREAM
01942 QDebug operator<<(QDebug dbg, const QColor &c)
01943 {
01944 #ifndef Q_BROKEN_DEBUG_STREAM
01945 if (!c.isValid())
01946 dbg.nospace() << "QColor(Invalid)";
01947 else if (c.spec() == QColor::Rgb)
01948 dbg.nospace() << "QColor(ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ")";
01949 else if (c.spec() == QColor::Hsv)
01950 dbg.nospace() << "QColor(AHSV " << c.alphaF() << ", " << c.hueF() << ", " << c.saturationF() << ", " << c.valueF() << ")";
01951 else if (c.spec() == QColor::Cmyk)
01952 dbg.nospace() << "QColor(ACMYK " << c.alphaF() << ", " << c.cyanF() << ", " << c.magentaF() << ", " << c.yellowF() << ", "
01953 << c.blackF()<< ")";
01954
01955 return dbg.space();
01956 #else
01957 qWarning("This compiler doesn't support streaming QColor to QDebug");
01958 return dbg;
01959 Q_UNUSED(c);
01960 #endif
01961 }
01962 #endif
01963
01964 #ifndef QT_NO_DATASTREAM
01965
01973 QDataStream &operator<<(QDataStream &stream, const QColor &color)
01974 {
01975 if (stream.version() < 7) {
01976 quint32 p = (quint32)color.rgb();
01977 if (stream.version() == 1)
01978 p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
01979 return stream << p;
01980 }
01981
01982 qint8 s = color.cspec;
01983 quint16 a = color.ct.argb.alpha;
01984 quint16 r = color.ct.argb.red;
01985 quint16 g = color.ct.argb.green;
01986 quint16 b = color.ct.argb.blue;
01987 quint16 p = color.ct.argb.pad;
01988
01989 stream << s;
01990 stream << a;
01991 stream << r;
01992 stream << g;
01993 stream << b;
01994 stream << p;
01995
01996 return stream;
01997 }
01998
02007 QDataStream &operator>>(QDataStream &stream, QColor &color)
02008 {
02009 if (stream.version() < 7) {
02010 quint32 p;
02011 stream >> p;
02012 if (stream.version() == 1)
02013 p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
02014 color.setRgb(p);
02015 return stream;
02016 }
02017
02018 qint8 s;
02019 quint16 a, r, g, b, p;
02020 stream >> s;
02021 stream >> a;
02022 stream >> r;
02023 stream >> g;
02024 stream >> b;
02025 stream >> p;
02026
02027 color.cspec = QColor::Spec(s);
02028 color.ct.argb.alpha = a;
02029 color.ct.argb.red = r;
02030 color.ct.argb.green = g;
02031 color.ct.argb.blue = b;
02032 color.ct.argb.pad = p;
02033
02034 return stream;
02035 }
02036 #endif
02037
02038
02039
02040
02041
02042
02043
02044