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