summaryrefslogtreecommitdiffstats
path: root/scene/gui/rich_text_label.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/rich_text_label.cpp')
-rw-r--r--scene/gui/rich_text_label.cpp58
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;