diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 07df9aba14c..cfe21c18b79 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -6816,6 +6816,22 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star unsigned int last_cluster_index = 0; 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; for (unsigned int i = 0; i < glyph_count; i++) { 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)); } } - if (!last_run || i < glyph_count - 1) { - // Do not add extra spacing to the last glyph of the string. + 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 and zero width glyphs. if (sp_sp && is_whitespace(p_sd->text[glyph_info[i].cluster])) { gl.advance += sp_sp; } else { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 466141f1fb2..53b9fb16c07 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -4810,6 +4810,17 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { sd->glyphs.push_back(gl); } else { // 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; for (int j = span.start; j < span.end; j++) { Glyph gl; @@ -4819,7 +4830,8 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { gl.count = 1; gl.font_size = span.font_size; 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; } 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)); } } - if (j < sd->end - 1) { - // Do not add extra spacing to the last glyph of the string. + if (zw) { + 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])) { gl.advance += sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(gl.font_rid, SPACING_SPACE); } else {