[Text Server] Store extra spacing of individual font variations.

This commit is contained in:
bruvzg 2023-08-24 11:56:50 +03:00
parent 6758a7f8c0
commit 5453503697
No known key found for this signature in database
GPG Key ID: 7960FCF39844EC38
22 changed files with 298 additions and 51 deletions

View File

@ -114,6 +114,10 @@
<param index="1" name="face_index" type="int" default="0" /> <param index="1" name="face_index" type="int" default="0" />
<param index="2" name="strength" type="float" default="0.0" /> <param index="2" name="strength" type="float" default="0.0" />
<param index="3" name="transform" type="Transform2D" default="Transform2D(1, 0, 0, 1, 0, 0)" /> <param index="3" name="transform" type="Transform2D" default="Transform2D(1, 0, 0, 1, 0, 0)" />
<param index="4" name="spacing_top" type="int" default="0" />
<param index="5" name="spacing_bottom" type="int" default="0" />
<param index="6" name="spacing_space" type="int" default="0" />
<param index="7" name="spacing_glyph" type="int" default="0" />
<description> <description>
Returns [TextServer] RID of the font cache for specific variation. Returns [TextServer] RID of the font cache for specific variation.
</description> </description>

View File

@ -130,6 +130,14 @@
Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
</description> </description>
</method> </method>
<method name="get_extra_spacing" qualifiers="const">
<return type="int" />
<param index="0" name="cache_index" type="int" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<description>
Returns spacing for [param spacing] (see [enum TextServer.SpacingType]) in pixels (not relative to the font size).
</description>
</method>
<method name="get_face_index" qualifiers="const"> <method name="get_face_index" qualifiers="const">
<return type="int" /> <return type="int" />
<param index="0" name="cache_index" type="int" /> <param index="0" name="cache_index" type="int" />
@ -436,6 +444,15 @@
Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness. Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
</description> </description>
</method> </method>
<method name="set_extra_spacing">
<return type="void" />
<param index="0" name="cache_index" type="int" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<param index="2" name="value" type="int" />
<description>
Sets the spacing for [param spacing] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size).
</description>
</method>
<method name="set_face_index"> <method name="set_face_index">
<return type="void" /> <return type="void" />
<param index="0" name="cache_index" type="int" /> <param index="0" name="cache_index" type="int" />

View File

@ -38,7 +38,7 @@
<param index="0" name="spacing" type="int" enum="TextServer.SpacingType" /> <param index="0" name="spacing" type="int" enum="TextServer.SpacingType" />
<param index="1" name="value" type="int" /> <param index="1" name="value" type="int" />
<description> <description>
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).
</description> </description>
</method> </method>
</methods> </methods>

View File

@ -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 list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size.
</description> </description>
</method> </method>
<method name="font_get_spacing" qualifiers="const">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<description>
Returns the spacing for [param spacing] (see [enum TextServer.SpacingType]) in pixels (not relative to the font size).
</description>
</method>
<method name="font_get_stretch" qualifiers="const"> <method name="font_get_stretch" qualifiers="const">
<return type="int" /> <return type="int" />
<param index="0" name="font_rid" type="RID" /> <param index="0" name="font_rid" type="RID" />
@ -828,6 +836,15 @@
Adds override for [method font_is_script_supported]. Adds override for [method font_is_script_supported].
</description> </description>
</method> </method>
<method name="font_set_spacing">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<param index="2" name="value" type="int" />
<description>
Sets the spacing for [param spacing] (see [enum TextServer.SpacingType]) to [param value] in pixels (not relative to the font size).
</description>
</method>
<method name="font_set_stretch"> <method name="font_set_stretch">
<return type="void" /> <return type="void" />
<param index="0" name="font_rid" type="RID" /> <param index="0" name="font_rid" type="RID" />

View File

