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 |