Skip to content

Commit

Permalink
Merge pull request #80605 from bruvzg/bmp_font_scale
Browse files Browse the repository at this point in the history
[Bitmap fonts] Add support for scaling.
  • Loading branch information
akien-mga committed Oct 13, 2023
2 parents 37ee293 + 9a1e0e4 commit b1fe1f1
Show file tree
Hide file tree
Showing 17 changed files with 341 additions and 8 deletions.
3 changes: 3 additions & 0 deletions doc/classes/FontFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@
<member name="fixed_size" type="int" setter="set_fixed_size" getter="get_fixed_size" default="0">
Font size, used only for the bitmap fonts.
</member>
<member name="fixed_size_scale_mode" type="int" setter="set_fixed_size_scale_mode" getter="get_fixed_size_scale_mode" enum="TextServer.FixedSizeScaleMode" default="0">
Scaling mode, used only for the bitmap fonts with [member fixed_size] greater than zero.
</member>
<member name="font_name" type="String" setter="set_font_name" getter="get_font_name" default="&quot;&quot;">
Font family name.
</member>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/ResourceImporterBMFont.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
<member name="fallbacks" type="Array" setter="" getter="" default="[]">
List of font fallbacks to use if a glyph isn't found in this bitmap font. Fonts at the beginning of the array are attempted first.
</member>
<member name="scaling_mode" type="int" setter="" getter="" default="2">
Font scaling mode.
</member>
</members>
</class>
3 changes: 3 additions & 0 deletions doc/classes/ResourceImporterImageFont.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
<member name="rows" type="int" setter="" getter="" default="1">
Number of rows in the font image. See also [member columns].
</member>
<member name="scaling_mode" type="int" setter="" getter="" default="2">
Font scaling mode.
</member>
</members>
</class>
24 changes: 24 additions & 0 deletions doc/classes/TextServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@
Returns bitmap font fixed size.
</description>
</method>
<method name="font_get_fixed_size_scale_mode" qualifiers="const">
<return type="int" enum="TextServer.FixedSizeScaleMode" />
<param index="0" name="font_rid" type="RID" />
<description>
Returned bitmap font scaling mode.
</description>
</method>
<method name="font_get_generate_mipmaps" qualifiers="const">
<return type="bool" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -674,6 +681,14 @@
Sets bitmap font fixed size. If set to value greater than zero, same cache entry will be used for all font sizes.
</description>
</method>
<method name="font_set_fixed_size_scale_mode">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="fixed_size_scale_mode" type="int" enum="TextServer.FixedSizeScaleMode" />
<description>
Sets bitmap font scaling mode. This property is used only if [code]fixed_size[/code] is greater than zero.
</description>
</method>
<method name="font_set_force_autohinter">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -2006,5 +2021,14 @@
<constant name="STRUCTURED_TEXT_CUSTOM" value="6" enum="StructuredTextParser">
User defined structured text BiDi override function.
</constant>
<constant name="FIXED_SIZE_SCALE_DISABLE" value="0" enum="FixedSizeScaleMode">
Bitmap font is not scaled.
</constant>
<constant name="FIXED_SIZE_SCALE_INTEGER_ONLY" value="1" enum="FixedSizeScaleMode">
Bitmap font is scaled to the closest integer multiple of the font's fixed size. This is the recommended option for pixel art fonts.
</constant>
<constant name="FIXED_SIZE_SCALE_ENABLED" value="2" enum="FixedSizeScaleMode">
Bitmap font is scaled to an arbitrary (fractional) size. This is the recommended option for non-pixel art fonts.
</constant>
</constants>
</class>
13 changes: 13 additions & 0 deletions doc/classes/TextServerExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@
<description>
</description>
</method>
<method name="_font_get_fixed_size_scale_mode" qualifiers="virtual const">
<return type="int" enum="TextServer.FixedSizeScaleMode" />
<param index="0" name="font_rid" type="RID" />
<description>
</description>
</method>
<method name="_font_get_generate_mipmaps" qualifiers="virtual const">
<return type="bool" />
<param index="0" name="font_rid" type="RID" />
Expand Down Expand Up @@ -590,6 +596,13 @@
<description>
</description>
</method>
<method name="_font_set_fixed_size_scale_mode" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
<param index="1" name="fixed_size_scale_mode" type="int" enum="TextServer.FixedSizeScaleMode" />
<description>
</description>
</method>
<method name="_font_set_force_autohinter" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
Expand Down
3 changes: 3 additions & 0 deletions editor/import/resource_importer_bmfont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ void ResourceImporterBMFont::get_import_options(const String &p_path, List<Impor
r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array()));

r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "scaling_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled (Integer),Enabled (Fractional)"), TextServer::FIXED_SIZE_SCALE_ENABLED));
}

Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
print_verbose("Importing BMFont font from: " + p_source_file);

