| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 * | 7 * |
| 8 */ | 8 */ |
| 9 #include <v8.h> | 9 #include <v8.h> |
| 10 | 10 |
| 11 using namespace v8; | 11 using namespace v8; |
| 12 | 12 |
| 13 #include "SkV8Example.h" | 13 #include "SkV8Example.h" |
| 14 | 14 |
| 15 #include "gl/GrGLUtil.h" | 15 #include "gl/GrGLUtil.h" |
| 16 #include "gl/GrGLDefines.h" | 16 #include "gl/GrGLDefines.h" |
| 17 #include "gl/GrGLInterface.h" | 17 #include "gl/GrGLInterface.h" |
| 18 #include "SkApplication.h" | 18 #include "SkApplication.h" |
| 19 #include "SkDraw.h" | 19 #include "SkDraw.h" |
| 20 #include "SkGpuDevice.h" | 20 #include "SkGpuDevice.h" |
| 21 #include "SkGraphics.h" | 21 #include "SkGraphics.h" |
| 22 #include "SkScalar.h" |
| 22 | 23 |
| 23 | 24 |
| 24 void application_init() { | 25 void application_init() { |
| 25 SkGraphics::Init(); | 26 SkGraphics::Init(); |
| 26 SkEvent::Init(); | 27 SkEvent::Init(); |
| 27 } | 28 } |
| 28 | 29 |
| 29 void application_term() { | 30 void application_term() { |
| 30 SkEvent::Term(); | 31 SkEvent::Term(); |
| 31 SkGraphics::Term(); | 32 SkGraphics::Term(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 const char* stack_trace_string = ToCString(stack_trace); | 73 const char* stack_trace_string = ToCString(stack_trace); |
| 73 fprintf(stderr, "%s\n", stack_trace_string); | 74 fprintf(stderr, "%s\n", stack_trace_string); |
| 74 } | 75 } |
| 75 } | 76 } |
| 76 } | 77 } |
| 77 | 78 |
| 78 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) | 79 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) |
| 79 : INHERITED(hwnd) | 80 : INHERITED(hwnd) |
| 80 , fJsCanvas(canvas) | 81 , fJsCanvas(canvas) |
| 81 { | 82 { |
| 82 fRotationAngle = SkIntToScalar(0); | |
| 83 this->setConfig(SkBitmap::kARGB_8888_Config); | 83 this->setConfig(SkBitmap::kARGB_8888_Config); |
| 84 this->setVisibleP(true); | 84 this->setVisibleP(true); |
| 85 this->setClipToBounds(false); | 85 this->setClipToBounds(false); |
| 86 } | 86 } |
| 87 | 87 |
| 88 JsCanvas* JsCanvas::unwrap(Handle<Object> obj) { | 88 JsCanvas* JsCanvas::Unwrap(Handle<Object> obj) { |
| 89 Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0)); | 89 Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0)); |
| 90 void* ptr = field->Value(); | 90 void* ptr = field->Value(); |
| 91 return static_cast<JsCanvas*>(ptr); | 91 return static_cast<JsCanvas*>(ptr); |
| 92 } | 92 } |
| 93 | 93 |
| 94 void JsCanvas::inval(const v8::FunctionCallbackInfo<Value>& args) { | 94 void JsCanvas::Inval(const v8::FunctionCallbackInfo<Value>& args) { |
| 95 unwrap(args.This())->fWindow->inval(NULL); | 95 Unwrap(args.This())->fWindow->inval(NULL); |
| 96 } | 96 } |
| 97 | 97 |
| 98 void JsCanvas::drawRect(const v8::FunctionCallbackInfo<Value>& args) { | 98 void JsCanvas::FillRect(const v8::FunctionCallbackInfo<Value>& args) { |
| 99 SkCanvas* canvas = unwrap(args.This())->fCanvas; | 99 JsCanvas* jsCanvas = Unwrap(args.This()); |
| 100 SkCanvas* canvas = jsCanvas->fCanvas; |
| 100 | 101 |
| 101 canvas->drawColor(SK_ColorWHITE); | 102 if (args.Length() != 4) { |
| 103 args.GetIsolate()->ThrowException( |
| 104 v8::String::NewFromUtf8( |
| 105 args.GetIsolate(), "Error: 4 arguments required.")); |
| 106 return; |
| 107 } |
| 108 // TODO(jcgregorio) Really figure out the conversion from JS numbers to |
| 109 // SkScalars. Maybe test if int first? Not sure of the performance impact. |
| 110 double x = args[0]->NumberValue(); |
| 111 double y = args[1]->NumberValue(); |
| 112 double w = args[2]->NumberValue(); |
| 113 double h = args[3]->NumberValue(); |
| 102 | 114 |
| 103 // Draw a rectangle with red paint. | |
| 104 SkPaint paint; | |
| 105 paint.setColor(SK_ColorRED); | |
| 106 SkRect rect = { | 115 SkRect rect = { |
| 107 SkIntToScalar(10), SkIntToScalar(10), | 116 SkDoubleToScalar(x), |
| 108 SkIntToScalar(128), SkIntToScalar(128) | 117 SkDoubleToScalar(y), |
| 118 SkDoubleToScalar(x) + SkDoubleToScalar(w), |
| 119 SkDoubleToScalar(y) + SkDoubleToScalar(h) |
| 109 }; | 120 }; |
| 110 canvas->drawRect(rect, paint); | 121 canvas->drawRect(rect, jsCanvas->fFillStyle); |
| 111 } | 122 } |
| 112 | 123 |
| 124 void JsCanvas::GetFillStyle(Local<String> name, |
| 125 const PropertyCallbackInfo<Value>& info) { |
| 126 JsCanvas* jsCanvas = Unwrap(info.This()); |
| 127 SkColor color = jsCanvas->fFillStyle.getColor(); |
| 128 char buf[8]; |
| 129 sprintf(buf, "#%02X%02X%02X", SkColorGetR(color), SkColorGetG(color), |
| 130 SkColorGetB(color)); |
| 131 |
| 132 info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buf)); |
| 133 } |
| 134 |
| 135 void JsCanvas::SetFillStyle(Local<String> name, Local<Value> value, |
| 136 const PropertyCallbackInfo<void>& info) { |
| 137 JsCanvas* jsCanvas = Unwrap(info.This()); |
| 138 Local<String> s = value->ToString(); |
| 139 if (s->Length() != 7) { |
| 140 info.GetIsolate()->ThrowException( |
| 141 v8::String::NewFromUtf8( |
| 142 info.GetIsolate(), "Invalid fill style format.")); |
| 143 return; |
| 144 } |
| 145 char buf[8]; |
| 146 s->WriteUtf8(buf, sizeof(buf)); |
| 147 |
| 148 if (buf[0] != '#') { |
| 149 info.GetIsolate()->ThrowException( |
| 150 v8::String::NewFromUtf8( |
| 151 info.GetIsolate(), "Invalid fill style format.")); |
| 152 return; |
| 153 } |
| 154 |
| 155 long color = strtol(buf+1, NULL, 16); |
| 156 jsCanvas->fFillStyle.setColor(SkColorSetA(SkColor(color), SK_AlphaOPAQUE)); |
| 157 } |
| 158 |
| 159 |
| 113 Persistent<ObjectTemplate> JsCanvas::fCanvasTemplate; | 160 Persistent<ObjectTemplate> JsCanvas::fCanvasTemplate; |
| 114 | 161 |
| 115 Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { | 162 Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { |
| 116 EscapableHandleScope handleScope(fIsolate); | 163 EscapableHandleScope handleScope(fIsolate); |
| 117 | 164 |
| 118 Local<ObjectTemplate> result = ObjectTemplate::New(); | 165 Local<ObjectTemplate> result = ObjectTemplate::New(); |
| 119 | 166 |
| 120 // Add a field to store the pointer to a JsCanvas instance. | 167 // Add a field to store the pointer to a JsCanvas instance. |
| 121 result->SetInternalFieldCount(1); | 168 result->SetInternalFieldCount(1); |
| 122 | 169 |
| 123 // Add accessors for each of the fields of the canvas object. | 170 // Add accessors for each of the fields of the canvas object. |
| 171 result->SetAccessor( |
| 172 String::NewFromUtf8(fIsolate, "fillStyle", String::kInternalizedString), |
| 173 GetFillStyle, SetFillStyle); |
| 174 |
| 175 // Add methods. |
| 124 result->Set( | 176 result->Set( |
| 125 String::NewFromUtf8( | 177 String::NewFromUtf8( |
| 126 fIsolate, "drawRect", String::kInternalizedString), | 178 fIsolate, "fillRect", String::kInternalizedString), |
| 127 FunctionTemplate::New(drawRect)); | 179 FunctionTemplate::New(FillRect)); |
| 128 result->Set( | 180 result->Set( |
| 129 String::NewFromUtf8( | 181 String::NewFromUtf8( |
| 130 fIsolate, "inval", String::kInternalizedString), | 182 fIsolate, "inval", String::kInternalizedString), |
| 131 FunctionTemplate::New(inval)); | 183 FunctionTemplate::New(Inval)); |
| 132 | 184 |
| 133 // Return the result through the current handle scope. | 185 // Return the result through the current handle scope. |
| 134 return handleScope.Escape(result); | 186 return handleScope.Escape(result); |
| 135 } | 187 } |
| 136 | 188 |
| 137 | 189 |
| 138 // Wraps 'this' in a Javascript object. | 190 // Wraps 'this' in a Javascript object. |
| 139 Handle<Object> JsCanvas::wrap() { | 191 Handle<Object> JsCanvas::wrap() { |
| 140 // Handle scope for temporary handles. | 192 // Handle scope for temporary handles. |
| 141 EscapableHandleScope handleScope(fIsolate); | 193 EscapableHandleScope handleScope(fIsolate); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 String::Utf8Value str(result); | 259 String::Utf8Value str(result); |
| 208 const char* cstr = ToCString(str); | 260 const char* cstr = ToCString(str); |
| 209 printf("%s\n", cstr); | 261 printf("%s\n", cstr); |
| 210 } | 262 } |
| 211 } | 263 } |
| 212 } | 264 } |
| 213 | 265 |
| 214 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { | 266 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { |
| 215 | 267 |
| 216 canvas->save(); | 268 canvas->save(); |
| 217 | 269 canvas->drawColor(SK_ColorWHITE); |
| 218 fRotationAngle += SkDoubleToScalar(0.2); | |
| 219 if (fRotationAngle > SkDoubleToScalar(360.0)) { | |
| 220 fRotationAngle -= SkDoubleToScalar(360.0); | |
| 221 } | |
| 222 | |
| 223 canvas->rotate(fRotationAngle); | |
| 224 | 270 |
| 225 // Now jump into JS and call the onDraw(canvas) method defined there. | 271 // Now jump into JS and call the onDraw(canvas) method defined there. |
| 226 fJsCanvas->onDraw(canvas, this); | 272 fJsCanvas->onDraw(canvas, this); |
| 227 | 273 |
| 228 canvas->restore(); | 274 canvas->restore(); |
| 229 | 275 |
| 230 INHERITED::onDraw(canvas); | 276 INHERITED::onDraw(canvas); |
| 231 } | 277 } |
| 232 | 278 |
| 233 | 279 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 const char* cstr = ToCString(str); | 349 const char* cstr = ToCString(str); |
| 304 printf("%s\n", cstr); | 350 printf("%s\n", cstr); |
| 305 return false; | 351 return false; |
| 306 } | 352 } |
| 307 } | 353 } |
| 308 | 354 |
| 309 Handle<String> fn_name = String::NewFromUtf8(fIsolate, "onDraw"); | 355 Handle<String> fn_name = String::NewFromUtf8(fIsolate, "onDraw"); |
| 310 Handle<Value> fn_val = context->Global()->Get(fn_name); | 356 Handle<Value> fn_val = context->Global()->Get(fn_name); |
| 311 | 357 |
| 312 if (!fn_val->IsFunction()) { | 358 if (!fn_val->IsFunction()) { |
| 359 printf("Not a function.\n"); |
| 313 return false; | 360 return false; |
| 314 } | 361 } |
| 315 | 362 |
| 316 // It is a function; cast it to a Function. | 363 // It is a function; cast it to a Function. |
| 317 Handle<Function> fn_fun = Handle<Function>::Cast(fn_val); | 364 Handle<Function> fn_fun = Handle<Function>::Cast(fn_val); |
| 318 | 365 |
| 319 // Store the function in a Persistent handle, since we also want that to | 366 // Store the function in a Persistent handle, since we also want that to |
| 320 // remain after this call returns. | 367 // remain after this call returns. |
| 321 fOnDraw.Reset(fIsolate, fn_fun); | 368 fOnDraw.Reset(fIsolate, fn_fun); |
| 322 | 369 |
| 323 // Also make the context persistent. | 370 // Also make the context persistent. |
| 324 fContext.Reset(fIsolate, context); | 371 fContext.Reset(fIsolate, context); |
| 325 return true; | 372 return true; |
| 326 } | 373 } |
| 327 | 374 |
| 328 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { | 375 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { |
| 329 printf("Started\n"); | 376 printf("Started\n"); |
| 330 | 377 |
| 331 // Get the default Isolate created at startup. | 378 // Get the default Isolate created at startup. |
| 332 Isolate* isolate = Isolate::GetCurrent(); | 379 Isolate* isolate = Isolate::GetCurrent(); |
| 333 | 380 |
| 334 JsCanvas* jsCanvas = new JsCanvas(isolate); | 381 JsCanvas* jsCanvas = new JsCanvas(isolate); |
| 335 const char* script = "function onDraw(canvas){" | 382 const char* script = |
| 336 "canvas.drawRect();" | 383 "var onDraw = function(){ \n" |
| 337 "canvas.inval();" | 384 " var tick = 0; \n" |
| 338 "};"; | 385 " function f(canvas) { \n" |
| 386 " tick += 0.001; \n" |
| 387 " canvas.fillStyle = '#00FF00'; \n" |
| 388 " canvas.fillRect(20, 20, 100, Math.abs(Math.cos(tick)*100)); \n" |
| 389 " canvas.inval(); \n" |
| 390 " }; \n" |
| 391 " return f; \n" |
| 392 "}(); \n"; |
| 339 if (!jsCanvas->initialize(script)) { | 393 if (!jsCanvas->initialize(script)) { |
| 340 printf("Failed to initialize.\n"); | 394 printf("Failed to initialize.\n"); |
| 341 exit(1); | 395 exit(1); |
| 342 } | 396 } |
| 343 | 397 |
| 344 return new SkV8ExampleWindow(hwnd, jsCanvas); | 398 return new SkV8ExampleWindow(hwnd, jsCanvas); |
| 345 } | 399 } |
| OLD | NEW |