From e001da2558d936fca377e4041ca150ff95c85104 Mon Sep 17 00:00:00 2001 From: jcgregorio Date: Wed, 29 Oct 2014 05:33:27 -0700 Subject: SkV8Sample: Now with Path2D and Path2DBuilder. BUG=skia: Review URL: https://codereview.chromium.org/661033005 --- experimental/SkV8Example/DrawingMethods.cpp | 2 +- experimental/SkV8Example/Path2D.cpp | 245 +++----------------------- experimental/SkV8Example/Path2D.h | 47 +++-- experimental/SkV8Example/Path2DBuilder.cpp | 261 ++++++++++++++++++++++++++++ experimental/SkV8Example/Path2DBuilder.h | 53 ++++++ experimental/SkV8Example/SkV8Example.cpp | 7 +- experimental/SkV8Example/js/sample.js | 27 +-- 7 files changed, 388 insertions(+), 254 deletions(-) create mode 100644 experimental/SkV8Example/Path2DBuilder.cpp create mode 100644 experimental/SkV8Example/Path2DBuilder.h (limited to 'experimental') diff --git a/experimental/SkV8Example/DrawingMethods.cpp b/experimental/SkV8Example/DrawingMethods.cpp index fdc8dc7d63..5fcdd6a5e1 100644 --- a/experimental/SkV8Example/DrawingMethods.cpp +++ b/experimental/SkV8Example/DrawingMethods.cpp @@ -114,7 +114,7 @@ void DrawingMethods::DrawPath(const v8::FunctionCallbackInfo& args) { fillStyle.setColor(SK_ColorBLACK); fillStyle.setAntiAlias(true); fillStyle.setStyle(SkPaint::kFill_Style); - canvas->drawPath(path->getSkPath(), fillStyle); + canvas->drawPath(*(path->path()), fillStyle); } diff --git a/experimental/SkV8Example/Path2D.cpp b/experimental/SkV8Example/Path2D.cpp index 5956f69de3..dded688167 100644 --- a/experimental/SkV8Example/Path2D.cpp +++ b/experimental/SkV8Example/Path2D.cpp @@ -11,234 +11,45 @@ #include "Global.h" Global* Path2D::gGlobal = NULL; +v8::Persistent Path2D::gPath2DTemplate; -void Path2D::ConstructPath(const v8::FunctionCallbackInfo& args) { - v8::HandleScope handleScope(gGlobal->getIsolate()); - Path2D* path = new Path2D(); - args.This()->SetInternalField( - 0, v8::External::New(gGlobal->getIsolate(), path)); +void weakPath2DCallback(const v8::WeakCallbackData& args) { + delete args.GetParameter(); } -#define ADD_METHOD(name, fn) \ - constructor->InstanceTemplate()->Set( \ - v8::String::NewFromUtf8( \ - global->getIsolate(), name, \ - v8::String::kInternalizedString), \ - v8::FunctionTemplate::New(global->getIsolate(), fn)) - -// Install the constructor in the global scope so Path2Ds can be constructed -// in JS. -void Path2D::AddToGlobal(Global* global) { - gGlobal = global; - - // Create a stack-allocated handle scope. +// Wraps an SkPath* in a Path2D object. +Path2D::Path2D(SkPath* path) : path_(path) { + // Handle scope for temporary handles. v8::HandleScope handleScope(gGlobal->getIsolate()); - v8::Handle context = gGlobal->getContext(); - - // Enter the scope so all operations take place in the scope. - v8::Context::Scope contextScope(context); - - v8::Local constructor = v8::FunctionTemplate::New( - gGlobal->getIsolate(), Path2D::ConstructPath); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - - ADD_METHOD("closePath", 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); - ADD_METHOD("oval", Oval); - ADD_METHOD("conicTo", ConicTo); - - context->Global()->Set(v8::String::NewFromUtf8( - gGlobal->getIsolate(), "Path2D"), constructor->GetFunction()); -} - -Path2D* Path2D::Unwrap(const v8::FunctionCallbackInfo& args) { - v8::Handle field = v8::Handle::Cast( - args.This()->GetInternalField(0)); - void* ptr = field->Value(); - return static_cast(ptr); -} + // Just once create the ObjectTemplate for what Path2D looks like in JS. + if (gPath2DTemplate.IsEmpty()) { + v8::Local localTemplate = v8::ObjectTemplate::New(); -void Path2D::ClosePath(const v8::FunctionCallbackInfo& args) { - Path2D* path = Unwrap(args); - path->fSkPath.close(); -} + // Add a field to store the pointer to a SkPath pointer. + localTemplate->SetInternalFieldCount(1); -void Path2D::MoveTo(const v8::FunctionCallbackInfo& args) { - if (args.Length() != 2) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8( - args.GetIsolate(), "Error: 2 arguments required.")); - return; + gPath2DTemplate.Reset(gGlobal->getIsolate(), localTemplate); } - double x = args[0]->NumberValue(); - double y = args[1]->NumberValue(); - Path2D* path = Unwrap(args); - path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); -} + v8::Handle templ = + v8::Local::New(gGlobal->getIsolate(), gPath2DTemplate); -void Path2D::LineTo(const v8::FunctionCallbackInfo& 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(); - Path2D* path = Unwrap(args); - path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); -} + // Create an empty Path2D wrapper. + v8::Local result = templ->NewInstance(); -void Path2D::QuadraticCurveTo(const v8::FunctionCallbackInfo& 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(); - Path2D* 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)); -} + // Store the SkPath pointer in the JavaScript wrapper. + result->SetInternalField(0, v8::External::New(gGlobal->getIsolate(), this)); + gGlobal->getIsolate()->AdjustAmountOfExternalAllocatedMemory(sizeof(SkPath)); -void Path2D::BezierCurveTo(const v8::FunctionCallbackInfo& 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(); - Path2D* 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)); + // Make a weak persistent and set up the callback so we can delete the path pointer. + // TODO(jcgregorio) Figure out why weakPath2DCallback never gets called and we leak. + v8::Persistent weak(gGlobal->getIsolate(), result); + weak.SetWeak(this, weakPath2DCallback); + this->handle_.Reset(gGlobal->getIsolate(), weak); } -void Path2D::Arc(const v8::FunctionCallbackInfo& 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 { - sweepAngle = startAngle - endAngle; - startAngle = endAngle; - } - - Path2D* 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 Path2D::Rect(const v8::FunctionCallbackInfo& 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) - }; - Path2D* path = Unwrap(args); - path->fSkPath.addRect(rect); -} - -void Path2D::Oval(const v8::FunctionCallbackInfo& args) { - if (args.Length() != 4 && args.Length() != 5) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8( - args.GetIsolate(), "Error: 4 or 5 args required.")); - return; - } - double x = args[0]->NumberValue(); - double y = args[1]->NumberValue(); - double radiusX = args[2]->NumberValue(); - double radiusY = args[3]->NumberValue(); - SkPath::Direction dir = SkPath::kCW_Direction; - if (args.Length() == 5 && !args[4]->BooleanValue()) { - dir = SkPath::kCCW_Direction; - } - Path2D* path = Unwrap(args); - SkRect rect = { - SkDoubleToScalar(x-radiusX), - SkDoubleToScalar(y-radiusX), - SkDoubleToScalar(x+radiusY), - SkDoubleToScalar(y+radiusY) - }; - - path->fSkPath.addOval(rect, dir); -} - -void Path2D::ConicTo(const v8::FunctionCallbackInfo& args) { - if (args.Length() != 5) { - args.GetIsolate()->ThrowException( - v8::String::NewFromUtf8( - args.GetIsolate(), "Error: 5 args required.")); - return; - } - double x1 = args[0]->NumberValue(); - double y1 = args[1]->NumberValue(); - double x2 = args[2]->NumberValue(); - double y2 = args[3]->NumberValue(); - double w = args[4]->NumberValue(); - Path2D* path = Unwrap(args); - - path->fSkPath.conicTo( - SkDoubleToScalar(x1), - SkDoubleToScalar(y1), - SkDoubleToScalar(x2), - SkDoubleToScalar(y2), - SkDoubleToScalar(w) - ); +Path2D::~Path2D() { + delete path_; + handle_.Reset(); + gGlobal->getIsolate()->AdjustAmountOfExternalAllocatedMemory(-sizeof(SkPath)); } diff --git a/experimental/SkV8Example/Path2D.h b/experimental/SkV8Example/Path2D.h index 93c1299c61..4ac9877fd7 100644 --- a/experimental/SkV8Example/Path2D.h +++ b/experimental/SkV8Example/Path2D.h @@ -17,36 +17,35 @@ class Global; +// Path2D bridges between JS and SkPath. class Path2D : SkNoncopyable { public: - Path2D() : fSkPath() {} - virtual ~Path2D() {} - - const SkPath& getSkPath() { return fSkPath; } - - // The JS Path2D constuctor implementation. - static void ConstructPath(const v8::FunctionCallbackInfo& args); - - // Add the Path2D JS constructor to the global context. - static void AddToGlobal(Global* global); - - // Path2D JS methods. - static void ClosePath(const v8::FunctionCallbackInfo& args); - static void MoveTo(const v8::FunctionCallbackInfo& args); - static void LineTo(const v8::FunctionCallbackInfo& args); - static void QuadraticCurveTo( - const v8::FunctionCallbackInfo& args); - static void BezierCurveTo(const v8::FunctionCallbackInfo& args); - static void Arc(const v8::FunctionCallbackInfo& args); - static void Rect(const v8::FunctionCallbackInfo& args); - static void Oval(const v8::FunctionCallbackInfo& args); - static void ConicTo(const v8::FunctionCallbackInfo& args); + Path2D(SkPath* path); + virtual ~Path2D(); + + static void AddToGlobal(Global* global) { + gGlobal = global; + } + + v8::Persistent& persistent() { + return handle_; + } + + SkPath* path() { + return path_; + } + private: - SkPath fSkPath; + // The handle to this object in JS space. + v8::Persistent handle_; - static Path2D* Unwrap(const v8::FunctionCallbackInfo& args); + SkPath* path_; + // The global context we are running in. static Global* gGlobal; + + // The template for what a JS Path2D object looks like. + static v8::Persistent gPath2DTemplate; }; #endif diff --git a/experimental/SkV8Example/Path2DBuilder.cpp b/experimental/SkV8Example/Path2DBuilder.cpp new file mode 100644 index 0000000000..ad05668139 --- /dev/null +++ b/experimental/SkV8Example/Path2DBuilder.cpp @@ -0,0 +1,261 @@ +/* + * Copyright 2014 Google Inc. + * + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#include "Global.h" +#include "Path2DBuilder.h" +#include "Path2D.h" +#include "SkPath.h" + +Global* Path2DBuilder::gGlobal = NULL; + +void Path2DBuilder::ConstructPath(const v8::FunctionCallbackInfo& args) { + v8::HandleScope handleScope(gGlobal->getIsolate()); + Path2DBuilder* path = new Path2DBuilder(); + args.This()->SetInternalField( + 0, v8::External::New(gGlobal->getIsolate(), path)); +} + +#define ADD_METHOD(name, fn) \ + constructor->InstanceTemplate()->Set( \ + v8::String::NewFromUtf8( \ + global->getIsolate(), name, \ + v8::String::kInternalizedString), \ + v8::FunctionTemplate::New(global->getIsolate(), fn)) + +// Install the constructor in the global scope so Path2DBuilders can be constructed +// in JS. +void Path2DBuilder::AddToGlobal(Global* global) { + gGlobal = global; + + // Create a stack-allocated handle scope. + v8::HandleScope handleScope(gGlobal->getIsolate()); + + v8::Handle context = gGlobal->getContext(); + + // Enter the scope so all operations take place in the scope. + v8::Context::Scope contextScope(context); + + v8::Local constructor = v8::FunctionTemplate::New( + gGlobal->getIsolate(), Path2DBuilder::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); + ADD_METHOD("oval", Oval); + ADD_METHOD("conicTo", ConicTo); + + ADD_METHOD("finalize", Finalize); + + context->Global()->Set(v8::String::NewFromUtf8( + gGlobal->getIsolate(), "Path2DBuilder"), constructor->GetFunction()); +} + +Path2DBuilder* Path2DBuilder::Unwrap(const v8::FunctionCallbackInfo& args) { + v8::Handle field = v8::Handle::Cast( + args.This()->GetInternalField(0)); + void* ptr = field->Value(); + return static_cast(ptr); +} + +void Path2DBuilder::ClosePath(const v8::FunctionCallbackInfo& args) { + Path2DBuilder* path = Unwrap(args); + path->fSkPath.close(); +} + +void Path2DBuilder::MoveTo(const v8::FunctionCallbackInfo& 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(); + Path2DBuilder* path = Unwrap(args); + path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); +} + +void Path2DBuilder::LineTo(const v8::FunctionCallbackInfo& 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(); + Path2DBuilder* path = Unwrap(args); + path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); +} + +void Path2DBuilder::QuadraticCurveTo(const v8::FunctionCallbackInfo& 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(); + Path2DBuilder* 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 Path2DBuilder::BezierCurveTo(const v8::FunctionCallbackInfo& 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(); + Path2DBuilder* 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 Path2DBuilder::Arc(const v8::FunctionCallbackInfo& 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 { + sweepAngle = startAngle - endAngle; + startAngle = endAngle; + } + + Path2DBuilder* 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 Path2DBuilder::Rect(const v8::FunctionCallbackInfo& 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) + }; + Path2DBuilder* path = Unwrap(args); + path->fSkPath.addRect(rect); +} + +void Path2DBuilder::Oval(const v8::FunctionCallbackInfo& args) { + if (args.Length() != 4 && args.Length() != 5) { + args.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + args.GetIsolate(), "Error: 4 or 5 args required.")); + return; + } + double x = args[0]->NumberValue(); + double y = args[1]->NumberValue(); + double radiusX = args[2]->NumberValue(); + double radiusY = args[3]->NumberValue(); + SkPath::Direction dir = SkPath::kCW_Direction; + if (args.Length() == 5 && !args[4]->BooleanValue()) { + dir = SkPath::kCCW_Direction; + } + Path2DBuilder* path = Unwrap(args); + SkRect rect = { + SkDoubleToScalar(x-radiusX), + SkDoubleToScalar(y-radiusX), + SkDoubleToScalar(x+radiusY), + SkDoubleToScalar(y+radiusY) + }; + + path->fSkPath.addOval(rect, dir); +} + +void Path2DBuilder::ConicTo(const v8::FunctionCallbackInfo& args) { + if (args.Length() != 5) { + args.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + args.GetIsolate(), "Error: 5 args required.")); + return; + } + double x1 = args[0]->NumberValue(); + double y1 = args[1]->NumberValue(); + double x2 = args[2]->NumberValue(); + double y2 = args[3]->NumberValue(); + double w = args[4]->NumberValue(); + Path2DBuilder* path = Unwrap(args); + + path->fSkPath.conicTo( + SkDoubleToScalar(x1), + SkDoubleToScalar(y1), + SkDoubleToScalar(x2), + SkDoubleToScalar(y2), + SkDoubleToScalar(w) + ); +} + +void Path2DBuilder::Finalize(const v8::FunctionCallbackInfo& args) { + Path2DBuilder* path = Unwrap(args); + + // Build Path2D from out fSkPath and return it. + SkPath* skPath = new SkPath(path->fSkPath); + + path->fSkPath.reset(); + + Path2D* pathWrap = new Path2D(skPath); + + args.GetReturnValue().Set(pathWrap->persistent()); +} diff --git a/experimental/SkV8Example/Path2DBuilder.h b/experimental/SkV8Example/Path2DBuilder.h new file mode 100644 index 0000000000..da9bddcb06 --- /dev/null +++ b/experimental/SkV8Example/Path2DBuilder.h @@ -0,0 +1,53 @@ +/* + * Copyright 2014 Google Inc. + * + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#ifndef SkV8Example_Path2DBuilder_DEFINED +#define SkV8Example_Path2DBuilder_DEFINED + +#include + +#include "SkPath.h" +#include "SkTypes.h" + +class Global; + +class Path2DBuilder : SkNoncopyable { +public: + Path2DBuilder() : fSkPath() {} + virtual ~Path2DBuilder() {} + + const SkPath& getSkPath() { return fSkPath; } + + // The JS Path2DBuilder constuctor implementation. + static void ConstructPath(const v8::FunctionCallbackInfo& args); + + // Add the Path2DBuilder JS constructor to the global context. + static void AddToGlobal(Global* global); + + // Path2DBuilder JS methods. + static void ClosePath(const v8::FunctionCallbackInfo& args); + static void MoveTo(const v8::FunctionCallbackInfo& args); + static void LineTo(const v8::FunctionCallbackInfo& args); + static void QuadraticCurveTo( + const v8::FunctionCallbackInfo& args); + static void BezierCurveTo(const v8::FunctionCallbackInfo& args); + static void Arc(const v8::FunctionCallbackInfo& args); + static void Rect(const v8::FunctionCallbackInfo& args); + static void Oval(const v8::FunctionCallbackInfo& args); + static void ConicTo(const v8::FunctionCallbackInfo& args); + static void Finalize(const v8::FunctionCallbackInfo& args); +private: + SkPath fSkPath; + + static Path2DBuilder* Unwrap(const v8::FunctionCallbackInfo& args); + + static Global* gGlobal; +}; + +#endif diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/SkV8Example.cpp index 84fe648c90..d537fd4d38 100644 --- a/experimental/SkV8Example/SkV8Example.cpp +++ b/experimental/SkV8Example/SkV8Example.cpp @@ -13,6 +13,7 @@ #include "Global.h" #include "JsContext.h" #include "Path2D.h" +#include "Path2DBuilder.h" #include "gl/GrGLUtil.h" #include "gl/GrGLDefines.h" @@ -129,6 +130,8 @@ void SkV8ExampleWindow::onSizeChange() { #endif } +Global* global = NULL; + void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { canvas->save(); @@ -164,6 +167,7 @@ void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { printf("Started\n"); + v8::V8::SetFlagsFromCommandLine(&argc, argv, true); SkCommandLineFlags::Parse(argc, argv); v8::V8::InitializeICU(); @@ -176,7 +180,7 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { v8::HandleScope handle_scope(isolate); isolate->Enter(); - Global* global = new Global(isolate); + global = new Global(isolate); // Set up things to look like a browser by creating @@ -210,6 +214,7 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { printf("Could not load file: %s.\n", FLAGS_infile[0]); exit(1); } + Path2DBuilder::AddToGlobal(global); Path2D::AddToGlobal(global); if (!global->parseScript(script)) { diff --git a/experimental/SkV8Example/js/sample.js b/experimental/SkV8Example/js/sample.js index 7e7e40a918..f04da337e2 100644 --- a/experimental/SkV8Example/js/sample.js +++ b/experimental/SkV8Example/js/sample.js @@ -2,23 +2,28 @@ * @fileoverview Sample onDraw script for use with SkV8Example. */ var onDraw = function(){ - var tick = 0; - var p = new Path2D(); - p.rect(0, 0, 200, 200); + var ticks = 0; + var b = new Path2DBuilder(); + b.rect(0, 0, 200, 200); + var p = b.finalize(); function f(context) { - tick += 0.1; + ticks += 1; context.translate(context.width/2, context.height/2); - context.rotate(tick); + context.rotate(ticks/10); context.drawPath(p); + + inval(); }; + + function onTimeout() { + console.log(ticks); + ticks = 0; + setTimeout(onTimeout, 1000); + } + setTimeout(onTimeout, 1000); + return f; }(); -function onTimeout() { - inval(); - print(setTimeout(onTimeout, 33)); -} - -setTimeout(onTimeout, 33); -- cgit v1.2.3