Back to index

scribus-ng  1.3.4.dfsg+svn20071115
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        bool cmsUse = doc ? doc->HasCMS : false;
00059        colorModel model = color.getColorModel();
00060        if (ScCore->haveCMS() && cmsUse)
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(doc->stdTransRGB, 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        bool cmsUse = doc ? doc->HasCMS : false;
00101        colorModel model = color.getColorModel();
00102        if (ScCore->haveCMS() && cmsUse)
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(doc->stdTransCMYK, 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, int 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 = color.CR * level / 100;
00161               cmyk.m = color.MG * level / 100;
00162               cmyk.y = color.YB * level / 100;
00163               cmyk.k = color.K * level / 100;
00164        }
00165 }
00166 
00167 void ScColorEngine::getShadeColorRGB(const ScColor& color, const ScribusDoc* doc, RGBColor& rgb, int 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.hsv(&h, &s, &v);
00181               snew = s * level / 100;
00182               vnew = 255 - ((255 - v) * level / 100);
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, int 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, int 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, int 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 //     bool alert = true;
00333        bool cmsUse = doc ? doc->HasCMS : false;
00334        if (ScCore->haveCMS() && cmsUse)
00335        {
00336               inC[0] = rgb.r * 257;
00337               inC[1] = rgb.g * 257;
00338               inC[2] = rgb.b * 257;
00339               if (!spot && doc->SoftProofing)
00340               {
00341                      cmsHTRANSFORM xform = gamutCkeck ? doc->stdProofGC : doc->stdProof;
00342                      cmsDoTransform(xform, inC, outC, 1);
00343                      r = outC[0] / 257;
00344                      g = outC[1] / 257;
00345                      b = outC[2] / 257;
00346               }
00347               else
00348               {
00349                      cmsDoTransform(doc->stdTransRGBMon, inC, outC, 1);
00350                      r = outC[0] / 257;
00351                      g = outC[1] / 257;
00352                      b = outC[2] / 257;
00353               }
00354        }
00355        return QColor(r, g, b);
00356 }
00357 
00358 QColor ScColorEngine::getColorProof(CMYKColor& cmyk, const ScribusDoc* doc, bool spot, bool gamutCkeck)
00359 {
00360        int  r = 0, g = 0, b = 0;
00361        WORD inC[4];
00362        WORD outC[4];
00363 //     bool alert = true;
00364        bool cmsUse = doc ? doc->HasCMS : false;
00365        if (ScCore->haveCMS() && cmsUse)
00366        {
00367               inC[0] = cmyk.c * 257;
00368               inC[1] = cmyk.m * 257;
00369               inC[2] = cmyk.y * 257;
00370               inC[3] = cmyk.k * 257;
00371               if (!spot && doc->SoftProofing)
00372               {
00373                      cmsHTRANSFORM xform = gamutCkeck ? doc->stdProofCMYKGC : doc->stdProofCMYK;
00374                      cmsDoTransform(xform, inC, outC, 1);
00375                      r = outC[0] / 257;
00376                      g = outC[1] / 257;
00377                      b = outC[2] / 257;
00378               }
00379               else
00380               {
00381                      cmsDoTransform(doc->stdTransCMYKMon, inC, outC, 1);
00382                      r = outC[0] / 257;
00383                      g = outC[1] / 257;
00384                      b = outC[2] / 257;
00385               }
00386        }
00387        else
00388        {
00389               r = 255 - QMIN(255, cmyk.c + cmyk.k);
00390               g = 255 - QMIN(255, cmyk.m + cmyk.k);
00391               b = 255 - QMIN(255, cmyk.y + cmyk.k);
00392        }
00393        return QColor(r, g, b);
00394 }
00395 
00396 QColor ScColorEngine::getDisplayColor(RGBColor& rgb, const ScribusDoc* doc, bool spot)
00397 {
00398        WORD inC[4];
00399        WORD outC[4];
00400        int r = rgb.r;
00401        int g = rgb.g;
00402        int b = rgb.b; 
00403 //     bool alert = true;
00404        bool cmsUse = doc ? doc->HasCMS : false;
00405        if (ScCore->haveCMS() && cmsUse)
00406        {
00407               inC[0] = r * 257;
00408               inC[1] = g * 257;
00409               inC[2] = b * 257;
00410               cmsDoTransform(doc->stdTransRGBMon, inC, outC, 1);
00411               r = outC[0] / 257;
00412               g = outC[1] / 257;
00413               b = outC[2] / 257;
00414        }
00415        return QColor(r, g, b);
00416 }
00417 
00418 QColor ScColorEngine::getDisplayColor(CMYKColor& cmyk, const ScribusDoc* doc, bool spot)
00419 {
00420        int  r = 0, g = 0, b = 0;
00421        WORD inC[4];
00422        WORD outC[4];
00423 //     bool alert = true;
00424        bool cmsUse = doc ? doc->HasCMS : false;
00425        if (ScCore->haveCMS() && cmsUse)
00426        {
00427               inC[0] = cmyk.c * 257;
00428               inC[1] = cmyk.m * 257;
00429               inC[2] = cmyk.y * 257;
00430               inC[3] = cmyk.k * 257;
00431               cmsDoTransform(doc->stdTransCMYKMon, inC, outC, 1);
00432               r = outC[0] / 257;
00433               g = outC[1] / 257;
00434               b = outC[2] / 257;
00435        }
00436        else
00437        {
00438               r = 255 - QMIN(255, cmyk.c + cmyk.k);
00439               g = 255 - QMIN(255, cmyk.m + cmyk.k);
00440               b = 255 - QMIN(255, cmyk.y + cmyk.k);
00441        }
00442        return QColor(r, g, b);
00443 }
00444 
00445 bool ScColorEngine::isOutOfGamut(const ScColor& color, const ScribusDoc* doc)
00446 {
00447        bool outOfGamutFlag = false;
00448        if (color.isSpotColor())
00449               return false;
00450        WORD inC[4];
00451        WORD outC[4];
00452        bool cmsUse = doc ? doc->HasCMS : false;
00453        if (ScCore->haveCMS() && cmsUse)
00454        {
00455               bool alert = true;
00456               cmsHTRANSFORM xformProof;
00457               if (color.getColorModel() == colorModelRGB)
00458               {
00459                      inC[0] = color.CR * 257;
00460                      inC[1] = color.MG * 257;
00461                      inC[2] = color.YB * 257;
00462                      xformProof = doc->stdProofGC;
00463                      if ((color.CR == 0) && (color.YB == 0) && (color.MG == 255))
00464                             alert = false;
00465                      if ((color.CR == color.MG && color.MG == color.YB))
00466                             alert = false;
00467               }
00468               else
00469               {
00470                      inC[0] = color.CR * 257;
00471                      inC[1] = color.MG * 257;
00472                      inC[2] = color.YB * 257;
00473                      inC[3] = color.K * 257;
00474                      xformProof = doc->stdProofCMYKGC;
00475                      if ((color.MG == 0) && (color.K == 0) && (color.CR == 255) && (color.YB == 255))
00476                             alert = false;
00477                      if ((color.MG == 0) && (color.CR == 0) && (color.YB == 0))
00478                             alert = false;
00479                      if ((color.MG == color.CR) && (color.CR == color.YB) && (color.YB == color.K))
00480                             alert = false;
00481               }
00482               if (alert)
00483               {
00484                      cmsDoTransform(xformProof, inC, outC, 1);
00485                      if ((outC[0]/257 == 0) && (outC[1]/257 == 255) && (outC[2]/257 == 0))
00486                             outOfGamutFlag = true;
00487               }
00488        }
00489        return outOfGamutFlag;
00490 }
00491 
00492 void ScColorEngine::applyGCR(ScColor& color, const ScribusDoc* doc)
00493 {
00494        bool cmsUse = doc ? doc->HasCMS : false;
00495        if (!(ScCore->haveCMS() && cmsUse))
00496        {
00497               CMYKColor cmyk;
00498               getCMYKValues(color, doc, cmyk);
00499               int k = QMIN(QMIN(cmyk.c, cmyk.m), cmyk.y);
00500               color.CR = cmyk.c - k;
00501               color.MG = cmyk.m - k;
00502               color.YB = cmyk.y - k;
00503               color.K = QMIN((cmyk.k + k), 255);
00504        }
00505 }