From 8e5ca402503a71c77d29a7d9432f7afcb17495f2 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 20 Feb 2025 12:12:29 +0900 Subject: [PATCH] text: allow the unnamed font If the font name is not specified, ThorVG will select any available font candidate. This could be useful for font fallback mechanism. --- examples/Text.cpp | 2 +- inc/thorvg.h | 1 + src/bindings/capi/thorvg_capi.h | 1 + src/renderer/tvgLoader.cpp | 12 ++++++++++++ src/renderer/tvgLoader.h | 1 + src/renderer/tvgText.h | 2 +- test/testText.cpp | 1 + 7 files changed, 18 insertions(+), 2 deletions(-) diff --git a/examples/Text.cpp b/examples/Text.cpp index 397f2f42..7c1e13d7 100644 --- a/examples/Text.cpp +++ b/examples/Text.cpp @@ -72,7 +72,7 @@ struct UserExample : tvgexam::Example canvas->push(text2); auto text3 = tvg::Text::gen(); - text3->font("Arial", 40); + text3->font(nullptr, 40); //Use any font text3->text("Kerning Test: VA, AV, TJ, JT"); text3->fill(255, 255, 255); text3->translate(0, 225); diff --git a/inc/thorvg.h b/inc/thorvg.h index f239051b..60879b66 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -1528,6 +1528,7 @@ public: * * @retval Result::InsufficientCondition when the specified @p name cannot be found. * + * @note If the @p name is not specified, ThorVG will select any available font candidate. * @note Experimental API */ Result font(const char* name, float size, const char* style = nullptr) noexcept; diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index 00627639..5414aed4 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -2021,6 +2021,7 @@ TVG_API Tvg_Paint* tvg_text_new(void); * @retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr passed as the @p paint argument. * @retval TVG_RESULT_INSUFFICIENT_CONDITION The specified @p name cannot be found. * +* @note If the @p name is not specified, ThorVG will select any available font candidate. * @note Experimental API */ TVG_API Tvg_Result tvg_text_set_font(Tvg_Paint* paint, const char* name, float size, const char* style); diff --git a/src/renderer/tvgLoader.cpp b/src/renderer/tvgLoader.cpp index 4e830a80..6acb0cdb 100644 --- a/src/renderer/tvgLoader.cpp +++ b/src/renderer/tvgLoader.cpp @@ -341,6 +341,18 @@ LoadModule* LoaderMgr::loader(const char* key) } +LoadModule* LoaderMgr::anyfont() +{ + INLIST_FOREACH(_activeLoaders, loader) { + if ((loader->type == FileType::Ttf) && loader->pathcache) { + ++loader->sharing; + return loader; + } + } + return nullptr; +} + + LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const char* mimeType, const char* rpath, bool copy) { //Note that users could use the same data pointer with the different content. diff --git a/src/renderer/tvgLoader.h b/src/renderer/tvgLoader.h index b67317f7..8ff940cf 100644 --- a/src/renderer/tvgLoader.h +++ b/src/renderer/tvgLoader.h @@ -34,6 +34,7 @@ struct LoaderMgr static LoadModule* loader(const uint32_t* data, uint32_t w, uint32_t h, ColorSpace cs, bool copy); static LoadModule* loader(const char* name, const char* data, uint32_t size, const char* mimeType, bool copy); static LoadModule* loader(const char* key); + static LoadModule* anyfont(); static bool retrieve(const char* filename); static bool retrieve(LoadModule* loader); }; diff --git a/src/renderer/tvgText.h b/src/renderer/tvgText.h index 0a026466..2745e274 100644 --- a/src/renderer/tvgText.h +++ b/src/renderer/tvgText.h @@ -62,7 +62,7 @@ struct Text::Impl : Paint::Impl Result font(const char* name, float size, const char* style) { - auto loader = LoaderMgr::loader(name); + auto loader = name ? LoaderMgr::loader(name) : LoaderMgr::anyfont(); if (!loader) return Result::InsufficientCondition; if (style && strstr(style, "italic")) italic = true; diff --git a/test/testText.cpp b/test/testText.cpp index 3399c9ac..927b5040 100644 --- a/test/testText.cpp +++ b/test/testText.cpp @@ -108,6 +108,7 @@ TEST_CASE("Text Font", "[tvgText]") REQUIRE(text->font("Arial", 80) == tvg::Result::Success); REQUIRE(text->font("Arial", 1) == tvg::Result::Success); REQUIRE(text->font("Arial", 50) == tvg::Result::Success); + REQUIRE(text->font(nullptr, 50) == tvg::Result::Success); REQUIRE(text->font("InvalidFont", 80) == tvg::Result::InsufficientCondition); Initializer::term();