浏览代码

Merge pull request #105504 from ExEago/master

`RichTextLabel`: Add methods to compute the height and width of a line
Thaddeus Crews 3 月之前
父节点
当前提交
4dbfcbfbbd
共有 3 个文件被更改,包括 57 次插入0 次删除
  1. 16 0
      doc/classes/RichTextLabel.xml
  2. 38 0
      scene/gui/rich_text_label.cpp
  3. 3 0
      scene/gui/rich_text_label.h

+ 16 - 0
doc/classes/RichTextLabel.xml

@@ -106,6 +106,14 @@
 				[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.
 			</description>
 		</method>
+		<method name="get_line_height" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="line" type="int" />
+			<description>
+				Returns the height of the line found at the provided index.
+				[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 the document is fully loaded.
+			</description>
+		</method>
 		<method name="get_line_offset">
 			<return type="float" />
 			<param index="0" name="line" type="int" />
@@ -123,6 +131,14 @@
 				[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.
 			</description>
 		</method>
+		<method name="get_line_width" qualifiers="const">
+			<return type="int" />
+			<param index="0" name="line" type="int" />
+			<description>
+				Returns the width of the line found at the provided index.
+				[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 the document is fully loaded.
+			</description>
+		</method>
 		<method name="get_menu" qualifiers="const">
 			<return type="PopupMenu" />
 			<description>

+ 38 - 0
scene/gui/rich_text_label.cpp

@@ -7089,6 +7089,41 @@ int RichTextLabel::get_content_width() const {
 	return total_width;
 }
 
+int RichTextLabel::get_line_height(int p_line) const {
+	const_cast<RichTextLabel *>(this)->_validate_line_caches();
+
+	int line_count = 0;
+	int to_line = main->first_invalid_line.load();
+	for (int i = 0; i < to_line; i++) {
+		MutexLock lock(main->lines[i].text_buf->get_mutex());
+		int lc = main->lines[i].text_buf->get_line_count();
+
+		if (p_line < line_count + lc) {
+			const Ref<TextParagraph> text_buf = main->lines[i].text_buf;
+			return text_buf->get_line_ascent(p_line - line_count) + text_buf->get_line_descent(p_line - line_count) + theme_cache.line_separation;
+		}
+		line_count += lc;
+	}
+	return 0;
+}
+
+int RichTextLabel::get_line_width(int p_line) const {
+	const_cast<RichTextLabel *>(this)->_validate_line_caches();
+
+	int line_count = 0;
+	int to_line = main->first_invalid_line.load();
+	for (int i = 0; i < to_line; i++) {
+		MutexLock lock(main->lines[i].text_buf->get_mutex());
+		int lc = main->lines[i].text_buf->get_line_count();
+
+		if (p_line < line_count + lc) {
+			return main->lines[i].text_buf->get_line_width(p_line - line_count);
+		}
+		line_count += lc;
+	}
+	return 0;
+}
+
 #ifndef DISABLE_DEPRECATED
 // People will be very angry, if their texts get erased, because of #39148. (3.x -> 4.0)
 // Although some people may not used bbcode_text, so we only overwrite, if bbcode_text is not empty.
@@ -7260,6 +7295,9 @@ void RichTextLabel::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height);
 	ClassDB::bind_method(D_METHOD("get_content_width"), &RichTextLabel::get_content_width);
 
+	ClassDB::bind_method(D_METHOD("get_line_height", "line"), &RichTextLabel::get_line_height);
+	ClassDB::bind_method(D_METHOD("get_line_width", "line"), &RichTextLabel::get_line_width);
+
 	ClassDB::bind_method(D_METHOD("get_line_offset", "line"), &RichTextLabel::get_line_offset);
 	ClassDB::bind_method(D_METHOD("get_paragraph_offset", "paragraph"), &RichTextLabel::get_paragraph_offset);
 

+ 3 - 0
scene/gui/rich_text_label.h

@@ -849,6 +849,9 @@ public:
 	int get_content_height() const;
 	int get_content_width() const;
 
+	int get_line_height(int p_line) const;
+	int get_line_width(int p_line) const;
+
 	void scroll_to_selection();
 
 	VScrollBar *get_v_scroll_bar() { return vscroll; }