Chromium Code Reviews| Index: experimental/SkV8Example/Path.cpp |
| diff --git a/experimental/SkV8Example/Path.cpp b/experimental/SkV8Example/Path.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..04349d36c43070c81d3d21a06f76380573f299c2 |
| --- /dev/null |
| +++ b/experimental/SkV8Example/Path.cpp |
| @@ -0,0 +1,196 @@ |
| +/* |
|
robertphillips
2014/01/06 15:37:04
2014?
jcgregorio
2014/01/06 15:57:31
Done.
|
| + * Copyright 2013 Google Inc. |
| + * |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + * |
| + */ |
| + |
| +#include "Path.h" |
| +#include "Global.h" |
| + |
|
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.
|
| +#define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI)) |
| + |
| +Global* Path::gGlobal = NULL; |
| + |
| +void Path::ConstructPath(const v8::FunctionCallbackInfo<Value>& args) { |
| + HandleScope handleScope(gGlobal->getIsolate()); |
| + Path* path = new Path(); |
| + args.This()->SetInternalField(0, External::New(path)); |
| +} |
| + |
| +#define ADD_METHOD(name, fn) \ |
| + constructor->InstanceTemplate()->Set( \ |
| + String::NewFromUtf8( \ |
| + global->getIsolate(), name, \ |
| + String::kInternalizedString), \ |
| + FunctionTemplate::New(fn)) |
| + |
| +// Install the constructor in the global scope so Paths can be constructed |
| +// in JS. |
| +void Path::AddToGlobal(Global* global) { |
| + gGlobal = global; |
| + |
| + // Create a stack-allocated handle scope. |
| + HandleScope handleScope(gGlobal->getIsolate()); |
| + |
| + Handle<Context> context = gGlobal->getContext(); |
| + |
| + // Enter the scope so all operations take place in the scope. |
| + Context::Scope contextScope(context); |
| + |
| + Local<FunctionTemplate> constructor = FunctionTemplate::New( |
| + Path::ConstructPath); |
| + constructor->InstanceTemplate()->SetInternalFieldCount(1); |
| + |
| + ADD_METHOD("close", ClosePath); |
| + ADD_METHOD("moveTo", MoveTo); |
| + ADD_METHOD("lineTo", LineTo); |
| + ADD_METHOD("quadraticCurveTo", QuadraticCurveTo); |
| + ADD_METHOD("bezierCurveTo", BezierCurveTo); |
| + ADD_METHOD("arc", Arc); |
| + ADD_METHOD("rect", Rect); |
| + |
| + context->Global()->Set(String::New("Path"), constructor->GetFunction()); |
| +} |
| + |
| +Path* Path::Unwrap(const v8::FunctionCallbackInfo<Value>& args) { |
| + Handle<External> field = Handle<External>::Cast( |
| + args.This()->GetInternalField(0)); |
| + void* ptr = field->Value(); |
| + return static_cast<Path*>(ptr); |
| +} |
| + |
| +void Path::ClosePath(const v8::FunctionCallbackInfo<Value>& args) { |
| + Path* path = Unwrap(args); |
| + path->fSkPath.close(); |
| +} |
| + |
| +void Path::MoveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 2) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 2 arguments required.")); |
| + return; |
| + } |
| + double x = args[0]->NumberValue(); |
| + double y = args[1]->NumberValue(); |
| + Path* path = Unwrap(args); |
| + path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| +} |
| + |
| +void Path::LineTo(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 2) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 2 arguments required.")); |
| + return; |
| + } |
| + double x = args[0]->NumberValue(); |
| + double y = args[1]->NumberValue(); |
| + Path* path = Unwrap(args); |
| + path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| +} |
| + |
| +void Path::QuadraticCurveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 4) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 4 arguments required.")); |
| + return; |
| + } |
| + double cpx = args[0]->NumberValue(); |
| + double cpy = args[1]->NumberValue(); |
| + double x = args[2]->NumberValue(); |
| + double y = args[3]->NumberValue(); |
| + Path* path = Unwrap(args); |
| + // TODO(jcgregorio) Doesn't handle the empty last path case correctly per |
| + // the HTML 5 spec. |
| + path->fSkPath.quadTo( |
| + SkDoubleToScalar(cpx), SkDoubleToScalar(cpy), |
| + SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| +} |
| + |
| +void Path::BezierCurveTo(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 6) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 6 arguments required.")); |
| + return; |
| + } |
| + double cp1x = args[0]->NumberValue(); |
| + double cp1y = args[1]->NumberValue(); |
| + double cp2x = args[2]->NumberValue(); |
| + double cp2y = args[3]->NumberValue(); |
| + double x = args[4]->NumberValue(); |
| + double y = args[5]->NumberValue(); |
| + Path* path = Unwrap(args); |
| + // TODO(jcgregorio) Doesn't handle the empty last path case correctly per |
| + // the HTML 5 spec. |
| + path->fSkPath.cubicTo( |
| + SkDoubleToScalar(cp1x), SkDoubleToScalar(cp1y), |
| + SkDoubleToScalar(cp2x), SkDoubleToScalar(cp2y), |
| + SkDoubleToScalar(x), SkDoubleToScalar(y)); |
| +} |
| + |
| +void Path::Arc(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 5 && args.Length() != 6) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 5 or 6 args required.")); |
| + return; |
| + } |
| + double x = args[0]->NumberValue(); |
| + double y = args[1]->NumberValue(); |
| + double radius = args[2]->NumberValue(); |
| + double startAngle = args[3]->NumberValue(); |
| + double endAngle = args[4]->NumberValue(); |
| + bool antiClockwise = false; |
| + if (args.Length() == 6) { |
| + antiClockwise = args[5]->BooleanValue(); |
| + } |
| + double sweepAngle; |
| + if (!antiClockwise) { |
| + sweepAngle = endAngle - startAngle; |
| + } else { |
|
robertphillips
2014/01/06 15:37:04
printf?
jcgregorio
2014/01/06 15:57:31
Done.
|
| + printf("antiClockwise\n"); |
| + sweepAngle = startAngle - endAngle; |
| + startAngle = endAngle; |
| + } |
|
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.
|
| + startAngle = startAngle*(180/SK_ScalarPI); |
| + |
| + Path* path = Unwrap(args); |
| + SkRect rect = { |
| + SkDoubleToScalar(x-radius), |
| + SkDoubleToScalar(y-radius), |
| + SkDoubleToScalar(x+radius), |
| + SkDoubleToScalar(y+radius) |
| + }; |
| + |
| + path->fSkPath.addArc(rect, SkRadiansToDegrees(startAngle), |
| + SkRadiansToDegrees(sweepAngle)); |
| +} |
| + |
| +void Path::Rect(const v8::FunctionCallbackInfo<Value>& args) { |
| + if (args.Length() != 4) { |
| + args.GetIsolate()->ThrowException( |
| + v8::String::NewFromUtf8( |
| + args.GetIsolate(), "Error: 4 arguments required.")); |
| + return; |
| + } |
| + double x = args[0]->NumberValue(); |
| + double y = args[1]->NumberValue(); |
| + double w = args[2]->NumberValue(); |
| + double h = args[3]->NumberValue(); |
| + |
| + SkRect rect = { |
| + SkDoubleToScalar(x), |
| + SkDoubleToScalar(y), |
| + SkDoubleToScalar(x) + SkDoubleToScalar(w), |
| + SkDoubleToScalar(y) + SkDoubleToScalar(h) |
| + }; |
| + Path* path = Unwrap(args); |
| + path->fSkPath.addRect(rect); |
| +} |
| + |