From 366e2d893e14826c3669e14911efa745d690d074 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Mon, 1 Aug 2022 12:03:20 +0300 Subject: [TextServer] Add a build warning when building with external FreeType without Brotli support. --- modules/text_server_adv/SCsub | 1 + modules/text_server_adv/text_server_adv.h | 5 ++++- modules/text_server_fb/SCsub | 1 + modules/text_server_fb/text_server_fb.h | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) (limited to 'modules') diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index d212fe62b4..93fd8fe45f 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -507,6 +507,7 @@ if env["builtin_msdfgen"] and msdfgen_enabled: env_text_server_adv.Prepend(CPPPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: + env_text_server_adv.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) env_text_server_adv.Prepend(CPPPATH=["#thirdparty/freetype/include"]) if env["builtin_graphite"] and freetype_enabled: diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 8cd0e753ba..8852c40406 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -112,7 +112,10 @@ using namespace godot; #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_BBOX_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. +#endif #include #include #endif diff --git a/modules/text_server_fb/SCsub b/modules/text_server_fb/SCsub index ca9322e450..8f626f02b8 100644 --- a/modules/text_server_fb/SCsub +++ b/modules/text_server_fb/SCsub @@ -12,6 +12,7 @@ if env["builtin_msdfgen"] and msdfgen_enabled: env_text_server_fb.Prepend(CPPPATH=["#thirdparty/msdfgen"]) if env["builtin_freetype"] and freetype_enabled: + env_text_server_fb.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) env_text_server_fb.Prepend(CPPPATH=["#thirdparty/freetype/include"]) env_text_server_fb.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index adb5cbb817..fef19d442b 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -98,6 +98,10 @@ using namespace godot; #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_BBOX_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. +#endif #endif /*************************************************************************/ -- cgit v1.2.3 From 066ca976909bbe81d702dfe464f8f5dfbb23d7e3 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Wed, 3 Aug 2022 13:38:37 +0300 Subject: Add Text Server related options to the build profiles editor. Adds SCons options to disable Brotli and Graphite. Adds option categories to the build profiles editor. Adds options default state to the build profiles editor. Adds Text Server related options to the build profiles editor. Fix misplaced OpenGL/Vulkan SCons options. --- SConstruct | 18 ++++-- editor/editor_build_profile.cpp | 130 ++++++++++++++++++++++++++++++++++---- editor/editor_build_profile.h | 20 +++++- modules/freetype/SCsub | 33 +++++----- modules/freetype/config.py | 8 +++ modules/mono/config.py | 50 ++++++--------- modules/text_server_adv/SCsub | 11 ++-- modules/text_server_adv/config.py | 8 +++ 8 files changed, 208 insertions(+), 70 deletions(-) (limited to 'modules') diff --git a/SConstruct b/SConstruct index 0fd9326e1c..17184c2e36 100644 --- a/SConstruct +++ b/SConstruct @@ -337,21 +337,27 @@ for path in module_search_paths: # Add module options. for name, path in modules_detected.items(): + sys.path.insert(0, path) + import config + if env_base["modules_enabled_by_default"]: enabled = True - - sys.path.insert(0, path) - import config - try: enabled = config.is_enabled() except AttributeError: pass - sys.path.remove(path) - sys.modules.pop("config") else: enabled = False + # Add module-specific options. + try: + for opt in config.get_opts(selected_platform): + opts.Add(opt) + except AttributeError: + pass + + sys.path.remove(path) + sys.modules.pop("config") opts.Add(BoolVariable("module_" + name + "_enabled", "Enable module '%s'" % (name,), enabled)) methods.write_modules(modules_detected) diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index d093ab518e..0f0ab4a339 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -46,19 +46,68 @@ const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = { "disable_3d_physics", "disable_navigation", "openxr", + "rendering_device", // FIXME: there's no scons option to disable rendering device "opengl3", "vulkan", + "module_text_server_fb_enabled", + "module_text_server_adv_enabled", + "module_freetype_enabled", + "brotli", + "graphite", + "module_msdfgen_enabled" +}; + +const bool EditorBuildProfile::build_option_disabled_by_default[BUILD_OPTION_MAX] = { + // This maps to SCons build options. + false, // 3D + false, // PHYSICS_2D + false, // PHYSICS_3D + false, // NAVIGATION + false, // XR + false, // RENDERING_DEVICE + false, // OPENGL + false, // VULKAN + true, // TEXT_SERVER_FALLBACK + false, // TEXT_SERVER_COMPLEX + false, // DYNAMIC_FONTS + false, // WOFF2_FONTS + false, // GRPAHITE_FONTS + false, // MSDFGEN }; const bool EditorBuildProfile::build_option_disable_values[BUILD_OPTION_MAX] = { // This maps to SCons build options. - true, - true, - true, - true, - false, - false, - false + true, // 3D + true, // PHYSICS_2D + true, // PHYSICS_3D + true, // NAVIGATION + false, // XR + false, // RENDERING_DEVICE + false, // OPENGL + false, // VULKAN + false, // TEXT_SERVER_FALLBACK + false, // TEXT_SERVER_COMPLEX + false, // DYNAMIC_FONTS + false, // WOFF2_FONTS + false, // GRPAHITE_FONTS + false, // MSDFGEN +}; + +const EditorBuildProfile::BuildOptionCategory EditorBuildProfile::build_option_category[BUILD_OPTION_MAX] = { + BUILD_OPTION_CATEGORY_GENERAL, // 3D + BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_2D + BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_3D + BUILD_OPTION_CATEGORY_GENERAL, // NAVIGATION + BUILD_OPTION_CATEGORY_GENERAL, // XR + BUILD_OPTION_CATEGORY_GENERAL, // RENDERING_DEVICE + BUILD_OPTION_CATEGORY_GENERAL, // OPENGL + BUILD_OPTION_CATEGORY_GENERAL, // VULKAN + BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_FALLBACK + BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_COMPLEX + BUILD_OPTION_CATEGORY_TEXT_SERVER, // DYNAMIC_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // WOFF2_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // GRPAHITE_FONTS + BUILD_OPTION_CATEGORY_TEXT_SERVER, // MSDFGEN }; void EditorBuildProfile::set_disable_class(const StringName &p_class, bool p_disabled) { @@ -127,6 +176,12 @@ String EditorBuildProfile::get_build_option_name(BuildOption p_build_option) { TTRC("RenderingDevice"), TTRC("OpenGL"), TTRC("Vulkan"), + TTRC("Text Server: Fallback"), + TTRC("Text Server: Advanced"), + TTRC("TTF, OTF, Type 1, WOFF1 Fonts"), + TTRC("WOFF2 Fonts"), + TTRC("SIL Graphite Fonts"), + TTRC("Multi-channel Signed Distance Field Font Rendering"), }; return TTRGET(build_option_names[p_build_option]); } @@ -143,11 +198,33 @@ String EditorBuildProfile::get_build_option_description(BuildOption p_build_opti TTRC("RenderingDevice based rendering (if disabled, the OpenGL back-end is required)."), TTRC("OpenGL back-end (if disabled, the RenderingDevice back-end is required)."), TTRC("Vulkan back-end of RenderingDevice."), + TTRC("Fallback implementation of Text Server\nSupports basic text layouts."), + TTRC("Text Server implementation powered by ICU and HarfBuzz libraries.\nSupports complex text layouts, BiDi, and contextual OpenType font features."), + TTRC("TrueType, OpenType, Type 1, and WOFF1 font format support using FreeType library (if disabled, WOFF2 support is also disabled)."), + TTRC("WOFF2 font format support using FreeType and Brotli libraries."), + TTRC("SIL Graphite smart font technology support (supported by Advanced Text Server only)."), + TTRC("Multi-channel signed distance field font rendering support using msdfgen library (pre-rendered MSDF fonts can be used even if this option disabled)."), }; return TTRGET(build_option_descriptions[p_build_option]); } +EditorBuildProfile::BuildOptionCategory EditorBuildProfile::get_build_option_category(BuildOption p_build_option) { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, BUILD_OPTION_CATEGORY_GENERAL); + return build_option_category[p_build_option]; +} + +String EditorBuildProfile::get_build_option_category_name(BuildOptionCategory p_build_option_category) { + ERR_FAIL_INDEX_V(p_build_option_category, BUILD_OPTION_CATEGORY_MAX, String()); + + const char *build_option_subcategories[BUILD_OPTION_CATEGORY_MAX]{ + TTRC("General Features:"), + TTRC("Text Rendering and Font Options:"), + }; + + return TTRGET(build_option_subcategories[p_build_option_category]); +} + Error EditorBuildProfile::save_to_file(const String &p_path) { Dictionary data; data["type"] = "build_profile"; @@ -160,8 +237,12 @@ Error EditorBuildProfile::save_to_file(const String &p_path) { Dictionary dis_build_options; for (int i = 0; i < BUILD_OPTION_MAX; i++) { - if (build_options_disabled[i]) { - dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i]; + if (build_options_disabled[i] != build_option_disabled_by_default[i]) { + if (build_options_disabled[i]) { + dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i]; + } else { + dis_build_options[build_option_identifiers[i]] = !build_option_disable_values[i]; + } } } @@ -211,7 +292,7 @@ Error EditorBuildProfile::load_from_file(const String &p_path) { } for (int i = 0; i < BUILD_OPTION_MAX; i++) { - build_options_disabled[i] = false; + build_options_disabled[i] = build_option_disabled_by_default[i]; } if (data.has("disabled_build_options")) { @@ -259,10 +340,24 @@ void EditorBuildProfile::_bind_methods() { BIND_ENUM_CONSTANT(BUILD_OPTION_RENDERING_DEVICE); BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL); BIND_ENUM_CONSTANT(BUILD_OPTION_VULKAN); + BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_FALLBACK); + BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_ADVANCED); + BIND_ENUM_CONSTANT(BUILD_OPTION_DYNAMIC_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_WOFF2_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_GRPAHITE_FONTS); + BIND_ENUM_CONSTANT(BUILD_OPTION_MSDFGEN); BIND_ENUM_CONSTANT(BUILD_OPTION_MAX); + + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_GENERAL); + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_TEXT_SERVER); + BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_MAX); } -EditorBuildProfile::EditorBuildProfile() {} +EditorBuildProfile::EditorBuildProfile() { + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) { + build_options_disabled[i] = build_option_disabled_by_default[i]; + } +} ////////////////////////// @@ -633,11 +728,18 @@ void EditorBuildProfileManager::_update_edited_profile() { TreeItem *root = class_list->create_item(); - TreeItem *build_options = class_list->create_item(root); - build_options->set_text(0, TTR("General Features:")); + HashMap subcats; + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_CATEGORY_MAX; i++) { + TreeItem *build_cat; + build_cat = class_list->create_item(root); + + build_cat->set_text(0, EditorBuildProfile::get_build_option_category_name(EditorBuildProfile::BuildOptionCategory(i))); + subcats[EditorBuildProfile::BuildOptionCategory(i)] = build_cat; + } + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) { TreeItem *build_option; - build_option = class_list->create_item(build_options); + build_option = class_list->create_item(subcats[EditorBuildProfile::get_build_option_category(EditorBuildProfile::BuildOption(i))]); build_option->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); build_option->set_text(0, EditorBuildProfile::get_build_option_name(EditorBuildProfile::BuildOption(i))); diff --git a/editor/editor_build_profile.h b/editor/editor_build_profile.h index bb6494b8c9..606c415429 100644 --- a/editor/editor_build_profile.h +++ b/editor/editor_build_profile.h @@ -53,7 +53,19 @@ public: BUILD_OPTION_RENDERING_DEVICE, BUILD_OPTION_OPENGL, BUILD_OPTION_VULKAN, - BUILD_OPTION_MAX + BUILD_OPTION_TEXT_SERVER_FALLBACK, + BUILD_OPTION_TEXT_SERVER_ADVANCED, + BUILD_OPTION_DYNAMIC_FONTS, + BUILD_OPTION_WOFF2_FONTS, + BUILD_OPTION_GRPAHITE_FONTS, + BUILD_OPTION_MSDFGEN, + BUILD_OPTION_MAX, + }; + + enum BuildOptionCategory { + BUILD_OPTION_CATEGORY_GENERAL, + BUILD_OPTION_CATEGORY_TEXT_SERVER, + BUILD_OPTION_CATEGORY_MAX, }; private: @@ -65,7 +77,9 @@ private: bool build_options_disabled[BUILD_OPTION_MAX] = {}; static const char *build_option_identifiers[BUILD_OPTION_MAX]; + static const bool build_option_disabled_by_default[BUILD_OPTION_MAX]; static const bool build_option_disable_values[BUILD_OPTION_MAX]; + static const BuildOptionCategory build_option_category[BUILD_OPTION_MAX]; String _get_build_option_name(BuildOption p_build_option) { return get_build_option_name(p_build_option); } @@ -93,11 +107,15 @@ public: static String get_build_option_name(BuildOption p_build_option); static String get_build_option_description(BuildOption p_build_option); static bool get_build_option_disable_value(BuildOption p_build_option); + static BuildOptionCategory get_build_option_category(BuildOption p_build_option); + + static String get_build_option_category_name(BuildOptionCategory p_build_option_category); EditorBuildProfile(); }; VARIANT_ENUM_CAST(EditorBuildProfile::BuildOption) +VARIANT_ENUM_CAST(EditorBuildProfile::BuildOptionCategory) class EditorFileSystemDirectory; diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index 4b2ea6faa5..8efcd72fb6 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -58,22 +58,23 @@ if env["builtin_freetype"]: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - thirdparty_brotli_dir = "#thirdparty/brotli/" - thirdparty_brotli_sources = [ - "common/constants.c", - "common/context.c", - "common/dictionary.c", - "common/platform.c", - "common/shared_dictionary.c", - "common/transform.c", - "dec/bit_reader.c", - "dec/decode.c", - "dec/huffman.c", - "dec/state.c", - ] - thirdparty_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] - env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) - env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) + if env["brotli"]: + thirdparty_brotli_dir = "#thirdparty/brotli/" + thirdparty_brotli_sources = [ + "common/constants.c", + "common/context.c", + "common/dictionary.c", + "common/platform.c", + "common/shared_dictionary.c", + "common/transform.c", + "dec/bit_reader.c", + "dec/decode.c", + "dec/huffman.c", + "dec/state.c", + ] + thirdparty_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources] + env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"]) + env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"]) if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"): env_freetype.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"]) diff --git a/modules/freetype/config.py b/modules/freetype/config.py index d22f9454ed..c0586d5536 100644 --- a/modules/freetype/config.py +++ b/modules/freetype/config.py @@ -2,5 +2,13 @@ def can_build(env, platform): return True +def get_opts(platform): + from SCons.Variables import BoolVariable + + return [ + BoolVariable("brotli", "Enable Brotli decompressor for WOFF2 fonts support", True), + ] + + def configure(env): pass diff --git a/modules/mono/config.py b/modules/mono/config.py index 3e6584590c..d895d2d92d 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -5,52 +5,44 @@ def can_build(env, platform): return not env["arch"].startswith("rv") -def configure(env): - platform = env["platform"] - - if platform not in supported_platforms: - raise RuntimeError("This module does not currently support building for this platform") - - env.add_module_version_string("mono") - - from SCons.Script import BoolVariable, PathVariable, Variables, Help +def get_opts(platform): + from SCons.Variables import BoolVariable, PathVariable default_mono_static = platform in ["ios", "javascript"] default_mono_bundles_zlib = platform in ["javascript"] - envvars = Variables() - envvars.Add( + return [ PathVariable( "mono_prefix", "Path to the Mono installation directory for the target platform and architecture", "", PathVariable.PathAccept, - ) - ) - envvars.Add( + ), PathVariable( "mono_bcl", "Path to a custom Mono BCL (Base Class Library) directory for the target platform", "", PathVariable.PathAccept, - ) - ) - envvars.Add(BoolVariable("mono_static", "Statically link Mono", default_mono_static)) - envvars.Add(BoolVariable("mono_glue", "Build with the Mono glue sources", True)) - envvars.Add(BoolVariable("build_cil", "Build C# solutions", True)) - envvars.Add( - BoolVariable("copy_mono_root", "Make a copy of the Mono installation directory to bundle with the editor", True) - ) - - # TODO: It would be great if this could be detected automatically instead - envvars.Add( + ), + BoolVariable("mono_static", "Statically link Mono", default_mono_static), + BoolVariable("mono_glue", "Build with the Mono glue sources", True), + BoolVariable("build_cil", "Build C# solutions", True), + BoolVariable( + "copy_mono_root", "Make a copy of the Mono installation directory to bundle with the editor", True + ), BoolVariable( "mono_bundles_zlib", "Specify if the Mono runtime was built with bundled zlib", default_mono_bundles_zlib - ) - ) + ), + ] + + +def configure(env): + platform = env["platform"] - envvars.Update(env) - Help(envvars.GenerateHelpText(env)) + if platform not in supported_platforms: + raise RuntimeError("This module does not currently support building for this platform") + + env.add_module_version_string("mono") if env["mono_bundles_zlib"]: # Mono may come with zlib bundled for WASM or on newer version when built with MinGW. diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 73e5c2bf74..c514ebcd1b 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -113,8 +113,11 @@ if env["builtin_harfbuzz"]: if freetype_enabled: thirdparty_sources += [ "src/hb-ft.cc", - "src/hb-graphite2.cc", ] + if env["graphite"]: + thirdparty_sources += [ + "src/hb-graphite2.cc", + ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_harfbuzz.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) @@ -133,7 +136,7 @@ if env["builtin_harfbuzz"]: ) if env["builtin_freetype"]: env_harfbuzz.Prepend(CPPPATH=["#thirdparty/freetype/include"]) - if env["builtin_graphite"]: + if env["builtin_graphite"] and env["graphite"]: env_harfbuzz.Prepend(CPPPATH=["#thirdparty/graphite/include"]) env_harfbuzz.Append(CCFLAGS=["-DGRAPHITE2_STATIC"]) @@ -165,7 +168,7 @@ if env["builtin_harfbuzz"]: env.Append(LIBS=[lib]) -if env["builtin_graphite"] and freetype_enabled: +if env["builtin_graphite"] and freetype_enabled and env["graphite"]: env_graphite = env_modules.Clone() env_graphite.disable_warnings() @@ -514,7 +517,7 @@ if env["builtin_msdfgen"] and msdfgen_enabled: if env["builtin_freetype"] and freetype_enabled: env_text_server_adv.Prepend(CPPPATH=["#thirdparty/freetype/include"]) -if env["builtin_graphite"] and freetype_enabled: +if env["builtin_graphite"] and freetype_enabled and env["graphite"]: env_text_server_adv.Prepend(CPPPATH=["#thirdparty/graphite/include"]) env_text_server_adv.add_source_files(module_obj, "*.cpp") diff --git a/modules/text_server_adv/config.py b/modules/text_server_adv/config.py index 8c8df9b05e..179a2ff378 100644 --- a/modules/text_server_adv/config.py +++ b/modules/text_server_adv/config.py @@ -2,6 +2,14 @@ def can_build(env, platform): return True +def get_opts(platform): + from SCons.Variables import BoolVariable + + return [ + BoolVariable("graphite", "Enable SIL Graphite smart fonts support", True), + ] + + def configure(env): pass -- cgit v1.2.3 From 4b155b939ba6f18a65b25c5599c2ecef4d70511a Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 5 Aug 2022 18:06:08 +0300 Subject: [Text Server] Prevent composite glyphs which incorporate kashida from being used for justification. Update TextServer tests to clean up on fail. --- modules/text_server_adv/text_server_adv.cpp | 2 +- tests/servers/test_text_server.h | 198 +++++++++++++++++----------- 2 files changed, 121 insertions(+), 79 deletions(-) (limited to 'modules') diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 21e1bfaa5c..73dbf2f443 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -4706,7 +4706,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape for (int i = 0; i < sd_size; i++) { if (sd_glyphs[i].count > 0) { char32_t c = sd->text[sd_glyphs[i].start - sd->start]; - if (c == 0x0640) { + if (c == 0x0640 && sd_glyphs[i].start == sd_glyphs[i].end - 1) { sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION; } if (sd->jstops.has(sd_glyphs[i].start)) { diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 57a2cae37f..9ebd0f34b4 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -44,7 +44,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Loading fonts") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC)) { continue; @@ -52,7 +52,7 @@ TEST_SUITE("[TextServer]") { RID font = ts->create_font(); ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size); - TEST_FAIL_COND(font == RID(), "Loading font failed."); + CHECK_FALSE_MESSAGE(font == RID(), "Loading font failed."); ts->free_rid(font); } } @@ -60,7 +60,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Font fallback") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -79,26 +79,26 @@ TEST_SUITE("[TextServer]") { // 6^ 17^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].start < 6) { - TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[1], "Incorrect font selected."); } if ((glyphs[j].start > 6) && (glyphs[j].start < 16)) { - TEST_FAIL_COND(glyphs[j].font_rid != font[0], "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[0], "Incorrect font selected."); } if (glyphs[j].start > 16) { - TEST_FAIL_COND(glyphs[j].font_rid != RID(), "Incorrect font selected."); - TEST_FAIL_COND(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); + CHECK_FALSE_MESSAGE(glyphs[j].font_rid != RID(), "Incorrect font selected."); + CHECK_FALSE_MESSAGE(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index."); } - TEST_FAIL_COND((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); - TEST_FAIL_COND(glyphs[j].font_size != 16, "Incorrect glyph font size."); + CHECK_FALSE_MESSAGE((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range."); + CHECK_FALSE_MESSAGE(glyphs[j].font_size != 16, "Incorrect glyph font size."); } ts->free_rid(ctx); @@ -113,7 +113,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: BiDi") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) { continue; @@ -132,23 +132,23 @@ TEST_SUITE("[TextServer]") { // 7^ 26^ RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed"); for (int j = 0; j < gl_size; j++) { if (glyphs[j].count > 0) { if (glyphs[j].start < 7) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if ((glyphs[j].start > 8) && (glyphs[j].start < 23)) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } if (glyphs[j].start > 26) { - TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); + CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); } } } @@ -165,7 +165,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Line break and align points") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -186,16 +186,16 @@ TEST_SUITE("[TextServer]") { { String test = U"Test test long text long text\n"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 30, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 30, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -203,11 +203,11 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 14 || j == 19 || j == 24) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 29) { - TEST_FAIL_COND((soft || !space || !hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || !space || !hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -216,21 +216,63 @@ TEST_SUITE("[TextServer]") { { String test = U"الحمـد"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { + ts->shaped_text_update_justification_ops(ctx); + + glyphs = ts->shaped_text_get_glyphs(ctx); + gl_size = ts->shaped_text_get_glyph_count(ctx); + + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + if (j == 1) { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); + } else { + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); + } + } + } + ts->free_rid(ctx); + } + + { + String test = U"الحمد"; + RID ctx = ts->create_shaped_text(); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); + bool ok = ts->shaped_text_add_string(ctx, test, font, 16); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); + ts->shaped_text_update_breaks(ctx); + + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + CHECK_FALSE_MESSAGE(gl_size != 5, "Invalid glyph count."); + for (int j = 0; j < gl_size; j++) { + bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; + bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; + bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE; + bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; + bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { @@ -239,7 +281,7 @@ TEST_SUITE("[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 6, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -247,9 +289,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 1) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -259,15 +301,15 @@ TEST_SUITE("[TextServer]") { { String test = U"الحمـد الرياضي العربي"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 21, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 21, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -275,9 +317,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 6 || j == 14) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } @@ -287,7 +329,7 @@ TEST_SUITE("[TextServer]") { glyphs = ts->shaped_text_get_glyphs(ctx); gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 23, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 23, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -295,13 +337,13 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 7 || j == 16) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else if (j == 3 || j == 9) { - TEST_FAIL_COND((soft || space || hard || !virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags."); } else if (j == 18) { - TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } } @@ -312,16 +354,16 @@ TEST_SUITE("[TextServer]") { { String test = U"เป็น ภาษา ราชการ และ ภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -329,9 +371,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -340,16 +382,16 @@ TEST_SUITE("[TextServer]") { if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) { String test = U"เป็นภาษาราชการและภาษา"; RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); ts->shaped_text_update_breaks(ctx); ts->shaped_text_update_justification_ops(ctx); const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); int gl_size = ts->shaped_text_get_glyph_count(ctx); - TEST_FAIL_COND(gl_size != 25, "Invalid glyph count."); + CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count."); for (int j = 0; j < gl_size; j++) { bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD; bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT; @@ -357,9 +399,9 @@ TEST_SUITE("[TextServer]") { bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL; bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION; if (j == 4 || j == 9 || j == 16 || j == 20) { - TEST_FAIL_COND((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((!soft || !space || hard || !virt || elo), "Invalid glyph flags."); } else { - TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags."); + CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags."); } } ts->free_rid(ctx); @@ -375,7 +417,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Line breaking") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -394,21 +436,21 @@ TEST_SUITE("[TextServer]") { font.push_back(font2); RID ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1); - TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number."); + CHECK_FALSE_MESSAGE(brks.size() != 6, "Invalid line breaks number."); if (brks.size() == 6) { - TEST_FAIL_COND(brks[0] != 0, "Invalid line break position."); - TEST_FAIL_COND(brks[1] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[1] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[2] != 5, "Invalid line break position."); - TEST_FAIL_COND(brks[3] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[3] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[4] != 10, "Invalid line break position."); - TEST_FAIL_COND(brks[5] != 14, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[4] != 10, "Invalid line break position."); + CHECK_FALSE_MESSAGE(brks[5] != 14, "Invalid line break position."); } ts->free_rid(ctx); @@ -423,7 +465,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Text layout: Justification") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) { continue; @@ -448,40 +490,40 @@ TEST_SUITE("[TextServer]") { float width_old, width; if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) { ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_1, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width != width_old), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width != width_old), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_2, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); } ctx = ts->create_shaped_text(); - TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed."); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); ok = ts->shaped_text_add_string(ctx, test_3, font, 16); - TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); + CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed."); width_old = ts->shaped_text_get_width(ctx); width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND); - TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width."); + CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width."); ts->free_rid(ctx); @@ -495,7 +537,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Unicode identifiers") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); static const char32_t *data[19] = { U"-30", U"100", U"10.1", U"10,1", U"1e2", U"1e-2", U"1e2e3", U"0xAB", U"AB", U"Test1", U"1Test", U"Test*1", U"test_testeT", U"test_tes teT", U"عَلَيْكُمْ", U"عَلَيْكُمْTest", U"ӒӖӚӜ", U"_test", U"ÂÃÄÅĀĂĄÇĆĈĊ" }; static bool isid[19] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, true, true }; @@ -516,7 +558,7 @@ TEST_SUITE("[TextServer]") { SUBCASE("[TextServer] Strip Diacritics") { for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { Ref ts = TextServerManager::get_singleton()->get_interface(i); - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); if (ts->has_feature(TextServer::FEATURE_SHAPING)) { CHECK(ts->strip_diacritics(U"ٱلسَّلَامُ عَلَيْكُمْ") == U"ٱلسلام عليكم"); @@ -544,7 +586,7 @@ TEST_SUITE("[TextServer]") { continue; } - TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); + CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface."); { String text1 = U"linguistically similar and effectively form"; // 14^ 22^ 26^ 38^ -- cgit v1.2.3