implement basic interfaces

major functions are added for Path specification.
added backend engine infra skeleton.

Change-Id: Ia923b02649cff545fa768ab8538ad7187195826f
This commit is contained in:
Hermet Park 2020-04-01 19:48:37 +09:00
parent bf05660666
commit 02b2d812e4
27 changed files with 541 additions and 36 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
build build
.vscode .vscode
*.swp *.swp
test testShape

View file

@ -50,7 +50,7 @@ private: \
namespace tvg namespace tvg
{ {
class SceneNode; enum class TIZENVG_EXPORT PathCommand { Close, MoveTo, LineTo, CubicTo };
/** /**
@ -65,7 +65,7 @@ class TIZENVG_EXPORT PaintNode
{ {
public: public:
virtual ~PaintNode() {} virtual ~PaintNode() {}
virtual int prepare() = 0; virtual int update() = 0;
}; };
@ -82,7 +82,12 @@ class TIZENVG_EXPORT ShapeNode final : public PaintNode
public: public:
~ShapeNode(); ~ShapeNode();
int prepare() noexcept override; int update() noexcept override;
int appendRect(float x, float y, float w, float h, float radius) noexcept;
int appendCircle(float cx, float cy, float radius) noexcept;
int fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept;
int clear() noexcept;
static std::unique_ptr<ShapeNode> gen(); static std::unique_ptr<ShapeNode> gen();
@ -103,8 +108,9 @@ class TIZENVG_EXPORT SceneNode final : public PaintNode
public: public:
~SceneNode(); ~SceneNode();
int update() noexcept override;
int push(std::unique_ptr<ShapeNode> shape) noexcept; int push(std::unique_ptr<ShapeNode> shape) noexcept;
int prepare() noexcept override;
static std::unique_ptr<SceneNode> gen() noexcept; static std::unique_ptr<SceneNode> gen() noexcept;
@ -128,6 +134,7 @@ public:
int push(std::unique_ptr<PaintNode> paint) noexcept; int push(std::unique_ptr<PaintNode> paint) noexcept;
int clear() noexcept; int clear() noexcept;
int update(PaintNode* node) noexcept;
int draw(bool async = true) noexcept; int draw(bool async = true) noexcept;
int sync() noexcept; int sync() noexcept;

View file

@ -0,0 +1,9 @@
source_file = [
'tvgGlRaster.h',
'tvgGlRaster.cpp',
]
glraster_dep = declare_dependency(
include_directories : include_directories('.'),
sources : source_file
)

View file

@ -0,0 +1,61 @@
/*
* 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_GL_RASTER_CPP_
#define _TVG_GL_RASTER_CPP_
#include "tvgCommon.h"
#include "tvgGlRaster.h"
static GlRaster* pInst = nullptr;
int GlRaster::prepare(ShapeNode *shape)
{
cout << "GlRaster prepare!!" << endl;
return 0;
}
int GlRaster::init()
{
if (pInst) return -1;
pInst = new GlRaster();
assert(pInst);
return 0;
}
int GlRaster::term()
{
if (!pInst) return -1;
cout << "GlRaster(" << pInst << ") destroyed!" << endl;
delete(pInst);
pInst = nullptr;
return 0;
}
GlRaster* GlRaster::inst()
{
assert(pInst);
return pInst;
}
#endif /* _TVG_GL_RASTER_CPP_ */

View file

@ -0,0 +1,38 @@
/*
* 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_GL_RASTER_H_
#define _TVG_GL_RASTER_H_
namespace tvg
{
class GlRaster : public RasterMethod
{
public:
int prepare(ShapeNode *shape) override;
static GlRaster* inst();
static int init();
static int term();
private:
GlRaster(){};
~GlRaster(){};
};
}
#endif /* _TVG_GL_RASTER_H_ */

View file

@ -1,7 +1,11 @@
subdir('sw_engine')
subdir('gl_engine')
source_file = [ source_file = [
'tvgCommon.h', 'tvgCommon.h',
'tvgEngine.cpp', 'tvgEngine.cpp',
'tvgCanvasBase.h', 'tvgCanvasBase.h',
'tvgShapePath.h',
'tvgSwCanvas.cpp', 'tvgSwCanvas.cpp',
'tvgGlCanvas.cpp', 'tvgGlCanvas.cpp',
'tvgSceneNode.cpp', 'tvgSceneNode.cpp',
@ -12,3 +16,4 @@ src_dep = declare_dependency(
include_directories : include_directories('.'), include_directories : include_directories('.'),
sources : source_file sources : source_file
) )

View file

@ -0,0 +1,9 @@
source_file = [
'tvgSwRaster.h',
'tvgSwRaster.cpp',
]
swraster_dep = declare_dependency(
include_directories : include_directories('.'),
sources : source_file
)

View file

@ -0,0 +1,61 @@
/*
* 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_SW_RASTER_CPP_
#define _TVG_SW_RASTER_CPP_
#include "tvgCommon.h"
#include "tvgSwRaster.h"
static SwRaster* pInst = nullptr;
int SwRaster::prepare(ShapeNode *shape)
{
cout << "SWRaster prepare!!" << endl;
return 0;
}
int SwRaster::init()
{
if (pInst) return -1;
pInst = new SwRaster();
assert(pInst);
return 0;
}
int SwRaster::term()
{
if (!pInst) return -1;
cout << "SwRaster(" << pInst << ") destroyed!" << endl;
delete(pInst);
pInst = nullptr;
return 0;
}
SwRaster* SwRaster::inst()
{
assert(pInst);
return pInst;
}
#endif /* _TVG_SW_RASTER_CPP_ */

View file

@ -0,0 +1,38 @@
/*
* 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_SW_RASTER_H_
#define _TVG_SW_RASTER_H_
namespace tvg
{
class SwRaster : public RasterMethod
{
public:
int prepare(ShapeNode *shape) override;
static SwRaster* inst();
static int init();
static int term();
private:
SwRaster(){};
~SwRaster(){};
};
}
#endif /* _TVG_SW_RASTER_H_ */

View file

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
* *
*/ */
#ifndef _TVG_CANVAS_CPP_ #ifndef _TVG_CANVAS_BASE_CPP_
#define _TVG_CANVAS_CPP_ #define _TVG_CANVAS_BASE_CPP_
#include "tvgCommon.h" #include "tvgCommon.h"
@ -25,17 +25,59 @@
struct CanvasBase struct CanvasBase
{ {
vector<PaintNode*> nodes;
RasterMethod* raster;
int push(unique_ptr<PaintNode> paint) CanvasBase(RasterMethod *pRaster):raster(pRaster)
{ {
}
~CanvasBase()
{
clear();
}
int reserve(size_t n)
{
nodes.reserve(n);
return 0; return 0;
} }
int clear() int clear()
{ {
for (auto node : nodes) {
delete(node);
}
nodes.clear();
return 0; return 0;
} }
int push(unique_ptr<PaintNode> paint)
{
PaintNode *node = paint.release();
assert(node);
nodes.push_back(node);
int ret = node->update();
if (ret) return ret;
if (SceneNode *scene = dynamic_cast<SceneNode *>(node)) {
//TODO:
} else if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
return raster->prepare(shape);
}
cout << "What type of PaintNode? = " << node << endl;
return -1;
}
}; };
@ -43,4 +85,4 @@ struct CanvasBase
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
#endif /* _TVG_CANVAS_CPP_ */ #endif /* _TVG_CANVAS_BASE_CPP_ */

View file

@ -24,6 +24,24 @@
using namespace std; using namespace std;
using namespace tvg; using namespace tvg;
using var = float;
namespace tvg
{
struct Point
{
float x, y;
};
class RasterMethod
{
public:
virtual ~RasterMethod() {}
virtual int prepare(ShapeNode *shape) = 0;
};
}
#endif //_TVG_COMMON_H_ #endif //_TVG_COMMON_H_

View file

@ -18,6 +18,8 @@
#define _TVG_ENGINE_CPP_ #define _TVG_ENGINE_CPP_
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgSwRaster.h"
#include "tvgGlRaster.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -30,13 +32,23 @@
int Engine::init() noexcept int Engine::init() noexcept
{ {
return 0; //TODO: Initialize Raster engines by configuration.
int ret = 0;
ret |= SwRaster::init();
ret |= GlRaster::init();
return ret;
} }
int Engine::term() noexcept int Engine::term() noexcept
{ {
return 0; int ret = 0;
ret |= SwRaster::term();
ret |= GlRaster::term();
return ret;
} }
#endif /* _TVG_ENGINE_CPP_ */ #endif /* _TVG_ENGINE_CPP_ */

View file

@ -19,6 +19,7 @@
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgCanvasBase.h" #include "tvgCanvasBase.h"
#include "tvgGlRaster.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -26,7 +27,7 @@
struct GlCanvas::Impl : CanvasBase struct GlCanvas::Impl : CanvasBase
{ {
//... Impl() : CanvasBase(GlRaster::inst()) {}
}; };

View file

@ -57,7 +57,7 @@ int SceneNode :: push(unique_ptr<ShapeNode> shape) noexcept
} }
int SceneNode :: prepare() noexcept int SceneNode :: update() noexcept
{ {
return 0; return 0;

View file

@ -18,6 +18,7 @@
#define _TVG_SHAPE_NODE_CPP_ #define _TVG_SHAPE_NODE_CPP_
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgShapePath.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -33,33 +34,25 @@ struct ShapeStroke
}; };
struct ShapePath
{
};
struct ShapeTransform struct ShapeTransform
{ {
var e[4*4]; float e[4*4];
};
struct ShapeChildren
{
vector<unique_ptr<ShapeNode>> v;
}; };
struct ShapeNode::Impl struct ShapeNode::Impl
{ {
ShapeChildren *children = nullptr;
ShapeTransform *transform = nullptr; ShapeTransform *transform = nullptr;
ShapeFill *fill = nullptr; ShapeFill *fill = nullptr;
ShapeStroke *stroke = nullptr; ShapeStroke *stroke = nullptr;
ShapePath *path = nullptr; ShapePath *path = nullptr;
uint32_t color = 0;
uint32_t id = 0;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
Impl() : path(new ShapePath)
{
}
~Impl() ~Impl()
{ {
@ -67,9 +60,7 @@ struct ShapeNode::Impl
if (stroke) delete(stroke); if (stroke) delete(stroke);
if (fill) delete(fill); if (fill) delete(fill);
if (transform) delete(transform); if (transform) delete(transform);
if (children) delete(children);
} }
}; };
@ -95,10 +86,69 @@ unique_ptr<ShapeNode> ShapeNode::gen()
} }
int ShapeNode :: prepare() noexcept int ShapeNode :: update() noexcept
{
auto impl = pImpl.get();
assert(impl);
return 0;
}
int ShapeNode :: clear() noexcept
{
auto impl = pImpl.get();
assert(impl);
return impl->path->clear();
}
int ShapeNode ::appendCircle(float cx, float cy, float radius) noexcept
{ {
return 0; return 0;
} }
int ShapeNode :: appendRect(float x, float y, float w, float h, float radius) noexcept
{
auto impl = pImpl.get();
assert(impl);
//clamping radius by minimum size
auto min = (w < h ? w : h) * 0.5f;
if (radius > min) radius = min;
//rectangle
if (radius == 0) {
impl->path->reserve(5, 4);
impl->path->moveTo(x, y);
impl->path->lineTo(x + w, y);
impl->path->lineTo(x + w, y + h);
impl->path->lineTo(x, y + h);
impl->path->close();
//circle
} else if (w == h && radius * 2 == w) {
appendCircle(x + (w * 0.5f), y + (h * 0.5f), radius);
} else {
//...
}
return 0;
}
int ShapeNode :: fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept
{
auto impl = pImpl.get();
assert(impl);
impl->color[0] = r;
impl->color[1] = g;
impl->color[2] = b;
impl->color[3] = a;
return 0;
}
#endif //_TVG_SHAPE_NODE_CPP_ #endif //_TVG_SHAPE_NODE_CPP_

