Skip to content

Commit c2ddb04

Browse files
committed
Merge pull request #108466 from bruvzg/rtl_vis_rect
[RTL] Add method to get visible content bounding box.
2 parents b3416c7 + 406a22d commit c2ddb04

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

doc/classes/RichTextLabel.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,15 @@
104104
<return type="int" />
105105
<description>
106106
Returns the height of the content.
107+
[b]Note:[/b] This method always returns the full content size, and is not affected by [member visible_ratio] and [member visible_characters]. To get the visible content size, use [method get_visible_content_rect].
107108
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_finished] or [signal finished] to determine whether document is fully loaded.
108109
</description>
109110
</method>
110111
<method name="get_content_width" qualifiers="const">
111112
<return type="int" />
112113
<description>
113114
Returns the width of the content.
115+
[b]Note:[/b] This method always returns the full content size, and is not affected by [member visible_ratio] and [member visible_characters]. To get the visible content size, use [method get_visible_content_rect].
114116
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_finished] or [signal finished] to determine whether document is fully loaded.
115117
</description>
116118
</method>
@@ -257,17 +259,52 @@
257259
[b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member CanvasItem.visible] property.
258260
</description>
259261
</method>
262+
<method name="get_visible_content_rect" qualifiers="const">
263+
<return type="Rect2i" />
264+
<description>
265+
Returns the bounding rectangle of the visible content.
266+
[b]Note:[/b] This method returns a correct value only after the label has been drawn.
267+
[codeblocks]
268+
[gdscript]
269+
extends RichTextLabel
270+
271+
@export var background_panel: Panel
272+
273+
func _ready():
274+
await draw
275+
background_panel.position = get_visible_content_rect().position
276+
background_panel.size = get_visible_content_rect().size
277+
[/gdscript]
278+
[csharp]
279+
public partial class TestLabel : RichTextLabel
280+
{
281+
[Export]
282+
public Panel BackgroundPanel { get; set; }
283+
284+
public override async void _Ready()
285+
{
286+
await ToSignal(this, Control.SignalName.Draw);
287+
BackgroundGPanel.Position = GetVisibleContentRect().Position;
288+
BackgroundPanel.Size = GetVisibleContentRect().Size;
289+
}
290+
}
291+
[/csharp]
292+
[/codeblocks]
293+
</description>
294+
</method>
260295
<method name="get_visible_line_count" qualifiers="const">
261296
<return type="int" />
262297
<description>
263298
Returns the number of visible lines.
299+
[b]Note:[/b] This method returns a correct value only after the label has been drawn.
264300
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_finished] or [signal finished] to determine whether document is fully loaded.
265301
</description>
266302
</method>
267303
<method name="get_visible_paragraph_count" qualifiers="const">
268304
<return type="int" />
269305
<description>
270306
Returns the number of visible paragraphs. A paragraph is considered visible if at least one of its lines is visible.
307+
[b]Note:[/b] This method returns a correct value only after the label has been drawn.
271308
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_finished] or [signal finished] to determine whether document is fully loaded.
272309
</description>
273310
</method>

scene/gui/rich_text_label.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ RichTextLabel::ItemCustomFX::~ItemCustomFX() {
5858
custom_effect.unref();
5959
}
6060

61+
Rect2i _merge_or_copy_rect(const Rect2i &p_a, const Rect2i &p_b) {
62+
if (!p_a.has_area()) {
63+
return p_b;
64+
} else {
65+
return p_a.merge(p_b);
66+
}
67+
}
68+
6169
RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const {
6270
if (!p_item) {
6371
return nullptr;
@@ -986,8 +994,10 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
986994
Size2 pad_size = rect.size.min(img->image->get_size());
987995
Vector2 pad_off = (rect.size - pad_size) / 2;
988996
img->image->draw_rect(ci, Rect2(p_ofs + rect.position + off + pad_off, pad_size), false, img->color);
997+
visible_rect = _merge_or_copy_rect(visible_rect, Rect2(p_ofs + rect.position + off + pad_off, pad_size));
989998
} else {
990999
img->image->draw_rect(ci, Rect2(p_ofs + rect.position + off, rect.size), false, img->color);
1000+
visible_rect = _merge_or_copy_rect(visible_rect, Rect2(p_ofs + rect.position + off, rect.size));
9911001
}
9921002
} break;
9931003
case ITEM_TABLE: {
@@ -1358,6 +1368,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
13581368
if (!skip) {
13591369
if (txt_visible) {
13601370
has_visible_chars = true;
1371+
visible_rect = _merge_or_copy_rect(visible_rect, Rect2i(fx_offset + char_off - Vector2i(0, l_ascent), Point2i(glyphs[i].advance, l_size.y)));
13611372
if (step == DRAW_STEP_TEXT) {
13621373
if (frid != RID()) {
13631374
TS->font_draw_glyph(frid, ci, glyphs[i].font_size, fx_offset + char_off, gl, font_color);
@@ -2501,6 +2512,7 @@ void RichTextLabel::_notification(int p_what) {
25012512

25022513
visible_paragraph_count = 0;
25032514
visible_line_count = 0;
2515+
visible_rect = Rect2i();
25042516

25052517
// New cache draw.
25062518
Point2 ofs = text_rect.get_position() + Vector2(0, vbegin + main->lines[from_line].offset.y - vofs);
@@ -7258,6 +7270,10 @@ int RichTextLabel::get_content_height() const {
72587270
return total_height;
72597271
}
72607272

7273+
Rect2i RichTextLabel::get_visible_content_rect() const {
7274+
return visible_rect;
7275+
}
7276+
72617277
int RichTextLabel::get_content_width() const {
72627278
const_cast<RichTextLabel *>(this)->_validate_line_caches();
72637279

@@ -7480,6 +7496,8 @@ void RichTextLabel::_bind_methods() {
74807496
ClassDB::bind_method(D_METHOD("get_line_height", "line"), &RichTextLabel::get_line_height);
74817497
ClassDB::bind_method(D_METHOD("get_line_width", "line"), &RichTextLabel::get_line_width);
74827498

7499+
ClassDB::bind_method(D_METHOD("get_visible_content_rect"), &RichTextLabel::get_visible_content_rect);
7500+
74837501
ClassDB::bind_method(D_METHOD("get_line_offset", "line"), &RichTextLabel::get_line_offset);
74847502
ClassDB::bind_method(D_METHOD("get_paragraph_offset", "paragraph"), &RichTextLabel::get_paragraph_offset);
74857503

scene/gui/rich_text_label.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ class RichTextLabel : public Control {
536536
int current_char_ofs = 0;
537537
int visible_paragraph_count = 0;
538538
int visible_line_count = 0;
539+
Rect2i visible_rect;
539540

540541
int tab_size = 4;
541542
bool underline_meta = true;
@@ -871,6 +872,8 @@ class RichTextLabel : public Control {
871872
int get_line_height(int p_line) const;
872873
int get_line_width(int p_line) const;
873874

875+
Rect2i get_visible_content_rect() const;
876+
874877
void scroll_to_selection();
875878

876879
VScrollBar *get_v_scroll_bar() { return vscroll; }

0 commit comments

Comments
 (0)