From f9fcd5874471b0c3bcb4eeedbd7d9abd134e52b3 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Sat, 4 Apr 2020 01:14:11 +0900 Subject: [PATCH] implement shape basics sw engine. Change-Id: I93788f40f7c4f59bcc9ab4dff9127bcb4e6c1466 --- inc/tizenvg.h | 11 ++- src/lib/gl_engine/tvgGlRaster.cpp | 17 +++- src/lib/gl_engine/tvgGlRaster.h | 2 +- src/lib/sw_engine/tvgSwCommon.h | 30 +++--- src/lib/sw_engine/tvgSwRaster.cpp | 21 +++- src/lib/sw_engine/tvgSwRaster.h | 2 +- src/lib/sw_engine/tvgSwShape.cpp | 202 +++++++++++++++++++++++++++++--------- src/lib/tvgCanvasBase.h | 8 +- src/lib/tvgCommon.h | 2 +- src/lib/tvgShapeNode.cpp | 22 ++++- src/lib/tvgShapePath.h | 16 +-- 11 files changed, 248 insertions(+), 85 deletions(-) diff --git a/inc/tizenvg.h b/inc/tizenvg.h index c9abb03..2c43a85 100644 --- a/inc/tizenvg.h +++ b/inc/tizenvg.h @@ -91,13 +91,16 @@ public: ~ShapeNode(); int update(RasterMethod* engine) noexcept override; + int clear() noexcept; 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; - int pathCommands(const PathCommand** cmds) noexcept; - int pathCoords(const Point** pts) noexcept; + + int fill(size_t r, size_t g, size_t b, size_t a) noexcept; + + int pathCommands(const PathCommand** cmds) const noexcept; + int pathCoords(const Point** pts) const noexcept; + int fill(size_t* r, size_t* g, size_t* b, size_t* a) const noexcept; static std::unique_ptr gen() noexcept; diff --git a/src/lib/gl_engine/tvgGlRaster.cpp b/src/lib/gl_engine/tvgGlRaster.cpp index f99205b..c3bb407 100644 --- a/src/lib/gl_engine/tvgGlRaster.cpp +++ b/src/lib/gl_engine/tvgGlRaster.cpp @@ -23,11 +23,22 @@ static GlRaster* pInst = nullptr; -void* GlRaster::prepare(ShapeNode* shape, void* data) +struct GlShape { - cout << "GlRaster prepare!!" << endl; + //TODO: +}; - return nullptr; + +void* GlRaster::prepare(const ShapeNode& shape, void* data) +{ + //prepare shape data + GlShape* sdata = static_cast(data); + if (!sdata) { + sdata = static_cast(calloc(1, sizeof(GlShape))); + assert(sdata); + } + + return sdata; } diff --git a/src/lib/gl_engine/tvgGlRaster.h b/src/lib/gl_engine/tvgGlRaster.h index f0db8bf..d6da2fe 100644 --- a/src/lib/gl_engine/tvgGlRaster.h +++ b/src/lib/gl_engine/tvgGlRaster.h @@ -23,7 +23,7 @@ namespace tvg class GlRaster : public RasterMethod { public: - void* prepare(ShapeNode* shape, void* data) override; + void* prepare(const ShapeNode& shape, void* data) override; static GlRaster* inst(); static int init(); static int term(); diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index e77c3fa..a153102 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -20,29 +20,31 @@ #include "tvgCommon.h" using namespace tvg; -using SwPos = signed long; -struct SwVector -{ - SwPos x; - SwPos y; -}; +constexpr auto SW_CURVE_TAG_ON = 1; +constexpr auto SW_CURVE_TAG_CUBIC = 2; struct SwOutline { - short* cntrs; /* the contour end points */ - short cntrsCnt; /* number of contours in glyph */ - SwVector* pts; /* the outline's points */ - short ptsCnt; /* number of points in the glyph */ - char* tags; /* the points flags */ - int flags; /* outline masks */ + size_t* cntrs; //the contour end points + size_t cntrsCnt; //number of contours in glyph + size_t reservedCntrsCnt; + Point* pts; //the outline's points + size_t ptsCnt; //number of points in the glyph + size_t reservedPtsCnt; + char* tags; //the points flags + size_t flags; //outline masks }; struct SwShape { - SwOutline outline; +// SwRleRaster raster; + SwOutline* outline; }; -bool shapeGenOutline(ShapeNode *shape, SwShape* sdata); +bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata); +void shapeDelOutline(const ShapeNode& shape, SwShape& sdata); +bool shapeGenRle(const ShapeNode& shape, SwShape& sdata); +bool shapeUpdateBBox(const ShapeNode& shape, SwShape& sdata); #endif /* _TVG_SW_COMMON_H_ */ diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index 88f81b2..a1afdda 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -26,16 +26,31 @@ static SwRaster* pInst = nullptr; +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ -void* SwRaster::prepare(ShapeNode *shape, void* data) +void* SwRaster::prepare(const ShapeNode& shape, void* data) { - SwShape *sdata = static_cast(data); + //prepare shape data + SwShape* sdata = static_cast(data); if (!sdata) { sdata = static_cast(calloc(1, sizeof(SwShape))); assert(sdata); } - bool closed = shapeGenOutline(shape, sdata); + //invisible? + size_t alpha; + shape.fill(nullptr, nullptr, nullptr, &alpha); + if (alpha == 0) return sdata; + + if (!shapeGenOutline(shape, *sdata)) return sdata; + + //TODO: From below sequence starts threading? + if (!shapeGenRle(shape, *sdata)) return sdata; + if (!shapeUpdateBBox(shape, *sdata)) return sdata; + + shapeDelOutline(shape, *sdata); return sdata; } diff --git a/src/lib/sw_engine/tvgSwRaster.h b/src/lib/sw_engine/tvgSwRaster.h index e16837e..07fc274 100644 --- a/src/lib/sw_engine/tvgSwRaster.h +++ b/src/lib/sw_engine/tvgSwRaster.h @@ -20,7 +20,7 @@ class SwRaster : public RasterMethod { public: - void* prepare(ShapeNode* shape, void* data) override; + void* prepare(const ShapeNode& shape, void* data) override; static SwRaster* inst(); static int init(); static int term(); diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index f9826e8..364ac3e 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -19,86 +19,188 @@ #include "tvgSwCommon.h" -static void growOutlineContour(SwShape *sdata, size_t n) -{ - sdata->outline.cntrsCnt = n; +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ +static void growOutlineContour(SwOutline& outline, size_t n) +{ if (n == 0) { - free(sdata->outline.cntrs); - sdata->outline.cntrs = nullptr; + free(outline.cntrs); + outline.cntrs = nullptr; + outline.cntrsCnt = 0; + outline.reservedCntrsCnt = 0; return; } - sdata->outline.cntrs = static_cast(realloc(sdata->outline.cntrs, n * sizeof(short))); - assert(sdata->outline.cntrs); + if (outline.reservedCntrsCnt >= outline.cntrsCnt + n) return; + + cout << "Grow Cntrs: " << outline.reservedCntrsCnt << " -> " << outline.cntrsCnt + n << endl;; + outline.reservedCntrsCnt = n; + outline.cntrs = static_cast(realloc(outline.cntrs, n * sizeof(size_t))); + assert(outline.cntrs); } -static void growOutlinePoint(SwShape *sdata, size_t n) +static void growOutlinePoint(SwOutline& outline, size_t n) { - sdata->outline.ptsCnt = n; - if (n == 0) { - free(sdata->outline.pts); - sdata->outline.pts = nullptr; - free(sdata->outline.tags); - sdata->outline.tags = nullptr; + free(outline.pts); + outline.pts = nullptr; + free(outline.tags); + outline.tags = nullptr; + outline.reservedPtsCnt = 0; + outline.ptsCnt = 0; return; } - sdata->outline.pts = static_cast(realloc(sdata->outline.pts, n * sizeof(SwVector))); - assert(sdata->outline.pts); - sdata->outline.tags = static_cast(realloc(sdata->outline.tags, n * sizeof(char))); - assert(sdata->outline.tags); + if (outline.reservedPtsCnt >= outline.ptsCnt + n) return; + + cout << "Grow Pts: " << outline.reservedPtsCnt << " -> " << outline.ptsCnt + n << endl; + outline.reservedPtsCnt = n; + outline.pts = static_cast(realloc(outline.pts, n * sizeof(Point))); + assert(outline.pts); + outline.tags = static_cast(realloc(outline.tags, n * sizeof(char))); + assert(outline.tags); } -static void outlineEnd(SwShape* sdata) +static void outlineEnd(SwOutline& outline) { - //grow contour 1 + growOutlineContour(outline, 1); + if (outline.ptsCnt > 0) { + outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1; + ++outline.cntrs; + } } -static void outlineMoveTo(SwShape* sdata, const Point* pt) +static void outlineMoveTo(SwOutline& outline, const Point* pt) { - //grow pts 1, - //grow contour 1 + assert(pt); + + growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = *pt; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON; + + if (outline.ptsCnt > 0) { + growOutlineContour(outline, 1); + outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1; + ++outline.cntrsCnt; + } + + ++outline.ptsCnt; } -static void outlineLineTo(SwShape* sdata, const Point* pt) +static void outlineLineTo(SwOutline& outline, const Point* pt) { - //grow pts 1 + assert(pt); + + growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = *pt; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON; + + ++outline.ptsCnt; } -static void outlineCubicTo(SwShape* sdata, const Point* ctrl1, const Point* ctrl2, const Point* pt) +static void outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* pt) { - //grow pts 3 + assert(ctrl1 && ctrl2 && pt); + + growOutlinePoint(outline, 3); + + outline.pts[outline.ptsCnt] = *ctrl1; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_CUBIC; + ++outline.ptsCnt; + + outline.pts[outline.ptsCnt] = *ctrl2; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_CUBIC; + ++outline.ptsCnt; + + outline.pts[outline.ptsCnt] = *ctrl1; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON; + ++outline.ptsCnt; } -static void outlineClose(SwShape* sdata) +static bool outlineClose(SwOutline& outline) { - //grow pts 1 + size_t i = 0; + + if (outline.cntrsCnt > 0) { + i = outline.cntrs[outline.cntrsCnt - 1] + 1; + } else { + i = 0; //First Path + } + + //Make sure there is at least one point in the current path + if (outline.ptsCnt == i) return false; + + //Close the path + growOutlinePoint(outline, 1); + + outline.pts[outline.ptsCnt] = outline.pts[i]; + outline.tags[outline.ptsCnt] = SW_CURVE_TAG_ON; + ++outline.ptsCnt; + + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +bool shapeGenRle(const ShapeNode& shape, SwShape& sdata) +{ + //TODO: rle + + return true; +} + + +bool shapeUpdateBBox(const ShapeNode& shape, SwShape& sdata) +{ + //TODO: + return true; } -bool shapeGenOutline(ShapeNode *shape, SwShape* sdata) +void shapeDelOutline(const ShapeNode& shape, SwShape& sdata) { - bool closed = false; + if (!sdata.outline) return; + SwOutline* outline = sdata.outline; + if (outline->cntrs) free(outline->cntrs); + if (outline->pts) free(outline->pts); + if (outline->tags) free(outline->tags); + free(outline); + + sdata.outline = nullptr; +} + + +bool shapeGenOutline(const ShapeNode& shape, SwShape& sdata) +{ const PathCommand* cmds = nullptr; - auto cmdCnt = shape->pathCommands(&cmds); + auto cmdCnt = shape.pathCommands(&cmds); const Point* pts = nullptr; - shape->pathCoords(&pts); + auto ptsCnt = shape.pathCoords(&pts); + + //No actual shape data + if (cmdCnt == 0 || ptsCnt == 0) return false; - //reservation + //smart reservation auto outlinePtsCnt = 0; auto outlineCntrsCnt = 0; +// auto closed = false; for (auto i = 0; i < cmdCnt; ++i) { - switch(*cmds) { + switch(*(cmds + i)) { case PathCommand::Close: { ++outlinePtsCnt; break; @@ -119,30 +221,40 @@ bool shapeGenOutline(ShapeNode *shape, SwShape* sdata) } } - ++outlinePtsCnt; //for close + ++outlinePtsCnt; //for close + ++outlineCntrsCnt; //for end + + SwOutline* outline = sdata.outline; - growOutlinePoint(sdata, outlinePtsCnt); - growOutlineContour(sdata, outlineCntrsCnt); + if (!outline) { + outline = static_cast(calloc(1, sizeof(SwOutline))); + assert(outline); + } else { + cout << "Outline was already allocated? How?" << endl; + } + + growOutlinePoint(*outline, outlinePtsCnt); + growOutlineContour(*outline, outlineCntrsCnt); //Generate Outlines while (cmdCnt-- > 0) { switch(*cmds) { case PathCommand::Close: { - outlineClose(sdata); + outlineClose(*outline); break; } case PathCommand::MoveTo: { - outlineMoveTo(sdata, pts); + outlineMoveTo(*outline, pts); ++pts; break; } case PathCommand::LineTo: { - outlineLineTo(sdata, pts); + outlineLineTo(*outline, pts); ++pts; break; } case PathCommand::CubicTo: { - outlineCubicTo(sdata, pts, pts + 1, pts + 2); + outlineCubicTo(*outline, pts, pts + 1, pts + 2); pts += 3; break; } @@ -150,9 +262,11 @@ bool shapeGenOutline(ShapeNode *shape, SwShape* sdata) ++cmds; } - outlineEnd(sdata); + outlineEnd(*outline); + + sdata.outline = outline; - return closed; + return true; } diff --git a/src/lib/tvgCanvasBase.h b/src/lib/tvgCanvasBase.h index 48fd7bd..f200d29 100644 --- a/src/lib/tvgCanvasBase.h +++ b/src/lib/tvgCanvasBase.h @@ -61,13 +61,17 @@ struct CanvasBase assert(node); nodes.push_back(node); - +#if 0 if (SceneNode *scene = dynamic_cast(node)) { } else if (ShapeNode *shape = dynamic_cast(node)) { return shape->update(raster); } - +#else + if (ShapeNode *shape = dynamic_cast(node)) { + return shape->update(raster); + } +#endif cout << "What type of PaintNode? = " << node << endl; return -1; diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index 5d7f85c..dfd908f 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -32,7 +32,7 @@ class RasterMethod { public: virtual ~RasterMethod() {} - virtual void* prepare(ShapeNode* shape, void* data) = 0; + virtual void* prepare(const ShapeNode& shape, void* data) = 0; }; } diff --git a/src/lib/tvgShapeNode.cpp b/src/lib/tvgShapeNode.cpp index b3726f0..26735c0 100644 --- a/src/lib/tvgShapeNode.cpp +++ b/src/lib/tvgShapeNode.cpp @@ -89,7 +89,7 @@ int ShapeNode :: update(RasterMethod* engine) noexcept auto impl = pImpl.get(); assert(impl); - impl->edata = engine->prepare(this, impl->edata); + impl->edata = engine->prepare(*this, impl->edata); if (impl->edata) return 0; return - 1; } @@ -104,7 +104,7 @@ int ShapeNode :: clear() noexcept } -int ShapeNode :: pathCommands(const PathCommand** cmds) noexcept +int ShapeNode :: pathCommands(const PathCommand** cmds) const noexcept { auto impl = pImpl.get(); assert(impl && cmds); @@ -115,7 +115,7 @@ int ShapeNode :: pathCommands(const PathCommand** cmds) noexcept } -int ShapeNode :: pathCoords(const Point** pts) noexcept +int ShapeNode :: pathCoords(const Point** pts) const noexcept { auto impl = pImpl.get(); assert(impl && pts); @@ -160,7 +160,7 @@ int ShapeNode :: appendRect(float x, float y, float w, float h, float radius) no } -int ShapeNode :: fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept +int ShapeNode :: fill(size_t r, size_t g, size_t b, size_t a) noexcept { auto impl = pImpl.get(); assert(impl); @@ -173,4 +173,18 @@ int ShapeNode :: fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept return 0; } + +int ShapeNode :: fill(size_t* r, size_t* g, size_t* b, size_t* a) const noexcept +{ + auto impl = pImpl.get(); + assert(impl); + + if (r) *r = impl->color[0]; + if (g) *g = impl->color[0]; + if (b) *b = impl->color[0]; + if (a) *a = impl->color[0]; + + return 0; +} + #endif //_TVG_SHAPE_NODE_CPP_ diff --git a/src/lib/tvgShapePath.h b/src/lib/tvgShapePath.h index eb3849e..0d11cdf 100644 --- a/src/lib/tvgShapePath.h +++ b/src/lib/tvgShapePath.h @@ -26,12 +26,12 @@ struct ShapePath { PathCommand* cmds = nullptr; - uint32_t cmdCnt = 0; - uint32_t reservedCmdCnt = 0; + size_t cmdCnt = 0; + size_t reservedCmdCnt = 0; Point *pts = nullptr; - uint32_t ptsCnt = 0; - uint32_t reservedPtsCnt = 0; + size_t ptsCnt = 0; + size_t reservedPtsCnt = 0; ~ShapePath() @@ -40,7 +40,7 @@ struct ShapePath if (pts) delete(pts); } - int reserveCmd(uint32_t cmdCnt) + int reserveCmd(size_t cmdCnt) { if (cmdCnt > reservedCmdCnt) { reservedCmdCnt = cmdCnt; @@ -50,7 +50,7 @@ struct ShapePath return 0; } - int reservePts(uint32_t ptsCnt) + int reservePts(size_t ptsCnt) { if (ptsCnt > reservedPtsCnt) { reservedPtsCnt = ptsCnt; @@ -60,7 +60,7 @@ struct ShapePath return 0; } - int reserve(uint32_t cmdCnt, uint32_t ptsCnt) + int reserve(size_t cmdCnt, size_t ptsCnt) { reserveCmd(cmdCnt); reservePts(ptsCnt); @@ -126,7 +126,7 @@ struct ShapePath Point min = { pts[0].x, pts[0].y }; Point max = { pts[0].x, pts[0].y }; - for(uint32_t i = 1; i <= ptsCnt; ++i) { + 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; -- 2.7.4