Font handling and rendering basically working.

master
Allen Webster 2019-07-24 00:41:40 -07:00
parent 3ddd3fc2fa
commit 6b3d61c035
38 changed files with 801 additions and 1934 deletions

View File

@ -815,30 +815,22 @@ DOC_SEE(int_color)
//int_color colors[Stag_COUNT]; //int_color colors[Stag_COUNT];
//}; //};
/*
DOC(Available_Font contains a name for a font was detected at startup either in the local 4coder font folder, or by the system. An available font is not necessarily loaded yet, and may fail to load for various reasons even though it appearsin the available font list.)
DOC_SEE(get_available_font)
*/
STRUCT Available_Font{
char name[64];
b32 in_local_font_folder;
};
/* /*
DOC(Every face is assigned a unique and consistent Face_ID for it's life time. This represents a slot in which a face can exist. The face in the slot is always valid once it exists, but the face might be changed or released durring it's lifetime. A Face_ID value of zero is reserved for the meaning "not a valid face".) DOC(Every face is assigned a unique and consistent Face_ID for it's life time. This represents a slot in which a face can exist. The face in the slot is always valid once it exists, but the face might be changed or released durring it's lifetime. A Face_ID value of zero is reserved for the meaning "not a valid face".)
*/ */
TYPEDEF u32 Face_ID; TYPEDEF u32 Face_ID;
/* // TODO(allen): redocument
DOC(Face_Description contains all the information unique to a single font face, including the font name, the size, and style of the face.) STRUCT Font_Load_Location{
DOC_SEE(get_available_font) String_Const_u8 file_name;
*/ b32 in_4coder_font_folder;
STRUCT Face_Description{ };
/* DOC(Indicates a face's association with an available font. This should be an exact copy of an Available_Font returned by get_available_fonts.) DOC_SEE(get_available_font) */
Available_Font font;
// TODO(allen): redocument
STRUCT Face_Load_Parameters{
/* DOC(Indicates the size for the face. Valid values must be greater than 0. Different fonts with the same pt_size do not necessarily have the same line height.) */ /* DOC(Indicates the size for the face. Valid values must be greater than 0. Different fonts with the same pt_size do not necessarily have the same line height.) */
i32 pt_size; u32 pt_size;
/* DOC(Indicates whether the face tries to use a bold style.) */ /* DOC(Indicates whether the face tries to use a bold style.) */
b32 bold; b32 bold;
@ -853,6 +845,12 @@ STRUCT Face_Description{
b32 hinting; b32 hinting;
}; };
// TODO(allen): redocument
STRUCT Face_Description{
Font_Load_Location font;
Face_Load_Parameters parameters;
};
STRUCT Face_Metrics{ STRUCT Face_Metrics{
f32 line_height; f32 line_height;
f32 typical_character_width; f32 typical_character_width;

View File

@ -759,13 +759,6 @@ get_buffer_face_description(Application_Links *app, Buffer_Summary *buffer){
return(result); return(result);
} }
static void
set_buffer_face_by_name(Application_Links *app, Buffer_Summary *buffer, char *name, i32 len){
if (buffer != 0){
set_buffer_face_by_name(app, buffer->buffer_id, SCu8(name, len));
}
}
static void static void
execute_standard_build(Application_Links *app, View_Summary *view, Buffer_ID active_buffer){ execute_standard_build(Application_Links *app, View_Summary *view, Buffer_ID active_buffer){
standard_search_and_build(app, view==0?0:view->view_id, active_buffer); standard_search_and_build(app, view==0?0:view->view_id, active_buffer);
@ -990,21 +983,6 @@ condense_whitespace(String *a){
} }
} }
static Face_ID
get_existing_face_id_matching_name(Application_Links *app, char *name, i32 len){
return(get_existing_face_id_matching_name(app, SCu8(name, len)));
}
static Face_ID
get_face_id_by_name(Application_Links *app, char *name, i32 len, Face_Description *base_description){
return(get_face_id_by_name(app, SCu8(name, len), base_description));
}
static void
set_global_face_by_name(Application_Links *app, char *name, i32 len, b32 apply_to_all_buffers){
set_global_face_by_name(app, SCu8(name, len), apply_to_all_buffers);
}
static void static void
insert_string__no_buffering(Buffer_Insertion *insertion, String string){ insert_string__no_buffering(Buffer_Insertion *insertion, String string){
insert_string__no_buffering(insertion, string_new_u8_from_old(string)); insert_string__no_buffering(insertion, string_new_u8_from_old(string));

View File

@ -772,7 +772,7 @@ CUSTOM_DOC("Increase the size of the face used by the current buffer.")
Buffer_ID buffer = view_get_buffer(app, view, AccessAll); Buffer_ID buffer = view_get_buffer(app, view, AccessAll);
Face_ID face_id = get_face_id(app, buffer); Face_ID face_id = get_face_id(app, buffer);
Face_Description description = get_face_description(app, face_id); Face_Description description = get_face_description(app, face_id);
++description.pt_size; ++description.parameters.pt_size;
try_modify_face(app, face_id, &description); try_modify_face(app, face_id, &description);
} }
@ -783,7 +783,7 @@ CUSTOM_DOC("Decrease the size of the face used by the current buffer.")
Buffer_ID buffer = view_get_buffer(app, view, AccessAll); Buffer_ID buffer = view_get_buffer(app, view, AccessAll);
Face_ID face_id = get_face_id(app, buffer); Face_ID face_id = get_face_id(app, buffer);
Face_Description description = get_face_description(app, face_id); Face_Description description = get_face_description(app, face_id);
--description.pt_size; --description.parameters.pt_size;
try_modify_face(app, face_id, &description); try_modify_face(app, face_id, &description);
} }

View File

@ -156,7 +156,8 @@ get_or_open_build_panel(Application_Links *app){
static void static void
set_fancy_compilation_buffer_font(Application_Links *app){ set_fancy_compilation_buffer_font(Application_Links *app){
Buffer_ID buffer = get_comp_buffer(app); Buffer_ID buffer = get_comp_buffer(app);
set_buffer_face_by_name(app, buffer, string_u8_litexpr("Inconsolata")); Font_Load_Location font = { string_u8_litexpr("Inconsolata-Regular.ttf"), true, };
set_buffer_face_by_font_load_location(app, buffer, &font);
} }
CUSTOM_COMMAND_SIG(build_in_build_panel) CUSTOM_COMMAND_SIG(build_in_build_panel)

View File

@ -1525,19 +1525,19 @@ load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *con
highlight_line_at_cursor = config->highlight_line_at_cursor; highlight_line_at_cursor = config->highlight_line_at_cursor;
Face_Description description = {}; Face_Description description = {};
umem len = config->default_font_name.size; description.font.file_name = config->default_font_name;
len = clamp_top(len, sizeof(description.font.name) - 1); description.font.in_4coder_font_folder = true;
u8 *name_ptr = config->default_font_name.str;
memcpy(description.font.name, name_ptr, len);
description.font.name[len] = 0;
if (override_font_size != 0){ if (override_font_size != 0){
description.pt_size = override_font_size; description.parameters.pt_size = override_font_size;
} }
else{ else{
description.pt_size = config->default_font_size; description.parameters.pt_size = config->default_font_size;
}
description.parameters.hinting = config->default_font_hinting || override_hinting;
if (!modify_global_face_by_description(app, description)){
description.font.in_4coder_font_folder = !description.font.in_4coder_font_folder;
modify_global_face_by_description(app, description);
} }
description.hinting = config->default_font_hinting || override_hinting;
change_global_face_by_description(app, description, true);
} }
end_temp(temp); end_temp(temp);

View File

@ -410,13 +410,13 @@ default_4coder_initialize(Application_Links *app, i32 override_font_size, b32 ov
static void static void
default_4coder_initialize(Application_Links *app, char **command_line_files, i32 file_count){ default_4coder_initialize(Application_Links *app, char **command_line_files, i32 file_count){
Face_Description command_line_description = get_face_description(app, 0); Face_Description command_line_description = get_face_description(app, 0);
default_4coder_initialize(app, command_line_files, file_count, command_line_description.pt_size, command_line_description.hinting); default_4coder_initialize(app, command_line_files, file_count, command_line_description.parameters.pt_size, command_line_description.parameters.hinting);
} }
static void static void
default_4coder_initialize(Application_Links *app){ default_4coder_initialize(Application_Links *app){
Face_Description command_line_description = get_face_description(app, 0); Face_Description command_line_description = get_face_description(app, 0);
default_4coder_initialize(app, 0, 0, command_line_description.pt_size, command_line_description.hinting); default_4coder_initialize(app, 0, 0, command_line_description.parameters.pt_size, command_line_description.parameters.hinting);
} }
static void static void

View File

@ -4,8 +4,7 @@
// TOP // TOP
// TODO(allen): transition wrappers internal Face_Description
static Face_Description
get_buffer_face_description(Application_Links *app, Buffer_ID buffer){ get_buffer_face_description(Application_Links *app, Buffer_ID buffer){
Face_ID current_id = get_face_id(app, buffer); Face_ID current_id = get_face_id(app, buffer);
Face_Description description = {}; Face_Description description = {};
@ -15,31 +14,42 @@ get_buffer_face_description(Application_Links *app, Buffer_ID buffer){
return(description); return(description);
} }
static Face_Description internal Face_Description
get_global_face_description(Application_Links *app){ get_global_face_description(Application_Links *app){
Face_ID current_id = get_face_id(app, 0); return(get_buffer_face_description(app, 0));
Face_Description description = get_face_description(app, current_id);
return(description);
} }
static b32 internal b32
descriptions_match(Face_Description *a, Face_Description *b){ font_load_location_match(Font_Load_Location *a, Font_Load_Location *b){
b32 result = false; b32 result = false;
if (string_match(SCchar(a->font.name), SCchar(b->font.name)) && a->font.in_local_font_folder == b->font.in_local_font_folder){ if (string_match(a->file_name, b->file_name) && a->in_4coder_font_folder == b->in_4coder_font_folder){
if (memcmp((&a->pt_size), (&b->pt_size), sizeof(*a) - sizeof(a->font)) == 0){
result = true; result = true;
} }
return(result);
}
internal b32
face_load_parameters_match(Face_Load_Parameters *a, Face_Load_Parameters *b){
return(block_compare(a, b, sizeof(*a)) == 0);
}
internal b32
face_description_match(Face_Description *a, Face_Description *b){
b32 result = false;
if (font_load_location_match(&a->font, &b->font) &&
face_load_parameters_match(&a->parameters, &b->parameters)){
result = true;
} }
return(result); return(result);
} }
static Face_ID internal Face_ID
get_existing_face_id_matching_name(Application_Links *app, String_Const_u8 name){ face_id_from_font_load_target(Application_Links *app, Font_Load_Location *font){
Face_ID largest_id = get_largest_face_id(app); Face_ID largest_id = get_largest_face_id(app);
Face_ID result = 0; Face_ID result = 0;
for (Face_ID id = 1; id <= largest_id; ++id){ for (Face_ID id = 1; id <= largest_id; ++id){
Face_Description compare = get_face_description(app, id); Face_Description compare = get_face_description(app, id);
if (string_match(SCu8(compare.font.name), name)){ if (font_load_location_match(&compare.font, font)){
result = id; result = id;
break; break;
} }
@ -47,13 +57,13 @@ get_existing_face_id_matching_name(Application_Links *app, String_Const_u8 name)
return(result); return(result);
} }
static Face_ID internal Face_ID
get_existing_face_id_matching_description(Application_Links *app, Face_Description *description){ face_id_from_face_load_parameters(Application_Links *app, Face_Load_Parameters *parameters){
Face_ID largest_id = get_largest_face_id(app); Face_ID largest_id = get_largest_face_id(app);
Face_ID result = 0; Face_ID result = 0;
for (Face_ID id = 1; id <= largest_id; ++id){ for (Face_ID id = 1; id <= largest_id; ++id){
Face_Description compare = get_face_description(app, id); Face_Description compare = get_face_description(app, id);
if (descriptions_match(&compare, description)){ if (face_load_parameters_match(&compare.parameters, parameters)){
result = id; result = id;
break; break;
} }
@ -61,68 +71,49 @@ get_existing_face_id_matching_description(Application_Links *app, Face_Descripti
return(result); return(result);
} }
static Face_ID internal Face_ID
get_face_id_by_name(Application_Links *app, String_Const_u8 name, Face_Description *base_description){ face_id_from_description(Application_Links *app, Face_Description *description){
Face_ID new_id = 0; Face_ID largest_id = get_largest_face_id(app);
name.size = clamp_top(name.size, sizeof(base_description->font.name) - 1); Face_ID result = 0;
if (!string_match(name, SCu8(base_description->font.name))){ for (Face_ID id = 1; id <= largest_id; ++id){
new_id = get_existing_face_id_matching_name(app, name); Face_Description compare = get_face_description(app, id);
if (new_id == 0){ if (face_description_match(&compare, description)){
Face_Description description = *base_description; result = id;
block_copy(description.font.name, name.str, name.size); break;
description.font.name[name.size] = 0;
description.font.in_local_font_folder = false;
new_id = try_create_new_face(app, &description);
if (new_id == 0){
description.font.in_local_font_folder = true;
new_id = try_create_new_face(app, &description);
} }
} }
} return(result);
return(new_id);
} }
static Face_ID internal b32
get_face_id_by_description(Application_Links *app, Face_Description *description, Face_Description *base_description){ modify_global_face_by_description(Application_Links *app, Face_Description description){
Face_ID new_id = 0;
if (!descriptions_match(description, base_description)){
new_id = get_existing_face_id_matching_description(app, description);
if (new_id == 0){
new_id = try_create_new_face(app, description);
}
}
return(new_id);
}
static void
set_global_face_by_name(Application_Links *app, String_Const_u8 name, b32 apply_to_all_buffers){
Face_ID global_face_id = get_face_id(app, 0);
Face_Description description = get_face_description(app, global_face_id);
Face_ID new_id = get_face_id_by_name(app, name, &description);
if (new_id != 0){
set_global_face(app, new_id, apply_to_all_buffers);
}
}
static void
change_global_face_by_description(Application_Links *app, Face_Description description, b32 apply_to_all_buffers){
Face_ID face_id = get_face_id(app, 0); Face_ID face_id = get_face_id(app, 0);
if (!try_modify_face(app, face_id, &description)){ return(try_modify_face(app, face_id, &description));
description.font.in_local_font_folder = !description.font.in_local_font_folder; }
try_modify_face(app, face_id, &description);
internal void
set_buffer_face_by_description(Application_Links *app, Buffer_ID buffer, Face_Description *description){
Face_ID id = face_id_from_description(app, description);
if (id == 0){
id = try_create_new_face(app, description);
}
if (id != 0){
buffer_set_face(app, buffer, id);
} }
} }
static void internal void
set_buffer_face_by_name(Application_Links *app, Buffer_ID buffer, String_Const_u8 name){ set_buffer_face_by_font_load_location(Application_Links *app, Buffer_ID buffer, Font_Load_Location *font){
Face_ID current_id = get_face_id(app, buffer); Face_Description description = get_buffer_face_description(app, buffer);
if (current_id != 0){ description.font = *font;
Face_Description description = get_face_description(app, current_id); set_buffer_face_by_description(app, buffer, &description);
Face_ID new_id = get_face_id_by_name(app, name, &description); }
if (new_id != 0){
buffer_set_face(app, buffer, new_id); internal void
} set_buffer_face_by_face_load_parameters(Application_Links *app, Buffer_ID buffer, Face_Load_Parameters *parameters){
} Face_Description description = get_buffer_face_description(app, buffer);
description.parameters = *parameters;
set_buffer_face_by_description(app, buffer, &description);
} }
// BOTTOM // BOTTOM

View File

@ -133,7 +133,7 @@ struct Application_Links;
#define GLOBAL_HISTORY_EDIT_GROUP_BEGIN_SIG(n) void n(Application_Links *app) #define GLOBAL_HISTORY_EDIT_GROUP_BEGIN_SIG(n) void n(Application_Links *app)
#define GLOBAL_HISTORY_EDIT_GROUP_END_SIG(n) void n(Application_Links *app) #define GLOBAL_HISTORY_EDIT_GROUP_END_SIG(n) void n(Application_Links *app)
#define BUFFER_SET_FACE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Face_ID id) #define BUFFER_SET_FACE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Face_ID id)
#define GET_FACE_DESCRIPTION_SIG(n) Face_Description n(Application_Links *app, Face_ID id) #define GET_FACE_DESCRIPTION_SIG(n) Face_Description n(Application_Links *app, Face_ID face_id)
#define GET_FACE_METRICS_SIG(n) Face_Metrics n(Application_Links *app, Face_ID face_id) #define GET_FACE_METRICS_SIG(n) Face_Metrics n(Application_Links *app, Face_ID face_id)
#define GET_FACE_ID_SIG(n) Face_ID n(Application_Links *app, Buffer_ID buffer_id) #define GET_FACE_ID_SIG(n) Face_ID n(Application_Links *app, Buffer_ID buffer_id)
#define TRY_CREATE_NEW_FACE_SIG(n) Face_ID n(Application_Links *app, Face_Description *description) #define TRY_CREATE_NEW_FACE_SIG(n) Face_ID n(Application_Links *app, Face_Description *description)
@ -1041,7 +1041,7 @@ static b32 buffer_history_clear_after_current_state(Application_Links *app, Buff
static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin(app));} static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin(app));}
static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end(app));} static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end(app));}
static b32 buffer_set_face(Application_Links *app, Buffer_ID buffer_id, Face_ID id){return(app->buffer_set_face(app, buffer_id, id));} static b32 buffer_set_face(Application_Links *app, Buffer_ID buffer_id, Face_ID id){return(app->buffer_set_face(app, buffer_id, id));}
static Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description(app, id));} static Face_Description get_face_description(Application_Links *app, Face_ID face_id){return(app->get_face_description(app, face_id));}
static Face_Metrics get_face_metrics(Application_Links *app, Face_ID face_id){return(app->get_face_metrics(app, face_id));} static Face_Metrics get_face_metrics(Application_Links *app, Face_ID face_id){return(app->get_face_metrics(app, face_id));}
static Face_ID get_face_id(Application_Links *app, Buffer_ID buffer_id){return(app->get_face_id(app, buffer_id));} static Face_ID get_face_id(Application_Links *app, Buffer_ID buffer_id){return(app->get_face_id(app, buffer_id));}
static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face(app, description));} static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face(app, description));}
@ -1221,7 +1221,7 @@ static b32 buffer_history_clear_after_current_state(Application_Links *app, Buff
static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin_(app));} static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin_(app));}
static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end_(app));} static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end_(app));}
static b32 buffer_set_face(Application_Links *app, Buffer_ID buffer_id, Face_ID id){return(app->buffer_set_face_(app, buffer_id, id));} static b32 buffer_set_face(Application_Links *app, Buffer_ID buffer_id, Face_ID id){return(app->buffer_set_face_(app, buffer_id, id));}
static Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description_(app, id));} static Face_Description get_face_description(Application_Links *app, Face_ID face_id){return(app->get_face_description_(app, face_id));}
static Face_Metrics get_face_metrics(Application_Links *app, Face_ID face_id){return(app->get_face_metrics_(app, face_id));} static Face_Metrics get_face_metrics(Application_Links *app, Face_ID face_id){return(app->get_face_metrics_(app, face_id));}
static Face_ID get_face_id(Application_Links *app, Buffer_ID buffer_id){return(app->get_face_id_(app, buffer_id));} static Face_ID get_face_id(Application_Links *app, Buffer_ID buffer_id){return(app->get_face_id_(app, buffer_id));}
static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face_(app, description));} static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face_(app, description));}

View File

@ -445,9 +445,9 @@ static Command_Metadata fcoder_metacmd_table[237] = {
{ PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 7 }, { PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 7 },
{ PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 22 }, { PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 22 },
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 128 }, { PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 128 },
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 162 }, { PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 163 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 177 }, { PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 178 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 183 }, { PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 184 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 928 }, { PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 928 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 934 }, { PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 934 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 940 }, { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 940 },

119
4ed.cpp
View File

@ -71,7 +71,7 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
if (view->file != file){ if (view->file != file){
continue; continue;
} }
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(pos)); Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(pos));
view_set_cursor(system, models, view, cursor, true); view_set_cursor(system, models, view, cursor, true);
view->mark = cursor.pos; view->mark = cursor.pos;
} }
@ -702,47 +702,19 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
//////////////////////////////// ////////////////////////////////
internal void*
base_reserve__system(void *user_data, umem size, umem *size_out){
System_Functions *system = (System_Functions*)user_data;
umem extra_size = 128;
umem increased_size = size + extra_size;
size = round_up_umem(increased_size, KB(4));
*size_out = size - extra_size;
void *ptr = system->memory_allocate(size);
*(umem*)ptr = size;
ptr = (u8*)ptr + extra_size;
return(ptr);
}
internal void
base_free__system(void *user_data, void *ptr){
System_Functions *system = (System_Functions*)user_data;
umem extra_size = 128;
ptr = (u8*)ptr - extra_size;
umem size = *(umem*)ptr;
system->memory_free(ptr, size);
}
internal Base_Allocator
make_base_allocator_system(System_Functions *system){
return(make_base_allocator(base_reserve__system, 0, 0,
base_free__system, 0, system));
}
internal Arena internal Arena
make_arena_models(Models *models, umem chunk_size, umem align){ make_arena_models(Models *models, umem chunk_size, umem align){
return(make_arena(&models->allocator, chunk_size, align)); return(make_arena(models->base_allocator, chunk_size, align));
} }
internal Arena internal Arena
make_arena_models(Models *models, umem chunk_size){ make_arena_models(Models *models, umem chunk_size){
return(make_arena(&models->allocator, chunk_size, 8)); return(make_arena(models->base_allocator, chunk_size, 8));
} }
internal Arena internal Arena
make_arena_models(Models *models){ make_arena_models(Models *models){
return(make_arena(&models->allocator, KB(16), 8)); return(make_arena(models->base_allocator, KB(16), 8));
} }
//////////////////////////////// ////////////////////////////////
@ -751,8 +723,8 @@ internal App_Vars*
app_setup_memory(System_Functions *system, Application_Memory *memory){ app_setup_memory(System_Functions *system, Application_Memory *memory){
Cursor cursor = make_cursor(memory->vars_memory, memory->vars_memory_size); Cursor cursor = make_cursor(memory->vars_memory, memory->vars_memory_size);
App_Vars *vars = push_array_zero(&cursor, App_Vars, 1); App_Vars *vars = push_array_zero(&cursor, App_Vars, 1);
vars->models.allocator = make_base_allocator_system(system); vars->models.mem.arena = make_arena_system(system);
vars->models.mem.arena = make_arena(&vars->models.allocator); vars->models.base_allocator = vars->models.mem.arena.base_allocator;
heap_init(&vars->models.mem.heap); heap_init(&vars->models.mem.heap);
heap_extend(&vars->models.mem.heap, memory->target_memory, memory->target_memory_size); heap_extend(&vars->models.mem.heap, memory->target_memory, memory->target_memory_size);
return(vars); return(vars);
@ -862,6 +834,9 @@ App_Init_Sig(app_init){
Arena *arena = &models->mem.arena; Arena *arena = &models->mem.arena;
// NOTE(allen): font set
font_set_init(system, &models->font_set);
// NOTE(allen): live set // NOTE(allen): live set
{ {
models->live_set.count = 0; models->live_set.count = 0;
@ -923,7 +898,13 @@ App_Init_Sig(app_init){
} }
// NOTE(allen): style setup // NOTE(allen): style setup
models->global_font_id = 1; {
Face_Description description = {};
description.font.file_name = string_u8_litexpr("liberation-mono.ttf");
description.font.in_4coder_font_folder = true;
description.parameters.pt_size = 12;
models->global_font_id = font_set_new_face(&models->font_set, &description);
}
app_hardcode_default_style(models); app_hardcode_default_style(models);
// NOTE(allen): title space // NOTE(allen): title space
@ -986,7 +967,7 @@ App_Step_Sig(app_step){
models->animate_next_frame = false; models->animate_next_frame = false;
// NOTE(allen): per-frame update of models state // NOTE(allen): per-frame update of models state
begin_frame(target); begin_frame(target, &models->font_set);
models->target = target; models->target = target;
models->input = input; models->input = input;
@ -1190,30 +1171,6 @@ App_Step_Sig(app_step){
models->hook_start(&models->app_links, files, files_count, flags, flags_count); models->hook_start(&models->app_links, files, files_count, flags, flags_count);
} }
#if 0
// Open command line files.
char space[512];
String cl_file_name = make_fixed_width_string(space);
copy_ss(&cl_file_name, models->hot_directory.string);
i32 cl_file_name_len = cl_file_name.size;
for (i32 i = 0; i < models->settings.init_files_count; ++i){
cl_file_name.size = cl_file_name_len;
String file_name = {};
Editing_File_Name canon_name = {};
if (get_canon_name(system, make_string_slowly(models->settings.init_files[i]), &canon_name)){
file_name = canon_name.name;
}
else{
append_sc(&cl_file_name, models->settings.init_files[i]);
file_name = cl_file_name;
}
Buffer_ID id = 0;
create_buffer(&models->app_links, file_name, 0, &id);
}
#endif
} }
// NOTE(allen): consume event stream // NOTE(allen): consume event stream
@ -1507,48 +1464,6 @@ App_Step_Sig(app_step){
models->render_caller(&models->app_links, frame); models->render_caller(&models->app_links, frame);
} }
#if 0
Panel *active_panel = layout_get_active_panel(layout);
View *active_view = active_panel->view;
// NOTE(allen): render the panels
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
i32_Rect full = panel->rect_full;
i32_Rect inner = panel->rect_inner;
View *view = panel->view;
//Style *style = &models->styles.styles[0];
Color_Table color_table = models->color_table;
draw_rectangle(target, full, color_table.vals[Stag_Back]);
File_Edit_Positions edit_pos = view_get_edit_pos(view);
GUI_Scroll_Vars *scroll_vars = &edit_pos.scroll;
b32 active = (panel == active_panel);
do_render_file_view(system, view, models, scroll_vars, active_view, inner, active, target);
view_set_edit_pos(view, edit_pos);
u32 margin_color = 0;
if (active){
margin_color = color_table.vals[Stag_Margin_Active];
}
else if (panel == mouse_panel){
margin_color = color_table.vals[Stag_Margin_Hover];
}
else{
margin_color = color_table.vals[Stag_Margin];
}
draw_rectangle(target, i32R( full.x0, full.y0, full.x1, inner.y0), margin_color);
draw_rectangle(target, i32R( full.x0, inner.y1, full.x1, full.y1), margin_color);
draw_rectangle(target, i32R( full.x0, inner.y0, inner.x0, inner.y1), margin_color);
draw_rectangle(target, i32R(inner.x1, inner.y0, full.x1, inner.y1), margin_color);
}
#endif
models->in_render_mode = false; models->in_render_mode = false;
end_render_section(target, system); end_render_section(target, system);
} }

View File

