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 
Unwrap(v8::Handle<v8::Object> obj)18 DrawingMethods* 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 
Save(const v8::FunctionCallbackInfo<v8::Value> & args)25 void 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 
Restore(const v8::FunctionCallbackInfo<v8::Value> & args)35 void 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 
Rotate(const v8::FunctionCallbackInfo<v8::Value> & args)45 void 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 
Translate(const v8::FunctionCallbackInfo<v8::Value> & args)62 void 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 
ResetTransform(const v8::FunctionCallbackInfo<v8::Value> & args)80 void 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 
DrawPath(const v8::FunctionCallbackInfo<v8::Value> & args)90 void 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 
GetWidth(v8::Local<v8::String> name,const v8::PropertyCallbackInfo<v8::Value> & info)121 void 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 
GetHeight(v8::Local<v8::String> name,const v8::PropertyCallbackInfo<v8::Value> & info)134 void 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 
addAttributesAndMethods(v8::Handle<v8::ObjectTemplate> tmpl)153 void 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