OLD | NEW |
(Empty) | |
| 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 |
| 10 #include "Path.h" |
| 11 #include "Global.h" |
| 12 |
| 13 Global* Path::gGlobal = NULL; |
| 14 |
| 15 void Path::ConstructPath(const v8::FunctionCallbackInfo<Value>& args) { |
| 16 HandleScope handleScope(gGlobal->getIsolate()); |
| 17 Path* path = new Path(); |
| 18 args.This()->SetInternalField(0, External::New(path)); |
| 19 } |
| 20 |
| 21 #define ADD_METHOD(name, fn) \ |
| 22 constructor->InstanceTemplate()->Set( \ |
| 23 String::NewFromUtf8( \ |
| 24 global->getIsolate(), name, \ |
| 25 String::kInternalizedString), \ |
| 26 FunctionTemplate::New(fn)) |
| 27 |
| 28 // Install the constructor in the global scope so Paths can be constructed |
| 29 // in JS. |
| 30 void Path::AddToGlobal(Global* global) { |
| 31 gGlobal = global; |
| 32 |
| 33 // Create a stack-allocated handle scope. |
| 34 HandleScope handleScope(gGlobal->getIsolate()); |
| 35 |
| 36 Handle<Context> context = gGlobal->getContext(); |
| 37 |
| 38 // Enter the scope so all operations take place in the scope. |
| 39 Context::Scope contextScope(context); |
| 40 |
| 41 Local<FunctionTemplate> constructor = FunctionTemplate::New( |
| 42 Path::ConstructPath); |
| 43 constructor->InstanceTemplate()->SetInternalFieldCount(1); |
| 44 |
| 45 ADD_METHOD("close", ClosePath); |
| 46 ADD_METHOD("moveTo", MoveTo); |
| 47 ADD_METHOD("lineTo", LineTo); |
| 48 ADD_METHOD("quadraticCurveTo", QuadraticCurveTo); |
| 49 ADD_METHOD("bezierCurveTo", BezierCurveTo); |
| 50 ADD_METHOD("arc", Arc); |
| 51 ADD_METHOD("rect", Rect); |
| 52 |
| 53 context->Global()->Set(String::New("Path"), constructor->GetFunction()); |
| 54 } |
| 55 |
| 56 Path* Path::Unwrap(const v8::FunctionCallbackInfo<Value>& args) { |
| 57 Handle<External> field = Handle<External>::Cast( |
| 58 args.This()->GetInternalField(0)); |
| 59 void* ptr = field->Value(); |
| 60 return static_cast<Path*>(ptr); |
| 61 } |
| 62 |
| 63 void Path::ClosePath(const v8::FunctionCallbackInfo<Value>& args) { |
| 64 Path* path = Unwrap(args); |
| 65 path->fSkPath.close(); |
| 66 } |
| 67 |
| 68 void Path::MoveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| 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 x = args[0]->NumberValue(); |
| 76 double y = args[1]->NumberValue(); |
| 77 Path* path = Unwrap(args); |
| 78 path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| 79 } |
| 80 |
| 81 void Path::LineTo(const v8::FunctionCallbackInfo<Value>& args) { |
| 82 if (args.Length() != 2) { |
| 83 args.GetIsolate()->ThrowException( |
| 84 v8::String::NewFromUtf8( |
| 85 args.GetIsolate(), "Error: 2 arguments required.")); |
| 86 return; |
| 87 } |
| 88 double x = args[0]->NumberValue(); |
| 89 double y = args[1]->NumberValue(); |
| 90 Path* path = Unwrap(args); |
| 91 path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| 92 } |
| 93 |
| 94 void Path::QuadraticCurveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| 95 if (args.Length() != 4) { |
| 96 args.GetIsolate()->ThrowException( |
| 97 v8::String::NewFromUtf8( |
| 98 args.GetIsolate(), "Error: 4 arguments required.")); |
| 99 return; |
| 100 } |
| 101 double cpx = args[0]->NumberValue(); |
| 102 double cpy = args[1]->NumberValue(); |
| 103 double x = args[2]->NumberValue(); |
| 104 double y = args[3]->NumberValue(); |
| 105 Path* path = Unwrap(args); |
| 106 // TODO(jcgregorio) Doesn't handle the empty last path case correctly per |
| 107 // the HTML 5 spec. |
| 108 path->fSkPath.quadTo( |
| 109 SkDoubleToScalar(cpx), SkDoubleToScalar(cpy), |
| 110 SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| 111 } |
| 112 |
| 113 void Path::BezierCurveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| 114 if (args.Length() != 6) { |
| 115 args.GetIsolate()->ThrowException( |
| 116 v8::String::NewFromUtf8( |
| 117 args.GetIsolate(), "Error: 6 arguments required.")); |
| 118 return; |
| 119 } |
| 120 double cp1x = args[0]->NumberValue(); |
| 121 double cp1y = args[1]->NumberValue(); |
| 122 double cp2x = args[2]->NumberValue(); |
| 123 double cp2y = args[3]->NumberValue(); |
| 124 double x = args[4]->NumberValue(); |
| 125 double y = args[5]->NumberValue(); |
| 126 Path* path = Unwrap(args); |
| 127 // TODO(jcgregorio) Doesn't handle the empty last path case correctly per |
| 128 // the HTML 5 spec. |
| 129 path->fSkPath.cubicTo( |
| 130 SkDoubleToScalar(cp1x), SkDoubleToScalar(cp1y), |
| 131 SkDoubleToScalar(cp2x), SkDoubleToScalar(cp2y), |
| 132 SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| 133 } |
| 134 |
| 135 void Path::Arc(const v8::FunctionCallbackInfo<Value>& args) { |
| 136 if (args.Length() != 5 && args.Length() != 6) { |
| 137 args.GetIsolate()->ThrowException( |
| 138 v8::String::NewFromUtf8( |
| 139 args.GetIsolate(), "Error: 5 or 6 args required.")); |
| 140 return; |
| 141 } |
| 142 double x = args[0]->NumberValue(); |
| 143 double y = args[1]->NumberValue(); |
| 144 double radius = args[2]->NumberValue(); |
| 145 double startAngle = args[3]->NumberValue(); |
| 146 double endAngle = args[4]->NumberValue(); |
| 147 bool antiClockwise = false; |
| 148 if (args.Length() == 6) { |
| 149 antiClockwise = args[5]->BooleanValue(); |
| 150 } |
| 151 double sweepAngle; |
| 152 if (!antiClockwise) { |
| 153 sweepAngle = endAngle - startAngle; |
| 154 } else { |
| 155 sweepAngle = startAngle - endAngle; |
| 156 startAngle = endAngle; |
| 157 } |
| 158 |
| 159 Path* path = Unwrap(args); |
| 160 SkRect rect = { |
| 161 SkDoubleToScalar(x-radius), |
| 162 SkDoubleToScalar(y-radius), |
| 163 SkDoubleToScalar(x+radius), |
| 164 SkDoubleToScalar(y+radius) |
| 165 }; |
| 166 |
| 167 path->fSkPath.addArc(rect, SkRadiansToDegrees(startAngle), |
| 168 SkRadiansToDegrees(sweepAngle)); |
| 169 } |
| 170 |
| 171 void Path::Rect(const v8::FunctionCallbackInfo<Value>& args) { |
| 172 if (args.Length() != 4) { |
| 173 args.GetIsolate()->ThrowException( |
| 174 v8::String::NewFromUtf8( |
| 175 args.GetIsolate(), "Error: 4 arguments required.")); |
| 176 return; |
| 177 } |
| 178 double x = args[0]->NumberValue(); |
| 179 double y = args[1]->NumberValue(); |
| 180 double w = args[2]->NumberValue(); |
| 181 double h = args[3]->NumberValue(); |
| 182 |
| 183 SkRect rect = { |
| 184 SkDoubleToScalar(x), |
| 185 SkDoubleToScalar(y), |
| 186 SkDoubleToScalar(x) + SkDoubleToScalar(w), |
| 187 SkDoubleToScalar(y) + SkDoubleToScalar(h) |
| 188 }; |
| 189 Path* path = Unwrap(args); |
| 190 path->fSkPath.addRect(rect); |
| 191 } |
| 192 |
OLD | NEW |