setup the font interface, complete with an opaque Render_Font; started breaking down the translation interface
							parent
							
								
									b871d5d2e5
								
							
						
					
					
						commit
						dc90ec0c83
					
				|  | @ -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; | ||||
|  |  | |||
							
								
								
									
										25
									
								
								4ed.cpp
								
								
								
								
							
							
						
						
									
										25
									
								
								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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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{ | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								4ed_system.h
								
								
								
								
							
							
						
						
									
										14
									
								
								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
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|      | ||||
|  |  | |||
|  | @ -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; | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -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
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -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
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster