Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TextServer] Store extra spacing of individual font variations. #80954

Merged
merged 1 commit into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/classes/Font.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@
<param index="1" name="face_index" type="int" default="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="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>
Returns [TextServer] RID of the font cache for specific variation.
</description>
Expand Down
17 changes: 17 additions & 0 deletions doc/classes/FontFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@
Returns embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
</description>
</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">
<return type="int" />
<param index="0" name="cache_index" type="int" />
Expand Down Expand Up @@ -436,6 +444,15 @@
Sets embolden strength, if is not equal to zero, emboldens the font outlines. Negative values reduce the outline thickness.
</description>
</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">
<return type="void" />
<param index="0" name="cache_index" type="int" />
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/FontVariation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<param index="0" name="spacing" type="int" enum="TextServer.SpacingType" />
<param index="1" name="value" type="int" />
<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>
</method>
</methods>
Expand Down
17 changes: 17 additions & 0 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</description>
</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">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -828,6 +836,15 @@
Adds override for [method font_is_script_supported].
</description>
</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">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/TextServerExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,13 @@
<description>
</description>
</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">
<return type="int" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -724,6 +731,14 @@
<description>
</description>
</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">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down
3 changes: 0 additions & 3 deletions editor/gui/editor_spin_slider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions misc/extension_api_validation/4.0-stable.expected
Original file line number Diff line number Diff line change
Expand Up @@ -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.
45 changes: 36 additions & 9 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
}
Expand Down
16 changes: 15 additions & 1 deletion modules/text_server_adv/text_server_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache;

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
};

Expand Down Expand Up @@ -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));
}
};
Expand Down Expand Up @@ -748,6 +759,9 @@ class TextServerAdvanced : public TextServerExtension {
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 &);

Expand Down
Loading
Loading