Fix text shadow outline draw batching.
This commit is contained in:
@ -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_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);
|
||||||
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);
|
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.
|
// Draw shadow, outline and text. Note: Do not merge this into the single loop iteration, to prevent overlaps.
|
||||||
int processed_glyphs_step = 0;
|
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)) {
|
if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -784,8 +788,10 @@ void Label::_notification(int p_what) {
|
|||||||
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
|
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));
|
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 (!skip) {
|
||||||
if (step == DRAW_STEP_SHADOW) {
|
if (step == DRAW_STEP_SHADOW_OUTLINE) {
|
||||||
draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
|
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) {
|
} else if (step == DRAW_STEP_OUTLINE) {
|
||||||
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
|
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
|
||||||
} else if (step == DRAW_STEP_TEXT) {
|
} 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++) {
|
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));
|
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 (!skip) {
|
||||||
if (step == DRAW_STEP_SHADOW) {
|
if (step == DRAW_STEP_SHADOW_OUTLINE) {
|
||||||
draw_glyph_shadow(glyphs[j], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
|
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) {
|
} else if (step == DRAW_STEP_OUTLINE) {
|
||||||
draw_glyph_outline(glyphs[j], ci, font_outline_color, outline_size, offset_step);
|
draw_glyph_outline(glyphs[j], ci, font_outline_color, outline_size, offset_step);
|
||||||
} else if (step == DRAW_STEP_TEXT) {
|
} 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++) {
|
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));
|
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 (!skip) {
|
||||||
if (step == DRAW_STEP_SHADOW) {
|
if (step == DRAW_STEP_SHADOW_OUTLINE) {
|
||||||
draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
|
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) {
|
} else if (step == DRAW_STEP_OUTLINE) {
|
||||||
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
|
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
|
||||||
} else if (step == DRAW_STEP_TEXT) {
|
} else if (step == DRAW_STEP_TEXT) {
|
||||||
|
|||||||
@ -39,6 +39,7 @@ class Label : public Control {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum LabelDrawStep {
|
enum LabelDrawStep {
|
||||||
|
DRAW_STEP_SHADOW_OUTLINE,
|
||||||
DRAW_STEP_SHADOW,
|
DRAW_STEP_SHADOW,
|
||||||
DRAW_STEP_OUTLINE,
|
DRAW_STEP_OUTLINE,
|
||||||
DRAW_STEP_TEXT,
|
DRAW_STEP_TEXT,
|
||||||
|
|||||||
@ -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;
|
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_outline_color = (step == DRAW_STEP_OUTLINE) ? _find_outline_color(it, p_outline_color) : Color();
|
||||||
Color font_shadow_color = p_font_shadow_color;
|
Color font_shadow_color = p_font_shadow_color;
|
||||||
bool txt_visible = false;
|
bool txt_visible = (font_color.a != 0);
|
||||||
if (step == DRAW_STEP_OUTLINE) {
|
if (step == DRAW_STEP_OUTLINE && (outline_size <= 0 || font_outline_color.a == 0)) {
|
||||||
txt_visible = (font_outline_color.a != 0 && outline_size > 0);
|
continue;
|
||||||
} else if (step == DRAW_STEP_SHADOW) {
|
} else if (step == DRAW_STEP_SHADOW_OUTLINE && (font_shadow_color.a == 0 || p_shadow_outline_size <= 0)) {
|
||||||
txt_visible = (font_shadow_color.a != 0);
|
continue;
|
||||||
|
} else if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0)) {
|
||||||
|
continue;
|
||||||
} else if (step == DRAW_STEP_TEXT) {
|
} else if (step == DRAW_STEP_TEXT) {
|
||||||
txt_visible = (font_color.a != 0);
|
|
||||||
bool has_ul = _find_underline(it);
|
bool has_ul = _find_underline(it);
|
||||||
if (!has_ul && underline_meta) {
|
if (!has_ul && underline_meta) {
|
||||||
ItemMeta *meta = nullptr;
|
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);
|
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;
|
ItemFade *fade = nullptr;
|
||||||
Item *fade_item = it;
|
Item *fade_item = it;
|
||||||
while (fade_item) {
|
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->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->relative_index = l.char_offset + glyphs[i].start - item_fx->char_ofs;
|
||||||
charfx->visibility = txt_visible;
|
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->font = frid;
|
||||||
charfx->glyph_index = gl;
|
charfx->glyph_index = gl;
|
||||||
charfx->glyph_flags = gl_fl;
|
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);
|
char_reverse_xform.set_origin(-char_off);
|
||||||
Transform2D char_final_xform = char_xform * char_reverse_xform;
|
Transform2D char_final_xform = char_xform * char_reverse_xform;
|
||||||
draw_set_transform_matrix(char_final_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);
|
font_color = font_shadow_color * Color(1, 1, 1, font_color.a);
|
||||||
|
|
||||||
char_reverse_xform.set_origin(-char_off - p_shadow_ofs);
|
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)) {
|
} 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);
|
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()) {
|
} 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);
|
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) {
|
} else if (step == DRAW_STEP_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_OUTLINE && frid != RID() && outline_size > 0) {
|
|
||||||
TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, outline_size, fx_offset + char_off, gl, font_color);
|
TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, outline_size, fx_offset + char_off, gl, font_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ class RichTextLabel : public Control {
|
|||||||
|
|
||||||
enum RTLDrawStep {
|
enum RTLDrawStep {
|
||||||
DRAW_STEP_BACKGROUND,
|
DRAW_STEP_BACKGROUND,
|
||||||
|
DRAW_STEP_SHADOW_OUTLINE,
|
||||||
DRAW_STEP_SHADOW,
|
DRAW_STEP_SHADOW,
|
||||||
DRAW_STEP_OUTLINE,
|
DRAW_STEP_OUTLINE,
|
||||||
DRAW_STEP_TEXT,
|
DRAW_STEP_TEXT,
|
||||||
|
|||||||
Reference in New Issue
Block a user