summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor/plugins/script_text_editor.cpp1
-rw-r--r--modules/text_server_adv/text_server_adv.cpp600
-rw-r--r--scene/gui/text_edit.cpp158
-rw-r--r--scene/gui/text_edit.h21
4 files changed, 453 insertions, 327 deletions
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index c44760807f..48239a5d99 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -158,7 +158,6 @@ void ScriptTextEditor::enable_editor() {
editor_enabled = true;
_enable_code_editor();
- _set_theme_for_script();
_validate_script();
}
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 78a87be971..19e94adf68 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -440,266 +440,260 @@ bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) {
}
}
-struct FeatureInfo {
- int32_t tag;
- String name;
-};
+static Map<StringName, int32_t> feature_sets;
-static FeatureInfo feature_set[] = {
+static void _insert_feature_sets() {
// Registered OpenType feature tags.
- { HB_TAG('a', 'a', 'l', 't'), "access_all_alternates" },
- { HB_TAG('a', 'b', 'v', 'f'), "above_base_forms" },
- { HB_TAG('a', 'b', 'v', 'm'), "above_base_mark_positioning" },
- { HB_TAG('a', 'b', 'v', 's'), "above_base_substitutions" },
- { HB_TAG('a', 'f', 'r', 'c'), "alternative_fractions" },
- { HB_TAG('a', 'k', 'h', 'n'), "akhands" },
- { HB_TAG('b', 'l', 'w', 'f'), "below_base_forms" },
- { HB_TAG('b', 'l', 'w', 'm'), "below_base_mark_positioning" },
- { HB_TAG('b', 'l', 'w', 's'), "below_base_substitutions" },
- { HB_TAG('c', 'a', 'l', 't'), "contextual_alternates" },
- { HB_TAG('c', 'a', 's', 'e'), "case_sensitive_forms" },
- { HB_TAG('c', 'c', 'm', 'p'), "glyph_composition" },
- { HB_TAG('c', 'f', 'a', 'r'), "conjunct_form_after_ro" },
- { HB_TAG('c', 'j', 'c', 't'), "conjunct_forms" },
- { HB_TAG('c', 'l', 'i', 'g'), "contextual_ligatures" },
- { HB_TAG('c', 'p', 'c', 't'), "centered_cjk_punctuation" },
- { HB_TAG('c', 'p', 's', 'p'), "capital_spacing" },
- { HB_TAG('c', 's', 'w', 'h'), "contextual_swash" },
- { HB_TAG('c', 'u', 'r', 's'), "cursive_positioning" },
- { HB_TAG('c', 'v', '0', '1'), "character_variant_01" },
- { HB_TAG('c', 'v', '0', '2'), "character_variant_02" },
- { HB_TAG('c', 'v', '0', '3'), "character_variant_03" },
- { HB_TAG('c', 'v', '0', '4'), "character_variant_04" },
- { HB_TAG('c', 'v', '0', '5'), "character_variant_05" },
- { HB_TAG('c', 'v', '0', '6'), "character_variant_06" },
- { HB_TAG('c', 'v', '0', '7'), "character_variant_07" },
- { HB_TAG('c', 'v', '0', '8'), "character_variant_08" },
- { HB_TAG('c', 'v', '0', '9'), "character_variant_09" },
- { HB_TAG('c', 'v', '1', '0'), "character_variant_10" },
- { HB_TAG('c', 'v', '1', '1'), "character_variant_11" },
- { HB_TAG('c', 'v', '1', '2'), "character_variant_12" },
- { HB_TAG('c', 'v', '1', '3'), "character_variant_13" },
- { HB_TAG('c', 'v', '1', '4'), "character_variant_14" },
- { HB_TAG('c', 'v', '1', '5'), "character_variant_15" },
- { HB_TAG('c', 'v', '1', '6'), "character_variant_16" },
- { HB_TAG('c', 'v', '1', '7'), "character_variant_17" },
- { HB_TAG('c', 'v', '1', '8'), "character_variant_18" },
- { HB_TAG('c', 'v', '1', '9'), "character_variant_19" },
- { HB_TAG('c', 'v', '2', '0'), "character_variant_20" },
- { HB_TAG('c', 'v', '2', '1'), "character_variant_21" },
- { HB_TAG('c', 'v', '2', '2'), "character_variant_22" },
- { HB_TAG('c', 'v', '2', '3'), "character_variant_23" },
- { HB_TAG('c', 'v', '2', '4'), "character_variant_24" },
- { HB_TAG('c', 'v', '2', '5'), "character_variant_25" },
- { HB_TAG('c', 'v', '2', '6'), "character_variant_26" },
- { HB_TAG('c', 'v', '2', '7'), "character_variant_27" },
- { HB_TAG('c', 'v', '2', '8'), "character_variant_28" },
- { HB_TAG('c', 'v', '2', '9'), "character_variant_29" },
- { HB_TAG('c', 'v', '3', '0'), "character_variant_30" },
- { HB_TAG('c', 'v', '3', '1'), "character_variant_31" },
- { HB_TAG('c', 'v', '3', '2'), "character_variant_32" },
- { HB_TAG('c', 'v', '3', '3'), "character_variant_33" },
- { HB_TAG('c', 'v', '3', '4'), "character_variant_34" },
- { HB_TAG('c', 'v', '3', '5'), "character_variant_35" },
- { HB_TAG('c', 'v', '3', '6'), "character_variant_36" },
- { HB_TAG('c', 'v', '3', '7'), "character_variant_37" },
- { HB_TAG('c', 'v', '3', '8'), "character_variant_38" },
- { HB_TAG('c', 'v', '3', '9'), "character_variant_39" },
- { HB_TAG('c', 'v', '4', '0'), "character_variant_40" },
- { HB_TAG('c', 'v', '4', '1'), "character_variant_41" },
- { HB_TAG('c', 'v', '4', '2'), "character_variant_42" },
- { HB_TAG('c', 'v', '4', '3'), "character_variant_43" },
- { HB_TAG('c', 'v', '4', '4'), "character_variant_44" },
- { HB_TAG('c', 'v', '4', '5'), "character_variant_45" },
- { HB_TAG('c', 'v', '4', '6'), "character_variant_46" },
- { HB_TAG('c', 'v', '4', '7'), "character_variant_47" },
- { HB_TAG('c', 'v', '4', '8'), "character_variant_48" },
- { HB_TAG('c', 'v', '4', '9'), "character_variant_49" },
- { HB_TAG('c', 'v', '5', '0'), "character_variant_50" },
- { HB_TAG('c', 'v', '5', '1'), "character_variant_51" },
- { HB_TAG('c', 'v', '5', '2'), "character_variant_52" },
- { HB_TAG('c', 'v', '5', '3'), "character_variant_53" },
- { HB_TAG('c', 'v', '5', '4'), "character_variant_54" },
- { HB_TAG('c', 'v', '5', '5'), "character_variant_55" },
- { HB_TAG('c', 'v', '5', '6'), "character_variant_56" },
- { HB_TAG('c', 'v', '5', '7'), "character_variant_57" },
- { HB_TAG('c', 'v', '5', '8'), "character_variant_58" },
- { HB_TAG('c', 'v', '5', '9'), "character_variant_59" },
- { HB_TAG('c', 'v', '6', '0'), "character_variant_60" },
- { HB_TAG('c', 'v', '6', '1'), "character_variant_61" },
- { HB_TAG('c', 'v', '6', '2'), "character_variant_62" },
- { HB_TAG('c', 'v', '6', '3'), "character_variant_63" },
- { HB_TAG('c', 'v', '6', '4'), "character_variant_64" },
- { HB_TAG('c', 'v', '6', '5'), "character_variant_65" },
- { HB_TAG('c', 'v', '6', '6'), "character_variant_66" },
- { HB_TAG('c', 'v', '6', '7'), "character_variant_67" },
- { HB_TAG('c', 'v', '6', '8'), "character_variant_68" },
- { HB_TAG('c', 'v', '6', '9'), "character_variant_69" },
- { HB_TAG('c', 'v', '7', '0'), "character_variant_70" },
- { HB_TAG('c', 'v', '7', '1'), "character_variant_71" },
- { HB_TAG('c', 'v', '7', '2'), "character_variant_72" },
- { HB_TAG('c', 'v', '7', '3'), "character_variant_73" },
- { HB_TAG('c', 'v', '7', '4'), "character_variant_74" },
- { HB_TAG('c', 'v', '7', '5'), "character_variant_75" },
- { HB_TAG('c', 'v', '7', '6'), "character_variant_76" },
- { HB_TAG('c', 'v', '7', '7'), "character_variant_77" },
- { HB_TAG('c', 'v', '7', '8'), "character_variant_78" },
- { HB_TAG('c', 'v', '7', '9'), "character_variant_79" },
- { HB_TAG('c', 'v', '8', '0'), "character_variant_80" },
- { HB_TAG('c', 'v', '8', '1'), "character_variant_81" },
- { HB_TAG('c', 'v', '8', '2'), "character_variant_82" },
- { HB_TAG('c', 'v', '8', '3'), "character_variant_83" },
- { HB_TAG('c', 'v', '8', '4'), "character_variant_84" },
- { HB_TAG('c', 'v', '8', '5'), "character_variant_85" },
- { HB_TAG('c', 'v', '8', '6'), "character_variant_86" },
- { HB_TAG('c', 'v', '8', '7'), "character_variant_87" },
- { HB_TAG('c', 'v', '8', '8'), "character_variant_88" },
- { HB_TAG('c', 'v', '8', '9'), "character_variant_89" },
- { HB_TAG('c', 'v', '9', '0'), "character_variant_90" },
- { HB_TAG('c', 'v', '9', '1'), "character_variant_91" },
- { HB_TAG('c', 'v', '9', '2'), "character_variant_92" },
- { HB_TAG('c', 'v', '9', '3'), "character_variant_93" },
- { HB_TAG('c', 'v', '9', '4'), "character_variant_94" },
- { HB_TAG('c', 'v', '9', '5'), "character_variant_95" },
- { HB_TAG('c', 'v', '9', '6'), "character_variant_96" },
- { HB_TAG('c', 'v', '9', '7'), "character_variant_97" },
- { HB_TAG('c', 'v', '9', '8'), "character_variant_98" },
- { HB_TAG('c', 'v', '9', '9'), "character_variant_99" },
- { HB_TAG('c', '2', 'p', 'c'), "petite_capitals_from_capitals" },
- { HB_TAG('c', '2', 's', 'c'), "small_capitals_from_capitals" },
- { HB_TAG('d', 'i', 's', 't'), "distances" },
- { HB_TAG('d', 'l', 'i', 'g'), "discretionary_ligatures" },
- { HB_TAG('d', 'n', 'o', 'm'), "denominators" },
- { HB_TAG('d', 't', 'l', 's'), "dotless_forms" },
- { HB_TAG('e', 'x', 'p', 't'), "expert_forms" },
- { HB_TAG('f', 'a', 'l', 't'), "final_glyph_on_line_alternates" },
- { HB_TAG('f', 'i', 'n', '2'), "terminal_forms_2" },
- { HB_TAG('f', 'i', 'n', '3'), "terminal_forms_3" },
- { HB_TAG('f', 'i', 'n', 'a'), "terminal_forms" },
- { HB_TAG('f', 'l', 'a', 'c'), "flattened_accent_forms" },
- { HB_TAG('f', 'r', 'a', 'c'), "fractions" },
- { HB_TAG('f', 'w', 'i', 'd'), "full_widths" },
- { HB_TAG('h', 'a', 'l', 'f'), "half_forms" },
- { HB_TAG('h', 'a', 'l', 'n'), "halant_forms" },
- { HB_TAG('h', 'a', 'l', 't'), "alternate_half_widths" },
- { HB_TAG('h', 'i', 's', 't'), "historical_forms" },
- { HB_TAG('h', 'k', 'n', 'a'), "horizontal_kana_alternates" },
- { HB_TAG('h', 'l', 'i', 'g'), "historical_ligatures" },
- { HB_TAG('h', 'n', 'g', 'l'), "hangul" },
- { HB_TAG('h', 'o', 'j', 'o'), "hojo_kanji_forms" },
- { HB_TAG('h', 'w', 'i', 'd'), "half_widths" },
- { HB_TAG('i', 'n', 'i', 't'), "initial_forms" },
- { HB_TAG('i', 's', 'o', 'l'), "isolated_forms" },
- { HB_TAG('i', 't', 'a', 'l'), "italics" },
- { HB_TAG('j', 'a', 'l', 't'), "justification_alternates" },
- { HB_TAG('j', 'p', '7', '8'), "jis78_forms" },
- { HB_TAG('j', 'p', '8', '3'), "jis83_forms" },
- { HB_TAG('j', 'p', '9', '0'), "jis90_forms" },
- { HB_TAG('j', 'p', '0', '4'), "jis2004_forms" },
- { HB_TAG('k', 'e', 'r', 'n'), "kerning" },
- { HB_TAG('l', 'f', 'b', 'd'), "left_bounds" },
- { HB_TAG('l', 'i', 'g', 'a'), "standard_ligatures" },
- { HB_TAG('l', 'j', 'm', 'o'), "leading_jamo_forms" },
- { HB_TAG('l', 'n', 'u', 'm'), "lining_figures" },
- { HB_TAG('l', 'o', 'c', 'l'), "localized_forms" },
- { HB_TAG('l', 't', 'r', 'a'), "left_to_right_alternates" },
- { HB_TAG('l', 't', 'r', 'm'), "left_to_right_mirrored_forms" },
- { HB_TAG('m', 'a', 'r', 'k'), "mark_positioning" },
- { HB_TAG('m', 'e', 'd', '2'), "medial_forms_2" },
- { HB_TAG('m', 'e', 'd', 'i'), "medial_forms" },
- { HB_TAG('m', 'g', 'r', 'k'), "mathematical_greek" },
- { HB_TAG('m', 'k', 'm', 'k'), "mark_to_mark_positioning" },
- { HB_TAG('m', 's', 'e', 't'), "mark_positioning_via_substitution" },
- { HB_TAG('n', 'a', 'l', 't'), "alternate_annotation_forms" },
- { HB_TAG('n', 'l', 'c', 'k'), "nlc_kanji_forms" },
- { HB_TAG('n', 'u', 'k', 't'), "nukta_forms" },
- { HB_TAG('n', 'u', 'm', 'r'), "numerators" },
- { HB_TAG('o', 'n', 'u', 'm'), "oldstyle_figures" },
- { HB_TAG('o', 'p', 'b', 'd'), "optical_bounds" },
- { HB_TAG('o', 'r', 'd', 'n'), "ordinals" },
- { HB_TAG('o', 'r', 'n', 'm'), "ornaments" },
- { HB_TAG('p', 'a', 'l', 't'), "proportional_alternate_widths" },
- { HB_TAG('p', 'c', 'a', 'p'), "petite_capitals" },
- { HB_TAG('p', 'k', 'n', 'a'), "proportional_kana" },
- { HB_TAG('p', 'n', 'u', 'm'), "proportional_figures" },
- { HB_TAG('p', 'r', 'e', 'f'), "pre_base_forms" },
- { HB_TAG('p', 'r', 'e', 's'), "pre_base_substitutions" },
- { HB_TAG('p', 's', 't', 'f'), "post_base_forms" },
- { HB_TAG('p', 's', 't', 's'), "post_base_substitutions" },
- { HB_TAG('p', 'w', 'i', 'd'), "proportional_widths" },
- { HB_TAG('q', 'w', 'i', 'd'), "quarter_widths" },
- { HB_TAG('r', 'a', 'n', 'd'), "randomize" },
- { HB_TAG('r', 'c', 'l', 't'), "required_contextual_alternates" },
- { HB_TAG('r', 'k', 'r', 'f'), "rakar_forms" },
- { HB_TAG('r', 'l', 'i', 'g'), "required_ligatures" },
- { HB_TAG('r', 'p', 'h', 'f'), "reph_forms" },
- { HB_TAG('r', 't', 'b', 'd'), "right_bounds" },
- { HB_TAG('r', 't', 'l', 'a'), "right_to_left_alternates" },
- { HB_TAG('r', 't', 'l', 'm'), "right_to_left_mirrored_forms" },
- { HB_TAG('r', 'u', 'b', 'y'), "ruby_notation_forms" },
- { HB_TAG('r', 'v', 'r', 'n'), "required_variation_alternates" },
- { HB_TAG('s', 'a', 'l', 't'), "stylistic_alternates" },
- { HB_TAG('s', 'i', 'n', 'f'), "scientific_inferiors" },
- { HB_TAG('s', 'i', 'z', 'e'), "optical_size" },
- { HB_TAG('s', 'm', 'c', 'p'), "small_capitals" },
- { HB_TAG('s', 'm', 'p', 'l'), "simplified_forms" },
- { HB_TAG('s', 's', '0', '1'), "stylistic_set_01" },
- { HB_TAG('s', 's', '0', '2'), "stylistic_set_02" },
- { HB_TAG('s', 's', '0', '3'), "stylistic_set_03" },
- { HB_TAG('s', 's', '0', '4'), "stylistic_set_04" },
- { HB_TAG('s', 's', '0', '5'), "stylistic_set_05" },
- { HB_TAG('s', 's', '0', '6'), "stylistic_set_06" },
- { HB_TAG('s', 's', '0', '7'), "stylistic_set_07" },
- { HB_TAG('s', 's', '0', '8'), "stylistic_set_08" },
- { HB_TAG('s', 's', '0', '9'), "stylistic_set_09" },
- { HB_TAG('s', 's', '1', '0'), "stylistic_set_10" },
- { HB_TAG('s', 's', '1', '1'), "stylistic_set_11" },
- { HB_TAG('s', 's', '1', '2'), "stylistic_set_12" },
- { HB_TAG('s', 's', '1', '3'), "stylistic_set_13" },
- { HB_TAG('s', 's', '1', '4'), "stylistic_set_14" },
- { HB_TAG('s', 's', '1', '5'), "stylistic_set_15" },
- { HB_TAG('s', 's', '1', '6'), "stylistic_set_16" },
- { HB_TAG('s', 's', '1', '7'), "stylistic_set_17" },
- { HB_TAG('s', 's', '1', '8'), "stylistic_set_18" },
- { HB_TAG('s', 's', '1', '9'), "stylistic_set_19" },
- { HB_TAG('s', 's', '2', '0'), "stylistic_set_20" },
- { HB_TAG('s', 's', 't', 'y'), "math_script_style_alternates" },
- { HB_TAG('s', 't', 'c', 'h'), "stretching_glyph_decomposition" },
- { HB_TAG('s', 'u', 'b', 's'), "subscript" },
- { HB_TAG('s', 'u', 'p', 's'), "superscript" },
- { HB_TAG('s', 'w', 's', 'h'), "swash" },
- { HB_TAG('t', 'i', 't', 'l'), "titling" },
- { HB_TAG('t', 'j', 'm', 'o'), "trailing_jamo_forms" },
- { HB_TAG('t', 'n', 'a', 'm'), "traditional_name_forms" },
- { HB_TAG('t', 'n', 'u', 'm'), "tabular_figures" },
- { HB_TAG('t', 'r', 'a', 'd'), "traditional_forms" },
- { HB_TAG('t', 'w', 'i', 'd'), "third_widths" },
- { HB_TAG('u', 'n', 'i', 'c'), "unicase" },
- { HB_TAG('v', 'a', 'l', 't'), "alternate_vertical_metrics" },
- { HB_TAG('v', 'a', 't', 'u'), "vattu_variants" },
- { HB_TAG('v', 'e', 'r', 't'), "vertical_writing" },
- { HB_TAG('v', 'h', 'a', 'l'), "alternate_vertical_half_metrics" },
- { HB_TAG('v', 'j', 'm', 'o'), "vowel_jamo_forms" },
- { HB_TAG('v', 'k', 'n', 'a'), "vertical_kana_alternates" },
- { HB_TAG('v', 'k', 'r', 'n'), "vertical_kerning" },
- { HB_TAG('v', 'p', 'a', 'l'), "proportional_alternate_vertical_metrics" },
- { HB_TAG('v', 'r', 't', '2'), "vertical_alternates_and_rotation" },
- { HB_TAG('v', 'r', 't', 'r'), "vertical_alternates_for_rotation" },
- { HB_TAG('z', 'e', 'r', 'o'), "slashed_zero" },
- // Registered OpenType variation tags.
- { HB_TAG('i', 't', 'a', 'l'), "italic" },
- { HB_TAG('o', 'p', 's', 'z'), "optical_size" },
- { HB_TAG('s', 'l', 'n', 't'), "slant" },
- { HB_TAG('w', 'd', 't', 'h'), "width" },
- { HB_TAG('w', 'g', 'h', 't'), "weight" },
- { 0, String() },
-};
+ feature_sets.insert("access_all_alternates", HB_TAG('a', 'a', 'l', 't'));
+ feature_sets.insert("above_base_forms", HB_TAG('a', 'b', 'v', 'f'));
+ feature_sets.insert("above_base_mark_positioning", HB_TAG('a', 'b', 'v', 'm'));
+ feature_sets.insert("above_base_substitutions", HB_TAG('a', 'b', 'v', 's'));
+ feature_sets.insert("alternative_fractions", HB_TAG('a', 'f', 'r', 'c'));
+ feature_sets.insert("akhands", HB_TAG('a', 'k', 'h', 'n'));
+ feature_sets.insert("below_base_forms", HB_TAG('b', 'l', 'w', 'f'));
+ feature_sets.insert("below_base_mark_positioning", HB_TAG('b', 'l', 'w', 'm'));
+ feature_sets.insert("below_base_substitutions", HB_TAG('b', 'l', 'w', 's'));
+ feature_sets.insert("contextual_alternates", HB_TAG('c', 'a', 'l', 't'));
+ feature_sets.insert("case_sensitive_forms", HB_TAG('c', 'a', 's', 'e'));
+ feature_sets.insert("glyph_composition", HB_TAG('c', 'c', 'm', 'p'));
+ feature_sets.insert("conjunct_form_after_ro", HB_TAG('c', 'f', 'a', 'r'));
+ feature_sets.insert("conjunct_forms", HB_TAG('c', 'j', 'c', 't'));
+ feature_sets.insert("contextual_ligatures", HB_TAG('c', 'l', 'i', 'g'));
+ feature_sets.insert("centered_cjk_punctuation", HB_TAG('c', 'p', 'c', 't'));
+ feature_sets.insert("capital_spacing", HB_TAG('c', 'p', 's', 'p'));
+ feature_sets.insert("contextual_swash", HB_TAG('c', 's', 'w', 'h'));
+ feature_sets.insert("cursive_positioning", HB_TAG('c', 'u', 'r', 's'));
+ feature_sets.insert("character_variant_01", HB_TAG('c', 'v', '0', '1'));
+ feature_sets.insert("character_variant_02", HB_TAG('c', 'v', '0', '2'));
+ feature_sets.insert("character_variant_03", HB_TAG('c', 'v', '0', '3'));
+ feature_sets.insert("character_variant_04", HB_TAG('c', 'v', '0', '4'));
+ feature_sets.insert("character_variant_05", HB_TAG('c', 'v', '0', '5'));
+ feature_sets.insert("character_variant_06", HB_TAG('c', 'v', '0', '6'));
+ feature_sets.insert("character_variant_07", HB_TAG('c', 'v', '0', '7'));
+ feature_sets.insert("character_variant_08", HB_TAG('c', 'v', '0', '8'));
+ feature_sets.insert("character_variant_09", HB_TAG('c', 'v', '0', '9'));
+ feature_sets.insert("character_variant_10", HB_TAG('c', 'v', '1', '0'));
+ feature_sets.insert("character_variant_11", HB_TAG('c', 'v', '1', '1'));
+ feature_sets.insert("character_variant_12", HB_TAG('c', 'v', '1', '2'));
+ feature_sets.insert("character_variant_13", HB_TAG('c', 'v', '1', '3'));
+ feature_sets.insert("character_variant_14", HB_TAG('c', 'v', '1', '4'));
+ feature_sets.insert("character_variant_15", HB_TAG('c', 'v', '1', '5'));
+ feature_sets.insert("character_variant_16", HB_TAG('c', 'v', '1', '6'));
+ feature_sets.insert("character_variant_17", HB_TAG('c', 'v', '1', '7'));
+ feature_sets.insert("character_variant_18", HB_TAG('c', 'v', '1', '8'));
+ feature_sets.insert("character_variant_19", HB_TAG('c', 'v', '1', '9'));
+ feature_sets.insert("character_variant_20", HB_TAG('c', 'v', '2', '0'));
+ feature_sets.insert("character_variant_21", HB_TAG('c', 'v', '2', '1'));
+ feature_sets.insert("character_variant_22", HB_TAG('c', 'v', '2', '2'));
+ feature_sets.insert("character_variant_23", HB_TAG('c', 'v', '2', '3'));
+ feature_sets.insert("character_variant_24", HB_TAG('c', 'v', '2', '4'));
+ feature_sets.insert("character_variant_25", HB_TAG('c', 'v', '2', '5'));
+ feature_sets.insert("character_variant_26", HB_TAG('c', 'v', '2', '6'));
+ feature_sets.insert("character_variant_27", HB_TAG('c', 'v', '2', '7'));
+ feature_sets.insert("character_variant_28", HB_TAG('c', 'v', '2', '8'));
+ feature_sets.insert("character_variant_29", HB_TAG('c', 'v', '2', '9'));
+ feature_sets.insert("character_variant_30", HB_TAG('c', 'v', '3', '0'));
+ feature_sets.insert("character_variant_31", HB_TAG('c', 'v', '3', '1'));
+ feature_sets.insert("character_variant_32", HB_TAG('c', 'v', '3', '2'));
+ feature_sets.insert("character_variant_33", HB_TAG('c', 'v', '3', '3'));
+ feature_sets.insert("character_variant_34", HB_TAG('c', 'v', '3', '4'));
+ feature_sets.insert("character_variant_35", HB_TAG('c', 'v', '3', '5'));
+ feature_sets.insert("character_variant_36", HB_TAG('c', 'v', '3', '6'));
+ feature_sets.insert("character_variant_37", HB_TAG('c', 'v', '3', '7'));
+ feature_sets.insert("character_variant_38", HB_TAG('c', 'v', '3', '8'));
+ feature_sets.insert("character_variant_39", HB_TAG('c', 'v', '3', '9'));
+ feature_sets.insert("character_variant_40", HB_TAG('c', 'v', '4', '0'));
+ feature_sets.insert("character_variant_41", HB_TAG('c', 'v', '4', '1'));
+ feature_sets.insert("character_variant_42", HB_TAG('c', 'v', '4', '2'));
+ feature_sets.insert("character_variant_43", HB_TAG('c', 'v', '4', '3'));
+ feature_sets.insert("character_variant_44", HB_TAG('c', 'v', '4', '4'));
+ feature_sets.insert("character_variant_45", HB_TAG('c', 'v', '4', '5'));
+ feature_sets.insert("character_variant_46", HB_TAG('c', 'v', '4', '6'));
+ feature_sets.insert("character_variant_47", HB_TAG('c', 'v', '4', '7'));
+ feature_sets.insert("character_variant_48", HB_TAG('c', 'v', '4', '8'));
+ feature_sets.insert("character_variant_49", HB_TAG('c', 'v', '4', '9'));
+ feature_sets.insert("character_variant_50", HB_TAG('c', 'v', '5', '0'));
+ feature_sets.insert("character_variant_51", HB_TAG('c', 'v', '5', '1'));
+ feature_sets.insert("character_variant_52", HB_TAG('c', 'v', '5', '2'));
+ feature_sets.insert("character_variant_53", HB_TAG('c', 'v', '5', '3'));
+ feature_sets.insert("character_variant_54", HB_TAG('c', 'v', '5', '4'));
+ feature_sets.insert("character_variant_55", HB_TAG('c', 'v', '5', '5'));
+ feature_sets.insert("character_variant_56", HB_TAG('c', 'v', '5', '6'));
+ feature_sets.insert("character_variant_57", HB_TAG('c', 'v', '5', '7'));
+ feature_sets.insert("character_variant_58", HB_TAG('c', 'v', '5', '8'));
+ feature_sets.insert("character_variant_59", HB_TAG('c', 'v', '5', '9'));
+ feature_sets.insert("character_variant_60", HB_TAG('c', 'v', '6', '0'));
+ feature_sets.insert("character_variant_61", HB_TAG('c', 'v', '6', '1'));
+ feature_sets.insert("character_variant_62", HB_TAG('c', 'v', '6', '2'));
+ feature_sets.insert("character_variant_63", HB_TAG('c', 'v', '6', '3'));
+ feature_sets.insert("character_variant_64", HB_TAG('c', 'v', '6', '4'));
+ feature_sets.insert("character_variant_65", HB_TAG('c', 'v', '6', '5'));
+ feature_sets.insert("character_variant_66", HB_TAG('c', 'v', '6', '6'));
+ feature_sets.insert("character_variant_67", HB_TAG('c', 'v', '6', '7'));
+ feature_sets.insert("character_variant_68", HB_TAG('c', 'v', '6', '8'));
+ feature_sets.insert("character_variant_69", HB_TAG('c', 'v', '6', '9'));
+ feature_sets.insert("character_variant_70", HB_TAG('c', 'v', '7', '0'));
+ feature_sets.insert("character_variant_71", HB_TAG('c', 'v', '7', '1'));
+ feature_sets.insert("character_variant_72", HB_TAG('c', 'v', '7', '2'));
+ feature_sets.insert("character_variant_73", HB_TAG('c', 'v', '7', '3'));
+ feature_sets.insert("character_variant_74", HB_TAG('c', 'v', '7', '4'));
+ feature_sets.insert("character_variant_75", HB_TAG('c', 'v', '7', '5'));
+ feature_sets.insert("character_variant_76", HB_TAG('c', 'v', '7', '6'));
+ feature_sets.insert("character_variant_77", HB_TAG('c', 'v', '7', '7'));
+ feature_sets.insert("character_variant_78", HB_TAG('c', 'v', '7', '8'));
+ feature_sets.insert("character_variant_79", HB_TAG('c', 'v', '7', '9'));
+ feature_sets.insert("character_variant_80", HB_TAG('c', 'v', '8', '0'));
+ feature_sets.insert("character_variant_81", HB_TAG('c', 'v', '8', '1'));
+ feature_sets.insert("character_variant_82", HB_TAG('c', 'v', '8', '2'));
+ feature_sets.insert("character_variant_83", HB_TAG('c', 'v', '8', '3'));
+ feature_sets.insert("character_variant_84", HB_TAG('c', 'v', '8', '4'));
+ feature_sets.insert("character_variant_85", HB_TAG('c', 'v', '8', '5'));
+ feature_sets.insert("character_variant_86", HB_TAG('c', 'v', '8', '6'));
+ feature_sets.insert("character_variant_87", HB_TAG('c', 'v', '8', '7'));
+ feature_sets.insert("character_variant_88", HB_TAG('c', 'v', '8', '8'));
+ feature_sets.insert("character_variant_89", HB_TAG('c', 'v', '8', '9'));
+ feature_sets.insert("character_variant_90", HB_TAG('c', 'v', '9', '0'));
+ feature_sets.insert("character_variant_91", HB_TAG('c', 'v', '9', '1'));
+ feature_sets.insert("character_variant_92", HB_TAG('c', 'v', '9', '2'));
+ feature_sets.insert("character_variant_93", HB_TAG('c', 'v', '9', '3'));
+ feature_sets.insert("character_variant_94", HB_TAG('c', 'v', '9', '4'));
+ feature_sets.insert("character_variant_95", HB_TAG('c', 'v', '9', '5'));
+ feature_sets.insert("character_variant_96", HB_TAG('c', 'v', '9', '6'));
+ feature_sets.insert("character_variant_97", HB_TAG('c', 'v', '9', '7'));
+ feature_sets.insert("character_variant_98", HB_TAG('c', 'v', '9', '8'));
+ feature_sets.insert("character_variant_99", HB_TAG('c', 'v', '9', '9'));
+ feature_sets.insert("petite_capitals_from_capitals", HB_TAG('c', '2', 'p', 'c'));
+ feature_sets.insert("small_capitals_from_capitals", HB_TAG('c', '2', 's', 'c'));
+ feature_sets.insert("distances", HB_TAG('d', 'i', 's', 't'));
+ feature_sets.insert("discretionary_ligatures", HB_TAG('d', 'l', 'i', 'g'));
+ feature_sets.insert("denominators", HB_TAG('d', 'n', 'o', 'm'));
+ feature_sets.insert("dotless_forms", HB_TAG('d', 't', 'l', 's'));
+ feature_sets.insert("expert_forms", HB_TAG('e', 'x', 'p', 't'));
+ feature_sets.insert("final_glyph_on_line_alternates", HB_TAG('f', 'a', 'l', 't'));
+ feature_sets.insert("terminal_forms_2", HB_TAG('f', 'i', 'n', '2'));
+ feature_sets.insert("terminal_forms_3", HB_TAG('f', 'i', 'n', '3'));
+ feature_sets.insert("terminal_forms", HB_TAG('f', 'i', 'n', 'a'));
+ feature_sets.insert("flattened_accent_forms", HB_TAG('f', 'l', 'a', 'c'));
+ feature_sets.insert("fractions", HB_TAG('f', 'r', 'a', 'c'));
+ feature_sets.insert("full_widths", HB_TAG('f', 'w', 'i', 'd'));
+ feature_sets.insert("half_forms", HB_TAG('h', 'a', 'l', 'f'));
+ feature_sets.insert("halant_forms", HB_TAG('h', 'a', 'l', 'n'));
+ feature_sets.insert("alternate_half_widths", HB_TAG('h', 'a', 'l', 't'));
+ feature_sets.insert("historical_forms", HB_TAG('h', 'i', 's', 't'));
+ feature_sets.insert("horizontal_kana_alternates", HB_TAG('h', 'k', 'n', 'a'));
+ feature_sets.insert("historical_ligatures", HB_TAG('h', 'l', 'i', 'g'));
+ feature_sets.insert("hangul", HB_TAG('h', 'n', 'g', 'l'));
+ feature_sets.insert("hojo_kanji_forms", HB_TAG('h', 'o', 'j', 'o'));
+ feature_sets.insert("half_widths", HB_TAG('h', 'w', 'i', 'd'));
+ feature_sets.insert("initial_forms", HB_TAG('i', 'n', 'i', 't'));
+ feature_sets.insert("isolated_forms", HB_TAG('i', 's', 'o', 'l'));
+ feature_sets.insert("italics", HB_TAG('i', 't', 'a', 'l'));
+ feature_sets.insert("justification_alternates", HB_TAG('j', 'a', 'l', 't'));
+ feature_sets.insert("jis78_forms", HB_TAG('j', 'p', '7', '8'));
+ feature_sets.insert("jis83_forms", HB_TAG('j', 'p', '8', '3'));
+ feature_sets.insert("jis90_forms", HB_TAG('j', 'p', '9', '0'));
+ feature_sets.insert("jis2004_forms", HB_TAG('j', 'p', '0', '4'));
+ feature_sets.insert("kerning", HB_TAG('k', 'e', 'r', 'n'));
+ feature_sets.insert("left_bounds", HB_TAG('l', 'f', 'b', 'd'));
+ feature_sets.insert("standard_ligatures", HB_TAG('l', 'i', 'g', 'a'));
+ feature_sets.insert("leading_jamo_forms", HB_TAG('l', 'j', 'm', 'o'));
+ feature_sets.insert("lining_figures", HB_TAG('l', 'n', 'u', 'm'));
+ feature_sets.insert("localized_forms", HB_TAG('l', 'o', 'c', 'l'));
+ feature_sets.insert("left_to_right_alternates", HB_TAG('l', 't', 'r', 'a'));
+ feature_sets.insert("left_to_right_mirrored_forms", HB_TAG('l', 't', 'r', 'm'));
+ feature_sets.insert("mark_positioning", HB_TAG('m', 'a', 'r', 'k'));
+ feature_sets.insert("medial_forms_2", HB_TAG('m', 'e', 'd', '2'));
+ feature_sets.insert("medial_forms", HB_TAG('m', 'e', 'd', 'i'));
+ feature_sets.insert("mathematical_greek", HB_TAG('m', 'g', 'r', 'k'));
+ feature_sets.insert("mark_to_mark_positioning", HB_TAG('m', 'k', 'm', 'k'));
+ feature_sets.insert("mark_positioning_via_substitution", HB_TAG('m', 's', 'e', 't'));
+ feature_sets.insert("alternate_annotation_forms", HB_TAG('n', 'a', 'l', 't'));
+ feature_sets.insert("nlc_kanji_forms", HB_TAG('n', 'l', 'c', 'k'));
+ feature_sets.insert("nukta_forms", HB_TAG('n', 'u', 'k', 't'));
+ feature_sets.insert("numerators", HB_TAG('n', 'u', 'm', 'r'));
+ feature_sets.insert("oldstyle_figures", HB_TAG('o', 'n', 'u', 'm'));
+ feature_sets.insert("optical_bounds", HB_TAG('o', 'p', 'b', 'd'));
+ feature_sets.insert("ordinals", HB_TAG('o', 'r', 'd', 'n'));
+ feature_sets.insert("ornaments", HB_TAG('o', 'r', 'n', 'm'));
+ feature_sets.insert("proportional_alternate_widths", HB_TAG('p', 'a', 'l', 't'));
+ feature_sets.insert("petite_capitals", HB_TAG('p', 'c', 'a', 'p'));
+ feature_sets.insert("proportional_kana", HB_TAG('p', 'k', 'n', 'a'));
+ feature_sets.insert("proportional_figures", HB_TAG('p', 'n', 'u', 'm'));
+ feature_sets.insert("pre_base_forms", HB_TAG('p', 'r', 'e', 'f'));
+ feature_sets.insert("pre_base_substitutions", HB_TAG('p', 'r', 'e', 's'));
+ feature_sets.insert("post_base_forms", HB_TAG('p', 's', 't', 'f'));
+ feature_sets.insert("post_base_substitutions", HB_TAG('p', 's', 't', 's'));
+ feature_sets.insert("proportional_widths", HB_TAG('p', 'w', 'i', 'd'));
+ feature_sets.insert("quarter_widths", HB_TAG('q', 'w', 'i', 'd'));
+ feature_sets.insert("randomize", HB_TAG('r', 'a', 'n', 'd'));
+ feature_sets.insert("required_contextual_alternates", HB_TAG('r', 'c', 'l', 't'));
+ feature_sets.insert("rakar_forms", HB_TAG('r', 'k', 'r', 'f'));
+ feature_sets.insert("required_ligatures", HB_TAG('r', 'l', 'i', 'g'));
+ feature_sets.insert("reph_forms", HB_TAG('r', 'p', 'h', 'f'));
+ feature_sets.insert("right_bounds", HB_TAG('r', 't', 'b', 'd'));
+ feature_sets.insert("right_to_left_alternates", HB_TAG('r', 't', 'l', 'a'));
+ feature_sets.insert("right_to_left_mirrored_forms", HB_TAG('r', 't', 'l', 'm'));
+ feature_sets.insert("ruby_notation_forms", HB_TAG('r', 'u', 'b', 'y'));
+ feature_sets.insert("required_variation_alternates", HB_TAG('r', 'v', 'r', 'n'));
+ feature_sets.insert("stylistic_alternates", HB_TAG('s', 'a', 'l', 't'));
+ feature_sets.insert("scientific_inferiors", HB_TAG('s', 'i', 'n', 'f'));
+ feature_sets.insert("optical_size", HB_TAG('s', 'i', 'z', 'e'));
+ feature_sets.insert("small_capitals", HB_TAG('s', 'm', 'c', 'p'));
+ feature_sets.insert("simplified_forms", HB_TAG('s', 'm', 'p', 'l'));
+ feature_sets.insert("stylistic_set_01", HB_TAG('s', 's', '0', '1'));
+ feature_sets.insert("stylistic_set_02", HB_TAG('s', 's', '0', '2'));
+ feature_sets.insert("stylistic_set_03", HB_TAG('s', 's', '0', '3'));
+ feature_sets.insert("stylistic_set_04", HB_TAG('s', 's', '0', '4'));
+ feature_sets.insert("stylistic_set_05", HB_TAG('s', 's', '0', '5'));
+ feature_sets.insert("stylistic_set_06", HB_TAG('s', 's', '0', '6'));
+ feature_sets.insert("stylistic_set_07", HB_TAG('s', 's', '0', '7'));
+ feature_sets.insert("stylistic_set_08", HB_TAG('s', 's', '0', '8'));
+ feature_sets.insert("stylistic_set_09", HB_TAG('s', 's', '0', '9'));
+ feature_sets.insert("stylistic_set_10", HB_TAG('s', 's', '1', '0'));
+ feature_sets.insert("stylistic_set_11", HB_TAG('s', 's', '1', '1'));
+ feature_sets.insert("stylistic_set_12", HB_TAG('s', 's', '1', '2'));
+ feature_sets.insert("stylistic_set_13", HB_TAG('s', 's', '1', '3'));
+ feature_sets.insert("stylistic_set_14", HB_TAG('s', 's', '1', '4'));
+ feature_sets.insert("stylistic_set_15", HB_TAG('s', 's', '1', '5'));
+ feature_sets.insert("stylistic_set_16", HB_TAG('s', 's', '1', '6'));
+ feature_sets.insert("stylistic_set_17", HB_TAG('s', 's', '1', '7'));
+ feature_sets.insert("stylistic_set_18", HB_TAG('s', 's', '1', '8'));
+ feature_sets.insert("stylistic_set_19", HB_TAG('s', 's', '1', '9'));
+ feature_sets.insert("stylistic_set_20", HB_TAG('s', 's', '2', '0'));
+ feature_sets.insert("math_script_style_alternates", HB_TAG('s', 's', 't', 'y'));
+ feature_sets.insert("stretching_glyph_decomposition", HB_TAG('s', 't', 'c', 'h'));
+ feature_sets.insert("subscript", HB_TAG('s', 'u', 'b', 's'));
+ feature_sets.insert("superscript", HB_TAG('s', 'u', 'p', 's'));
+ feature_sets.insert("swash", HB_TAG('s', 'w', 's', 'h'));
+ feature_sets.insert("titling", HB_TAG('t', 'i', 't', 'l'));
+ feature_sets.insert("trailing_jamo_forms", HB_TAG('t', 'j', 'm', 'o'));
+ feature_sets.insert("traditional_name_forms", HB_TAG('t', 'n', 'a', 'm'));
+ feature_sets.insert("tabular_figures", HB_TAG('t', 'n', 'u', 'm'));
+ feature_sets.insert("traditional_forms", HB_TAG('t', 'r', 'a', 'd'));
+ feature_sets.insert("third_widths", HB_TAG('t', 'w', 'i', 'd'));
+ feature_sets.insert("unicase", HB_TAG('u', 'n', 'i', 'c'));
+ feature_sets.insert("alternate_vertical_metrics", HB_TAG('v', 'a', 'l', 't'));
+ feature_sets.insert("vattu_variants", HB_TAG('v', 'a', 't', 'u'));
+ feature_sets.insert("vertical_writing", HB_TAG('v', 'e', 'r', 't'));
+ feature_sets.insert("alternate_vertical_half_metrics", HB_TAG('v', 'h', 'a', 'l'));
+ feature_sets.insert("vowel_jamo_forms", HB_TAG('v', 'j', 'm', 'o'));
+ feature_sets.insert("vertical_kana_alternates", HB_TAG('v', 'k', 'n', 'a'));
+ feature_sets.insert("vertical_kerning", HB_TAG('v', 'k', 'r', 'n'));
+ feature_sets.insert("proportional_alternate_vertical_metrics", HB_TAG('v', 'p', 'a', 'l'));
+ feature_sets.insert("vertical_alternates_and_rotation", HB_TAG('v', 'r', 't', '2'));
+ feature_sets.insert("vertical_alternates_for_rotation", HB_TAG('v', 'r', 't', 'r'));
+ feature_sets.insert("slashed_zero", HB_TAG('z', 'e', 'r', 'o'));
+ // Registered OpenType variation tag.
+ feature_sets.insert("italic", HB_TAG('i', 't', 'a', 'l'));
+ feature_sets.insert("optical_size", HB_TAG('o', 'p', 's', 'z'));
+ feature_sets.insert("slant", HB_TAG('s', 'l', 'n', 't'));
+ feature_sets.insert("width", HB_TAG('w', 'd', 't', 'h'));
+ feature_sets.insert("weight", HB_TAG('w', 'g', 'h', 't'));
+}
int32_t TextServerAdvanced::name_to_tag(const String &p_name) const {
- for (int i = 0; feature_set[i].tag != 0; i++) {
- if (feature_set[i].name == p_name) {
- return feature_set[i].tag;
- }
+ if (feature_sets.has(p_name)) {
+ return feature_sets[p_name];
}
// No readable name, use tag string.
@@ -707,9 +701,9 @@ int32_t TextServerAdvanced::name_to_tag(const String &p_name) const {
}
String TextServerAdvanced::tag_to_name(int32_t p_tag) const {
- for (int i = 0; feature_set[i].tag != 0; i++) {
- if (feature_set[i].tag == p_tag) {
- return feature_set[i].name;
+ for (const KeyValue<StringName, int32_t> &E : feature_sets) {
+ if (E.value == p_tag) {
+ return E.key;
}
}
@@ -4633,30 +4627,76 @@ real_t TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) con
}
struct num_system_data {
- String lang;
+ Set<String> lang;
String digits;
String percent_sign;
String exp;
};
static num_system_data num_systems[]{
- { "ar,ar_AR,ar_BH,ar_DJ,ar_EG,ar_ER,ar_IL,ar_IQ,ar_JO,ar_KM,ar_KW,ar_LB,ar_MR,ar_OM,ar_PS,ar_QA,ar_SA,ar_SD,ar_SO,ar_SS,ar_SY,ar_TD,ar_YE", U"٠١٢٣٤٥٦٧٨٩٫", U"٪", U"اس" },
- { "fa,ks,pa_Arab,ps,ug,ur_IN,ur,uz_Arab", U"۰۱۲۳۴۵۶۷۸۹٫", U"٪", U"اس" },
- { "as,bn,mni", U"০১২৩৪৫৬৭৮৯.", U"%", U"e" },
- { "mr,ne", U"०१२३४५६७८९.", U"%", U"e" },
- { "dz", U"༠༡༢༣༤༥༦༧༨༩.", U"%", U"e" },
- { "sat", U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙.", U"%", U"e" },
- { "my", U"၀၁၂၃၄၅၆၇၈၉.", U"%", U"e" },
- { String(), String(), String(), String() },
+ { Set<String>(), U"٠١٢٣٤٥٦٧٨٩٫", U"٪", U"اس" },
+ { Set<String>(), U"۰۱۲۳۴۵۶۷۸۹٫", U"٪", U"اس" },
+ { Set<String>(), U"০১২৩৪৫৬৭৮৯.", U"%", U"e" },
+ { Set<String>(), U"०१२३४५६७८९.", U"%", U"e" },
+ { Set<String>(), U"༠༡༢༣༤༥༦༧༨༩.", U"%", U"e" },
+ { Set<String>(), U"᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙.", U"%", U"e" },
+ { Set<String>(), U"၀၁၂၃၄၅၆၇၈၉.", U"%", U"e" },
+ { Set<String>(), String(), String(), String() },
};
+static void _insert_num_systems_lang() {
+ num_systems[0].lang.insert(StringName("ar"));
+ num_systems[0].lang.insert(StringName("ar_AR"));
+ num_systems[0].lang.insert(StringName("ar_BH"));
+ num_systems[0].lang.insert(StringName("ar_DJ"));
+ num_systems[0].lang.insert(StringName("ar_EG"));
+ num_systems[0].lang.insert(StringName("ar_ER"));
+ num_systems[0].lang.insert(StringName("ar_IL"));
+ num_systems[0].lang.insert(StringName("ar_IQ"));
+ num_systems[0].lang.insert(StringName("ar_JO"));
+ num_systems[0].lang.insert(StringName("ar_KM"));
+ num_systems[0].lang.insert(StringName("ar_KW"));
+ num_systems[0].lang.insert(StringName("ar_LB"));
+ num_systems[0].lang.insert(StringName("ar_MR"));
+ num_systems[0].lang.insert(StringName("ar_OM"));
+ num_systems[0].lang.insert(StringName("ar_PS"));
+ num_systems[0].lang.insert(StringName("ar_QA"));
+ num_systems[0].lang.insert(StringName("ar_SA"));
+ num_systems[0].lang.insert(StringName("ar_SD"));
+ num_systems[0].lang.insert(StringName("ar_SO"));
+ num_systems[0].lang.insert(StringName("ar_SS"));
+ num_systems[0].lang.insert(StringName("ar_SY"));
+ num_systems[0].lang.insert(StringName("ar_TD"));
+ num_systems[0].lang.insert(StringName("ar_YE"));
+
+ num_systems[1].lang.insert(StringName("fa"));
+ num_systems[1].lang.insert(StringName("ks"));
+ num_systems[1].lang.insert(StringName("pa_Arab"));
+ num_systems[1].lang.insert(StringName("ug"));
+ num_systems[1].lang.insert(StringName("ur_IN"));
+ num_systems[1].lang.insert(StringName("ur"));
+ num_systems[1].lang.insert(StringName("uz_Arab"));
+
+ num_systems[2].lang.insert(StringName("as"));
+ num_systems[2].lang.insert(StringName("bn"));
+ num_systems[2].lang.insert(StringName("mni"));
+
+ num_systems[3].lang.insert(StringName("mr"));
+ num_systems[3].lang.insert(StringName("ne"));
+
+ num_systems[4].lang.insert(StringName("dz"));
+
+ num_systems[5].lang.insert(StringName("sat"));
+
+ num_systems[6].lang.insert(StringName("my"));
+}
+
String TextServerAdvanced::format_number(const String &p_string, const String &p_language) const {
- String lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
- for (int i = 0; num_systems[i].lang != String(); i++) {
- Vector<String> langs = num_systems[i].lang.split(",");
- if (langs.has(lang)) {
+ for (int i = 0; num_systems[i].lang.size() != 0; i++) {
+ if (num_systems[i].lang.has(lang)) {
if (num_systems[i].digits == String()) {
return p_string;
}
@@ -4677,12 +4717,11 @@ String TextServerAdvanced::format_number(const String &p_string, const String &p
}
String TextServerAdvanced::parse_number(const String &p_string, const String &p_language) const {
- String lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
- for (int i = 0; num_systems[i].lang != String(); i++) {
- Vector<String> langs = num_systems[i].lang.split(",");
- if (langs.has(lang)) {
+ for (int i = 0; num_systems[i].lang.size() != 0; i++) {
+ if (num_systems[i].lang.has(lang)) {
if (num_systems[i].digits == String()) {
return p_string;
}
@@ -4706,11 +4745,10 @@ String TextServerAdvanced::parse_number(const String &p_string, const String &p_
}
String TextServerAdvanced::percent_sign(const String &p_language) const {
- String lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
+ const StringName lang = (p_language == "") ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
- for (int i = 0; num_systems[i].lang != String(); i++) {
- Vector<String> langs = num_systems[i].lang.split(",");
- if (langs.has(lang)) {
+ for (int i = 0; num_systems[i].lang.size() != 0; i++) {
+ if (num_systems[i].lang.has(lang)) {
if (num_systems[i].percent_sign == String()) {
return "%";
}
@@ -4730,6 +4768,8 @@ void TextServerAdvanced::register_server() {
}
TextServerAdvanced::TextServerAdvanced() {
+ _insert_num_systems_lang();
+ _insert_feature_sets();
hb_bmp_create_font_funcs();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index b9e9a4d450..f64c07df76 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -37,6 +37,7 @@
#include "core/object/script_language.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
+#include "core/string/string_builder.h"
#include "core/string/translation.h"
#include "scene/main/window.h"
@@ -78,7 +79,11 @@ void TextEdit::Text::set_font_size(int p_font_size) {
}
void TextEdit::Text::set_tab_size(int p_tab_size) {
+ if (tab_size == p_tab_size) {
+ return;
+ }
tab_size = p_tab_size;
+ tab_size_dirty = true;
}
int TextEdit::Text::get_tab_size() const {
@@ -118,10 +123,8 @@ int TextEdit::Text::get_line_width(int p_line, int p_wrap_index) const {
return text[p_line].data_buf->get_size().x;
}
-int TextEdit::Text::get_line_height(int p_line, int p_wrap_index) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), 0);
-
- return text[p_line].data_buf->get_line_size(p_wrap_index).y;
+int TextEdit::Text::get_line_height() const {
+ return line_height;
}
void TextEdit::Text::set_width(float p_width) {
@@ -153,6 +156,36 @@ _FORCE_INLINE_ const String &TextEdit::Text::operator[](int p_line) const {
return text[p_line].data;
}
+void TextEdit::Text::_calculate_line_height() {
+ int height = 0;
+ for (int i = 0; i < text.size(); i++) {
+ // Found another line with the same height...nothing to update.
+ if (text[i].height == line_height) {
+ height = line_height;
+ break;
+ }
+ height = MAX(height, text[i].height);
+ }
+ line_height = height;
+}
+
+void TextEdit::Text::_calculate_max_line_width() {
+ int width = 0;
+ for (int i = 0; i < text.size(); i++) {
+ if (is_hidden(i)) {
+ continue;
+ }
+
+ // Found another line with the same width...nothing to update.
+ if (text[i].width == max_width) {
+ width = max_width;
+ break;
+ }
+ width = MAX(width, text[i].width);
+ }
+ max_width = width;
+}
+
void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Vector<Vector2i> &p_bidi_override) {
ERR_FAIL_INDEX(p_line, text.size());
@@ -182,17 +215,54 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_
tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
text.write[p_line].data_buf->tab_align(tabs);
}
+
+ // Update height.
+ const int old_height = text.write[p_line].height;
+ const int wrap_amount = get_line_wrap_amount(p_line);
+ int height = font->get_height(font_size);
+ for (int i = 0; i <= wrap_amount; i++) {
+ height = MAX(height, text[p_line].data_buf->get_line_size(i).y);
+ }
+ text.write[p_line].height = height;
+
+ // If this line has shrunk, this may no longer the the tallest line.
+ if (old_height == line_height && height < line_height) {
+ _calculate_line_height();
+ } else {
+ line_height = MAX(height, line_height);
+ }
+
+ // Update width.
+ const int old_width = text.write[p_line].width;
+ int width = get_line_width(p_line);
+ text.write[p_line].width = width;
+
+ // If this line has shrunk, this may no longer the the longest line.
+ if (old_width == max_width && width < max_width) {
+ _calculate_max_line_width();
+ } else if (!is_hidden(p_line)) {
+ max_width = MAX(width, max_width);
+ }
}
void TextEdit::Text::invalidate_all_lines() {
for (int i = 0; i < text.size(); i++) {
text.write[i].data_buf->set_width(width);
- if (tab_size > 0) {
- Vector<float> tabs;
- tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
- text.write[i].data_buf->tab_align(tabs);
+ if (tab_size_dirty) {
+ if (tab_size > 0) {
+ Vector<float> tabs;
+ tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
+ text.write[i].data_buf->tab_align(tabs);
+ }
+ // Tabs have changes, force width update.
+ text.write[i].width = get_line_width(i);
}
}
+
+ if (tab_size_dirty) {
+ _calculate_max_line_width();
+ tab_size_dirty = false;
+ }
}
void TextEdit::Text::invalidate_all() {
@@ -211,16 +281,8 @@ void TextEdit::Text::clear() {
insert(0, "", Vector<Vector2i>());
}
-int TextEdit::Text::get_max_width(bool p_exclude_hidden) const {
- // Quite some work, but should be fast enough.
-
- int max = 0;
- for (int i = 0; i < text.size(); i++) {
- if (!p_exclude_hidden || !is_hidden(i)) {
- max = MAX(max, get_line_width(i));
- }
- }
- return max;
+int TextEdit::Text::get_max_width() const {
+ return max_width;
}
void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override) {
@@ -243,7 +305,20 @@ void TextEdit::Text::insert(int p_at, const String &p_text, const Vector<Vector2
}
void TextEdit::Text::remove(int p_at) {
+ int height = text[p_at].height;
+ int width = text[p_at].width;
+
text.remove(p_at);
+
+ // If this is the tallest line, we need to get the next tallest.
+ if (height == line_height) {
+ _calculate_line_height();
+ }
+
+ // If this is the longest line, we need to get the next longest.
+ if (width == max_width) {
+ _calculate_max_line_width();
+ }
}
void TextEdit::Text::add_gutter(int p_at) {
@@ -293,7 +368,7 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
call_deferred(SNAME("_update_scrollbars"));
- call_deferred(SNAME("_update_wrap_at"));
+ call_deferred(SNAME("_update_wrap_at_column"));
}
} break;
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
@@ -644,8 +719,9 @@ void TextEdit::_notification(int p_what) {
int characters = 0;
int tabs = 0;
for (int j = 0; j < str.length(); j++) {
- if (color_map.has(last_wrap_column + j)) {
- current_color = color_map[last_wrap_column + j].get("color");
+ const Variant *color_data = color_map.getptr(last_wrap_column + j);
+ if (color_data != nullptr) {
+ current_color = (color_data->operator Dictionary()).get("color", font_color);
if (!editable) {
current_color.a = font_readonly_color.a;
}
@@ -1023,8 +1099,9 @@ void TextEdit::_notification(int p_what) {
char_ofs = 0;
}
for (int j = 0; j < gl_size; j++) {
- if (color_map.has(glyphs[j].start)) {
- current_color = color_map[glyphs[j].start].get("color");
+ const Variant *color_data = color_map.getptr(glyphs[j].start);
+ if (color_data != nullptr) {
+ current_color = (color_data->operator Dictionary()).get("color", font_color);
if (!editable && current_color.a > font_readonly_color.a) {
current_color.a = font_readonly_color.a;
}
@@ -2548,15 +2625,15 @@ void TextEdit::set_text(const String &p_text) {
}
String TextEdit::get_text() const {
- String longthing;
- int len = text.size();
- for (int i = 0; i < len; i++) {
- longthing += text[i];
- if (i != len - 1) {
- longthing += "\n";
+ StringBuilder ret_text;
+ const int text_size = text.size();
+ for (int i = 0; i < text_size; i++) {
+ ret_text += text[i];
+ if (i != text_size - 1) {
+ ret_text += "\n";
}
}
- return longthing;
+ return ret_text.as_string();
}
int TextEdit::get_line_count() const {
@@ -2592,13 +2669,7 @@ int TextEdit::get_line_width(int p_line, int p_wrap_index) const {
}
int TextEdit::get_line_height() const {
- int height = font->get_height(font_size);
- for (int i = 0; i < text.size(); i++) {
- for (int j = 0; j <= text.get_line_wrap_amount(i); j++) {
- height = MAX(height, text.get_line_height(i, j));
- }
- }
- return height + line_spacing;
+ return text.get_line_height() + line_spacing;
}
int TextEdit::get_indent_level(int p_line) const {
@@ -4151,6 +4222,9 @@ TextEdit::GutterType TextEdit::get_gutter_type(int p_gutter) const {
void TextEdit::set_gutter_width(int p_gutter, int p_width) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
+ if (gutters[p_gutter].width == p_width) {
+ return;
+ }
gutters.write[p_gutter].width = p_width;
_update_gutter_width();
}
@@ -4166,6 +4240,9 @@ int TextEdit::get_total_gutter_width() const {
void TextEdit::set_gutter_draw(int p_gutter, bool p_draw) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
+ if (gutters[p_gutter].draw == p_draw) {
+ return;
+ }
gutters.write[p_gutter].draw = p_draw;
_update_gutter_width();
}
@@ -5458,7 +5535,7 @@ void TextEdit::_update_scrollbars() {
}
int visible_width = size.width - style_normal->get_minimum_size().width;
- int total_width = text.get_max_width(true) + vmin.x + gutters_width + gutter_padding;
+ int total_width = text.get_max_width() + vmin.x + gutters_width + gutter_padding;
if (draw_minimap) {
total_width += minimap_width;
@@ -5910,8 +5987,6 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
text.set_hidden(p_line, false);
}
- text.invalidate_cache(p_line);
-
r_end_line = p_line + substrings.size() - 1;
r_end_column = text[r_end_line].length() - postinsert_text.length();
@@ -5968,8 +6043,6 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
}
text.set(p_from_line, pre_text + post_text, structured_text_parser(st_parser, st_args, pre_text + post_text));
- text.invalidate_cache(p_from_line);
-
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree()) {
MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
@@ -5986,7 +6059,6 @@ TextEdit::TextEdit() {
set_default_cursor_shape(CURSOR_IBEAM);
text.set_tab_size(text.get_tab_size());
- text.clear();
h_scroll = memnew(HScrollBar);
v_scroll = memnew(VScrollBar);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 07999c2442..e996bba983 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -144,6 +144,8 @@ private:
Color background_color = Color(0, 0, 0, 0);
bool hidden = false;
+ int height = 0;
+ int width = 0;
Line() {
data_buf.instantiate();
@@ -152,6 +154,7 @@ private:
private:
bool is_dirty = false;
+ bool tab_size_dirty = false;
mutable Vector<Line> text;
Ref<Font> font;
@@ -162,11 +165,16 @@ private:
TextServer::Direction direction = TextServer::DIRECTION_AUTO;
bool draw_control_chars = false;
+ int line_height = -1;
+ int max_width = -1;
int width = -1;
int tab_size = 4;
int gutter_count = 0;
+ void _calculate_line_height();
+ void _calculate_max_line_width();
+
public:
void set_tab_size(int p_tab_size);
int get_tab_size() const;
@@ -176,9 +184,9 @@ private:
void set_direction_and_language(TextServer::Direction p_direction, const String &p_language);
void set_draw_control_chars(bool p_draw_control_chars);
- int get_line_height(int p_line, int p_wrap_index) const;
+ int get_line_height() const;
int get_line_width(int p_line, int p_wrap_index = -1) const;
- int get_max_width(bool p_exclude_hidden = false) const;
+ int get_max_width() const;
void set_width(float p_width);
int get_line_wrap_amount(int p_line) const;
@@ -187,7 +195,14 @@ private:
const Ref<TextParagraph> get_line_data(int p_line) const;
void set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override);
- void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; }
+ void set_hidden(int p_line, bool p_hidden) {
+ text.write[p_line].hidden = p_hidden;
+ if (!p_hidden && text[p_line].width > max_width) {
+ max_width = text[p_line].width;
+ } else if (p_hidden && text[p_line].width == max_width) {
+ _calculate_max_line_width();
+ }
+ }
bool is_hidden(int p_line) const { return text[p_line].hidden; }
void insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override);
void remove(int p_at);