@@ -430,13 +430,13 @@ inline void draw_glyph_shadow(const Glyph &p_gl, const RID &p_canvas, const Colo
430430 }
431431}
432432
433- 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) {
433+ inline void draw_glyph_shadow_outline (const Glyph &p_gl, const RID &p_canvas, const Color &p_font_shadow_color, const Vector2 &p_ofs, int p_shadow_outline_size , const Vector2 &shadow_ofs) {
434434 if (p_gl.font_rid != RID ()) {
435435 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);
436436 }
437437}
438438
439- 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) {
439+ inline void draw_glyph_outline (const Glyph &p_gl, const RID &p_canvas, const Color &p_font_outline_color, const Vector2 &p_ofs, int p_outline_size ) {
440440 if (p_gl.font_rid != RID ()) {
441441 if (p_font_outline_color.a != 0.0 && p_outline_size > 0 ) {
442442 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);
@@ -747,6 +747,8 @@ void Label::_notification(int p_what) {
747747 Color font_outline_color = has_settings ? settings->get_outline_color () : theme_cache.font_outline_color ;
748748 int outline_size = has_settings ? settings->get_outline_size () : theme_cache.font_outline_size ;
749749 int shadow_outline_size = has_settings ? settings->get_shadow_size () : theme_cache.font_shadow_outline_size ;
750+ Vector<LabelSettings::StackedOutlineData> stacked_outline_datas = has_settings ? settings->get_stacked_outline_data () : Vector<LabelSettings::StackedOutlineData>();
751+ Vector<LabelSettings::StackedShadowData> stacked_shadow_datas = has_settings ? settings->get_stacked_shadow_data () : Vector<LabelSettings::StackedShadowData>();
750752 bool rtl_layout = is_layout_rtl ();
751753
752754 style->draw (ci, Rect2 (Point2 (0 , 0 ), get_size ()));
@@ -798,95 +800,67 @@ void Label::_notification(int p_what) {
798800
799801 ofs.y += asc;
800802
801- // Draw shadow, outline and text . Note: Do not merge this into the single loop iteration, to prevent overlaps.
803+ // Draw text effects and main texts . Note: Do not merge this into the single loop iteration, to prevent overlaps.
802804 int processed_glyphs_step = 0 ;
803- for (int step = DRAW_STEP_SHADOW_OUTLINE; step < DRAW_STEP_MAX; step++) {
804- if (step == DRAW_STEP_SHADOW_OUTLINE && (font_shadow_color.a == 0 || shadow_outline_size <= 0 )) {
805- continue ;
806- }
807- if (step == DRAW_STEP_SHADOW && (font_shadow_color.a == 0 )) {
808- continue ;
809- }
810- if (step == DRAW_STEP_OUTLINE && (outline_size <= 0 || font_outline_color.a == 0 )) {
811- continue ;
812- }
813805
814- processed_glyphs_step = processed_glyphs;
815- Vector2 offset_step = ofs;
816- // Draw RTL ellipsis string when necessary.
817- if (rtl && ellipsis_pos >= 0 ) {
818- for (int gl_idx = ellipsis_gl_size - 1 ; gl_idx >= 0 ; gl_idx--) {
819- for (int j = 0 ; j < ellipsis_glyphs[gl_idx].repeat ; j++) {
820- 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));
821- if (!skip) {
822- if (step == DRAW_STEP_SHADOW_OUTLINE) {
823- draw_glyph_shadow_outline (ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
824- } else if (step == DRAW_STEP_SHADOW) {
825- draw_glyph_shadow (ellipsis_glyphs[gl_idx], ci, font_shadow_color, offset_step, shadow_ofs);
826- } else if (step == DRAW_STEP_OUTLINE) {
827- draw_glyph_outline (ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
828- } else if (step == DRAW_STEP_TEXT) {
829- draw_glyph (ellipsis_glyphs[gl_idx], ci, font_color, offset_step);
830- }
831- }
832- processed_glyphs_step++;
833- offset_step.x += ellipsis_glyphs[gl_idx].advance ;
834- }
806+ // Draw shadow outline.
807+ if (font_shadow_color.a != 0 && shadow_outline_size > 0 ) {
808+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, font_shadow_color, draw_glyph_shadow_outline, shadow_outline_size, shadow_ofs);
809+ }
810+
811+ // Draw shadow.
812+ if (font_shadow_color.a > 0 ) {
813+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, font_shadow_color, draw_glyph_shadow, shadow_ofs);
814+ }
815+
816+ // Draw stacked shadow.
817+ if (stacked_shadow_datas.size () != 0 ) {
818+ int draw_iterations = stacked_shadow_datas.size ();
819+
820+ for (int draw_iteration_index = draw_iterations - 1 ; draw_iteration_index >= 0 ; --draw_iteration_index) {
821+ LabelSettings::StackedShadowData stacked_shadow_data = stacked_shadow_datas[draw_iteration_index];
822+ if (stacked_shadow_data.outline_size > 0 ) {
823+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, stacked_shadow_data.color , draw_glyph_shadow_outline, stacked_shadow_data.outline_size , stacked_shadow_data.offset );
835824 }
825+
826+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, stacked_shadow_data.color , draw_glyph_shadow, stacked_shadow_data.offset );
836827 }
837- // Draw main text.
838- for (int j = 0 ; j < gl_size; j++) {
839- // Trim when necessary.
840- if (trim_pos >= 0 ) {
841- if (rtl) {
842- if (j < trim_pos) {
843- continue ;
844- }
845- } else {
846- if (j >= trim_pos) {
847- break ;
848- }
849- }
850- }
851- for (int k = 0 ; k < glyphs[j].repeat ; k++) {
852- 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));
853- if (!skip) {
854- if (step == DRAW_STEP_SHADOW_OUTLINE) {
855- draw_glyph_shadow_outline (glyphs[j], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
856- } else if (step == DRAW_STEP_SHADOW) {
857- draw_glyph_shadow (glyphs[j], ci, font_shadow_color, offset_step, shadow_ofs);
858- } else if (step == DRAW_STEP_OUTLINE) {
859- draw_glyph_outline (glyphs[j], ci, font_outline_color, outline_size, offset_step);
860- } else if (step == DRAW_STEP_TEXT) {
861- draw_glyph (glyphs[j], ci, font_color, offset_step);
862- }
863- }
864- processed_glyphs_step++;
865- offset_step.x += glyphs[j].advance ;
828+ }
829+
830+ // Draw stacked outline.
831+ if (stacked_outline_datas.size () != 0 ) {
832+ int stacked_outline_draw_size = outline_size;
833+
834+ int draw_iterations = stacked_outline_datas.size ();
835+
836+ for (int j = 0 ; j < draw_iterations; j++) {
837+ int stacked_outline_size = stacked_outline_datas[j].size ;
838+ if (stacked_outline_size <= 0 ) {
839+ continue ;
866840 }
841+ stacked_outline_draw_size += stacked_outline_size;
867842 }
868- // Draw LTR ellipsis string when necessary.
869- if (!rtl && ellipsis_pos >= 0 ) {
870- for (int gl_idx = 0 ; gl_idx < ellipsis_gl_size; gl_idx++) {
871- for (int j = 0 ; j < ellipsis_glyphs[gl_idx].repeat ; j++) {
872- 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));
873- if (!skip) {
874- if (step == DRAW_STEP_SHADOW_OUTLINE) {
875- draw_glyph_shadow_outline (ellipsis_glyphs[gl_idx], ci, font_shadow_color, shadow_outline_size, offset_step, shadow_ofs);
876- } else if (step == DRAW_STEP_SHADOW) {
877- draw_glyph_shadow (ellipsis_glyphs[gl_idx], ci, font_shadow_color, offset_step, shadow_ofs);
878- } else if (step == DRAW_STEP_OUTLINE) {
879- draw_glyph_outline (ellipsis_glyphs[gl_idx], ci, font_outline_color, outline_size, offset_step);
880- } else if (step == DRAW_STEP_TEXT) {
881- draw_glyph (ellipsis_glyphs[gl_idx], ci, font_color, offset_step);
882- }
883- }
884- processed_glyphs_step++;
885- offset_step.x += ellipsis_glyphs[gl_idx].advance ;
886- }
843+
844+ for (int draw_iteration_index = draw_iterations - 1 ; draw_iteration_index >= 0 ; --draw_iteration_index) {
845+ LabelSettings::StackedOutlineData stacked_outline_data = stacked_outline_datas[draw_iteration_index];
846+ if (stacked_outline_data.size <= 0 ) {
847+ continue ;
887848 }
849+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, stacked_outline_data.color , draw_glyph_outline, stacked_outline_draw_size);
850+ stacked_outline_draw_size -= stacked_outline_data.size ;
888851 }
889852 }
853+
854+ // Draw outline.
855+ if (outline_size > 0 && font_outline_color.a != 0 ) {
856+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, font_outline_color, draw_glyph_outline, outline_size);
857+ }
858+
859+ // Draw text.
860+ {
861+ draw_text (rtl, ellipsis_pos, ellipsis_gl_size, ellipsis_glyphs, trim_chars, para.start , visible_chars, trim_glyphs_ltr, processed_glyphs_step, processed_glyphs, visible_glyphs, trim_glyphs_rtl, total_glyphs, ci, ofs, gl_size, trim_pos, glyphs, font_color, draw_glyph);
862+ }
863+
890864 processed_glyphs = processed_glyphs_step;
891865 ofs.y += dsc + line_spacing;
892866 }
0 commit comments