3636#include " core/os/os.h"
3737#include " core/string/translation.h"
3838#include " scene/gui/label.h"
39+ #include " scene/gui/rich_text_effect.h"
3940#include " scene/resources/atlas_texture.h"
4041#include " scene/scene_string_names.h"
4142#include " servers/display_server.h"
4546#include " modules/regex/regex.h"
4647#endif
4748
49+ RichTextLabel::ItemCustomFX::ItemCustomFX () {
50+ type = ITEM_CUSTOMFX ;
51+ char_fx_transform.instantiate ();
52+ }
53+
54+ RichTextLabel::ItemCustomFX::~ItemCustomFX () {
55+ _clear_children ();
56+
57+ char_fx_transform.unref ();
58+ custom_effect.unref ();
59+ }
60+
4861RichTextLabel::Item *RichTextLabel::_get_next_item (Item *p_item, bool p_free) const {
4962 if (p_free) {
5063 if (p_item->subitems .size ()) {
@@ -1030,6 +1043,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
10301043 }
10311044
10321045 bool txt_visible = (font_outline_color.a != 0 ) || (font_shadow_color.a != 0 );
1046+ Transform2D char_xform;
1047+ char_xform.set_origin (gloff + p_ofs);
10331048
10341049 for (int j = 0 ; j < fx_stack.size (); j++) {
10351050 ItemFX *item_fx = fx_stack[j];
@@ -1053,10 +1068,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
10531068 charfx->glyph_count = gl_cn;
10541069 charfx->offset = fx_offset;
10551070 charfx->color = font_color;
1071+ charfx->transform = char_xform;
10561072
10571073 bool effect_status = custom_effect->_process_effect_impl (charfx);
10581074 custom_fx_ok = effect_status;
10591075
1076+ char_xform = charfx->transform ;
10601077 fx_offset += charfx->offset ;
10611078 font_color = charfx->color ;
10621079 frid = charfx->font ;
@@ -1110,6 +1127,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
11101127 fx_offset = fx_offset.round ();
11111128 }
11121129
1130+ Vector2i char_off = char_xform.get_origin ();
1131+
11131132 // Draw glyph outlines.
11141133 const Color modulated_outline_color = font_outline_color * Color (1 , 1 , 1 , font_color.a );
11151134 const Color modulated_shadow_color = font_shadow_color * Color (1 , 1 , 1 , font_color.a );
@@ -1118,20 +1137,32 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
11181137 bool skip = (trim_chars && l.char_offset + glyphs[i].end > visible_characters) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs));
11191138 if (!skip && frid != RID ()) {
11201139 if (modulated_shadow_color.a > 0 ) {
1121- TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color);
1122- }
1123- if (modulated_shadow_color.a > 0 && p_shadow_outline_size > 0 ) {
1124- TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , p_shadow_outline_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color);
1140+ Transform2D char_reverse_xform;
1141+ char_reverse_xform.set_origin (-char_off - p_shadow_ofs);
1142+ Transform2D char_final_xform = char_xform * char_reverse_xform;
1143+ char_final_xform.columns [2 ] += p_shadow_ofs;
1144+ draw_set_transform_matrix (char_final_xform);
1145+
1146+ TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , fx_offset + char_off + p_shadow_ofs, gl, modulated_shadow_color);
1147+ if (p_shadow_outline_size > 0 ) {
1148+ TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , p_shadow_outline_size, fx_offset + char_off + p_shadow_ofs, gl, modulated_shadow_color);
1149+ }
11251150 }
11261151 if (modulated_outline_color.a != 0.0 && size > 0 ) {
1127- TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , size, p_ofs + fx_offset + gloff, gl, modulated_outline_color);
1152+ Transform2D char_reverse_xform;
1153+ char_reverse_xform.set_origin (-char_off);
1154+ Transform2D char_final_xform = char_xform * char_reverse_xform;
1155+ draw_set_transform_matrix (char_final_xform);
1156+
1157+ TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , size, fx_offset + char_off, gl, modulated_outline_color);
11281158 }
11291159 }
11301160 processed_glyphs_ol++;
11311161 }
11321162 gloff.x += glyphs[i].advance ;
11331163 }
11341164 }
1165+ draw_set_transform_matrix (Transform2D ());
11351166
11361167 Vector2 fbg_line_off = off + p_ofs;
11371168 // Draw background color box
@@ -1258,6 +1289,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
12581289
12591290 bool txt_visible = (font_color.a != 0 );
12601291
1292+ Transform2D char_xform;
1293+ char_xform.set_origin (p_ofs + off);
1294+
12611295 for (int j = 0 ; j < fx_stack.size (); j++) {
12621296 ItemFX *item_fx = fx_stack[j];
12631297 bool cn = cprev_cluster || (cprev_conn && item_fx->connected );
@@ -1280,10 +1314,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
12801314 charfx->glyph_count = gl_cn;
12811315 charfx->offset = fx_offset;
12821316 charfx->color = font_color;
1317+ charfx->transform = char_xform;
12831318
12841319 bool effect_status = custom_effect->_process_effect_impl (charfx);
12851320 custom_fx_ok = effect_status;
12861321
1322+ char_xform = charfx->transform ;
12871323 fx_offset += charfx->offset ;
12881324 font_color = charfx->color ;
12891325 frid = charfx->font ;
@@ -1337,6 +1373,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13371373 fx_offset = fx_offset.round ();
13381374 }
13391375
1376+ Vector2i char_off = char_xform.get_origin ();
1377+ Transform2D char_reverse_xform;
1378+ char_reverse_xform.set_origin (-char_off);
1379+ char_xform = char_xform * char_reverse_xform;
1380+ draw_set_transform_matrix (char_xform);
1381+
13401382 if (selected && use_selected_font_color) {
13411383 font_color = theme_cache.font_selected_color ;
13421384 }
@@ -1347,9 +1389,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13471389 if (txt_visible) {
13481390 if (!skip) {
13491391 if (frid != RID ()) {
1350- TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , p_ofs + fx_offset + off , gl, font_color);
1392+ TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , fx_offset + char_off , gl, font_color);
13511393 } 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 )) {
1352- TS ->draw_hex_code_box (ci, glyphs[i].font_size , p_ofs + fx_offset + off , gl, font_color);
1394+ TS ->draw_hex_code_box (ci, glyphs[i].font_size , fx_offset + char_off , gl, font_color);
13531395 }
13541396 }
13551397 r_processed_glyphs++;
@@ -1377,6 +1419,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13771419 }
13781420 off.x += glyphs[i].advance ;
13791421 }
1422+
1423+ draw_set_transform_matrix (Transform2D ());
13801424 }
13811425 if (ul_started) {
13821426 ul_started = false ;
0 commit comments