summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2024-06-16 10:46:23 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2024-06-18 09:04:51 +0300
commitdc8d7ef43ea881ccc4fbb391f9dc22fa46168a7f (patch)
tree0364ea86e9d7363b63b679e9241c4a7f096a8d53
parente2fc6d38cb240ea23bd5700514f8a8ce7011e89c (diff)
downloadredot-engine-dc8d7ef43ea881ccc4fbb391f9dc22fa46168a7f.tar.gz
[TextServer] Save advances rounding remainders to prevent rounding error accumulation.
-rw-r--r--modules/text_server_adv/text_server_adv.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 361d88af90..33ba2da761 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -6052,6 +6052,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
unsigned int last_cluster_index = 0;
bool last_cluster_valid = true;
+ double adv_rem = 0.0;
for (unsigned int i = 0; i < glyph_count; i++) {
if ((i > 0) && (last_cluster_id != glyph_info[i].cluster)) {
if (p_direction == HB_DIRECTION_RTL || p_direction == HB_DIRECTION_BTT) {
@@ -6097,21 +6098,31 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
gl.index = glyph_info[i].codepoint;
if (gl.index != 0) {
_ensure_glyph(fd, fss, gl.index | mod);
+ if (subpos) {
+ gl.x_off = (double)glyph_pos[i].x_offset / (64.0 / scale);
+ } else if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
+ gl.x_off = Math::round(adv_rem + ((double)glyph_pos[i].x_offset / (64.0 / scale)));
+ } else {
+ gl.x_off = Math::round((double)glyph_pos[i].x_offset / (64.0 / scale));
+ }
+ if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
+ gl.y_off = -Math::round((double)glyph_pos[i].y_offset / (64.0 / scale));
+ } else {
+ gl.y_off = -Math::round(adv_rem + ((double)glyph_pos[i].y_offset / (64.0 / scale)));
+ }
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (subpos) {
gl.advance = (double)glyph_pos[i].x_advance / (64.0 / scale) + ea;
} else {
- gl.advance = Math::round((double)glyph_pos[i].x_advance / (64.0 / scale) + ea);
+ double full_adv = adv_rem + ((double)glyph_pos[i].x_advance / (64.0 / scale) + ea);
+ gl.advance = Math::round(full_adv);
+ adv_rem = full_adv - gl.advance;
}
} else {
- gl.advance = -Math::round((double)glyph_pos[i].y_advance / (64.0 / scale));
- }
- if (subpos) {
- gl.x_off = (double)glyph_pos[i].x_offset / (64.0 / scale);
- } else {
- gl.x_off = Math::round((double)glyph_pos[i].x_offset / (64.0 / scale));
+ double full_adv = adv_rem + ((double)glyph_pos[i].y_advance / (64.0 / scale));
+ gl.advance = -Math::round(full_adv);
+ adv_rem = full_adv + gl.advance;
}
- gl.y_off = -Math::round((double)glyph_pos[i].y_offset / (64.0 / scale));
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
gl.y_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));
} else {