Add an hinting mode setting to DynamicFonts

- Editor font hinting can now be tweaked in the Editor Settings.
- DynamicFonts used in projects now have tweakable hinting settings
  in their DynamicFontData child. Changes will be visible upon
  reloading the scene in the editor.

(cherry picked from commit c1544c12ef)
This commit is contained in:
Hugo Locurcio 2018-02-27 15:04:08 +01:00 committed by Hein-Pieter van Braam
parent 99331ca395
commit 8a0966a8cb
4 changed files with 65 additions and 11 deletions

View File

@ -103,9 +103,11 @@ void editor_register_fonts(Ref<Theme> p_theme) {
/* Custom font */ /* Custom font */
String custom_font = EditorSettings::get_singleton()->get("interface/editor/main_font"); String custom_font = EditorSettings::get_singleton()->get("interface/editor/main_font");
DynamicFontData::Hinting font_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/main_font_hinting");
Ref<DynamicFontData> CustomFont; Ref<DynamicFontData> CustomFont;
if (custom_font.length() > 0) { if (custom_font.length() > 0) {
CustomFont.instance(); CustomFont.instance();
CustomFont->set_hinting(font_hinting);
CustomFont->set_font_path(custom_font); CustomFont->set_font_path(custom_font);
CustomFont->set_force_autohinter(true); //just looks better..i think? CustomFont->set_force_autohinter(true); //just looks better..i think?
} }
@ -113,9 +115,11 @@ void editor_register_fonts(Ref<Theme> p_theme) {
/* Custom source code font */ /* Custom source code font */
String custom_font_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); String custom_font_source = EditorSettings::get_singleton()->get("interface/editor/code_font");
DynamicFontData::Hinting font_source_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/code_font_hinting");
Ref<DynamicFontData> CustomFontSource; Ref<DynamicFontData> CustomFontSource;
if (custom_font_source.length() > 0) { if (custom_font_source.length() > 0) {
CustomFontSource.instance(); CustomFontSource.instance();
CustomFontSource->set_hinting(font_source_hinting);
CustomFontSource->set_font_path(custom_font_source); CustomFontSource->set_font_path(custom_font_source);
} }
@ -123,38 +127,45 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<DynamicFontData> DefaultFont; Ref<DynamicFontData> DefaultFont;
DefaultFont.instance(); DefaultFont.instance();
DefaultFont->set_hinting(font_hinting);
DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size); DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size);
DefaultFont->set_force_autohinter(true); //just looks better..i think? DefaultFont->set_force_autohinter(true); //just looks better..i think?
Ref<DynamicFontData> FontFallback; Ref<DynamicFontData> FontFallback;
FontFallback.instance(); FontFallback.instance();
FontFallback->set_hinting(font_hinting);
FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size);
FontFallback->set_force_autohinter(true); //just looks better..i think? FontFallback->set_force_autohinter(true); //just looks better..i think?
Ref<DynamicFontData> FontJapanese; Ref<DynamicFontData> FontJapanese;
FontJapanese.instance(); FontJapanese.instance();
FontJapanese->set_hinting(font_hinting);
FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size);
FontJapanese->set_force_autohinter(true); //just looks better..i think? FontJapanese->set_force_autohinter(true); //just looks better..i think?
Ref<DynamicFontData> FontArabic; Ref<DynamicFontData> FontArabic;
FontArabic.instance(); FontArabic.instance();
FontArabic->set_hinting(font_hinting);
FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
FontArabic->set_force_autohinter(true); //just looks better..i think? FontArabic->set_force_autohinter(true); //just looks better..i think?
Ref<DynamicFontData> FontHebrew; Ref<DynamicFontData> FontHebrew;
FontHebrew.instance(); FontHebrew.instance();
FontHebrew->set_hinting(font_hinting);
FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size); FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size);
FontHebrew->set_force_autohinter(true); //just looks better..i think? FontHebrew->set_force_autohinter(true); //just looks better..i think?
Ref<DynamicFontData> FontThai; Ref<DynamicFontData> FontThai;
FontThai.instance(); FontThai.instance();
FontThai->set_hinting(font_hinting);
FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
FontThai->set_force_autohinter(true); //just looks better..i think? FontThai->set_force_autohinter(true); //just looks better..i think?
/* Source Code Pro */ /* Hack */
Ref<DynamicFontData> dfmono; Ref<DynamicFontData> dfmono;
dfmono.instance(); dfmono.instance();
dfmono->set_hinting(font_source_hinting);
dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size); dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size);
//dfd->set_force_autohinter(true); //just looks better..i think? //dfd->set_force_autohinter(true); //just looks better..i think?

View File

@ -285,6 +285,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/code_font_size", 14); _initial_set("interface/editor/code_font_size", 14);
hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/main_font_hinting", 2);
hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/code_font_hinting", 2);
hints["interface/editor/code_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/code_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/main_font", ""); _initial_set("interface/editor/main_font", "");
hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/code_font", ""); _initial_set("interface/editor/code_font", "");

View File

