api: path api revision for v1.0

Unify the Path commands & pts getters.

C++ API modiciation:
- uint32_t Shape::pathCommands(const PathCommand** cmds) const
- uint32_t Shape::pathCoords(const PathCommand** cmds) const
 -> Result Shape::path(const PathCommand** cmds, uint32_t* cmdsCnt, const Point** pts, uint32_t* ptsCnt)

C API modification:
- Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt)
- Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Commands** cmds, uint32_t* cnt)
 -> Tvg_Result tvg_shape_get_path(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cmdsCnt, const Tvg_Point** pts, uint32_t* ptsCnt)

issue: https://github.com/thorvg/thorvg/issues/3116
This commit is contained in:
Hermet Park 2025-01-13 17:22:20 +09:00 committed by Hermet Park
parent 5361ad1617
commit 48c8094d19
8 changed files with 52 additions and 68 deletions

View file

@ -73,14 +73,11 @@ void contents()
//////2. Solid transformed shape //////2. Solid transformed shape
//Set a shape //Set a shape
const Tvg_Path_Command* cmds; const Tvg_Path_Command* cmds;
uint32_t cmdCnt;
const Tvg_Point* pts; const Tvg_Point* pts;
uint32_t ptsCnt; uint32_t cmdCnt, ptsCnt;
tvg_shape_get_path(shape1, &cmds, &cmdCnt, &pts, &ptsCnt);
Tvg_Paint* shape2 = tvg_shape_new(); Tvg_Paint* shape2 = tvg_shape_new();
tvg_shape_get_path_commands(shape1, &cmds, &cmdCnt);
tvg_shape_get_path_coords(shape1, &pts, &ptsCnt);
tvg_shape_append_path(shape2, cmds, cmdCnt, pts, ptsCnt); tvg_shape_append_path(shape2, cmds, cmdCnt, pts, ptsCnt);
tvg_shape_set_fill_color(shape2, 255, 255, 255, 128); tvg_shape_set_fill_color(shape2, 255, 255, 255, 128);

View file

