1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 sccolor.cpp - description
9 -------------------
10 begin : Sun Sep 9 2001
11 copyright : (C) 2001 by Franz Schmid
12 email : Franz.Schmid@altmuehlnet.de
13 ***************************************************************************/
14
15 /***************************************************************************
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 ***************************************************************************/
23
24 #include <cmath>
25
26 #include "sccolorengine.h"
27 #include "scribuscore.h"
28 #include "scribusdoc.h"
29 #include "colormgmt/sccolormgmtengine.h"
30
getRGBColor(const ScColor & color,const ScribusDoc * doc)31 QColor ScColorEngine::getRGBColor(const ScColor& color, const ScribusDoc* doc)
32 {
33 RGBColor rgb;
34 getRGBValues(color, doc, rgb);
35 return QColor(rgb.r, rgb.g, rgb.b);
36 }
37
convertToModel(const ScColor & color,const ScribusDoc * doc,colorModel model)38 ScColor ScColorEngine::convertToModel(const ScColor& color, const ScribusDoc* doc, colorModel model)
39 {
40 colorModel oldModel = color.getColorModel();
41 if (oldModel == model)
42 return ScColor(color);
43 ScColor newCol;
44 if (model == colorModelRGB)
45 {
46 RGBColorF rgb;
47 getRGBValues(color, doc, rgb);
48 newCol.setRgbColorF(rgb.r, rgb.g, rgb.b);
49 }
50 else if (model == colorModelCMYK)
51 {
52 CMYKColorF cmyk;
53 getCMYKValues(color, doc, cmyk);
54 newCol.setColorF(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
55 }
56 else if (model == colorModelLab)
57 {
58 ScColorMgmtEngine engine(ScCore->defaultEngine);
59 if (oldModel == colorModelRGB)
60 {
61 ScColorProfile profRGB = doc ? doc->DocInputRGBProf : ScCore->defaultRGBProfile;
62 ScColorProfile profLab = ScCore->defaultLabProfile;
63 ScColorTransform trans = engine.createTransform(profRGB, Format_RGB_16, profLab, Format_Lab_Dbl, Intent_Perceptual, 0);
64 double outC[3];
65 unsigned short inC[3];
66 inC[0] = qRound(color.m_values[0] * 65535);
67 inC[1] = qRound(color.m_values[1] * 65535);
68 inC[2] = qRound(color.m_values[2] * 65535);
69 trans.apply(inC, outC, 1);
70 newCol.setLabColor(outC[0], outC[1], outC[2]);
71 }
72 else
73 {
74 ScColorProfile profCMYK = doc ? doc->DocInputCMYKProf : ScCore->defaultCMYKProfile;
75 ScColorProfile profLab = ScCore->defaultLabProfile;
76 ScColorTransform trans = engine.createTransform(profCMYK, Format_CMYK_16, profLab, Format_Lab_Dbl, Intent_Perceptual, 0);
77 double outC[3];
78 unsigned short inC[4];
79 inC[0] = qRound(color.m_values[0] * 65535);
80 inC[1] = qRound(color.m_values[1] * 65535);
81 inC[2] = qRound(color.m_values[2] * 65535);
82 inC[3] = qRound(color.m_values[3] * 65535);
83 trans.apply(inC, outC, 1);
84 newCol.setLabColor(outC[0], outC[1], outC[2]);
85 }
86 }
87 return newCol;
88 }
89
getRGBValues(const ScColor & color,const ScribusDoc * doc,RGBColor & rgb)90 void ScColorEngine::getRGBValues(const ScColor& color, const ScribusDoc* doc, RGBColor& rgb)
91 {
92 colorModel model = color.getColorModel();
93 ScColorTransform transRGB = doc ? doc->stdTransRGB : ScCore->defaultCMYKToRGBTrans;
94 if (ScCore->haveCMS() && transRGB)
95 {
96 if (model == colorModelRGB)
97 {
98 rgb.r = qRound(color.m_values[0] * 255.0);
99 rgb.g = qRound(color.m_values[1] * 255.0);
100 rgb.b = qRound(color.m_values[2] * 255.0);
101 }
102 else if (model == colorModelCMYK)
103 {
104 unsigned short inC[4];
105 unsigned short outC[4];
106 inC[0] = qRound(color.m_values[0] * 65535);
107 inC[1] = qRound(color.m_values[1] * 65535);
108 inC[2] = qRound(color.m_values[2] * 65535);
109 inC[3] = qRound(color.m_values[3] * 65535);
110 transRGB.apply(inC, outC, 1);
111 rgb.r = outC[0] / 257;
112 rgb.g = outC[1] / 257;
113 rgb.b = outC[2] / 257;
114 }
115 else if (model == colorModelLab)
116 {
117 ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
118 double inC[3];
119 inC[0] = color.m_L_val;
120 inC[1] = color.m_a_val;
121 inC[2] = color.m_b_val;
122 quint16 outC[3];
123 trans.apply(inC, outC, 1);
124 rgb.r = outC[0] / 257;
125 rgb.g = outC[1] / 257;
126 rgb.b = outC[2] / 257;
127 }
128 }
129 else if (model == colorModelCMYK)
130 {
131 double r = 1.0 - qMin(1.0, color.m_values[0] + color.m_values[3]);
132 double g = 1.0 - qMin(1.0, color.m_values[1] + color.m_values[3]);
133 double b = 1.0 - qMin(1.0, color.m_values[2] + color.m_values[3]);
134 rgb.r = qRound(r * 255.0);
135 rgb.g = qRound(g * 255.0);
136 rgb.b = qRound(b * 255.0);
137 }
138 else if (model == colorModelRGB)
139 {
140 rgb.r = qRound(color.m_values[0] * 255.0);
141 rgb.g = qRound(color.m_values[1] * 255.0);
142 rgb.b = qRound(color.m_values[2] * 255.0);
143 }
144 else if (model == colorModelLab)
145 {
146 // First step: Lab -> XYZ
147 double var_Y = (color.m_L_val + 16) / 116.0;
148 double var_X = color.m_a_val / 500.0 + var_Y;
149 double var_Z = var_Y - color.m_b_val / 200.0;
150 if (pow(var_Y, 3) > 0.008856)
151 var_Y = pow(var_Y, 3);
152 else
153 var_Y = (var_Y - 16.0 / 116.0) / 7.787;
154 if (pow(var_X, 3) > 0.008856)
155 var_X = pow(var_X, 3);
156 else
157 var_X = (var_X - 16.0 / 116.0) / 7.787;
158 if (pow(var_Z, 3) > 0.008856)
159 var_Z = pow(var_Z, 3);
160 else
161 var_Z = (var_Z - 16.0 / 116.0) / 7.787;
162 // Second step: XYZ -> RGB
163 // Whitepoint D50
164 var_X = 0.990720 * var_X;
165 var_Y = 1.00000 * var_Y;
166 var_Z = 0.825210 * var_Z;
167 double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
168 double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
169 double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
170 if (var_R > 0.0031308)
171 var_R = 1.055 * (pow(var_R, (1.0 / 2.4))) - 0.055;
172 else
173 var_R = 12.92 * var_R;
174 if (var_G > 0.0031308)
175 var_G = 1.055 * (pow(var_G, (1.0 / 2.4))) - 0.055;
176 else
177 var_G = 12.92 * var_G;
178 if (var_B > 0.0031308)
179 var_B = 1.055 * (pow(var_B, (1.0 / 2.4))) - 0.055;
180 else
181 var_B = 12.92 * var_B;
182 rgb.r = qRound(qMax(qMin(var_R, 1.0), 0.0) * 255.0);
183 rgb.g = qRound(qMax(qMin(var_G, 1.0), 0.0) * 255.0);
184 rgb.b = qRound(qMax(qMin(var_B, 1.0), 0.0) * 255.0);
185 /* ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
186 double inC[3];
187 inC[0] = color.L_val;
188 inC[1] = color.a_val;
189 inC[2] = color.b_val;
190 quint16 outC[3];
191 trans.apply(inC, outC, 1);
192 rgb.r = outC[0] / 257;
193 rgb.g = outC[1] / 257;
194 rgb.b = outC[2] / 257;*/
195 }
196 }
197
getRGBValues(const ScColor & color,const ScribusDoc * doc,RGBColorF & rgb)198 void ScColorEngine::getRGBValues(const ScColor& color, const ScribusDoc* doc, RGBColorF& rgb)
199 {
200 colorModel model = color.getColorModel();
201 ScColorTransform transRGB = doc ? doc->stdTransRGB : ScCore->defaultCMYKToRGBTrans;
202 if (ScCore->haveCMS() && transRGB)
203 {
204 if (model == colorModelRGB)
205 {
206 rgb.r = color.m_values[0];
207 rgb.g = color.m_values[1];
208 rgb.b = color.m_values[2];
209 }
210 else if (model == colorModelCMYK)
211 {
212 unsigned short inC[4];
213 unsigned short outC[4];
214 inC[0] = qRound(color.m_values[0] * 65535);
215 inC[1] = qRound(color.m_values[1] * 65535);
216 inC[2] = qRound(color.m_values[2] * 65535);
217 inC[3] = qRound(color.m_values[3] * 65535);
218 transRGB.apply(inC, outC, 1);
219 rgb.r = outC[0] / 65535.0;
220 rgb.g = outC[1] / 65535.0;
221 rgb.b = outC[2] / 65535.0;
222 }
223 else if (model == colorModelLab)
224 {
225 ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
226 double inC[3];
227 inC[0] = color.m_L_val;
228 inC[1] = color.m_a_val;
229 inC[2] = color.m_b_val;
230 quint16 outC[3];
231 trans.apply(inC, outC, 1);
232 rgb.r = outC[0] / 65535.0;
233 rgb.g = outC[1] / 65535.0;
234 rgb.b = outC[2] / 65535.0;
235 }
236 }
237 else if (model == colorModelCMYK)
238 {
239 rgb.r = 1.0 - qMin(1.0, color.m_values[0] + color.m_values[3]);
240 rgb.g = 1.0 - qMin(1.0, color.m_values[1] + color.m_values[3]);
241 rgb.b = 1.0 - qMin(1.0, color.m_values[2] + color.m_values[3]);
242 }
243 else if (model == colorModelRGB)
244 {
245 rgb.r = color.m_values[0];
246 rgb.g = color.m_values[1];
247 rgb.b = color.m_values[2];
248 }
249 else if (model == colorModelLab)
250 {
251 // First step: Lab -> XYZ
252 double var_Y = (color.m_L_val + 16) / 116.0;
253 double var_X = color.m_a_val / 500.0 + var_Y;
254 double var_Z = var_Y - color.m_b_val / 200.0;
255 if (pow(var_Y, 3) > 0.008856)
256 var_Y = pow(var_Y, 3);
257 else
258 var_Y = (var_Y - 16.0 / 116.0) / 7.787;
259 if (pow(var_X, 3) > 0.008856)
260 var_X = pow(var_X, 3);
261 else
262 var_X = (var_X - 16.0 / 116.0) / 7.787;
263 if (pow(var_Z, 3) > 0.008856)
264 var_Z = pow(var_Z, 3);
265 else
266 var_Z = (var_Z - 16.0 / 116.0) / 7.787;
267 // Second step: XYZ -> RGB
268 // Whitepoint D50
269 var_X = 0.990720 * var_X;
270 var_Y = 1.00000 * var_Y;
271 var_Z = 0.825210 * var_Z;
272 double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
273 double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
274 double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
275 if (var_R > 0.0031308)
276 var_R = 1.055 * (pow(var_R, (1.0 / 2.4))) - 0.055;
277 else
278 var_R = 12.92 * var_R;
279 if (var_G > 0.0031308)
280 var_G = 1.055 * (pow(var_G, (1.0 / 2.4))) - 0.055;
281 else
282 var_G = 12.92 * var_G;
283 if (var_B > 0.0031308)
284 var_B = 1.055 * (pow(var_B, (1.0 / 2.4))) - 0.055;
285 else
286 var_B = 12.92 * var_B;
287 rgb.r = qMax(0.0, qMin(var_R, 1.0));
288 rgb.g = qMax(0.0, qMin(var_G, 1.0));
289 rgb.b = qMax(0.0, qMin(var_B, 1.0));
290 /* ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
291 double inC[3];
292 inC[0] = color.L_val;
293 inC[1] = color.a_val;
294 inC[2] = color.b_val;
295 quint16 outC[3];
296 trans.apply(inC, outC, 1);
297 rgb.r = outC[0] / 65535.0;
298 rgb.g = outC[1] / 65535.0;
299 rgb.b = outC[2] / 65535.0;*/
300 }
301 }
302
getCMYKValues(const ScColor & color,const ScribusDoc * doc,CMYKColor & cmyk)303 void ScColorEngine::getCMYKValues(const ScColor& color, const ScribusDoc* doc, CMYKColor& cmyk)
304 {
305 unsigned short inC[4];
306 unsigned short outC[4];
307 colorModel model = color.getColorModel();
308 ScColorTransform transCMYK = doc ? doc->stdTransCMYK : ScCore->defaultRGBToCMYKTrans;
309 if (ScCore->haveCMS() && transCMYK)
310 {
311 if (model == colorModelRGB)
312 {
313 // allow RGB greys to go to CMYK greys without transform
314 if (color.m_values[0] == color.m_values[1] && color.m_values[1] == color.m_values[2])
315 {
316 cmyk.c = cmyk.m = cmyk.y = 0;
317 cmyk.k = 255 - qRound(color.m_values[0] * 255.0);
318 }
319 else
320 {
321 inC[0] = qRound(color.m_values[0] * 65535.0);
322 inC[1] = qRound(color.m_values[1] * 65535.0);
323 inC[2] = qRound(color.m_values[2] * 65535.0);
324 transCMYK.apply(inC, outC, 1);
325 cmyk.c = outC[0] / 257;
326 cmyk.m = outC[1] / 257;
327 cmyk.y = outC[2] / 257;
328 cmyk.k = outC[3] / 257;
329 }
330 }
331 else if (model == colorModelCMYK)
332 {
333 cmyk.c = qRound(color.m_values[0] * 255.0);
334 cmyk.m = qRound(color.m_values[1] * 255.0);
335 cmyk.y = qRound(color.m_values[2] * 255.0);
336 cmyk.k = qRound(color.m_values[3] * 255.0);
337 }
338 else if (model == colorModelLab)
339 {
340 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
341 double inC[3];
342 inC[0] = color.m_L_val;
343 inC[1] = color.m_a_val;
344 inC[2] = color.m_b_val;
345 quint16 outC[4];
346 trans.apply(inC, outC, 1);
347 cmyk.c = outC[0] / 257;
348 cmyk.m = outC[1] / 257;
349 cmyk.y = outC[2] / 257;
350 cmyk.k = outC[3] / 257;
351 }
352 }
353 else if (model == colorModelRGB)
354 {
355 double k = qMin(qMin(1.0 - color.m_values[0], 1.0 - color.m_values[1]), 1.0 - color.m_values[2]);
356 cmyk.k = qRound(k * 255.0);
357 cmyk.c = 255 - qRound((color.m_values[0] - k) * 255.0);
358 cmyk.m = 255 - qRound((color.m_values[1] - k) * 255.0);
359 cmyk.y = 255 - qRound((color.m_values[2] - k) * 255.0);
360 }
361 else if (model == colorModelCMYK)
362 {
363 cmyk.c = qRound(color.m_values[0] * 255.0);
364 cmyk.m = qRound(color.m_values[1] * 255.0);
365 cmyk.y = qRound(color.m_values[2] * 255.0);
366 cmyk.k = qRound(color.m_values[3] * 255.0);
367 }
368 else if (model == colorModelLab)
369 {
370 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
371 double inC[3];
372 inC[0] = color.m_L_val;
373 inC[1] = color.m_a_val;
374 inC[2] = color.m_b_val;
375 quint16 outC[4];
376 trans.apply(inC, outC, 1);
377 cmyk.c = outC[0] / 257;
378 cmyk.m = outC[1] / 257;
379 cmyk.y = outC[2] / 257;
380 cmyk.k = outC[3] / 257;
381 }
382 }
383
getCMYKValues(const ScColor & color,const ScribusDoc * doc,CMYKColorF & cmyk)384 void ScColorEngine::getCMYKValues(const ScColor& color, const ScribusDoc* doc, CMYKColorF& cmyk)
385 {
386 unsigned short inC[4];
387 unsigned short outC[4];
388 colorModel model = color.getColorModel();
389 ScColorTransform transCMYK = doc ? doc->stdTransCMYK : ScCore->defaultRGBToCMYKTrans;
390 if (ScCore->haveCMS() && transCMYK)
391 {
392 if (model == colorModelRGB)
393 {
394 // allow RGB greys to go to CMYK greys without transform
395 if (color.m_values[0] == color.m_values[1] && color.m_values[1] == color.m_values[2])
396 {
397 cmyk.c = cmyk.m = cmyk.y = 0;
398 cmyk.k = 1.0 - color.m_values[0];
399 }
400 else
401 {
402 inC[0] = qRound(color.m_values[0] * 65535.0);
403 inC[1] = qRound(color.m_values[1] * 65535.0);
404 inC[2] = qRound(color.m_values[2] * 65535.0);
405 transCMYK.apply(inC, outC, 1);
406 cmyk.c = outC[0] / 65535.0;
407 cmyk.m = outC[1] / 65535.0;
408 cmyk.y = outC[2] / 65535.0;
409 cmyk.k = outC[3] / 65535.0;
410 }
411 }
412 else if (model == colorModelCMYK)
413 {
414 cmyk.c = color.m_values[0];
415 cmyk.m = color.m_values[1];
416 cmyk.y = color.m_values[2];
417 cmyk.k = color.m_values[3];
418 }
419 else if (model == colorModelLab)
420 {
421 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
422 double inC[3];
423 inC[0] = color.m_L_val;
424 inC[1] = color.m_a_val;
425 inC[2] = color.m_b_val;
426 quint16 outC[4];
427 trans.apply(inC, outC, 1);
428 cmyk.c = outC[0] / 65535.0;
429 cmyk.m = outC[1] / 65535.0;
430 cmyk.y = outC[2] / 65535.0;
431 cmyk.k = outC[3] / 65535.0;
432 }
433 }
434 else if (model == colorModelRGB)
435 {
436 cmyk.k = qMin(qMin(1.0 - color.m_values[0], 1.0 - color.m_values[1]), 1.0 - color.m_values[2]);
437 cmyk.c = 1.0 - (color.m_values[0] - cmyk.k);
438 cmyk.m = 1.0 - (color.m_values[1] - cmyk.k);
439 cmyk.y = 1.0 - (color.m_values[2] - cmyk.k);
440 }
441 else if (model == colorModelCMYK)
442 {
443 cmyk.c = color.m_values[0];
444 cmyk.m = color.m_values[1];
445 cmyk.y = color.m_values[2];
446 cmyk.k = color.m_values[3];
447 }
448 else if (model == colorModelLab)
449 {
450 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
451 double inC[3];
452 inC[0] = color.m_L_val;
453 inC[1] = color.m_a_val;
454 inC[2] = color.m_b_val;
455 quint16 outC[4];
456 trans.apply(inC, outC, 1);
457 cmyk.c = outC[0] / 65535.0;
458 cmyk.m = outC[1] / 65535.0;
459 cmyk.y = outC[2] / 65535.0;
460 cmyk.k = outC[3] / 65535.0;
461 }
462 }
463
getShadeColorCMYK(const ScColor & color,const ScribusDoc * doc,CMYKColor & cmyk,double level)464 void ScColorEngine::getShadeColorCMYK(const ScColor& color, const ScribusDoc* doc,
465 CMYKColor& cmyk, double level)
466 {
467 if (color.getColorModel() == colorModelRGB)
468 {
469 RGBColorF rgb;
470 getShadeColorRGB(color, doc, rgb, level);
471 ScColor tmpR;
472 tmpR.setRgbColorF(rgb.r, rgb.g, rgb.b);
473 getCMYKValues(tmpR, doc, cmyk);
474 }
475 else if (color.getColorModel() == colorModelCMYK)
476 {
477 cmyk.c = qRound(color.m_values[0] * level / 100.0 * 255.0);
478 cmyk.m = qRound(color.m_values[1] * level / 100.0 * 255.0);
479 cmyk.y = qRound(color.m_values[2] * level / 100.0 * 255.0);
480 cmyk.k = qRound(color.m_values[3] * level / 100.0 * 255.0);
481 }
482 else if (color.getColorModel() == colorModelLab)
483 {
484 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
485 double inC[3];
486 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
487 inC[1] = color.m_a_val * (level / 100.0);
488 inC[2] = color.m_b_val * (level / 100.0);
489 quint16 outC[4];
490 trans.apply(inC, outC, 1);
491 cmyk.c = outC[0] / 257;
492 cmyk.m = outC[1] / 257;
493 cmyk.y = outC[2] / 257;
494 cmyk.k = outC[3] / 257;
495 }
496 }
497
getShadeColorCMYK(const ScColor & color,const ScribusDoc * doc,CMYKColorF & cmyk,double level)498 void ScColorEngine::getShadeColorCMYK(const ScColor& color, const ScribusDoc* doc, CMYKColorF& cmyk, double level)
499 {
500 if (color.getColorModel() == colorModelRGB)
501 {
502 RGBColorF rgb;
503 getShadeColorRGB(color, doc, rgb, level);
504 ScColor tmpR;
505 tmpR.setRgbColorF(rgb.r, rgb.g, rgb.b);
506 getCMYKValues(tmpR, doc, cmyk);
507 }
508 else if (color.getColorModel() == colorModelCMYK)
509 {
510 cmyk.c = color.m_values[0] * level / 100.0;
511 cmyk.m = color.m_values[1] * level / 100.0;
512 cmyk.y = color.m_values[2] * level / 100.0;
513 cmyk.k = color.m_values[3] * level / 100.0;
514 }
515 else if (color.getColorModel() == colorModelLab)
516 {
517 ScColorTransform trans = doc ? doc->stdLabToCMYKTrans : ScCore->defaultLabToCMYKTrans;
518 double inC[3];
519 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
520 inC[1] = color.m_a_val * (level / 100.0);
521 inC[2] = color.m_b_val * (level / 100.0);
522 quint16 outC[4];
523 trans.apply(inC, outC, 1);
524 cmyk.c = outC[0] / 65535.0;
525 cmyk.m = outC[1] / 65535.0;
526 cmyk.y = outC[2] / 65535.0;
527 cmyk.k = outC[3] / 65535.0;
528 }
529 }
530
getShadeColorRGB(const ScColor & color,const ScribusDoc * doc,RGBColor & rgb,double level)531 void ScColorEngine::getShadeColorRGB(const ScColor& color, const ScribusDoc* doc, RGBColor& rgb, double level)
532 {
533 if (color.getColorModel() == colorModelCMYK)
534 {
535 CMYKColor cmyk;
536 getShadeColorCMYK(color, doc, cmyk, level);
537 ScColor tmpC(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
538 getRGBValues(tmpC, doc, rgb);
539 }
540 else if (color.getColorModel() == colorModelRGB)
541 {
542 HSVColorF hsv;
543 RGBColorF rgbF;
544 color.getRawRGBColor(&rgbF);
545 rgbF.toHsv(hsv);
546 hsv.s = hsv.s * (level / 100.0);
547 hsv.v = 1.0 - (1.0 - hsv.v) * (level / 100.0);
548 hsv.toRgb(rgb);
549 //We could also compute rgb shade using rgb directly
550 /*rgb.r = 255 - ((255 - color.m_values[0]) * level / 100);
551 rgb.g = 255 - ((255 - color.m_values[1]) * level / 100);
552 rgb.b = 255 - ((255 - color.m_values[2]) * level / 100);*/
553 }
554 else if (color.getColorModel() == colorModelLab)
555 {
556 ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
557 double inC[3];
558 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
559 inC[1] = color.m_a_val * (level / 100.0);
560 inC[2] = color.m_b_val * (level / 100.0);
561 quint16 outC[3];
562 trans.apply(inC, outC, 1);
563 rgb.r = outC[0] / 257;
564 rgb.g = outC[1] / 257;
565 rgb.b = outC[2] / 257;
566 }
567 }
568
getShadeColorRGB(const ScColor & color,const ScribusDoc * doc,RGBColorF & rgb,double level)569 void ScColorEngine::getShadeColorRGB(const ScColor& color, const ScribusDoc* doc, RGBColorF& rgb, double level)
570 {
571 if (color.getColorModel() == colorModelCMYK)
572 {
573 CMYKColorF cmyk;
574 getShadeColorCMYK(color, doc, cmyk, level);
575 ScColor tmpC;
576 tmpC.setColorF(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
577 getRGBValues(tmpC, doc, rgb);
578 }
579 else if (color.getColorModel() == colorModelRGB)
580 {
581 HSVColorF hsv;
582 color.getRawRGBColor(&rgb);
583 rgb.toHsv(hsv);
584 hsv.s = hsv.s * (level / 100.0);
585 hsv.v = 1.0 - (1.0 - hsv.v) * (level / 100.0);
586 hsv.toRgb(rgb);
587 //We could also compute rgb shade using rgb directly
588 /*rgb.r = 1.0 - ((1.0 - color.m_values[0]) * level / 100.0);
589 rgb.g = 1.0 - ((1.0 - color.m_values[1]) * level / 100.0);
590 rgb.b = 1.0 - ((1.0 - color.m_values[2]) * level / 100.0);*/
591 }
592 else if (color.getColorModel() == colorModelLab)
593 {
594 ScColorTransform trans = doc ? doc->stdLabToRGBTrans : ScCore->defaultLabToRGBTrans;
595 double inC[3];
596 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
597 inC[1] = color.m_a_val * (level / 100.0);
598 inC[2] = color.m_b_val * (level / 100.0);
599 quint16 outC[3];
600 trans.apply(inC, outC, 1);
601 rgb.r = outC[0] / 65535.0;
602 rgb.g = outC[1] / 65535.0;
603 rgb.b = outC[2] / 65535.0;
604 }
605 }
606
getDisplayColor(const ScColor & color,const ScribusDoc * doc)607 QColor ScColorEngine::getDisplayColor(const ScColor& color, const ScribusDoc* doc)
608 {
609 QColor tmp;
610 if (color.getColorModel() == colorModelRGB)
611 {
612 RGBColorF rgb;
613 rgb.r = color.m_values[0];
614 rgb.g = color.m_values[1];
615 rgb.b = color.m_values[2];
616 tmp = getDisplayColor(rgb, doc, color.isSpotColor());
617 }
618 else if (color.getColorModel() == colorModelCMYK)
619 {
620 CMYKColorF cmyk;
621 cmyk.c = color.m_values[0];
622 cmyk.m = color.m_values[1];
623 cmyk.y = color.m_values[2];
624 cmyk.k = color.m_values[3];
625 tmp = getDisplayColor(cmyk, doc, color.isSpotColor());
626 }
627 else if (color.getColorModel() == colorModelLab)
628 {
629 bool cmsUse = doc ? doc->HasCMS : false;
630 ScColorTransform trans = doc ? doc->stdLabToScreenTrans : ScCore->defaultLabToRGBTrans;
631 if (cmsUse && trans)
632 {
633 double inC[3];
634 inC[0] = color.m_L_val;
635 inC[1] = color.m_a_val;
636 inC[2] = color.m_b_val;
637 quint16 outC[3];
638 trans.apply(inC, outC, 1);
639 tmp = QColor(outC[0] / 257, outC[1] / 257, outC[2] / 257);
640 }
641 else
642 {
643 // First step: Lab -> XYZ
644 double var_Y = (color.m_L_val + 16) / 116.0;
645 double var_X = color.m_a_val / 500.0 + var_Y;
646 double var_Z = var_Y - color.m_b_val / 200.0;
647 if (pow(var_Y, 3) > 0.008856)
648 var_Y = pow(var_Y, 3);
649 else
650 var_Y = (var_Y - 16.0 / 116.0) / 7.787;
651 if (pow(var_X, 3) > 0.008856)
652 var_X = pow(var_X, 3);
653 else
654 var_X = (var_X - 16.0 / 116.0) / 7.787;
655 if (pow(var_Z, 3) > 0.008856)
656 var_Z = pow(var_Z, 3);
657 else
658 var_Z = (var_Z - 16.0 / 116.0) / 7.787;
659 // Second step: XYZ -> RGB
660 // Whitepoint D50
661 var_X = 0.990720 * var_X;
662 var_Y = 1.00000 * var_Y;
663 var_Z = 0.825210 * var_Z;
664 double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
665 double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
666 double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
667 if (var_R > 0.0031308)
668 var_R = 1.055 * (pow(var_R, (1.0 / 2.4))) - 0.055;
669 else
670 var_R = 12.92 * var_R;
671 if (var_G > 0.0031308)
672 var_G = 1.055 * (pow(var_G, (1.0 / 2.4))) - 0.055;
673 else
674 var_G = 12.92 * var_G;
675 if (var_B > 0.0031308)
676 var_B = 1.055 * (pow(var_B, (1.0 / 2.4))) - 0.055;
677 else
678 var_B = 12.92 * var_B;
679 tmp = QColor(0, 0, 0, 0);
680 var_R = qMax(qMin(var_R, 1.0), 0.0);
681 var_G = qMax(qMin(var_G, 1.0), 0.0);
682 var_B = qMax(qMin(var_B, 1.0), 0.0);
683 tmp.setRgbF(var_R, var_G, var_B);
684 }
685 }
686 return tmp;
687 }
688
getDisplayColor(const ScColor & color,const ScribusDoc * doc,double level)689 QColor ScColorEngine::getDisplayColor(const ScColor& color, const ScribusDoc* doc, double level)
690 {
691 QColor tmp;
692 if (color.getColorModel() == colorModelRGB)
693 {
694 RGBColorF rgb;
695 rgb.r = color.m_values[0];
696 rgb.g = color.m_values[1];
697 rgb.b = color.m_values[2];
698 getShadeColorRGB(color, doc, rgb, level);
699 tmp = getDisplayColor(rgb, doc, color.isSpotColor());
700 }
701 else if (color.getColorModel() == colorModelCMYK)
702 {
703 CMYKColorF cmyk;
704 cmyk.c = color.m_values[0];
705 cmyk.m = color.m_values[1];
706 cmyk.y = color.m_values[2];
707 cmyk.k = color.m_values[3];
708 getShadeColorCMYK(color, doc, cmyk, level);
709 tmp = getDisplayColor(cmyk, doc, color.isSpotColor());
710 }
711 else if (color.getColorModel() == colorModelLab)
712 {
713 ScColorTransform trans = doc ? doc->stdLabToScreenTrans : ScCore->defaultLabToRGBTrans;
714 double inC[3];
715 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
716 inC[1] = color.m_a_val * (level / 100.0);
717 inC[2] = color.m_b_val * (level / 100.0);
718 quint16 outC[3];
719 trans.apply(inC, outC, 1);
720 tmp = QColor(outC[0] / 257, outC[1] / 257, outC[2] / 257);
721 }
722 return tmp;
723 }
724
getDisplayColorGC(const ScColor & color,const ScribusDoc * doc,bool * outOfG)725 QColor ScColorEngine::getDisplayColorGC(const ScColor& color, const ScribusDoc* doc, bool *outOfG)
726 {
727 QColor tmp;
728 bool doSoftProofing = doc ? doc->SoftProofing : false;
729 bool doGamutCheck = doc ? doc->Gamut : false;
730 if (doSoftProofing && doGamutCheck)
731 {
732 bool outOfGamutFlag = isOutOfGamut(color, doc);
733 if (outOfG != nullptr)
734 *outOfG = outOfGamutFlag;
735 tmp = outOfGamutFlag ? QColor(0, 255, 0) : getDisplayColor(color, doc);
736 }
737 else
738 tmp = getDisplayColor(color, doc);
739 return tmp;
740 }
741
getColorProof(const ScColor & color,const ScribusDoc * doc,bool gamutCheck)742 QColor ScColorEngine::getColorProof(const ScColor& color, const ScribusDoc* doc, bool gamutCheck)
743 {
744 QColor tmp;
745 bool gamutChkEnabled = doc ? doc->Gamut : false;
746 bool spot = color.isSpotColor();
747 if (color.getColorModel() == colorModelRGB)
748 {
749 // Match 133x behavior (RGB greys map to cmyk greys) until we are able to make rgb profiled output
750 if (color.m_values[0] == color.m_values[1] && color.m_values[1] == color.m_values[2])
751 gamutChkEnabled = false;
752 RGBColor rgb;
753 rgb.r = qRound(color.m_values[0] * 255.0);
754 rgb.g = qRound(color.m_values[1] * 255.0);
755 rgb.b = qRound(color.m_values[2] * 255.0);
756 tmp = getColorProof(rgb, doc, spot, gamutCheck & gamutChkEnabled);
757 }
758 else
759 {
760 CMYKColor cmyk;
761 cmyk.c = qRound(color.m_values[0] * 255.0);
762 cmyk.m = qRound(color.m_values[1] * 255.0);
763 cmyk.y = qRound(color.m_values[2] * 255.0);
764 cmyk.k = qRound(color.m_values[3] * 255.0);
765 tmp = getColorProof(cmyk, doc, spot, gamutCheck & gamutChkEnabled);
766 }
767 return tmp;
768 }
769
getShadeColor(const ScColor & color,const ScribusDoc * doc,double level)770 QColor ScColorEngine::getShadeColor(const ScColor& color, const ScribusDoc* doc, double level)
771 {
772 RGBColor rgb;
773 rgb.r = qRound(color.m_values[0] * 255.0);
774 rgb.g = qRound(color.m_values[1] * 255.0);
775 rgb.b = qRound(color.m_values[2] * 255.0);
776 getShadeColorRGB(color, doc, rgb, level);
777 return QColor(rgb.r, rgb.g, rgb.b);
778 }
779
getShadeColorProof(const ScColor & color,const ScribusDoc * doc,double level)780 QColor ScColorEngine::getShadeColorProof(const ScColor& color, const ScribusDoc* doc, double level)
781 {
782 QColor tmp;
783 bool doGC = doc ? doc->Gamut : false;
784 bool cmsUse = doc ? doc->HasCMS : false;
785 bool softProof = doc ? doc->SoftProofing : false;
786
787 if (color.getColorModel() == colorModelRGB)
788 {
789 RGBColorF rgb;
790 rgb.r = color.m_values[0];
791 rgb.g = color.m_values[1];
792 rgb.b = color.m_values[2];
793 getShadeColorRGB(color, doc, rgb, level);
794 // Match 133x behavior for rgb grey until we are able to make rgb profiled output
795 // (RGB greys map to cmyk greys)
796 if ((cmsUse && softProof) && (rgb.r == rgb.g && rgb.g == rgb.b))
797 {
798 doGC = false;
799 CMYKColorF cmyk;
800 cmyk.c = cmyk.m = cmyk.y = 0;
801 cmyk.k = 1.0 - rgb.g;
802 tmp = getColorProof(cmyk, doc, color.isSpotColor(), doGC);
803 }
804 else
805 tmp = getColorProof(rgb, doc, color.isSpotColor(), doGC);
806 }
807 else if (color.getColorModel() == colorModelCMYK)
808 {
809 CMYKColorF cmyk;
810 cmyk.c = color.m_values[0];
811 cmyk.m = color.m_values[1];
812 cmyk.y = color.m_values[2];
813 cmyk.k = color.m_values[3];
814 getShadeColorCMYK(color, doc, cmyk, level);
815 tmp = getColorProof(cmyk, doc, color.isSpotColor(), doGC);
816 }
817 else if (color.getColorModel() == colorModelLab)
818 {
819 double inC[3];
820 inC[0] = 100 - (100 - color.m_L_val) * (level / 100.0);
821 inC[1] = color.m_a_val * (level / 100.0);
822 inC[2] = color.m_b_val * (level / 100.0);
823 quint16 outC[3];
824 ScColorTransform trans = doc ? doc->stdLabToScreenTrans : ScCore->defaultLabToRGBTrans;
825 ScColorTransform transProof = doc ? doc->stdProofLab : ScCore->defaultLabToRGBTrans;
826 ScColorTransform transProofGC = doc ? doc->stdProofLabGC : ScCore->defaultLabToRGBTrans;
827 if (cmsUse && doc && doc->SoftProofing)
828 {
829 ScColorTransform xform = doGC ? transProofGC : transProof;
830 xform.apply(inC, outC, 1);
831 tmp = QColor(outC[0] / 257, outC[1] / 257, outC[2] / 257);
832 }
833 else
834 {
835 trans.apply(inC, outC, 1);
836 tmp = QColor(outC[0] / 257, outC[1] / 257, outC[2] / 257);
837 }
838 }
839
840 return tmp;
841 }
842
getColorProof(RGBColor & rgb,const ScribusDoc * doc,bool spot,bool gamutCkeck)843 QColor ScColorEngine::getColorProof(RGBColor& rgb, const ScribusDoc* doc, bool spot, bool gamutCkeck)
844 {
845 unsigned short inC[4];
846 unsigned short outC[4];
847 int r = rgb.r, g = rgb.g, b = rgb.b;
848 ScColorTransform transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
849 ScColorTransform transProof = doc ? doc->stdProof : ScCore->defaultRGBToScreenSolidTrans;
850 ScColorTransform transProofGC = doc ? doc->stdProofGC : ScCore->defaultRGBToScreenSolidTrans;
851 bool cmsUse = doc ? doc->HasCMS : false;
852 bool cmsTrans = (transRGBMon && transProof && transProofGC);
853 if (ScCore->haveCMS() && cmsTrans)
854 {
855 inC[0] = rgb.r * 257;
856 inC[1] = rgb.g * 257;
857 inC[2] = rgb.b * 257;
858 if (cmsUse && !spot && doc->SoftProofing)
859 {
860 ScColorTransform xform = gamutCkeck ? transProofGC : transProof;
861 xform.apply(inC, outC, 1);
862 r = outC[0] / 257;
863 g = outC[1] / 257;
864 b = outC[2] / 257;
865 }
866 else
867 {
868 transRGBMon.apply(inC, outC, 1);
869 r = outC[0] / 257;
870 g = outC[1] / 257;
871 b = outC[2] / 257;
872 }
873 }
874 return QColor(r, g, b);
875 }
876
getColorProof(RGBColorF & rgb,const ScribusDoc * doc,bool spot,bool gamutCkeck)877 QColor ScColorEngine::getColorProof(RGBColorF& rgb, const ScribusDoc* doc, bool spot, bool gamutCkeck)
878 {
879 unsigned short inC[4];
880 unsigned short outC[4];
881 int r = qRound(rgb.r * 255.0);
882 int g = qRound(rgb.g * 255.0);
883 int b = qRound(rgb.b * 255.0);
884 ScColorTransform transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
885 ScColorTransform transProof = doc ? doc->stdProof : ScCore->defaultRGBToScreenSolidTrans;
886 ScColorTransform transProofGC = doc ? doc->stdProofGC : ScCore->defaultRGBToScreenSolidTrans;
887 bool cmsUse = doc ? doc->HasCMS : false;
888 bool cmsTrans = (transRGBMon && transProof && transProofGC);
889 if (ScCore->haveCMS() && cmsTrans)
890 {
891 inC[0] = rgb.r * 65535.0;
892 inC[1] = rgb.g * 65535.0;
893 inC[2] = rgb.b * 65535.0;
894 if (cmsUse && !spot && doc->SoftProofing)
895 {
896 ScColorTransform xform = gamutCkeck ? transProofGC : transProof;
897 xform.apply(inC, outC, 1);
898 r = outC[0] / 257;
899 g = outC[1] / 257;
900 b = outC[2] / 257;
901 }
902 else
903 {
904 transRGBMon.apply(inC, outC, 1);
905 r = outC[0] / 257;
906 g = outC[1] / 257;
907 b = outC[2] / 257;
908 }
909 }
910 return QColor(r, g, b);
911 }
912
getColorProof(CMYKColor & cmyk,const ScribusDoc * doc,bool spot,bool gamutCkeck)913 QColor ScColorEngine::getColorProof(CMYKColor& cmyk, const ScribusDoc* doc, bool spot, bool gamutCkeck)
914 {
915 int r = 0, g = 0, b = 0;
916 unsigned short inC[4];
917 unsigned short outC[4];
918 ScColorTransform transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
919 ScColorTransform transProofCMYK = doc ? doc->stdProofCMYK : ScCore->defaultCMYKToRGBTrans;
920 ScColorTransform transProofCMYKGC = doc ? doc->stdProofCMYKGC : ScCore->defaultCMYKToRGBTrans;
921 bool cmsUse = doc ? doc->HasCMS : false;
922 bool cmsTrans = (transCMYKMon && transProofCMYK && transProofCMYKGC);
923 if (ScCore->haveCMS() && cmsTrans)
924 {
925 inC[0] = cmyk.c * 257;
926 inC[1] = cmyk.m * 257;
927 inC[2] = cmyk.y * 257;
928 inC[3] = cmyk.k * 257;
929 if (cmsUse && !spot && doc->SoftProofing)
930 {
931 ScColorTransform xform = gamutCkeck ? transProofCMYKGC : transProofCMYK;
932 xform.apply(inC, outC, 1);
933 r = outC[0] / 257;
934 g = outC[1] / 257;
935 b = outC[2] / 257;
936 }
937 else
938 {
939 transCMYKMon.apply(inC, outC, 1);
940 r = outC[0] / 257;
941 g = outC[1] / 257;
942 b = outC[2] / 257;
943 }
944 }
945 else
946 {
947 r = 255 - qMin(255, cmyk.c + cmyk.k);
948 g = 255 - qMin(255, cmyk.m + cmyk.k);
949 b = 255 - qMin(255, cmyk.y + cmyk.k);
950 }
951 return QColor(r, g, b);
952 }
953
getColorProof(CMYKColorF & cmyk,const ScribusDoc * doc,bool spot,bool gamutCkeck)954 QColor ScColorEngine::getColorProof(CMYKColorF& cmyk, const ScribusDoc* doc, bool spot, bool gamutCkeck)
955 {
956 int r = 0, g = 0, b = 0;
957 unsigned short inC[4];
958 unsigned short outC[4];
959 ScColorTransform transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
960 ScColorTransform transProofCMYK = doc ? doc->stdProofCMYK : ScCore->defaultCMYKToRGBTrans;
961 ScColorTransform transProofCMYKGC = doc ? doc->stdProofCMYKGC : ScCore->defaultCMYKToRGBTrans;
962 bool cmsUse = doc ? doc->HasCMS : false;
963 bool cmsTrans = (transCMYKMon && transProofCMYK && transProofCMYKGC);
964 if (ScCore->haveCMS() && cmsTrans)
965 {
966 inC[0] = cmyk.c * 65535.0;
967 inC[1] = cmyk.m * 65535.0;
968 inC[2] = cmyk.y * 65535.0;
969 inC[3] = cmyk.k * 65535.0;
970 if (cmsUse && !spot && doc->SoftProofing)
971 {
972 ScColorTransform xform = gamutCkeck ? transProofCMYKGC : transProofCMYK;
973 xform.apply(inC, outC, 1);
974 r = outC[0] / 257;
975 g = outC[1] / 257;
976 b = outC[2] / 257;
977 }
978 else
979 {
980 transCMYKMon.apply(inC, outC, 1);
981 r = outC[0] / 257;
982 g = outC[1] / 257;
983 b = outC[2] / 257;
984 }
985 }
986 else
987 {
988 r = 255 - qMin(255, qRound((cmyk.c + cmyk.k) * 255.0));
989 g = 255 - qMin(255, qRound((cmyk.m + cmyk.k) * 255.0));
990 b = 255 - qMin(255, qRound((cmyk.y + cmyk.k) * 255.0));
991 }
992 return QColor(r, g, b);
993 }
994
getDisplayColor(RGBColor & rgb,const ScribusDoc * doc,bool spot)995 QColor ScColorEngine::getDisplayColor(RGBColor& rgb, const ScribusDoc* doc, bool spot)
996 {
997 unsigned short inC[4];
998 unsigned short outC[4];
999 int r = rgb.r;
1000 int g = rgb.g;
1001 int b = rgb.b;
1002 ScColorTransform transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
1003 if (ScCore->haveCMS() && transRGBMon)
1004 {
1005 inC[0] = r * 257;
1006 inC[1] = g * 257;
1007 inC[2] = b * 257;
1008 transRGBMon.apply(inC, outC, 1);
1009 r = outC[0] / 257;
1010 g = outC[1] / 257;
1011 b = outC[2] / 257;
1012 }
1013 return QColor(r, g, b);
1014 }
1015
getDisplayColor(RGBColorF & rgb,const ScribusDoc * doc,bool spot)1016 QColor ScColorEngine::getDisplayColor(RGBColorF& rgb, const ScribusDoc* doc, bool spot)
1017 {
1018 unsigned short inC[4];
1019 unsigned short outC[4];
1020 int r = rgb.r * 255.0;
1021 int g = rgb.g * 255.0;
1022 int b = rgb.b * 255.0;
1023 ScColorTransform transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
1024 if (ScCore->haveCMS() && transRGBMon)
1025 {
1026 inC[0] = rgb.r * 65535.0;
1027 inC[1] = rgb.g * 65535.0;
1028 inC[2] = rgb.b * 65535.0;
1029 transRGBMon.apply(inC, outC, 1);
1030 r = outC[0] / 257;
1031 g = outC[1] / 257;
1032 b = outC[2] / 257;
1033 }
1034 return QColor(r, g, b);
1035 }
1036
getDisplayColor(CMYKColor & cmyk,const ScribusDoc * doc,bool spot)1037 QColor ScColorEngine::getDisplayColor(CMYKColor& cmyk, const ScribusDoc* doc, bool spot)
1038 {
1039 int r = 0, g = 0, b = 0;
1040 unsigned short inC[4];
1041 unsigned short outC[4];
1042 ScColorTransform transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
1043 if (ScCore->haveCMS() && transCMYKMon)
1044 {
1045 inC[0] = cmyk.c * 257;
1046 inC[1] = cmyk.m * 257;
1047 inC[2] = cmyk.y * 257;
1048 inC[3] = cmyk.k * 257;
1049 transCMYKMon.apply(inC, outC, 1);
1050 r = outC[0] / 257;
1051 g = outC[1] / 257;
1052 b = outC[2] / 257;
1053 }
1054 else
1055 {
1056 r = 255 - qMin(255, cmyk.c + cmyk.k);
1057 g = 255 - qMin(255, cmyk.m + cmyk.k);
1058 b = 255 - qMin(255, cmyk.y + cmyk.k);
1059 }
1060 return QColor(r, g, b);
1061 }
1062
getDisplayColor(CMYKColorF & cmyk,const ScribusDoc * doc,bool spot)1063 QColor ScColorEngine::getDisplayColor(CMYKColorF& cmyk, const ScribusDoc* doc, bool spot)
1064 {
1065 int r = 0, g = 0, b = 0;
1066 unsigned short inC[4];
1067 unsigned short outC[4];
1068 ScColorTransform transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
1069 if (ScCore->haveCMS() && transCMYKMon)
1070 {
1071 inC[0] = cmyk.c * 65535.0;
1072 inC[1] = cmyk.m * 65535.0;
1073 inC[2] = cmyk.y * 65535.0;
1074 inC[3] = cmyk.k * 65535.0;
1075 transCMYKMon.apply(inC, outC, 1);
1076 r = outC[0] / 257;
1077 g = outC[1] / 257;
1078 b = outC[2] / 257;
1079 }
1080 else
1081 {
1082 r = 255 - qMin(255, qRound((cmyk.c + cmyk.k) * 255.0));
1083 g = 255 - qMin(255, qRound((cmyk.m + cmyk.k) * 255.0));
1084 b = 255 - qMin(255, qRound((cmyk.y + cmyk.k) * 255.0));
1085 }
1086 return QColor(r, g, b);
1087 }
1088
isOutOfGamut(const ScColor & color,const ScribusDoc * doc)1089 bool ScColorEngine::isOutOfGamut(const ScColor& color, const ScribusDoc* doc)
1090 {
1091 bool outOfGamutFlag = false;
1092 if (color.isSpotColor())
1093 return false;
1094 unsigned short inC[4];
1095 unsigned short outC[4];
1096 bool cmsUse = doc ? doc->HasCMS : false;
1097 if (ScCore->haveCMS() && cmsUse)
1098 {
1099 bool alert = true;
1100 ScColorTransform xformProof;
1101 if (color.getColorModel() == colorModelRGB)
1102 {
1103 inC[0] = qRound(color.m_values[0] * 65535.0);
1104 inC[1] = qRound(color.m_values[1] * 65535.0);
1105 inC[2] = qRound(color.m_values[2] * 65535.0);
1106 xformProof = doc->stdProofGC;
1107 if ((color.m_values[0] == 0) && (color.m_values[1] == 0) && (color.m_values[2] == 1.0))
1108 alert = false;
1109 if ((color.m_values[0] == color.m_values[1] && color.m_values[1] == color.m_values[2]))
1110 alert = false;
1111 }
1112 else if (color.getColorModel() == colorModelCMYK)
1113 {
1114 inC[0] = qRound(color.m_values[0] * 65535.0);
1115 inC[1] = qRound(color.m_values[1] * 65535.0);
1116 inC[2] = qRound(color.m_values[2] * 65535.0);
1117 inC[3] = qRound(color.m_values[3] * 65535.0);
1118 xformProof = doc->stdProofCMYKGC;
1119 if ((color.m_values[0] == 1.0) && (color.m_values[1] == 0) && (color.m_values[3] == 0) && (color.m_values[2] == 1.0))
1120 alert = false;
1121 if ((color.m_values[0] == 0.0) && (color.m_values[1] == 0) && (color.m_values[2] == 0))
1122 alert = false;
1123 if ((color.m_values[0] == color.m_values[1]) && (color.m_values[0] == color.m_values[2]) && (color.m_values[2] == color.m_values[3]))
1124 alert = false;
1125 }
1126 else if (color.getColorModel() == colorModelLab)
1127 {
1128 double inC[3];
1129 inC[0] = color.m_L_val;
1130 inC[1] = color.m_a_val;
1131 inC[2] = color.m_b_val;
1132 xformProof = doc->stdProofLabGC;
1133 xformProof.apply(inC, outC, 1);
1134 if ((outC[0]/257 == 0) && (outC[1]/257 == 255) && (outC[2]/257 == 0))
1135 outOfGamutFlag = true;
1136 alert = false;
1137 }
1138 if (alert)
1139 {
1140 xformProof.apply(inC, outC, 1);
1141 if ((outC[0]/257 == 0) && (outC[1]/257 == 255) && (outC[2]/257 == 0))
1142 outOfGamutFlag = true;
1143 }
1144 }
1145 return outOfGamutFlag;
1146 }
1147
applyGCR(ScColor & color,const ScribusDoc * doc)1148 void ScColorEngine::applyGCR(ScColor& color, const ScribusDoc* doc)
1149 {
1150 bool cmsUse = doc ? doc->HasCMS : false;
1151 if (!(ScCore->haveCMS() && cmsUse) && (color.getColorModel() != colorModelLab))
1152 {
1153 CMYKColor cmyk;
1154 getCMYKValues(color, doc, cmyk);
1155 int k = qMin(qMin(cmyk.c, cmyk.m), cmyk.y);
1156 color.m_values[0] = (cmyk.c - k) / 255.0;
1157 color.m_values[1] = (cmyk.m - k) / 255.0;
1158 color.m_values[2] = (cmyk.y - k) / 255.0;
1159 color.m_values[3] = qMin((cmyk.k + k) / 255.0, 1.0);
1160 }
1161 }
1162