Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

sccolorengine.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008                           sccolor.cpp  -  description
00009                              -------------------
00010     begin                : Sun Sep 9 2001
00011     copyright            : (C) 2001 by Franz Schmid
00012     email                : Franz.Schmid@altmuehlnet.de
00013  ***************************************************************************/
00014 
00015 /***************************************************************************
00016  *                                                                         *
00017  *   This program is free software; you can redistribute it and/or modify  *
00018  *   it under the terms of the GNU General Public License as published by  *
00019  *   the Free Software Foundation; either version 2 of the License, or     *
00020  *   (at your option) any later version.                                   *
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             // allow RGB greys to go got to CMYK greys without transform
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         //We could also compute rgb shade using rgb directly
00186         /*rgb.CR = 255 - ((255 - color.CR) * level / 100);
00187         rgb.MG = 255 - ((255 - color.MG) * level / 100);
00188         rgb.YB = 255 - ((255 - color.YB) * level / 100);*/
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         // Match 133x behavior (RGB greys map to cmyk greys) until we are able to make rgb profiled output
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         // Match 133x behavior for rgb grey until we are able to make rgb profiled output
00308         // (RGB greys map to cmyk greys)
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 }
Created with personalized Doxygen. This is documentation for GPL software Scribus - Open Source Desktop Publishing.