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 " scene/theme/theme_db.h"
4647#include " modules/regex/regex.h"
4748#endif
4849
50+ RichTextLabel::ItemCustomFX::ItemCustomFX () {
51+ type = ITEM_CUSTOMFX ;
52+ char_fx_transform.instantiate ();
53+ }
54+
55+ RichTextLabel::ItemCustomFX::~ItemCustomFX () {
56+ _clear_children ();
57+
58+ char_fx_transform.unref ();
59+ custom_effect.unref ();
60+ }
61+
4962RichTextLabel::Item *RichTextLabel::_get_next_item (Item *p_item, bool p_free) const {
5063 if (p_free) {
5164 if (p_item->subitems .size ()) {
@@ -1028,6 +1041,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
10281041 }
10291042
10301043 bool txt_visible = (font_outline_color.a != 0 ) || (font_shadow_color.a != 0 );
1044+ Transform2D char_xform;
1045+ char_xform.set_origin (gloff + p_ofs);
10311046
10321047 for (int j = 0 ; j < fx_stack.size (); j++) {
10331048 ItemFX *item_fx = fx_stack[j];
@@ -1051,10 +1066,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
10511066 charfx->glyph_count = gl_cn;
10521067 charfx->offset = fx_offset;
10531068 charfx->color = font_color;
1069+ charfx->transform = char_xform;
10541070
10551071 bool effect_status = custom_effect->_process_effect_impl (charfx);
10561072 custom_fx_ok = effect_status;
10571073
1074+ char_xform = charfx->transform ;
10581075 fx_offset += charfx->offset ;
10591076 font_color = charfx->color ;
10601077 frid = charfx->font ;
@@ -1108,6 +1125,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
11081125 fx_offset = fx_offset.round ();
11091126 }
11101127
1128+ Vector2i char_off = char_xform.get_origin ();
1129+
11111130 // Draw glyph outlines.
11121131 const Color modulated_outline_color = font_outline_color * Color (1 , 1 , 1 , font_color.a );
11131132 const Color modulated_shadow_color = font_shadow_color * Color (1 , 1 , 1 , font_color.a );
@@ -1116,20 +1135,32 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
11161135 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));
11171136 if (!skip && frid != RID ()) {
11181137 if (modulated_shadow_color.a > 0 ) {
1119- TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color);
1120- }
1121- if (modulated_shadow_color.a > 0 && p_shadow_outline_size > 0 ) {
1122- 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);
1138+ Transform2D char_reverse_xform;
1139+ char_reverse_xform.set_origin (-char_off - p_shadow_ofs);
1140+ Transform2D char_final_xform = char_xform * char_reverse_xform;
1141+ char_final_xform.columns [2 ] += p_shadow_ofs;
1142+ draw_set_transform_matrix (char_final_xform);
1143+
1144+ TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , fx_offset + char_off + p_shadow_ofs, gl, modulated_shadow_color);
1145+ if (p_shadow_outline_size > 0 ) {
1146+ 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);
1147+ }
11231148 }
11241149 if (modulated_outline_color.a != 0.0 && size > 0 ) {
1125- TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , size, p_ofs + fx_offset + gloff, gl, modulated_outline_color);
1150+ Transform2D char_reverse_xform;
1151+ char_reverse_xform.set_origin (-char_off);
1152+ Transform2D char_final_xform = char_xform * char_reverse_xform;
1153+ draw_set_transform_matrix (char_final_xform);
1154+
1155+ TS ->font_draw_glyph_outline (frid, ci, glyphs[i].font_size , size, fx_offset + char_off, gl, modulated_outline_color);
11261156 }
11271157 }
11281158 processed_glyphs_ol++;
11291159 }
11301160 gloff.x += glyphs[i].advance ;
11311161 }
11321162 }
1163+ draw_set_transform_matrix (Transform2D ());
11331164
11341165 Vector2 fbg_line_off = off + p_ofs;
11351166 // Draw background color box
@@ -1256,6 +1287,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
12561287
12571288 bool txt_visible = (font_color.a != 0 );
12581289
1290+ Transform2D char_xform;
1291+ char_xform.set_origin (p_ofs + off);
1292+
12591293 for (int j = 0 ; j < fx_stack.size (); j++) {
12601294 ItemFX *item_fx = fx_stack[j];
12611295 bool cn = cprev_cluster || (cprev_conn && item_fx->connected );
@@ -1278,10 +1312,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
12781312 charfx->glyph_count = gl_cn;
12791313 charfx->offset = fx_offset;
12801314 charfx->color = font_color;
1315+ charfx->transform = char_xform;
12811316
12821317 bool effect_status = custom_effect->_process_effect_impl (charfx);
12831318 custom_fx_ok = effect_status;
12841319
1320+ char_xform = charfx->transform ;
12851321 fx_offset += charfx->offset ;
12861322 font_color = charfx->color ;
12871323 frid = charfx->font ;
@@ -1335,6 +1371,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13351371 fx_offset = fx_offset.round ();
13361372 }
13371373
1374+ Vector2i char_off = char_xform.get_origin ();
1375+ Transform2D char_reverse_xform;
1376+ char_reverse_xform.set_origin (-char_off);
1377+ char_xform = char_xform * char_reverse_xform;
1378+ draw_set_transform_matrix (char_xform);
1379+
13381380 if (selected && use_selected_font_color) {
13391381 font_color = theme_cache.font_selected_color ;
13401382 }
@@ -1345,9 +1387,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13451387 if (txt_visible) {
13461388 if (!skip) {
13471389 if (frid != RID ()) {
1348- TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , p_ofs + fx_offset + off , gl, font_color);
1390+ TS ->font_draw_glyph (frid, ci, glyphs[i].font_size , fx_offset + char_off , gl, font_color);
13491391 } 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 )) {
1350- TS ->draw_hex_code_box (ci, glyphs[i].font_size , p_ofs + fx_offset + off , gl, font_color);
1392+ TS ->draw_hex_code_box (ci, glyphs[i].font_size , fx_offset + char_off , gl, font_color);
13511393 }
13521394 }
13531395 r_processed_glyphs++;
@@ -1375,6 +1417,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13751417 }
13761418 off.x += glyphs[i].advance ;
13771419 }
1420+
1421+ draw_set_transform_matrix (Transform2D ());
13781422 }
13791423 if (ul_started) {
13801424 ul_started = false ;
0 commit comments