From aaddec7cb889c8d26ea8658de879c19958e425bb Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Wed, 5 Apr 2023 12:49:38 +0300 Subject: [PATCH] [TextServer] Add support for retrieving OpenType name strings. --- doc/classes/Font.xml | 6 ++ doc/classes/TextServer.xml | 7 ++ doc/classes/TextServerExtension.xml | 6 ++ modules/text_server_adv/text_server_adv.cpp | 113 ++++++++++++++++++++ modules/text_server_adv/text_server_adv.h | 1 + scene/resources/font.cpp | 5 + scene/resources/font.h | 1 + servers/text/text_server_extension.cpp | 7 ++ servers/text/text_server_extension.h | 2 + servers/text_server.cpp | 1 + servers/text_server.h | 1 + 11 files changed, 150 insertions(+) diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index 03cd7f835a4..fc4c4b4b5d8 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -215,6 +215,12 @@ Returns a set of OpenType feature tags. More info: [url=https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags]OpenType feature tags[/url]. + + + + Returns [Dictionary] with OpenType font name strings (localized font names, version, description, license information, sample text, etc.). + + diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 207349a76aa..807be99da36 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -334,6 +334,13 @@ Returns font OpenType feature set override. + + + + + Returns [Dictionary] with OpenType font name strings (localized font names, version, description, license information, sample text, etc.). + + diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index 0f04c3a10df..171318b96db 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -287,6 +287,12 @@ + + + + + + diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index dfc820050fe..6231702e845 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2017,6 +2017,119 @@ String TextServerAdvanced::_font_get_name(const RID &p_font_rid) const { return fd->font_name; } +Dictionary TextServerAdvanced::_font_get_ot_name_strings(const RID &p_font_rid) const { + FontAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Dictionary()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Dictionary()); + + hb_face_t *hb_face = hb_font_get_face(fd->cache[size]->hb_handle); + + unsigned int num_entries = 0; + const hb_ot_name_entry_t *names = hb_ot_name_list_names(hb_face, &num_entries); + HashMap names_for_lang; + for (unsigned int i = 0; i < num_entries; i++) { + String name; + switch (names[i].name_id) { + case HB_OT_NAME_ID_COPYRIGHT: { + name = "copyright"; + } break; + case HB_OT_NAME_ID_FONT_FAMILY: { + name = "family_name"; + } break; + case HB_OT_NAME_ID_FONT_SUBFAMILY: { + name = "subfamily_name"; + } break; + case HB_OT_NAME_ID_UNIQUE_ID: { + name = "unique_identifier"; + } break; + case HB_OT_NAME_ID_FULL_NAME: { + name = "full_name"; + } break; + case HB_OT_NAME_ID_VERSION_STRING: { + name = "version"; + } break; + case HB_OT_NAME_ID_POSTSCRIPT_NAME: { + name = "postscript_name"; + } break; + case HB_OT_NAME_ID_TRADEMARK: { + name = "trademark"; + } break; + case HB_OT_NAME_ID_MANUFACTURER: { + name = "manufacturer"; + } break; + case HB_OT_NAME_ID_DESIGNER: { + name = "designer"; + } break; + case HB_OT_NAME_ID_DESCRIPTION: { + name = "description"; + } break; + case HB_OT_NAME_ID_VENDOR_URL: { + name = "vendor_url"; + } break; + case HB_OT_NAME_ID_DESIGNER_URL: { + name = "designer_url"; + } break; + case HB_OT_NAME_ID_LICENSE: { + name = "license"; + } break; + case HB_OT_NAME_ID_LICENSE_URL: { + name = "license_url"; + } break; + case HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY: { + name = "typographic_family_name"; + } break; + case HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY: { + name = "typographic_subfamily_name"; + } break; + case HB_OT_NAME_ID_MAC_FULL_NAME: { + name = "full_name_macos"; + } break; + case HB_OT_NAME_ID_SAMPLE_TEXT: { + name = "sample_text"; + } break; + case HB_OT_NAME_ID_CID_FINDFONT_NAME: { + name = "cid_findfont_name"; + } break; + case HB_OT_NAME_ID_WWS_FAMILY: { + name = "weight_width_slope_family_name"; + } break; + case HB_OT_NAME_ID_WWS_SUBFAMILY: { + name = "weight_width_slope_subfamily_name"; + } break; + case HB_OT_NAME_ID_LIGHT_BACKGROUND: { + name = "light_background_palette"; + } break; + case HB_OT_NAME_ID_DARK_BACKGROUND: { + name = "dark_background_palette"; + } break; + case HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: { + name = "postscript_name_prefix"; + } break; + default: { + name = vformat("unknown_%d", names[i].name_id); + } break; + } + String text; + unsigned int text_size = hb_ot_name_get_utf32(hb_face, names[i].name_id, names[i].language, nullptr, nullptr) + 1; + text.resize(text_size); + hb_ot_name_get_utf32(hb_face, names[i].name_id, names[i].language, &text_size, (uint32_t *)text.ptrw()); + if (!text.is_empty()) { + Dictionary &id_string = names_for_lang[String(hb_language_to_string(names[i].language))]; + id_string[name] = text; + } + } + + Dictionary out; + for (const KeyValue &E : names_for_lang) { + out[E.key] = E.value; + } + + return out; +} + void TextServerAdvanced::_font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) { FontAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 4b8c3f7cd38..74ba6576042 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -714,6 +714,7 @@ public: MODBIND2(font_set_name, const RID &, const String &); MODBIND1RC(String, font_get_name, const RID &); + MODBIND1RC(Dictionary, font_get_ot_name_strings, const RID &); MODBIND2(font_set_antialiasing, const RID &, TextServer::FontAntialiasing); MODBIND1RC(TextServer::FontAntialiasing, font_get_antialiasing, const RID &); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index a9d8fc38a4e..0047f443d00 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -62,6 +62,7 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("get_font_name"), &Font::get_font_name); ClassDB::bind_method(D_METHOD("get_font_style_name"), &Font::get_font_style_name); + ClassDB::bind_method(D_METHOD("get_ot_name_strings"), &Font::get_ot_name_strings); ClassDB::bind_method(D_METHOD("get_font_style"), &Font::get_font_style); ClassDB::bind_method(D_METHOD("get_font_weight"), &Font::get_font_weight); ClassDB::bind_method(D_METHOD("get_font_stretch"), &Font::get_font_stretch); @@ -243,6 +244,10 @@ String Font::get_font_name() const { return TS->font_get_name(_get_rid()); } +Dictionary Font::get_ot_name_strings() const { + return TS->font_get_ot_name_strings(_get_rid()); +} + String Font::get_font_style_name() const { return TS->font_get_style_name(_get_rid()); } diff --git a/scene/resources/font.h b/scene/resources/font.h index a99151640eb..5d600451a17 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -126,6 +126,7 @@ public: virtual String get_font_name() const; virtual String get_font_style_name() const; + virtual Dictionary get_ot_name_strings() const; virtual BitField get_font_style() const; virtual int get_font_weight() const; virtual int get_font_stretch() const; diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 511417664f2..e3e86acb7ac 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -65,6 +65,7 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_name, "font_rid", "name"); GDVIRTUAL_BIND(_font_get_name, "font_rid"); + GDVIRTUAL_BIND(_font_get_ot_name_strings, "font_rid"); GDVIRTUAL_BIND(_font_set_style_name, "font_rid", "name_style"); GDVIRTUAL_BIND(_font_get_style_name, "font_rid"); @@ -476,6 +477,12 @@ String TextServerExtension::font_get_name(const RID &p_font_rid) const { return ret; } +Dictionary TextServerExtension::font_get_ot_name_strings(const RID &p_font_rid) const { + Dictionary ret; + GDVIRTUAL_CALL(_font_get_ot_name_strings, p_font_rid, ret); + return ret; +} + void TextServerExtension::font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) { GDVIRTUAL_CALL(_font_set_antialiasing, p_font_rid, p_antialiasing); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 402f0ec7acb..cfaec7e629e 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -101,8 +101,10 @@ public: virtual void font_set_name(const RID &p_font_rid, const String &p_name) override; virtual String font_get_name(const RID &p_font_rid) const override; + virtual Dictionary font_get_ot_name_strings(const RID &p_font_rid) const override; GDVIRTUAL2(_font_set_name, RID, const String &); GDVIRTUAL1RC(String, _font_get_name, RID); + GDVIRTUAL1RC(Dictionary, _font_get_ot_name_strings, RID); virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override; virtual String font_get_style_name(const RID &p_font_rid) const override; diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 30c601bc0d1..929cbc9ec63 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -219,6 +219,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_name", "font_rid", "name"), &TextServer::font_set_name); ClassDB::bind_method(D_METHOD("font_get_name", "font_rid"), &TextServer::font_get_name); + ClassDB::bind_method(D_METHOD("font_get_ot_name_strings", "font_rid"), &TextServer::font_get_ot_name_strings); ClassDB::bind_method(D_METHOD("font_set_style_name", "font_rid", "name"), &TextServer::font_set_style_name); ClassDB::bind_method(D_METHOD("font_get_style_name", "font_rid"), &TextServer::font_get_style_name); diff --git a/servers/text_server.h b/servers/text_server.h index 170249bf77f..a4ea1dfdc7c 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -251,6 +251,7 @@ public: virtual void font_set_name(const RID &p_font_rid, const String &p_name) = 0; virtual String font_get_name(const RID &p_font_rid) const = 0; + virtual Dictionary font_get_ot_name_strings(const RID &p_font_rid) const { return Dictionary(); } virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) = 0; virtual String font_get_style_name(const RID &p_font_rid) const = 0;