Font handling and rendering basically working.
This commit is contained in:
parent
3ddd3fc2fa
commit
6b3d61c035
|
@ -815,30 +815,22 @@ DOC_SEE(int_color)
|
|||
//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".)
|
||||
*/
|
||||
TYPEDEF u32 Face_ID;
|
||||
|
||||
/*
|
||||
DOC(Face_Description contains all the information unique to a single font face, including the font name, the size, and style of the face.)
|
||||
DOC_SEE(get_available_font)
|
||||
*/
|
||||
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 Font_Load_Location{
|
||||
String_Const_u8 file_name;
|
||||
b32 in_4coder_font_folder;
|
||||
};
|
||||
|
||||
|
||||
// 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.) */
|
||||
i32 pt_size;
|
||||
u32 pt_size;
|
||||
|
||||
/* DOC(Indicates whether the face tries to use a bold style.) */
|
||||
b32 bold;
|
||||
|
@ -853,6 +845,12 @@ STRUCT Face_Description{
|
|||
b32 hinting;
|
||||
};
|
||||
|
||||
// TODO(allen): redocument
|
||||
STRUCT Face_Description{
|
||||
Font_Load_Location font;
|
||||
Face_Load_Parameters parameters;
|
||||
};
|
||||
|
||||
STRUCT Face_Metrics{
|
||||
f32 line_height;
|
||||
f32 typical_character_width;
|
||||
|
|
|
@ -759,13 +759,6 @@ get_buffer_face_description(Application_Links *app, Buffer_Summary *buffer){
|
|||
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
|
||||
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);
|
||||
|
@ -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
|
||||
insert_string__no_buffering(Buffer_Insertion *insertion, String string){
|
||||
insert_string__no_buffering(insertion, string_new_u8_from_old(string));
|
||||
|
|
|
@ -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);
|
||||
Face_ID face_id = get_face_id(app, buffer);
|
||||
Face_Description description = get_face_description(app, face_id);
|
||||
++description.pt_size;
|
||||
++description.parameters.pt_size;
|
||||
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);
|
||||
Face_ID face_id = get_face_id(app, buffer);
|
||||
Face_Description description = get_face_description(app, face_id);
|
||||
--description.pt_size;
|
||||
--description.parameters.pt_size;
|
||||
try_modify_face(app, face_id, &description);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,8 @@ get_or_open_build_panel(Application_Links *app){
|
|||
static void
|
||||
set_fancy_compilation_buffer_font(Application_Links *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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
Face_Description description = {};
|
||||
umem len = config->default_font_name.size;
|
||||
len = clamp_top(len, sizeof(description.font.name) - 1);
|
||||
u8 *name_ptr = config->default_font_name.str;
|
||||
memcpy(description.font.name, name_ptr, len);
|
||||
description.font.name[len] = 0;
|
||||
description.font.file_name = config->default_font_name;
|
||||
description.font.in_4coder_font_folder = true;
|
||||
if (override_font_size != 0){
|
||||
description.pt_size = override_font_size;
|
||||
description.parameters.pt_size = override_font_size;
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -410,13 +410,13 @@ default_4coder_initialize(Application_Links *app, i32 override_font_size, b32 ov
|
|||
static void
|
||||
default_4coder_initialize(Application_Links *app, char **command_line_files, i32 file_count){
|
||||
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
|
||||
default_4coder_initialize(Application_Links *app){
|
||||
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
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
// TODO(allen): transition wrappers
|
||||
static Face_Description
|
||||
internal Face_Description
|
||||
get_buffer_face_description(Application_Links *app, Buffer_ID buffer){
|
||||
Face_ID current_id = get_face_id(app, buffer);
|
||||
Face_Description description = {};
|
||||
|
@ -15,31 +14,42 @@ get_buffer_face_description(Application_Links *app, Buffer_ID buffer){
|
|||
return(description);
|
||||
}
|
||||
|
||||
static Face_Description
|
||||
internal Face_Description
|
||||
get_global_face_description(Application_Links *app){
|
||||
Face_ID current_id = get_face_id(app, 0);
|
||||
Face_Description description = get_face_description(app, current_id);
|
||||
return(description);
|
||||
return(get_buffer_face_description(app, 0));
|
||||
}
|
||||
|
||||
static b32
|
||||
descriptions_match(Face_Description *a, Face_Description *b){
|
||||
internal b32
|
||||
font_load_location_match(Font_Load_Location *a, Font_Load_Location *b){
|
||||
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 (memcmp((&a->pt_size), (&b->pt_size), sizeof(*a) - sizeof(a->font)) == 0){
|
||||
result = true;
|
||||
}
|
||||
if (string_match(a->file_name, b->file_name) && a->in_4coder_font_folder == b->in_4coder_font_folder){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Face_ID
|
||||
get_existing_face_id_matching_name(Application_Links *app, String_Const_u8 name){
|
||||
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);
|
||||
}
|
||||
|
||||
internal Face_ID
|
||||
face_id_from_font_load_target(Application_Links *app, Font_Load_Location *font){
|
||||
Face_ID largest_id = get_largest_face_id(app);
|
||||
Face_ID result = 0;
|
||||
for (Face_ID id = 1; id <= largest_id; ++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;
|
||||
break;
|
||||
}
|
||||
|
@ -47,13 +57,13 @@ get_existing_face_id_matching_name(Application_Links *app, String_Const_u8 name)
|
|||
return(result);
|
||||
}
|
||||
|
||||
static Face_ID
|
||||
get_existing_face_id_matching_description(Application_Links *app, Face_Description *description){
|
||||
internal Face_ID
|
||||
face_id_from_face_load_parameters(Application_Links *app, Face_Load_Parameters *parameters){
|
||||
Face_ID largest_id = get_largest_face_id(app);
|
||||
Face_ID result = 0;
|
||||
for (Face_ID id = 1; id <= largest_id; ++id){
|
||||
Face_Description compare = get_face_description(app, id);
|
||||
if (descriptions_match(&compare, description)){
|
||||
if (face_load_parameters_match(&compare.parameters, parameters)){
|
||||
result = id;
|
||||
break;
|
||||
}
|
||||
|
@ -61,68 +71,49 @@ get_existing_face_id_matching_description(Application_Links *app, Face_Descripti
|
|||
return(result);
|
||||
}
|
||||
|
||||
static Face_ID
|
||||
get_face_id_by_name(Application_Links *app, String_Const_u8 name, Face_Description *base_description){
|
||||
Face_ID new_id = 0;
|
||||
name.size = clamp_top(name.size, sizeof(base_description->font.name) - 1);
|
||||
if (!string_match(name, SCu8(base_description->font.name))){
|
||||
new_id = get_existing_face_id_matching_name(app, name);
|
||||
if (new_id == 0){
|
||||
Face_Description description = *base_description;
|
||||
block_copy(description.font.name, name.str, name.size);
|
||||
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);
|
||||
}
|
||||
internal Face_ID
|
||||
face_id_from_description(Application_Links *app, Face_Description *description){
|
||||
Face_ID largest_id = get_largest_face_id(app);
|
||||
Face_ID result = 0;
|
||||
for (Face_ID id = 1; id <= largest_id; ++id){
|
||||
Face_Description compare = get_face_description(app, id);
|
||||
if (face_description_match(&compare, description)){
|
||||
result = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(new_id);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static Face_ID
|
||||
get_face_id_by_description(Application_Links *app, Face_Description *description, Face_Description *base_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){
|
||||
internal b32
|
||||
modify_global_face_by_description(Application_Links *app, Face_Description description){
|
||||
Face_ID face_id = get_face_id(app, 0);
|
||||
if (!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);
|
||||
return(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
|
||||
set_buffer_face_by_name(Application_Links *app, Buffer_ID buffer, String_Const_u8 name){
|
||||
Face_ID current_id = get_face_id(app, buffer);
|
||||
if (current_id != 0){
|
||||
Face_Description description = get_face_description(app, current_id);
|
||||
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_font_load_location(Application_Links *app, Buffer_ID buffer, Font_Load_Location *font){
|
||||
Face_Description description = get_buffer_face_description(app, buffer);
|
||||
description.font = *font;
|
||||
set_buffer_face_by_description(app, buffer, &description);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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_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 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_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)
|
||||
|
@ -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_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 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_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));}
|
||||
|
@ -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_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 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_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));}
|
||||
|
|
|
@ -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_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_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(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(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(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, 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, 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(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 },
|
||||
|
|
119
4ed.cpp
119
4ed.cpp
|
@ -71,7 +71,7 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
|
|||
if (view->file != file){
|
||||
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->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
|
||||
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
|
||||
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
|
||||
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){
|
||||
Cursor cursor = make_cursor(memory->vars_memory, memory->vars_memory_size);
|
||||
App_Vars *vars = push_array_zero(&cursor, App_Vars, 1);
|
||||
vars->models.allocator = make_base_allocator_system(system);
|
||||
vars->models.mem.arena = make_arena(&vars->models.allocator);
|
||||
vars->models.mem.arena = make_arena_system(system);
|
||||
vars->models.base_allocator = vars->models.mem.arena.base_allocator;
|
||||
heap_init(&vars->models.mem.heap);
|
||||
heap_extend(&vars->models.mem.heap, memory->target_memory, memory->target_memory_size);
|
||||
return(vars);
|
||||
|
@ -862,6 +834,9 @@ App_Init_Sig(app_init){
|
|||
|
||||
Arena *arena = &models->mem.arena;
|
||||
|
||||
// NOTE(allen): font set
|
||||
font_set_init(system, &models->font_set);
|
||||
|
||||
// NOTE(allen): live set
|
||||
{
|
||||
models->live_set.count = 0;
|
||||
|
@ -923,7 +898,13 @@ App_Init_Sig(app_init){
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// NOTE(allen): title space
|
||||
|
@ -986,7 +967,7 @@ App_Step_Sig(app_step){
|
|||
models->animate_next_frame = false;
|
||||
|
||||
// NOTE(allen): per-frame update of models state
|
||||
begin_frame(target);
|
||||
begin_frame(target, &models->font_set);
|
||||
models->target = target;
|
||||
models->input = input;
|
||||
|
||||
|
@ -1190,30 +1171,6 @@ App_Step_Sig(app_step){
|
|||
|
||||
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
|
||||
|
@ -1507,48 +1464,6 @@ App_Step_Sig(app_step){
|
|||
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;
|
||||
end_render_section(target, system);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ Context_Get_Arena(Application_Links *app){
|
|||
API_EXPORT Base_Allocator*
|
||||
Context_Get_Base_Allocator(Application_Links *app){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
return(&models->allocator);
|
||||
return(models->base_allocator);
|
||||
}
|
||||
|
||||
API_EXPORT b32
|
||||
|
@ -775,10 +775,7 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
new_value = 48;
|
||||
}
|
||||
if (new_value != file->settings.display_width){
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
file->settings.display_width = new_value;
|
||||
file_measure_wraps(system, &models->mem, file, face);
|
||||
adjust_views_looking_at_file_to_new_cursor(system, models, file);
|
||||
|
@ -792,10 +789,7 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
new_value = 0;
|
||||
}
|
||||
if (new_value != file->settings.minimum_base_display_width){
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
file->settings.minimum_base_display_width = new_value;
|
||||
file_measure_wraps(system, &models->mem, file, face);
|
||||
adjust_views_looking_at_file_to_new_cursor(system, models, file);
|
||||
|
@ -873,11 +867,7 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
}
|
||||
|
||||
if (full_remeasure){
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
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);
|
||||
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){
|
||||
vptrs[vptr_count] = 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;
|
||||
column_numbers[vptr_count] = (i32)cursor.character;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1778,7 +1768,7 @@ DOC_SEE(Full_Cursor)
|
|||
if (file->settings.unwrapped_lines && seek.type == buffer_seek_wrapped_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){
|
||||
result.wrapped_x = result.unwrapped_x;
|
||||
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){
|
||||
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);
|
||||
result = true;
|
||||
}
|
||||
|
@ -1864,7 +1854,7 @@ DOC_SEE(Buffer_Seek)
|
|||
Assert(file != 0);
|
||||
if (api_check_buffer(file)){
|
||||
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;
|
||||
}
|
||||
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;
|
||||
Face_ID result = 0;
|
||||
#if 0
|
||||
Face_ID result = models->system->font.get_largest_id();
|
||||
#endif
|
||||
NotImplemented;
|
||||
return(result);
|
||||
return(font_set_get_largest_id(&models->font_set));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
b32 did_change = false;
|
||||
|
||||
NotImplemented;
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(id);
|
||||
if (font.valid){
|
||||
did_change = true;
|
||||
|
||||
Face *face = font_set_face_from_id(&models->font_set, id);
|
||||
if (face != 0){
|
||||
if (apply_to_all_buffers){
|
||||
global_set_font_and_update_files(system, models, id);
|
||||
}
|
||||
else{
|
||||
models->global_font_id = id;
|
||||
}
|
||||
did_change = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
if (api_check_buffer(file)){
|
||||
System_Functions *system = models->system;
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(id);
|
||||
if (font.valid){
|
||||
if (font_set_face_from_id(&models->font_set, id) != 0){
|
||||
did_change = true;
|
||||
file_set_font(system, models, file, id);
|
||||
}
|
||||
#endif
|
||||
Face *face = 0;
|
||||
if (face != 0){
|
||||
did_change = true;
|
||||
file_set_font(system, models, file, id);
|
||||
file_set_font(models->system, models, file, id);
|
||||
}
|
||||
}
|
||||
return(did_change);
|
||||
}
|
||||
|
||||
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(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;
|
||||
System_Functions *system = models->system;
|
||||
Face_Description description = {};
|
||||
if (id != 0){
|
||||
#if 0
|
||||
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_id != 0){
|
||||
Face *face = font_set_face_from_id(&models->font_set, face_id);
|
||||
if (face != 0){
|
||||
face_to_face_description(face, &description);
|
||||
Assert(description.font.name[0] != 0);
|
||||
description = face->description;
|
||||
}
|
||||
}
|
||||
else{
|
||||
description.pt_size = models->settings.font_size;
|
||||
description.hinting = models->settings.use_hinting;
|
||||
description.parameters.pt_size = models->settings.font_size;
|
||||
description.parameters.hinting = models->settings.use_hinting;
|
||||
}
|
||||
return(description);
|
||||
}
|
||||
|
@ -3282,17 +3183,10 @@ Get_Face_Metrics(Application_Links *app, Face_ID face_id){
|
|||
System_Functions *system = models->system;
|
||||
Face_Metrics result = {};
|
||||
if (face_id != 0){
|
||||
#if 0
|
||||
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;
|
||||
Face *face = font_set_face_from_id(&models->font_set, face_id);
|
||||
if (face != 0){
|
||||
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);
|
||||
|
@ -3339,16 +3233,7 @@ DOC_SEE(Face_Description)
|
|||
*/
|
||||
{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
System_Functions *system = models->system;
|
||||
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);
|
||||
return(font_set_new_face(&models->font_set, description));
|
||||
}
|
||||
|
||||
API_EXPORT b32
|
||||
|
@ -3366,15 +3251,7 @@ DOC_SEE(try_create_new_face)
|
|||
*/
|
||||
{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
System_Functions *system = models->system;
|
||||
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);
|
||||
return(alter_font_and_update_files(models->system, models, id, description));
|
||||
}
|
||||
|
||||
API_EXPORT b32
|
||||
|
@ -3586,11 +3463,7 @@ DOC_RETURN(This call returns non-zero on success.)
|
|||
*/{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
System_Functions *system = models->system;
|
||||
// TODO(allen): rewrite this with a better OS layer API
|
||||
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));
|
||||
return(system->get_4ed_path(arena));
|
||||
}
|
||||
|
||||
// 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;
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
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;
|
||||
}
|
||||
else{
|
||||
Color_Table color_table = models->color_table;
|
||||
point = draw_helper__models_space_to_screen_space(models, point);
|
||||
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;
|
||||
}
|
||||
return(result);
|
||||
|
@ -3766,7 +3639,7 @@ API_EXPORT f32
|
|||
Get_String_Advance(Application_Links *app, Face_ID font_id, String_Const_u8 str)
|
||||
{
|
||||
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
|
||||
|
@ -3849,7 +3722,7 @@ Text_Layout_Buffer_Point_To_Layout_Point(Application_Links *app, Text_Layout_ID
|
|||
if (api_check_buffer(file)){
|
||||
System_Functions *system = models->system;
|
||||
// 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;
|
||||
if (file->settings.unwrapped_lines){
|
||||
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)){
|
||||
System_Functions *system = models->system;
|
||||
// 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;
|
||||
if (file->settings.unwrapped_lines){
|
||||
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;
|
||||
Face_ID font_id = file->settings.font_id;
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, font_id);
|
||||
|
||||
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_y = intermediate_cursor.wrapped_y;
|
||||
if (file->settings.unwrapped_lines){
|
||||
scroll_y = intermediate_cursor.unwrapped_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 end_pos = 0;
|
||||
|
@ -4119,7 +3989,7 @@ Get_View_Visible_Range(Application_Links *app, View_ID view_id){
|
|||
if (api_check_view(view)){
|
||||
i32 view_height = rect_height(view->panel->rect_inner);
|
||||
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);
|
||||
Full_Cursor max_cursor = view_compute_cursor(app, view_id, seek);
|
||||
result = Ii32((i32)min_cursor.pos, (i32)max_cursor.pos);
|
||||
|
|
|
@ -28,7 +28,7 @@ struct App_Settings{
|
|||
};
|
||||
|
||||
struct Models{
|
||||
Base_Allocator allocator;
|
||||
Base_Allocator *base_allocator;
|
||||
Mem_Options mem;
|
||||
|
||||
App_Settings settings;
|
||||
|
@ -72,6 +72,7 @@ struct Models{
|
|||
Parse_Context_Memory parse_context_memory;
|
||||
Global_History global_history;
|
||||
Text_Layout_Container text_layouts;
|
||||
Font_Set font_set;
|
||||
|
||||
Dynamic_Variable_Layout variable_layout;
|
||||
Dynamic_Workspace dynamic_workspace;
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
|
||||
#include "4coder_base_types.h"
|
||||
#include "4coder_table.h"
|
||||
#include "4ed_font.h"
|
||||
#include "4ed_font_interface.h"
|
||||
#include "4ed_system.h"
|
||||
|
||||
#include "4coder_base_types.cpp"
|
||||
#include "4coder_string_match.cpp"
|
||||
#include "4coder_stringf.cpp"
|
||||
#include "4coder_app_links_allocator.cpp"
|
||||
#include "4ed_system_allocator.cpp"
|
||||
#include "4coder_hash_functions.cpp"
|
||||
#include "4coder_table.cpp"
|
||||
|
||||
|
@ -68,6 +69,7 @@ struct Mem_Options{
|
|||
#include "4ed_view.h"
|
||||
#include "4ed_edit.h"
|
||||
#include "4ed_text_layout.h"
|
||||
#include "4ed_font_set.h"
|
||||
#include "4ed_app_models.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
|
@ -75,7 +77,8 @@ struct Mem_Options{
|
|||
#include "4ed_memory_bank.cpp"
|
||||
#include "4ed_dynamic_variables.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_render_target.cpp"
|
||||
#include "4ed_render_format.cpp"
|
||||
|
|
|
@ -705,7 +705,7 @@ buffer_measure_character_starts(System_Functions *system, Gap_Buffer *buffer, i3
|
|||
for (; i < stream.end; ++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)){
|
||||
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;
|
||||
}
|
||||
|
||||
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)){
|
||||
|
@ -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){
|
||||
if (!S.skipping_whitespace){
|
||||
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{
|
||||
S.current_adv = params.face->byte_advance;
|
||||
|
@ -990,7 +990,7 @@ buffer_remeasure_character_starts(System_Functions *system, Gap_Buffer *buffer,
|
|||
do{
|
||||
for (; char_i < stream.end; ++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)){
|
||||
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){
|
||||
{
|
||||
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)){
|
||||
|
@ -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){
|
||||
|
||||
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{
|
||||
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,
|
||||
Render_Item_Flag render_flags){
|
||||
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);
|
||||
|
||||
|
@ -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){
|
||||
{
|
||||
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)){
|
||||
|
@ -1814,7 +1814,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32
|
|||
|
||||
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;
|
||||
S.write = write_render_item(S.write, I, ' ', 0, flags);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// TOP
|
||||
|
||||
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_ptr = state->token_array.tokens;
|
||||
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->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->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];
|
||||
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)){
|
||||
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;
|
||||
f32 adv = 0;
|
||||
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'){
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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){
|
||||
{
|
||||
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)){
|
||||
|
@ -545,7 +545,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
|
|||
word_stage = 1;
|
||||
}
|
||||
else{
|
||||
f32 adv = font_get_glyph_advance(params.system, params.face, codepoint);
|
||||
f32 adv = font_get_glyph_advance(params.face, codepoint);
|
||||
|
||||
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){
|
||||
{
|
||||
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)){
|
||||
|
@ -680,7 +680,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
|
|||
for (; i < stream.end; ++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)){
|
||||
|
@ -690,7 +690,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
|
|||
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;
|
||||
|
||||
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){
|
||||
{
|
||||
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)){
|
||||
|
@ -726,7 +726,7 @@ file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *fil
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
21
4ed_edit.cpp
21
4ed_edit.cpp
|
@ -10,7 +10,8 @@
|
|||
// TOP
|
||||
|
||||
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){
|
||||
system->cancel_job(BACKGROUND_THREADS, file->state.lex_job);
|
||||
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)){
|
||||
View *view = panel->view;
|
||||
if (view->file == file){
|
||||
Full_Cursor render_cursor = view_get_render_cursor(system, view);
|
||||
Full_Cursor target_cursor = view_get_render_cursor_target(system, view);
|
||||
Full_Cursor render_cursor = view_get_render_cursor(models, 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_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;
|
||||
if (view->file == file){
|
||||
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);
|
||||
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;
|
||||
f32 new_y_val_aligned = 0;
|
||||
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){
|
||||
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 (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){
|
||||
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????
|
||||
edit_pre_state_change(system, heap, models, file);
|
||||
edit_pre_state_change(models, heap, file);
|
||||
|
||||
// NOTE(allen): edit range hook
|
||||
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
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
Assert(font.valid);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
Assert(face != 0);
|
||||
|
||||
file_measure_wraps(system, &models->mem, file, face);
|
||||
|
|
23
4ed_file.cpp
23
4ed_file.cpp
|
@ -237,12 +237,9 @@ file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek){
|
|||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor__inner(System_Functions *system, Editing_File *file, Buffer_Seek seek, b32 return_hint){
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
Assert(font.valid);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
file_compute_cursor__inner(Models *models, Editing_File *file, Buffer_Seek seek, b32 return_hint){
|
||||
System_Functions *system = models->system;
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
Assert(face != 0);
|
||||
|
||||
Full_Cursor result = {};
|
||||
|
@ -314,13 +311,13 @@ file_compute_cursor__inner(System_Functions *system, Editing_File *file, Buffer_
|
|||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek seek){
|
||||
return(file_compute_cursor__inner(system, file, seek, false));
|
||||
file_compute_cursor(Models *models, Editing_File *file, Buffer_Seek seek){
|
||||
return(file_compute_cursor__inner(models, file, seek, false));
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor_hint(System_Functions *system, Editing_File *file, Buffer_Seek seek){
|
||||
return(file_compute_cursor__inner(system, file, seek, true));
|
||||
file_compute_cursor_hint(Models *models, Editing_File *file, Buffer_Seek seek){
|
||||
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;
|
||||
file->settings.font_id = font_id;
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
Assert(font.valid);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, font_id);
|
||||
Assert(face != 0);
|
||||
|
||||
file_measure_starts(heap, &file->state.buffer);
|
||||
|
|
230
4ed_font.cpp
230
4ed_font.cpp
|
@ -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
|
||||
|
87
4ed_font.h
87
4ed_font.h
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
@ -22,107 +22,6 @@ struct FT_Codepoint_Index_Pair_Array{
|
|||
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
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -26,8 +26,9 @@ draw_change_clip(Render_Target *target, i32_Rect clip_box){
|
|||
}
|
||||
|
||||
internal void
|
||||
begin_frame(Render_Target *target){
|
||||
begin_frame(Render_Target *target, void *font_set){
|
||||
target->buffer.pos = 0;
|
||||
target->font_set = font_set;
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -139,19 +140,16 @@ snap_point_to_boundary(Vec2 point){
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
|
||||
if (face != 0){
|
||||
point = snap_point_to_boundary(point);
|
||||
|
||||
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_end = str + string.size;
|
||||
|
@ -160,7 +158,7 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
|
|||
Translation_Emits emits = {};
|
||||
|
||||
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)){
|
||||
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){
|
||||
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;
|
||||
total_delta += d;
|
||||
}
|
||||
|
@ -183,7 +181,7 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
|
|||
Vec2 pp = point;
|
||||
for (u32 j = 0; j < 3; ++j){
|
||||
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;
|
||||
|
@ -197,30 +195,30 @@ draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, St
|
|||
}
|
||||
|
||||
internal f32
|
||||
draw_string(System_Functions *system, 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)));
|
||||
draw_string(Render_Target *target, Face_ID font_id, String_Const_u8 string, Vec2 point, u32 color){
|
||||
return(draw_string(target, font_id, string, point, color, 0, V2(1.f, 0.f)));
|
||||
}
|
||||
|
||||
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){
|
||||
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
|
||||
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){
|
||||
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
|
||||
font_string_width(System_Functions *system, 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)));
|
||||
font_string_width(Render_Target *target, Face_ID font_id, String_Const_u8 str){
|
||||
return(draw_string(target, font_id, str, V2(0, 0), 0, 0, V2(0, 0)));
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(System_Functions *system, 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)));
|
||||
font_string_width(Render_Target *target, Face_ID font_id, u8 *str){
|
||||
return(draw_string(target, font_id, SCu8(str), V2(0, 0), 0, 0, V2(0, 0)));
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -36,6 +36,8 @@ struct Render_Target{
|
|||
|
||||
// TODO(allen): rewrite render system to work on an arena
|
||||
Cursor buffer;
|
||||
|
||||
void *font_set;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -208,10 +208,10 @@ typedef Sys_Memory_Set_Protection_Sig(System_Memory_Set_Protection);
|
|||
typedef Sys_Memory_Free_Sig(System_Memory_Free);
|
||||
|
||||
// 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);
|
||||
|
||||
#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);
|
||||
|
||||
// behavior and appearance options
|
||||
|
@ -226,6 +226,8 @@ typedef Sys_Is_Fullscreen_Sig(System_Is_Fullscreen);
|
|||
|
||||
struct System_Functions{
|
||||
Font_Make_Face_Function *font_make_face;
|
||||
Graphics_Get_Texture_Function *get_texture;
|
||||
Graphics_Fill_Texture_Function *fill_texture;
|
||||
|
||||
// files (tracked api): 11
|
||||
System_Set_File_List *set_file_list;
|
||||
|
|
|
@ -98,7 +98,7 @@ translating_select_emit_rule_ASCII(Translation_State *tran, Translation_Byte_Des
|
|||
}
|
||||
|
||||
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->last_byte_handler = desc.last_byte_handler;
|
||||
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
|
||||
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 = {};
|
||||
translating_consume_byte(tran, ch, i, size, &description);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
88
4ed_view.cpp
88
4ed_view.cpp
|
@ -117,9 +117,9 @@ view_height(Models *models, View *view){
|
|||
}
|
||||
|
||||
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);
|
||||
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 = {};
|
||||
if (view->file->settings.unwrapped_lines){
|
||||
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
|
||||
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;
|
||||
i32 max_x = (i32)view_width(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;
|
||||
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
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
result = true;
|
||||
}
|
||||
|
@ -270,9 +272,9 @@ view_set_preferred_x(View *view, Full_Cursor cursor){
|
|||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -285,7 +287,7 @@ view_set_cursor(System_Functions *system, Models *models, View *view, Full_Curso
|
|||
}
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
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;
|
||||
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));
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
i32 pos = (i32)edit_pos.cursor_pos;
|
||||
if (view_move_cursor_to_view(system, models, view, edit_pos.scroll, &pos, view->preferred_x)){
|
||||
Full_Cursor cursor = file_compute_cursor(system, view->file, seek_pos(pos));
|
||||
if (view_move_cursor_to_view(models, view, edit_pos.scroll, &pos, view->preferred_x)){
|
||||
Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(pos));
|
||||
edit_pos.cursor_pos = cursor.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);
|
||||
view_set_edit_pos(view, edit_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
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
|
||||
Assert(face != 0);
|
||||
|
||||
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;
|
||||
if (view->file == file){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -391,10 +390,7 @@ adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *mod
|
|||
internal void
|
||||
file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){
|
||||
Face_ID font_id = file->settings.font_id;
|
||||
#if 0
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
#endif
|
||||
Face *face = 0;
|
||||
Face *face = font_set_face_from_id(&models->font_set, font_id);
|
||||
file_measure_wraps(system, &models->mem, file, face);
|
||||
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
|
||||
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;
|
||||
NotImplemented;
|
||||
#if 0
|
||||
if (system->font.face_change_settings(font_id, new_settings)){
|
||||
if (font_set_modify_face(&models->font_set, face_id, new_description)){
|
||||
success = true;
|
||||
for (Node *node = models->working_set.used_sentinel.next;
|
||||
node != &models->working_set.used_sentinel;
|
||||
node = node->next){
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return(success);
|
||||
}
|
||||
|
||||
internal b32
|
||||
release_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id, Face_ID replacement_id){
|
||||
b32 success = false;
|
||||
NotImplemented;
|
||||
#if 0
|
||||
if (system->font.face_release(font_id)){
|
||||
Font_Pointers font = system->font.get_pointers_by_id(replacement_id);
|
||||
if (!font.valid){
|
||||
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);
|
||||
if (font_set_release_face(&models->font_set, font_id)){
|
||||
Face *face = font_set_face_from_id(&models->font_set, replacement_id);
|
||||
if (face == 0){
|
||||
replacement_id = font_set_get_fallback_face(&models->font_set);
|
||||
Assert(font_set_face_from_id(&models->font_set, replacement_id) != 0);
|
||||
}
|
||||
success = true;
|
||||
for (Node *node = models->working_set.used_sentinel.next;
|
||||
node != &models->working_set.used_sentinel;
|
||||
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);
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
#endif
|
||||
return(success);
|
||||
}
|
||||
|
||||
|
@ -1230,36 +1214,36 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
|
|||
}
|
||||
|
||||
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 = {};
|
||||
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{
|
||||
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);
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
view_get_render_cursor(System_Functions *system, View *view, f32 scroll_y){
|
||||
return(file_get_render_cursor(system, view->file, scroll_y));
|
||||
view_get_render_cursor(Models *models, View *view, f32 scroll_y){
|
||||
return(file_get_render_cursor(models, view->file, scroll_y));
|
||||
}
|
||||
|
||||
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);
|
||||
f32 scroll_y = edit_pos.scroll.scroll_y;
|
||||
//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
|
||||
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);
|
||||
f32 scroll_y = (f32)edit_pos.scroll.target_y;
|
||||
//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
|
||||
|
|
|
@ -190,6 +190,8 @@
|
|||
|
||||
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
|
||||
|
||||
#define GL_DEBUG_OUTPUT 0x92E0
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
|
||||
|
|
|
@ -13,49 +13,39 @@
|
|||
//#include "4ed_opengl_funcs.h"
|
||||
#include "4ed_opengl_defines.h"
|
||||
|
||||
#if 0
|
||||
internal GLuint
|
||||
gl__texture_initialize(GLint tex_width, GLint tex_height, u32 *pixels){
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
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);
|
||||
internal void
|
||||
gl__bind_texture(Render_Target *t, i32 texid){
|
||||
if (t->bound_texture != texid){
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texid);
|
||||
t->bound_texture = texid;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
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_T, GL_CLAMP_TO_EDGE);
|
||||
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_MAX_LEVEL, 0);
|
||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, dim.x, dim.y, 0, GL_RED, GL_UNSIGNED_INT, 0);
|
||||
return(tex);
|
||||
}
|
||||
|
||||
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;
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, p.x, p.y, p.z, dim.x, dim.y, dim.z, GL_RED, GL_UNSIGNED_INT, data);
|
||||
return(result);
|
||||
}
|
||||
|
||||
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 (texture != 0){
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
|
||||
}
|
||||
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
|
||||
|
@ -71,26 +61,26 @@ uniform vec2 view_t;
|
|||
uniform mat2x2 view_m;
|
||||
uniform vec4 color;
|
||||
in vec2 vertex_p;
|
||||
in vec2 vertex_t;
|
||||
in vec3 vertex_t;
|
||||
smooth out vec4 fragment_color;
|
||||
smooth out vec2 uv;
|
||||
smooth out vec3 uvw;
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = vec4(view_m*(vertex_p - view_t), 0.f, 1.f);
|
||||
fragment_color = color;
|
||||
uv = vertex_t;
|
||||
uvw = vertex_t;
|
||||
}
|
||||
)foo";
|
||||
|
||||
char *gl__fragment = R"foo(
|
||||
smooth in vec4 fragment_color;
|
||||
smooth in vec2 uv;
|
||||
uniform sampler2D sampler;
|
||||
smooth in vec3 uvw;
|
||||
uniform sampler2DArray sampler;
|
||||
uniform float texture_override;
|
||||
out vec4 out_color;
|
||||
void main(void)
|
||||
{
|
||||
out_color = fragment_color*(texture(sampler, uv).r + texture_override);
|
||||
out_color = fragment_color*(texture(sampler, uvw).r + texture_override);
|
||||
}
|
||||
)foo";
|
||||
|
||||
|
@ -171,6 +161,8 @@ gl__make_program(char *header, char *vertex, char *fragment){
|
|||
|
||||
internal void
|
||||
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 u32 attribute_buffer = 0;
|
||||
local_persist GL_Program gpu_program = {};
|
||||
|
@ -179,6 +171,7 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
first_opengl_call = false;
|
||||
|
||||
#if !SHIP_MODE
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
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_LOW, 0, 0, true);
|
||||
|
@ -202,7 +195,7 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
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_last = 0;
|
||||
|
||||
i32 glyph_counter = 0;
|
||||
|
||||
u8 *start = (u8*)t->buffer.base;
|
||||
u8 *end = (u8*)t->buffer.base + t->buffer.pos;
|
||||
Render_Command_Header *header = 0;
|
||||
|
@ -240,7 +235,7 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
case RenCom_Rectangle:
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -255,7 +250,7 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
0.f, -2.f/height,
|
||||
};
|
||||
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);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count);
|
||||
|
@ -264,59 +259,27 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
|
||||
case RenCom_Glyph:
|
||||
{
|
||||
Render_Command_Glyph *glyph = (Render_Command_Glyph*)header;
|
||||
#if 0
|
||||
Font_Pointers font = system_font_get_pointers_by_id(glyph->font_id);
|
||||
if (!font.valid){
|
||||
#if 1
|
||||
if ((glyph_counter += 1) > 10){
|
||||
break;
|
||||
}
|
||||
#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){
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
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_Bounds bounds = face->bounds[glyph_index];
|
||||
GLuint tex = face->gpu_texture;
|
||||
Vec3_f32 gpu_texture_dim = face->gpu_texture_dim;
|
||||
#endif
|
||||
GLuint tex = face->texture;
|
||||
Vec3_f32 texture_dim = face->texture_dim;
|
||||
|
||||
f32 x = glyph->pos.x;
|
||||
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);
|
||||
}
|
||||
|
||||
gl__draw_bind_texture(t, tex);
|
||||
gl__bind_texture(t, tex);
|
||||
|
||||
Vec4 c = unpack_color4(glyph->color);
|
||||
|
||||
|
@ -362,7 +325,7 @@ gl_render(Render_Target *t, Arena *scratch){
|
|||
0.f, -2.f/height,
|
||||
};
|
||||
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);
|
||||
glUniform1f(gpu_program.texture_override, 0.f);
|
||||
|
|
|
@ -124,22 +124,16 @@ load_custom_code(){
|
|||
}
|
||||
|
||||
internal void
|
||||
read_command_line(i32 argc, char **argv){
|
||||
//LOG("Reading command line\n");
|
||||
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);
|
||||
read_command_line(Arena *scratch, i32 argc, char **argv){
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
String_Const_u8 curdir = sysfunc.get_current_path(scratch);
|
||||
curdir = string_mod_replace_character(curdir, '\\', '/');
|
||||
|
||||
char **files = 0;
|
||||
i32 *file_count = 0;
|
||||
app.read_command_line(&sysfunc, &memory_vars, curdir, &plat_settings, &files, &file_count, argc, argv);
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
//LOG("Read command line.\n");
|
||||
end_temp(temp);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
|
|
@ -46,18 +46,16 @@ system_load_library(Arena *scratch, Library *library, char *name_cstr, Load_Libr
|
|||
name_cstr = full_name.str;
|
||||
}
|
||||
|
||||
umem memory_size = KB(4);
|
||||
String_Const_char path = {};
|
||||
path.str = push_array(scratch, char, memory_size);
|
||||
String_Const_u8 path = {};
|
||||
switch (location){
|
||||
case LoadLibrary_CurrentDirectory:
|
||||
{
|
||||
path.size = (umem)sysfunc.get_current_path(path.str, (i32)memory_size);
|
||||
path = sysfunc.get_current_path(scratch);
|
||||
}break;
|
||||
|
||||
case LoadLibrary_BinaryDirectory:
|
||||
{
|
||||
path.size = (umem)sysfunc.get_4ed_path(path.str, (i32)memory_size);
|
||||
path = sysfunc.get_4ed_path(scratch);
|
||||
}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;
|
||||
if (path.size > 0){
|
||||
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{
|
||||
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){
|
||||
u32 fill_size = clamp_top((u32)(path.size), (u32)(full_file_max - 1));
|
||||
block_copy(full_file_out, path.str, fill_size);
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
# include "4coder_default_bindings.cpp"
|
||||
#endif
|
||||
|
||||
#include "4ed_font.h"
|
||||
#include "4ed_font_interface.h"
|
||||
#include "4ed_font_set.h"
|
||||
#include "4ed_system.h"
|
||||
#include "4ed_render_target.h"
|
||||
#include "4ed_render_format.h"
|
||||
|
@ -120,12 +121,13 @@ global System_Functions sysfunc;
|
|||
|
||||
#include "4ed_standard_libraries.cpp"
|
||||
#include "4ed_coroutine.cpp"
|
||||
#include "4ed_font.cpp"
|
||||
#include "4ed_font_face.cpp"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
#include "4coder_hash_functions.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
|
||||
//
|
||||
|
||||
sysfunc.font_make_face = ft__font_make_face;
|
||||
sysfunc.get_texture = gl__get_texture;
|
||||
sysfunc.fill_texture = gl__fill_texture;
|
||||
link_system_code();
|
||||
|
||||
//
|
||||
|
@ -2082,7 +2087,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
//
|
||||
// Read Command Line
|
||||
//
|
||||
read_command_line(argc, argv);
|
||||
read_command_line(&shared_vars.scratch, argc, argv);
|
||||
|
||||
//
|
||||
// Load Custom Code
|
||||
|
@ -2236,16 +2241,14 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
// 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");
|
||||
app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, curdir, custom_api);
|
||||
{
|
||||
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);
|
||||
end_temp(temp);
|
||||
}
|
||||
|
||||
//
|
||||
// Main loop
|
||||
|
|
|
@ -71,8 +71,10 @@ Sys_Memory_Free_Sig(system_memory_free){
|
|||
|
||||
internal
|
||||
Sys_Get_Current_Path_Sig(system_get_current_path){
|
||||
i32 result = GetCurrentDirectory_utf8(&shared_vars.scratch, capacity, (u8*)out);
|
||||
return(result);
|
||||
DWORD size = GetCurrentDirectory_utf8(&shared_vars.scratch, 0, 0);
|
||||
u8 *out = push_array(arena, u8, size);
|
||||
GetCurrentDirectory_utf8(&shared_vars.scratch, size, out);
|
||||
return(SCu8(out, size - 1));
|
||||
}
|
||||
|
||||
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.str[win32vars.binary_path.size] = 0;
|
||||
}
|
||||
i32 copy_size = Min((i32)(win32vars.binary_path.size), capacity);
|
||||
block_copy(out, win32vars.binary_path.str, copy_size);
|
||||
return((i32)(win32vars.binary_path.size));
|
||||
return(push_string_copy(arena, win32vars.binary_path));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -166,22 +166,22 @@ internal DWORD
|
|||
GetCurrentDirectory_utf8(Arena *scratch, DWORD max, u8 *buffer){
|
||||
DWORD result = 0;
|
||||
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
|
||||
u32 buffer_16_max = KB(40);
|
||||
u16 *buffer_16 = push_array(scratch, u16, buffer_16_max);
|
||||
|
||||
DWORD buffer_16_len = GetCurrentDirectoryW(buffer_16_max, (LPWSTR)buffer_16);
|
||||
|
||||
b32 error = false;
|
||||
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){
|
||||
buffer[buffer_8_len] = 0;
|
||||
result = buffer_8_len;
|
||||
if (buffer != 0){
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
u32 buffer_16_max = KB(40);
|
||||
u16 *buffer_16 = push_array(scratch, u16, buffer_16_max);
|
||||
DWORD buffer_16_len = GetCurrentDirectoryW(buffer_16_max, (LPWSTR)buffer_16);
|
||||
b32 error = false;
|
||||
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){
|
||||
buffer[buffer_8_len] = 0;
|
||||
result = buffer_8_len;
|
||||
}
|
||||
end_temp(temp);
|
||||
}
|
||||
else{
|
||||
result = GetCurrentDirectoryW(0, 0);
|
||||
}
|
||||
|
||||
end_temp(temp);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -39,3 +39,8 @@ list__parameters
|
|||
list_query__parameters
|
||||
list_identifier__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)
|
||||
|
|
Loading…
Reference in New Issue