diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index e87712825d2..63e7d80737b 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -114,6 +114,10 @@ + + + + Returns [TextServer] RID of the font cache for specific variation. diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml index 86d1cb552a7..1628f8819fa 100644 --- a/doc/classes/FontFile.xml +++ b/doc/classes/FontFile.xml @@ -130,6 +130,14 @@ Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. + + + + + + Returns spacing for [param spacing] (see [enum TextServer.SpacingType]) in pixels (not relative to the font size). + + @@ -436,6 +444,15 @@ Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. + + + + + + + Sets the spacing for [param spacing] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size). + + diff --git a/doc/classes/FontVariation.xml b/doc/classes/FontVariation.xml index f02fda31b96..128f3b5a851 100644 --- a/doc/classes/FontVariation.xml +++ b/doc/classes/FontVariation.xml @@ -38,7 +38,7 @@ - Sets the spacing for [code]type[/code] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size). + Sets the spacing for [param spacing] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size). diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index bf376fba629..0103f873bd1 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -378,6 +378,14 @@ Returns list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. + + + + + + Returns the spacing for [param spacing] (see [enum TextServer.SpacingType]) in pixels (not relative to the font size). + + @@ -828,6 +836,15 @@ Adds override for [method font_is_script_supported]. + + + + + + + Sets the spacing for [param spacing] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size). + + diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml index c58e3b705f9..82162e77bef 100644 --- a/doc/classes/TextServerExtension.xml +++ b/doc/classes/TextServerExtension.xml @@ -325,6 +325,13 @@ + + + + + + + @@ -724,6 +731,14 @@ + + + + + + + + diff --git a/editor/gui/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp index 451827da09c..fa94a107f08 100644 --- a/editor/gui/editor_spin_slider.cpp +++ b/editor/gui/editor_spin_slider.cpp @@ -336,9 +336,6 @@ void EditorSpinSlider::_draw_spin_slider() { int suffix_start = numstr.length(); RID num_rid = TS->create_shaped_text(); TS->shaped_text_add_string(num_rid, numstr + U"\u2009" + suffix, font->get_rids(), font_size, font->get_opentype_features()); - for (int i = 0; i < TextServer::SPACING_MAX; i++) { - TS->shaped_text_set_spacing(num_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); - } float text_start = rtl ? Math::round(sb->get_offset().x) : Math::round(sb->get_offset().x + label_width + sep); Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs); diff --git a/misc/extension_api_validation/4.0-stable.expected b/misc/extension_api_validation/4.0-stable.expected index 5f982cbff6d..89dbe8ebfa8 100644 --- a/misc/extension_api_validation/4.0-stable.expected +++ b/misc/extension_api_validation/4.0-stable.expected @@ -451,3 +451,10 @@ Validate extension JSON: Error: Field 'classes/PopupMenu/methods/add_icon_shortc Validate extension JSON: Error: Field 'classes/PopupMenu/methods/add_shortcut/arguments': size changed value in new API, from 3 to 4. Added optional argument. Compatibility methods registered. + + +GH-80954 +-------- +Validate extension JSON: Error: Field 'classes/Font/methods/find_variation/arguments': size changed value in new API, from 4 to 8. + +Added optional arguments. Compatibility method registered. diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 804a16423d9..cbe48db494f 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2336,6 +2336,29 @@ double TextServerAdvanced::_font_get_embolden(const RID &p_font_rid) const { return fd->embolden; } +void TextServerAdvanced::_font_set_spacing(const RID &p_font_rid, SpacingType p_spacing, int64_t p_value) { + ERR_FAIL_INDEX((int)p_spacing, 4); + FontAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->extra_spacing[p_spacing] != p_value) { + _font_clear_cache(fd); + fd->extra_spacing[p_spacing] = p_value; + } +} + +int64_t TextServerAdvanced::_font_get_spacing(const RID &p_font_rid, SpacingType p_spacing) const { + ERR_FAIL_INDEX_V((int)p_spacing, 4, 0); + + FontAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0); + + MutexLock lock(fd->mutex); + + return fd->extra_spacing[p_spacing]; +} + void TextServerAdvanced::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { FontAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -4129,8 +4152,8 @@ bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const V } else { if (gl.font_rid.is_valid()) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - sd->ascent = MAX(sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off)); - sd->descent = MAX(sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off)); + sd->ascent = MAX(sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_TOP), -gl.y_off)); + sd->descent = MAX(sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM), gl.y_off)); } else { sd->ascent = MAX(sd->ascent, 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)); @@ -4384,8 +4407,8 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S } else { if (gl.font_rid.is_valid()) { if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) { - p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off)); - p_new_sd->descent = MAX(p_new_sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off)); + p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_TOP), -gl.y_off)); + p_new_sd->descent = MAX(p_new_sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM), gl.y_off)); } else { p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); p_new_sd->descent = MAX(p_new_sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); @@ -4707,7 +4730,7 @@ void TextServerAdvanced::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ int ellipsis_width = 0; if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { - ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + (cut_per_word ? whitespace_adv.x : 0); + ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + _font_get_spacing(dot_gl_font_rid, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); } int ell_min_characters = 6; @@ -5559,6 +5582,10 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star _font_set_oversampling(sysf.rid, key.oversampling); _font_set_embolden(sysf.rid, key.embolden); _font_set_transform(sysf.rid, key.transform); + _font_set_spacing(sysf.rid, SPACING_TOP, key.extra_spacing[SPACING_TOP]); + _font_set_spacing(sysf.rid, SPACING_BOTTOM, key.extra_spacing[SPACING_BOTTOM]); + _font_set_spacing(sysf.rid, SPACING_SPACE, key.extra_spacing[SPACING_SPACE]); + _font_set_spacing(sysf.rid, SPACING_GLYPH, key.extra_spacing[SPACING_GLYPH]); if (system_fonts.has(key)) { system_fonts[key].var.push_back(sysf); @@ -5613,8 +5640,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star Vector2i fss = _get_size(fd, fs); hb_font_t *hb_font = _font_get_hb_handle(f, fs); double scale = _font_get_scale(f, fs); - double sp_sp = p_sd->extra_spacing[SPACING_SPACE]; - double sp_gl = p_sd->extra_spacing[SPACING_GLYPH]; + double sp_sp = p_sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(f, SPACING_SPACE); + double sp_gl = p_sd->extra_spacing[SPACING_GLYPH] + _font_get_spacing(f, SPACING_GLYPH); bool last_run = (p_sd->end == p_end); double ea = _get_extra_advance(f, fs); 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); @@ -5799,8 +5826,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star if (failed_subrun_start != p_end + 1) { _shape_run(p_sd, failed_subrun_start, failed_subrun_end, p_script, p_direction, p_fonts, p_span, p_fb_index + 1, p_start, p_end); } - p_sd->ascent = MAX(p_sd->ascent, _font_get_ascent(f, fs)); - p_sd->descent = MAX(p_sd->descent, _font_get_descent(f, fs)); + p_sd->ascent = MAX(p_sd->ascent, _font_get_ascent(f, fs) + _font_get_spacing(f, SPACING_TOP)); + p_sd->descent = MAX(p_sd->descent, _font_get_descent(f, fs) + _font_get_spacing(f, SPACING_BOTTOM)); p_sd->upos = MAX(p_sd->upos, _font_get_underline_position(f, fs)); p_sd->uthk = MAX(p_sd->uthk, _font_get_underline_thickness(f, fs)); } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index f27fa1dee95..7445becfae0 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -316,6 +316,7 @@ class TextServerAdvanced : public TextServerExtension { String style_name; int weight = 400; int stretch = 100; + int extra_spacing[4] = { 0, 0, 0, 0 }; HashMap cache; @@ -554,9 +555,10 @@ class TextServerAdvanced : public TextServerExtension { double oversampling = 0.0; double embolden = 0.0; Transform2D transform; + int extra_spacing[4] = { 0, 0, 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); + 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]); } SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerAdvanced *p_fb) { @@ -577,6 +579,10 @@ class TextServerAdvanced : public TextServerExtension { oversampling = p_fb->_font_get_oversampling(p_font); embolden = p_fb->_font_get_embolden(p_font); transform = p_fb->_font_get_transform(p_font); + extra_spacing[SPACING_TOP] = p_fb->_font_get_spacing(p_font, SPACING_TOP); + 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); } }; @@ -605,6 +611,11 @@ class TextServerAdvanced : public TextServerExtension { hash = hash_murmur3_one_real(p_a.transform[0].y, hash); hash = hash_murmur3_one_real(p_a.transform[1].x, hash); hash = hash_murmur3_one_real(p_a.transform[1].y, hash); + hash = hash_murmur3_one_32(p_a.extra_spacing[SPACING_TOP], hash); + 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); + 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)); } }; @@ -748,6 +759,9 @@ public: MODBIND2(font_set_embolden, const RID &, double); MODBIND1RC(double, font_get_embolden, const RID &); + MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t); + MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType); + MODBIND2(font_set_transform, const RID &, const Transform2D &); MODBIND1RC(Transform2D, font_get_transform, const RID &); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 4976c70b3b0..d0587bf6c06 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1330,6 +1330,28 @@ double TextServerFallback::_font_get_embolden(const RID &p_font_rid) const { return fd->embolden; } +void TextServerFallback::_font_set_spacing(const RID &p_font_rid, SpacingType p_spacing, int64_t p_value) { + ERR_FAIL_INDEX((int)p_spacing, 4); + FontFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->extra_spacing[p_spacing] != p_value) { + _font_clear_cache(fd); + fd->extra_spacing[p_spacing] = p_value; + } +} + +int64_t TextServerFallback::_font_get_spacing(const RID &p_font_rid, SpacingType p_spacing) const { + ERR_FAIL_INDEX_V((int)p_spacing, 4, 0); + + FontFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0); + + MutexLock lock(fd->mutex); + return fd->extra_spacing[p_spacing]; +} + void TextServerFallback::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { FontFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -2999,8 +3021,8 @@ bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const V } else { if (gl.font_rid.is_valid()) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - 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)); + sd->ascent = MAX(sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_TOP)); + sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM)); } else { sd->ascent = MAX(sd->ascent, 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)); @@ -3165,8 +3187,8 @@ RID TextServerFallback::_shaped_text_substr(const RID &p_shaped, int64_t p_start } else { if (gl.font_rid.is_valid()) { if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->ascent = MAX(new_sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size)); - new_sd->descent = MAX(new_sd->descent, _font_get_descent(gl.font_rid, gl.font_size)); + new_sd->ascent = MAX(new_sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_TOP)); + new_sd->descent = MAX(new_sd->descent, _font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM)); } else { new_sd->ascent = MAX(new_sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); new_sd->descent = MAX(new_sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); @@ -3510,7 +3532,7 @@ void TextServerFallback::_shaped_text_overrun_trim_to_width(const RID &p_shaped_ int ellipsis_width = 0; if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { - ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + (cut_per_word ? whitespace_adv.x : 0); + ellipsis_width = 3 * dot_adv.x + sd->extra_spacing[SPACING_GLYPH] + _font_get_spacing(dot_gl_font_rid, SPACING_GLYPH) + (cut_per_word ? whitespace_adv.x : 0); } int ell_min_characters = 6; @@ -3849,6 +3871,10 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { _font_set_oversampling(sysf.rid, key.oversampling); _font_set_embolden(sysf.rid, key.embolden); _font_set_transform(sysf.rid, key.transform); + _font_set_spacing(sysf.rid, SPACING_TOP, key.extra_spacing[SPACING_TOP]); + _font_set_spacing(sysf.rid, SPACING_BOTTOM, key.extra_spacing[SPACING_BOTTOM]); + _font_set_spacing(sysf.rid, SPACING_SPACE, key.extra_spacing[SPACING_SPACE]); + _font_set_spacing(sysf.rid, SPACING_GLYPH, key.extra_spacing[SPACING_GLYPH]); if (system_fonts.has(key)) { system_fonts[key].var.push_back(sysf); @@ -3873,8 +3899,8 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { 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)); + sd->ascent = MAX(sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_TOP)); + sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM)); } else { 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); @@ -3886,9 +3912,9 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) { if (j < sd->end - 1) { // Do not add extra spacing to the last glyph of the string. if (is_whitespace(sd->text[j - sd->start])) { - gl.advance += sd->extra_spacing[SPACING_SPACE]; + gl.advance += sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(gl.font_rid, SPACING_SPACE); } else { - gl.advance += sd->extra_spacing[SPACING_GLYPH]; + gl.advance += sd->extra_spacing[SPACING_GLYPH] + _font_get_spacing(gl.font_rid, SPACING_GLYPH); } } sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size)); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 457573ecb3d..c44b45fc27b 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -268,6 +268,7 @@ class TextServerFallback : public TextServerExtension { String style_name; int weight = 400; int stretch = 100; + int extra_spacing[4] = { 0, 0, 0, 0 }; HashMap cache; @@ -471,9 +472,10 @@ class TextServerFallback : public TextServerExtension { double oversampling = 0.0; double embolden = 0.0; Transform2D transform; + int extra_spacing[4] = { 0, 0, 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); + 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]); } SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerFallback *p_fb) { @@ -494,6 +496,10 @@ class TextServerFallback : public TextServerExtension { oversampling = p_fb->_font_get_oversampling(p_font); embolden = p_fb->_font_get_embolden(p_font); transform = p_fb->_font_get_transform(p_font); + extra_spacing[SPACING_TOP] = p_fb->_font_get_spacing(p_font, SPACING_TOP); + 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); } }; @@ -522,6 +528,10 @@ class TextServerFallback : public TextServerExtension { hash = hash_murmur3_one_real(p_a.transform[0].y, hash); hash = hash_murmur3_one_real(p_a.transform[1].x, hash); hash = hash_murmur3_one_real(p_a.transform[1].y, hash); + hash = hash_murmur3_one_32(p_a.extra_spacing[SPACING_TOP], hash); + 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); 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)); } }; @@ -613,6 +623,9 @@ public: MODBIND2(font_set_embolden, const RID &, double); MODBIND1RC(double, font_get_embolden, const RID &); + MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t); + MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType); + MODBIND2(font_set_transform, const RID &, const Transform2D &); MODBIND1RC(Transform2D, font_get_transform, const RID &); diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index b0e7c732538..3d304de1df9 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -473,9 +473,6 @@ void Label3D::_shape() { String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; TS->shaped_text_add_string(text_rid, txt, font->get_rids(), font_size, font->get_opentype_features(), language); - for (int i = 0; i < TextServer::SPACING_MAX; i++) { - TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); - } TypedArray stt; if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) { @@ -493,9 +490,6 @@ void Label3D::_shape() { for (int i = 0; i < spans; i++) { TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features()); } - for (int i = 0; i < TextServer::SPACING_MAX; i++) { - TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); - } dirty_font = false; dirty_lines = true; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index aec9722fec1..cf0627c6f1b 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -127,9 +127,6 @@ void Label::_shape() { TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features()); } } - for (int i = 0; i < TextServer::SPACING_MAX; i++) { - TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); - } TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, txt)); if (!tab_stops.is_empty()) { TS->shaped_text_tab_align(text_rid, tab_stops); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 956e93466cb..bb727ff62cd 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2314,9 +2314,6 @@ void LineEdit::_shape() { TS->shaped_text_set_preserve_control(text_rid, draw_control_chars); TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), language); - for (int i = 0; i < TextServer::SPACING_MAX; i++) { - TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i))); - } TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t)); full_width = TS->shaped_text_get_size(text_rid).x; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 070c79c0ee1..29b85e0d763 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -243,9 +243,6 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref< font_size = font_size_it->font_size; } TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features()); - for (int j = 0; j < TextServer::SPACING_MAX; j++) { - TS->shaped_text_set_spacing(t, TextServer::SpacingType(j), font->get_spacing(TextServer::SpacingType(j))); - } } } diff --git a/scene/resources/font.compat.inc b/scene/resources/font.compat.inc new file mode 100644 index 00000000000..bf504325564 --- /dev/null +++ b/scene/resources/font.compat.inc @@ -0,0 +1,41 @@ +/**************************************************************************/ +/* font.compat.inc */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef DISABLE_DEPRECATED + +RID Font::_find_variation_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { + return find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform, 0, 0, 0, 0); +} + +void Font::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::_find_variation_compat_80954, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D())); +} + +#endif diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index df0bd8bc2e8..f5edc8d5e98 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -29,6 +29,7 @@ /**************************************************************************/ #include "font.h" +#include "font.compat.inc" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -50,7 +51,7 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("get_fallbacks"), &Font::get_fallbacks); // Output. - ClassDB::bind_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform"), &Font::find_variation, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D())); + ClassDB::bind_method(D_METHOD("find_variation", "variation_coordinates", "face_index", "strength", "transform", "spacing_top", "spacing_bottom", "spacing_space", "spacing_glyph"), &Font::find_variation, DEFVAL(0), DEFVAL(0.0), DEFVAL(Transform2D()), DEFVAL(0), DEFVAL(0), DEFVAL(0), DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids); // Font metrics. @@ -916,6 +917,9 @@ void FontFile::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform", "cache_index", "transform"), &FontFile::set_transform); ClassDB::bind_method(D_METHOD("get_transform", "cache_index"), &FontFile::get_transform); + ClassDB::bind_method(D_METHOD("set_extra_spacing", "cache_index", "spacing", "value"), &FontFile::set_extra_spacing); + ClassDB::bind_method(D_METHOD("get_extra_spacing", "cache_index", "spacing"), &FontFile::get_extra_spacing); + ClassDB::bind_method(D_METHOD("set_face_index", "cache_index", "face_index"), &FontFile::set_face_index); ClassDB::bind_method(D_METHOD("get_face_index", "cache_index"), &FontFile::get_face_index); @@ -1126,6 +1130,18 @@ bool FontFile::_set(const StringName &p_name, const Variant &p_value) { } else if (tokens.size() == 3 && tokens[2] == "transform") { set_transform(cache_index, p_value); return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_top") { + set_extra_spacing(cache_index, TextServer::SPACING_TOP, p_value); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_bottom") { + set_extra_spacing(cache_index, TextServer::SPACING_BOTTOM, p_value); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_space") { + set_extra_spacing(cache_index, TextServer::SPACING_SPACE, p_value); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_glyph") { + set_extra_spacing(cache_index, TextServer::SPACING_GLYPH, p_value); + return true; } if (tokens.size() >= 5) { Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int()); @@ -1205,6 +1221,18 @@ bool FontFile::_get(const StringName &p_name, Variant &r_ret) const { } else if (tokens.size() == 3 && tokens[2] == "transform") { r_ret = get_transform(cache_index); return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_top") { + r_ret = get_extra_spacing(cache_index, TextServer::SPACING_TOP); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_bottom") { + r_ret = get_extra_spacing(cache_index, TextServer::SPACING_BOTTOM); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_space") { + r_ret = get_extra_spacing(cache_index, TextServer::SPACING_SPACE); + return true; + } else if (tokens.size() == 3 && tokens[2] == "spacing_glyph") { + r_ret = get_extra_spacing(cache_index, TextServer::SPACING_GLYPH); + return true; } if (tokens.size() >= 5) { Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int()); @@ -1276,6 +1304,10 @@ void FontFile::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, prefix + "face_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); p_list->push_back(PropertyInfo(Variant::FLOAT, prefix + "embolden", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); p_list->push_back(PropertyInfo(Variant::TRANSFORM2D, prefix + "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); + p_list->push_back(PropertyInfo(Variant::INT, prefix + "spacing_top", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); + p_list->push_back(PropertyInfo(Variant::INT, prefix + "spacing_bottom", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); + p_list->push_back(PropertyInfo(Variant::INT, prefix + "spacing_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); + p_list->push_back(PropertyInfo(Variant::INT, prefix + "spacing_glyph", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); for (int j = 0; j < sizes.size(); j++) { Vector2i sz = sizes[j]; @@ -2183,7 +2215,7 @@ real_t FontFile::get_oversampling() const { return oversampling; } -RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { +RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const { // Find existing variation cache. const Dictionary &supported_coords = get_supported_variation_list(); for (int i = 0; i < cache.size(); i++) { @@ -2193,6 +2225,10 @@ RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_fa match = match && (TS->font_get_face_index(cache[i]) == p_face_index); match = match && (TS->font_get_embolden(cache[i]) == p_strength); match = match && (TS->font_get_transform(cache[i]) == p_transform); + match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_TOP) == p_spacing_top); + match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_BOTTOM) == p_spacing_bottom); + match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_SPACE) == p_spacing_space); + match = match && (TS->font_get_spacing(cache[i], TextServer::SPACING_GLYPH) == p_spacing_glyph); for (const Variant *V = supported_coords.next(nullptr); V && match; V = supported_coords.next(V)) { const Vector3 &def = supported_coords[*V]; @@ -2231,6 +2267,10 @@ RID FontFile::find_variation(const Dictionary &p_variation_coordinates, int p_fa TS->font_set_face_index(cache[idx], p_face_index); TS->font_set_embolden(cache[idx], p_strength); TS->font_set_transform(cache[idx], p_transform); + TS->font_set_spacing(cache[idx], TextServer::SPACING_TOP, p_spacing_top); + TS->font_set_spacing(cache[idx], TextServer::SPACING_BOTTOM, p_spacing_bottom); + TS->font_set_spacing(cache[idx], TextServer::SPACING_SPACE, p_spacing_space); + TS->font_set_spacing(cache[idx], TextServer::SPACING_GLYPH, p_spacing_glyph); return cache[idx]; } @@ -2312,6 +2352,18 @@ Transform2D FontFile::get_transform(int p_cache_index) const { return TS->font_get_transform(cache[p_cache_index]); } +void FontFile::set_extra_spacing(int p_cache_index, TextServer::SpacingType p_spacing, int64_t p_value) { + ERR_FAIL_COND(p_cache_index < 0); + _ensure_rid(p_cache_index); + TS->font_set_spacing(cache[p_cache_index], p_spacing, p_value); +} + +int64_t FontFile::get_extra_spacing(int p_cache_index, TextServer::SpacingType p_spacing) const { + ERR_FAIL_COND_V(p_cache_index < 0, 0); + _ensure_rid(p_cache_index); + return TS->font_get_spacing(cache[p_cache_index], p_spacing); +} + void FontFile::set_face_index(int p_cache_index, int64_t p_index) { ERR_FAIL_COND(p_cache_index < 0); ERR_FAIL_COND(p_index < 0); @@ -2848,10 +2900,10 @@ int FontVariation::get_spacing(TextServer::SpacingType p_spacing) const { return extra_spacing[p_spacing]; } -RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { +RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const { Ref f = _get_base_font_or_default(); if (f.is_valid()) { - return f->find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform); + return f->find_variation(p_variation_coordinates, p_face_index, p_strength, p_transform, p_spacing_top, p_spacing_bottom, p_spacing_space, p_spacing_glyph); } return RID(); } @@ -2859,7 +2911,7 @@ RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int RID FontVariation::_get_rid() const { Ref f = _get_base_font_or_default(); if (f.is_valid()) { - return f->find_variation(variation.opentype, variation.face_index, variation.embolden, variation.transform); + return f->find_variation(variation.opentype, variation.face_index, variation.embolden, variation.transform, extra_spacing[TextServer::SPACING_TOP], extra_spacing[TextServer::SPACING_BOTTOM], extra_spacing[TextServer::SPACING_SPACE], extra_spacing[TextServer::SPACING_GLYPH]); } return RID(); } @@ -3328,7 +3380,7 @@ int SystemFont::get_spacing(TextServer::SpacingType p_spacing) const { } } -RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { +RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform, int p_spacing_top, int p_spacing_bottom, int p_spacing_space, int p_spacing_glyph) const { Ref f = _get_base_font_or_default(); if (f.is_valid()) { Dictionary var = p_variation_coordinates; @@ -3344,9 +3396,9 @@ RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_ if (!face_indeces.is_empty()) { int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1); - return f->find_variation(var, face_indeces[face_index], p_strength, p_transform); + return f->find_variation(var, face_indeces[face_index], p_strength, p_transform, p_spacing_top, p_spacing_bottom, p_spacing_space, p_spacing_glyph); } else { - return f->find_variation(var, 0, p_strength, p_transform); + return f->find_variation(var, 0, p_strength, p_transform, p_spacing_top, p_spacing_bottom, p_spacing_space, p_spacing_glyph); } } return RID(); diff --git a/scene/resources/font.h b/scene/resources/font.h index d8374c4447c..30ae11a235c 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -103,6 +103,11 @@ protected: virtual void reset_state() override; +#ifndef DISABLE_DEPRECATED + RID _find_variation_compat_80954(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const; + static void _bind_compatibility_methods(); +#endif + public: virtual void _invalidate_rids(); @@ -113,7 +118,7 @@ public: virtual TypedArray get_fallbacks() const; // Output. - virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const { return RID(); }; + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const { return RID(); }; virtual RID _get_rid() const { return RID(); }; virtual TypedArray get_rids() const; @@ -268,7 +273,7 @@ public: virtual real_t get_oversampling() const; // Cache. - virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const override; virtual RID _get_rid() const override; virtual int get_cache_count() const; @@ -288,6 +293,9 @@ public: virtual void set_transform(int p_cache_index, Transform2D p_transform); virtual Transform2D get_transform(int p_cache_index) const; + virtual void set_extra_spacing(int p_cache_index, TextServer::SpacingType p_spacing, int64_t p_value); + virtual int64_t get_extra_spacing(int p_cache_index, TextServer::SpacingType p_spacing) const; + virtual void set_face_index(int p_cache_index, int64_t p_index); virtual int64_t get_face_index(int p_cache_index) const; @@ -420,7 +428,7 @@ public: virtual int get_spacing(TextServer::SpacingType p_spacing) const override; // Output. - virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const override; virtual RID _get_rid() const override; FontVariation(); @@ -513,7 +521,7 @@ public: virtual int get_spacing(TextServer::SpacingType p_spacing) const override; - virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D(), int p_spacing_top = 0, int p_spacing_bottom = 0, int p_spacing_space = 0, int p_spacing_glyph = 0) const override; virtual RID _get_rid() const override; int64_t get_face_count() const override; diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 6fc13867cc1..91a2c9797e0 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -109,6 +109,9 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_embolden, "font_rid", "strength"); GDVIRTUAL_BIND(_font_get_embolden, "font_rid"); + GDVIRTUAL_BIND(_font_set_spacing, "font_rid", "spacing", "value"); + GDVIRTUAL_BIND(_font_get_spacing, "font_rid", "spacing"); + GDVIRTUAL_BIND(_font_set_transform, "font_rid", "transform"); GDVIRTUAL_BIND(_font_get_transform, "font_rid"); @@ -599,6 +602,16 @@ double TextServerExtension::font_get_embolden(const RID &p_font_rid) const { return ret; } +void TextServerExtension::font_set_spacing(const RID &p_font_rid, SpacingType p_spacing, int64_t p_value) { + GDVIRTUAL_CALL(_font_set_spacing, p_font_rid, p_spacing, p_value); +} + +int64_t TextServerExtension::font_get_spacing(const RID &p_font_rid, SpacingType p_spacing) const { + int64_t ret = 0; + GDVIRTUAL_CALL(_font_get_spacing, p_font_rid, p_spacing, ret); + return ret; +} + void TextServerExtension::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { GDVIRTUAL_CALL(_font_set_transform, p_font_rid, p_transform); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index a0c47a70d65..1d475f13d4c 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -161,6 +161,11 @@ public: GDVIRTUAL2(_font_set_embolden, RID, double); GDVIRTUAL1RC(double, _font_get_embolden, RID); + virtual void font_set_spacing(const RID &p_font_rid, SpacingType p_spacing, int64_t p_value) override; + virtual int64_t font_get_spacing(const RID &p_font_rid, SpacingType p_spacing) const override; + GDVIRTUAL3(_font_set_spacing, const RID &, SpacingType, int64_t); + GDVIRTUAL2RC(int64_t, _font_get_spacing, const RID &, SpacingType); + virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override; virtual Transform2D font_get_transform(const RID &p_font_rid) const override; GDVIRTUAL2(_font_set_transform, RID, Transform2D); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 28c6b20f7b4..3c901f573e4 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -263,6 +263,9 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_embolden", "font_rid", "strength"), &TextServer::font_set_embolden); ClassDB::bind_method(D_METHOD("font_get_embolden", "font_rid"), &TextServer::font_get_embolden); + ClassDB::bind_method(D_METHOD("font_set_spacing", "font_rid", "spacing", "value"), &TextServer::font_set_spacing); + ClassDB::bind_method(D_METHOD("font_get_spacing", "font_rid", "spacing"), &TextServer::font_get_spacing); + ClassDB::bind_method(D_METHOD("font_set_transform", "font_rid", "transform"), &TextServer::font_set_transform); ClassDB::bind_method(D_METHOD("font_get_transform", "font_rid"), &TextServer::font_get_transform); diff --git a/servers/text_server.h b/servers/text_server.h index 7bc353cb8cb..d0cfd87b64b 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -295,6 +295,9 @@ public: virtual void font_set_embolden(const RID &p_font_rid, double p_strength) = 0; virtual double font_get_embolden(const RID &p_font_rid) const = 0; + virtual void font_set_spacing(const RID &p_font_rid, SpacingType p_spacing, int64_t p_value) = 0; + virtual int64_t font_get_spacing(const RID &p_font_rid, SpacingType p_spacing) const = 0; + virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) = 0; virtual Transform2D font_get_transform(const RID &p_font_rid) const = 0;