From 25a1321243bb85c92f9e03772c559e5ac30e36bf Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Mon, 28 Aug 2023 12:24:30 +0900 Subject: [PATCH] common: stroke dash offset support with new apis. This change just allows users to use the offset of the stroke dash. Actually feature enhacement has been introduced by 478e45f9f3d330aea65e839b58ba05f4be3a02a8. @APIs: uint32_t Shape::strokeDash(const float** dashPattern) -> uint32_t Shape::strokeDash(const float** dashPattern, float* offset = nullptr) Result Shape::strokeDash(const float* dashPattern, uint32_t cnt) -> Result Shape::strokeDash(const float* dashPattern, uint32_t cnt, float offset = 0.0f) Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt) -> Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt, float offset) Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt) -> Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt, float* offset) @Issue: https://github.com/thorvg/thorvg/issues/1372 --- inc/thorvg.h | 10 ++++++++-- src/bindings/capi/thorvg_capi.h | 15 ++++++--------- src/bindings/capi/tvgCapi.cpp | 10 +++++----- src/examples/Capi.cpp | 2 +- src/loaders/lottie/tvgLottieBuilder.cpp | 2 +- src/loaders/svg/tvgSvgSceneBuilder.cpp | 2 +- src/renderer/tvgShape.cpp | 8 ++++---- src/savers/tvg/tvgTvgSaver.cpp | 2 +- test/capi/capiShape.cpp | 4 ++-- test/testShape.cpp | 4 ++++ 10 files changed, 33 insertions(+), 26 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index e96e92b2..c10ed5ca 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -976,6 +976,7 @@ public: * * @param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. * @param[in] cnt The length of the @p dashPattern array. + * @param[in] offset The shift of the starting point within the repeating dash pattern from which the path's dashing begins. * * @retval Result::Success When succeed. * @retval Result::FailedAllocation An internal error with a memory allocation for an object to be dashed. @@ -983,8 +984,10 @@ public: * * @note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt. * @warning @p cnt must be greater than 1 if the dash pattern is valid. + * + * @since 1.0 */ - Result strokeDash(const float* dashPattern, uint32_t cnt) noexcept; + Result strokeDash(const float* dashPattern, uint32_t cnt, float offset = 0.0f) noexcept; /** * @brief Sets the cap style of the stroke in the open sub-paths. @@ -1144,10 +1147,13 @@ public: * @brief Gets the dash pattern of the stroke. * * @param[out] dashPattern The pointer to the memory, where the dash pattern array is stored. + * @param[out] offset The shift of the starting point within the repeating dash pattern. * * @return The length of the @p dashPattern array. + * + * @since 1.0 */ - uint32_t strokeDash(const float** dashPattern) const noexcept; + uint32_t strokeDash(const float** dashPattern, float* offset = nullptr) const noexcept; /** * @brief Gets the cap style used for stroking the path. diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index d79cb42e..6577217e 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -1385,16 +1385,10 @@ TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gra /*! * \brief Sets the shape's stroke dash pattern. * -* \code -* //dash pattern examples -* float dashPattern[2] = {20, 10}; // -- -- -- -* float dashPattern[2] = {40, 20}; // ---- ---- ---- -* float dashPattern[4] = {10, 20, 30, 40} // - --- - --- -* \endcode -* * \param[in] paint A Tvg_Paint pointer to the shape object. * \param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. * \param[in] cnt The size of the @p dashPattern array. +* \param[in] offset The shift of the starting point within the repeating dash pattern from which the path's dashing begins. * * \return Tvg_Result enumeration. * \retval TVG_RESULT_SUCCESS Succeed. @@ -1402,8 +1396,9 @@ TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gra * \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. * * \note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt. +* \since 1.0 */ -TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt); +TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt, float offset); /*! @@ -1414,12 +1409,14 @@ TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dash * \param[in] paint A Tvg_Paint pointer to the shape object. * \param[out] dashPattern The array of consecutive pair values of the dash length and the gap length. * \param[out] cnt The size of the @p dashPattern array. +* \param[out] offset The shift of the starting point within the repeating dash pattern. * * \return Tvg_Result enumeration. * \retval TVG_RESULT_SUCCESS Succeed. * \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. +* \since 1.0 */ -TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt); +TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt, float* offset); /*! diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 8d5d31a7..37238be2 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -382,17 +382,17 @@ TVG_API Tvg_Result tvg_shape_get_stroke_gradient(const Tvg_Paint* paint, Tvg_Gra } -TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt) +TVG_API Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt, float offset) { if (!paint) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(paint)->strokeDash(dashPattern, cnt); + return (Tvg_Result) reinterpret_cast(paint)->strokeDash(dashPattern, cnt, offset); } -TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt) +TVG_API Tvg_Result tvg_shape_get_stroke_dash(const Tvg_Paint* paint, const float** dashPattern, uint32_t* cnt, float* offset) { - if (!paint || !cnt || !dashPattern) return TVG_RESULT_INVALID_ARGUMENT; - *cnt = reinterpret_cast(paint)->strokeDash(dashPattern); + if (!paint) return TVG_RESULT_INVALID_ARGUMENT; + *cnt = reinterpret_cast(paint)->strokeDash(dashPattern, offset); return TVG_RESULT_SUCCESS; } diff --git a/src/examples/Capi.cpp b/src/examples/Capi.cpp index 0e46b927..afe0f2aa 100644 --- a/src/examples/Capi.cpp +++ b/src/examples/Capi.cpp @@ -161,7 +161,7 @@ void testCapi() //Prapare a dash for the stroke float dashPattern[4] = {15.0f, 30.0f, 2.0f, 30.0f}; - tvg_shape_set_stroke_dash(scene_shape2, dashPattern, 4); + tvg_shape_set_stroke_dash(scene_shape2, dashPattern, 4, 0.0f); tvg_shape_set_stroke_cap(scene_shape2, TVG_STROKE_CAP_ROUND); tvg_shape_set_stroke_color(scene_shape2, 0, 0, 255, 255); tvg_shape_set_stroke_width(scene_shape2, 15.0f); diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 174c6426..36a000e4 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -226,7 +226,7 @@ static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext& ct float dashes[2]; dashes[0] = stroke->dashSize(frameNo); dashes[1] = dashes[0] + stroke->dashGap(frameNo); - P(ctx.propagator)->strokeDash(dashes, 2, stroke->dashOffset(frameNo)); + ctx.propagator->strokeDash(dashes, 2, stroke->dashOffset(frameNo)); } else { ctx.propagator->strokeDash(nullptr, 0); } diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index f3b6015f..b3ce586f 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -352,7 +352,7 @@ static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg, vg->strokeJoin(style->stroke.join); vg->strokeMiterlimit(style->stroke.miterlimit); if (style->stroke.dash.array.count > 0) { - P(vg)->strokeDash(style->stroke.dash.array.data, style->stroke.dash.array.count, style->stroke.dash.offset); + vg->strokeDash(style->stroke.dash.array.data, style->stroke.dash.array.count, style->stroke.dash.offset); } //If stroke property is nullptr then do nothing diff --git a/src/renderer/tvgShape.cpp b/src/renderer/tvgShape.cpp index cf87936d..cb279472 100644 --- a/src/renderer/tvgShape.cpp +++ b/src/renderer/tvgShape.cpp @@ -335,15 +335,15 @@ const Fill* Shape::strokeFill() const noexcept } -Result Shape::strokeDash(const float* dashPattern, uint32_t cnt) noexcept +Result Shape::strokeDash(const float* dashPattern, uint32_t cnt, float offset) noexcept { - return pImpl->strokeDash(dashPattern, cnt, 0); + return pImpl->strokeDash(dashPattern, cnt, offset); } -uint32_t Shape::strokeDash(const float** dashPattern) const noexcept +uint32_t Shape::strokeDash(const float** dashPattern, float* offset) const noexcept { - return pImpl->rs.strokeDash(dashPattern, nullptr); + return pImpl->rs.strokeDash(dashPattern, offset); } diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index 352dbb59..d8ac7d9d 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -479,7 +479,7 @@ TvgBinCounter TvgSaver::serializeStroke(const Shape* shape, const Matrix* pTrans //dash const float* dashPattern = nullptr; float offset = 0.0f; - auto dashCnt = P(shape)->rs.strokeDash(&dashPattern, &offset); + auto dashCnt = shape->strokeDash(&dashPattern, &offset); if (dashPattern && dashCnt > 0) { TvgBinCounter dashCntSize = SIZE(dashCnt); TvgBinCounter dashPtrnSize = dashCnt * SIZE(dashPattern[0]); diff --git a/test/capi/capiShape.cpp b/test/capi/capiShape.cpp index a9c2c1c6..d981fae2 100644 --- a/test/capi/capiShape.cpp +++ b/test/capi/capiShape.cpp @@ -190,8 +190,8 @@ TEST_CASE("Stroke dash", "[capiStrokeDash]") float* dash_get; uint32_t cnt; - REQUIRE(tvg_shape_set_stroke_dash(paint, dash, 2) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_shape_get_stroke_dash(paint, (const float**) &dash_get, &cnt) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_shape_set_stroke_dash(paint, dash, 2, 0.0f) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_shape_get_stroke_dash(paint, (const float**) &dash_get, &cnt, nullptr) == TVG_RESULT_SUCCESS); REQUIRE(cnt == 2); for (uint32_t i = 0; i < cnt; i++) { REQUIRE(dash_get[i] == dash[i]); diff --git a/test/testShape.cpp b/test/testShape.cpp index 1d104871..b3385715 100644 --- a/test/testShape.cpp +++ b/test/testShape.cpp @@ -169,13 +169,17 @@ TEST_CASE("Stroking", "[tvgShape]") float dashPattern2[3] = {1.0f, 1.5f, 2.22f}; REQUIRE(shape->strokeDash(dashPattern2, 3) == Result::Success); + REQUIRE(shape->strokeDash(dashPattern2, 3, 4.5) == Result::Success); const float* dashPattern3; + float offset; REQUIRE(shape->strokeDash(nullptr) == 3); REQUIRE(shape->strokeDash(&dashPattern3) == 3); + REQUIRE(shape->strokeDash(&dashPattern3, &offset) == 3); REQUIRE(dashPattern3[0] == 1.0f); REQUIRE(dashPattern3[1] == 1.5f); REQUIRE(dashPattern3[2] == 2.22f); + REQUIRE(offset == 4.5f); REQUIRE(shape->strokeDash(nullptr, 0) == Result::Success);