@ -80,6 +80,14 @@ void DynamicFontData::set_force_autohinter(bool p_force) {
void DynamicFontData::_bind_methods() { void DynamicFontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path); ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path);
ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path); ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path);
ClassDB::bind_method(D_METHOD("set_hinting", "mode"), &DynamicFontData::set_hinting);
ClassDB::bind_method(D_METHOD("get_hinting"), &DynamicFontData::get_hinting);
ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting");
BIND_ENUM_CONSTANT(HINTING_NONE);
BIND_ENUM_CONSTANT(HINTING_LIGHT);
BIND_ENUM_CONSTANT(HINTING_NORMAL);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_path", PROPERTY_HINT_FILE, "*.ttf,*.otf"), "set_font_path", "get_font_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_path", PROPERTY_HINT_FILE, "*.ttf,*.otf"), "set_font_path", "get_font_path");
} }
@ -87,6 +95,7 @@ void DynamicFontData::_bind_methods() {
DynamicFontData::DynamicFontData() { DynamicFontData::DynamicFontData() {
force_autohinter = false; force_autohinter = false;
hinting = DynamicFontData::HINTING_NORMAL;
font_mem = NULL; font_mem = NULL;
font_mem_size = 0; font_mem_size = 0;
} }
@ -197,8 +206,6 @@ Error DynamicFontAtSize::_load() {
if (id.filter) if (id.filter)
texture_flags |= Texture::FLAG_FILTER; texture_flags |= Texture::FLAG_FILTER;
//print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER));
valid = true; valid = true;
return OK; return OK;
} }
@ -431,15 +438,28 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
char_map[p_char] = ch; char_map[p_char] = ch;
return; return;
} }
int error = FT_Load_Char(face, p_char, FT_LOAD_RENDER | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
int ft_hinting;
switch (font->hinting) {
case DynamicFontData::HINTING_NONE:
ft_hinting = FT_LOAD_NO_HINTING;
break;
case DynamicFontData::HINTING_LIGHT:
ft_hinting = FT_LOAD_TARGET_LIGHT;
break;
default:
ft_hinting = FT_LOAD_TARGET_NORMAL;
break;
}
int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0) | ft_hinting);
if (!error) { if (!error) {
error = FT_Render_Glyph(face->glyph, ft_render_mode_normal); error = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
} }
if (error) { if (error) {
int advance = 0; int advance = 0;
//stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0);
//print_line("char has no bitmap: "+itos(p_char)+" but advance is "+itos(advance*scale));
Character ch; Character ch;
ch.texture_idx = -1; ch.texture_idx = -1;
ch.advance = advance; ch.advance = advance;
@ -454,7 +474,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
int w = slot->bitmap.width; int w = slot->bitmap.width;
int h = slot->bitmap.rows; int h = slot->bitmap.rows;
//int p = slot->bitmap.pitch;
int yofs = slot->bitmap_top; int yofs = slot->bitmap_top;
int xofs = slot->bitmap_left; int xofs = slot->bitmap_left;
int advance = slot->advance.x >> 6; int advance = slot->advance.x >> 6;
@ -508,8 +527,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
break; break;
} }
//print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" X: "+itos(tex_x)+" Y: "+itos(tex_y));
if (tex_index == -1) { if (tex_index == -1) {
//could not find texture to fit, create one //could not find texture to fit, create one
tex_x = 0; tex_x = 0;
@ -610,8 +627,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
chr.rect.position /= oversampling; chr.rect.position /= oversampling;
chr.rect.size /= oversampling; chr.rect.size /= oversampling;
//print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs));
char_map[p_char] = chr; char_map[p_char] = chr;
} }
@ -722,6 +737,18 @@ void DynamicFont::set_use_filter(bool p_enable) {
_reload_cache(); _reload_cache();
} }
DynamicFontData::Hinting DynamicFontData::get_hinting() const {
return hinting;
}
void DynamicFontData::set_hinting(Hinting p_hinting) {
if (hinting == p_hinting)
return;
hinting = p_hinting;
}
int DynamicFont::get_spacing(int p_type) const { int DynamicFont::get_spacing(int p_type) const {
if (p_type == SPACING_TOP) { if (p_type == SPACING_TOP) {

View File

@ -64,10 +64,20 @@ public:
} }
}; };
enum Hinting {
HINTING_NONE,
HINTING_LIGHT,
HINTING_NORMAL
};
Hinting get_hinting() const;
void set_hinting(Hinting p_hinting);
private: private:
const uint8_t *font_mem; const uint8_t *font_mem;
int font_mem_size; int font_mem_size;
bool force_autohinter; bool force_autohinter;
Hinting hinting;
String font_path; String font_path;
Map<CacheID, DynamicFontAtSize *> size_cache; Map<CacheID, DynamicFontAtSize *> size_cache;
@ -91,6 +101,8 @@ public:
~DynamicFontData(); ~DynamicFontData();
}; };
VARIANT_ENUM_CAST(DynamicFontData::Hinting);
class DynamicFontAtSize : public Reference { class DynamicFontAtSize : public Reference {
GDCLASS(DynamicFontAtSize, Reference) GDCLASS(DynamicFontAtSize, Reference)