| Index: experimental/SkV8Example/JsContext.cpp
|
| diff --git a/experimental/SkV8Example/JsContext.cpp b/experimental/SkV8Example/JsContext.cpp
|
| index c84962190508fb38f1f93fd5f98982093bd64bd8..8b0b0729797427ce6bf7291fe997d98b93a29f8e 100644
|
| --- a/experimental/SkV8Example/JsContext.cpp
|
| +++ b/experimental/SkV8Example/JsContext.cpp
|
| @@ -23,257 +23,8 @@ static const char* to_cstring(const v8::String::Utf8Value& value) {
|
| return *value ? *value : "<string conversion failed>";
|
| }
|
|
|
| -JsContext* JsContext::Unwrap(Handle<Object> obj) {
|
| - Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
|
| - void* ptr = field->Value();
|
| - return static_cast<JsContext*>(ptr);
|
| -}
|
| -
|
| -void JsContext::FillRect(const v8::FunctionCallbackInfo<Value>& args) {
|
| - JsContext* jsContext = Unwrap(args.This());
|
| - SkCanvas* canvas = jsContext->fCanvas;
|
| -
|
| - if (args.Length() != 4) {
|
| - args.GetIsolate()->ThrowException(
|
| - v8::String::NewFromUtf8(
|
| - args.GetIsolate(), "Error: 4 arguments required."));
|
| - return;
|
| - }
|
| - // TODO(jcgregorio) Really figure out the conversion from JS numbers to
|
| - // SkScalars. Maybe test if int first? Not sure of the performance impact.
|
| - double x = args[0]->NumberValue();
|
| - double y = args[1]->NumberValue();
|
| - double w = args[2]->NumberValue();
|
| - double h = args[3]->NumberValue();
|
| -
|
| - SkRect rect = {
|
| - SkDoubleToScalar(x),
|
| - SkDoubleToScalar(y),
|
| - SkDoubleToScalar(x) + SkDoubleToScalar(w),
|
| - SkDoubleToScalar(y) + SkDoubleToScalar(h)
|
| - };
|
| - canvas->drawRect(rect, jsContext->fFillStyle);
|
| -}
|
| -
|
| -void JsContext::Save(const v8::FunctionCallbackInfo<Value>& args) {
|
| - JsContext* jsContext = Unwrap(args.This());
|
| - SkCanvas* canvas = jsContext->fCanvas;
|
| -
|
| - canvas->save();
|
| -}
|
| -
|
| -void JsContext::Restore(const v8::FunctionCallbackInfo<Value>& args) {
|
| - JsContext* jsContext = Unwrap(args.This());
|
| - SkCanvas* canvas = jsContext->fCanvas;
|
| -
|
| - canvas->restore();
|
| -}
|
| -
|
| -void JsContext::Rotate(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;
|
| - }
|
| - double angle = args[0]->NumberValue();
|
| - canvas->rotate(SkRadiansToDegrees(angle));
|
| -}
|
| -
|
| -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();
|
| - Path2D* path = static_cast<Path2D*>(ptr);
|
| -
|
| - canvas->drawPath(path->getSkPath(), jsContext->fStrokeStyle);
|
| -}
|
| -
|
| -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();
|
| - Path2D* path = static_cast<Path2D*>(ptr);
|
| -
|
| - canvas->drawPath(path->getSkPath(), jsContext->fFillStyle);
|
| -}
|
| -
|
| -void JsContext::GetStyle(Local<String> name,
|
| - const PropertyCallbackInfo<Value>& info,
|
| - const SkPaint& style) {
|
| - char buf[8];
|
| - SkColor color = style.getColor();
|
| - sprintf(buf, "#%02X%02X%02X", SkColorGetR(color), SkColorGetG(color),
|
| - SkColorGetB(color));
|
| -
|
| - info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buf));
|
| -}
|
| -
|
| -void JsContext::SetStyle(Local<String> name, Local<Value> value,
|
| - const PropertyCallbackInfo<void>& info,
|
| - SkPaint& style) {
|
| - Local<String> s = value->ToString();
|
| - if (s->Length() != 7 && s->Length() != 9) {
|
| - info.GetIsolate()->ThrowException(
|
| - v8::String::NewFromUtf8(
|
| - info.GetIsolate(),
|
| - "Invalid fill style format length."));
|
| - return;
|
| - }
|
| - char buf[10];
|
| - s->WriteUtf8(buf, sizeof(buf));
|
| -
|
| - if (buf[0] != '#') {
|
| - info.GetIsolate()->ThrowException(
|
| - v8::String::NewFromUtf8(
|
| - info.GetIsolate(), "Invalid fill style format."));
|
| - return;
|
| - }
|
| -
|
| - // Colors can be RRGGBBAA, but SkColor uses ARGB.
|
| - long color = strtol(buf+1, NULL, 16);
|
| - uint32_t alpha = SK_AlphaOPAQUE;
|
| - if (s->Length() == 9) {
|
| - alpha = color & 0xFF;
|
| - color >>= 8;
|
| - }
|
| - style.setColor(SkColorSetA(SkColor(color), alpha));
|
| -}
|
| -
|
| -void JsContext::GetFillStyle(Local<String> name,
|
| - const PropertyCallbackInfo<Value>& info) {
|
| - JsContext* jsContext = Unwrap(info.This());
|
| - GetStyle(name, info, jsContext->fFillStyle);
|
| -}
|
| -
|
| -void JsContext::GetStrokeStyle(Local<String> name,
|
| - const PropertyCallbackInfo<Value>& info) {
|
| - JsContext* jsContext = Unwrap(info.This());
|
| - GetStyle(name, info, jsContext->fStrokeStyle);
|
| -}
|
| -
|
| -void JsContext::SetFillStyle(Local<String> name, Local<Value> value,
|
| - const PropertyCallbackInfo<void>& info) {
|
| - JsContext* jsContext = Unwrap(info.This());
|
| - SetStyle(name, value, info, jsContext->fFillStyle);
|
| -}
|
| -
|
| -void JsContext::SetStrokeStyle(Local<String> name, Local<Value> value,
|
| - const PropertyCallbackInfo<void>& info) {
|
| - JsContext* jsContext = Unwrap(info.This());
|
| - SetStyle(name, value, info, jsContext->fStrokeStyle);
|
| -}
|
| -
|
| -
|
| -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(jsContext->fGlobal->getIsolate(), size.fWidth));
|
| -}
|
| -
|
| -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(jsContext->fGlobal->getIsolate(), size.fHeight));
|
| -}
|
| -
|
| -
|
| Persistent<ObjectTemplate> JsContext::gContextTemplate;
|
|
|
| -#define ADD_METHOD(name, fn) \
|
| - result->Set(String::NewFromUtf8( \
|
| - fGlobal->getIsolate(), name, \
|
| - String::kInternalizedString), \
|
| - FunctionTemplate::New(fGlobal->getIsolate(), fn))
|
| -
|
| -Handle<ObjectTemplate> JsContext::makeContextTemplate() {
|
| - EscapableHandleScope handleScope(fGlobal->getIsolate());
|
| -
|
| - Local<ObjectTemplate> result = ObjectTemplate::New();
|
| -
|
| - // Add a field to store the pointer to a JsContext instance.
|
| - result->SetInternalFieldCount(1);
|
| -
|
| - // 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(), "strokeStyle", String::kInternalizedString),
|
| - GetStrokeStyle, SetStrokeStyle);
|
| - result->SetAccessor(String::NewFromUtf8(
|
| - fGlobal->getIsolate(), "width", String::kInternalizedString),
|
| - GetWidth);
|
| - result->SetAccessor(String::NewFromUtf8(
|
| - fGlobal->getIsolate(), "height", String::kInternalizedString),
|
| - GetHeight);
|
| -
|
| - // Add methods.
|
| - ADD_METHOD("fillRect", FillRect);
|
| - ADD_METHOD("stroke", Stroke);
|
| - ADD_METHOD("fill", Fill);
|
| - ADD_METHOD("rotate", Rotate);
|
| - ADD_METHOD("save", Save);
|
| - ADD_METHOD("restore", Restore);
|
| - ADD_METHOD("translate", Translate);
|
| - ADD_METHOD("resetTransform", ResetTransform);
|
| -
|
| - // Return the result through the current handle scope.
|
| - return handleScope.Escape(result);
|
| -}
|
| -
|
| -
|
| // Wraps 'this' in a Javascript object.
|
| Handle<Object> JsContext::wrap() {
|
| // Handle scope for temporary handles.
|
| @@ -282,8 +33,14 @@ Handle<Object> JsContext::wrap() {
|
| // Fetch the template for creating JavaScript JsContext wrappers.
|
| // It only has to be created once, which we do on demand.
|
| if (gContextTemplate.IsEmpty()) {
|
| - Handle<ObjectTemplate> raw_template = this->makeContextTemplate();
|
| - gContextTemplate.Reset(fGlobal->getIsolate(), raw_template);
|
| + Local<ObjectTemplate> localTemplate = ObjectTemplate::New();
|
| +
|
| + // Add a field to store the pointer to a JsContext instance.
|
| + localTemplate->SetInternalFieldCount(1);
|
| +
|
| + this->addAttributesAndMethods(localTemplate);
|
| +
|
| + gContextTemplate.Reset(fGlobal->getIsolate(), localTemplate);
|
| }
|
| Handle<ObjectTemplate> templ =
|
| Local<ObjectTemplate>::New(fGlobal->getIsolate(), gContextTemplate);
|
|
|