Skip to content

Improve the table in RichTextLabel#116277

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Rindbee:improve-the-table-in-RichTextLabel
Feb 23, 2026
Merged

Improve the table in RichTextLabel#116277
Repiteo merged 1 commit intogodotengine:masterfrom
Rindbee:improve-the-table-in-RichTextLabel

Conversation

@Rindbee
Copy link
Contributor

@Rindbee Rindbee commented Feb 14, 2026

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.

2026-02-14_15-58

When shrink is true, 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 when shrink is false.

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

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; 13 padding.position.x of tabl_1 cell_1; 14 padding.size.x of 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 for TextParagraph.

Available width for TextParagraph is equal to the available width for table in the TextParagraph.

cell.width = table_h_separation + padding.position.x + padding.size.x + Available width for TextParagraph + line indents

column.*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 (not col_count - 1) * table_h_separation should be used.


The previous _set_table_size() method has been split into two methods: _update_table_column_width() is used to calculate the width allocation; _update_table_size() is used to calculate the offset.

_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.

Image
Before 2026-02-15_15-49
After 2026-02-15_15-50

As shown in the table above, table_h_separation/table_v_separation are used as padding for all cells in the table. They take effect simultaneously with custom padding in cells. Perhaps they should be used as margin?

Height calculation
2026-02-14_21-59

1~8 half of table_v_separation; 9,11,13,14,16 padding.position.y for different cells; 10,12,15,17 padding.size.y for 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).



@dalexeev dalexeev modified the milestones: 4.7, 4.x Feb 14, 2026
@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch from 84a4beb to 21ffbdd Compare February 15, 2026 01:14
@Rindbee Rindbee marked this pull request as ready for review February 15, 2026 04:08
@Rindbee Rindbee requested a review from a team as a code owner February 15, 2026 04:08
@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch from c2aa0de to 8b8b394 Compare February 15, 2026 04:36
@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch 2 times, most recently from 94c0c71 to 32408d4 Compare February 16, 2026 10:57
@mooflu
Copy link
Contributor

mooflu commented Feb 16, 2026

As shown in the table above, table_h_separation/table_v_separation are used as padding for all cells in the table. They take effect simultaneously with custom padding in cells. Perhaps they should be used as margin?

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.
My still buggy WIP (yours covers both cell padding and table separations, so I’ll stop working on mine)
e907b04

Played around with your changes and it behaves much more consistent than before 🎉
I did notice that horizontal cell padding can result in not matching the table box when text direction is set to right-to-left.
And cell border not showing up all around the cell.
RTL:
image

LTR:
image

[table=3] 
[cell padding=0,0,0,0  bg=red][center]brown fox lazy dog[/center][/cell]
[cell padding=10,0,0,0 bg=brown border=yellow][left]fox[/left][/cell]
[cell padding=10,0,0,0 bg=darkgreen][right]dog[/right][/cell]
[cell padding=10,0,0,0 bg=brown border=yellow][left]fox[/left][/cell]
[cell padding=0,0,0,0  bg=red][center]brown fox lazy dog[/center][/cell]
[cell padding=10,0,0,0 bg=darkgreen][right]dog[/right][/cell]
[/table]

@Rindbee
Copy link
Contributor Author

Rindbee commented Feb 17, 2026

I was looking into making table separations work consistently like margins. I.e. cell’s background color isn’t applied to it.

Do you mean cellspacing in HTML?

I did notice that horizontal cell padding can result in not matching the table box when text direction is set to right-to-left.

Regarding RTL, since the table is inline, and the RichTextLabel doesn't flip the other text horizontally after enabling RTL, I'm unsure at what step its Rect calculation reaches. Is its flip center the table center or the frame center?

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.

I did notice that horizontal cell padding can result in not matching the table box when text direction is set to right-to-left.

Unable to reproduce.

And cell border not showing up all around the cell.

Peek.2026-02-17.10-34.mp4

The border not displaying may be due to floating-point precision.

@mooflu
Copy link
Contributor

mooflu commented Feb 17, 2026

Do you mean cellspacing in HTML?

yes, or border-spacing in css

The border not displaying may be due to floating-point precision.

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.mp4

jsfiddle to show rtl/ltr behavior for html/css. Click on the table to toggle ltr/rtl.
https://jsfiddle.net/tue6m0rb/6/

@Rindbee
Copy link
Contributor Author

Rindbee commented Feb 17, 2026

Peek.2026-02-17.12-26.mp4

The 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

@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch from 32408d4 to 5f45bc7 Compare February 17, 2026 06:34
@Rindbee
Copy link
Contributor Author

Rindbee commented Feb 17, 2026

Peek.2026-02-17.14-42.mp4

Flip only within the table rect (the table is treated as a character).

@bruvzg bruvzg self-requested a review February 17, 2026 06:45
@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch 2 times, most recently from 6015f0d to 61a511e Compare February 17, 2026 08:07
The table should be neat and tidy.
@Rindbee Rindbee force-pushed the improve-the-table-in-RichTextLabel branch from 61a511e to 10a91ca Compare February 18, 2026 01:10
Comment on lines +1213 to +1216
// 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;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Repiteo Repiteo merged commit 9a1a0e9 into godotengine:master Feb 23, 2026
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Feb 23, 2026

Thanks!

@Rindbee Rindbee deleted the improve-the-table-in-RichTextLabel branch February 23, 2026 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing space to the right of code blocks in editor help RichTextLabel BBCode table background color can extend beyond parent's bounds

6 participants