From dc90ec0c83cc26ae22c114176c1dccbf0d802a65 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Mar 2017 20:20:24 -0500 Subject: [PATCH] setup the font interface, complete with an opaque Render_Font; started breaking down the translation interface --- 4coder_lib/4coder_utf8.h | 9 + 4ed.cpp | 25 +-- 4ed_api_implementation.cpp | 96 ++++----- 4ed_app_target.cpp | 3 +- 4ed_file_view.cpp | 280 +++++++++++++------------- 4ed_rendering.h | 4 +- 4ed_rendering_helper.cpp | 13 +- 4ed_system.h | 14 +- 4ed_system_shared.cpp | 42 ++-- file/4coder_buffer.cpp | 268 ++++++++++++++---------- font/4coder_font_data.h | 29 ++- font/4coder_font_interface.h | 53 +++++ font/4coder_font_static_functions.cpp | 47 +++++ win32_4ed.cpp | 11 +- 14 files changed, 525 insertions(+), 369 deletions(-) create mode 100644 font/4coder_font_interface.h create mode 100644 font/4coder_font_static_functions.cpp diff --git a/4coder_lib/4coder_utf8.h b/4coder_lib/4coder_utf8.h index d60de499..76d6580d 100644 --- a/4coder_lib/4coder_utf8.h +++ b/4coder_lib/4coder_utf8.h @@ -40,6 +40,15 @@ typedef int32_t b32_4tech; #endif // standard preamble end +static b32_4tech +codepoint_is_whitespace(u32_4tech codepoint){ + b32_4tech result = false; + if (codepoint == ' ' || codepoint == '\r' || codepoint == '\n' || codepoint == '\t'){ + result = true; + } + return(result); +} + static u32_4tech utf8_to_u32_length_unchecked(u8_4tech *buffer, u32_4tech *length_out){ u32_4tech result = 0; diff --git a/4ed.cpp b/4ed.cpp index 2529edf2..6bd4792a 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -235,7 +235,7 @@ do_feedback_message(System_Functions *system, Models *models, String value, b32 for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_cursor_move(iter.view, pos); + view_cursor_move(system, iter.view, pos); } } } @@ -274,7 +274,7 @@ panel_make_empty(System_Functions *system, App_Vars *vars, Panel *panel){ Assert(panel->view == 0); new_view = live_set_alloc_view(&vars->live_set, panel, models); - view_set_file(new_view.view, models->scratch_buffer, models); + view_set_file(system, new_view.view, models->scratch_buffer, models); new_view.view->map = get_map(models, mapid_file); return(new_view.view); @@ -362,16 +362,15 @@ COMMAND_DECL(reopen){ init_normal_file(system, models, file, buffer, size); for (i32 i = 0; i < vptr_count; ++i){ - view_set_file(vptrs[i], file, models); + view_set_file(system, vptrs[i], file, models); int32_t line = line_number[i]; int32_t character = column_number[i]; *vptrs[i]->edit_pos = edit_poss[i]; - Full_Cursor cursor = view_compute_cursor(vptrs[i], seek_line_char(line, character), 0); + Full_Cursor cursor = view_compute_cursor(system, vptrs[i], seek_line_char(line, character), 0); - view_set_cursor(vptrs[i], cursor, true, - file->settings.unwrapped_lines); + view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines); } } else{ @@ -449,12 +448,11 @@ COMMAND_DECL(toggle_line_wrap){ if (file->settings.unwrapped_lines){ file->settings.unwrapped_lines = 0; view->edit_pos->scroll.target_x = 0; - view_cursor_move(view, view->edit_pos->cursor.pos); } else{ file->settings.unwrapped_lines = 1; - view_cursor_move(view, view->edit_pos->cursor.pos); } + view_cursor_move(system, view, view->edit_pos->cursor.pos); view_set_relative_scrolling(view, scrolling); } @@ -520,7 +518,7 @@ COMMAND_DECL(open_menu){ COMMAND_DECL(open_debug){ USE_VIEW(view); view_show_GUI(view, VUI_Debug); - view->debug_vars = debug_vars_zero(); + view->debug_vars = null_debug_vars; } COMMAND_DECL(user_callback){ @@ -1616,8 +1614,7 @@ update_cli_handle_without_file(System_Functions *system, Models *models, } internal i32 -update_cli_handle_with_file(System_Functions *system, Models *models, - CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ +update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ i32 result = 0; u32 amount = 0; @@ -1642,7 +1639,7 @@ update_cli_handle_with_file(System_Functions *system, Models *models, for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_cursor_move(iter.view, new_cursor); + view_cursor_move(system, iter.view, new_cursor); } } @@ -1947,7 +1944,7 @@ App_Step_Sig(app_step){ } if (i < models->layout.panel_count){ - view_set_file(panel->view, models->message_buffer, models); + view_set_file(system, panel->view, models->message_buffer, models); view_show_file(panel->view); ++i; panel = panel->next; @@ -2262,7 +2259,7 @@ App_Step_Sig(app_step){ if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){ if (file_scroll){ - view_set_scroll(view, ip_result.vars); + view_set_scroll(system, view, ip_result.vars); } else{ *scroll_vars = ip_result.vars; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 71a9cbe4..41726bce 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -64,7 +64,7 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Command_Data *cm } internal void -fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ +fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ Buffer_ID buffer_id = 0; File_Viewing_Data *data = &vptr->file_data; @@ -84,7 +84,7 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ view->buffer_id = buffer_id; - view->mark = view_compute_cursor(vptr, seek_pos(vptr->edit_pos->mark), 0); + view->mark = view_compute_cursor(system, vptr, seek_pos(vptr->edit_pos->mark), 0); view->cursor = vptr->edit_pos->cursor; view->preferred_x = vptr->edit_pos->preferred_x; @@ -96,8 +96,8 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ inline void -fill_view_summary(View_Summary *view, View *vptr, Command_Data *cmd){ - fill_view_summary(view, vptr, &cmd->vars->live_set, &cmd->models->working_set); +fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Command_Data *cmd){ + fill_view_summary(system, view, vptr, &cmd->vars->live_set, &cmd->models->working_set); } internal Editing_File* @@ -195,8 +195,7 @@ DOC_PARAM(command, The command parameter specifies the command that shall be exe DOC_PARAM(command_len, The parameter command_len specifies the length of the command string.) DOC_PARAM(flags, Flags for the behavior of the call are specified in the flags parameter.) DOC_RETURN(This call returns non-zero on success.) -DOC( -A call to exec_system_command executes a command as if called from the command line, and sends the output to a buffer. The buffer identifier can name a new buffer that does not exist, name a buffer that does exist, or provide the id of a buffer that does exist. +DOC(A call to exec_system_command executes a command as if called from the command line, and sends the output to a buffer. The buffer identifier can name a new buffer that does not exist, name a buffer that does exist, or provide the id of a buffer that does exist. If the buffer is not already in an open view and the view parameter is not NULL, then the provided view will display the output buffer. @@ -316,8 +315,8 @@ DOC_SEE(Command_Line_Interface_Flag) command_string = make_string_terminated(part, command, command_len); } - if (vptr && bind_to_new_view){ - view_set_file(vptr, file, models); + if (vptr != 0 && bind_to_new_view){ + view_set_file(system, vptr, file, models); view_show_file(vptr); } @@ -342,7 +341,7 @@ DOC_SEE(Command_Line_Interface_Flag) goto done; } - done: + done:; end_temp_memory(temp); return(result); } @@ -881,7 +880,7 @@ DOC_SEE(Buffer_Setting_ID) //Font_Info *font_info = get_font_info(models->font_set, font_id); //Render_Font *font = font_info->font; Render_Font *font = 0; - file_set_width(models, file, new_value, font); + file_set_width(system, models, file, new_value, font); } }break; @@ -895,7 +894,7 @@ DOC_SEE(Buffer_Setting_ID) //i16 font_id = file->settings.font_id; //Render_Font *font = get_font_info(models->font_set, font_id)->font; Render_Font *font = 0; - file_set_min_base_width(models, file, new_value, font); + file_set_min_base_width(system, models, file, new_value, font); } }break; @@ -986,7 +985,7 @@ DOC_SEE(Buffer_Setting_ID) file_allocate_character_starts_as_needed(&models->mem.general, file); buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); file_measure_wraps(models, file, font); - file_update_cursor_positions(models, file); + file_update_cursor_positions(system, models, file); } }break; @@ -1307,25 +1306,25 @@ internal_get_view_first(Command_Data *cmd, View_Summary *view){ Panel *panel = layout->used_sentinel.next; Assert(panel != &layout->used_sentinel); - fill_view_summary(view, panel->view, cmd); + System_Functions *system = cmd->system; + fill_view_summary(system, view, panel->view, cmd); } internal void internal_get_view_next(Command_Data *cmd, View_Summary *view){ + System_Functions *system = cmd->system; Editing_Layout *layout = &cmd->models->layout; Live_Views *live_set = &cmd->vars->live_set; int32_t index = view->view_id - 1; - View *vptr = 0; - Panel *panel = 0; if (index >= 0 && index < live_set->max){ - vptr = live_set->views + index; - panel = vptr->panel; + View *vptr = live_set->views + index; + Panel *panel = vptr->panel; if (panel){ panel = panel->next; } if (panel && panel != &layout->used_sentinel){ - fill_view_summary(view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + fill_view_summary(system, view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); } else{ *view = null_view_summary; @@ -1393,15 +1392,15 @@ DOC_RETURN(This call returns a summary that describes the indicated view if it i DOC_SEE(Access_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View_Summary view = {0}; Live_Views *live_set = cmd->live_set; i32 max = live_set->max; - View *vptr = 0; view_id -= 1; if (view_id >= 0 && view_id < max){ - vptr = live_set->views + view_id; - fill_view_summary(&view, vptr, live_set, &cmd->models->working_set); + View *vptr = live_set->views + view_id; + fill_view_summary(system, &view, vptr, live_set, &cmd->models->working_set); if (!access_test(view.lock_flags, access)){ view = null_view_summary; } @@ -1419,13 +1418,13 @@ DOC_SEE(set_active_view) DOC_SEE(Access_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; - + System_Functions *system = cmd->system; Panel *panel = cmd->models->layout.panels + cmd->models->layout.active_panel; Assert(panel->view != 0); View_Summary view = {0}; - fill_view_summary(&view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + fill_view_summary(system, &view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); if (!access_test(view.lock_flags, access)){ view = null_view_summary; } @@ -1486,7 +1485,7 @@ DOC_SEE(View_Split_Position) models->layout.active_panel = (i32)(split.panel - models->layout.panels); panel_make_empty(system, cmd->vars, split.panel); - fill_view_summary(&result, split.panel->view, cmd); + fill_view_summary(system, &result, split.panel->view, cmd); } return(result); @@ -1654,6 +1653,7 @@ DOC_RETURN(This call returns non-zero on success.) DOC_SEE(View_Setting_ID) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); bool32 result = false; @@ -1676,7 +1676,7 @@ DOC_SEE(View_Setting_ID) }break; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); @@ -1727,16 +1727,16 @@ DOC_SEE(Buffer_Seek) DOC_SEE(Full_Cursor) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); - Editing_File *file = 0; bool32 result = false; if (vptr){ - file = vptr->file_data.file; - if (file && !file->is_loading){ + Editing_File *file = vptr->file_data.file; + if (file != 0 && !file->is_loading){ result = true; - *cursor_out = view_compute_cursor(vptr, seek, 0); - fill_view_summary(view, vptr, cmd); + *cursor_out = view_compute_cursor(system, vptr, seek, 0); + fill_view_summary(system, view, vptr, cmd); } } @@ -1759,6 +1759,7 @@ cursor in the same column or x position. DOC_SEE(Buffer_Seek) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; bool32 result = false; @@ -1768,9 +1769,9 @@ DOC_SEE(Buffer_Seek) Assert(file); if (!file->is_loading){ result = true; - Full_Cursor cursor = view_compute_cursor(vptr, seek, 0); + Full_Cursor cursor = view_compute_cursor(system, vptr, seek, 0); view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines); - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } } @@ -1784,6 +1785,7 @@ DOC(TODO) DOC_SEE(GUI_Scroll_Vars) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; bool32 result = false; @@ -1792,8 +1794,8 @@ DOC_SEE(GUI_Scroll_Vars) file = vptr->file_data.file; if (file && !file->is_loading){ result = true; - view_set_scroll(vptr, scroll); - fill_view_summary(view, vptr, cmd); + view_set_scroll(system, vptr, scroll); + fill_view_summary(system, view, vptr, cmd); } } @@ -1810,6 +1812,7 @@ DOC(This call sets the the view's mark position.) DOC_SEE(Buffer_Seek) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; Full_Cursor cursor = {0}; @@ -1820,14 +1823,14 @@ DOC_SEE(Buffer_Seek) if (file && !file->is_loading){ if (seek.type != buffer_seek_pos){ result = true; - cursor = view_compute_cursor(vptr, seek, 0); + cursor = view_compute_cursor(system, vptr, seek, 0); vptr->edit_pos->mark = cursor.pos; } else{ result = true; vptr->edit_pos->mark = seek.pos; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } } @@ -1850,18 +1853,19 @@ and the turn_on set to false, will switch back to showing the cursor. ) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); bool32 result = false; if (vptr){ result = true; if (turn_on){ - view_set_temp_highlight(vptr, start, end); + view_set_temp_highlight(system, vptr, start, end); } else{ vptr->file_data.show_temp_highlight = 0; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); @@ -1874,33 +1878,29 @@ DOC_PARAM(view, The view parameter specifies the view in which to display the bu DOC_PARAM(buffer_id, The buffer_id parameter specifies which buffer to show in the view.) DOC_PARAM(flags, The flags parameter specifies behaviors for setting the buffer.) DOC_RETURN(This call returns non-zero on success.) -DOC -( -On success view_set_buffer sets the specified view's current buffer and -cancels and dialogue shown in the view and displays the file. -) +DOC(On success view_set_buffer sets the specified view's current buffer and cancels and dialogue shown in the view and displays the file.) DOC_SEE(Set_Buffer_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Models *models = cmd->models; - Editing_File *file = 0; bool32 result = false; if (vptr){ - file = working_set_get_active_file(&models->working_set, buffer_id); + Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id); - if (file){ + if (file != 0){ result = true; if (file != vptr->file_data.file){ - view_set_file(vptr, file, models); + view_set_file(system, vptr, file, models); if (!(flags & SetBuffer_KeepOriginalGUI)){ view_show_file(vptr); } } } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index b04c2072..82beb368 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -33,7 +33,6 @@ # include "4ed_debug_mem.h" #endif -#include "font/4coder_font_data.h" #include "4ed_rendering.h" #include "4ed.h" @@ -62,5 +61,7 @@ #include "4ed_file_view.cpp" #include "4ed.cpp" +#include "font/4coder_font_static_functions.cpp" + // BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index f5a21318..34948bf7 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -186,11 +186,7 @@ struct Debug_Vars{ i32 mode; i32 inspecting_view_id; }; -inline Debug_Vars -debug_vars_zero(){ - Debug_Vars vars = {0}; - return(vars); -} +global_const Debug_Vars null_debug_vars = {0}; struct View{ View_Persistent persistent; @@ -384,14 +380,11 @@ view_cursor_limits(View *view){ } internal Full_Cursor -view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ +view_compute_cursor(System_Functions *system, View *view, Buffer_Seek seek, b32 return_hint){ Editing_File *file = view->file_data.file; -#if 0 - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font; -#endif - Render_Font *font = 0; + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + Assert(font != 0); Full_Cursor result = {0}; @@ -461,7 +454,7 @@ view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ } inline Full_Cursor -view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ +view_compute_cursor_from_xy(System_Functions *system, View *view, f32 seek_x, f32 seek_y){ Buffer_Seek seek; if (view->file_data.file->settings.unwrapped_lines){ seek = seek_unwrapped_xy(seek_x, seek_y, 0); @@ -470,7 +463,7 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ seek = seek_wrapped_xy(seek_x, seek_y, 0); } - Full_Cursor result = view_compute_cursor(view, seek, 0); + Full_Cursor result = view_compute_cursor(system, view, seek, 0); return(result); } @@ -556,8 +549,7 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){ } internal b32 -view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, - Full_Cursor *cursor, f32 preferred_x){ +view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars scroll, Full_Cursor *cursor, f32 preferred_x){ b32 result = 0; if (view->edit_pos){ @@ -586,8 +578,7 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, cursor_y -= line_height; } - *cursor = view_compute_cursor_from_xy( - view, preferred_x, cursor_y); + *cursor = view_compute_cursor_from_xy(system, view, preferred_x, cursor_y); result = 1; } @@ -608,12 +599,11 @@ view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapp } internal void -view_set_scroll(View *view, GUI_Scroll_Vars scroll){ +view_set_scroll(System_Functions *system, View *view, GUI_Scroll_Vars scroll){ if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){ edit_pos_set_scroll(view->edit_pos, scroll); Full_Cursor cursor = view->edit_pos->cursor; - if (view_move_cursor_to_view(view, view->edit_pos->scroll, - &cursor, view->edit_pos->preferred_x)){ + if (view_move_cursor_to_view(system, view, view->edit_pos->scroll, &cursor, view->edit_pos->preferred_x)){ view->edit_pos->cursor = cursor; } } @@ -630,13 +620,12 @@ view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, } inline void -view_set_temp_highlight(View *view, i32 pos, i32 end_pos){ - view->file_data.temp_highlight = view_compute_cursor(view, seek_pos(pos), 0); +view_set_temp_highlight(System_Functions *system, View *view, i32 pos, i32 end_pos){ + view->file_data.temp_highlight = view_compute_cursor(system, view, seek_pos(pos), 0); view->file_data.temp_highlight_end_pos = end_pos; view->file_data.show_temp_highlight = 1; - view_set_cursor(view, view->file_data.temp_highlight, - 0, view->file_data.file->settings.unwrapped_lines); + view_set_cursor(view, view->file_data.temp_highlight, 0, view->file_data.file->settings.unwrapped_lines); } struct View_And_ID{ @@ -884,7 +873,7 @@ file_grow_starts_as_needed(General_Memory *general, Gap_Buffer *buffer, i32 addi } internal void -file_update_cursor_positions(Models *models, Editing_File *file){ +file_update_cursor_positions(System_Functions *system, Models *models, Editing_File *file){ Editing_Layout *layout = &models->layout; for (View_Iter iter = file_view_iter_init(layout, file, 0); file_view_iter_good(iter); @@ -892,11 +881,11 @@ file_update_cursor_positions(Models *models, Editing_File *file){ i32 pos = view_get_cursor_pos(iter.view); if (!iter.view->file_data.show_temp_highlight){ - Full_Cursor cursor = view_compute_cursor(iter.view, seek_pos(pos), 0); + Full_Cursor cursor = view_compute_cursor(system, iter.view, seek_pos(pos), 0); view_set_cursor(iter.view, cursor, 1, iter.view->file_data.file->settings.unwrapped_lines); } else{ - view_set_temp_highlight(iter.view, pos, iter.view->file_data.temp_highlight_end_pos); + view_set_temp_highlight(system, iter.view, pos, iter.view->file_data.temp_highlight_end_pos); } } } @@ -960,10 +949,10 @@ file_allocate_character_starts_as_needed(General_Memory *general, Editing_File * } internal void -file_measure_character_starts(Models *models, Editing_File *file){ +file_measure_character_starts(System_Functions *system, Models *models, Editing_File *file){ file_allocate_character_starts_as_needed(&models->mem.general, file); buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - file_update_cursor_positions(models, file); + file_update_cursor_positions(system, models, file); } internal void @@ -1014,8 +1003,13 @@ struct Code_Wrap_State{ Render_Font *font; f32 tab_indent_amount; + f32 byte_advance; Buffer_Translating_State tran; + Buffer_Translating_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; }; internal void @@ -1039,6 +1033,7 @@ wrap_state_init(Code_Wrap_State *state, Editing_File *file, Render_Font *font){ state->tab_indent_amount = get_codepoint_advance(font, '\t'); #endif state->tab_indent_amount = 2.f; + state->byte_advance = font_get_byte_advance(font); state->tran = null_buffer_translating_state; } @@ -1137,19 +1132,19 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ u8 ch = (u8)state->stream.data[i]; - translating_consume_byte(&state->tran, ch, i, state->size); + translating_fully_process_byte(&state->tran, ch, i, state->size, &state->emits); - for (TRANSLATION_OUTPUT(&state->tran)){ - TRANSLATION_GET_STEP(&state->tran); + for (TRANSLATION_OUTPUT(state->J, state->emits)){ + TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits); - if (state->tran.do_newline){ + if (state->behavior.do_newline){ state->consume_newline = 1; goto doublebreak; } - else if(state->tran.do_number_advance || state->tran.do_codepoint_advance){ - u32 n = state->tran.step_current.value; + else if(state->behavior.do_number_advance || state->behavior.do_codepoint_advance){ + u32 n = state->step.value; f32 adv = 0; - if (state->tran.do_codepoint_advance){ + if (state->behavior.do_codepoint_advance){ #if 0 adv = get_codepoint_advance(state->font, n); #endif @@ -1160,7 +1155,7 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ } } else{ - adv = state->font->byte_advance; + adv = state->byte_advance; skipping_whitespace = false; } @@ -1927,21 +1922,21 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ } internal void -file_measure_wraps_and_fix_cursor(Models *models, Editing_File *file, Render_Font *font){ +file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){ file_measure_wraps(models, file, font); - file_update_cursor_positions(models, file); + file_update_cursor_positions(system, models, file); } internal void -file_set_width(Models *models, Editing_File *file, i32 display_width, Render_Font *font){ +file_set_width(System_Functions *system, Models *models, Editing_File *file, i32 display_width, Render_Font *font){ file->settings.display_width = display_width; - file_measure_wraps_and_fix_cursor(models, file, font); + file_measure_wraps_and_fix_cursor(system, models, file, font); } internal void -file_set_min_base_width(Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){ +file_set_min_base_width(System_Functions *system, Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){ file->settings.minimum_base_display_width = minimum_base_display_width; - file_measure_wraps_and_fix_cursor(models, file, font); + file_measure_wraps_and_fix_cursor(system, models, file, font); } // @@ -2799,10 +2794,9 @@ file_view_nullify_file(View *view){ } internal void -update_view_line_height(Models *models, View *view, Font_ID font_id){ - //Render_Font *font = get_font_info(models->font_set, font_id)->font; - Render_Font *font = 0; - view->line_height = font->height; +update_view_line_height(System_Functions *system, Models *models, View *view, Font_ID font_id){ + Render_Font *font = system->font.get_render_data_by_id(font_id); + view->line_height = font_get_height(font); } inline void @@ -2812,13 +2806,13 @@ view_cursor_move(View *view, Full_Cursor cursor){ } inline void -view_cursor_move(View *view, i32 pos){ - Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), 0); +view_cursor_move(System_Functions *system, View *view, i32 pos){ + Full_Cursor cursor = view_compute_cursor(system, view, seek_pos(pos), 0); view_cursor_move(view, cursor); } inline void -view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){ +view_cursor_move(System_Functions *system, View *view, f32 x, f32 y, b32 round_down = 0){ Buffer_Seek seek; if (view->file_data.file->settings.unwrapped_lines){ seek = seek_unwrapped_xy(x, y, round_down); @@ -2827,13 +2821,13 @@ view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){ seek = seek_wrapped_xy(x, y, round_down); } - Full_Cursor cursor = view_compute_cursor(view, seek, 0); + Full_Cursor cursor = view_compute_cursor(system, view, seek, 0); view_cursor_move(view, cursor); } inline void -view_cursor_move(View *view, i32 line, i32 character){ - Full_Cursor cursor = view_compute_cursor(view, seek_line_char(line, character), 0); +view_cursor_move(System_Functions *system, View *view, i32 line, i32 character){ + Full_Cursor cursor = view_compute_cursor(system, view, seek_line_char(line, character), 0); view_cursor_move(view, cursor); } @@ -2854,7 +2848,7 @@ view_show_file(View *view){ } internal void -view_set_file(View *view, Editing_File *file, Models *models){ +view_set_file(System_Functions *system, View *view, Editing_File *file, Models *models){ Assert(file); if (view->file_data.file != 0){ @@ -2874,10 +2868,10 @@ view_set_file(View *view, Editing_File *file, Models *models){ edit_pos = edit_pos_get_new(file, view->persistent.id); view->edit_pos = edit_pos; - update_view_line_height(models, view, file->settings.font_id); + update_view_line_height(system, models, view, file->settings.font_id); if (edit_pos->cursor.line == 0){ - view_cursor_move(view, 0); + view_cursor_move(system, view, 0); } if (view->showing_ui == VUI_None){ @@ -3180,7 +3174,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil Assert(view->edit_pos); i32 cursor_pos = cursors[cursor_count++].pos; - Full_Cursor new_cursor = view_compute_cursor(view, seek_pos(cursor_pos), 0); + Full_Cursor new_cursor = view_compute_cursor(system, view, seek_pos(cursor_pos), 0); GUI_Scroll_Vars scroll = view->edit_pos->scroll; @@ -3189,7 +3183,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil if (view->edit_pos->scroll_i != new_scroll_i){ view->edit_pos->scroll_i = new_scroll_i; - Full_Cursor temp_cursor = view_compute_cursor(view, seek_pos(view->edit_pos->scroll_i), 0); + Full_Cursor temp_cursor = view_compute_cursor(system, view, seek_pos(view->edit_pos->scroll_i), 0); f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height); f32 y_position = temp_cursor.wrapped_y; @@ -3475,7 +3469,7 @@ apply_history_edit(System_Functions *system, Models *models, Editing_File *file, file_do_single_edit(system, models, file, spec, history_mode); if (view){ - view_cursor_move(view, step.edit.start + step.edit.len); + view_cursor_move(system, view, step.edit.start + step.edit.len); view->edit_pos->mark = view->edit_pos->cursor.pos; Style *style = main_style(models); @@ -3686,28 +3680,28 @@ style_get_color(Style *style, Cpp_Token token){ } internal void -file_set_font(Models *models, Editing_File *file, Font_ID font_id){ +file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){ file->settings.font_id = font_id; //Font_Info *font_info = get_font_info(models->font_set, file->settings.font_id); //Render_Font *font = font_info->font; Render_Font *font = 0; - file_measure_wraps_and_fix_cursor(models, file, font); + file_measure_wraps_and_fix_cursor(system, models, file, font); Editing_Layout *layout = &models->layout; for (View_Iter iter = file_view_iter_init(layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - update_view_line_height(models, iter.view, font_id); + update_view_line_height(system, models, iter.view, font_id); } } internal void -global_set_font(Models *models, Font_ID font_id){ +global_set_font(System_Functions *system, Models *models, Font_ID font_id){ File_Node *node = 0; File_Node *sentinel = &models->working_set.used_sentinel; for (dll_items(node, sentinel)){ Editing_File *file = (Editing_File*)node; - file_set_font(models, file, font_id); + file_set_font(system, models, file, font_id); } models->global_font_id = font_id; } @@ -3845,7 +3839,7 @@ view_open_file(System_Functions *system, Models *models, View *view, String file } if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } } @@ -3886,7 +3880,7 @@ view_interactive_new_file(System_Functions *system, Models *models, View *view, } if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } } @@ -3909,12 +3903,12 @@ kill_file(System_Functions *system, Models *models, Editing_File *file){ iter = file_view_iter_next(iter)){ if (node != used){ iter.view->file_data.file = 0; - view_set_file(iter.view, (Editing_File*)node, models); + view_set_file(system, iter.view, (Editing_File*)node, models); node = node->next; } else{ iter.view->file_data.file = 0; - view_set_file(iter.view, 0, models); + view_set_file(system, iter.view, 0, models); } } } @@ -4016,7 +4010,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32 { Editing_File *file = working_set_name_contains(&models->working_set, dest); if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } view_show_file(view); }break; @@ -4720,59 +4714,57 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su switch (view->color_mode){ case CV_Mode_Library: - message = make_lit_string("Current Theme - Click to Edit"); - gui_do_text_field(target, message, empty_string); - - id.id[0] = (u64)(main_style(models)); - if (gui_do_style_preview(target, id, 0)){ - view->color_mode = CV_Mode_Adjusting; - } - - if (view->file_data.file){ - message = make_lit_string("Set Font"); - id.id[0] = (u64)(&view->file_data.file->settings.font_id); - - if (gui_do_button(target, id, message)){ - view->color_mode = CV_Mode_Font; - } - } - - message = make_lit_string("Set Global Font"); - id.id[0] = (u64)(&models->global_font_id); - - if (gui_do_button(target, id, message)){ - view->color_mode = CV_Mode_Global_Font; - } - - - - message = make_lit_string("Theme Library - Click to Select"); - gui_do_text_field(target, message, empty_string); - - gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9 * view->line_height, show_scrollbar); - { - i32 count = models->styles.count; - Style *style; - i32 i; + message = make_lit_string("Current Theme - Click to Edit"); + gui_do_text_field(target, message, empty_string); - for (i = 1; i < count; ++i, ++style){ - style = get_style(models, i); - id.id[0] = (u64)(style); - if (gui_do_style_preview(target, id, i)){ - style_copy(main_style(models), style); + id.id[0] = (u64)(main_style(models)); + if (gui_do_style_preview(target, id, 0)){ + view->color_mode = CV_Mode_Adjusting; + } + + if (view->file_data.file){ + message = make_lit_string("Set Font"); + id.id[0] = (u64)(&view->file_data.file->settings.font_id); + + if (gui_do_button(target, id, message)){ + view->color_mode = CV_Mode_Font; } } + + message = make_lit_string("Set Global Font"); + id.id[0] = (u64)(&models->global_font_id); + + if (gui_do_button(target, id, message)){ + view->color_mode = CV_Mode_Global_Font; + } + + message = make_lit_string("Theme Library - Click to Select"); + gui_do_text_field(target, message, empty_string); + + gui_begin_scrollable(target, scroll_context, view->gui_scroll, + 9 * view->line_height, show_scrollbar); + + { + i32 count = models->styles.count; + for (i32 i = 1; i < count; ++i){ + Style *style = get_style(models, i); + id.id[0] = (u64)(style); + if (gui_do_style_preview(target, id, i)){ + style_copy(main_style(models), style); + } + } + } + + gui_end_scrollable(target); } - - gui_end_scrollable(target); break; case CV_Mode_Global_Font: case CV_Mode_Font: { - Assert(view->file_data.file); + Editing_File *file = view->file_data.file; + Assert(file != 0); //Font_Set *font_set = models->font_set; //Font_Info *info = 0; @@ -4786,34 +4778,43 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su Font_ID font_id = models->global_font_id; if (view->color_mode == CV_Mode_Font){ - font_id = view->file_data.file->settings.font_id; + font_id = file->settings.font_id; } + // TODO(allen): paginate the display Font_ID new_font_id = font_id; - Font_ID count = 2; - for (Font_ID i = 1; i < count; ++i){ - String font_name = {0}; - id.id[0] = (u64)i; - if (i != font_id){ - if (gui_do_font_button(target, id, i, font_name)){ - new_font_id = i; + u32 total_count = system->font.get_count(); + u32 count = Min(total_count, 10); + + for (u32 font_index = 1; font_index < count; ++font_index){ + Font_ID this_font_id = 0; + system->font.get_ids_by_index(font_index, 1, &font_id); + + char name_space[256]; + String name = make_fixed_width_string(name_space); + name.size = system->font.get_name_by_index(font_index, name.str, name.memory_size); + + id.id[0] = (u64)this_font_id; + if (this_font_id != font_id){ + if (gui_do_font_button(target, id, this_font_id, name)){ + new_font_id = this_font_id; } } else{ char message_space[256]; message = make_fixed_width_string(message_space); copy_ss(&message, make_lit_string("currently selected: ")); - append_ss(&message, font_name); - gui_do_font_button(target, id, i, message); + append_ss(&message, name); + gui_do_font_button(target, id, this_font_id, message); } } if (font_id != new_font_id){ if (view->color_mode == CV_Mode_Font){ - file_set_font(models, view->file_data.file, new_font_id); + file_set_font(system, models, file, new_font_id); } else{ - global_set_font(models, new_font_id); + global_set_font(system, models, new_font_id); } } }break; @@ -5907,7 +5908,7 @@ do_step_file_view(System_Functions *system, View *view, i32_Rect rect, b32 is_ac } internal i32 -draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target){ +draw_file_loaded(System_Functions *system, View *view, i32_Rect rect, b32 is_active, Render_Target *target){ Models *models = view->persistent.models; Editing_File *file = view->file_data.file; Style *style = main_style(models); @@ -5950,10 +5951,10 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target Full_Cursor render_cursor; if (!file->settings.unwrapped_lines){ - render_cursor = view_compute_cursor(view, seek_wrapped_xy(0, scroll_y, 0), 1); + render_cursor = view_compute_cursor(system, view, seek_wrapped_xy(0, scroll_y, 0), 1); } else{ - render_cursor = view_compute_cursor(view, seek_unwrapped_xy(0, scroll_y, 0), 1); + render_cursor = view_compute_cursor(system, view, seek_unwrapped_xy(0, scroll_y, 0), 1); } view->edit_pos->scroll_i = render_cursor.pos; @@ -6093,8 +6094,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1); - if (view->file_data.show_whitespace && highlight_color == 0 && - char_is_whitespace((char)item->glyphid)){ + if (view->file_data.show_whitespace && highlight_color == 0 && codepoint_is_whitespace(item->codepoint)){ highlight_this_color = style->main.highlight_white_color; } else{ @@ -6132,8 +6132,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target if (ind == view->edit_pos->mark && prev_ind != ind){ draw_rectangle_outline(target, char_rect, mark_color); } - if (item->glyphid != 0){ - font_draw_glyph(target, font_id, (u8)item->glyphid, item->x0, item->y0, char_color); + if (item->codepoint != 0){ + font_draw_glyph(target, font_id, item->codepoint, item->x0, item->y0, char_color); } prev_ind = ind; } @@ -6396,13 +6396,15 @@ draw_button(GUI_Target *gui_target, Render_Target *target, View *view, Font_ID f } internal void -draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, Style *style){ +draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, Style *style){ Models *models = view->persistent.models; AllowLocal(models); i32 active_level = gui_active_level(gui_target, id); //Font_Info *info = get_font_info(models->font_set, font_id); - String font_name = {0}; - Render_Font *font = 0; + char font_name_space[256]; + String font_name = make_fixed_width_string(font_name_space); + font_name.size = system->font.get_name_by_id(font_id, font_name.str, font_name.memory_size); + Render_Font *font = system->font.get_render_data_by_id(font_id); i32_Rect inner = get_inner_rect(rect, 3); @@ -6424,7 +6426,7 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, Fo draw_string(target, font_id, font_name, font_x, y, text_color); } - i32 height = font->height; + i32 height = font_get_height(font); x = inner.x0; y += height; x = ceil32(draw_string(target, font_id, "if", x, y, keyword_color)); @@ -6441,9 +6443,7 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, Fo } internal i32 -do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scroll, - View *active, i32_Rect rect, b32 is_active, - Render_Target *target, Input_Summary *user_input){ +do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){ Editing_File *file = view->file_data.file; i32 result = 0; @@ -6488,7 +6488,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol case guicom_file: { if (file_is_ready(file)){ - result = draw_file_loaded(view, gui_session.rect, is_active, target); + result = draw_file_loaded(system, view, gui_session.rect, is_active, target); } }break; @@ -6551,7 +6551,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol i32 style_index = *(i32*)(b + 1); Style *style = get_style(view->persistent.models, style_index); - draw_style_preview(gui_target, target, view, font_id, gui_session.rect, b->id, style); + draw_style_preview(system, gui_target, target, view, font_id, gui_session.rect, b->id, style); }break; case guicom_fixed_option: diff --git a/4ed_rendering.h b/4ed_rendering.h index 001c175c..2cd9af0d 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -45,7 +45,7 @@ struct Render_Piece_Glyph{ Vec2 pos; u32 color; Font_ID font_id; - u8 character; + u32 codepoint; }; struct Render_Piece_Glyph_Advance{ @@ -53,7 +53,7 @@ struct Render_Piece_Glyph_Advance{ u32 color; f32 advance; Font_ID font_id; - u8 character; + u32 codepoint; }; struct Render_Piece_Change_Clip{ diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp index cb78aaa0..bec1b00c 100644 --- a/4ed_rendering_helper.cpp +++ b/4ed_rendering_helper.cpp @@ -113,25 +113,20 @@ font_predict_size(i32 pt_size){ } internal void -font_draw_glyph(Render_Target *target, Font_ID font_id, i32 type, u8 character, f32 x, f32 y, u32 color){ - -#if 0 +font_draw_glyph(Render_Target *target, Font_ID font_id, i32 type, u32 codepoint, f32 x, f32 y, u32 color){ Render_Piece_Combined piece; piece.header.type = type; piece.glyph.pos.x = x; piece.glyph.pos.y = y; piece.glyph.color = color; piece.glyph.font_id = font_id; - piece.glyph.character = character; + piece.glyph.codepoint = codepoint; target->push_piece(target, piece); - font_set_use(&target->font_set, font_id); -#endif - } internal void -font_draw_glyph(Render_Target *target, Font_ID font_id, u8 character, f32 x, f32 y, u32 color){ - font_draw_glyph(target, font_id, piece_type_glyph, character, x, y, color); +font_draw_glyph(Render_Target *target, Font_ID font_id, u32 codepoint, f32 x, f32 y, u32 color){ + font_draw_glyph(target, font_id, piece_type_glyph, codepoint, x, y, color); } internal f32 diff --git a/4ed_system.h b/4ed_system.h index 25f165ce..41eb4a2f 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -9,15 +9,21 @@ // TOP +#if !defined(FCODER_SYSTEM_INTERFACE_H) +#define FCODER_SYSTEM_INTERFACE_H + +#include "font/4coder_font_interface.h" + +// types struct Plat_Handle{ u32 d[4]; }; static Plat_Handle null_plat_handle = {0}; -inline int32_t +inline b32 handle_equal(Plat_Handle a, Plat_Handle b){ - int32_t result = (memcmp(&a, &b, sizeof(a)) == 0); + b32 result = (memcmp(&a, &b, sizeof(a)) == 0); return(result); } @@ -233,6 +239,8 @@ typedef Sys_Send_Exit_Signal_Sig(System_Send_Exit_Signal); typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States); struct System_Functions{ + Font_Functions font; + // files (tracked api): 10 System_Set_File_List *set_file_list; System_Get_Canonical *get_canonical; @@ -287,5 +295,7 @@ struct System_Functions{ INTERNAL_System_Get_Thread_States *internal_get_thread_states; }; +#endif + // BOTTOM diff --git a/4ed_system_shared.cpp b/4ed_system_shared.cpp index 330d98d0..c979be61 100644 --- a/4ed_system_shared.cpp +++ b/4ed_system_shared.cpp @@ -9,6 +9,8 @@ // TOP +#include "font/4coder_font_data.h" + // // Standard implementation of file system stuff based on the file track layer. // @@ -181,8 +183,7 @@ internal void sysshared_partition_grow(Partition *part, i32 new_size){ void *data = 0; if (new_size > part->max){ - // TODO(allen): attempt to grow in place by just - // acquiring next vpages?! + // TODO(allen): attempt to grow in place by just acquiring next vpages?! data = system_get_memory(new_size); memcpy(data, part->base, part->pos); system_free_memory(part->base); @@ -420,8 +421,7 @@ get_exact_render_quad(Glyph_Bounds *b, i32 pw, i32 ph, float xpos, float ypos){ } inline void -private_draw_glyph(Render_Target *target, Render_Font *font, u32 character, f32 x, f32 y, u32 color){ - +private_draw_glyph(Render_Target *target, Render_Font *font, u32 codepoint, f32 x, f32 y, u32 color){ #if 0 Glyph_Data glyph = {0}; if (get_codepoint_glyph_data(font, character, &glyph)){ @@ -439,12 +439,10 @@ private_draw_glyph(Render_Target *target, Render_Font *font, u32 character, f32 glEnd(); } #endif - } inline void -private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, f32 x, f32 y, f32 advance, u32 color){ - +private_draw_glyph_mono(Render_Target *target, Render_Font *font, u32 codepoint, f32 x, f32 y, f32 advance, u32 color){ #if 0 Glyph_Data glyph = {0}; if (get_codepoint_glyph_data(font, character, &glyph)){ @@ -473,8 +471,9 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, } inline void -private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, f32 x, f32 y, u32 color){ - private_draw_glyph_mono(target, font, character, x, y, (f32)font->advance, color); +private_draw_glyph_mono(Render_Target *target, Render_Font *font, u32 character, f32 x, f32 y, u32 color){ + f32 advance = (f32)font_get_advance(font); + private_draw_glyph_mono(target, font, character, x, y, advance, color); } internal void @@ -561,14 +560,16 @@ launch_rendering(Render_Target *target){ #define internal static internal void -font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Glyph_Page *page, u32 page_number, i32 tab_width){ +font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Layout_Page *layout_page, u32 page_number, i32 tab_width){ Temp_Memory temp = begin_temp_memory(part); - Assert(page != 0); - page->page_number = page_number; + Assert(layout_page != 0); + layout_page->page_number = page_number; + + Glyph_Page *glyph_page = (Glyph_Page*)(layout_page + 1); // prepare to read glyphs into a temporary texture buffer i32 max_glyph_w = face->size->metrics.x_ppem; - i32 max_glyph_h = font->height; + i32 max_glyph_h = font_get_height(font); i32 tex_width = 64; i32 tex_height = 0; @@ -599,10 +600,10 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, // fill the texture u32 base_codepoint = (page_number << 8); - Glyph_Bounds *glyphs = &page->glyphs[0]; + Glyph_Bounds *glyphs = &glyph_page->glyphs[0]; Glyph_Bounds *glyph_ptr = glyphs; - f32 *advances = &page->advance[0]; + f32 *advances = &layout_page->advance[0]; f32 *advance_ptr = advances; for(u32 i = 0; i < ITEM_PER_FONT_PAGE; ++i, ++glyph_ptr, ++advance_ptr){ u32 codepoint = i + base_codepoint; @@ -611,6 +612,8 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, i32 w = face->glyph->bitmap.width; i32 h = face->glyph->bitmap.rows; + i32 ascent = font_get_ascent(font); + // move to next line if necessary if(pen_x + w >= tex_width){ pen_x = 0; @@ -624,7 +627,7 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, glyph_ptr->y1 = (f32)(pen_y + h + 1); glyph_ptr->xoff = (f32)(face->glyph->bitmap_left); - glyph_ptr->yoff = (f32)(font->ascent - face->glyph->bitmap_top); + glyph_ptr->yoff = (f32)(ascent - face->glyph->bitmap_top); glyph_ptr->xoff2 = glyph_ptr->xoff + w; glyph_ptr->yoff2 = glyph_ptr->yoff + h + 1; @@ -649,8 +652,8 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, // upload texture tex_height = round_up_pot_u32(pen_y + max_glyph_h + 2); - page->tex_width = tex_width; - page->tex_height = tex_height; + glyph_page->tex_width = tex_width; + glyph_page->tex_height = tex_height; u32 tex; glGenTextures(1, &tex); @@ -665,8 +668,7 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels); glBindTexture(GL_TEXTURE_2D, 0); - page->tex = tex; - page->page_number = page_number; + glyph_page->tex = tex; end_temp_memory(temp); diff --git a/file/4coder_buffer.cpp b/file/4coder_buffer.cpp index 0729980b..2fc46af3 100644 --- a/file/4coder_buffer.cpp +++ b/file/4coder_buffer.cpp @@ -336,6 +336,12 @@ struct Buffer_Model_Step{ u32 byte_length; }; +struct Buffer_Model_Behavior{ + b32 do_newline; + b32 do_codepoint_advance; + b32 do_number_advance; +}; + enum{ BufferModelUnit_None, BufferModelUnit_Codepoint, @@ -349,26 +355,23 @@ struct Buffer_Translating_State{ u32 fill_expected; u32 byte_class; - b32 emit_type; + u32 emit_type; b32 rebuffer_current; b32 emit_current_as_cp; - Buffer_Model_Step steps[5]; - Buffer_Model_Step step_current; - u32 step_count; - u32 step_j; - u32 codepoint; u32 codepoint_length; b32 do_codepoint; b32 do_numbers; - - b32 do_newline; - b32 do_codepoint_advance; - b32 do_number_advance; }; global_const Buffer_Translating_State null_buffer_translating_state = {0}; +struct Buffer_Translating_Emits{ + Buffer_Model_Step steps[5]; + Buffer_Model_Step step_current; + u32 step_count; +}; + internal void translating_consume_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size){ tran->byte_class = 0; @@ -433,7 +436,10 @@ translating_consume_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size) if (tran->emit_type == BufferModelUnit_None && i+1 == size){ tran->emit_type = BufferModelUnit_Numbers; } - +} + +internal void +translating_select_emit_type(Buffer_Translating_State *tran){ tran->codepoint = 0; tran->codepoint_length = 0; tran->do_codepoint = false; @@ -452,23 +458,26 @@ translating_consume_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size) } Assert((tran->do_codepoint + tran->do_numbers) <= 1); - - tran->step_count = 0; +} + +internal void +translating_generate_emits(Buffer_Translating_State *tran, u8 ch, u32 i, Buffer_Translating_Emits *emits_out){ + emits_out->step_count = 0; if (tran->do_codepoint){ - tran->steps[0].type = 1; - tran->steps[0].value = tran->codepoint; - tran->steps[0].i = tran->fill_start_i; - tran->steps[0].byte_length = tran->codepoint_length; - tran->step_count = 1; + emits_out->steps[0].type = 1; + emits_out->steps[0].value = tran->codepoint; + emits_out->steps[0].i = tran->fill_start_i; + emits_out->steps[0].byte_length = tran->codepoint_length; + emits_out->step_count = 1; } else if (tran->do_numbers){ for (u32 j = 0; j < tran->fill_i; ++j){ - tran->steps[j].type = 0; - tran->steps[j].value = tran->fill_buffer[j]; - tran->steps[j].i = tran->fill_start_i + j; - tran->steps[j].byte_length = 1; + emits_out->steps[j].type = 0; + emits_out->steps[j].value = tran->fill_buffer[j]; + emits_out->steps[j].i = tran->fill_start_i + j; + emits_out->steps[j].byte_length = 1; } - tran->step_count = tran->fill_i; + emits_out->step_count = tran->fill_i; } if (tran->do_codepoint || tran->do_numbers){ @@ -488,39 +497,52 @@ translating_consume_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size) else if (tran->emit_current_as_cp){ Assert(tran->do_codepoint || tran->do_numbers); - tran->steps[tran->step_count].type = 1; - tran->steps[tran->step_count].value = ch; - tran->steps[tran->step_count].i = i; - tran->steps[tran->step_count].byte_length = 1; - ++tran->step_count; + emits_out->steps[emits_out->step_count].type = 1; + emits_out->steps[emits_out->step_count].value = ch; + emits_out->steps[emits_out->step_count].i = i; + emits_out->steps[emits_out->step_count].byte_length = 1; + ++emits_out->step_count; } } internal void -translation_step_read(Buffer_Translating_State *tran){ - tran->do_newline = false; - tran->do_codepoint_advance = false; - tran->do_number_advance = false; - if (tran->step_current.type == 1){ - switch (tran->step_current.value){ +translating_fully_process_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size, Buffer_Translating_Emits *emits_out){ + translating_consume_byte(tran, ch, i, size); + translating_select_emit_type(tran); + translating_generate_emits(tran, ch, i, emits_out); +} + +internal void +translation_step_read(Buffer_Model_Step step, Buffer_Model_Behavior *behavior_out){ + behavior_out->do_newline = false; + behavior_out->do_codepoint_advance = false; + behavior_out->do_number_advance = false; + if (step.type == 1){ + switch (step.value){ case '\n': { - tran->do_newline = true; + behavior_out->do_newline = true; }break; default: { - tran->do_codepoint_advance = true; + behavior_out->do_codepoint_advance = true; }break; } } else{ - tran->do_number_advance = true; + behavior_out->do_number_advance = true; } } -#define TRANSLATION_OUTPUT(t) (t)->step_j = 0; (t)->step_j < (t)->step_count; ++(t)->step_j -#define TRANSLATION_GET_STEP(t) (t)->step_current = (t)->steps[(t)->step_j]; translation_step_read(t) +#define TRANSLATION_DECL_OUTPUT(_j,_emit) u32 _j = 0; _j < (_emit).step_count; ++_j +#define TRANSLATION_DECL_GET_STEP(_step,_behav,_j,_emit) \ +Buffer_Model_Step _step = _emit.steps[_j]; Buffer_Model_Behavior _behav; \ +translation_step_read(_step, &_behav) + +#define TRANSLATION_OUTPUT(_j,_emit) _j = 0; _j < (_emit).step_count; ++_j +#define TRANSLATION_GET_STEP(_step,_behav,_j,_emit)\ +(_step) = _emit.steps[_j]; translation_step_read((_step), &(_behav)) // // Implementation of the gap buffer @@ -935,6 +957,7 @@ buffer_measure_character_starts(Gap_Buffer *buffer, i32 *character_starts, i32 m } Buffer_Translating_State tran = {0}; + Buffer_Translating_Emits emits = {0}; stream.use_termination_character = 1; stream.terminator = '\n'; @@ -944,19 +967,19 @@ buffer_measure_character_starts(Gap_Buffer *buffer, i32 *character_starts, i32 m for (; i < stream.end; ++i){ u8 ch = (u8)stream.data[i]; - translating_consume_byte(&tran, ch, i, size); + translating_fully_process_byte(&tran, ch, i, size, &emits); - for (TRANSLATION_OUTPUT(&tran)){ - TRANSLATION_GET_STEP(&tran); + for (TRANSLATION_DECL_OUTPUT(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); - if (tran.do_newline){ + if (behavior.do_newline){ ++character_index; character_starts[line_index++] = character_index; if (virtual_white){ skipping_whitespace = 1; } } - else if (tran.do_codepoint_advance || tran.do_number_advance){ + else if (behavior.do_codepoint_advance || behavior.do_number_advance){ if (ch != ' ' && ch != '\t'){ skipping_whitespace = 0; } @@ -1014,9 +1037,11 @@ struct Buffer_Measure_Wrap_State{ b32 did_wrap; b32 first_of_the_line; - u8 ch; - Buffer_Translating_State tran; + Buffer_Translating_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; i32 __pc__; }; @@ -1060,18 +1085,20 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para S.still_looping = 0; do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; - - if (S.ch != ' ' && S.ch != '\t'){ - S.skipping_whitespace = false; + { + u8 ch = (u8)S.stream.data[S.i]; + + if (ch != ' ' && ch != '\t'){ + S.skipping_whitespace = false; + } + + translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits); } - translating_consume_byte(&S.tran, S.ch, S.i, S.size); - - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_OUTPUT(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); - if (S.tran.do_newline){ + if (S.behavior.do_newline){ ++S.current_wrap_index; params.wrap_line_index[S.line_index++] = S.current_wrap_index; @@ -1090,13 +1117,13 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para } S.first_of_the_line = 1; } - else if (S.tran.do_number_advance || S.tran.do_codepoint_advance){ + else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ if (!S.skipping_whitespace){ S.current_adv = 2.f; #if 0 - if (S.tran.do_codepoint_advance){ + if (S.behavior.do_codepoint_advance){ S.current_adv = get_codepoint_advance(params.font, S.tran.step_current.value); } else{ @@ -1271,6 +1298,7 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e // Translation Buffer_Translating_State tran = {0}; + Buffer_Translating_Emits emits = {0}; stream.use_termination_character = 1; stream.terminator = '\n'; @@ -1279,12 +1307,12 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e do{ for (; char_i < stream.end; ++char_i){ u8 ch = (u8)stream.data[char_i]; - translating_consume_byte(&tran, ch, char_i, size); + translating_fully_process_byte(&tran, ch, char_i, size, &emits); - for (TRANSLATION_OUTPUT(&tran)){ - TRANSLATION_GET_STEP(&tran); + for (TRANSLATION_DECL_OUTPUT(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); - if (tran.do_newline){ + if (behavior.do_newline){ character_starts[line_i++] = last_char_start; ++current_char_start; last_char_start = current_char_start; @@ -1296,7 +1324,7 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e goto buffer_remeasure_character_starts_end; } } - else if (tran.do_codepoint_advance || tran.do_number_advance){ + else if (behavior.do_codepoint_advance || behavior.do_number_advance){ if (ch != ' ' && ch != '\t'){ skipping_whitespace = 0; } @@ -1565,9 +1593,15 @@ struct Buffer_Cursor_Seek_State{ b32 first_of_the_line; b32 xy_seek; f32 ch_width; - u8 ch; + + i32 font_height; Buffer_Translating_State tran; + Buffer_Translating_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; + i32 __pc__; }; @@ -1589,6 +1623,8 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa DrCase(4); } + S.font_height = font_get_height(params.font); + S.xy_seek = (params.seek.type == buffer_seek_wrapped_xy || params.seek.type == buffer_seek_unwrapped_xy); S.size = buffer_size(params.buffer); @@ -1630,7 +1666,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa case buffer_seek_unwrapped_xy: { - line_index = (i32)(params.seek.y / params.font->height); + line_index = (i32)(params.seek.y / S.font_height); if (line_index >= params.buffer->line_count){ line_index = params.buffer->line_count - 1; } @@ -1641,7 +1677,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa case buffer_seek_wrapped_xy: { - line_index = buffer_get_line_index_from_wrapped_y(params.wrap_line_index, params.seek.y, params.font->height, 0, params.buffer->line_count); + line_index = buffer_get_line_index_from_wrapped_y(params.wrap_line_index, params.seek.y, S.font_height, 0, params.buffer->line_count); }break; default: InvalidCodePath; @@ -1653,9 +1689,9 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.next_cursor.line = line_index + 1; S.next_cursor.character = 1; S.next_cursor.wrap_line = params.wrap_line_index[line_index] + 1; - S.next_cursor.unwrapped_y = (f32)(line_index * params.font->height); + S.next_cursor.unwrapped_y = (f32)(line_index * S.font_height); S.next_cursor.unwrapped_x = 0; - S.next_cursor.wrapped_y = (f32)(params.wrap_line_index[line_index] * params.font->height); + S.next_cursor.wrapped_y = (f32)(params.wrap_line_index[line_index] * S.font_height); S.next_cursor.wrapped_x = 0; } @@ -1676,9 +1712,9 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa if (buffer_stringify_loop(&S.stream, params.buffer, S.next_cursor.pos, S.size)){ do{ for (; S.next_cursor.pos < S.stream.end; ++S.next_cursor.pos){ - S.ch = (u8)S.stream.data[S.next_cursor.pos]; + u8 ch = (u8)S.stream.data[S.next_cursor.pos]; - if (S.ch != ' ' && S.ch != '\t'){ + if (ch != ' ' && ch != '\t'){ goto double_break_vwhite; } else{ @@ -1752,22 +1788,23 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.still_looping = 0; do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; + { + u8 ch = (u8)S.stream.data[S.i]; + translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits); + } - translating_consume_byte(&S.tran, S.ch, S.i, S.size); - - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_OUTPUT(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); S.prev_cursor = S.this_cursor; S.this_cursor = S.next_cursor; - if (S.tran.do_newline){ + if (S.behavior.do_newline){ ++S.next_cursor.character_pos; ++S.next_cursor.line; ++S.next_cursor.wrap_line; - S.next_cursor.unwrapped_y += params.font->height; - S.next_cursor.wrapped_y += params.font->height; + S.next_cursor.unwrapped_y += S.font_height; + S.next_cursor.wrapped_y += S.font_height; S.next_cursor.character = 1; S.next_cursor.unwrapped_x = 0; @@ -1781,7 +1818,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.next_cursor.wrapped_x = line_shift; S.first_of_the_line = 1; } - else if (S.tran.do_number_advance || S.tran.do_codepoint_advance){ + else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ S.ch_width = 2.f; @@ -1794,18 +1831,18 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa } #endif - if (S.tran.step_current.i >= S.wrap_unit_end){ + if (S.step.i >= S.wrap_unit_end){ S_stop.status = BLStatus_NeedWrapDetermination; S_stop.line_index = S.next_cursor.line-1; S_stop.wrap_line_index = S.next_cursor.wrap_line-1; - S_stop.pos = S.tran.step_current.i; + S_stop.pos = S.step.i; S_stop.x = S.next_cursor.wrapped_x; DrYield(4, S_stop); S.wrap_unit_end = wrap_unit_end; if (do_wrap && !S.first_of_the_line){ - S.next_cursor.wrapped_y += params.font->height; + S.next_cursor.wrapped_y += S.font_height; ++S.next_cursor.wrap_line; if (params.virtual_white){ @@ -1828,7 +1865,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.first_of_the_line = 0; } - S.next_cursor.pos += S.tran.step_current.byte_length; + S.next_cursor.pos += S.step.byte_length; f32 x = 0, px = 0, y = 0, py = 0; switch (params.seek.type){ @@ -1874,9 +1911,9 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa goto buffer_cursor_seek_end; } - if (y > params.seek.y - params.font->height && x >= params.seek.x){ + if (y > params.seek.y - S.font_height && x >= params.seek.x){ if (!params.seek.round_down){ - if (py >= y && S.ch != '\n' && (params.seek.x - px) < (x - params.seek.x)){ + if (py >= y && !S.behavior.do_newline && (params.seek.x - px) < (x - params.seek.x)){ S.this_cursor = S.prev_cursor; } goto buffer_cursor_seek_end; @@ -1971,7 +2008,7 @@ enum Buffer_Render_Flag{ typedef struct Buffer_Render_Item{ i32 index; - u32 glyphid; + u32 codepoint; u32 flags; f32 x0, y0; f32 x1, y1; @@ -1981,27 +2018,28 @@ typedef struct Render_Item_Write{ Buffer_Render_Item *item; f32 x, y; Render_Font *font; + i32 font_height; f32 x_min; f32 x_max; } Render_Item_Write; inline Render_Item_Write -write_render_item(Render_Item_Write write, i32 index, u32 glyphid, u32 flags){ +write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){ #if 0 - f32 ch_width = get_codepoint_advance(write.font, glyphid); + f32 ch_width = get_codepoint_advance(write.font, codepoint); #endif f32 ch_width = 2.f; if (write.x <= write.x_max && write.x + ch_width >= write.x_min){ write.item->index = index; - write.item->glyphid = glyphid; + write.item->codepoint = codepoint; write.item->flags = flags; write.item->x0 = write.x; write.item->y0 = write.y; write.item->x1 = write.x + ch_width; - write.item->y1 = write.y + write.font->height; + write.item->y1 = write.y + write.font_height; ++write.item; } @@ -2041,9 +2079,9 @@ struct Buffer_Render_State{ f32 shift_y; f32 ch_width; - u8 ch; Render_Item_Write write; + f32 byte_advance; i32 line; i32 wrap_line; @@ -2052,6 +2090,10 @@ struct Buffer_Render_State{ i32 wrap_unit_end; Buffer_Translating_State tran; + Buffer_Translating_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; i32 __pc__; }; @@ -2100,9 +2142,12 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.x = S.shift_x + line_shift; S.write.y = S.shift_y; S.write.font = params.font; + S.write.font_height = font_get_height(params.font); S.write.x_min = params.port_x; S.write.x_max = params.port_x + params.clip_w; + S.byte_advance = font_get_byte_advance(params.font); + if (params.virtual_white){ S.skipping_whitespace = 1; } @@ -2112,17 +2157,19 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 if (buffer_stringify_loop(&S.stream, params.buffer, S.i, S.size)){ do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; - translating_consume_byte(&S.tran, S.ch, S.i, S.size); + { + u8 ch = (u8)S.stream.data[S.i]; + translating_fully_process_byte(&S.tran, ch, S.i, S.size, &S.emits); + } - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_OUTPUT(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); - if (!S.tran.do_newline && S.tran.step_current.i >= S.wrap_unit_end){ + if (!S.behavior.do_newline && S.step.i >= S.wrap_unit_end){ S_stop.status = BLStatus_NeedWrapDetermination; S_stop.line_index = S.line; S_stop.wrap_line_index = S.wrap_line; - S_stop.pos = S.tran.step_current.i; + S_stop.pos = S.step.i; S_stop.x = S.write.x - S.shift_x; DrYield(4, S_stop); @@ -2142,7 +2189,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 switch (params.wrap_slashes){ case WrapIndicator_Show_After_Line: { - S.write = write_render_item(S.write, S.tran.step_current.i-1, '\\', BRFlag_Ghost_Character); + S.write = write_render_item(S.write, S.step.i-1, '\\', BRFlag_Ghost_Character); }break; case WrapIndicator_Show_At_Wrap_Edge: @@ -2150,12 +2197,12 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 if (S.write.x < S.shift_x + params.width){ S.write.x = S.shift_x + params.width; } - S.write = write_render_item(S.write, S.tran.step_current.i-1, '\\', BRFlag_Ghost_Character); + S.write = write_render_item(S.write, S.step.i-1, '\\', BRFlag_Ghost_Character); }break; } S.write.x = S.shift_x + line_shift; - S.write.y += params.font->height; + S.write.y += S.write.font_height; } } } @@ -2165,8 +2212,8 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } S.first_of_the_line = false; - if (S.tran.do_newline){ - S.write = write_render_item(S.write, S.tran.step_current.i, ' ', 0); + if (S.behavior.do_newline){ + S.write = write_render_item(S.write, S.step.i, ' ', 0); if (params.virtual_white){ S_stop.status = BLStatus_NeedLineShift; @@ -2181,18 +2228,18 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 ++S.wrap_line; S.write.x = S.shift_x + line_shift; - S.write.y += params.font->height; + S.write.y += S.write.font_height; S.first_of_the_line = true; } - else if (S.tran.do_codepoint_advance){ - u32 n = S.tran.step_current.value; + else if (S.behavior.do_codepoint_advance){ + u32 n = S.step.value; if (n != ' ' && n != '\t'){ S.skipping_whitespace = false; } if (!S.skipping_whitespace){ - u32 I = S.tran.step_current.i; + u32 I = S.step.i; switch (n){ case '\r': { @@ -2204,7 +2251,6 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 case '\t': { - #if 0 S.ch_width = get_codepoint_advance(params.font, '\t'); #endif @@ -2222,12 +2268,12 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } } } - else if (S.tran.do_number_advance){ - u8 n = (u8)S.tran.step_current.value; - u32 I = S.tran.step_current.i; + else if (S.behavior.do_number_advance){ + u8 n = (u8)S.step.value; + u32 I = S.step.i; S.skipping_whitespace = false; - S.ch_width = params.font->byte_advance; + S.ch_width = S.byte_advance; f32 new_x = S.write.x + S.ch_width; u8 cs[3]; @@ -2247,7 +2293,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.x = new_x; } - if (!S.skipping_whitespace && !S.tran.do_newline){ + if (!S.skipping_whitespace && !S.behavior.do_newline){ S.first_of_the_line = false; } } diff --git a/font/4coder_font_data.h b/font/4coder_font_data.h index 8f072e30..b1a73655 100644 --- a/font/4coder_font_data.h +++ b/font/4coder_font_data.h @@ -12,10 +12,20 @@ #if !defined(FCODER_FONT_DATA_H) #define FCODER_FONT_DATA_H -typedef u32 Font_ID; - #define ITEM_PER_FONT_PAGE 256 +struct Layout_Page{ + u32 page_number; + f32 advance[ITEM_PER_FONT_PAGE]; +}; + +struct Render_Font{ + Layout_Page **_layout_pages; + u32 page_count, page_max; + f32 byte_advance; + i32 height, ascent, descent, line_skip, advance; +}; + struct Glyph_Bounds{ f32 x0, x1; f32 y0, y1; @@ -31,24 +41,9 @@ struct Glyph_Data{ }; struct Glyph_Page{ - u32 page_number; u32 tex; i32 tex_width, tex_height; Glyph_Bounds glyphs[ITEM_PER_FONT_PAGE]; - f32 advance[ITEM_PER_FONT_PAGE]; -}; - -struct Render_Font{ - char name_[24]; - String name; - b32 loaded; - - Glyph_Page **pages; - u32 page_count, page_max; - - f32 byte_advance; - i32 height, ascent, descent, line_skip; - i32 advance; }; #endif diff --git a/font/4coder_font_interface.h b/font/4coder_font_interface.h new file mode 100644 index 00000000..1558e830 --- /dev/null +++ b/font/4coder_font_interface.h @@ -0,0 +1,53 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 11.03.2017 + * + * Font system interface. + * + */ + +// TOP + +#if !defined(FCODER_FONT_INTERFACE_H) +#define FCODER_FONT_INTERFACE_H + +typedef u32 Font_ID; + +struct Render_Font; + +#define Sys_Font_Get_Count_Sig(name_) u32 (name_)(void) +typedef Sys_Font_Get_Count_Sig(Font_Get_Count_Function); + +#define Sys_Font_Get_IDs_By_Index_Sig(name_) b32 (name_)(u32 first_index, u32 index_count, u32 *id_out) +typedef Sys_Font_Get_IDs_By_Index_Sig(Font_Get_IDs_By_Index_Function); + +#define Sys_Font_Get_Name_By_Index_Sig(name_) u32 (name_)(u32 font_index, char *str_out, u32 str_out_cap) +typedef Sys_Font_Get_Name_By_Index_Sig(Font_Get_Name_By_Index_Function); + +#define Sys_Font_Get_Name_By_ID_Sig(name_) u32 (name_)(u32 font_index, char *str_out, u32 str_out_cap) +typedef Sys_Font_Get_Name_By_ID_Sig(Font_Get_Name_By_ID_Function); + +#define Sys_Font_Get_Render_Data_By_ID_Sig(name_) Render_Font* (name_)(u32 font_id) +typedef Sys_Font_Get_Render_Data_By_ID_Sig(Font_Get_Render_Data_By_ID_Function); + +struct Font_Functions{ + Font_Get_Count_Function *get_count; + Font_Get_IDs_By_Index_Function *get_ids_by_index; + Font_Get_Name_By_Index_Function *get_name_by_index; + Font_Get_Name_By_ID_Function *get_name_by_id; + Font_Get_Render_Data_By_ID_Function *get_render_data_by_id; +}; + +internal f32 font_get_byte_advance(Render_Font *font); +internal i32 font_get_height(Render_Font *font); +internal i32 font_get_ascent(Render_Font *font); +internal i32 font_get_descent(Render_Font *font); +internal i32 font_get_line_skip(Render_Font *font); +internal i32 font_get_advance(Render_Font *font); + +#endif + +// BOTTOM + + diff --git a/font/4coder_font_static_functions.cpp b/font/4coder_font_static_functions.cpp new file mode 100644 index 00000000..be9556f6 --- /dev/null +++ b/font/4coder_font_static_functions.cpp @@ -0,0 +1,47 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 11.03.2017 + * + * Implements some basic getters for fonts set up to make the font type opaque. + * + */ + +// TOP + +#include "4coder_font_data.h" + +internal f32 +font_get_byte_advance(Render_Font *font){ + return(font->byte_advance); +} + +internal i32 +font_get_height(Render_Font *font){ + return(font->height); +} + +internal i32 +font_get_ascent(Render_Font *font){ + return(font->ascent); +} + +internal i32 +font_get_descent(Render_Font *font){ + return(font->descent); +} + +internal i32 +font_get_line_skip(Render_Font *font){ + return(font->line_skip); +} + +internal i32 +font_get_advance(Render_Font *font){ + return(font->advance); +} + +// BOTTOM + + + diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 184ba3a9..9436dbe1 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -54,7 +54,6 @@ #include "4ed_math.h" #include "4ed_system.h" -#include "font/4coder_font_data.h" #include "4ed_rendering.h" #include "4ed.h" @@ -2514,13 +2513,15 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS return(0); } +#include "font/4coder_font_static_functions.cpp" + #if 0 // NOTE(allen): In case I want to switch back to a console // application at some point. int main(int argc, char **argv){ HINSTANCE hInstance = GetModuleHandle(0); +} #endif - - // BOTTOM - - + +// BOTTOM +