Improve the table in RichTextLabel#116277
Conversation
84a4beb to
21ffbdd
Compare
c2aa0de to
8b8b394
Compare
94c0c71 to
32408d4
Compare
I think they should. Behaving more like a html/css table would be more familiar to most devs. I was looking into making table separations work consistently like margins. I.e. cell’s background color isn’t applied to it. Played around with your changes and it behaves much more consistent than before 🎉 |
Do you mean
Regarding RTL, since the table is inline, and the This may need to be calculated along with other text. I'm not very familiar with RTL. Although some ancient Chinese books are read from right to left, they are actually read from top to bottom, then from right to left. This is different from RTL. Some ancient texts (calligraphy and painting) used as titles may appear to be RTL, but they can also be considered as one character per line. In short, this is not common in Chinese books.
Unable to reproduce.
Peek.2026-02-17.10-34.mp4The border not displaying may be due to floating-point precision. |
yes, or
Sorry if I wasn't clear. In RTL only using RichTextLabel's text direction. I would expect borders to show at 100% zoom like with LTR. Probably because of cell overlap in RTL. This is what I see when I toggle RichTextLabel's text direction: ltr_rtl_table.mp4jsfiddle to show rtl/ltr behavior for html/css. Click on the table to toggle ltr/rtl. |
Peek.2026-02-17.12-26.mp4The second table shows that it is inline. Furthermore, the other elements within the line are not sorted from right to left. This behavior is somewhat inconsistent. I'm not sure about its expected behavior either. Is it simply a matter of flipping the table layout horizontally in place? It seems that if other elements in the same row aren't flipped, this is the only option. The Chinese character order isn't flipped, but the Chinese punctuation is. Confusing. Peek.2026-02-17.13-05.mp4 |
32408d4 to
5f45bc7
Compare
Peek.2026-02-17.14-42.mp4Flip only within the table rect (the table is treated as a character). |
6015f0d to
61a511e
Compare
The table should be neat and tidy.
61a511e to
10a91ca
Compare
| // To prevent the border of the right cell from being covered. | ||
| cell_rect.size.x -= 1; | ||
| draw_rect(cell_rect, row_bg, true); | ||
| cell_rect.size.x += 1; |
There was a problem hiding this comment.
The drawn border will extend beyond the rect on the left and top sides.
In RTL, because cells in a row are drawn from right to left, the border of the right cell may be covered by the background color of the left cell.
|
Thanks! |


This PR uses an algorithm similar to that in
BoxContainer::_resort()to allocate the available width. It makes the table occupy as much of the available width as possible.When
shrinkistrue, it ensures that if the width has reached the maximum width, it will not expand (even if an expand ratio is specified). If the maximum width is not reached, the behavior is similar to whenshrinkisfalse.When the maximum width of a column is greater than its minimum width,
expand=1(if not specified) will be enabled automatically.The minimum and maximum widths of columns take into account the case of nested tables.
Width calculation
1,2 stylebox border widths; 3 the width of the scroll bar; 4 line indent; 5,6,7,8,9,10,11,12 half of
table_h_separation; 13padding.position.xof tabl_1 cell_1; 14padding.size.xof tabl_1 cell_1; 15,17,19 same as 13, but for different cells; 16,18,20 same as 14, but for different cells; 21,22,23 available width forTextParagraph.Available width for
TextParagraphis equal to the available width for table in theTextParagraph.cell.width=table_h_separation+padding.position.x+padding.size.x+Available width for TextParagraph+ line indentscolumn.*width=max(cell.*width)in the same column.table.*width=sum(columns.*width).Since padding may vary from cell to cell, the maximum and minimum width of a column is calculated from the left border to the right border (exclude
table_h_separation).The width of the outermost cell should be calculated recursively for the width of the nested tables within it.
Note: If the offset is calculated according to #93140, then
col_count(notcol_count - 1) *table_h_separationshould be used.The previous
_set_table_size()method has been split into two methods:_update_table_column_width()is used to calculate thewidthallocation;_update_table_size()is used to calculate theoffset._update_table_column_width()should be called after calculating the maximum and minimum widths, and before resizing the elements (_resize_line()) within the table. This ensures that nested tables are allocated the ideal width, rather than being divided equally according to the ratios.While meeting the above width requirements, this PR minimizes the height occupied by the table.
As shown in the table above,
table_h_separation/table_v_separationare used as padding for all cells in the table. They take effect simultaneously with custompaddingin cells. Perhaps they should be used as margin?Height calculation
1~8 half of
table_v_separation; 9,11,13,14,16padding.position.yfor different cells; 10,12,15,17padding.size.yfor different cells; 18,19,20,21 height of different TextParagraph.cell.height=table_v_separation+padding.position.y+padding.size.y+TextParagraph.y+line_separations +paragraph_separation.row.height=max(cell.height)in the same row.table.height=sum(rows.height).RichTextLabelBBCode table background color can extend beyond parent's bounds #115833.