#include #include using namespace emscripten; using namespace std; using namespace tvg; string defaultData(""); class __attribute__((visibility("default"))) ThorvgWasm { public: static unique_ptr create() { return unique_ptr(new ThorvgWasm()); } string getError() { return mErrorMsg; } string getDefaultData() { return defaultData; } bool load(string data, int width, int height) { mErrorMsg = "None"; if (!mSwCanvas) { mErrorMsg = "Canvas is NULL"; return false; } mPicture = Picture::gen().release(); if (!mPicture) { mErrorMsg = "Picture get failed"; return false; } mSwCanvas->clear(); if (data.empty()) data = defaultData; const char *cdata = data.c_str(); if (mPicture->load(cdata, strlen(cdata)) != Result::Success) { /* mPicture is not handled as unique_ptr yet, so delete here */ delete(mPicture); mPicture = nullptr; mErrorMsg = "Load failed"; return false; } /* need to reset size to calculate scale in Picture.size internally before calling updateSize */ mWidth = 0; mHeight = 0; updateSize(width, height); if (mSwCanvas->push(unique_ptr(mPicture)) != Result::Success) { mErrorMsg = "Push failed"; return false; } return true; } void update(int width, int height) { mErrorMsg = "None"; if (!mSwCanvas) { mErrorMsg = "Canvas is NULL"; return; } if (!mPicture) { mErrorMsg = "Picture is NULL"; return; } if (mWidth == width && mHeight == height) { return; } updateSize(width, height); if (mSwCanvas->update(mPicture) != Result::Success) { mErrorMsg = "Update failed"; return; } return; } val render() { mErrorMsg = "None"; if (!mSwCanvas) { mErrorMsg = "Canvas is NULL"; return val(typed_memory_view(0, nullptr)); } if (mSwCanvas->draw() != Result::Success) { mErrorMsg = "Draw failed"; return val(typed_memory_view(0, nullptr)); } mSwCanvas->sync(); return val(typed_memory_view(mWidth * mHeight * 4, mBuffer.get())); } private: explicit ThorvgWasm() { mErrorMsg = "None"; Initializer::init(CanvasEngine::Sw, 0); mSwCanvas = SwCanvas::gen(); if (!mSwCanvas) { mErrorMsg = "Canvas get failed"; return; } } void updateSize(int width, int height) { if (!mSwCanvas) return; if (mWidth == width && mHeight == height) return; mWidth = width; mHeight = height; mBuffer = make_unique(mWidth * mHeight * 4); mSwCanvas->target((uint32_t *)mBuffer.get(), mWidth, mWidth, mHeight, SwCanvas::ABGR8888); if (mPicture) mPicture->size(width, height); } private: string mErrorMsg; unique_ptr< SwCanvas > mSwCanvas = nullptr; Picture* mPicture = nullptr; unique_ptr mBuffer = nullptr; uint32_t mWidth{0}; uint32_t mHeight{0}; }; // Binding code EMSCRIPTEN_BINDINGS(thorvg_bindings) { class_("ThorvgWasm") .constructor(&ThorvgWasm::create) .function("getError", &ThorvgWasm::getError, allow_raw_pointers()) .function("getDefaultData", &ThorvgWasm::getDefaultData, allow_raw_pointers()) .function("load", &ThorvgWasm::load) .function("update", &ThorvgWasm::update) .function("render", &ThorvgWasm::render); }