Merge pull request #110317 from bruvzg/ts_zero_w

[TextServer] Do not add extra spacing to zero-width glyphs.
This commit is contained in:
Thaddeus Crews 2025-10-01 13:12:38 -05:00
commit 6f014135c4
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
2 changed files with 36 additions and 5 deletions

View file

@ -6816,6 +6816,22 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
unsigned int last_cluster_index = 0; unsigned int last_cluster_index = 0;
bool last_cluster_valid = true; bool last_cluster_valid = true;
unsigned int last_non_zero_w = glyph_count - 1;
if (last_run) {
for (unsigned int i = glyph_count - 1; i > 0; i--) {
last_non_zero_w = i;
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (glyph_pos[i].x_advance != 0) {
break;
}
} else {
if (glyph_pos[i].y_advance != 0) {
break;
}
}
}
}
double adv_rem = 0.0; double adv_rem = 0.0;
for (unsigned int i = 0; i < glyph_count; i++) { for (unsigned int i = 0; i < glyph_count; i++) {
if ((i > 0) && (last_cluster_id != glyph_info[i].cluster)) { if ((i > 0) && (last_cluster_id != glyph_info[i].cluster)) {
@ -6907,8 +6923,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
gl.x_off += _font_get_baseline_offset(gl.font_rid) * (double)(_font_get_ascent(gl.font_rid, gl.font_size) + _font_get_descent(gl.font_rid, gl.font_size)); gl.x_off += _font_get_baseline_offset(gl.font_rid) * (double)(_font_get_ascent(gl.font_rid, gl.font_size) + _font_get_descent(gl.font_rid, gl.font_size));
} }
} }
if (!last_run || i < glyph_count - 1) { if ((!last_run || i < last_non_zero_w) && !Math::is_zero_approx(gl.advance)) {
// Do not add extra spacing to the last glyph of the string. // Do not add extra spacing to the last glyph of the string and zero width glyphs.
if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) { if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) {
gl.advance += sp_sp; gl.advance += sp_sp;
} else { } else {

View file

@ -4810,6 +4810,17 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
sd->glyphs.push_back(gl); sd->glyphs.push_back(gl);
} else { } else {
// Text span. // Text span.
int last_non_zero_w = sd->end - 1;
if (i == sd->spans.size() - 1) {
for (int j = span.end - 1; j > span.start; j--) {
last_non_zero_w = j;
uint32_t idx = (int32_t)sd->text[j - sd->start];
if (!is_control(idx) && !(idx >= 0x200B && idx <= 0x200D)) {
break;
}
}
}
RID prev_font; RID prev_font;
for (int j = span.start; j < span.end; j++) { for (int j = span.start; j < span.end; j++) {
Glyph gl; Glyph gl;
@ -4819,7 +4830,8 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
gl.count = 1; gl.count = 1;
gl.font_size = span.font_size; gl.font_size = span.font_size;
gl.index = (int32_t)sd->text[j - sd->start]; // Use codepoint. gl.index = (int32_t)sd->text[j - sd->start]; // Use codepoint.
if (gl.index == 0x0009 || gl.index == 0x000b) { bool zw = (gl.index >= 0x200b && gl.index <= 0x200d);
if (gl.index == 0x0009 || gl.index == 0x000b || zw) {
gl.index = 0x0020; gl.index = 0x0020;
} }
if (!sd->preserve_control && is_control(gl.index)) { if (!sd->preserve_control && is_control(gl.index)) {
@ -4865,8 +4877,11 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
} }
} }
if (j < sd->end - 1) { if (zw) {
// Do not add extra spacing to the last glyph of the string. gl.advance = 0.0;
}
if ((j < last_non_zero_w) && !Math::is_zero_approx(gl.advance)) {
// Do not add extra spacing to the last glyph of the string and zero width glyphs.
if (is_whitespace(sd->text[j - sd->start])) { if (is_whitespace(sd->text[j - sd->start])) {
gl.advance += sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(gl.font_rid, SPACING_SPACE); gl.advance += sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(gl.font_rid, SPACING_SPACE);
} else { } else {