SkV8Sample: Now with Path2D and Path2DBuilder.
BUG=skia: Review URL: https://codereview.chromium.org/661033005
This commit is contained in:
parent
79f8faeea2
commit
e001da2558
@ -114,7 +114,7 @@ void DrawingMethods::DrawPath(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
fillStyle.setColor(SK_ColorBLACK);
|
||||
fillStyle.setAntiAlias(true);
|
||||
fillStyle.setStyle(SkPaint::kFill_Style);
|
||||
canvas->drawPath(path->getSkPath(), fillStyle);
|
||||
canvas->drawPath(*(path->path()), fillStyle);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,234 +11,45 @@
|
||||
#include "Global.h"
|
||||
|
||||
Global* Path2D::gGlobal = NULL;
|
||||
v8::Persistent<v8::ObjectTemplate> Path2D::gPath2DTemplate;
|
||||
|
||||
void Path2D::ConstructPath(const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Object, Path2D>& 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<v8::Context> context = gGlobal->getContext();
|
||||
// Just once create the ObjectTemplate for what Path2D looks like in JS.
|
||||
if (gPath2DTemplate.IsEmpty()) {
|
||||
v8::Local<v8::ObjectTemplate> localTemplate = v8::ObjectTemplate::New();
|
||||
|
||||
// Enter the scope so all operations take place in the scope.
|
||||
v8::Context::Scope contextScope(context);
|
||||
// Add a field to store the pointer to a SkPath pointer.
|
||||
localTemplate->SetInternalFieldCount(1);
|
||||
|
||||
v8::Local<v8::FunctionTemplate> constructor = v8::FunctionTemplate::New(
|
||||
gGlobal->getIsolate(), Path2D::ConstructPath);
|
||||
constructor->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
gPath2DTemplate.Reset(gGlobal->getIsolate(), localTemplate);
|
||||
}
|
||||
v8::Handle<v8::ObjectTemplate> templ =
|
||||
v8::Local<v8::ObjectTemplate>::New(gGlobal->getIsolate(), gPath2DTemplate);
|
||||
|
||||
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);
|
||||
// Create an empty Path2D wrapper.
|
||||
v8::Local<v8::Object> result = templ->NewInstance();
|
||||
|
||||
context->Global()->Set(v8::String::NewFromUtf8(
|
||||
gGlobal->getIsolate(), "Path2D"), constructor->GetFunction());
|
||||
// Store the SkPath pointer in the JavaScript wrapper.
|
||||
result->SetInternalField(0, v8::External::New(gGlobal->getIsolate(), this));
|
||||
gGlobal->getIsolate()->AdjustAmountOfExternalAllocatedMemory(sizeof(SkPath));
|
||||
|
||||
// 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<v8::Object> weak(gGlobal->getIsolate(), result);
|
||||
weak.SetWeak(this, weakPath2DCallback);
|
||||
this->handle_.Reset(gGlobal->getIsolate(), weak);
|
||||
}
|
||||
|
||||
Path2D* Path2D::Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(
|
||||
args.This()->GetInternalField(0));
|
||||
void* ptr = field->Value();
|
||||
return static_cast<Path2D*>(ptr);
|
||||
}
|
||||
|
||||
void Path2D::ClosePath(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Path2D* path = Unwrap(args);
|
||||
path->fSkPath.close();
|
||||
}
|
||||
|
||||
void Path2D::MoveTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
Path2D* path = Unwrap(args);
|
||||
path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
|
||||
}
|
||||
|
||||
void Path2D::LineTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
Path2D* path = Unwrap(args);
|
||||
path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
|
||||
}
|
||||
|
||||
void Path2D::QuadraticCurveTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
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));
|
||||
}
|
||||
|
||||
void Path2D::BezierCurveTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
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));
|
||||
}
|
||||
|
||||
void Path2D::Arc(const v8::FunctionCallbackInfo<v8::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 {
|
||||
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<v8::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)
|
||||
};
|
||||
Path2D* path = Unwrap(args);
|
||||
path->fSkPath.addRect(rect);
|
||||
}
|
||||
|
||||
void Path2D::Oval(const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Value>& 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));
|
||||
}
|
||||
|
@ -17,36 +17,35 @@
|
||||
|
||||
class Global;
|
||||
|
||||
// Path2D bridges between JS and SkPath.
|
||||
class Path2D : SkNoncopyable {
|
||||
public:
|
||||
Path2D() : fSkPath() {}
|
||||
virtual ~Path2D() {}
|
||||
Path2D(SkPath* path);
|
||||
virtual ~Path2D();
|
||||
|
||||
const SkPath& getSkPath() { return fSkPath; }
|
||||
static void AddToGlobal(Global* global) {
|
||||
gGlobal = global;
|
||||
}
|
||||
|
||||
// The JS Path2D constuctor implementation.
|
||||
static void ConstructPath(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
v8::Persistent<v8::Object>& persistent() {
|
||||
return handle_;
|
||||
}
|
||||
|
||||
// Add the Path2D JS constructor to the global context.
|
||||
static void AddToGlobal(Global* global);
|
||||
SkPath* path() {
|
||||
return path_;
|
||||
}
|
||||
|
||||
// Path2D JS methods.
|
||||
static void ClosePath(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void MoveTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void LineTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void QuadraticCurveTo(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void BezierCurveTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Arc(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Rect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Oval(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void ConicTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
private:
|
||||
SkPath fSkPath;
|
||||
// The handle to this object in JS space.
|
||||
v8::Persistent<v8::Object> handle_;
|
||||
|
||||
static Path2D* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& 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<v8::ObjectTemplate> gPath2DTemplate;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
261
experimental/SkV8Example/Path2DBuilder.cpp
Normal file
261
experimental/SkV8Example/Path2DBuilder.cpp
Normal file
@ -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<v8::Value>& 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<v8::Context> context = gGlobal->getContext();
|
||||
|
||||
// Enter the scope so all operations take place in the scope.
|
||||
v8::Context::Scope contextScope(context);
|
||||
|
||||
v8::Local<v8::FunctionTemplate> 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<v8::Value>& args) {
|
||||
v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(
|
||||
args.This()->GetInternalField(0));
|
||||
void* ptr = field->Value();
|
||||
return static_cast<Path2DBuilder*>(ptr);
|
||||
}
|
||||
|
||||
void Path2DBuilder::ClosePath(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
Path2DBuilder* path = Unwrap(args);
|
||||
path->fSkPath.close();
|
||||
}
|
||||
|
||||
void Path2DBuilder::MoveTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
Path2DBuilder* path = Unwrap(args);
|
||||
path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
|
||||
}
|
||||
|
||||
void Path2DBuilder::LineTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
Path2DBuilder* path = Unwrap(args);
|
||||
path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
|
||||
}
|
||||
|
||||
void Path2DBuilder::QuadraticCurveTo(const v8::FunctionCallbackInfo<v8::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();
|
||||
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<v8::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();
|
||||
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<v8::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 {
|
||||
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<v8::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)
|
||||
};
|
||||
Path2DBuilder* path = Unwrap(args);
|
||||
path->fSkPath.addRect(rect);
|
||||
}
|
||||
|
||||
void Path2DBuilder::Oval(const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Value>& 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<v8::Value>& 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());
|
||||
}
|
53
experimental/SkV8Example/Path2DBuilder.h
Normal file
53
experimental/SkV8Example/Path2DBuilder.h
Normal file
@ -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 <v8.h>
|
||||
|
||||
#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<v8::Value>& args);
|
||||
|
||||
// Add the Path2DBuilder JS constructor to the global context.
|
||||
static void AddToGlobal(Global* global);
|
||||
|
||||
// Path2DBuilder JS methods.
|
||||
static void ClosePath(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void MoveTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void LineTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void QuadraticCurveTo(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void BezierCurveTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Arc(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Rect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Oval(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void ConicTo(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
static void Finalize(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
private:
|
||||
SkPath fSkPath;
|
||||
|
||||
static Path2DBuilder* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
static Global* gGlobal;
|
||||
};
|
||||
|
||||
#endif
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -16,6 +16,8 @@
|
||||
'../experimental/SkV8Example/Global.h',
|
||||
'../experimental/SkV8Example/JsContext.cpp',
|
||||
'../experimental/SkV8Example/JsContext.h',
|
||||
'../experimental/SkV8Example/Path2DBuilder.cpp',
|
||||
'../experimental/SkV8Example/Path2DBuilder.h',
|
||||
'../experimental/SkV8Example/Path2D.cpp',
|
||||
'../experimental/SkV8Example/Path2D.h',
|
||||
'../experimental/SkV8Example/SkV8Example.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user