font work
This commit is contained in:
parent
f8c5738dc1
commit
da19d21bac
|
@ -103,7 +103,7 @@ typedef struct File_List{
|
|||
int block_size;
|
||||
} File_List;
|
||||
|
||||
// NOTE(allen|a4.0.7): This is used to identify which buffer
|
||||
// NOTE(allen|a4.0.8): This is used to identify which buffer
|
||||
// an operation should work on when you might want to
|
||||
// identify it by id or by name.
|
||||
typedef struct Buffer_Identifier{
|
||||
|
@ -117,6 +117,8 @@ enum Command_ID{
|
|||
|
||||
cmdid_center_view,
|
||||
cmdid_left_adjust_view,
|
||||
cmdid_page_up,
|
||||
cmdid_page_down,
|
||||
|
||||
cmdid_word_complete,
|
||||
|
||||
|
@ -125,6 +127,18 @@ enum Command_ID{
|
|||
cmdid_history_backward,
|
||||
cmdid_history_forward,
|
||||
|
||||
cmdid_to_uppercase,
|
||||
cmdid_to_lowercase,
|
||||
|
||||
cmdid_toggle_line_wrap,
|
||||
cmdid_toggle_show_whitespace,
|
||||
cmdid_clean_all_lines,
|
||||
cmdid_eol_dosify,
|
||||
cmdid_eol_nixify,
|
||||
|
||||
cmdid_hide_scrollbar,
|
||||
cmdid_show_scrollbar,
|
||||
|
||||
cmdid_interactive_new,
|
||||
cmdid_interactive_open,
|
||||
cmdid_reopen,
|
||||
|
@ -134,31 +148,15 @@ enum Command_ID{
|
|||
cmdid_interactive_kill_buffer,
|
||||
cmdid_kill_buffer,
|
||||
|
||||
cmdid_to_uppercase,
|
||||
cmdid_to_lowercase,
|
||||
|
||||
cmdid_toggle_line_wrap,
|
||||
cmdid_toggle_show_whitespace,
|
||||
|
||||
cmdid_clean_all_lines,
|
||||
cmdid_eol_dosify,
|
||||
cmdid_eol_nixify,
|
||||
|
||||
cmdid_open_panel_vsplit,
|
||||
cmdid_open_panel_hsplit,
|
||||
cmdid_close_panel,
|
||||
cmdid_change_active_panel,
|
||||
|
||||
cmdid_page_up,
|
||||
cmdid_page_down,
|
||||
|
||||
cmdid_open_color_tweaker,
|
||||
cmdid_open_config,
|
||||
cmdid_open_menu,
|
||||
cmdid_open_debug,
|
||||
|
||||
cmdid_hide_scrollbar,
|
||||
cmdid_show_scrollbar,
|
||||
cmdid_open_panel_vsplit,
|
||||
cmdid_open_panel_hsplit,
|
||||
cmdid_close_panel,
|
||||
cmdid_change_active_panel,
|
||||
|
||||
//
|
||||
cmdid_count
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#define BUFFER_REPLACE_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len)
|
||||
#define BUFFER_SEEK_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags)
|
||||
#define BUFFER_SET_SETTING_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int setting, int value)
|
||||
#define BUFFER_SAVE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, char *filename, int filename_len)
|
||||
#define CREATE_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int filename_len, int do_in_background)
|
||||
#define SAVE_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, char *filename, int filename_len)
|
||||
#define KILL_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Identifier buffer, int always_kill, int view_id)
|
||||
#define GET_VIEW_FIRST_SIG(n) View_Summary n(Application_Links *app)
|
||||
#define GET_VIEW_NEXT_SIG(n) void n(Application_Links *app, View_Summary *view)
|
||||
#define GET_VIEW_SIG(n) View_Summary n(Application_Links *app, int index)
|
||||
|
@ -34,8 +36,6 @@
|
|||
#define VIEW_POST_FADE_SIG(n) int n(Application_Links *app, View_Summary *view, int ticks, int start, int end, unsigned int color)
|
||||
#define VIEW_SET_PASTE_REWRITE__SIG(n) void n(Application_Links *app, View_Summary *view)
|
||||
#define VIEW_GET_PASTE_REWRITE__SIG(n) int n(Application_Links *app, View_Summary *view)
|
||||
#define VIEW_OPEN_FILE_SIG(n) int n(Application_Links *app, View_Summary *view, char *filename, int filename_len, int do_in_background)
|
||||
#define VIEW_KILL_BUFFER_SIG(n) int n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer)
|
||||
#define GET_USER_INPUT_SIG(n) User_Input n(Application_Links *app, unsigned int get_type, unsigned int abort_type)
|
||||
#define GET_COMMAND_INPUT_SIG(n) User_Input n(Application_Links *app)
|
||||
#define GET_EVENT_MESSAGE_SIG(n) Event_Message n(Application_Links *app)
|
||||
|
@ -69,7 +69,9 @@ extern "C"{
|
|||
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||
typedef BUFFER_SEEK_SIG(Buffer_Seek_Function);
|
||||
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function);
|
||||
typedef BUFFER_SAVE_SIG(Buffer_Save_Function);
|
||||
typedef CREATE_BUFFER_SIG(Create_Buffer_Function);
|
||||
typedef SAVE_BUFFER_SIG(Save_Buffer_Function);
|
||||
typedef KILL_BUFFER_SIG(Kill_Buffer_Function);
|
||||
typedef GET_VIEW_FIRST_SIG(Get_View_First_Function);
|
||||
typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function);
|
||||
typedef GET_VIEW_SIG(Get_View_Function);
|
||||
|
@ -84,8 +86,6 @@ extern "C"{
|
|||
typedef VIEW_POST_FADE_SIG(View_Post_Fade_Function);
|
||||
typedef VIEW_SET_PASTE_REWRITE__SIG(View_Set_Paste_Rewrite__Function);
|
||||
typedef VIEW_GET_PASTE_REWRITE__SIG(View_Get_Paste_Rewrite__Function);
|
||||
typedef VIEW_OPEN_FILE_SIG(View_Open_File_Function);
|
||||
typedef VIEW_KILL_BUFFER_SIG(View_Kill_Buffer_Function);
|
||||
typedef GET_USER_INPUT_SIG(Get_User_Input_Function);
|
||||
typedef GET_COMMAND_INPUT_SIG(Get_Command_Input_Function);
|
||||
typedef GET_EVENT_MESSAGE_SIG(Get_Event_Message_Function);
|
||||
|
@ -122,7 +122,9 @@ struct Application_Links{
|
|||
Buffer_Replace_Range_Function *buffer_replace_range;
|
||||
Buffer_Seek_Function *buffer_seek;
|
||||
Buffer_Set_Setting_Function *buffer_set_setting;
|
||||
Buffer_Save_Function *buffer_save;
|
||||
Create_Buffer_Function *create_buffer;
|
||||
Save_Buffer_Function *save_buffer;
|
||||
Kill_Buffer_Function *kill_buffer;
|
||||
Get_View_First_Function *get_view_first;
|
||||
Get_View_Next_Function *get_view_next;
|
||||
Get_View_Function *get_view;
|
||||
|
@ -137,8 +139,6 @@ struct Application_Links{
|
|||
View_Post_Fade_Function *view_post_fade;
|
||||
View_Set_Paste_Rewrite__Function *view_set_paste_rewrite_;
|
||||
View_Get_Paste_Rewrite__Function *view_get_paste_rewrite_;
|
||||
View_Open_File_Function *view_open_file;
|
||||
View_Kill_Buffer_Function *view_kill_buffer;
|
||||
Get_User_Input_Function *get_user_input;
|
||||
Get_Command_Input_Function *get_command_input;
|
||||
Get_Event_Message_Function *get_event_message;
|
||||
|
@ -177,7 +177,9 @@ app_links->buffer_read_range = external_buffer_read_range;\
|
|||
app_links->buffer_replace_range = external_buffer_replace_range;\
|
||||
app_links->buffer_seek = external_buffer_seek;\
|
||||
app_links->buffer_set_setting = external_buffer_set_setting;\
|
||||
app_links->buffer_save = external_buffer_save;\
|
||||
app_links->create_buffer = external_create_buffer;\
|
||||
app_links->save_buffer = external_save_buffer;\
|
||||
app_links->kill_buffer = external_kill_buffer;\
|
||||
app_links->get_view_first = external_get_view_first;\
|
||||
app_links->get_view_next = external_get_view_next;\
|
||||
app_links->get_view = external_get_view;\
|
||||
|
@ -192,8 +194,6 @@ app_links->view_set_buffer = external_view_set_buffer;\
|
|||
app_links->view_post_fade = external_view_post_fade;\
|
||||
app_links->view_set_paste_rewrite_ = external_view_set_paste_rewrite_;\
|
||||
app_links->view_get_paste_rewrite_ = external_view_get_paste_rewrite_;\
|
||||
app_links->view_open_file = external_view_open_file;\
|
||||
app_links->view_kill_buffer = external_view_kill_buffer;\
|
||||
app_links->get_user_input = external_get_user_input;\
|
||||
app_links->get_command_input = external_get_command_input;\
|
||||
app_links->get_event_message = external_get_event_message;\
|
||||
|
|
|
@ -96,7 +96,7 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){
|
|||
CUSTOM_COMMAND_SIG(open_my_files){
|
||||
// TODO(allen|a4.0.8): comment
|
||||
View_Summary view = app->get_active_view(app);
|
||||
app->view_open_file(app, &view, literal("w:/4ed/data/test/basic.cpp"), false);
|
||||
view_open_file(app, &view, literal("w:/4ed/data/test/basic.cpp"), false);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(build_at_launch_location){
|
||||
|
|
|
@ -784,7 +784,7 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes){
|
|||
append(&file_name, make_string(short_file_name, size));
|
||||
|
||||
exec_command(app, cmdid_change_active_panel);
|
||||
app->view_open_file(app, &view, expand_str(file_name), false);
|
||||
view_open_file(app, &view, expand_str(file_name), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,10 +1065,8 @@ CUSTOM_COMMAND_SIG(close_all_code){
|
|||
}
|
||||
}
|
||||
|
||||
View_Summary view = app->get_active_view(app);
|
||||
|
||||
for (int i = 0; i < buffers_to_close_count; ++i){
|
||||
app->view_kill_buffer(app, &view, buffer_identifier(buffers_to_close[i]));
|
||||
app->kill_buffer(app, buffer_identifier(buffers_to_close[i]), true, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -725,4 +725,25 @@ buffer_identifier(int id){
|
|||
return(identifier);
|
||||
}
|
||||
|
||||
static int
|
||||
view_open_file(Application_Links *app, View_Summary *view,
|
||||
char *filename, int filename_len, int do_in_background){
|
||||
int result = false;
|
||||
Buffer_Summary buffer = app->get_buffer_by_name(app, filename, filename_len);
|
||||
if (buffer.exists){
|
||||
app->view_set_buffer(app, view, buffer.buffer_id);
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
buffer = app->create_buffer(app, filename, filename_len, do_in_background);
|
||||
if (!do_in_background){
|
||||
if (buffer.exists){
|
||||
app->view_set_buffer(app, view, buffer.buffer_id);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ i32R(int32_t l, int32_t t, int32_t r, int32_t b){
|
|||
i32_Rect rect;
|
||||
rect.x0 = l; rect.y0 = t;
|
||||
rect.x1 = r; rect.y1 = b;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline i32_Rect
|
||||
|
@ -41,7 +41,7 @@ i32R(f32_Rect r){
|
|||
rect.y0 = (int32_t)r.y0;
|
||||
rect.x1 = (int32_t)r.x1;
|
||||
rect.y1 = (int32_t)r.y1;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline i32_Rect
|
||||
|
@ -49,7 +49,7 @@ i32XYWH(int32_t x, int32_t y, int32_t w, int32_t h){
|
|||
i32_Rect rect;
|
||||
rect.x0 = x; rect.y0 = y;
|
||||
rect.x1 = x+w; rect.y1 = y+h;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline f32_Rect
|
||||
|
@ -57,7 +57,7 @@ f32R(float l, float t, float r, float b){
|
|||
f32_Rect rect;
|
||||
rect.x0 = l; rect.y0 = t;
|
||||
rect.x1 = r; rect.y1 = b;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline f32_Rect
|
||||
|
@ -67,7 +67,7 @@ f32R(i32_Rect r){
|
|||
rect.y0 = (float)r.y0;
|
||||
rect.x1 = (float)r.x1;
|
||||
rect.y1 = (float)r.y1;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline f32_Rect
|
||||
|
@ -75,7 +75,7 @@ f32XYWH(float x, float y, float w, float h){
|
|||
f32_Rect rect;
|
||||
rect.x0 = x; rect.y0 = y;
|
||||
rect.x1 = x+w; rect.y1 = y+h;
|
||||
return rect;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
inline int
|
||||
|
|
12
4ed.cpp
12
4ed.cpp
|
@ -1793,23 +1793,23 @@ App_Init_Sig(app_init){
|
|||
|
||||
Font_Setup font_setup[] = {
|
||||
{literal("LiberationSans-Regular.ttf"),
|
||||
literal("liberation sans"),
|
||||
literal("Liberation Sans"),
|
||||
font_size},
|
||||
|
||||
{literal("liberation-mono.ttf"),
|
||||
literal("liberation mono"),
|
||||
literal("Liberation Mono"),
|
||||
font_size},
|
||||
|
||||
{literal("Hack-Regular.ttf"),
|
||||
literal("hack"),
|
||||
literal("Hack"),
|
||||
font_size},
|
||||
|
||||
{literal("CutiveMono-Regular.ttf"),
|
||||
literal("cutive mono"),
|
||||
literal("Cutive Mono"),
|
||||
font_size},
|
||||
|
||||
{literal("Inconsolata-Regular.ttf"),
|
||||
literal("inconsolata"),
|
||||
literal("Inconsolata"),
|
||||
font_size},
|
||||
};
|
||||
i32 font_count = ArrayCount(font_setup);
|
||||
|
@ -2650,7 +2650,7 @@ App_Step_Sig(app_step){
|
|||
"\n"
|
||||
"New in alpha 4.0.7:\n"
|
||||
"-Right click sets the mark\n"
|
||||
"-Clicks are now have key codes so they can have event bound in customizations\n"
|
||||
"-Clicks now have key codes so they can have events bound in customizations\n"
|
||||
"-<alt d> opens a debug view, see more in README.txt\n"
|
||||
"\n"
|
||||
"New in alpha 4.0.6:\n"
|
||||
|
|
|
@ -129,15 +129,24 @@ imp_get_file(Command_Data *cmd, Buffer_Summary *buffer){
|
|||
}
|
||||
|
||||
internal View*
|
||||
imp_get_view(Command_Data *cmd, View_Summary *view){
|
||||
View *vptr = 0;
|
||||
imp_get_view(Command_Data *cmd, int view_id){
|
||||
Live_Views *live_set = cmd->live_set;
|
||||
int view_id = view->view_id - 1;
|
||||
View *vptr = 0;
|
||||
|
||||
if (view->exists){
|
||||
view_id = view_id - 1;
|
||||
if (view_id >= 0 && view_id < live_set->max){
|
||||
vptr = live_set->views + view_id;
|
||||
}
|
||||
|
||||
return(vptr);
|
||||
}
|
||||
|
||||
internal View*
|
||||
imp_get_view(Command_Data *cmd, View_Summary *view){
|
||||
View *vptr = 0;
|
||||
|
||||
if (view->exists){
|
||||
vptr = imp_get_view(cmd, view->view_id);
|
||||
}
|
||||
|
||||
return(vptr);
|
||||
|
@ -652,7 +661,7 @@ BUFFER_SET_SETTING_SIG(external_buffer_set_setting){
|
|||
return(result);
|
||||
}
|
||||
|
||||
BUFFER_SAVE_SIG(external_buffer_save){
|
||||
SAVE_BUFFER_SIG(external_save_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
|
@ -670,6 +679,93 @@ BUFFER_SAVE_SIG(external_buffer_save){
|
|||
return(result);
|
||||
}
|
||||
|
||||
// TODO(allen): REPLACE THIS WITH CREATE_BUFFER!!!
|
||||
CREATE_BUFFER_SIG(external_create_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
|
||||
Buffer_Summary result = {0};
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
if (filename != 0){
|
||||
String filename_string = make_string(filename, filename_len);
|
||||
Editing_File *file = working_set_contains(system, working_set, filename_string);
|
||||
if (file == 0){
|
||||
File_Loading loading = system->file_load_begin(filename);
|
||||
if (loading.exists){
|
||||
b32 in_general_mem = false;
|
||||
char *buffer = push_array(part, char, loading.size);
|
||||
|
||||
if (buffer == 0){
|
||||
buffer = (char*)general_memory_allocate(general, loading.size);
|
||||
if (buffer != 0){
|
||||
in_general_mem = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (system->file_load_end(loading, buffer)){
|
||||
file = working_set_alloc_always(working_set, general);
|
||||
if (file){
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, filename_string);
|
||||
working_set_add(system, working_set, file, general);
|
||||
init_normal_file(system, models, file,
|
||||
buffer, loading.size);
|
||||
fill_buffer_summary(&result, file, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
if (in_general_mem){
|
||||
general_memory_free(general, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
file = working_set_alloc_always(working_set, general);
|
||||
if (file){
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, filename_string);
|
||||
working_set_add(system, working_set, file, general);
|
||||
init_normal_file(system, models, file, 0, 0);
|
||||
fill_buffer_summary(&result, file, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
fill_buffer_summary(&result, file, cmd);
|
||||
}
|
||||
}
|
||||
end_temp_memory(temp);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
KILL_BUFFER_SIG(external_kill_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
View *vptr = imp_get_view(cmd, view_id);
|
||||
Editing_File *file = get_file_from_identifier(system, working_set, buffer);
|
||||
int result = false;
|
||||
|
||||
if (file){
|
||||
result = true;
|
||||
if (always_kill){
|
||||
kill_file(system, models, file, string_zero());
|
||||
}
|
||||
else{
|
||||
try_kill_file(system, models, file, vptr, string_zero());
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
GET_VIEW_FIRST_SIG(external_get_view_first){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Editing_Layout *layout = &cmd->models->layout;
|
||||
|
@ -913,69 +1009,6 @@ VIEW_GET_PASTE_REWRITE__SIG(external_view_get_paste_rewrite_){
|
|||
return(result);
|
||||
}
|
||||
|
||||
VIEW_OPEN_FILE_SIG(external_view_open_file){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
Live_Views *live_set = cmd->live_set;
|
||||
|
||||
int result = false;
|
||||
|
||||
// TODO(allen): do in background
|
||||
// option happens in parallel.
|
||||
|
||||
Partition *part = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
String string = make_string_terminated(part, filename, filename_len);
|
||||
|
||||
if (do_in_background){
|
||||
result = true;
|
||||
view_open_file(system, models, 0, string);
|
||||
}
|
||||
else if (view){
|
||||
View *vptr = 0;
|
||||
int view_id = view->view_id - 1;
|
||||
if (view_id >= 0 && view_id < live_set->max){
|
||||
vptr = live_set->views + view_id;
|
||||
result = true;
|
||||
|
||||
view_open_file(system, models, 0, string);
|
||||
|
||||
fill_view_summary(view, vptr, live_set, working_set);
|
||||
}
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
VIEW_KILL_BUFFER_SIG(external_view_kill_buffer){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Models *models = cmd->models;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
View *vptr = imp_get_view(cmd, view);
|
||||
Editing_File *file = 0;
|
||||
int result = false;
|
||||
|
||||
if (vptr){
|
||||
file = get_file_from_identifier(system, working_set, buffer);
|
||||
|
||||
if (file){
|
||||
result = true;
|
||||
try_kill_file(system, models, file, vptr, string_zero());
|
||||
fill_view_summary(view, vptr, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
GET_USER_INPUT_SIG(external_get_user_input){
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
|
|
|
@ -382,23 +382,22 @@ file_init_strings(Editing_File *file){
|
|||
file->name.extension = make_fixed_width_string(file->name.extension_);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
||||
String f, ext;
|
||||
internal void
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, String filename){
|
||||
String ext;
|
||||
|
||||
Assert(file->name.live_name.str != 0);
|
||||
|
||||
f = make_string_slowly(filename);
|
||||
copy_checked(&file->name.source_path, f);
|
||||
copy_checked(&file->name.source_path, filename);
|
||||
|
||||
file->name.live_name.size = 0;
|
||||
get_front_of_directory(&file->name.live_name, f);
|
||||
get_front_of_directory(&file->name.live_name, filename);
|
||||
|
||||
if (file->name.source_path.size == file->name.live_name.size){
|
||||
file->name.extension.size = 0;
|
||||
}
|
||||
else{
|
||||
ext = file_extension(f);
|
||||
ext = file_extension(filename);
|
||||
copy(&file->name.extension, ext);
|
||||
}
|
||||
|
||||
|
@ -435,6 +434,12 @@ file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
|||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
||||
String f = make_string_slowly(filename);
|
||||
file_set_name(working_set, file, f);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){
|
||||
u64 stamp = system->file_time_stamp(filename);
|
||||
|
@ -613,19 +618,6 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general,
|
|||
buffer->widths_count = state.count;
|
||||
}
|
||||
|
||||
struct Opaque_Font_Advance{
|
||||
void *data;
|
||||
int stride;
|
||||
};
|
||||
|
||||
inline Opaque_Font_Advance
|
||||
get_opaque_font_advance(Render_Font *font){
|
||||
Opaque_Font_Advance result;
|
||||
result.data = (char*)font->chardata + OffsetOfPtr(font->chardata, xadvance);
|
||||
result.stride = sizeof(*font->chardata);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline i32
|
||||
view_wrapped_line_span(f32 line_width, f32 max_width){
|
||||
i32 line_count = CEIL32(line_width / max_width);
|
||||
|
@ -700,7 +692,8 @@ view_measure_wraps(General_Memory *general, View *view){
|
|||
|
||||
internal void
|
||||
file_create_from_string(System_Functions *system, Models *models,
|
||||
Editing_File *file, char *filename, String val, b8 read_only = 0){
|
||||
Editing_File *file, char *name,
|
||||
String val, b8 read_only = 0){
|
||||
|
||||
Font_Set *font_set = models->font_set;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
@ -731,11 +724,12 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
}
|
||||
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, (char*)filename);
|
||||
|
||||
file_set_name(working_set, file, (char*)name);
|
||||
|
||||
file->state.font_id = models->global_font.font_id;
|
||||
|
||||
file_synchronize_times(system, file, filename);
|
||||
file_synchronize_times(system, file, name);
|
||||
|
||||
Render_Font *font = get_font_info(font_set, file->state.font_id)->font;
|
||||
float *advance_data = 0;
|
||||
|
@ -5423,7 +5417,14 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
|
|||
u32 char_color = main_color;
|
||||
if (item->flags & BRFlag_Special_Character) char_color = special_color;
|
||||
|
||||
f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1);
|
||||
#if 0
|
||||
i32_Rect char_rect = i32R(item->x0, item->y0,
|
||||
item->x1, item->y1);
|
||||
#else
|
||||
f32_Rect char_rect = f32R(item->x0, item->y0,
|
||||
item->x1, item->y1);
|
||||
#endif
|
||||
|
||||
if (view->file_data.show_whitespace && highlight_color == 0 &&
|
||||
char_is_whitespace((char)item->glyphid)){
|
||||
highlight_this_color = style->main.highlight_white_color;
|
||||
|
|
|
@ -119,7 +119,10 @@ font_set_load(Partition *partition, Font_Set *set, i16 font_id){
|
|||
font__insert(&set->used_slots, slot);
|
||||
|
||||
Render_Font *font = (Render_Font*)(slot + 1);
|
||||
set->font_load(font, info->filename.str, info->pt_size, 4, 1);
|
||||
set->font_load(font,
|
||||
info->filename.str,
|
||||
info->name.str,
|
||||
info->pt_size, 4, true);
|
||||
info->font = font;
|
||||
slot->font_id = font_id;
|
||||
}
|
||||
|
@ -182,7 +185,10 @@ font_set_add(Partition *partition, Font_Set *set,
|
|||
info->filename = filename;
|
||||
info->name = name;
|
||||
info->pt_size = pt_size;
|
||||
set->font_load(&dummy_font, info->filename.str, info->pt_size, 4, 0);
|
||||
set->font_load(&dummy_font,
|
||||
info->filename.str,
|
||||
info->name.str,
|
||||
info->pt_size, 4, false);
|
||||
info->height = dummy_font.height;
|
||||
info->advance = dummy_font.advance;
|
||||
|
||||
|
|
|
@ -165,19 +165,56 @@ private_draw_gradient(Render_Target *target, f32_Rect rect,
|
|||
glEnd();
|
||||
}
|
||||
|
||||
struct Render_Quad{
|
||||
f32 x0, y0, x1, y1;
|
||||
f32 s0, t0, s1, t1;
|
||||
};
|
||||
|
||||
inline Render_Quad
|
||||
get_render_quad(Glyph_Data *b, int pw, int ph, float xpos, float ypos){
|
||||
Render_Quad q;
|
||||
|
||||
float ipw = 1.0f / pw, iph = 1.0f / ph;
|
||||
|
||||
q.x0 = xpos + b->xoff;
|
||||
q.y0 = ypos + b->yoff;
|
||||
q.x1 = xpos + b->xoff2;
|
||||
q.y1 = ypos + b->yoff2;
|
||||
|
||||
q.s0 = b->x0 * ipw;
|
||||
q.t0 = b->y0 * iph;
|
||||
q.s1 = b->x1 * ipw;
|
||||
q.t1 = b->y1 * iph;
|
||||
|
||||
return(q);
|
||||
}
|
||||
|
||||
inline Render_Quad
|
||||
get_exact_render_quad(Glyph_Data *b, int pw, int ph, float xpos, float ypos){
|
||||
Render_Quad q;
|
||||
|
||||
float ipw = 1.0f / pw, iph = 1.0f / ph;
|
||||
|
||||
q.x0 = xpos;
|
||||
q.y0 = ypos + b->yoff;
|
||||
q.x1 = xpos + (b->xoff2 - b->xoff);
|
||||
q.y1 = ypos + b->yoff2;
|
||||
|
||||
q.s0 = b->x0 * ipw;
|
||||
q.t0 = b->y0 * iph;
|
||||
q.s1 = b->x1 * ipw;
|
||||
q.t1 = b->y1 * iph;
|
||||
|
||||
return(q);
|
||||
}
|
||||
|
||||
inline void
|
||||
private_draw_glyph(Render_Target *target, Render_Font *font,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
f32 x_shift, y_shift;
|
||||
x_shift = 0;
|
||||
y_shift = (f32)font->ascent;
|
||||
|
||||
x += x_shift;
|
||||
y += y_shift;
|
||||
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
|
||||
character, &x, &y, &q, 0);
|
||||
Render_Quad q = get_render_quad(
|
||||
font->glyphs + character,
|
||||
font->tex_width, font->tex_height, x, y
|
||||
);
|
||||
|
||||
draw_set_color(target, color);
|
||||
draw_bind_texture(target, font->tex);
|
||||
|
@ -194,19 +231,18 @@ private_draw_glyph(Render_Target *target, Render_Font *font,
|
|||
inline void
|
||||
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
|
||||
f32 x, f32 y, f32 advance, u32 color){
|
||||
f32 x_shift, y_shift;
|
||||
i32 left = font->chardata[character].x0;
|
||||
i32 right = font->chardata[character].x1;
|
||||
i32 width = (right - left);
|
||||
x_shift = (f32)(advance - width) * .5f - font->chardata[character].xoff;
|
||||
y_shift = (f32)font->ascent;
|
||||
|
||||
f32 left = font->glyphs[character].x0;
|
||||
f32 right = font->glyphs[character].x1;
|
||||
f32 width = (right - left);
|
||||
f32 x_shift = (advance - width) * .5f;
|
||||
|
||||
x += x_shift;
|
||||
y += y_shift;
|
||||
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
|
||||
character, &x, &y, &q, 0);
|
||||
Render_Quad q = get_exact_render_quad(
|
||||
font->glyphs + character,
|
||||
font->tex_width, font->tex_height, x, y
|
||||
);
|
||||
|
||||
draw_set_color(target, color);
|
||||
draw_bind_texture(target, font->tex);
|
||||
|
@ -305,6 +341,23 @@ launch_rendering(Render_Target *target){
|
|||
|
||||
#undef ExtractStruct
|
||||
|
||||
internal void*
|
||||
part_alloc(int size, void *context){
|
||||
Partition *part = (Partition*)context;
|
||||
void *result = push_block(part, size);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
part_free(void *ptr, void *context){
|
||||
}
|
||||
|
||||
#define STBTT_malloc part_alloc
|
||||
#define STBTT_free part_free
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
|
||||
// TODO(allen): Put the burden of translation outside
|
||||
// of this function (and other functions implementing
|
||||
// the same interface).
|
||||
|
@ -324,7 +377,7 @@ draw_font_load(Partition *part,
|
|||
|
||||
i32 result = 1;
|
||||
|
||||
stbtt_packedchar *chardata = font_out->chardata;
|
||||
stbtt_packedchar chardata[256];
|
||||
|
||||
File_Data file = sysshared_load_file(filename.str);
|
||||
|
||||
|
@ -364,6 +417,7 @@ draw_font_load(Partition *part,
|
|||
font_out->tex_width = tex_width;
|
||||
font_out->tex_height = tex_height;
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
stbtt_pack_context spc;
|
||||
|
||||
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height,
|
||||
|
@ -380,6 +434,7 @@ draw_font_load(Partition *part,
|
|||
else{
|
||||
result = 0;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
if (result){
|
||||
GLuint font_tex;
|
||||
|
@ -395,21 +450,37 @@ draw_font_load(Partition *part,
|
|||
font_out->tex = font_tex;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
font_out->chardata['\r'] = font_out->chardata[' '];
|
||||
font_out->chardata['\n'] = font_out->chardata[' '];
|
||||
font_out->chardata['\t'] = font_out->chardata[' '];
|
||||
font_out->chardata['\t'].xadvance *= tab_width;
|
||||
f32 *advance_data = font_out->advance_data;
|
||||
Glyph_Data *glyphs = font_out->glyphs;
|
||||
for (u8 code_point = 0; code_point < 128; ++code_point){
|
||||
advance_data[code_point] = (f32)(CEIL32(chardata[code_point].xadvance));
|
||||
glyphs[code_point].x0 = chardata[code_point].x0;
|
||||
glyphs[code_point].y0 = chardata[code_point].y0;
|
||||
glyphs[code_point].x1 = chardata[code_point].x1;
|
||||
glyphs[code_point].y1 = chardata[code_point].y1;
|
||||
glyphs[code_point].xoff = chardata[code_point].xoff;
|
||||
glyphs[code_point].yoff = chardata[code_point].yoff + font_out->ascent;
|
||||
glyphs[code_point].xoff2 = chardata[code_point].xoff2;
|
||||
glyphs[code_point].yoff2 = chardata[code_point].yoff2 + font_out->ascent;
|
||||
}
|
||||
|
||||
glyphs['\r'] = glyphs[' '];
|
||||
advance_data['\r'] = advance_data[' '];
|
||||
|
||||
glyphs['\n'] = glyphs[' '];
|
||||
advance_data['\n'] = advance_data[' '];
|
||||
|
||||
glyphs['\t'] = glyphs[' '];
|
||||
advance_data['\t'] = advance_data[' ']*tab_width;
|
||||
|
||||
i32 max_advance = 0;
|
||||
for (u8 code_point = 0; code_point < 128; ++code_point){
|
||||
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
|
||||
font_out->glyphs[code_point].exists = 1;
|
||||
i32 advance = CEIL32(font_out->chardata[code_point].xadvance);
|
||||
if (max_advance < advance) max_advance = advance;
|
||||
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
|
||||
i32 advance = CEIL32(advance_data[code_point]);
|
||||
if (max_advance < advance){
|
||||
max_advance = advance;
|
||||
}
|
||||
else if (code_point == '\r' || code_point == '\n' || code_point == '\t'){
|
||||
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
|
||||
}
|
||||
}
|
||||
font_out->advance = max_advance - 1;
|
||||
|
|
|
@ -12,25 +12,14 @@
|
|||
#ifndef FRED_RENDERING_H
|
||||
#define FRED_RENDERING_H
|
||||
|
||||
internal void*
|
||||
part_alloc(int size, void *context){
|
||||
Partition *part = (Partition*)context;
|
||||
void *result = push_block(part, size);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
part_free(void *ptr, void *context){
|
||||
}
|
||||
|
||||
#define STBTT_malloc part_alloc
|
||||
#define STBTT_free part_free
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
|
||||
struct Glyph_Data{
|
||||
b32 exists;
|
||||
|
||||
f32 x0, x1;
|
||||
f32 y0, y1;
|
||||
|
||||
f32 xoff, yoff;
|
||||
f32 xoff2, yoff2;
|
||||
};
|
||||
|
||||
struct Render_Font{
|
||||
|
@ -38,8 +27,10 @@ struct Render_Font{
|
|||
String name;
|
||||
b32 loaded;
|
||||
|
||||
// TODO(allen): Have our own type here instead
|
||||
// of stbtt_packedchar, and have both stb fonts
|
||||
// and OS fonts go to our type.
|
||||
Glyph_Data glyphs[256];
|
||||
stbtt_packedchar chardata[256];
|
||||
float advance_data[256];
|
||||
i32 height, ascent, descent, line_skip;
|
||||
i32 advance;
|
||||
|
@ -114,6 +105,7 @@ typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
|
|||
#define Font_Load_Sig(name) i32 name( \
|
||||
Render_Font *font_out, \
|
||||
char *filename, \
|
||||
char *fontname, \
|
||||
i32 pt_size, \
|
||||
i32 tab_width, \
|
||||
b32 store_texture)
|
||||
|
|
|
@ -115,11 +115,6 @@ font_predict_size(i32 pt_size){
|
|||
return pt_size*pt_size*128;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_set_tabwidth(Render_Font *font, i32 tab_width){
|
||||
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, f32 advance, u32 color){
|
||||
|
@ -155,117 +150,95 @@ font_draw_glyph(Render_Target *target, i16 font_id,
|
|||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline f32
|
||||
font_get_glyph_width(Render_Target *target, i16 font_id, u16 character){
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 result = 0.f;
|
||||
if (font) result = font->chardata[character].xadvance;
|
||||
return (result);
|
||||
}
|
||||
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||
f32 x = 0;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
u8 c = str[i] % 128;
|
||||
x += advance_data[c];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, String str){
|
||||
f32 x = 0;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
u8 c = str.str[i] % 128;
|
||||
x += advance_data[c];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
char *str, i32 x_, i32 y, u32 color){
|
||||
real32 x = (real32)x_;
|
||||
f32 x = (f32)x_;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
u8 c = str[i] % 128;
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
x += advance_data[c];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
u8 c = str[i] % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
String str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_draw_glyph(target, font_id, c,
|
||||
x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
u8 c = str.str[i] % 128;
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += advance_data[c];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
u8 c = str.str[i] % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_max_width(Font_Set *font_set, i16 font_id, char *characters){
|
||||
Render_Font *font = get_font_info(font_set, font_id)->font;
|
||||
f32 cx, x = 0;
|
||||
if (font){
|
||||
stbtt_packedchar *chardata = font->chardata;
|
||||
for (i32 i = 0; characters[i]; ++i){
|
||||
cx = chardata[characters[i]].xadvance;
|
||||
if (x < cx) x = cx;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_string_width(Render_Target *target, i16 font_id, String string){
|
||||
f32 result = 0;
|
||||
for (i32 i = 0; i < string.size; ++i){
|
||||
u8 c = string.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return result;
|
||||
return(x);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -31,7 +31,9 @@ int Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int sta
|
|||
int Buffer_Seek(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags);
|
||||
int Buffer_Set_Setting(Application_Links *app, Buffer_Summary *buffer, int setting, int value);
|
||||
|
||||
int Buffer_Save(Application_Links *app, Buffer_Summary *buffer, char *filename, int filename_len);
|
||||
Buffer_Summary Create_Buffer(Application_Links *app, char *filename, int filename_len, int do_in_background);
|
||||
int Save_Buffer(Application_Links *app, Buffer_Summary *buffer, char *filename, int filename_len);
|
||||
int Kill_Buffer(Application_Links *app, Buffer_Identifier buffer, int always_kill, int view_id);
|
||||
|
||||
// View manipulation
|
||||
View_Summary Get_View_First(Application_Links *app);
|
||||
|
@ -57,10 +59,6 @@ int View_Post_Fade(Application_Links *app, View_Summary *view, int ticks, int st
|
|||
void View_Set_Paste_Rewrite_(Application_Links *app, View_Summary *view);
|
||||
int View_Get_Paste_Rewrite_(Application_Links *app, View_Summary *view);
|
||||
|
||||
// TODO(allen): Make sure this is just right.
|
||||
int View_Open_File(Application_Links *app, View_Summary *view, char *filename, int filename_len, int do_in_background);
|
||||
int View_Kill_Buffer(Application_Links *app, View_Summary *view, Buffer_Identifier buffer);
|
||||
|
||||
// Directly get user input
|
||||
User_Input Get_User_Input(Application_Links *app, unsigned int get_type, unsigned int abort_type);
|
||||
User_Input Get_Command_Input(Application_Links *app);
|
||||
|
|
|
@ -520,7 +520,8 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
|
|||
#endif
|
||||
|
||||
// NOTE(allen): This opens the file and puts it in &view
|
||||
app->view_open_file(app, &view, expand_str(FileName), false);
|
||||
// This returns false if the open fails.
|
||||
view_open_file(app, &view, expand_str(FileName), false);
|
||||
|
||||
Result.buffer = app->get_buffer_by_name(app, FileName.str, FileName.size);
|
||||
|
||||
|
@ -655,7 +656,7 @@ CUSTOM_COMMAND_SIG(casey_save_and_make_without_asking)
|
|||
exec_command(app, cmdid_save);
|
||||
#endif
|
||||
|
||||
app->buffer_save(app, &buffer, buffer.file_name, buffer.file_name_len);
|
||||
app->save_buffer(app, &buffer, buffer.file_name, buffer.file_name_len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -1153,7 +1154,7 @@ OpenProject(Application_Links *app, char *ProjectFileName)
|
|||
exec_command(app, cmdid_interactive_open);
|
||||
#endif
|
||||
|
||||
app->view_open_file(app, 0, dir.str, dir.size, true);
|
||||
view_open_file(app, 0, dir.str, dir.size, true);
|
||||
++TotalOpenAttempts;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1177,6 +1177,7 @@ Font_Load_Sig(system_draw_font_load){
|
|||
success = win32_draw_font_load(&win32vars.font_part,
|
||||
font_out,
|
||||
filename,
|
||||
fontname,
|
||||
pt_size,
|
||||
tab_width,
|
||||
oversample,
|
||||
|
|
302
win32_font.cpp
302
win32_font.cpp
|
@ -9,25 +9,36 @@
|
|||
|
||||
// TOP
|
||||
|
||||
struct Glyph_Bitmap{
|
||||
HBITMAP bitmap_handle;
|
||||
char *pixels;
|
||||
struct GMetrics{
|
||||
f32 advance;
|
||||
f32 xoff;
|
||||
f32 xoff2;
|
||||
};
|
||||
|
||||
void
|
||||
win32_get_box(HDC dc, TCHAR character, int *x0, int *y0, int *x1, int *y1){
|
||||
SIZE size;
|
||||
GetTextExtentPoint32A(dc, &character, 1, &size);
|
||||
*x0 = 0;
|
||||
*y0 = 0;
|
||||
*x1 = size.cx;
|
||||
*y1 = size.cy;
|
||||
internal b32
|
||||
win32_glyph_metrics(HDC dc, int code, GMetrics *gmetrics){
|
||||
b32 result = false;
|
||||
ABCFLOAT abc = {0};
|
||||
INT width;
|
||||
|
||||
if (GetCharWidth32W(dc, code, code, &width)){
|
||||
gmetrics->advance = (f32)width;
|
||||
if (GetCharABCWidthsFloat(dc, code, code, &abc)){
|
||||
gmetrics->xoff = abc.abcfA;
|
||||
gmetrics->xoff2 = (abc.abcfA + abc.abcfB);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal i32
|
||||
win32_draw_font_load(Partition *part,
|
||||
Render_Font *font_out,
|
||||
char *filename_untranslated,
|
||||
char *fontname,
|
||||
i32 pt_size,
|
||||
i32 tab_width,
|
||||
i32 oversample,
|
||||
|
@ -36,77 +47,127 @@ win32_draw_font_load(Partition *part,
|
|||
char space_[1024];
|
||||
String filename = make_fixed_width_string(space_);
|
||||
b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated);
|
||||
if (!translate_success) return 0;
|
||||
|
||||
i32 result = 0;
|
||||
|
||||
if (translate_success){
|
||||
HDC dc = GetDC(win32vars.window_handle);
|
||||
|
||||
AddFontResourceEx(filename.str, FR_PRIVATE, 0);
|
||||
|
||||
HFONT font_handle =
|
||||
CreateFontA(pt_size, 0, 0, 0,
|
||||
FW_NORMAL, // WEIGHT
|
||||
FALSE, // ITALICS
|
||||
FALSE, // UNDERLINE
|
||||
FALSE, // STRIKE-OUT
|
||||
HFONT font_handle = CreateFont(
|
||||
pt_size,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FW_NORMAL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
ANSI_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
ANTIALIASED_QUALITY,
|
||||
DEFAULT_PITCH|FF_DONTCARE,
|
||||
filename.str);
|
||||
DEFAULT_QUALITY,
|
||||
FF_DONTCARE | DEFAULT_PITCH,
|
||||
fontname
|
||||
);
|
||||
HBITMAP bmp_handle = CreateBitmap(
|
||||
pt_size*2, pt_size*2,
|
||||
4, 32,
|
||||
0
|
||||
);
|
||||
|
||||
if (font_handle){
|
||||
HDC dc = CreateCompatibleDC(0);
|
||||
|
||||
if (dc){
|
||||
TEXTMETRIC metrics;
|
||||
GetTextMetrics(dc, &metrics);
|
||||
font_out->height = metrics.tmHeight + metrics.tmExternalLeading;
|
||||
font_out->ascent = metrics.tmAscent;
|
||||
font_out->descent = -metrics.tmDescent;
|
||||
font_out->line_skip = metrics.tmExternalLeading;
|
||||
font_out->advance = metrics.tmMaxCharWidth;
|
||||
if (font_handle != 0 && bmp_handle != 0){
|
||||
SelectObject(dc, font_handle);
|
||||
SelectObject(dc, bmp_handle);
|
||||
|
||||
memset(font_out, 0, sizeof(*font_out));
|
||||
|
||||
TEXTMETRIC metric;
|
||||
if (GetTextMetrics(dc, &metric)){
|
||||
|
||||
font_out->height = (i32)(metric.tmHeight + metric.tmExternalLeading);
|
||||
font_out->ascent = (i32)(metric.tmAscent);
|
||||
font_out->descent = (i32)(metric.tmDescent);
|
||||
font_out->line_skip = (i32)(metric.tmExternalLeading);
|
||||
|
||||
if (!store_texture){
|
||||
result = 1;
|
||||
if (store_texture){
|
||||
}
|
||||
else{
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
|
||||
i32 tex_width = pt_size*16*oversample;
|
||||
i32 tex_height = pt_size*16*oversample;
|
||||
i32 tex_width = pt_size*16;
|
||||
i32 tex_height = pt_size*16;
|
||||
void *block = sysshared_push_block(part, tex_width * tex_height);
|
||||
|
||||
Glyph_Bitmap glyph_bitmap;
|
||||
glyph_bitmap.bitmap_handle = CreateCompatibleBitmap(dc, tex_width, tex_height);
|
||||
glyph_bitmap.pixels = push_array(part, char, tex_width*tex_height);
|
||||
font_out->tex_width = tex_width;
|
||||
font_out->tex_height = tex_height;
|
||||
|
||||
SelectObject(dc, glyph_bitmap.bitmap_handle);
|
||||
SelectObject(dc, font_handle);
|
||||
result = 1;
|
||||
/////////////////////////////////////////////////////////////////
|
||||
stbtt_pack_context spc_;
|
||||
|
||||
SetBkColor(dc, RGB(0, 0, 0));
|
||||
|
||||
stbtt_pack_context context = {0};
|
||||
stbtt_PackBegin(&context, (unsigned char*)glyph_bitmap.pixels, tex_width, tex_height, 0, 1, part);
|
||||
int pack_result;
|
||||
{
|
||||
stbtt_pack_context *spc = &spc_;
|
||||
unsigned char *pixels = (u8*)block;
|
||||
int pw = tex_width;
|
||||
int ph = tex_height;
|
||||
int stride_in_bytes = tex_width;
|
||||
int padding = 1;
|
||||
void *alloc_context = part;
|
||||
|
||||
{
|
||||
stbtt_pack_context *spc = &context;
|
||||
int first_unicode_char_in_range = 0;
|
||||
int num_chars_in_range = 128;
|
||||
stbtt_packedchar *chardata_for_range = font_out->chardata;
|
||||
stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
|
||||
int num_nodes = pw - padding;
|
||||
stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
|
||||
|
||||
if (context == NULL || nodes == NULL) {
|
||||
if (context != NULL) STBTT_free(context, alloc_context);
|
||||
if (nodes != NULL) STBTT_free(nodes , alloc_context);
|
||||
pack_result = 0;
|
||||
goto packbegin_end;
|
||||
}
|
||||
|
||||
spc->user_allocator_context = alloc_context;
|
||||
spc->width = pw;
|
||||
spc->height = ph;
|
||||
spc->pixels = pixels;
|
||||
spc->pack_info = context;
|
||||
spc->nodes = nodes;
|
||||
spc->padding = padding;
|
||||
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
|
||||
spc->h_oversample = 1;
|
||||
spc->v_oversample = 1;
|
||||
|
||||
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
|
||||
|
||||
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
|
||||
|
||||
pack_result = 1;
|
||||
goto packbegin_end;
|
||||
}
|
||||
}
|
||||
packbegin_end:;
|
||||
|
||||
if (pack_result){
|
||||
|
||||
int pack_font_range_result;
|
||||
|
||||
{
|
||||
stbtt_pack_range range;
|
||||
range.first_unicode_char_in_range = first_unicode_char_in_range;
|
||||
range.num_chars_in_range = num_chars_in_range;
|
||||
range.chardata_for_range = chardata_for_range;
|
||||
range.first_unicode_char_in_range = 0;
|
||||
range.num_chars_in_range = 128;
|
||||
range.chardata_for_range = font_out->chardata;
|
||||
range.font_size = STBTT_POINT_SIZE((f32)pt_size);
|
||||
|
||||
{
|
||||
stbtt_pack_context *spc = &spc_;
|
||||
stbtt_pack_range *ranges = ⦥
|
||||
int num_ranges = 1;
|
||||
|
||||
{
|
||||
float recip_h = 1.0f / spc->h_oversample;
|
||||
float recip_v = 1.0f / spc->v_oversample;
|
||||
float sub_x = stbtt__oversample_shift(spc->h_oversample);
|
||||
float sub_y = stbtt__oversample_shift(spc->v_oversample);
|
||||
int i,j,k,n, return_value = 1;
|
||||
stbrp_context *context = (stbrp_context *) spc->pack_info;
|
||||
stbrp_rect *rects;
|
||||
|
@ -124,19 +185,32 @@ win32_draw_font_load(Partition *part,
|
|||
n += ranges[i].num_chars_in_range;
|
||||
|
||||
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
|
||||
if (rects == NULL)
|
||||
return 0;
|
||||
if (rects == NULL){
|
||||
pack_font_range_result = 0;
|
||||
goto pack_font_range_end;
|
||||
}
|
||||
|
||||
//info.userdata = spc->user_allocator_context;
|
||||
//stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
|
||||
k=0;
|
||||
for (i=0; i < num_ranges; ++i) {
|
||||
//float fh = ranges[i].font_size;
|
||||
//float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
|
||||
for (j=0; j < ranges[i].num_chars_in_range; ++j) {
|
||||
int x0,y0,x1,y1;
|
||||
int w,h;
|
||||
|
||||
TCHAR character = (TCHAR)(ranges[i].first_unicode_char_in_range + j);
|
||||
win32_get_box(dc, character, &x0, &y0, &x1, &y1);
|
||||
GMetrics gmetrics;
|
||||
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
if (!win32_glyph_metrics(dc, ranges[i].first_unicode_char_in_range + j, &gmetrics)){
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
w = CEIL32(gmetrics.xoff2 - gmetrics.xoff);
|
||||
h = font_out->ascent + font_out->descent;
|
||||
|
||||
rects[k].w = (stbrp_coord) (w + spc->padding);
|
||||
rects[k].h = (stbrp_coord) (h + spc->padding);
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
@ -145,47 +219,65 @@ win32_draw_font_load(Partition *part,
|
|||
|
||||
k = 0;
|
||||
for (i=0; i < num_ranges; ++i) {
|
||||
//float fh = ranges[i].font_size;
|
||||
//float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
|
||||
for (j=0; j < ranges[i].num_chars_in_range; ++j) {
|
||||
stbrp_rect *r = &rects[k];
|
||||
if (r->was_packed) {
|
||||
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
||||
int advance, x0,y0,x1,y1;
|
||||
int glyph = ranges[i].first_unicode_char_in_range + j;
|
||||
//int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j);
|
||||
int code = ranges[i].first_unicode_char_in_range + j;
|
||||
stbrp_coord pad = (stbrp_coord) spc->padding;
|
||||
|
||||
GetCharWidth32W(dc, glyph, glyph, &advance);
|
||||
|
||||
TCHAR character = (TCHAR)(ranges[i].first_unicode_char_in_range + j);
|
||||
win32_get_box(dc, character, &x0, &y0, &x1, &y1);
|
||||
|
||||
// pad on left and top
|
||||
r->x += pad;
|
||||
r->y += pad;
|
||||
r->w -= pad;
|
||||
r->h -= pad;
|
||||
|
||||
SetTextColor(dc, RGB(255, 255, 255));
|
||||
TextOutA(dc, r->x, r->y, &character, 1);
|
||||
#if 0
|
||||
int advance, lsb, x0,y0,x1,y1;
|
||||
|
||||
if (spc->h_oversample > 1)
|
||||
stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
|
||||
r->w, r->h, spc->stride_in_bytes,
|
||||
spc->h_oversample);
|
||||
stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb);
|
||||
stbtt_GetGlyphBitmapBox(&info, glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
&x0,&y0,&x1,&y1);
|
||||
stbtt_MakeGlyphBitmapSubpixel(&info,
|
||||
spc->pixels + r->x + r->y*spc->stride_in_bytes,
|
||||
r->w - spc->h_oversample+1,
|
||||
r->h - spc->v_oversample+1,
|
||||
spc->stride_in_bytes,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
0,0,
|
||||
glyph);
|
||||
#else
|
||||
float advance, x0, y0, x1, y1;
|
||||
|
||||
if (spc->v_oversample > 1)
|
||||
stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
|
||||
r->w, r->h, spc->stride_in_bytes,
|
||||
spc->v_oversample);
|
||||
GMetrics gmetrics;
|
||||
if (!win32_glyph_metrics(dc, code, &gmetrics)){
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
advance = gmetrics.advance;
|
||||
x0 = gmetrics.xoff;
|
||||
y0 = -font_out->ascent;
|
||||
x1 = gmetrics.xoff2;
|
||||
y1 = font_out->descent;
|
||||
|
||||
#endif
|
||||
|
||||
bc->x0 = (stbtt_int16) r->x;
|
||||
bc->y0 = (stbtt_int16) r->y;
|
||||
bc->x1 = (stbtt_int16) (r->x + r->w);
|
||||
bc->y1 = (stbtt_int16) (r->y + r->h);
|
||||
bc->xadvance = (float) advance;
|
||||
bc->xoff = (float) x0 * recip_h + sub_x;
|
||||
bc->yoff = (float) y0 * recip_v + sub_y;
|
||||
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
|
||||
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
|
||||
bc->xoff = (float) x0;
|
||||
bc->yoff = (float) y0;
|
||||
bc->xoff2 = (float) (x0 + r->w);
|
||||
bc->yoff2 = (float) (y0 + r->h);
|
||||
} else {
|
||||
return_value = 0; // if any fail, report failure
|
||||
}
|
||||
|
@ -195,10 +287,31 @@ win32_draw_font_load(Partition *part,
|
|||
}
|
||||
|
||||
STBTT_free(rects, spc->user_allocator_context);
|
||||
pack_font_range_result = return_value;
|
||||
goto pack_font_range_end;
|
||||
}
|
||||
}
|
||||
pack_font_range_end:;
|
||||
|
||||
result = return_value;
|
||||
|
||||
if (return_value){
|
||||
if (!pack_font_range_result){
|
||||
result = 0;
|
||||
}
|
||||
|
||||
{
|
||||
stbtt_pack_context *spc = &spc_;
|
||||
{
|
||||
STBTT_free(spc->nodes , spc->user_allocator_context);
|
||||
STBTT_free(spc->pack_info, spc->user_allocator_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
if (result){
|
||||
GLuint font_tex;
|
||||
glGenTextures(1, &font_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, font_tex);
|
||||
|
@ -207,7 +320,9 @@ win32_draw_font_load(Partition *part,
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, glyph_bitmap.pixels);
|
||||
memset(block, 0xFF, tex_width*tex_height);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block);
|
||||
|
||||
font_out->tex = font_tex;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
@ -216,19 +331,24 @@ win32_draw_font_load(Partition *part,
|
|||
font_out->chardata['\n'] = font_out->chardata[' '];
|
||||
font_out->chardata['\t'] = font_out->chardata[' '];
|
||||
font_out->chardata['\t'].xadvance *= tab_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 code_point = 0; code_point < 128; ++code_point){
|
||||
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
|
||||
}
|
||||
|
||||
stbtt_PackEnd(&context);
|
||||
i32 max_advance = metric.tmMaxCharWidth;
|
||||
font_out->advance = max_advance - 1;
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteObject(font_handle);
|
||||
DeleteObject(bmp_handle);
|
||||
}
|
||||
|
||||
ReleaseDC(win32vars.window_handle, dc);
|
||||
}
|
||||
|
||||
return(result);
|
||||
|
|
Loading…
Reference in New Issue