• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "fxjs/cjs_color.h"
8 
9 #include <vector>
10 
11 #include "fxjs/JS_Define.h"
12 #include "fxjs/cjs_event_context.h"
13 #include "fxjs/cjs_eventhandler.h"
14 #include "fxjs/cjs_object.h"
15 #include "fxjs/cjs_runtime.h"
16 
17 const JSPropertySpec CJS_Color::PropertySpecs[] = {
18     {"black", get_black_static, set_black_static},
19     {"blue", get_blue_static, set_blue_static},
20     {"cyan", get_cyan_static, set_cyan_static},
21     {"dkGray", get_dark_gray_static, set_dark_gray_static},
22     {"gray", get_gray_static, set_gray_static},
23     {"green", get_green_static, set_green_static},
24     {"ltGray", get_light_gray_static, set_light_gray_static},
25     {"magenta", get_magenta_static, set_magenta_static},
26     {"red", get_red_static, set_red_static},
27     {"transparent", get_transparent_static, set_transparent_static},
28     {"white", get_white_static, set_white_static},
29     {"yellow", get_yellow_static, set_yellow_static}};
30 
31 const JSMethodSpec CJS_Color::MethodSpecs[] = {{"convert", convert_static},
32                                                {"equal", equal_static}};
33 
34 int CJS_Color::ObjDefnID = -1;
35 
36 // static
DefineJSObjects(CFXJS_Engine * pEngine)37 void CJS_Color::DefineJSObjects(CFXJS_Engine* pEngine) {
38   ObjDefnID = pEngine->DefineObj("color", FXJSOBJTYPE_STATIC,
39                                  JSConstructor<CJS_Color, color>,
40                                  JSDestructor<CJS_Color>);
41   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
42   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
43 }
44 
45 // static
ConvertPWLColorToArray(CJS_Runtime * pRuntime,const CFX_Color & color)46 v8::Local<v8::Array> color::ConvertPWLColorToArray(CJS_Runtime* pRuntime,
47                                                    const CFX_Color& color) {
48   v8::Local<v8::Array> array;
49   switch (color.nColorType) {
50     case CFX_Color::kTransparent:
51       array = pRuntime->NewArray();
52       pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"T"));
53       break;
54     case CFX_Color::kGray:
55       array = pRuntime->NewArray();
56       pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"G"));
57       pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
58       break;
59     case CFX_Color::kRGB:
60       array = pRuntime->NewArray();
61       pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"RGB"));
62       pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
63       pRuntime->PutArrayElement(array, 2, pRuntime->NewNumber(color.fColor2));
64       pRuntime->PutArrayElement(array, 3, pRuntime->NewNumber(color.fColor3));
65       break;
66     case CFX_Color::kCMYK:
67       array = pRuntime->NewArray();
68       pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"CMYK"));
69       pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
70       pRuntime->PutArrayElement(array, 2, pRuntime->NewNumber(color.fColor2));
71       pRuntime->PutArrayElement(array, 3, pRuntime->NewNumber(color.fColor3));
72       pRuntime->PutArrayElement(array, 4, pRuntime->NewNumber(color.fColor4));
73       break;
74   }
75   return array;
76 }
77 
78 // static
ConvertArrayToPWLColor(CJS_Runtime * pRuntime,v8::Local<v8::Array> array)79 CFX_Color color::ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
80                                         v8::Local<v8::Array> array) {
81   int nArrayLen = pRuntime->GetArrayLength(array);
82   if (nArrayLen < 1)
83     return CFX_Color();
84 
85   WideString sSpace =
86       pRuntime->ToWideString(pRuntime->GetArrayElement(array, 0));
87   if (sSpace == L"T")
88     return CFX_Color(CFX_Color::kTransparent);
89 
90   float d1 = 0;
91   if (nArrayLen > 1) {
92     d1 = static_cast<float>(
93         pRuntime->ToDouble(pRuntime->GetArrayElement(array, 1)));
94   }
95 
96   if (sSpace == L"G")
97     return CFX_Color(CFX_Color::kGray, d1);
98 
99   float d2 = 0;
100   float d3 = 0;
101   if (nArrayLen > 2) {
102     d2 = static_cast<float>(
103         pRuntime->ToDouble(pRuntime->GetArrayElement(array, 2)));
104   }
105   if (nArrayLen > 3) {
106     d3 = static_cast<float>(
107         pRuntime->ToDouble(pRuntime->GetArrayElement(array, 3)));
108   }
109 
110   if (sSpace == L"RGB")
111     return CFX_Color(CFX_Color::kRGB, d1, d2, d3);
112 
113   float d4 = 0;
114   if (nArrayLen > 4) {
115     d4 = static_cast<float>(
116         pRuntime->ToDouble(pRuntime->GetArrayElement(array, 4)));
117   }
118   if (sSpace == L"CMYK")
119     return CFX_Color(CFX_Color::kCMYK, d1, d2, d3, d4);
120 
121   return CFX_Color();
122 }
123 
color(CJS_Object * pJSObject)124 color::color(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {
125   m_crTransparent = CFX_Color(CFX_Color::kTransparent);
126   m_crBlack = CFX_Color(CFX_Color::kGray, 0);
127   m_crWhite = CFX_Color(CFX_Color::kGray, 1);
128   m_crRed = CFX_Color(CFX_Color::kRGB, 1, 0, 0);
129   m_crGreen = CFX_Color(CFX_Color::kRGB, 0, 1, 0);
130   m_crBlue = CFX_Color(CFX_Color::kRGB, 0, 0, 1);
131   m_crCyan = CFX_Color(CFX_Color::kCMYK, 1, 0, 0, 0);
132   m_crMagenta = CFX_Color(CFX_Color::kCMYK, 0, 1, 0, 0);
133   m_crYellow = CFX_Color(CFX_Color::kCMYK, 0, 0, 1, 0);
134   m_crDKGray = CFX_Color(CFX_Color::kGray, 0.25);
135   m_crGray = CFX_Color(CFX_Color::kGray, 0.5);
136   m_crLTGray = CFX_Color(CFX_Color::kGray, 0.75);
137 }
138 
~color()139 color::~color() {}
140 
get_transparent(CJS_Runtime * pRuntime)141 CJS_Return color::get_transparent(CJS_Runtime* pRuntime) {
142   return GetPropertyHelper(pRuntime, &m_crTransparent);
143 }
144 
set_transparent(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)145 CJS_Return color::set_transparent(CJS_Runtime* pRuntime,
146                                   v8::Local<v8::Value> vp) {
147   return SetPropertyHelper(pRuntime, vp, &m_crTransparent);
148 }
149 
get_black(CJS_Runtime * pRuntime)150 CJS_Return color::get_black(CJS_Runtime* pRuntime) {
151   return GetPropertyHelper(pRuntime, &m_crBlack);
152 }
153 
set_black(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)154 CJS_Return color::set_black(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
155   return SetPropertyHelper(pRuntime, vp, &m_crBlack);
156 }
157 
get_white(CJS_Runtime * pRuntime)158 CJS_Return color::get_white(CJS_Runtime* pRuntime) {
159   return GetPropertyHelper(pRuntime, &m_crWhite);
160 }
161 
set_white(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)162 CJS_Return color::set_white(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
163   return SetPropertyHelper(pRuntime, vp, &m_crWhite);
164 }
165 
get_red(CJS_Runtime * pRuntime)166 CJS_Return color::get_red(CJS_Runtime* pRuntime) {
167   return GetPropertyHelper(pRuntime, &m_crRed);
168 }
169 
set_red(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)170 CJS_Return color::set_red(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
171   return SetPropertyHelper(pRuntime, vp, &m_crRed);
172 }
173 
get_green(CJS_Runtime * pRuntime)174 CJS_Return color::get_green(CJS_Runtime* pRuntime) {
175   return GetPropertyHelper(pRuntime, &m_crGreen);
176 }
177 
set_green(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)178 CJS_Return color::set_green(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
179   return SetPropertyHelper(pRuntime, vp, &m_crGreen);
180 }
181 
get_blue(CJS_Runtime * pRuntime)182 CJS_Return color::get_blue(CJS_Runtime* pRuntime) {
183   return GetPropertyHelper(pRuntime, &m_crBlue);
184 }
185 
set_blue(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)186 CJS_Return color::set_blue(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
187   return SetPropertyHelper(pRuntime, vp, &m_crBlue);
188 }
189 
get_cyan(CJS_Runtime * pRuntime)190 CJS_Return color::get_cyan(CJS_Runtime* pRuntime) {
191   return GetPropertyHelper(pRuntime, &m_crCyan);
192 }
193 
set_cyan(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)194 CJS_Return color::set_cyan(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
195   return SetPropertyHelper(pRuntime, vp, &m_crCyan);
196 }
197 
get_magenta(CJS_Runtime * pRuntime)198 CJS_Return color::get_magenta(CJS_Runtime* pRuntime) {
199   return GetPropertyHelper(pRuntime, &m_crMagenta);
200 }
201 
set_magenta(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)202 CJS_Return color::set_magenta(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
203   return SetPropertyHelper(pRuntime, vp, &m_crMagenta);
204 }
205 
get_yellow(CJS_Runtime * pRuntime)206 CJS_Return color::get_yellow(CJS_Runtime* pRuntime) {
207   return GetPropertyHelper(pRuntime, &m_crYellow);
208 }
209 
set_yellow(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)210 CJS_Return color::set_yellow(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
211   return SetPropertyHelper(pRuntime, vp, &m_crYellow);
212 }
213 
get_dark_gray(CJS_Runtime * pRuntime)214 CJS_Return color::get_dark_gray(CJS_Runtime* pRuntime) {
215   return GetPropertyHelper(pRuntime, &m_crDKGray);
216 }
217 
set_dark_gray(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)218 CJS_Return color::set_dark_gray(CJS_Runtime* pRuntime,
219                                 v8::Local<v8::Value> vp) {
220   return SetPropertyHelper(pRuntime, vp, &m_crDKGray);
221 }
222 
get_gray(CJS_Runtime * pRuntime)223 CJS_Return color::get_gray(CJS_Runtime* pRuntime) {
224   return GetPropertyHelper(pRuntime, &m_crGray);
225 }
226 
set_gray(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)227 CJS_Return color::set_gray(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
228   return SetPropertyHelper(pRuntime, vp, &m_crGray);
229 }
230 
get_light_gray(CJS_Runtime * pRuntime)231 CJS_Return color::get_light_gray(CJS_Runtime* pRuntime) {
232   return GetPropertyHelper(pRuntime, &m_crLTGray);
233 }
234 
set_light_gray(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)235 CJS_Return color::set_light_gray(CJS_Runtime* pRuntime,
236                                  v8::Local<v8::Value> vp) {
237   return SetPropertyHelper(pRuntime, vp, &m_crLTGray);
238 }
239 
GetPropertyHelper(CJS_Runtime * pRuntime,CFX_Color * var)240 CJS_Return color::GetPropertyHelper(CJS_Runtime* pRuntime, CFX_Color* var) {
241   v8::Local<v8::Value> array = ConvertPWLColorToArray(pRuntime, *var);
242   if (array.IsEmpty())
243     return CJS_Return(pRuntime->NewArray());
244   return CJS_Return(array);
245 }
246 
SetPropertyHelper(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp,CFX_Color * var)247 CJS_Return color::SetPropertyHelper(CJS_Runtime* pRuntime,
248                                     v8::Local<v8::Value> vp,
249                                     CFX_Color* var) {
250   if (vp.IsEmpty() || !vp->IsArray())
251     return CJS_Return(false);
252 
253   *var = ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(vp));
254   return CJS_Return(true);
255 }
256 
convert(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)257 CJS_Return color::convert(CJS_Runtime* pRuntime,
258                           const std::vector<v8::Local<v8::Value>>& params) {
259   int iSize = params.size();
260   if (iSize < 2)
261     return CJS_Return(false);
262   if (params[0].IsEmpty() || !params[0]->IsArray())
263     return CJS_Return(false);
264 
265   WideString sDestSpace = pRuntime->ToWideString(params[1]);
266   int nColorType = CFX_Color::kTransparent;
267   if (sDestSpace == L"T")
268     nColorType = CFX_Color::kTransparent;
269   else if (sDestSpace == L"G")
270     nColorType = CFX_Color::kGray;
271   else if (sDestSpace == L"RGB")
272     nColorType = CFX_Color::kRGB;
273   else if (sDestSpace == L"CMYK")
274     nColorType = CFX_Color::kCMYK;
275 
276   CFX_Color color =
277       ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
278 
279   v8::Local<v8::Value> array =
280       ConvertPWLColorToArray(pRuntime, color.ConvertColorType(nColorType));
281   if (array.IsEmpty())
282     return CJS_Return(pRuntime->NewArray());
283   return CJS_Return(array);
284 }
285 
equal(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)286 CJS_Return color::equal(CJS_Runtime* pRuntime,
287                         const std::vector<v8::Local<v8::Value>>& params) {
288   if (params.size() < 2)
289     return CJS_Return(false);
290   if (params[0].IsEmpty() || !params[0]->IsArray() || params[1].IsEmpty() ||
291       !params[1]->IsArray()) {
292     return CJS_Return(false);
293   }
294 
295   CFX_Color color1 =
296       ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
297   CFX_Color color2 =
298       ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[1]));
299 
300   color1 = color1.ConvertColorType(color2.nColorType);
301   return CJS_Return(pRuntime->NewBoolean(color1 == color2));
302 }
303