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.
This commit is contained in:
Hugo Locurcio 2018-02-27 15:04:08 +01:00
parent 636e48b707
commit c1544c12ef
No known key found for this signature in database
GPG Key ID: 39E8F8BE30B0A49C
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

@ -290,6 +290,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;
} }
@ -212,8 +221,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;
} }
@ -454,15 +461,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_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT | (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;
@ -477,7 +497,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;
@ -536,8 +555,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;
@ -645,8 +662,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;
} }
@ -758,6 +773,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)