[TextServer / Font] Add support for customizable baseline offset.

This commit is contained in:
bruvzg
2024-01-28 12:34:56 +02:00
parent 17e7f85c06
commit 85df221610
19 changed files with 242 additions and 24 deletions

View File

@ -1403,6 +1403,37 @@ int64_t TextServerFallback::_font_get_spacing(const RID &p_font_rid, SpacingType
}
}
void TextServerFallback::_font_set_baseline_offset(const RID &p_font_rid, float p_baseline_offset) {
FontFallbackLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid);
if (fdv) {
if (fdv->baseline_offset != p_baseline_offset) {
fdv->baseline_offset = p_baseline_offset;
}
} else {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
if (fd->baseline_offset != p_baseline_offset) {
_font_clear_cache(fd);
fd->baseline_offset = p_baseline_offset;
}
}
}
float TextServerFallback::_font_get_baseline_offset(const RID &p_font_rid) const {
FontFallbackLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid);
if (fdv) {
return fdv->baseline_offset;
} else {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_NULL_V(fd, 0.0);
MutexLock lock(fd->mutex);
return fd->baseline_offset;
}
}
void TextServerFallback::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
@ -4105,12 +4136,12 @@ bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
gl.advance = _font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x;
gl.x_off = 0;
gl.y_off = 0;
gl.y_off = _font_get_baseline_offset(gl.font_rid) * (double)(_font_get_ascent(gl.font_rid, gl.font_size) + _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);
gl.x_off = -Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5) + _font_get_baseline_offset(gl.font_rid) * (double)(_font_get_ascent(gl.font_rid, gl.font_size) + _font_get_descent(gl.font_rid, gl.font_size));
gl.y_off = _font_get_ascent(gl.font_rid, gl.font_size);
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));

View File

@ -248,6 +248,7 @@ class TextServerFallback : public TextServerExtension {
struct FontFallbackLinkedVariation {
RID base_font;
int extra_spacing[4] = { 0, 0, 0, 0 };
float baseline_offset = 0.0;
};
struct FontFallback {
@ -275,6 +276,7 @@ class TextServerFallback : public TextServerExtension {
int weight = 400;
int stretch = 100;
int extra_spacing[4] = { 0, 0, 0, 0 };
float baseline_offset = 0.0;
HashMap<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> cache;
@ -490,9 +492,10 @@ class TextServerFallback : public TextServerExtension {
double embolden = 0.0;
Transform2D transform;
int extra_spacing[4] = { 0, 0, 0, 0 };
float baseline_offset = 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) && (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]);
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]) && (baseline_offset == p_b.baseline_offset);
}
SystemFontKey(const String &p_font_name, bool p_italic, int p_weight, int p_stretch, RID p_font, const TextServerFallback *p_fb) {
@ -517,6 +520,7 @@ class TextServerFallback : public TextServerExtension {
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);
baseline_offset = p_fb->_font_get_baseline_offset(p_font);
}
};
@ -549,6 +553,7 @@ class TextServerFallback : public TextServerExtension {
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);
hash = hash_murmur3_one_double(p_a.baseline_offset, 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));
}
};
@ -648,6 +653,9 @@ public:
MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t);
MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType);
MODBIND2(font_set_baseline_offset, const RID &, float);
MODBIND1RC(float, font_get_baseline_offset, const RID &);
MODBIND2(font_set_transform, const RID &, const Transform2D &);
MODBIND1RC(Transform2D, font_get_transform, const RID &);