Array fallbacks = p_options["fallbacks"];
TextServer::FixedSizeScaleMode smode = (TextServer::FixedSizeScaleMode)p_options["scaling_mode"].operator int();

Ref<FontFile> font;
font.instantiate();
Expand All @@ -78,6 +80,7 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &

font->set_allow_system_fallback(false);
font->set_fallbacks(fallbacks);
font->set_fixed_size_scale_mode(smode);

int flg = 0;
if ((bool)p_options["compress"]) {
Expand Down
3 changes: 3 additions & 0 deletions editor/import/resource_importer_imagefont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void ResourceImporterImageFont::get_import_options(const String &p_path, List<Im
r_options->push_back(ImportOption(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), Array()));

r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "scaling_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled (Integer),Enabled (Fractional)"), TextServer::FIXED_SIZE_SCALE_ENABLED));
}

bool ResourceImporterImageFont::_decode_range(const String &p_token, int32_t &r_pos) {
Expand Down Expand Up @@ -98,6 +99,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
Array fallbacks = p_options["fallbacks"];
Rect2i img_margin = p_options["image_margin"];
Rect2i char_margin = p_options["character_margin"];
TextServer::FixedSizeScaleMode smode = (TextServer::FixedSizeScaleMode)p_options["scaling_mode"].operator int();

Ref<Image> img;
img.instantiate();
Expand Down Expand Up @@ -126,6 +128,7 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
font->set_oversampling(1.0f);
font->set_fallbacks(fallbacks);
font->set_texture_image(0, Vector2i(chr_height, 0), 0, img);
font->set_fixed_size_scale_mode(smode);

int pos = 0;
for (int i = 0; i < ranges.size(); i++) {
Expand Down
114 changes: 110 additions & 4 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2249,7 +2249,7 @@ void TextServerAdvanced::_font_set_msdf_size(const RID &p_font_rid, int64_t p_ms

int64_t TextServerAdvanced::_font_get_msdf_size(const RID &p_font_rid) const {
FontAdvanced *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;
Expand All @@ -2265,12 +2265,28 @@ void TextServerAdvanced::_font_set_fixed_size(const RID &p_font_rid, int64_t p_f

int64_t TextServerAdvanced::_font_get_fixed_size(const RID &p_font_rid) const {
FontAdvanced *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 TextServerAdvanced::_font_set_fixed_size_scale_mode(const RID &p_font_rid, TextServer::FixedSizeScaleMode p_fixed_size_scale_mode) {
FontAdvanced *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 TextServerAdvanced::_font_get_fixed_size_scale_mode(const RID &p_font_rid) const {
FontAdvanced *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 TextServerAdvanced::_font_set_allow_system_fallback(const RID &p_font_rid, bool p_allow_system_fallback) {
FontAdvanced *fd = _get_font_data(p_font_rid);
ERR_FAIL_NULL(fd);
Expand Down Expand Up @@ -2507,6 +2523,12 @@ double TextServerAdvanced::_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;
}
Expand All @@ -2533,6 +2555,12 @@ double TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -2560,6 +2588,12 @@ double TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -2587,6 +2621,12 @@ double TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -2619,6 +2659,12 @@ double TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -2828,6 +2874,12 @@ Vector2 TextServerAdvanced::_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 {
Expand Down Expand Up @@ -2875,6 +2927,12 @@ Vector2 TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -2920,6 +2978,12 @@ Vector2 TextServerAdvanced::_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;
}
Expand Down Expand Up @@ -3143,6 +3207,12 @@ Dictionary TextServerAdvanced::_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])));
Expand Down Expand Up @@ -3225,6 +3295,12 @@ Vector2 TextServerAdvanced::_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];
}
Expand All @@ -3235,6 +3311,12 @@ Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_s
FT_Get_Kerning(fd->cache[size]->face, p_glyph_pair.x, p_glyph_pair.y, 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);
}
Expand Down Expand Up @@ -3499,8 +3581,20 @@ void TextServerAdvanced::_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 {
Expand Down Expand Up @@ -3591,8 +3685,20 @@ void TextServerAdvanced::_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 {
Expand Down
4 changes: 4 additions & 0 deletions modules/text_server_adv/text_server_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ class TextServerAdvanced : public TextServerExtension {
bool mipmaps = false;
bool msdf = false;
int msdf_range = 14;
FixedSizeScaleMode fixed_size_scale_mode = FIXED_SIZE_SCALE_DISABLE;
int msdf_source_size = 48;
int fixed_size = 0;
bool allow_system_fallback = true;
Expand Down Expand Up @@ -763,6 +764,9 @@ class TextServerAdvanced : public TextServerExtension {
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 &);

Expand Down
Loading

0 comments on commit b1fe1f1

Please sign in to comment.