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 <allan.jensen@qt.io>
This commit is contained in:
Eirik Aavitsland 2019-01-22 13:26:02 +01:00
parent 66c3a71e91
commit 01f090e9e4
2 changed files with 22 additions and 17 deletions

View File

@ -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;
}

View File

@ -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();