diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-31 14:21:56 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-31 14:21:56 +0100 |
commit | ae81a569b952c116d72716a10b17c08dfc5f81e8 (patch) | |
tree | 3e2fbfcd9d10b1682bf0ee8c92607383ef207b77 /modules | |
parent | 252900613403024168330147fabaa5a3cc30eedd (diff) | |
parent | 68ec84cded610113512535f849c6709dd4b7840a (diff) |
Merge pull request #67409 from bruvzg/fix_oversampling_rounding
[TextServer] Do not round glyph advances / coordinates if font oversampling or bitmap glyph scaling is used.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 53 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 30 |
2 files changed, 47 insertions, 36 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index a8f5a3802c..c0fec4531d 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2630,9 +2630,10 @@ Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64 ea.x = fd->embolden * double(size.x) / 64.0; } + double scale = _font_get_scale(p_font_rid, p_size); if (fd->msdf) { return (gl[p_glyph | mod].advance + ea) * (double)p_size / (double)fd->msdf_source_size; - } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { + } else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) { return (gl[p_glyph | mod].advance + ea).round(); } else { return gl[p_glyph | mod].advance + ea; @@ -3261,13 +3262,15 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca Size2 csize = gl.rect.size * (double)p_size / (double)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { + double scale = _font_get_scale(p_font_rid, p_size); Point2 cpos = p_pos; - cpos.y = Math::floor(cpos.y); if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.125)); + cpos.x = cpos.x + 0.125; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.25)); - } else { + cpos.x = cpos.x + 0.25; + } + if (scale == 1.0) { + cpos.y = Math::floor(cpos.y); cpos.x = Math::floor(cpos.x); } cpos += gl.rect.position; @@ -3352,12 +3355,14 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { Point2 cpos = p_pos; - cpos.y = Math::floor(cpos.y); + double scale = _font_get_scale(p_font_rid, p_size); if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.125)); + cpos.x = cpos.x + 0.125; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.25)); - } else { + cpos.x = cpos.x + 0.25; + } + if (scale == 1.0) { + cpos.y = Math::floor(cpos.y); cpos.x = Math::floor(cpos.x); } cpos += gl.rect.position; @@ -4975,7 +4980,8 @@ bool TextServerAdvanced::_shaped_text_update_justification_ops(const RID &p_shap Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, const RID &p_font, int64_t p_font_size) { hb_font_t *hb_font = _font_get_hb_handle(p_font, p_font_size); - bool subpos = (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); + double scale = _font_get_scale(p_font, p_font_size); + bool subpos = (scale != 1.0) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); ERR_FAIL_COND_V(hb_font == nullptr, Glyph()); hb_buffer_clear_contents(p_sd->hb_buffer); @@ -5001,25 +5007,24 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char gl.font_size = p_font_size; if (glyph_count > 0) { - double scale = _font_get_scale(p_font, p_font_size); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size); + gl.advance = (double)glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size); } else { - gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size)); + gl.advance = Math::round((double)glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size)); } } else { - gl.advance = -Math::round(glyph_pos[0].y_advance / (64.0 / scale)); + gl.advance = -Math::round((double)glyph_pos[0].y_advance / (64.0 / scale)); } gl.count = 1; gl.index = glyph_info[0].codepoint; if (subpos) { - gl.x_off = glyph_pos[0].x_offset / (64.0 / scale); + gl.x_off = (double)glyph_pos[0].x_offset / (64.0 / scale); } else { - gl.x_off = Math::round(glyph_pos[0].x_offset / (64.0 / scale)); + gl.x_off = Math::round((double)glyph_pos[0].x_offset / (64.0 / scale)); } - gl.y_off = -Math::round(glyph_pos[0].y_offset / (64.0 / scale)); + gl.y_off = -Math::round((double)glyph_pos[0].y_offset / (64.0 / scale)); if ((glyph_info[0].codepoint != 0) || !u_isgraph(p_char)) { gl.flags |= GRAPHEME_IS_VALID; @@ -5092,7 +5097,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star double sp_gl = p_sd->extra_spacing[SPACING_GLYPH]; bool last_run = (p_sd->end == p_end); double ea = _get_extra_advance(f, fs); - bool subpos = (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); + bool subpos = (scale != 1.0) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); ERR_FAIL_COND(hb_font == nullptr); hb_buffer_clear_contents(p_sd->hb_buffer); @@ -5193,19 +5198,19 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star _ensure_glyph(fd, fss, gl.index | mod); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea; + gl.advance = (double)glyph_pos[i].x_advance / (64.0 / scale) + ea; } else { - gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale) + ea); + gl.advance = Math::round((double)glyph_pos[i].x_advance / (64.0 / scale) + ea); } } else { - gl.advance = -Math::round(glyph_pos[i].y_advance / (64.0 / scale)); + gl.advance = -Math::round((double)glyph_pos[i].y_advance / (64.0 / scale)); } if (subpos) { - gl.x_off = glyph_pos[i].x_offset / (64.0 / scale); + gl.x_off = (double)glyph_pos[i].x_offset / (64.0 / scale); } else { - gl.x_off = Math::round(glyph_pos[i].x_offset / (64.0 / scale)); + gl.x_off = Math::round((double)glyph_pos[i].x_offset / (64.0 / scale)); } - gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / scale)); + gl.y_off = -Math::round((double)glyph_pos[i].y_offset / (64.0 / scale)); } if (!last_run || i < glyph_count - 1) { // Do not add extra spacing to the last glyph of the string. diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 24553dc9d9..cd8df34f60 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1711,9 +1711,10 @@ Vector2 TextServerFallback::_font_get_glyph_advance(const RID &p_font_rid, int64 ea.x = fd->embolden * double(size.x) / 64.0; } + double scale = _font_get_scale(p_font_rid, p_size); if (fd->msdf) { return (gl[p_glyph | mod].advance + ea) * (double)p_size / (double)fd->msdf_source_size; - } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { + } else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) { return (gl[p_glyph | mod].advance + ea).round(); } else { return gl[p_glyph | mod].advance + ea; @@ -2325,12 +2326,14 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { Point2 cpos = p_pos; - cpos.y = Math::floor(cpos.y); + double scale = _font_get_scale(p_font_rid, p_size); if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.125)); + cpos.x = cpos.x + 0.125; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.25)); - } else { + cpos.x = cpos.x + 0.25; + } + if (scale == 1.0) { + cpos.y = Math::floor(cpos.y); cpos.x = Math::floor(cpos.x); } cpos += gl.rect.position; @@ -2415,12 +2418,14 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { Point2 cpos = p_pos; - cpos.y = Math::floor(cpos.y); + double scale = _font_get_scale(p_font_rid, p_size); if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.125)); + cpos.x = cpos.x + 0.125; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - cpos.x = ((int)Math::floor(cpos.x + 0.25)); - } else { + cpos.x = cpos.x + 0.25; + } + if (scale == 1.0) { + cpos.y = Math::floor(cpos.y); cpos.x = Math::floor(cpos.x); } cpos += gl.rect.position; @@ -3643,17 +3648,18 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { } } + double scale = _font_get_scale(gl.font_rid, gl.font_size); if (gl.font_rid.is_valid()) { - bool subpos = (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_AUTO && gl.font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); + bool subpos = (scale != 1.0) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_AUTO && gl.font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); if (sd->text[j - sd->start] != 0 && !is_linebreak(sd->text[j - sd->start])) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - gl.advance = Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x); + gl.advance = _font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x; gl.x_off = 0; gl.y_off = 0; sd->ascent = MAX(sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size)); sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size)); } else { - gl.advance = Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y); + gl.advance = _font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y; gl.x_off = -Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5); gl.y_off = _font_get_ascent(gl.font_rid, gl.font_size); sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); |