diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index b951566707e..c41072b20cb 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -380,6 +380,13 @@ Adds a [code][font][/code] tag with an italics font to the tag stack. This is the same as adding an [code][i][/code] tag if not currently in a [code][b][/code] tag. + + + + + Adds language code used for text shaping algorithm and Open-Type font features. + + diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4780ce873cd..a802e626522 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2564,7 +2564,10 @@ String RichTextLabel::_find_language(Item *p_item) { Item *item = p_item; while (item) { - if (item->type == ITEM_PARAGRAPH) { + if (item->type == ITEM_LANGUAGE) { + ItemLanguage *p = static_cast(item); + return p->language; + } else if (item->type == ITEM_PARAGRAPH) { ItemParagraph *p = static_cast(item); return p->language; } @@ -3441,6 +3444,17 @@ void RichTextLabel::push_meta(const Variant &p_meta) { _add_item(item, true); } +void RichTextLabel::push_language(const String &p_language) { + _stop_thread(); + MutexLock data_lock(data_mutex); + + ERR_FAIL_COND(current->type == ITEM_TABLE); + ItemLanguage *item = memnew(ItemLanguage); + + item->language = p_language; + _add_item(item, true); +} + void RichTextLabel::push_hint(const String &p_string) { _stop_thread(); MutexLock data_lock(data_mutex); @@ -4222,6 +4236,11 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_indent(indent_level); pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag.begins_with("lang=")) { + String lang = tag.substr(5, tag.length()).unquote(); + push_language(lang); + pos = brk_end + 1; + tag_stack.push_front("lang"); } else if (tag == "p") { push_paragraph(HORIZONTAL_ALIGNMENT_LEFT); pos = brk_end + 1; @@ -5607,6 +5626,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize", "bullet"), &RichTextLabel::push_list, DEFVAL(String::utf8("•"))); ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta); ClassDB::bind_method(D_METHOD("push_hint", "description"), &RichTextLabel::push_hint); + ClassDB::bind_method(D_METHOD("push_language", "language"), &RichTextLabel::push_language); ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline); ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough); ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align", "align_to_row"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP), DEFVAL(-1)); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 0d0917a9d8c..a3230cf13c7 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -77,7 +77,8 @@ public: ITEM_HINT, ITEM_DROPCAP, ITEM_CUSTOMFX, - ITEM_CONTEXT + ITEM_CONTEXT, + ITEM_LANGUAGE, }; enum MenuItems { @@ -237,6 +238,11 @@ private: ItemHint() { type = ITEM_HINT; } }; + struct ItemLanguage : public Item { + String language; + ItemLanguage() { type = ITEM_LANGUAGE; } + }; + struct ItemParagraph : public Item { HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; String language; @@ -615,6 +621,7 @@ public: void push_outline_color(const Color &p_color); void push_underline(); void push_strikethrough(); + void push_language(const String &p_language); void push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", TextServer::StructuredTextParser p_st_parser = TextServer::STRUCTURED_TEXT_DEFAULT, BitField p_jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE, const PackedFloat32Array &p_tab_stops = PackedFloat32Array()); void push_indent(int p_level); void push_list(int p_level, ListType p_list, bool p_capitalize, const String &p_bullet = String::utf8("•"));