common gradient: implement linear/radial gradient interfaces. 53/235753/7
authorHermet Park <chuneon.park@samsung.com>
Tue, 9 Jun 2020 06:40:13 +0000 (15:40 +0900)
committerHermet Park <chuneon.park@samsung.com>
Wed, 10 Jun 2020 08:03:25 +0000 (17:03 +0900)
Change-Id: Ica9c54e662e73592d3fddcabed09b1605b3a5a4f

17 files changed:
.gitignore
inc/tizenvg.h
src/lib/gl_engine/meson.build
src/lib/meson.build
src/lib/tvgCanvasImpl.h
src/lib/tvgCommon.h
src/lib/tvgFill.cpp [new file with mode: 0644]
src/lib/tvgLinearGradient.cpp [new file with mode: 0644]
src/lib/tvgRadialGradient.cpp [new file with mode: 0644]
src/lib/tvgRenderCommon.h
src/lib/tvgScene.cpp
src/lib/tvgSceneImpl.h
src/lib/tvgShape.cpp
src/lib/tvgShapeImpl.h
src/meson.build
test/makefile
test/testLinearGradient.cpp [new file with mode: 0644]

index ba439cb..b9cdf24 100644 (file)
@@ -14,3 +14,4 @@ testTransform
 testSceneTransform
 testStroke
 testStrokeLine
+testLinearGradient
index a2d245d..b089387 100644 (file)
@@ -35,6 +35,7 @@
 extern "C" {
 #endif
 
+
 #define _TVG_DECLARE_PRIVATE(A) \
 protected: \
     struct Impl; \
@@ -43,16 +44,21 @@ protected: \
     const A& operator=(const A&) = delete; \
     A()
 
-#define _TVG_DECLARE_ACCESSOR(A) \
-    friend A
-
 #define _TVG_DISABLE_CTOR(A) \
     A() = delete; \
     ~A() = delete
 
-#define _TVG_DECALRE_IDENTIFIER(A) \
+#define _TVG_DECLARE_ACCESSOR(A) \
+    friend A
+
+#define _TVG_DECLARE_ACCESSORS(A, B) \
+    friend A; \
+    friend B
+
+#define _TVG_DECALRE_IDENTIFIER() \
 protected: \
-    unsigned A##_Id
+    unsigned id
+
 
 namespace tvg
 {
@@ -93,9 +99,79 @@ public:
 
     virtual Result bounds(float* x, float* y, float* w, float* h) const = 0;
 
-    _TVG_DECALRE_IDENTIFIER(Paint);
-    _TVG_DECLARE_ACCESSOR(Scene);
-    _TVG_DECLARE_ACCESSOR(Canvas);
+    _TVG_DECALRE_IDENTIFIER();
+    _TVG_DECLARE_ACCESSORS(Canvas, Scene);
+};
+
+
+/**
+ * @class Fill
+ *
+ * @ingroup TizenVG
+ *
+ * @brief description...
+ *
+ */
+class TVG_EXPORT Fill
+{
+public:
+    struct ColorStop
+    {
+        float pos;
+        uint8_t r, g, b, a;
+    };
+
+    virtual ~Fill();
+
+    Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept;
+    uint32_t colorStops(const ColorStop** colorStops) const noexcept;
+
+    _TVG_DECALRE_IDENTIFIER();
+    _TVG_DECLARE_PRIVATE(Fill);
+};
+
+
+/**
+ * @class LinearGradient
+ *
+ * @ingroup TizenVG
+ *
+ * @brief description...
+ *
+ */
+class TVG_EXPORT LinearGradient final : public Fill
+{
+public:
+    ~LinearGradient();
+
+    Result linear(float x1, float y1, float x2, float y2) noexcept;
+    Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept;
+
+    static std::unique_ptr<LinearGradient> gen() noexcept;
+
+    _TVG_DECLARE_PRIVATE(LinearGradient);
+};
+
+
+/**
+ * @class RadialGradient
+ *
+ * @ingroup TizenVG
+ *
+ * @brief description...
+ *
+ */
+class TVG_EXPORT RadialGradient final : public Fill
+{
+public:
+    ~RadialGradient();
+
+    Result radial(float cx, float cy, float radius) noexcept;
+    Result radial(float* cx, float* cy, float* radius) const noexcept;
+
+    static std::unique_ptr<RadialGradient> gen() noexcept;
+
+    _TVG_DECLARE_PRIVATE(RadialGradient);
 };
 
 
@@ -161,6 +237,7 @@ public:
 
     //Fill
     Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
+    Result fill(std::unique_ptr<Fill> f) noexcept;
 
     //Transform
     Result rotate(float degree) noexcept override;
@@ -171,6 +248,7 @@ public:
     uint32_t pathCommands(const PathCommand** cmds) const noexcept;
     uint32_t pathCoords(const Point** pts) const noexcept;
     Result fill(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept;
+    const Fill* fill() const noexcept;
     Result bounds(float* x, float* y, float* w, float* h) const noexcept override;
 
     float strokeWidth() const noexcept;
@@ -181,9 +259,8 @@ public:
 
     static std::unique_ptr<Shape> gen() noexcept;
 
-    _TVG_DECLARE_ACCESSOR(Scene);
-    _TVG_DECLARE_ACCESSOR(Canvas);
     _TVG_DECLARE_PRIVATE(Shape);
+    _TVG_DECLARE_ACCESSORS(Canvas, Scene);
 };
 
 
@@ -211,8 +288,8 @@ public:
 
     static std::unique_ptr<Scene> gen() noexcept;
 
-    _TVG_DECLARE_PRIVATE(Scene);
     _TVG_DECLARE_ACCESSOR(Canvas);
+    _TVG_DECLARE_PRIVATE(Scene);
 };
 
 