@ -98,7 +98,7 @@ Context_Get_Arena(Application_Links *app){
API_EXPORT Base_Allocator* API_EXPORT Base_Allocator*
Context_Get_Base_Allocator(Application_Links *app){ Context_Get_Base_Allocator(Application_Links *app){
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
return(&models->allocator); return(models->base_allocator);
} }
API_EXPORT b32 API_EXPORT b32
@ -775,10 +775,7 @@ DOC_SEE(Buffer_Setting_ID)
new_value = 48; new_value = 48;
} }
if (new_value != file->settings.display_width){ if (new_value != file->settings.display_width){
#if 0 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
#endif
Face *face = 0;
file->settings.display_width = new_value; file->settings.display_width = new_value;
file_measure_wraps(system, &models->mem, file, face); file_measure_wraps(system, &models->mem, file, face);
adjust_views_looking_at_file_to_new_cursor(system, models, file); adjust_views_looking_at_file_to_new_cursor(system, models, file);
@ -792,10 +789,7 @@ DOC_SEE(Buffer_Setting_ID)
new_value = 0; new_value = 0;
} }
if (new_value != file->settings.minimum_base_display_width){ if (new_value != file->settings.minimum_base_display_width){
#if 0 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
#endif
Face *face = 0;
file->settings.minimum_base_display_width = new_value; file->settings.minimum_base_display_width = new_value;
file_measure_wraps(system, &models->mem, file, face); file_measure_wraps(system, &models->mem, file, face);
adjust_views_looking_at_file_to_new_cursor(system, models, file); adjust_views_looking_at_file_to_new_cursor(system, models, file);
@ -873,11 +867,7 @@ DOC_SEE(Buffer_Setting_ID)
} }
if (full_remeasure){ if (full_remeasure){
#if 0 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
#endif
Face *face = 0;
file_allocate_character_starts_as_needed(&models->mem.heap, file); file_allocate_character_starts_as_needed(&models->mem.heap, file);
buffer_measure_character_starts(system, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); buffer_measure_character_starts(system, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_measure_wraps(system, &models->mem, file, face); file_measure_wraps(system, &models->mem, file, face);
@ -1132,7 +1122,7 @@ Buffer_Reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag fl
if (view_it->file == file){ if (view_it->file == file){
vptrs[vptr_count] = view_it; vptrs[vptr_count] = view_it;
File_Edit_Positions edit_pos = view_get_edit_pos(view_it); File_Edit_Positions edit_pos = view_get_edit_pos(view_it);
Full_Cursor cursor = file_compute_cursor(system, view_it->file, seek_pos(edit_pos.cursor_pos)); Full_Cursor cursor = file_compute_cursor(models, view_it->file, seek_pos(edit_pos.cursor_pos));
line_numbers[vptr_count] = (i32)cursor.line; line_numbers[vptr_count] = (i32)cursor.line;
column_numbers[vptr_count] = (i32)cursor.character; column_numbers[vptr_count] = (i32)cursor.character;
view_it->file = models->scratch_buffer; view_it->file = models->scratch_buffer;
@ -1149,7 +1139,7 @@ Buffer_Reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag fl
view_set_file(system, models, vptrs[i], file); view_set_file(system, models, vptrs[i], file);
vptrs[i]->file = file; vptrs[i]->file = file;
Full_Cursor cursor = file_compute_cursor(system, file, seek_line_char(line_numbers[i], column_numbers[i])); Full_Cursor cursor = file_compute_cursor(models, file, seek_line_char(line_numbers[i], column_numbers[i]));
view_set_cursor(system, models, vptrs[i], cursor, true); view_set_cursor(system, models, vptrs[i], cursor, true);
} }
@ -1778,7 +1768,7 @@ DOC_SEE(Full_Cursor)
if (file->settings.unwrapped_lines && seek.type == buffer_seek_wrapped_xy){ if (file->settings.unwrapped_lines && seek.type == buffer_seek_wrapped_xy){
seek.type = buffer_seek_unwrapped_xy; seek.type = buffer_seek_unwrapped_xy;
} }
result = file_compute_cursor(models->system, file, seek); result = file_compute_cursor(models, file, seek);
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
result.wrapped_x = result.unwrapped_x; result.wrapped_x = result.unwrapped_x;
result.wrapped_y = result.unwrapped_y; result.wrapped_y = result.unwrapped_y;
@ -1809,7 +1799,7 @@ DOC_SEE(Buffer_Seek)
if (file->settings.unwrapped_lines && seek.type == buffer_seek_wrapped_xy){ if (file->settings.unwrapped_lines && seek.type == buffer_seek_wrapped_xy){
seek.type = buffer_seek_unwrapped_xy; seek.type = buffer_seek_unwrapped_xy;
} }
Full_Cursor cursor = file_compute_cursor(models->system, file, seek); Full_Cursor cursor = file_compute_cursor(models, file, seek);
view_set_cursor(models->system, models, view, cursor, set_preferred_x); view_set_cursor(models->system, models, view, cursor, set_preferred_x);
result = true; result = true;
} }
@ -1864,7 +1854,7 @@ DOC_SEE(Buffer_Seek)
Assert(file != 0); Assert(file != 0);
if (api_check_buffer(file)){ if (api_check_buffer(file)){
if (seek.type != buffer_seek_pos){ if (seek.type != buffer_seek_pos){
Full_Cursor cursor = file_compute_cursor(models->system, file, seek); Full_Cursor cursor = file_compute_cursor(models, file, seek);
view->mark = cursor.pos; view->mark = cursor.pos;
} }
else{ else{
@ -2937,12 +2927,7 @@ DOC_RETURN(Returns the largest face ID that could be valid. There is no guarant
*/ */
{ {
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
Face_ID result = 0; return(font_set_get_largest_id(&models->font_set));
#if 0
Face_ID result = models->system->font.get_largest_id();
#endif
NotImplemented;
return(result);
} }
API_EXPORT b32 API_EXPORT b32
@ -2958,21 +2943,16 @@ DOC_RETURN(Returns true if the given id was a valid face and the change was made
System_Functions *system = models->system; System_Functions *system = models->system;
b32 did_change = false; b32 did_change = false;
Face *face = font_set_face_from_id(&models->font_set, id);
NotImplemented; if (face != 0){
#if 0
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
did_change = true;
if (apply_to_all_buffers){ if (apply_to_all_buffers){
global_set_font_and_update_files(system, models, id); global_set_font_and_update_files(system, models, id);
} }
else{ else{
models->global_font_id = id; models->global_font_id = id;
} }
did_change = true;
} }
#endif
return(did_change); return(did_change);
} }
@ -3147,67 +3127,6 @@ Global_History_Edit_Group_End(Application_Links *app){
global_history_adjust_edit_grouping_counter(&models->global_history, -1); global_history_adjust_edit_grouping_counter(&models->global_history, -1);
} }
internal void
face_to_face_description(Face *face, Face_Description *description){
umem size = clamp_top(face->name.size, sizeof(description->font.name) - 1);
block_copy(description->font.name, face->name.str, size);
description->font.name[size] = 0;
description->font.in_local_font_folder = face->settings.stub.in_font_folder;
description->pt_size = face->settings.parameters.pt_size;
description->bold = face->settings.parameters.bold;
description->italic = face->settings.parameters.italics;
description->underline = face->settings.parameters.underline;
description->hinting = face->settings.parameters.use_hinting;
}
internal b32
face_description_to_settings(System_Functions *system, Face_Description description, Face_Settings *settings){
b32 success = false;
String_Const_u8 desc_name = SCu8(description.font.name);
if (description.font.in_local_font_folder){
#if 0
i32 count = system->font.get_loadable_count();
for (i32 i = 0; i < count; ++i){
Font_Loadable_Description loadable = {};
system->font.get_loadable(i, &loadable);
if (loadable.valid){
if (!loadable.stub.in_font_folder){
break;
}
String_Const_u8 loadable_name = SCu8(loadable.display_name, loadable.display_len);
if (string_match(loadable_name, desc_name)){
success = true;
block_copy_struct(&settings->stub, &loadable.stub);
break;
}
}
}
#endif
}
else{
success = true;
settings->stub.load_from_path = false;
settings->stub.in_font_folder = false;
settings->stub.len = (i32)cstring_length(description.font.name);
memcpy(settings->stub.name, description.font.name, settings->stub.len + 1);
}
if (success){
settings->parameters.pt_size = description.pt_size;
settings->parameters.italics = description.italic;
settings->parameters.bold = description.bold;
settings->parameters.underline = description.underline;
settings->parameters.use_hinting = description.hinting;
}
return(success);
}
API_EXPORT b32 API_EXPORT b32
Buffer_Set_Face(Application_Links *app, Buffer_ID buffer_id, Face_ID id) Buffer_Set_Face(Application_Links *app, Buffer_ID buffer_id, Face_ID id)
/* /*
@ -3222,25 +3141,16 @@ DOC_RETURN(Returns true if the given id was a valid face and the change was made
b32 did_change = false; b32 did_change = false;
if (api_check_buffer(file)){ if (api_check_buffer(file)){
System_Functions *system = models->system; if (font_set_face_from_id(&models->font_set, id) != 0){
#if 0
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
did_change = true; did_change = true;
file_set_font(system, models, file, id); file_set_font(models->system, models, file, id);
}
#endif
Face *face = 0;
if (face != 0){
did_change = true;
file_set_font(system, models, file, id);
} }
} }
return(did_change); return(did_change);
} }
API_EXPORT Face_Description API_EXPORT Face_Description
Get_Face_Description(Application_Links *app, Face_ID id) Get_Face_Description(Application_Links *app, Face_ID face_id)
/* /*
DOC_PARAM(id, The face slot from which to read a description. If zero gets default values.) DOC_PARAM(id, The face slot from which to read a description. If zero gets default values.)
DOC(Fills out the values of a Face_Description struct, which includes all the information that determines the appearance of the face. If the id does not specify a valid face the description will be invalid. An invalid description has a zero length string in it's font.name field (i.e. description.font.name[0] == 0), and a valid description always contains a non-zero length string in the font.name field (i.e. description.font.name[0] != 0) DOC(Fills out the values of a Face_Description struct, which includes all the information that determines the appearance of the face. If the id does not specify a valid face the description will be invalid. An invalid description has a zero length string in it's font.name field (i.e. description.font.name[0] == 0), and a valid description always contains a non-zero length string in the font.name field (i.e. description.font.name[0] != 0)
@ -3253,25 +3163,16 @@ DOC_SEE(Face_Description)
*/ */
{ {
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
System_Functions *system = models->system;
Face_Description description = {}; Face_Description description = {};
if (id != 0){ if (face_id != 0){
#if 0 Face *face = font_set_face_from_id(&models->font_set, face_id);
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
font_pointers_to_face_description(font, &description);
Assert(description.font.name[0] != 0);
}
#endif
Face *face = 0;
if (face != 0){ if (face != 0){
face_to_face_description(face, &description); description = face->description;
Assert(description.font.name[0] != 0);
} }
} }
else{ else{
description.pt_size = models->settings.font_size; description.parameters.pt_size = models->settings.font_size;
description.hinting = models->settings.use_hinting; description.parameters.hinting = models->settings.use_hinting;
} }
return(description); return(description);
} }
@ -3282,17 +3183,10 @@ Get_Face_Metrics(Application_Links *app, Face_ID face_id){
System_Functions *system = models->system; System_Functions *system = models->system;
Face_Metrics result = {}; Face_Metrics result = {};
if (face_id != 0){ if (face_id != 0){
#if 0 Face *face = font_set_face_from_id(&models->font_set, face_id);
Font_Pointers font = system->font.get_pointers_by_id(face_id);
if (font.valid){
result.line_height = (f32)font.metrics->height;
result.typical_character_width = font.metrics->sub_advances[1];
}
#endif
Face *face = 0;
if (face != 0){ if (face != 0){
result.line_height = (f32)face->height; result.line_height = (f32)face->height;
result.typical_character_width = face->sub_advances[1]; result.typical_character_width = face->byte_sub_advances[1];
} }
} }
return(result); return(result);
@ -3339,16 +3233,7 @@ DOC_SEE(Face_Description)
*/ */
{ {
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
System_Functions *system = models->system; return(font_set_new_face(&models->font_set, description));
Face_ID id = 0;
Face_Settings settings = {};
if (face_description_to_settings(system, *description, &settings)){
#if 0
id = system->font.face_allocate_and_init(&settings);
#endif
NotImplemented;
}
return(id);
} }
API_EXPORT b32 API_EXPORT b32
@ -3366,15 +3251,7 @@ DOC_SEE(try_create_new_face)
*/ */
{ {
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
System_Functions *system = models->system; return(alter_font_and_update_files(models->system, models, id, description));
b32 success = false;
Face_Settings settings = {};
if (face_description_to_settings(system, *description, &settings)){
if (alter_font_and_update_files(system, models, id, &settings)){
success = true;
}
}
return(success);
} }
API_EXPORT b32 API_EXPORT b32
@ -3586,11 +3463,7 @@ DOC_RETURN(This call returns non-zero on success.)
*/{ */{
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
System_Functions *system = models->system; System_Functions *system = models->system;
// TODO(allen): rewrite this with a better OS layer API return(system->get_4ed_path(arena));
i32 required_size = system->get_4ed_path(0, 0);
char *memory = push_array(arena, char, required_size + 1);
required_size = system->get_4ed_path(memory, required_size);
return(SCu8(memory, required_size));
} }
// TODO(allen): do(add a "shown but auto-hides on timer" setting for cursor show type) // TODO(allen): do(add a "shown but auto-hides on timer" setting for cursor show type)
@ -3749,14 +3622,14 @@ Draw_String(Application_Links *app, Face_ID font_id, String_Const_u8 str, Vec2 p
Vec2 result = point; Vec2 result = point;
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
if (models->target == 0){ if (models->target == 0){
f32 width = font_string_width(models->system, models->target, font_id, str); f32 width = font_string_width(models->target, font_id, str);
result += delta*width; result += delta*width;
} }
else{ else{
Color_Table color_table = models->color_table; Color_Table color_table = models->color_table;
point = draw_helper__models_space_to_screen_space(models, point); point = draw_helper__models_space_to_screen_space(models, point);
u32 actual_color = finalize_color(color_table, color); u32 actual_color = finalize_color(color_table, color);
f32 width = draw_string(models->system, models->target, font_id, str, point, actual_color, flags, delta); f32 width = draw_string(models->target, font_id, str, point, actual_color, flags, delta);
result += delta*width; result += delta*width;
} }
return(result); return(result);
@ -3766,7 +3639,7 @@ API_EXPORT f32
Get_String_Advance(Application_Links *app, Face_ID font_id, String_Const_u8 str) Get_String_Advance(Application_Links *app, Face_ID font_id, String_Const_u8 str)
{ {
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
return(font_string_width(models->system, models->target, font_id, str)); return(font_string_width(models->target, font_id, str));
} }
API_EXPORT void API_EXPORT void
@ -3849,7 +3722,7 @@ Text_Layout_Buffer_Point_To_Layout_Point(Application_Links *app, Text_Layout_ID
if (api_check_buffer(file)){ if (api_check_buffer(file)){
System_Functions *system = models->system; System_Functions *system = models->system;
// TODO(allen): this could be computed and stored _once_ right? // TODO(allen): this could be computed and stored _once_ right?
Full_Cursor top = file_compute_cursor(system, file, seek_line_char(layout.point.line_number, 1)); Full_Cursor top = file_compute_cursor(models, file, seek_line_char(layout.point.line_number, 1));
f32 top_y = top.wrapped_y; f32 top_y = top.wrapped_y;
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
top_y = top.unwrapped_y; top_y = top.unwrapped_y;
@ -3873,7 +3746,7 @@ Text_Layout_Layout_Point_To_Buffer_Point(Application_Links *app, Text_Layout_ID
if (api_check_buffer(file)){ if (api_check_buffer(file)){
System_Functions *system = models->system; System_Functions *system = models->system;
// TODO(allen): this could be computed and stored _once_ right? // TODO(allen): this could be computed and stored _once_ right?
Full_Cursor top = file_compute_cursor(system, file, seek_line_char(layout.point.line_number, 1)); Full_Cursor top = file_compute_cursor(models, file, seek_line_char(layout.point.line_number, 1));
f32 top_y = top.wrapped_y; f32 top_y = top.wrapped_y;
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
top_y = top.unwrapped_y; top_y = top.unwrapped_y;
@ -3943,19 +3816,16 @@ Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_
b32 wrapped = !file->settings.unwrapped_lines; b32 wrapped = !file->settings.unwrapped_lines;
Face_ID font_id = file->settings.font_id; Face_ID font_id = file->settings.font_id;
#if 0 Face *face = font_set_face_from_id(&models->font_set, font_id);
Font_Pointers font = system->font.get_pointers_by_id(font_id);
#endif
Face *face = 0;
Full_Cursor intermediate_cursor = file_compute_cursor(system, file, seek_line_char(buffer_point.line_number, 1)); Full_Cursor intermediate_cursor = file_compute_cursor(models, file, seek_line_char(buffer_point.line_number, 1));
f32 scroll_x = buffer_point.pixel_shift.x; f32 scroll_x = buffer_point.pixel_shift.x;
f32 scroll_y = intermediate_cursor.wrapped_y; f32 scroll_y = intermediate_cursor.wrapped_y;
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
scroll_y = intermediate_cursor.unwrapped_y; scroll_y = intermediate_cursor.unwrapped_y;
} }
scroll_y += buffer_point.pixel_shift.y; scroll_y += buffer_point.pixel_shift.y;
Full_Cursor render_cursor = file_get_render_cursor(system, file, scroll_y); Full_Cursor render_cursor = file_get_render_cursor(models, file, scroll_y);
i32 item_count = 0; i32 item_count = 0;
i32 end_pos = 0; i32 end_pos = 0;
@ -4119,7 +3989,7 @@ Get_View_Visible_Range(Application_Links *app, View_ID view_id){
if (api_check_view(view)){ if (api_check_view(view)){
i32 view_height = rect_height(view->panel->rect_inner); i32 view_height = rect_height(view->panel->rect_inner);
i32 line_height = view->line_height; i32 line_height = view->line_height;
Full_Cursor min_cursor = view_get_render_cursor(models->system, view); Full_Cursor min_cursor = view_get_render_cursor(models, view);
Buffer_Seek seek = seek_unwrapped_xy(0.f, min_cursor.wrapped_y + view_height + line_height, false); Buffer_Seek seek = seek_unwrapped_xy(0.f, min_cursor.wrapped_y + view_height + line_height, false);
Full_Cursor max_cursor = view_compute_cursor(app, view_id, seek); Full_Cursor max_cursor = view_compute_cursor(app, view_id, seek);
result = Ii32((i32)min_cursor.pos, (i32)max_cursor.pos); result = Ii32((i32)min_cursor.pos, (i32)max_cursor.pos);

View File

@ -28,7 +28,7 @@ struct App_Settings{
}; };
struct Models{ struct Models{
Base_Allocator allocator; Base_Allocator *base_allocator;
Mem_Options mem; Mem_Options mem;
App_Settings settings; App_Settings settings;
@ -72,6 +72,7 @@ struct Models{
Parse_Context_Memory parse_context_memory; Parse_Context_Memory parse_context_memory;
Global_History global_history; Global_History global_history;
Text_Layout_Container text_layouts; Text_Layout_Container text_layouts;
Font_Set font_set;
Dynamic_Variable_Layout variable_layout; Dynamic_Variable_Layout variable_layout;
Dynamic_Workspace dynamic_workspace; Dynamic_Workspace dynamic_workspace;

View File

@ -18,13 +18,14 @@
#include "4coder_base_types.h" #include "4coder_base_types.h"
#include "4coder_table.h" #include "4coder_table.h"
#include "4ed_font.h" #include "4ed_font_interface.h"
#include "4ed_system.h" #include "4ed_system.h"
#include "4coder_base_types.cpp" #include "4coder_base_types.cpp"
#include "4coder_string_match.cpp" #include "4coder_string_match.cpp"
#include "4coder_stringf.cpp" #include "4coder_stringf.cpp"
#include "4coder_app_links_allocator.cpp" #include "4coder_app_links_allocator.cpp"
#include "4ed_system_allocator.cpp"
#include "4coder_hash_functions.cpp" #include "4coder_hash_functions.cpp"
#include "4coder_table.cpp" #include "4coder_table.cpp"
@ -68,6 +69,7 @@ struct Mem_Options{
#include "4ed_view.h" #include "4ed_view.h"
#include "4ed_edit.h" #include "4ed_edit.h"
#include "4ed_text_layout.h" #include "4ed_text_layout.h"
#include "4ed_font_set.h"
#include "4ed_app_models.h" #include "4ed_app_models.h"
#include "4ed_mem.cpp" #include "4ed_mem.cpp"
@ -75,7 +77,8 @@ struct Mem_Options{
#include "4ed_memory_bank.cpp" #include "4ed_memory_bank.cpp"
#include "4ed_dynamic_variables.cpp" #include "4ed_dynamic_variables.cpp"
#include "4ed_parse_context.cpp" #include "4ed_parse_context.cpp"
#include "4ed_font.cpp" #include "4ed_font_face.cpp"
#include "4ed_font_set.cpp"
#include "4ed_translation.cpp" #include "4ed_translation.cpp"
#include "4ed_render_target.cpp" #include "4ed_render_target.cpp"
#include "4ed_render_format.cpp" #include "4ed_render_format.cpp"

View File

@ -705,7 +705,7 @@ buffer_measure_character_starts(System_Functions *system, Gap_Buffer *buffer, i3
for (; i < stream.end; ++i){ for (; i < stream.end; ++i){
u8 ch = (u8)stream.data[i]; u8 ch = (u8)stream.data[i];
translating_fully_process_byte(system, &tran, ch, i, size, &emits); translating_fully_process_byte(&tran, ch, i, size, &emits);
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
@ -781,7 +781,7 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para
S.skipping_whitespace = false; S.skipping_whitespace = false;
} }
translating_fully_process_byte(params.system, &S.tran, ch, S.i, S.size, &S.emits); translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits);
} }
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
@ -809,7 +809,7 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para
else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){
if (!S.skipping_whitespace){ if (!S.skipping_whitespace){
if (S.behavior.do_codepoint_advance){ if (S.behavior.do_codepoint_advance){
S.current_adv = font_get_glyph_advance(params.system, params.face, S.step.value); S.current_adv = font_get_glyph_advance(params.face, S.step.value);
} }
else{ else{
S.current_adv = params.face->byte_advance; S.current_adv = params.face->byte_advance;
@ -990,7 +990,7 @@ buffer_remeasure_character_starts(System_Functions *system, Gap_Buffer *buffer,
do{ do{
for (; char_i < stream.end; ++char_i){ for (; char_i < stream.end; ++char_i){
u8 ch = (u8)stream.data[char_i]; u8 ch = (u8)stream.data[char_i];
translating_fully_process_byte(system, &tran, ch, char_i, size, &emits); translating_fully_process_byte(&tran, ch, char_i, size, &emits);
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
@ -1417,7 +1417,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
for (; S.i < S.stream.end; ++S.i){ for (; S.i < S.stream.end; ++S.i){
{ {
u8 ch = (u8)S.stream.data[S.i]; u8 ch = (u8)S.stream.data[S.i];
translating_fully_process_byte(params.system, &S.tran, ch, S.i, S.size, &S.emits); translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits);
} }
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
@ -1448,7 +1448,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){
if (S.behavior.do_codepoint_advance){ if (S.behavior.do_codepoint_advance){
S.ch_width = font_get_glyph_advance(params.system, params.face, S.step.value); S.ch_width = font_get_glyph_advance(params.face, S.step.value);
} }
else{ else{
S.ch_width = params.face->byte_advance; S.ch_width = params.face->byte_advance;
@ -1628,7 +1628,7 @@ internal Render_Item_Write
write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags, write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags,
Render_Item_Flag render_flags){ Render_Item_Flag render_flags){
if (write.item < write.item_end){ if (write.item < write.item_end){
f32 ch_width = font_get_glyph_advance(write.system, write.face, codepoint); f32 ch_width = font_get_glyph_advance(write.face, codepoint);
b32 visible_on_layout = (write.x_min <= write.x + ch_width && write.x <= write.x_max); b32 visible_on_layout = (write.x_min <= write.x + ch_width && write.x <= write.x_max);
@ -1714,7 +1714,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32
for (; S.i < S.stream.end; ++S.i){ for (; S.i < S.stream.end; ++S.i){
{ {
u8 ch = (u8)S.stream.data[S.i]; u8 ch = (u8)S.stream.data[S.i];
translating_fully_process_byte(params.system, &S.tran, ch, S.i, S.size, &S.emits); translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits);
} }
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
@ -1814,7 +1814,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32
case '\t': case '\t':
{ {
S.ch_width = font_get_glyph_advance(params.system, params.face, '\t'); S.ch_width = font_get_glyph_advance(params.face, '\t');
f32 new_x = S.write.x + S.ch_width; f32 new_x = S.write.x + S.ch_width;
S.write = write_render_item(S.write, I, ' ', 0, flags); S.write = write_render_item(S.write, I, ' ', 0, flags);

View File

@ -10,7 +10,7 @@
// TOP // TOP
internal void internal void
wrap_state_init(System_Functions *system, Code_Wrap_State *state, Editing_File *file, Face *face){ wrap_state_init(Code_Wrap_State *state, Editing_File *file, Face *face){
state->token_array = file->state.token_array; state->token_array = file->state.token_array;
state->token_ptr = state->token_array.tokens; state->token_ptr = state->token_array.tokens;
state->end_token = state->token_ptr + state->token_array.count; state->end_token = state->token_ptr + state->token_array.count;
@ -27,7 +27,7 @@ wrap_state_init(System_Functions *system, Code_Wrap_State *state, Editing_File *
state->face = face; state->face = face;
state->tab_indent_amount = font_get_glyph_advance(system, face, '\t'); state->tab_indent_amount = font_get_glyph_advance(face, '\t');
state->byte_advance = face->byte_advance; state->byte_advance = face->byte_advance;
state->tran = null_buffer_translating_state; state->tran = null_buffer_translating_state;
@ -123,7 +123,7 @@ wrap_state_consume_token(System_Functions *system, Face *face, Code_Wrap_State *
} }
u8 ch = (u8)state->stream.data[i]; u8 ch = (u8)state->stream.data[i];
translating_fully_process_byte(system, &state->tran, ch, i, state->size, &state->emits); translating_fully_process_byte(&state->tran, ch, i, state->size, &state->emits);
for (TRANSLATION_EMIT_LOOP(state->J, state->emits)){ for (TRANSLATION_EMIT_LOOP(state->J, state->emits)){
TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits); TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits);
@ -136,7 +136,7 @@ wrap_state_consume_token(System_Functions *system, Face *face, Code_Wrap_State *
u32 n = state->step.value; u32 n = state->step.value;
f32 adv = 0; f32 adv = 0;
if (state->behavior.do_codepoint_advance){ if (state->behavior.do_codepoint_advance){
adv = font_get_glyph_advance(system, state->face, n); adv = font_get_glyph_advance(state->face, n);
if (n != ' ' && n != '\t'){ if (n != ' ' && n != '\t'){
skipping_whitespace = false; skipping_whitespace = false;
@ -484,7 +484,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
i32 max_wrap_indent_mark = Million(1); i32 max_wrap_indent_mark = Million(1);
if (params.virtual_white && file->state.tokens_complete && !file->state.still_lexing){ if (params.virtual_white && file->state.tokens_complete && !file->state.still_lexing){
wrap_state_init(system, &wrap_state, file, face); wrap_state_init(&wrap_state, file, face);
use_tokens = true; use_tokens = true;
potential_marks = push_array(scratch, Potential_Wrap_Indent_Pair, floor32(width)); potential_marks = push_array(scratch, Potential_Wrap_Indent_Pair, floor32(width));
@ -531,7 +531,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
for (; i < stream.end; ++i){ for (; i < stream.end; ++i){
{ {
u8 ch = stream.data[i]; u8 ch = stream.data[i];
translating_fully_process_byte(system, &tran, ch, i, size, &emits); translating_fully_process_byte(&tran, ch, i, size, &emits);
} }
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
@ -545,7 +545,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
word_stage = 1; word_stage = 1;
} }
else{ else{
f32 adv = font_get_glyph_advance(params.system, params.face, codepoint); f32 adv = font_get_glyph_advance(params.face, codepoint);
x += adv; x += adv;
self_x += adv; self_x += adv;
@ -659,7 +659,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
for (; i < stream.end; ++i){ for (; i < stream.end; ++i){
{ {
u8 ch = stream.data[i]; u8 ch = stream.data[i];
translating_fully_process_byte(system, &tran, ch, i, end_i, &emits); translating_fully_process_byte(&tran, ch, i, end_i, &emits);
} }
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
@ -680,7 +680,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
for (; i < stream.end; ++i){ for (; i < stream.end; ++i){
{ {
u8 ch = stream.data[i]; u8 ch = stream.data[i];
translating_fully_process_byte(system, &tran, ch, i, end_i, &emits); translating_fully_process_byte(&tran, ch, i, end_i, &emits);
} }
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
@ -690,7 +690,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
goto doublebreak_stage1; goto doublebreak_stage1;
} }
f32 adv = font_get_glyph_advance(params.system, params.face, buffer_step.value); f32 adv = font_get_glyph_advance(params.face, buffer_step.value);
x += adv; x += adv;
if (!first_word && x > current_width){ if (!first_word && x > current_width){
@ -715,7 +715,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
for (; i < stream.end; ++i){ for (; i < stream.end; ++i){
{ {
u8 ch = stream.data[i]; u8 ch = stream.data[i];
translating_fully_process_byte(system, &tran, ch, i, end_i, &emits); translating_fully_process_byte(&tran, ch, i, end_i, &emits);
} }
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
@ -726,7 +726,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
goto doublebreak_stage2; goto doublebreak_stage2;
} }
f32 adv = font_get_glyph_advance(params.system, params.face, buffer_step.value); f32 adv = font_get_glyph_advance(params.face, buffer_step.value);
x += adv; x += adv;
} }
} }

View File

@ -10,7 +10,8 @@
// TOP // TOP
internal void internal void
edit_pre_state_change(System_Functions *system, Heap *heap, Models *models, Editing_File *file){ edit_pre_state_change(Models *models, Heap *heap, Editing_File *file){
System_Functions *system = models->system;
if (file->state.still_lexing){ if (file->state.still_lexing){
system->cancel_job(BACKGROUND_THREADS, file->state.lex_job); system->cancel_job(BACKGROUND_THREADS, file->state.lex_job);
if (file->state.swap_array.tokens){ if (file->state.swap_array.tokens){
@ -27,8 +28,8 @@ edit_pre_state_change(System_Functions *system, Heap *heap, Models *models, Edit
panel = layout_get_next_open_panel(layout, panel)){ panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view; View *view = panel->view;
if (view->file == file){ if (view->file == file){
Full_Cursor render_cursor = view_get_render_cursor(system, view); Full_Cursor render_cursor = view_get_render_cursor(models, view);
Full_Cursor target_cursor = view_get_render_cursor_target(system, view); Full_Cursor target_cursor = view_get_render_cursor_target(models, view);
view->temp_view_top_left_pos = (i32)render_cursor.pos; view->temp_view_top_left_pos = (i32)render_cursor.pos;
view->temp_view_top_left_target_pos = (i32)target_cursor.pos; view->temp_view_top_left_target_pos = (i32)target_cursor.pos;
} }
@ -172,7 +173,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
View *view = panel->view; View *view = panel->view;
if (view->file == file){ if (view->file == file){
i32 cursor_pos = cursors[cursor_count++].pos; i32 cursor_pos = cursors[cursor_count++].pos;
Full_Cursor new_cursor = file_compute_cursor(system, file, seek_pos(cursor_pos)); Full_Cursor new_cursor = file_compute_cursor(models, file, seek_pos(cursor_pos));
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
GUI_Scroll_Vars scroll = edit_pos.scroll; GUI_Scroll_Vars scroll = edit_pos.scroll;
@ -183,7 +184,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
i32 top_left_target_pos = cursors[cursor_count++].pos; i32 top_left_target_pos = cursors[cursor_count++].pos;
f32 new_y_val_aligned = 0; f32 new_y_val_aligned = 0;
if (view->temp_view_top_left_pos != top_left_pos){ if (view->temp_view_top_left_pos != top_left_pos){
Full_Cursor new_position_cursor = file_compute_cursor(system, file, seek_pos(top_left_pos)); Full_Cursor new_position_cursor = file_compute_cursor(models, file, seek_pos(top_left_pos));
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
new_y_val_aligned = new_position_cursor.unwrapped_y; new_y_val_aligned = new_position_cursor.unwrapped_y;
} }
@ -194,7 +195,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
} }
if (view->temp_view_top_left_target_pos != top_left_target_pos){ if (view->temp_view_top_left_target_pos != top_left_target_pos){
if (top_left_target_pos != top_left_pos){ if (top_left_target_pos != top_left_pos){
Full_Cursor new_position_cursor = file_compute_cursor(system, file, seek_pos(top_left_target_pos)); Full_Cursor new_position_cursor = file_compute_cursor(models, file, seek_pos(top_left_target_pos));
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
new_y_val_aligned = new_position_cursor.unwrapped_y; new_y_val_aligned = new_position_cursor.unwrapped_y;
} }
@ -252,7 +253,7 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range
} }
// NOTE(allen): fixing stuff beforewards???? // NOTE(allen): fixing stuff beforewards????
edit_pre_state_change(system, heap, models, file); edit_pre_state_change(models, heap, file);
// NOTE(allen): edit range hook // NOTE(allen): edit range hook
if (models->hook_file_edit_range != 0){ if (models->hook_file_edit_range != 0){
@ -294,11 +295,7 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range
} }
// NOTE(allen): wrap meta data // NOTE(allen): wrap meta data
#if 0 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
Assert(font.valid);
#endif
Face *face = 0;
Assert(face != 0); Assert(face != 0);
file_measure_wraps(system, &models->mem, file, face); file_measure_wraps(system, &models->mem, file, face);

View File

@ -237,12 +237,9 @@ file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek){
} }
internal Full_Cursor internal Full_Cursor
file_compute_cursor__inner(System_Functions *system, Editing_File *file, Buffer_Seek seek, b32 return_hint){ file_compute_cursor__inner(Models *models, Editing_File *file, Buffer_Seek seek, b32 return_hint){
#if 0 System_Functions *system = models->system;
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id); Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Assert(font.valid);
#endif
Face *face = 0;
Assert(face != 0); Assert(face != 0);
Full_Cursor result = {}; Full_Cursor result = {};
@ -314,13 +311,13 @@ file_compute_cursor__inner(System_Functions *system, Editing_File *file, Buffer_
} }
internal Full_Cursor internal Full_Cursor
file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek seek){ file_compute_cursor(Models *models, Editing_File *file, Buffer_Seek seek){
return(file_compute_cursor__inner(system, file, seek, false)); return(file_compute_cursor__inner(models, file, seek, false));
} }
internal Full_Cursor internal Full_Cursor
file_compute_cursor_hint(System_Functions *system, Editing_File *file, Buffer_Seek seek){ file_compute_cursor_hint(Models *models, Editing_File *file, Buffer_Seek seek){
return(file_compute_cursor__inner(system, file, seek, true)); return(file_compute_cursor__inner(models, file, seek, true));
} }
//////////////////////////////// ////////////////////////////////
@ -450,11 +447,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
Face_ID font_id = models->global_font_id; Face_ID font_id = models->global_font_id;
file->settings.font_id = font_id; file->settings.font_id = font_id;
#if 0 Face *face = font_set_face_from_id(&models->font_set, font_id);
Font_Pointers font = system->font.get_pointers_by_id(font_id);
Assert(font.valid);
#endif
Face *face = 0;
Assert(face != 0); Assert(face != 0);
file_measure_starts(heap, &file->state.buffer); file_measure_starts(heap, &file->state.buffer);

View File

@ -1,230 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 11.03.2017
*
* Implements some basic getters for fonts set up to make the font type opaque.
*
*/
// TOP
// TODO(allen): This is really "renderer font helpers or something like that"
#if 0
internal Face_ID
font_get_id_by_name(System_Functions *system, String_Const_u8 name){
Face_ID id = 0;
u32 count = system->font.get_count();
for (Face_ID id_it = 1; id_it <= count; ++id_it){
char str[256];
i32 str_len = system->font.get_name_by_id(id_it, str, sizeof(str));
if (str_len > 0){
String_Const_u8 font_name = SCu8(str, str_len);
if (string_match(font_name, name)){
id = id_it;
break;
}
}
}
return(id);
}
internal Glyph_Page**
font_page_lookup(Font_Page_Storage *page_storage, u32 page_number, b32 get_empty_slot){
Glyph_Page **result = 0;
if (page_storage->page_max > 0){
u32 first_index = page_number % page_storage->page_max;
u32 range_count = 0;
u32 ranges[4];
if (first_index == 0){
ranges[0] = 0;
ranges[1] = page_storage->page_max;
range_count = 2;
}
else{
ranges[0] = first_index;
ranges[1] = page_storage->page_max;
ranges[2] = 0;
ranges[3] = first_index;
range_count = 4;
}
Glyph_Page **pages = page_storage->pages;
if (get_empty_slot){
for (u32 j = 0; j < range_count; j += 2){
u32 stop = ranges[j+1];
for (u32 i = ranges[j]; i < stop; ++i){
if (pages[i] == FONT_PAGE_EMPTY || pages[i] == FONT_PAGE_DELETED){
result = &pages[i];
goto break2;
}
if (pages[i]->page_number == page_number){
goto break2;
}
}
}
}
else{
for (u32 j = 0; j < range_count; j += 2){
u32 stop = ranges[j+1];
for (u32 i = ranges[j]; i < stop; ++i){
if (pages[i] == FONT_PAGE_EMPTY){
goto break2;
}
if (pages[i] != FONT_PAGE_DELETED && pages[i]->page_number == page_number){
result = &pages[i];
goto break2;
}
}
}
}
break2:;
}
return(result);
}
internal Glyph_Page*
font_get_page(Font_Page_Storage *pages, u32 page_number){
Glyph_Page *result = 0;
if (page_number <= 0x10FF){
Glyph_Page **page_get_result = font_page_lookup(pages, page_number, false);
if (page_get_result != 0){
result = *page_get_result;
}
}
return(result);
}
internal Glyph_Page*
font_allocate_and_hash_new_page(System_Functions *system, Font_Page_Storage *storage, u32 page_number){
Glyph_Page *new_page = 0;
if (page_number <= 0x10FF){
b32 has_space = true;
// Grow and rehash the table if we need to now.
u32 new_page_count = 1;
u32 new_max = (storage->page_count + new_page_count)*3;
if (storage->page_max < FONT_PAGE_MAX && new_max > storage->page_max*2){
Glyph_Page **pages = (Glyph_Page**)system->font.allocate(sizeof(Glyph_Page*)*new_max);
if (pages != 0){
u32 old_max = storage->page_max;
Glyph_Page **old_pages = storage->pages;
storage->pages = pages;
storage->page_max = new_max;
memset(pages, 0, sizeof(*pages)*new_max);
if (old_pages != 0){
for (u32 i = 0; i < old_max; ++i){
Glyph_Page *this_page = old_pages[i];
if (this_page != FONT_PAGE_EMPTY && this_page != FONT_PAGE_DELETED){
u32 this_page_number = this_page->page_number;
Glyph_Page **dest = font_page_lookup(storage, this_page_number, true);
Assert(dest != 0);
*dest = this_page;
}
}
system->font.free(old_pages);
}
}
else{
has_space = false;
}
}
// Allocate and hash a new page if there is room in the table.
if (has_space){
new_page = (Glyph_Page*)system->font.allocate(sizeof(Glyph_Page));
if (new_page != 0){
Glyph_Page **dest = font_page_lookup(storage, page_number, true);
Assert(dest != 0);
*dest = new_page;
storage->page_count += new_page_count;
}
}
}
return(new_page);
}
internal Glyph_Page*
font_make_page(System_Functions *system, Font_Settings *settings, Font_Metrics *metrics, Font_Page_Storage *pages, u32 page_number){
Glyph_Page *new_page = font_allocate_and_hash_new_page(system, pages, page_number);
if (new_page != 0){
system->font.load_page(settings, metrics, new_page, page_number);
}
return(new_page);
}
///////
// HACK(allen): Hack optimizations
struct Font_Cached_Lookup_Result{
Glyph_Page *page;
u32 index;
};
internal Font_Cached_Lookup_Result
font_cached_lookup(Font_Page_Storage *pages, u32 page_number){
Font_Cached_Lookup_Result result = {};
result.index = page_number % ArrayCount(pages->cache);
if (pages->cache[result.index].page_number == page_number){
result.page = pages->cache[result.index].page;
}
if (result.page == 0){
result.page = font_get_page(pages, page_number);
}
return(result);
}
internal Glyph_Page*
font_cached_get_page(Font_Page_Storage *pages, u32 page_number){
Font_Cached_Lookup_Result result = font_cached_lookup(pages, page_number);
if (result.page != 0){
pages->cache[result.index].page = result.page;
pages->cache[result.index].page_number = page_number;
}
return(result.page);
}
internal Glyph_Page*
font_cached_get_or_make_page(System_Functions *system, Font_Settings *settings, Font_Metrics *metrics, Font_Page_Storage *pages, u32 page_number){
Font_Cached_Lookup_Result result = font_cached_lookup(pages, page_number);
if (result.page == 0){
result.page = font_make_page(system, settings, metrics, pages, page_number);
}
if (result.page != 0){
pages->cache[result.index].page = result.page;
pages->cache[result.index].page_number = page_number;
}
return(result.page);
}
///////
internal f32
font_get_glyph_advance(System_Functions *system, Font_Settings *settings, Font_Metrics *metrics, Font_Page_Storage *pages, u32 codepoint){
f32 result = 0.f;
u32 page_number = (codepoint >> 8);
Glyph_Page *page = font_cached_get_or_make_page(system, settings, metrics, pages, page_number);
u32 glyph_index = codepoint & 0xFF;
if (page != 0 && page->advance[glyph_index] > 0.f){
result = page->advance[glyph_index];
}
return(result);
}
#endif
internal f32
font_get_glyph_advance(System_Functions *system, Face *face, u32 codepoint){
f32 result = 0.f;
NotImplemented;
return(result);
}
// BOTTOM

View File

@ -1,87 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 11.03.2017
*
* Font system interface.
*
*/
// TOP
#if !defined(FCODER_FONT_H)
#define FCODER_FONT_H
struct Font_Loadable_Stub{
b32 load_from_path;
b32 in_font_folder;
i32 len;
char name[256];
};
struct Face_Parameters{
i32 pt_size;
b32 italics;
b32 bold;
b32 underline;
b32 use_hinting;
};
struct Face_Settings{
Font_Loadable_Stub stub;
Face_Parameters parameters;
};
struct Glyph_Bounds{
Rect_f32 uv;
f32 w;
Rect_f32 xy_off;
};
typedef i32 Texture_Kind;
struct Face{
Face_Settings settings;
// NOTE(allen): Metrics
String_Const_u8 name;
f32 height;
f32 ascent;
f32 descent;
f32 line_skip;
f32 advance;
f32 underline_yoff1;
f32 underline_yoff2;
f32 byte_advance;
f32 sub_advances[3];
// NOTE(allen): Glyph data
Table_u32_u16 codepoint_to_index_table;
i32 index_count;
Glyph_Bounds *bounds;
Glyph_Bounds white;
Texture_Kind gpu_texture_kind;
u32 gpu_texture;
Vec3_f32 gpu_texture_dim;
};
////////////////////////////////
typedef u32 Get_GPU_Texture_Function(Vec3_i32 dim, Texture_Kind texture_kind);
typedef b32 Fill_GPU_Texture_Function(Texture_Kind texture_kind, u32 gpu_texture,
Vec3_i32 p, Vec3_i32 dim, void *data);
// NOTE(allen): Platform layer calls - implemented in a "font provider"
typedef Face Font_Make_Face_Function(Arena *arena, Face_Settings *settings,
Get_GPU_Texture_Function *get_gpu_texture,
Fill_GPU_Texture_Function *fill_gpu_texture);
#endif
// BOTTOM

70
4ed_font_face.cpp Normal file
View File

@ -0,0 +1,70 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 23.07.2019
*
* Face basic operations.
*
*/
// TOP
internal b32
codepoint_index_map_read(Codepoint_Index_Map *map, u32 codepoint, u16 *index_out){
b32 success = true;
if (codepoint == 0 && map->has_zero_index){
*index_out = map->zero_index;
}
else if (table_read(&map->table, codepoint, index_out)){
// NOTE(allen): do nothing
}
else{
success = false;
}
return(success);
}
internal u16
codepoint_index_map_count(Codepoint_Index_Map *map){
return(map->max_index + 1);
}
internal f32
font_get_glyph_advance(Face *face, u32 codepoint){
f32 result = 0.f;
if (codepoint == '\t'){
result = face->space_advance*4.f;
}
else{
u16 index = 0;
if (codepoint_index_map_read(&face->codepoint_to_index_map, codepoint, &index)){
if (index < face->index_count){
result = face->advance[index];
}
}
}
return(result);
}
internal f32
font_get_max_glyph_advance_range(Face *face, u32 codepoint_first, u32 codepoint_last){
f32 result = font_get_glyph_advance(face, codepoint_first);
for (u32 i = codepoint_first + 1; i <= codepoint_last; i += 1){
f32 a = font_get_glyph_advance(face, i);
result = Max(a, result);
}
return(result);
}
internal f32
font_get_average_glyph_advance_range(Face *face, u32 codepoint_first, u32 codepoint_last){
f32 result = 0.f;
for (u32 i = codepoint_first; i <= codepoint_last; i += 1){
result += font_get_glyph_advance(face, i);
}
result /= (f32)(codepoint_last - codepoint_first + 1);
return(result);
}
// BOTTOM

84
4ed_font_interface.h Normal file
View File

@ -0,0 +1,84 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 11.03.2017
*
* Font system interface.
*
*/
// TOP
#if !defined(FCODER_FONT_INTERFACE_H)
#define FCODER_FONT_INTERFACE_H
typedef i32 Texture_Kind;
enum{
TextureKind_Error,
TextureKind_Mono,
};
typedef u32 Graphics_Get_Texture_Function(Vec3_i32 dim, Texture_Kind texture_kind);
typedef b32 Graphics_Fill_Texture_Function(Texture_Kind texture_kind, u32 texture,
Vec3_i32 p, Vec3_i32 dim, void *data);
////////////////////////////////
struct Glyph_Bounds{
Rect_f32 uv;
f32 w;
Rect_f32 xy_off;
};
struct Codepoint_Index_Map{
b32 has_zero_index;
u16 zero_index;
u16 max_index;
Table_u32_u16 table;
};
struct Face{
Face_Description description;
// NOTE(allen): Metrics
f32 height;
f32 ascent;
f32 descent;
f32 line_skip;
f32 max_advance;
f32 underline_yoff1;
f32 underline_yoff2;
f32 space_advance;
f32 digit_advance;
f32 hex_advance;
f32 byte_advance;
f32 byte_sub_advances[3];
f32 typical_lowercase_advance;
f32 typical_uppercase_advance;
f32 typical_advance;
// NOTE(allen): Glyph data
Codepoint_Index_Map codepoint_to_index_map;
u16 index_count;
Glyph_Bounds *bounds;
f32 *advance;
Glyph_Bounds white;
Texture_Kind texture_kind;
u32 texture;
Vec3_f32 texture_dim;
};
////////////////////////////////
// NOTE(allen): Platform layer calls - implemented in a "font provider"
typedef Face *Font_Make_Face_Function(Arena *arena, Face_Description *description);
#endif
// BOTTOM

File diff suppressed because it is too large Load Diff

View File

@ -22,107 +22,6 @@ struct FT_Codepoint_Index_Pair_Array{
i32 count; i32 count;
}; };
#if 0
struct Font_Slot{
b32 is_active;
Font_Settings settings;
Font_Metrics metrics;
Font_Data data;
#if 0
Font_Page_Storage pages;
#endif
};
struct Font_Slot_Page{
Font_Slot_Page *next;
Font_Slot_Page *prev;
u64 *is_active;
Font_Settings *settings;
Font_Metrics *metrics;
Font_Page_Storage *pages;
i32 used_count;
i32 fill_count;
i32 max;
Face_ID first_id;
};
struct Font_Slot_Page_And_Index{
Font_Slot_Page *page;
i32 index;
};
// NOTE(allen): SLOT_PER_PAGE must be >= 1
global i32 SLOT_PER_PAGE = 32;
global i32 SLOT_SIZE = sizeof(Font_Settings) + sizeof(Font_Metrics) + sizeof(Font_Page_Storage);
global i32 SLOT_PAGE_SIZE = sizeof(Font_Slot_Page) + ((SLOT_PER_PAGE + 63)/64)*8 + SLOT_PER_PAGE*SLOT_SIZE;
struct Font_Vars{
Font_Slot_Page slot_pages_sentinel;
i32 used_slot_count;
i32 max_slot_count;
Face_ID largest_font_id;
// HACK(allen): // HACK(allen): // HACK(allen):
// TODO(allen): Upgrade this to have "unlimited" resizable memory.
Font_Loadable_Description loadables[4096];
i32 loadable_count;
u32 pt_size;
b32 use_hinting;
};
global Font_Vars fontvars = {};
struct Font_Setup{
Font_Setup *next;
Font_Loadable_Stub stub;
b32 has_display_name;
i32 len;
char name[64];
};
struct _Setup_List{
Font_Setup *first;
Font_Setup *last;
};
// NOTE(allen): Procedures to be implemented per-OS for the freetype font provider.
struct Font_Path{
char *name;
i32 len;
b32 used_base_file;
};
struct Font_Raw_Data{
u8 *data;
i32 size;
b32 used_base_file;
};
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 = {}; 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(n,p){ \
Font_Raw_Data data = {}; LOG("there is no font data retrieval procedure available\n"); return(data);}
#endif
#endif #endif
// BOTTOM // BOTTOM

167
4ed_font_set.cpp Normal file
View File

@ -0,0 +1,167 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 23.07.2019
*
* Type for organizating the set of all loaded font faces.
*
*/
// TOP
internal Face_ID
font_set__alloc_face_id(Font_Set *set){
Face_ID result = 0;
if (set->free_ids != 0){
Font_Face_ID_Node *node = set->free_ids;
result = node->id;
sll_stack_pop(set->free_ids);
sll_stack_push(set->free_id_nodes, node);
}
else{
result = set->next_id_counter;
set->next_id_counter += 1;
}
return(result);
}
internal void
font_set__free_face_id(Font_Set *set, Face_ID id){
if (id + 1 == set->next_id_counter){
set->next_id_counter -= 1;
}
else{
Font_Face_ID_Node *node = 0;
if (set->free_id_nodes == 0){
node = push_array(&set->arena, Font_Face_ID_Node, 1);
}
else{
node = set->free_id_nodes;
sll_stack_pop(set->free_id_nodes);
}
sll_stack_push(set->free_ids, node);
node->id = id;
}
}
internal Font_Face_Slot*
font_set__alloc_face_slot(Font_Set *set){
Font_Face_Slot *result = 0;
if (set->free_face_slots == 0){
result = push_array(&set->arena, Font_Face_Slot, 1);
}
else{
result = set->free_face_slots;
sll_stack_pop(set->free_face_slots);
}
return(result);
}
internal void
font_set__free_face_slot(Font_Set *set, Font_Face_Slot *slot){
if (slot->arena.base_allocator != 0){
linalloc_clear(&slot->arena);
}
block_zero_struct(slot);
sll_stack_push(set->free_face_slots, slot);
}
internal void
font_set_init(System_Functions *system, Font_Set *set){
block_zero_struct(set);
set->system = system;
set->arena = make_arena_system(system);
set->next_id_counter = 1;
set->id_to_slot_table = make_table_u64_u64(set->arena.base_allocator, 40);
}
internal Face_ID
font_set_new_face(Font_Set *set, Face_Description *description){
Face_ID result = 0;
Arena arena = make_arena_system(set->system);
Face *face = set->system->font_make_face(&arena, description);
if (face != 0){
Font_Face_Slot *slot = font_set__alloc_face_slot(set);
slot->arena = arena;
slot->face = face;
result = font_set__alloc_face_id(set);
table_insert(&set->id_to_slot_table, result, (u64)slot);
}
else{
linalloc_clear(&arena);
}
return(result);
}
internal Font_Face_Slot*
font_set__get_face_slot(Font_Set *set, Face_ID id){
Font_Face_Slot *result = 0;
u64 slot_ptr_u64 = 0;
if (table_read(&set->id_to_slot_table, id, &slot_ptr_u64)){
result = (Font_Face_Slot*)slot_ptr_u64;
}
return(result);
}
internal b32
font_set_release_face(Font_Set *set, Face_ID id){
b32 result = false;
Font_Face_Slot *slot = font_set__get_face_slot(set, id);
if (slot != 0){
table_erase(&set->id_to_slot_table, id);
font_set__free_face_slot(set, slot);
font_set__free_face_id(set, id);
result = true;
}
return(result);
}
internal Face*
font_set_face_from_id(Font_Set *set, Face_ID id){
Face *result = 0;
Font_Face_Slot *slot = font_set__get_face_slot(set, id);
if (slot != 0){
result = slot->face;
}
return(result);
}
internal Face_ID
font_set_get_fallback_face(Font_Set *set){
Face_ID result = 0;
for (Face_ID i = 1; i < set->next_id_counter; i += 1){
if (font_set__get_face_slot(set, i) != 0){
result = i;
break;
}
}
return(result);
}
internal Face_ID
font_set_get_largest_id(Font_Set *set){
return(set->next_id_counter - 1);
}
internal b32
font_set_modify_face(Font_Set *set, Face_ID id, Face_Description *description){
b32 result = false;
Font_Face_Slot *slot = font_set__get_face_slot(set, id);
if (slot != 0){
Arena arena = make_arena_system(set->system);
Face *face = set->system->font_make_face(&arena, description);
if (face != 0){
linalloc_clear(&slot->arena);
slot->arena = arena;
slot->face = face;
result = true;
}
else{
linalloc_clear(&arena);
}
}
return(result);
}
// BOTTOM

43
4ed_font_set.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 23.07.2019
*
* Type for organizating the set of all loaded font faces.
*
*/
// TOP
#if !defined(FRED_FONT_SET_H)
#define FRED_FONT_SET_H
struct Font_Face_ID_Node{
Font_Face_ID_Node *next;
Face_ID id;
};
union Font_Face_Slot{
struct{
Font_Face_Slot *next;
};
struct{
Arena arena;
Face *face;
};
};
struct Font_Set{
struct System_Functions *system;
Arena arena;
Face_ID next_id_counter;
Font_Face_ID_Node *free_ids;
Font_Face_ID_Node *free_id_nodes;
Font_Face_Slot *free_face_slots;
Table_u64_u64 id_to_slot_table;
};
#endif
// BOTTOM

View File

@ -26,8 +26,9 @@ draw_change_clip(Render_Target *target, i32_Rect clip_box){
} }
internal void internal void
begin_frame(Render_Target *target){ begin_frame(Render_Target *target, void *font_set){
target->buffer.pos = 0; target->buffer.pos = 0;
target->font_set = font_set;
} }
internal void internal void
@ -139,19 +140,16 @@ snap_point_to_boundary(Vec2 point){
} }
internal f32 internal f32
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color, u32 flags, Vec2 delta){ draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color, u32 flags, Vec2 delta){
f32 total_delta = 0.f; f32 total_delta = 0.f;
#if 0
Font_Pointers font = system->font.get_pointers_by_id(font_id);
#endif
Face *face = 0; Face *face = 0;
if (face != 0){ if (face != 0){
point = snap_point_to_boundary(point); point = snap_point_to_boundary(point);
f32 byte_advance = face->byte_advance; f32 byte_advance = face->byte_advance;
f32 *sub_advances = face->sub_advances; f32 *byte_sub_advances = face->byte_sub_advances;
u8 *str = (u8*)string.str; u8 *str = (u8*)string.str;
u8 *str_end = str + string.size; u8 *str_end = str + string.size;
@ -160,7 +158,7 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
Translation_Emits emits = {}; Translation_Emits emits = {};
for (u32 i = 0; str < str_end; ++str, ++i){ for (u32 i = 0; str < str_end; ++str, ++i){
translating_fully_process_byte(system, &tran, *str, i, (i32)string.size, &emits); translating_fully_process_byte(&tran, *str, i, (i32)string.size, &emits);
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
@ -170,7 +168,7 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
if (color != 0){ if (color != 0){
draw_font_glyph(target, font_id, codepoint, point.x, point.y, color, flags); draw_font_glyph(target, font_id, codepoint, point.x, point.y, color, flags);
} }
f32 d = font_get_glyph_advance(system, face, codepoint); f32 d = font_get_glyph_advance(face, codepoint);
point += d*delta; point += d*delta;
total_delta += d; total_delta += d;
} }
@ -183,7 +181,7 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
Vec2 pp = point; Vec2 pp = point;
for (u32 j = 0; j < 3; ++j){ for (u32 j = 0; j < 3; ++j){
draw_font_glyph(target, font_id, cs[j], pp.x, pp.y, color, flags); draw_font_glyph(target, font_id, cs[j], pp.x, pp.y, color, flags);
pp += delta*sub_advances[j]; pp += delta*byte_sub_advances[j];
} }
} }
point += byte_advance*delta; point += byte_advance*delta;
@ -197,30 +195,30 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
} }
internal f32 internal f32
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color){ draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color){
return(draw_string(system, target, font_id, string, point, color, 0, V2(1.f, 0.f))); return(draw_string(target, font_id, string, point, color, 0, V2(1.f, 0.f)));
} }
internal f32 internal f32
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point,
u32 color, u32 flags, Vec2 delta){ u32 color, u32 flags, Vec2 delta){
return(draw_string(system, target, font_id, SCu8(str), point, color, flags, delta)); return(draw_string(target, font_id, SCu8(str), point, color, flags, delta));
} }
internal f32 internal f32
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, u8 *str, Vec2 point, draw_string(Render_Target *target, Face_ID font_id, u8 *str, Vec2 point,
u32 color){ u32 color){
return(draw_string(system, target, font_id, SCu8(str), point, color, 0, V2(1.f, 0.f))); return(draw_string(target, font_id, SCu8(str), point, color, 0, V2(1.f, 0.f)));
} }
internal f32 internal f32
font_string_width(System_Functions *system, Render_Target *target, Face_ID font_id, String_Const_u8 str){ font_string_width(Render_Target *target, Face_ID font_id, String_Const_u8 str){
return(draw_string(system, target, font_id, str, V2(0, 0), 0, 0, V2(0, 0))); return(draw_string(target, font_id, str, V2(0, 0), 0, 0, V2(0, 0)));
} }
internal f32 internal f32
font_string_width(System_Functions *system, Render_Target *target, Face_ID font_id, u8 *str){ font_string_width(Render_Target *target, Face_ID font_id, u8 *str){
return(draw_string(system, target, font_id, SCu8(str), V2(0, 0), 0, 0, V2(0, 0))); return(draw_string(target, font_id, SCu8(str), V2(0, 0), 0, 0, V2(0, 0)));
} }
// BOTTOM // BOTTOM

View File

@ -36,6 +36,8 @@ struct Render_Target{
// TODO(allen): rewrite render system to work on an arena // TODO(allen): rewrite render system to work on an arena
Cursor buffer; Cursor buffer;
void *font_set;
}; };
#endif #endif

View File

@ -208,10 +208,10 @@ typedef Sys_Memory_Set_Protection_Sig(System_Memory_Set_Protection);
typedef Sys_Memory_Free_Sig(System_Memory_Free); typedef Sys_Memory_Free_Sig(System_Memory_Free);
// file system // file system
#define Sys_Get_Current_Path_Sig(name) i32 name(char *out, i32 capacity) #define Sys_Get_Current_Path_Sig(name) String_Const_u8 name(Arena *arena)
typedef Sys_Get_Current_Path_Sig(System_Get_Current_Path); typedef Sys_Get_Current_Path_Sig(System_Get_Current_Path);
#define Sys_Get_4ed_Path_Sig(name) i32 name(char *out, i32 capacity) #define Sys_Get_4ed_Path_Sig(name) String_Const_u8 name(Arena *arena)
typedef Sys_Get_4ed_Path_Sig(System_Get_4ed_Path); typedef Sys_Get_4ed_Path_Sig(System_Get_4ed_Path);
// behavior and appearance options // behavior and appearance options
@ -226,6 +226,8 @@ typedef Sys_Is_Fullscreen_Sig(System_Is_Fullscreen);
struct System_Functions{ struct System_Functions{
Font_Make_Face_Function *font_make_face; Font_Make_Face_Function *font_make_face;
Graphics_Get_Texture_Function *get_texture;
Graphics_Fill_Texture_Function *fill_texture;
// files (tracked api): 11 // files (tracked api): 11
System_Set_File_List *set_file_list; System_Set_File_List *set_file_list;

View File

@ -98,7 +98,7 @@ translating_select_emit_rule_ASCII(Translation_State *tran, Translation_Byte_Des
} }
internal void internal void
translating_select_emit_rule_UTF8(System_Functions *system, Translation_State *tran, Translation_Byte_Description desc, Translation_Emit_Rule *type_out){ translating_select_emit_rule_UTF8(Translation_State *tran, Translation_Byte_Description desc, Translation_Emit_Rule *type_out){
type_out->byte_class = desc.byte_class; type_out->byte_class = desc.byte_class;
type_out->last_byte_handler = desc.last_byte_handler; type_out->last_byte_handler = desc.last_byte_handler;
type_out->emit_type = desc.prelim_emit_type; type_out->emit_type = desc.prelim_emit_type;
@ -178,11 +178,11 @@ translating_generate_emits(Translation_State *tran, Translation_Emit_Rule emit_r
} }
internal void internal void
translating_fully_process_byte(System_Functions *system, Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Emits *emits_out){ translating_fully_process_byte(Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Emits *emits_out){
Translation_Byte_Description description = {}; Translation_Byte_Description description = {};
translating_consume_byte(tran, ch, i, size, &description); translating_consume_byte(tran, ch, i, size, &description);
Translation_Emit_Rule emit_rule = {}; Translation_Emit_Rule emit_rule = {};
translating_select_emit_rule_UTF8(system, tran, description, &emit_rule); translating_select_emit_rule_UTF8(tran, description, &emit_rule);
translating_generate_emits(tran, emit_rule, ch, i, emits_out); translating_generate_emits(tran, emit_rule, ch, i, emits_out);
} }

View File

@ -117,9 +117,9 @@ view_height(Models *models, View *view){
} }
internal Vec2_i32 internal Vec2_i32
view_get_cursor_xy(System_Functions *system, View *view){ view_get_cursor_xy(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(system, view->file, seek_pos(edit_pos.cursor_pos)); Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(edit_pos.cursor_pos));
Vec2_i32 result = {}; Vec2_i32 result = {};
if (view->file->settings.unwrapped_lines){ if (view->file->settings.unwrapped_lines){
result = V2i32((i32)cursor.unwrapped_x, (i32)cursor.unwrapped_y); result = V2i32((i32)cursor.unwrapped_x, (i32)cursor.unwrapped_y);
@ -175,12 +175,13 @@ view_compute_max_target_y(Models *models, View *view){
//////////////////////////////// ////////////////////////////////
internal b32 internal b32
view_move_view_to_cursor(System_Functions *system, Models *models, View *view, GUI_Scroll_Vars *scroll){ view_move_view_to_cursor(Models *models, View *view, GUI_Scroll_Vars *scroll){
System_Functions *system = models->system;
b32 result = false; b32 result = false;
i32 max_x = (i32)view_width(models, view); i32 max_x = (i32)view_width(models, view);
i32 max_y = view_compute_max_target_y(models, view); i32 max_y = view_compute_max_target_y(models, view);
Vec2_i32 cursor = view_get_cursor_xy(system, view); Vec2_i32 cursor = view_get_cursor_xy(models, view);
GUI_Scroll_Vars scroll_vars = *scroll; GUI_Scroll_Vars scroll_vars = *scroll;
i32 target_x = scroll_vars.target_x; i32 target_x = scroll_vars.target_x;
@ -213,9 +214,10 @@ view_move_view_to_cursor(System_Functions *system, Models *models, View *view, G
} }
internal b32 internal b32
view_move_cursor_to_view(System_Functions *system, Models *models, View *view, GUI_Scroll_Vars scroll, i32 *pos_in_out, f32 preferred_x){ view_move_cursor_to_view(Models *models, View *view, GUI_Scroll_Vars scroll, i32 *pos_in_out, f32 preferred_x){
System_Functions *system = models->system;
Editing_File *file = view->file; Editing_File *file = view->file;
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(*pos_in_out)); Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(*pos_in_out));
i32 line_height = view->line_height; i32 line_height = view->line_height;
f32 old_cursor_y = 0.f; f32 old_cursor_y = 0.f;
@ -246,7 +248,7 @@ view_move_cursor_to_view(System_Functions *system, Models *models, View *view, G
cursor_y -= line_height; cursor_y -= line_height;
} }
Buffer_Seek seek = seek_xy(preferred_x, cursor_y, false, file->settings.unwrapped_lines); Buffer_Seek seek = seek_xy(preferred_x, cursor_y, false, file->settings.unwrapped_lines);
cursor = file_compute_cursor(system, file, seek); cursor = file_compute_cursor(models, file, seek);
*pos_in_out = (i32)cursor.pos; *pos_in_out = (i32)cursor.pos;
result = true; result = true;
} }
@ -270,9 +272,9 @@ view_set_preferred_x(View *view, Full_Cursor cursor){
} }
internal void internal void
view_set_preferred_x_to_current_position(System_Functions *system, View *view){ view_set_preferred_x_to_current_position(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(system, view->file, seek_pos(edit_pos.cursor_pos)); Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(edit_pos.cursor_pos));
view_set_preferred_x(view, cursor); view_set_preferred_x(view, cursor);
} }
@ -285,7 +287,7 @@ view_set_cursor(System_Functions *system, Models *models, View *view, Full_Curso
} }
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
GUI_Scroll_Vars scroll = edit_pos.scroll; GUI_Scroll_Vars scroll = edit_pos.scroll;
if (view_move_view_to_cursor(system, models, view, &scroll)){ if (view_move_view_to_cursor(models, view, &scroll)){
edit_pos.scroll = scroll; edit_pos.scroll = scroll;
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
} }
@ -297,8 +299,8 @@ view_set_scroll(System_Functions *system, Models *models, View *view, GUI_Scroll
file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(models, view)); file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(models, view));
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
i32 pos = (i32)edit_pos.cursor_pos; i32 pos = (i32)edit_pos.cursor_pos;
if (view_move_cursor_to_view(system, models, view, edit_pos.scroll, &pos, view->preferred_x)){ if (view_move_cursor_to_view(models, view, edit_pos.scroll, &pos, view->preferred_x)){
Full_Cursor cursor = file_compute_cursor(system, view->file, seek_pos(pos)); Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(pos));
edit_pos.cursor_pos = cursor.pos; edit_pos.cursor_pos = cursor.pos;
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
} }
@ -343,12 +345,9 @@ view_set_file(System_Functions *system, Models *models, View *view, Editing_File
File_Edit_Positions edit_pos = file_edit_positions_pop(file); File_Edit_Positions edit_pos = file_edit_positions_pop(file);
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
view->mark = edit_pos.cursor_pos; view->mark = edit_pos.cursor_pos;
view_set_preferred_x_to_current_position(system, view); view_set_preferred_x_to_current_position(models, view);
#if 0 Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
#endif
Face *face = 0;
Assert(face != 0); Assert(face != 0);
view->line_height = (i32)face->height; view->line_height = (i32)face->height;
@ -382,7 +381,7 @@ adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *mod
View *view = panel->view; View *view = panel->view;
if (view->file == file){ if (view->file == file){
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(edit_pos.cursor_pos)); Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(edit_pos.cursor_pos));
view_set_cursor(system, models, view, cursor, true); view_set_cursor(system, models, view, cursor, true);
} }
} }
@ -391,10 +390,7 @@ adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *mod
internal void internal void
file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){ file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){
Face_ID font_id = file->settings.font_id; Face_ID font_id = file->settings.font_id;
#if 0 Face *face = font_set_face_from_id(&models->font_set, font_id);
Font_Pointers font = system->font.get_pointers_by_id(font_id);
#endif
Face *face = 0;
file_measure_wraps(system, &models->mem, file, face); file_measure_wraps(system, &models->mem, file, face);
adjust_views_looking_at_file_to_new_cursor(system, models, file); adjust_views_looking_at_file_to_new_cursor(system, models, file);
@ -427,43 +423,31 @@ global_set_font_and_update_files(System_Functions *system, Models *models, Face_
} }
internal b32 internal b32
alter_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id, Face_Settings *new_settings){ alter_font_and_update_files(System_Functions *system, Models *models, Face_ID face_id, Face_Description *new_description){
b32 success = false; b32 success = false;
NotImplemented; if (font_set_modify_face(&models->font_set, face_id, new_description)){
#if 0
if (system->font.face_change_settings(font_id, new_settings)){
success = true; success = true;
for (Node *node = models->working_set.used_sentinel.next; for (Node *node = models->working_set.used_sentinel.next;
node != &models->working_set.used_sentinel; node != &models->working_set.used_sentinel;
node = node->next){ node = node->next){
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
if (file->settings.font_id == font_id){ if (file->settings.font_id == face_id){
file_full_remeasure(system, models, file); file_full_remeasure(system, models, file);
} }
} }
} }
#endif
return(success); return(success);
} }
internal b32 internal b32
release_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id, Face_ID replacement_id){ release_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id, Face_ID replacement_id){
b32 success = false; b32 success = false;
NotImplemented; if (font_set_release_face(&models->font_set, font_id)){
#if 0 Face *face = font_set_face_from_id(&models->font_set, replacement_id);
if (system->font.face_release(font_id)){ if (face == 0){
Font_Pointers font = system->font.get_pointers_by_id(replacement_id); replacement_id = font_set_get_fallback_face(&models->font_set);
if (!font.valid){ Assert(font_set_face_from_id(&models->font_set, replacement_id) != 0);
Face_ID largest_id = system->font.get_largest_id();
for (replacement_id = 1; replacement_id <= largest_id && replacement_id > 0; ++replacement_id){
font = system->font.get_pointers_by_id(replacement_id);
if (font.valid){
break;
} }
}
Assert(replacement_id <= largest_id && replacement_id > 0);
}
success = true;
for (Node *node = models->working_set.used_sentinel.next; for (Node *node = models->working_set.used_sentinel.next;
node != &models->working_set.used_sentinel; node != &models->working_set.used_sentinel;
node = node->next){ node = node->next){
@ -472,8 +456,8 @@ release_font_and_update_files(System_Functions *system, Models *models, Face_ID
file_set_font(system, models, file, replacement_id); file_set_font(system, models, file, replacement_id);
} }
} }
success = true;
} }
#endif
return(success); return(success);
} }
@ -1230,36 +1214,36 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
} }
internal Full_Cursor internal Full_Cursor
file_get_render_cursor(System_Functions *system, Editing_File *file, f32 scroll_y){ file_get_render_cursor(Models *models, Editing_File *file, f32 scroll_y){
Full_Cursor result = {}; Full_Cursor result = {};
if (file->settings.unwrapped_lines){ if (file->settings.unwrapped_lines){
result = file_compute_cursor_hint(system, file, seek_unwrapped_xy(0, scroll_y, false)); result = file_compute_cursor_hint(models, file, seek_unwrapped_xy(0, scroll_y, false));
} }
else{ else{
result = file_compute_cursor(system, file, seek_wrapped_xy(0, scroll_y, false)); result = file_compute_cursor(models, file, seek_wrapped_xy(0, scroll_y, false));
} }
return(result); return(result);
} }
internal Full_Cursor internal Full_Cursor
view_get_render_cursor(System_Functions *system, View *view, f32 scroll_y){ view_get_render_cursor(Models *models, View *view, f32 scroll_y){
return(file_get_render_cursor(system, view->file, scroll_y)); return(file_get_render_cursor(models, view->file, scroll_y));
} }
internal Full_Cursor internal Full_Cursor
view_get_render_cursor(System_Functions *system, View *view){ view_get_render_cursor(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
f32 scroll_y = edit_pos.scroll.scroll_y; f32 scroll_y = edit_pos.scroll.scroll_y;
//scroll_y += view->widget_height; //scroll_y += view->widget_height;
return(view_get_render_cursor(system, view, scroll_y)); return(view_get_render_cursor(models, view, scroll_y));
} }
internal Full_Cursor internal Full_Cursor
view_get_render_cursor_target(System_Functions *system, View *view){ view_get_render_cursor_target(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view); File_Edit_Positions edit_pos = view_get_edit_pos(view);
f32 scroll_y = (f32)edit_pos.scroll.target_y; f32 scroll_y = (f32)edit_pos.scroll.target_y;
//scroll_y += view->widget_height; //scroll_y += view->widget_height;
return(view_get_render_cursor(system, view, scroll_y)); return(view_get_render_cursor(models, view, scroll_y));
} }
internal void internal void

View File

@ -190,6 +190,8 @@
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#define GL_DEBUG_OUTPUT 0x92E0
//////////////////////////////// ////////////////////////////////
#define GL_FRAMEBUFFER_UNDEFINED 0x8219 #define GL_FRAMEBUFFER_UNDEFINED 0x8219

View File

@ -13,49 +13,39 @@
//#include "4ed_opengl_funcs.h" //#include "4ed_opengl_funcs.h"
#include "4ed_opengl_defines.h" #include "4ed_opengl_defines.h"
#if 0 internal void
internal GLuint gl__bind_texture(Render_Target *t, i32 texid){
gl__texture_initialize(GLint tex_width, GLint tex_height, u32 *pixels){ if (t->bound_texture != texid){
GLuint tex; glBindTexture(GL_TEXTURE_2D_ARRAY, texid);
glGenTextures(1, &tex); t->bound_texture = texid;
glBindTexture(GL_TEXTURE_2D, tex); }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, tex_width, tex_height, 0, GL_RED, GL_UNSIGNED_INT, pixels);
return(tex);
} }
#endif
internal u32 internal u32
gl__get_gpu_texture(Vec3_i32 dim, Texture_Kind texture_kind){ gl__get_texture(Vec3_i32 dim, Texture_Kind texture_kind){
u32 tex = 0; u32 tex = 0;
glGenTextures(1, &tex); glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex); glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, dim.x, dim.y, dim.z, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, dim.x, dim.y, 0, GL_RED, GL_UNSIGNED_INT, 0);
return(tex); return(tex);
} }
internal b32 internal b32
gl__fill_gpu_texture(Texture_Kind texture_kind, u32 gpu_texture, Vec3_i32 p, Vec3_i32 dim, void *data){ gl__fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void *data){
b32 result = false; b32 result = false;
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, p.x, p.y, p.z, dim.x, dim.y, dim.z, GL_RED, GL_UNSIGNED_INT, data); if (texture != 0){
return(result); glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
}
internal void
gl__draw_bind_texture(Render_Target *t, i32 texid){
if (t->bound_texture != texid){
glBindTexture(GL_TEXTURE_2D, texid);
t->bound_texture = texid;
} }
if (dim.x > 0 && dim.y > 0 && dim.z > 0){
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, p.x, p.y, p.z, dim.x, dim.y, dim.z, GL_RED, GL_UNSIGNED_BYTE, data);
}
return(result);
} }
internal void CALL_CONVENTION internal void CALL_CONVENTION
@ -71,26 +61,26 @@ uniform vec2 view_t;
uniform mat2x2 view_m; uniform mat2x2 view_m;
uniform vec4 color; uniform vec4 color;
in vec2 vertex_p; in vec2 vertex_p;
in vec2 vertex_t; in vec3 vertex_t;
smooth out vec4 fragment_color; smooth out vec4 fragment_color;
smooth out vec2 uv; smooth out vec3 uvw;
void main(void) void main(void)
{ {
gl_Position = vec4(view_m*(vertex_p - view_t), 0.f, 1.f); gl_Position = vec4(view_m*(vertex_p - view_t), 0.f, 1.f);
fragment_color = color; fragment_color = color;
uv = vertex_t; uvw = vertex_t;
} }
)foo"; )foo";
char *gl__fragment = R"foo( char *gl__fragment = R"foo(
smooth in vec4 fragment_color; smooth in vec4 fragment_color;
smooth in vec2 uv; smooth in vec3 uvw;
uniform sampler2D sampler; uniform sampler2DArray sampler;
uniform float texture_override; uniform float texture_override;
out vec4 out_color; out vec4 out_color;
void main(void) void main(void)
{ {
out_color = fragment_color*(texture(sampler, uv).r + texture_override); out_color = fragment_color*(texture(sampler, uvw).r + texture_override);
} }
)foo"; )foo";
@ -171,6 +161,8 @@ gl__make_program(char *header, char *vertex, char *fragment){
internal void internal void
gl_render(Render_Target *t, Arena *scratch){ gl_render(Render_Target *t, Arena *scratch){
Font_Set *font_set = (Font_Set*)t->font_set;
local_persist b32 first_opengl_call = true; local_persist b32 first_opengl_call = true;
local_persist u32 attribute_buffer = 0; local_persist u32 attribute_buffer = 0;
local_persist GL_Program gpu_program = {}; local_persist GL_Program gpu_program = {};
@ -179,6 +171,7 @@ gl_render(Render_Target *t, Arena *scratch){
first_opengl_call = false; first_opengl_call = false;
#if !SHIP_MODE #if !SHIP_MODE
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, true); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, true);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, true); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, true);
@ -202,7 +195,7 @@ gl_render(Render_Target *t, Arena *scratch){
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
//////////////////////////////// ////////////////////////////////
@ -229,6 +222,8 @@ gl_render(Render_Target *t, Arena *scratch){
t->free_texture_first = 0; t->free_texture_first = 0;
t->free_texture_last = 0; t->free_texture_last = 0;
i32 glyph_counter = 0;
u8 *start = (u8*)t->buffer.base; u8 *start = (u8*)t->buffer.base;
u8 *end = (u8*)t->buffer.base + t->buffer.pos; u8 *end = (u8*)t->buffer.base + t->buffer.pos;
Render_Command_Header *header = 0; Render_Command_Header *header = 0;
@ -240,7 +235,7 @@ gl_render(Render_Target *t, Arena *scratch){
case RenCom_Rectangle: case RenCom_Rectangle:
{ {
Render_Command_Rectangle *rectangle = (Render_Command_Rectangle*)header; Render_Command_Rectangle *rectangle = (Render_Command_Rectangle*)header;
gl__draw_bind_texture(t, 0); gl__bind_texture(t, 0);
Vec4 c = unpack_color4(rectangle->color); Vec4 c = unpack_color4(rectangle->color);
@ -255,7 +250,7 @@ gl_render(Render_Target *t, Arena *scratch){
0.f, -2.f/height, 0.f, -2.f/height,
}; };
glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m);
glUniform4f(gpu_program.color, c.r, c.g, c.b, c.a); glUniform4f(gpu_program.color, c.r*c.a, c.g*c.a, c.b*c.a, c.a);
glUniform1f(gpu_program.texture_override, 1.f); glUniform1f(gpu_program.texture_override, 1.f);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count);
@ -264,59 +259,27 @@ gl_render(Render_Target *t, Arena *scratch){
case RenCom_Glyph: case RenCom_Glyph:
{ {
Render_Command_Glyph *glyph = (Render_Command_Glyph*)header; #if 1
#if 0 if ((glyph_counter += 1) > 10){
Font_Pointers font = system_font_get_pointers_by_id(glyph->font_id);
if (!font.valid){
break; break;
} }
#endif #endif
Face *face = 0;
Render_Command_Glyph *glyph = (Render_Command_Glyph*)header;
Face *face = font_set_face_from_id(font_set, glyph->font_id);
if (face == 0){ if (face == 0){
break; break;
} }
u32 codepoint = glyph->codepoint; u32 codepoint = glyph->codepoint;
#if 0
u32 page_number = codepoint/GLYPHS_PER_PAGE;
Glyph_Page *page = font_cached_get_page(font.pages, page_number);
if (page == 0){
break;
}
if (!page->has_gpu_setup){
Temp_Memory temp = begin_temp(scratch);
i32 tex_width = 0;
i32 tex_height = 0;
u32 *pixels = font_load_page_pixels(scratch, font.settings, page, page_number, &tex_width, &tex_height);
page->has_gpu_setup = true;
page->gpu_tex = gl__texture_initialize(tex_width, tex_height, pixels);
end_temp(temp);
}
if (page->gpu_tex == 0){
break;
}
u32 glyph_index = codepoint%GLYPHS_PER_PAGE;
Glyph_Bounds bounds = page->glyphs[glyph_index];
GLuint tex = page->gpu_tex;
i32 tex_width = page->tex_width;
i32 tex_height = page->tex_height;
// TODO(allen): do(think about baking unit_u/unit_v into font data)
f32 unit_u = 1.f/tex_width;
f32 unit_v = 1.f/tex_height;
#else
u16 glyph_index = 0; u16 glyph_index = 0;
if (!table_read(&face->codepoint_to_index_table, codepoint, &glyph_index)){ if (!codepoint_index_map_read(&face->codepoint_to_index_map, codepoint, &glyph_index)){
glyph_index = 0; glyph_index = 0;
} }
Glyph_Bounds bounds = face->bounds[glyph_index]; Glyph_Bounds bounds = face->bounds[glyph_index];
GLuint tex = face->gpu_texture; GLuint tex = face->texture;
Vec3_f32 gpu_texture_dim = face->gpu_texture_dim; Vec3_f32 texture_dim = face->texture_dim;
#endif
f32 x = glyph->pos.x; f32 x = glyph->pos.x;
f32 y = glyph->pos.y; f32 y = glyph->pos.y;
@ -345,7 +308,7 @@ gl_render(Render_Target *t, Arena *scratch){
vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uv = V2(uv.x0, uv.y0); vertices[3].xy = V2(xy.x1, xy.y0); vertices[3].uv = V2(uv.x0, uv.y0);
} }
gl__draw_bind_texture(t, tex); gl__bind_texture(t, tex);
Vec4 c = unpack_color4(glyph->color); Vec4 c = unpack_color4(glyph->color);
@ -362,7 +325,7 @@ gl_render(Render_Target *t, Arena *scratch){
0.f, -2.f/height, 0.f, -2.f/height,
}; };
glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m);
glUniform4f(gpu_program.color, c.r, c.g, c.b, c.a); glUniform4f(gpu_program.color, c.r*c.a, c.g*c.a, c.b*c.a, c.a);
glUniform1i(gpu_program.sampler, 0); glUniform1i(gpu_program.sampler, 0);
glUniform1f(gpu_program.texture_override, 0.f); glUniform1f(gpu_program.texture_override, 0.f);

View File

@ -124,22 +124,16 @@ load_custom_code(){
} }
internal void internal void
read_command_line(i32 argc, char **argv){ read_command_line(Arena *scratch, i32 argc, char **argv){
//LOG("Reading command line\n"); Temp_Memory temp = begin_temp(scratch);
char cwd[4096]; String_Const_u8 curdir = sysfunc.get_current_path(scratch);
u32 size = sysfunc.get_current_path(cwd, sizeof(cwd));
if (size == 0 || size >= sizeof(cwd)){
system_error_box("Could not get current directory at launch.");
}
String_Const_u8 curdir = SCu8(cwd, size);
curdir = string_mod_replace_character(curdir, '\\', '/'); curdir = string_mod_replace_character(curdir, '\\', '/');
char **files = 0; char **files = 0;
i32 *file_count = 0; i32 *file_count = 0;
app.read_command_line(&sysfunc, &memory_vars, curdir, &plat_settings, &files, &file_count, argc, argv); app.read_command_line(&sysfunc, &memory_vars, curdir, &plat_settings, &files, &file_count, argc, argv);
sysshared_filter_real_files(files, file_count); sysshared_filter_real_files(files, file_count);
//LOG("Read command line.\n"); end_temp(temp);
} }
internal void internal void

View File

@ -46,18 +46,16 @@ system_load_library(Arena *scratch, Library *library, char *name_cstr, Load_Libr
name_cstr = full_name.str; name_cstr = full_name.str;
} }
umem memory_size = KB(4); String_Const_u8 path = {};
String_Const_char path = {};
path.str = push_array(scratch, char, memory_size);
switch (location){ switch (location){
case LoadLibrary_CurrentDirectory: case LoadLibrary_CurrentDirectory:
{ {
path.size = (umem)sysfunc.get_current_path(path.str, (i32)memory_size); path = sysfunc.get_current_path(scratch);
}break; }break;
case LoadLibrary_BinaryDirectory: case LoadLibrary_BinaryDirectory:
{ {
path.size = (umem)sysfunc.get_4ed_path(path.str, (i32)memory_size); path = sysfunc.get_4ed_path(scratch);
}break; }break;
//default: LOG("Invalid library location passed.\n"); break; //default: LOG("Invalid library location passed.\n"); break;
@ -66,12 +64,12 @@ system_load_library(Arena *scratch, Library *library, char *name_cstr, Load_Libr
b32 success = false; b32 success = false;
if (path.size > 0){ if (path.size > 0){
if (path.str[path.size - 1] != SLASH){ if (path.str[path.size - 1] != SLASH){
path = push_stringf(scratch, "%.*s%c%.*s", string_expand(path), SLASH, string_expand(name)); path = push_u8_stringf(scratch, "%.*s%c%.*s", string_expand(path), SLASH, string_expand(name));
} }
else{ else{
path = push_stringf(scratch, "%.*s%.*s", string_expand(path), string_expand(name)); path = push_u8_stringf(scratch, "%.*s%.*s", string_expand(path), string_expand(name));
} }
success = system_load_library_direct(library, path.str); success = system_load_library_direct(library, (char*)path.str);
if (success && full_file_out != 0 && full_file_out > 0){ if (success && full_file_out != 0 && full_file_out > 0){
u32 fill_size = clamp_top((u32)(path.size), (u32)(full_file_max - 1)); u32 fill_size = clamp_top((u32)(path.size), (u32)(full_file_max - 1));
block_copy(full_file_out, path.str, fill_size); block_copy(full_file_out, path.str, fill_size);

View File

@ -42,7 +42,8 @@
# include "4coder_default_bindings.cpp" # include "4coder_default_bindings.cpp"
#endif #endif
#include "4ed_font.h" #include "4ed_font_interface.h"
#include "4ed_font_set.h"
#include "4ed_system.h" #include "4ed_system.h"
#include "4ed_render_target.h" #include "4ed_render_target.h"
#include "4ed_render_format.h" #include "4ed_render_format.h"
@ -120,12 +121,13 @@ global System_Functions sysfunc;
#include "4ed_standard_libraries.cpp" #include "4ed_standard_libraries.cpp"
#include "4ed_coroutine.cpp" #include "4ed_coroutine.cpp"
#include "4ed_font.cpp" #include "4ed_font_face.cpp"
#include "4ed_mem.cpp" #include "4ed_mem.cpp"
#include "4coder_hash_functions.cpp" #include "4coder_hash_functions.cpp"
#include "4ed_system_allocator.cpp" #include "4ed_system_allocator.cpp"
#include "4ed_font_set.cpp"
//////////////////////////////// ////////////////////////////////
@ -2039,6 +2041,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// System Linkage // System Linkage
// //
sysfunc.font_make_face = ft__font_make_face;
sysfunc.get_texture = gl__get_texture;
sysfunc.fill_texture = gl__fill_texture;
link_system_code(); link_system_code();
// //
@ -2082,7 +2087,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// //
// Read Command Line // Read Command Line
// //
read_command_line(argc, argv); read_command_line(&shared_vars.scratch, argc, argv);
// //
// Load Custom Code // Load Custom Code
@ -2236,16 +2241,14 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// App init // App init
// //
char cwd[4096];
u32 size = sysfunc.get_current_path(cwd, sizeof(cwd));
if (size == 0 || size >= sizeof(cwd)){
system_error_box("Could not get current directory at launch.");
}
String_Const_u8 curdir = SCu8(cwd, size);
curdir = string_mod_replace_character(curdir, '\\', '/');
//LOG("Initializing application variables\n"); //LOG("Initializing application variables\n");
{
Temp_Memory temp = begin_temp(&shared_vars.scratch);
String_Const_u8 curdir = sysfunc.get_current_path(&shared_vars.scratch);
curdir = string_mod_replace_character(curdir, '\\', '/');
app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, curdir, custom_api); app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, curdir, custom_api);
end_temp(temp);
}
// //
// Main loop // Main loop

View File

@ -71,8 +71,10 @@ Sys_Memory_Free_Sig(system_memory_free){
internal internal
Sys_Get_Current_Path_Sig(system_get_current_path){ Sys_Get_Current_Path_Sig(system_get_current_path){
i32 result = GetCurrentDirectory_utf8(&shared_vars.scratch, capacity, (u8*)out); DWORD size = GetCurrentDirectory_utf8(&shared_vars.scratch, 0, 0);
return(result); u8 *out = push_array(arena, u8, size);
GetCurrentDirectory_utf8(&shared_vars.scratch, size, out);
return(SCu8(out, size - 1));
} }
internal internal
@ -88,9 +90,7 @@ Sys_Get_4ed_Path_Sig(system_get_4ed_path){
win32vars.binary_path = string_remove_last_folder(win32vars.binary_path); win32vars.binary_path = string_remove_last_folder(win32vars.binary_path);
win32vars.binary_path.str[win32vars.binary_path.size] = 0; win32vars.binary_path.str[win32vars.binary_path.size] = 0;
} }
i32 copy_size = Min((i32)(win32vars.binary_path.size), capacity); return(push_string_copy(arena, win32vars.binary_path));
block_copy(out, win32vars.binary_path.str, copy_size);
return((i32)(win32vars.binary_path.size));
} }
// //

View File

@ -166,22 +166,22 @@ internal DWORD
GetCurrentDirectory_utf8(Arena *scratch, DWORD max, u8 *buffer){ GetCurrentDirectory_utf8(Arena *scratch, DWORD max, u8 *buffer){
DWORD result = 0; DWORD result = 0;
if (buffer != 0){
Temp_Memory temp = begin_temp(scratch); Temp_Memory temp = begin_temp(scratch);
u32 buffer_16_max = KB(40); u32 buffer_16_max = KB(40);
u16 *buffer_16 = push_array(scratch, u16, buffer_16_max); u16 *buffer_16 = push_array(scratch, u16, buffer_16_max);
DWORD buffer_16_len = GetCurrentDirectoryW(buffer_16_max, (LPWSTR)buffer_16); DWORD buffer_16_len = GetCurrentDirectoryW(buffer_16_max, (LPWSTR)buffer_16);
b32 error = false; b32 error = false;
u32 buffer_8_len = (u32)utf16_to_utf8_minimal_checking(buffer, max-1, buffer_16, buffer_16_len, &error); u32 buffer_8_len = (u32)utf16_to_utf8_minimal_checking(buffer, max-1, buffer_16, buffer_16_len, &error);
if (buffer_8_len < max && !error){ if (buffer_8_len < max && !error){
buffer[buffer_8_len] = 0; buffer[buffer_8_len] = 0;
result = buffer_8_len; result = buffer_8_len;
} }
end_temp(temp); end_temp(temp);
}
else{
result = GetCurrentDirectoryW(0, 0);
}
return(result); return(result);
} }

View File

@ -39,3 +39,8 @@ list__parameters
list_query__parameters list_query__parameters
list_identifier__parameters list_identifier__parameters
list_type_definition__parameters list_type_definition__parameters
set_buffer_face_by_name -> set_buffer_face_by_font_load_location
get_existing_face_id_matching_name -> face_id_from_font_load_target
get_face_id_by_name
set_global_face_by_name -> set_buffer_face_by_font_load_location (with id = 0)