From 01f090e9e45399f72b8bc73793797d44a69b2a2e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 22 Jan 2019 13:26:02 +0100 Subject: [PATCH] Fix QColor::toCmyk() for rgb(0, 0, 0) We translate all pure gray colors into cmyk having c,m,y=0 and only the k value expressing the darkness. But a fix introduced to avoid division by 0 caused rgb(0, 0, 0) to be an exception to this; it ended up being translated as c,m,y,k=1 instead. Fix by catching the potential div-by-0 situation earlier and directly set the orthodox cmyk translation: c,m,y=0,k=1. Fixes: QTBUG-73171 Change-Id: I3774eaf9d96e096ac5c47c55d28881bea2bd1309 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qcolor.cpp | 37 +++++++++++-------- tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 318d55c4c3..1f1835d5da 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2193,27 +2193,32 @@ QColor QColor::toCmyk() const Q_DECL_NOTHROW color.cspec = Cmyk; color.ct.acmyk.alpha = ct.argb.alpha; - // rgb -> cmy - const qreal r = ct.argb.red / qreal(USHRT_MAX); - const qreal g = ct.argb.green / qreal(USHRT_MAX); - const qreal b = ct.argb.blue / qreal(USHRT_MAX); - qreal c = qreal(1.0) - r; - qreal m = qreal(1.0) - g; - qreal y = qreal(1.0) - b; + if (!ct.argb.red && !ct.argb.green && !ct.argb.blue) { + // Avoid div-by-0 below + color.ct.acmyk.cyan = 0; + color.ct.acmyk.magenta = 0; + color.ct.acmyk.yellow = 0; + color.ct.acmyk.black = USHRT_MAX; + } else { + // rgb -> cmy + const qreal r = ct.argb.red / qreal(USHRT_MAX); + const qreal g = ct.argb.green / qreal(USHRT_MAX); + const qreal b = ct.argb.blue / qreal(USHRT_MAX); + qreal c = qreal(1.0) - r; + qreal m = qreal(1.0) - g; + qreal y = qreal(1.0) - b; - // cmy -> cmyk - const qreal k = qMin(c, qMin(m, y)); - - if (!qFuzzyIsNull(k - 1)) { + // cmy -> cmyk + const qreal k = qMin(c, qMin(m, y)); c = (c - k) / (qreal(1.0) - k); m = (m - k) / (qreal(1.0) - k); y = (y - k) / (qreal(1.0) - k); - } - color.ct.acmyk.cyan = qRound(c * USHRT_MAX); - color.ct.acmyk.magenta = qRound(m * USHRT_MAX); - color.ct.acmyk.yellow = qRound(y * USHRT_MAX); - color.ct.acmyk.black = qRound(k * USHRT_MAX); + color.ct.acmyk.cyan = qRound(c * USHRT_MAX); + color.ct.acmyk.magenta = qRound(m * USHRT_MAX); + color.ct.acmyk.yellow = qRound(y * USHRT_MAX); + color.ct.acmyk.black = qRound(k * USHRT_MAX); + } return color; } diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 72bad03a6a..17289e0b85 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -1291,7 +1291,7 @@ void tst_QColor::toCmyk_data() << QColor::fromHslF(180./360., 1., 0.5, 1.0); QTest::newRow("data1") - << QColor::fromCmyk(255, 255, 255, 255) + << QColor::fromCmyk(0, 0, 0, 255) << QColor::fromRgb(0, 0, 0) << QColor::fromRgb(0, 0, 0).toHsv() << QColor::fromRgb(0, 0, 0).toHsl();