diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2024-01-28 12:34:56 +0200 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2024-01-28 13:26:49 +0200 |
commit | 85df221610e72e4b93f4eaf57a2f470c6da8e54d (patch) | |
tree | 358ed654919436c367fc418fc01bc0c20244babd /modules/text_server_adv | |
parent | 17e7f85c06366b427e5068c5b3e2940e27ff5f1d (diff) | |
download | redot-engine-85df221610e72e4b93f4eaf57a2f470c6da8e54d.tar.gz |
[TextServer / Font] Add support for customizable baseline offset.
Diffstat (limited to 'modules/text_server_adv')
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 41 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.h | 11 |
2 files changed, 50 insertions, 2 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 19f302423c..b4028492c7 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2409,6 +2409,37 @@ int64_t TextServerAdvanced::_font_get_spacing(const RID &p_font_rid, SpacingType } } +void TextServerAdvanced::_font_set_baseline_offset(const RID &p_font_rid, float p_baseline_offset) { + FontAdvancedLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); + if (fdv) { + if (fdv->baseline_offset != p_baseline_offset) { + fdv->baseline_offset = p_baseline_offset; + } + } else { + FontAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_NULL(fd); + + MutexLock lock(fd->mutex); + if (fd->baseline_offset != p_baseline_offset) { + _font_clear_cache(fd); + fd->baseline_offset = p_baseline_offset; + } + } +} + +float TextServerAdvanced::_font_get_baseline_offset(const RID &p_font_rid) const { + FontAdvancedLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); + if (fdv) { + return fdv->baseline_offset; + } else { + FontAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_NULL_V(fd, 0.0); + + MutexLock lock(fd->mutex); + return fd->baseline_offset; + } +} + void TextServerAdvanced::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { FontAdvanced *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -5750,6 +5781,11 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char gl.x_off = Math::round((double)glyph_pos[0].x_offset / (64.0 / scale)); } gl.y_off = -Math::round((double)glyph_pos[0].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 { + 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 ((glyph_info[0].codepoint != 0) || !u_isgraph(p_char)) { gl.flags |= GRAPHEME_IS_VALID; @@ -5964,6 +6000,11 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star gl.x_off = Math::round((double)glyph_pos[i].x_offset / (64.0 / scale)); } 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 { + 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. diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 0b5fe47b8b..6f53ecfa8f 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -297,6 +297,7 @@ class TextServerAdvanced : public TextServerExtension { struct FontAdvancedLinkedVariation { RID base_font; int extra_spacing[4] = { 0, 0, 0, 0 }; + float baseline_offset = 0.0; }; struct FontAdvanced { @@ -324,6 +325,7 @@ class TextServerAdvanced : public TextServerExtension { int weight = 400; int stretch = 100; int extra_spacing[4] = { 0, 0, 0, 0 }; + float baseline_offset = 0.0; HashMap<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache; @@ -574,9 +576,10 @@ class TextServerAdvanced : public TextServerExtension { double embolden = 0.0; Transform2D transform; int extra_spacing[4] = { 0, 0, 0, 0 }; + float baseline_offset = 0.0; bool operator==(const SystemFontKey &p_b) const { - return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]); + return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset); } SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerAdvanced *p_fb) { @@ -601,6 +604,7 @@ class TextServerAdvanced : public TextServerExtension { extra_spacing[SPACING_BOTTOM] = p_fb->_font_get_spacing(p_font, SPACING_BOTTOM); extra_spacing[SPACING_SPACE] = p_fb->_font_get_spacing(p_font, SPACING_SPACE); extra_spacing[SPACING_GLYPH] = p_fb->_font_get_spacing(p_font, SPACING_GLYPH); + baseline_offset = p_fb->_font_get_baseline_offset(p_font); } }; @@ -633,7 +637,7 @@ class TextServerAdvanced : public TextServerExtension { hash = hash_murmur3_one_32(p_a.extra_spacing[SPACING_BOTTOM], hash); hash = hash_murmur3_one_32(p_a.extra_spacing[SPACING_SPACE], hash); hash = hash_murmur3_one_32(p_a.extra_spacing[SPACING_GLYPH], hash); - + hash = hash_murmur3_one_double(p_a.baseline_offset, hash); return hash_fmix32(hash_murmur3_one_32(((int)p_a.mipmaps) | ((int)p_a.msdf << 1) | ((int)p_a.italic << 2) | ((int)p_a.force_autohinter << 3) | ((int)p_a.hinting << 4) | ((int)p_a.subpixel_positioning << 8) | ((int)p_a.antialiasing << 12), hash)); } }; @@ -781,6 +785,9 @@ public: MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t); MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType); + MODBIND2(font_set_baseline_offset, const RID &, float); + MODBIND1RC(float, font_get_baseline_offset, const RID &); + MODBIND2(font_set_transform, const RID &, const Transform2D &); MODBIND1RC(Transform2D, font_get_transform, const RID &); |