Use a DynamicFont for the default project theme

This makes font oversampling work out of the box, while also increasing
the supported character set's size. The default font is now larger
as well to better fit today's screen resolutions.

The OpenSans SemiBold font was chosen for two reasons:

- Small file size, yet its character set supports Latin-1 and Cyrillic
  text.
- A heavier font weight looks better in most "game" scenarios and is
  more readable against mixed-color backgrounds.

This is considered a breaking change as it changes the default font's
metrics, which will likely affect how Control nodes are laid out in
scenes (unless a custom font is in use).
This commit is contained in:
Hugo Locurcio 2020-06-16 20:34:48 +02:00
parent c6bef53727
commit d211c05111
No known key found for this signature in database
GPG Key ID: 39E8F8BE30B0A49C
8 changed files with 77 additions and 38629 deletions

View File

@ -53,7 +53,7 @@ def make_fonts_header(target, source, env):
g.write("#ifndef _EDITOR_FONTS_H\n")
g.write("#define _EDITOR_FONTS_H\n")
# saving uncompressed, since freetype will reference from memory pointer
# Saving uncompressed, since FreeType will reference from memory pointer.
for i in range(len(source)):
with open(source[i], "rb") as f:
buf = f.read()

View File

@ -2,4 +2,16 @@
Import("env")
import os
import os.path
from platform_methods import run_in_subprocess
import default_theme_builders
env.add_source_files(env.scene_sources, "*.cpp")
env.Depends("#scene/resources/default_theme/default_font.gen.h", "#thirdparty/fonts/OpenSans_SemiBold.ttf")
env.CommandNoCache(
"#scene/resources/default_theme/default_font.gen.h",
"#thirdparty/fonts/OpenSans_SemiBold.ttf",
run_in_subprocess(default_theme_builders.make_fonts_header),
)

View File

@ -30,15 +30,12 @@
#include "default_theme.h"
#include "scene/resources/theme.h"
#include "core/os/os.h"
#include "theme_data.h"
#include "font_hidpi.inc"
#include "font_lodpi.inc"
#include "default_font.gen.h"
#include "scene/resources/font.h"
#include "scene/resources/theme.h"
#include "servers/text_server.h"
#include "theme_data.h"
typedef Map<const void *, Ref<ImageTexture>> TexCacheMap;
@ -128,38 +125,6 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
return texture;
}
static Ref<FontData> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) {
Ref<FontData> font(memnew(FontData));
font->new_bitmap(p_height, p_ascent, p_height);
Ref<Image> image = memnew(Image(p_img));
Ref<ImageTexture> tex = memnew(ImageTexture);
tex->create_from_image(image);
font->bitmap_add_texture(tex);
for (int i = 0; i < p_charcount; i++) {
const int *c = &p_char_rects[i * 8];
int chr = c[0];
Rect2 frect;
frect.position.x = c[1];
frect.position.y = c[2];
frect.size.x = c[3];
frect.size.y = c[4];
Point2 align(c[6], c[5]);
int advance = c[7];
font->bitmap_add_char(chr, 0, frect, align, advance);
}
for (int i = 0; i < p_kerning_count; i++) {
font->bitmap_add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]);
}
return font;
}
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
Ref<StyleBox> style(memnew(StyleBoxEmpty));
@ -1024,18 +989,25 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
int default_font_size = 14;
int default_font_size = 16;
if (p_font.is_valid()) {
// Use the custom font defined in the Project Settings.
default_font = p_font;
} else if (p_hidpi) {
Ref<FontData> font_data = make_font(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data);
default_font.instance();
default_font->add_data(font_data);
} else {
Ref<FontData> font_data = make_font(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data);
default_font.instance();
default_font->add_data(font_data);
// Use the default DynamicFont (separate from the editor font).
// The default DynamicFont is chosen to have a small file size since it's
// embedded in both editor and export template binaries.
Ref<Font> dynamic_font;
dynamic_font.instance();
Ref<FontData> dynamic_font_data;
dynamic_font_data.instance();
dynamic_font_data->load_memory(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size, "ttf", default_font_size);
dynamic_font->add_data(dynamic_font_data);
default_font = dynamic_font;
}
Ref<Font> large_font = default_font;
fill_default_theme(t, default_font, large_font, default_icon, default_style, p_hidpi ? 2.0 : 1.0);

View File

@ -0,0 +1,40 @@
"""Functions used to generate source files during build time
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
"""
import os
import os.path
from platform_methods import subprocess_main
def make_fonts_header(target, source, env):
dst = target[0]
g = open(dst, "w", encoding="utf-8")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _DEFAULT_FONTS_H\n")
g.write("#define _DEFAULT_FONTS_H\n")
# Saving uncompressed, since FreeType will reference from memory pointer.
for i in range(len(source)):
with open(source[i], "rb") as f:
buf = f.read()
name = os.path.splitext(os.path.basename(source[i]))[0]
g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n")
g.write("static const unsigned char _font_" + name + "[] = {\n")
for j in range(len(buf)):
g.write("\t" + str(buf[j]) + ",\n")
g.write("};\n")
g.write("#endif")
g.close()
if __name__ == "__main__":
subprocess_main(globals())

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -72,7 +72,7 @@ Files extracted from upstream:
- All cpp files listed in `modules/raycast/godot_update_embree.py`
- All header files in the directories listed in `modules/raycast/godot_update_embree.py`
The `modules/raycast/godot_update_embree.py`script can be used to pull the
The `modules/raycast/godot_update_embree.py` script can be used to pull the
relevant files from the latest Embree-aarch64 release and apply some automatic changes.
Some changes have been made in order to remove exceptions and fix minor build errors.
@ -137,6 +137,10 @@ Files extracted from upstream source:
* Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/
* Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted)
* License: Apache 2.0
- `OpenSans_SemiBold.ttf`:
* Upstream: https://fonts.google.com/specimen/Open+Sans
* Version: 1.10 (downloaded from Google Fonts in February 2021)
* License: Apache 2.0
- `Tamsyn*.png`:
* Upstream: http://www.fial.com/~scott/tamsyn-font/
* Version: 1.11 (2015)

BIN
thirdparty/fonts/OpenSans_SemiBold.ttf vendored Normal file

Binary file not shown.