1/* 2 * Copyright 2014 Google Inc. 3 * 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 * 8 */ 9#include <v8.h> 10 11#include "Global.h" 12#include "DrawingMethods.h" 13#include "Path2D.h" 14#include "SkCanvas.h" 15#include "SkPaint.h" 16 17 18DrawingMethods* DrawingMethods::Unwrap(v8::Handle<v8::Object> obj) { 19 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(obj->GetInternalField(0)); 20 void* ptr = field->Value(); 21 return static_cast<DrawingMethods*>(ptr); 22} 23 24 25void DrawingMethods::Save(const v8::FunctionCallbackInfo<v8::Value>& args) { 26 DrawingMethods* drawingMethods = Unwrap(args.This()); 27 SkCanvas* canvas = drawingMethods->getCanvas(); 28 if (NULL == canvas) { 29 return; 30 } 31 32 canvas->save(); 33} 34 35void DrawingMethods::Restore(const v8::FunctionCallbackInfo<v8::Value>& args) { 36 DrawingMethods* drawingMethods = Unwrap(args.This()); 37 SkCanvas* canvas = drawingMethods->getCanvas(); 38 if (NULL == canvas) { 39 return; 40 } 41 42 canvas->restore(); 43} 44 45void DrawingMethods::Rotate(const v8::FunctionCallbackInfo<v8::Value>& args) { 46 DrawingMethods* drawingMethods = Unwrap(args.This()); 47 SkCanvas* canvas = drawingMethods->getCanvas(); 48 if (NULL == canvas) { 49 return; 50 } 51 52 if (args.Length() != 1) { 53 args.GetIsolate()->ThrowException( 54 v8::String::NewFromUtf8( 55 args.GetIsolate(), "Error: 1 arguments required.")); 56 return; 57 } 58 double angle = args[0]->NumberValue(); 59 canvas->rotate(SkRadiansToDegrees(angle)); 60} 61 62void DrawingMethods::Translate(const v8::FunctionCallbackInfo<v8::Value>& args) { 63 DrawingMethods* drawingMethods = Unwrap(args.This()); 64 SkCanvas* canvas = drawingMethods->getCanvas(); 65 if (NULL == canvas) { 66 return; 67 } 68 69 if (args.Length() != 2) { 70 args.GetIsolate()->ThrowException( 71 v8::String::NewFromUtf8( 72 args.GetIsolate(), "Error: 2 arguments required.")); 73 return; 74 } 75 double dx = args[0]->NumberValue(); 76 double dy = args[1]->NumberValue(); 77 canvas->translate(SkDoubleToScalar(dx), SkDoubleToScalar(dy)); 78} 79 80void DrawingMethods::ResetTransform(const v8::FunctionCallbackInfo<v8::Value>& args) { 81 DrawingMethods* drawingMethods = Unwrap(args.This()); 82 SkCanvas* canvas = drawingMethods->getCanvas(); 83 if (NULL == canvas) { 84 return; 85 } 86 87 canvas->resetMatrix(); 88} 89 90void DrawingMethods::DrawPath(const v8::FunctionCallbackInfo<v8::Value>& args) { 91 DrawingMethods* drawingMethods = Unwrap(args.This()); 92 SkCanvas* canvas = drawingMethods->getCanvas(); 93 if (NULL == canvas) { 94 return; 95 } 96 97 if (args.Length() != 1) { 98 args.GetIsolate()->ThrowException( 99 v8::String::NewFromUtf8( 100 args.GetIsolate(), "Error: 1 argument required.")); 101 return; 102 } 103 104 v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast( 105 args[0]->ToObject()->GetInternalField(0)); 106 void* ptr = field->Value(); 107 Path2D* path = static_cast<Path2D*>(ptr); 108 if (NULL == path) { 109 return; 110 } 111 // TODO(jcgregorio) Add support for Paint2D parameter after Paint2D is 112 // implemented. 113 SkPaint fillStyle; 114 fillStyle.setColor(SK_ColorBLACK); 115 fillStyle.setAntiAlias(true); 116 fillStyle.setStyle(SkPaint::kFill_Style); 117 canvas->drawPath(*(path->path()), fillStyle); 118} 119 120 121void DrawingMethods::GetWidth(v8::Local<v8::String> name, 122 const v8::PropertyCallbackInfo<v8::Value>& info) { 123 DrawingMethods* drawingMethods = Unwrap(info.This()); 124 SkCanvas* canvas = drawingMethods->getCanvas(); 125 if (NULL == canvas) { 126 return; 127 } 128 129 info.GetReturnValue().Set( 130 v8::Int32::New( 131 drawingMethods->fGlobal->getIsolate(), canvas->imageInfo().width())); 132} 133 134void DrawingMethods::GetHeight(v8::Local<v8::String> name, 135 const v8::PropertyCallbackInfo<v8::Value>& info) { 136 DrawingMethods* drawingMethods = Unwrap(info.This()); 137 SkCanvas* canvas = drawingMethods->getCanvas(); 138 if (NULL == canvas) { 139 return; 140 } 141 142 info.GetReturnValue().Set( 143 v8::Int32::New( 144 drawingMethods->fGlobal->getIsolate(), canvas->imageInfo().height())); 145} 146 147#define ADD_METHOD(name, fn) \ 148 tmpl->Set(v8::String::NewFromUtf8( \ 149 fGlobal->getIsolate(), name, \ 150 v8::String::kInternalizedString), \ 151 v8::FunctionTemplate::New(fGlobal->getIsolate(), fn)) 152 153void DrawingMethods::addAttributesAndMethods(v8::Handle<v8::ObjectTemplate> tmpl) { 154 v8::HandleScope scope(fGlobal->getIsolate()); 155 156 // Add accessors for each of the fields of the context object. 157 tmpl->SetAccessor(v8::String::NewFromUtf8( 158 fGlobal->getIsolate(), "width", v8::String::kInternalizedString), 159 GetWidth); 160 tmpl->SetAccessor(v8::String::NewFromUtf8( 161 fGlobal->getIsolate(), "height", v8::String::kInternalizedString), 162 GetHeight); 163 164 // Add methods. 165 ADD_METHOD("save", Save); 166 ADD_METHOD("restore", Restore); 167 ADD_METHOD("rotate", Rotate); 168 ADD_METHOD("translate", Translate); 169 ADD_METHOD("resetTransform", ResetTransform); 170 171 ADD_METHOD("drawPath", DrawPath); 172} 173