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] 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.

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.
*
* \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);
/*!

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

View file

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

View file

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

View file

@ -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

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
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]);

View file

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

View file

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