@@ -231,6 +308,7 @@ public:
 
     Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept;
     Result sync() noexcept override;
+
     static std::unique_ptr<SwCanvas> gen() noexcept;
 
     _TVG_DECLARE_PRIVATE(SwCanvas);
@@ -254,6 +332,7 @@ public:
 
     Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept;
     Result sync() noexcept override;
+
     static std::unique_ptr<GlCanvas> gen() noexcept;
 
     _TVG_DECLARE_PRIVATE(GlCanvas);
index 41a25e0..5494f69 100644 (file)
@@ -1,12 +1,12 @@
 source_file = [
    'tvgGlCommon.h',
+   'tvgGlGeometry.h',
    'tvgGlGpuBuffer.h',
    'tvgGlProgram.h',
-   'tvgGlRenderer.cpp',
    'tvgGlRenderer.h',
    'tvgGlShader.h',
-   'tvgGlGeometry.h',
-   ]
+   'tvgGlRenderer.cpp',
+]
 
 glraster_dep = declare_dependency(
    include_directories : include_directories('.'),
index 0a56f0d..5aba9bb 100644 (file)
@@ -2,18 +2,21 @@ subdir('sw_engine')
 subdir('gl_engine')
 
 source_file = [
+   'tvgCanvasImpl.h',
    'tvgCommon.h',
    'tvgRenderCommon.h',
+   'tvgSceneImpl.h',
    'tvgShapePath.h',
    'tvgShapeImpl.h',
-   'tvgCanvasImpl.h',
-   'tvgSceneImpl.h',
-   'tvgEngine.cpp',
    'tvgCanvas.cpp',
-   'tvgSwCanvas.cpp',
+   'tvgEngine.cpp',
+   'tvgFill.cpp',
    'tvgGlCanvas.cpp',
+   'tvgLinearGradient.cpp',
+   'tvgRadialGradient.cpp',
    'tvgScene.cpp',
-   'tvgShape.cpp'
+   'tvgShape.cpp',
+   'tvgSwCanvas.cpp',
 ]
 
 src_dep = declare_dependency(
index 078385a..c6dc073 100644 (file)
@@ -53,7 +53,7 @@ struct Canvas::Impl
         assert(renderer);
 
         for (auto paint : paints) {
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if (!SCENE_IMPL->clear(*renderer)) return Result::InsufficientCondition;
@@ -73,7 +73,7 @@ struct Canvas::Impl
         assert(renderer);
 
         for(auto paint: paints) {
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if (!SCENE_IMPL->update(*renderer, nullptr)) return Result::InsufficientCondition;
@@ -89,7 +89,7 @@ struct Canvas::Impl
     {
         assert(renderer);
 
-        if (paint->Paint_Id == PAINT_ID_SCENE) {
+        if (paint->id == PAINT_ID_SCENE) {
             //We know renderer type, avoid dynamic_cast for performance.
             auto scene = static_cast<Scene*>(paint);
             if (!SCENE_IMPL->update(*renderer)) return Result::InsufficientCondition;
@@ -108,7 +108,7 @@ struct Canvas::Impl
         if (!renderer->clear()) return Result::InsufficientCondition;
 
         for(auto paint: paints) {
-           if (paint->Paint_Id == PAINT_ID_SCENE) {
+           if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition;
index ca18cca..49c3f96 100644 (file)
@@ -34,6 +34,9 @@ using namespace tvg;
 #define PAINT_ID_SHAPE 0
 #define PAINT_ID_SCENE 1
 
+#define FILL_ID_LINEAR 0
+#define FILL_ID_RADIAL 1
+
 #include "tvgRenderCommon.h"
 #include "tvgShapePath.h"
 #include "tvgShapeImpl.h"
diff --git a/src/lib/tvgFill.cpp b/src/lib/tvgFill.cpp
new file mode 100644 (file)
index 0000000..13001c8
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_FILL_CPP_
+#define _TVG_FILL_CPP_
+
+#include "tvgCommon.h"
+
+
+/************************************************************************/
+/* Internal Class Implementation                                        */
+/************************************************************************/
+
+struct Fill::Impl
+{
+    ColorStop* colorStops = nullptr;
+    uint32_t cnt = 0;
+
+    ~Impl()
+    {
+        if (colorStops) free(colorStops);
+    }
+};
+
+
+/************************************************************************/
+/* External Class Implementation                                        */
+/************************************************************************/
+
+Fill::Fill():pImpl(make_unique<Impl>())
+{
+}
+
+
+Fill::~Fill()
+{
+}
+
+
+Result Fill::colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    if (cnt == 0) {
+        if (impl->colorStops) {
+            free(impl->colorStops);
+            impl->colorStops = nullptr;
+            impl->cnt = cnt;
+        }
+        return Result::Success;
+    }
+
+    if (impl->cnt != cnt) {
+        impl->colorStops = static_cast<ColorStop*>(realloc(impl->colorStops, cnt * sizeof(ColorStop)));
+    }
+
+    impl->cnt = cnt;
+    memcpy(impl->colorStops, colorStops, cnt * sizeof(ColorStop));
+
+    return Result::Success;
+}
+
+
+uint32_t Fill::colorStops(const ColorStop** colorStops) const noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return 0;
+
+    if (colorStops) *colorStops = impl->colorStops;
+
+    return impl->cnt;
+}
+
+#endif /* _TVG_FILL_CPP_ */
\ No newline at end of file
diff --git a/src/lib/tvgLinearGradient.cpp b/src/lib/tvgLinearGradient.cpp
new file mode 100644 (file)
index 0000000..9ea803d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_LINEAR_GRADIENT_CPP_
+#define _TVG_LINEAR_GRADIENT_CPP_
+
+#include "tvgCommon.h"
+
+/************************************************************************/
+/* Internal Class Implementation                                        */
+/************************************************************************/
+
+struct LinearGradient::Impl
+{
+    float x1, y1, x2, y2;
+};
+
+
+/************************************************************************/
+/* External Class Implementation                                        */
+/************************************************************************/
+
+LinearGradient::LinearGradient():pImpl(make_unique<Impl>())
+{
+    id = FILL_ID_LINEAR;
+}
+
+
+LinearGradient::~LinearGradient()
+{
+}
+
+
+Result LinearGradient::linear(float x1, float y1, float x2, float y2) noexcept
+{
+    if (fabsf(x2 - x1) < FLT_EPSILON && fabsf(y2 - y1) < FLT_EPSILON)
+        return Result::InvalidArguments;
+
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    impl->x1 = x1;
+    impl->y1 = y1;
+    impl->x2 = x2;
+    impl->y2 = y2;
+
+    return Result::Success;
+}
+
+
+Result LinearGradient::linear(float* x1, float* y1, float* x2, float* y2) const noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    if (x1) *x1 = impl->x1;
+    if (x2) *x2 = impl->x2;
+    if (y1) *y1 = impl->y1;
+    if (y2) *y2 = impl->y2;
+
+    return Result::Success;
+}
+
+
+unique_ptr<LinearGradient> LinearGradient::gen() noexcept
+{
+    auto fill = unique_ptr<LinearGradient>(new LinearGradient);
+    assert(fill);
+
+    return fill;
+}
+
+#endif /* _TVG_LINEAR_GRADIENT_CPP_ */
\ No newline at end of file
diff --git a/src/lib/tvgRadialGradient.cpp b/src/lib/tvgRadialGradient.cpp
new file mode 100644 (file)
index 0000000..2447e6f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_RADIAL_GRADIENT_CPP_
+#define _TVG_RADIAL_GRADIENT_CPP_
+
+#include "tvgCommon.h"
+
+/************************************************************************/
+/* Internal Class Implementation                                        */
+/************************************************************************/
+
+struct RadialGradient::Impl
+{
+    float cx, cy, radius;
+};
+
+
+/************************************************************************/
+/* External Class Implementation                                        */
+/************************************************************************/
+
+RadialGradient::RadialGradient():pImpl(make_unique<Impl>())
+{
+    id = FILL_ID_RADIAL;
+}
+
+
+RadialGradient::~RadialGradient()
+{
+}
+
+
+Result RadialGradient::radial(float cx, float cy, float radius) noexcept
+{
+    if (radius < FLT_EPSILON)
+        return Result::InvalidArguments;
+
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    impl->cx = cx;
+    impl->cy = cy;
+    impl->radius = radius;
+
+    return Result::Success;
+}
+
+
+Result RadialGradient::radial(float* cx, float* cy, float* radius) const noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    if (cx) *cx = impl->cx;
+    if (cy) *cy = impl->cy;
+    if (radius) *radius = impl->radius;
+
+    return Result::Success;
+}
+
+
+unique_ptr<RadialGradient> RadialGradient::gen() noexcept
+{
+    auto fill = unique_ptr<RadialGradient>(new RadialGradient);
+    assert(fill);
+
+    return fill;
+}
+
+#endif /* _TVG_RADIAL_GRADIENT_CPP_ */
\ No newline at end of file
index 0e98e17..f89d949 100644 (file)
@@ -28,7 +28,7 @@ struct Surface
     uint32_t w, h;
 };
 
-enum RenderUpdateFlag {None = 0, Path = 1, Fill = 2, Stroke = 4, Transform = 8, All = 16};
+enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, All = 32};
 
 struct RenderTransform
 {
index a1c7a7f..ac2ae82 100644 (file)
@@ -25,7 +25,7 @@
 
 Scene::Scene() : pImpl(make_unique<Impl>())
 {
-    Paint_Id = PAINT_ID_SCENE;
+    id = PAINT_ID_SCENE;
 }
 
 
index 1f1fa14..8596292 100644 (file)
@@ -39,7 +39,7 @@ struct Scene::Impl
     bool clear(RenderMethod& renderer)
     {
         for (auto paint : paints) {
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if (!SCENE_IMPL->clear(renderer)) return false;
@@ -57,7 +57,7 @@ struct Scene::Impl
     bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag)
     {
         for(auto paint: paints) {
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if (!SCENE_IMPL->update(renderer, transform, flag)) return false;
@@ -97,7 +97,7 @@ struct Scene::Impl
     bool render(RenderMethod &renderer)
     {
         for(auto paint: paints) {
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if(!SCENE_IMPL->render(renderer)) return false;
@@ -122,7 +122,7 @@ struct Scene::Impl
             auto w2 = 0.0f;
             auto h2 = 0.0f;
 
-            if (paint->Paint_Id == PAINT_ID_SCENE) {
+            if (paint->id == PAINT_ID_SCENE) {
                 //We know renderer type, avoid dynamic_cast for performance.
                 auto scene = static_cast<Scene*>(paint);
                 if (!SCENE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false;
index 5119ac8..012fcb1 100644 (file)
@@ -32,7 +32,7 @@ constexpr auto PATH_KAPPA = 0.552284f;
 
 Shape :: Shape() : pImpl(make_unique<Impl>())
 {
-    Paint_Id = PAINT_ID_SHAPE;
+    id = PAINT_ID_SHAPE;
 }
 
 
@@ -226,7 +226,29 @@ Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
     impl->color[1] = g;
     impl->color[2] = b;
     impl->color[3] = a;
-    impl->flag |= RenderUpdateFlag::Fill;
+    impl->flag |= RenderUpdateFlag::Color;
+
+    if (impl->fill) {
+        delete(impl->fill);
+        impl->fill = nullptr;
+        impl->flag |= RenderUpdateFlag::Gradient;
+    }
+
+    return Result::Success;
+}
+
+
+Result Shape::fill(unique_ptr<Fill> f) noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return Result::MemoryCorruption;
+
+    auto p = f.release();
+    if (!p) return Result::MemoryCorruption;
+
+    if (impl->fill) delete(impl->fill);
+    impl->fill = p;
+    impl->flag |= RenderUpdateFlag::Gradient;
 
     return Result::Success;
 }
@@ -245,6 +267,14 @@ Result Shape::fill(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcep
     return Result::Success;
 }
 
+const Fill* Shape::fill() const noexcept
+{
+    auto impl = pImpl.get();
+    if (!impl) return nullptr;
+
+    return impl->fill;
+}
+
 
 Result Shape::scale(float factor) noexcept
 {
index 08acb36..4cce022 100644 (file)
 /* Internal Class Implementation                                        */
 /************************************************************************/
 
-struct ShapeFill
-{
-};
-
-
 struct ShapeStroke
 {
     float width = 0;
@@ -46,9 +41,9 @@ struct ShapeStroke
 
 struct Shape::Impl
 {
-    ShapeFill *fill = nullptr;
-    ShapeStroke *stroke = nullptr;
     ShapePath *path = nullptr;
+    Fill *fill = nullptr;
+    ShapeStroke *stroke = nullptr;
     RenderTransform *transform = nullptr;
     uint8_t color[4] = {0, 0, 0, 0};    //r, g, b, a
     uint32_t flag = RenderUpdateFlag::None;
@@ -62,8 +57,8 @@ struct Shape::Impl
     ~Impl()
     {
         if (path) delete(path);
-        if (stroke) delete(stroke);
         if (fill) delete(fill);
+        if (stroke) delete(stroke);
         if (transform) delete(transform);
     }
 
index aded001..a0ef37d 100644 (file)
@@ -1,4 +1,4 @@
-compiler_flags = ['-DTIZENVG_BUILD']
+compiler_flags = ['-DTVG_BUILD']
 
 subdir('lib')
 subdir('examples')
index 2aba05d..353d7b8 100644 (file)
@@ -12,3 +12,4 @@ all:
        gcc -o testSceneTransform testSceneTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
        gcc -o testStroke testStroke.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
        gcc -o testStrokeLine testStrokeLine.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
+       gcc -o testLinearGradient testLinearGradient.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp
new file mode 100644 (file)
index 0000000..4f87cad
--- /dev/null
@@ -0,0 +1,107 @@
+#include <tizenvg.h>
+#include <Elementary.h>
+
+using namespace std;
+
+#define WIDTH 800
+#define HEIGHT 800
+
+static uint32_t buffer[WIDTH * HEIGHT];
+
+void tvgtest()
+{
+    //Initialize TizenVG Engine
+    tvg::Engine::init();
+
+    //Create a Canvas
+    auto canvas = tvg::SwCanvas::gen();
+    canvas->target(buffer, WIDTH, WIDTH, HEIGHT);
+    canvas->reserve(3);                          //reserve 3 shape nodes (optional)
+
+    //Linear Gradient Color Stops
+    tvg::Fill::ColorStop colorStops[3];
+    colorStops[0] = {0, 255, 0, 0, 255};
+    colorStops[1] = {0.5, 255, 255, 255, 255};
+    colorStops[2] = {1, 0, 0, 255, 255};
+
+    //Prepare Round Rectangle
+    auto shape1 = tvg::Shape::gen();
+    shape1->appendRect(0, 0, 400, 400, 50);      //x, y, w, h, cornerRadius
+    shape1->stroke(255, 255, 255, 255);
+    shape1->stroke(2);
+
+    //LinearGradient
+    auto fill = tvg::LinearGradient::gen();
+    fill->linear(0, 0, 400, 400);
+    fill->colorStops(colorStops, 3);
+
+    shape1->fill(move(fill));
+    canvas->push(move(shape1));
+
+
+    //Prepare Circle
+    auto shape2 = tvg::Shape::gen();
+    shape2->appendCircle(400, 400, 200, 200);    //cx, cy, radiusW, radiusH
+    shape2->stroke(255, 255, 255, 255);
+    shape2->stroke(2);
+
+    //LinearGradient
+    auto fill2 = tvg::LinearGradient::gen();
+    fill2->linear(400, 200, 400, 600);
+    fill2->colorStops(colorStops, 3);
+
+    shape2->fill(move(fill2));
+    canvas->push(move(shape2));
+
+
+    //Prepare Ellipse
+    auto shape3 = tvg::Shape::gen();
+    shape3->appendCircle(600, 600, 150, 100);    //cx, cy, radiusW, radiusH
+    shape3->stroke(255, 255, 255, 255);
+    shape3->stroke(2);
+
+    //LinearGradient
+    auto fill3 = tvg::LinearGradient::gen();
+    fill3->linear(450, 600, 750, 600);
+    fill3->colorStops(colorStops, 3);
+
+    shape3->fill(move(fill3));
+    canvas->push(move(shape3));
+
+    //Draw the Shapes onto the Canvas
+    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();
+}