@ -1150,22 +1150,21 @@ public:
Result order(bool strokeFirst) noexcept; Result order(bool strokeFirst) noexcept;
/** /**
* @brief Gets the commands data of the path. * @brief Retrieves the current path data of the shape.
* *
* @param[out] cmds The pointer to the array of the commands from the path. * This function provides access to the shape's path data, including the commands
* and points that define the path.
* *
* @return The length of the @p cmds array when succeed, zero otherwise. * @param[out] cmds Pointer to the array of commands representing the path.
* Can be @c nullptr if this information is not needed.
* @param[out] cmdsCnt Pointer to the variable that receives the number of commands in the @p cmds array.
* Can be @c nullptr if this information is not needed.
* @param[out] pts Pointer to the array of two-dimensional points that define the path.
* Can be @c nullptr if this information is not needed.
* @param[out] ptsCnt Pointer to the variable that receives the number of points in the @p pts array.
* Can be @c nullptr if this information is not needed.
*/ */
uint32_t pathCommands(const PathCommand** cmds) const noexcept; Result path(const PathCommand** cmds, uint32_t* cmdsCnt, const Point** pts, uint32_t* ptsCnt) const noexcept;
/**
* @brief Gets the points values of the path.
*
* @param[out] pts The pointer to the array of the two-dimensional points from the path.
*
* @return The length of the @p pts array when succeed, zero otherwise.
*/
uint32_t pathCoords(const Point** pts) const noexcept;
/** /**
* @brief Gets the pointer to the gradient fill of the shape. * @brief Gets the pointer to the gradient fill of the shape.

View file

@ -1225,33 +1225,26 @@ TVG_API Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Comman
/*! /*!
* @brief Gets the points values of the path. * @brief Retrieves the current path data of the shape.
* *
* The function does not allocate any data, it operates on internal memory. There is no need to free the @p pts array. * This function provides access to the shape's path data, including the commands
* and points that define the path.
* *
* @param[in] paint A Tvg_Paint pointer to the shape object. * @param[out] cmds Pointer to the array of commands representing the path.
* @param[out] pts The pointer to the array of the two-dimensional points from the path. * Can be @c nullptr if this information is not needed.
* @param[out] cnt The length of the @p pts array. * @param[out] cmdsCnt Pointer to the variable that receives the number of commands in the @p cmds array.
* Can be @c nullptr if this information is not needed.
* @param[out] pts Pointer to the array of two-dimensional points that define the path.
* Can be @c nullptr if this information is not needed.
* @param[out] ptsCnt Pointer to the variable that receives the number of points in the @p pts array.
* Can be @c nullptr if this information is not needed.
* *
* @return Tvg_Result enumeration. * @return Tvg_Result enumeration.
* @retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument. * @retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer.
*
* @note If any of the arguments are @c nullptr, that value will be ignored.
*/ */
TVG_API Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt); TVG_API Tvg_Result tvg_shape_get_path(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cmdsCnt, const Tvg_Point** pts, uint32_t* ptsCnt);
/*!
* @brief Gets the commands data of the path.
*
* The function does not allocate any data. There is no need to free the @p cmds array.
*
* @param[in] paint A Tvg_Paint pointer to the shape object.
* @param[out] cmds The pointer to the array of the commands from the path.
* @param[out] cnt The length of the @p cmds array.
*
* @return Tvg_Result enumeration.
* @retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the argument.
*/
TVG_API Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cnt);
/*! /*!
@ -2149,7 +2142,7 @@ TVG_API Tvg_Result tvg_font_load(const char* path);
* @param[in] name The name under which the font will be stored and accessible (e.x. in a @p tvg_text_set_font API). * @param[in] name The name under which the font will be stored and accessible (e.x. in a @p tvg_text_set_font API).
* @param[in] data A pointer to a memory location where the content of the font data is stored. * @param[in] data A pointer to a memory location where the content of the font data is stored.
* @param[in] size The size in bytes of the memory occupied by the @p data. * @param[in] size The size in bytes of the memory occupied by the @p data.
* @param[in] mimetype Mimetype or extension of font data. In case a @c NULL or an empty "" value is provided the loader will be determined automatically. * @param[in] mimetype Mimetype or extension of font data. In case a @c nullptr or an empty "" value is provided the loader will be determined automatically.
* @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not (default). * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not (default).
* *
* @return Tvg_Result enumeration. * @return Tvg_Result enumeration.

View file

@ -373,18 +373,10 @@ TVG_API Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Comman
} }
TVG_API Tvg_Result tvg_shape_get_path_coords(const Tvg_Paint* paint, const Tvg_Point** pts, uint32_t* cnt) TVG_API Tvg_Result tvg_shape_get_path(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cmdsCnt, const Tvg_Point** pts, uint32_t* ptsCnt)
{ {
if (!paint || !pts || !cnt) return TVG_RESULT_INVALID_ARGUMENT; if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
*cnt = reinterpret_cast<const Shape*>(paint)->pathCoords((const Point**)pts); return (Tvg_Result) reinterpret_cast<const Shape*>(paint)->path((const PathCommand**)cmds, cmdsCnt, (const Point**)pts, ptsCnt);
return TVG_RESULT_SUCCESS;
}
TVG_API Tvg_Result tvg_shape_get_path_commands(const Tvg_Paint* paint, const Tvg_Path_Command** cmds, uint32_t* cnt)
{
if (!paint || !cmds || !cnt) return TVG_RESULT_INVALID_ARGUMENT;
*cnt = reinterpret_cast<const Shape*>(paint)->pathCommands((const PathCommand**)cmds);
return TVG_RESULT_SUCCESS; return TVG_RESULT_SUCCESS;
} }

View file

@ -423,7 +423,8 @@ static Paint* _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform) static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform)
{ {
auto currentPtsCnt = shape->pathCoords(nullptr); uint32_t currentPtsCnt;
shape->path(nullptr, nullptr, nullptr, &currentPtsCnt);
if (!_recognizeShape(node, shape)) return false; if (!_recognizeShape(node, shape)) return false;
@ -431,8 +432,9 @@ static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* sh
auto m = transform ? transform : (node->transform ? node->transform : nullptr); auto m = transform ? transform : (node->transform ? node->transform : nullptr);
if (m) { if (m) {
const Point *pts = nullptr; const Point *pts;
auto ptsCnt = shape->pathCoords(&pts); uint32_t ptsCnt;
shape->path(nullptr, nullptr, &pts, &ptsCnt);
auto p = const_cast<Point*>(pts) + currentPtsCnt; auto p = const_cast<Point*>(pts) + currentPtsCnt;
while (currentPtsCnt++ < ptsCnt) { while (currentPtsCnt++ < ptsCnt) {
*p *= *m; *p *= *m;

View file

@ -80,7 +80,8 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Mat
//Rectangle Candidates? //Rectangle Candidates?
const Point* pts; const Point* pts;
auto ptsCnt = shape->pathCoords(&pts); uint32_t ptsCnt;
shape->path(nullptr, nullptr, &pts, &ptsCnt);
//nothing to clip //nothing to clip
if (ptsCnt == 0) return Result::InvalidArguments; if (ptsCnt == 0) return Result::InvalidArguments;

View file

@ -49,17 +49,15 @@ Result Shape::reset() noexcept
} }
uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept Result Shape::path(const PathCommand** cmds, uint32_t* cmdsCnt, const Point** pts, uint32_t* ptsCnt) const noexcept
{ {
if (cmds) *cmds = SHAPE(this)->rs.path.cmds.data; if (cmds) *cmds = SHAPE(this)->rs.path.cmds.data;
return SHAPE(this)->rs.path.cmds.count; if (cmdsCnt) *cmdsCnt = SHAPE(this)->rs.path.cmds.count;
}
uint32_t Shape::pathCoords(const Point** pts) const noexcept
{
if (pts) *pts = SHAPE(this)->rs.path.pts.data; if (pts) *pts = SHAPE(this)->rs.path.pts.data;
return SHAPE(this)->rs.path.pts.count; if (ptsCnt) *ptsCnt = SHAPE(this)->rs.path.pts.count;
return Result::Success;
} }

View file

@ -110,10 +110,11 @@ TEST_CASE("Appending Paths", "[tvgShape]")
REQUIRE(shape->appendPath(cmds, 5, pts, 5) == Result::Success); REQUIRE(shape->appendPath(cmds, 5, pts, 5) == Result::Success);
const PathCommand* cmds2; const PathCommand* cmds2;
REQUIRE(shape->pathCommands(&cmds2) == 5);
const Point* pts2; const Point* pts2;
REQUIRE(shape->pathCoords(&pts2) == 5); uint32_t cmds2Cnt, pts2Cnt;
REQUIRE(shape->path(&cmds2, &cmds2Cnt, &pts2, &pts2Cnt) == Result::Success);
REQUIRE(cmds2Cnt == 5);
REQUIRE(pts2Cnt == 5);
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
REQUIRE(cmds2[i] == cmds[i]); REQUIRE(cmds2[i] == cmds[i]);
@ -122,8 +123,9 @@ TEST_CASE("Appending Paths", "[tvgShape]")
} }
shape->reset(); shape->reset();
REQUIRE(shape->pathCommands(nullptr) == 0); REQUIRE(shape->path(nullptr, &cmds2Cnt, nullptr, &pts2Cnt) == Result::Success);
REQUIRE(shape->pathCoords(nullptr) == 0); REQUIRE(cmds2Cnt == 0);
REQUIRE(pts2Cnt == 0);
} }
TEST_CASE("Stroking", "[tvgShape]") TEST_CASE("Stroking", "[tvgShape]")