1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

[TextEdit] Add support for optional wrapped line indentation.

This commit is contained in:
bruvzg
2024-02-19 13:41:12 +02:00
parent 81f3d43cc1
commit dad4aae386
9 changed files with 122 additions and 10 deletions

View File

@@ -535,6 +535,7 @@ void TextServer::_bind_methods() {
BIND_BITFIELD_FLAG(BREAK_GRAPHEME_BOUND);
BIND_BITFIELD_FLAG(BREAK_ADAPTIVE);
BIND_BITFIELD_FLAG(BREAK_TRIM_EDGE_SPACES);
BIND_BITFIELD_FLAG(BREAK_TRIM_INDENT);
/* VisibleCharactersBehavior */
BIND_ENUM_CONSTANT(VC_CHARS_BEFORE_SHAPING);
@@ -750,13 +751,28 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
int l_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
double indent = 0.0;
if (p_break_flags.has_flag(BREAK_TRIM_INDENT)) {
for (int i = 0; i < l_size; i++) {
if ((l_gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB || (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
indent += l_gl[i].advance * l_gl[i].repeat;
} else {
break;
}
}
}
for (int i = 0; i < l_size; i++) {
double l_width = p_width[chunk];
if (l_width > indent) {
l_width -= indent;
}
if (l_gl[i].start < p_start) {
prev_safe_break = i + 1;
continue;
}
if (l_gl[i].count > 0) {
if ((p_width[chunk] > 0) && (width + l_gl[i].advance > p_width[chunk]) && (last_safe_break >= 0)) {
if ((l_width > 0) && (width + l_gl[i].advance > l_width) && (last_safe_break >= 0)) {
if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) {
int start_pos = prev_safe_break;
int end_pos = last_safe_break;
@@ -891,13 +907,25 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
int l_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
double indent = 0.0;
if (p_break_flags.has_flag(BREAK_TRIM_INDENT)) {
for (int i = 0; i < l_size; i++) {
if ((l_gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB || (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
indent += l_gl[i].advance * l_gl[i].repeat;
} else {
break;
}
}
}
double l_width = p_width;
for (int i = 0; i < l_size; i++) {
if (l_gl[i].start < p_start) {
prev_safe_break = i + 1;
continue;
}
if (l_gl[i].count > 0) {
if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) {
if ((l_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > l_width) && (last_safe_break >= 0)) {
if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) {
int start_pos = prev_safe_break;
int end_pos = last_safe_break;
@@ -910,6 +938,9 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= l_gl[start_pos].start) {
lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end);
if (p_width > indent) {
l_width = p_width - indent;
}
last_end = l_gl[end_pos].end;
}
trim_next = true;
@@ -917,6 +948,9 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= line_start) {
lines.push_back(line_start);
lines.push_back(l_gl[last_safe_break].end);
if (p_width > indent) {
l_width = p_width - indent;
}
last_end = l_gl[last_safe_break].end;
}
}
@@ -943,12 +977,18 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= l_gl[start_pos].start) {
lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end);
if (p_width > indent) {
l_width = p_width - indent;
}
last_end = l_gl[end_pos].end;
}
} else {
if (last_end <= line_start) {
lines.push_back(line_start);
lines.push_back(l_gl[i].end);
if (p_width > indent) {
l_width = p_width - indent;
}
last_end = l_gl[i].end;
}
}