Przeglądaj źródła

Fix RichTextEffect `visibility` to Account for Skipped Characters.

A picture is easier to describe this issue than words. Basically, rich
text effects allowed for character visibility changes. While doing so
would work properly, the rich text label would render the next `word` in
an offset accounting for the hidden characters (leaving a huge space.)

This patch fixes this issue by keeping track of the amount of
`backtrack` necessary per line.

(cherry picked from commit b3fd4884d7dd2e1c5f5d5dadd8af6ed13ab131ac)
Eoin O'Neill 5 lat temu
rodzic
commit
0dedc0a1a3
1 zmienionych plików z 12 dodań i 3 usunięć
  1. 12 3
      scene/gui/rich_text_label.cpp

+ 12 - 3
scene/gui/rich_text_label.cpp

@@ -199,6 +199,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 	int line_ascent = cfont->get_ascent();
 	int line_ascent = cfont->get_ascent();
 	int line_descent = cfont->get_descent();
 	int line_descent = cfont->get_descent();
 
 
+	int backtrack = 0; // for dynamic hidden content.
+
 	int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW
 	int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW
 
 
 	Variant meta;
 	Variant meta;
@@ -209,6 +211,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 	{                                                                                                                                                           \
 	{                                                                                                                                                           \
 		if (p_mode != PROCESS_CACHE) {                                                                                                                          \
 		if (p_mode != PROCESS_CACHE) {                                                                                                                          \
 			line++;                                                                                                                                             \
 			line++;                                                                                                                                             \
+			backtrack = 0;                                                                                                                                      \
 			if (!line_is_blank) {                                                                                                                               \
 			if (!line_is_blank) {                                                                                                                               \
 				nonblank_line_count++;                                                                                                                          \
 				nonblank_line_count++;                                                                                                                          \
 			}                                                                                                                                                   \
 			}                                                                                                                                                   \
@@ -258,7 +261,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 		l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width));                                                               \
 		l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width));                                                               \
 		l.minimum_width = MAX(l.minimum_width, m_width);                                                                                    \
 		l.minimum_width = MAX(l.minimum_width, m_width);                                                                                    \
 	}                                                                                                                                       \
 	}                                                                                                                                       \
-	if (wofs + m_width > p_width) {                                                                                                         \
+	if (wofs - backtrack + m_width > p_width) {                                                                                             \
 		line_wrapped = true;                                                                                                                \
 		line_wrapped = true;                                                                                                                \
 		if (p_mode == PROCESS_CACHE) {                                                                                                      \
 		if (p_mode == PROCESS_CACHE) {                                                                                                      \
 			if (spaces > 0)                                                                                                                 \
 			if (spaces > 0)                                                                                                                 \
@@ -385,6 +388,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 					int fw = 0;
 					int fw = 0;
 
 
 					lh = 0;
 					lh = 0;
+
 					if (p_mode != PROCESS_CACHE) {
 					if (p_mode != PROCESS_CACHE) {
 						lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
 						lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
 						line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1;
 						line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1;
@@ -427,13 +431,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 
 
 					{
 					{
 
 
-						int ofs = 0;
+						int ofs = 0 - backtrack;
 
 
 						for (int i = 0; i < end; i++) {
 						for (int i = 0; i < end; i++) {
 							int pofs = wofs + ofs;
 							int pofs = wofs + ofs;
 
 
 							if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
 							if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
-								//int o = (wofs+w)-p_click_pos.x;
 
 
 								int cw = font->get_char_size(c[i], c[i + 1]).x;
 								int cw = font->get_char_size(c[i], c[i + 1]).x;
 
 
@@ -476,7 +479,10 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 								bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) &&
 								bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) &&
 																				 faded_visibility > 0.0f);
 																				 faded_visibility > 0.0f);
 
 
+								const bool previously_visible = visible;
+
 								for (int j = 0; j < fx_stack.size(); j++) {
 								for (int j = 0; j < fx_stack.size(); j++) {
+
 									ItemFX *item_fx = fx_stack[j];
 									ItemFX *item_fx = fx_stack[j];
 
 
 									if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
 									if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
@@ -570,6 +576,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 									} else {
 									} else {
 										cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color);
 										cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color);
 									}
 									}
+								} else if (previously_visible) {
+									backtrack += font->get_char_size(fx_char, c[i + 1]).x;
 								}
 								}
 
 
 								p_char_count++;
 								p_char_count++;
@@ -643,6 +651,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 			case ITEM_NEWLINE: {
 			case ITEM_NEWLINE: {
 
 
 				lh = 0;
 				lh = 0;
+
 				if (p_mode != PROCESS_CACHE) {
 				if (p_mode != PROCESS_CACHE) {
 					lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
 					lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
 					line_is_blank = true;
 					line_is_blank = true;