got fonts working under linux; reorganized layer to more closely match windows

This commit is contained in:
Allen Webster 2017-03-26 21:52:06 -04:00
parent a78f653c80
commit bca15da440
6 changed files with 163 additions and 185 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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;