From 9b035f057c62cafecb5bfef96efce846a86bf00e Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 24 Nov 2022 23:28:44 -0800 Subject: [PATCH] common Paint: Add name getter/setter API Adds an API that can set/get string type name to tvgPaint. This can be used when the user needs to traverse the scene tree or find a specific instance. +) The SVG's "id" attribute is set to name when SVG is loaded. --- inc/thorvg.h | 22 ++++++++++++++++++++++ src/lib/tvgPaint.cpp | 16 ++++++++++++++++ src/lib/tvgPaint.h | 1 + src/loaders/svg/tvgSvgSceneBuilder.cpp | 3 +++ test/testPaint.cpp | 14 ++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/inc/thorvg.h b/inc/thorvg.h index 8bc7f1880..ad5554564 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -372,6 +372,28 @@ class TVG_EXPORT Paint */ uint32_t identifier() const noexcept; + /** + * @brief Sets the name for the current instance. + * + * The name can be up to 127 characters long. + * + * @note The "id" attribute of the SVG format is set to name, and save/load is not yet supported in the case of the TVG format. + * + * @return Result::Success when succeed, Result::InvalidArguments in case the name length exceeded 128 characters. + * + * @BETA_API + */ + Result name(std::string name) const noexcept; + + /** + * @brief Returns the name set for the current instance. + * + * @return The name set on the current instance when succeed, otherwise an empty string. + * + * @BETA_API + */ + std::string name() const noexcept; + _TVG_DECLARE_ACCESSOR(); _TVG_DECLARE_PRIVATE(Paint); }; diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index d0e908ddf..40eb4778f 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -104,6 +104,7 @@ Paint* Paint::Impl::duplicate() } ret->pImpl->opacity = opacity; + ret->pImpl->name = name; if (compData) ret->pImpl->composite(ret, compData->target->duplicate(), compData->method); @@ -405,3 +406,18 @@ uint32_t Paint::identifier() const noexcept { return pImpl->id; } + + +Result Paint::name(std::string name) const noexcept +{ + if (name.length() > 128) return Result::InvalidArguments; + pImpl->name = name; + return Result::Success; +} + + +std::string Paint::name() const noexcept +{ + return pImpl->name; +} + diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index c170559a3..ba05edb13 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -66,6 +66,7 @@ namespace tvg uint32_t ctxFlag = ContextFlag::Invalid; uint32_t id; uint8_t opacity = 255; + std::string name = ""; ~Impl() { diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 4cb4ffdae..2972f466a 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -729,6 +729,7 @@ static unique_ptr _sceneBuildHelper(const SvgNode* node, const Box& vBox, } else if ((*child)->type == SvgNodeType::Image) { auto image = _imageBuildHelper(*child, vBox, svgPath); if (image) { + if ((*child)->id) image->name(std::string((*child)->id)); scene->push(move(image)); if (isMaskWhite) *isMaskWhite = false; } @@ -743,6 +744,7 @@ static unique_ptr _sceneBuildHelper(const SvgNode* node, const Box& vBox, *isMaskWhite = false; } } + if ((*child)->id) shape->name(std::string((*child)->id)); scene->push(move(shape)); } } @@ -750,6 +752,7 @@ static unique_ptr _sceneBuildHelper(const SvgNode* node, const Box& vBox, _applyComposition(scene.get(), node, vBox, svgPath); scene->opacity(node->style->opacity); } + if (node->id) scene->name(std::string(node->id)); return scene; } return nullptr; diff --git a/test/testPaint.cpp b/test/testPaint.cpp index 1ef05f107..b4ada85bc 100644 --- a/test/testPaint.cpp +++ b/test/testPaint.cpp @@ -114,6 +114,17 @@ TEST_CASE("Opacity", "[tvgPaint]") REQUIRE(shape->opacity() == 0); } +TEST_CASE("Name", "[tvgPaint]") +{ + auto shape = Shape::gen(); + REQUIRE(shape); + + REQUIRE(shape->name().empty()); + + REQUIRE(shape->name("test") == Result::Success); + REQUIRE(shape->name() == "test"); +} + TEST_CASE("Bounding Box", "[tvgPaint]") { auto shape = Shape::gen(); @@ -152,6 +163,7 @@ TEST_CASE("Duplication", "[tvgPaint]") REQUIRE(shape->translate(200.0f, 100.0f) == Result::Success); REQUIRE(shape->scale(2.2f) == Result::Success); REQUIRE(shape->rotate(90.0f) == Result::Success); + REQUIRE(shape->name("test") == Result::Success); auto comp = Shape::gen(); REQUIRE(comp); @@ -164,6 +176,8 @@ TEST_CASE("Duplication", "[tvgPaint]") //Compare properties REQUIRE(dup->opacity() == 0); + REQUIRE(dup->name() == "test"); + auto m = shape->transform(); REQUIRE(m.e11 == Approx(0.0f).margin(0.000001)); REQUIRE(m.e12 == Approx(-2.2f).margin(0.000001));