From bca15da440a5bcaf1f1a4f9aa52097a2f475523e Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Mar 2017 21:52:06 -0400 Subject: [PATCH] got fonts working under linux; reorganized layer to more closely match windows --- 4coder_API/types.h | 3 +- linux_4ed.cpp | 190 +++++++++++++++++---------------------- linux_4ed_file_track.cpp | 10 +-- linux_4ed_fonts.cpp | 97 ++++++++++++++------ win32_4ed.cpp | 4 +- win32_4ed_fonts.cpp | 44 +-------- 6 files changed, 163 insertions(+), 185 deletions(-) diff --git a/4coder_API/types.h b/4coder_API/types.h index 6d9a3d6f..3a01b10e 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -424,7 +424,8 @@ STRUCT File_Info{ int32_t folder; }; -/* DOC(File_List is a list of File_Info structs.) */ +/* DOC(File_List is a list of File_Info structs.) +DOC_SEE(File_Info) */ STRUCT File_List{ /* DOC(This field is for inernal use.) */ void *block; diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 0466c92a..eca3eacf 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -98,19 +98,14 @@ #define LINUX_FN_DEBUG(fmt, ...) #endif -#if (__cplusplus <= 199711L) -#define static_assert(x, ...) -#endif - #define SUPPORT_DPI 1 #define InterlockedCompareExchange(dest, ex, comp) __sync_val_compare_and_swap((dest), (comp), (ex)) #include "4ed_file_track.h" +#include "4ed_font_interface_to_os.h" #include "4ed_system_shared.h" -#include "linux_4ed_file_track.cpp" - // // Linux structs / enums // @@ -251,14 +246,6 @@ internal Sys_Release_Lock_Sig(system_release_lock); internal void system_wait_cv(i32, i32); internal void system_signal_cv(i32, i32); -// -// Linux static assertions -// - -static_assert(sizeof(Plat_Handle) >= sizeof(ucontext_t*), "Plat_Handle not big enough"); -static_assert(sizeof(Plat_Handle) >= sizeof(sem_t*), "Plat_Handle not big enough"); -static_assert(sizeof(Plat_Handle) >= sizeof(int), "Plat_Handle not big enough"); - // // Shared system functions (system_shared.h) // @@ -291,20 +278,9 @@ LinuxFreeMemory(void *block){ } } -internal -Sys_Get_Memory_Sig(system_get_memory_){ - return(LinuxGetMemory_(size, line_number, file_name)); -} - -internal -Sys_Free_Memory_Sig(system_free_memory){ - LinuxFreeMemory(block); -} - - internal Sys_File_Can_Be_Made_Sig(system_file_can_be_made){ - b32 result = access(filename, W_OK) == 0; + b32 result = access((char*)filename, W_OK) == 0; LINUX_FN_DEBUG("%s = %d", filename, result); return(result); } @@ -324,6 +300,69 @@ Sys_Get_Binary_Path_Sig(system_get_binary_path){ return size; } +// +// custom.h +// + +internal +Sys_Memory_Allocate_Sig(system_memory_allocate){ + // NOTE(allen): This must return the exact base of the vpage. + // We will count on the user to keep track of size themselves. + void *result = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if(result == MAP_FAILED){ + perror("mmap"); + result = NULL; + } + return(result); +} + +internal +Sys_Memory_Set_Protection_Sig(system_memory_set_protection){ + // NOTE(allen): + // There is no such thing as "write only" in windows + // so I just made write = write + read in all cases. + bool32 result = 1; + int protect = 0; + + flags = flags & 0x7; + + switch (flags){ + case 0: + protect = PROT_NONE; break; + + case MemProtect_Read: + protect = PROT_READ; break; + + case MemProtect_Write: + case MemProtect_Read|MemProtect_Write: + protect = PROT_READ | PROT_WRITE; break; + + case MemProtect_Execute: + protect = PROT_EXEC; break; + + case MemProtect_Execute|MemProtect_Read: + protect = PROT_READ | PROT_EXEC; break; + + // NOTE(inso): some W^X protection things might be unhappy about this one + case MemProtect_Execute|MemProtect_Write: + case MemProtect_Execute|MemProtect_Write|MemProtect_Read: + protect = PROT_READ | PROT_WRITE | PROT_EXEC; break; + } + + if(mprotect(ptr, size, protect) == -1){ + result = 0; + perror("mprotect"); + } + + return(result); +} + +internal +Sys_Memory_Free_Sig(system_memory_free){ + // NOTE(allen): This must take the exact base of the vpage. + munmap(ptr, size); +} + // // System Functions (4ed_system.h) // @@ -342,7 +381,7 @@ Sys_Set_File_List_Sig(system_set_file_list){ b32 clear_list = false; if(directory == 0){ - system_free_memory(file_list->block); + system_memory_free(file_list->block, file_list->block_size); file_list->block = 0; file_list->block_size = 0; file_list->infos = 0; @@ -379,8 +418,8 @@ Sys_Set_File_List_Sig(system_set_file_list){ required_size = character_count + file_count * sizeof(File_Info); if (file_list->block_size < required_size){ - system_free_memory(file_list->block); - file_list->block = system_get_memory(required_size); + system_memory_free(file_list->block, file_list->block_size); + file_list->block = system_memory_allocate(required_size); file_list->block_size = required_size; } @@ -423,7 +462,7 @@ Sys_Set_File_List_Sig(system_set_file_list){ closedir(d); } else { - system_free_memory(file_list->block); + system_memory_free(file_list->block, file_list->block_size); file_list->block = 0; file_list->block_size = 0; file_list->infos = 0; @@ -597,69 +636,6 @@ Sys_Now_Time_Sig(system_now_time){ return(result); } -// -// custom.h -// - -internal -Sys_Memory_Allocate_Sig(system_memory_allocate){ - // NOTE(allen): This must return the exact base of the vpage. - // We will count on the user to keep track of size themselves. - void *result = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(result == MAP_FAILED){ - perror("mmap"); - result = NULL; - } - return(result); -} - -internal -Sys_Memory_Set_Protection_Sig(system_memory_set_protection){ - // NOTE(allen): - // There is no such thing as "write only" in windows - // so I just made write = write + read in all cases. - bool32 result = 1; - int protect = 0; - - flags = flags & 0x7; - - switch (flags){ - case 0: - protect = PROT_NONE; break; - - case MemProtect_Read: - protect = PROT_READ; break; - - case MemProtect_Write: - case MemProtect_Read|MemProtect_Write: - protect = PROT_READ | PROT_WRITE; break; - - case MemProtect_Execute: - protect = PROT_EXEC; break; - - case MemProtect_Execute|MemProtect_Read: - protect = PROT_READ | PROT_EXEC; break; - - // NOTE(inso): some W^X protection things might be unhappy about this one - case MemProtect_Execute|MemProtect_Write: - case MemProtect_Execute|MemProtect_Write|MemProtect_Read: - protect = PROT_READ | PROT_WRITE | PROT_EXEC; break; - } - - if(mprotect(ptr, size, protect) == -1){ - result = 0; - perror("mprotect"); - } - - return(result); -} - -internal -Sys_Memory_Free_Sig(system_memory_free){ - // NOTE(allen): This must take the exact base of the vpage. - munmap(ptr, size); -} - internal Sys_File_Exists_Sig(system_file_exists){ int result = 0; @@ -1075,7 +1051,7 @@ JobThreadProc(void* lpParameter){ internal void initialize_unbounded_queue(Unbounded_Work_Queue *source_queue){ i32 max = 512; - source_queue->jobs = (Full_Job_Data*)system_get_memory(max*sizeof(Full_Job_Data)); + source_queue->jobs = (Full_Job_Data*)system_memory_allocate(max*sizeof(Full_Job_Data)); source_queue->count = 0; source_queue->max = max; source_queue->skip = 0; @@ -1184,12 +1160,12 @@ Sys_Post_Job_Sig(system_post_job){ while (queue->count >= queue->max){ i32 new_max = queue->max*2; - Full_Job_Data *new_jobs = (Full_Job_Data*) - system_get_memory(new_max*sizeof(Full_Job_Data)); + u32 job_size = sizeof(Full_Job_Data); + Full_Job_Data *new_jobs = (Full_Job_Data*)system_memory_allocate(new_max*job_size); memcpy(new_jobs, queue->jobs, queue->count); - system_free_memory(queue->jobs); + system_memory_free(queue->jobs, queue->max*job_size); queue->jobs = new_jobs; queue->max = new_max; @@ -1283,11 +1259,11 @@ Sys_Grow_Thread_Memory_Sig(system_grow_thread_memory){ old_data = memory->data; old_size = memory->size; new_size = l_round_up_i32(memory->size*2, KB(4)); - memory->data = system_get_memory(new_size); + memory->data = system_memory_allocate(new_size); memory->size = new_size; if (old_data){ memcpy(memory->data, old_data, old_size); - system_free_memory(old_data); + system_memory_free(old_data, old_size); } system_release_lock(CANCEL_LOCK0 + memory->id - 1); } @@ -1335,8 +1311,8 @@ INTERNAL_Sys_Get_Thread_States_Sig(internal_get_thread_states){ // Linux rendering/font system functions // +#include "4ed_font_data.h" #include "4ed_system_shared.cpp" -#include "linux_4ed_fonts.cpp" // // End of system funcs @@ -2912,14 +2888,14 @@ main(int argc, char **argv) LinuxLoadRenderCode(); memory_vars.vars_memory_size = MB(2); - memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size); + memory_vars.vars_memory = system_memory_allocate(memory_vars.vars_memory_size); memory_vars.target_memory_size = MB(512); - memory_vars.target_memory = system_get_memory(memory_vars.target_memory_size); + memory_vars.target_memory = system_memory_allocate(memory_vars.target_memory_size); memory_vars.user_memory_size = MB(2); - memory_vars.user_memory = system_get_memory(memory_vars.user_memory_size); + memory_vars.user_memory = system_memory_allocate(memory_vars.user_memory_size); linuxvars.target.max = MB(1); - linuxvars.target.push_buffer = (char*)system_get_memory(linuxvars.target.max); + linuxvars.target.push_buffer = (char*)system_memory_allocate(linuxvars.target.max); if(memory_vars.vars_memory == NULL || memory_vars.target_memory == NULL || memory_vars.user_memory == NULL || linuxvars.target.push_buffer == NULL){ LinuxFatalErrorMsg("Could not allocate sufficient memory. Please make sure you have atleast 512Mb of RAM free. (This requirement will be relaxed in the future)."); @@ -3041,7 +3017,7 @@ main(int argc, char **argv) const size_t stack_size = MB(2); for (i32 i = 0; i < ArrayCount(linuxvars.coroutine_data); ++i){ linuxvars.coroutine_data[i].stack.ss_size = stack_size; - linuxvars.coroutine_data[i].stack.ss_sp = system_get_memory(stack_size); + linuxvars.coroutine_data[i].stack.ss_sp = system_memory_allocate(stack_size); } Thread_Context background[4] = {}; @@ -3376,7 +3352,9 @@ main(int argc, char **argv) return 0; } -#include "font/4coder_font_static_functions.cpp" +#include "linux_4ed_fonts.cpp" +#include "linux_4ed_file_track.cpp" +#include "4ed_font_static_functions.cpp" // BOTTOM // vim: expandtab:ts=4:sts=4:sw=4 diff --git a/linux_4ed_file_track.cpp b/linux_4ed_file_track.cpp index 7aa3c29a..348aaff4 100644 --- a/linux_4ed_file_track.cpp +++ b/linux_4ed_file_track.cpp @@ -64,7 +64,7 @@ init_track_system(File_Track_System *system, Partition *scratch, void *table_mem } FILE_TRACK_LINK File_Track_Result -add_listener(File_Track_System *system, Partition *scratch, char *filename){ +add_listener(File_Track_System *system, Partition *scratch, u8 *filename){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); @@ -72,7 +72,7 @@ add_listener(File_Track_System *system, Partition *scratch, char *filename){ pthread_mutex_lock(&vars->lock); if(tracking_system_has_space(tables, 1)){ - char *dir = dirname(strdupa(filename)); + char *dir = dirname(strdupa((char*)filename)); size_t dir_len = strlen(dir) + 1; if(vars->string_mem_end - vars->string_mem_begin >= dir_len){ @@ -114,7 +114,7 @@ add_listener(File_Track_System *system, Partition *scratch, char *filename){ } FILE_TRACK_LINK File_Track_Result -remove_listener(File_Track_System *system, Partition *scratch, char *filename){ +remove_listener(File_Track_System *system, Partition *scratch, u8 *filename){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); @@ -122,7 +122,7 @@ remove_listener(File_Track_System *system, Partition *scratch, char *filename){ pthread_mutex_lock(&vars->lock); - char *dir = dirname(strdupa(filename)); + char *dir = dirname(strdupa((char*)filename)); // NOTE(inso): this assumes the filename was previously added for(uint32_t i = 0; i < tables->max; ++i){ @@ -199,7 +199,7 @@ expand_track_system_listeners(File_Track_System *system, Partition *scratch, voi } FILE_TRACK_LINK File_Track_Result -get_change_event(File_Track_System *system, Partition *scratch, char *buffer, int32_t max, int32_t *size){ +get_change_event(File_Track_System *system, Partition *scratch, u8 *buffer, int32_t max, int32_t *size){ File_Track_Result result = FileTrack_NoMoreEvents; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); diff --git a/linux_4ed_fonts.cpp b/linux_4ed_fonts.cpp index 86faed7d..766fb4e2 100644 --- a/linux_4ed_fonts.cpp +++ b/linux_4ed_fonts.cpp @@ -10,9 +10,9 @@ // TOP #include "4ed_system_shared.h" -#include "font/4coder_font_interface.h" -#include "font/4coder_font_interface_to_os.h" -#include "font/4coder_font_data.h" +#include "4ed_font_interface.h" +#include "4ed_font_interface_to_os.h" +#include "4ed_font_data.h" struct Linux_Fonts{ Partition part; @@ -24,7 +24,7 @@ global Linux_Fonts linux_fonts = {0}; internal Sys_Font_Get_Count_Sig(system_font_get_count){ - return(5); + return(linux_fonts.font_count); } internal @@ -87,6 +87,9 @@ Sys_Font_Free_Sig(system_font_free){ internal Sys_Font_Init_Sig(system_font_init){ + Partition *scratch = &shared_vars.scratch; + Temp_Memory temp = begin_temp_memory(scratch); + font->get_count = system_font_get_count; font->get_ids_by_index = system_font_get_ids_by_index; font->get_name_by_index = system_font_get_name_by_index; @@ -99,35 +102,73 @@ Sys_Font_Init_Sig(system_font_init){ font_size = clamp_bottom(8, font_size); struct Font_Setup{ + Font_Setup *next_font; char *c_filename; - i32 filename_len; - char *c_name; - i32 name_len; - u32 pt_size; - }; - Font_Setup font_setup[] = { - {literal("LiberationSans-Regular.ttf"), literal("Liberation Sans"), font_size}, - {literal("liberation-mono.ttf"), literal("Liberation Mono"), font_size}, - {literal("Hack-Regular.ttf"), literal("Hack"), font_size}, - {literal("CutiveMono-Regular.ttf"), literal("Cutive Mono"), font_size}, - {literal("Inconsolata-Regular.ttf"), literal("Inconsolata"), font_size}, }; - u32 font_count = Min(ArrayCount(linux_fonts.fonts), ArrayCount(font_setup)); - for (u32 i = 0; i < font_count; ++i){ - String filename = make_string(font_setup[i].c_filename, font_setup[i].filename_len); - String name = make_string(font_setup[i].c_name, font_setup[i].name_len); - u32 pt_size = font_setup[i].pt_size; - Render_Font *render_font = &linux_fonts.fonts[i]; - - char full_filename_space[256]; - String full_filename = make_fixed_width_string(full_filename_space); - sysshared_to_binary_path(&full_filename, filename.str); - - system_set_font(&linuxvars.system, &linux_fonts.part, render_font, full_filename, name, pt_size, use_hinting); + Font_Setup *first_setup = 0; + Font_Setup *head_setup = 0; + + u32 dir_max = KB(32); + u8 *directory = push_array(scratch, u8, dir_max); + String dir_str = make_string_cap(directory, 0, dir_max); + i32 dir_len = system_get_binary_path(&dir_str); + Assert(dir_len < dir_max); + + { + String dir_str = make_string_cap(directory, dir_len, dir_max); + set_last_folder_sc(&dir_str, "fonts", '/'); + terminate_with_null(&dir_str); + dir_len = dir_str.size; } - linux_fonts.font_count = font_count; + partition_reduce(scratch, dir_max - dir_len - 1); + partition_align(scratch, 8); + + File_List file_list = {0}; + system_set_file_list(&file_list, (char*)directory, 0, 0, 0); + + for (u32 i = 0; i < file_list.count; ++i){ + File_Info *info = &file_list.infos[i]; + if (first_setup == 0){ + first_setup = push_struct(scratch, Font_Setup); + head_setup = first_setup; + } + else{ + head_setup->next_font = push_struct(scratch, Font_Setup); + head_setup = head_setup->next_font; + } + head_setup->next_font = 0; + + char *filename = info->filename; + u32 len = 0; + for (;filename[len];++len); + + head_setup->c_filename = push_array(scratch, char, dir_len+len+1); + memcpy(head_setup->c_filename, directory, dir_len); + memcpy(head_setup->c_filename + dir_len, filename, len+1); + + partition_align(scratch, 8); + } + + system_set_file_list(&file_list, 0, 0, 0, 0); + + u32 font_count_max = ArrayCount(linux_fonts.fonts); + u32 font_count = 0; + u32 i = 0; + for (Font_Setup *ptr = first_setup; ptr != 0; ptr = ptr->next_font, ++i){ + if (i < font_count_max){ + Render_Font *render_font = &linux_fonts.fonts[i]; + + system_set_font(&linuxvars.system, &linux_fonts.part, render_font, ptr->c_filename, font_size, use_hinting); + } + + ++font_count; + } + + linux_fonts.font_count = clamp_top(font_count, font_count_max); + + end_temp_memory(temp); } // BOTTOM diff --git a/win32_4ed.cpp b/win32_4ed.cpp index bd230e49..4e5703a9 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -2469,14 +2469,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } #include "win32_4ed_fonts.cpp" - #include "win32_4ed_file_track.cpp" #include "4ed_font_static_functions.cpp" #include "win32_utf8.cpp" #if 0 -// NOTE(allen): In case I want to switch back to a console -// application at some point. +// NOTE(allen): In case I want to switch back to a console application at some point. int main(int argc, char **argv){ HINSTANCE hInstance = GetModuleHandle(0); } diff --git a/win32_4ed_fonts.cpp b/win32_4ed_fonts.cpp index e9671a72..3c13329a 100644 --- a/win32_4ed_fonts.cpp +++ b/win32_4ed_fonts.cpp @@ -101,46 +101,6 @@ Sys_Font_Init_Sig(system_font_init){ font_size = clamp_bottom(8, font_size); -#if 0 - struct TEST_DATA{ - char *c_filename; - i32 filename_len; - char *c_name; - i32 name_len; - }; - TEST_DATA TEST_SETUP[] = { - {literal("fonts/LiberationSans-Regular.ttf"), literal("Liberation Sans"), }, - {literal("fonts/liberation-mono.ttf"), literal("Liberation Mono"), }, - {literal("fonts/Hack-Regular.ttf"), literal("Hack"), }, - {literal("fonts/CutiveMono-Regular.ttf"), literal("Cutive Mono"), }, - {literal("fonts/Inconsolata-Regular.ttf"), literal("Inconsolata"), }, - }; - - u32 TEST_COUNT = ArrayCount(TEST_SETUP); - for (u32 i = 0; i < TEST_COUNT; ++i){ - if (first_setup == 0){ - head_setup = push_struct(scratch, Font_Setup); - first_setup = head_setup; - } - else{ - head_setup->next_font = push_struct(scratch, Font_Setup); - head_setup = head_setup->next_font; - } - - TEST_DATA *TEST = &TEST_SETUP[i]; - - head_setup->c_filename = push_array(scratch, char, TEST->filename_len+1); - memcpy(head_setup->c_filename, TEST->c_filename, TEST->filename_len+1); - head_setup->filename_len = TEST->filename_len; - - head_setup->c_name = push_array(scratch, char, TEST->name_len+1); - memcpy(head_setup->c_name, TEST->c_name, TEST->name_len+1); - head_setup->name_len = TEST->name_len; - - partition_align(scratch, 8); - } -#endif - struct Font_Setup{ Font_Setup *next_font; char *c_filename; @@ -151,12 +111,12 @@ Sys_Font_Init_Sig(system_font_init){ u32 dir_max = KB(32); u8 *directory = push_array(scratch, u8, dir_max); - DWORD dir_len = GetModuleFileName_utf8(0, directory, dir_max-1); + String dir_str = make_string_cap(directory, 0, dir_max); + i32 dir_len = system_get_binary_path(&dir_str); Assert(dir_len < dir_max); { String dir_str = make_string_cap(directory, dir_len, dir_max); - remove_last_folder(&dir_str); set_last_folder_sc(&dir_str, "fonts", '\\'); terminate_with_null(&dir_str); dir_len = dir_str.size;