From 5fdc1f7fc86b9a9667741491c63d060ecfb15dd6 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 24 Jul 2020 11:03:20 +0900 Subject: [PATCH 01/16] sw_engine: revise stroke scaling logic. previous fast track logic is useless, it actually doesn't helpful for performance, just increase the code complexity. Change-Id: Ib6ad204edfb241d74c41413dfec7ab42fb02af81 --- src/lib/sw_engine/tvgSwCommon.h | 4 +--- src/lib/sw_engine/tvgSwStroke.cpp | 27 ++++++--------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index bad159b..5f7ec46 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -153,13 +153,11 @@ struct SwStroke SwStrokeBorder borders[2]; - float sx; - float sy; + float sx, sy; bool firstPt; bool openSubPath; bool handleWideStrokes; - bool postScale; }; struct SwDashStroke diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index 53fae90..15cbf02 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -36,10 +36,8 @@ static inline SwFixed SIDE_TO_ROTATE(const int32_t s) static inline void SCALE(SwStroke& stroke, SwPoint& pt) { - if (stroke.postScale) { - pt.x = pt.x * stroke.sx; - pt.y = pt.y * stroke.sy; - } + pt.x *= stroke.sx; + pt.y *= stroke.sy; } @@ -548,7 +546,6 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl SwPoint delta = {alen, 0}; mathRotate(delta, beta); - SCALE(stroke, delta); delta += _start; //circumnavigate the negative sector backwards @@ -848,26 +845,14 @@ void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); - auto scale = 1.0f; - if (transform) { - //Fast Track: if x/y scale factor is identical, we can scale width size simply. - auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); - auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); - if (fabsf(sx - sy) < FLT_EPSILON) { - scale = sx; - stroke.postScale = false; - //Try scaling stroke with normal approach. - } else { - stroke.postScale = true; - stroke.sx = sx; - stroke.sy = sy; - } + stroke.sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + stroke.sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); } else { - stroke.postScale = false; + stroke.sx = stroke.sy = 1.0f; } - stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5 * scale); + stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); stroke.cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... -- 2.7.4 From 76a7c900bebceb7735712366cb7571b2fa105874 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 23 Jul 2020 20:56:05 +0900 Subject: [PATCH 02/16] sw_engine gradient: support x/y scale for radial gradient Change-Id: Id725637e261642d0e92d100c73841278b7f44c1c --- src/lib/sw_engine/tvgSwCommon.h | 2 ++ src/lib/sw_engine/tvgSwFill.cpp | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 5f7ec46..469ce0f 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -193,6 +193,8 @@ struct SwFill uint32_t* ctable; FillSpread spread; + float sx, sy; + bool translucent; }; diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 43514bc..0ac9383 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -130,12 +130,25 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr if (radial->radial(&fill->radial.cx, &fill->radial.cy, &radius) != Result::Success) return false; if (radius < FLT_EPSILON) return true; + fill->sx = 1.0f; + fill->sy = 1.0f; + if (transform) { auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e13; auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e23; fill->radial.cx = tx; fill->radial.cy = ty; - radius *= transform->e33; + + auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); + + //FIXME; Scale + Rotation is not working properly + radius *= sx; + + if (fabsf(sx - sy) > FLT_EPSILON) { + fill->sx = sx; + fill->sy = sy; + } } fill->radial.a = radius * radius; @@ -190,8 +203,8 @@ void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, if (fill->radial.a < FLT_EPSILON) return; //Rotation - auto rx = x + 0.5f - fill->radial.cx; - auto ry = y + 0.5f - fill->radial.cy; + auto rx = (x + 0.5f - fill->radial.cx) * fill->sy; + auto ry = (y + 0.5f - fill->radial.cy) * fill->sx; auto inv2a = fill->radial.inv2a; auto rxy = rx * rx + ry * ry; auto rxryPlus = 2 * rx; -- 2.7.4 From bee94d48fee5c2d17716d63f5b15d79c45feab36 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 24 Jul 2020 21:09:24 +0900 Subject: [PATCH 03/16] sw_engine gradient: support x/y scale for linear gradient Change-Id: Ic58e7cc61a3c90307b6cfb629eb8af69b75fb903 --- src/lib/sw_engine/tvgSwFill.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 0ac9383..266acaa 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -96,16 +96,18 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; if (transform) { + auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); auto cx = (x2 - x1) * 0.5f + x1; auto cy = (y2 - y1) * 0.5f + y1; auto dx = x1 - cx; auto dy = y1 - cy; - x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; - y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; + x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + (cx * sx); + y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + (cy * sy); dx = x2 - cx; dy = y2 - cy; - x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; - y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; + x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + (cx * sx); + y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + (cy * sy); } fill->linear.dx = x2 - x1; @@ -116,7 +118,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dx /= fill->linear.len; fill->linear.dy /= fill->linear.len; - fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; + fill->linear.offset = -fill->linear.dx * x1 -fill->linear.dy * y1; return true; } @@ -158,20 +160,23 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr } -static inline uint32_t _clamp(const SwFill* fill, uint32_t pos) +static inline uint32_t _clamp(const SwFill* fill, int32_t pos) { switch (fill->spread) { case FillSpread::Pad: { if (pos >= GRADIENT_STOP_SIZE) pos = GRADIENT_STOP_SIZE - 1; + else if (pos < 0) pos = 0; break; } case FillSpread::Repeat: { + if (pos < 0) pos = GRADIENT_STOP_SIZE + pos; pos = pos % GRADIENT_STOP_SIZE; break; } case FillSpread::Reflect: { auto limit = GRADIENT_STOP_SIZE * 2; pos = pos % limit; + if (pos < 0) pos = limit + pos; if (pos >= GRADIENT_STOP_SIZE) pos = (limit - pos - 1); break; } @@ -180,16 +185,16 @@ static inline uint32_t _clamp(const SwFill* fill, uint32_t pos) } -static inline uint32_t _fixedPixel(const SwFill* fill, uint32_t pos) +static inline uint32_t _fixedPixel(const SwFill* fill, int32_t pos) { - auto i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; + int32_t i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; return fill->ctable[_clamp(fill, i)]; } static inline uint32_t _pixel(const SwFill* fill, float pos) { - auto i = static_cast(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); + auto i = static_cast(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); return fill->ctable[_clamp(fill, i)]; } @@ -226,13 +231,13 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, if (fill->linear.len < FLT_EPSILON) return; //Rotation - auto rx = x + 0.5f; - auto ry = y + 0.5f; - auto t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); - auto inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); if (fabsf(inc) < FLT_EPSILON) { - auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); rasterARGB32(dst, color, offset, len); return; } -- 2.7.4 From 87a6b5219f4c61ce747f71a76845b0d641917299 Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Mon, 27 Jul 2020 14:07:03 +0200 Subject: [PATCH 04/16] capi: Added wrapper for tvg::Shape::scale Change-Id: Ie8380478d9e5bf99c924f3b93cfbb3d80ff55611 --- inc/thorvg_capi.h | 1 + src/bindings/capi/tvgCapi.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index 7c92184..d7f98ec 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -140,6 +140,7 @@ TVG_EXPORT Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* d TVG_EXPORT Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap); TVG_EXPORT Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join); TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor); #ifdef __cplusplus } diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 6ba0e6d..2e4e866 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -226,6 +226,11 @@ TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t return (Tvg_Result) reinterpret_cast(paint)->fill(r, g, b, a); } +TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor) +{ + return (Tvg_Result) reinterpret_cast(paint)->scale(factor); +} + #ifdef __cplusplus } #endif \ No newline at end of file -- 2.7.4 From 52ece17fc37f69535f8b0b278fc36e80868b5166 Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Mon, 27 Jul 2020 14:08:01 +0200 Subject: [PATCH 05/16] capi: Added wrapper for tvg::Shape::rotate Change-Id: I2cef6600586c037caaf8d2f45fc6d78e93dce925 --- inc/thorvg_capi.h | 1 + src/bindings/capi/tvgCapi.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index d7f98ec..9d32483 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -141,6 +141,7 @@ TVG_EXPORT Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap TVG_EXPORT Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join); TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor); +TVG_EXPORT Tvg_Result tvg_shape_rotate(Tvg_Paint* paint, float degree); #ifdef __cplusplus } diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 2e4e866..bd83ccd 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -231,6 +231,11 @@ TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor) return (Tvg_Result) reinterpret_cast(paint)->scale(factor); } +TVG_EXPORT Tvg_Result tvg_shape_rotate(Tvg_Paint* paint, float degree) +{ + return (Tvg_Result) reinterpret_cast(paint)->rotate(degree); +} + #ifdef __cplusplus } #endif \ No newline at end of file -- 2.7.4 From ba17287419a739a3d2f0fb86d5af7ecb323d727e Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Mon, 27 Jul 2020 14:08:51 +0200 Subject: [PATCH 06/16] capi: Added wrapper for tvg::Shape::translate Change-Id: Idcf672926c489148f15c654f85b4d6c3ff8cde80 --- inc/thorvg_capi.h | 1 + src/bindings/capi/tvgCapi.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index 9d32483..efb135b 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -142,6 +142,7 @@ TVG_EXPORT Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Joi TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor); TVG_EXPORT Tvg_Result tvg_shape_rotate(Tvg_Paint* paint, float degree); +TVG_EXPORT Tvg_Result tvg_shape_translate(Tvg_Paint* paint, float x, float y); #ifdef __cplusplus } diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index bd83ccd..5c6fd59 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -236,6 +236,11 @@ TVG_EXPORT Tvg_Result tvg_shape_rotate(Tvg_Paint* paint, float degree) return (Tvg_Result) reinterpret_cast(paint)->rotate(degree); } +TVG_EXPORT Tvg_Result tvg_shape_translate(Tvg_Paint* paint, float x, float y) +{ + return (Tvg_Result) reinterpret_cast(paint)->translate(x, y); +} + #ifdef __cplusplus } #endif \ No newline at end of file -- 2.7.4 From 621d60712684d7f82e9776ff1af07cc566fcf965 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 28 Jul 2020 20:46:11 +0900 Subject: [PATCH 07/16] updated AUTHORS Change-Id: Ia3b91f2dff139b80c5e968be2a0ecb725e6b62bd --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 348597a..1299d6b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,3 +2,4 @@ Hermet Park Prudhvi Raj Vasireddi Junsu Choi Pranay Samanta +Mateusz Palkowski -- 2.7.4 From d2d4a2a3e7f959531f69516fb3828b7df7fc84f9 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 28 Jul 2020 20:57:18 +0900 Subject: [PATCH 08/16] gl_engine: updated file permission. please keep 664 for files. Change-Id: Iaddd87b0d35a74bc8c6cbf330fecbd28e14ad57a --- src/lib/gl_engine/tvgGlGeometry.cpp | 0 src/lib/gl_engine/tvgGlRenderer.cpp | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/lib/gl_engine/tvgGlGeometry.cpp mode change 100755 => 100644 src/lib/gl_engine/tvgGlRenderer.cpp diff --git a/src/lib/gl_engine/tvgGlGeometry.cpp b/src/lib/gl_engine/tvgGlGeometry.cpp old mode 100755 new mode 100644 diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp old mode 100755 new mode 100644 -- 2.7.4 From 8a924cbd78a1e019e9af48e4d021963c0942c8d1 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 29 Jul 2020 13:40:11 +0900 Subject: [PATCH 09/16] sw_engine: fix out of cell memory. we can adjust cell size if the cell memory is out. the main rle logic missed the exception handling. Change-Id: I4419eefefccafd788729111eafeb65aa4e6a20e9 --- src/lib/sw_engine/tvgSwRle.cpp | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index 6ee6f7c..d88a837 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -625,17 +625,15 @@ invalid_outline: } -static bool _genRle(RleWorker& rw) +static int _genRle(RleWorker& rw) { - bool ret = false; - if (setjmp(rw.jmpBuf) == 0) { - ret = _decomposeOutline(rw); + auto ret = _decomposeOutline(rw); if (!rw.invalid) _recordCell(rw); - } else { - cout << "Lack of Cell Memory" << endl; + if (ret) return 0; //success + else return 1; //fail } - return ret; + return -1; //lack of cell memory } @@ -646,14 +644,9 @@ static bool _genRle(RleWorker& rw) SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias) { - //Please adjust when you out of cell memory (default: 16384L) - constexpr auto RENDER_POOL_SIZE = 163840L * 2; + constexpr auto RENDER_POOL_SIZE = 16384L; constexpr auto BAND_SIZE = 40; - assert(outline); - assert(outline->cntrs && outline->pts); - assert(outline->ptsCnt == outline->cntrs[outline->cntrsCnt - 1] + 1); - //TODO: We can preserve several static workers in advance RleWorker rw; Cell buffer[RENDER_POOL_SIZE / sizeof(Cell)]; @@ -693,6 +686,7 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& auto min = rw.cellMin.y; auto yMax = rw.cellMax.y; SwCoord max; + int ret; for (int n = 0; n < bandCnt; ++n, min = max) { max = min + rw.bandSize; @@ -706,8 +700,8 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& rw.yCells = static_cast(rw.buffer); rw.yCnt = band->max - band->min; - auto cellStart = sizeof(Cell*) * (int)rw.yCnt; - auto cellMod = cellStart % sizeof(Cell); + int cellStart = sizeof(Cell*) * (int)rw.yCnt; + int cellMod = cellStart % sizeof(Cell); if (cellMod > 0) cellStart += sizeof(Cell) - cellMod; @@ -722,7 +716,7 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& rw.maxCells = cellsMax - rw.cells; if (rw.maxCells < 2) goto reduce_bands; - for (auto y = 0; y < rw.yCnt; ++y) + for (int y = 0; y < rw.yCnt; ++y) rw.yCells[y] = nullptr; rw.cellsCnt = 0; @@ -731,11 +725,14 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& rw.cellMax.y = band->max; rw.cellYCnt = band->max - band->min; - if (!_genRle(rw)) goto error; - - _sweep(rw); - --band; - continue; + ret = _genRle(rw); + if (ret == 0) { + _sweep(rw); + --band; + continue; + } else if (ret == 1) { + goto error; + } reduce_bands: /* render pool overflow: we will reduce the render band by half */ -- 2.7.4 From 9e0c4666af8e7411595136853fb30d9a65e3ab7a Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 29 Jul 2020 14:25:18 +0900 Subject: [PATCH 10/16] common: revise transform interfaces. transform interfaces are getting duplicated in derived classes. we moved to the super for smaller apis count. Applied strategy pattern to hide the inheritance. Change-Id: I7b0c3ff9317e9bf3c97bb0c849bf55e79ee9a591 --- inc/thorvg.h | 23 ++++++--------- src/lib/meson.build | 1 + src/lib/tvgCommon.h | 1 + src/lib/tvgPaint.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/tvgPaint.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/tvgScene.cpp | 57 ++----------------------------------- src/lib/tvgSceneImpl.h | 6 ++++ src/lib/tvgShape.cpp | 58 ++----------------------------------- src/lib/tvgShapeImpl.h | 6 ++++ 9 files changed, 177 insertions(+), 126 deletions(-) create mode 100644 src/lib/tvgPaint.cpp create mode 100644 src/lib/tvgPaint.h diff --git a/inc/thorvg.h b/inc/thorvg.h index bdca5a2..c8dafaf 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -97,9 +97,16 @@ struct Matrix class TVG_EXPORT Paint { public: - virtual ~Paint() {} + virtual ~Paint(); + + Result rotate(float degree) noexcept; + Result scale(float factor) noexcept; + Result translate(float x, float y) noexcept; + Result transform(const Matrix& m) noexcept; + Result bounds(float* x, float* y, float* w, float* h) const noexcept; _TVG_DECALRE_IDENTIFIER(); + _TVG_DECLARE_PRIVATE(Paint); }; @@ -243,18 +250,11 @@ public: Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept; Result fill(std::unique_ptr f) noexcept; - //Transform - Result rotate(float degree) noexcept; - Result scale(float factor) noexcept; - Result translate(float x, float y) noexcept; - Result transform(const Matrix& m) noexcept; - //Getters 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; float strokeWidth() const noexcept; Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept; @@ -287,13 +287,6 @@ public: Result reserve(uint32_t size) noexcept; Result load(const std::string& path) noexcept; - Result rotate(float degree) noexcept; - Result scale(float factor) noexcept; - Result translate(float x, float y) noexcept; - Result transform(const Matrix& m) noexcept; - - Result bounds(float* x, float* y, float* w, float* h) const noexcept; - static std::unique_ptr gen() noexcept; _TVG_DECLARE_ACCESSOR(Canvas); diff --git a/src/lib/meson.build b/src/lib/meson.build index ad02261..64cedbd 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -27,6 +27,7 @@ source_file = [ 'tvgInitializer.cpp', 'tvgLinearGradient.cpp', 'tvgLoaderMgr.cpp', + 'tvgPaint.cpp', 'tvgRadialGradient.cpp', 'tvgRender.cpp', 'tvgScene.cpp', diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index ac91f49..3c390b1 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -43,6 +43,7 @@ using namespace tvg; #include "tvgLoader.h" #include "tvgLoaderMgr.h" #include "tvgRender.h" +#include "tvgPaint.h" #include "tvgShapePath.h" #include "tvgShapeImpl.h" #include "tvgSceneImpl.h" diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp new file mode 100644 index 0000000..7eeca19 --- /dev/null +++ b/src/lib/tvgPaint.cpp @@ -0,0 +1,74 @@ +/* + * 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_PAINT_CPP_ +#define _TVG_PAINT_CPP_ + +#include "tvgCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +Paint :: Paint() : pImpl(make_unique()) +{ +} + + +Paint :: ~Paint() +{ +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +Result Paint::rotate(float degree) noexcept +{ + if (pImpl.get()->ts->rotate(degree)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::scale(float factor) noexcept +{ + if (pImpl.get()->ts->scale(factor)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::translate(float x, float y) noexcept +{ + if (pImpl.get()->ts->translate(x, y)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::transform(const Matrix& m) noexcept +{ + if (pImpl.get()->ts->transform(m)) return Result::Success; + return Result::FailedAllocation; +} + + +Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept +{ + if (pImpl.get()->ts->bounds(x, y, w, h)) return Result::Success; + return Result::InsufficientCondition; +} + +#endif //_TVG_PAINT_CPP_ \ No newline at end of file diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h new file mode 100644 index 0000000..cd0933b --- /dev/null +++ b/src/lib/tvgPaint.h @@ -0,0 +1,77 @@ +/* + * 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_PAINT_H_ +#define _TVG_PAINT_H_ + +namespace tvg +{ + struct ITransformMethod + { + virtual ~ITransformMethod(){} + virtual bool rotate(float degree) = 0; + virtual bool scale(float factor) = 0; + virtual bool translate(float x, float y) = 0; + virtual bool transform(const Matrix& m) = 0; + virtual bool bounds(float* x, float* y, float* w, float* h) const = 0; + }; + + struct Paint::Impl + { + ITransformMethod* ts = nullptr; + + ~Impl() { + if (ts) delete(ts); + } + }; + + + template + struct TransformMethod : ITransformMethod + { + T* _inst = nullptr; + + TransformMethod(T* inst) : _inst(inst) {} + ~TransformMethod(){} + + bool rotate(float degree) override + { + return _inst->rotate(degree); + } + + bool scale(float factor) override + { + return _inst->scale(factor); + } + + bool translate(float x, float y) override + { + return _inst->translate(x, y); + } + + bool transform(const Matrix& m) override + { + return _inst->transform(m); + } + + bool bounds(float* x, float* y, float* w, float* h) const override + { + return _inst->bounds(x, y, w, h); + } + }; +} + +#endif //_TVG_PAINT_H_ \ No newline at end of file diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index 1980d96..78ca868 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -26,6 +26,8 @@ Scene::Scene() : pImpl(make_unique()) { _id = PAINT_ID_SCENE; + + Paint::pImpl.get()->ts = pImpl.get()->transformMethod(); } @@ -64,61 +66,6 @@ Result Scene::reserve(uint32_t size) noexcept } -Result Scene::scale(float factor) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->scale(factor)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Scene::rotate(float degree) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->rotate(degree)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Scene::translate(float x, float y) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->translate(x, y)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Scene::transform(const Matrix& m) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->transform(m)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Scene::bounds(float* x, float* y, float* w, float* h) const noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->bounds(x, y, w, h)) return Result::InsufficientCondition; - - return Result::Success; -} - - Result Scene::load(const std::string& path) noexcept { if (path.empty()) return Result::InvalidArguments; diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 9972d72..08b42d3 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -231,6 +231,12 @@ struct Scene::Impl if (!loader->read()) return Result::Unknown; return Result::Success; } + + ITransformMethod* transformMethod() + { + return new TransformMethod(this); + } + }; #endif //_TVG_SCENE_IMPL_H_ \ No newline at end of file diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index 36aefed..c822f94 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -25,7 +25,6 @@ /************************************************************************/ constexpr auto PATH_KAPPA = 0.552284f; - /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -33,6 +32,8 @@ constexpr auto PATH_KAPPA = 0.552284f; Shape :: Shape() : pImpl(make_unique()) { _id = PAINT_ID_SHAPE; + + Paint::pImpl.get()->ts = pImpl.get()->transformMethod(); } @@ -280,61 +281,6 @@ const Fill* Shape::fill() const noexcept } -Result Shape::scale(float factor) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->scale(factor)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Shape::rotate(float degree) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->rotate(degree)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Shape::translate(float x, float y) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->translate(x, y)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Shape::transform(const Matrix& m) noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->transform(m)) return Result::FailedAllocation; - - return Result::Success; -} - - -Result Shape::bounds(float* x, float* y, float* w, float* h) const noexcept -{ - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->bounds(x, y, w, h)) return Result::InsufficientCondition; - - return Result::Success; -} - - Result Shape::stroke(float width) noexcept { auto impl = pImpl.get(); diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index 54d37a3..c38916a 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -235,6 +235,12 @@ struct Shape::Impl return true; } + + + ITransformMethod* transformMethod() + { + return new TransformMethod(this); + } }; #endif //_TVG_SHAPE_IMPL_H_ \ No newline at end of file -- 2.7.4 From cd699738b60a2d128e0f1c4fceeab3ef9aadb009 Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Wed, 29 Jul 2020 12:23:18 +0200 Subject: [PATCH 11/16] capi: Added wrapper for tvg::Shape::transform (fixed) Change-Id: Ibbb867e828a07af90f38ed506894d026004fa53d --- inc/thorvg_capi.h | 1 + src/bindings/capi/tvgCapi.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index efb135b..96724dc 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -143,6 +143,7 @@ TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor); TVG_EXPORT Tvg_Result tvg_shape_rotate(Tvg_Paint* paint, float degree); TVG_EXPORT Tvg_Result tvg_shape_translate(Tvg_Paint* paint, float x, float y); +TVG_EXPORT Tvg_Result tvg_shape_transform(Tvg_Paint* paint, const Tvg_Matrix* m); #ifdef __cplusplus } diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 5c6fd59..1972bd0 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -241,6 +241,11 @@ TVG_EXPORT Tvg_Result tvg_shape_translate(Tvg_Paint* paint, float x, float y) return (Tvg_Result) reinterpret_cast(paint)->translate(x, y); } +TVG_EXPORT Tvg_Result tvg_shape_transform(Tvg_Paint* paint, const Tvg_Matrix* m) +{ + return (Tvg_Result) reinterpret_cast(paint)->transform(*(reinterpret_cast(m))); +} + #ifdef __cplusplus } #endif \ No newline at end of file -- 2.7.4 From afc7bc8c2fcbf978940afa2c5ffe25dc4896ed9e Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 29 Jul 2020 19:47:28 +0900 Subject: [PATCH 12/16] common: code refactoring remove exceptional handling which is inevitable scenario. Change-Id: I761a59a38f4578291ee8bc044c5ca989feedbe79 --- src/lib/tvgCanvas.cpp | 29 +++------- src/lib/tvgCommon.h | 1 + src/lib/tvgFill.cpp | 18 ++---- src/lib/tvgLinearGradient.cpp | 22 +++----- src/lib/tvgPaint.cpp | 10 ++-- src/lib/tvgRadialGradient.cpp | 21 +++---- src/lib/tvgScene.cpp | 15 +---- src/lib/tvgShape.cpp | 124 +++++++++++------------------------------- 8 files changed, 67 insertions(+), 173 deletions(-) diff --git a/src/lib/tvgCanvas.cpp b/src/lib/tvgCanvas.cpp index 01fcae1..d110aee 100644 --- a/src/lib/tvgCanvas.cpp +++ b/src/lib/tvgCanvas.cpp @@ -36,59 +36,44 @@ Canvas::~Canvas() Result Canvas::reserve(uint32_t n) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - impl->paints.reserve(n); + IMPL->paints.reserve(n); return Result::Success; } Result Canvas::push(unique_ptr paint) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - return impl->push(move(paint)); + return IMPL->push(move(paint)); } Result Canvas::clear() noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - return impl->clear(); + return IMPL->clear(); } Result Canvas::draw(bool async) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - return impl->draw(); + return IMPL->draw(); } Result Canvas::update() noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - return impl->update(); + return IMPL->update(); } Result Canvas::update(Paint* paint) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - return impl->update(paint); + return IMPL->update(paint); } Result Canvas::sync() noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (impl->renderer->flush()) return Result::Success; + if (IMPL->renderer->flush()) return Result::Success; return Result::InsufficientCondition; } diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index 3c390b1..2e5bd13 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -30,6 +30,7 @@ using namespace std; using namespace tvg; +#define IMPL pImpl.get() #define SCENE_IMPL scene->pImpl.get() #define SHAPE_IMPL shape->pImpl.get() diff --git a/src/lib/tvgFill.cpp b/src/lib/tvgFill.cpp index bfef7a6..fe3ef3f 100644 --- a/src/lib/tvgFill.cpp +++ b/src/lib/tvgFill.cpp @@ -54,7 +54,6 @@ 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) { @@ -78,21 +77,15 @@ Result Fill::colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept uint32_t Fill::colorStops(const ColorStop** colorStops) const noexcept { - auto impl = pImpl.get(); - if (!impl) return 0; - - if (colorStops) *colorStops = impl->colorStops; + if (colorStops) *colorStops = IMPL->colorStops; - return impl->cnt; + return IMPL->cnt; } Result Fill::spread(FillSpread s) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - impl->spread = s; + IMPL->spread = s; return Result::Success; } @@ -100,10 +93,7 @@ Result Fill::spread(FillSpread s) noexcept FillSpread Fill::spread() const noexcept { - auto impl = pImpl.get(); - assert(impl); - - return impl->spread; + return IMPL->spread; } #endif /* _TVG_FILL_CPP_ */ \ No newline at end of file diff --git a/src/lib/tvgLinearGradient.cpp b/src/lib/tvgLinearGradient.cpp index 4499454..88be20c 100644 --- a/src/lib/tvgLinearGradient.cpp +++ b/src/lib/tvgLinearGradient.cpp @@ -49,13 +49,10 @@ 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; + IMPL->x1 = x1; + IMPL->y1 = y1; + IMPL->x2 = x2; + IMPL->y2 = y2; return Result::Success; } @@ -63,13 +60,10 @@ Result LinearGradient::linear(float x1, float y1, float x2, float y2) noexcept 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; + if (x1) *x1 = IMPL->x1; + if (x2) *x2 = IMPL->x2; + if (y1) *y1 = IMPL->y1; + if (y2) *y2 = IMPL->y2; return Result::Success; } diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index 7eeca19..b33b764 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -39,35 +39,35 @@ Paint :: ~Paint() Result Paint::rotate(float degree) noexcept { - if (pImpl.get()->ts->rotate(degree)) return Result::Success; + if (IMPL->ts->rotate(degree)) return Result::Success; return Result::FailedAllocation; } Result Paint::scale(float factor) noexcept { - if (pImpl.get()->ts->scale(factor)) return Result::Success; + if (IMPL->ts->scale(factor)) return Result::Success; return Result::FailedAllocation; } Result Paint::translate(float x, float y) noexcept { - if (pImpl.get()->ts->translate(x, y)) return Result::Success; + if (IMPL->ts->translate(x, y)) return Result::Success; return Result::FailedAllocation; } Result Paint::transform(const Matrix& m) noexcept { - if (pImpl.get()->ts->transform(m)) return Result::Success; + if (IMPL->ts->transform(m)) return Result::Success; return Result::FailedAllocation; } Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept { - if (pImpl.get()->ts->bounds(x, y, w, h)) return Result::Success; + if (IMPL->ts->bounds(x, y, w, h)) return Result::Success; return Result::InsufficientCondition; } diff --git a/src/lib/tvgRadialGradient.cpp b/src/lib/tvgRadialGradient.cpp index 895cccb..154e163 100644 --- a/src/lib/tvgRadialGradient.cpp +++ b/src/lib/tvgRadialGradient.cpp @@ -46,15 +46,11 @@ RadialGradient::~RadialGradient() Result RadialGradient::radial(float cx, float cy, float radius) noexcept { - if (radius < FLT_EPSILON) - return Result::InvalidArguments; + 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; + IMPL->cx = cx; + IMPL->cy = cy; + IMPL->radius = radius; return Result::Success; } @@ -62,12 +58,9 @@ Result RadialGradient::radial(float cx, float cy, float radius) noexcept 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; + if (cx) *cx = IMPL->cx; + if (cy) *cy = IMPL->cy; + if (radius) *radius = IMPL->radius; return Result::Success; } diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index 78ca868..adbbe09 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -44,12 +44,9 @@ unique_ptr Scene::gen() noexcept Result Scene::push(unique_ptr paint) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - auto p = paint.release(); if (!p) return Result::MemoryCorruption; - impl->paints.push_back(p); + IMPL->paints.push_back(p); return Result::Success; } @@ -57,10 +54,7 @@ Result Scene::push(unique_ptr paint) noexcept Result Scene::reserve(uint32_t size) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - impl->paints.reserve(size); + IMPL->paints.reserve(size); return Result::Success; } @@ -70,10 +64,7 @@ Result Scene::load(const std::string& path) noexcept { if (path.empty()) return Result::InvalidArguments; - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - return impl->load(path); + return IMPL->load(path); } #endif /* _TVG_SCENE_CPP_ */ \ No newline at end of file diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index c822f94..ddd3ef0 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -50,12 +50,9 @@ unique_ptr Shape::gen() noexcept Result Shape::reset() noexcept { - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; - - impl->path->reset(); + IMPL->path->reset(); - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -65,12 +62,9 @@ uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept { if (!cmds) return 0; - auto impl = pImpl.get(); - if (!impl || !impl->path) return 0; - - *cmds = impl->path->cmds; + *cmds = IMPL->path->cmds; - return impl->path->cmdCnt; + return IMPL->path->cmdCnt; } @@ -78,12 +72,9 @@ uint32_t Shape::pathCoords(const Point** pts) const noexcept { if (!pts) return 0; - auto impl = pImpl.get(); - if (!impl || !impl->path) return 0; + *pts = IMPL->path->pts; - *pts = impl->path->pts; - - return impl->path->ptsCnt; + return IMPL->path->ptsCnt; } @@ -91,13 +82,10 @@ Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point* { if (cmdCnt < 0 || ptsCnt < 0 || !pts || !ptsCnt) return Result::InvalidArguments; - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; + IMPL->path->grow(cmdCnt, ptsCnt); + IMPL->path->append(cmds, cmdCnt, pts, ptsCnt); - impl->path->grow(cmdCnt, ptsCnt); - impl->path->append(cmds, cmdCnt, pts, ptsCnt); - - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -105,12 +93,9 @@ Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point* Result Shape::moveTo(float x, float y) noexcept { - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; + IMPL->path->moveTo(x, y); - impl->path->moveTo(x, y); - - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -118,12 +103,9 @@ Result Shape::moveTo(float x, float y) noexcept Result Shape::lineTo(float x, float y) noexcept { - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; + IMPL->path->lineTo(x, y); - impl->path->lineTo(x, y); - - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -131,12 +113,9 @@ Result Shape::lineTo(float x, float y) noexcept Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept { - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; + IMPL->path->cubicTo(cx1, cy1, cx2, cy2, x, y); - impl->path->cubicTo(cx1, cy1, cx2, cy2, x, y); - - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -144,12 +123,9 @@ Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float Result Shape::close() noexcept { - auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; + IMPL->path->close(); - impl->path->close(); - - impl->flag |= RenderUpdateFlag::Path; + IMPL->flag |= RenderUpdateFlag::Path; return Result::Success; } @@ -158,7 +134,6 @@ Result Shape::close() noexcept Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept { auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; auto rxKappa = rx * PATH_KAPPA; auto ryKappa = ry * PATH_KAPPA; @@ -180,7 +155,6 @@ Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) noexcept { auto impl = pImpl.get(); - if (!impl || !impl->path) return Result::MemoryCorruption; auto halfW = w * 0.5f; auto halfH = h * 0.5f; @@ -225,7 +199,6 @@ Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept { auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; impl->color[0] = r; impl->color[1] = g; @@ -246,7 +219,6 @@ Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept Result Shape::fill(unique_ptr f) noexcept { auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; auto p = f.release(); if (!p) return Result::MemoryCorruption; @@ -262,7 +234,6 @@ Result Shape::fill(unique_ptr f) noexcept Result Shape::fill(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept { auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; if (r) *r = impl->color[0]; if (g) *g = impl->color[1]; @@ -274,19 +245,13 @@ Result Shape::fill(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcep const Fill* Shape::fill() const noexcept { - auto impl = pImpl.get(); - if (!impl) return nullptr; - - return impl->fill; + return IMPL->fill; } Result Shape::stroke(float width) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->strokeWidth(width)) return Result::FailedAllocation; + if (!IMPL->strokeWidth(width)) return Result::FailedAllocation; return Result::Success; } @@ -294,20 +259,14 @@ Result Shape::stroke(float width) noexcept float Shape::strokeWidth() const noexcept { - auto impl = pImpl.get(); - if (!impl) return 0; - - if (!impl->stroke) return 0; - return impl->stroke->width; + if (!IMPL->stroke) return 0; + return IMPL->stroke->width; } Result Shape::stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->strokeColor(r, g, b, a)) return Result::FailedAllocation; + if (!IMPL->strokeColor(r, g, b, a)) return Result::FailedAllocation; return Result::Success; } @@ -316,7 +275,6 @@ Result Shape::stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept Result Shape::strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept { auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; if (!impl->stroke) return Result::InsufficientCondition; @@ -333,10 +291,7 @@ Result Shape::stroke(const float* dashPattern, uint32_t cnt) noexcept { if (cnt < 2 || !dashPattern) return Result::InvalidArguments; - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->strokeDash(dashPattern, cnt)) return Result::FailedAllocation; + if (!IMPL->strokeDash(dashPattern, cnt)) return Result::FailedAllocation; return Result::Success; } @@ -344,22 +299,16 @@ Result Shape::stroke(const float* dashPattern, uint32_t cnt) noexcept uint32_t Shape::strokeDash(const float** dashPattern) const noexcept { - auto impl = pImpl.get(); - assert(impl); - - if (!impl->stroke) return 0; + if (!IMPL->stroke) return 0; - if (dashPattern) *dashPattern = impl->stroke->dashPattern; - return impl->stroke->dashCnt; + if (dashPattern) *dashPattern = IMPL->stroke->dashPattern; + return IMPL->stroke->dashCnt; } Result Shape::stroke(StrokeCap cap) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->strokeCap(cap)) return Result::FailedAllocation; + if (!IMPL->strokeCap(cap)) return Result::FailedAllocation; return Result::Success; } @@ -367,10 +316,7 @@ Result Shape::stroke(StrokeCap cap) noexcept Result Shape::stroke(StrokeJoin join) noexcept { - auto impl = pImpl.get(); - if (!impl) return Result::MemoryCorruption; - - if (!impl->strokeJoin(join)) return Result::FailedAllocation; + if (!IMPL->strokeJoin(join)) return Result::FailedAllocation; return Result::Success; } @@ -378,23 +324,17 @@ Result Shape::stroke(StrokeJoin join) noexcept StrokeCap Shape::strokeCap() const noexcept { - auto impl = pImpl.get(); - assert(impl); - - if (!impl->stroke) return StrokeCap::Square; + if (!IMPL->stroke) return StrokeCap::Square; - return impl->stroke->cap; + return IMPL->stroke->cap; } StrokeJoin Shape::strokeJoin() const noexcept { - auto impl = pImpl.get(); - assert(impl); - - if (!impl->stroke) return StrokeJoin::Bevel; + if (!IMPL->stroke) return StrokeJoin::Bevel; - return impl->stroke->join; + return IMPL->stroke->join; } -- 2.7.4 From 8ed9edd33e4c167f9f6b51cac6588511e796130c Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 29 Jul 2020 20:41:34 +0900 Subject: [PATCH 13/16] common: code refactoring keep consistency of internal functions among the paint type methods. Change-Id: I98a42ac398ddc5aaf49ac59e5cbb1790266bd612 --- src/lib/tvgCanvasImpl.h | 14 +++++++------- src/lib/tvgSceneImpl.h | 12 ++++++------ src/lib/tvgShape.cpp | 2 +- src/lib/tvgShapeImpl.h | 17 +++++++++-------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 94737c9..5960f02 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -59,10 +59,10 @@ struct Canvas::Impl if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. auto scene = static_cast(paint); - if (!SCENE_IMPL->clear(*renderer)) return Result::InsufficientCondition; + if (!SCENE_IMPL->dispose(*renderer)) return Result::InsufficientCondition; } else { auto shape = static_cast(paint); - if (!SHAPE_IMPL->dispose(*shape, *renderer)) return Result::InsufficientCondition; + if (!SHAPE_IMPL->dispose(*renderer)) return Result::InsufficientCondition; } delete(paint); } @@ -79,10 +79,10 @@ struct Canvas::Impl if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. auto scene = static_cast(paint); - if (!SCENE_IMPL->update(*renderer, nullptr)) return Result::InsufficientCondition; + if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; } else { auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*shape, *renderer, nullptr)) return Result::InsufficientCondition; + if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; } } return Result::Success; @@ -95,10 +95,10 @@ struct Canvas::Impl if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. auto scene = static_cast(paint); - if (!SCENE_IMPL->update(*renderer)) return Result::InsufficientCondition; + if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; } else { auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*shape, *renderer)) return Result::InsufficientCondition; + if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; } return Result::Success; } @@ -116,7 +116,7 @@ struct Canvas::Impl if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition; } else { auto shape = static_cast(paint); - if(!SHAPE_IMPL->render(*shape, *renderer)) return Result::InsufficientCondition; + if(!SHAPE_IMPL->render(*renderer)) return Result::InsufficientCondition; } } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 08b42d3..b8d71f2 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -37,16 +37,16 @@ struct Scene::Impl if (rTransform) delete(rTransform); } - bool clear(RenderMethod& renderer) + bool dispose(RenderMethod& renderer) { for (auto paint : paints) { if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. auto scene = static_cast(paint); - if (!SCENE_IMPL->clear(renderer)) return false; + if (!SCENE_IMPL->dispose(renderer)) return false; } else { auto shape = static_cast(paint); - if (!SHAPE_IMPL->dispose(*shape, renderer)) return false; + if (!SHAPE_IMPL->dispose(renderer)) return false; } delete(paint); } @@ -64,13 +64,13 @@ struct Scene::Impl if (!SCENE_IMPL->update(renderer, transform, flag)) return false; } else { auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*shape, renderer, transform, flag)) return false; + if (!SHAPE_IMPL->update(renderer, transform, flag)) return false; } } return true; } - bool update(RenderMethod &renderer, const RenderTransform* pTransform = nullptr, uint32_t pFlag = 0) + bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag) { if (loader) { auto scene = loader->data(); @@ -114,7 +114,7 @@ struct Scene::Impl if(!SCENE_IMPL->render(renderer)) return false; } else { auto shape = static_cast(paint); - if(!SHAPE_IMPL->render(*shape, renderer)) return false; + if(!SHAPE_IMPL->render(renderer)) return false; } } return true; diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index ddd3ef0..648c0ee 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -29,7 +29,7 @@ constexpr auto PATH_KAPPA = 0.552284f; /* External Class Implementation */ /************************************************************************/ -Shape :: Shape() : pImpl(make_unique()) +Shape :: Shape() : pImpl(make_unique(this)) { _id = PAINT_ID_SHAPE; diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index c38916a..b733bd5 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -48,9 +48,10 @@ struct Shape::Impl uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a uint32_t flag = RenderUpdateFlag::None; void *edata = nullptr; //engine data + Shape *shape = nullptr; - Impl() : path(new ShapePath) + Impl(Shape* s) : path(new ShapePath), shape(s) { } @@ -62,17 +63,17 @@ struct Shape::Impl if (rTransform) delete(rTransform); } - bool dispose(Shape& shape, RenderMethod& renderer) + bool dispose(RenderMethod& renderer) { - return renderer.dispose(shape, edata); + return renderer.dispose(*shape, edata); } - bool render(Shape& shape, RenderMethod& renderer) + bool render(RenderMethod& renderer) { - return renderer.render(shape, edata); + return renderer.render(*shape, edata); } - bool update(Shape& shape, RenderMethod& renderer, const RenderTransform* pTransform = nullptr, uint32_t pFlag = 0) + bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag) { if (flag & RenderUpdateFlag::Transform) { if (!rTransform) return false; @@ -84,10 +85,10 @@ struct Shape::Impl if (rTransform && pTransform) { RenderTransform outTransform(pTransform, rTransform); - edata = renderer.prepare(shape, edata, &outTransform, static_cast(pFlag | flag)); + edata = renderer.prepare(*shape, edata, &outTransform, static_cast(pFlag | flag)); } else { auto outTransform = pTransform ? pTransform : rTransform; - edata = renderer.prepare(shape, edata, outTransform, static_cast(pFlag | flag)); + edata = renderer.prepare(*shape, edata, outTransform, static_cast(pFlag | flag)); } flag = RenderUpdateFlag::None; -- 2.7.4 From 80d47fd7d342828ab06bc710ee234514552f9fbb Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 30 Jul 2020 13:40:18 +0900 Subject: [PATCH 14/16] common: revise canvas interfaces. 1. removed async option which doesn't work currently, rather than it, we can add async option in initiailizer class. 2. removed update() method. Instead, we can call update(paint = nullptr); which has exactly same behavior. Change-Id: I7909a50d804b97baf413a2ff6365a3cf79a3689e --- inc/thorvg.h | 3 +-- inc/thorvg_capi.h | 2 +- src/bindings/capi/tvgCapi.cpp | 6 +++--- src/lib/tvgCanvas.cpp | 8 +------- src/lib/tvgCanvasImpl.h | 30 ++++++++++++++---------------- test/testCapi.c | 2 +- 6 files changed, 21 insertions(+), 30 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index c8dafaf..6475890 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -157,9 +157,8 @@ public: Result reserve(uint32_t n) noexcept; virtual Result push(std::unique_ptr paint) noexcept; virtual Result clear() noexcept; - virtual Result update() noexcept; virtual Result update(Paint* paint) noexcept; - virtual Result draw(bool async = true) noexcept; + virtual Result draw() noexcept; virtual Result sync() noexcept; _TVG_DECLARE_ACCESSOR(Scene); diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index efb135b..7189599 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -117,7 +117,7 @@ TVG_EXPORT Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); TVG_EXPORT Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas); TVG_EXPORT Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas); TVG_EXPORT Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint); -TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, unsigned char async); +TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas); TVG_EXPORT Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas); diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 5c6fd59..55fdecc 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -104,7 +104,7 @@ TVG_EXPORT Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas) TVG_EXPORT Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas) { - return (Tvg_Result) reinterpret_cast(canvas)->update(); + return (Tvg_Result) reinterpret_cast(canvas)->update(nullptr); } @@ -114,9 +114,9 @@ TVG_EXPORT Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* pai } -TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, unsigned char async) +TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas) { - return (Tvg_Result) reinterpret_cast(canvas)->draw(async); + return (Tvg_Result) reinterpret_cast(canvas)->draw(); } diff --git a/src/lib/tvgCanvas.cpp b/src/lib/tvgCanvas.cpp index d110aee..e9db461 100644 --- a/src/lib/tvgCanvas.cpp +++ b/src/lib/tvgCanvas.cpp @@ -53,18 +53,12 @@ Result Canvas::clear() noexcept } -Result Canvas::draw(bool async) noexcept +Result Canvas::draw() noexcept { return IMPL->draw(); } -Result Canvas::update() noexcept -{ - return IMPL->update(); -} - - Result Canvas::update(Paint* paint) noexcept { return IMPL->update(paint); diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 5960f02..77af3d5 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -71,11 +71,12 @@ struct Canvas::Impl return Result::Success; } - Result update() + Result update(Paint* paint) { if (!renderer) return Result::InsufficientCondition; - for(auto paint: paints) { + //Update single paint node + if (paint) { if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. auto scene = static_cast(paint); @@ -84,21 +85,18 @@ struct Canvas::Impl auto shape = static_cast(paint); if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; } - } - return Result::Success; - } - - Result update(Paint* paint) - { - if (!renderer) return Result::InsufficientCondition; - - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + //Update retained all paint nodes } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + for(auto paint: paints) { + if (paint->id() == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); + if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + } else { + auto shape = static_cast(paint); + if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + } + } } return Result::Success; } diff --git a/test/testCapi.c b/test/testCapi.c index 5b8b91b..6a46e97 100644 --- a/test/testCapi.c +++ b/test/testCapi.c @@ -26,7 +26,7 @@ void testCapi() tvg_shape_fill_color(shape, 255, 255, 0, 255); tvg_canvas_push(canvas, shape); - tvg_canvas_draw(canvas, 1); + tvg_canvas_draw(canvas); tvg_canvas_sync(canvas); tvg_canvas_destroy(canvas); -- 2.7.4 From 8dca270a30d3ad116ee34fbacfd4026fbb9501a0 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 30 Jul 2020 14:47:04 +0900 Subject: [PATCH 15/16] common: code refactoring for simplicity. Introduce internal PaintMethod since there more derived paint classes are coming. This PaintMethod is a sort of Strategy Pattern method. Change-Id: I29c49f5d4ddbfb9e429d4976636b20b39914ee20 --- inc/thorvg.h | 7 ++----- src/lib/tvgCanvasImpl.h | 36 ++++++------------------------------ src/lib/tvgCommon.h | 3 --- src/lib/tvgPaint.cpp | 10 +++++----- src/lib/tvgPaint.h | 45 +++++++++++++++++++++++++++++++++------------ src/lib/tvgScene.cpp | 4 +--- src/lib/tvgSceneImpl.h | 38 +++++--------------------------------- src/lib/tvgShape.cpp | 4 +--- src/lib/tvgShapeImpl.h | 2 +- 9 files changed, 54 insertions(+), 95 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 6475890..36fed95 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -105,8 +105,9 @@ public: Result transform(const Matrix& m) noexcept; Result bounds(float* x, float* y, float* w, float* h) const noexcept; - _TVG_DECALRE_IDENTIFIER(); _TVG_DECLARE_PRIVATE(Paint); + _TVG_DECLARE_ACCESSOR(Canvas); + _TVG_DECLARE_ACCESSOR(Scene); }; @@ -161,7 +162,6 @@ public: virtual Result draw() noexcept; virtual Result sync() noexcept; - _TVG_DECLARE_ACCESSOR(Scene); _TVG_DECLARE_PRIVATE(Canvas); }; @@ -264,8 +264,6 @@ public: static std::unique_ptr gen() noexcept; _TVG_DECLARE_PRIVATE(Shape); - _TVG_DECLARE_ACCESSOR(Canvas); - _TVG_DECLARE_ACCESSOR(Scene); }; @@ -288,7 +286,6 @@ public: static std::unique_ptr gen() noexcept; - _TVG_DECLARE_ACCESSOR(Canvas); _TVG_DECLARE_PRIVATE(Scene); }; diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 77af3d5..a1b9b78 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -56,14 +56,7 @@ struct Canvas::Impl if (!renderer->clear()) return Result::InsufficientCondition; for (auto paint : paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->dispose(*renderer)) return Result::InsufficientCondition; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->dispose(*renderer)) return Result::InsufficientCondition; - } + paint->IMPL->method->dispose(*renderer); delete(paint); } paints.clear(); @@ -77,24 +70,14 @@ struct Canvas::Impl //Update single paint node if (paint) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) { + return Result::InsufficientCondition; } //Update retained all paint nodes } else { for(auto paint: paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(*renderer, nullptr, RenderUpdateFlag::None)) return Result::InsufficientCondition; + if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) { + return Result::InsufficientCondition; } } } @@ -108,14 +91,7 @@ struct Canvas::Impl if (!renderer->preRender()) return Result::InsufficientCondition; for(auto paint: paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition; - } else { - auto shape = static_cast(paint); - if(!SHAPE_IMPL->render(*renderer)) return Result::InsufficientCondition; - } + if(!paint->IMPL->method->render(*renderer)) return Result::InsufficientCondition; } if (!renderer->postRender()) return Result::InsufficientCondition; diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index 2e5bd13..4cec18f 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -34,9 +34,6 @@ using namespace tvg; #define SCENE_IMPL scene->pImpl.get() #define SHAPE_IMPL shape->pImpl.get() -#define PAINT_ID_SHAPE 0 -#define PAINT_ID_SCENE 1 - #define FILL_ID_LINEAR 0 #define FILL_ID_RADIAL 1 diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index b33b764..cbd68c6 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -39,35 +39,35 @@ Paint :: ~Paint() Result Paint::rotate(float degree) noexcept { - if (IMPL->ts->rotate(degree)) return Result::Success; + if (IMPL->method->rotate(degree)) return Result::Success; return Result::FailedAllocation; } Result Paint::scale(float factor) noexcept { - if (IMPL->ts->scale(factor)) return Result::Success; + if (IMPL->method->scale(factor)) return Result::Success; return Result::FailedAllocation; } Result Paint::translate(float x, float y) noexcept { - if (IMPL->ts->translate(x, y)) return Result::Success; + if (IMPL->method->translate(x, y)) return Result::Success; return Result::FailedAllocation; } Result Paint::transform(const Matrix& m) noexcept { - if (IMPL->ts->transform(m)) return Result::Success; + if (IMPL->method->transform(m)) return Result::Success; return Result::FailedAllocation; } Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept { - if (IMPL->ts->bounds(x, y, w, h)) return Result::Success; + if (IMPL->method->bounds(x, y, w, h)) return Result::Success; return Result::InsufficientCondition; } diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index cd0933b..31dcbf4 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -19,57 +19,78 @@ namespace tvg { - struct ITransformMethod + struct PaintMethod { - virtual ~ITransformMethod(){} + virtual ~PaintMethod(){} + + virtual bool dispose(RenderMethod& renderer) = 0; + virtual bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag) = 0; + virtual bool render(RenderMethod& renderer) = 0; + virtual bool rotate(float degree) = 0; virtual bool scale(float factor) = 0; virtual bool translate(float x, float y) = 0; virtual bool transform(const Matrix& m) = 0; virtual bool bounds(float* x, float* y, float* w, float* h) const = 0; + }; struct Paint::Impl { - ITransformMethod* ts = nullptr; + PaintMethod* method = nullptr; ~Impl() { - if (ts) delete(ts); + if (method) delete(method); } }; template - struct TransformMethod : ITransformMethod + struct TransformMethod : PaintMethod { - T* _inst = nullptr; + T* inst = nullptr; - TransformMethod(T* inst) : _inst(inst) {} + TransformMethod(T* inst) : inst(_inst) {} ~TransformMethod(){} bool rotate(float degree) override { - return _inst->rotate(degree); + return inst->rotate(degree); } bool scale(float factor) override { - return _inst->scale(factor); + return inst->scale(factor); } bool translate(float x, float y) override { - return _inst->translate(x, y); + return inst->translate(x, y); } bool transform(const Matrix& m) override { - return _inst->transform(m); + return inst->transform(m); } bool bounds(float* x, float* y, float* w, float* h) const override { - return _inst->bounds(x, y, w, h); + return inst->bounds(x, y, w, h); + } + + bool dispose(RenderMethod& renderer) + { + return inst->dispose(renderer); + } + + bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag) + { + return inst->update(renderer, pTransform, pFlag); + } + + bool render(RenderMethod& renderer) + { + return inst->render(renderer); } }; } diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index adbbe09..4d04364 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -25,9 +25,7 @@ Scene::Scene() : pImpl(make_unique()) { - _id = PAINT_ID_SCENE; - - Paint::pImpl.get()->ts = pImpl.get()->transformMethod(); + Paint::IMPL->method = IMPL->transformMethod(); } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index b8d71f2..bd49714 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -40,14 +40,7 @@ struct Scene::Impl bool dispose(RenderMethod& renderer) { for (auto paint : paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->dispose(renderer)) return false; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->dispose(renderer)) return false; - } + paint->IMPL->method->dispose(renderer); delete(paint); } paints.clear(); @@ -58,14 +51,7 @@ struct Scene::Impl bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag) { for(auto paint: paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->update(renderer, transform, flag)) return false; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->update(renderer, transform, flag)) return false; - } + if (!paint->IMPL->method->update(renderer, transform, flag)) return false; } return true; } @@ -108,14 +94,7 @@ struct Scene::Impl bool render(RenderMethod &renderer) { for(auto paint: paints) { - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if(!SCENE_IMPL->render(renderer)) return false; - } else { - auto shape = static_cast(paint); - if(!SHAPE_IMPL->render(renderer)) return false; - } + if(!paint->IMPL->method->render(renderer)) return false; } return true; } @@ -139,14 +118,7 @@ struct Scene::Impl auto w2 = 0.0f; auto h2 = 0.0f; - if (paint->id() == PAINT_ID_SCENE) { - //We know renderer type, avoid dynamic_cast for performance. - auto scene = static_cast(paint); - if (!SCENE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false; - } else { - auto shape = static_cast(paint); - if (!SHAPE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false; - } + if (paint->IMPL->method->bounds(&x2, &y2, &w2, &h2)) return false; //Merge regions if (x2 < x) x = x2; @@ -232,7 +204,7 @@ struct Scene::Impl return Result::Success; } - ITransformMethod* transformMethod() + PaintMethod* transformMethod() { return new TransformMethod(this); } diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index 648c0ee..f42c160 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -31,9 +31,7 @@ constexpr auto PATH_KAPPA = 0.552284f; Shape :: Shape() : pImpl(make_unique(this)) { - _id = PAINT_ID_SHAPE; - - Paint::pImpl.get()->ts = pImpl.get()->transformMethod(); + Paint::IMPL->method = IMPL->transformMethod(); } diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index b733bd5..955deb6 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -238,7 +238,7 @@ struct Shape::Impl } - ITransformMethod* transformMethod() + PaintMethod* transformMethod() { return new TransformMethod(this); } -- 2.7.4 From 39b77361c5598c90faa32222b996f90756521600 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 30 Jul 2020 15:10:59 +0900 Subject: [PATCH 16/16] common: code refactoring. changed just internal variable & method names. no logical changes. Change-Id: I01782ec59dec3ff2232e03de7b3863100d9cc27f --- src/lib/tvgCanvasImpl.h | 8 ++++---- src/lib/tvgPaint.cpp | 10 +++++----- src/lib/tvgPaint.h | 24 +++++++++++++++++------- src/lib/tvgScene.cpp | 2 +- src/lib/tvgSceneImpl.h | 14 ++++---------- src/lib/tvgShape.cpp | 2 +- src/lib/tvgShapeImpl.h | 6 ------ 7 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index a1b9b78..2776735 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -56,7 +56,7 @@ struct Canvas::Impl if (!renderer->clear()) return Result::InsufficientCondition; for (auto paint : paints) { - paint->IMPL->method->dispose(*renderer); + paint->IMPL->method()->dispose(*renderer); delete(paint); } paints.clear(); @@ -70,13 +70,13 @@ struct Canvas::Impl //Update single paint node if (paint) { - if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) { + if (!paint->IMPL->method()->update(*renderer, nullptr, RenderUpdateFlag::None)) { return Result::InsufficientCondition; } //Update retained all paint nodes } else { for(auto paint: paints) { - if (!paint->IMPL->method->update(*renderer, nullptr, RenderUpdateFlag::None)) { + if (!paint->IMPL->method()->update(*renderer, nullptr, RenderUpdateFlag::None)) { return Result::InsufficientCondition; } } @@ -91,7 +91,7 @@ struct Canvas::Impl if (!renderer->preRender()) return Result::InsufficientCondition; for(auto paint: paints) { - if(!paint->IMPL->method->render(*renderer)) return Result::InsufficientCondition; + if(!paint->IMPL->method()->render(*renderer)) return Result::InsufficientCondition; } if (!renderer->postRender()) return Result::InsufficientCondition; diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index cbd68c6..8aa62d2 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -39,35 +39,35 @@ Paint :: ~Paint() Result Paint::rotate(float degree) noexcept { - if (IMPL->method->rotate(degree)) return Result::Success; + if (IMPL->method()->rotate(degree)) return Result::Success; return Result::FailedAllocation; } Result Paint::scale(float factor) noexcept { - if (IMPL->method->scale(factor)) return Result::Success; + if (IMPL->method()->scale(factor)) return Result::Success; return Result::FailedAllocation; } Result Paint::translate(float x, float y) noexcept { - if (IMPL->method->translate(x, y)) return Result::Success; + if (IMPL->method()->translate(x, y)) return Result::Success; return Result::FailedAllocation; } Result Paint::transform(const Matrix& m) noexcept { - if (IMPL->method->transform(m)) return Result::Success; + if (IMPL->method()->transform(m)) return Result::Success; return Result::FailedAllocation; } Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept { - if (IMPL->method->bounds(x, y, w, h)) return Result::Success; + if (IMPL->method()->bounds(x, y, w, h)) return Result::Success; return Result::InsufficientCondition; } diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index 31dcbf4..45e4c01 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -19,9 +19,9 @@ namespace tvg { - struct PaintMethod + struct StrategyMethod { - virtual ~PaintMethod(){} + virtual ~StrategyMethod(){} virtual bool dispose(RenderMethod& renderer) = 0; virtual bool update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t pFlag) = 0; @@ -37,21 +37,31 @@ namespace tvg struct Paint::Impl { - PaintMethod* method = nullptr; + StrategyMethod* smethod = nullptr; ~Impl() { - if (method) delete(method); + if (smethod) delete(smethod); + } + + void method(StrategyMethod* method) + { + smethod = method; + } + + StrategyMethod* method() + { + return smethod; } }; template - struct TransformMethod : PaintMethod + struct PaintMethod : StrategyMethod { T* inst = nullptr; - TransformMethod(T* inst) : inst(_inst) {} - ~TransformMethod(){} + PaintMethod(T* _inst) : inst(_inst) {} + ~PaintMethod(){} bool rotate(float degree) override { diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index 4d04364..d34d57a 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -25,7 +25,7 @@ Scene::Scene() : pImpl(make_unique()) { - Paint::IMPL->method = IMPL->transformMethod(); + Paint::IMPL->method(new PaintMethod(IMPL)); } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index bd49714..0ba1f1f 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -40,7 +40,7 @@ struct Scene::Impl bool dispose(RenderMethod& renderer) { for (auto paint : paints) { - paint->IMPL->method->dispose(renderer); + paint->IMPL->method()->dispose(renderer); delete(paint); } paints.clear(); @@ -51,7 +51,7 @@ struct Scene::Impl bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag) { for(auto paint: paints) { - if (!paint->IMPL->method->update(renderer, transform, flag)) return false; + if (!paint->IMPL->method()->update(renderer, transform, flag)) return false; } return true; } @@ -94,7 +94,7 @@ struct Scene::Impl bool render(RenderMethod &renderer) { for(auto paint: paints) { - if(!paint->IMPL->method->render(renderer)) return false; + if(!paint->IMPL->method()->render(renderer)) return false; } return true; } @@ -118,7 +118,7 @@ struct Scene::Impl auto w2 = 0.0f; auto h2 = 0.0f; - if (paint->IMPL->method->bounds(&x2, &y2, &w2, &h2)) return false; + if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false; //Merge regions if (x2 < x) x = x2; @@ -203,12 +203,6 @@ struct Scene::Impl if (!loader->read()) return Result::Unknown; return Result::Success; } - - PaintMethod* transformMethod() - { - return new TransformMethod(this); - } - }; #endif //_TVG_SCENE_IMPL_H_ \ No newline at end of file diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index f42c160..7d26614 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -31,7 +31,7 @@ constexpr auto PATH_KAPPA = 0.552284f; Shape :: Shape() : pImpl(make_unique(this)) { - Paint::IMPL->method = IMPL->transformMethod(); + Paint::IMPL->method(new PaintMethod(IMPL)); } diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index 955deb6..a7755da 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -236,12 +236,6 @@ struct Shape::Impl return true; } - - - PaintMethod* transformMethod() - { - return new TransformMethod(this); - } }; #endif //_TVG_SHAPE_IMPL_H_ \ No newline at end of file -- 2.7.4