Home | History | Annotate | Download | only in pdfwindow
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "fpdfsdk/pdfwindow/cpwl_color.h"
      8 
      9 #include <algorithm>
     10 
     11 namespace {
     12 
     13 bool InRange(FX_FLOAT comp) {
     14   return comp >= 0.0f && comp <= 1.0f;
     15 }
     16 
     17 CPWL_Color ConvertCMYK2GRAY(FX_FLOAT dC,
     18                             FX_FLOAT dM,
     19                             FX_FLOAT dY,
     20                             FX_FLOAT dK) {
     21   if (!InRange(dC) || !InRange(dM) || !InRange(dY) || !InRange(dK))
     22     return CPWL_Color(COLORTYPE_GRAY);
     23   return CPWL_Color(
     24       COLORTYPE_GRAY,
     25       1.0f - std::min(1.0f, 0.3f * dC + 0.59f * dM + 0.11f * dY + dK));
     26 }
     27 
     28 CPWL_Color ConvertGRAY2CMYK(FX_FLOAT dGray) {
     29   if (!InRange(dGray))
     30     return CPWL_Color(COLORTYPE_CMYK);
     31   return CPWL_Color(COLORTYPE_CMYK, 0.0f, 0.0f, 0.0f, 1.0f - dGray);
     32 }
     33 
     34 CPWL_Color ConvertGRAY2RGB(FX_FLOAT dGray) {
     35   if (!InRange(dGray))
     36     return CPWL_Color(COLORTYPE_RGB);
     37   return CPWL_Color(COLORTYPE_RGB, dGray, dGray, dGray);
     38 }
     39 
     40 CPWL_Color ConvertRGB2GRAY(FX_FLOAT dR, FX_FLOAT dG, FX_FLOAT dB) {
     41   if (!InRange(dR) || !InRange(dG) || !InRange(dB))
     42     return CPWL_Color(COLORTYPE_GRAY);
     43   return CPWL_Color(COLORTYPE_GRAY, 0.3f * dR + 0.59f * dG + 0.11f * dB);
     44 }
     45 
     46 CPWL_Color ConvertCMYK2RGB(FX_FLOAT dC, FX_FLOAT dM, FX_FLOAT dY, FX_FLOAT dK) {
     47   if (!InRange(dC) || !InRange(dM) || !InRange(dY) || !InRange(dK))
     48     return CPWL_Color(COLORTYPE_RGB);
     49   return CPWL_Color(COLORTYPE_RGB, 1.0f - std::min(1.0f, dC + dK),
     50                     1.0f - std::min(1.0f, dM + dK),
     51                     1.0f - std::min(1.0f, dY + dK));
     52 }
     53 
     54 CPWL_Color ConvertRGB2CMYK(FX_FLOAT dR, FX_FLOAT dG, FX_FLOAT dB) {
     55   if (!InRange(dR) || !InRange(dG) || !InRange(dB))
     56     return CPWL_Color(COLORTYPE_CMYK);
     57 
     58   FX_FLOAT c = 1.0f - dR;
     59   FX_FLOAT m = 1.0f - dG;
     60   FX_FLOAT y = 1.0f - dB;
     61   return CPWL_Color(COLORTYPE_CMYK, c, m, y, std::min(c, std::min(m, y)));
     62 }
     63 
     64 }  // namespace
     65 
     66 CPWL_Color CPWL_Color::ConvertColorType(int32_t nConvertColorType) const {
     67   if (nColorType == nConvertColorType)
     68     return *this;
     69 
     70   CPWL_Color ret;
     71   switch (nColorType) {
     72     case COLORTYPE_TRANSPARENT:
     73       ret = *this;
     74       ret.nColorType = COLORTYPE_TRANSPARENT;
     75       break;
     76     case COLORTYPE_GRAY:
     77       switch (nConvertColorType) {
     78         case COLORTYPE_RGB:
     79           ret = ConvertGRAY2RGB(fColor1);
     80           break;
     81         case COLORTYPE_CMYK:
     82           ret = ConvertGRAY2CMYK(fColor1);
     83           break;
     84       }
     85       break;
     86     case COLORTYPE_RGB:
     87       switch (nConvertColorType) {
     88         case COLORTYPE_GRAY:
     89           ret = ConvertRGB2GRAY(fColor1, fColor2, fColor3);
     90           break;
     91         case COLORTYPE_CMYK:
     92           ret = ConvertRGB2CMYK(fColor1, fColor2, fColor3);
     93           break;
     94       }
     95       break;
     96     case COLORTYPE_CMYK:
     97       switch (nConvertColorType) {
     98         case COLORTYPE_GRAY:
     99           ret = ConvertCMYK2GRAY(fColor1, fColor2, fColor3, fColor4);
    100           break;
    101         case COLORTYPE_RGB:
    102           ret = ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4);
    103           break;
    104       }
    105       break;
    106   }
    107   return ret;
    108 }
    109 
    110 FX_COLORREF CPWL_Color::ToFXColor(int32_t nTransparency) const {
    111   CPWL_Color ret;
    112   switch (nColorType) {
    113     case COLORTYPE_TRANSPARENT: {
    114       ret = CPWL_Color(COLORTYPE_TRANSPARENT, 0, 0, 0, 0);
    115       break;
    116     }
    117     case COLORTYPE_GRAY: {
    118       ret = ConvertGRAY2RGB(fColor1);
    119       ret.fColor4 = nTransparency;
    120       break;
    121     }
    122     case COLORTYPE_RGB: {
    123       ret = CPWL_Color(COLORTYPE_RGB, fColor1, fColor2, fColor3);
    124       ret.fColor4 = nTransparency;
    125       break;
    126     }
    127     case COLORTYPE_CMYK: {
    128       ret = ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4);
    129       ret.fColor4 = nTransparency;
    130       break;
    131     }
    132   }
    133   return ArgbEncode(ret.fColor4, static_cast<int32_t>(ret.fColor1 * 255),
    134                     static_cast<int32_t>(ret.fColor2 * 255),
    135                     static_cast<int32_t>(ret.fColor3 * 255));
    136 }
    137 
    138 CPWL_Color CPWL_Color::operator-(FX_FLOAT fColorSub) const {
    139   CPWL_Color sRet(nColorType);
    140   switch (nColorType) {
    141     case COLORTYPE_TRANSPARENT:
    142       sRet.nColorType = COLORTYPE_RGB;
    143       sRet.fColor1 = std::max(1.0f - fColorSub, 0.0f);
    144       sRet.fColor2 = std::max(1.0f - fColorSub, 0.0f);
    145       sRet.fColor3 = std::max(1.0f - fColorSub, 0.0f);
    146       break;
    147     case COLORTYPE_RGB:
    148     case COLORTYPE_GRAY:
    149     case COLORTYPE_CMYK:
    150       sRet.fColor1 = std::max(fColor1 - fColorSub, 0.0f);
    151       sRet.fColor2 = std::max(fColor2 - fColorSub, 0.0f);
    152       sRet.fColor3 = std::max(fColor3 - fColorSub, 0.0f);
    153       sRet.fColor4 = std::max(fColor4 - fColorSub, 0.0f);
    154       break;
    155   }
    156   return sRet;
    157 }
    158 
    159 CPWL_Color CPWL_Color::operator/(FX_FLOAT fColorDivide) const {
    160   CPWL_Color sRet(nColorType);
    161   switch (nColorType) {
    162     case COLORTYPE_TRANSPARENT:
    163       sRet.nColorType = COLORTYPE_RGB;
    164       sRet.fColor1 = 1.0f / fColorDivide;
    165       sRet.fColor2 = 1.0f / fColorDivide;
    166       sRet.fColor3 = 1.0f / fColorDivide;
    167       break;
    168     case COLORTYPE_RGB:
    169     case COLORTYPE_GRAY:
    170     case COLORTYPE_CMYK:
    171       sRet = *this;
    172       sRet.fColor1 /= fColorDivide;
    173       sRet.fColor2 /= fColorDivide;
    174       sRet.fColor3 /= fColorDivide;
    175       sRet.fColor4 /= fColorDivide;
    176       break;
    177   }
    178   return sRet;
    179 }
    180