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
InRange(FX_FLOAT comp)13 bool InRange(FX_FLOAT comp) {
14 return comp >= 0.0f && comp <= 1.0f;
15 }
16
ConvertCMYK2GRAY(FX_FLOAT dC,FX_FLOAT dM,FX_FLOAT dY,FX_FLOAT dK)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
ConvertGRAY2CMYK(FX_FLOAT dGray)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
ConvertGRAY2RGB(FX_FLOAT dGray)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
ConvertRGB2GRAY(FX_FLOAT dR,FX_FLOAT dG,FX_FLOAT dB)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
ConvertCMYK2RGB(FX_FLOAT dC,FX_FLOAT dM,FX_FLOAT dY,FX_FLOAT dK)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
ConvertRGB2CMYK(FX_FLOAT dR,FX_FLOAT dG,FX_FLOAT dB)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
ConvertColorType(int32_t nConvertColorType) const66 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
ToFXColor(int32_t nTransparency) const110 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
operator -(FX_FLOAT fColorSub) const138 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
operator /(FX_FLOAT fColorDivide) const159 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