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;