Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RTL] Parse "\r\n" as a single paragraph break, add some documentation notes. #99668

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/classes/RichTextLabel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</brief_description>
<description>
A control for displaying text that can contain custom fonts, images, and basic formatting. [RichTextLabel] manages these as an internal tag stack. It also adapts itself to given width/heights.
[b]Note:[/b] [method newline], [method push_paragraph], [code]"\n"[/code], [code]"\r\n"[/code], [code]p[/code] tag, and alignment tags start a new paragraph. Each paragraph is processed independently, in its own BiDi context. If you want to force line wrapping within paragraph, any other line breaking character can be used, e.g., Form Feed (U+000C), Next Line (U+0085), Line Separator (U+2028).
[b]Note:[/b] Assignments to [member text] clear the tag stack and reconstruct it from the property's contents. Any edits made to [member text] will erase previous edits made from other manual sources such as [method append_text] and the [code]push_*[/code] / [method pop] methods.
[b]Note:[/b] RichTextLabel doesn't support entangled BBCode tags. For example, instead of using [code skip-lint][b]bold[i]bold italic[/b]italic[/i][/code], use [code skip-lint][b]bold[i]bold italic[/i][/b][i]italic[/i][/code].
[b]Note:[/b] [code]push_*/pop_*[/code] functions won't affect BBCode.
Expand Down Expand Up @@ -99,6 +100,7 @@
<return type="int" />
<description>
Returns the total number of lines in the text. Wrapped text is counted as multiple lines.
[b]Note:[/b] If [member visible_characters_behavior] is set to [constant TextServer.VC_CHARS_BEFORE_SHAPING] only visible wrapped lines are counted.
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_finished] or [signal finished] to determine whether document is fully loaded.
</description>
</method>
Expand Down
1 change: 1 addition & 0 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1914,6 +1914,7 @@
</constant>
<constant name="VC_CHARS_BEFORE_SHAPING" value="0" enum="VisibleCharactersBehavior">
Trims text before the shaping. e.g, increasing [member Label.visible_characters] or [member RichTextLabel.visible_characters] value is visually identical to typing the text.
[b]Note:[/b] In this mode, trimmed text is not processed at all. It is not accounted in line breaking and size calculations.
</constant>
<constant name="VC_CHARS_AFTER_SHAPING" value="1" enum="VisibleCharactersBehavior">
Displays glyphs that are mapped to the first [member Label.visible_characters] or [member RichTextLabel.visible_characters] characters from the beginning of the text.
Expand Down
51 changes: 27 additions & 24 deletions scene/gui/rich_text_label.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3055,21 +3055,22 @@ void RichTextLabel::add_text(const String &p_text) {
}

int pos = 0;
String t = p_text.replace("\r\n", "\n");

while (pos < p_text.length()) {
int end = p_text.find_char('\n', pos);
while (pos < t.length()) {
int end = t.find_char('\n', pos);
String line;
bool eol = false;
if (end == -1) {
end = p_text.length();
end = t.length();
} else {
eol = true;
}

if (pos == 0 && end == p_text.length()) {
line = p_text;
if (pos == 0 && end == t.length()) {
line = t;
} else {
line = p_text.substr(pos, end - pos);
line = t.substr(pos, end - pos);
}

if (line.length() > 0) {
Expand Down Expand Up @@ -3501,7 +3502,7 @@ void RichTextLabel::push_dropcap(const String &p_string, const Ref<Font> &p_font
ItemDropcap *item = memnew(ItemDropcap);
item->owner = get_instance_id();
item->rid = items.make_rid(item);
item->text = p_string;
item->text = p_string.replace("\r\n", "\n");
item->font = p_font;
item->font_size = p_size;
item->color = p_color;
Expand Down Expand Up @@ -4213,21 +4214,23 @@ void RichTextLabel::append_text(const String &p_bbcode) {
bool after_list_open_tag = false;
bool after_list_close_tag = false;

while (pos <= p_bbcode.length()) {
int brk_pos = p_bbcode.find_char('[', pos);
String bbcode = p_bbcode.replace("\r\n", "\n");

while (pos <= bbcode.length()) {
int brk_pos = bbcode.find_char('[', pos);

if (brk_pos < 0) {
brk_pos = p_bbcode.length();
brk_pos = bbcode.length();
}

String txt = brk_pos > pos ? p_bbcode.substr(pos, brk_pos - pos) : "";
String txt = brk_pos > pos ? bbcode.substr(pos, brk_pos - pos) : "";

// Trim the first newline character, it may be added later as needed.
if (after_list_close_tag || after_list_open_tag) {
txt = txt.trim_prefix("\n");
}

if (brk_pos == p_bbcode.length()) {
if (brk_pos == bbcode.length()) {
// For tags that are not properly closed.
if (txt.is_empty() && after_list_open_tag) {
txt = "\n";
Expand All @@ -4239,16 +4242,16 @@ void RichTextLabel::append_text(const String &p_bbcode) {
break; //nothing else to add
}

int brk_end = _find_unquoted(p_bbcode, ']', brk_pos + 1);
int brk_end = _find_unquoted(bbcode, ']', brk_pos + 1);

if (brk_end == -1) {
//no close, add the rest
txt += p_bbcode.substr(brk_pos, p_bbcode.length() - brk_pos);
txt += bbcode.substr(brk_pos, bbcode.length() - brk_pos);
add_text(txt);
break;
}

String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
String tag = bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
Vector<String> split_tag_block = _split_unquoted(tag, ' ');

// Find optional parameters.
Expand Down Expand Up @@ -4706,11 +4709,11 @@ void RichTextLabel::append_text(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("p");
} else if (tag == "url") {
int end = p_bbcode.find_char('[', brk_end);
int end = bbcode.find_char('[', brk_end);
if (end == -1) {
end = p_bbcode.length();
end = bbcode.length();
}
String url = p_bbcode.substr(brk_end + 1, end - brk_end - 1).unquote();
String url = bbcode.substr(brk_end + 1, end - brk_end - 1).unquote();
push_meta(url, META_UNDERLINE_ALWAYS);

pos = brk_end + 1;
Expand Down Expand Up @@ -4774,12 +4777,12 @@ void RichTextLabel::append_text(const String &p_bbcode) {
outline_color = Color::from_string(outline_color_option->value, outline_color);
}

int end = p_bbcode.find_char('[', brk_end);
int end = bbcode.find_char('[', brk_end);
if (end == -1) {
end = p_bbcode.length();
end = bbcode.length();
}

String dc_txt = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
String dc_txt = bbcode.substr(brk_end + 1, end - brk_end - 1);

push_dropcap(dc_txt, f, fs, dropcap_margins, color, outline_size, outline_color);

Expand Down Expand Up @@ -4819,12 +4822,12 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}

int end = p_bbcode.find_char('[', brk_end);
int end = bbcode.find_char('[', brk_end);
if (end == -1) {
end = p_bbcode.length();
end = bbcode.length();
}

String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
String image = bbcode.substr(brk_end + 1, end - brk_end - 1);

Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
if (texture.is_valid()) {
Expand Down