From fa304b51303c21d27a89cb6b83578560843b1327 Mon Sep 17 00:00:00 2001 From: Marius Hanl Date: Sat, 12 Nov 2022 21:02:54 +0100 Subject: [PATCH] Fix RichTextLabel: BBCode [color] tags are not counting in font char spacing Each BBCode tag is drawn individually, so we have to add the character spacing manually. --- scene/gui/rich_text_label.cpp | 27 +++++++++++++++++++-------- scene/resources/dynamic_font.cpp | 4 ++++ scene/resources/dynamic_font.h | 2 ++ scene/resources/font.h | 4 ++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index f38f266c7ee..260e1c980d3 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -361,6 +361,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int ascent = font->get_ascent(); int descent = font->get_descent(); + // Each BBCode tag is drawn individually, so we have to add the character spacing manually. + int spacing_char = 0; + if (visible_characters != 0) { + spacing_char = font->get_spacing_char(); + } + Color color; Color font_color_shadow; bool underline = false; @@ -446,7 +452,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & end++; } CHECK_HEIGHT(fh); - ENSURE_WIDTH(w); + ENSURE_WIDTH(w + spacing_char); + + // ENSURE_WIDTH may create a new line. In this case we are at the beginning and don't want to shift the initial text. + if (line_is_blank) { + spacing_char = 0; + } line_ascent = MAX(line_ascent, ascent); line_descent = MAX(line_descent, descent); @@ -600,21 +611,21 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & const Color char_color = selected && override_selected_font_color ? selection_fg : fx_color; const Color shadow_color = p_font_color_shadow * Color(1, 1, 1, char_color.a); + const Point2 base_pos = p_ofs + Point2(align_ofs + pofs + spacing_char, y + lh - line_descent); if (shadow_color.a > 0) { - const Point2 shadow_base_pos = p_ofs + Point2(align_ofs + pofs, y + lh - line_descent); - font->draw_char(ci, shadow_base_pos + shadow_ofs + fx_offset, fx_char, c[i + 1], shadow_color); + font->draw_char(ci, base_pos + shadow_ofs + fx_offset, fx_char, c[i + 1], shadow_color); if (p_shadow_as_outline) { - font->draw_char(ci, shadow_base_pos + Vector2(-shadow_ofs.x, shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); - font->draw_char(ci, shadow_base_pos + Vector2(shadow_ofs.x, -shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); - font->draw_char(ci, shadow_base_pos + Vector2(-shadow_ofs.x, -shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); + font->draw_char(ci, base_pos + Vector2(-shadow_ofs.x, shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); + font->draw_char(ci, base_pos + Vector2(shadow_ofs.x, -shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); + font->draw_char(ci, base_pos + Vector2(-shadow_ofs.x, -shadow_ofs.y) + fx_offset, fx_char, c[i + 1], shadow_color); } } if (selected) { - drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent), fx_char, c[i + 1], char_color); + drawer.draw_char(ci, base_pos, fx_char, c[i + 1], char_color); } else { - cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], char_color); + cw = drawer.draw_char(ci, base_pos + fx_offset, fx_char, c[i + 1], char_color); } } else if (previously_visible && c[i] != '\t') { backtrack += current_char_width; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 4bf2074501d..e78443019c0 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -1028,6 +1028,10 @@ int DynamicFont::get_spacing(int p_type) const { return 0; } +int DynamicFont::get_spacing_char() const { + return spacing_char; +} + void DynamicFont::set_spacing(int p_type, int p_value) { if (p_type == SPACING_TOP) { spacing_top = p_value; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 63a7da62b11..8a6381de280 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -352,6 +352,8 @@ public: virtual float get_ascent() const; virtual float get_descent() const; + virtual int get_spacing_char() const; + virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const; String get_available_chars() const; diff --git a/scene/resources/font.h b/scene/resources/font.h index abd6bc0241b..0e790455cb3 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -52,6 +52,7 @@ public: virtual float get_ascent() const = 0; virtual float get_descent() const = 0; + virtual int get_spacing_char() const = 0; virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0; Size2 get_string_size(const String &p_string) const; @@ -179,6 +180,9 @@ public: void set_ascent(float p_ascent); float get_ascent() const; float get_descent() const; + int get_spacing_char() const { + return 0; + } void add_texture(const Ref &p_texture); void add_char(int32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);