149
src/lib/tvgShapePath.h Normal file
View file

@ -0,0 +1,149 @@
/*
* 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_SHAPE_PATH_CPP_
#define _TVG_SHAPE_PATH_CPP_
#include "tvgCommon.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct ShapePath
{
PathCommand* cmds = nullptr;
uint32_t cmdCnt = 0;
uint32_t reservedCmdCnt = 0;
Point *pts = nullptr;
uint32_t ptsCnt = 0;
uint32_t reservedPtsCnt = 0;
~ShapePath()
{
if (cmds) delete(cmds);
if (pts) delete(pts);
}
int reserveCmd(uint32_t cmdCnt)
{
if (cmdCnt > reservedCmdCnt) {
reservedCmdCnt = cmdCnt;
cmds = static_cast<PathCommand*>(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt));
assert(cmds);
}
return 0;
}
int reservePts(uint32_t ptsCnt)
{
if (ptsCnt > reservedPtsCnt) {
reservedPtsCnt = ptsCnt;
pts = static_cast<Point*>(realloc(pts, sizeof(Point) * reservedPtsCnt));
assert(pts);
}
return 0;
}
int reserve(uint32_t cmdCnt, uint32_t ptsCnt)
{
reserveCmd(cmdCnt);
reservePts(ptsCnt);
return 0;
}
int clear()
{
cmdCnt = 0;
ptsCnt = 0;
return 0;
}
int 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)
{
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)
{
if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2);
if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2);
cmds[cmdCnt++] = PathCommand::CubicTo;
pts[ptsCnt++] = {cx1, cy1};
pts[ptsCnt++] = {cx2, cy2};
pts[ptsCnt++] = {x, y};
return 0;
}
int 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(uint32_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;
}
};
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
#endif //_TVG_SHAPE_PATH_CPP_

View file

@ -19,6 +19,8 @@
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgCanvasBase.h" #include "tvgCanvasBase.h"
#include "tvgSwRaster.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -29,6 +31,8 @@ struct SwCanvas::Impl : CanvasBase
uint32_t* buffer = nullptr; uint32_t* buffer = nullptr;
int stride = 0; int stride = 0;
int height = 0; int height = 0;
Impl() : CanvasBase(SwRaster::inst()) {}
}; };
@ -65,6 +69,7 @@ int SwCanvas::push(unique_ptr<PaintNode> paint) noexcept
{ {
auto impl = pImpl.get(); auto impl = pImpl.get();
assert(impl); assert(impl);
return impl->push(move(paint)); return impl->push(move(paint));
} }

View file

@ -3,7 +3,7 @@ compiler_flags = ['-DTIZENVG_BUILD']
subdir('lib') subdir('lib')
subdir('examples') subdir('examples')
tizenvg_lib_dep = [ src_dep ] tizenvg_lib_dep = [ src_dep, swraster_dep, glraster_dep ]
tizenvg_lib = library( tizenvg_lib = library(
'tizenvg', 'tizenvg',

View file

@ -1,2 +1,2 @@
all: all:
gcc -o tvgDrawShape tvgDrawShape.cpp -g -lstdc++ `pkg-config --cflags --libs tizenvg` gcc -o testShape testShape.cpp -g -lstdc++ `pkg-config --cflags --libs tizenvg`

View file

@ -17,8 +17,8 @@ int main(int argc, char **argv)
//Prepare a Shape (Rectangle) //Prepare a Shape (Rectangle)
auto shape1 = tvg::ShapeNode::gen(); auto shape1 = tvg::ShapeNode::gen();
// shape1->rect(0, 0, 400, 400, 0.1); //x, y, w, h, corner_radius shape1->appendRect(0, 0, 400, 400, 0); //x, y, w, h, corner_radius
// shape1->fill(0, 255, 0, 255); //r, g, b, a shape1->fill(0, 255, 0, 255); //r, g, b, a
/* Push the shape into the Canvas drawing list /* Push the shape into the Canvas drawing list
When this shape is into the canvas list, the shape could update & prepare When this shape is into the canvas list, the shape could update & prepare