From 16c002fe7c5d9f41f2a4f8de1b7a03fb83563e63 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 20 Nov 2017 12:51:02 -0500 Subject: [PATCH] Font italics and bold working on Windows --- 4ed_font.h | 1 + 4ed_font_provider_freetype.cpp | 88 ++++++++++++++++++++++++++++------ 4ed_font_provider_freetype.h | 27 +++++++++-- platform_linux/linux_4ed.cpp | 6 +++ platform_mac/mac_4ed.cpp | 6 +++ platform_win32/win32_4ed.cpp | 14 ++++-- 6 files changed, 121 insertions(+), 21 deletions(-) diff --git a/4ed_font.h b/4ed_font.h index c863a0e4..cc52d08c 100644 --- a/4ed_font.h +++ b/4ed_font.h @@ -15,6 +15,7 @@ // NOTE(allen): A description of an available font. struct Font_Loadable_Stub{ b32 load_from_path; + b32 in_font_folder; i32 len; char name[256]; }; diff --git a/4ed_font_provider_freetype.cpp b/4ed_font_provider_freetype.cpp index 51163893..a930c0b2 100644 --- a/4ed_font_provider_freetype.cpp +++ b/4ed_font_provider_freetype.cpp @@ -33,23 +33,56 @@ font_ft_flags(b32 use_hinting){ } internal b32 -font_ft_get_face(FT_Library ft, Font_Loadable_Stub *stub, FT_Face *face){ +font_ft_get_face(FT_Library ft, Font_Loadable_Stub *stub, Font_Parameters *parameters, FT_Face *face){ b32 success = true; + b32 do_transform = false; if (stub->load_from_path){ + // TODO(allen): Look for italics/bold stuff? FT_Error error = FT_New_Face(ft, stub->name, 0, face); success = (error == 0); + do_transform = success; } else{ - Font_Raw_Data data = system_font_data(stub->name); - if (data.size > 0){ - FT_Error error = FT_New_Memory_Face(ft, data.data, data.size, 0, face); - success = (error == 0); + switch (system_font_method){ + case SystemFontMethod_FilePath: + { + Font_Path path = system_font_path(stub->name, parameters); + if (path.len > 0){ + FT_Error error = FT_New_Face(ft, path.name, 0, face); + success = (error == 0); + do_transform = (success && path.used_base_file); + } + else{ + success = false; + } + end_temp_memory(path.temp); + }break; + + case SystemFontMethod_RawData: + { + Font_Raw_Data data = system_font_data(stub->name, parameters); + if (data.size > 0){ + FT_Error error = FT_New_Memory_Face(ft, data.data, data.size, 0, face); + success = (error == 0); + do_transform = (success && data.used_base_file); + } + else{ + success = false; + } + end_temp_memory(data.temp); + }break; } - else{ - success = false; - } - end_temp_memory(data.temp); } + +#if 0 + if (do_transform && parameters != 0){ + if (parameters->italics || parameters->bold){ + FT_Matrix matrix = {0}; + FT_Set_Transform(face, &matrix, 0); + } + } +#endif + return(success); } @@ -62,7 +95,7 @@ font_load_name(Font_Loadable_Stub *stub, char *buffer, i32 capacity){ FT_Init_FreeType(&ft); FT_Face face; - if (font_ft_get_face(ft, stub, &face)){ + if (font_ft_get_face(ft, stub, 0, &face)){ char *name = face->family_name; i32 name_len = str_size(name); if (name_len < capacity){ @@ -84,14 +117,21 @@ font_load_page_layout(Font_Settings *settings, Font_Metrics *metrics, Glyph_Page page->has_layout = true; u32 pt_size = settings->parameters.pt_size; + b32 italics = settings->parameters.italics; + b32 bold = settings->parameters.bold; + b32 underline = settings->parameters.underline; b32 use_hinting = settings->parameters.use_hinting; + AllowLocal(italics); + AllowLocal(bold); + AllowLocal(underline); + // TODO(allen): Stop redoing all this init for each call. FT_Library ft; FT_Init_FreeType(&ft); FT_Face face; - b32 has_a_good_face = font_ft_get_face(ft, &settings->stub, &face); + b32 has_a_good_face = font_ft_get_face(ft, &settings->stub, &settings->parameters, &face); if (has_a_good_face){ FT_Size_RequestRec_ size = {}; @@ -176,15 +216,22 @@ font_load_page_pixels(Partition *part, Font_Settings *settings, Glyph_Page *page Assert(page->has_layout); Assert(page->page_number == page_number); - i32 pt_size = settings->parameters.pt_size; + u32 pt_size = settings->parameters.pt_size; + b32 italics = settings->parameters.italics; + b32 bold = settings->parameters.bold; + b32 underline = settings->parameters.underline; b32 use_hinting = settings->parameters.use_hinting; + AllowLocal(italics); + AllowLocal(bold); + AllowLocal(underline); + // TODO(allen): Stop redoing all this init for each call. FT_Library ft; FT_Init_FreeType(&ft); FT_Face face; - b32 has_a_good_face = font_ft_get_face(ft, &settings->stub, &face); + b32 has_a_good_face = font_ft_get_face(ft, &settings->stub, &settings->parameters, &face); u32 *pixels = 0; if (has_a_good_face){ @@ -292,7 +339,7 @@ font_load(System_Functions *system, Font_Settings *settings, Font_Metrics *metri FT_Init_FreeType(&ft); FT_Face face; - b32 success = font_ft_get_face(ft, &settings->stub, &face); + b32 success = font_ft_get_face(ft, &settings->stub, &settings->parameters, &face); if (success){ FT_Size_RequestRec_ size = {}; @@ -707,6 +754,7 @@ system_font_get_local_stubs(Partition *part){ sll_push(list.first, list.last, setup); setup->stub.load_from_path = true; + setup->stub.in_font_folder = true; memcpy(&setup->stub.name[0], directory, dir_len); memcpy(&setup->stub.name[dir_len], filename, len + 1); setup->stub.len = dir_len + len; @@ -775,7 +823,17 @@ system_font_init(Font_Functions *font_links, u32 pt_size, b32 use_hinting, Font_ } if (name_good){ - memcpy(&loadable->stub, stub, sizeof(*stub)); + if (stub->in_font_folder){ + memcpy(&loadable->stub, stub, sizeof(*stub)); + } + else{ + stub->load_from_path = false; + stub->in_font_folder = false; + stub->len = loadable->display_len; + memset(loadable->stub.name, 0, sizeof(stub->name)); + memcpy(loadable->stub.name, loadable->display_name, stub->len); + } + loadable->valid = true; ++fontvars.loadable_count; } diff --git a/4ed_font_provider_freetype.h b/4ed_font_provider_freetype.h index ef1a60b8..f1a944ce 100644 --- a/4ed_font_provider_freetype.h +++ b/4ed_font_provider_freetype.h @@ -76,17 +76,38 @@ struct Font_Setup_List{ }; // NOTE(allen): Procedures to be implemented per-OS for the freetype font provider. +struct Font_Path{ + Temp_Memory temp; + char *name; + i32 len; + b32 used_base_file; +}; + struct Font_Raw_Data{ Temp_Memory temp; u8 *data; i32 size; + b32 used_base_file; }; -#define Sys_Font_Data(name) Font_Raw_Data system_font_data(char *name) -internal Sys_Font_Data(name); +enum{ + SystemFontMethod_FilePath, + SystemFontMethod_RawData, +}; + +#define Sys_Font_Path(name, parameters) Font_Path system_font_path(char *name, Font_Parameters *parameters) +internal Sys_Font_Path(name, parameters); + +#define Sys_Font_Path_Not_Used \ +internal Sys_Font_Path(n,p){ \ + Font_Path path = {0}; LOG("there is no font path retrieval procedure available\n"); return(path);} + +#define Sys_Font_Data(name, parameters) Font_Raw_Data system_font_data(char *name, Font_Parameters *parameters) +internal Sys_Font_Data(name, parameters); #define Sys_Font_Data_Not_Used \ -internal Sys_Font_Data(name){Font_Raw_Data data = {0}; LOG("there is no font data retrieval procedure available\n"); return(data);} +internal Sys_Font_Data(n,p){ \ + Font_Raw_Data data = {0}; LOG("there is no font data retrieval procedure available\n"); return(data);} #endif diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index 9d9a32a2..b6a6c807 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -458,12 +458,18 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ } #include "4ed_font_provider_freetype.h" +global u32 system_font_method = SystemFontMethod_FilePath; #include "4ed_font_provider_freetype.cpp" #undef internal #include #define internal static +internal +Sys_Font_Path(name, parameters){ + // TODO(allen) +} + Sys_Font_Data_Not_Used; internal char* diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 64b271c6..5d45916d 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -333,8 +333,14 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ } #include "4ed_font_provider_freetype.h" +global u32 system_font_method = SystemFontMethod_FilePath; #include "4ed_font_provider_freetype.cpp" +internal +Sys_Font_Path(name, parameters){ + // TODO(allen) +} + Sys_Font_Data_Not_Used; internal void diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index d7983fca..0352a4bd 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -511,19 +511,27 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ } #include "4ed_font_provider_freetype.h" +global u32 system_font_method = SystemFontMethod_RawData; #include "4ed_font_provider_freetype.cpp" +Sys_Font_Path_Not_Used; + internal -Sys_Font_Data(name){ +Sys_Font_Data(name, parameters){ Font_Raw_Data data = {0}; + int weight = FW_REGULAR; + if (parameters->bold){ + weight = FW_BOLD; + } + HFONT hfont = CreateFontA( 0, 0, 0, 0, - 0, - FALSE, // Italic + weight, // Weight + parameters->italics, // Italic FALSE, // Underline FALSE, // Strikeout ANSI_CHARSET,