common scene: implement basic scene behaviors and testScene sample.

Scene is a group(list) of paints.

This class is designed for vector data set which is prepared before canvas.
If a set of vector data is loaded from other resources such as files,
they can construct these data set using Scene.
This then can be pushed into canvas as one completed image.

Scene is supposed to be used in svg loading and storing to tvg specific data format(tvg)

Change-Id: Ie2ffebf74e79c59d99a77880630a54b6baad7eec
This commit is contained in:
Hermet Park 2020-05-05 10:20:50 +09:00
parent 4ff97a6a40
commit 0716d3e774
10 changed files with 207 additions and 40 deletions

1
.gitignore vendored
View file

@ -9,4 +9,5 @@ testPathCopy
testBlending testBlending
testUpdate testUpdate
testDirectUpdate testDirectUpdate
testScene
testTransform testTransform

View file

@ -56,6 +56,7 @@ namespace tvg
enum class TIZENVG_EXPORT PathCommand { Close, MoveTo, LineTo, CubicTo }; enum class TIZENVG_EXPORT PathCommand { Close, MoveTo, LineTo, CubicTo };
class RenderMethod; class RenderMethod;
class Scene;
struct Point struct Point
{ {
@ -107,6 +108,7 @@ public:
virtual int draw(bool async = true) noexcept; virtual int draw(bool async = true) noexcept;
virtual int sync() = 0; virtual int sync() = 0;
_TIZENVG_DECLARE_ACCESSOR(Scene);
_TIZENVG_DECLARE_PRIVATE(Canvas); _TIZENVG_DECLARE_PRIVATE(Canvas);
}; };
@ -149,8 +151,9 @@ public:
static std::unique_ptr<Shape> gen() noexcept; static std::unique_ptr<Shape> gen() noexcept;
_TIZENVG_DECLARE_PRIVATE(Shape); _TIZENVG_DECLARE_ACCESSOR(Scene);
_TIZENVG_DECLARE_ACCESSOR(Canvas); _TIZENVG_DECLARE_ACCESSOR(Canvas);
_TIZENVG_DECLARE_PRIVATE(Shape);
}; };
@ -167,7 +170,8 @@ class TIZENVG_EXPORT Scene final : public Paint
public: public:
~Scene(); ~Scene();
int push(std::unique_ptr<Shape> shape) noexcept; int push(std::unique_ptr<Paint> shape) noexcept;
int reserve(size_t size) noexcept;
int rotate(float degree) noexcept override; int rotate(float degree) noexcept override;
int scale(float factor) noexcept override; int scale(float factor) noexcept override;
@ -179,6 +183,7 @@ public:
static std::unique_ptr<Scene> gen() noexcept; static std::unique_ptr<Scene> gen() noexcept;
_TIZENVG_DECLARE_PRIVATE(Scene); _TIZENVG_DECLARE_PRIVATE(Scene);
_TIZENVG_DECLARE_ACCESSOR(Canvas);
}; };

View file

@ -7,6 +7,7 @@ source_file = [
'tvgShapePath.h', 'tvgShapePath.h',
'tvgShapeImpl.h', 'tvgShapeImpl.h',
'tvgCanvasImpl.h', 'tvgCanvasImpl.h',
'tvgSceneImpl.h',
'tvgEngine.cpp', 'tvgEngine.cpp',
'tvgCanvas.cpp', 'tvgCanvas.cpp',
'tvgSwCanvas.cpp', 'tvgSwCanvas.cpp',

View file

@ -18,7 +18,6 @@
#define _TVG_CANVAS_IMPL_H_ #define _TVG_CANVAS_IMPL_H_
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgShapeImpl.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -55,9 +54,9 @@ struct Canvas::Impl
for (auto paint : paints) { for (auto paint : paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) { if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl; if (!SCENE_IMPL->clear(*renderer)) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) { } else if (auto shape = dynamic_cast<Shape*>(paint)) {
if (!shape->pImpl.get()->dispose(*shape, *renderer)) return -1; if (!SHAPE_IMPL->dispose(*shape, *renderer)) return -1;
} }
delete(paint); delete(paint);
} }
@ -72,9 +71,9 @@ struct Canvas::Impl
for(auto paint: paints) { for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) { if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl; if (!SCENE_IMPL->update(*renderer)) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) { } else if (auto shape = dynamic_cast<Shape*>(paint)) {
if (!shape->pImpl.get()->update(*shape, *renderer)) return -1; if (!SHAPE_IMPL->update(*shape, *renderer)) return -1;
} }
} }
return 0; return 0;
@ -85,9 +84,9 @@ struct Canvas::Impl
assert(renderer); assert(renderer);
if (auto scene = dynamic_cast<Scene*>(paint)) { if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl; if (!SCENE_IMPL->update(*renderer)) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) { } else if (auto shape = dynamic_cast<Shape*>(paint)) {
if (!shape->pImpl.get()->update(*shape, *renderer)) return -1; if (!SHAPE_IMPL->update(*shape, *renderer)) return -1;
} }
return 0; return 0;
} }
@ -101,9 +100,9 @@ struct Canvas::Impl
for(auto paint: paints) { for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) { if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl; if(!SCENE_IMPL->render(*renderer)) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) { } else if (auto shape = dynamic_cast<Shape*>(paint)) {
if(!shape->pImpl.get()->render(*shape, *renderer)) return -1; if(!SHAPE_IMPL->render(*shape, *renderer)) return -1;
} }
} }
return 0; return 0;

