mirror of
https://github.com/alibaba/GCanvas.git
synced 2025-12-08 17:36:42 +00:00
189 lines
6.4 KiB
C++
189 lines
6.4 KiB
C++
#include "Canvas.h"
|
|
#include "TextMetrics.h"
|
|
namespace NodeBinding
|
|
{
|
|
Napi::FunctionReference Canvas::constructor;
|
|
|
|
Canvas::Canvas(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Canvas>(info)
|
|
{
|
|
Napi::Env env = info.Env();
|
|
Napi::HandleScope scope(env);
|
|
|
|
checkArgs(info, 2);
|
|
mWidth = info[0].As<Napi::Number>().Int32Value();
|
|
mHeight = info[1].As<Napi::Number>().Int32Value();
|
|
mRenderContext = std::make_shared<GRenderContext>(mWidth, mHeight);
|
|
mRenderContext->initRenderEnviroment();
|
|
|
|
|
|
}
|
|
|
|
int Canvas::getWidth()
|
|
{
|
|
return mWidth;
|
|
}
|
|
|
|
int Canvas::getHeight()
|
|
{
|
|
return mHeight;
|
|
}
|
|
|
|
Napi::Value Canvas::getWidth(const Napi::CallbackInfo &info)
|
|
{
|
|
return Napi::Number::New(info.Env(), mWidth);
|
|
}
|
|
|
|
Napi::Value Canvas::getHeight(const Napi::CallbackInfo &info)
|
|
{
|
|
return Napi::Number::New(info.Env(), mHeight);
|
|
}
|
|
|
|
void Canvas::Init(Napi::Env env, Napi::Object exports)
|
|
{
|
|
Napi::HandleScope scope(env);
|
|
|
|
Napi::Function func =
|
|
DefineClass(env,
|
|
"Canvas",
|
|
{
|
|
InstanceAccessor("width", &Canvas::getWidth, nullptr),
|
|
InstanceAccessor("height", &Canvas::getHeight, nullptr),
|
|
InstanceMethod("getContext", &Canvas::getContext),
|
|
InstanceMethod("createPNG", &Canvas::createPNG),
|
|
InstanceMethod("createJPEG", &Canvas::createJPEG),
|
|
InstanceMethod("createPNGStreamSync", &Canvas::createPNGStreamSync),
|
|
InstanceMethod("createJPGStreamSync", &Canvas::createJPGStreamSync),
|
|
});
|
|
constructor = Napi::Persistent(func);
|
|
constructor.SuppressDestruct();
|
|
return;
|
|
}
|
|
|
|
Napi::Object Canvas::NewInstance(Napi::Env env, Napi::Value arg, Napi::Value arg2)
|
|
{
|
|
Napi::Object obj = constructor.New({arg, arg2});
|
|
obj.Set("name", Napi::String::New(env, "gcanvas"));
|
|
Canvas *canvas = Napi::ObjectWrap<Canvas>::Unwrap(obj);
|
|
canvas->mRef = Napi::ObjectReference::New(obj);
|
|
return obj;
|
|
}
|
|
|
|
Napi::Value Canvas::getContext(const Napi::CallbackInfo &info)
|
|
{
|
|
Napi::Env env = info.Env();
|
|
checkArgs(info, 1);
|
|
std::string type = info[0].As<Napi::String>().Utf8Value();
|
|
if (type == "2d")
|
|
{
|
|
if (this->context2dRef.IsEmpty())
|
|
{
|
|
Napi::Object obj = Context2D::NewInstance(env);
|
|
this->context2dRef = Napi::ObjectReference::New(obj);
|
|
Context2D *ctx = Napi::ObjectWrap<Context2D>::Unwrap(obj);
|
|
ctx->setRenderContext(this->mRenderContext);
|
|
ctx->setCanvasRef(this);
|
|
return obj;
|
|
}
|
|
else
|
|
{
|
|
return this->context2dRef.Value();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throwError(info, "only support 2d now");
|
|
return Napi::Object::New(env);
|
|
}
|
|
}
|
|
void Canvas::createPNG(const Napi::CallbackInfo &info)
|
|
{
|
|
NodeBinding::checkArgs(info, 1);
|
|
std::string arg = info[0].As<Napi::String>().Utf8Value();
|
|
if (this->mRenderContext)
|
|
{
|
|
this->mRenderContext->makeCurrent();
|
|
this->mRenderContext->drawFrame();
|
|
this->mRenderContext->render2file(arg.c_str(), PNG_FORAMT);
|
|
}
|
|
return;
|
|
}
|
|
void Canvas::createJPEG(const Napi::CallbackInfo &info)
|
|
{
|
|
NodeBinding::checkArgs(info, 1);
|
|
std::string arg = info[0].As<Napi::String>().Utf8Value();
|
|
if (this->mRenderContext)
|
|
{
|
|
this->mRenderContext->makeCurrent();
|
|
this->mRenderContext->drawFrame();
|
|
this->mRenderContext->render2file(arg.c_str(), JPEG_FORMAT);
|
|
}
|
|
return;
|
|
}
|
|
Napi::Value Canvas::createJPGStreamSync(const Napi::CallbackInfo &info)
|
|
{
|
|
NodeBinding::checkArgs(info, 2);
|
|
Napi::Function callback = info[0].As<Napi::Function>();
|
|
if (this->mRenderContext)
|
|
{
|
|
this->mRenderContext->makeCurrent();
|
|
this->mRenderContext->drawFrame();
|
|
}
|
|
unsigned char *data = (unsigned char *)malloc(1 * sizeof(unsigned char));
|
|
unsigned long size = 0;
|
|
int ret = this->mRenderContext->getImagePixelJPG(&data, size);
|
|
if (ret == 0 && size > 0)
|
|
{
|
|
//handlescope 表示作用域,一般调用callback函数时使用
|
|
Napi::HandleScope scope(info.Env());
|
|
Napi::Buffer<unsigned char> buffer = Napi::Buffer<unsigned char>::Copy(info.Env(), data, size);
|
|
callback.Call({info.Env().Null(),
|
|
buffer,
|
|
Napi::Number::New(info.Env(), size)});
|
|
}
|
|
else
|
|
{
|
|
Napi::HandleScope scope(info.Env());
|
|
callback.Call({Napi::String::New(Env(), "createJPGStreamFail"),
|
|
info.Env().Null(),
|
|
info.Env().Null()});
|
|
}
|
|
if (data)
|
|
{
|
|
delete data;
|
|
data = nullptr;
|
|
}
|
|
}
|
|
|
|
Napi::Value Canvas::createPNGStreamSync(const Napi::CallbackInfo &info)
|
|
{
|
|
NodeBinding::checkArgs(info, 2);
|
|
Napi::Function callback = info[0].As<Napi::Function>();
|
|
if (this->mRenderContext)
|
|
{
|
|
this->mRenderContext->makeCurrent();
|
|
this->mRenderContext->drawFrame();
|
|
}
|
|
std::vector<unsigned char> in;
|
|
int ret = this->mRenderContext->getImagePixelPNG(in);
|
|
if (ret == 0)
|
|
{
|
|
//handlescope 表示作用域,一般调用callback函数时使用
|
|
Napi::HandleScope scope(info.Env());
|
|
Napi::Buffer<unsigned char> buffer = Napi::Buffer<unsigned char>::Copy(info.Env(), &in[0], in.size());
|
|
callback.Call({info.Env().Null(),
|
|
buffer,
|
|
Napi::Number::New(info.Env(), in.size())});
|
|
}
|
|
else
|
|
{
|
|
Napi::HandleScope scope(info.Env());
|
|
callback.Call({Napi::String::New(Env(), "createPNGStreamFail"),
|
|
info.Env().Null(),
|
|
info.Env().Null()});
|
|
}
|
|
}
|
|
Canvas::~Canvas()
|
|
{
|
|
this->mRenderContext = nullptr;
|
|
}
|
|
} // namespace NodeBinding
|