[Text Server] Store extra spacing of individual font variations.
This commit is contained in:
@ -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));
|
||||
|
||||
@ -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<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> 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 &);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user