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 "sccolorengine.h"
00025 #include "scribuscore.h"
00026 #include CMS_INC
00027
00028 QColor ScColorEngine::getRGBColor(const ScColor& color, const ScribusDoc* doc)
00029 {
00030 RGBColor rgb;
00031 getRGBValues(color, doc, rgb);
00032 return QColor(rgb.r, rgb.g, rgb.b);
00033 }
00034
00035 ScColor ScColorEngine::convertToModel(const ScColor& color, const ScribusDoc* doc, colorModel model)
00036 {
00037 colorModel oldModel = color.getColorModel();
00038 if( oldModel == model )
00039 return ScColor(color);
00040 ScColor newCol;
00041 if( model == colorModelRGB )
00042 {
00043 RGBColor rgb;
00044 getRGBValues(color, doc, rgb);
00045 newCol.setColorRGB(rgb.r, rgb.g, rgb.b);
00046 }
00047 else
00048 {
00049 CMYKColor cmyk;
00050 getCMYKValues(color, doc, cmyk);
00051 newCol.setColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
00052 }
00053 return newCol;
00054 }
00055
00056 void ScColorEngine::getRGBValues(const ScColor& color, const ScribusDoc* doc, RGBColor& rgb)
00057 {
00058 colorModel model = color.getColorModel();
00059 cmsHTRANSFORM transRGB = doc ? doc->stdTransRGB : ScCore->defaultCMYKToRGBTrans;
00060 if (ScCore->haveCMS() && transRGB)
00061 {
00062 if (model == colorModelRGB)
00063 {
00064 rgb.r = color.CR;
00065 rgb.g = color.MG;
00066 rgb.b = color.YB;
00067 }
00068 else
00069 {
00070 WORD inC[4];
00071 WORD outC[4];
00072 inC[0] = color.CR * 257;
00073 inC[1] = color.MG * 257;
00074 inC[2] = color.YB * 257;
00075 inC[3] = color.K * 257;
00076 cmsDoTransform(transRGB, inC, outC, 1);
00077 rgb.r = outC[0] / 257;
00078 rgb.g = outC[1] / 257;
00079 rgb.b = outC[2] / 257;
00080 }
00081 }
00082 else if (model == colorModelCMYK)
00083 {
00084 rgb.r = 255 - qMin(255, color.CR + color.K);
00085 rgb.g = 255 - qMin(255, color.MG + color.K);
00086 rgb.b = 255 - qMin(255, color.YB + color.K);
00087 }
00088 else
00089 {
00090 rgb.r = color.CR;
00091 rgb.g = color.MG;
00092 rgb.b = color.YB;
00093 }
00094 }
00095
00096 void ScColorEngine::getCMYKValues(const ScColor& color, const ScribusDoc* doc, CMYKColor& cmyk)
00097 {
00098 WORD inC[4];
00099 WORD outC[4];
00100 colorModel model = color.getColorModel();
00101 cmsHTRANSFORM transCMYK = doc ? doc->stdTransCMYK : ScCore->defaultRGBToCMYKTrans;
00102 if (ScCore->haveCMS() && transCMYK)
00103 {
00104 if (model == colorModelRGB)
00105 {
00106
00107 if (color.CR == color.MG && color.MG == color.YB)
00108 {
00109 cmyk.c = cmyk.m = cmyk.y = 0;
00110 cmyk.k = 255 - color.CR;
00111 }
00112 else
00113 {
00114 inC[0] = color.CR * 257;
00115 inC[1] = color.MG * 257;
00116 inC[2] = color.YB * 257;
00117 cmsDoTransform(transCMYK, inC, outC, 1);
00118 cmyk.c = outC[0] / 257;
00119 cmyk.m = outC[1] / 257;
00120 cmyk.y = outC[2] / 257;
00121 cmyk.k = outC[3] / 257;
00122 }
00123 }
00124 else
00125 {
00126 cmyk.c = color.CR;
00127 cmyk.m = color.MG;
00128 cmyk.y = color.YB;
00129 cmyk.k = color.K;
00130 }
00131 }
00132 else if (model == colorModelRGB)
00133 {
00134 cmyk.k = qMin(qMin(255 - color.CR, 255 - color.MG), 255 - color.YB);
00135 cmyk.c = 255 - color.CR - cmyk.k;
00136 cmyk.m = 255 - color.MG - cmyk.k;
00137 cmyk.y = 255 - color.YB - cmyk.k;
00138 }
00139 else
00140 {
00141 cmyk.c = color.CR;
00142 cmyk.m = color.MG;
00143 cmyk.y = color.YB;
00144 cmyk.k = color.K;
00145 }
00146 }
00147
00148 void ScColorEngine::getShadeColorCMYK(const ScColor& color, const ScribusDoc* doc,
00149 CMYKColor& cmyk, double level)
00150 {
00151 if (color.getColorModel() == colorModelRGB)
00152 {
00153 RGBColor rgb;
00154 getShadeColorRGB(color, doc, rgb, level);
00155 ScColor tmpR(rgb.r, rgb.g, rgb.b);
00156 getCMYKValues(tmpR, doc, cmyk);
00157 }
00158 else
00159 {
00160 cmyk.c = qRound(color.CR * level / 100.0);
00161 cmyk.m = qRound(color.MG * level / 100.0);
00162 cmyk.y = qRound(color.YB * level / 100.0);
00163 cmyk.k = qRound(color.K * level / 100.0);
00164 }
00165 }
00166
00167 void ScColorEngine::getShadeColorRGB(const ScColor& color, const ScribusDoc* doc, RGBColor& rgb, double level)
00168 {
00169 if (color.getColorModel() == colorModelCMYK)
00170 {
00171 CMYKColor cmyk;
00172 getShadeColorCMYK(color, doc, cmyk, level);
00173 ScColor tmpC(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
00174 getRGBValues(tmpC, doc, rgb);
00175 }
00176 else
00177 {
00178 int h, s, v, snew, vnew;
00179 QColor tmpR(color.CR, color.MG, color.YB);
00180 tmpR.getHsv(&h, &s, &v);
00181 snew = qRound(s * level / 100.0);
00182 vnew = 255 - qRound(((255 - v) * level / 100.0));
00183 tmpR.setHsv(h, snew, vnew);
00184 tmpR.getRgb(&rgb.r, &rgb.g, &rgb.b);
00185
00186
00187
00188
00189 }
00190 }
00191
00192 QColor ScColorEngine::getDisplayColor(const ScColor& color, const ScribusDoc* doc)
00193 {
00194 QColor tmp;
00195 if (color.getColorModel() == colorModelRGB)
00196 {
00197 RGBColor rgb;
00198 rgb.r = color.CR;
00199 rgb.g = color.MG;
00200 rgb.b = color.YB;
00201 tmp = getDisplayColor(rgb, doc, color.isSpotColor());
00202 }
00203 else
00204 {
00205 CMYKColor cmyk;
00206 cmyk.c = color.CR;
00207 cmyk.m = color.MG;
00208 cmyk.y = color.YB;
00209 cmyk.k = color.K;
00210 tmp = getDisplayColor(cmyk, doc, color.isSpotColor());
00211 }
00212 return tmp;
00213 }
00214
00215 QColor ScColorEngine::getDisplayColor(const ScColor& color, const ScribusDoc* doc, double level)
00216 {
00217 QColor tmp;
00218 if (color.getColorModel() == colorModelRGB)
00219 {
00220 RGBColor rgb;
00221 rgb.r = color.CR;
00222 rgb.g = color.MG;
00223 rgb.b = color.YB;
00224 getShadeColorRGB(color, doc, rgb, level);
00225 tmp = getDisplayColor(rgb, doc, color.isSpotColor());
00226 }
00227 else
00228 {
00229 CMYKColor cmyk;
00230 cmyk.c = color.CR;
00231 cmyk.m = color.MG;
00232 cmyk.y = color.YB;
00233 cmyk.k = color.K;
00234 getShadeColorCMYK(color, doc, cmyk, level);
00235 tmp = getDisplayColor(cmyk, doc, color.isSpotColor());
00236 }
00237 return tmp;
00238 }
00239
00240 QColor ScColorEngine::getDisplayColorGC(const ScColor& color, const ScribusDoc* doc)
00241 {
00242 QColor tmp;
00243 bool doSoftProofing = doc ? doc->SoftProofing : false;
00244 bool doGamutCheck = doc ? doc->Gamut : false;
00245 if ( doSoftProofing && doGamutCheck )
00246 {
00247 bool outOfGamutFlag = isOutOfGamut(color, doc);
00248 tmp = outOfGamutFlag ? QColor(0, 255, 0) : getDisplayColor(color, doc);
00249 }
00250 else
00251 tmp = getDisplayColor(color, doc);
00252 return tmp;
00253 }
00254
00255 QColor ScColorEngine::getColorProof(const ScColor& color, const ScribusDoc* doc, bool gamutCheck)
00256 {
00257 QColor tmp;
00258 bool gamutChkEnabled = doc ? doc->Gamut : false;
00259 bool spot = color.isSpotColor();
00260 if (color.getColorModel() == colorModelRGB)
00261 {
00262
00263 if ( color.CR == color.MG && color.MG == color.YB )
00264 gamutChkEnabled = false;
00265 RGBColor rgb;
00266 rgb.r = color.CR;
00267 rgb.g = color.MG;
00268 rgb.b = color.YB;
00269 tmp = getColorProof(rgb, doc, spot, gamutCheck & gamutChkEnabled);
00270 }
00271 else
00272 {
00273 CMYKColor cmyk;
00274 cmyk.c = color.CR;
00275 cmyk.m = color.MG;
00276 cmyk.y = color.YB;
00277 cmyk.k = color.K;
00278 tmp = getColorProof(cmyk, doc, spot, gamutCheck & gamutChkEnabled);
00279 }
00280 return tmp;
00281 }
00282
00283 QColor ScColorEngine::getShadeColor(const ScColor& color, const ScribusDoc* doc, double level)
00284 {
00285 RGBColor rgb;
00286 rgb.r = color.CR;
00287 rgb.g = color.MG;
00288 rgb.b = color.YB;
00289 getShadeColorRGB(color, doc, rgb, level);
00290 return QColor(rgb.r, rgb.g, rgb.b);
00291 }
00292
00293 QColor ScColorEngine::getShadeColorProof(const ScColor& color, const ScribusDoc* doc, double level)
00294 {
00295 QColor tmp;
00296 bool doGC = false;
00297 if (doc)
00298 doGC = doc->Gamut;
00299
00300 if (color.getColorModel() == colorModelRGB)
00301 {
00302 RGBColor rgb;
00303 rgb.r = color.CR;
00304 rgb.g = color.MG;
00305 rgb.b = color.YB;
00306 getShadeColorRGB(color, doc, rgb, level);
00307
00308
00309 if ( rgb.r == rgb.g && rgb.g == rgb.b )
00310 doGC = false;
00311 tmp = getColorProof(rgb, doc, color.isSpotColor(), doGC);
00312 }
00313 else
00314 {
00315 CMYKColor cmyk;
00316 cmyk.c = color.CR;
00317 cmyk.m = color.MG;
00318 cmyk.y = color.YB;
00319 cmyk.k = color.K;
00320 getShadeColorCMYK(color, doc, cmyk, level);
00321 tmp = getColorProof(cmyk, doc, color.isSpotColor(), doGC);
00322 }
00323
00324 return tmp;
00325 }
00326
00327 QColor ScColorEngine::getColorProof(RGBColor& rgb, const ScribusDoc* doc, bool spot, bool gamutCkeck)
00328 {
00329 WORD inC[4];
00330 WORD outC[4];
00331 int r = rgb.r, g = rgb.g, b = rgb.b;
00332 cmsHTRANSFORM transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
00333 cmsHTRANSFORM transProof = doc ? doc->stdProof : ScCore->defaultRGBToScreenSolidTrans;
00334 cmsHTRANSFORM transProofGC = doc ? doc->stdProofGC : ScCore->defaultRGBToScreenSolidTrans;
00335 bool cmsUse = doc ? doc->HasCMS : false;
00336 bool cmsTrans = (transRGBMon && transProof && transProofGC);
00337 if (ScCore->haveCMS() && cmsTrans)
00338 {
00339 inC[0] = rgb.r * 257;
00340 inC[1] = rgb.g * 257;
00341 inC[2] = rgb.b * 257;
00342 if (cmsUse && !spot && doc->SoftProofing)
00343 {
00344 cmsHTRANSFORM xform = gamutCkeck ? transProofGC : transProof;
00345 cmsDoTransform(xform, inC, outC, 1);
00346 r = outC[0] / 257;
00347 g = outC[1] / 257;
00348 b = outC[2] / 257;
00349 }
00350 else
00351 {
00352 cmsDoTransform(transRGBMon, inC, outC, 1);
00353 r = outC[0] / 257;
00354 g = outC[1] / 257;
00355 b = outC[2] / 257;
00356 }
00357 }
00358 return QColor(r, g, b);
00359 }
00360
00361 QColor ScColorEngine::getColorProof(CMYKColor& cmyk, const ScribusDoc* doc, bool spot, bool gamutCkeck)
00362 {
00363 int r = 0, g = 0, b = 0;
00364 WORD inC[4];
00365 WORD outC[4];
00366 cmsHTRANSFORM transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
00367 cmsHTRANSFORM transProofCMYK = doc ? doc->stdProofCMYK : ScCore->defaultCMYKToRGBTrans;
00368 cmsHTRANSFORM transProofCMYKGC = doc ? doc->stdProofCMYKGC : ScCore->defaultCMYKToRGBTrans;
00369 bool cmsUse = doc ? doc->HasCMS : false;
00370 bool cmsTrans = (transCMYKMon && transProofCMYK && transProofCMYKGC);
00371 if (ScCore->haveCMS() && cmsTrans)
00372 {
00373 inC[0] = cmyk.c * 257;
00374 inC[1] = cmyk.m * 257;
00375 inC[2] = cmyk.y * 257;
00376 inC[3] = cmyk.k * 257;
00377 if (cmsUse && !spot && doc->SoftProofing)
00378 {
00379 cmsHTRANSFORM xform = gamutCkeck ? transProofCMYKGC : transProofCMYK;
00380 cmsDoTransform(xform, inC, outC, 1);
00381 r = outC[0] / 257;
00382 g = outC[1] / 257;
00383 b = outC[2] / 257;
00384 }
00385 else
00386 {
00387 cmsDoTransform(transCMYKMon, inC, outC, 1);
00388 r = outC[0] / 257;
00389 g = outC[1] / 257;
00390 b = outC[2] / 257;
00391 }
00392 }
00393 else
00394 {
00395 r = 255 - qMin(255, cmyk.c + cmyk.k);
00396 g = 255 - qMin(255, cmyk.m + cmyk.k);
00397 b = 255 - qMin(255, cmyk.y + cmyk.k);
00398 }
00399 return QColor(r, g, b);
00400 }
00401
00402 QColor ScColorEngine::getDisplayColor(RGBColor& rgb, const ScribusDoc* doc, bool spot)
00403 {
00404 WORD inC[4];
00405 WORD outC[4];
00406 int r = rgb.r;
00407 int g = rgb.g;
00408 int b = rgb.b;
00409 cmsHTRANSFORM transRGBMon = doc ? doc->stdTransRGBMon : ScCore->defaultRGBToScreenSolidTrans;
00410 if (ScCore->haveCMS() && transRGBMon)
00411 {
00412 inC[0] = r * 257;
00413 inC[1] = g * 257;
00414 inC[2] = b * 257;
00415 cmsDoTransform(transRGBMon, inC, outC, 1);
00416 r = outC[0] / 257;
00417 g = outC[1] / 257;
00418 b = outC[2] / 257;
00419 }
00420 return QColor(r, g, b);
00421 }
00422
00423 QColor ScColorEngine::getDisplayColor(CMYKColor& cmyk, const ScribusDoc* doc, bool spot)
00424 {
00425 int r = 0, g = 0, b = 0;
00426 WORD inC[4];
00427 WORD outC[4];
00428 cmsHTRANSFORM transCMYKMon = doc ? doc->stdTransCMYKMon : ScCore->defaultCMYKToRGBTrans;
00429 if (ScCore->haveCMS() && transCMYKMon)
00430 {
00431 inC[0] = cmyk.c * 257;
00432 inC[1] = cmyk.m * 257;
00433 inC[2] = cmyk.y * 257;
00434 inC[3] = cmyk.k * 257;
00435 cmsDoTransform(transCMYKMon, inC, outC, 1);
00436 r = outC[0] / 257;
00437 g = outC[1] / 257;
00438 b = outC[2] / 257;
00439 }
00440 else
00441 {
00442 r = 255 - qMin(255, cmyk.c + cmyk.k);
00443 g = 255 - qMin(255, cmyk.m + cmyk.k);
00444 b = 255 - qMin(255, cmyk.y + cmyk.k);
00445 }
00446 return QColor(r, g, b);
00447 }
00448
00449 bool ScColorEngine::isOutOfGamut(const ScColor& color, const ScribusDoc* doc)
00450 {
00451 bool outOfGamutFlag = false;
00452 if (color.isSpotColor())
00453 return false;
00454 WORD inC[4];
00455 WORD outC[4];
00456 bool cmsUse = doc ? doc->HasCMS : false;
00457 if (ScCore->haveCMS() && cmsUse)
00458 {
00459 bool alert = true;
00460 cmsHTRANSFORM xformProof;
00461 if (color.getColorModel() == colorModelRGB)
00462 {
00463 inC[0] = color.CR * 257;
00464 inC[1] = color.MG * 257;
00465 inC[2] = color.YB * 257;
00466 xformProof = doc->stdProofGC;
00467 if ((color.CR == 0) && (color.YB == 0) && (color.MG == 255))
00468 alert = false;
00469 if ((color.CR == color.MG && color.MG == color.YB))
00470 alert = false;
00471 }
00472 else
00473 {
00474 inC[0] = color.CR * 257;
00475 inC[1] = color.MG * 257;
00476 inC[2] = color.YB * 257;
00477 inC[3] = color.K * 257;
00478 xformProof = doc->stdProofCMYKGC;
00479 if ((color.MG == 0) && (color.K == 0) && (color.CR == 255) && (color.YB == 255))
00480 alert = false;
00481 if ((color.MG == 0) && (color.CR == 0) && (color.YB == 0))
00482 alert = false;
00483 if ((color.MG == color.CR) && (color.CR == color.YB) && (color.YB == color.K))
00484 alert = false;
00485 }
00486 if (alert)
00487 {
00488 cmsDoTransform(xformProof, inC, outC, 1);
00489 if ((outC[0]/257 == 0) && (outC[1]/257 == 255) && (outC[2]/257 == 0))
00490 outOfGamutFlag = true;
00491 }
00492 }
00493 return outOfGamutFlag;
00494 }
00495
00496 void ScColorEngine::applyGCR(ScColor& color, const ScribusDoc* doc)
00497 {
00498 bool cmsUse = doc ? doc->HasCMS : false;
00499 if (!(ScCore->haveCMS() && cmsUse))
00500 {
00501 CMYKColor cmyk;
00502 getCMYKValues(color, doc, cmyk);
00503 int k = qMin(qMin(cmyk.c, cmyk.m), cmyk.y);
00504 color.CR = cmyk.c - k;
00505 color.MG = cmyk.m - k;
00506 color.YB = cmyk.y - k;
00507 color.K = qMin((cmyk.k + k), 255);
00508 }
00509 }