testSceneTransform
testStroke
testStrokeLine
+testLinearGradient
extern "C" {
#endif
+
#define _TVG_DECLARE_PRIVATE(A) \
protected: \
struct Impl; \
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
{
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);
};
//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;
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;
static std::unique_ptr<Shape> gen() noexcept;
- _TVG_DECLARE_ACCESSOR(Scene);
- _TVG_DECLARE_ACCESSOR(Canvas);
_TVG_DECLARE_PRIVATE(Shape);
+ _TVG_DECLARE_ACCESSORS(Canvas, Scene);
};
static std::unique_ptr<Scene> gen() noexcept;
- _TVG_DECLARE_PRIVATE(Scene);
_TVG_DECLARE_ACCESSOR(Canvas);
+ _TVG_DECLARE_PRIVATE(Scene);
};
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);
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);
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('.'),
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(
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;
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;
{
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;
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;
#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"
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
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
{
Scene::Scene() : pImpl(make_unique<Impl>())
{
- Paint_Id = PAINT_ID_SCENE;
+ id = PAINT_ID_SCENE;
}
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;
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;
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;
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;
Shape :: Shape() : pImpl(make_unique<Impl>())
{
- Paint_Id = PAINT_ID_SHAPE;
+ id = PAINT_ID_SHAPE;
}
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;
}
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
{
/* Internal Class Implementation */
/************************************************************************/
-struct ShapeFill
-{
-};
-
-
struct ShapeStroke
{
float width = 0;
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;
~Impl()
{
if (path) delete(path);
- if (stroke) delete(stroke);
if (fill) delete(fill);
+ if (stroke) delete(stroke);
if (transform) delete(transform);
}
-compiler_flags = ['-DTIZENVG_BUILD']
+compiler_flags = ['-DTVG_BUILD']
subdir('lib')
subdir('examples')
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`
--- /dev/null
+#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();
+}