--- /dev/null
+#include "Common.h"
+#include <fstream>
+
+/************************************************************************/
+/* Drawing Commands */
+/************************************************************************/
+
+uint32_t *data = nullptr;
+
+void tvgDrawCmds(tvg::Canvas* canvas)
+{
+ if (!canvas) return;
+
+ //Background
+ auto shape = tvg::Shape::gen();
+ shape->appendRect(0, 0, WIDTH, HEIGHT, 0, 0);
+ shape->fill(255, 255, 255, 255);
+
+ if (canvas->push(move(shape)) != tvg::Result::Success) return;
+
+ string path(EXAMPLE_DIR"/rawimage_200x300.raw");
+
+ ifstream file(path);
+ if (!file.is_open()) return ;
+ data = (uint32_t*)malloc(sizeof(uint32_t) * (200*300));
+ file.read(reinterpret_cast<char *>(data), sizeof (data) * 200 * 300);
+ file.close();
+
+ auto picture = tvg::Picture::gen();
+ if (picture->load(data, 200, 300, true) != tvg::Result::Success) return;
+ picture->translate(400, 250);
+
+ //Alpha mask
+ auto mask = tvg::Shape::gen();
+ mask->appendCircle(500, 350, 75, 75);
+ mask->fill(0, 0, 0, 50);
+ if (canvas->push(move(picture)) != tvg::Result::Success) return;
+
+ auto cover = tvg::Shape::gen();
+ cover->appendRect(400, 250, 200, 300, 0, 0);
+ cover->fill(255, 255, 0, 255);
+ cover->composite(move(mask), tvg::CompositeMethod::AlphaMask);
+ if (canvas->push(move(cover)) != tvg::Result::Success) return;
+
+}
+
+
+/************************************************************************/
+/* Sw Engine Test Code */
+/************************************************************************/
+
+static unique_ptr<tvg::SwCanvas> swCanvas;
+
+void tvgSwTest(uint32_t* buffer)
+{
+ //Create a Canvas
+ swCanvas = tvg::SwCanvas::gen();
+ swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
+
+ /* Push the shape into the Canvas drawing list
+ When this shape is into the canvas list, the shape could update & prepare
+ internal data asynchronously for coming rendering.
+ Canvas keeps this shape node unless user call canvas->clear() */
+ tvgDrawCmds(swCanvas.get());
+}
+
+void drawSwView(void* data, Eo* obj)
+{
+ if (swCanvas->draw() == tvg::Result::Success) {
+ swCanvas->sync();
+ }
+}
+
+
+/************************************************************************/
+/* GL Engine Test Code */
+/************************************************************************/
+
+static unique_ptr<tvg::GlCanvas> glCanvas;
+
+void initGLview(Evas_Object *obj)
+{
+ static constexpr auto BPP = 4;
+
+ //Create a Canvas
+ glCanvas = tvg::GlCanvas::gen();
+ glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
+
+ /* Push the shape into the Canvas drawing list
+ When this shape is into the canvas list, the shape could update & prepare
+ internal data asynchronously for coming rendering.
+ Canvas keeps this shape node unless user call canvas->clear() */
+ tvgDrawCmds(glCanvas.get());
+}
+
+void drawGLview(Evas_Object *obj)
+{
+ auto gl = elm_glview_gl_api_get(obj);
+ gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ gl->glClear(GL_COLOR_BUFFER_BIT);
+
+ if (glCanvas->draw() == tvg::Result::Success) {
+ glCanvas->sync();
+ }
+}
+
+
+/************************************************************************/
+/* Main Code */
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+ tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
+ }
+
+ //Initialize ThorVG Engine
+ if (tvgEngine == tvg::CanvasEngine::Sw) {
+ cout << "tvg engine: software" << endl;
+ } else {
+ cout << "tvg engine: opengl" << endl;
+ }
+
+ //Threads Count
+ auto threads = std::thread::hardware_concurrency();
+
+ //Initialize ThorVG Engine
+ if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
+
+ elm_init(argc, argv);
+
+ if (tvgEngine == tvg::CanvasEngine::Sw) {
+ createSwView();
+ } else {
+ createGlView();
+ }
+
+ elm_run();
+ elm_shutdown();
+
+ //Terminate ThorVG Engine
+ tvg::Initializer::term(tvg::CanvasEngine::Sw);
+
+ if (data) free(data);
+
+ } else {
+ cout << "engine is not supported" << endl;
+ }
+ return 0;
+}
return out;
}
+SwSpan* _intersectMaskRegion(const SwRleData *clip, const SwRleData *targetRle, SwSpan *outSpans, uint32_t spanCnt)
+{
+
+ auto out = outSpans;
+ auto spans = targetRle->spans;
+ auto end = targetRle->spans + targetRle->size;
+ auto clipSpans = clip->spans;
+ auto clipSpans1 = clip->spans;
+ auto clipEnd = clip->spans + clip->size;
+
+ auto maskClipMin = clipSpans1->y;
+ auto maskClipMax = clipSpans1->y;
+
+ while (clipSpans1->y) {
+ if (clipSpans1->y > maskClipMax)
+ maskClipMax = clipSpans1->y;
+
+ if (clipSpans1->y < maskClipMax)
+ maskClipMin = clipSpans1->y;
+ clipSpans1++;
+ }
+
+ while (spanCnt && spans < end ) {
+ if (clipSpans > clipEnd) {
+ spans = end;
+ break;
+ }
+
+
+ if (spans->y < maskClipMin || spans->y > maskClipMax) {
+ out->x = spans->x;
+ out->y = spans->y;
+ out->len = spans->len;
+ out->coverage = spans->coverage;
+ ++out;
+ }
+ else {
+ while (clipSpans->y) {
+ auto sx1 = spans->x;
+ auto sx2 = sx1 + spans->len;
+ auto cx1 = clipSpans->x;
+ auto cx2 = cx1 + clipSpans->len;
+ auto x = sx1 > cx1 ? sx1 : cx1;
+ auto len = (sx2 < cx2 ? sx2 : cx2) - x;
+
+ if (len > 1) {
+ out->x = sx1;
+ out->y = clipSpans->y;
+ out->len = cx1-sx1;
+ out->coverage = spans->coverage;
+ ++out;
+
+ out->x = cx2;
+ out->y = clipSpans->y;
+ out->len = sx2 - cx2;
+ out->coverage = spans->coverage;
+ ++out;
+ }
+ clipSpans++;
+ }
+ }
+ --spanCnt;
+ ++spans;
+ }
+
+ return out;
+}
+
+
SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRle, SwSpan *outSpans, uint32_t spanCnt)
{
auto out = outSpans;
if (spans) free(spans);
}
+
+
+void rleAlphaMask(SwRleData *rle, const SwRleData *clip)
+{
+ if (rle->size == 0 || clip->size == 0) return;
+ auto spanCnt = rle->size + clip->size;
+
+ auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (spanCnt)));
+
+ if (!spans) return;
+ auto spansEnd = _intersectMaskRegion(clip, rle, spans, spanCnt);
+
+ //Update Spans
+ updateRleSpans(rle, spans, spansEnd - spans);
+
+ if (spans) free(spans);
+}
+