|
@ -5,6 +5,7 @@ |
|
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|
|
//
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#include <string.h> |
|
|
#include "canvas.h" |
|
|
#include "canvas.h" |
|
|
|
|
|
|
|
|
using namespace v8; |
|
|
using namespace v8; |
|
@ -20,6 +21,7 @@ Canvas::Initialize(Handle<Object> target) { |
|
|
t->InstanceTemplate()->SetInternalFieldCount(1); |
|
|
t->InstanceTemplate()->SetInternalFieldCount(1); |
|
|
t->SetClassName(String::NewSymbol("Canvas")); |
|
|
t->SetClassName(String::NewSymbol("Canvas")); |
|
|
|
|
|
|
|
|
|
|
|
NODE_SET_PROTOTYPE_METHOD(t, "streamPNG", StreamPNG); |
|
|
NODE_SET_PROTOTYPE_METHOD(t, "savePNG", SavePNG); |
|
|
NODE_SET_PROTOTYPE_METHOD(t, "savePNG", SavePNG); |
|
|
target->Set(String::NewSymbol("Canvas"), t->GetFunction()); |
|
|
target->Set(String::NewSymbol("Canvas"), t->GetFunction()); |
|
|
} |
|
|
} |
|
@ -42,6 +44,46 @@ Canvas::New(const Arguments &args) { |
|
|
return args.This(); |
|
|
return args.This(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
unsigned char *pos; |
|
|
|
|
|
unsigned char *end; |
|
|
|
|
|
Handle<Function> fn; |
|
|
|
|
|
} closure_t; |
|
|
|
|
|
|
|
|
|
|
|
static cairo_status_t |
|
|
|
|
|
writeToBuffer(void *c, const uint8_t *data, unsigned len) { |
|
|
|
|
|
printf("bytes %d\n", len); |
|
|
|
|
|
closure_t *closure = (closure_t *) c; |
|
|
|
|
|
if (closure->pos + len > closure->end) |
|
|
|
|
|
return CAIRO_STATUS_WRITE_ERROR; |
|
|
|
|
|
memcpy(closure->pos, data, len); |
|
|
|
|
|
Handle<Value> argv[1]; |
|
|
|
|
|
argv[0] = String::New("test"); |
|
|
|
|
|
closure->fn.Call(Context::GetCurrent()->Global(), 1, argv); |
|
|
|
|
|
closure->pos += len; |
|
|
|
|
|
return CAIRO_STATUS_SUCCESS; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Return a node Buffer containing PNG data. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> |
|
|
|
|
|
Canvas::StreamPNG(const Arguments &args) { |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
// TODO: error handling
|
|
|
|
|
|
if (!args[0]->IsFunction()) |
|
|
|
|
|
return ThrowException(Exception::TypeError(String::New("function required"))); |
|
|
|
|
|
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args.This()); |
|
|
|
|
|
closure_t closure; |
|
|
|
|
|
uint8_t data[64 * 1024]; |
|
|
|
|
|
closure.pos = data; |
|
|
|
|
|
closure.end = data + sizeof(data); |
|
|
|
|
|
closure.fn = Handle<Function>::Cast(args[0]); // TODO: leakage?
|
|
|
|
|
|
cairo_surface_write_to_png_stream(canvas->getSurface(), writeToBuffer, &closure); |
|
|
|
|
|
return Undefined(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/*
|
|
|
/*
|
|
|
* Initialize cairo surface. |
|
|
* Initialize cairo surface. |
|
|
*/ |
|
|
*/ |
|
|