@ -325,6 +325,13 @@
<description> <description>
</description> </description>
</method> </method>
<method name="_font_get_spacing" qualifiers="virtual const">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<description>
</description>
</method>
<method name="_font_get_stretch" qualifiers="virtual const"> <method name="_font_get_stretch" qualifiers="virtual const">
<return type="int" /> <return type="int" />
<param index="0" name="font_rid" type="RID" /> <param index="0" name="font_rid" type="RID" />
@ -724,6 +731,14 @@
<description> <description>
</description> </description>
</method> </method>
<method name="_font_set_spacing" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="spacing" type="int" enum="TextServer.SpacingType" />
<param index="2" name="value" type="int" />
<description>
</description>
</method>
<method name="_font_set_stretch" qualifiers="virtual"> <method name="_font_set_stretch" qualifiers="virtual">
<return type="void" /> <return type="void" />
<param index="0" name="font_rid" type="RID" /> <param index="0" name="font_rid" type="RID" />

View File

@ -336,9 +336,6 @@ void EditorSpinSlider::_draw_spin_slider() {
int suffix_start = numstr.length(); int suffix_start = numstr.length();
RID num_rid = TS->create_shaped_text(); 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()); 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); 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); Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs);

View File

@ -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. 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. 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.

View File

@ -2336,6 +2336,29 @@ double TextServerAdvanced::_font_get_embolden(const RID &p_font_rid) const {
return fd->embolden; 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) { void TextServerAdvanced::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid); FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd); ERR_FAIL_COND(!fd);
@ -4129,8 +4152,8 @@ bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const V
} else { } else {
if (gl.font_rid.is_valid()) { if (gl.font_rid.is_valid()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) { if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->ascent = MAX(sd->ascent, MAX(_font_get_ascent(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), 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 { } else {
sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); 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)); 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 { } else {
if (gl.font_rid.is_valid()) { if (gl.font_rid.is_valid()) {
if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) { 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->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), 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 { } 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->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)); 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; int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { 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; 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_oversampling(sysf.rid, key.oversampling);
_font_set_embolden(sysf.rid, key.embolden); _font_set_embolden(sysf.rid, key.embolden);
_font_set_transform(sysf.rid, key.transform); _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)) { if (system_fonts.has(key)) {
system_fonts[key].var.push_back(sysf); 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); Vector2i fss = _get_size(fd, fs);
hb_font_t *hb_font = _font_get_hb_handle(f, fs); hb_font_t *hb_font = _font_get_hb_handle(f, fs);
double scale = _font_get_scale(f, fs); double scale = _font_get_scale(f, fs);
double sp_sp = p_sd->extra_spacing[SPACING_SPACE]; double sp_sp = p_sd->extra_spacing[SPACING_SPACE] + _font_get_spacing(f, SPACING_SPACE);
double sp_gl = p_sd->extra_spacing[SPACING_GLYPH]; double sp_gl = p_sd->extra_spacing[SPACING_GLYPH] + _font_get_spacing(f, SPACING_GLYPH);
bool last_run = (p_sd->end == p_end); bool last_run = (p_sd->end == p_end);
double ea = _get_extra_advance(f, fs); 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); 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) { 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); _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->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)); 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->upos = MAX(p_sd->upos, _font_get_underline_position(f, fs));
p_sd->uthk = MAX(p_sd->uthk, _font_get_underline_thickness(f, fs)); p_sd->uthk = MAX(p_sd->uthk, _font_get_underline_thickness(f, fs));
} }

View File

