1e001da2558d936fca377e4041ca150ff95c85104jcgregorio/* 2e001da2558d936fca377e4041ca150ff95c85104jcgregorio * Copyright 2014 Google Inc. 3e001da2558d936fca377e4041ca150ff95c85104jcgregorio * 4e001da2558d936fca377e4041ca150ff95c85104jcgregorio * 5e001da2558d936fca377e4041ca150ff95c85104jcgregorio * Use of this source code is governed by a BSD-style license that can be 6e001da2558d936fca377e4041ca150ff95c85104jcgregorio * found in the LICENSE file. 7e001da2558d936fca377e4041ca150ff95c85104jcgregorio * 8e001da2558d936fca377e4041ca150ff95c85104jcgregorio */ 9e001da2558d936fca377e4041ca150ff95c85104jcgregorio 10e001da2558d936fca377e4041ca150ff95c85104jcgregorio#include "Global.h" 11e001da2558d936fca377e4041ca150ff95c85104jcgregorio#include "Path2DBuilder.h" 12e001da2558d936fca377e4041ca150ff95c85104jcgregorio#include "Path2D.h" 13e001da2558d936fca377e4041ca150ff95c85104jcgregorio#include "SkPath.h" 14e001da2558d936fca377e4041ca150ff95c85104jcgregorio 15e001da2558d936fca377e4041ca150ff95c85104jcgregorioGlobal* Path2DBuilder::gGlobal = NULL; 16e001da2558d936fca377e4041ca150ff95c85104jcgregorio 17e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::ConstructPath(const v8::FunctionCallbackInfo<v8::Value>& args) { 18e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::HandleScope handleScope(gGlobal->getIsolate()); 19e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = new Path2DBuilder(); 20e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.This()->SetInternalField( 21e001da2558d936fca377e4041ca150ff95c85104jcgregorio 0, v8::External::New(gGlobal->getIsolate(), path)); 22e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 23e001da2558d936fca377e4041ca150ff95c85104jcgregorio 24e001da2558d936fca377e4041ca150ff95c85104jcgregorio#define ADD_METHOD(name, fn) \ 25e001da2558d936fca377e4041ca150ff95c85104jcgregorio constructor->InstanceTemplate()->Set( \ 26e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( \ 27e001da2558d936fca377e4041ca150ff95c85104jcgregorio global->getIsolate(), name, \ 28e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::kInternalizedString), \ 29e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::FunctionTemplate::New(global->getIsolate(), fn)) 30e001da2558d936fca377e4041ca150ff95c85104jcgregorio 31e001da2558d936fca377e4041ca150ff95c85104jcgregorio// Install the constructor in the global scope so Path2DBuilders can be constructed 32e001da2558d936fca377e4041ca150ff95c85104jcgregorio// in JS. 33e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::AddToGlobal(Global* global) { 34e001da2558d936fca377e4041ca150ff95c85104jcgregorio gGlobal = global; 35e001da2558d936fca377e4041ca150ff95c85104jcgregorio 36e001da2558d936fca377e4041ca150ff95c85104jcgregorio // Create a stack-allocated handle scope. 37e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::HandleScope handleScope(gGlobal->getIsolate()); 38e001da2558d936fca377e4041ca150ff95c85104jcgregorio 39e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::Handle<v8::Context> context = gGlobal->getContext(); 40e001da2558d936fca377e4041ca150ff95c85104jcgregorio 41e001da2558d936fca377e4041ca150ff95c85104jcgregorio // Enter the scope so all operations take place in the scope. 42e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::Context::Scope contextScope(context); 43e001da2558d936fca377e4041ca150ff95c85104jcgregorio 44e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::Local<v8::FunctionTemplate> constructor = v8::FunctionTemplate::New( 45e001da2558d936fca377e4041ca150ff95c85104jcgregorio gGlobal->getIsolate(), Path2DBuilder::ConstructPath); 46e001da2558d936fca377e4041ca150ff95c85104jcgregorio constructor->InstanceTemplate()->SetInternalFieldCount(1); 47e001da2558d936fca377e4041ca150ff95c85104jcgregorio 48e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("close", ClosePath); 49e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("moveTo", MoveTo); 50e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("lineTo", LineTo); 51e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("quadraticCurveTo", QuadraticCurveTo); 52e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("bezierCurveTo", BezierCurveTo); 53e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("arc", Arc); 54e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("rect", Rect); 55e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("oval", Oval); 56e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("conicTo", ConicTo); 57e001da2558d936fca377e4041ca150ff95c85104jcgregorio 58e001da2558d936fca377e4041ca150ff95c85104jcgregorio ADD_METHOD("finalize", Finalize); 59e001da2558d936fca377e4041ca150ff95c85104jcgregorio 60e001da2558d936fca377e4041ca150ff95c85104jcgregorio context->Global()->Set(v8::String::NewFromUtf8( 61e001da2558d936fca377e4041ca150ff95c85104jcgregorio gGlobal->getIsolate(), "Path2DBuilder"), constructor->GetFunction()); 62e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 63e001da2558d936fca377e4041ca150ff95c85104jcgregorio 64e001da2558d936fca377e4041ca150ff95c85104jcgregorioPath2DBuilder* Path2DBuilder::Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args) { 65e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast( 66e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.This()->GetInternalField(0)); 67e001da2558d936fca377e4041ca150ff95c85104jcgregorio void* ptr = field->Value(); 68e001da2558d936fca377e4041ca150ff95c85104jcgregorio return static_cast<Path2DBuilder*>(ptr); 69e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 70e001da2558d936fca377e4041ca150ff95c85104jcgregorio 71e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::ClosePath(const v8::FunctionCallbackInfo<v8::Value>& args) { 72e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 73e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.close(); 74e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 75e001da2558d936fca377e4041ca150ff95c85104jcgregorio 76e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::MoveTo(const v8::FunctionCallbackInfo<v8::Value>& args) { 77e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 2) { 78e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 79e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 80e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 2 arguments required.")); 81e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 82e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 83e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[0]->NumberValue(); 84e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[1]->NumberValue(); 85e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 86e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); 87e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 88e001da2558d936fca377e4041ca150ff95c85104jcgregorio 89e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::LineTo(const v8::FunctionCallbackInfo<v8::Value>& args) { 90e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 2) { 91e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 92e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 93e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 2 arguments required.")); 94e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 95e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 96e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[0]->NumberValue(); 97e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[1]->NumberValue(); 98e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 99e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y)); 100e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 101e001da2558d936fca377e4041ca150ff95c85104jcgregorio 102e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::QuadraticCurveTo(const v8::FunctionCallbackInfo<v8::Value>& args) { 103e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 4) { 104e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 105e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 106e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 4 arguments required.")); 107e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 108e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 109e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cpx = args[0]->NumberValue(); 110e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cpy = args[1]->NumberValue(); 111e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[2]->NumberValue(); 112e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[3]->NumberValue(); 113e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 114e001da2558d936fca377e4041ca150ff95c85104jcgregorio // TODO(jcgregorio) Doesn't handle the empty last path case correctly per 115e001da2558d936fca377e4041ca150ff95c85104jcgregorio // the HTML 5 spec. 116e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.quadTo( 117e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(cpx), SkDoubleToScalar(cpy), 118e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x), SkDoubleToScalar(y)); 119e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 120e001da2558d936fca377e4041ca150ff95c85104jcgregorio 121e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::BezierCurveTo(const v8::FunctionCallbackInfo<v8::Value>& args) { 122e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 6) { 123e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 124e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 125e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 6 arguments required.")); 126e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 127e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 128e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cp1x = args[0]->NumberValue(); 129e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cp1y = args[1]->NumberValue(); 130e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cp2x = args[2]->NumberValue(); 131e001da2558d936fca377e4041ca150ff95c85104jcgregorio double cp2y = args[3]->NumberValue(); 132e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[4]->NumberValue(); 133e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[5]->NumberValue(); 134e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 135e001da2558d936fca377e4041ca150ff95c85104jcgregorio // TODO(jcgregorio) Doesn't handle the empty last path case correctly per 136e001da2558d936fca377e4041ca150ff95c85104jcgregorio // the HTML 5 spec. 137e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.cubicTo( 138e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(cp1x), SkDoubleToScalar(cp1y), 139e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(cp2x), SkDoubleToScalar(cp2y), 140e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x), SkDoubleToScalar(y)); 141e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 142e001da2558d936fca377e4041ca150ff95c85104jcgregorio 143e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::Arc(const v8::FunctionCallbackInfo<v8::Value>& args) { 144e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 5 && args.Length() != 6) { 145e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 146e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 147e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 5 or 6 args required.")); 148e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 149e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 150e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[0]->NumberValue(); 151e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[1]->NumberValue(); 152e001da2558d936fca377e4041ca150ff95c85104jcgregorio double radius = args[2]->NumberValue(); 153e001da2558d936fca377e4041ca150ff95c85104jcgregorio double startAngle = args[3]->NumberValue(); 154e001da2558d936fca377e4041ca150ff95c85104jcgregorio double endAngle = args[4]->NumberValue(); 155e001da2558d936fca377e4041ca150ff95c85104jcgregorio bool antiClockwise = false; 156e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() == 6) { 157e001da2558d936fca377e4041ca150ff95c85104jcgregorio antiClockwise = args[5]->BooleanValue(); 158e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 159e001da2558d936fca377e4041ca150ff95c85104jcgregorio double sweepAngle; 160e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (!antiClockwise) { 161e001da2558d936fca377e4041ca150ff95c85104jcgregorio sweepAngle = endAngle - startAngle; 162e001da2558d936fca377e4041ca150ff95c85104jcgregorio } else { 163e001da2558d936fca377e4041ca150ff95c85104jcgregorio sweepAngle = startAngle - endAngle; 164e001da2558d936fca377e4041ca150ff95c85104jcgregorio startAngle = endAngle; 165e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 166e001da2558d936fca377e4041ca150ff95c85104jcgregorio 167e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 168e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkRect rect = { 169e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x-radius), 170e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y-radius), 171e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x+radius), 172e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y+radius) 173e001da2558d936fca377e4041ca150ff95c85104jcgregorio }; 174e001da2558d936fca377e4041ca150ff95c85104jcgregorio 175e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.addArc(rect, SkRadiansToDegrees(startAngle), 176e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkRadiansToDegrees(sweepAngle)); 177e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 178e001da2558d936fca377e4041ca150ff95c85104jcgregorio 179e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::Rect(const v8::FunctionCallbackInfo<v8::Value>& args) { 180e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 4) { 181e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 182e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 183e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 4 arguments required.")); 184e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 185e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 186e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[0]->NumberValue(); 187e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[1]->NumberValue(); 188e001da2558d936fca377e4041ca150ff95c85104jcgregorio double w = args[2]->NumberValue(); 189e001da2558d936fca377e4041ca150ff95c85104jcgregorio double h = args[3]->NumberValue(); 190e001da2558d936fca377e4041ca150ff95c85104jcgregorio 191e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkRect rect = { 192e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x), 193e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y), 194e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x) + SkDoubleToScalar(w), 195e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y) + SkDoubleToScalar(h) 196e001da2558d936fca377e4041ca150ff95c85104jcgregorio }; 197e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 198e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.addRect(rect); 199e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 200e001da2558d936fca377e4041ca150ff95c85104jcgregorio 201e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::Oval(const v8::FunctionCallbackInfo<v8::Value>& args) { 202e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 4 && args.Length() != 5) { 203e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 204e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 205e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 4 or 5 args required.")); 206e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 207e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 208e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x = args[0]->NumberValue(); 209e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y = args[1]->NumberValue(); 210e001da2558d936fca377e4041ca150ff95c85104jcgregorio double radiusX = args[2]->NumberValue(); 211e001da2558d936fca377e4041ca150ff95c85104jcgregorio double radiusY = args[3]->NumberValue(); 212e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkPath::Direction dir = SkPath::kCW_Direction; 213e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() == 5 && !args[4]->BooleanValue()) { 214e001da2558d936fca377e4041ca150ff95c85104jcgregorio dir = SkPath::kCCW_Direction; 215e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 216e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 217e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkRect rect = { 218e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x-radiusX), 219e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y-radiusX), 220e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x+radiusY), 221e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y+radiusY) 222e001da2558d936fca377e4041ca150ff95c85104jcgregorio }; 223e001da2558d936fca377e4041ca150ff95c85104jcgregorio 224e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.addOval(rect, dir); 225e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 226e001da2558d936fca377e4041ca150ff95c85104jcgregorio 227e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::ConicTo(const v8::FunctionCallbackInfo<v8::Value>& args) { 228e001da2558d936fca377e4041ca150ff95c85104jcgregorio if (args.Length() != 5) { 229e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate()->ThrowException( 230e001da2558d936fca377e4041ca150ff95c85104jcgregorio v8::String::NewFromUtf8( 231e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetIsolate(), "Error: 5 args required.")); 232e001da2558d936fca377e4041ca150ff95c85104jcgregorio return; 233e001da2558d936fca377e4041ca150ff95c85104jcgregorio } 234e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x1 = args[0]->NumberValue(); 235e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y1 = args[1]->NumberValue(); 236e001da2558d936fca377e4041ca150ff95c85104jcgregorio double x2 = args[2]->NumberValue(); 237e001da2558d936fca377e4041ca150ff95c85104jcgregorio double y2 = args[3]->NumberValue(); 238e001da2558d936fca377e4041ca150ff95c85104jcgregorio double w = args[4]->NumberValue(); 239e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 240e001da2558d936fca377e4041ca150ff95c85104jcgregorio 241e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.conicTo( 242e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x1), 243e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y1), 244e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(x2), 245e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(y2), 246e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkDoubleToScalar(w) 247e001da2558d936fca377e4041ca150ff95c85104jcgregorio ); 248e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 249e001da2558d936fca377e4041ca150ff95c85104jcgregorio 250e001da2558d936fca377e4041ca150ff95c85104jcgregoriovoid Path2DBuilder::Finalize(const v8::FunctionCallbackInfo<v8::Value>& args) { 251e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2DBuilder* path = Unwrap(args); 252e001da2558d936fca377e4041ca150ff95c85104jcgregorio 253e001da2558d936fca377e4041ca150ff95c85104jcgregorio // Build Path2D from out fSkPath and return it. 254e001da2558d936fca377e4041ca150ff95c85104jcgregorio SkPath* skPath = new SkPath(path->fSkPath); 255e001da2558d936fca377e4041ca150ff95c85104jcgregorio 256e001da2558d936fca377e4041ca150ff95c85104jcgregorio path->fSkPath.reset(); 257e001da2558d936fca377e4041ca150ff95c85104jcgregorio 258e001da2558d936fca377e4041ca150ff95c85104jcgregorio Path2D* pathWrap = new Path2D(skPath); 259e001da2558d936fca377e4041ca150ff95c85104jcgregorio 260e001da2558d936fca377e4041ca150ff95c85104jcgregorio args.GetReturnValue().Set(pathWrap->persistent()); 261e001da2558d936fca377e4041ca150ff95c85104jcgregorio} 262