[RTL] Use separate paragraph copy for the partially visible paragraphs.

This commit is contained in:
Pāvels Nadtočajevs 2025-09-09 10:35:16 +03:00
parent 019889d1da
commit 0d19e18b00
No known key found for this signature in database
GPG key ID: 8413210218EF35D2
19 changed files with 346 additions and 51 deletions

View file

@ -33,6 +33,7 @@
void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &TextLine::clear);
ClassDB::bind_method(D_METHOD("duplicate"), &TextLine::duplicate);
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &TextLine::set_direction);
ClassDB::bind_method(D_METHOD("get_direction"), &TextLine::get_direction);
@ -64,6 +65,7 @@ void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextLine::add_string, DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length", "baseline"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align", "baseline"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("has_object", "key"), &TextLine::has_object);
ClassDB::bind_method(D_METHOD("set_width", "width"), &TextLine::set_width);
ClassDB::bind_method(D_METHOD("get_width"), &TextLine::get_width);
@ -149,6 +151,23 @@ void TextLine::clear() {
TS->shaped_text_clear(rid);
}
Ref<TextLine> TextLine::duplicate() const {
Ref<TextLine> copy;
copy.instantiate();
if (rid.is_valid()) {
copy->rid = TS->shaped_text_duplicate(rid);
}
copy->dirty = true;
copy->width = width;
copy->flags = flags;
copy->alignment = alignment;
copy->el_char = el_char;
copy->overrun_behavior = overrun_behavior;
copy->tab_stops = tab_stops;
return copy;
}
void TextLine::set_preserve_invalid(bool p_enabled) {
TS->shaped_text_set_preserve_invalid(rid, p_enabled);
dirty = true;
@ -212,6 +231,11 @@ bool TextLine::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment
return TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align, p_baseline);
}
bool TextLine::has_object(Variant p_key) const {
_shape();
return TS->shaped_text_has_object(rid, p_key);
}
Array TextLine::get_objects() const {
return TS->shaped_text_get_objects(rid);
}

View file

@ -66,6 +66,7 @@ public:
RID get_rid() const;
void clear();
Ref<TextLine> duplicate() const;
void set_direction(TextServer::Direction p_direction);
TextServer::Direction get_direction() const;
@ -85,6 +86,7 @@ public:
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1, float p_baseline = 0.0);
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0);
bool has_object(Variant p_key) const;
void set_horizontal_alignment(HorizontalAlignment p_alignment);
HorizontalAlignment get_horizontal_alignment() const;

View file

@ -33,6 +33,7 @@
void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &TextParagraph::clear);
ClassDB::bind_method(D_METHOD("duplicate"), &TextParagraph::duplicate);
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &TextParagraph::set_direction);
ClassDB::bind_method(D_METHOD("get_direction"), &TextParagraph::get_direction);
@ -72,6 +73,7 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextParagraph::add_string, DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length", "baseline"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align", "baseline"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("has_object", "key"), &TextParagraph::has_object);
ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &TextParagraph::set_alignment);
ClassDB::bind_method(D_METHOD("get_alignment"), &TextParagraph::get_alignment);
@ -322,6 +324,31 @@ void TextParagraph::clear() {
TS->shaped_text_clear(dropcap_rid);
}
Ref<TextParagraph> TextParagraph::duplicate() const {
Ref<TextParagraph> copy;
copy.instantiate();
if (dropcap_rid.is_valid()) {
copy->dropcap_rid = TS->shaped_text_duplicate(dropcap_rid);
}
copy->dropcap_lines = dropcap_lines;
copy->dropcap_margins = dropcap_margins;
if (rid.is_valid()) {
copy->rid = TS->shaped_text_duplicate(rid);
}
copy->lines_dirty = true;
copy->line_spacing = line_spacing;
copy->width = width;
copy->max_lines_visible = max_lines_visible;
copy->brk_flags = brk_flags;
copy->jst_flags = jst_flags;
copy->el_char = el_char;
copy->overrun_behavior = overrun_behavior;
copy->alignment = alignment;
copy->tab_stops = tab_stops;
return copy;
}
void TextParagraph::set_preserve_invalid(bool p_enabled) {
_THREAD_SAFE_METHOD_
@ -448,6 +475,12 @@ bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlig
return res;
}
bool TextParagraph::has_object(Variant p_key) const {
_THREAD_SAFE_METHOD_
return TS->shaped_text_has_object(rid, p_key);
}
void TextParagraph::set_alignment(HorizontalAlignment p_alignment) {
_THREAD_SAFE_METHOD_

View file

@ -85,6 +85,8 @@ public:
void clear();
Ref<TextParagraph> duplicate() const;
void set_direction(TextServer::Direction p_direction);
TextServer::Direction get_direction() const;
TextServer::Direction get_inferred_direction() const;
@ -109,6 +111,7 @@ public:
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1, float p_baseline = 0.0);
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, float p_baseline = 0.0);
bool has_object(Variant p_key) const;
void set_alignment(HorizontalAlignment p_alignment);
HorizontalAlignment get_alignment() const;