View file

@ -24,9 +24,16 @@
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include "tizenvg.h" #include "tizenvg.h"
#include "tvgRenderCommon.h"
using namespace std; using namespace std;
using namespace tvg; using namespace tvg;
#define SCENE_IMPL scene->pImpl.get()
#define SHAPE_IMPL shape->pImpl.get()
#include "tvgRenderCommon.h"
#include "tvgShapePath.h"
#include "tvgShapeImpl.h"
#include "tvgSceneImpl.h"
#endif //_TVG_COMMON_H_ #endif //_TVG_COMMON_H_

View file

@ -19,17 +19,6 @@
#include "tvgCommon.h" #include "tvgCommon.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct Scene::Impl
{
};
/************************************************************************/ /************************************************************************/
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
@ -42,7 +31,6 @@ Scene::Scene() : pImpl(make_unique<Impl>())
Scene::~Scene() Scene::~Scene()
{ {
cout << "Scene(" << this << ") destroyed!" << endl;
} }
@ -52,8 +40,26 @@ unique_ptr<Scene> Scene::gen() noexcept
} }
int Scene::push(unique_ptr<Shape> shape) noexcept int Scene::push(unique_ptr<Paint> paint) noexcept
{ {
auto impl = pImpl.get();
assert(impl);
auto p = paint.release();
assert(p);
impl->paints.push_back(p);
return 0;
}
int Scene::reserve(size_t size) noexcept
{
auto impl = pImpl.get();
assert(impl);
impl->paints.reserve(size);
return 0; return 0;
} }

76
src/lib/tvgSceneImpl.h Normal file
View file

@ -0,0 +1,76 @@
/*
* 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_SCENE_IMPL_H_
#define _TVG_SCENE_IMPL_H_
#include "tvgCommon.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct Scene::Impl
{
vector<Paint*> paints;
~Impl()
{
//Are you sure clear() prior to this?
assert(paints.empty());
}
bool clear(RenderMethod& renderer)
{
for (auto paint : paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
if (!SCENE_IMPL->clear(renderer)) return false;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
if (!SHAPE_IMPL->dispose(*shape, renderer)) return false;
}
delete(paint);
}
paints.clear();
return true;
}
bool update(RenderMethod &renderer)
{
for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
if (!SCENE_IMPL->update(renderer)) return false;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
if (!SHAPE_IMPL->update(*shape, renderer)) return false;
}
}
return true;
}
bool render(RenderMethod &renderer)
{
for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
if(!SCENE_IMPL->render(renderer)) return false;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
if(!SHAPE_IMPL->render(*shape, renderer)) return false;
}
}
return true;
}
};
#endif //_TVG_SCENE_IMPL_H_

View file

@ -18,7 +18,6 @@
#define _TVG_SHAPE_IMPL_H_ #define _TVG_SHAPE_IMPL_H_
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgShapePath.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */

View file

@ -7,4 +7,5 @@ all:
gcc -o testBlending testBlending.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg` gcc -o testBlending testBlending.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testUpdate testUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg` gcc -o testUpdate testUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testDirectUpdate testDirectUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg` gcc -o testDirectUpdate testDirectUpdate.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testScene testScene.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`
gcc -o testTransform testTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg` gcc -o testTransform testTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary tizenvg`

View file

