diff options
Diffstat (limited to 'scene/gui/rich_text_label.cpp')
-rw-r--r-- | scene/gui/rich_text_label.cpp | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 96e338544c..cd821c7612 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -36,6 +36,7 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "scene/gui/label.h" +#include "scene/gui/rich_text_effect.h" #include "scene/resources/atlas_texture.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" @@ -46,6 +47,18 @@ #include "modules/regex/regex.h" #endif +RichTextLabel::ItemCustomFX::ItemCustomFX() { + type = ITEM_CUSTOMFX; + char_fx_transform.instantiate(); +} + +RichTextLabel::ItemCustomFX::~ItemCustomFX() { + _clear_children(); + + char_fx_transform.unref(); + custom_effect.unref(); +} + RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const { if (p_free) { if (p_item->subitems.size()) { @@ -1028,6 +1041,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } bool txt_visible = (font_outline_color.a != 0) || (font_shadow_color.a != 0); + Transform2D char_xform; + char_xform.set_origin(gloff + p_ofs); for (int j = 0; j < fx_stack.size(); j++) { ItemFX *item_fx = fx_stack[j]; @@ -1051,10 +1066,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o charfx->glyph_count = gl_cn; charfx->offset = fx_offset; charfx->color = font_color; + charfx->transform = char_xform; bool effect_status = custom_effect->_process_effect_impl(charfx); custom_fx_ok = effect_status; + char_xform = charfx->transform; fx_offset += charfx->offset; font_color = charfx->color; frid = charfx->font; @@ -1108,6 +1125,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o fx_offset = fx_offset.round(); } + Vector2i char_off = char_xform.get_origin(); + // Draw glyph outlines. const Color modulated_outline_color = font_outline_color * Color(1, 1, 1, font_color.a); const Color modulated_shadow_color = font_shadow_color * Color(1, 1, 1, font_color.a); @@ -1116,13 +1135,24 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o 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)); if (!skip && frid != RID()) { if (modulated_shadow_color.a > 0) { - TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color); - } - if (modulated_shadow_color.a > 0 && p_shadow_outline_size > 0) { - 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); + Transform2D char_reverse_xform; + char_reverse_xform.set_origin(-char_off - p_shadow_ofs); + Transform2D char_final_xform = char_xform * char_reverse_xform; + char_final_xform.columns[2] += p_shadow_ofs; + draw_set_transform_matrix(char_final_xform); + + TS->font_draw_glyph(frid, ci, glyphs[i].font_size, fx_offset + char_off + p_shadow_ofs, gl, modulated_shadow_color); + if (p_shadow_outline_size > 0) { + 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); + } } if (modulated_outline_color.a != 0.0 && size > 0) { - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, modulated_outline_color); + Transform2D char_reverse_xform; + char_reverse_xform.set_origin(-char_off); + Transform2D char_final_xform = char_xform * char_reverse_xform; + draw_set_transform_matrix(char_final_xform); + + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, fx_offset + char_off, gl, modulated_outline_color); } } processed_glyphs_ol++; @@ -1130,6 +1160,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o gloff.x += glyphs[i].advance; } } + draw_set_transform_matrix(Transform2D()); Vector2 fbg_line_off = off + p_ofs; // Draw background color box @@ -1256,6 +1287,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o bool txt_visible = (font_color.a != 0); + Transform2D char_xform; + char_xform.set_origin(p_ofs + off); + for (int j = 0; j < fx_stack.size(); j++) { ItemFX *item_fx = fx_stack[j]; 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 charfx->glyph_count = gl_cn; charfx->offset = fx_offset; charfx->color = font_color; + charfx->transform = char_xform; bool effect_status = custom_effect->_process_effect_impl(charfx); custom_fx_ok = effect_status; + char_xform = charfx->transform; fx_offset += charfx->offset; font_color = charfx->color; frid = charfx->font; @@ -1335,6 +1371,12 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o fx_offset = fx_offset.round(); } + Vector2i char_off = char_xform.get_origin(); + Transform2D char_reverse_xform; + char_reverse_xform.set_origin(-char_off); + char_xform = char_xform * char_reverse_xform; + draw_set_transform_matrix(char_xform); + if (selected && use_selected_font_color) { font_color = theme_cache.font_selected_color; } @@ -1345,9 +1387,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o if (txt_visible) { if (!skip) { if (frid != RID()) { - TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, font_color); + TS->font_draw_glyph(frid, ci, glyphs[i].font_size, fx_offset + char_off, gl, font_color); } 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, p_ofs + fx_offset + off, gl, font_color); + TS->draw_hex_code_box(ci, glyphs[i].font_size, fx_offset + char_off, gl, font_color); } } r_processed_glyphs++; @@ -1375,6 +1417,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } off.x += glyphs[i].advance; } + + draw_set_transform_matrix(Transform2D()); } if (ul_started) { ul_started = false; |