From d4d3b9c724768dd7799c610b7d496fbf48507ff3 Mon Sep 17 00:00:00 2001 From: Zach Bjornson Date: Thu, 10 Sep 2015 16:01:42 -0700 Subject: [PATCH] Update to NAN 2 and node 3+ APIs --- .travis.yml | 15 +- benchmarks/run.js | 105 ++-- package.json | 4 +- src/Canvas.cc | 258 +++++---- src/Canvas.h | 8 +- src/CanvasGradient.cc | 73 ++- src/CanvasGradient.h | 6 +- src/CanvasPattern.cc | 36 +- src/CanvasPattern.h | 6 +- src/CanvasRenderingContext2d.cc | 939 ++++++++++++++------------------ src/CanvasRenderingContext2d.h | 6 +- src/FontFace.cc | 38 +- src/FontFace.h | 6 +- src/Image.cc | 105 ++-- src/Image.h | 16 +- src/ImageData.cc | 70 +-- src/ImageData.h | 6 +- src/JPEGStream.h | 32 +- src/closure.h | 6 +- src/init.cc | 12 +- test/canvas.test.js | 18 + 21 files changed, 841 insertions(+), 924 deletions(-) diff --git a/.travis.yml b/.travis.yml index 72413b9..dd7671f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,20 @@ node_js: - "0.12" - "iojs-v1.8.4" - "iojs-v2.5.0" + - "iojs-v3.3.0" + - "4" +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.8 before_install: - - '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28' + - if [[ $TRAVIS_NODE_VERSION == 0.8 ]]; then npm install -g npm@1.4.28; fi + - if [[ $TRAVIS_OS_NAME == "linux" ]]; then export CXX=g++-4.8; fi + - $CXX --version - sudo chown -R $USER /usr/local - sh install + - npm explore npm -g -- npm install node-gyp@latest +after_script: + - make benchmark diff --git a/benchmarks/run.js b/benchmarks/run.js index a251a59..f19498c 100644 --- a/benchmarks/run.js +++ b/benchmarks/run.js @@ -1,6 +1,7 @@ - /** - * Module dependencies. + * Adaptive benchmarking. Starts with `initialTimes` iterations, increasing by + * a power of two each time until the benchmark takes at least `minDuration_ms` + * milliseconds to complete. */ var Canvas = require('../lib/canvas') @@ -8,34 +9,50 @@ var Canvas = require('../lib/canvas') , largeCanvas = new Canvas(1000, 1000) , ctx = canvas.getContext('2d'); -var times = 10000; -console.log('\n \x1b[33m%s\x1b[0m times\n', times); +var initialTimes = 10; +var minDuration_ms = 2000; -function bm(label, overrideTimes, fn) { - var start = new Date - , n = times; +var queue = [], running = false; - if ('function' == typeof overrideTimes) { - fn = overrideTimes; - } else { - n = overrideTimes; - label += ' (' + n + ' times)'; - } - - var pending = n; +function bm(label, fn) { + queue.push({label: label, fn: fn}); + next(); +} - function done(){ - var duration = (new Date - start) / 1000; - console.log(' - \x1b[33m%s\x1b[0m %ss', label, duration); +function next() { + if (queue.length && !running) { + run(queue.pop(), initialTimes, Date.now()); } +} - if (fn.length) { - while (n--) fn(function(){ - --pending || done(); +function run(benchmark, n, start) { + running = true; + var originalN = n; + var fn = benchmark.fn; + if (fn.length) { // async + var pending = n; + while (n--) fn(function () { + --pending || done(benchmark, originalN, start, true); }); } else { while (n--) fn(); - done(); + done(benchmark, originalN, start); + } +} + +function done(benchmark, times, start, async) { + var duration = Date.now() - start; + if (duration < minDuration_ms) { + run(benchmark, times * 2, Date.now()); + } else { + var opsSec = times / duration * 1000 + if (async) { + console.log(' - \x1b[33m%s\x1b[0m %s ops/sec (%s times, async)', benchmark.label, opsSec.toLocaleString(), times); + } else { + console.log(' - \x1b[33m%s\x1b[0m %s ops/sec (%s times)', benchmark.label, opsSec.toLocaleString(), times); + } + running = false; + next(); } } @@ -46,7 +63,7 @@ bm('lineTo()', function(){ }); bm('arc()', function(){ - ctx.arc(75,75,50,0,Math.PI*2,true); + ctx.arc(75,75,50,0,Math.PI*2,true); }); bm('fillStyle= hex', function(){ @@ -57,6 +74,8 @@ bm('fillStyle= rgba()', function(){ ctx.fillStyle = 'rgba(0,255,80,1)'; }); +// Apparently there's a bug in cairo by which the fillRect and strokeRect are +// slow only after a ton of arcs have been drawn. bm('fillRect()', function(){ ctx.fillRect(50, 50, 100, 100); }); @@ -73,19 +92,31 @@ bm('linear gradients', function(){ ctx.fillRect(10,10,130,130); }); -bm('toBuffer() 200x200', 50, function(){ +bm('toBuffer() 200x200', function(){ canvas.toBuffer(); }); -bm('toBuffer() 1000x1000', 50, function(){ +bm('toBuffer() 1000x1000', function(){ largeCanvas.toBuffer(); }); -bm('toBuffer().toString("base64") 200x200', 50, function(){ +bm('toBuffer() async 200x200', function(done){ + canvas.toBuffer(function (err, buf) { + done(); + }); +}); + +bm('toBuffer() async 1000x1000', function(done){ + largeCanvas.toBuffer(function (err, buf) { + done(); + }); +}); + +bm('toBuffer().toString("base64") 200x200', function(){ canvas.toBuffer().toString('base64'); }); -bm('toDataURL() 200x200', 50, function(){ +bm('toDataURL() 200x200', function(){ canvas.toDataURL(); }); @@ -109,14 +140,12 @@ bm('getImageData(0,0,100,100)', function(){ ctx.getImageData(0,0,100,100); }); -// bm('PNGStream 200x200', 50, function(done){ -// var stream = canvas.createSyncPNGStream(); -// stream.on('data', function(chunk){ -// // whatever -// }); -// stream.on('end', function(){ -// done(); -// }); -// }); - -console.log(); +bm('PNGStream 200x200', function(done){ + var stream = canvas.createSyncPNGStream(); + stream.on('data', function(chunk){ + // whatever + }); + stream.on('end', function(){ + done(); + }); +}); diff --git a/package.json b/package.json index d32c38d..9b41659 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test": "make test" }, "dependencies": { - "nan": "^1.8.4" + "nan": "^2.0.9" }, "devDependencies": { "body-parser": "^1.13.3", @@ -33,7 +33,7 @@ "mocha": "*" }, "engines": { - "node": ">=0.8.0 <3" + "node": ">=0.8.0" }, "main": "./lib/canvas.js", "license": "MIT" diff --git a/src/Canvas.cc b/src/Canvas.cc index bc670c4..7e77013 100644 --- a/src/Canvas.cc +++ b/src/Canvas.cc @@ -20,42 +20,42 @@ #include "JPEGStream.h" #endif -Persistent Canvas::constructor; +Nan::Persistent Canvas::constructor; /* * Initialize Canvas. */ void -Canvas::Initialize(Handle target) { - NanScope(); +Canvas::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(Canvas::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(Canvas::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("Canvas")); + ctor->SetClassName(Nan::New("Canvas").ToLocalChecked()); // Prototype Local proto = ctor->PrototypeTemplate(); - NODE_SET_PROTOTYPE_METHOD(ctor, "toBuffer", ToBuffer); - NODE_SET_PROTOTYPE_METHOD(ctor, "streamPNGSync", StreamPNGSync); + Nan::SetPrototypeMethod(ctor, "toBuffer", ToBuffer); + Nan::SetPrototypeMethod(ctor, "streamPNGSync", StreamPNGSync); #ifdef HAVE_JPEG - NODE_SET_PROTOTYPE_METHOD(ctor, "streamJPEGSync", StreamJPEGSync); + Nan::SetPrototypeMethod(ctor, "streamJPEGSync", StreamJPEGSync); #endif - proto->SetAccessor(NanNew("type"), GetType); - proto->SetAccessor(NanNew("width"), GetWidth, SetWidth); - proto->SetAccessor(NanNew("height"), GetHeight, SetHeight); - - NanSetTemplate(proto, "PNG_NO_FILTERS", NanNew(PNG_NO_FILTERS)); - NanSetTemplate(proto, "PNG_FILTER_NONE", NanNew(PNG_FILTER_NONE)); - NanSetTemplate(proto, "PNG_FILTER_SUB", NanNew(PNG_FILTER_SUB)); - NanSetTemplate(proto, "PNG_FILTER_UP", NanNew(PNG_FILTER_UP)); - NanSetTemplate(proto, "PNG_FILTER_AVG", NanNew(PNG_FILTER_AVG)); - NanSetTemplate(proto, "PNG_FILTER_PAETH", NanNew(PNG_FILTER_PAETH)); - NanSetTemplate(proto, "PNG_ALL_FILTERS", NanNew(PNG_ALL_FILTERS)); - - target->Set(NanNew("Canvas"), ctor->GetFunction()); + Nan::SetAccessor(proto, Nan::New("type").ToLocalChecked(), GetType); + Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth, SetWidth); + Nan::SetAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight, SetHeight); + + Nan::SetTemplate(proto, "PNG_NO_FILTERS", Nan::New(PNG_NO_FILTERS)); + Nan::SetTemplate(proto, "PNG_FILTER_NONE", Nan::New(PNG_FILTER_NONE)); + Nan::SetTemplate(proto, "PNG_FILTER_SUB", Nan::New(PNG_FILTER_SUB)); + Nan::SetTemplate(proto, "PNG_FILTER_UP", Nan::New(PNG_FILTER_UP)); + Nan::SetTemplate(proto, "PNG_FILTER_AVG", Nan::New(PNG_FILTER_AVG)); + Nan::SetTemplate(proto, "PNG_FILTER_PAETH", Nan::New(PNG_FILTER_PAETH)); + Nan::SetTemplate(proto, "PNG_ALL_FILTERS", Nan::New(PNG_ALL_FILTERS)); + + Nan::Set(target, Nan::New("Canvas").ToLocalChecked(), ctor->GetFunction()); } /* @@ -63,19 +63,18 @@ Canvas::Initialize(Handle target) { */ NAN_METHOD(Canvas::New) { - NanScope(); int width = 0, height = 0; canvas_type_t type = CANVAS_TYPE_IMAGE; - if (args[0]->IsNumber()) width = args[0]->Uint32Value(); - if (args[1]->IsNumber()) height = args[1]->Uint32Value(); - if (args[2]->IsString()) type = !strcmp("pdf", *String::Utf8Value(args[2])) + if (info[0]->IsNumber()) width = info[0]->Uint32Value(); + if (info[1]->IsNumber()) height = info[1]->Uint32Value(); + if (info[2]->IsString()) type = !strcmp("pdf", *String::Utf8Value(info[2])) ? CANVAS_TYPE_PDF - : !strcmp("svg", *String::Utf8Value(args[2])) + : !strcmp("svg", *String::Utf8Value(info[2])) ? CANVAS_TYPE_SVG : CANVAS_TYPE_IMAGE; Canvas *canvas = new Canvas(width, height, type); - canvas->Wrap(args.This()); - NanReturnValue(args.This()); + canvas->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); } /* @@ -83,9 +82,8 @@ NAN_METHOD(Canvas::New) { */ NAN_GETTER(Canvas::GetType) { - NanScope(); - Canvas *canvas = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(canvas->isPDF() ? "pdf" : canvas->isSVG() ? "svg" : "image")); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(canvas->isPDF() ? "pdf" : canvas->isSVG() ? "svg" : "image").ToLocalChecked()); } /* @@ -93,9 +91,8 @@ NAN_GETTER(Canvas::GetType) { */ NAN_GETTER(Canvas::GetWidth) { - NanScope(); - Canvas *canvas = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(canvas->width)); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(canvas->width)); } /* @@ -103,11 +100,10 @@ NAN_GETTER(Canvas::GetWidth) { */ NAN_SETTER(Canvas::SetWidth) { - NanScope(); if (value->IsNumber()) { - Canvas *canvas = ObjectWrap::Unwrap(args.This()); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); canvas->width = value->Uint32Value(); - canvas->resurface(args.This()); + canvas->resurface(info.This()); } } @@ -116,9 +112,8 @@ NAN_SETTER(Canvas::SetWidth) { */ NAN_GETTER(Canvas::GetHeight) { - NanScope(); - Canvas *canvas = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(canvas->height)); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(canvas->height)); } /* @@ -126,11 +121,10 @@ NAN_GETTER(Canvas::GetHeight) { */ NAN_SETTER(Canvas::SetHeight) { - NanScope(); if (value->IsNumber()) { - Canvas *canvas = ObjectWrap::Unwrap(args.This()); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); canvas->height = value->Uint32Value(); - canvas->resurface(args.This()); + canvas->resurface(info.This()); } } @@ -200,7 +194,7 @@ int Canvas::EIO_AfterToBuffer(eio_req *req) { #endif - NanScope(); + Nan::HandleScope scope; closure_t *closure = (closure_t *) req->data; #if NODE_VERSION_AT_LEAST(0, 6, 0) delete req; @@ -212,9 +206,9 @@ Canvas::EIO_AfterToBuffer(eio_req *req) { Local argv[1] = { Canvas::Error(closure->status) }; closure->pfn->Call(1, argv); } else { - Local buf = NanNewBufferHandle((char*)closure->data, closure->len); + Local buf = Nan::CopyBuffer((char*)closure->data, closure->len).ToLocalChecked(); memcpy(Buffer::Data(buf), closure->data, closure->len); - Local argv[2] = { NanNew(NanNull()), buf }; + Local argv[2] = { Nan::Null(), buf }; closure->pfn->Call(2, argv); } @@ -234,31 +228,31 @@ Canvas::EIO_AfterToBuffer(eio_req *req) { */ NAN_METHOD(Canvas::ToBuffer) { - NanScope(); cairo_status_t status; uint32_t compression_level = 6; uint32_t filter = PNG_ALL_FILTERS; - Canvas *canvas = ObjectWrap::Unwrap(args.This()); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); // TODO: async / move this out if (canvas->isPDF() || canvas->isSVG()) { cairo_surface_finish(canvas->surface()); closure_t *closure = (closure_t *) canvas->closure(); - Local buf = NanNewBufferHandle((char*) closure->data, closure->len); - NanReturnValue(buf); + Local buf = Nan::CopyBuffer((char*) closure->data, closure->len).ToLocalChecked(); + info.GetReturnValue().Set(buf); + return; } - if (args.Length() > 1 && !(args[1]->StrictEquals(NanUndefined()) && args[2]->StrictEquals(NanUndefined()))) { - if (!args[1]->StrictEquals(NanUndefined())) { + if (info.Length() > 1 && !(info[1]->IsUndefined() && info[2]->IsUndefined())) { + if (!info[1]->IsUndefined()) { bool good = true; - if (args[1]->IsNumber()) { - compression_level = args[1]->Uint32Value(); - } else if (args[1]->IsString()) { - if (args[1]->StrictEquals(NanNew("0"))) { + if (info[1]->IsNumber()) { + compression_level = info[1]->Uint32Value(); + } else if (info[1]->IsString()) { + if (info[1]->StrictEquals(Nan::New("0").ToLocalChecked())) { compression_level = 0; } else { - uint32_t tmp = args[1]->Uint32Value(); + uint32_t tmp = info[1]->Uint32Value(); if (tmp == 0) { good = false; } else { @@ -271,24 +265,24 @@ NAN_METHOD(Canvas::ToBuffer) { if (good) { if (compression_level > 9) { - return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); + return Nan::ThrowRangeError("Allowed compression levels lie in the range [0, 9]."); } } else { - return NanThrowTypeError("Compression level must be a number."); + return Nan::ThrowTypeError("Compression level must be a number."); } } - if (!args[2]->StrictEquals(NanUndefined())) { - if (args[2]->IsUint32()) { - filter = args[2]->Uint32Value(); + if (!info[2]->IsUndefined()) { + if (info[2]->IsUint32()) { + filter = info[2]->Uint32Value(); } else { - return NanThrowTypeError("Invalid filter value."); + return Nan::ThrowTypeError("Invalid filter value."); } } } // Async - if (args[0]->IsFunction()) { + if (info[0]->IsFunction()) { closure_t *closure = (closure_t *) malloc(sizeof(closure_t)); status = closure_init(closure, canvas, compression_level, filter); @@ -296,12 +290,12 @@ NAN_METHOD(Canvas::ToBuffer) { if (status) { closure_destroy(closure); free(closure); - return NanThrowError(Canvas::Error(status)); + return Nan::ThrowError(Canvas::Error(status)); } // TODO: only one callback fn in closure canvas->Ref(); - closure->pfn = new NanCallback(args[0].As()); + closure->pfn = new Nan::Callback(info[0].As()); #if NODE_VERSION_AT_LEAST(0, 6, 0) uv_work_t* req = new uv_work_t; @@ -312,7 +306,7 @@ NAN_METHOD(Canvas::ToBuffer) { ev_ref(EV_DEFAULT_UC); #endif - NanReturnUndefined(); + return; // Sync } else { closure_t closure; @@ -321,7 +315,7 @@ NAN_METHOD(Canvas::ToBuffer) { // ensure closure is ok if (status) { closure_destroy(&closure); - return NanThrowError(Canvas::Error(status)); + return Nan::ThrowError(Canvas::Error(status)); } TryCatch try_catch; @@ -329,14 +323,16 @@ NAN_METHOD(Canvas::ToBuffer) { if (try_catch.HasCaught()) { closure_destroy(&closure); - NanReturnValue(try_catch.ReThrow()); + try_catch.ReThrow(); + return; } else if (status) { closure_destroy(&closure); - return NanThrowError(Canvas::Error(status)); + return Nan::ThrowError(Canvas::Error(status)); } else { - Local buf = NanNewBufferHandle((char *)closure.data, closure.len); + Local buf = Nan::CopyBuffer((char *)closure.data, closure.len).ToLocalChecked(); closure_destroy(&closure); - NanReturnValue(buf); + info.GetReturnValue().Set(buf); + return; } } } @@ -347,14 +343,14 @@ NAN_METHOD(Canvas::ToBuffer) { static cairo_status_t streamPNG(void *c, const uint8_t *data, unsigned len) { - NanScope(); + Nan::HandleScope scope; closure_t *closure = (closure_t *) c; - Local buf = NanNewBufferHandle((char *)data, len); + Local buf = Nan::CopyBuffer((char *)data, len).ToLocalChecked(); Local argv[3] = { - NanNew(NanNull()) + Nan::Null() , buf - , NanNew(len) }; - NanMakeCallback(NanGetCurrentContext()->Global(), closure->fn, 3, argv); + , Nan::New(len) }; + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)closure->fn, 3, argv); return CAIRO_STATUS_SUCCESS; } @@ -363,23 +359,22 @@ streamPNG(void *c, const uint8_t *data, unsigned len) { */ NAN_METHOD(Canvas::StreamPNGSync) { - NanScope(); uint32_t compression_level = 6; uint32_t filter = PNG_ALL_FILTERS; // TODO: async as well - if (!args[0]->IsFunction()) - return NanThrowTypeError("callback function required"); + if (!info[0]->IsFunction()) + return Nan::ThrowTypeError("callback function required"); - if (args.Length() > 1 && !(args[1]->StrictEquals(NanUndefined()) && args[2]->StrictEquals(NanUndefined()))) { - if (!args[1]->StrictEquals(NanUndefined())) { + if (info.Length() > 1 && !(info[1]->IsUndefined() && info[2]->IsUndefined())) { + if (!info[1]->IsUndefined()) { bool good = true; - if (args[1]->IsNumber()) { - compression_level = args[1]->Uint32Value(); - } else if (args[1]->IsString()) { - if (args[1]->StrictEquals(NanNew("0"))) { + if (info[1]->IsNumber()) { + compression_level = info[1]->Uint32Value(); + } else if (info[1]->IsString()) { + if (info[1]->StrictEquals(Nan::New("0").ToLocalChecked())) { compression_level = 0; } else { - uint32_t tmp = args[1]->Uint32Value(); + uint32_t tmp = info[1]->Uint32Value(); if (tmp == 0) { good = false; } else { @@ -392,26 +387,26 @@ NAN_METHOD(Canvas::StreamPNGSync) { if (good) { if (compression_level > 9) { - return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); + return Nan::ThrowRangeError("Allowed compression levels lie in the range [0, 9]."); } } else { - return NanThrowTypeError("Compression level must be a number."); + return Nan::ThrowTypeError("Compression level must be a number."); } } - if (!args[2]->StrictEquals(NanUndefined())) { - if (args[2]->IsUint32()) { - filter = args[2]->Uint32Value(); + if (!info[2]->IsUndefined()) { + if (info[2]->IsUint32()) { + filter = info[2]->Uint32Value(); } else { - return NanThrowTypeError("Invalid filter value."); + return Nan::ThrowTypeError("Invalid filter value."); } } } - Canvas *canvas = ObjectWrap::Unwrap(args.This()); + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); closure_t closure; - closure.fn = Handle::Cast(args[0]); + closure.fn = Local::Cast(info[0]); closure.compression_level = compression_level; closure.filter = filter; @@ -420,18 +415,19 @@ NAN_METHOD(Canvas::StreamPNGSync) { cairo_status_t status = canvas_write_to_png_stream(canvas->surface(), streamPNG, &closure); if (try_catch.HasCaught()) { - NanReturnValue(try_catch.ReThrow()); + try_catch.ReThrow(); + return; } else if (status) { Local argv[1] = { Canvas::Error(status) }; - NanMakeCallback(NanGetCurrentContext()->Global(), closure.fn, 1, argv); + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)closure.fn, 1, argv); } else { Local argv[3] = { - NanNew(NanNull()) - , NanNew(NanNull()) - , NanNew(0) }; - NanMakeCallback(NanGetCurrentContext()->Global(), closure.fn, 1, argv); + Nan::Null() + , Nan::Null() + , Nan::New(0) }; + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)closure.fn, 1, argv); } - NanReturnUndefined(); + return; } /* @@ -441,27 +437,27 @@ NAN_METHOD(Canvas::StreamPNGSync) { #ifdef HAVE_JPEG NAN_METHOD(Canvas::StreamJPEGSync) { - NanScope(); // TODO: async as well - if (!args[0]->IsNumber()) - return NanThrowTypeError("buffer size required"); - if (!args[1]->IsNumber()) - return NanThrowTypeError("quality setting required"); - if (!args[2]->IsBoolean()) - return NanThrowTypeError("progressive setting required"); - if (!args[3]->IsFunction()) - return NanThrowTypeError("callback function required"); - - Canvas *canvas = ObjectWrap::Unwrap(args.This()); + if (!info[0]->IsNumber()) + return Nan::ThrowTypeError("buffer size required"); + if (!info[1]->IsNumber()) + return Nan::ThrowTypeError("quality setting required"); + if (!info[2]->IsBoolean()) + return Nan::ThrowTypeError("progressive setting required"); + if (!info[3]->IsFunction()) + return Nan::ThrowTypeError("callback function required"); + + Canvas *canvas = Nan::ObjectWrap::Unwrap(info.This()); closure_t closure; - closure.fn = Handle::Cast(args[3]); + closure.fn = Local::Cast(info[3]); TryCatch try_catch; - write_to_jpeg_stream(canvas->surface(), args[0]->NumberValue(), args[1]->NumberValue(), args[2]->BooleanValue(), &closure); + write_to_jpeg_stream(canvas->surface(), info[0]->NumberValue(), info[1]->NumberValue(), info[2]->BooleanValue(), &closure); - if (try_catch.HasCaught()) - NanReturnValue(try_catch.ReThrow()); - NanReturnUndefined(); + if (try_catch.HasCaught()) { + try_catch.ReThrow(); + } + return; } #endif @@ -470,7 +466,7 @@ NAN_METHOD(Canvas::StreamJPEGSync) { * Initialize cairo surface. */ -Canvas::Canvas(int w, int h, canvas_type_t t): ObjectWrap() { +Canvas::Canvas(int w, int h, canvas_type_t t): Nan::ObjectWrap() { type = t; width = w; height = h; @@ -492,7 +488,7 @@ Canvas::Canvas(int w, int h, canvas_type_t t): ObjectWrap() { } else { _surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); assert(_surface); - NanAdjustExternalMemory(4 * w * h); + Nan::AdjustExternalMemory(4 * w * h); } } @@ -511,7 +507,7 @@ Canvas::~Canvas() { break; case CANVAS_TYPE_IMAGE: cairo_surface_destroy(_surface); - NanAdjustExternalMemory(-4 * width * height); + Nan::AdjustExternalMemory(-4 * width * height); break; } } @@ -521,9 +517,9 @@ Canvas::~Canvas() { */ void -Canvas::resurface(Handle canvas) { - NanScope(); - Handle context; +Canvas::resurface(Local canvas) { + Nan::HandleScope scope; + Local context; switch (type) { case CANVAS_TYPE_PDF: cairo_pdf_surface_set_size(_surface, width, height); @@ -537,9 +533,9 @@ Canvas::resurface(Handle canvas) { _surface = cairo_svg_surface_create_for_stream(toBuffer, _closure, width, height); // Reset context - context = canvas->Get(NanNew("context")); + context = canvas->Get(Nan::New("context").ToLocalChecked()); if (!context->IsUndefined()) { - Context2d *context2d = ObjectWrap::Unwrap(context->ToObject()); + Context2d *context2d = Nan::ObjectWrap::Unwrap(context->ToObject()); cairo_t *prev = context2d->context(); context2d->setContext(cairo_create(surface())); cairo_destroy(prev); @@ -551,12 +547,12 @@ Canvas::resurface(Handle canvas) { int old_height = cairo_image_surface_get_height(_surface); cairo_surface_destroy(_surface); _surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - NanAdjustExternalMemory(4 * (width * height - old_width * old_height)); + Nan::AdjustExternalMemory(4 * (width * height - old_width * old_height)); // Reset context - context = canvas->Get(NanNew("context")); + context = canvas->Get(Nan::New("context").ToLocalChecked()); if (!context->IsUndefined()) { - Context2d *context2d = ObjectWrap::Unwrap(context->ToObject()); + Context2d *context2d = Nan::ObjectWrap::Unwrap(context->ToObject()); cairo_t *prev = context2d->context(); context2d->setContext(cairo_create(surface())); cairo_destroy(prev); @@ -571,5 +567,5 @@ Canvas::resurface(Handle canvas) { Local Canvas::Error(cairo_status_t status) { - return Exception::Error(NanNew(cairo_status_to_string(status))); + return Exception::Error(Nan::New(cairo_status_to_string(status)).ToLocalChecked()); } diff --git a/src/Canvas.h b/src/Canvas.h index 22904d3..bf58b9b 100644 --- a/src/Canvas.h +++ b/src/Canvas.h @@ -47,13 +47,13 @@ typedef enum { * Canvas. */ -class Canvas: public node::ObjectWrap { +class Canvas: public Nan::ObjectWrap { public: int width; int height; canvas_type_t type; - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); static NAN_METHOD(ToBuffer); static NAN_GETTER(GetType); @@ -85,7 +85,7 @@ class Canvas: public node::ObjectWrap { inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } inline int stride(){ return cairo_image_surface_get_stride(_surface); } Canvas(int width, int height, canvas_type_t type); - void resurface(Handle canvas); + void resurface(Local canvas); private: ~Canvas(); diff --git a/src/CanvasGradient.cc b/src/CanvasGradient.cc index 9e41c58..2b4f4e4 100644 --- a/src/CanvasGradient.cc +++ b/src/CanvasGradient.cc @@ -9,25 +9,25 @@ #include "Canvas.h" #include "CanvasGradient.h" -Persistent Gradient::constructor; +Nan::Persistent Gradient::constructor; /* * Initialize CanvasGradient. */ void -Gradient::Initialize(Handle target) { - NanScope(); +Gradient::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(Gradient::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(Gradient::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("CanvasGradient")); + ctor->SetClassName(Nan::New("CanvasGradient").ToLocalChecked()); // Prototype - NODE_SET_PROTOTYPE_METHOD(ctor, "addColorStop", AddColorStop); - target->Set(NanNew("CanvasGradient"), ctor->GetFunction()); + Nan::SetPrototypeMethod(ctor, "addColorStop", AddColorStop); + Nan::Set(target, Nan::New("CanvasGradient").ToLocalChecked(), ctor->GetFunction()); } /* @@ -35,33 +35,33 @@ Gradient::Initialize(Handle target) { */ NAN_METHOD(Gradient::New) { - NanScope(); - // Linear - if (4 == args.Length()) { + if (4 == info.Length()) { Gradient *grad = new Gradient( - args[0]->NumberValue() - , args[1]->NumberValue() - , args[2]->NumberValue() - , args[3]->NumberValue()); - grad->Wrap(args.This()); - NanReturnValue(args.This()); + info[0]->NumberValue() + , info[1]->NumberValue() + , info[2]->NumberValue() + , info[3]->NumberValue()); + grad->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + return; } // Radial - if (6 == args.Length()) { + if (6 == info.Length()) { Gradient *grad = new Gradient( - args[0]->NumberValue() - , args[1]->NumberValue() - , args[2]->NumberValue() - , args[3]->NumberValue() - , args[4]->NumberValue() - , args[5]->NumberValue()); - grad->Wrap(args.This()); - NanReturnValue(args.This()); + info[0]->NumberValue() + , info[1]->NumberValue() + , info[2]->NumberValue() + , info[3]->NumberValue() + , info[4]->NumberValue() + , info[5]->NumberValue()); + grad->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + return; } - return NanThrowTypeError("invalid arguments"); + return Nan::ThrowTypeError("invalid arguments"); } /* @@ -69,31 +69,28 @@ NAN_METHOD(Gradient::New) { */ NAN_METHOD(Gradient::AddColorStop) { - NanScope(); - if (!args[0]->IsNumber()) - return NanThrowTypeError("offset required"); - if (!args[1]->IsString()) - return NanThrowTypeError("color string required"); + if (!info[0]->IsNumber()) + return Nan::ThrowTypeError("offset required"); + if (!info[1]->IsString()) + return Nan::ThrowTypeError("color string required"); - Gradient *grad = ObjectWrap::Unwrap(args.This()); + Gradient *grad = Nan::ObjectWrap::Unwrap(info.This()); short ok; - String::Utf8Value str(args[1]); + String::Utf8Value str(info[1]); uint32_t rgba = rgba_from_string(*str, &ok); if (ok) { rgba_t color = rgba_create(rgba); cairo_pattern_add_color_stop_rgba( grad->pattern() - , args[0]->NumberValue() + , info[0]->NumberValue() , color.r , color.g , color.b , color.a); } else { - return NanThrowTypeError("parse color failed"); + return Nan::ThrowTypeError("parse color failed"); } - - NanReturnUndefined(); } /* diff --git a/src/CanvasGradient.h b/src/CanvasGradient.h index bcc531a..2459eb6 100644 --- a/src/CanvasGradient.h +++ b/src/CanvasGradient.h @@ -10,10 +10,10 @@ #include "Canvas.h" -class Gradient: public node::ObjectWrap { +class Gradient: public Nan::ObjectWrap { public: - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); static NAN_METHOD(AddColorStop); Gradient(double x0, double y0, double x1, double y1); diff --git a/src/CanvasPattern.cc b/src/CanvasPattern.cc index 38c86d7..1e1be3d 100644 --- a/src/CanvasPattern.cc +++ b/src/CanvasPattern.cc @@ -9,27 +9,27 @@ #include "Image.h" #include "CanvasPattern.h" -Persistent Pattern::constructor; +Nan::Persistent Pattern::constructor; /* * Initialize CanvasPattern. */ void -Pattern::Initialize(Handle target) { - NanScope(); +Pattern::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(Pattern::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(Pattern::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("CanvasPattern")); + ctor->SetClassName(Nan::New("CanvasPattern").ToLocalChecked()); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("CanvasPattern")); + ctor->SetClassName(Nan::New("CanvasPattern").ToLocalChecked()); // Prototype - target->Set(NanNew("CanvasPattern"), ctor->GetFunction()); + Nan::Set(target, Nan::New("CanvasPattern").ToLocalChecked(), ctor->GetFunction()); } /* @@ -37,39 +37,37 @@ Pattern::Initialize(Handle target) { */ NAN_METHOD(Pattern::New) { - NanScope(); - int w = 0 , h = 0; cairo_surface_t *surface; - Local obj = args[0]->ToObject(); + Local obj = info[0]->ToObject(); // Image - if (NanHasInstance(Image::constructor, obj)) { - Image *img = ObjectWrap::Unwrap(obj); + if (Nan::New(Image::constructor)->HasInstance(obj)) { + Image *img = Nan::ObjectWrap::Unwrap(obj); if (!img->isComplete()) { - return NanThrowError("Image given has not completed loading"); + return Nan::ThrowError("Image given has not completed loading"); } w = img->width; h = img->height; surface = img->surface(); // Canvas - } else if (NanHasInstance(Canvas::constructor, obj)) { - Canvas *canvas = ObjectWrap::Unwrap(obj); + } else if (Nan::New(Canvas::constructor)->HasInstance(obj)) { + Canvas *canvas = Nan::ObjectWrap::Unwrap(obj); w = canvas->width; h = canvas->height; surface = canvas->surface(); // Invalid } else { - return NanThrowTypeError("Image or Canvas expected"); + return Nan::ThrowTypeError("Image or Canvas expected"); } Pattern *pattern = new Pattern(surface,w,h); - pattern->Wrap(args.This()); - NanReturnValue(args.This()); + pattern->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); } diff --git a/src/CanvasPattern.h b/src/CanvasPattern.h index ea3faeb..ffdbba6 100644 --- a/src/CanvasPattern.h +++ b/src/CanvasPattern.h @@ -10,10 +10,10 @@ #include "Canvas.h" -class Pattern: public node::ObjectWrap { +class Pattern: public Nan::ObjectWrap { public: - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); Pattern(cairo_surface_t *surface, int w, int h); inline cairo_pattern_t *pattern(){ return _pattern; } diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index c2666c8..5736ef4 100755 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -34,21 +34,21 @@ #define isinf(x) std::isinf(x) #endif -Persistent Context2d::constructor; +Nan::Persistent Context2d::constructor; /* * Rectangle arg assertions. */ #define RECT_ARGS \ - if (!args[0]->IsNumber() \ - ||!args[1]->IsNumber() \ - ||!args[2]->IsNumber() \ - ||!args[3]->IsNumber()) NanReturnUndefined(); \ - double x = args[0]->NumberValue(); \ - double y = args[1]->NumberValue(); \ - double width = args[2]->NumberValue(); \ - double height = args[3]->NumberValue(); + if (!info[0]->IsNumber() \ + ||!info[1]->IsNumber() \ + ||!info[2]->IsNumber() \ + ||!info[3]->IsNumber()) return; \ + double x = info[0]->NumberValue(); \ + double y = info[1]->NumberValue(); \ + double width = info[2]->NumberValue(); \ + double height = info[3]->NumberValue(); /* * Text baselines. @@ -91,77 +91,77 @@ void state_assign_fontFamily(canvas_state_t *state, const char *str) { */ void -Context2d::Initialize(Handle target) { - NanScope(); +Context2d::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(Context2d::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(Context2d::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("CanvasRenderingContext2d")); + ctor->SetClassName(Nan::New("CanvasRenderingContext2d").ToLocalChecked()); // Prototype Local proto = ctor->PrototypeTemplate(); - NODE_SET_PROTOTYPE_METHOD(ctor, "drawImage", DrawImage); - NODE_SET_PROTOTYPE_METHOD(ctor, "putImageData", PutImageData); - NODE_SET_PROTOTYPE_METHOD(ctor, "getImageData", GetImageData); - NODE_SET_PROTOTYPE_METHOD(ctor, "addPage", AddPage); - NODE_SET_PROTOTYPE_METHOD(ctor, "save", Save); - NODE_SET_PROTOTYPE_METHOD(ctor, "restore", Restore); - NODE_SET_PROTOTYPE_METHOD(ctor, "rotate", Rotate); - NODE_SET_PROTOTYPE_METHOD(ctor, "translate", Translate); - NODE_SET_PROTOTYPE_METHOD(ctor, "transform", Transform); - NODE_SET_PROTOTYPE_METHOD(ctor, "resetTransform", ResetTransform); - NODE_SET_PROTOTYPE_METHOD(ctor, "isPointInPath", IsPointInPath); - NODE_SET_PROTOTYPE_METHOD(ctor, "scale", Scale); - NODE_SET_PROTOTYPE_METHOD(ctor, "clip", Clip); - NODE_SET_PROTOTYPE_METHOD(ctor, "fill", Fill); - NODE_SET_PROTOTYPE_METHOD(ctor, "stroke", Stroke); - NODE_SET_PROTOTYPE_METHOD(ctor, "fillText", FillText); - NODE_SET_PROTOTYPE_METHOD(ctor, "strokeText", StrokeText); - NODE_SET_PROTOTYPE_METHOD(ctor, "fillRect", FillRect); - NODE_SET_PROTOTYPE_METHOD(ctor, "strokeRect", StrokeRect); - NODE_SET_PROTOTYPE_METHOD(ctor, "clearRect", ClearRect); - NODE_SET_PROTOTYPE_METHOD(ctor, "rect", Rect); - NODE_SET_PROTOTYPE_METHOD(ctor, "measureText", MeasureText); - NODE_SET_PROTOTYPE_METHOD(ctor, "moveTo", MoveTo); - NODE_SET_PROTOTYPE_METHOD(ctor, "lineTo", LineTo); - NODE_SET_PROTOTYPE_METHOD(ctor, "bezierCurveTo", BezierCurveTo); - NODE_SET_PROTOTYPE_METHOD(ctor, "quadraticCurveTo", QuadraticCurveTo); - NODE_SET_PROTOTYPE_METHOD(ctor, "beginPath", BeginPath); - NODE_SET_PROTOTYPE_METHOD(ctor, "closePath", ClosePath); - NODE_SET_PROTOTYPE_METHOD(ctor, "arc", Arc); - NODE_SET_PROTOTYPE_METHOD(ctor, "arcTo", ArcTo); - NODE_SET_PROTOTYPE_METHOD(ctor, "setLineDash", SetLineDash); - NODE_SET_PROTOTYPE_METHOD(ctor, "getLineDash", GetLineDash); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setFont", SetFont); + Nan::SetPrototypeMethod(ctor, "drawImage", DrawImage); + Nan::SetPrototypeMethod(ctor, "putImageData", PutImageData); + Nan::SetPrototypeMethod(ctor, "getImageData", GetImageData); + Nan::SetPrototypeMethod(ctor, "addPage", AddPage); + Nan::SetPrototypeMethod(ctor, "save", Save); + Nan::SetPrototypeMethod(ctor, "restore", Restore); + Nan::SetPrototypeMethod(ctor, "rotate", Rotate); + Nan::SetPrototypeMethod(ctor, "translate", Translate); + Nan::SetPrototypeMethod(ctor, "transform", Transform); + Nan::SetPrototypeMethod(ctor, "resetTransform", ResetTransform); + Nan::SetPrototypeMethod(ctor, "isPointInPath", IsPointInPath); + Nan::SetPrototypeMethod(ctor, "scale", Scale); + Nan::SetPrototypeMethod(ctor, "clip", Clip); + Nan::SetPrototypeMethod(ctor, "fill", Fill); + Nan::SetPrototypeMethod(ctor, "stroke", Stroke); + Nan::SetPrototypeMethod(ctor, "fillText", FillText); + Nan::SetPrototypeMethod(ctor, "strokeText", StrokeText); + Nan::SetPrototypeMethod(ctor, "fillRect", FillRect); + Nan::SetPrototypeMethod(ctor, "strokeRect", StrokeRect); + Nan::SetPrototypeMethod(ctor, "clearRect", ClearRect); + Nan::SetPrototypeMethod(ctor, "rect", Rect); + Nan::SetPrototypeMethod(ctor, "measureText", MeasureText); + Nan::SetPrototypeMethod(ctor, "moveTo", MoveTo); + Nan::SetPrototypeMethod(ctor, "lineTo", LineTo); + Nan::SetPrototypeMethod(ctor, "bezierCurveTo", BezierCurveTo); + Nan::SetPrototypeMethod(ctor, "quadraticCurveTo", QuadraticCurveTo); + Nan::SetPrototypeMethod(ctor, "beginPath", BeginPath); + Nan::SetPrototypeMethod(ctor, "closePath", ClosePath); + Nan::SetPrototypeMethod(ctor, "arc", Arc); + Nan::SetPrototypeMethod(ctor, "arcTo", ArcTo); + Nan::SetPrototypeMethod(ctor, "setLineDash", SetLineDash); + Nan::SetPrototypeMethod(ctor, "getLineDash", GetLineDash); + Nan::SetPrototypeMethod(ctor, "_setFont", SetFont); #ifdef HAVE_FREETYPE - NODE_SET_PROTOTYPE_METHOD(ctor, "_setFontFace", SetFontFace); + Nan::SetPrototypeMethod(ctor, "_setFontFace", SetFontFace); #endif - NODE_SET_PROTOTYPE_METHOD(ctor, "_setFillColor", SetFillColor); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setStrokeColor", SetStrokeColor); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setFillPattern", SetFillPattern); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setStrokePattern", SetStrokePattern); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setTextBaseline", SetTextBaseline); - NODE_SET_PROTOTYPE_METHOD(ctor, "_setTextAlignment", SetTextAlignment); - proto->SetAccessor(NanNew("patternQuality"), GetPatternQuality, SetPatternQuality); - proto->SetAccessor(NanNew("globalCompositeOperation"), GetGlobalCompositeOperation, SetGlobalCompositeOperation); - proto->SetAccessor(NanNew("globalAlpha"), GetGlobalAlpha, SetGlobalAlpha); - proto->SetAccessor(NanNew("shadowColor"), GetShadowColor, SetShadowColor); - proto->SetAccessor(NanNew("fillColor"), GetFillColor); - proto->SetAccessor(NanNew("strokeColor"), GetStrokeColor); - proto->SetAccessor(NanNew("miterLimit"), GetMiterLimit, SetMiterLimit); - proto->SetAccessor(NanNew("lineWidth"), GetLineWidth, SetLineWidth); - proto->SetAccessor(NanNew("lineCap"), GetLineCap, SetLineCap); - proto->SetAccessor(NanNew("lineJoin"), GetLineJoin, SetLineJoin); - proto->SetAccessor(NanNew("lineDashOffset"), GetLineDashOffset, SetLineDashOffset); - proto->SetAccessor(NanNew("shadowOffsetX"), GetShadowOffsetX, SetShadowOffsetX); - proto->SetAccessor(NanNew("shadowOffsetY"), GetShadowOffsetY, SetShadowOffsetY); - proto->SetAccessor(NanNew("shadowBlur"), GetShadowBlur, SetShadowBlur); - proto->SetAccessor(NanNew("antialias"), GetAntiAlias, SetAntiAlias); - proto->SetAccessor(NanNew("textDrawingMode"), GetTextDrawingMode, SetTextDrawingMode); - proto->SetAccessor(NanNew("filter"), GetFilter, SetFilter); - target->Set(NanNew("CanvasRenderingContext2d"), ctor->GetFunction()); + Nan::SetPrototypeMethod(ctor, "_setFillColor", SetFillColor); + Nan::SetPrototypeMethod(ctor, "_setStrokeColor", SetStrokeColor); + Nan::SetPrototypeMethod(ctor, "_setFillPattern", SetFillPattern); + Nan::SetPrototypeMethod(ctor, "_setStrokePattern", SetStrokePattern); + Nan::SetPrototypeMethod(ctor, "_setTextBaseline", SetTextBaseline); + Nan::SetPrototypeMethod(ctor, "_setTextAlignment", SetTextAlignment); + Nan::SetAccessor(proto, Nan::New("patternQuality").ToLocalChecked(), GetPatternQuality, SetPatternQuality); + Nan::SetAccessor(proto, Nan::New("globalCompositeOperation").ToLocalChecked(), GetGlobalCompositeOperation, SetGlobalCompositeOperation); + Nan::SetAccessor(proto, Nan::New("globalAlpha").ToLocalChecked(), GetGlobalAlpha, SetGlobalAlpha); + Nan::SetAccessor(proto, Nan::New("shadowColor").ToLocalChecked(), GetShadowColor, SetShadowColor); + Nan::SetAccessor(proto, Nan::New("fillColor").ToLocalChecked(), GetFillColor); + Nan::SetAccessor(proto, Nan::New("strokeColor").ToLocalChecked(), GetStrokeColor); + Nan::SetAccessor(proto, Nan::New("miterLimit").ToLocalChecked(), GetMiterLimit, SetMiterLimit); + Nan::SetAccessor(proto, Nan::New("lineWidth").ToLocalChecked(), GetLineWidth, SetLineWidth); + Nan::SetAccessor(proto, Nan::New("lineCap").ToLocalChecked(), GetLineCap, SetLineCap); + Nan::SetAccessor(proto, Nan::New("lineJoin").ToLocalChecked(), GetLineJoin, SetLineJoin); + Nan::SetAccessor(proto, Nan::New("lineDashOffset").ToLocalChecked(), GetLineDashOffset, SetLineDashOffset); + Nan::SetAccessor(proto, Nan::New("shadowOffsetX").ToLocalChecked(), GetShadowOffsetX, SetShadowOffsetX); + Nan::SetAccessor(proto, Nan::New("shadowOffsetY").ToLocalChecked(), GetShadowOffsetY, SetShadowOffsetY); + Nan::SetAccessor(proto, Nan::New("shadowBlur").ToLocalChecked(), GetShadowBlur, SetShadowBlur); + Nan::SetAccessor(proto, Nan::New("antialias").ToLocalChecked(), GetAntiAlias, SetAntiAlias); + Nan::SetAccessor(proto, Nan::New("textDrawingMode").ToLocalChecked(), GetTextDrawingMode, SetTextDrawingMode); + Nan::SetAccessor(proto, Nan::New("filter").ToLocalChecked(), GetFilter, SetFilter); + Nan::Set(target, Nan::New("CanvasRenderingContext2d").ToLocalChecked(), ctor->GetFunction()); } /* @@ -378,7 +378,6 @@ Context2d::shadow(void (fn)(cairo_t *cr)) { double dx = x2-x1, dy = y2-y1; cairo_user_to_device_distance(_context, &dx, &dy); int pad = state->shadowBlur * 2; - cairo_surface_t *surface = cairo_get_group_target(_context); cairo_surface_t *shadow_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, dx + 2 * pad, @@ -537,14 +536,13 @@ Context2d::blur(cairo_surface_t *surface, int radius) { */ NAN_METHOD(Context2d::New) { - NanScope(); - Local obj = args[0]->ToObject(); - if (!NanHasInstance(Canvas::constructor, obj)) - return NanThrowTypeError("Canvas expected"); - Canvas *canvas = ObjectWrap::Unwrap(obj); + Local obj = info[0]->ToObject(); + if (!Nan::New(Canvas::constructor)->HasInstance(obj)) + return Nan::ThrowTypeError("Canvas expected"); + Canvas *canvas = Nan::ObjectWrap::Unwrap(obj); Context2d *context = new Context2d(canvas); - context->Wrap(args.This()); - NanReturnValue(args.This()); + context->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); } /* @@ -552,13 +550,12 @@ NAN_METHOD(Context2d::New) { */ NAN_METHOD(Context2d::AddPage) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); if (!context->canvas()->isPDF()) { - return NanThrowError("only PDF canvases support .nextPage()"); + return Nan::ThrowError("only PDF canvases support .nextPage()"); } cairo_show_page(context->context()); - NanReturnUndefined(); + return; } /* @@ -570,14 +567,12 @@ NAN_METHOD(Context2d::AddPage) { */ NAN_METHOD(Context2d::PutImageData) { - NanScope(); + Local obj = info[0]->ToObject(); + if (!Nan::New(ImageData::constructor)->HasInstance(obj)) + return Nan::ThrowTypeError("ImageData expected"); - Local obj = args[0]->ToObject(); - if (!NanHasInstance(ImageData::constructor, obj)) - return NanThrowTypeError("ImageData expected"); - - Context2d *context = ObjectWrap::Unwrap(args.This()); - ImageData *imageData = ObjectWrap::Unwrap(obj); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + ImageData *imageData = Nan::ObjectWrap::Unwrap(obj); uint8_t *src = imageData->data(); uint8_t *dst = context->canvas()->data(); @@ -589,12 +584,12 @@ NAN_METHOD(Context2d::PutImageData) { , sy = 0 , sw = 0 , sh = 0 - , dx = args[1]->Int32Value() - , dy = args[2]->Int32Value() + , dx = info[1]->Int32Value() + , dy = info[2]->Int32Value() , rows , cols; - switch (args.Length()) { + switch (info.Length()) { // imageData, dx, dy case 3: cols = std::min(imageData->width(), context->canvas()->width - dx); @@ -602,10 +597,10 @@ NAN_METHOD(Context2d::PutImageData) { break; // imageData, dx, dy, sx, sy, sw, sh case 7: - sx = args[3]->Int32Value(); - sy = args[4]->Int32Value(); - sw = args[5]->Int32Value(); - sh = args[6]->Int32Value(); + sx = info[3]->Int32Value(); + sy = info[4]->Int32Value(); + sw = info[5]->Int32Value(); + sh = info[6]->Int32Value(); // fix up negative height, width if (sw < 0) sx += sw, sw = -sw; if (sh < 0) sy += sh, sh = -sh; @@ -626,10 +621,10 @@ NAN_METHOD(Context2d::PutImageData) { rows = std::min(sh, context->canvas()->height - dy); break; default: - return NanThrowError("invalid arguments"); + return Nan::ThrowError("invalid arguments"); } - if (cols <= 0 || rows <= 0) NanReturnUndefined(); + if (cols <= 0 || rows <= 0) return; src += sy * srcStride + sx * 4; dst += dstStride * dy + 4 * dx; @@ -674,8 +669,6 @@ NAN_METHOD(Context2d::PutImageData) { , dy , cols , rows); - - NanReturnUndefined(); } /* @@ -686,20 +679,18 @@ NAN_METHOD(Context2d::PutImageData) { */ NAN_METHOD(Context2d::GetImageData) { - NanScope(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); Canvas *canvas = context->canvas(); - int sx = args[0]->Int32Value(); - int sy = args[1]->Int32Value(); - int sw = args[2]->Int32Value(); - int sh = args[3]->Int32Value(); + int sx = info[0]->Int32Value(); + int sy = info[1]->Int32Value(); + int sw = info[2]->Int32Value(); + int sh = info[3]->Int32Value(); if (!sw) - return NanThrowError("IndexSizeError: The source width is 0."); + return Nan::ThrowError("IndexSizeError: The source width is 0."); if (!sh) - return NanThrowError("IndexSizeError: The source height is 0."); + return Nan::ThrowError("IndexSizeError: The source height is 0."); // WebKit and Firefox have this behavior: // Flip the coordinates so the origin is top/left-most: @@ -736,25 +727,28 @@ NAN_METHOD(Context2d::GetImageData) { int dstStride = sw * 4; uint8_t *src = canvas->data(); - uint8_t *dst = (uint8_t *)calloc(1, size); - NanAdjustExternalMemory(size); - + #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 10 Local global = Context::GetCurrent()->Global(); - Handle bufargv[] = { NanNew(size) }; - Local buffer = global->Get(NanNew("ArrayBuffer")).As()->NewInstance(1, bufargv); - - Handle caargv[] = { buffer, NanNew(0), NanNew(size) }; - Local clampedArray = global->Get(NanNew("Uint8ClampedArray")).As()->NewInstance(3, caargv); + Local sizeHandle = Nan::New(size); + Local bufargv[] = { sizeHandle }; + Local buffer = global->Get(Nan::New("ArrayBuffer").ToLocalChecked()).As()->NewInstance(1, bufargv); - clampedArray->SetIndexedPropertiesToExternalArrayData(dst, kExternalPixelArray, size); + Local zeroHandle = Nan::New(0); + Local caargv[] = { buffer, zeroHandle, sizeHandle }; + Local clampedArray = global->Get(Nan::New("Uint8ClampedArray").ToLocalChecked()).As()->NewInstance(3, caargv); + uint8_t *dst = (uint8_t *) clampedArray->GetIndexedPropertiesExternalArrayData(); #else Local buffer = ArrayBuffer::New(Isolate::GetCurrent(), size); Local clampedArray = Uint8ClampedArray::New(buffer, 0, size); - clampedArray->SetIndexedPropertiesToExternalArrayData(dst, kExternalUint8ClampedArray, size); +#if NODE_MAJOR_VERSION < 3 + uint8_t *dst = (uint8_t *)clampedArray->GetIndexedPropertiesExternalArrayData(); +#else + uint8_t *dst = (uint8_t *)buffer->GetContents().Data(); #endif - +#endif + // Normalize data (argb -> rgba) for (int y = 0; y < sh; ++y) { uint32_t *row = (uint32_t *)(src + srcStride * (y + sy)); @@ -785,12 +779,14 @@ NAN_METHOD(Context2d::GetImageData) { } const int argc = 3; - Local argv[argc] = { clampedArray, NanNew(sw), NanNew(sh) }; + Local swHandle = Nan::New(sw); + Local shHandle = Nan::New(sh); + Local argv[argc] = { clampedArray, swHandle, shHandle }; - Local cons = NanNew(ImageData::constructor); + Local cons = Nan::New(ImageData::constructor); Local instance = cons->GetFunction()->NewInstance(argc, argv); - NanReturnValue(instance); + info.GetReturnValue().Set(instance); } /* @@ -803,10 +799,8 @@ NAN_METHOD(Context2d::GetImageData) { */ NAN_METHOD(Context2d::DrawImage) { - NanScope(); - - if (args.Length() < 3) - return NanThrowTypeError("invalid arguments"); + if (info.Length() < 3) + return Nan::ThrowTypeError("invalid arguments"); float sx = 0 , sy = 0 @@ -816,62 +810,62 @@ NAN_METHOD(Context2d::DrawImage) { cairo_surface_t *surface; - Local obj = args[0]->ToObject(); + Local obj = info[0]->ToObject(); // Image - if (NanHasInstance(Image::constructor, obj)) { - Image *img = ObjectWrap::Unwrap(obj); + if (Nan::New(Image::constructor)->HasInstance(obj)) { + Image *img = Nan::ObjectWrap::Unwrap(obj); if (!img->isComplete()) { - return NanThrowError("Image given has not completed loading"); + return Nan::ThrowError("Image given has not completed loading"); } sw = img->width; sh = img->height; surface = img->surface(); // Canvas - } else if (NanHasInstance(Canvas::constructor, obj)) { - Canvas *canvas = ObjectWrap::Unwrap(obj); + } else if (Nan::New(Canvas::constructor)->HasInstance(obj)) { + Canvas *canvas = Nan::ObjectWrap::Unwrap(obj); sw = canvas->width; sh = canvas->height; surface = canvas->surface(); // Invalid } else { - return NanThrowTypeError("Image or Canvas expected"); + return Nan::ThrowTypeError("Image or Canvas expected"); } - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); // Arguments - switch (args.Length()) { + switch (info.Length()) { // img, sx, sy, sw, sh, dx, dy, dw, dh case 9: - sx = args[1]->NumberValue(); - sy = args[2]->NumberValue(); - sw = args[3]->NumberValue(); - sh = args[4]->NumberValue(); - dx = args[5]->NumberValue(); - dy = args[6]->NumberValue(); - dw = args[7]->NumberValue(); - dh = args[8]->NumberValue(); + sx = info[1]->NumberValue(); + sy = info[2]->NumberValue(); + sw = info[3]->NumberValue(); + sh = info[4]->NumberValue(); + dx = info[5]->NumberValue(); + dy = info[6]->NumberValue(); + dw = info[7]->NumberValue(); + dh = info[8]->NumberValue(); break; // img, dx, dy, dw, dh case 5: - dx = args[1]->NumberValue(); - dy = args[2]->NumberValue(); - dw = args[3]->NumberValue(); - dh = args[4]->NumberValue(); + dx = info[1]->NumberValue(); + dy = info[2]->NumberValue(); + dw = info[3]->NumberValue(); + dh = info[4]->NumberValue(); break; // img, dx, dy case 3: - dx = args[1]->NumberValue(); - dy = args[2]->NumberValue(); + dx = info[1]->NumberValue(); + dy = info[2]->NumberValue(); dw = sw; dh = sh; break; default: - return NanThrowTypeError("invalid arguments"); + return Nan::ThrowTypeError("invalid arguments"); } // Start draw @@ -906,8 +900,6 @@ NAN_METHOD(Context2d::DrawImage) { cairo_paint_with_alpha(ctx, context->state->globalAlpha); cairo_restore(ctx); - - NanReturnUndefined(); } /* @@ -915,9 +907,8 @@ NAN_METHOD(Context2d::DrawImage) { */ NAN_GETTER(Context2d::GetGlobalAlpha) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(context->state->globalAlpha)); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(context->state->globalAlpha)); } /* @@ -927,7 +918,7 @@ NAN_GETTER(Context2d::GetGlobalAlpha) { NAN_SETTER(Context2d::SetGlobalAlpha) { double n = value->NumberValue(); if (n >= 0 && n <= 1) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->globalAlpha = n; } } @@ -937,8 +928,7 @@ NAN_SETTER(Context2d::SetGlobalAlpha) { */ NAN_GETTER(Context2d::GetGlobalCompositeOperation) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); const char *op = "source-over"; @@ -980,7 +970,7 @@ NAN_GETTER(Context2d::GetGlobalCompositeOperation) { #endif } - NanReturnValue(NanNew(op)); + info.GetReturnValue().Set(Nan::New(op).ToLocalChecked()); } /* @@ -988,7 +978,7 @@ NAN_GETTER(Context2d::GetGlobalCompositeOperation) { */ NAN_SETTER(Context2d::SetPatternQuality) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); String::Utf8Value quality(value->ToString()); if (0 == strcmp("fast", *quality)) { context->state->patternQuality = CAIRO_FILTER_FAST; @@ -1008,8 +998,7 @@ NAN_SETTER(Context2d::SetPatternQuality) { */ NAN_GETTER(Context2d::GetPatternQuality) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *quality; switch (context->state->patternQuality) { case CAIRO_FILTER_FAST: quality = "fast"; break; @@ -1018,7 +1007,7 @@ NAN_GETTER(Context2d::GetPatternQuality) { case CAIRO_FILTER_BILINEAR: quality = "bilinear"; break; default: quality = "good"; } - NanReturnValue(NanNew(quality)); + info.GetReturnValue().Set(Nan::New(quality).ToLocalChecked()); } /* @@ -1026,7 +1015,7 @@ NAN_GETTER(Context2d::GetPatternQuality) { */ NAN_SETTER(Context2d::SetGlobalCompositeOperation) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); String::Utf8Value type(value->ToString()); if (0 == strcmp("xor", *type)) { @@ -1103,9 +1092,8 @@ NAN_SETTER(Context2d::SetGlobalCompositeOperation) { */ NAN_GETTER(Context2d::GetShadowOffsetX) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(context->state->shadowOffsetX)); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(context->state->shadowOffsetX)); } /* @@ -1113,7 +1101,7 @@ NAN_GETTER(Context2d::GetShadowOffsetX) { */ NAN_SETTER(Context2d::SetShadowOffsetX) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->shadowOffsetX = value->NumberValue(); } @@ -1122,9 +1110,8 @@ NAN_SETTER(Context2d::SetShadowOffsetX) { */ NAN_GETTER(Context2d::GetShadowOffsetY) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(context->state->shadowOffsetY)); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(context->state->shadowOffsetY)); } /* @@ -1132,7 +1119,7 @@ NAN_GETTER(Context2d::GetShadowOffsetY) { */ NAN_SETTER(Context2d::SetShadowOffsetY) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->shadowOffsetY = value->NumberValue(); } @@ -1141,9 +1128,8 @@ NAN_SETTER(Context2d::SetShadowOffsetY) { */ NAN_GETTER(Context2d::GetShadowBlur) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(context->state->shadowBlur)); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(context->state->shadowBlur)); } /* @@ -1153,7 +1139,7 @@ NAN_GETTER(Context2d::GetShadowBlur) { NAN_SETTER(Context2d::SetShadowBlur) { int n = value->NumberValue(); if (n >= 0) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->shadowBlur = n; } } @@ -1163,8 +1149,7 @@ NAN_SETTER(Context2d::SetShadowBlur) { */ NAN_GETTER(Context2d::GetAntiAlias) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *aa; switch (cairo_get_antialias(context->context())) { case CAIRO_ANTIALIAS_NONE: aa = "none"; break; @@ -1172,7 +1157,7 @@ NAN_GETTER(Context2d::GetAntiAlias) { case CAIRO_ANTIALIAS_SUBPIXEL: aa = "subpixel"; break; default: aa = "default"; } - NanReturnValue(NanNew(aa)); + info.GetReturnValue().Set(Nan::New(aa).ToLocalChecked()); } /* @@ -1181,7 +1166,7 @@ NAN_GETTER(Context2d::GetAntiAlias) { NAN_SETTER(Context2d::SetAntiAlias) { String::Utf8Value str(value->ToString()); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); cairo_antialias_t a; if (0 == strcmp("none", *str)) { @@ -1203,8 +1188,7 @@ NAN_SETTER(Context2d::SetAntiAlias) { */ NAN_GETTER(Context2d::GetTextDrawingMode) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *mode; if (context->state->textDrawingMode == TEXT_DRAW_PATHS) { mode = "path"; @@ -1213,7 +1197,7 @@ NAN_GETTER(Context2d::GetTextDrawingMode) { } else { mode = "unknown"; } - NanReturnValue(NanNew(mode)); + info.GetReturnValue().Set(Nan::New(mode).ToLocalChecked()); } /* @@ -1222,7 +1206,7 @@ NAN_GETTER(Context2d::GetTextDrawingMode) { NAN_SETTER(Context2d::SetTextDrawingMode) { String::Utf8Value str(value->ToString()); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); if (0 == strcmp("path", *str)) { context->state->textDrawingMode = TEXT_DRAW_PATHS; } else if (0 == strcmp("glyph", *str)) { @@ -1235,8 +1219,7 @@ NAN_SETTER(Context2d::SetTextDrawingMode) { */ NAN_GETTER(Context2d::GetFilter) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *filter; switch (cairo_pattern_get_filter(cairo_get_source(context->context()))) { case CAIRO_FILTER_FAST: filter = "fast"; break; @@ -1245,7 +1228,7 @@ NAN_GETTER(Context2d::GetFilter) { case CAIRO_FILTER_BILINEAR: filter = "bilinear"; break; default: filter = "good"; } - NanReturnValue(NanNew(filter)); + info.GetReturnValue().Set(Nan::New(filter).ToLocalChecked()); } /* @@ -1254,7 +1237,7 @@ NAN_GETTER(Context2d::GetFilter) { NAN_SETTER(Context2d::SetFilter) { String::Utf8Value str(value->ToString()); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_filter_t filter; if (0 == strcmp("fast", *str)) { filter = CAIRO_FILTER_FAST; @@ -1275,9 +1258,8 @@ NAN_SETTER(Context2d::SetFilter) { */ NAN_GETTER(Context2d::GetMiterLimit) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(cairo_get_miter_limit(context->context()))); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(cairo_get_miter_limit(context->context()))); } /* @@ -1287,7 +1269,7 @@ NAN_GETTER(Context2d::GetMiterLimit) { NAN_SETTER(Context2d::SetMiterLimit) { double n = value->NumberValue(); if (n > 0) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_set_miter_limit(context->context(), n); } } @@ -1297,9 +1279,8 @@ NAN_SETTER(Context2d::SetMiterLimit) { */ NAN_GETTER(Context2d::GetLineWidth) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(cairo_get_line_width(context->context()))); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(cairo_get_line_width(context->context()))); } /* @@ -1309,7 +1290,7 @@ NAN_GETTER(Context2d::GetLineWidth) { NAN_SETTER(Context2d::SetLineWidth) { double n = value->NumberValue(); if (n > 0 && n != std::numeric_limits::infinity()) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_set_line_width(context->context(), n); } } @@ -1319,15 +1300,14 @@ NAN_SETTER(Context2d::SetLineWidth) { */ NAN_GETTER(Context2d::GetLineJoin) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *join; switch (cairo_get_line_join(context->context())) { case CAIRO_LINE_JOIN_BEVEL: join = "bevel"; break; case CAIRO_LINE_JOIN_ROUND: join = "round"; break; default: join = "miter"; } - NanReturnValue(NanNew(join)); + info.GetReturnValue().Set(Nan::New(join).ToLocalChecked()); } /* @@ -1335,7 +1315,7 @@ NAN_GETTER(Context2d::GetLineJoin) { */ NAN_SETTER(Context2d::SetLineJoin) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); String::Utf8Value type(value->ToString()); if (0 == strcmp("round", *type)) { @@ -1352,15 +1332,14 @@ NAN_SETTER(Context2d::SetLineJoin) { */ NAN_GETTER(Context2d::GetLineCap) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); const char *cap; switch (cairo_get_line_cap(context->context())) { case CAIRO_LINE_CAP_ROUND: cap = "round"; break; case CAIRO_LINE_CAP_SQUARE: cap = "square"; break; default: cap = "butt"; } - NanReturnValue(NanNew(cap)); + info.GetReturnValue().Set(Nan::New(cap).ToLocalChecked()); } /* @@ -1368,7 +1347,7 @@ NAN_GETTER(Context2d::GetLineCap) { */ NAN_SETTER(Context2d::SetLineCap) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); String::Utf8Value type(value->ToString()); if (0 == strcmp("round", *type)) { @@ -1385,15 +1364,15 @@ NAN_SETTER(Context2d::SetLineCap) { */ NAN_METHOD(Context2d::IsPointInPath) { - NanScope(); - if (args[0]->IsNumber() && args[1]->IsNumber()) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (info[0]->IsNumber() && info[1]->IsNumber()) { + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); - double x = args[0]->NumberValue() - , y = args[1]->NumberValue(); - NanReturnValue(NanNew(cairo_in_fill(ctx, x, y) || cairo_in_stroke(ctx, x, y))); + double x = info[0]->NumberValue() + , y = info[1]->NumberValue(); + info.GetReturnValue().Set(Nan::New(cairo_in_fill(ctx, x, y) || cairo_in_stroke(ctx, x, y))); + return; } - NanReturnValue(NanFalse()); + info.GetReturnValue().Set(Nan::False()); } /* @@ -1401,21 +1380,18 @@ NAN_METHOD(Context2d::IsPointInPath) { */ NAN_METHOD(Context2d::SetFillPattern) { - NanScope(); - - Local obj = args[0]->ToObject(); - if (NanHasInstance(Gradient::constructor, obj)){ - Context2d *context = ObjectWrap::Unwrap(args.This()); - Gradient *grad = ObjectWrap::Unwrap(obj); + Local obj = info[0]->ToObject(); + if (Nan::New(Gradient::constructor)->HasInstance(obj)){ + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + Gradient *grad = Nan::ObjectWrap::Unwrap(obj); context->state->fillGradient = grad->pattern(); - } else if(NanHasInstance(Pattern::constructor, obj)){ - Context2d *context = ObjectWrap::Unwrap(args.This()); - Pattern *pattern = ObjectWrap::Unwrap(obj); + } else if(Nan::New(Pattern::constructor)->HasInstance(obj)){ + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + Pattern *pattern = Nan::ObjectWrap::Unwrap(obj); context->state->fillPattern = pattern->pattern(); } else { - return NanThrowTypeError("Gradient or Pattern expected"); + return Nan::ThrowTypeError("Gradient or Pattern expected"); } - NanReturnUndefined(); } /* @@ -1423,22 +1399,18 @@ NAN_METHOD(Context2d::SetFillPattern) { */ NAN_METHOD(Context2d::SetStrokePattern) { - NanScope(); - - Local obj = args[0]->ToObject(); - if (NanHasInstance(Gradient::constructor, obj)){ - Context2d *context = ObjectWrap::Unwrap(args.This()); - Gradient *grad = ObjectWrap::Unwrap(obj); + Local obj = info[0]->ToObject(); + if (Nan::New(Gradient::constructor)->HasInstance(obj)){ + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + Gradient *grad = Nan::ObjectWrap::Unwrap(obj); context->state->strokeGradient = grad->pattern(); - } else if(NanHasInstance(Pattern::constructor, obj)){ - Context2d *context = ObjectWrap::Unwrap(args.This()); - Pattern *pattern = ObjectWrap::Unwrap(obj); + } else if(Nan::New(Pattern::constructor)->HasInstance(obj)){ + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + Pattern *pattern = Nan::ObjectWrap::Unwrap(obj); context->state->strokePattern = pattern->pattern(); } else { - return NanThrowTypeError("Gradient or Pattern expected"); + return Nan::ThrowTypeError("Gradient or Pattern expected"); } - - NanReturnUndefined(); } /* @@ -1450,7 +1422,7 @@ NAN_SETTER(Context2d::SetShadowColor) { String::Utf8Value str(value->ToString()); uint32_t rgba = rgba_from_string(*str, &ok); if (ok) { - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->shadow = rgba_create(rgba); } } @@ -1460,11 +1432,10 @@ NAN_SETTER(Context2d::SetShadowColor) { */ NAN_GETTER(Context2d::GetShadowColor) { - NanScope(); char buf[64]; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); rgba_to_string(context->state->shadow, buf, sizeof(buf)); - NanReturnValue(NanNew(buf)); + info.GetReturnValue().Set(Nan::New(buf).ToLocalChecked()); } /* @@ -1472,16 +1443,14 @@ NAN_GETTER(Context2d::GetShadowColor) { */ NAN_METHOD(Context2d::SetFillColor) { - NanScope(); short ok; - if (!args[0]->IsString()) NanReturnUndefined(); - String::Utf8Value str(args[0]); + if (!info[0]->IsString()) return; + String::Utf8Value str(info[0]); uint32_t rgba = rgba_from_string(*str, &ok); - if (!ok) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (!ok) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->fillPattern = context->state->fillGradient = NULL; context->state->fill = rgba_create(rgba); - NanReturnUndefined(); } /* @@ -1489,11 +1458,10 @@ NAN_METHOD(Context2d::SetFillColor) { */ NAN_GETTER(Context2d::GetFillColor) { - NanScope(); char buf[64]; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); rgba_to_string(context->state->fill, buf, sizeof(buf)); - NanReturnValue(NanNew(buf)); + info.GetReturnValue().Set(Nan::New(buf).ToLocalChecked()); } /* @@ -1501,16 +1469,14 @@ NAN_GETTER(Context2d::GetFillColor) { */ NAN_METHOD(Context2d::SetStrokeColor) { - NanScope(); short ok; - if (!args[0]->IsString()) NanReturnUndefined(); - String::Utf8Value str(args[0]); + if (!info[0]->IsString()) return; + String::Utf8Value str(info[0]); uint32_t rgba = rgba_from_string(*str, &ok); - if (!ok) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (!ok) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->state->strokePattern = context->state->strokeGradient = NULL; context->state->stroke = rgba_create(rgba); - NanReturnUndefined(); } /* @@ -1518,11 +1484,10 @@ NAN_METHOD(Context2d::SetStrokeColor) { */ NAN_GETTER(Context2d::GetStrokeColor) { - NanScope(); char buf[64]; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); rgba_to_string(context->state->stroke, buf, sizeof(buf)); - NanReturnValue(NanNew(buf)); + info.GetReturnValue().Set(Nan::New(buf).ToLocalChecked()); } /* @@ -1530,25 +1495,21 @@ NAN_GETTER(Context2d::GetStrokeColor) { */ NAN_METHOD(Context2d::BezierCurveTo) { - NanScope(); - - if (!args[0]->IsNumber() - ||!args[1]->IsNumber() - ||!args[2]->IsNumber() - ||!args[3]->IsNumber() - ||!args[4]->IsNumber() - ||!args[5]->IsNumber()) NanReturnUndefined(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (!info[0]->IsNumber() + ||!info[1]->IsNumber() + ||!info[2]->IsNumber() + ||!info[3]->IsNumber() + ||!info[4]->IsNumber() + ||!info[5]->IsNumber()) return; + + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_curve_to(context->context() - , args[0]->NumberValue() - , args[1]->NumberValue() - , args[2]->NumberValue() - , args[3]->NumberValue() - , args[4]->NumberValue() - , args[5]->NumberValue()); - - NanReturnUndefined(); + , info[0]->NumberValue() + , info[1]->NumberValue() + , info[2]->NumberValue() + , info[3]->NumberValue() + , info[4]->NumberValue() + , info[5]->NumberValue()); } /* @@ -1556,21 +1517,19 @@ NAN_METHOD(Context2d::BezierCurveTo) { */ NAN_METHOD(Context2d::QuadraticCurveTo) { - NanScope(); - - if (!args[0]->IsNumber() - ||!args[1]->IsNumber() - ||!args[2]->IsNumber() - ||!args[3]->IsNumber()) NanReturnUndefined(); + if (!info[0]->IsNumber() + ||!info[1]->IsNumber() + ||!info[2]->IsNumber() + ||!info[3]->IsNumber()) return; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); double x, y - , x1 = args[0]->NumberValue() - , y1 = args[1]->NumberValue() - , x2 = args[2]->NumberValue() - , y2 = args[3]->NumberValue(); + , x1 = info[0]->NumberValue() + , y1 = info[1]->NumberValue() + , x2 = info[2]->NumberValue() + , y2 = info[3]->NumberValue(); cairo_get_current_point(ctx, &x, &y); @@ -1584,8 +1543,6 @@ NAN_METHOD(Context2d::QuadraticCurveTo) { , x2 + 2.0 / 3.0 * (x1 - x2), y2 + 2.0 / 3.0 * (y1 - y2) , x2 , y2); - - NanReturnUndefined(); } /* @@ -1593,10 +1550,8 @@ NAN_METHOD(Context2d::QuadraticCurveTo) { */ NAN_METHOD(Context2d::Save) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->save(); - NanReturnUndefined(); } /* @@ -1604,10 +1559,8 @@ NAN_METHOD(Context2d::Save) { */ NAN_METHOD(Context2d::Restore) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->restore(); - NanReturnUndefined(); } /* @@ -1615,10 +1568,8 @@ NAN_METHOD(Context2d::Restore) { */ NAN_METHOD(Context2d::BeginPath) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_new_path(context->context()); - NanReturnUndefined(); } /* @@ -1626,10 +1577,8 @@ NAN_METHOD(Context2d::BeginPath) { */ NAN_METHOD(Context2d::ClosePath) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_close_path(context->context()); - NanReturnUndefined(); } /* @@ -1637,11 +1586,9 @@ NAN_METHOD(Context2d::ClosePath) { */ NAN_METHOD(Context2d::Rotate) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_rotate(context->context() - , args[0]->IsNumber() ? args[0]->NumberValue() : 0); - NanReturnUndefined(); + , info[0]->IsNumber() ? info[0]->NumberValue() : 0); } /* @@ -1649,21 +1596,17 @@ NAN_METHOD(Context2d::Rotate) { */ NAN_METHOD(Context2d::Transform) { - NanScope(); - cairo_matrix_t matrix; cairo_matrix_init(&matrix - , args[0]->IsNumber() ? args[0]->NumberValue() : 0 - , args[1]->IsNumber() ? args[1]->NumberValue() : 0 - , args[2]->IsNumber() ? args[2]->NumberValue() : 0 - , args[3]->IsNumber() ? args[3]->NumberValue() : 0 - , args[4]->IsNumber() ? args[4]->NumberValue() : 0 - , args[5]->IsNumber() ? args[5]->NumberValue() : 0); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + , info[0]->IsNumber() ? info[0]->NumberValue() : 0 + , info[1]->IsNumber() ? info[1]->NumberValue() : 0 + , info[2]->IsNumber() ? info[2]->NumberValue() : 0 + , info[3]->IsNumber() ? info[3]->NumberValue() : 0 + , info[4]->IsNumber() ? info[4]->NumberValue() : 0 + , info[5]->IsNumber() ? info[5]->NumberValue() : 0); + + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_transform(context->context(), &matrix); - - NanReturnUndefined(); } /* @@ -1671,10 +1614,8 @@ NAN_METHOD(Context2d::Transform) { */ NAN_METHOD(Context2d::ResetTransform) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_identity_matrix(context->context()); - NanReturnUndefined(); } /* @@ -1682,12 +1623,10 @@ NAN_METHOD(Context2d::ResetTransform) { */ NAN_METHOD(Context2d::Translate) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_translate(context->context() - , args[0]->IsNumber() ? args[0]->NumberValue() : 0 - , args[1]->IsNumber() ? args[1]->NumberValue() : 0); - NanReturnUndefined(); + , info[0]->IsNumber() ? info[0]->NumberValue() : 0 + , info[1]->IsNumber() ? info[1]->NumberValue() : 0); } /* @@ -1695,12 +1634,10 @@ NAN_METHOD(Context2d::Translate) { */ NAN_METHOD(Context2d::Scale) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_scale(context->context() - , args[0]->IsNumber() ? args[0]->NumberValue() : 0 - , args[1]->IsNumber() ? args[1]->NumberValue() : 0); - NanReturnUndefined(); + , info[0]->IsNumber() ? info[0]->NumberValue() : 0 + , info[1]->IsNumber() ? info[1]->NumberValue() : 0); } /* @@ -1708,11 +1645,9 @@ NAN_METHOD(Context2d::Scale) { */ NAN_METHOD(Context2d::Clip) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); cairo_clip_preserve(ctx); - NanReturnUndefined(); } /* @@ -1720,10 +1655,8 @@ NAN_METHOD(Context2d::Clip) { */ NAN_METHOD(Context2d::Fill) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->fill(true); - NanReturnUndefined(); } /* @@ -1731,10 +1664,8 @@ NAN_METHOD(Context2d::Fill) { */ NAN_METHOD(Context2d::Stroke) { - NanScope(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->stroke(true); - NanReturnUndefined(); } /* @@ -1742,16 +1673,14 @@ NAN_METHOD(Context2d::Stroke) { */ NAN_METHOD(Context2d::FillText) { - NanScope(); + if (!info[1]->IsNumber() + || !info[2]->IsNumber()) return; - if (!args[1]->IsNumber() - || !args[2]->IsNumber()) NanReturnUndefined(); + String::Utf8Value str(info[0]->ToString()); + double x = info[1]->NumberValue(); + double y = info[2]->NumberValue(); - String::Utf8Value str(args[0]->ToString()); - double x = args[1]->NumberValue(); - double y = args[2]->NumberValue(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->savePath(); if (context->state->textDrawingMode == TEXT_DRAW_GLYPHS) { @@ -1762,8 +1691,6 @@ NAN_METHOD(Context2d::FillText) { context->fill(); } context->restorePath(); - - NanReturnUndefined(); } /* @@ -1771,16 +1698,14 @@ NAN_METHOD(Context2d::FillText) { */ NAN_METHOD(Context2d::StrokeText) { - NanScope(); + if (!info[1]->IsNumber() + || !info[2]->IsNumber()) return; - if (!args[1]->IsNumber() - || !args[2]->IsNumber()) NanReturnUndefined(); + String::Utf8Value str(info[0]->ToString()); + double x = info[1]->NumberValue(); + double y = info[2]->NumberValue(); - String::Utf8Value str(args[0]->ToString()); - double x = args[1]->NumberValue(); - double y = args[2]->NumberValue(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); context->savePath(); if (context->state->textDrawingMode == TEXT_DRAW_GLYPHS) { @@ -1791,8 +1716,6 @@ NAN_METHOD(Context2d::StrokeText) { context->stroke(); } context->restorePath(); - - NanReturnUndefined(); } /* @@ -1905,19 +1828,15 @@ Context2d::setTextPath(const char *str, double x, double y) { */ NAN_METHOD(Context2d::LineTo) { - NanScope(); - - if (!args[0]->IsNumber()) - return NanThrowTypeError("lineTo() x must be a number"); - if (!args[1]->IsNumber()) - return NanThrowTypeError("lineTo() y must be a number"); + if (!info[0]->IsNumber()) + return Nan::ThrowTypeError("lineTo() x must be a number"); + if (!info[1]->IsNumber()) + return Nan::ThrowTypeError("lineTo() y must be a number"); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_line_to(context->context() - , args[0]->NumberValue() - , args[1]->NumberValue()); - - NanReturnUndefined(); + , info[0]->NumberValue() + , info[1]->NumberValue()); } /* @@ -1925,19 +1844,15 @@ NAN_METHOD(Context2d::LineTo) { */ NAN_METHOD(Context2d::MoveTo) { - NanScope(); - - if (!args[0]->IsNumber()) - return NanThrowTypeError("moveTo() x must be a number"); - if (!args[1]->IsNumber()) - return NanThrowTypeError("moveTo() y must be a number"); + if (!info[0]->IsNumber()) + return Nan::ThrowTypeError("moveTo() x must be a number"); + if (!info[1]->IsNumber()) + return Nan::ThrowTypeError("moveTo() y must be a number"); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_move_to(context->context() - , args[0]->NumberValue() - , args[1]->NumberValue()); - - NanReturnUndefined(); + , info[0]->NumberValue() + , info[1]->NumberValue()); } /* @@ -1946,28 +1861,26 @@ NAN_METHOD(Context2d::MoveTo) { #ifdef HAVE_FREETYPE NAN_METHOD(Context2d::SetFontFace) { - NanScope(); - // Ignore invalid args - if (!args[0]->IsObject() - || !args[1]->IsNumber()) - return NanThrowTypeError("Expected object and number"); + if (!info[0]->IsObject() + || !info[1]->IsNumber()) + return Nan::ThrowTypeError("Expected object and number"); - Local obj = args[0]->ToObject(); + Local obj = info[0]->ToObject(); - if (!NanHasInstance(FontFace::constructor, obj)) - return NanThrowTypeError("FontFace expected"); + if (!Nan::New(FontFace::constructor)->HasInstance(obj)) + return Nan::ThrowTypeError("FontFace expected"); - FontFace *face = ObjectWrap::Unwrap(obj); - double size = args[1]->NumberValue(); + FontFace *face = Nan::ObjectWrap::Unwrap(obj); + double size = info[1]->NumberValue(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); cairo_set_font_size(ctx, size); cairo_set_font_face(ctx, face->cairoFace()); - NanReturnUndefined(); + return; } #endif @@ -1981,22 +1894,20 @@ NAN_METHOD(Context2d::SetFontFace) { */ NAN_METHOD(Context2d::SetFont) { - NanScope(); - // Ignore invalid args - if (!args[0]->IsString() - || !args[1]->IsString() - || !args[2]->IsNumber() - || !args[3]->IsString() - || !args[4]->IsString()) NanReturnUndefined(); + if (!info[0]->IsString() + || !info[1]->IsString() + || !info[2]->IsNumber() + || !info[3]->IsString() + || !info[4]->IsString()) return; - String::Utf8Value weight(args[0]); - String::Utf8Value style(args[1]); - double size = args[2]->NumberValue(); - String::Utf8Value unit(args[3]); - String::Utf8Value family(args[4]); + String::Utf8Value weight(info[0]); + String::Utf8Value style(info[1]); + double size = info[2]->NumberValue(); + String::Utf8Value unit(info[3]); + String::Utf8Value family(info[4]); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); #if HAVE_PANGO @@ -2064,8 +1975,6 @@ NAN_METHOD(Context2d::SetFont) { cairo_select_font_face(ctx, *family, s, w); #endif - - NanReturnUndefined(); } #if HAVE_PANGO @@ -2097,13 +2006,11 @@ Context2d::setFontFromState() { */ NAN_METHOD(Context2d::MeasureText) { - NanScope(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); - String::Utf8Value str(args[0]->ToString()); - Local obj = NanNew(); + String::Utf8Value str(info[0]->ToString()); + Local obj = Nan::New(); #if HAVE_PANGO @@ -2144,21 +2051,22 @@ NAN_METHOD(Context2d::MeasureText) { y_offset = 0.0; } - obj->Set(NanNew("width"), NanNew(logical_rect.width)); - obj->Set(NanNew("actualBoundingBoxLeft"), - NanNew(x_offset - PANGO_LBEARING(logical_rect))); - obj->Set(NanNew("actualBoundingBoxRight"), - NanNew(x_offset + PANGO_RBEARING(logical_rect))); - obj->Set(NanNew("actualBoundingBoxAscent"), - NanNew(-(y_offset+ink_rect.y))); - obj->Set(NanNew("actualBoundingBoxDescent"), - NanNew((PANGO_DESCENT(ink_rect) + y_offset))); - obj->Set(NanNew("emHeightAscent"), - NanNew(PANGO_ASCENT(logical_rect) - y_offset)); - obj->Set(NanNew("emHeightDescent"), - NanNew(PANGO_DESCENT(logical_rect) + y_offset)); - obj->Set(NanNew("alphabeticBaseline"), - NanNew((pango_font_metrics_get_ascent(metrics) / PANGO_SCALE) + obj->Set(Nan::New("width").ToLocalChecked(), + Nan::New(logical_rect.width)); + obj->Set(Nan::New("actualBoundingBoxLeft").ToLocalChecked(), + Nan::New(x_offset - PANGO_LBEARING(logical_rect))); + obj->Set(Nan::New("actualBoundingBoxRight").ToLocalChecked(), + Nan::New(x_offset + PANGO_RBEARING(logical_rect))); + obj->Set(Nan::New("actualBoundingBoxAscent").ToLocalChecked(), + Nan::New(-(y_offset+ink_rect.y))); + obj->Set(Nan::New("actualBoundingBoxDescent").ToLocalChecked(), + Nan::New((PANGO_DESCENT(ink_rect) + y_offset))); + obj->Set(Nan::New("emHeightAscent").ToLocalChecked(), + Nan::New(PANGO_ASCENT(logical_rect) - y_offset)); + obj->Set(Nan::New("emHeightDescent").ToLocalChecked(), + Nan::New(PANGO_DESCENT(logical_rect) + y_offset)); + obj->Set(Nan::New("alphabeticBaseline").ToLocalChecked(), + Nan::New((pango_font_metrics_get_ascent(metrics) / PANGO_SCALE) + y_offset)); pango_font_metrics_unref(metrics); @@ -2199,22 +2107,26 @@ NAN_METHOD(Context2d::MeasureText) { y_offset = 0.0; } - obj->Set(NanNew("width"), NanNew(te.x_advance)); - obj->Set(NanNew("actualBoundingBoxLeft"), - NanNew(x_offset - te.x_bearing)); - obj->Set(NanNew("actualBoundingBoxRight"), - NanNew((te.x_bearing + te.width) - x_offset)); - obj->Set(NanNew("actualBoundingBoxAscent"), - NanNew(-(te.y_bearing + y_offset))); - obj->Set(NanNew("actualBoundingBoxDescent"), - NanNew(te.height + te.y_bearing + y_offset)); - obj->Set(NanNew("emHeightAscent"), NanNew(fe.ascent - y_offset)); - obj->Set(NanNew("emHeightDescent"), NanNew(fe.descent + y_offset)); - obj->Set(NanNew("alphabeticBaseline"), NanNew(y_offset)); + obj->Set(Nan::New("width").ToLocalChecked(), + Nan::New(te.x_advance)); + obj->Set(Nan::New("actualBoundingBoxLeft").ToLocalChecked(), + Nan::New(x_offset - te.x_bearing)); + obj->Set(Nan::New("actualBoundingBoxRight").ToLocalChecked(), + Nan::New((te.x_bearing + te.width) - x_offset)); + obj->Set(Nan::New("actualBoundingBoxAscent").ToLocalChecked(), + Nan::New(-(te.y_bearing + y_offset))); + obj->Set(Nan::New("actualBoundingBoxDescent").ToLocalChecked(), + Nan::New(te.height + te.y_bearing + y_offset)); + obj->Set(Nan::New("emHeightAscent").ToLocalChecked(), + Nan::New(fe.ascent - y_offset)); + obj->Set(Nan::New("emHeightDescent").ToLocalChecked(), + Nan::New(fe.descent + y_offset)); + obj->Set(Nan::New("alphabeticBaseline").ToLocalChecked(), + Nan::New(y_offset)); #endif - NanReturnValue(obj); + info.GetReturnValue().Set(obj); } /* @@ -2222,13 +2134,9 @@ NAN_METHOD(Context2d::MeasureText) { */ NAN_METHOD(Context2d::SetTextBaseline) { - NanScope(); - - if (!args[0]->IsInt32()) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - context->state->textBaseline = args[0]->Int32Value(); - - NanReturnUndefined(); + if (!info[0]->IsInt32()) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + context->state->textBaseline = info[0]->Int32Value(); } /* @@ -2236,13 +2144,9 @@ NAN_METHOD(Context2d::SetTextBaseline) { */ NAN_METHOD(Context2d::SetTextAlignment) { - NanScope(); - - if (!args[0]->IsInt32()) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); - context->state->textAlignment = args[0]->Int32Value(); - - NanReturnUndefined(); + if (!info[0]->IsInt32()) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); + context->state->textAlignment = info[0]->Int32Value(); } /* @@ -2250,26 +2154,23 @@ NAN_METHOD(Context2d::SetTextAlignment) { * ref: http://www.w3.org/TR/2dcontext/#dom-context-2d-setlinedash */ NAN_METHOD(Context2d::SetLineDash) { - NanScope(); - - if (!args[0]->IsArray()) NanReturnUndefined(); - Handle dash = Handle::Cast(args[0]); + if (!info[0]->IsArray()) return; + Local dash = Local::Cast(info[0]); uint32_t dashes = dash->Length() & 1 ? dash->Length() * 2 : dash->Length(); std::vector a(dashes); for (uint32_t i=0; i d = dash->Get(i % dash->Length()); - if (!d->IsNumber()) NanReturnUndefined(); + if (!d->IsNumber()) return; a[i] = d->NumberValue(); - if (a[i] < 0 || isnan(a[i]) || isinf(a[i])) NanReturnUndefined(); + if (a[i] < 0 || isnan(a[i]) || isinf(a[i])) return; } - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); double offset; cairo_get_dash(ctx, NULL, &offset); cairo_set_dash(ctx, a.data(), dashes, offset); - NanReturnUndefined(); } /* @@ -2277,19 +2178,17 @@ NAN_METHOD(Context2d::SetLineDash) { * ref: http://www.w3.org/TR/2dcontext/#dom-context-2d-setlinedash */ NAN_METHOD(Context2d::GetLineDash) { - NanScope(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); int dashes = cairo_get_dash_count(ctx); std::vector a(dashes); cairo_get_dash(ctx, a.data(), NULL); - Local dash = NanNew(dashes); + Local dash = Nan::New(dashes); for (int i=0; iSet(NanNew(i), NanNew(a[i])); + dash->Set(Nan::New(i), Nan::New(a[i])); - NanReturnValue(dash); + info.GetReturnValue().Set(dash); } /* @@ -2297,12 +2196,10 @@ NAN_METHOD(Context2d::GetLineDash) { * ref: http://www.w3.org/TR/2dcontext/#dom-context-2d-setlinedash */ NAN_SETTER(Context2d::SetLineDashOffset) { - NanScope(); - double offset = value->NumberValue(); if (isnan(offset) || isinf(offset)) return; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); int dashes = cairo_get_dash_count(ctx); @@ -2316,14 +2213,12 @@ NAN_SETTER(Context2d::SetLineDashOffset) { * ref: http://www.w3.org/TR/2dcontext/#dom-context-2d-setlinedash */ NAN_GETTER(Context2d::GetLineDashOffset) { - NanScope(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); double offset; cairo_get_dash(ctx, NULL, &offset); - NanReturnValue(NanNew(offset)); + info.GetReturnValue().Set(Nan::New(offset)); } /* @@ -2331,16 +2226,14 @@ NAN_GETTER(Context2d::GetLineDashOffset) { */ NAN_METHOD(Context2d::FillRect) { - NanScope(); RECT_ARGS; - if (0 == width || 0 == height) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (0 == width || 0 == height) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); context->savePath(); cairo_rectangle(ctx, x, y, width, height); context->fill(); context->restorePath(); - NanReturnUndefined(); } /* @@ -2348,16 +2241,14 @@ NAN_METHOD(Context2d::FillRect) { */ NAN_METHOD(Context2d::StrokeRect) { - NanScope(); RECT_ARGS; - if (0 == width && 0 == height) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (0 == width && 0 == height) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); context->savePath(); cairo_rectangle(ctx, x, y, width, height); context->stroke(); context->restorePath(); - NanReturnUndefined(); } /* @@ -2365,10 +2256,9 @@ NAN_METHOD(Context2d::StrokeRect) { */ NAN_METHOD(Context2d::ClearRect) { - NanScope(); RECT_ARGS; - if (0 == width || 0 == height) NanReturnUndefined(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + if (0 == width || 0 == height) return; + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); cairo_save(ctx); context->savePath(); @@ -2377,7 +2267,6 @@ NAN_METHOD(Context2d::ClearRect) { cairo_fill(ctx); context->restorePath(); cairo_restore(ctx); - NanReturnUndefined(); } /* @@ -2385,9 +2274,8 @@ NAN_METHOD(Context2d::ClearRect) { */ NAN_METHOD(Context2d::Rect) { - NanScope(); RECT_ARGS; - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); if (width == 0) { cairo_move_to(ctx, x, y); @@ -2398,7 +2286,6 @@ NAN_METHOD(Context2d::Rect) { } else { cairo_rectangle(ctx, x, y, width, height); } - NanReturnUndefined(); } /* @@ -2406,36 +2293,32 @@ NAN_METHOD(Context2d::Rect) { */ NAN_METHOD(Context2d::Arc) { - NanScope(); - - if (!args[0]->IsNumber() - || !args[1]->IsNumber() - || !args[2]->IsNumber() - || !args[3]->IsNumber() - || !args[4]->IsNumber()) NanReturnUndefined(); + if (!info[0]->IsNumber() + || !info[1]->IsNumber() + || !info[2]->IsNumber() + || !info[3]->IsNumber() + || !info[4]->IsNumber()) return; - bool anticlockwise = args[5]->BooleanValue(); + bool anticlockwise = info[5]->BooleanValue(); - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); - if (anticlockwise && M_PI * 2 != args[4]->NumberValue()) { + if (anticlockwise && M_PI * 2 != info[4]->NumberValue()) { cairo_arc_negative(ctx - , args[0]->NumberValue() - , args[1]->NumberValue() - , args[2]->NumberValue() - , args[3]->NumberValue() - , args[4]->NumberValue()); + , info[0]->NumberValue() + , info[1]->NumberValue() + , info[2]->NumberValue() + , info[3]->NumberValue() + , info[4]->NumberValue()); } else { cairo_arc(ctx - , args[0]->NumberValue() - , args[1]->NumberValue() - , args[2]->NumberValue() - , args[3]->NumberValue() - , args[4]->NumberValue()); + , info[0]->NumberValue() + , info[1]->NumberValue() + , info[2]->NumberValue() + , info[3]->NumberValue() + , info[4]->NumberValue()); } - - NanReturnUndefined(); } /* @@ -2445,15 +2328,13 @@ NAN_METHOD(Context2d::Arc) { */ NAN_METHOD(Context2d::ArcTo) { - NanScope(); + if (!info[0]->IsNumber() + || !info[1]->IsNumber() + || !info[2]->IsNumber() + || !info[3]->IsNumber() + || !info[4]->IsNumber()) return; - if (!args[0]->IsNumber() - || !args[1]->IsNumber() - || !args[2]->IsNumber() - || !args[3]->IsNumber() - || !args[4]->IsNumber()) NanReturnUndefined(); - - Context2d *context = ObjectWrap::Unwrap(args.This()); + Context2d *context = Nan::ObjectWrap::Unwrap(info.This()); cairo_t *ctx = context->context(); // Current path point @@ -2462,18 +2343,18 @@ NAN_METHOD(Context2d::ArcTo) { Point p0(x, y); // Point (x0,y0) - Point p1(args[0]->NumberValue(), args[1]->NumberValue()); + Point p1(info[0]->NumberValue(), info[1]->NumberValue()); // Point (x1,y1) - Point p2(args[2]->NumberValue(), args[3]->NumberValue()); + Point p2(info[2]->NumberValue(), info[3]->NumberValue()); - float radius = args[4]->NumberValue(); + float radius = info[4]->NumberValue(); if ((p1.x == p0.x && p1.y == p0.y) || (p1.x == p2.x && p1.y == p2.y) || radius == 0.f) { cairo_line_to(ctx, p1.x, p1.y); - NanReturnUndefined(); + return; } Point p1p0((p0.x - p1.x),(p0.y - p1.y)); @@ -2485,7 +2366,7 @@ NAN_METHOD(Context2d::ArcTo) { // all points on a line logic if (-1 == cos_phi) { cairo_line_to(ctx, p1.x, p1.y); - NanReturnUndefined(); + return; } if (1 == cos_phi) { @@ -2494,7 +2375,7 @@ NAN_METHOD(Context2d::ArcTo) { double factor_max = max_length / p1p0_length; Point ep((p0.x + factor_max * p1p0.x), (p0.y + factor_max * p1p0.y)); cairo_line_to(ctx, ep.x, ep.y); - NanReturnUndefined(); + return; } float tangent = radius / tan(acos(cos_phi) / 2); @@ -2545,6 +2426,4 @@ NAN_METHOD(Context2d::ArcTo) { , sa , ea); } - - NanReturnUndefined(); } diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index e377ad6..22dac4a 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -63,14 +63,14 @@ typedef struct { void state_assign_fontFamily(canvas_state_t *state, const char *str); #endif -class Context2d: public node::ObjectWrap { +class Context2d: public Nan::ObjectWrap { public: short stateno; canvas_state_t *states[CANVAS_MAX_STATES]; canvas_state_t *state; Context2d(Canvas *canvas); - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); static NAN_METHOD(DrawImage); static NAN_METHOD(PutImageData); diff --git a/src/FontFace.cc b/src/FontFace.cc index 2028f9b..3758f15 100755 --- a/src/FontFace.cc +++ b/src/FontFace.cc @@ -8,7 +8,7 @@ #include -Persistent FontFace::constructor; +Nan::Persistent FontFace::constructor; /* * Destroy ft_face. @@ -26,17 +26,17 @@ FontFace::~FontFace() { */ void -FontFace::Initialize(Handle target) { - NanScope(); +FontFace::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(FontFace::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(FontFace::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("FontFace")); + ctor->SetClassName(Nan::New("FontFace").ToLocalChecked()); // Prototype - target->Set(NanNew("FontFace"), ctor->GetFunction()); + Nan::Set(target, Nan::New("FontFace").ToLocalChecked(), ctor->GetFunction()); } /* @@ -53,15 +53,13 @@ static cairo_user_data_key_t key; */ NAN_METHOD(FontFace::New) { - NanScope(); - - if (!args[0]->IsString() - || !args[1]->IsNumber()) { - return NanThrowError("Wrong argument types passed to FontFace constructor"); + if (!info[0]->IsString() + || !info[1]->IsNumber()) { + return Nan::ThrowError("Wrong argument types passed to FontFace constructor"); } - String::Utf8Value filePath(args[0]); - int faceIdx = int(args[1]->NumberValue()); + String::Utf8Value filePath(info[0]); + int faceIdx = int(info[1]->NumberValue()); FT_Face ftFace; FT_Error ftError; @@ -71,21 +69,21 @@ NAN_METHOD(FontFace::New) { _initLibrary = false; ftError = FT_Init_FreeType(&library); if (ftError) { - return NanThrowError("Could not load library"); + return Nan::ThrowError("Could not load library"); } } // Create new freetype font face. ftError = FT_New_Face(library, *filePath, faceIdx, &ftFace); if (ftError) { - return NanThrowError("Could not load font file"); + return Nan::ThrowError("Could not load font file"); } #if HAVE_PANGO // Load the font file in fontconfig FcBool ok = FcConfigAppFontAddFile(FcConfigGetCurrent(), (FcChar8 *)(*filePath)); if (!ok) { - return NanThrowError("Could not load font in FontConfig"); + return Nan::ThrowError("Could not load font in FontConfig"); } #endif @@ -98,7 +96,7 @@ NAN_METHOD(FontFace::New) { if (status) { cairo_font_face_destroy (crFace); FT_Done_Face (ftFace); - return NanThrowError("Failed to setup cairo font face user data"); + return Nan::ThrowError("Failed to setup cairo font face user data"); } // Explicit reference count the cairo font face. Otherwise the font face might @@ -106,7 +104,7 @@ NAN_METHOD(FontFace::New) { cairo_font_face_reference(crFace); FontFace *face = new FontFace(ftFace, crFace); - face->Wrap(args.This()); - NanReturnValue(args.This()); + face->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); } diff --git a/src/FontFace.h b/src/FontFace.h index b1e13e4..2032cef 100644 --- a/src/FontFace.h +++ b/src/FontFace.h @@ -13,10 +13,10 @@ #include #include FT_FREETYPE_H -class FontFace: public node::ObjectWrap { +class FontFace: public Nan::ObjectWrap { public: - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); FontFace(FT_Face ftFace, cairo_font_face_t *crFace) :_ftFace(ftFace), _crFace(crFace) {} diff --git a/src/Image.cc b/src/Image.cc index 6410e4e..4821aee 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -28,38 +28,38 @@ typedef struct { uint8_t *buf; } read_closure_t; -Persistent Image::constructor; +Nan::Persistent Image::constructor; /* * Initialize Image. */ void -Image::Initialize(Handle target) { - NanScope(); +Image::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; - Local ctor = NanNew(Image::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(Image::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("Image")); + ctor->SetClassName(Nan::New("Image").ToLocalChecked()); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("Image")); + ctor->SetClassName(Nan::New("Image").ToLocalChecked()); // Prototype Local proto = ctor->PrototypeTemplate(); - proto->SetAccessor(NanNew("source"), GetSource, SetSource); - proto->SetAccessor(NanNew("complete"), GetComplete); - proto->SetAccessor(NanNew("width"), GetWidth); - proto->SetAccessor(NanNew("height"), GetHeight); - proto->SetAccessor(NanNew("onload"), GetOnload, SetOnload); - proto->SetAccessor(NanNew("onerror"), GetOnerror, SetOnerror); + Nan::SetAccessor(proto, Nan::New("source").ToLocalChecked(), GetSource, SetSource); + Nan::SetAccessor(proto, Nan::New("complete").ToLocalChecked(), GetComplete); + Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth); + Nan::SetAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight); + Nan::SetAccessor(proto, Nan::New("onload").ToLocalChecked(), GetOnload, SetOnload); + Nan::SetAccessor(proto, Nan::New("onerror").ToLocalChecked(), GetOnerror, SetOnerror); #if CAIRO_VERSION_MINOR >= 10 - proto->SetAccessor(NanNew("dataMode"), GetDataMode, SetDataMode); - ctor->Set(NanNew("MODE_IMAGE"), NanNew(DATA_IMAGE)); - ctor->Set(NanNew("MODE_MIME"), NanNew(DATA_MIME)); + Nan::SetAccessor(proto, Nan::New("dataMode").ToLocalChecked(), GetDataMode, SetDataMode); + ctor->Set(Nan::New("MODE_IMAGE").ToLocalChecked(), Nan::New(DATA_IMAGE)); + ctor->Set(Nan::New("MODE_MIME").ToLocalChecked(), Nan::New(DATA_MIME)); #endif - target->Set(NanNew("Image"), ctor->GetFunction()); + Nan::Set(target, Nan::New("Image").ToLocalChecked(), ctor->GetFunction()); } /* @@ -67,11 +67,10 @@ Image::Initialize(Handle target) { */ NAN_METHOD(Image::New) { - NanScope(); Image *img = new Image; img->data_mode = DATA_IMAGE; - img->Wrap(args.This()); - NanReturnValue(args.This()); + img->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); } /* @@ -79,9 +78,8 @@ NAN_METHOD(Image::New) { */ NAN_GETTER(Image::GetComplete) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(Image::COMPLETE == img->state)); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(Image::COMPLETE == img->state)); } #if CAIRO_VERSION_MINOR >= 10 @@ -91,9 +89,8 @@ NAN_GETTER(Image::GetComplete) { */ NAN_GETTER(Image::GetDataMode) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(img->data_mode)); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(img->data_mode)); } /* @@ -102,7 +99,7 @@ NAN_GETTER(Image::GetDataMode) { NAN_SETTER(Image::SetDataMode) { if (value->IsNumber()) { - Image *img = ObjectWrap::Unwrap(args.This()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); int mode = value->Uint32Value(); img->data_mode = (data_mode_t) mode; } @@ -115,18 +112,16 @@ NAN_SETTER(Image::SetDataMode) { */ NAN_GETTER(Image::GetWidth) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(img->width)); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(img->width)); } /* * Get height. */ NAN_GETTER(Image::GetHeight) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(img->height)); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(img->height)); } /* @@ -134,9 +129,8 @@ NAN_GETTER(Image::GetHeight) { */ NAN_GETTER(Image::GetSource) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(img->filename ? img->filename : "")); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(img->filename ? img->filename : "").ToLocalChecked()); } /* @@ -147,7 +141,7 @@ void Image::clearData() { if (_surface) { cairo_surface_destroy(_surface); - NanAdjustExternalMemory(-_data_len); + Nan::AdjustExternalMemory(-_data_len); _data_len = 0; _surface = NULL; } @@ -167,8 +161,7 @@ Image::clearData() { */ NAN_SETTER(Image::SetSource) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); cairo_status_t status = CAIRO_STATUS_READ_ERROR; img->clearData(); @@ -259,12 +252,11 @@ Image::readPNG(void *c, uint8_t *data, unsigned int len) { */ NAN_GETTER(Image::GetOnload) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); if (img->onload) { - NanReturnValue(img->onload->GetFunction()); + info.GetReturnValue().Set(img->onload->GetFunction()); } else { - NanReturnNull(); + info.GetReturnValue().SetNull(); } } @@ -274,8 +266,8 @@ NAN_GETTER(Image::GetOnload) { NAN_SETTER(Image::SetOnload) { if (value->IsFunction()) { - Image *img = ObjectWrap::Unwrap(args.This()); - img->onload = new NanCallback(value.As()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + img->onload = new Nan::Callback(value.As()); } } @@ -284,12 +276,11 @@ NAN_SETTER(Image::SetOnload) { */ NAN_GETTER(Image::GetOnerror) { - NanScope(); - Image *img = ObjectWrap::Unwrap(args.This()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); if (img->onerror) { - NanReturnValue(img->onerror->GetFunction()); + info.GetReturnValue().Set(img->onerror->GetFunction()); } else { - NanReturnNull(); + info.GetReturnValue().SetNull(); } } @@ -299,8 +290,8 @@ NAN_GETTER(Image::GetOnerror) { NAN_SETTER(Image::SetOnerror) { if (value->IsFunction()) { - Image *img = ObjectWrap::Unwrap(args.This()); - img->onerror = new NanCallback(value.As()); + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + img->onerror = new Nan::Callback(value.As()); } } @@ -356,13 +347,13 @@ Image::load() { void Image::loaded() { - NanScope(); + Nan::HandleScope scope; state = COMPLETE; width = cairo_image_surface_get_width(_surface); height = cairo_image_surface_get_height(_surface); _data_len = height * cairo_image_surface_get_stride(_surface); - NanAdjustExternalMemory(_data_len); + Nan::AdjustExternalMemory(_data_len); if (onload != NULL) { onload->Call(0, NULL); @@ -377,7 +368,7 @@ Image::loaded() { void Image::error(Local err) { - NanScope(); + Nan::HandleScope scope; if (onerror != NULL) { Local argv[1] = { err }; onerror->Call(1, argv); @@ -448,7 +439,7 @@ get_gif_transparent_color(GifFileType *gif, int frame) { int len = gif->SavedImages[frame].ExtensionBlockCount; for (int x = 0; x < len; ++x, ++ext) { if ((ext->Function == GRAPHICS_EXT_FUNC_CODE) && (ext->Bytes[0] & 1)) { - return ext->Bytes[3] == 0 ? 0 : (uint8_t) ext->Bytes[3]; + return ext->Bytes[3] == 0 ? 0 : (uint8_t) ext->Bytes[3]; } } return -1; @@ -810,7 +801,7 @@ Image::decodeJPEGBufferIntoMimeSurface(uint8_t *buf, unsigned len) { void clearMimeData(void *closure) { - NanAdjustExternalMemory(-((read_closure_t *)closure)->len); + Nan::AdjustExternalMemory(-((read_closure_t *)closure)->len); free(((read_closure_t *) closure)->buf); free(closure); } @@ -837,7 +828,7 @@ Image::assignDataAsMime(uint8_t *data, int len, const char *mime_type) { mime_closure->buf = mime_data; mime_closure->len = len; - NanAdjustExternalMemory(len); + Nan::AdjustExternalMemory(len); return cairo_surface_set_mime_data(_surface , mime_type diff --git a/src/Image.h b/src/Image.h index 805fb80..5c7d6a2 100644 --- a/src/Image.h +++ b/src/Image.h @@ -27,14 +27,14 @@ -class Image: public node::ObjectWrap { +class Image: public Nan::ObjectWrap { public: char *filename; int width, height; - NanCallback *onload; - NanCallback *onerror; - static Persistent constructor; - static void Initialize(Handle target); + Nan::Callback *onload; + Nan::Callback *onerror; + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); static NAN_GETTER(GetSource); static NAN_GETTER(GetOnload); @@ -47,9 +47,9 @@ class Image: public node::ObjectWrap { static NAN_SETTER(SetOnload); static NAN_SETTER(SetOnerror); static NAN_SETTER(SetDataMode); - inline cairo_surface_t *surface(){ return _surface; } - inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } - inline int stride(){ return cairo_image_surface_get_stride(_surface); } + inline cairo_surface_t *surface(){ return _surface; } + inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); } + inline int stride(){ return cairo_image_surface_get_stride(_surface); } static int isPNG(uint8_t *data); static int isJPEG(uint8_t *data); static int isGIF(uint8_t *data); diff --git a/src/ImageData.cc b/src/ImageData.cc index 13ecfaf..74d2754 100644 --- a/src/ImageData.cc +++ b/src/ImageData.cc @@ -7,27 +7,27 @@ #include "ImageData.h" -Persistent ImageData::constructor; +Nan::Persistent ImageData::constructor; /* * Initialize ImageData. */ void -ImageData::Initialize(Handle target) { - NanScope(); +ImageData::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { + Nan::HandleScope scope; // Constructor - Local ctor = NanNew(ImageData::New); - NanAssignPersistent(constructor, ctor); + Local ctor = Nan::New(ImageData::New); + constructor.Reset(ctor); ctor->InstanceTemplate()->SetInternalFieldCount(1); - ctor->SetClassName(NanNew("ImageData")); + ctor->SetClassName(Nan::New("ImageData").ToLocalChecked()); // Prototype Local proto = ctor->PrototypeTemplate(); - proto->SetAccessor(NanNew("width"), GetWidth); - proto->SetAccessor(NanNew("height"), GetHeight); - target->Set(NanNew("ImageData"), ctor->GetFunction()); + Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth); + Nan::SetAccessor(proto, Nan::New("height").ToLocalChecked(), GetHeight); + Nan::Set(target, Nan::New("ImageData").ToLocalChecked(), ctor->GetFunction()); } /* @@ -35,8 +35,6 @@ ImageData::Initialize(Handle target) { */ NAN_METHOD(ImageData::New) { - NanScope(); - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 10 Local clampedArray; Local global = Context::GetCurrent()->Global(); @@ -47,29 +45,29 @@ NAN_METHOD(ImageData::New) { int width; int height; - - if (args[0]->IsUint32() && args[1]->IsUint32()) { - width = args[0]->Uint32Value(); - height = args[1]->Uint32Value(); + if (info[0]->IsUint32() && info[1]->IsUint32()) { + width = info[0]->Uint32Value(); + height = info[1]->Uint32Value(); int size = width * height; #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 10 - Handle caargv[] = { NanNew(size) }; - Local clampedArray = global->Get(NanNew("Uint8ClampedArray")).As()->NewInstance(1, caargv); + Local sizeHandle = Nan::New(size); + Local caargv[] = { sizeHandle }; + clampedArray = global->Get(Nan::New("Uint8ClampedArray").ToLocalChecked()).As()->NewInstance(1, caargv); #else clampedArray = Uint8ClampedArray::New(ArrayBuffer::New(Isolate::GetCurrent(), size), 0, size); #endif #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 10 - } else if (args[0]->ToObject()->GetIndexedPropertiesExternalArrayDataType() == kExternalPixelArray && args[1]->IsUint32()) { - clampedArray = args[0]->ToObject(); + } else if (info[0]->ToObject()->GetIndexedPropertiesExternalArrayDataType() == kExternalPixelArray && info[1]->IsUint32()) { + clampedArray = info[0]->ToObject(); #else - } else if (args[0]->IsUint8ClampedArray() && args[1]->IsUint32()) { - clampedArray = args[0].As(); + } else if (info[0]->IsUint8ClampedArray() && info[1]->IsUint32()) { + clampedArray = info[0].As(); #endif - width = args[1]->Uint32Value(); - if (args[2]->IsUint32()) { - height = args[2]->Uint32Value(); + width = info[1]->Uint32Value(); + if (info[2]->IsUint32()) { + height = info[2]->Uint32Value(); } else { #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 10 height = clampedArray->GetIndexedPropertiesExternalArrayDataLength() / width; @@ -78,20 +76,24 @@ NAN_METHOD(ImageData::New) { #endif } } else { - NanThrowTypeError("Expected (Uint8ClampedArray, width[, height]) or (width, height)"); - NanReturnUndefined(); + Nan::ThrowTypeError("Expected (Uint8ClampedArray, width[, height]) or (width, height)"); + return; } // No behavior defined in spec. This is what WebKit does: if (width < 1) width = 1; if (height < 1) height = 1; +#if NODE_MAJOR_VERSION < 3 void *dataPtr = clampedArray->GetIndexedPropertiesExternalArrayData(); +#else + void *dataPtr = clampedArray->Buffer()->GetContents().Data(); +#endif ImageData *imageData = new ImageData(reinterpret_cast(dataPtr), width, height); - imageData->Wrap(args.This()); - args.This()->Set(NanNew("data"), clampedArray); - NanReturnValue(args.This()); + imageData->Wrap(info.This()); + info.This()->Set(Nan::New("data").ToLocalChecked(), clampedArray); + info.GetReturnValue().Set(info.This()); } /* @@ -99,9 +101,8 @@ NAN_METHOD(ImageData::New) { */ NAN_GETTER(ImageData::GetWidth) { - NanScope(); - ImageData *imageData = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(imageData->width())); + ImageData *imageData = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(imageData->width())); } /* @@ -109,7 +110,6 @@ NAN_GETTER(ImageData::GetWidth) { */ NAN_GETTER(ImageData::GetHeight) { - NanScope(); - ImageData *imageData = ObjectWrap::Unwrap(args.This()); - NanReturnValue(NanNew(imageData->height())); + ImageData *imageData = Nan::ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(imageData->height())); } diff --git a/src/ImageData.h b/src/ImageData.h index 4ef6e12..db4e42a 100644 --- a/src/ImageData.h +++ b/src/ImageData.h @@ -12,10 +12,10 @@ #include #include "v8.h" -class ImageData: public node::ObjectWrap { +class ImageData: public Nan::ObjectWrap { public: - static Persistent constructor; - static void Initialize(Handle target); + static Nan::Persistent constructor; + static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); static NAN_METHOD(New); static NAN_GETTER(GetWidth); static NAN_GETTER(GetHeight); diff --git a/src/JPEGStream.h b/src/JPEGStream.h index 95962e3..a8c4843 100644 --- a/src/JPEGStream.h +++ b/src/JPEGStream.h @@ -29,15 +29,15 @@ init_closure_destination(j_compress_ptr cinfo){ boolean empty_closure_output_buffer(j_compress_ptr cinfo){ - NanScope(); + Nan::HandleScope scope; closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; - Local buf = NanNewBufferHandle((char *)dest->buffer, dest->bufsize); + Local buf = Nan::NewBuffer((char *)dest->buffer, dest->bufsize).ToLocalChecked(); Local argv[3] = { - NanNew(NanNull()) - , NanNew(buf) - , NanNew(dest->bufsize) + Nan::Null() + , buf + , Nan::New(dest->bufsize) }; - NanMakeCallback(NanGetCurrentContext()->Global(), dest->closure->fn, 3, argv); + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)dest->closure->fn, 3, argv); cinfo->dest->next_output_byte = dest->buffer; cinfo->dest->free_in_buffer = dest->bufsize; return true; @@ -45,28 +45,28 @@ empty_closure_output_buffer(j_compress_ptr cinfo){ void term_closure_destination(j_compress_ptr cinfo){ - NanScope(); + Nan::HandleScope scope; closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; /* emit remaining data */ size_t remaining = dest->bufsize - cinfo->dest->free_in_buffer; - Local buf = NanNewBufferHandle((char *)dest->buffer, remaining); + Local buf = Nan::NewBuffer((char *)dest->buffer, remaining).ToLocalChecked(); Local data_argv[3] = { - NanNew(NanNull()) - , NanNew(buf) - , NanNew(remaining) + Nan::Null() + , buf + , Nan::New(remaining) }; - NanMakeCallback(NanGetCurrentContext()->Global(), dest->closure->fn, 3, data_argv); + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)dest->closure->fn, 3, data_argv); // emit "end" Local end_argv[3] = { - NanNew(NanNull()) - , NanNew(NanNull()) - , NanNew(0) + Nan::Null() + , Nan::Null() + , Nan::New(0) }; - NanMakeCallback(NanGetCurrentContext()->Global(), dest->closure->fn, 3, end_argv); + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), (v8::Local)dest->closure->fn, 3, end_argv); } void diff --git a/src/closure.h b/src/closure.h index 3ac6632..1fb6bce 100644 --- a/src/closure.h +++ b/src/closure.h @@ -23,8 +23,8 @@ */ typedef struct { - NanCallback *pfn; - Handle fn; + Nan::Callback *pfn; + Local fn; unsigned len; unsigned max_len; uint8_t *data; @@ -58,7 +58,7 @@ void closure_destroy(closure_t *closure) { if (closure->len) { free(closure->data); - NanAdjustExternalMemory(-((intptr_t) closure->max_len)); + Nan::AdjustExternalMemory(-((intptr_t) closure->max_len)); } } diff --git a/src/init.cc b/src/init.cc index 14fd705..e496c80 100755 --- a/src/init.cc +++ b/src/init.cc @@ -17,9 +17,7 @@ #include "FontFace.h" #endif -extern "C" void -init (Handle target) { - NanScope(); +NAN_MODULE_INIT(init) { Canvas::Initialize(target); Image::Initialize(target); ImageData::Initialize(target); @@ -30,7 +28,7 @@ init (Handle target) { FontFace::Initialize(target); #endif - target->Set(NanNew("cairoVersion"), NanNew(cairo_version_string())); + target->Set(Nan::New("cairoVersion").ToLocalChecked(), Nan::New(cairo_version_string()).ToLocalChecked()); #ifdef HAVE_JPEG #ifndef JPEG_LIB_VERSION_MAJOR @@ -55,16 +53,16 @@ init (Handle target) { } else { snprintf(jpeg_version, 10, "%d", JPEG_LIB_VERSION_MAJOR); } - target->Set(NanNew("jpegVersion"), NanNew(jpeg_version)); + target->Set(Nan::New("jpegVersion").ToLocalChecked(), Nan::New(jpeg_version).ToLocalChecked()); #endif #ifdef HAVE_GIF #ifndef GIF_LIB_VERSION char gif_version[10]; snprintf(gif_version, 10, "%d.%d.%d", GIFLIB_MAJOR, GIFLIB_MINOR, GIFLIB_RELEASE); - target->Set(NanNew("gifVersion"), NanNew(gif_version)); + target->Set(Nan::New("gifVersion").ToLocalChecked(), Nan::New(gif_version).ToLocalChecked()); #else - target->Set(NanNew("gifVersion"), NanNew(GIF_LIB_VERSION)); + target->Set(Nan::New("gifVersion").ToLocalChecked(), Nan::New(GIF_LIB_VERSION).ToLocalChecked()); #endif #endif } diff --git a/test/canvas.test.js b/test/canvas.test.js index 2f66bdd..8080272 100644 --- a/test/canvas.test.js +++ b/test/canvas.test.js @@ -639,5 +639,23 @@ module.exports = { assert.equal(0, imageData.data[i+2]); assert.equal(255, imageData.data[i+3]); + }, + + 'test Canvas#createSyncPNGStream()': function(done) { + var canvas = new Canvas(20, 20); + var stream = canvas.createSyncPNGStream(); + var firstChunk = true; + stream.on('data', function(chunk){ + if (firstChunk) { + firstChunk = false; + assert.equal('PNG', chunk.slice(1,4).toString()); + } + }); + stream.on('end', function(){ + done(); + }); + stream.on('error', function(err) { + done(err); + }); } }