[Bitmap fonts] Add support for scaling.

This commit is contained in:
bruvzg
2023-08-14 10:42:49 +03:00
parent 37ee293be8
commit 9a1e0e4aef
17 changed files with 341 additions and 8 deletions

View File

@ -1243,7 +1243,7 @@ void TextServerFallback::_font_set_msdf_size(const RID &p_font_rid, int64_t p_ms
int64_t TextServerFallback::_font_get_msdf_size(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, false);
ERR_FAIL_NULL_V(fd, 0);
MutexLock lock(fd->mutex);
return fd->msdf_source_size;
@ -1259,12 +1259,28 @@ void TextServerFallback::_font_set_fixed_size(const RID &p_font_rid, int64_t p_f
int64_t TextServerFallback::_font_get_fixed_size(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, false);
ERR_FAIL_NULL_V(fd, 0);
MutexLock lock(fd->mutex);
return fd->fixed_size;
}
void TextServerFallback::_font_set_fixed_size_scale_mode(const RID &p_font_rid, TextServer::FixedSizeScaleMode p_fixed_size_scale_mode) {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
MutexLock lock(fd->mutex);
fd->fixed_size_scale_mode = p_fixed_size_scale_mode;
}
TextServer::FixedSizeScaleMode TextServerFallback::_font_get_fixed_size_scale_mode(const RID &p_font_rid) const {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL_V(fd, FIXED_SIZE_SCALE_DISABLE);
MutexLock lock(fd->mutex);
return fd->fixed_size_scale_mode;
}
void TextServerFallback::_font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) {
FontFallback *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
@ -1502,6 +1518,12 @@ double TextServerFallback::_font_get_ascent(const RID &p_font_rid, int64_t p_siz
if (fd->msdf) {
return fd->cache[size]->ascent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fd->cache[size]->ascent * (double)p_size / (double)fd->fixed_size;
} else {
return fd->cache[size]->ascent * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return fd->cache[size]->ascent;
}
@ -1528,6 +1550,12 @@ double TextServerFallback::_font_get_descent(const RID &p_font_rid, int64_t p_si
if (fd->msdf) {
return fd->cache[size]->descent * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fd->cache[size]->descent * (double)p_size / (double)fd->fixed_size;
} else {
return fd->cache[size]->descent * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return fd->cache[size]->descent;
}
@ -1555,6 +1583,12 @@ double TextServerFallback::_font_get_underline_position(const RID &p_font_rid, i
if (fd->msdf) {
return fd->cache[size]->underline_position * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fd->cache[size]->underline_position * (double)p_size / (double)fd->fixed_size;
} else {
return fd->cache[size]->underline_position * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return fd->cache[size]->underline_position;
}
@ -1582,6 +1616,12 @@ double TextServerFallback::_font_get_underline_thickness(const RID &p_font_rid,
if (fd->msdf) {
return fd->cache[size]->underline_thickness * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fd->cache[size]->underline_thickness * (double)p_size / (double)fd->fixed_size;
} else {
return fd->cache[size]->underline_thickness * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return fd->cache[size]->underline_thickness;
}
@ -1614,6 +1654,12 @@ double TextServerFallback::_font_get_scale(const RID &p_font_rid, int64_t p_size
if (fd->msdf) {
return fd->cache[size]->scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return fd->cache[size]->scale * (double)p_size / (double)fd->fixed_size;
} else {
return fd->cache[size]->scale * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return fd->cache[size]->scale / fd->cache[size]->oversampling;
}
@ -1809,6 +1855,12 @@ Vector2 TextServerFallback::_font_get_glyph_advance(const RID &p_font_rid, int64
double scale = _font_get_scale(p_font_rid, p_size);
if (fd->msdf) {
return (gl[p_glyph | mod].advance + ea) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return (gl[p_glyph | mod].advance + ea) * (double)p_size / (double)fd->fixed_size;
} else {
return (gl[p_glyph | mod].advance + ea) * Math::round((double)p_size / (double)fd->fixed_size);
}
} else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) {
return (gl[p_glyph | mod].advance + ea).round();
} else {
@ -1856,6 +1908,12 @@ Vector2 TextServerFallback::_font_get_glyph_offset(const RID &p_font_rid, const
if (fd->msdf) {
return gl[p_glyph | mod].rect.position * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return gl[p_glyph | mod].rect.position * (double)p_size.x / (double)fd->fixed_size;
} else {
return gl[p_glyph | mod].rect.position * Math::round((double)p_size.x / (double)fd->fixed_size);
}
} else {
return gl[p_glyph | mod].rect.position;
}
@ -1901,6 +1959,12 @@ Vector2 TextServerFallback::_font_get_glyph_size(const RID &p_font_rid, const Ve
if (fd->msdf) {
return gl[p_glyph | mod].rect.size * (double)p_size.x / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return gl[p_glyph | mod].rect.size * (double)p_size.x / (double)fd->fixed_size;
} else {
return gl[p_glyph | mod].rect.size * Math::round((double)p_size.x / (double)fd->fixed_size);
}
} else {
return gl[p_glyph | mod].rect.size;
}
@ -2124,6 +2188,12 @@ Dictionary TextServerFallback::_font_get_glyph_contours(const RID &p_font_rid, i
double scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale;
if (fd->msdf) {
scale = scale * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
scale = scale * (double)p_size / (double)fd->fixed_size;
} else {
scale = scale * Math::round((double)p_size / (double)fd->fixed_size);
}
}
for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_points; i++) {
points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, -fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i])));
@ -2206,6 +2276,12 @@ Vector2 TextServerFallback::_font_get_kerning(const RID &p_font_rid, int64_t p_s
if (kern.has(p_glyph_pair)) {
if (fd->msdf) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return kern[p_glyph_pair] * (double)p_size / (double)fd->fixed_size;
} else {
return kern[p_glyph_pair] * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return kern[p_glyph_pair];
}
@ -2218,6 +2294,12 @@ Vector2 TextServerFallback::_font_get_kerning(const RID &p_font_rid, int64_t p_s
FT_Get_Kerning(fd->cache[size]->face, glyph_a, glyph_b, FT_KERNING_DEFAULT, &delta);
if (fd->msdf) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->msdf_source_size;
} else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->fixed_size;
} else {
return Vector2(delta.x, delta.y) * Math::round((double)p_size / (double)fd->fixed_size);
}
} else {
return Vector2(delta.x, delta.y);
}
@ -2435,8 +2517,20 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
cpos.y = Math::floor(cpos.y);
cpos.x = Math::floor(cpos.x);
}
cpos += gl.rect.position;
Vector2 gpos = gl.rect.position;
Size2 csize = gl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
csize *= gl_scale;
} else {
double gl_scale = Math::round((double)p_size / (double)fd->fixed_size);
gpos *= gl_scale;
csize *= gl_scale;
}
}
cpos += gpos;
if (lcd_aa) {
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
} else {
@ -2527,8 +2621,20 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R
cpos.y = Math::floor(cpos.y);
cpos.x = Math::floor(cpos.x);
}
cpos += gl.rect.position;
Vector2 gpos = gl.rect.position;
Size2 csize = gl.rect.size;
if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
double gl_scale = (double)p_size / (double)fd->fixed_size;
gpos *= gl_scale;
csize *= gl_scale;
} else {
double gl_scale = Math::round((double)p_size / (double)fd->fixed_size);
gpos *= gl_scale;
csize *= gl_scale;
}
}
cpos += gpos;
if (lcd_aa) {
RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
} else {

View File

@ -256,6 +256,7 @@ class TextServerFallback : public TextServerExtension {
TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
bool mipmaps = false;
bool msdf = false;
FixedSizeScaleMode fixed_size_scale_mode = FIXED_SIZE_SCALE_DISABLE;
int msdf_range = 14;
int msdf_source_size = 48;
int fixed_size = 0;
@ -627,6 +628,9 @@ public:
MODBIND2(font_set_fixed_size, const RID &, int64_t);
MODBIND1RC(int64_t, font_get_fixed_size, const RID &);
MODBIND2(font_set_fixed_size_scale_mode, const RID &, FixedSizeScaleMode);
MODBIND1RC(FixedSizeScaleMode, font_get_fixed_size_scale_mode, const RID &);
MODBIND2(font_set_allow_system_fallback, const RID &, bool);
MODBIND1RC(bool, font_is_allow_system_fallback, const RID &);