Add MSDF and mipmap generation project settings for the default font

This can be used to improve Label3D and scaled Control appearance
in prototypes.
This commit is contained in:
Hugo Locurcio 2022-04-22 20:05:54 +02:00
parent 68ee730774
commit 43c34bf611
No known key found for this signature in database
GPG Key ID: 39E8F8BE30B0A49C
5 changed files with 23 additions and 7 deletions

View File

@ -578,9 +578,19 @@
<member name="gui/theme/default_font_antialiased" type="bool" setter="" getter="" default="true">
If set to [code]true[/code], default font uses 8-bit anitialiased glyph rendering. See [member FontData.antialiased].
</member>
<member name="gui/theme/default_font_generate_mipmaps" type="bool" setter="" getter="" default="false">
If set to [code]true[/code], the default font will have mipmaps generated. This prevents text from looking grainy when a [Control] is scaled down, or when a [Label3D] is viewed from a long distance (if [member Label3D.texture_filter] is set to a mode that displays mipmaps).
Enabling [member gui/theme/default_font_generate_mipmaps] increases font generation time and memory usage. Only enable this setting if you actually need it.
[b]Note:[/b] This setting does not affect custom [Font]s used within the project.
</member>
<member name="gui/theme/default_font_hinting" type="int" setter="" getter="" default="1">
Default font hinting mode. See [member FontData.hinting].
</member>
<member name="gui/theme/default_font_multichannel_signed_distance_field" type="bool" setter="" getter="" default="false">
If set to [code]true[/code], the default font will use multichannel signed distance field (MSDF) for crisp rendering at any size. Since this approach does not rely on rasterizing the font every time its size changes, this allows for resizing the font in real-time without any performance penalty. Text will also not look grainy for [Control]s that are scaled down (or for [Label3D]s viewed from a long distance).
MSDF font rendering can be combined with [member gui/theme/default_font_generate_mipmaps] to further improve font rendering quality when scaled down.
[b]Note:[/b] This setting does not affect custom [Font]s used within the project.
</member>
<member name="gui/theme/default_font_subpixel_positioning" type="int" setter="" getter="" default="1">
Default font glyph sub-pixel positioning mode. See [member FontData.subpixel_positioning].
</member>

View File

@ -1109,6 +1109,9 @@ void initialize_theme() {
TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST("gui/theme/default_font_subpixel_positioning", TextServer::SUBPIXEL_POSITIONING_AUTO);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_subpixel_positioning", PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false);
const bool font_generate_mipmaps = GLOBAL_DEF_RST("gui/theme/default_font_generate_mipmaps", false);
Ref<Font> font;
if (!font_path.is_empty()) {
font = ResourceLoader::load(font_path);
@ -1119,7 +1122,7 @@ void initialize_theme() {
// Always make the default theme to avoid invalid default font/icon/style in the given theme.
if (RenderingServer::get_singleton()) {
make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiased);
make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiased, font_msdf, font_generate_mipmaps);
}
if (!theme_path.is_empty()) {

View File

@ -1026,7 +1026,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
default_style = make_flat_stylebox(Color(1, 0.365, 0.365), 4, 4, 4, 4, 0, false, 2);
}
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa) {
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel, TextServer::Hinting p_font_hinting, bool p_font_antialiased, bool p_font_msdf, bool p_font_generate_mipmaps) {
Ref<Theme> t;
t.instantiate();
@ -1051,9 +1051,12 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
Ref<FontData> dynamic_font_data;
dynamic_font_data.instantiate();
dynamic_font_data->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
dynamic_font_data->set_subpixel_positioning(p_subpixel);
dynamic_font_data->set_hinting(p_hinting);
dynamic_font_data->set_antialiased(p_aa);
dynamic_font_data->set_subpixel_positioning(p_font_subpixel);
dynamic_font_data->set_hinting(p_font_hinting);
dynamic_font_data->set_antialiased(p_font_antialiased);
dynamic_font_data->set_multichannel_signed_distance_field(p_font_msdf);
dynamic_font_data->set_generate_mipmaps(p_font_generate_mipmaps);
dynamic_font->add_data(dynamic_font_data);
default_font = dynamic_font;

View File

@ -36,7 +36,7 @@
const int default_font_size = 16;
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa);
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, bool p_font_antialiased = true, bool p_font_msdf = false, bool p_font_generate_mipmaps = false);
void clear_default_theme();
#endif

View File

@ -199,7 +199,7 @@ struct GodotTestCaseListener : public doctest::IReporter {
memnew(InputMap);
InputMap::get_singleton()->load_default();
make_default_theme(1.0, Ref<Font>(), TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::HINTING_LIGHT, true);
make_default_theme(1.0, Ref<Font>());
memnew(SceneTree);
SceneTree::get_singleton()->initialize();