[TextServer] Do not add empty lines if space trimming flag is set.

This commit is contained in:
Pāvels Nadtočajevs 2025-10-20 11:37:43 +03:00
parent 7864ac8019
commit 3f1d973651
No known key found for this signature in database
GPG Key ID: 8413210218EF35D2
2 changed files with 61 additions and 8 deletions

View File

@ -885,10 +885,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;
@ -929,10 +929,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;
@ -1068,10 +1068,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) {
@ -1111,11 +1111,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]);
} }