@ -316,6 +316,7 @@ class TextServerAdvanced : public TextServerExtension {
String style_name; String style_name;
int weight = 400; int weight = 400;
int stretch = 100; int stretch = 100;
int extra_spacing[4] = { 0, 0, 0, 0 };
HashMap<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache; HashMap<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache;
@ -554,9 +555,10 @@ class TextServerAdvanced : public TextServerExtension {
double oversampling = 0.0; double oversampling = 0.0;
double embolden = 0.0; double embolden = 0.0;
Transform2D transform; Transform2D transform;
int extra_spacing[4] = { 0, 0, 0, 0 };
bool operator==(const SystemFontKey &p_b) const { 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) { 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); oversampling = p_fb->_font_get_oversampling(p_font);
embolden = p_fb->_font_get_embolden(p_font); embolden = p_fb->_font_get_embolden(p_font);
transform = p_fb->_font_get_transform(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[0].y, hash);
hash = hash_murmur3_one_real(p_a.transform[1].x, 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_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)); 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); MODBIND2(font_set_embolden, const RID &, double);
MODBIND1RC(double, font_get_embolden, const RID &); 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 &); MODBIND2(font_set_transform, const RID &, const Transform2D &);
MODBIND1RC(Transform2D, font_get_transform, const RID &); MODBIND1RC(Transform2D, font_get_transform, const RID &);

View File

@ -1330,6 +1330,28 @@ double TextServerFallback::_font_get_embolden(const RID &p_font_rid) const {
return fd->embolden; 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) { void TextServerFallback::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontFallback *fd = font_owner.get_or_null(p_font_rid); FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd); ERR_FAIL_COND(!fd);
@ -2999,8 +3021,8 @@ bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const V
} else { } else {
if (gl.font_rid.is_valid()) { if (gl.font_rid.is_valid()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) { if (sd->orientation == ORIENTATION_HORIZONTAL) {
sd->ascent = MAX(sd->ascent, _font_get_ascent(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)); sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM));
} else { } else {
sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5)); 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)); 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 { } else {
if (gl.font_rid.is_valid()) { if (gl.font_rid.is_valid()) {
if (new_sd->orientation == ORIENTATION_HORIZONTAL) { if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
new_sd->ascent = MAX(new_sd->ascent, _font_get_ascent(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)); 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 { } 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->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)); 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; int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) { 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; 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_oversampling(sysf.rid, key.oversampling);
_font_set_embolden(sysf.rid, key.embolden); _font_set_embolden(sysf.rid, key.embolden);
_font_set_transform(sysf.rid, key.transform); _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)) { if (system_fonts.has(key)) {
system_fonts[key].var.push_back(sysf); 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.advance = _font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x;
gl.x_off = 0; gl.x_off = 0;
gl.y_off = 0; gl.y_off = 0;
sd->ascent = MAX(sd->ascent, _font_get_ascent(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)); sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size) + _font_get_spacing(gl.font_rid, SPACING_BOTTOM));
} else { } else {
gl.advance = _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.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) { if (j < sd->end - 1) {
// Do not add extra spacing to the last glyph of the string. // Do not add extra spacing to the last glyph of the string.
if (is_whitespace(sd->text[j - sd->start])) { 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 { } 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)); sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size));

View File

@ -268,6 +268,7 @@ class TextServerFallback : public TextServerExtension {
String style_name; String style_name;
int weight = 400; int weight = 400;
int stretch = 100; int stretch = 100;
int extra_spacing[4] = { 0, 0, 0, 0 };
HashMap<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> cache; HashMap<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> cache;
@ -471,9 +472,10 @@ class TextServerFallback : public TextServerExtension {
double oversampling = 0.0; double oversampling = 0.0;
double embolden = 0.0; double embolden = 0.0;
Transform2D transform; Transform2D transform;
int extra_spacing[4] = { 0, 0, 0, 0 };
bool operator==(const SystemFontKey &p_b) const { 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) { 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); oversampling = p_fb->_font_get_oversampling(p_font);
embolden = p_fb->_font_get_embolden(p_font); embolden = p_fb->_font_get_embolden(p_font);
transform = p_fb->_font_get_transform(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[0].y, hash);
hash = hash_murmur3_one_real(p_a.transform[1].x, 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_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)); 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); MODBIND2(font_set_embolden, const RID &, double);
MODBIND1RC(double, font_get_embolden, const RID &); 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 &); MODBIND2(font_set_transform, const RID &, const Transform2D &);
MODBIND1RC(Transform2D, font_get_transform, const RID &); MODBIND1RC(Transform2D, font_get_transform, const RID &);

