Merge pull request #68576 from Maran23/rich-text-label-bbcode-color-tag-fix

[3.x] Fix RichTextLabel: BBCode [color] tags are not counting in font char spacing
This commit is contained in:
Rémi Verschelde 2023-02-13 13:08:13 +01:00
commit 48217503c5
No known key found for this signature in database
GPG Key ID: C3336907360768E1
4 changed files with 29 additions and 8 deletions

View File

@ -361,6 +361,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int ascent = font->get_ascent(); int ascent = font->get_ascent();
int descent = font->get_descent(); 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 color;
Color font_color_shadow; Color font_color_shadow;
bool underline = false; bool underline = false;
@ -446,7 +452,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
end++; end++;
} }
CHECK_HEIGHT(fh); 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_ascent = MAX(line_ascent, ascent);
line_descent = MAX(line_descent, descent); 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 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 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) { if (shadow_color.a > 0) {
const Point2 shadow_base_pos = p_ofs + Point2(align_ofs + pofs, y + lh - line_descent); font->draw_char(ci, base_pos + shadow_ofs + fx_offset, fx_char, c[i + 1], shadow_color);
font->draw_char(ci, shadow_base_pos + shadow_ofs + fx_offset, fx_char, c[i + 1], shadow_color);
if (p_shadow_as_outline) { 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, 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, 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);
} }
} }
if (selected) { 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 { } 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') { } else if (previously_visible && c[i] != '\t') {
backtrack += current_char_width; backtrack += current_char_width;

View File

@ -1028,6 +1028,10 @@ int DynamicFont::get_spacing(int p_type) const {
return 0; return 0;
} }
int DynamicFont::get_spacing_char() const {
return spacing_char;
}
void DynamicFont::set_spacing(int p_type, int p_value) { void DynamicFont::set_spacing(int p_type, int p_value) {
if (p_type == SPACING_TOP) { if (p_type == SPACING_TOP) {
spacing_top = p_value; spacing_top = p_value;

View File

@ -352,6 +352,8 @@ public:
virtual float get_ascent() const; virtual float get_ascent() const;
virtual float get_descent() 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; virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const;
String get_available_chars() const; String get_available_chars() const;

View File

@ -52,6 +52,7 @@ public:
virtual float get_ascent() const = 0; virtual float get_ascent() const = 0;
virtual float get_descent() 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; virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0;
Size2 get_string_size(const String &p_string) const; Size2 get_string_size(const String &p_string) const;
@ -179,6 +180,9 @@ public:
void set_ascent(float p_ascent); void set_ascent(float p_ascent);
float get_ascent() const; float get_ascent() const;
float get_descent() const; float get_descent() const;
int get_spacing_char() const {
return 0;
}
void add_texture(const Ref<Texture> &p_texture); void add_texture(const Ref<Texture> &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); void add_char(int32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);