font work
This commit is contained in:
parent
f8c5738dc1
commit
da19d21bac
|
@ -103,7 +103,7 @@ typedef struct File_List{
|
||||||
int block_size;
|
int block_size;
|
||||||
} File_List;
|
} 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
|
// an operation should work on when you might want to
|
||||||
// identify it by id or by name.
|
// identify it by id or by name.
|
||||||
typedef struct Buffer_Identifier{
|
typedef struct Buffer_Identifier{
|
||||||
|
@ -117,6 +117,8 @@ enum Command_ID{
|
||||||
|
|
||||||
cmdid_center_view,
|
cmdid_center_view,
|
||||||
cmdid_left_adjust_view,
|
cmdid_left_adjust_view,
|
||||||
|
cmdid_page_up,
|
||||||
|
cmdid_page_down,
|
||||||
|
|
||||||
cmdid_word_complete,
|
cmdid_word_complete,
|
||||||
|
|
||||||
|
@ -125,6 +127,18 @@ enum Command_ID{
|
||||||
cmdid_history_backward,
|
cmdid_history_backward,
|
||||||
cmdid_history_forward,
|
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_new,
|
||||||
cmdid_interactive_open,
|
cmdid_interactive_open,
|
||||||
cmdid_reopen,
|
cmdid_reopen,
|
||||||
|
@ -134,31 +148,15 @@ enum Command_ID{
|
||||||
cmdid_interactive_kill_buffer,
|
cmdid_interactive_kill_buffer,
|
||||||
cmdid_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_color_tweaker,
|
||||||
cmdid_open_config,
|
cmdid_open_config,
|
||||||
cmdid_open_menu,
|
cmdid_open_menu,
|
||||||
cmdid_open_debug,
|
cmdid_open_debug,
|
||||||
|
|
||||||
cmdid_hide_scrollbar,
|
cmdid_open_panel_vsplit,
|
||||||
cmdid_show_scrollbar,
|
cmdid_open_panel_hsplit,
|
||||||
|
cmdid_close_panel,
|
||||||
|
cmdid_change_active_panel,
|
||||||
|
|
||||||
//
|
//
|
||||||
cmdid_count
|
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_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_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_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_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_NEXT_SIG(n) void n(Application_Links *app, View_Summary *view)
|
||||||
#define GET_VIEW_SIG(n) View_Summary n(Application_Links *app, int index)
|
#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_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_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_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_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_COMMAND_INPUT_SIG(n) User_Input n(Application_Links *app)
|
||||||
#define GET_EVENT_MESSAGE_SIG(n) Event_Message 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_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||||
typedef BUFFER_SEEK_SIG(Buffer_Seek_Function);
|
typedef BUFFER_SEEK_SIG(Buffer_Seek_Function);
|
||||||
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_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_FIRST_SIG(Get_View_First_Function);
|
||||||
typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function);
|
typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function);
|
||||||
typedef GET_VIEW_SIG(Get_View_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_POST_FADE_SIG(View_Post_Fade_Function);
|
||||||
typedef VIEW_SET_PASTE_REWRITE__SIG(View_Set_Paste_Rewrite__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_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_USER_INPUT_SIG(Get_User_Input_Function);
|
||||||
typedef GET_COMMAND_INPUT_SIG(Get_Command_Input_Function);
|
typedef GET_COMMAND_INPUT_SIG(Get_Command_Input_Function);
|
||||||
typedef GET_EVENT_MESSAGE_SIG(Get_Event_Message_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_Replace_Range_Function *buffer_replace_range;
|
||||||
Buffer_Seek_Function *buffer_seek;
|
Buffer_Seek_Function *buffer_seek;
|
||||||
Buffer_Set_Setting_Function *buffer_set_setting;
|
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_First_Function *get_view_first;
|
||||||
Get_View_Next_Function *get_view_next;
|
Get_View_Next_Function *get_view_next;
|
||||||
Get_View_Function *get_view;
|
Get_View_Function *get_view;
|
||||||
|
@ -137,8 +139,6 @@ struct Application_Links{
|
||||||
View_Post_Fade_Function *view_post_fade;
|
View_Post_Fade_Function *view_post_fade;
|
||||||
View_Set_Paste_Rewrite__Function *view_set_paste_rewrite_;
|
View_Set_Paste_Rewrite__Function *view_set_paste_rewrite_;
|
||||||
View_Get_Paste_Rewrite__Function *view_get_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_User_Input_Function *get_user_input;
|
||||||
Get_Command_Input_Function *get_command_input;
|
Get_Command_Input_Function *get_command_input;
|
||||||
Get_Event_Message_Function *get_event_message;
|
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_replace_range = external_buffer_replace_range;\
|
||||||
app_links->buffer_seek = external_buffer_seek;\
|
app_links->buffer_seek = external_buffer_seek;\
|
||||||
app_links->buffer_set_setting = external_buffer_set_setting;\
|
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_first = external_get_view_first;\
|
||||||
app_links->get_view_next = external_get_view_next;\
|
app_links->get_view_next = external_get_view_next;\
|
||||||
app_links->get_view = external_get_view;\
|
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_post_fade = external_view_post_fade;\
|
||||||
app_links->view_set_paste_rewrite_ = external_view_set_paste_rewrite_;\
|
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_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_user_input = external_get_user_input;\
|
||||||
app_links->get_command_input = external_get_command_input;\
|
app_links->get_command_input = external_get_command_input;\
|
||||||
app_links->get_event_message = external_get_event_message;\
|
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){
|
CUSTOM_COMMAND_SIG(open_my_files){
|
||||||
// TODO(allen|a4.0.8): comment
|
// TODO(allen|a4.0.8): comment
|
||||||
View_Summary view = app->get_active_view(app);
|
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){
|
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));
|
append(&file_name, make_string(short_file_name, size));
|
||||||
|
|
||||||
exec_command(app, cmdid_change_active_panel);
|
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){
|
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);
|
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;
|
i32_Rect rect;
|
||||||
rect.x0 = l; rect.y0 = t;
|
rect.x0 = l; rect.y0 = t;
|
||||||
rect.x1 = r; rect.y1 = b;
|
rect.x1 = r; rect.y1 = b;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline i32_Rect
|
inline i32_Rect
|
||||||
|
@ -41,7 +41,7 @@ i32R(f32_Rect r){
|
||||||
rect.y0 = (int32_t)r.y0;
|
rect.y0 = (int32_t)r.y0;
|
||||||
rect.x1 = (int32_t)r.x1;
|
rect.x1 = (int32_t)r.x1;
|
||||||
rect.y1 = (int32_t)r.y1;
|
rect.y1 = (int32_t)r.y1;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline i32_Rect
|
inline i32_Rect
|
||||||
|
@ -49,7 +49,7 @@ i32XYWH(int32_t x, int32_t y, int32_t w, int32_t h){
|
||||||
i32_Rect rect;
|
i32_Rect rect;
|
||||||
rect.x0 = x; rect.y0 = y;
|
rect.x0 = x; rect.y0 = y;
|
||||||
rect.x1 = x+w; rect.y1 = y+h;
|
rect.x1 = x+w; rect.y1 = y+h;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32_Rect
|
inline f32_Rect
|
||||||
|
@ -57,7 +57,7 @@ f32R(float l, float t, float r, float b){
|
||||||
f32_Rect rect;
|
f32_Rect rect;
|
||||||
rect.x0 = l; rect.y0 = t;
|
rect.x0 = l; rect.y0 = t;
|
||||||
rect.x1 = r; rect.y1 = b;
|
rect.x1 = r; rect.y1 = b;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32_Rect
|
inline f32_Rect
|
||||||
|
@ -67,7 +67,7 @@ f32R(i32_Rect r){
|
||||||
rect.y0 = (float)r.y0;
|
rect.y0 = (float)r.y0;
|
||||||
rect.x1 = (float)r.x1;
|
rect.x1 = (float)r.x1;
|
||||||
rect.y1 = (float)r.y1;
|
rect.y1 = (float)r.y1;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32_Rect
|
inline f32_Rect
|
||||||
|
@ -75,7 +75,7 @@ f32XYWH(float x, float y, float w, float h){
|
||||||
f32_Rect rect;
|
f32_Rect rect;
|
||||||
rect.x0 = x; rect.y0 = y;
|
rect.x0 = x; rect.y0 = y;
|
||||||
rect.x1 = x+w; rect.y1 = y+h;
|
rect.x1 = x+w; rect.y1 = y+h;
|
||||||
return rect;
|
return(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
|
|
12
4ed.cpp
12
4ed.cpp
|
@ -1793,23 +1793,23 @@ App_Init_Sig(app_init){
|
||||||
|
|
||||||
Font_Setup font_setup[] = {
|
Font_Setup font_setup[] = {
|
||||||
{literal("LiberationSans-Regular.ttf"),
|
{literal("LiberationSans-Regular.ttf"),
|
||||||
literal("liberation sans"),
|
literal("Liberation Sans"),
|
||||||
font_size},
|
font_size},
|
||||||
|
|
||||||
{literal("liberation-mono.ttf"),
|
{literal("liberation-mono.ttf"),
|
||||||
literal("liberation mono"),
|
literal("Liberation Mono"),
|
||||||
font_size},
|
font_size},
|
||||||
|
|
||||||
{literal("Hack-Regular.ttf"),
|
{literal("Hack-Regular.ttf"),
|
||||||
literal("hack"),
|
literal("Hack"),
|
||||||
font_size},
|
font_size},
|
||||||
|
|
||||||
{literal("CutiveMono-Regular.ttf"),
|
{literal("CutiveMono-Regular.ttf"),
|
||||||
literal("cutive mono"),
|
literal("Cutive Mono"),
|
||||||
font_size},
|
font_size},
|
||||||
|
|
||||||
{literal("Inconsolata-Regular.ttf"),
|
{literal("Inconsolata-Regular.ttf"),
|
||||||
literal("inconsolata"),
|
literal("Inconsolata"),
|
||||||
font_size},
|
font_size},
|
||||||
};
|
};
|
||||||
i32 font_count = ArrayCount(font_setup);
|
i32 font_count = ArrayCount(font_setup);
|
||||||
|
@ -2650,7 +2650,7 @@ App_Step_Sig(app_step){
|
||||||
"\n"
|
"\n"
|
||||||
"New in alpha 4.0.7:\n"
|
"New in alpha 4.0.7:\n"
|
||||||
"-Right click sets the mark\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"
|
"-<alt d> opens a debug view, see more in README.txt\n"
|
||||||
"\n"
|
"\n"
|
||||||
"New in alpha 4.0.6:\n"
|
"New in alpha 4.0.6:\n"
|
||||||
|
|
|
@ -129,15 +129,24 @@ imp_get_file(Command_Data *cmd, Buffer_Summary *buffer){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal View*
|
internal View*
|
||||||
imp_get_view(Command_Data *cmd, View_Summary *view){
|
imp_get_view(Command_Data *cmd, int view_id){
|
||||||
View *vptr = 0;
|
|
||||||
Live_Views *live_set = cmd->live_set;
|
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){
|
if (view_id >= 0 && view_id < live_set->max){
|
||||||
vptr = live_set->views + view_id;
|
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);
|
return(vptr);
|
||||||
|
@ -652,7 +661,7 @@ BUFFER_SET_SETTING_SIG(external_buffer_set_setting){
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
BUFFER_SAVE_SIG(external_buffer_save){
|
SAVE_BUFFER_SIG(external_save_buffer){
|
||||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||||
System_Functions *system = cmd->system;
|
System_Functions *system = cmd->system;
|
||||||
Models *models = cmd->models;
|
Models *models = cmd->models;
|
||||||
|
@ -670,6 +679,93 @@ BUFFER_SAVE_SIG(external_buffer_save){
|
||||||
return(result);
|
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){
|
GET_VIEW_FIRST_SIG(external_get_view_first){
|
||||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||||
Editing_Layout *layout = &cmd->models->layout;
|
Editing_Layout *layout = &cmd->models->layout;
|
||||||
|
@ -913,69 +1009,6 @@ VIEW_GET_PASTE_REWRITE__SIG(external_view_get_paste_rewrite_){
|
||||||
return(result);
|
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){
|
GET_USER_INPUT_SIG(external_get_user_input){
|
||||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||||
System_Functions *system = cmd->system;
|
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_);
|
file->name.extension = make_fixed_width_string(file->name.extension_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
internal void
|
||||||
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
file_set_name(Working_Set *working_set, Editing_File *file, String filename){
|
||||||
String f, ext;
|
String ext;
|
||||||
|
|
||||||
Assert(file->name.live_name.str != 0);
|
Assert(file->name.live_name.str != 0);
|
||||||
|
|
||||||
f = make_string_slowly(filename);
|
copy_checked(&file->name.source_path, filename);
|
||||||
copy_checked(&file->name.source_path, f);
|
|
||||||
|
|
||||||
file->name.live_name.size = 0;
|
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){
|
if (file->name.source_path.size == file->name.live_name.size){
|
||||||
file->name.extension.size = 0;
|
file->name.extension.size = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ext = file_extension(f);
|
ext = file_extension(filename);
|
||||||
copy(&file->name.extension, ext);
|
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
|
inline void
|
||||||
file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){
|
file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){
|
||||||
u64 stamp = system->file_time_stamp(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;
|
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
|
inline i32
|
||||||
view_wrapped_line_span(f32 line_width, f32 max_width){
|
view_wrapped_line_span(f32 line_width, f32 max_width){
|
||||||
i32 line_count = CEIL32(line_width / max_width);
|
i32 line_count = CEIL32(line_width / max_width);
|
||||||
|
@ -700,7 +692,8 @@ view_measure_wraps(General_Memory *general, View *view){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
file_create_from_string(System_Functions *system, Models *models,
|
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;
|
Font_Set *font_set = models->font_set;
|
||||||
Working_Set *working_set = &models->working_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_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->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;
|
Render_Font *font = get_font_info(font_set, file->state.font_id)->font;
|
||||||
float *advance_data = 0;
|
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;
|
u32 char_color = main_color;
|
||||||
if (item->flags & BRFlag_Special_Character) char_color = special_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 &&
|
if (view->file_data.show_whitespace && highlight_color == 0 &&
|
||||||
char_is_whitespace((char)item->glyphid)){
|
char_is_whitespace((char)item->glyphid)){
|
||||||
highlight_this_color = style->main.highlight_white_color;
|
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);
|
font__insert(&set->used_slots, slot);
|
||||||
|
|
||||||
Render_Font *font = (Render_Font*)(slot + 1);
|
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;
|
info->font = font;
|
||||||
slot->font_id = font_id;
|
slot->font_id = font_id;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +185,10 @@ font_set_add(Partition *partition, Font_Set *set,
|
||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->name = name;
|
info->name = name;
|
||||||
info->pt_size = pt_size;
|
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->height = dummy_font.height;
|
||||||
info->advance = dummy_font.advance;
|
info->advance = dummy_font.advance;
|
||||||
|
|
||||||
|
|
|
@ -165,19 +165,56 @@ private_draw_gradient(Render_Target *target, f32_Rect rect,
|
||||||
glEnd();
|
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
|
inline void
|
||||||
private_draw_glyph(Render_Target *target, Render_Font *font,
|
private_draw_glyph(Render_Target *target, Render_Font *font,
|
||||||
u8 character, f32 x, f32 y, u32 color){
|
u8 character, f32 x, f32 y, u32 color){
|
||||||
f32 x_shift, y_shift;
|
Render_Quad q = get_render_quad(
|
||||||
x_shift = 0;
|
font->glyphs + character,
|
||||||
y_shift = (f32)font->ascent;
|
font->tex_width, font->tex_height, x, y
|
||||||
|
);
|
||||||
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);
|
|
||||||
|
|
||||||
draw_set_color(target, color);
|
draw_set_color(target, color);
|
||||||
draw_bind_texture(target, font->tex);
|
draw_bind_texture(target, font->tex);
|
||||||
|
@ -194,19 +231,18 @@ private_draw_glyph(Render_Target *target, Render_Font *font,
|
||||||
inline void
|
inline void
|
||||||
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
|
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
|
||||||
f32 x, f32 y, f32 advance, u32 color){
|
f32 x, f32 y, f32 advance, u32 color){
|
||||||
f32 x_shift, y_shift;
|
|
||||||
i32 left = font->chardata[character].x0;
|
f32 left = font->glyphs[character].x0;
|
||||||
i32 right = font->chardata[character].x1;
|
f32 right = font->glyphs[character].x1;
|
||||||
i32 width = (right - left);
|
f32 width = (right - left);
|
||||||
x_shift = (f32)(advance - width) * .5f - font->chardata[character].xoff;
|
f32 x_shift = (advance - width) * .5f;
|
||||||
y_shift = (f32)font->ascent;
|
|
||||||
|
|
||||||
x += x_shift;
|
x += x_shift;
|
||||||
y += y_shift;
|
|
||||||
|
|
||||||
stbtt_aligned_quad q;
|
Render_Quad q = get_exact_render_quad(
|
||||||
stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
|
font->glyphs + character,
|
||||||
character, &x, &y, &q, 0);
|
font->tex_width, font->tex_height, x, y
|
||||||
|
);
|
||||||
|
|
||||||
draw_set_color(target, color);
|
draw_set_color(target, color);
|
||||||
draw_bind_texture(target, font->tex);
|
draw_bind_texture(target, font->tex);
|
||||||
|
@ -305,6 +341,23 @@ launch_rendering(Render_Target *target){
|
||||||
|
|
||||||
#undef ExtractStruct
|
#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
|
// TODO(allen): Put the burden of translation outside
|
||||||
// of this function (and other functions implementing
|
// of this function (and other functions implementing
|
||||||
// the same interface).
|
// the same interface).
|
||||||
|
@ -324,7 +377,7 @@ draw_font_load(Partition *part,
|
||||||
|
|
||||||
i32 result = 1;
|
i32 result = 1;
|
||||||
|
|
||||||
stbtt_packedchar *chardata = font_out->chardata;
|
stbtt_packedchar chardata[256];
|
||||||
|
|
||||||
File_Data file = sysshared_load_file(filename.str);
|
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_width = tex_width;
|
||||||
font_out->tex_height = tex_height;
|
font_out->tex_height = tex_height;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
stbtt_pack_context spc;
|
stbtt_pack_context spc;
|
||||||
|
|
||||||
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height,
|
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height,
|
||||||
|
@ -380,6 +434,7 @@ draw_font_load(Partition *part,
|
||||||
else{
|
else{
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (result){
|
if (result){
|
||||||
GLuint font_tex;
|
GLuint font_tex;
|
||||||
|
@ -395,21 +450,37 @@ draw_font_load(Partition *part,
|
||||||
font_out->tex = font_tex;
|
font_out->tex = font_tex;
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
font_out->chardata['\r'] = font_out->chardata[' '];
|
f32 *advance_data = font_out->advance_data;
|
||||||
font_out->chardata['\n'] = font_out->chardata[' '];
|
Glyph_Data *glyphs = font_out->glyphs;
|
||||||
font_out->chardata['\t'] = font_out->chardata[' '];
|
for (u8 code_point = 0; code_point < 128; ++code_point){
|
||||||
font_out->chardata['\t'].xadvance *= tab_width;
|
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;
|
i32 max_advance = 0;
|
||||||
for (u8 code_point = 0; code_point < 128; ++code_point){
|
for (u8 code_point = 0; code_point < 128; ++code_point){
|
||||||
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
|
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
|
||||||
font_out->glyphs[code_point].exists = 1;
|
font_out->glyphs[code_point].exists = 1;
|
||||||
i32 advance = CEIL32(font_out->chardata[code_point].xadvance);
|
i32 advance = CEIL32(advance_data[code_point]);
|
||||||
if (max_advance < advance) max_advance = advance;
|
if (max_advance < advance){
|
||||||
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
|
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;
|
font_out->advance = max_advance - 1;
|
||||||
|
|
|
@ -12,25 +12,14 @@
|
||||||
#ifndef FRED_RENDERING_H
|
#ifndef FRED_RENDERING_H
|
||||||
#define 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{
|
struct Glyph_Data{
|
||||||
b32 exists;
|
b32 exists;
|
||||||
|
|
||||||
|
f32 x0, x1;
|
||||||
|
f32 y0, y1;
|
||||||
|
|
||||||
|
f32 xoff, yoff;
|
||||||
|
f32 xoff2, yoff2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Render_Font{
|
struct Render_Font{
|
||||||
|
@ -38,8 +27,10 @@ struct Render_Font{
|
||||||
String name;
|
String name;
|
||||||
b32 loaded;
|
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];
|
Glyph_Data glyphs[256];
|
||||||
stbtt_packedchar chardata[256];
|
|
||||||
float advance_data[256];
|
float advance_data[256];
|
||||||
i32 height, ascent, descent, line_skip;
|
i32 height, ascent, descent, line_skip;
|
||||||
i32 advance;
|
i32 advance;
|
||||||
|
@ -114,6 +105,7 @@ typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
|
||||||
#define Font_Load_Sig(name) i32 name( \
|
#define Font_Load_Sig(name) i32 name( \
|
||||||
Render_Font *font_out, \
|
Render_Font *font_out, \
|
||||||
char *filename, \
|
char *filename, \
|
||||||
|
char *fontname, \
|
||||||
i32 pt_size, \
|
i32 pt_size, \
|
||||||
i32 tab_width, \
|
i32 tab_width, \
|
||||||
b32 store_texture)
|
b32 store_texture)
|
||||||
|
|
|
@ -115,11 +115,6 @@ font_predict_size(i32 pt_size){
|
||||||
return pt_size*pt_size*128;
|
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
|
internal void
|
||||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||||
u8 character, f32 x, f32 y, f32 advance, u32 color){
|
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);
|
font_set_use(target->partition, &target->font_set, font_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32
|
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||||
f32 x = 0;
|
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){
|
for (i32 i = 0; str[i]; ++i){
|
||||||
u8 c = str[i];
|
u8 c = str[i] % 128;
|
||||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
x += advance_data[c];
|
||||||
c = c % 128;
|
|
||||||
x += font_get_glyph_width(target, font_id, c);
|
|
||||||
}
|
}
|
||||||
return x;
|
}
|
||||||
|
|
||||||
|
return(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
font_string_width(Render_Target *target, i16 font_id, String str){
|
font_string_width(Render_Target *target, i16 font_id, String str){
|
||||||
f32 x = 0;
|
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){
|
for (i32 i = 0; i < str.size; ++i){
|
||||||
u8 c = str.str[i];
|
u8 c = str.str[i] % 128;
|
||||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
x += advance_data[c];
|
||||||
c = c % 128;
|
|
||||||
x += font_get_glyph_width(target, font_id, c);
|
|
||||||
}
|
}
|
||||||
return x;
|
}
|
||||||
|
|
||||||
|
return(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
draw_string(Render_Target *target, i16 font_id,
|
draw_string(Render_Target *target, i16 font_id,
|
||||||
char *str, i32 x_, i32 y, u32 color){
|
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){
|
for (i32 i = 0; str[i]; ++i){
|
||||||
u8 c = str[i];
|
u8 c = str[i] % 128;
|
||||||
// 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);
|
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
|
internal f32
|
||||||
draw_string_mono(Render_Target *target, i16 font_id,
|
draw_string_mono(Render_Target *target, i16 font_id,
|
||||||
char *str, f32 x, f32 y, f32 advance, u32 color){
|
char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||||
for (i32 i = 0; str[i]; ++i){
|
for (i32 i = 0; str[i]; ++i){
|
||||||
u8 c = str[i];
|
u8 c = str[i] % 128;
|
||||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
|
||||||
c = c % 128;
|
|
||||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||||
x += advance;
|
x += advance;
|
||||||
}
|
}
|
||||||
return x;
|
return(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
draw_string(Render_Target *target, i16 font_id,
|
draw_string(Render_Target *target, i16 font_id,
|
||||||
String str, i32 x_, i32 y, u32 color){
|
String str, i32 x_, i32 y, u32 color){
|
||||||
f32 x = (f32)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; i < str.size; ++i){
|
for (i32 i = 0; i < str.size; ++i){
|
||||||
u8 c = str.str[i];
|
u8 c = str.str[i] % 128;
|
||||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||||
c = c % 128;
|
x += advance_data[c];
|
||||||
font_draw_glyph(target, font_id, c,
|
|
||||||
x, (f32)y, color);
|
|
||||||
x += font_get_glyph_width(target, font_id, c);
|
|
||||||
}
|
}
|
||||||
return x;
|
}
|
||||||
|
|
||||||
|
return(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal f32
|
internal f32
|
||||||
draw_string_mono(Render_Target *target, i16 font_id,
|
draw_string_mono(Render_Target *target, i16 font_id,
|
||||||
String str, f32 x, f32 y, f32 advance, u32 color){
|
String str, f32 x, f32 y, f32 advance, u32 color){
|
||||||
for (i32 i = 0; i < str.size; ++i){
|
for (i32 i = 0; i < str.size; ++i){
|
||||||
u8 c = str.str[i];
|
u8 c = str.str[i] % 128;
|
||||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
|
||||||
c = c % 128;
|
|
||||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||||
x += advance;
|
x += advance;
|
||||||
}
|
}
|
||||||
return x;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// 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_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_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 manipulation
|
||||||
View_Summary Get_View_First(Application_Links *app);
|
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);
|
void View_Set_Paste_Rewrite_(Application_Links *app, View_Summary *view);
|
||||||
int View_Get_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
|
// Directly get user input
|
||||||
User_Input Get_User_Input(Application_Links *app, unsigned int get_type, unsigned int abort_type);
|
User_Input Get_User_Input(Application_Links *app, unsigned int get_type, unsigned int abort_type);
|
||||||
User_Input Get_Command_Input(Application_Links *app);
|
User_Input Get_Command_Input(Application_Links *app);
|
||||||
|
|
|
@ -520,7 +520,8 @@ SwitchToOrLoadFile(struct Application_Links *app, String FileName, bool CreateIf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE(allen): This opens the file and puts it in &view
|
// 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);
|
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);
|
exec_command(app, cmdid_save);
|
||||||
#endif
|
#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
|
#if 0
|
||||||
|
@ -1153,7 +1154,7 @@ OpenProject(Application_Links *app, char *ProjectFileName)
|
||||||
exec_command(app, cmdid_interactive_open);
|
exec_command(app, cmdid_interactive_open);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
app->view_open_file(app, 0, dir.str, dir.size, true);
|
view_open_file(app, 0, dir.str, dir.size, true);
|
||||||
++TotalOpenAttempts;
|
++TotalOpenAttempts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1177,6 +1177,7 @@ Font_Load_Sig(system_draw_font_load){
|
||||||
success = win32_draw_font_load(&win32vars.font_part,
|
success = win32_draw_font_load(&win32vars.font_part,
|
||||||
font_out,
|
font_out,
|
||||||
filename,
|
filename,
|
||||||
|
fontname,
|
||||||
pt_size,
|
pt_size,
|
||||||
tab_width,
|
tab_width,
|
||||||
oversample,
|
oversample,
|
||||||
|
|
302
win32_font.cpp
302
win32_font.cpp
|
@ -9,25 +9,36 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
struct Glyph_Bitmap{
|
struct GMetrics{
|
||||||
HBITMAP bitmap_handle;
|
f32 advance;
|
||||||
char *pixels;
|
f32 xoff;
|
||||||
|
f32 xoff2;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
internal b32
|
||||||
win32_get_box(HDC dc, TCHAR character, int *x0, int *y0, int *x1, int *y1){
|
win32_glyph_metrics(HDC dc, int code, GMetrics *gmetrics){
|
||||||
SIZE size;
|
b32 result = false;
|
||||||
GetTextExtentPoint32A(dc, &character, 1, &size);
|
ABCFLOAT abc = {0};
|
||||||
*x0 = 0;
|
INT width;
|
||||||
*y0 = 0;
|
|
||||||
*x1 = size.cx;
|
if (GetCharWidth32W(dc, code, code, &width)){
|
||||||
*y1 = size.cy;
|
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
|
internal i32
|
||||||
win32_draw_font_load(Partition *part,
|
win32_draw_font_load(Partition *part,
|
||||||
Render_Font *font_out,
|
Render_Font *font_out,
|
||||||
char *filename_untranslated,
|
char *filename_untranslated,
|
||||||
|
char *fontname,
|
||||||
i32 pt_size,
|
i32 pt_size,
|
||||||
i32 tab_width,
|
i32 tab_width,
|
||||||
i32 oversample,
|
i32 oversample,
|
||||||
|
@ -36,77 +47,127 @@ win32_draw_font_load(Partition *part,
|
||||||
char space_[1024];
|
char space_[1024];
|
||||||
String filename = make_fixed_width_string(space_);
|
String filename = make_fixed_width_string(space_);
|
||||||
b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated);
|
b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated);
|
||||||
if (!translate_success) return 0;
|
|
||||||
|
|
||||||
i32 result = 0;
|
i32 result = 0;
|
||||||
|
|
||||||
|
if (translate_success){
|
||||||
|
HDC dc = GetDC(win32vars.window_handle);
|
||||||
|
|
||||||
AddFontResourceEx(filename.str, FR_PRIVATE, 0);
|
AddFontResourceEx(filename.str, FR_PRIVATE, 0);
|
||||||
|
|
||||||
HFONT font_handle =
|
HFONT font_handle = CreateFont(
|
||||||
CreateFontA(pt_size, 0, 0, 0,
|
pt_size,
|
||||||
FW_NORMAL, // WEIGHT
|
0,
|
||||||
FALSE, // ITALICS
|
0,
|
||||||
FALSE, // UNDERLINE
|
0,
|
||||||
FALSE, // STRIKE-OUT
|
FW_NORMAL,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
ANSI_CHARSET,
|
ANSI_CHARSET,
|
||||||
OUT_DEFAULT_PRECIS,
|
OUT_DEFAULT_PRECIS,
|
||||||
CLIP_DEFAULT_PRECIS,
|
CLIP_DEFAULT_PRECIS,
|
||||||
ANTIALIASED_QUALITY,
|
DEFAULT_QUALITY,
|
||||||
DEFAULT_PITCH|FF_DONTCARE,
|
FF_DONTCARE | DEFAULT_PITCH,
|
||||||
filename.str);
|
fontname
|
||||||
|
);
|
||||||
|
HBITMAP bmp_handle = CreateBitmap(
|
||||||
|
pt_size*2, pt_size*2,
|
||||||
|
4, 32,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
if (font_handle){
|
|
||||||
HDC dc = CreateCompatibleDC(0);
|
|
||||||
|
|
||||||
if (dc){
|
if (font_handle != 0 && bmp_handle != 0){
|
||||||
TEXTMETRIC metrics;
|
SelectObject(dc, font_handle);
|
||||||
GetTextMetrics(dc, &metrics);
|
SelectObject(dc, bmp_handle);
|
||||||
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;
|
|
||||||
|
|
||||||
|
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;
|
result = 1;
|
||||||
if (store_texture){
|
}
|
||||||
|
else{
|
||||||
Temp_Memory temp = begin_temp_memory(part);
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
|
|
||||||
i32 tex_width = pt_size*16*oversample;
|
i32 tex_width = pt_size*16;
|
||||||
i32 tex_height = pt_size*16*oversample;
|
i32 tex_height = pt_size*16;
|
||||||
|
void *block = sysshared_push_block(part, tex_width * tex_height);
|
||||||
|
|
||||||
Glyph_Bitmap glyph_bitmap;
|
font_out->tex_width = tex_width;
|
||||||
glyph_bitmap.bitmap_handle = CreateCompatibleBitmap(dc, tex_width, tex_height);
|
font_out->tex_height = tex_height;
|
||||||
glyph_bitmap.pixels = push_array(part, char, tex_width*tex_height);
|
|
||||||
|
|
||||||
SelectObject(dc, glyph_bitmap.bitmap_handle);
|
result = 1;
|
||||||
SelectObject(dc, font_handle);
|
/////////////////////////////////////////////////////////////////
|
||||||
|
stbtt_pack_context spc_;
|
||||||
|
|
||||||
SetBkColor(dc, RGB(0, 0, 0));
|
int pack_result;
|
||||||
|
{
|
||||||
stbtt_pack_context context = {0};
|
stbtt_pack_context *spc = &spc_;
|
||||||
stbtt_PackBegin(&context, (unsigned char*)glyph_bitmap.pixels, tex_width, tex_height, 0, 1, part);
|
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;
|
stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
|
||||||
int first_unicode_char_in_range = 0;
|
int num_nodes = pw - padding;
|
||||||
int num_chars_in_range = 128;
|
stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
|
||||||
stbtt_packedchar *chardata_for_range = font_out->chardata;
|
|
||||||
|
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;
|
stbtt_pack_range range;
|
||||||
range.first_unicode_char_in_range = first_unicode_char_in_range;
|
range.first_unicode_char_in_range = 0;
|
||||||
range.num_chars_in_range = num_chars_in_range;
|
range.num_chars_in_range = 128;
|
||||||
range.chardata_for_range = chardata_for_range;
|
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 = ⦥
|
stbtt_pack_range *ranges = ⦥
|
||||||
int num_ranges = 1;
|
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;
|
int i,j,k,n, return_value = 1;
|
||||||
stbrp_context *context = (stbrp_context *) spc->pack_info;
|
stbrp_context *context = (stbrp_context *) spc->pack_info;
|
||||||
stbrp_rect *rects;
|
stbrp_rect *rects;
|
||||||
|
@ -124,19 +185,32 @@ win32_draw_font_load(Partition *part,
|
||||||
n += ranges[i].num_chars_in_range;
|
n += ranges[i].num_chars_in_range;
|
||||||
|
|
||||||
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
|
rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
|
||||||
if (rects == NULL)
|
if (rects == NULL){
|
||||||
return 0;
|
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;
|
k=0;
|
||||||
for (i=0; i < num_ranges; ++i) {
|
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) {
|
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);
|
GMetrics gmetrics;
|
||||||
win32_get_box(dc, character, &x0, &y0, &x1, &y1);
|
|
||||||
|
|
||||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
if (!win32_glyph_metrics(dc, ranges[i].first_unicode_char_in_range + j, &gmetrics)){
|
||||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
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;
|
++k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,47 +219,65 @@ win32_draw_font_load(Partition *part,
|
||||||
|
|
||||||
k = 0;
|
k = 0;
|
||||||
for (i=0; i < num_ranges; ++i) {
|
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) {
|
for (j=0; j < ranges[i].num_chars_in_range; ++j) {
|
||||||
stbrp_rect *r = &rects[k];
|
stbrp_rect *r = &rects[k];
|
||||||
if (r->was_packed) {
|
if (r->was_packed) {
|
||||||
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
||||||
int advance, x0,y0,x1,y1;
|
//int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j);
|
||||||
int glyph = 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;
|
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
|
// pad on left and top
|
||||||
r->x += pad;
|
r->x += pad;
|
||||||
r->y += pad;
|
r->y += pad;
|
||||||
r->w -= pad;
|
r->w -= pad;
|
||||||
r->h -= pad;
|
r->h -= pad;
|
||||||
|
|
||||||
SetTextColor(dc, RGB(255, 255, 255));
|
#if 0
|
||||||
TextOutA(dc, r->x, r->y, &character, 1);
|
int advance, lsb, x0,y0,x1,y1;
|
||||||
|
|
||||||
if (spc->h_oversample > 1)
|
stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb);
|
||||||
stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
|
stbtt_GetGlyphBitmapBox(&info, glyph,
|
||||||
r->w, r->h, spc->stride_in_bytes,
|
scale * spc->h_oversample,
|
||||||
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)
|
GMetrics gmetrics;
|
||||||
stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
|
if (!win32_glyph_metrics(dc, code, &gmetrics)){
|
||||||
r->w, r->h, spc->stride_in_bytes,
|
result = false;
|
||||||
spc->v_oversample);
|
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->x0 = (stbtt_int16) r->x;
|
||||||
bc->y0 = (stbtt_int16) r->y;
|
bc->y0 = (stbtt_int16) r->y;
|
||||||
bc->x1 = (stbtt_int16) (r->x + r->w);
|
bc->x1 = (stbtt_int16) (r->x + r->w);
|
||||||
bc->y1 = (stbtt_int16) (r->y + r->h);
|
bc->y1 = (stbtt_int16) (r->y + r->h);
|
||||||
bc->xadvance = (float) advance;
|
bc->xadvance = (float) advance;
|
||||||
bc->xoff = (float) x0 * recip_h + sub_x;
|
bc->xoff = (float) x0;
|
||||||
bc->yoff = (float) y0 * recip_v + sub_y;
|
bc->yoff = (float) y0;
|
||||||
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
|
bc->xoff2 = (float) (x0 + r->w);
|
||||||
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
|
bc->yoff2 = (float) (y0 + r->h);
|
||||||
} else {
|
} else {
|
||||||
return_value = 0; // if any fail, report failure
|
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);
|
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;
|
GLuint font_tex;
|
||||||
glGenTextures(1, &font_tex);
|
glGenTextures(1, &font_tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, 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_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
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;
|
font_out->tex = font_tex;
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
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['\n'] = font_out->chardata[' '];
|
||||||
font_out->chardata['\t'] = font_out->chardata[' '];
|
font_out->chardata['\t'] = font_out->chardata[' '];
|
||||||
font_out->chardata['\t'].xadvance *= tab_width;
|
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);
|
end_temp_memory(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteObject(font_handle);
|
DeleteObject(font_handle);
|
||||||
|
DeleteObject(bmp_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDC(win32vars.window_handle, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
|
|
Loading…
Reference in New Issue