View File

@ -473,9 +473,6 @@ void Label3D::_shape() {
String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; 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); 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<Vector3i> stt; TypedArray<Vector3i> stt;
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) { if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
@ -493,9 +490,6 @@ void Label3D::_shape() {
for (int i = 0; i < spans; i++) { 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()); 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_font = false;
dirty_lines = true; dirty_lines = true;

View File

@ -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()); 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)); TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, txt));
if (!tab_stops.is_empty()) { if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(text_rid, tab_stops); TS->shaped_text_tab_align(text_rid, tab_stops);

View File

@ -2314,9 +2314,6 @@ void LineEdit::_shape() {
TS->shaped_text_set_preserve_control(text_rid, draw_control_chars); 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); 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)); 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; full_width = TS->shaped_text_get_size(text_rid).x;

View File

@ -243,9 +243,6 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<
font_size = font_size_it->font_size; font_size = font_size_it->font_size;
} }
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features()); 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)));
}
} }
} }

View File

@ -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

View File

@ -29,6 +29,7 @@
/**************************************************************************/ /**************************************************************************/
#include "font.h" #include "font.h"
#include "font.compat.inc"
#include "core/io/image_loader.h" #include "core/io/image_loader.h"
#include "core/io/resource_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); ClassDB::bind_method(D_METHOD("get_fallbacks"), &Font::get_fallbacks);
// Output. // 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); ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids);
// Font metrics. // 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("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("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("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); 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") { } else if (tokens.size() == 3 && tokens[2] == "transform") {
set_transform(cache_index, p_value); set_transform(cache_index, p_value);
return true; 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) { if (tokens.size() >= 5) {
Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int()); 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") { } else if (tokens.size() == 3 && tokens[2] == "transform") {
r_ret = get_transform(cache_index); r_ret = get_transform(cache_index);
return true; 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) { if (tokens.size() >= 5) {
Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int()); Vector2i sz = Vector2i(tokens[2].to_int(), tokens[3].to_int());
@ -1276,6 +1304,10 @@ void FontFile::_get_property_list(List<PropertyInfo> *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::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::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::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++) { for (int j = 0; j < sizes.size(); j++) {
Vector2i sz = sizes[j]; Vector2i sz = sizes[j];
@ -2183,7 +2215,7 @@ real_t FontFile::get_oversampling() const {
return oversampling; 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. // Find existing variation cache.
const Dictionary &supported_coords = get_supported_variation_list(); const Dictionary &supported_coords = get_supported_variation_list();
for (int i = 0; i < cache.size(); i++) { 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_face_index(cache[i]) == p_face_index);
match = match && (TS->font_get_embolden(cache[i]) == p_strength); 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_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)) { for (const Variant *V = supported_coords.next(nullptr); V && match; V = supported_coords.next(V)) {
const Vector3 &def = supported_coords[*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_face_index(cache[idx], p_face_index);
TS->font_set_embolden(cache[idx], p_strength); TS->font_set_embolden(cache[idx], p_strength);
TS->font_set_transform(cache[idx], p_transform); 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]; 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]); 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) { void FontFile::set_face_index(int p_cache_index, int64_t p_index) {
ERR_FAIL_COND(p_cache_index < 0); ERR_FAIL_COND(p_cache_index < 0);
ERR_FAIL_COND(p_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]; 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<Font> f = _get_base_font_or_default(); Ref<Font> f = _get_base_font_or_default();
if (f.is_valid()) { 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(); return RID();
} }
@ -2859,7 +2911,7 @@ RID FontVariation::find_variation(const Dictionary &p_variation_coordinates, int
RID FontVariation::_get_rid() const { RID FontVariation::_get_rid() const {
Ref<Font> f = _get_base_font_or_default(); Ref<Font> f = _get_base_font_or_default();
if (f.is_valid()) { 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(); 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<Font> f = _get_base_font_or_default(); Ref<Font> f = _get_base_font_or_default();
if (f.is_valid()) { if (f.is_valid()) {
Dictionary var = p_variation_coordinates; 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()) { if (!face_indeces.is_empty()) {
int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1); 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 { } 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(); return RID();

View File

@ -103,6 +103,11 @@ protected:
virtual void reset_state() override; 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: public:
virtual void _invalidate_rids(); virtual void _invalidate_rids();
@ -113,7 +118,7 @@ public:
virtual TypedArray<Font> get_fallbacks() const; virtual TypedArray<Font> get_fallbacks() const;
// Output. // 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 RID _get_rid() const { return RID(); };
virtual TypedArray<RID> get_rids() const; virtual TypedArray<RID> get_rids() const;
@ -268,7 +273,7 @@ public:
virtual real_t get_oversampling() const; virtual real_t get_oversampling() const;
// Cache. // 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 RID _get_rid() const override;
virtual int get_cache_count() const; virtual int get_cache_count() const;
@ -288,6 +293,9 @@ public:
virtual void set_transform(int p_cache_index, Transform2D p_transform); virtual void set_transform(int p_cache_index, Transform2D p_transform);
virtual Transform2D get_transform(int p_cache_index) const; 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 void set_face_index(int p_cache_index, int64_t p_index);
virtual int64_t get_face_index(int p_cache_index) const; 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; virtual int get_spacing(TextServer::SpacingType p_spacing) const override;
// Output. // 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; virtual RID _get_rid() const override;
FontVariation(); FontVariation();
@ -513,7 +521,7 @@ public:
virtual int get_spacing(TextServer::SpacingType p_spacing) const override; 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; virtual RID _get_rid() const override;
int64_t get_face_count() const override; int64_t get_face_count() const override;

View File

@ -109,6 +109,9 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_set_embolden, "font_rid", "strength"); GDVIRTUAL_BIND(_font_set_embolden, "font_rid", "strength");
GDVIRTUAL_BIND(_font_get_embolden, "font_rid"); 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_set_transform, "font_rid", "transform");
GDVIRTUAL_BIND(_font_get_transform, "font_rid"); GDVIRTUAL_BIND(_font_get_transform, "font_rid");
@ -599,6 +602,16 @@ double TextServerExtension::font_get_embolden(const RID &p_font_rid) const {
return ret; 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) { void TextServerExtension::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
GDVIRTUAL_CALL(_font_set_transform, p_font_rid, p_transform); GDVIRTUAL_CALL(_font_set_transform, p_font_rid, p_transform);
} }

View File

@ -161,6 +161,11 @@ public:
GDVIRTUAL2(_font_set_embolden, RID, double); GDVIRTUAL2(_font_set_embolden, RID, double);
GDVIRTUAL1RC(double, _font_get_embolden, RID); 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 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; virtual Transform2D font_get_transform(const RID &p_font_rid) const override;
GDVIRTUAL2(_font_set_transform, RID, Transform2D); GDVIRTUAL2(_font_set_transform, RID, Transform2D);

View File

@ -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_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_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_set_transform", "font_rid", "transform"), &TextServer::font_set_transform);
ClassDB::bind_method(D_METHOD("font_get_transform", "font_rid"), &TextServer::font_get_transform); ClassDB::bind_method(D_METHOD("font_get_transform", "font_rid"), &TextServer::font_get_transform);

View File

@ -295,6 +295,9 @@ public:
virtual void font_set_embolden(const RID &p_font_rid, double p_strength) = 0; 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 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 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; virtual Transform2D font_get_transform(const RID &p_font_rid) const = 0;