File indexing completed on 2024-12-08 12:18:36

0001 #include "kcolorutilstest.h"
0002 
0003 #include <QTest>
0004 
0005 #include "../colors/kcolorspaces.cpp" // private implementation
0006 #include "../colors/kcolorspaces_p.h" // private header
0007 #include <kcolorutils.h>
0008 
0009 void tst_KColorUtils::testOverlay()
0010 {
0011     QColor color1(10, 10, 100);
0012     QColor color2(10, 10, 160);
0013     QColor blended = KColorUtils::overlayColors(color1, color2);
0014     QCOMPARE(blended, color2); // no transparency.
0015 
0016     QColor previous;
0017     // check that when altering the alpha of color2 to be less and less transparent this
0018     // means we are moving more and more towards color2
0019     for (int i = 10; i <= 255; i += 10) {
0020         color2.setAlpha(i);
0021         blended = KColorUtils::overlayColors(color1, color2);
0022         if (previous.isValid()) {
0023             QCOMPARE(previous.red(), 10);
0024             QCOMPARE(previous.green(), 10);
0025             QVERIFY(previous.blue() <= blended.blue());
0026         }
0027         previous = blended;
0028     }
0029 
0030     // only the alpha of color 2 alters the output
0031     color2.setAlpha(255); // opaque
0032     color1.setAlpha(80); // opaque
0033     blended = KColorUtils::overlayColors(color2, color2);
0034     QCOMPARE(blended.red(), color2.red());
0035     QCOMPARE(blended.green(), color2.green());
0036     QCOMPARE(blended.blue(), color2.blue());
0037 
0038     // merge from itself to itself gives; TADA; itself again ;)
0039     color2.setAlpha(127);
0040     blended = KColorUtils::overlayColors(color2, color2);
0041     QCOMPARE(blended.red(), color2.red());
0042     QCOMPARE(blended.green(), color2.green());
0043     QCOMPARE(blended.blue(), color2.blue());
0044 }
0045 
0046 /* clang-format off */
0047 #define compareColors(c1, c2) \
0048     if (c1 != c2) { \
0049         fprintf(stderr, "%08x != expected value %08x\n", c1.rgb(), c2.rgb()); \
0050         QCOMPARE(c1, c2); \
0051     } \
0052     (void)0
0053 /* clang-format on */
0054 
0055 void tst_KColorUtils::testMix()
0056 {
0057     int r;
0058     int g;
0059     int b;
0060     int k;
0061     for (r = 0; r < 52; r++) {
0062         for (g = 0; g < 52; g++) {
0063             for (b = 0; b < 52; b++) {
0064                 QColor color(r * 5, g * 5, b * 5);
0065                 // Test blend-to-black spectrum
0066                 for (k = 5; k >= 0; k--) {
0067                     QColor result = KColorUtils::mix(Qt::black, color, k * 0.2);
0068                     compareColors(result, QColor(r * k, g * k, b * k));
0069                 }
0070                 // Test blend-to-white spectrum
0071                 for (k = 5; k >= 0; k--) {
0072                     int n = 51 * (5 - k);
0073                     QColor result = KColorUtils::mix(Qt::white, color, k * 0.2);
0074                     compareColors(result, QColor(n + r * k, n + g * k, n + b * k));
0075                 }
0076                 // Test blend-to-self across a couple bias values
0077                 for (k = 5; k >= 0; k--) {
0078                     QColor result = KColorUtils::mix(color, color, k * 0.2);
0079                     compareColors(result, color);
0080                 }
0081             }
0082         }
0083     }
0084 
0085     const auto colorA = QColor::fromRgb(255, 255, 255, 1);
0086     const auto colorB = QColor::fromRgb(0, 0, 0, 255);
0087     const auto mixed = KColorUtils::mix(colorA, colorB, 0.5);
0088 
0089     QVERIFY2(mixed.redF() <= 0.01, "colorA should have little influence on colorB due to low opacity");
0090     QVERIFY2(mixed.greenF() <= 0.01, "colorA should have little influence on colorB due to low opacity");
0091     QVERIFY2(mixed.blueF() <= 0.01, "colorA should have little influence on colorB due to low opacity");
0092 }
0093 
0094 void tst_KColorUtils::testHCY()
0095 {
0096     int r;
0097     int g;
0098     int b;
0099     for (r = 0; r < 256; r += 5) {
0100         for (g = 0; g < 256; g += 5) {
0101             for (b = 0; b < 256; b += 5) {
0102                 QColor color(r, g, b);
0103                 KColorSpaces::KHCY hcy(color);
0104                 compareColors(hcy.qColor(), color);
0105             }
0106         }
0107     }
0108 }
0109 
0110 void tst_KColorUtils::testContrast()
0111 {
0112     QCOMPARE(KColorUtils::contrastRatio(Qt::black, Qt::white), qreal(21.0));
0113     QCOMPARE(KColorUtils::contrastRatio(Qt::white, Qt::black), qreal(21.0));
0114     QCOMPARE(KColorUtils::contrastRatio(Qt::black, Qt::black), qreal(1.0));
0115     QCOMPARE(KColorUtils::contrastRatio(Qt::white, Qt::white), qreal(1.0));
0116 
0117     // TODO better tests :-)
0118 }
0119 
0120 void checkIsGray(const QColor &color, int line)
0121 {
0122     KColorSpaces::KHCY hcy(color);
0123     if (hcy.c != qreal(0.0)) {
0124         fprintf(stderr, "%08x has chroma %g, expected gray!\n", color.rgb(), hcy.c);
0125     }
0126     QTest::qCompare(hcy.c, qreal(0.0), "hcy.c", "0.0", __FILE__, line);
0127 }
0128 
0129 void tst_KColorUtils::testShading()
0130 {
0131     const QColor testGray(128, 128, 128); // Qt::gray isn't pure gray!
0132 
0133     // Test that KHCY gets chroma correct for white/black, grays
0134     checkIsGray(Qt::white, __LINE__);
0135     checkIsGray(testGray, __LINE__);
0136     checkIsGray(Qt::black, __LINE__);
0137 
0138     // Test that lighten/darken/shade don't change chroma for grays
0139     checkIsGray(KColorUtils::shade(Qt::white, -0.1), __LINE__);
0140     checkIsGray(KColorUtils::shade(Qt::black, 0.1), __LINE__);
0141     checkIsGray(KColorUtils::darken(Qt::white, 0.1), __LINE__);
0142     checkIsGray(KColorUtils::darken(testGray, 0.1), __LINE__);
0143     checkIsGray(KColorUtils::darken(testGray, -0.1), __LINE__);
0144     checkIsGray(KColorUtils::darken(Qt::black, -0.1), __LINE__);
0145     checkIsGray(KColorUtils::lighten(Qt::black, 0.1), __LINE__);
0146     checkIsGray(KColorUtils::lighten(testGray, 0.1), __LINE__);
0147     checkIsGray(KColorUtils::lighten(testGray, -0.1), __LINE__);
0148     checkIsGray(KColorUtils::lighten(Qt::white, -0.1), __LINE__);
0149 }
0150 
0151 QTEST_MAIN(tst_KColorUtils)
0152 
0153 #include "moc_kcolorutilstest.cpp"