Skip to content

Commit

Permalink
Merge pull request #60513 from Calinou/default-font-add-msdf-mipmap
Browse files Browse the repository at this point in the history
Add MSDF and mipmap generation project settings for the default font
  • Loading branch information
akien-mga committed Apr 26, 2022
2 parents fce210c + 43c34bf commit e9e2aaf
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 7 deletions.
10 changes: 10 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
5 changes: 4 additions & 1 deletion scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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()) {
Expand Down
11 changes: 7 additions & 4 deletions scene/resources/default_theme/default_theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion scene/resources/default_theme/default_theme.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,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();
Expand Down

0 comments on commit e9e2aaf

Please sign in to comment.