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