Index: experimental/SkV8Example/JsContext.cpp |
diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/JsContext.cpp |
similarity index 50% |
copy from experimental/SkV8Example/SkV8Example.cpp |
copy to experimental/SkV8Example/JsContext.cpp |
index fb4f42d705f809e4da15b338f7566a1d4c8e2504..87f7d0efe3bc0a8a330a66ead9d66f4787555ad9 100644 |
--- a/experimental/SkV8Example/SkV8Example.cpp |
+++ b/experimental/SkV8Example/JsContext.cpp |
@@ -1,3 +1,4 @@ |
+ |
/* |
* Copyright 2013 Google Inc. |
* |
@@ -10,32 +11,11 @@ |
using namespace v8; |
-#include "SkV8Example.h" |
#include "Global.h" |
+#include "JsContext.h" |
+#include "Path.h" |
+#include "SkCanvas.h" |
-#include "gl/GrGLUtil.h" |
-#include "gl/GrGLDefines.h" |
-#include "gl/GrGLInterface.h" |
-#include "SkApplication.h" |
-#include "SkCommandLineFlags.h" |
-#include "SkData.h" |
-#include "SkDraw.h" |
-#include "SkGpuDevice.h" |
-#include "SkGraphics.h" |
-#include "SkScalar.h" |
- |
- |
-DEFINE_string2(infile, i, NULL, "Name of file to load JS from.\n"); |
- |
-void application_init() { |
- SkGraphics::Init(); |
- SkEvent::Init(); |
-} |
- |
-void application_term() { |
- SkEvent::Term(); |
- SkGraphics::Term(); |
-} |
// Extracts a C string from a V8 Utf8Value. |
// TODO(jcgregrio) Currently dup'd in two files, fix. |
@@ -43,16 +23,15 @@ static const char* to_cstring(const v8::String::Utf8Value& value) { |
return *value ? *value : "<string conversion failed>"; |
} |
- |
-JsCanvas* JsCanvas::Unwrap(Handle<Object> obj) { |
+JsContext* JsContext::Unwrap(Handle<Object> obj) { |
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0)); |
void* ptr = field->Value(); |
- return static_cast<JsCanvas*>(ptr); |
+ return static_cast<JsContext*>(ptr); |
} |
-void JsCanvas::FillRect(const v8::FunctionCallbackInfo<Value>& args) { |
- JsCanvas* jsCanvas = Unwrap(args.This()); |
- SkCanvas* canvas = jsCanvas->fCanvas; |
+void JsContext::FillRect(const v8::FunctionCallbackInfo<Value>& args) { |
+ JsContext* jsContext = Unwrap(args.This()); |
+ SkCanvas* canvas = jsContext->fCanvas; |
if (args.Length() != 4) { |
args.GetIsolate()->ThrowException( |
@@ -73,13 +52,78 @@ void JsCanvas::FillRect(const v8::FunctionCallbackInfo<Value>& args) { |
SkDoubleToScalar(x) + SkDoubleToScalar(w), |
SkDoubleToScalar(y) + SkDoubleToScalar(h) |
}; |
- canvas->drawRect(rect, jsCanvas->fFillStyle); |
+ jsContext->fFillStyle.setStyle(SkPaint::kFill_Style); |
+ canvas->drawRect(rect, jsContext->fFillStyle); |
+} |
+ |
+void JsContext::Translate(const v8::FunctionCallbackInfo<Value>& args) { |
+ JsContext* jsContext = Unwrap(args.This()); |
+ SkCanvas* canvas = jsContext->fCanvas; |
+ |
+ if (args.Length() != 2) { |
+ args.GetIsolate()->ThrowException( |
+ v8::String::NewFromUtf8( |
+ args.GetIsolate(), "Error: 2 arguments required.")); |
+ return; |
+ } |
+ double dx = args[0]->NumberValue(); |
+ double dy = args[1]->NumberValue(); |
+ canvas->translate(SkDoubleToScalar(dx), SkDoubleToScalar(dy)); |
+} |
+ |
+void JsContext::ResetTransform(const v8::FunctionCallbackInfo<Value>& args) { |
+ JsContext* jsContext = Unwrap(args.This()); |
+ SkCanvas* canvas = jsContext->fCanvas; |
+ |
+ canvas->resetMatrix(); |
+} |
+ |
+void JsContext::Stroke(const v8::FunctionCallbackInfo<Value>& args) { |
+ JsContext* jsContext = Unwrap(args.This()); |
+ SkCanvas* canvas = jsContext->fCanvas; |
+ |
+ if (args.Length() != 1) { |
+ args.GetIsolate()->ThrowException( |
+ v8::String::NewFromUtf8( |
+ args.GetIsolate(), "Error: 1 arguments required.")); |
+ return; |
+ } |
+ |
+ Handle<External> field = Handle<External>::Cast( |
+ args[0]->ToObject()->GetInternalField(0)); |
+ void* ptr = field->Value(); |
+ Path* path = static_cast<Path*>(ptr); |
+ |
+ jsContext->fFillStyle.setStyle(SkPaint::kStroke_Style); |
+ canvas->drawPath(path->getSkPath(), jsContext->fFillStyle); |
} |
-void JsCanvas::GetFillStyle(Local<String> name, |
+ |
+void JsContext::Fill(const v8::FunctionCallbackInfo<Value>& args) { |
+ JsContext* jsContext = Unwrap(args.This()); |
+ SkCanvas* canvas = jsContext->fCanvas; |
+ |
+ if (args.Length() != 1) { |
+ args.GetIsolate()->ThrowException( |
+ v8::String::NewFromUtf8( |
+ args.GetIsolate(), "Error: 1 arguments required.")); |
+ return; |
+ } |
+ |
+ Handle<External> field = Handle<External>::Cast( |
+ args[0]->ToObject()->GetInternalField(0)); |
+ void* ptr = field->Value(); |
+ Path* path = static_cast<Path*>(ptr); |
+ |
+ jsContext->fFillStyle.setStyle(SkPaint::kFill_Style); |
+ canvas->drawPath(path->getSkPath(), jsContext->fFillStyle); |
+} |
+ |
+ |
+void JsContext::GetFillStyle(Local<String> name, |
const PropertyCallbackInfo<Value>& info) { |
- JsCanvas* jsCanvas = Unwrap(info.This()); |
- SkColor color = jsCanvas->fFillStyle.getColor(); |
+ JsContext* jsContext = Unwrap(info.This()); |
+ SkColor color = jsContext->fFillStyle.getColor(); |
char buf[8]; |
sprintf(buf, "#%02X%02X%02X", SkColorGetR(color), SkColorGetG(color), |
SkColorGetB(color)); |
@@ -87,9 +131,9 @@ void JsCanvas::GetFillStyle(Local<String> name, |
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buf)); |
} |
-void JsCanvas::SetFillStyle(Local<String> name, Local<Value> value, |
+void JsContext::SetFillStyle(Local<String> name, Local<Value> value, |
const PropertyCallbackInfo<void>& info) { |
- JsCanvas* jsCanvas = Unwrap(info.This()); |
+ JsContext* jsContext = Unwrap(info.This()); |
Local<String> s = value->ToString(); |
if (s->Length() != 7) { |
info.GetIsolate()->ThrowException( |
@@ -108,25 +152,47 @@ void JsCanvas::SetFillStyle(Local<String> name, Local<Value> value, |
} |
long color = strtol(buf+1, NULL, 16); |
- jsCanvas->fFillStyle.setColor(SkColorSetA(SkColor(color), SK_AlphaOPAQUE)); |
+ jsContext->fFillStyle.setColor(SkColorSetA(SkColor(color), SK_AlphaOPAQUE)); |
} |
-Persistent<ObjectTemplate> JsCanvas::fCanvasTemplate; |
+void JsContext::GetWidth(Local<String> name, |
+ const PropertyCallbackInfo<Value>& info) { |
+ JsContext* jsContext = Unwrap(info.This()); |
+ SkISize size = jsContext->fCanvas->getDeviceSize(); |
+ |
+ info.GetReturnValue().Set(Int32::New(size.fWidth)); |
+} |
-Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { |
+void JsContext::GetHeight(Local<String> name, |
+ const PropertyCallbackInfo<Value>& info) { |
+ JsContext* jsContext = Unwrap(info.This()); |
+ SkISize size = jsContext->fCanvas->getDeviceSize(); |
+ |
+ info.GetReturnValue().Set(Int32::New(size.fHeight)); |
+} |
+ |
+ |
+Persistent<ObjectTemplate> JsContext::gContextTemplate; |
+ |
+Handle<ObjectTemplate> JsContext::makeContextTemplate() { |
EscapableHandleScope handleScope(fGlobal->getIsolate()); |
Local<ObjectTemplate> result = ObjectTemplate::New(); |
- // Add a field to store the pointer to a JsCanvas instance. |
+ // Add a field to store the pointer to a JsContext instance. |
result->SetInternalFieldCount(1); |
- // Add accessors for each of the fields of the canvas object. |
- result->SetAccessor( |
- String::NewFromUtf8( |
- fGlobal->getIsolate(), "fillStyle", String::kInternalizedString), |
- GetFillStyle, SetFillStyle); |
+ // Add accessors for each of the fields of the context object. |
+ result->SetAccessor(String::NewFromUtf8( |
+ fGlobal->getIsolate(), "fillStyle", String::kInternalizedString), |
+ GetFillStyle, SetFillStyle); |
+ result->SetAccessor(String::NewFromUtf8( |
+ fGlobal->getIsolate(), "width", String::kInternalizedString), |
+ GetWidth); |
+ result->SetAccessor(String::NewFromUtf8( |
+ fGlobal->getIsolate(), "height", String::kInternalizedString), |
+ GetHeight); |
// Add methods. |
result->Set( |
@@ -134,6 +200,26 @@ Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { |
fGlobal->getIsolate(), "fillRect", |
String::kInternalizedString), |
FunctionTemplate::New(FillRect)); |
+ result->Set( |
+ String::NewFromUtf8( |
+ fGlobal->getIsolate(), "stroke", |
+ String::kInternalizedString), |
+ FunctionTemplate::New(Stroke)); |
+ result->Set( |
+ String::NewFromUtf8( |
+ fGlobal->getIsolate(), "fill", |
+ String::kInternalizedString), |
+ FunctionTemplate::New(Fill)); |
+ result->Set( |
+ String::NewFromUtf8( |
+ fGlobal->getIsolate(), "translate", |
+ String::kInternalizedString), |
+ FunctionTemplate::New(Translate)); |
+ result->Set( |
+ String::NewFromUtf8( |
+ fGlobal->getIsolate(), "resetTransform", |
+ String::kInternalizedString), |
+ FunctionTemplate::New(ResetTransform)); |
// Return the result through the current handle scope. |
return handleScope.Escape(result); |
@@ -141,28 +227,28 @@ Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { |
// Wraps 'this' in a Javascript object. |
-Handle<Object> JsCanvas::wrap() { |
+Handle<Object> JsContext::wrap() { |
// Handle scope for temporary handles. |
EscapableHandleScope handleScope(fGlobal->getIsolate()); |
- // Fetch the template for creating JavaScript JsCanvas wrappers. |
+ // Fetch the template for creating JavaScript JsContext wrappers. |
// It only has to be created once, which we do on demand. |
- if (fCanvasTemplate.IsEmpty()) { |
- Handle<ObjectTemplate> raw_template = this->makeCanvasTemplate(); |
- fCanvasTemplate.Reset(fGlobal->getIsolate(), raw_template); |
+ if (gContextTemplate.IsEmpty()) { |
+ Handle<ObjectTemplate> raw_template = this->makeContextTemplate(); |
+ gContextTemplate.Reset(fGlobal->getIsolate(), raw_template); |
} |
Handle<ObjectTemplate> templ = |
- Local<ObjectTemplate>::New(fGlobal->getIsolate(), fCanvasTemplate); |
+ Local<ObjectTemplate>::New(fGlobal->getIsolate(), gContextTemplate); |
- // Create an empty JsCanvas wrapper. |
+ // Create an empty JsContext wrapper. |
Local<Object> result = templ->NewInstance(); |
// Wrap the raw C++ pointer in an External so it can be referenced |
// from within JavaScript. |
- Handle<External> canvasPtr = External::New(fGlobal->getIsolate(), this); |
+ Handle<External> contextPtr = External::New(fGlobal->getIsolate(), this); |
- // Store the canvas pointer in the JavaScript wrapper. |
- result->SetInternalField(0, canvasPtr); |
+ // Store the context pointer in the JavaScript wrapper. |
+ result->SetInternalField(0, contextPtr); |
// Return the result through the current handle scope. Since each |
// of these handles will go away when the handle scope is deleted |
@@ -171,7 +257,7 @@ Handle<Object> JsCanvas::wrap() { |
return handleScope.Escape(result); |
} |
-void JsCanvas::onDraw(SkCanvas* canvas) { |
+void JsContext::onDraw(SkCanvas* canvas) { |
// Record canvas and window in this. |
fCanvas = canvas; |
@@ -185,15 +271,15 @@ void JsCanvas::onDraw(SkCanvas* canvas) { |
Context::Scope contextScope(context); |
// Wrap the C++ this pointer in a JavaScript wrapper. |
- Handle<Object> canvasObj = this->wrap(); |
+ Handle<Object> contextObj = this->wrap(); |
// Set up an exception handler before calling the Process function. |
TryCatch tryCatch; |
// Invoke the process function, giving the global object as 'this' |
- // and one argument, this JsCanvas. |
+ // and one argument, this JsContext. |
const int argc = 1; |
- Handle<Value> argv[argc] = { canvasObj }; |
+ Handle<Value> argv[argc] = { contextObj }; |
Local<Function> onDraw = |
Local<Function>::New(fGlobal->getIsolate(), fOnDraw); |
Handle<Value> result = onDraw->Call(context->Global(), argc, argv); |
@@ -216,7 +302,7 @@ void JsCanvas::onDraw(SkCanvas* canvas) { |
} |
// Fetch the onDraw function from the global context. |
-bool JsCanvas::initialize() { |
+bool JsContext::initialize() { |
// Create a stack-allocated handle scope. |
HandleScope handleScope(fGlobal->getIsolate()); |
@@ -248,79 +334,3 @@ bool JsCanvas::initialize() { |
return true; |
} |
- |
-SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) |
- : INHERITED(hwnd) |
- , fJsCanvas(canvas) |
-{ |
- this->setConfig(SkBitmap::kARGB_8888_Config); |
- this->setVisibleP(true); |
- this->setClipToBounds(false); |
-} |
- |
-void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { |
- |
- canvas->save(); |
- canvas->drawColor(SK_ColorWHITE); |
- |
- // Now jump into JS and call the onDraw(canvas) method defined there. |
- fJsCanvas->onDraw(canvas); |
- |
- canvas->restore(); |
- |
- INHERITED::onDraw(canvas); |
-} |
- |
- |
-#ifdef SK_BUILD_FOR_WIN |
-void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { |
- RECT winRect; |
- winRect.top = rect.top(); |
- winRect.bottom = rect.bottom(); |
- winRect.right = rect.right(); |
- winRect.left = rect.left(); |
- InvalidateRect((HWND)this->getHWND(), &winRect, false); |
-} |
-#endif |
- |
-SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { |
- printf("Started\n"); |
- |
- SkCommandLineFlags::Parse(argc, argv); |
- |
- // Get the default Isolate created at startup. |
- Isolate* isolate = Isolate::GetCurrent(); |
- Global* global = new Global(isolate); |
- |
- const char* script = |
-"function onDraw(canvas) { \n" |
-" canvas.fillStyle = '#00FF00'; \n" |
-" canvas.fillRect(20, 20, 100, 100); \n" |
-" canvas.inval(); \n" |
-"} \n"; |
- |
- SkAutoTUnref<SkData> data; |
- if (FLAGS_infile.count()) { |
- data.reset(SkData::NewFromFileName(FLAGS_infile[0])); |
- script = static_cast<const char*>(data->data()); |
- } |
- if (NULL == script) { |
- printf("Could not load file: %s.\n", FLAGS_infile[0]); |
- exit(1); |
- } |
- |
- if (!global->parseScript(script)) { |
- printf("Failed to parse file: %s.\n", FLAGS_infile[0]); |
- exit(1); |
- } |
- |
- JsCanvas* jsCanvas = new JsCanvas(global); |
- |
- if (!jsCanvas->initialize()) { |
- printf("Failed to initialize.\n"); |
- exit(1); |
- } |
- SkV8ExampleWindow* win = new SkV8ExampleWindow(hwnd, jsCanvas); |
- global->setWindow(win); |
- return win; |
-} |