diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 9a9d09cac2..6df2b42f9f 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -392,14 +392,15 @@ inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_fo } } -inline void draw_glyph_shadow(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_shadow_color, int p_shadow_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { +inline void draw_glyph_shadow(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_shadow_color, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { if (p_gl.font_rid != RID()) { - if (p_font_shadow_color.a > 0) { - TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); - } - if (p_font_shadow_color.a > 0 && p_shadow_outline_size > 0) { - TS->font_draw_glyph_outline(p_gl.font_rid, p_canvas, p_gl.font_size, p_shadow_outline_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); - } + TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); + } +} + +inline void draw_glyph_shadow_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_shadow_color, int p_shadow_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { + if (p_gl.font_rid != RID()) { + TS->font_draw_glyph_outline(p_gl.font_rid, p_canvas, p_gl.font_size, p_shadow_outline_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); } } @@ -768,7 +769,10 @@ void Label::_notification(int p_what) { // Draw shadow, outline and text. Note: Do not merge this into the single loop iteration, to prevent overlaps. int processed_glyphs_step = 0; - for (int step = DRAW_STEP_SHADOW; step < DRAW_STEP_MAX; step++) { + for (int step = DRAW_STEP_SHADOW_OUTLINE; step < DRAW_STEP_MAX; step++) { + if (step == DRAW_STEP_SHADOW_OUTLINE && (font_shadow_color.a == 0 || shadow_outline_size <= 0)) { + continue; + } if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0)) { continue; } @@ -784,8 +788,10 @@ void Label::_notification(int p_what) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end + para.start > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs)); if (!skip) { - if (step == DRAW_STEP_SHADOW) { - draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + if (step == DRAW_STEP_SHADOW_OUTLINE) { + draw_glyph_shadow_outline(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + } else if (step == DRAW_STEP_SHADOW) { + draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, offset_step, shadow_ofs); } else if (step == DRAW_STEP_OUTLINE) { draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step); } else if (step == DRAW_STEP_TEXT) { @@ -814,8 +820,10 @@ void Label::_notification(int p_what) { for (int k = 0; k < glyphs[j].repeat; k++) { bool skip = (trim_chars && glyphs[j].end + para.start > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs)); if (!skip) { - if (step == DRAW_STEP_SHADOW) { - draw_glyph_shadow(glyphs[j], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + if (step == DRAW_STEP_SHADOW_OUTLINE) { + draw_glyph_shadow_outline(glyphs[j], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + } else if (step == DRAW_STEP_SHADOW) { + draw_glyph_shadow(glyphs[j], ci, font_shadow_color, offset_step, shadow_ofs); } else if (step == DRAW_STEP_OUTLINE) { draw_glyph_outline(glyphs[j], ci, font_outline_color, outline_size, offset_step); } else if (step == DRAW_STEP_TEXT) { @@ -832,8 +840,10 @@ void Label::_notification(int p_what) { for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end + para.start > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs)); if (!skip) { - if (step == DRAW_STEP_SHADOW) { - draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + if (step == DRAW_STEP_SHADOW_OUTLINE) { + draw_glyph_shadow_outline(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs); + } else if (step == DRAW_STEP_SHADOW) { + draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, offset_step, shadow_ofs); } else if (step == DRAW_STEP_OUTLINE) { draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step); } else if (step == DRAW_STEP_TEXT) { diff --git a/scene/gui/label.h b/scene/gui/label.h index 6b224e0cb0..936445adf6 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -39,6 +39,7 @@ class Label : public Control { private: enum LabelDrawStep { + DRAW_STEP_SHADOW_OUTLINE, DRAW_STEP_SHADOW, DRAW_STEP_OUTLINE, DRAW_STEP_TEXT, diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index a76a43b25a..91beafa4c1 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1051,17 +1051,18 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } - Color font_color = (step == DRAW_STEP_SHADOW || step == DRAW_STEP_OUTLINE || step == DRAW_STEP_TEXT) ? _find_color(it, p_base_color) : Color(); + Color font_color = (step == DRAW_STEP_SHADOW_OUTLINE || step == DRAW_STEP_SHADOW || step == DRAW_STEP_OUTLINE || step == DRAW_STEP_TEXT) ? _find_color(it, p_base_color) : Color(); int outline_size = (step == DRAW_STEP_OUTLINE) ? _find_outline_size(it, p_outline_size) : 0; Color font_outline_color = (step == DRAW_STEP_OUTLINE) ? _find_outline_color(it, p_outline_color) : Color(); Color font_shadow_color = p_font_shadow_color; - bool txt_visible = false; - if (step == DRAW_STEP_OUTLINE) { - txt_visible = (font_outline_color.a != 0 && outline_size > 0); - } else if (step == DRAW_STEP_SHADOW) { - txt_visible = (font_shadow_color.a != 0); + bool txt_visible = (font_color.a != 0); + if (step == DRAW_STEP_OUTLINE && (outline_size <= 0 || font_outline_color.a == 0)) { + continue; + } else if (step == DRAW_STEP_SHADOW_OUTLINE && (font_shadow_color.a == 0 || p_shadow_outline_size <= 0)) { + continue; + } else if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0)) { + continue; } else if (step == DRAW_STEP_TEXT) { - txt_visible = (font_color.a != 0); bool has_ul = _find_underline(it); if (!has_ul && underline_meta) { ItemMeta *meta = nullptr; @@ -1146,7 +1147,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off_step.x, off_step.y + y_off), st_color, underline_width); } } - if (step == DRAW_STEP_SHADOW || step == DRAW_STEP_OUTLINE || step == DRAW_STEP_TEXT) { + if (step == DRAW_STEP_SHADOW_OUTLINE || step == DRAW_STEP_SHADOW || step == DRAW_STEP_OUTLINE || step == DRAW_STEP_TEXT) { ItemFade *fade = nullptr; Item *fade_item = it; while (fade_item) { @@ -1209,7 +1210,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o charfx->range = Vector2i(l.char_offset + glyphs[i].start, l.char_offset + glyphs[i].end); charfx->relative_index = l.char_offset + glyphs[i].start - item_fx->char_ofs; charfx->visibility = txt_visible; - charfx->outline = (step == DRAW_STEP_SHADOW) || (step == DRAW_STEP_OUTLINE); + charfx->outline = (step == DRAW_STEP_SHADOW_OUTLINE) || (step == DRAW_STEP_SHADOW) || (step == DRAW_STEP_OUTLINE); charfx->font = frid; charfx->glyph_index = gl; charfx->glyph_flags = gl_fl; @@ -1284,7 +1285,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o char_reverse_xform.set_origin(-char_off); Transform2D char_final_xform = char_xform * char_reverse_xform; draw_set_transform_matrix(char_final_xform); - } else if (step == DRAW_STEP_SHADOW) { + } else if (step == DRAW_STEP_SHADOW_OUTLINE || step == DRAW_STEP_SHADOW) { font_color = font_shadow_color * Color(1, 1, 1, font_color.a); char_reverse_xform.set_origin(-char_off - p_shadow_ofs); @@ -1311,12 +1312,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } else if (((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) && ((glyphs[i].flags & TextServer::GRAPHEME_IS_EMBEDDED_OBJECT) != TextServer::GRAPHEME_IS_EMBEDDED_OBJECT)) { TS->draw_hex_code_box(ci, glyphs[i].font_size, fx_offset + char_off, gl, font_color); } + } else if (step == DRAW_STEP_SHADOW_OUTLINE && frid != RID()) { + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, fx_offset + char_off + p_shadow_ofs, gl, font_color); } else if (step == DRAW_STEP_SHADOW && frid != RID()) { TS->font_draw_glyph(frid, ci, glyphs[i].font_size, fx_offset + char_off + p_shadow_ofs, gl, font_color); - if (p_shadow_outline_size > 0) { - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, fx_offset + char_off + p_shadow_ofs, gl, font_color); - } - } else if (step == DRAW_STEP_OUTLINE && frid != RID() && outline_size > 0) { + } else if (step == DRAW_STEP_OUTLINE && frid != RID()) { TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, outline_size, fx_offset + char_off, gl, font_color); } } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 6b46526049..ec140750da 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -45,6 +45,7 @@ class RichTextLabel : public Control { enum RTLDrawStep { DRAW_STEP_BACKGROUND, + DRAW_STEP_SHADOW_OUTLINE, DRAW_STEP_SHADOW, DRAW_STEP_OUTLINE, DRAW_STEP_TEXT,