mirror of
https://github.com/godotengine/godot
synced 2024-09-05 16:56:44 +00:00
[RTL] Add support for shaping in background thread.
This commit is contained in:
parent
5631b59e21
commit
cfcdfc38e2
|
@ -60,6 +60,7 @@
|
|||
<argument index="0" name="character" type="int" />
|
||||
<description>
|
||||
Returns the line number of the character position provided.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_character_paragraph">
|
||||
|
@ -67,24 +68,28 @@
|
|||
<argument index="0" name="character" type="int" />
|
||||
<description>
|
||||
Returns the paragraph number of the character position provided.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_content_height" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the height of the content.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_content_width" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the width of the content.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_line_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the total number of lines in the text. Wrapped text is counted as multiple lines.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_line_offset">
|
||||
|
@ -92,6 +97,7 @@
|
|||
<argument index="0" name="line" type="int" />
|
||||
<description>
|
||||
Returns the vertical offset 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_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_menu" qualifiers="const">
|
||||
|
@ -112,6 +118,7 @@
|
|||
<argument index="0" name="paragraph" type="int" />
|
||||
<description>
|
||||
Returns the vertical offset of the paragraph 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_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_parsed_text" qualifiers="const">
|
||||
|
@ -155,12 +162,14 @@
|
|||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of visible lines.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_visible_paragraph_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of visible paragraphs. A paragraph is considered visible if at least one of its lines is visible.
|
||||
[b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded.
|
||||
</description>
|
||||
</method>
|
||||
<method name="install_effect">
|
||||
|
@ -176,6 +185,12 @@
|
|||
Returns whether the menu is visible. Use this instead of [code]get_menu().visible[/code] to improve performance (so the creation of the menu is avoided).
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_ready" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
If [member threaded] is enabled, returns [code]true[/code] if the background thread has finished text processing, otherwise always return [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="newline">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
@ -476,6 +491,10 @@
|
|||
The range of characters to display, as a [float] between 0.0 and 1.0. When assigned an out of range value, it's the same as assigning 1.0.
|
||||
[b]Note:[/b] Setting this property updates [member visible_characters] based on current [method get_total_character_count].
|
||||
</member>
|
||||
<member name="progress_bar_delay" type="int" setter="set_progress_bar_delay" getter="get_progress_bar_delay" default="1000">
|
||||
The delay after which the loading progress bar is displayed, in milliseconds. Set to [code]-1[/code] to disable progress bar entirely.
|
||||
[b]Note:[/b] Progress bar is dislayed only if [member threaded] is enabled.
|
||||
</member>
|
||||
<member name="scroll_active" type="bool" setter="set_scroll_active" getter="is_scroll_active" default="true">
|
||||
If [code]true[/code], the scrollbar is visible. Setting this to [code]false[/code] does not block scrolling completely. See [method scroll_to_line].
|
||||
</member>
|
||||
|
@ -504,6 +523,9 @@
|
|||
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
|
||||
Base text writing direction.
|
||||
</member>
|
||||
<member name="threaded" type="bool" setter="set_threaded" getter="is_threaded" default="false">
|
||||
If [code]true[/code], text processing is done in a background thread.
|
||||
</member>
|
||||
<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1">
|
||||
The restricted number of characters to display in the label. If [code]-1[/code], all characters will be displayed.
|
||||
[b]Note:[/b] Setting this property updates [member percent_visible] based on current [method get_total_character_count].
|
||||
|
@ -513,6 +535,11 @@
|
|||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="finished">
|
||||
<description>
|
||||
Triggered when the document is fully loaded.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="meta_clicked">
|
||||
<argument index="0" name="meta" type="Variant" />
|
||||
<description>
|
||||
|
|
|
@ -196,6 +196,7 @@ EditorAbout::EditorAbout() {
|
|||
// License
|
||||
|
||||
_license_text = memnew(RichTextLabel);
|
||||
_license_text->set_threaded(true);
|
||||
_license_text->set_name(TTR("License"));
|
||||
_license_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
_license_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
@ -272,6 +273,7 @@ EditorAbout::EditorAbout() {
|
|||
tpl_hbc->add_child(_tpl_tree);
|
||||
|
||||
_tpl_text = memnew(RichTextLabel);
|
||||
_tpl_text->set_threaded(true);
|
||||
_tpl_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
_tpl_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
tpl_hbc->add_child(_tpl_text);
|
||||
|
|
|
@ -235,7 +235,7 @@ String EditorHelp::_fix_constant(const String &p_constant) const {
|
|||
}
|
||||
|
||||
void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview) {
|
||||
method_line[p_method.name] = class_desc->get_line_count() - 2; //gets overridden if description
|
||||
method_line[p_method.name] = class_desc->get_paragraph_count() - 2; //gets overridden if description
|
||||
|
||||
const bool is_vararg = p_method.qualifiers.contains("vararg");
|
||||
|
||||
|
@ -593,8 +593,8 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Class description
|
||||
if (!cd.description.is_empty()) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_line_count() - 2));
|
||||
description_line = class_desc->get_line_count() - 2;
|
||||
section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_paragraph_count() - 2));
|
||||
description_line = class_desc->get_paragraph_count() - 2;
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Description"));
|
||||
|
@ -664,7 +664,7 @@ void EditorHelp::_update_doc() {
|
|||
}
|
||||
|
||||
if (has_properties) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Properties"));
|
||||
|
@ -682,7 +682,7 @@ void EditorHelp::_update_doc() {
|
|||
if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
|
||||
property_line[cd.properties[i].name] = class_desc->get_paragraph_count() - 2; //gets overridden if description
|
||||
|
||||
// Property type.
|
||||
class_desc->push_cell();
|
||||
|
@ -828,7 +828,7 @@ void EditorHelp::_update_doc() {
|
|||
cd.constructors.sort();
|
||||
}
|
||||
|
||||
section_line.push_back(Pair<String, int>(TTR("Constructors"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Constructors"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Constructors"));
|
||||
|
@ -839,7 +839,7 @@ void EditorHelp::_update_doc() {
|
|||
if (sort_methods) {
|
||||
methods.sort();
|
||||
}
|
||||
section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Methods"));
|
||||
|
@ -851,7 +851,7 @@ void EditorHelp::_update_doc() {
|
|||
cd.operators.sort();
|
||||
}
|
||||
|
||||
section_line.push_back(Pair<String, int>(TTR("Operators"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Operators"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Operators"));
|
||||
|
@ -860,7 +860,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Theme properties
|
||||
if (!cd.theme_properties.is_empty()) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Theme Properties"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Theme Properties"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Theme Properties"));
|
||||
|
@ -882,7 +882,7 @@ void EditorHelp::_update_doc() {
|
|||
data_type_names["style"] = TTR("Styles");
|
||||
|
||||
for (int i = 0; i < cd.theme_properties.size(); i++) {
|
||||
theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; // Gets overridden if description.
|
||||
theme_property_line[cd.theme_properties[i].name] = class_desc->get_paragraph_count() - 2; // Gets overridden if description.
|
||||
|
||||
if (theme_data_type != cd.theme_properties[i].data_type) {
|
||||
theme_data_type = cd.theme_properties[i].data_type;
|
||||
|
@ -954,7 +954,7 @@ void EditorHelp::_update_doc() {
|
|||
cd.signals.sort();
|
||||
}
|
||||
|
||||
section_line.push_back(Pair<String, int>(TTR("Signals"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Signals"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Signals"));
|
||||
|
@ -967,7 +967,7 @@ void EditorHelp::_update_doc() {
|
|||
class_desc->push_indent(1);
|
||||
|
||||
for (int i = 0; i < cd.signals.size(); i++) {
|
||||
signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; // Gets overridden if description.
|
||||
signal_line[cd.signals[i].name] = class_desc->get_paragraph_count() - 2; // Gets overridden if description.
|
||||
|
||||
class_desc->push_font(doc_code_font); // monofont
|
||||
class_desc->push_color(headline_color);
|
||||
|
@ -1040,7 +1040,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Enums
|
||||
if (enums.size()) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Enumerations"));
|
||||
|
@ -1051,7 +1051,7 @@ void EditorHelp::_update_doc() {
|
|||
class_desc->add_newline();
|
||||
|
||||
for (KeyValue<String, Vector<DocData::ConstantDoc>> &E : enums) {
|
||||
enum_line[E.key] = class_desc->get_line_count() - 2;
|
||||
enum_line[E.key] = class_desc->get_paragraph_count() - 2;
|
||||
|
||||
class_desc->push_font(doc_code_font);
|
||||
class_desc->push_color(title_color);
|
||||
|
@ -1098,7 +1098,7 @@ void EditorHelp::_update_doc() {
|
|||
}
|
||||
|
||||
// Add the enum constant line to the constant_line map so we can locate it as a constant.
|
||||
constant_line[enum_list[i].name] = class_desc->get_line_count() - 2;
|
||||
constant_line[enum_list[i].name] = class_desc->get_paragraph_count() - 2;
|
||||
|
||||
class_desc->push_font(doc_code_font);
|
||||
class_desc->push_color(headline_color);
|
||||
|
@ -1144,7 +1144,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Constants
|
||||
if (constants.size()) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Constants"));
|
||||
|
@ -1155,7 +1155,7 @@ void EditorHelp::_update_doc() {
|
|||
class_desc->add_newline();
|
||||
|
||||
for (int i = 0; i < constants.size(); i++) {
|
||||
constant_line[constants[i].name] = class_desc->get_line_count() - 2;
|
||||
constant_line[constants[i].name] = class_desc->get_paragraph_count() - 2;
|
||||
class_desc->push_font(doc_code_font);
|
||||
|
||||
if (constants[i].value.begins_with("Color(") && constants[i].value.ends_with(")")) {
|
||||
|
@ -1205,7 +1205,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Property descriptions
|
||||
if (property_descr) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Property Descriptions"));
|
||||
|
@ -1220,7 +1220,7 @@ void EditorHelp::_update_doc() {
|
|||
continue;
|
||||
}
|
||||
|
||||
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2;
|
||||
property_line[cd.properties[i].name] = class_desc->get_paragraph_count() - 2;
|
||||
|
||||
class_desc->push_table(2);
|
||||
class_desc->set_table_column_expand(1, true);
|
||||
|
@ -1371,7 +1371,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Constructor descriptions
|
||||
if (constructor_descriptions) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Constructor Descriptions"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Constructor Descriptions"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Constructor Descriptions"));
|
||||
|
@ -1380,7 +1380,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Method descriptions
|
||||
if (method_descriptions) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Method Descriptions"));
|
||||
|
@ -1389,7 +1389,7 @@ void EditorHelp::_update_doc() {
|
|||
|
||||
// Operator descriptions
|
||||
if (operator_descriptions) {
|
||||
section_line.push_back(Pair<String, int>(TTR("Operator Descriptions"), class_desc->get_line_count() - 2));
|
||||
section_line.push_back(Pair<String, int>(TTR("Operator Descriptions"), class_desc->get_paragraph_count() - 2));
|
||||
class_desc->push_color(title_color);
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text(TTR("Operator Descriptions"));
|
||||
|
@ -1868,6 +1868,7 @@ EditorHelp::EditorHelp() {
|
|||
|
||||
class_desc = memnew(RichTextLabel);
|
||||
add_child(class_desc);
|
||||
class_desc->set_threaded(true);
|
||||
class_desc->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
class_desc->add_theme_color_override("selection_color", get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.4));
|
||||
|
||||
|
|
|
@ -1691,6 +1691,8 @@ hb_font_t *TextServerAdvanced::_font_get_hb_handle(const RID &p_font_rid, int64_
|
|||
}
|
||||
|
||||
RID TextServerAdvanced::create_font() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
FontDataAdvanced *fd = memnew(FontDataAdvanced);
|
||||
|
||||
return font_owner.make_rid(fd);
|
||||
|
@ -3359,6 +3361,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
|
|||
|
||||
RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ShapedTextDataAdvanced *sd = memnew(ShapedTextDataAdvanced);
|
||||
sd->hb_buffer = hb_buffer_create();
|
||||
sd->direction = p_direction;
|
||||
|
@ -3748,6 +3751,8 @@ void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
|
|||
}
|
||||
|
||||
RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_COND_V(!sd, RID());
|
||||
|
||||
|
|
|
@ -853,6 +853,8 @@ _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontDataFallback *p_fo
|
|||
}
|
||||
|
||||
RID TextServerFallback::create_font() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
FontDataFallback *fd = memnew(FontDataFallback);
|
||||
|
||||
return font_owner.make_rid(fd);
|
||||
|
@ -2429,6 +2431,7 @@ void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
|
|||
|
||||
RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ShapedTextDataFallback *sd = memnew(ShapedTextDataFallback);
|
||||
sd->direction = p_direction;
|
||||
sd->orientation = p_orientation;
|
||||
|
@ -2807,6 +2810,8 @@ void TextServerFallback::_realign(ShapedTextDataFallback *p_sd) const {
|
|||
}
|
||||
|
||||
RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
|
||||
ERR_FAIL_COND_V(!sd, RID());
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -141,10 +141,10 @@ private:
|
|||
struct ItemFrame : public Item {
|
||||
bool cell = false;
|
||||
|
||||
Vector<Line> lines;
|
||||
int first_invalid_line = 0;
|
||||
int first_invalid_font_line = 0;
|
||||
int first_resized_line = 0;
|
||||
LocalVector<Line> lines;
|
||||
std::atomic<int> first_invalid_line;
|
||||
std::atomic<int> first_invalid_font_line;
|
||||
std::atomic<int> first_resized_line;
|
||||
|
||||
ItemFrame *parent_frame = nullptr;
|
||||
|
||||
|
@ -155,7 +155,12 @@ private:
|
|||
Size2 max_size_over = Size2(-1, -1);
|
||||
Rect2 padding;
|
||||
|
||||
ItemFrame() { type = ITEM_FRAME; }
|
||||
ItemFrame() {
|
||||
type = ITEM_FRAME;
|
||||
first_invalid_line.store(0);
|
||||
first_invalid_font_line.store(0);
|
||||
first_resized_line.store(0);
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemText : public Item {
|
||||
|
@ -263,8 +268,8 @@ private:
|
|||
int width = 0;
|
||||
};
|
||||
|
||||
Vector<Column> columns;
|
||||
Vector<float> rows;
|
||||
LocalVector<Column> columns;
|
||||
LocalVector<float> rows;
|
||||
|
||||
int total_width = 0;
|
||||
int total_height = 0;
|
||||
|
@ -363,6 +368,16 @@ private:
|
|||
Item *current = nullptr;
|
||||
ItemFrame *current_frame = nullptr;
|
||||
|
||||
Thread thread;
|
||||
Mutex data_mutex;
|
||||
bool threaded = false;
|
||||
std::atomic<bool> stop_thread;
|
||||
std::atomic<bool> updating;
|
||||
std::atomic<double> loaded;
|
||||
|
||||
uint64_t loading_started = 0;
|
||||
int progress_delay = 1000;
|
||||
|
||||
VScrollBar *vscroll = nullptr;
|
||||
|
||||
AutowrapMode autowrap_mode = AUTOWRAP_WORD_SMART;
|
||||
|
@ -392,7 +407,11 @@ private:
|
|||
Array custom_effects;
|
||||
|
||||
void _invalidate_current_line(ItemFrame *p_frame);
|
||||
void _validate_line_caches(ItemFrame *p_frame);
|
||||
|
||||
static void _thread_function(void *self);
|
||||
void _stop_thread();
|
||||
bool _validate_line_caches();
|
||||
void _process_line_caches();
|
||||
|
||||
void _add_item(Item *p_item, bool p_enter = false, bool p_ensure_newline = false);
|
||||
void _remove_item(Item *p_item, const int p_line, const int p_subitem_line);
|
||||
|
@ -446,8 +465,9 @@ private:
|
|||
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
|
||||
bool _search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search);
|
||||
|
||||
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
|
||||
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
|
||||
float _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h, int *r_char_offset);
|
||||
float _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h);
|
||||
|
||||
void _update_line_font(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size);
|
||||
int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs);
|
||||
float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool p_table = false);
|
||||
|
@ -480,9 +500,9 @@ private:
|
|||
bool _find_layout_subitem(Item *from, Item *to);
|
||||
void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack);
|
||||
|
||||
void _update_scroll();
|
||||
void _update_fx(ItemFrame *p_frame, double p_delta_time);
|
||||
void _scroll_changed(double);
|
||||
int _find_first_line(int p_from, int p_to, int p_vofs) const;
|
||||
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
virtual String get_tooltip(const Point2 &p_pos) const override;
|
||||
|
@ -611,6 +631,14 @@ public:
|
|||
bool is_deselect_on_focus_loss_enabled() const;
|
||||
void deselect();
|
||||
|
||||
bool is_ready() const;
|
||||
|
||||
void set_threaded(bool p_threaded);
|
||||
bool is_threaded() const;
|
||||
|
||||
void set_progress_bar_delay(int p_delay_ms);
|
||||
int get_progress_bar_delay() const;
|
||||
|
||||
// Context menu.
|
||||
PopupMenu *get_menu() const;
|
||||
bool is_menu_visible() const;
|
||||
|
|
|
@ -139,7 +139,7 @@ void TextParagraph::_bind_methods() {
|
|||
|
||||
void TextParagraph::_shape_lines() {
|
||||
if (lines_dirty) {
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
TS->free_rid(lines_rid[i]);
|
||||
}
|
||||
lines_rid.clear();
|
||||
|
@ -218,14 +218,14 @@ void TextParagraph::_shape_lines() {
|
|||
|
||||
// Fill after min_size calculation.
|
||||
if (autowrap_enabled) {
|
||||
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, lines_rid.size()) : lines_rid.size();
|
||||
bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size();
|
||||
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, (int)lines_rid.size()) : (int)lines_rid.size();
|
||||
bool lines_hidden = visible_lines > 0 && visible_lines < (int)lines_rid.size();
|
||||
if (lines_hidden) {
|
||||
overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
|
||||
}
|
||||
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
if (i < visible_lines - 1 || lines_rid.size() == 1) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
if (i < visible_lines - 1 || (int)lines_rid.size() == 1) {
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
|
||||
} else if (i == (visible_lines - 1)) {
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags);
|
||||
|
@ -238,7 +238,7 @@ void TextParagraph::_shape_lines() {
|
|||
|
||||
} else {
|
||||
// Autowrap disabled.
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], width, flags);
|
||||
overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
|
||||
|
@ -258,8 +258,10 @@ RID TextParagraph::get_rid() const {
|
|||
}
|
||||
|
||||
RID TextParagraph::get_line_rid(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), RID());
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), RID());
|
||||
return lines_rid[p_line];
|
||||
}
|
||||
|
||||
|
@ -268,9 +270,11 @@ RID TextParagraph::get_dropcap_rid() const {
|
|||
}
|
||||
|
||||
void TextParagraph::clear() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
spacing_top = 0;
|
||||
spacing_bottom = 0;
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
TS->free_rid(lines_rid[i]);
|
||||
}
|
||||
lines_rid.clear();
|
||||
|
@ -279,57 +283,79 @@ void TextParagraph::clear() {
|
|||
}
|
||||
|
||||
void TextParagraph::set_preserve_invalid(bool p_enabled) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_preserve_invalid(rid, p_enabled);
|
||||
TS->shaped_text_set_preserve_invalid(dropcap_rid, p_enabled);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
bool TextParagraph::get_preserve_invalid() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return TS->shaped_text_get_preserve_invalid(rid);
|
||||
}
|
||||
|
||||
void TextParagraph::set_preserve_control(bool p_enabled) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_preserve_control(rid, p_enabled);
|
||||
TS->shaped_text_set_preserve_control(dropcap_rid, p_enabled);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
bool TextParagraph::get_preserve_control() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return TS->shaped_text_get_preserve_control(rid);
|
||||
}
|
||||
|
||||
void TextParagraph::set_direction(TextServer::Direction p_direction) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_direction(rid, p_direction);
|
||||
TS->shaped_text_set_direction(dropcap_rid, p_direction);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
TextServer::Direction TextParagraph::get_direction() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
return TS->shaped_text_get_direction(rid);
|
||||
}
|
||||
|
||||
void TextParagraph::set_custom_punctuation(const String &p_punct) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_custom_punctuation(rid, p_punct);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
String TextParagraph::get_custom_punctuation() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return TS->shaped_text_get_custom_punctuation(rid);
|
||||
}
|
||||
|
||||
void TextParagraph::set_orientation(TextServer::Orientation p_orientation) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_orientation(rid, p_orientation);
|
||||
TS->shaped_text_set_orientation(dropcap_rid, p_orientation);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
TextServer::Orientation TextParagraph::get_orientation() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
return TS->shaped_text_get_orientation(rid);
|
||||
}
|
||||
|
||||
bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins, const Dictionary &p_opentype_features, const String &p_language) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ERR_FAIL_COND_V(p_fonts.is_null(), false);
|
||||
TS->shaped_text_clear(dropcap_rid);
|
||||
dropcap_margins = p_dropcap_margins;
|
||||
|
@ -339,12 +365,16 @@ bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts,
|
|||
}
|
||||
|
||||
void TextParagraph::clear_dropcap() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
dropcap_margins = Rect2();
|
||||
TS->shaped_text_clear(dropcap_rid);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ERR_FAIL_COND_V(p_fonts.is_null(), false);
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language, p_meta);
|
||||
spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
|
||||
|
@ -362,23 +392,31 @@ int TextParagraph::get_spacing_bottom() const {
|
|||
}
|
||||
|
||||
void TextParagraph::set_bidi_override(const Array &p_override) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
TS->shaped_text_set_bidi_override(rid, p_override);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
bool TextParagraph::add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
bool res = TS->shaped_text_add_object(rid, p_key, p_size, p_inline_align, p_length);
|
||||
lines_dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool TextParagraph::resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
bool res = TS->shaped_text_resize_object(rid, p_key, p_size, p_inline_align);
|
||||
lines_dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
void TextParagraph::set_alignment(HorizontalAlignment p_alignment) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (alignment != p_alignment) {
|
||||
if (alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
|
||||
alignment = p_alignment;
|
||||
|
@ -394,11 +432,15 @@ HorizontalAlignment TextParagraph::get_alignment() const {
|
|||
}
|
||||
|
||||
void TextParagraph::tab_align(const Vector<float> &p_tab_stops) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
tab_stops = p_tab_stops;
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
void TextParagraph::set_flags(uint16_t p_flags) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (flags != p_flags) {
|
||||
flags = p_flags;
|
||||
lines_dirty = true;
|
||||
|
@ -410,6 +452,8 @@ uint16_t TextParagraph::get_flags() const {
|
|||
}
|
||||
|
||||
void TextParagraph::set_text_overrun_behavior(TextParagraph::OverrunBehavior p_behavior) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (overrun_behavior != p_behavior) {
|
||||
overrun_behavior = p_behavior;
|
||||
lines_dirty = true;
|
||||
|
@ -421,6 +465,8 @@ TextParagraph::OverrunBehavior TextParagraph::get_text_overrun_behavior() const
|
|||
}
|
||||
|
||||
void TextParagraph::set_width(float p_width) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (width != p_width) {
|
||||
width = p_width;
|
||||
lines_dirty = true;
|
||||
|
@ -432,6 +478,8 @@ float TextParagraph::get_width() const {
|
|||
}
|
||||
|
||||
Size2 TextParagraph::get_non_wrapped_size() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom);
|
||||
|
@ -441,9 +489,11 @@ Size2 TextParagraph::get_non_wrapped_size() const {
|
|||
}
|
||||
|
||||
Size2 TextParagraph::get_size() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
Size2 size;
|
||||
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, lines_rid.size()) : lines_rid.size();
|
||||
int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, (int)lines_rid.size()) : (int)lines_rid.size();
|
||||
for (int i = 0; i < visible_lines; i++) {
|
||||
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
|
@ -458,11 +508,15 @@ Size2 TextParagraph::get_size() const {
|
|||
}
|
||||
|
||||
int TextParagraph::get_line_count() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
return lines_rid.size();
|
||||
return (int)lines_rid.size();
|
||||
}
|
||||
|
||||
void TextParagraph::set_max_lines_visible(int p_lines) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (p_lines != max_lines_visible) {
|
||||
max_lines_visible = p_lines;
|
||||
lines_dirty = true;
|
||||
|
@ -474,14 +528,18 @@ int TextParagraph::get_max_lines_visible() const {
|
|||
}
|
||||
|
||||
Array TextParagraph::get_line_objects(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), Array());
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Array());
|
||||
return TS->shaped_text_get_objects(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), Rect2());
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Rect2());
|
||||
Rect2 xrect = TS->shaped_text_get_object_rect(lines_rid[p_line], p_key);
|
||||
for (int i = 0; i < p_line; i++) {
|
||||
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
|
||||
|
@ -495,8 +553,10 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
|
|||
}
|
||||
|
||||
Size2 TextParagraph::get_line_size(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), Size2());
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Size2());
|
||||
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y + spacing_top + spacing_bottom);
|
||||
} else {
|
||||
|
@ -505,42 +565,56 @@ Size2 TextParagraph::get_line_size(int p_line) const {
|
|||
}
|
||||
|
||||
Vector2i TextParagraph::get_line_range(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), Vector2i());
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Vector2i());
|
||||
return TS->shaped_text_get_range(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_ascent(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), 0.f);
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_descent(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), 0.f);
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_descent(lines_rid[p_line]) + spacing_bottom;
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_width(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), 0.f);
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_width(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_underline_position(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), 0.f);
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_underline_position(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_underline_thickness(int p_line) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines_rid.size(), 0.f);
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_underline_thickness(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
Size2 TextParagraph::get_dropcap_size() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return TS->shaped_text_get_size(dropcap_rid) + dropcap_margins.size + dropcap_margins.position;
|
||||
}
|
||||
|
||||
|
@ -549,6 +623,8 @@ int TextParagraph::get_dropcap_lines() const {
|
|||
}
|
||||
|
||||
void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color, const Color &p_dc_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
Vector2 ofs = p_pos;
|
||||
float h_offset = 0.f;
|
||||
|
@ -571,7 +647,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
TS->shaped_text_draw(dropcap_rid, p_canvas, dc_off + Vector2(0, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.size.y + dropcap_margins.position.y / 2), -1, -1, p_dc_color);
|
||||
}
|
||||
|
||||
int lines_visible = (max_lines_visible >= 0) ? MIN(max_lines_visible, lines_rid.size()) : lines_rid.size();
|
||||
int lines_visible = (max_lines_visible >= 0) ? MIN(max_lines_visible, (int)lines_rid.size()) : (int)lines_rid.size();
|
||||
|
||||
for (int i = 0; i < lines_visible; i++) {
|
||||
float l_width = width;
|
||||
|
@ -650,6 +726,8 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
}
|
||||
|
||||
void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, const Color &p_dc_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
Vector2 ofs = p_pos;
|
||||
|
||||
|
@ -673,7 +751,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
TS->shaped_text_draw_outline(dropcap_rid, p_canvas, dc_off + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_dc_color);
|
||||
}
|
||||
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
float l_width = width;
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
|
@ -750,6 +828,8 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
}
|
||||
|
||||
int TextParagraph::hit_test(const Point2 &p_coords) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
Vector2 ofs;
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
|
@ -761,7 +841,7 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines_rid[i]).y)) {
|
||||
return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.x);
|
||||
|
@ -778,6 +858,8 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
|
|||
}
|
||||
|
||||
void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Vector2 ofs = p_pos;
|
||||
float h_offset = 0.f;
|
||||
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
|
@ -800,6 +882,8 @@ void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color
|
|||
}
|
||||
|
||||
void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Vector2 ofs = p_pos;
|
||||
float h_offset = 0.f;
|
||||
if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
|
@ -822,8 +906,10 @@ void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int
|
|||
}
|
||||
|
||||
void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND(p_line < 0 || p_line >= lines_rid.size());
|
||||
ERR_FAIL_COND(p_line < 0 || p_line >= (int)lines_rid.size());
|
||||
|
||||
Vector2 ofs = p_pos;
|
||||
|
||||
|
@ -836,8 +922,10 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co
|
|||
}
|
||||
|
||||
void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size, const Color &p_color) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND(p_line < 0 || p_line >= lines_rid.size());
|
||||
ERR_FAIL_COND(p_line < 0 || p_line >= (int)lines_rid.size());
|
||||
|
||||
Vector2 ofs = p_pos;
|
||||
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
|
@ -862,7 +950,7 @@ TextParagraph::TextParagraph() {
|
|||
}
|
||||
|
||||
TextParagraph::~TextParagraph() {
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
TS->free_rid(lines_rid[i]);
|
||||
}
|
||||
lines_rid.clear();
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#ifndef TEXT_PARAGRAPH_H
|
||||
#define TEXT_PARAGRAPH_H
|
||||
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "scene/resources/font.h"
|
||||
#include "servers/text_server.h"
|
||||
|
||||
|
@ -38,6 +39,7 @@
|
|||
|
||||
class TextParagraph : public RefCounted {
|
||||
GDCLASS(TextParagraph, RefCounted);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum OverrunBehavior {
|
||||
|
@ -54,7 +56,7 @@ private:
|
|||
Rect2 dropcap_margins;
|
||||
|
||||
RID rid;
|
||||
Vector<RID> lines_rid;
|
||||
LocalVector<RID> lines_rid;
|
||||
int spacing_top = 0;
|
||||
int spacing_bottom = 0;
|
||||
|
||||
|
@ -156,6 +158,8 @@ public:
|
|||
|
||||
int hit_test(const Point2 &p_coords) const;
|
||||
|
||||
Mutex &get_mutex() const { return _thread_safe_; };
|
||||
|
||||
TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
|
||||
TextParagraph();
|
||||
~TextParagraph();
|
||||
|
|
Loading…
Reference in a new issue