Merge pull request #111839 from bruvzg/no_empty_brk_lines

[TextServer] Do not add empty lines if space trimming flag is set.
This commit is contained in:
Rémi Verschelde 2025-12-16 12:49:31 +01:00
commit 8e68058505
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 61 additions and 8 deletions

View File

@ -896,10 +896,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
start_pos += l_gl[start_pos].count; start_pos += l_gl[start_pos].count;
} }
while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos <= end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count; end_pos -= l_gl[end_pos].count;
} }
if (last_end <= l_gl[start_pos].start) { if (last_end <= l_gl[start_pos].start && l_gl[start_pos].start != l_gl[end_pos].end) {
lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end); lines.push_back(l_gl[end_pos].end);
cur_safe_brk = last_safe_break; cur_safe_brk = last_safe_break;
@ -940,10 +940,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
start_pos += l_gl[start_pos].count; start_pos += l_gl[start_pos].count;
} }
while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos <= end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count; end_pos -= l_gl[end_pos].count;
} }
if (last_end <= l_gl[start_pos].start) { if (last_end <= l_gl[start_pos].start && l_gl[start_pos].start != l_gl[end_pos].end) {
lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end); lines.push_back(l_gl[end_pos].end);
last_end = l_gl[i].end; last_end = l_gl[i].end;
@ -1079,10 +1079,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
start_pos += l_gl[start_pos].count; start_pos += l_gl[start_pos].count;
} }
while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos <= end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count; end_pos -= l_gl[end_pos].count;
} }
if (last_end <= l_gl[start_pos].start) { if (last_end <= l_gl[start_pos].start && l_gl[start_pos].start != l_gl[end_pos].end) {
lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end); lines.push_back(l_gl[end_pos].end);
if (p_width > indent && i > indent_end) { if (p_width > indent && i > indent_end) {
@ -1122,11 +1122,11 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_START_EDGE_SPACES) && trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
start_pos += l_gl[start_pos].count; start_pos += l_gl[start_pos].count;
} }
while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { while (p_break_flags.has_flag(BREAK_TRIM_END_EDGE_SPACES) && (start_pos <= end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) {
end_pos -= l_gl[end_pos].count; end_pos -= l_gl[end_pos].count;
} }
trim_next = true; trim_next = true;
if (last_end <= l_gl[start_pos].start) { if (last_end <= l_gl[start_pos].start && l_gl[start_pos].start != l_gl[end_pos].end) {
lines.push_back(l_gl[start_pos].start); lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end); lines.push_back(l_gl[end_pos].end);
if (p_width > indent && i > indent_end) { if (p_width > indent && i > indent_end) {

View File

@ -603,6 +603,59 @@ TEST_SUITE("[TextServer]") {
ts->free_rid(ctx); ts->free_rid(ctx);
String test_2 = U"Word Wrap";
// 5^
ctx = ts->create_shaped_text();
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
ok = ts->shaped_text_add_string(ctx, test_2, font, 16);
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
brks = ts->shaped_text_get_line_breaks(ctx, 43);
CHECK_FALSE_MESSAGE(brks.size() != 4, "Invalid line breaks number.");
if (brks.size() == 4) {
CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[1] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[3] != 9, "Invalid line break position.");
}
brks = ts->shaped_text_get_line_breaks(ctx, 43.0, 0, TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES);
CHECK_FALSE_MESSAGE(brks.size() != 4, "Invalid line breaks number.");
if (brks.size() == 4) {
CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[1] != 4, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[3] != 9, "Invalid line break position.");
}
brks = ts->shaped_text_get_line_breaks(ctx, 43.0, 0, TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES);
CHECK_FALSE_MESSAGE(brks.size() != 4, "Invalid line breaks number.");
if (brks.size() == 4) {
CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[1] != 4, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[3] != 9, "Invalid line break position.");
}
brks = ts->shaped_text_get_line_breaks(ctx, 43.0, 0, TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY);
CHECK_FALSE_MESSAGE(brks.size() != 6, "Invalid line breaks number.");
if (brks.size() == 6) {
CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[1] != 4, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[2] != 4, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[3] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[4] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[5] != 9, "Invalid line break position.");
}
ts->free_rid(ctx);
for (int j = 0; j < font.size(); j++) { for (int j = 0; j < font.size(); j++) {
ts->free_rid(font[j]); ts->free_rid(font[j]);
} }