[Label] Move shadow drawing into a separate draw step.
This commit is contained in:
parent
0175be8948
commit
af9e8128f9
2 changed files with 54 additions and 79 deletions
|
@ -316,7 +316,7 @@ inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_fo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_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, int p_shadow_outline_size, 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) {
|
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);
|
||||||
|
@ -324,6 +324,11 @@ inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Col
|
||||||
if (p_font_shadow_color.a > 0 && p_shadow_outline_size > 0) {
|
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_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_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_outline_color, int p_outline_size, const Vector2 &p_ofs) {
|
||||||
|
if (p_gl.font_rid != RID()) {
|
||||||
if (p_font_outline_color.a != 0.0 && p_outline_size > 0) {
|
if (p_font_outline_color.a != 0.0 && p_outline_size > 0) {
|
||||||
TS->font_draw_glyph_outline(p_gl.font_rid, p_canvas, p_gl.font_size, p_outline_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off), p_gl.index, p_font_outline_color);
|
TS->font_draw_glyph_outline(p_gl.font_rid, p_canvas, p_gl.font_size, p_outline_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off), p_gl.index, p_font_outline_color);
|
||||||
}
|
}
|
||||||
|
@ -537,25 +542,36 @@ void Label::_notification(int p_what) {
|
||||||
const Glyph *ellipsis_glyphs = TS->shaped_text_get_ellipsis_glyphs(lines_rid[i]);
|
const Glyph *ellipsis_glyphs = TS->shaped_text_get_ellipsis_glyphs(lines_rid[i]);
|
||||||
int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]);
|
int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]);
|
||||||
|
|
||||||
// Draw outline. Note: Do not merge this into the single loop with the main text, to prevent overlaps.
|
// Draw shadow, outline and text. Note: Do not merge this into the single loop iteration, to prevent overlaps.
|
||||||
int processed_glyphs_ol = processed_glyphs;
|
for (int step = DRAW_STEP_SHADOW; step < DRAW_STEP_MAX; step++) {
|
||||||
if ((outline_size > 0 && font_outline_color.a != 0) || (font_shadow_color.a != 0)) {
|
if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0)) {
|
||||||
Vector2 offset = ofs;
|
continue;
|
||||||
|
}
|
||||||
|
if (step == DRAW_STEP_OUTLINE && (outline_size <= 0 || font_outline_color.a == 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int processed_glyphs_step = processed_glyphs;
|
||||||
|
Vector2 offset_step = ofs;
|
||||||
// Draw RTL ellipsis string when necessary.
|
// Draw RTL ellipsis string when necessary.
|
||||||
if (rtl && ellipsis_pos >= 0) {
|
if (rtl && ellipsis_pos >= 0) {
|
||||||
for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) {
|
for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) {
|
||||||
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 > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs));
|
bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs));
|
||||||
//Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
|
if (step == DRAW_STEP_SHADOW) {
|
||||||
|
draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, 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) {
|
||||||
|
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, offset_step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
processed_glyphs_ol++;
|
processed_glyphs_step++;
|
||||||
offset.x += ellipsis_glyphs[gl_idx].advance;
|
offset_step.x += ellipsis_glyphs[gl_idx].advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw main text.
|
// Draw main text.
|
||||||
for (int j = 0; j < gl_size; j++) {
|
for (int j = 0; j < gl_size; j++) {
|
||||||
// Trim when necessary.
|
// Trim when necessary.
|
||||||
|
@ -571,88 +587,40 @@ 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 > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs));
|
bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs));
|
||||||
|
|
||||||
// Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
draw_glyph_outline(glyphs[j], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
|
if (step == DRAW_STEP_SHADOW) {
|
||||||
|
draw_glyph_shadow(glyphs[j], ci, font_shadow_color, shadow_outline_size, 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) {
|
||||||
|
draw_glyph(glyphs[j], ci, font_color, offset_step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
processed_glyphs_ol++;
|
processed_glyphs_step++;
|
||||||
offset.x += glyphs[j].advance;
|
offset_step.x += glyphs[j].advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Draw LTR ellipsis string when necessary.
|
// Draw LTR ellipsis string when necessary.
|
||||||
if (!rtl && ellipsis_pos >= 0) {
|
if (!rtl && ellipsis_pos >= 0) {
|
||||||
for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) {
|
for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) {
|
||||||
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 > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs));
|
bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs_step >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_step < total_glyphs - visible_glyphs));
|
||||||
//Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs);
|
if (step == DRAW_STEP_SHADOW) {
|
||||||
|
draw_glyph_shadow(ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, 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) {
|
||||||
|
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, offset_step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
processed_glyphs_ol++;
|
processed_glyphs_step++;
|
||||||
offset.x += ellipsis_glyphs[gl_idx].advance;
|
offset_step.x += ellipsis_glyphs[gl_idx].advance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw main text. Note: Do not merge this into the single loop with the outline, to prevent overlaps.
|
|
||||||
|
|
||||||
// Draw RTL ellipsis string when necessary.
|
|
||||||
if (rtl && ellipsis_pos >= 0) {
|
|
||||||
for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) {
|
|
||||||
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
|
|
||||||
bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs));
|
|
||||||
//Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
|
||||||
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs);
|
|
||||||
}
|
|
||||||
processed_glyphs++;
|
|
||||||
ofs.x += ellipsis_glyphs[gl_idx].advance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw main text.
|
|
||||||
for (int j = 0; j < gl_size; j++) {
|
|
||||||
// Trim when necessary.
|
|
||||||
if (trim_pos >= 0) {
|
|
||||||
if (rtl) {
|
|
||||||
if (j < trim_pos) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (j >= trim_pos) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int k = 0; k < glyphs[j].repeat; k++) {
|
|
||||||
bool skip = (trim_chars && glyphs[j].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs));
|
|
||||||
|
|
||||||
// Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
|
||||||
draw_glyph(glyphs[j], ci, font_color, ofs);
|
|
||||||
}
|
|
||||||
processed_glyphs++;
|
|
||||||
ofs.x += glyphs[j].advance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Draw LTR ellipsis string when necessary.
|
|
||||||
if (!rtl && ellipsis_pos >= 0) {
|
|
||||||
for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) {
|
|
||||||
for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) {
|
|
||||||
bool skip = (trim_chars && ellipsis_glyphs[gl_idx].end > visible_chars) || (trim_glyphs_ltr && (processed_glyphs >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs < total_glyphs - visible_glyphs));
|
|
||||||
//Draw glyph outlines and shadow.
|
|
||||||
if (!skip) {
|
|
||||||
draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs);
|
|
||||||
}
|
|
||||||
processed_glyphs++;
|
|
||||||
ofs.x += ellipsis_glyphs[gl_idx].advance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing;
|
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -38,6 +38,13 @@ class Label : public Control {
|
||||||
GDCLASS(Label, Control);
|
GDCLASS(Label, Control);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum LabelDrawStep {
|
||||||
|
DRAW_STEP_SHADOW,
|
||||||
|
DRAW_STEP_OUTLINE,
|
||||||
|
DRAW_STEP_TEXT,
|
||||||
|
DRAW_STEP_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT;
|
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT;
|
||||||
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_TOP;
|
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_TOP;
|
||||||
String text;
|
String text;
|
||||||
|
|
Loading…
Reference in a new issue