소스 검색

Fix bad rendering of BBCode tables in `RichTextLabel`

Text overflowed canvas as tables didn't calculate correctly the width
of their columns. They used the whole table width available for each
column. Also, the `cell` parameter was wrongly parsed if used with its
optional argument (expand ratio).

This PR fixs the parsing of `cell` parameter (i.e. `cell=e`) and the
distribution of the full table width between columns, but it overrides
automatically the `expand` flag if the column is smaller than it could
be, to allow a better UX out-of-the-box. It keeps the `expand_ratio`
flag to let the user customize how every column grows in relation to
the rest.

Partially fix #6289.
robfram 7 년 전
부모
커밋
5358befb41
2개의 변경된 파일10개의 추가작업 그리고 3개의 파일을 삭제
  1. 8 3
      scene/gui/rich_text_label.cpp
  2. 2 0
      scene/gui/rich_text_label.h

+ 8 - 3
scene/gui/rich_text_label.cpp

@@ -125,6 +125,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 		l.descent_caches.clear();
 		l.char_count = 0;
 		l.minimum_width = 0;
+		l.maximum_width = 0;
 	}
 
 	int wofs = margin;
@@ -200,7 +201,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 
 #define ENSURE_WIDTH(m_width)                                                                                                                                   \
 	if (p_mode == PROCESS_CACHE) {                                                                                                                              \
-		l.minimum_width = MAX(l.minimum_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);                                                                                                        \
 	}                                                                                                                                                           \
 	if (wofs + m_width > p_width) {                                                                                                                             \
 		if (p_mode == PROCESS_CACHE) {                                                                                                                          \
@@ -469,6 +471,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 					//set minimums to zero
 					for (int i = 0; i < table->columns.size(); i++) {
 						table->columns[i].min_width = 0;
+						table->columns[i].max_width = 0;
 						table->columns[i].width = 0;
 					}
 					//compute minimum width for each cell
@@ -486,6 +489,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 
 							_process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color());
 							table->columns[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width);
+							table->columns[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width);
 						}
 						idx++;
 					}
@@ -498,12 +502,13 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
 
 					for (int i = 0; i < table->columns.size(); i++) {
 						remaining_width -= table->columns[i].min_width;
+						if (table->columns[i].max_width > table->columns[i].min_width)
+							table->columns[i].expand = true;
 						if (table->columns[i].expand)
 							total_ratio += table->columns[i].expand_ratio;
 					}
 
 					//assign actual widths
-
 					for (int i = 0; i < table->columns.size(); i++) {
 						table->columns[i].width = table->columns[i].min_width;
 						if (table->columns[i].expand)
@@ -1633,7 +1638,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
 			tag_stack.push_front(tag);
 		} else if (tag.begins_with("cell=")) {
 
-			int ratio = tag.substr(6, tag.length()).to_int();
+			int ratio = tag.substr(5, tag.length()).to_int();
 			if (ratio < 1)
 				ratio = 1;
 			//use monospace font

+ 2 - 0
scene/gui/rich_text_label.h

@@ -87,6 +87,7 @@ private:
 		int height_accum_cache;
 		int char_count;
 		int minimum_width;
+		int maximum_width;
 
 		Line() {
 			from = NULL;
@@ -199,6 +200,7 @@ private:
 			bool expand;
 			int expand_ratio;
 			int min_width;
+			int max_width;
 			int width;
 		};