|
|
@ -45,6 +45,15 @@ Canvas::Initialize(Handle<Object> target) { |
|
|
|
proto->SetAccessor(NanSymbol("type"), GetType); |
|
|
|
proto->SetAccessor(NanSymbol("width"), GetWidth, SetWidth); |
|
|
|
proto->SetAccessor(NanSymbol("height"), GetHeight, SetHeight); |
|
|
|
|
|
|
|
proto->Set("PNG_NO_FILTERS", Uint32::New(PNG_NO_FILTERS)); |
|
|
|
proto->Set("PNG_FILTER_NONE", Uint32::New(PNG_FILTER_NONE)); |
|
|
|
proto->Set("PNG_FILTER_SUB", Uint32::New(PNG_FILTER_SUB)); |
|
|
|
proto->Set("PNG_FILTER_UP", Uint32::New(PNG_FILTER_UP)); |
|
|
|
proto->Set("PNG_FILTER_AVG", Uint32::New(PNG_FILTER_AVG)); |
|
|
|
proto->Set("PNG_FILTER_PAETH", Uint32::New(PNG_FILTER_PAETH)); |
|
|
|
proto->Set("PNG_ALL_FILTERS", Uint32::New(PNG_ALL_FILTERS)); |
|
|
|
|
|
|
|
target->Set(NanSymbol("Canvas"), ctor->GetFunction()); |
|
|
|
} |
|
|
|
|
|
|
@ -225,6 +234,7 @@ NAN_METHOD(Canvas::ToBuffer) { |
|
|
|
NanScope(); |
|
|
|
cairo_status_t status; |
|
|
|
uint32_t compression_level = 6; |
|
|
|
uint32_t filter = PNG_ALL_FILTERS; |
|
|
|
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args.This()); |
|
|
|
|
|
|
|
// TODO: async / move this out
|
|
|
@ -236,38 +246,48 @@ NAN_METHOD(Canvas::ToBuffer) { |
|
|
|
NanReturnValue(buf); |
|
|
|
} |
|
|
|
|
|
|
|
if (args.Length() == 2 && !args[1]->StrictEquals(Undefined())) { |
|
|
|
bool good = true; |
|
|
|
if (args[1]->IsNumber()) { |
|
|
|
compression_level = args[1]->Uint32Value(); |
|
|
|
} else if (args[1]->IsString()) { |
|
|
|
if (args[1]->StrictEquals(String::New("0"))) { |
|
|
|
compression_level = 0; |
|
|
|
} else { |
|
|
|
uint32_t tmp = args[1]->Uint32Value(); |
|
|
|
if (tmp == 0) { |
|
|
|
good = false; |
|
|
|
if (args.Length() > 1 && !(args[1]->StrictEquals(Undefined()) && args[2]->StrictEquals(Undefined()))) { |
|
|
|
if (!args[1]->StrictEquals(Undefined())) { |
|
|
|
bool good = true; |
|
|
|
if (args[1]->IsNumber()) { |
|
|
|
compression_level = args[1]->Uint32Value(); |
|
|
|
} else if (args[1]->IsString()) { |
|
|
|
if (args[1]->StrictEquals(String::New("0"))) { |
|
|
|
compression_level = 0; |
|
|
|
} else { |
|
|
|
compression_level = tmp; |
|
|
|
uint32_t tmp = args[1]->Uint32Value(); |
|
|
|
if (tmp == 0) { |
|
|
|
good = false; |
|
|
|
} else { |
|
|
|
compression_level = tmp; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
good = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (good) { |
|
|
|
if (compression_level > 9) { |
|
|
|
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); |
|
|
|
} else { |
|
|
|
good = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (good) { |
|
|
|
if (compression_level > 9) { |
|
|
|
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Compression level must be a number."); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Compression level must be a number."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!args[2]->StrictEquals(Undefined())) { |
|
|
|
if (args[2]->IsUint32()) { |
|
|
|
filter = args[1]->Uint32Value(); |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Invalid filter value."); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Async
|
|
|
|
if (args[0]->IsFunction()) { |
|
|
|
closure_t *closure = (closure_t *) malloc(sizeof(closure_t)); |
|
|
|
status = closure_init(closure, canvas, compression_level); |
|
|
|
status = closure_init(closure, canvas, compression_level, filter); |
|
|
|
|
|
|
|
// ensure closure is ok
|
|
|
|
if (status) { |
|
|
@ -293,7 +313,7 @@ NAN_METHOD(Canvas::ToBuffer) { |
|
|
|
// Sync
|
|
|
|
} else { |
|
|
|
closure_t closure; |
|
|
|
status = closure_init(&closure, canvas, compression_level); |
|
|
|
status = closure_init(&closure, canvas, compression_level, filter); |
|
|
|
|
|
|
|
// ensure closure is ok
|
|
|
|
if (status) { |
|
|
@ -342,36 +362,47 @@ 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 (args.Length() == 2 && !args[1]->StrictEquals(Undefined())) { |
|
|
|
bool good = true; |
|
|
|
if (args[1]->IsNumber()) { |
|
|
|
compression_level = args[1]->Uint32Value(); |
|
|
|
} else if (args[1]->IsString()) { |
|
|
|
if (args[1]->StrictEquals(String::New("0"))) { |
|
|
|
compression_level = 0; |
|
|
|
} else { |
|
|
|
uint32_t tmp = args[1]->Uint32Value(); |
|
|
|
if (tmp == 0) { |
|
|
|
good = false; |
|
|
|
if (args.Length() > 1 && !(args[1]->StrictEquals(Undefined()) && args[2]->StrictEquals(Undefined()))) { |
|
|
|
if (!args[1]->StrictEquals(Undefined())) { |
|
|
|
bool good = true; |
|
|
|
if (args[1]->IsNumber()) { |
|
|
|
compression_level = args[1]->Uint32Value(); |
|
|
|
} else if (args[1]->IsString()) { |
|
|
|
if (args[1]->StrictEquals(String::New("0"))) { |
|
|
|
compression_level = 0; |
|
|
|
} else { |
|
|
|
compression_level = tmp; |
|
|
|
uint32_t tmp = args[1]->Uint32Value(); |
|
|
|
if (tmp == 0) { |
|
|
|
good = false; |
|
|
|
} else { |
|
|
|
compression_level = tmp; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
good = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (good) { |
|
|
|
if (compression_level > 9) { |
|
|
|
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); |
|
|
|
} else { |
|
|
|
good = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (good) { |
|
|
|
if (compression_level > 9) { |
|
|
|
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9]."); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Compression level must be a number."); |
|
|
|
} |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Compression level must be a number."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!args[2]->StrictEquals(Undefined())) { |
|
|
|
if (args[2]->IsUint32()) { |
|
|
|
filter = args[1]->Uint32Value(); |
|
|
|
} else { |
|
|
|
return NanThrowTypeError("Invalid filter value."); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -379,6 +410,7 @@ NAN_METHOD(Canvas::StreamPNGSync) { |
|
|
|
closure_t closure; |
|
|
|
closure.fn = Handle<Function>::Cast(args[0]); |
|
|
|
closure.compression_level = compression_level; |
|
|
|
closure.filter = filter; |
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
|
|
|
|
@ -443,7 +475,7 @@ Canvas::Canvas(int w, int h, canvas_type_t t): ObjectWrap() { |
|
|
|
if (CANVAS_TYPE_PDF == t) { |
|
|
|
_closure = malloc(sizeof(closure_t)); |
|
|
|
assert(_closure); |
|
|
|
cairo_status_t status = closure_init((closure_t *) _closure, this, 0); |
|
|
|
cairo_status_t status = closure_init((closure_t *) _closure, this, 0, PNG_NO_FILTERS); |
|
|
|
assert(status == CAIRO_STATUS_SUCCESS); |
|
|
|
_surface = cairo_pdf_surface_create_for_stream(toBuffer, _closure, w, h); |
|
|
|
} else { |
|
|
|