@ -1,4 +1,5 @@
#include <tizenvg.h> #include <tizenvg.h>
#include <Elementary.h>
using namespace std; using namespace std;
@ -7,39 +8,79 @@ using namespace std;
static uint32_t buffer[WIDTH * HEIGHT]; static uint32_t buffer[WIDTH * HEIGHT];
int main(int argc, char **argv) void tvgtest()
{ {
//Initialize TizenVG Engine //Initialize TizenVG Engine
tvg::Engine::init(); tvg::Engine::init();
//Create a Canvas //Create a Canvas
auto canvas = tvg::SwCanvas::gen(buffer, WIDTH, HEIGHT); auto canvas = tvg::SwCanvas::gen();
canvas->target(buffer, WIDTH, WIDTH, HEIGHT);
//Create a Scene //Create a Scene
auto scene = tvg::Scene::gen(); auto scene = tvg::Scene::gen();
scene->reserve(3); //reserve 3 shape nodes (optional) scene->reserve(3); //reserve 3 shape nodes (optional)
//Shape1 //Prepare Round Rectangle
auto shape1 = tvg::Shape::gen(); auto shape1 = tvg::Shape::gen();
shape1->rect(0, 0, 400, 400, 0.1); shape1->appendRect(0, 0, 400, 400, 50); //x, y, w, h, cornerRadius
shape1->fill(255, 0, 0, 255); shape1->fill(0, 255, 0, 255); //r, g, b, a
shape1->rotate(0, 0, 45); //axis x, y, z
scene->push(move(shape1)); scene->push(move(shape1));
//Shape2 //Prepare Circle
auto shape2 = tvg::Shape::gen(); auto shape2 = tvg::Shape::gen();
shape2->rect(0, 0, 400, 400, 0.1); shape2->appendCircle(400, 400, 200, 200); //cx, cy, radiusW, radiusH
shape2->fill(0, 255, 0, 255); shape2->fill(255, 255, 0, 255); //r, g, b, a
shape2->transform(matrix); //by matrix (var matrix[4 * 4];)
scene->push(move(shape2)); scene->push(move(shape2));
//Shape3 //Prepare Ellipse
auto shape3 = tvg::Shape::gen(); auto shape3 = tvg::Shape::gen();
shape3->rect(0, 0, 400, 400, 0.1); shape3->appendCircle(600, 600, 150, 100); //cx, cy, radiusW, radiusH
shape3->fill(0, 0, 255, 255); shape3->fill(0, 255, 255, 255); //r, g, b, a
shape3->origin(100, 100); //offset
scene->push(move(shape3)); scene->push(move(shape3));
//Create another Scene
auto scene2 = tvg::Scene::gen();
scene2->reserve(2); //reserve 2 shape nodes (optional)
//Star
auto shape4 = tvg::Shape::gen();
//Appends Paths
shape4->moveTo(199, 34);
shape4->lineTo(253, 143);
shape4->lineTo(374, 160);
shape4->lineTo(287, 244);
shape4->lineTo(307, 365);
shape4->lineTo(199, 309);
shape4->lineTo(97, 365);
shape4->lineTo(112, 245);
shape4->lineTo(26, 161);
shape4->lineTo(146, 143);
shape4->close();
shape4->fill(0, 0, 255, 255);
scene2->push(move(shape4));
//Circle
auto shape5 = tvg::Shape::gen();
auto cx = 550.0f;
auto cy = 550.0f;
auto radius = 125.0f;
auto halfRadius = radius * 0.552284f;
//Append Paths
shape5->moveTo(cx, cy - radius);
shape5->cubicTo(cx + halfRadius, cy - radius, cx + radius, cy - halfRadius, cx + radius, cy);
shape5->cubicTo(cx + radius, cy + halfRadius, cx + halfRadius, cy + radius, cx, cy+ radius);
shape5->cubicTo(cx - halfRadius, cy + radius, cx - radius, cy + halfRadius, cx - radius, cy);
shape5->cubicTo(cx - radius, cy - halfRadius, cx - halfRadius, cy - radius, cx, cy - radius);
shape5->fill(255, 0, 0, 255);
scene2->push(move(shape5));
//Push scene2 onto the scene
scene->push(move(scene2));
//Draw the Scene onto the Canvas //Draw the Scene onto the Canvas
canvas->push(move(scene)); canvas->push(move(scene));
canvas->draw(); canvas->draw();
@ -48,3 +89,34 @@ int main(int argc, char **argv)
//Terminate TizenVG Engine //Terminate TizenVG Engine
tvg::Engine::term(); 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();
}