summaryrefslogtreecommitdiffstats
path: root/modules/text_server_adv
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2023-08-24 11:56:50 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2023-08-24 11:58:12 +0300
commit545350369774ffb56d207f22102c0b9c58035192 (patch)
tree0ede2d8d4c17d8ec652ae95fc585f5f9495a18ca /modules/text_server_adv
parent6758a7f8c07d1f4c8ec4f052ded6d26402967ebe (diff)
downloadredot-engine-545350369774ffb56d207f22102c0b9c58035192.tar.gz
[Text Server] Store extra spacing of individual font variations.
Diffstat (limited to 'modules/text_server_adv')
-rw-r--r--modules/text_server_adv/text_server_adv.cpp45
-rw-r--r--modules/text_server_adv/text_server_adv.h16
2 files changed, 51 insertions, 10 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 804a16423d..cbe48db494 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 f27fa1dee9..7445becfae 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<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> 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 &);