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
478e45f9f3.

@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
This commit is contained in:
Mira Grudzinska 2023-08-28 12:24:30 +09:00 committed by Hermet Park
parent f3a2d2a5a6
commit 25a1321243
10 changed files with 33 additions and 26 deletions

View file

@ -976,6 +976,7 @@ public:
* *
* @param[in] dashPattern The array of consecutive pair values of the dash length and the gap length. * @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] 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::Success When succeed.
* @retval Result::FailedAllocation An internal error with a memory allocation for an object to be dashed. * @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. * @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. * @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. * @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. * @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] 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. * @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. * @brief Gets the cap style used for stroking the path.

View file

@ -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. * \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] 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] 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] 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. * \return Tvg_Result enumeration.
* \retval TVG_RESULT_SUCCESS Succeed. * \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. * \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. * \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[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] 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] 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. * \return Tvg_Result enumeration.
* \retval TVG_RESULT_SUCCESS Succeed. * \retval TVG_RESULT_SUCCESS Succeed.
* \retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer passed as an argument. * \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);
/*! /*!

View file

@ -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; if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
return (Tvg_Result) reinterpret_cast<Shape*>(paint)->strokeDash(dashPattern, cnt); return (Tvg_Result) reinterpret_cast<Shape*>(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; if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
*cnt = reinterpret_cast<const Shape*>(paint)->strokeDash(dashPattern); *cnt = reinterpret_cast<const Shape*>(paint)->strokeDash(dashPattern, offset);
return TVG_RESULT_SUCCESS; return TVG_RESULT_SUCCESS;
} }

View file

@ -161,7 +161,7 @@ void testCapi()
//Prapare a dash for the stroke //Prapare a dash for the stroke
float dashPattern[4] = {15.0f, 30.0f, 2.0f, 30.0f}; 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_cap(scene_shape2, TVG_STROKE_CAP_ROUND);
tvg_shape_set_stroke_color(scene_shape2, 0, 0, 255, 255); tvg_shape_set_stroke_color(scene_shape2, 0, 0, 255, 255);
tvg_shape_set_stroke_width(scene_shape2, 15.0f); tvg_shape_set_stroke_width(scene_shape2, 15.0f);

View file

@ -226,7 +226,7 @@ static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext& ct
float dashes[2]; float dashes[2];
dashes[0] = stroke->dashSize(frameNo); dashes[0] = stroke->dashSize(frameNo);
dashes[1] = dashes[0] + stroke->dashGap(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 { } else {
ctx.propagator->strokeDash(nullptr, 0); ctx.propagator->strokeDash(nullptr, 0);
} }

View file

@ -352,7 +352,7 @@ static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg,
vg->strokeJoin(style->stroke.join); vg->strokeJoin(style->stroke.join);
vg->strokeMiterlimit(style->stroke.miterlimit); vg->strokeMiterlimit(style->stroke.miterlimit);
if (style->stroke.dash.array.count > 0) { 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 //If stroke property is nullptr then do nothing

View file

@ -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);
} }

View file

@ -479,7 +479,7 @@ TvgBinCounter TvgSaver::serializeStroke(const Shape* shape, const Matrix* pTrans
//dash //dash
const float* dashPattern = nullptr; const float* dashPattern = nullptr;
float offset = 0.0f; float offset = 0.0f;
auto dashCnt = P(shape)->rs.strokeDash(&dashPattern, &offset); auto dashCnt = shape->strokeDash(&dashPattern, &offset);
if (dashPattern && dashCnt > 0) { if (dashPattern && dashCnt > 0) {
TvgBinCounter dashCntSize = SIZE(dashCnt); TvgBinCounter dashCntSize = SIZE(dashCnt);
TvgBinCounter dashPtrnSize = dashCnt * SIZE(dashPattern[0]); TvgBinCounter dashPtrnSize = dashCnt * SIZE(dashPattern[0]);

View file

@ -190,8 +190,8 @@ TEST_CASE("Stroke dash", "[capiStrokeDash]")
float* dash_get; float* dash_get;
uint32_t cnt; uint32_t cnt;
REQUIRE(tvg_shape_set_stroke_dash(paint, dash, 2) == 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) == TVG_RESULT_SUCCESS); REQUIRE(tvg_shape_get_stroke_dash(paint, (const float**) &dash_get, &cnt, nullptr) == TVG_RESULT_SUCCESS);
REQUIRE(cnt == 2); REQUIRE(cnt == 2);
for (uint32_t i = 0; i < cnt; i++) { for (uint32_t i = 0; i < cnt; i++) {
REQUIRE(dash_get[i] == dash[i]); REQUIRE(dash_get[i] == dash[i]);

View file

@ -169,13 +169,17 @@ TEST_CASE("Stroking", "[tvgShape]")
float dashPattern2[3] = {1.0f, 1.5f, 2.22f}; float dashPattern2[3] = {1.0f, 1.5f, 2.22f};
REQUIRE(shape->strokeDash(dashPattern2, 3) == Result::Success); REQUIRE(shape->strokeDash(dashPattern2, 3) == Result::Success);
REQUIRE(shape->strokeDash(dashPattern2, 3, 4.5) == Result::Success);
const float* dashPattern3; const float* dashPattern3;
float offset;
REQUIRE(shape->strokeDash(nullptr) == 3); REQUIRE(shape->strokeDash(nullptr) == 3);
REQUIRE(shape->strokeDash(&dashPattern3) == 3); REQUIRE(shape->strokeDash(&dashPattern3) == 3);
REQUIRE(shape->strokeDash(&dashPattern3, &offset) == 3);
REQUIRE(dashPattern3[0] == 1.0f); REQUIRE(dashPattern3[0] == 1.0f);
REQUIRE(dashPattern3[1] == 1.5f); REQUIRE(dashPattern3[1] == 1.5f);
REQUIRE(dashPattern3[2] == 2.22f); REQUIRE(dashPattern3[2] == 2.22f);
REQUIRE(offset == 4.5f);
REQUIRE(shape->strokeDash(nullptr, 0) == Result::Success); REQUIRE(shape->strokeDash(nullptr, 0) == Result::Success);