summaryrefslogtreecommitdiff
path: root/modules/text_server_adv
diff options
context:
space:
mode:
Diffstat (limited to 'modules/text_server_adv')
-rw-r--r--modules/text_server_adv/SCsub19
-rw-r--r--modules/text_server_adv/gdextension_build/SConstruct92
-rw-r--r--modules/text_server_adv/gdextension_build/text_server_adv.gdextension24
-rw-r--r--modules/text_server_adv/text_server_adv.cpp757
-rw-r--r--modules/text_server_adv/text_server_adv.h438
-rw-r--r--modules/text_server_adv/thorvg_bounds_iterator.cpp70
-rw-r--r--modules/text_server_adv/thorvg_bounds_iterator.h58
-rw-r--r--modules/text_server_adv/thorvg_svg_in_ot.cpp320
-rw-r--r--modules/text_server_adv/thorvg_svg_in_ot.h86
9 files changed, 1294 insertions, 570 deletions
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index 8d0245f0f6..3c7a89b705 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -39,6 +39,9 @@ thirdparty_obj = []
freetype_enabled = "freetype" in env.module_list
msdfgen_enabled = "msdfgen" in env.module_list
+if "svg" in env.module_list:
+ env_text_server_adv.Prepend(CPPPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/lib"])
+
if env["builtin_harfbuzz"]:
env_harfbuzz = env_modules.Clone()
env_harfbuzz.disable_warnings()
@@ -131,9 +134,14 @@ if env["builtin_harfbuzz"]:
env_harfbuzz.Append(
CCFLAGS=[
"-DHAVE_FREETYPE",
- "-DHAVE_GRAPHITE2",
]
)
+ if env["graphite"]:
+ env_harfbuzz.Append(
+ CCFLAGS=[
+ "-DHAVE_GRAPHITE2",
+ ]
+ )
if env["builtin_freetype"]:
env_harfbuzz.Prepend(CPPPATH=["#thirdparty/freetype/include"])
if env["builtin_graphite"] and env["graphite"]:
@@ -215,6 +223,9 @@ if env["builtin_graphite"] and freetype_enabled and env["graphite"]:
]
)
+ if env.msvc: # Not our business to fix.
+ env_graphite.Append(CCFLAGS=["-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS"])
+
lib = env_graphite.add_library("graphite_builtin", thirdparty_sources)
thirdparty_obj += lib
@@ -443,9 +454,9 @@ if env["builtin_icu"]:
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
- icu_data_name = "icudt71l.dat"
+ icu_data_name = "icudt72l.dat"
- if env_icu["tools"]:
+ if env.editor_build:
env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name)
env_icu.Command("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name, make_icu_data)
env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/"])
@@ -479,7 +490,7 @@ if env["builtin_icu"]:
"-DICU_DATA_NAME=" + icu_data_name,
]
)
- if env_text_server_adv["tools"]:
+ if env.editor_build:
env_text_server_adv.Append(CXXFLAGS=["-DICU_STATIC_DATA"])
env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"])
diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct
index 488d1f641b..4a363fdd7a 100644
--- a/modules/text_server_adv/gdextension_build/SConstruct
+++ b/modules/text_server_adv/gdextension_build/SConstruct
@@ -23,6 +23,7 @@ opts.Add(BoolVariable("brotli_enabled", "Use Brotli library", True))
opts.Add(BoolVariable("freetype_enabled", "Use FreeType library", True))
opts.Add(BoolVariable("msdfgen_enabled", "Use MSDFgen library (require FreeType)", True))
opts.Add(BoolVariable("graphite_enabled", "Use Graphite library (require FreeType)", True))
+opts.Add(BoolVariable("thorvg_enabled", "Use ThorVG library (require FreeType)", True))
opts.Add(BoolVariable("static_icu_data", "Use built-in ICU data", True))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
@@ -34,6 +35,79 @@ if not env["verbose"]:
if env["platform"] == "windows" and not env["use_mingw"]:
env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.
+# ThorVG
+if env["thorvg_enabled"] and env["freetype_enabled"]:
+ env_tvg = env.Clone()
+ env_tvg.disable_warnings()
+
+ thirdparty_tvg_dir = "../../../thirdparty/thorvg/"
+ thirdparty_tvg_sources = [
+ "src/lib/sw_engine/tvgSwFill.cpp",
+ "src/lib/sw_engine/tvgSwImage.cpp",
+ "src/lib/sw_engine/tvgSwMath.cpp",
+ "src/lib/sw_engine/tvgSwMemPool.cpp",
+ "src/lib/sw_engine/tvgSwRaster.cpp",
+ "src/lib/sw_engine/tvgSwRenderer.cpp",
+ "src/lib/sw_engine/tvgSwRle.cpp",
+ "src/lib/sw_engine/tvgSwShape.cpp",
+ "src/lib/sw_engine/tvgSwStroke.cpp",
+ "src/lib/tvgAccessor.cpp",
+ "src/lib/tvgBezier.cpp",
+ "src/lib/tvgCanvas.cpp",
+ "src/lib/tvgFill.cpp",
+ "src/lib/tvgGlCanvas.cpp",
+ "src/lib/tvgInitializer.cpp",
+ "src/lib/tvgLinearGradient.cpp",
+ "src/lib/tvgLoader.cpp",
+ "src/lib/tvgLzw.cpp",
+ "src/lib/tvgPaint.cpp",
+ "src/lib/tvgPicture.cpp",
+ "src/lib/tvgRadialGradient.cpp",
+ "src/lib/tvgRender.cpp",
+ "src/lib/tvgSaver.cpp",
+ "src/lib/tvgScene.cpp",
+ "src/lib/tvgShape.cpp",
+ "src/lib/tvgSwCanvas.cpp",
+ "src/lib/tvgTaskScheduler.cpp",
+ "src/loaders/external_png/tvgPngLoader.cpp",
+ "src/loaders/jpg/tvgJpgd.cpp",
+ "src/loaders/jpg/tvgJpgLoader.cpp",
+ "src/loaders/raw/tvgRawLoader.cpp",
+ "src/loaders/svg/tvgSvgCssStyle.cpp",
+ "src/loaders/svg/tvgSvgLoader.cpp",
+ "src/loaders/svg/tvgSvgPath.cpp",
+ "src/loaders/svg/tvgSvgSceneBuilder.cpp",
+ "src/loaders/svg/tvgSvgUtil.cpp",
+ "src/loaders/svg/tvgXmlParser.cpp",
+ "src/loaders/tvg/tvgTvgBinInterpreter.cpp",
+ "src/loaders/tvg/tvgTvgLoader.cpp",
+ "src/savers/tvg/tvgTvgSaver.cpp",
+ ]
+ thirdparty_tvg_sources = [thirdparty_tvg_dir + file for file in thirdparty_tvg_sources]
+
+ env_tvg.Append(
+ CPPPATH=[
+ "../../../thirdparty/thorvg/inc",
+ "../../../thirdparty/thorvg/src/lib",
+ "../../../thirdparty/thorvg/src/lib/sw_engine",
+ "../../../thirdparty/thorvg/src/loaders/external_png",
+ "../../../thirdparty/thorvg/src/loaders/jpg",
+ "../../../thirdparty/thorvg/src/loaders/raw",
+ "../../../thirdparty/thorvg/src/loaders/svg",
+ "../../../thirdparty/thorvg/src/loaders/tvg",
+ "../../../thirdparty/thorvg/src/savers/tvg",
+ "../../../thirdparty/libpng",
+ ]
+ )
+ env.Append(CPPPATH=["../../../thirdparty/thorvg/inc", "../../../thirdparty/thorvg/src/lib"])
+ env.Append(CPPDEFINES=["MODULE_SVG_ENABLED"])
+
+ lib = env_tvg.Library(
+ f'tvg_builtin{env["suffix"]}{env["LIBSUFFIX"]}',
+ thirdparty_tvg_sources,
+ )
+ env.Append(LIBS=[lib])
+
# MSDFGEN
if env["msdfgen_enabled"] and env["freetype_enabled"]:
env_msdfgen = env.Clone()
@@ -68,7 +142,7 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
env.Append(CPPDEFINES=["MODULE_MSDFGEN_ENABLED"])
lib = env_msdfgen.Library(
- f'msdfgen_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+ f'msdfgen_builtin{env["suffix"]}{env["LIBSUFFIX"]}',
thirdparty_msdfgen_sources,
)
env.Append(LIBS=[lib])
@@ -193,13 +267,13 @@ if env["freetype_enabled"]:
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
]
)
- if env["target"] == "debug":
+ if env.dev_build:
env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
env.Append(CPPDEFINES=["MODULE_FREETYPE_ENABLED"])
lib = env_freetype.Library(
- f'freetype_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+ f'freetype_builtin{env["suffix"]}{env["LIBSUFFIX"]}',
thirdparty_freetype_sources,
)
env.Append(LIBS=[lib])
@@ -321,7 +395,7 @@ if env["freetype_enabled"]:
env.Append(CPPPATH=["../../../thirdparty/harfbuzz/src"])
lib = env_harfbuzz.Library(
- f'harfbuzz_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+ f'harfbuzz_builtin{env["suffix"]}{env["LIBSUFFIX"]}',
thirdparty_harfbuzz_sources,
)
env.Prepend(LIBS=[lib])
@@ -381,7 +455,7 @@ if env["graphite_enabled"] and env["freetype_enabled"]:
)
lib = env_graphite.Library(
- f'graphite_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+ f'graphite_builtin{env["suffix"]}{env["LIBSUFFIX"]}',
thirdparty_graphite_sources,
)
env.Append(LIBS=[lib])
@@ -597,7 +671,7 @@ thirdparty_icu_sources = [
]
thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources]
-icu_data_name = "icudt71l.dat"
+icu_data_name = "icudt72l.dat"
if env["static_icu_data"]:
env_icu.Depends("../../../thirdparty/icu4c/icudata.gen.h", "../../../thirdparty/icu4c/" + icu_data_name)
@@ -640,9 +714,7 @@ env.Append(CPPPATH=["../../../thirdparty/icu4c/common/", "../../../thirdparty/ic
if env["platform"] == "windows":
env.Append(LIBS=["advapi32"])
-lib = env_icu.Library(
- f'icu_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}', thirdparty_icu_sources
-)
+lib = env_icu.Library(f'icu_builtin{env["suffix"]}{env["LIBSUFFIX"]}', thirdparty_icu_sources)
env.Append(LIBS=[lib])
env.Append(CPPDEFINES=["GDEXTENSION"])
@@ -662,7 +734,7 @@ if env["platform"] == "macos":
)
else:
library = env.SharedLibrary(
- f'./bin/libtextserver_advanced.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["SHLIBSUFFIX"]}',
+ f'./bin/libtextserver_advanced{env["suffix"]}{env["SHLIBSUFFIX"]}',
source=sources,
)
diff --git a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
index 11ed271ae9..c12fcfdfdf 100644
--- a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
+++ b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension
@@ -4,9 +4,21 @@ entry_symbol = "textserver_advanced_init"
[libraries]
-linux.64.debug = "bin/libtextserver_advanced.linux.debug.64.so"
-linux.64.release = "bin/libtextserver_advanced.linux.release.64.so"
-windows.64.debug = "bin/libtextserver_advanced.windows.debug.64.dll"
-windows.64.release = "bin/libtextserver_advanced.windows.release.64.dll"
-macos.debug = "bin/libtextserver_advanced.macos.debug.framework"
-macos.release = "bin/libtextserver_advanced.macos.release.framework"
+linux.x86_64.debug = "bin/libtextserver_advanced.linux.template_debug.x86_64.so"
+linux.x86_64.release = "bin/libtextserver_advanced.linux.template_release.x86_64.so"
+linux.x86_32.debug = "bin/libtextserver_advanced.linux.template_debug.x86_32.so"
+linux.x86_32.release = "bin/libtextserver_advanced.linux.template_release.x86_32.so"
+linux.arm64.debug = "bin/libtextserver_advanced.linux.template_debug.arm64.so"
+linux.arm64.release = "bin/libtextserver_advanced.linux.template_release.arm64.so"
+linux.rv64.debug = "bin/libtextserver_advanced.linux.template_debug.rv64.so"
+linux.rv64.release = "bin/libtextserver_advanced.linux.template_release.rv64.so"
+
+windows.x86_64.debug = "bin/libtextserver_advanced.windows.template_debug.x86_64.dll"
+windows.x86_64.release = "bin/libtextserver_advanced.windows.template_release.x86_64.dll"
+windows.x86_32.debug = "bin/libtextserver_advanced.windows.template_debug.x86_32.dll"
+windows.x86_32.release = "bin/libtextserver_advanced.windows.template_release.x86_32.dll"
+windows.arm64.debug = "bin/libtextserver_advanced.windows.template_debug.arm64.dll"
+windows.arm64.release = "bin/libtextserver_advanced.windows.template_release.arm64.dll"
+
+macos.debug = "bin/libtextserver_advanced.macos.template_debug.framework"
+macos.release = "bin/libtextserver_advanced.macos.template_release.framework"
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 3565254ac7..166325c551 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -33,7 +33,7 @@
#ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.
-#include <godot_cpp/classes/file.hpp>
+#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
@@ -41,6 +41,8 @@
using namespace godot;
+#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var)
+
#else
// Headers for building as built-in module.
@@ -50,7 +52,7 @@ using namespace godot;
#include "core/string/print_string.h"
#include "core/string/translation.h"
-#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
+#include "modules/modules_enabled.gen.h" // For freetype, msdfgen, svg.
#endif
@@ -69,6 +71,10 @@ using namespace godot;
#include "msdfgen.h"
#endif
+#ifdef MODULE_SVG_ENABLED
+#include "thorvg_svg_in_ot.h"
+#endif
+
/*************************************************************************/
/* bmp_font_t HarfBuzz Bitmap font interface */
/*************************************************************************/
@@ -327,7 +333,7 @@ _FORCE_INLINE_ bool is_connected_to_prev(char32_t p_chr, char32_t p_pchr) {
/*************************************************************************/
-bool TextServerAdvanced::has_feature(Feature p_feature) const {
+bool TextServerAdvanced::_has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_SIMPLE_LAYOUT:
case FEATURE_BIDI_LAYOUT:
@@ -354,7 +360,7 @@ bool TextServerAdvanced::has_feature(Feature p_feature) const {
return false;
}
-String TextServerAdvanced::get_name() const {
+String TextServerAdvanced::_get_name() const {
#ifdef GDEXTENSION
return "ICU / HarfBuzz / Graphite (GDExtension)";
#else
@@ -362,7 +368,7 @@ String TextServerAdvanced::get_name() const {
#endif
}
-int64_t TextServerAdvanced::get_features() const {
+int64_t TextServerAdvanced::_get_features() const {
int64_t interface_features = FEATURE_SIMPLE_LAYOUT | FEATURE_BIDI_LAYOUT | FEATURE_VERTICAL_LAYOUT | FEATURE_SHAPING | FEATURE_KASHIDA_JUSTIFICATION | FEATURE_BREAK_ITERATORS | FEATURE_FONT_BITMAP | FEATURE_FONT_VARIABLE | FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION | FEATURE_USE_SUPPORT_DATA;
#ifdef MODULE_FREETYPE_ENABLED
interface_features |= FEATURE_FONT_DYNAMIC;
@@ -374,7 +380,7 @@ int64_t TextServerAdvanced::get_features() const {
return interface_features;
}
-void TextServerAdvanced::free_rid(const RID &p_rid) {
+void TextServerAdvanced::_free_rid(const RID &p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
FontAdvanced *fd = font_owner.get_or_null(p_rid);
@@ -387,12 +393,12 @@ void TextServerAdvanced::free_rid(const RID &p_rid) {
}
}
-bool TextServerAdvanced::has(const RID &p_rid) {
+bool TextServerAdvanced::_has(const RID &p_rid) {
_THREAD_SAFE_METHOD_
return font_owner.owns(p_rid) || shaped_owner.owns(p_rid);
}
-bool TextServerAdvanced::load_support_data(const String &p_filename) {
+bool TextServerAdvanced::_load_support_data(const String &p_filename) {
_THREAD_SAFE_METHOD_
#ifdef ICU_STATIC_DATA
@@ -410,7 +416,11 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
return false;
}
uint64_t len = f->get_length();
+#ifdef GDEXTENSION
+ PackedByteArray icu_data = f->get_buffer(len);
+#else
PackedByteArray icu_data = f->_get_buffer(len);
+#endif
UErrorCode err = U_ZERO_ERROR;
udata_setCommonData(icu_data.ptr(), &err);
@@ -429,7 +439,7 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
return true;
}
-String TextServerAdvanced::get_support_data_filename() const {
+String TextServerAdvanced::_get_support_data_filename() const {
#ifdef ICU_STATIC_DATA
return _MKSTR(ICU_DATA_NAME);
#else
@@ -437,7 +447,7 @@ String TextServerAdvanced::get_support_data_filename() const {
#endif
}
-String TextServerAdvanced::get_support_data_info() const {
+String TextServerAdvanced::_get_support_data_info() const {
#ifdef ICU_STATIC_DATA
return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(").");
#else
@@ -445,7 +455,7 @@ String TextServerAdvanced::get_support_data_info() const {
#endif
}
-bool TextServerAdvanced::save_support_data(const String &p_filename) const {
+bool TextServerAdvanced::_save_support_data(const String &p_filename) const {
_THREAD_SAFE_METHOD_
#ifdef ICU_STATIC_DATA
@@ -459,7 +469,11 @@ bool TextServerAdvanced::save_support_data(const String &p_filename) const {
PackedByteArray icu_data;
icu_data.resize(U_ICUDATA_SIZE);
memcpy(icu_data.ptrw(), U_ICUDATA_ENTRY_POINT, U_ICUDATA_SIZE);
+#ifdef GDEXTENSION
+ f->store_buffer(icu_data);
+#else
f->_store_buffer(icu_data);
+#endif
return true;
#else
@@ -467,7 +481,7 @@ bool TextServerAdvanced::save_support_data(const String &p_filename) const {
#endif
}
-bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const {
+bool TextServerAdvanced::_is_locale_right_to_left(const String &p_locale) const {
String l = p_locale.get_slicec('_', 0);
if ((l == "ar") || (l == "dv") || (l == "he") || (l == "fa") || (l == "ff") || (l == "ku") || (l == "ur")) {
return true;
@@ -739,7 +753,7 @@ void TextServerAdvanced::_insert_feature_sets() {
_insert_feature("weight", HB_TAG('w', 'g', 'h', 't'), Variant::Type::INT, false);
}
-int64_t TextServerAdvanced::name_to_tag(const String &p_name) const {
+int64_t TextServerAdvanced::_name_to_tag(const String &p_name) const {
if (feature_sets.has(p_name)) {
return feature_sets[p_name];
}
@@ -762,7 +776,7 @@ bool TextServerAdvanced::_get_tag_hidden(int64_t p_tag) const {
return false;
}
-String TextServerAdvanced::tag_to_name(int64_t p_tag) const {
+String TextServerAdvanced::_tag_to_name(int64_t p_tag) const {
if (feature_sets_inv.has(p_tag)) {
return feature_sets_inv[p_tag].name;
}
@@ -780,58 +794,27 @@ String TextServerAdvanced::tag_to_name(int64_t p_tag) const {
_FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_texture_pos_for_glyph(FontForSizeAdvanced *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height, bool p_msdf) const {
FontTexturePosition ret;
- ret.index = -1;
int mw = p_width;
int mh = p_height;
- for (int i = 0; i < p_data->textures.size(); i++) {
- const FontTexture &ct = p_data->textures[i];
-
- if (p_image_format != ct.format) {
+ ShelfPackTexture *ct = p_data->textures.ptrw();
+ for (int32_t i = 0; i < p_data->textures.size(); i++) {
+ if (p_image_format != ct[i].format) {
continue;
}
-
- if (mw > ct.texture_w || mh > ct.texture_h) { // Too big for this texture.
- continue;
- }
-
- if (ct.offsets.size() < ct.texture_w) {
+ if (mw > ct[i].texture_w || mh > ct[i].texture_h) { // Too big for this texture.
continue;
}
- ret.y = 0x7fffffff;
- ret.x = 0;
-
- for (int j = 0; j < ct.texture_w - mw; j++) {
- int max_y = 0;
-
- for (int k = j; k < j + mw; k++) {
- int y = ct.offsets[k];
- if (y > max_y) {
- max_y = y;
- }
- }
-
- if (max_y < ret.y) {
- ret.y = max_y;
- ret.x = j;
- }
- }
-
- if (ret.y == 0x7fffffff || ret.y + mh > ct.texture_h) {
- continue; // Fail, could not fit it here.
+ ret = ct[i].pack_rect(i, mh, mw);
+ if (ret.index != -1) {
+ break;
}
-
- ret.index = i;
- break;
}
if (ret.index == -1) {
// Could not find texture to fit, create one.
- ret.x = 0;
- ret.y = 0;
-
int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
#ifdef GDEXTENSION
@@ -859,12 +842,9 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
#endif
}
- FontTexture tex;
- tex.texture_w = texsize;
- tex.texture_h = texsize;
+ ShelfPackTexture tex = ShelfPackTexture(texsize, texsize);
tex.format = p_image_format;
tex.imgdata.resize(texsize * texsize * p_color_size);
-
{
// Zero texture.
uint8_t *w = tex.imgdata.ptrw();
@@ -887,14 +867,10 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
ERR_FAIL_V(ret);
}
}
- tex.offsets.resize(texsize);
- int32_t *offw = tex.offsets.ptrw();
- for (int i = 0; i < texsize; i++) { // Zero offsets.
- offw[i] = 0;
- }
-
p_data->textures.push_back(tex);
- ret.index = p_data->textures.size() - 1;
+
+ int32_t idx = p_data->textures.size() - 1;
+ ret = p_data->textures.write[idx].pack_rect(idx, mh, mw);
}
return ret;
@@ -1028,7 +1004,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh, true);
ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph());
- FontTexture &tex = p_data->textures.write[tex_pos.index];
+ ShelfPackTexture &tex = p_data->textures.write[tex_pos.index];
edgeColoringSimple(shape, 3.0); // Max. angle.
msdfgen::Bitmap<float, 4> image(w, h); // Texture size.
@@ -1043,8 +1019,14 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
td.projection = &projection;
td.distancePixelConversion = &distancePixelConversion;
+#ifdef GDEXTENSION
+ for (int i = 0; i < h; i++) {
+ _generateMTSDF_threaded(i, &td);
+ }
+#else
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerAdvanced::_generateMTSDF_threaded, &td, h, -1, true, SNAME("FontServerRasterizeMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
+#endif
msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config);
@@ -1065,12 +1047,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
tex.dirty = true;
- // Update height array.
- int32_t *offw = tex.offsets.ptrw();
- for (int k = tex_pos.x; k < tex_pos.x + mw; k++) {
- offw[k] = tex_pos.y + mh;
- }
-
chr.texture_idx = tex_pos.index;
chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2);
@@ -1118,8 +1094,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph());
// Fit character in char texture.
-
- FontTexture &tex = p_data->textures.write[tex_pos.index];
+ ShelfPackTexture &tex = p_data->textures.write[tex_pos.index];
{
uint8_t *wr = tex.imgdata.ptrw();
@@ -1184,12 +1159,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
tex.dirty = true;
- // Update height array.
- int32_t *offw = tex.offsets.ptrw();
- for (int k = tex_pos.x; k < tex_pos.x + mw; k++) {
- offw[k] = tex_pos.y + mh;
- }
-
FontGlyph chr;
chr.advance = advance * p_data->scale / p_data->oversampling;
chr.texture_idx = tex_pos.index;
@@ -1379,7 +1348,13 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
int error = 0;
if (!ft_library) {
error = FT_Init_FreeType(&ft_library);
- ERR_FAIL_COND_V_MSG(error != 0, false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'.");
+ if (error != 0) {
+ memdelete(fd);
+ ERR_FAIL_V_MSG(false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'.");
+ }
+#ifdef MODULE_SVG_ENABLED
+ FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks());
+#endif
}
memset(&fd->stream, 0, sizeof(FT_StreamRec));
@@ -1408,6 +1383,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
if (error) {
FT_Done_Face(fd->face);
fd->face = nullptr;
+ memdelete(fd);
ERR_FAIL_V_MSG(false, "FreeType: Error loading font: '" + String(FT_Error_String(error)) + "'.");
}
@@ -1415,7 +1391,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
fd->oversampling = 1.0;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0) {
- fd->oversampling = font_get_global_oversampling();
+ fd->oversampling = _font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
}
@@ -1808,8 +1784,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
coords.write[i] = CLAMP(var.value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
- if (p_font_data->variation_coordinates.has(tag_to_name(var.tag))) {
- var.value = p_font_data->variation_coordinates[tag_to_name(var.tag)];
+ if (p_font_data->variation_coordinates.has(_tag_to_name(var.tag))) {
+ var.value = p_font_data->variation_coordinates[_tag_to_name(var.tag)];
coords.write[i] = CLAMP(var.value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
@@ -1821,6 +1797,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
FT_Done_MM_Var(ft_library, amaster);
}
#else
+ memdelete(fd);
ERR_FAIL_V_MSG(false, "FreeType: Can't load dynamic font, engine is compiled without FreeType support!");
#endif
} else {
@@ -1854,7 +1831,7 @@ hb_font_t *TextServerAdvanced::_font_get_hb_handle(const RID &p_font_rid, int64_
return fd->cache[size]->hb_handle;
}
-RID TextServerAdvanced::create_font() {
+RID TextServerAdvanced::_create_font() {
_THREAD_SAFE_METHOD_
FontAdvanced *fd = memnew(FontAdvanced);
@@ -1862,7 +1839,7 @@ RID TextServerAdvanced::create_font() {
return font_owner.make_rid(fd);
}
-void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
+void TextServerAdvanced::_font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1873,7 +1850,7 @@ void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteAr
fd->data_size = fd->data.size();
}
-void TextServerAdvanced::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
+void TextServerAdvanced::_font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1884,7 +1861,7 @@ void TextServerAdvanced::font_set_data_ptr(const RID &p_font_rid, const uint8_t
fd->data_size = p_data_size;
}
-void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
+void TextServerAdvanced::_font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
ERR_FAIL_COND(p_face_index < 0);
ERR_FAIL_COND(p_face_index >= 0x7FFF);
@@ -1898,7 +1875,7 @@ void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_fa
}
}
-int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_face_index(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1906,7 +1883,7 @@ int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
return fd->face_index;
}
-int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_face_count(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1920,6 +1897,9 @@ int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
if (!ft_library) {
error = FT_Init_FreeType(&ft_library);
ERR_FAIL_COND_V_MSG(error != 0, false, "FreeType: Error initializing library: '" + String(FT_Error_String(error)) + "'.");
+#ifdef MODULE_SVG_ENABLED
+ FT_Property_Set(ft_library, "ot-svg", "svg-hooks", get_tvg_svg_in_ot_hooks());
+#endif
}
FT_StreamRec stream;
@@ -1947,7 +1927,7 @@ int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
return face_count;
}
-void TextServerAdvanced::font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
+void TextServerAdvanced::_font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1957,7 +1937,7 @@ void TextServerAdvanced::font_set_style(const RID &p_font_rid, BitField<FontStyl
fd->style_flags = p_style;
}
-BitField<TextServer::FontStyle> TextServerAdvanced::font_get_style(const RID &p_font_rid) const {
+BitField<TextServer::FontStyle> TextServerAdvanced::_font_get_style(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1967,7 +1947,7 @@ BitField<TextServer::FontStyle> TextServerAdvanced::font_get_style(const RID &p_
return fd->style_flags;
}
-void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String &p_name) {
+void TextServerAdvanced::_font_set_style_name(const RID &p_font_rid, const String &p_name) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1977,7 +1957,7 @@ void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String
fd->style_name = p_name;
}
-String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_style_name(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -1987,7 +1967,7 @@ String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
return fd->style_name;
}
-void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_name) {
+void TextServerAdvanced::_font_set_name(const RID &p_font_rid, const String &p_name) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1997,7 +1977,7 @@ void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_na
fd->font_name = p_name;
}
-String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_name(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -2007,7 +1987,7 @@ String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
return fd->font_name;
}
-void TextServerAdvanced::font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
+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);
@@ -2018,7 +1998,7 @@ void TextServerAdvanced::font_set_antialiasing(RID p_font_rid, TextServer::FontA
}
}
-TextServer::FontAntialiasing TextServerAdvanced::font_get_antialiasing(RID p_font_rid) const {
+TextServer::FontAntialiasing TextServerAdvanced::_font_get_antialiasing(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TextServer::FONT_ANTIALIASING_NONE);
@@ -2026,7 +2006,7 @@ TextServer::FontAntialiasing TextServerAdvanced::font_get_antialiasing(RID p_fon
return fd->antialiasing;
}
-void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
+void TextServerAdvanced::_font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2035,13 +2015,14 @@ void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p
for (KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
for (int i = 0; i < E.value->textures.size(); i++) {
E.value->textures.write[i].dirty = true;
+ E.value->textures.write[i].texture = Ref<ImageTexture>();
}
}
fd->mipmaps = p_generate_mipmaps;
}
}
-bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_get_generate_mipmaps(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2049,7 +2030,7 @@ bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const
return fd->mipmaps;
}
-void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
+void TextServerAdvanced::_font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2060,7 +2041,7 @@ void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &
}
}
-bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2068,7 +2049,7 @@ bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p
return fd->msdf;
}
-void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
+void TextServerAdvanced::_font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2079,7 +2060,7 @@ void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_
}
}
-int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_msdf_pixel_range(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2087,7 +2068,7 @@ int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) con
return fd->msdf_range;
}
-void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
+void TextServerAdvanced::_font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2098,7 +2079,7 @@ void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msd
}
}
-int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_msdf_size(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2106,7 +2087,7 @@ int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
return fd->msdf_source_size;
}
-void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
+void TextServerAdvanced::_font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2114,7 +2095,7 @@ void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fi
fd->fixed_size = p_fixed_size;
}
-int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_fixed_size(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2122,7 +2103,7 @@ int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
return fd->fixed_size;
}
-void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
+void TextServerAdvanced::_font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2133,7 +2114,7 @@ void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p
}
}
-bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_is_force_autohinter(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2141,7 +2122,7 @@ bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
return fd->force_autohinter;
}
-void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
+void TextServerAdvanced::_font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2152,7 +2133,7 @@ void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hin
}
}
-TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid) const {
+TextServer::Hinting TextServerAdvanced::_font_get_hinting(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, HINTING_NONE);
@@ -2160,7 +2141,7 @@ TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid)
return fd->hinting;
}
-void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
+void TextServerAdvanced::_font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2168,7 +2149,7 @@ void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, Te
fd->subpixel_positioning = p_subpixel;
}
-TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positioning(const RID &p_font_rid) const {
+TextServer::SubpixelPositioning TextServerAdvanced::_font_get_subpixel_positioning(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, SUBPIXEL_POSITIONING_DISABLED);
@@ -2176,7 +2157,7 @@ TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positionin
return fd->subpixel_positioning;
}
-void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_strength) {
+void TextServerAdvanced::_font_set_embolden(const RID &p_font_rid, double p_strength) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2187,7 +2168,7 @@ void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_stren
}
}
-double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
+double TextServerAdvanced::_font_get_embolden(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2195,7 +2176,7 @@ double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
return fd->embolden;
}
-void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
+void TextServerAdvanced::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2206,7 +2187,7 @@ void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transfo
}
}
-Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const {
+Transform2D TextServerAdvanced::_font_get_transform(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Transform2D());
@@ -2214,7 +2195,7 @@ Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const
return fd->transform;
}
-void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
+void TextServerAdvanced::_font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2225,7 +2206,7 @@ void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, c
}
}
-Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_get_variation_coordinates(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2233,7 +2214,7 @@ Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_
return fd->variation_coordinates;
}
-void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
+void TextServerAdvanced::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2244,7 +2225,7 @@ void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_o
}
}
-double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
+double TextServerAdvanced::_font_get_oversampling(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2252,7 +2233,7 @@ double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
return fd->oversampling;
}
-TypedArray<Vector2i> TextServerAdvanced::font_get_size_cache_list(const RID &p_font_rid) const {
+TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -2264,7 +2245,7 @@ TypedArray<Vector2i> TextServerAdvanced::font_get_size_cache_list(const RID &p_f
return ret;
}
-void TextServerAdvanced::font_clear_size_cache(const RID &p_font_rid) {
+void TextServerAdvanced::_font_clear_size_cache(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2275,7 +2256,7 @@ void TextServerAdvanced::font_clear_size_cache(const RID &p_font_rid) {
fd->cache.clear();
}
-void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2286,7 +2267,7 @@ void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vec
}
}
-void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
+void TextServerAdvanced::_font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2297,7 +2278,7 @@ void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->ascent = p_ascent;
}
-double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2313,7 +2294,7 @@ double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size
}
}
-void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
+void TextServerAdvanced::_font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2323,7 +2304,7 @@ void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->descent = p_descent;
}
-double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_descent(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2339,7 +2320,7 @@ double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_siz
}
}
-void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
+void TextServerAdvanced::_font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2350,7 +2331,7 @@ void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int6
fd->cache[size]->underline_position = p_underline_position;
}
-double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2366,7 +2347,7 @@ double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, in
}
}
-void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
+void TextServerAdvanced::_font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2377,7 +2358,7 @@ void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int
fd->cache[size]->underline_thickness = p_underline_thickness;
}
-double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2393,7 +2374,7 @@ double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, i
}
}
-void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
+void TextServerAdvanced::_font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2409,7 +2390,7 @@ void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, d
fd->cache[size]->scale = p_scale;
}
-double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_scale(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2425,7 +2406,7 @@ double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size)
}
}
-int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
+int64_t TextServerAdvanced::_font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -2437,7 +2418,7 @@ int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const
return fd->cache[size]->textures.size();
}
-void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2447,7 +2428,7 @@ void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector
fd->cache[size]->textures.clear();
}
-void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
+void TextServerAdvanced::_font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2459,7 +2440,7 @@ void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector
fd->cache[size]->textures.remove_at(p_texture_index);
}
-void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
+void TextServerAdvanced::_font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND(p_image.is_null());
@@ -2472,16 +2453,14 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec
fd->cache[size]->textures.resize(p_texture_index + 1);
}
- FontTexture &tex = fd->cache[size]->textures.write[p_texture_index];
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[p_texture_index];
tex.imgdata = p_image->get_data();
tex.texture_w = p_image->get_width();
tex.texture_h = p_image->get_height();
tex.format = p_image->get_format();
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
+ Ref<Image> img = Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
if (fd->mipmaps) {
img->generate_mipmaps();
}
@@ -2490,7 +2469,7 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec
tex.dirty = false;
}
-Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+Ref<Image> TextServerAdvanced::_font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Ref<Image>());
@@ -2499,15 +2478,12 @@ Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, con
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Ref<Image>());
ERR_FAIL_INDEX_V(p_texture_index, fd->cache[size]->textures.size(), Ref<Image>());
- const FontTexture &tex = fd->cache[size]->textures[p_texture_index];
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
-
- return img;
+ const ShelfPackTexture &tex = fd->cache[size]->textures[p_texture_index];
+ return Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
}
-void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
+void TextServerAdvanced::_font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offsets) {
+ ERR_FAIL_COND(p_offsets.size() % 4 != 0);
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2519,11 +2495,14 @@ void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const V
fd->cache[size]->textures.resize(p_texture_index + 1);
}
- FontTexture &tex = fd->cache[size]->textures.write[p_texture_index];
- tex.offsets = p_offset;
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[p_texture_index];
+ tex.shelves.clear();
+ for (int32_t i = 0; i < p_offsets.size(); i += 4) {
+ tex.shelves.push_back(Shelf(p_offsets[i], p_offsets[i + 1], p_offsets[i + 2], p_offsets[i + 3]));
+ }
}
-PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+PackedInt32Array TextServerAdvanced::_font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -2532,11 +2511,23 @@ PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), PackedInt32Array());
ERR_FAIL_INDEX_V(p_texture_index, fd->cache[size]->textures.size(), PackedInt32Array());
- const FontTexture &tex = fd->cache[size]->textures[p_texture_index];
- return tex.offsets;
+ const ShelfPackTexture &tex = fd->cache[size]->textures[p_texture_index];
+ PackedInt32Array ret;
+ ret.resize(tex.shelves.size() * 4);
+
+ int32_t *wr = ret.ptrw();
+ int32_t i = 0;
+ for (const Shelf &E : tex.shelves) {
+ wr[i * 4] = E.x;
+ wr[i * 4 + 1] = E.y;
+ wr[i * 4 + 2] = E.w;
+ wr[i * 4 + 3] = E.h;
+ i++;
+ }
+ return ret;
}
-PackedInt32Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
+PackedInt32Array TextServerAdvanced::_font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -2552,7 +2543,7 @@ PackedInt32Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid,
return ret;
}
-void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2563,7 +2554,7 @@ void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i
fd->cache[size]->glyph_map.clear();
}
-void TextServerAdvanced::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
+void TextServerAdvanced::_font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2588,7 +2579,7 @@ double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) c
}
}
-Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2616,16 +2607,17 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
ea.x = fd->embolden * double(size.x) / 64.0;
}
+ double scale = _font_get_scale(p_font_rid, p_size);
if (fd->msdf) {
return (gl[p_glyph | mod].advance + ea) * (double)p_size / (double)fd->msdf_source_size;
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
+ } else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) {
return (gl[p_glyph | mod].advance + ea).round();
} else {
return gl[p_glyph | mod].advance + ea;
}
}
-void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
+void TextServerAdvanced::_font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2640,7 +2632,7 @@ void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p
gl[p_glyph].found = true;
}
-Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2670,7 +2662,7 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
}
}
-void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
+void TextServerAdvanced::_font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2685,7 +2677,7 @@ void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vect
gl[p_glyph].found = true;
}
-Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2715,7 +2707,7 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
}
}
-void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
+void TextServerAdvanced::_font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2730,7 +2722,7 @@ void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector
gl[p_glyph].found = true;
}
-Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Rect2 TextServerAdvanced::_font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Rect2());
@@ -2755,7 +2747,7 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
return gl[p_glyph | mod].uv_rect;
}
-void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
+void TextServerAdvanced::_font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2770,7 +2762,7 @@ void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vec
gl[p_glyph].found = true;
}
-int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+int64_t TextServerAdvanced::_font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, -1);
@@ -2795,7 +2787,7 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
return gl[p_glyph | mod].texture_idx;
}
-void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
+void TextServerAdvanced::_font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2810,7 +2802,7 @@ void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const
gl[p_glyph].found = true;
}
-RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+RID TextServerAdvanced::_font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, RID());
@@ -2837,10 +2829,8 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
if (RenderingServer::get_singleton() != nullptr) {
if (gl[p_glyph | mod].texture_idx != -1) {
if (fd->cache[size]->textures[gl[p_glyph | mod].texture_idx].dirty) {
- FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph | mod].texture_idx];
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[gl[p_glyph | mod].texture_idx];
+ Ref<Image> img = Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
if (fd->mipmaps) {
img->generate_mipmaps();
}
@@ -2858,7 +2848,7 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
return RID();
}
-Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Size2 TextServerAdvanced::_font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Size2());
@@ -2885,10 +2875,8 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
if (RenderingServer::get_singleton() != nullptr) {
if (gl[p_glyph | mod].texture_idx != -1) {
if (fd->cache[size]->textures[gl[p_glyph | mod].texture_idx].dirty) {
- FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph | mod].texture_idx];
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[gl[p_glyph | mod].texture_idx];
+ Ref<Image> img = Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
if (fd->mipmaps) {
img->generate_mipmaps();
}
@@ -2906,7 +2894,7 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
return Size2();
}
-Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
+Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2956,7 +2944,7 @@ Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, in
#endif
}
-TypedArray<Vector2i> TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
+TypedArray<Vector2i> TextServerAdvanced::_font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -2972,7 +2960,7 @@ TypedArray<Vector2i> TextServerAdvanced::font_get_kerning_list(const RID &p_font
return ret;
}
-void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
+void TextServerAdvanced::_font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2983,7 +2971,7 @@ void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p
fd->cache[size]->kerning_map.clear();
}
-void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
+void TextServerAdvanced::_font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2994,7 +2982,7 @@ void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_si
fd->cache[size]->kerning_map.erase(p_glyph_pair);
}
-void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
+void TextServerAdvanced::_font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3005,7 +2993,7 @@ void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->kerning_map[p_glyph_pair] = p_kerning;
}
-Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
+Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -3038,7 +3026,7 @@ Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_si
return Vector2();
}
-int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
+int64_t TextServerAdvanced::_font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
@@ -3063,7 +3051,7 @@ int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t
#endif
}
-bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) const {
+bool TextServerAdvanced::_font_has_char(const RID &p_font_rid, int64_t p_char) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
if (!fd) {
@@ -3084,7 +3072,7 @@ bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) co
return (at_size) ? at_size->glyph_map.has((int32_t)p_char) : false;
}
-String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_supported_chars(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -3117,7 +3105,7 @@ String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const
return chars;
}
-void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
+void TextServerAdvanced::_font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + ".");
@@ -3152,7 +3140,7 @@ void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i
}
}
-void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
+void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3183,7 +3171,7 @@ void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i
#endif
}
-void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
+void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3232,10 +3220,8 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
#endif
if (RenderingServer::get_singleton() != nullptr) {
if (fd->cache[size]->textures[gl.texture_idx].dirty) {
- FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx];
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[gl.texture_idx];
+ Ref<Image> img = Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
if (fd->mipmaps) {
img->generate_mipmaps();
}
@@ -3253,13 +3239,15 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
Size2 csize = gl.rect.size * (double)p_size / (double)fd->msdf_source_size;
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range);
} else {
+ double scale = _font_get_scale(p_font_rid, p_size);
Point2 cpos = p_pos;
- cpos.y = Math::floor(cpos.y);
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- cpos.x = ((int)Math::floor(cpos.x + 0.125));
+ cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- cpos.x = ((int)Math::floor(cpos.x + 0.25));
- } else {
+ cpos.x = cpos.x + 0.25;
+ }
+ if (scale == 1.0) {
+ cpos.y = Math::floor(cpos.y);
cpos.x = Math::floor(cpos.x);
}
cpos += gl.rect.position;
@@ -3275,7 +3263,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
}
-void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
+void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3324,10 +3312,8 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
#endif
if (RenderingServer::get_singleton() != nullptr) {
if (fd->cache[size]->textures[gl.texture_idx].dirty) {
- FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx];
- Ref<Image> img;
- img.instantiate();
- img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
+ ShelfPackTexture &tex = fd->cache[size]->textures.write[gl.texture_idx];
+ Ref<Image> img = Image::create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata);
if (fd->mipmaps) {
img->generate_mipmaps();
}
@@ -3346,12 +3332,14 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range);
} else {
Point2 cpos = p_pos;
- cpos.y = Math::floor(cpos.y);
+ double scale = _font_get_scale(p_font_rid, p_size);
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- cpos.x = ((int)Math::floor(cpos.x + 0.125));
+ cpos.x = cpos.x + 0.125;
} else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- cpos.x = ((int)Math::floor(cpos.x + 0.25));
- } else {
+ cpos.x = cpos.x + 0.25;
+ }
+ if (scale == 1.0) {
+ cpos.y = Math::floor(cpos.y);
cpos.x = Math::floor(cpos.x);
}
cpos += gl.rect.position;
@@ -3367,7 +3355,7 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
}
-bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
+bool TextServerAdvanced::_font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3379,7 +3367,7 @@ bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const
}
}
-void TextServerAdvanced::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
+void TextServerAdvanced::_font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3387,7 +3375,7 @@ void TextServerAdvanced::font_set_language_support_override(const RID &p_font_ri
fd->language_support_overrides[p_language] = p_supported;
}
-bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
+bool TextServerAdvanced::_font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3395,7 +3383,7 @@ bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_ri
return fd->language_support_overrides[p_language];
}
-void TextServerAdvanced::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
+void TextServerAdvanced::_font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3403,7 +3391,7 @@ void TextServerAdvanced::font_remove_language_support_override(const RID &p_font
fd->language_support_overrides.erase(p_language);
}
-PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerAdvanced::_font_get_language_support_overrides(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -3415,7 +3403,7 @@ PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const
return out;
}
-bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
+bool TextServerAdvanced::_font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3429,7 +3417,7 @@ bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const S
}
}
-void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
+void TextServerAdvanced::_font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3437,7 +3425,7 @@ void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid,
fd->script_support_overrides[p_script] = p_supported;
}
-bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
+bool TextServerAdvanced::_font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3445,7 +3433,7 @@ bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid,
return fd->script_support_overrides[p_script];
}
-void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
+void TextServerAdvanced::_font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3453,7 +3441,7 @@ void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_r
fd->script_support_overrides.erase(p_script);
}
-PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerAdvanced::_font_get_script_support_overrides(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -3465,7 +3453,7 @@ PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RI
return out;
}
-void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
+void TextServerAdvanced::_font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3475,7 +3463,7 @@ void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_r
fd->feature_overrides = p_overrides;
}
-Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_get_opentype_feature_overrides(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3483,7 +3471,7 @@ Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_
return fd->feature_overrides;
}
-Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_supported_feature_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3493,7 +3481,7 @@ Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid
return fd->supported_features;
}
-Dictionary TextServerAdvanced::font_supported_variation_list(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_supported_variation_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3503,11 +3491,11 @@ Dictionary TextServerAdvanced::font_supported_variation_list(const RID &p_font_r
return fd->supported_varaitions;
}
-double TextServerAdvanced::font_get_global_oversampling() const {
+double TextServerAdvanced::_font_get_global_oversampling() const {
return oversampling;
}
-void TextServerAdvanced::font_set_global_oversampling(double p_oversampling) {
+void TextServerAdvanced::_font_set_global_oversampling(double p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
@@ -3515,8 +3503,8 @@ void TextServerAdvanced::font_set_global_oversampling(double p_oversampling) {
font_owner.get_owned_list(&fonts);
bool font_cleared = false;
for (const RID &E : fonts) {
- if (!font_is_multichannel_signed_distance_field(E) && font_get_oversampling(E) <= 0) {
- font_clear_size_cache(E);
+ if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
+ _font_clear_size_cache(E);
font_cleared = true;
}
}
@@ -3625,7 +3613,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
p_shaped->parent = RID();
}
-RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+RID TextServerAdvanced::_create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = memnew(ShapedTextDataAdvanced);
@@ -3635,7 +3623,7 @@ RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, Te
return shaped_owner.make_rid(sd);
}
-void TextServerAdvanced::shaped_text_clear(const RID &p_shaped) {
+void TextServerAdvanced::_shaped_text_clear(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3650,7 +3638,7 @@ void TextServerAdvanced::shaped_text_clear(const RID &p_shaped) {
invalidate(sd, true);
}
-void TextServerAdvanced::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
+void TextServerAdvanced::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3664,7 +3652,7 @@ void TextServerAdvanced::shaped_text_set_direction(const RID &p_shaped, TextServ
}
}
-TextServer::Direction TextServerAdvanced::shaped_text_get_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerAdvanced::_shaped_text_get_direction(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR);
@@ -3672,7 +3660,7 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_direction(const RID &p
return sd->direction;
}
-TextServer::Direction TextServerAdvanced::shaped_text_get_inferred_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerAdvanced::_shaped_text_get_inferred_direction(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR);
@@ -3680,7 +3668,7 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_inferred_direction(con
return sd->para_direction;
}
-void TextServerAdvanced::shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
+void TextServerAdvanced::_shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3694,14 +3682,14 @@ void TextServerAdvanced::shaped_text_set_custom_punctuation(const RID &p_shaped,
}
}
-String TextServerAdvanced::shaped_text_get_custom_punctuation(const RID &p_shaped) const {
+String TextServerAdvanced::_shaped_text_get_custom_punctuation(const RID &p_shaped) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, String());
return sd->custom_punct;
}
-void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
+void TextServerAdvanced::_shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3718,7 +3706,7 @@ void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, cons
invalidate(sd, false);
}
-void TextServerAdvanced::shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
+void TextServerAdvanced::_shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3732,7 +3720,7 @@ void TextServerAdvanced::shaped_text_set_orientation(const RID &p_shaped, TextSe
}
}
-void TextServerAdvanced::shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
+void TextServerAdvanced::_shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3744,7 +3732,7 @@ void TextServerAdvanced::shaped_text_set_preserve_invalid(const RID &p_shaped, b
}
}
-bool TextServerAdvanced::shaped_text_get_preserve_invalid(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_get_preserve_invalid(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3752,7 +3740,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_invalid(const RID &p_shaped) c
return sd->preserve_invalid;
}
-void TextServerAdvanced::shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
+void TextServerAdvanced::_shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3766,7 +3754,7 @@ void TextServerAdvanced::shaped_text_set_preserve_control(const RID &p_shaped, b
}
}
-bool TextServerAdvanced::shaped_text_get_preserve_control(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_get_preserve_control(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3774,7 +3762,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_control(const RID &p_shaped) c
return sd->preserve_control;
}
-void TextServerAdvanced::shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
+void TextServerAdvanced::_shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
ERR_FAIL_INDEX((int)p_spacing, 4);
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3789,7 +3777,7 @@ void TextServerAdvanced::shaped_text_set_spacing(const RID &p_shaped, SpacingTyp
}
}
-int64_t TextServerAdvanced::shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
+int64_t TextServerAdvanced::_shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
ERR_FAIL_INDEX_V((int)p_spacing, 4, 0);
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
@@ -3799,7 +3787,7 @@ int64_t TextServerAdvanced::shaped_text_get_spacing(const RID &p_shaped, Spacing
return sd->extra_spacing[p_spacing];
}
-TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(const RID &p_shaped) const {
+TextServer::Orientation TextServerAdvanced::_shaped_text_get_orientation(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL);
@@ -3807,20 +3795,20 @@ TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(const RI
return sd->orientation;
}
-int64_t TextServerAdvanced::shaped_get_span_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_get_span_count(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
return sd->spans.size();
}
-Variant TextServerAdvanced::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
+Variant TextServerAdvanced::_shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Variant());
ERR_FAIL_INDEX_V(p_index, sd->spans.size(), Variant());
return sd->spans[p_index].meta;
}
-void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
+void TextServerAdvanced::_shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
ERR_FAIL_INDEX(p_index, sd->spans.size());
@@ -3833,7 +3821,7 @@ void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_
invalidate(sd, false);
}
-bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
+bool TextServerAdvanced::_shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
ERR_FAIL_COND_V(p_size <= 0, false);
@@ -3868,7 +3856,7 @@ bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const Strin
return true;
}
-bool TextServerAdvanced::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
+bool TextServerAdvanced::_shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3898,7 +3886,7 @@ bool TextServerAdvanced::shaped_text_add_object(const RID &p_shaped, const Varia
return true;
}
-bool TextServerAdvanced::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
+bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3939,14 +3927,14 @@ bool TextServerAdvanced::shaped_text_resize_object(const RID &p_shaped, const Va
} else {
if (gl.font_rid.is_valid()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- sd->ascent = MAX(sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
- sd->descent = MAX(sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
+ sd->ascent = MAX(sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
+ sd->descent = MAX(sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
} else {
- sd->ascent = MAX(sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
- sd->upos = MAX(sd->upos, font_get_underline_position(gl.font_rid, gl.font_size));
- sd->uthk = MAX(sd->uthk, font_get_underline_thickness(gl.font_rid, gl.font_size));
+ sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size));
+ sd->uthk = MAX(sd->uthk, _font_get_underline_thickness(gl.font_rid, gl.font_size));
} else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@@ -4033,7 +4021,7 @@ void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
p_sd->descent = full_descent;
}
-RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
+RID TextServerAdvanced::_shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
@@ -4041,10 +4029,10 @@ RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start,
MutexLock lock(sd->mutex);
if (sd->parent != RID()) {
- return shaped_text_substr(sd->parent, p_start, p_length);
+ return _shaped_text_substr(sd->parent, p_start, p_length);
}
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
ERR_FAIL_COND_V(p_start < 0 || p_length < 0, RID());
ERR_FAIL_COND_V(sd->start > p_start || sd->end < p_start, RID());
@@ -4148,11 +4136,11 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
} else {
if (gl.font_rid.is_valid()) {
if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) {
- p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
- p_new_sd->descent = MAX(p_new_sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
+ p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
+ p_new_sd->descent = MAX(p_new_sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
} else {
- p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- p_new_sd->descent = MAX(p_new_sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ p_new_sd->descent = MAX(p_new_sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
} else if (p_new_sd->preserve_invalid || (p_new_sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
@@ -4178,7 +4166,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
return true;
}
-RID TextServerAdvanced::shaped_text_get_parent(const RID &p_shaped) const {
+RID TextServerAdvanced::_shaped_text_get_parent(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, RID());
@@ -4186,16 +4174,16 @@ RID TextServerAdvanced::shaped_text_get_parent(const RID &p_shaped) const {
return sd->parent;
}
-double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
+double TextServerAdvanced::_shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->justification_ops_valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_update_justification_ops(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_update_justification_ops(p_shaped);
}
sd->fit_width_minimum_reached = false;
@@ -4343,16 +4331,16 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
return Math::ceil(justification_width);
}
-double TextServerAdvanced::shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
+double TextServerAdvanced::_shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_update_breaks(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_update_breaks(p_shaped);
}
for (int i = 0; i < p_tab_stops.size(); i++) {
@@ -4399,13 +4387,13 @@ double TextServerAdvanced::shaped_text_tab_align(const RID &p_shaped, const Pack
return 0.0;
}
-void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
+void TextServerAdvanced::_shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped_line);
+ _shaped_text_shape(p_shaped_line);
}
sd->text_trimmed = false;
@@ -4444,30 +4432,30 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
// Find usable fonts, if fonts from the last glyph do not have required chars.
RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(dot_gl_font_rid, '.')) {
+ if (!_font_has_char(dot_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], '.')) {
+ if (_font_has_char(fonts[i], '.')) {
dot_gl_font_rid = fonts[i];
break;
}
}
}
RID whitespace_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(whitespace_gl_font_rid, '.')) {
+ if (!_font_has_char(whitespace_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], ' ')) {
+ if (_font_has_char(fonts[i], ' ')) {
whitespace_gl_font_rid = fonts[i];
break;
}
}
}
- int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.') : -10;
- Vector2 dot_adv = dot_gl_font_rid.is_valid() ? font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
- int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ') : -10;
- Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
+ int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.', 0) : -10;
+ Vector2 dot_adv = dot_gl_font_rid.is_valid() ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
+ int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ', 0) : -10;
+ Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) {
@@ -4566,7 +4554,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
}
}
-int64_t TextServerAdvanced::shaped_text_get_trim_pos(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_trim_pos(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
@@ -4574,7 +4562,7 @@ int64_t TextServerAdvanced::shaped_text_get_trim_pos(const RID &p_shaped) const
return sd->overrun_trim_data.trim_pos;
}
-int64_t TextServerAdvanced::shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
@@ -4582,7 +4570,7 @@ int64_t TextServerAdvanced::shaped_text_get_ellipsis_pos(const RID &p_shaped) co
return sd->overrun_trim_data.ellipsis_pos;
}
-const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerAdvanced::_shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataAdvanced invalid.");
@@ -4590,7 +4578,7 @@ const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
-int64_t TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataAdvanced invalid.");
@@ -4598,13 +4586,13 @@ int64_t TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
-bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (sd->line_breaks_valid) {
@@ -4615,6 +4603,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
if (!sd->break_ops_valid) {
sd->breaks.clear();
+ sd->break_inserts = 0;
UErrorCode err = U_ZERO_ERROR;
int i = 0;
while (i < sd->spans.size()) {
@@ -4643,6 +4632,12 @@ bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
sd->breaks[pos] = true;
} else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) {
sd->breaks[pos] = false;
+
+ int pos_p = pos - 1 - sd->start;
+ char32_t c = sd->text[pos_p];
+ if (pos - sd->start != sd->end && !is_whitespace(c) && (c != 0xfffc)) {
+ sd->break_inserts++;
+ }
}
}
}
@@ -4652,60 +4647,83 @@ bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
sd->break_ops_valid = true;
}
+ Vector<Glyph> glyphs_new;
+
+ bool rewrite = false;
+ int sd_shift = 0;
+ int sd_size = sd->glyphs.size();
+ Glyph *sd_glyphs = sd->glyphs.ptrw();
+ Glyph *sd_glyphs_new = nullptr;
+
+ if (sd->break_inserts > 0) {
+ glyphs_new.resize(sd->glyphs.size() + sd->break_inserts);
+ sd_glyphs_new = glyphs_new.ptrw();
+ rewrite = true;
+ } else {
+ sd_glyphs_new = sd_glyphs;
+ }
+
sd->sort_valid = false;
sd->glyphs_logical.clear();
- int sd_size = sd->glyphs.size();
const char32_t *ch = sd->text.ptr();
- Glyph *sd_glyphs = sd->glyphs.ptrw();
int c_punct_size = sd->custom_punct.length();
const char32_t *c_punct = sd->custom_punct.ptr();
for (int i = 0; i < sd_size; i++) {
+ if (rewrite) {
+ for (int j = 0; j < sd_glyphs[i].count; j++) {
+ sd_glyphs_new[sd_shift + i + j] = sd_glyphs[i + j];
+ }
+ }
if (sd_glyphs[i].count > 0) {
char32_t c = ch[sd_glyphs[i].start - sd->start];
if (c == 0xfffc) {
+ i += (sd_glyphs[i].count - 1);
continue;
}
if (c == 0x0009 || c == 0x000b) {
- sd_glyphs[i].flags |= GRAPHEME_IS_TAB;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_TAB;
}
if (is_whitespace(c)) {
- sd_glyphs[i].flags |= GRAPHEME_IS_SPACE;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_SPACE;
}
if (c_punct_size == 0) {
if (u_ispunct(c) && c != 0x005f) {
- sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_PUNCTUATION;
}
} else {
for (int j = 0; j < c_punct_size; j++) {
if (c_punct[j] == c) {
- sd_glyphs[i].flags |= GRAPHEME_IS_PUNCTUATION;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_PUNCTUATION;
break;
}
}
}
if (is_underscore(c)) {
- sd_glyphs[i].flags |= GRAPHEME_IS_UNDERSCORE;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_UNDERSCORE;
}
if (sd->breaks.has(sd_glyphs[i].end)) {
if (sd->breaks[sd_glyphs[i].end] && (is_linebreak(c))) {
- sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_BREAK_HARD;
} else if (is_whitespace(c)) {
- sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT;
+ sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_BREAK_SOFT;
} else {
int count = sd_glyphs[i].count;
// Do not add extra space at the end of the line.
if (sd_glyphs[i].end == sd->end) {
+ i += (sd_glyphs[i].count - 1);
continue;
}
// Do not add extra space after existing space.
if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) {
if ((i + count < sd_size - 1) && ((sd_glyphs[i + count].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) {
+ i += (sd_glyphs[i].count - 1);
continue;
}
} else {
- if ((i > 0) && ((sd_glyphs[i - 1].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT))) {
+ if ((sd_glyphs[i].flags & (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) == (GRAPHEME_IS_SPACE | GRAPHEME_IS_BREAK_SOFT)) {
+ i += (sd_glyphs[i].count - 1);
continue;
}
}
@@ -4718,22 +4736,25 @@ bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
gl.flags = GRAPHEME_IS_BREAK_SOFT | GRAPHEME_IS_VIRTUAL | GRAPHEME_IS_SPACE;
if (sd_glyphs[i].flags & GRAPHEME_IS_RTL) {
gl.flags |= GRAPHEME_IS_RTL;
- sd->glyphs.insert(i, gl); // Insert before.
+ for (int j = sd_glyphs[i].count - 1; j >= 0; j--) {
+ sd_glyphs_new[sd_shift + i + j + 1] = sd_glyphs_new[sd_shift + i + j];
+ }
+ sd_glyphs_new[sd_shift + i] = gl;
} else {
- sd->glyphs.insert(i + count, gl); // Insert after.
+ sd_glyphs_new[sd_shift + i + count] = gl;
}
- i += count;
-
- // Update write pointer and size.
- sd_size = sd->glyphs.size();
- sd_glyphs = sd->glyphs.ptrw();
- continue;
+ sd_shift++;
+ ERR_FAIL_COND_V_MSG(sd_shift > sd->break_inserts, false, "Invalid break insert count!");
}
}
-
i += (sd_glyphs[i].count - 1);
}
}
+ ERR_FAIL_COND_V_MSG(sd_shift != sd->break_inserts, false, "Invalid break insert count!");
+
+ if (sd->break_inserts > 0) {
+ sd->glyphs = glyphs_new;
+ }
sd->line_breaks_valid = true;
@@ -4815,16 +4836,16 @@ _FORCE_INLINE_ int64_t _generate_kashida_justification_opportunies(const String
return kashida_pos;
}
-bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_update_justification_ops(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- shaped_text_update_breaks(p_shaped);
+ _shaped_text_update_breaks(p_shaped);
}
if (sd->justification_ops_valid) {
@@ -4969,7 +4990,8 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape
Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, const RID &p_font, int64_t p_font_size) {
hb_font_t *hb_font = _font_get_hb_handle(p_font, p_font_size);
- bool subpos = (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+ double scale = _font_get_scale(p_font, p_font_size);
+ bool subpos = (scale != 1.0) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
ERR_FAIL_COND_V(hb_font == nullptr, Glyph());
hb_buffer_clear_contents(p_sd->hb_buffer);
@@ -4995,25 +5017,24 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char
gl.font_size = p_font_size;
if (glyph_count > 0) {
- double scale = font_get_scale(p_font, p_font_size);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (subpos) {
- gl.advance = glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size);
+ gl.advance = (double)glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size);
} else {
- gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size));
+ gl.advance = Math::round((double)glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size));
}
} else {
- gl.advance = -Math::round(glyph_pos[0].y_advance / (64.0 / scale));
+ gl.advance = -Math::round((double)glyph_pos[0].y_advance / (64.0 / scale));
}
gl.count = 1;
gl.index = glyph_info[0].codepoint;
if (subpos) {
- gl.x_off = glyph_pos[0].x_offset / (64.0 / scale);
+ gl.x_off = (double)glyph_pos[0].x_offset / (64.0 / scale);
} else {
- gl.x_off = Math::round(glyph_pos[0].x_offset / (64.0 / scale));
+ gl.x_off = Math::round((double)glyph_pos[0].x_offset / (64.0 / scale));
}
- gl.y_off = -Math::round(glyph_pos[0].y_offset / (64.0 / scale));
+ gl.y_off = -Math::round((double)glyph_pos[0].y_offset / (64.0 / scale));
if ((glyph_info[0].codepoint != 0) || !u_isgraph(p_char)) {
gl.flags |= GRAPHEME_IS_VALID;
@@ -5030,7 +5051,7 @@ _FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source
if (value >= 0) {
hb_feature_t feature;
if (keys[i].get_type() == Variant::STRING) {
- feature.tag = name_to_tag(keys[i]);
+ feature.tag = _name_to_tag(keys[i]);
} else {
feature.tag = keys[i];
}
@@ -5063,6 +5084,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
p_sd->ascent = MAX(p_sd->ascent, get_hex_code_box_size(fs, gl.index).y);
} else {
gl.advance = get_hex_code_box_size(fs, gl.index).y;
+ gl.y_off = get_hex_code_box_size(fs, gl.index).y;
+ gl.x_off = -Math::round(get_hex_code_box_size(fs, gl.index).x * 0.5);
p_sd->ascent = MAX(p_sd->ascent, Math::round(get_hex_code_box_size(fs, gl.index).x * 0.5));
p_sd->descent = MAX(p_sd->descent, Math::round(get_hex_code_box_size(fs, gl.index).x * 0.5));
}
@@ -5081,12 +5104,12 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
Vector2i fss = _get_size(fd, fs);
hb_font_t *hb_font = _font_get_hb_handle(f, fs);
- double scale = font_get_scale(f, fs);
+ double scale = _font_get_scale(f, fs);
double sp_sp = p_sd->extra_spacing[SPACING_SPACE];
double sp_gl = p_sd->extra_spacing[SPACING_GLYPH];
bool last_run = (p_sd->end == p_end);
double ea = _get_extra_advance(f, fs);
- bool subpos = (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+ bool subpos = (scale != 1.0) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
ERR_FAIL_COND(hb_font == nullptr);
hb_buffer_clear_contents(p_sd->hb_buffer);
@@ -5114,7 +5137,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
hb_buffer_add_utf32(p_sd->hb_buffer, (const uint32_t *)p_sd->text.ptr(), p_sd->text.length(), p_start, p_end - p_start);
Vector<hb_feature_t> ftrs;
- _add_featuers(font_get_opentype_feature_overrides(f), ftrs);
+ _add_featuers(_font_get_opentype_feature_overrides(f), ftrs);
_add_featuers(p_sd->spans[p_span].features, ftrs);
hb_shape(hb_font, p_sd->hb_buffer, ftrs.is_empty() ? nullptr : &ftrs[0], ftrs.size());
@@ -5187,19 +5210,19 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
_ensure_glyph(fd, fss, gl.index | mod);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (subpos) {
- gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea;
+ gl.advance = (double)glyph_pos[i].x_advance / (64.0 / scale) + ea;
} else {
- gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale) + ea);
+ gl.advance = Math::round((double)glyph_pos[i].x_advance / (64.0 / scale) + ea);
}
} else {
- gl.advance = -Math::round(glyph_pos[i].y_advance / (64.0 / scale));
+ gl.advance = -Math::round((double)glyph_pos[i].y_advance / (64.0 / scale));
}
if (subpos) {
- gl.x_off = glyph_pos[i].x_offset / (64.0 / scale);
+ gl.x_off = (double)glyph_pos[i].x_offset / (64.0 / scale);
} else {
- gl.x_off = Math::round(glyph_pos[i].x_offset / (64.0 / scale));
+ gl.x_off = Math::round((double)glyph_pos[i].x_offset / (64.0 / scale));
}
- gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / scale));
+ gl.y_off = -Math::round((double)glyph_pos[i].y_offset / (64.0 / scale));
}
if (!last_run || i < glyph_count - 1) {
// Do not add extra spacing to the last glyph of the string.
@@ -5245,7 +5268,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
p_sd->ascent = MAX(p_sd->ascent, -w[i + j].y_off);
p_sd->descent = MAX(p_sd->descent, w[i + j].y_off);
} else {
- double gla = Math::round(font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5);
+ double gla = Math::round(_font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5);
p_sd->ascent = MAX(p_sd->ascent, gla);
p_sd->descent = MAX(p_sd->descent, gla);
}
@@ -5268,14 +5291,14 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
if (failed_subrun_start != p_end + 1) {
_shape_run(p_sd, failed_subrun_start, failed_subrun_end, p_script, p_direction, p_fonts, p_span, p_fb_index + 1);
}
- p_sd->ascent = MAX(p_sd->ascent, font_get_ascent(f, fs));
- p_sd->descent = MAX(p_sd->descent, font_get_descent(f, fs));
- p_sd->upos = MAX(p_sd->upos, font_get_underline_position(f, fs));
- p_sd->uthk = MAX(p_sd->uthk, font_get_underline_thickness(f, fs));
+ p_sd->ascent = MAX(p_sd->ascent, _font_get_ascent(f, fs));
+ p_sd->descent = MAX(p_sd->descent, _font_get_descent(f, fs));
+ p_sd->upos = MAX(p_sd->upos, _font_get_underline_position(f, fs));
+ p_sd->uthk = MAX(p_sd->uthk, _font_get_underline_thickness(f, fs));
}
}
-bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -5286,7 +5309,7 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
invalidate(sd, false);
if (sd->parent != RID()) {
- shaped_text_shape(sd->parent);
+ _shaped_text_shape(sd->parent);
ShapedTextDataAdvanced *parent_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_COND_V(!parent_sd->valid, false);
ERR_FAIL_COND_V(!_shape_substr(sd, parent_sd, sd->start, sd->end - sd->start), false);
@@ -5386,7 +5409,7 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
int32_t script_run_end = MIN(sd->script_iter->script_ranges[j].end, bidi_run_end);
char scr_buffer[5] = { 0, 0, 0, 0, 0 };
hb_tag_to_string(hb_script_to_iso15924_tag(sd->script_iter->script_ranges[j].script), scr_buffer);
- String script = String(scr_buffer);
+ String script_code = String(scr_buffer);
int spn_from = (is_rtl) ? 0 : sd->spans.size() - 1;
int spn_to = (is_rtl) ? sd->spans.size() : -1;
@@ -5426,8 +5449,8 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
fonts.push_back(sd->spans[k].fonts[0]);
}
for (int l = 1; l < font_count; l++) {
- if (font_is_script_supported(span.fonts[l], script)) {
- if (font_is_language_supported(span.fonts[l], span.language)) {
+ if (_font_is_script_supported(span.fonts[l], script_code)) {
+ if (_font_is_language_supported(span.fonts[l], span.language)) {
fonts.push_back(sd->spans[k].fonts[l]);
} else {
fonts_scr_only.push_back(sd->spans[k].fonts[l]);
@@ -5451,7 +5474,7 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
return sd->valid;
}
-bool TextServerAdvanced::shaped_text_is_ready(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_is_ready(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -5459,35 +5482,35 @@ bool TextServerAdvanced::shaped_text_is_ready(const RID &p_shaped) const {
return sd->valid;
}
-const Glyph *TextServerAdvanced::shaped_text_get_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerAdvanced::_shaped_text_get_glyphs(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.ptr();
}
-int64_t TextServerAdvanced::shaped_text_get_glyph_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_glyph_count(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.size();
}
-const Glyph *TextServerAdvanced::shaped_text_sort_logical(const RID &p_shaped) {
+const Glyph *TextServerAdvanced::_shaped_text_sort_logical(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->sort_valid) {
@@ -5499,7 +5522,7 @@ const Glyph *TextServerAdvanced::shaped_text_sort_logical(const RID &p_shaped) {
return sd->glyphs_logical.ptr();
}
-Vector2i TextServerAdvanced::shaped_text_get_range(const RID &p_shaped) const {
+Vector2i TextServerAdvanced::_shaped_text_get_range(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
@@ -5507,7 +5530,7 @@ Vector2i TextServerAdvanced::shaped_text_get_range(const RID &p_shaped) const {
return Vector2(sd->start, sd->end);
}
-Array TextServerAdvanced::shaped_text_get_objects(const RID &p_shaped) const {
+Array TextServerAdvanced::_shaped_text_get_objects(const RID &p_shaped) const {
Array ret;
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, ret);
@@ -5520,25 +5543,25 @@ Array TextServerAdvanced::shaped_text_get_objects(const RID &p_shaped) const {
return ret;
}
-Rect2 TextServerAdvanced::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
+Rect2 TextServerAdvanced::_shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Rect2());
MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), Rect2());
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->objects[p_key].rect;
}
-Size2 TextServerAdvanced::shaped_text_get_size(const RID &p_shaped) const {
+Size2 TextServerAdvanced::_shaped_text_get_size(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Size2());
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->orientation == TextServer::ORIENTATION_HORIZONTAL) {
return Size2((sd->text_trimmed ? sd->width_trimmed : sd->width), sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM]).ceil();
@@ -5547,58 +5570,58 @@ Size2 TextServerAdvanced::shaped_text_get_size(const RID &p_shaped) const {
}
}
-double TextServerAdvanced::shaped_text_get_ascent(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_ascent(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->ascent + sd->extra_spacing[SPACING_TOP];
}
-double TextServerAdvanced::shaped_text_get_descent(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_descent(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->descent + sd->extra_spacing[SPACING_BOTTOM];
}
-double TextServerAdvanced::shaped_text_get_width(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_width(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return Math::ceil(sd->text_trimmed ? sd->width_trimmed : sd->width);
}
-double TextServerAdvanced::shaped_text_get_underline_position(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_underline_position(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->upos;
}
-double TextServerAdvanced::shaped_text_get_underline_thickness(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_underline_thickness(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->uthk;
@@ -5779,7 +5802,7 @@ void TextServerAdvanced::_insert_num_systems_lang() {
}
}
-String TextServerAdvanced::format_number(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_format_number(const String &p_string, const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
@@ -5804,7 +5827,7 @@ String TextServerAdvanced::format_number(const String &p_string, const String &p
return res;
}
-String TextServerAdvanced::parse_number(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_parse_number(const String &p_string, const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
@@ -5832,7 +5855,7 @@ String TextServerAdvanced::parse_number(const String &p_string, const String &p_
return res;
}
-String TextServerAdvanced::percent_sign(const String &p_language) const {
+String TextServerAdvanced::_percent_sign(const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
for (int i = 0; i < num_systems.size(); i++) {
@@ -5846,7 +5869,7 @@ String TextServerAdvanced::percent_sign(const String &p_language) const {
return "%";
}
-int64_t TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const {
+int64_t TextServerAdvanced::_is_confusable(const String &p_string, const PackedStringArray &p_dict) const {
UErrorCode status = U_ZERO_ERROR;
int64_t match_index = -1;
@@ -5886,7 +5909,7 @@ int64_t TextServerAdvanced::is_confusable(const String &p_string, const PackedSt
return match_index;
}
-bool TextServerAdvanced::spoof_check(const String &p_string) const {
+bool TextServerAdvanced::_spoof_check(const String &p_string) const {
UErrorCode status = U_ZERO_ERROR;
Char16String utf16 = p_string.utf16();
@@ -5908,7 +5931,7 @@ bool TextServerAdvanced::spoof_check(const String &p_string) const {
return (bitmask != 0);
}
-String TextServerAdvanced::strip_diacritics(const String &p_string) const {
+String TextServerAdvanced::_strip_diacritics(const String &p_string) const {
UErrorCode err = U_ZERO_ERROR;
// Get NFKD normalizer singleton.
@@ -5941,7 +5964,7 @@ String TextServerAdvanced::strip_diacritics(const String &p_string) const {
return result;
}
-String TextServerAdvanced::string_to_upper(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_string_to_upper(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
@@ -5960,7 +5983,7 @@ String TextServerAdvanced::string_to_upper(const String &p_string, const String
return String::utf16(upper.ptr(), len);
}
-String TextServerAdvanced::string_to_lower(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_string_to_lower(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
@@ -5978,7 +6001,7 @@ String TextServerAdvanced::string_to_lower(const String &p_string, const String
return String::utf16(lower.ptr(), len);
}
-PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_string, const String &p_language) const {
+PackedInt32Array TextServerAdvanced::_string_get_word_breaks(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
@@ -6026,7 +6049,7 @@ PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_stri
return ret;
}
-bool TextServerAdvanced::is_valid_identifier(const String &p_string) const {
+bool TextServerAdvanced::_is_valid_identifier(const String &p_string) const {
enum UAX31SequenceStatus {
SEQ_NOT_STARTED,
SEQ_STARTED,
@@ -6047,7 +6070,7 @@ bool TextServerAdvanced::is_valid_identifier(const String &p_string) const {
if (U_FAILURE(err)) {
return false; // Failed to load normalizer.
}
- bool isnurom = unorm2_isNormalized(norm_c, utf16.ptr(), utf16.length(), &err);
+ bool isnurom = unorm2_isNormalized(norm_c, utf16.get_data(), utf16.length(), &err);
if (U_FAILURE(err) || !isnurom) {
return false; // Do not conform to Normalization Form C.
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index b9633a9b71..10fe3c2316 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -42,6 +42,7 @@
#include <godot_cpp/godot.hpp>
#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/ext_wrappers.gen.inc>
#include <godot_cpp/core/mutex_lock.hpp>
#include <godot_cpp/variant/array.hpp>
@@ -79,13 +80,15 @@ using namespace godot;
#else
// Headers for building as built-in module.
+#include "servers/text/text_server_extension.h"
+
+#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/worker_thread_pool.h"
#include "core/templates/hash_map.h"
#include "core/templates/rid_owner.h"
#include "scene/resources/texture.h"
-#include "servers/text/text_server_extension.h"
-#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
+#include "modules/modules_enabled.gen.h" // For freetype, msdfgen, svg.
#endif
@@ -114,6 +117,7 @@ using namespace godot;
#include FT_ADVANCES_H
#include FT_MULTIPLE_MASTERS_H
#include FT_BBOX_H
+#include FT_MODULE_H
#include FT_CONFIG_OPTIONS_H
#if !defined(FT_CONFIG_OPTION_USE_BROTLI) && !defined(_MSC_VER)
#warning FreeType is configured without Brotli support, built-in fonts will not be available.
@@ -165,20 +169,86 @@ class TextServerAdvanced : public TextServerExtension {
const int rect_range = 1;
- struct FontTexture {
+ struct FontTexturePosition {
+ int32_t index = -1;
+ int32_t x = 0;
+ int32_t y = 0;
+
+ FontTexturePosition() {}
+ FontTexturePosition(int32_t p_id, int32_t p_x, int32_t p_y) :
+ index(p_id), x(p_x), y(p_y) {}
+ };
+
+ struct Shelf {
+ int32_t x = 0;
+ int32_t y = 0;
+ int32_t w = 0;
+ int32_t h = 0;
+
+ FontTexturePosition alloc_shelf(int32_t p_id, int32_t p_w, int32_t p_h) {
+ if (p_w > w || p_h > h) {
+ return FontTexturePosition(-1, 0, 0);
+ }
+ int32_t xx = x;
+ x += p_w;
+ w -= p_w;
+ return FontTexturePosition(p_id, xx, y);
+ }
+
+ Shelf() {}
+ Shelf(int32_t p_x, int32_t p_y, int32_t p_w, int32_t p_h) :
+ x(p_x), y(p_y), w(p_w), h(p_h) {}
+ };
+
+ struct ShelfPackTexture {
+ int32_t texture_w = 1024;
+ int32_t texture_h = 1024;
+
Image::Format format;
PackedByteArray imgdata;
- int texture_w = 0;
- int texture_h = 0;
- PackedInt32Array offsets;
Ref<ImageTexture> texture;
bool dirty = true;
- };
- struct FontTexturePosition {
- int index = 0;
- int x = 0;
- int y = 0;
+ List<Shelf> shelves;
+
+ FontTexturePosition pack_rect(int32_t p_id, int32_t p_h, int32_t p_w) {
+ int32_t y = 0;
+ int32_t waste = 0;
+ Shelf *best_shelf = nullptr;
+ int32_t best_waste = std::numeric_limits<std::int32_t>::max();
+
+ for (Shelf &E : shelves) {
+ y += E.h;
+ if (p_w > E.w) {
+ continue;
+ }
+ if (p_h == E.h) {
+ return E.alloc_shelf(p_id, p_w, p_h);
+ }
+ if (p_h > E.h) {
+ continue;
+ }
+ if (p_h < E.h) {
+ waste = (E.h - p_h) * p_w;
+ if (waste < best_waste) {
+ best_waste = waste;
+ best_shelf = &E;
+ }
+ }
+ }
+ if (best_shelf) {
+ return best_shelf->alloc_shelf(p_id, p_w, p_h);
+ }
+ if (p_h <= (texture_h - y) && p_w <= texture_w) {
+ List<Shelf>::Element *E = shelves.push_back(Shelf(0, y, texture_w, p_h));
+ return E->get().alloc_shelf(p_id, p_w, p_h);
+ }
+ return FontTexturePosition(-1, 0, 0);
+ }
+
+ ShelfPackTexture() {}
+ ShelfPackTexture(int32_t p_w, int32_t p_h) :
+ texture_w(p_w), texture_h(p_h) {}
};
struct FontGlyph {
@@ -199,7 +269,7 @@ class TextServerAdvanced : public TextServerExtension {
Vector2i size;
- Vector<FontTexture> textures;
+ Vector<ShelfPackTexture> textures;
HashMap<int32_t, FontGlyph> glyph_map;
HashMap<Vector2i, Vector2> kerning_map;
hb_font_t *hb_handle = nullptr;
@@ -381,6 +451,7 @@ class TextServerAdvanced : public TextServerExtension {
HashMap<int, bool> jstops;
HashMap<int, bool> breaks;
+ int break_inserts = 0;
bool break_ops_valid = false;
bool js_ops_valid = false;
@@ -462,258 +533,259 @@ protected:
void invalidate(ShapedTextDataAdvanced *p_shaped, bool p_text = false);
public:
- virtual bool has_feature(Feature p_feature) const override;
- virtual String get_name() const override;
- virtual int64_t get_features() const override;
+ MODBIND1RC(bool, has_feature, Feature);
+ MODBIND0RC(String, get_name);
+ MODBIND0RC(int64_t, get_features);
- virtual void free_rid(const RID &p_rid) override;
- virtual bool has(const RID &p_rid) override;
- virtual bool load_support_data(const String &p_filename) override;
+ MODBIND1(free_rid, const RID &);
+ MODBIND1R(bool, has, const RID &);
+ MODBIND1R(bool, load_support_data, const String &);
- virtual String get_support_data_filename() const override;
- virtual String get_support_data_info() const override;
- virtual bool save_support_data(const String &p_filename) const override;
+ MODBIND0RC(String, get_support_data_filename);
+ MODBIND0RC(String, get_support_data_info);
+ MODBIND1RC(bool, save_support_data, const String &);
- virtual bool is_locale_right_to_left(const String &p_locale) const override;
+ MODBIND1RC(bool, is_locale_right_to_left, const String &);
- virtual int64_t name_to_tag(const String &p_name) const override;
- virtual String tag_to_name(int64_t p_tag) const override;
+ MODBIND1RC(int64_t, name_to_tag, const String &);
+ MODBIND1RC(String, tag_to_name, int64_t);
/* Font interface */
- virtual RID create_font() override;
- virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override;
- virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override;
+ MODBIND0R(RID, create_font);
+
+ MODBIND2(font_set_data, const RID &, const PackedByteArray &);
+ MODBIND3(font_set_data_ptr, const RID &, const uint8_t *, int64_t);
- virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) override;
- virtual int64_t font_get_face_index(const RID &p_font_rid) const override;
+ MODBIND2(font_set_face_index, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_face_index, const RID &);
- virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
+ MODBIND1RC(int64_t, font_get_face_count, const RID &);
- virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
- virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
+ MODBIND2(font_set_style, const RID &, BitField<FontStyle>);
+ MODBIND1RC(BitField<FontStyle>, font_get_style, const 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;
+ MODBIND2(font_set_style_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_style_name, const RID &);
- 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;
+ MODBIND2(font_set_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_name, const RID &);
- virtual void font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) override;
- virtual TextServer::FontAntialiasing font_get_antialiasing(RID p_font_rid) const override;
+ MODBIND2(font_set_antialiasing, const RID &, TextServer::FontAntialiasing);
+ MODBIND1RC(TextServer::FontAntialiasing, font_get_antialiasing, const RID &);
- virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override;
- virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override;
+ MODBIND2(font_set_generate_mipmaps, const RID &, bool);
+ MODBIND1RC(bool, font_get_generate_mipmaps, const RID &);
- virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override;
- virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override;
+ MODBIND2(font_set_multichannel_signed_distance_field, const RID &, bool);
+ MODBIND1RC(bool, font_is_multichannel_signed_distance_field, const RID &);
- virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) override;
- virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const override;
+ MODBIND2(font_set_msdf_pixel_range, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_pixel_range, const RID &);
- virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) override;
- virtual int64_t font_get_msdf_size(const RID &p_font_rid) const override;
+ MODBIND2(font_set_msdf_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_size, const RID &);
- virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override;
- virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override;
+ MODBIND2(font_set_fixed_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_fixed_size, const RID &);
- virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override;
- virtual bool font_is_force_autohinter(const RID &p_font_rid) const override;
+ MODBIND2(font_set_force_autohinter, const RID &, bool);
+ MODBIND1RC(bool, font_is_force_autohinter, const RID &);
- virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override;
- virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override;
+ MODBIND2(font_set_subpixel_positioning, const RID &, SubpixelPositioning);
+ MODBIND1RC(SubpixelPositioning, font_get_subpixel_positioning, const RID &);
- virtual void font_set_embolden(const RID &p_font_rid, double p_strength) override;
- virtual double font_get_embolden(const RID &p_font_rid) const override;
+ MODBIND2(font_set_embolden, const RID &, double);
+ MODBIND1RC(double, font_get_embolden, const RID &);
- virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override;
- virtual Transform2D font_get_transform(const RID &p_font_rid) const override;
+ MODBIND2(font_set_transform, const RID &, const Transform2D &);
+ MODBIND1RC(Transform2D, font_get_transform, const RID &);
- virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) override;
- virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const override;
+ MODBIND2(font_set_variation_coordinates, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_variation_coordinates, const RID &);
- virtual void font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) override;
- virtual TextServer::Hinting font_get_hinting(const RID &p_font_rid) const override;
+ MODBIND2(font_set_hinting, const RID &, TextServer::Hinting);
+ MODBIND1RC(TextServer::Hinting, font_get_hinting, const RID &);
- virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override;
- virtual double font_get_oversampling(const RID &p_font_rid) const override;
+ MODBIND2(font_set_oversampling, const RID &, double);
+ MODBIND1RC(double, font_get_oversampling, const RID &);
- virtual TypedArray<Vector2i> font_get_size_cache_list(const RID &p_font_rid) const override;
- virtual void font_clear_size_cache(const RID &p_font_rid) override;
- virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override;
+ MODBIND1RC(TypedArray<Vector2i>, font_get_size_cache_list, const RID &);
+ MODBIND1(font_clear_size_cache, const RID &);
+ MODBIND2(font_remove_size_cache, const RID &, const Vector2i &);
- virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
- virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
+ MODBIND3(font_set_ascent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_ascent, const RID &, int64_t);
- virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override;
- virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override;
+ MODBIND3(font_set_descent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_descent, const RID &, int64_t);
- virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override;
- virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override;
+ MODBIND3(font_set_underline_position, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_position, const RID &, int64_t);
- virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override;
- virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override;
+ MODBIND3(font_set_underline_thickness, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_thickness, const RID &, int64_t);
- virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
- virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
+ MODBIND3(font_set_scale, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_scale, const RID &, int64_t);
- virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
- virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
- virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
+ MODBIND2RC(int64_t, font_get_texture_count, const RID &, const Vector2i &);
+ MODBIND2(font_clear_textures, const RID &, const Vector2i &);
+ MODBIND3(font_remove_texture, const RID &, const Vector2i &, int64_t);
- virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override;
- virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
+ MODBIND4(font_set_texture_image, const RID &, const Vector2i &, int64_t, const Ref<Image> &);
+ MODBIND3RC(Ref<Image>, font_get_texture_image, const RID &, const Vector2i &, int64_t);
- virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override;
- virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
+ MODBIND4(font_set_texture_offsets, const RID &, const Vector2i &, int64_t, const PackedInt32Array &);
+ MODBIND3RC(PackedInt32Array, font_get_texture_offsets, const RID &, const Vector2i &, int64_t);
- virtual PackedInt32Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override;
- virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override;
- virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override;
+ MODBIND2RC(PackedInt32Array, font_get_glyph_list, const RID &, const Vector2i &);
+ MODBIND2(font_clear_glyphs, const RID &, const Vector2i &);
+ MODBIND3(font_remove_glyph, const RID &, const Vector2i &, int64_t);
- virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override;
- virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override;
+ MODBIND3RC(Vector2, font_get_glyph_advance, const RID &, int64_t, int64_t);
+ MODBIND4(font_set_glyph_advance, const RID &, int64_t, int64_t, const Vector2 &);
- virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override;
+ MODBIND3RC(Vector2, font_get_glyph_offset, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_offset, const RID &, const Vector2i &, int64_t, const Vector2 &);
- virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override;
+ MODBIND3RC(Vector2, font_get_glyph_size, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_size, const RID &, const Vector2i &, int64_t, const Vector2 &);
- virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override;
+ MODBIND3RC(Rect2, font_get_glyph_uv_rect, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_uv_rect, const RID &, const Vector2i &, int64_t, const Rect2 &);
- virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override;
+ MODBIND3RC(int64_t, font_get_glyph_texture_idx, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_texture_idx, const RID &, const Vector2i &, int64_t, int64_t);
- virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+ MODBIND3RC(RID, font_get_glyph_texture_rid, const RID &, const Vector2i &, int64_t);
+ MODBIND3RC(Size2, font_get_glyph_texture_size, const RID &, const Vector2i &, int64_t);
- virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
+ MODBIND3RC(Dictionary, font_get_glyph_contours, const RID &, int64_t, int64_t);
- virtual TypedArray<Vector2i> font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override;
- virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override;
- virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override;
+ MODBIND2RC(TypedArray<Vector2i>, font_get_kerning_list, const RID &, int64_t);
+ MODBIND2(font_clear_kerning_map, const RID &, int64_t);
+ MODBIND3(font_remove_kerning, const RID &, int64_t, const Vector2i &);
- virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
- virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const override;
+ MODBIND4(font_set_kerning, const RID &, int64_t, const Vector2i &, const Vector2 &);
+ MODBIND3RC(Vector2, font_get_kerning, const RID &, int64_t, const Vector2i &);
- virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override;
+ MODBIND4RC(int64_t, font_get_glyph_index, const RID &, int64_t, int64_t, int64_t);
- virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
- virtual String font_get_supported_chars(const RID &p_font_rid) const override;
+ MODBIND2RC(bool, font_has_char, const RID &, int64_t);
+ MODBIND1RC(String, font_get_supported_chars, const RID &);
- virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
- virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
+ MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
+ MODBIND3(font_render_glyph, const RID &, const Vector2i &, int64_t);
- virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
- virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ MODBIND6C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &);
+ MODBIND7C(font_draw_glyph_outline, const RID &, const RID &, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
- virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
- virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
- virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) override;
- virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) override;
- virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) override;
+ MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
+ MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_language_support_override, const RID &, const String &);
+ MODBIND2(font_remove_language_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_language_support_overrides, const RID &);
- virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const override;
- virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) override;
- virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) override;
- virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) override;
- virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) override;
+ MODBIND2RC(bool, font_is_script_supported, const RID &, const String &);
+ MODBIND3(font_set_script_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_script_support_override, const RID &, const String &);
+ MODBIND2(font_remove_script_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_script_support_overrides, const RID &);
- virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) override;
- virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const override;
+ MODBIND2(font_set_opentype_feature_overrides, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_opentype_feature_overrides, const RID &);
- virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const override;
- virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const override;
+ MODBIND1RC(Dictionary, font_supported_feature_list, const RID &);
+ MODBIND1RC(Dictionary, font_supported_variation_list, const RID &);
- virtual double font_get_global_oversampling() const override;
- virtual void font_set_global_oversampling(double p_oversampling) override;
+ MODBIND0RC(double, font_get_global_oversampling);
+ MODBIND1(font_set_global_oversampling, double);
/* Shaped text buffer interface */
- virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+ MODBIND2R(RID, create_shaped_text, Direction, Orientation);
- virtual void shaped_text_clear(const RID &p_shaped) override;
+ MODBIND1(shaped_text_clear, const RID &);
- virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
- virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
- virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override;
+ MODBIND2(shaped_text_set_direction, const RID &, Direction);
+ MODBIND1RC(Direction, shaped_text_get_direction, const RID &);
+ MODBIND1RC(Direction, shaped_text_get_inferred_direction, const RID &);
- virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
+ MODBIND2(shaped_text_set_bidi_override, const RID &, const Array &);
- virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) override;
- virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const override;
+ MODBIND2(shaped_text_set_custom_punctuation, const RID &, const String &);
+ MODBIND1RC(String, shaped_text_get_custom_punctuation, const RID &);
- virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
- virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const override;
+ MODBIND2(shaped_text_set_orientation, const RID &, Orientation);
+ MODBIND1RC(Orientation, shaped_text_get_orientation, const RID &);
- virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) override;
- virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const override;
+ MODBIND2(shaped_text_set_preserve_invalid, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_invalid, const RID &);
- virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override;
- virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override;
+ MODBIND2(shaped_text_set_preserve_control, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_control, const RID &);
- virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+ MODBIND3(shaped_text_set_spacing, const RID &, SpacingType, int64_t);
+ MODBIND2RC(int64_t, shaped_text_get_spacing, const RID &, SpacingType);
- virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
- virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
- virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+ MODBIND7R(bool, shaped_text_add_string, const RID &, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
+ MODBIND5R(bool, shaped_text_add_object, const RID &, const Variant &, const Size2 &, InlineAlignment, int64_t);
+ MODBIND4R(bool, shaped_text_resize_object, const RID &, const Variant &, const Size2 &, InlineAlignment);
- virtual int64_t shaped_get_span_count(const RID &p_shaped) const override;
- virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override;
- virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+ MODBIND1RC(int64_t, shaped_get_span_count, const RID &);
+ MODBIND2RC(Variant, shaped_get_span_meta, const RID &, int64_t);
+ MODBIND5(shaped_set_span_update_font, const RID &, int64_t, const TypedArray<RID> &, int64_t, const Dictionary &);
- virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
- virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
+ MODBIND3RC(RID, shaped_text_substr, const RID &, int64_t, int64_t);
+ MODBIND1RC(RID, shaped_text_get_parent, const RID &);
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
- virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
+ MODBIND3R(double, shaped_text_fit_to_width, const RID &, double, BitField<TextServer::JustificationFlag>);
+ MODBIND2R(double, shaped_text_tab_align, const RID &, const PackedFloat32Array &);
- virtual bool shaped_text_shape(const RID &p_shaped) override;
- virtual bool shaped_text_update_breaks(const RID &p_shaped) override;
- virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override;
+ MODBIND1R(bool, shaped_text_shape, const RID &);
+ MODBIND1R(bool, shaped_text_update_breaks, const RID &);
+ MODBIND1R(bool, shaped_text_update_justification_ops, const RID &);
- virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
- virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
- virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
- virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
+ MODBIND1RC(int64_t, shaped_text_get_trim_pos, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_pos, const RID &);
+ MODBIND1RC(const Glyph *, shaped_text_get_ellipsis_glyphs, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_glyph_count, const RID &);
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
+ MODBIND3(shaped_text_overrun_trim_to_width, const RID &, double, BitField<TextServer::TextOverrunFlag>);
- virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
+ MODBIND1RC(bool, shaped_text_is_ready, const RID &);
- virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override;
- virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override;
- virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override;
+ MODBIND1RC(const Glyph *, shaped_text_get_glyphs, const RID &);
+ MODBIND1R(const Glyph *, shaped_text_sort_logical, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_glyph_count, const RID &);
- virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
+ MODBIND1RC(Vector2i, shaped_text_get_range, const RID &);
- virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
- virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
+ MODBIND1RC(Array, shaped_text_get_objects, const RID &);
+ MODBIND2RC(Rect2, shaped_text_get_object_rect, const RID &, const Variant &);
- virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
- virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
- virtual double shaped_text_get_descent(const RID &p_shaped) const override;
- virtual double shaped_text_get_width(const RID &p_shaped) const override;
- virtual double shaped_text_get_underline_position(const RID &p_shaped) const override;
- virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override;
+ MODBIND1RC(Size2, shaped_text_get_size, const RID &);
+ MODBIND1RC(double, shaped_text_get_ascent, const RID &);
+ MODBIND1RC(double, shaped_text_get_descent, const RID &);
+ MODBIND1RC(double, shaped_text_get_width, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_position, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_thickness, const RID &);
- virtual String format_number(const String &p_string, const String &p_language = "") const override;
- virtual String parse_number(const String &p_string, const String &p_language = "") const override;
- virtual String percent_sign(const String &p_language = "") const override;
+ MODBIND2RC(String, format_number, const String &, const String &);
+ MODBIND2RC(String, parse_number, const String &, const String &);
+ MODBIND1RC(String, percent_sign, const String &);
- virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override;
+ MODBIND2RC(PackedInt32Array, string_get_word_breaks, const String &, const String &);
- virtual int64_t is_confusable(const String &p_string, const PackedStringArray &p_dict) const override;
- virtual bool spoof_check(const String &p_string) const override;
+ MODBIND2RC(int64_t, is_confusable, const String &, const PackedStringArray &);
+ MODBIND1RC(bool, spoof_check, const String &);
- virtual String strip_diacritics(const String &p_string) const override;
- virtual bool is_valid_identifier(const String &p_string) const override;
+ MODBIND1RC(String, strip_diacritics, const String &);
+ MODBIND1RC(bool, is_valid_identifier, const String &);
- virtual String string_to_upper(const String &p_string, const String &p_language = "") const override;
- virtual String string_to_lower(const String &p_string, const String &p_language = "") const override;
+ MODBIND2RC(String, string_to_upper, const String &, const String &);
+ MODBIND2RC(String, string_to_lower, const String &, const String &);
TextServerAdvanced();
~TextServerAdvanced();
diff --git a/modules/text_server_adv/thorvg_bounds_iterator.cpp b/modules/text_server_adv/thorvg_bounds_iterator.cpp
new file mode 100644
index 0000000000..54a6136134
--- /dev/null
+++ b/modules/text_server_adv/thorvg_bounds_iterator.cpp
@@ -0,0 +1,70 @@
+/*************************************************************************/
+/* thorvg_bounds_iterator.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/godot.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
+
+#include "core/typedefs.h"
+
+#include "modules/modules_enabled.gen.h" // For svg.
+#endif
+
+#ifdef MODULE_SVG_ENABLED
+
+#include "thorvg_bounds_iterator.h"
+
+#include <tvgIteratorAccessor.h>
+#include <tvgPaint.h>
+
+// This function uses private ThorVG API to get bounding box of top level children elements.
+
+void tvg_get_bounds(tvg::Picture *p_picture, float &r_min_x, float &r_min_y, float &r_max_x, float &r_max_y) {
+ tvg::IteratorAccessor itrAccessor;
+ if (tvg::Iterator *it = itrAccessor.iterator(p_picture)) {
+ while (const tvg::Paint *child = it->next()) {
+ float x = 0, y = 0, w = 0, h = 0;
+ child->bounds(&x, &y, &w, &h, true);
+ r_min_x = MIN(x, r_min_x);
+ r_min_y = MIN(y, r_min_y);
+ r_max_x = MAX(x + w, r_max_x);
+ r_max_y = MAX(y + h, r_max_y);
+ }
+ delete (it);
+ }
+}
+
+#endif // MODULE_SVG_ENABLED
diff --git a/modules/text_server_adv/thorvg_bounds_iterator.h b/modules/text_server_adv/thorvg_bounds_iterator.h
new file mode 100644
index 0000000000..e54e30eaa2
--- /dev/null
+++ b/modules/text_server_adv/thorvg_bounds_iterator.h
@@ -0,0 +1,58 @@
+/*************************************************************************/
+/* thorvg_bounds_iterator.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef THORVG_BOUNDS_ITERATOR_H
+#define THORVG_BOUNDS_ITERATOR_H
+
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/core/mutex_lock.hpp>
+#include <godot_cpp/godot.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
+
+#include "core/typedefs.h"
+
+#include "modules/modules_enabled.gen.h" // For svg.
+#endif
+
+#ifdef MODULE_SVG_ENABLED
+
+#include <thorvg.h>
+
+void tvg_get_bounds(tvg::Picture *p_picture, float &r_min_x, float &r_min_y, float &r_max_x, float &r_max_y);
+
+#endif // MODULE_SVG_ENABLED
+
+#endif // THORVG_BOUNDS_ITERATOR_H
diff --git a/modules/text_server_adv/thorvg_svg_in_ot.cpp b/modules/text_server_adv/thorvg_svg_in_ot.cpp
new file mode 100644
index 0000000000..7863ab67fa
--- /dev/null
+++ b/modules/text_server_adv/thorvg_svg_in_ot.cpp
@@ -0,0 +1,320 @@
+/*************************************************************************/
+/* thorvg_svg_in_ot.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/classes/xml_parser.hpp>
+#include <godot_cpp/core/mutex_lock.hpp>
+#include <godot_cpp/godot.hpp>
+#include <godot_cpp/templates/vector.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
+
+#include "core/error/error_macros.h"
+#include "core/io/xml_parser.h"
+#include "core/os/memory.h"
+#include "core/os/os.h"
+#include "core/string/ustring.h"
+#include "core/typedefs.h"
+#include "core/variant/variant.h"
+
+#include "modules/modules_enabled.gen.h" // For svg.
+#endif
+
+#ifdef MODULE_SVG_ENABLED
+
+#include "thorvg_bounds_iterator.h"
+#include "thorvg_svg_in_ot.h"
+
+#include <freetype/otsvg.h>
+#include <ft2build.h>
+
+#include <math.h>
+#include <stdlib.h>
+
+FT_Error tvg_svg_in_ot_init(FT_Pointer *p_state) {
+ *p_state = memnew(TVG_State);
+
+ return FT_Err_Ok;
+}
+
+void tvg_svg_in_ot_free(FT_Pointer *p_state) {
+ TVG_State *state = *reinterpret_cast<TVG_State **>(p_state);
+ memdelete(state);
+}
+
+FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Pointer *p_state) {
+ TVG_State *state = *reinterpret_cast<TVG_State **>(p_state);
+ if (!state) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "SVG in OT state not initialized.");
+ }
+ MutexLock lock(state->mutex);
+
+ FT_SVG_Document document = (FT_SVG_Document)p_slot->other;
+ FT_Size_Metrics metrics = document->metrics;
+
+ GL_State &gl_state = state->glyph_map[p_slot->glyph_index];
+ if (!gl_state.ready) {
+ Ref<XMLParser> parser;
+ parser.instantiate();
+#ifdef GDEXTENSION
+ PackedByteArray data;
+ data.resize(document->svg_document_length);
+ memcpy(data.ptrw(), document->svg_document, document->svg_document_length);
+ parser->open_buffer(data);
+#else
+ parser->_open_buffer((const uint8_t *)document->svg_document, document->svg_document_length);
+#endif
+
+ float aspect = 1.0f;
+ String xml_body;
+ while (parser->read() == OK) {
+ if (parser->has_attribute("id")) {
+#ifdef GDEXTENSION
+ const String &gl_name = parser->get_named_attribute_value("id");
+#else
+ const String &gl_name = parser->get_attribute_value("id");
+#endif
+ if (gl_name.begins_with("glyph")) {
+ int dot_pos = gl_name.find(".");
+ int64_t gl_idx = gl_name.substr(5, (dot_pos > 0) ? dot_pos - 5 : -1).to_int();
+ if (p_slot->glyph_index != gl_idx) {
+ parser->skip_section();
+ continue;
+ }
+ }
+ }
+ if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "svg") {
+ if (parser->has_attribute("viewBox")) {
+#ifdef GDEXTENSION
+ PackedStringArray vb = parser->get_named_attribute_value("viewBox").split(" ");
+#else
+ Vector<String> vb = parser->get_attribute_value("viewBox").split(" ");
+#endif
+
+ if (vb.size() == 4) {
+ aspect = vb[2].to_float() / vb[3].to_float();
+ }
+ }
+ continue;
+ }
+#ifdef GDEXTENSION
+ if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
+ xml_body = xml_body + "<" + parser->get_node_name();
+ for (int i = 0; i < parser->get_attribute_count(); i++) {
+ xml_body = xml_body + " " + parser->get_attribute_name(i) + "=\"" + parser->get_attribute_value(i) + "\"";
+ }
+ xml_body = xml_body + ">";
+ } else if (parser->get_node_type() == XMLParser::NODE_TEXT) {
+ xml_body = xml_body + parser->get_node_data();
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
+ xml_body = xml_body + "</" + parser->get_node_name() + ">";
+ }
+#else
+ if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
+ xml_body += vformat("<%s", parser->get_node_name());
+ for (int i = 0; i < parser->get_attribute_count(); i++) {
+ xml_body += vformat(" %s=\"%s\"", parser->get_attribute_name(i), parser->get_attribute_value(i));
+ }
+ xml_body += ">";
+ } else if (parser->get_node_type() == XMLParser::NODE_TEXT) {
+ xml_body += parser->get_node_data();
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END) {
+ xml_body += vformat("</%s>", parser->get_node_name());
+ }
+#endif
+ }
+ String temp_xml = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
+
+ std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
+ tvg::Result result = picture->load(temp_xml.utf8().get_data(), temp_xml.utf8().length(), "svg+xml", false);
+ if (result != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (bounds detection).");
+ }
+
+ float min_x = INFINITY, min_y = INFINITY, max_x = -INFINITY, max_y = -INFINITY;
+ tvg_get_bounds(picture.get(), min_x, min_y, max_x, max_y);
+
+ float new_h = (max_y - min_y);
+ float new_w = (max_x - min_x);
+
+ if (new_h * aspect >= new_w) {
+ new_w = (new_h * aspect);
+ } else {
+ new_h = (new_w / aspect);
+ }
+
+#ifdef GDEXTENSION
+ gl_state.xml_code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
+#else
+ gl_state.xml_code = vformat("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%f %f %f %f\">", min_x, min_y, new_w, new_h) + xml_body;
+#endif
+
+ picture = tvg::Picture::gen();
+ result = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
+ if (result != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph metrics).");
+ }
+
+ float x_svg_to_out, y_svg_to_out;
+ x_svg_to_out = (float)metrics.x_ppem / new_w;
+ y_svg_to_out = (float)metrics.y_ppem / new_h;
+
+ gl_state.m.e11 = (double)document->transform.xx / (1 << 16) * x_svg_to_out;
+ gl_state.m.e12 = -(double)document->transform.xy / (1 << 16) * x_svg_to_out;
+ gl_state.m.e21 = -(double)document->transform.yx / (1 << 16) * y_svg_to_out;
+ gl_state.m.e22 = (double)document->transform.yy / (1 << 16) * y_svg_to_out;
+ gl_state.m.e13 = (double)document->delta.x / 64 * new_w / metrics.x_ppem;
+ gl_state.m.e23 = -(double)document->delta.y / 64 * new_h / metrics.y_ppem;
+ gl_state.m.e31 = 0;
+ gl_state.m.e32 = 0;
+ gl_state.m.e33 = 1;
+
+ result = picture->transform(gl_state.m);
+ if (result != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to apply transform to SVG document.");
+ }
+
+ result = picture->bounds(&gl_state.x, &gl_state.y, &gl_state.w, &gl_state.h, true);
+ if (result != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to get SVG bounds.");
+ }
+
+ gl_state.bmp_y = -min_y * gl_state.h / new_h;
+ gl_state.bmp_x = min_x * gl_state.w / new_w;
+
+ gl_state.ready = true;
+ }
+
+ p_slot->bitmap_left = (FT_Int)gl_state.bmp_x;
+ p_slot->bitmap_top = (FT_Int)gl_state.bmp_y;
+
+ float tmp = ceil(gl_state.h);
+ p_slot->bitmap.rows = (unsigned int)tmp;
+ tmp = ceil(gl_state.w);
+ p_slot->bitmap.width = (unsigned int)tmp;
+ p_slot->bitmap.pitch = (int)p_slot->bitmap.width * 4;
+ p_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
+
+ float metrics_width, metrics_height;
+ float horiBearingX, horiBearingY;
+ float vertBearingX, vertBearingY;
+
+ metrics_width = (float)gl_state.w;
+ metrics_height = (float)gl_state.h;
+ horiBearingX = (float)gl_state.x;
+ horiBearingY = (float)-gl_state.y;
+ vertBearingX = p_slot->metrics.horiBearingX / 64.0f - p_slot->metrics.horiAdvance / 64.0f / 2;
+ vertBearingY = (p_slot->metrics.vertAdvance / 64.0f - p_slot->metrics.height / 64.0f) / 2;
+
+ tmp = roundf(metrics_width * 64);
+ p_slot->metrics.width = (FT_Pos)tmp;
+ tmp = roundf(metrics_height * 64);
+ p_slot->metrics.height = (FT_Pos)tmp;
+
+ p_slot->metrics.horiBearingX = (FT_Pos)(horiBearingX * 64);
+ p_slot->metrics.horiBearingY = (FT_Pos)(horiBearingY * 64);
+ p_slot->metrics.vertBearingX = (FT_Pos)(vertBearingX * 64);
+ p_slot->metrics.vertBearingY = (FT_Pos)(vertBearingY * 64);
+
+ if (p_slot->metrics.vertAdvance == 0) {
+ p_slot->metrics.vertAdvance = (FT_Pos)(metrics_height * 1.2f * 64);
+ }
+
+ return FT_Err_Ok;
+}
+
+FT_Error tvg_svg_in_ot_render(FT_GlyphSlot p_slot, FT_Pointer *p_state) {
+ TVG_State *state = *reinterpret_cast<TVG_State **>(p_state);
+ if (!state) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "SVG in OT state not initialized.");
+ }
+ MutexLock lock(state->mutex);
+
+ if (!state->glyph_map.has(p_slot->glyph_index)) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "SVG glyph not loaded.");
+ }
+
+ GL_State &gl_state = state->glyph_map[p_slot->glyph_index];
+ ERR_FAIL_COND_V_MSG(!gl_state.ready, FT_Err_Invalid_SVG_Document, "SVG glyph not ready.");
+
+ std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
+ tvg::Result res = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph rendering).");
+ }
+ res = picture->transform(gl_state.m);
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to apply transform to SVG document.");
+ }
+
+ std::unique_ptr<tvg::SwCanvas> sw_canvas = tvg::SwCanvas::gen();
+ res = sw_canvas->target((uint32_t *)p_slot->bitmap.buffer, (int)p_slot->bitmap.width, (int)p_slot->bitmap.width, (int)p_slot->bitmap.rows, tvg::SwCanvas::ARGB8888_STRAIGHT);
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_Outline, "Failed to create SVG canvas.");
+ }
+ res = sw_canvas->push(std::move(picture));
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_Outline, "Failed to set SVG canvas source.");
+ }
+ res = sw_canvas->draw();
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_Outline, "Failed to draw to SVG canvas.");
+ }
+ res = sw_canvas->sync();
+ if (res != tvg::Result::Success) {
+ ERR_FAIL_V_MSG(FT_Err_Invalid_Outline, "Failed to sync SVG canvas.");
+ }
+
+ state->glyph_map.erase(p_slot->glyph_index);
+
+ p_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
+ p_slot->bitmap.num_grays = 256;
+ p_slot->format = FT_GLYPH_FORMAT_BITMAP;
+
+ return FT_Err_Ok;
+}
+
+SVG_RendererHooks tvg_svg_in_ot_hooks = {
+ (SVG_Lib_Init_Func)tvg_svg_in_ot_init,
+ (SVG_Lib_Free_Func)tvg_svg_in_ot_free,
+ (SVG_Lib_Render_Func)tvg_svg_in_ot_render,
+ (SVG_Lib_Preset_Slot_Func)tvg_svg_in_ot_preset_slot,
+};
+
+SVG_RendererHooks *get_tvg_svg_in_ot_hooks() {
+ return &tvg_svg_in_ot_hooks;
+}
+
+#endif // MODULE_SVG_ENABLED
diff --git a/modules/text_server_adv/thorvg_svg_in_ot.h b/modules/text_server_adv/thorvg_svg_in_ot.h
new file mode 100644
index 0000000000..b2816193d9
--- /dev/null
+++ b/modules/text_server_adv/thorvg_svg_in_ot.h
@@ -0,0 +1,86 @@
+/*************************************************************************/
+/* thorvg_svg_in_ot.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef THORVG_SVG_IN_OT_H
+#define THORVG_SVG_IN_OT_H
+
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/core/mutex_lock.hpp>
+#include <godot_cpp/godot.hpp>
+#include <godot_cpp/templates/hash_map.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
+
+#include "core/os/mutex.h"
+#include "core/templates/hash_map.h"
+#include "core/typedefs.h"
+
+#include "modules/modules_enabled.gen.h" // For svg.
+#endif
+
+#ifdef MODULE_SVG_ENABLED
+
+#include <freetype/freetype.h>
+#include <freetype/otsvg.h>
+#include <ft2build.h>
+#include <thorvg.h>
+
+struct GL_State {
+ bool ready = false;
+ float bmp_x = 0;
+ float bmp_y = 0;
+ float x = 0;
+ float y = 0;
+ float w = 0;
+ float h = 0;
+ String xml_code;
+ tvg::Matrix m;
+};
+
+struct TVG_State {
+ Mutex mutex;
+ HashMap<uint32_t, GL_State> glyph_map;
+};
+
+FT_Error tvg_svg_in_ot_init(FT_Pointer *p_state);
+void tvg_svg_in_ot_free(FT_Pointer *p_state);
+FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Pointer *p_state);
+FT_Error tvg_svg_in_ot_render(FT_GlyphSlot p_slot, FT_Pointer *p_state);
+
+SVG_RendererHooks *get_tvg_svg_in_ot_hooks();
+
+#endif // MODULE_SVG_ENABLED
+
+#endif // THORVG_SVG_IN_OT_H