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 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 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 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 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 139 color::~color() {} 140 141 CJS_Return color::get_transparent(CJS_Runtime* pRuntime) { 142 return GetPropertyHelper(pRuntime, &m_crTransparent); 143 } 144 145 CJS_Return color::set_transparent(CJS_Runtime* pRuntime, 146 v8::Local<v8::Value> vp) { 147 return SetPropertyHelper(pRuntime, vp, &m_crTransparent); 148 } 149 150 CJS_Return color::get_black(CJS_Runtime* pRuntime) { 151 return GetPropertyHelper(pRuntime, &m_crBlack); 152 } 153 154 CJS_Return color::set_black(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 155 return SetPropertyHelper(pRuntime, vp, &m_crBlack); 156 } 157 158 CJS_Return color::get_white(CJS_Runtime* pRuntime) { 159 return GetPropertyHelper(pRuntime, &m_crWhite); 160 } 161 162 CJS_Return color::set_white(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 163 return SetPropertyHelper(pRuntime, vp, &m_crWhite); 164 } 165 166 CJS_Return color::get_red(CJS_Runtime* pRuntime) { 167 return GetPropertyHelper(pRuntime, &m_crRed); 168 } 169 170 CJS_Return color::set_red(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 171 return SetPropertyHelper(pRuntime, vp, &m_crRed); 172 } 173 174 CJS_Return color::get_green(CJS_Runtime* pRuntime) { 175 return GetPropertyHelper(pRuntime, &m_crGreen); 176 } 177 178 CJS_Return color::set_green(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 179 return SetPropertyHelper(pRuntime, vp, &m_crGreen); 180 } 181 182 CJS_Return color::get_blue(CJS_Runtime* pRuntime) { 183 return GetPropertyHelper(pRuntime, &m_crBlue); 184 } 185 186 CJS_Return color::set_blue(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 187 return SetPropertyHelper(pRuntime, vp, &m_crBlue); 188 } 189 190 CJS_Return color::get_cyan(CJS_Runtime* pRuntime) { 191 return GetPropertyHelper(pRuntime, &m_crCyan); 192 } 193 194 CJS_Return color::set_cyan(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 195 return SetPropertyHelper(pRuntime, vp, &m_crCyan); 196 } 197 198 CJS_Return color::get_magenta(CJS_Runtime* pRuntime) { 199 return GetPropertyHelper(pRuntime, &m_crMagenta); 200 } 201 202 CJS_Return color::set_magenta(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 203 return SetPropertyHelper(pRuntime, vp, &m_crMagenta); 204 } 205 206 CJS_Return color::get_yellow(CJS_Runtime* pRuntime) { 207 return GetPropertyHelper(pRuntime, &m_crYellow); 208 } 209 210 CJS_Return color::set_yellow(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 211 return SetPropertyHelper(pRuntime, vp, &m_crYellow); 212 } 213 214 CJS_Return color::get_dark_gray(CJS_Runtime* pRuntime) { 215 return GetPropertyHelper(pRuntime, &m_crDKGray); 216 } 217 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 223 CJS_Return color::get_gray(CJS_Runtime* pRuntime) { 224 return GetPropertyHelper(pRuntime, &m_crGray); 225 } 226 227 CJS_Return color::set_gray(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 228 return SetPropertyHelper(pRuntime, vp, &m_crGray); 229 } 230 231 CJS_Return color::get_light_gray(CJS_Runtime* pRuntime) { 232 return GetPropertyHelper(pRuntime, &m_crLTGray); 233 } 234 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 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 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 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 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