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