testMultiShapes
testMergeShapes
testBoundary
+testPath
int appendRect(float x, float y, float w, float h, float cornerRadius) noexcept;
int appendCircle(float cx, float cy, float radiusW, float radiusH) noexcept;
+ int appendPath(const PathCommand* cmds, size_t cmdCnt, const Point* pts, size_t ptsCnt) noexcept;
int fill(size_t r, size_t g, size_t b, size_t a) noexcept;
#include <vector>
#include <math.h>
#include <float.h>
+#include <string.h>
#include "tizenvg.h"
#include "tvgRenderCommon.h"
auto impl = pImpl.get();
assert(impl);
- return impl->path->clear();
+ impl->path->clear();
+
+ return 0;
}
}
+int ShapeNode::appendPath(const PathCommand *cmds, size_t cmdCnt, const Point* pts, size_t ptsCnt) noexcept
+{
+ if (cmdCnt < 0 || ptsCnt < 0) return -1;
+ assert(cmds && pts);
+
+ auto impl = pImpl.get();
+ assert(impl);
+
+ impl->path->append(cmds, cmdCnt, pts, ptsCnt);
+
+ return 0;
+}
+
+
int ShapeNode::appendCircle(float cx, float cy, float radiusW, float radiusH) noexcept
{
auto impl = pImpl.get();
auto halfKappaW = radiusW * PATH_KAPPA;
auto halfKappaH = radiusH * PATH_KAPPA;
- impl->path->reserve(6, 13);
+ impl->path->grow(6, 13);
impl->path->moveTo(cx, cy - radiusH);
impl->path->cubicTo(cx + halfKappaW, cy - radiusH, cx + radiusW, cy - halfKappaH, cx + radiusW, cy);
impl->path->cubicTo(cx + radiusW, cy + halfKappaH, cx + halfKappaW, cy + radiusH, cx, cy + radiusH);
//rectangle
if (cornerRadius == 0) {
- impl->path->reserve(5, 4);
+ impl->path->grow(5, 4);
impl->path->moveTo(x, y);
impl->path->lineTo(x + w, y);
impl->path->lineTo(x + w, y + h);
return appendCircle(x + (w * 0.5f), y + (h * 0.5f), cornerRadius, cornerRadius);
} else {
auto halfKappa = cornerRadius * 0.5;
- impl->path->reserve(10, 17);
+ impl->path->grow(10, 17);
impl->path->moveTo(x + cornerRadius, y);
impl->path->lineTo(x + w - cornerRadius, y);
impl->path->cubicTo(x + w - cornerRadius + halfKappa, y, x + w, y + cornerRadius - halfKappa, x + w, y + cornerRadius);
if (pts) delete(pts);
}
- int reserveCmd(size_t cmdCnt)
+ void reserveCmd(size_t cmdCnt)
{
- if (cmdCnt > reservedCmdCnt) {
- reservedCmdCnt = cmdCnt;
- cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt));
- assert(cmds);
- }
- return 0;
+ if (cmdCnt <= reservedCmdCnt) return;
+ reservedCmdCnt = cmdCnt;
+ cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt));
+ assert(cmds);
}
- int reservePts(size_t ptsCnt)
+ void reservePts(size_t ptsCnt)
{
- if (ptsCnt > reservedPtsCnt) {
- reservedPtsCnt = ptsCnt;
- pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt));
- assert(pts);
- }
- return 0;
+ if (ptsCnt <= reservedPtsCnt) return;
+ reservedPtsCnt = ptsCnt;
+ pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt));
+ assert(pts);
}
- int reserve(size_t cmdCnt, size_t ptsCnt)
+ void reserve(size_t cmdCnt, size_t ptsCnt)
{
reserveCmd(cmdCnt);
reservePts(ptsCnt);
+ }
- return 0;
+ void grow(size_t cmdCnt, size_t ptsCnt)
+ {
+ reserveCmd(this->cmdCnt + cmdCnt);
+ reservePts(this->ptsCnt + ptsCnt);
}
- int clear()
+ void clear()
{
cmdCnt = 0;
ptsCnt = 0;
+ }
- return 0;
+ void append(const PathCommand* cmds, size_t cmdCnt, const Point* pts, size_t ptsCnt)
+ {
+ grow(cmdCnt, ptsCnt);
+ memcpy(this->cmds + this->cmdCnt, cmds, sizeof(PathCommand) * cmdCnt);
+ memcpy(this->pts + this->ptsCnt, pts, sizeof(Point) * ptsCnt);
+ this->cmdCnt += cmdCnt;
+ this->ptsCnt += ptsCnt;
}
- int moveTo(float x, float y)
+ void moveTo(float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
cmds[cmdCnt++] = PathCommand::MoveTo;
pts[ptsCnt++] = {x, y};
-
- return 0;
}
- int lineTo(float x, float y)
+ void lineTo(float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2);
cmds[cmdCnt++] = PathCommand::LineTo;
pts[ptsCnt++] = {x, y};
-
- return 0;
}
- int cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y)
+ void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2);
pts[ptsCnt++] = {cx1, cy1};
pts[ptsCnt++] = {cx2, cy2};
pts[ptsCnt++] = {x, y};
-
- return 0;
}
-
- int close()
+ void close()
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
cmds[cmdCnt++] = PathCommand::Close;
-
- return 0;
- }
-
- int bounds(float& x, float& y, float& w, float& h)
- {
- if (ptsCnt == 0) return -1;
-
- Point min = { pts[0].x, pts[0].y };
- Point max = { pts[0].x, pts[0].y };
-
- for(size_t i = 1; i <= ptsCnt; ++i) {
- if (pts[i].x < min.x) min.x = pts[i].x;
- if (pts[i].y < min.y) min.y = pts[i].y;
- if (pts[i].x > max.x) max.x = pts[i].x;
- if (pts[i].y > max.y) max.y = pts[i].y;
- }
-
- x = min.x;
- y = min.y;
- w = max.x - min.x;
- h = max.y - min.y;
-
- return 0;
}
};
gcc -o testMultiShapes testMultiShapes.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testMergeShapes testMergeShapes.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testBoundary testBoundary.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
+ gcc -o testPath testPath.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
#include <tizenvg.h>
+#include <Elementary.h>
using namespace std;
static uint32_t buffer[WIDTH * HEIGHT];
-int main(int argc, char **argv)
+void tvgtest()
{
//Initialize TizenVG Engine
tvg::Engine::init();
//Create a Canvas
auto canvas = tvg::SwCanvas::gen(buffer, WIDTH, HEIGHT);
- //Prepare Path
- auto path = tvg::Path::gen();
- path.reserve(cmdCnt, ptCnt); //command count, points count
- path.moveTo(...);
- path.lineTo(...);
- path.cubicTo(...);
- path.close();
+ /* Star */
+
+ //Prepare Path Commands
+ tvg::PathCommand cmds[11];
+ cmds[0] = tvg::PathCommand::MoveTo;
+ cmds[1] = tvg::PathCommand::LineTo;
+ cmds[2] = tvg::PathCommand::LineTo;
+ cmds[3] = tvg::PathCommand::LineTo;
+ cmds[4] = tvg::PathCommand::LineTo;
+ cmds[5] = tvg::PathCommand::LineTo;
+ cmds[6] = tvg::PathCommand::LineTo;
+ cmds[7] = tvg::PathCommand::LineTo;
+ cmds[8] = tvg::PathCommand::LineTo;
+ cmds[9] = tvg::PathCommand::LineTo;
+ cmds[10] = tvg::PathCommand::Close;
+
+ //Prepare Path Points
+ tvg::Point pts[10];
+ pts[0] = {199, 34}; //MoveTo
+ pts[1] = {253, 143}; //LineTo
+ pts[2] = {374, 160}; //LineTo
+ pts[3] = {287, 244}; //LineTo
+ pts[4] = {307, 365}; //LineTo
+ pts[5] = {199, 309}; //LineTo
+ pts[6] = {97, 365}; //LineTo
+ pts[7] = {112, 245}; //LineTo
+ pts[8] = {26, 161}; //LineTo
+ pts[9] = {146, 143}; //LineTo
- //Prepare a Shape
auto shape1 = tvg::ShapeNode::gen();
- shape1->path(move(path)); //migrate owner otherwise,
- shape1->path(path.get()); //copy raw data directly for performance
+ shape1->appendPath(cmds, 11, pts, 10); //copy path data
shape1->fill(0, 255, 0, 255);
-
- //Draw the Shape onto the Canvas
canvas->push(move(shape1));
+
+
+ /* Circle */
+ auto cx = 550.0f;
+ auto cy = 550.0f;
+ auto radius = 125.0f;
+ auto halfRadius = radius * 0.552284f;
+
+ //Prepare Path Commands
+ tvg::PathCommand cmds2[6];
+ cmds2[0] = tvg::PathCommand::MoveTo;
+ cmds2[1] = tvg::PathCommand::CubicTo;
+ cmds2[2] = tvg::PathCommand::CubicTo;
+ cmds2[3] = tvg::PathCommand::CubicTo;
+ cmds2[4] = tvg::PathCommand::CubicTo;
+ cmds2[5] = tvg::PathCommand::Close;
+
+ //Prepare Path Points
+ tvg::Point pts2[13];
+ pts2[0] = {cx, cy - radius}; //MoveTo
+ //CubicTo 1
+ pts2[1] = {cx + halfRadius, cy - radius}; //Ctrl1
+ pts2[2] = {cx + radius, cy - halfRadius}; //Ctrl2
+ pts2[3] = {cx + radius, cy}; //To
+ //CubicTo 2
+ pts2[4] = {cx + radius, cy + halfRadius}; //Ctrl1
+ pts2[5] = {cx + halfRadius, cy + radius}; //Ctrl2
+ pts2[6] = {cx, cy+ radius}; //To
+ //CubicTo 3
+ pts2[7] = {cx - halfRadius, cy + radius}; //Ctrl1
+ pts2[8] = {cx - radius, cy + halfRadius}; //Ctrl2
+ pts2[9] = {cx - radius, cy}; //To
+ //CubicTo 4
+ pts2[10] = {cx - radius, cy - halfRadius}; //Ctrl1
+ pts2[11] = {cx - halfRadius, cy - radius}; //Ctrl2
+ pts2[12] = {cx, cy - radius}; //To
+
+ auto shape2 = tvg::ShapeNode::gen();
+ shape2->appendPath(cmds2, 6, pts2, 13); //copy path data
+ shape2->fill(255, 255, 0, 255);
+ canvas->push(move(shape2));
+
canvas->draw();
canvas->sync();
//Terminate TizenVG Engine
tvg::Engine::term();
}
+
+void
+win_del(void *data, Evas_Object *o, void *ev)
+{
+ elm_exit();
+}
+
+int main(int argc, char **argv)
+{
+ tvgtest();
+
+ //Show the result using EFL...
+ elm_init(argc, argv);
+
+ Eo* win = elm_win_util_standard_add(NULL, "TizenVG Test");
+ evas_object_smart_callback_add(win, "delete,request", win_del, 0);
+
+ Eo* img = evas_object_image_filled_add(evas_object_evas_get(win));
+ evas_object_image_size_set(img, WIDTH, HEIGHT);
+ evas_object_image_data_set(img, buffer);
+ evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(img);
+
+ elm_win_resize_object_add(win, img);
+ evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT);
+ evas_object_show(win);
+
+ elm_run();
+ elm_shutdown();
+}