From eb29349caf97626326a59805ab1b5bc28d1beefc Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 4 Nov 2019 05:37:45 -0800 Subject: [PATCH] Layout with cool parantheses thing working --- 4ed.cpp | 38 +++-- 4ed_api_implementation.cpp | 4 +- 4ed_app_target.cpp | 1 + 4ed_buffer.cpp | 231 ----------------------------- 4ed_file.cpp | 73 +++------ custom/4coder_code_index.cpp | 122 +++++++-------- custom/4coder_code_index.h | 4 - custom/4coder_default_include.cpp | 1 + custom/4coder_layout.cpp | 237 ++++++++++++++++++++++++++++++ custom/4coder_layout_rule.cpp | 25 ++++ custom/4coder_layout_rule.h | 7 + custom/4coder_string_match.cpp | 2 +- 12 files changed, 373 insertions(+), 372 deletions(-) create mode 100644 custom/4coder_layout.cpp diff --git a/4ed.cpp b/4ed.cpp index e95cb421..55c718e4 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -11,7 +11,7 @@ internal void output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){ - i64 end = buffer_size(&file->state.buffer); + i64 end = buffer_size(&file->state.buffer); Edit_Behaviors behaviors = {}; edit_single(tctx, models, file, Ii64(end), value, behaviors); } @@ -61,9 +61,7 @@ fill_hardcode_default_style(Color_Table color_table){ color_table.vals[Stag_Include] = color_table.vals[Stag_Str_Constant]; color_table.vals[Stag_Preproc] = color_table.vals[Stag_Default]; color_table.vals[Stag_Special_Character] = 0xFFFF0000; - color_table.vals[Stag_Ghost_Character] = color_blend(color_table.vals[Stag_Default], - 0.5f, - color_table.vals[Stag_Back]); + color_table.vals[Stag_Ghost_Character] = color_blend(color_table.vals[Stag_Default], 0.5f, color_table.vals[Stag_Back]); color_table.vals[Stag_Paste] = 0xFFDDEE00; color_table.vals[Stag_Undo] = 0xFF00DDEE; @@ -71,10 +69,10 @@ fill_hardcode_default_style(Color_Table color_table){ color_table.vals[Stag_Highlight_Junk] = 0xff3a0000; color_table.vals[Stag_Highlight_White] = 0xff003a3a; - color_table.vals[Stag_Bar] = 0xFF888888; - color_table.vals[Stag_Base] = 0xFF000000; - color_table.vals[Stag_Pop1] = 0xFF3C57DC; - color_table.vals[Stag_Pop2] = 0xFFFF0000; + color_table.vals[Stag_Bar] = 0xFF888888; + color_table.vals[Stag_Base] = 0xFF000000; + color_table.vals[Stag_Pop1] = 0xFF3C57DC; + color_table.vals[Stag_Pop2] = 0xFFFF0000; color_table.vals[Stag_Back_Cycle_1] = 0x10A00000; color_table.vals[Stag_Back_Cycle_2] = 0x0C00A000; @@ -116,8 +114,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, if (arg[0] == '-' && arg[1] == '-'){ char *long_arg_name = arg+2; - if (string_match(SCu8(long_arg_name), - string_u8_litexpr("custom"))){ + if (string_match(SCu8(long_arg_name), string_u8_litexpr("custom"))){ mode = CLMode_Custom; continue; } @@ -132,18 +129,18 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, if (arg[0] == '-'){ action = CLAct_Ignore; switch (arg[1]){ - case 'd': action = CLAct_CustomDLL; strict = false; break; - case 'D': action = CLAct_CustomDLL; strict = true; break; + case 'd': action = CLAct_CustomDLL; strict = false; break; + case 'D': action = CLAct_CustomDLL; strict = true; break; - case 'i': action = CLAct_InitialFilePosition; break; + case 'i': action = CLAct_InitialFilePosition; break; - case 'w': action = CLAct_WindowSize; break; - case 'W': action = CLAct_WindowMaximize; break; - case 'p': action = CLAct_WindowPosition; break; - case 'F': action = CLAct_WindowFullscreen; break; + case 'w': action = CLAct_WindowSize; break; + case 'W': action = CLAct_WindowMaximize; break; + case 'p': action = CLAct_WindowPosition; break; + case 'F': action = CLAct_WindowFullscreen; break; - case 'f': action = CLAct_FontSize; break; - case 'h': action = CLAct_FontUseHinting; --i; break; + case 'f': action = CLAct_FontSize; break; + case 'h': action = CLAct_FontUseHinting; --i; break; } } else if (arg[0] != 0){ @@ -625,8 +622,7 @@ App_Step_Sig(app_step){ b32 event_was_handled = false; Input_Event *event = &node->event; - if (event->kind == InputEventKind_TextInsert && - event->text.blocked){ + if (event->kind == InputEventKind_TextInsert && event->text.blocked){ continue; } diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 527c62ce..6b8c08a5 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -413,9 +413,7 @@ buffer_pos_at_relative_xy(Application_Links *app, Buffer_ID buffer_id, } api(custom) function Rect_f32 -buffer_relative_box_of_pos(Application_Links *app, Buffer_ID buffer_id, - f32 width, Face_ID face_id, - i64 base_line, i64 pos){ +buffer_relative_box_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){ Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); Rect_f32 result = {}; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 548083ad..71f26ecb 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -61,6 +61,7 @@ //////////////////////////////// #include "4coder_base_types.cpp" +#include "4coder_layout.cpp" #include "4coder_system_helpers.cpp" #include "4coder_events.cpp" #include "4coder_string_match.cpp" diff --git a/4ed_buffer.cpp b/4ed_buffer.cpp index 9a75169a..8717f9e7 100644 --- a/4ed_buffer.cpp +++ b/4ed_buffer.cpp @@ -854,236 +854,5 @@ buffer_chunk_position_iterate(String_Const_u8_Array chunks, Buffer_Chunk_Positio return(past_end); } -//////////////////////////////// - -internal i64 -buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ - i64 closest_match = 0; - if (p.y < 0.f){ - closest_match = list.manifested_index_range.min; - } - else if (p.y >= list.height){ - closest_match = list.manifested_index_range.max; - } - else{ - if (0.f < p.x && p.x < max_f32){ - f32 bottom_padding = list.bottom_padding; - f32 closest_x = -max_f32; - for (Layout_Item_Block *block = list.first; - block != 0; - block = block->next){ - i64 count = block->item_count; - Layout_Item *item = block->items; - for (i32 i = 0; i < count; i += 1, item += 1){ - if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ - continue; - } - // NOTE(allen): This only works if we build layouts in y-sorted order. - if (p.y < item->rect.y0){ - goto double_break; - } - if (item->rect.y1 + bottom_padding <= p.y){ - continue; - } - f32 dist0 = p.x - item->rect.x0; - f32 dist1 = item->rect.x1 - p.x; - if (dist0 >= 0.f && dist1 > 0.f){ - closest_match = item->index; - goto double_break; - } - // NOTE(allen): One of dist0 and dist1 are negative, but certainly not both. - // 1. Take the negative one. - // 2. If the negative distance is larger than closest_x, then this is closer. - f32 neg_dist = min(dist0, dist1); - if (closest_x < neg_dist){ - closest_x = neg_dist; - closest_match = item->index; - } - } - } - double_break:; - } - else{ - - if (p.x == max_f32){ - Layout_Item *prev_item = 0; - for (Layout_Item_Block *block = list.first; - block != 0; - block = block->next){ - i64 count = block->item_count; - Layout_Item *item = block->items; - for (i32 i = 0; i < count; i += 1, item += 1){ - if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ - continue; - } - if (p.y < item->rect.y0){ - goto double_break_2; - } - prev_item = item; - if (item->rect.y1 <= p.y){ - continue; - } - } - } - - double_break_2:; - if (prev_item != 0){ - closest_match = prev_item->index; - } - else{ - closest_match = list.manifested_index_range.max; - } - } - else{ - Layout_Item *closest_item = 0; - for (Layout_Item_Block *block = list.first; - block != 0; - block = block->next){ - i64 count = block->item_count; - Layout_Item *item = block->items; - for (i32 i = 0; i < count; i += 1, item += 1){ - if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ - continue; - } - // NOTE(allen): This only works if we build layouts in y-sorted order. - if (p.y < item->rect.y0){ - goto double_break_3; - } - if (item->rect.y1 <= p.y){ - continue; - } - closest_item = item; - goto double_break_3; - } - } - - double_break_3:; - if (closest_item != 0){ - closest_match = closest_item->index; - } - else{ - closest_match = list.manifested_index_range.min; - } - } - - } - } - return(closest_match); -} - -internal Layout_Item* -buffer_layout_get_first_with_index(Layout_Item_List list, i64 index){ - Layout_Item *result = 0; - Layout_Item *prev = 0; - for (Layout_Item_Block *block = list.first; - block != 0; - block = block->next){ - i64 count = block->item_count; - Layout_Item *item = block->items; - for (i32 i = 0; i < count; i += 1, item += 1){ - if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ - continue; - } - if (item->index > index){ - result = prev; - goto done; - } - if (item->index == index){ - result = item; - goto done; - } - prev = item; - } - } - if (result == 0){ - result = prev; - } - done:; - return(result); -} - -internal Rect_f32 -buffer_layout_box_of_pos(Layout_Item_List list, i64 index){ - Rect_f32 result = {}; - Layout_Item *item = buffer_layout_get_first_with_index(list, index); - if (item != 0){ - result = item->rect; - } - return(result); -} - -internal i64 -buffer_layout_get_pos_at_character(Layout_Item_List list, i64 character){ - i64 result = 0; - if (character <= 0){ - result = list.manifested_index_range.min; - } - else if (character >= list.character_count){ - result = list.manifested_index_range.max; - } - else{ - i64 counter = 0; - i64 next_counter = 0; - for (Layout_Item_Block *node = list.first; - node != 0; - node = node->next, counter = next_counter){ - next_counter = counter + node->character_count; - if (character >= next_counter){ - continue; - } - - i64 count = node->item_count; - i64 relative_character = character - counter; - i64 relative_character_counter = 0; - - Layout_Item *item = node->items; - for (i64 i = 0; i < count; i += 1, item += 1){ - if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ - continue; - } - if (relative_character_counter == relative_character){ - result = item->index; - break; - } - relative_character_counter += 1; - } - - break; - } - } - return(result); -} - -internal i64 -buffer_layout_character_from_pos(Layout_Item_List list, i64 index){ - i64 result = 0; - i64 prev_index = -1; - if (index <= list.manifested_index_range.first){ - result = 0; - } - else if (index > list.manifested_index_range.one_past_last){ - result = list.character_count - 1; - } - else{ - for (Layout_Item_Block *node = list.first; - node != 0; - node = node->next){ - Layout_Item *item = node->items; - i64 count = node->item_count; - for (i64 i = 0; i < count; i += 1, item += 1){ - if (item->index >= index){ - goto double_break; - } - if (item->index > prev_index){ - prev_index = item->index; - result += 1; - } - } - } - } - double_break:; - return(result); -} - // BOTTOM diff --git a/4ed_file.cpp b/4ed_file.cpp index 4627017a..2e900e79 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -413,8 +413,7 @@ file_line_y_difference(Thread_Context *tctx, Models *models, Editing_File *file, if (line_a != line_b){ Interval_i64 line_range = Ii64(line_a, line_b); for (i64 i = line_range.min; i < line_range.max; i += 1){ - Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, - width, face, i); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, i); result += line.height; } if (line_a < line_b){ @@ -428,14 +427,10 @@ internal i64 file_pos_at_relative_xy(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){ - Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, - layout_func, width, face, base_line, - relative_xy.y); + Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, layout_func, width, face, base_line, relative_xy.y); relative_xy.y -= shift.y_delta; - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - shift.line); - return(buffer_layout_nearest_pos_to_xy(line, relative_xy)); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, shift.line); + return(layout_nearest_pos_to_xy(line, relative_xy)); } internal Rect_f32 @@ -443,14 +438,10 @@ file_relative_box_of_pos(Thread_Context *tctx, Models *models, Editing_File *fil Layout_Function *layout_func, f32 width, Face *face, i64 base_line, i64 pos){ i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1; - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - line_number); - Rect_f32 result = buffer_layout_box_of_pos(line, pos); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number); + Rect_f32 result = layout_box_of_pos(line, pos); - f32 y_difference = file_line_y_difference(tctx, models, file, - layout_func, width, face, - line_number, base_line); + f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line); result.y0 += y_difference; result.y1 += y_difference; @@ -461,9 +452,7 @@ function Vec2_f32 file_relative_xy_of_pos(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 base_line, i64 pos){ - Rect_f32 rect = file_relative_box_of_pos(tctx, models, file, - layout_func, width, face, - base_line, pos); + Rect_f32 rect = file_relative_box_of_pos(tctx, models, file, layout_func, width, face, base_line, pos); return(rect_center(rect)); } @@ -471,9 +460,7 @@ internal Buffer_Point file_normalize_buffer_point(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, Buffer_Point point){ - Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, - layout_func, width, face, point.line_number, - point.pixel_shift.y); + Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, layout_func, width, face, point.line_number, point.pixel_shift.y); point.line_number = shift.line; point.pixel_shift.y -= shift.y_delta; point.pixel_shift.x = clamp_bot(0.f, point.pixel_shift.x); @@ -485,18 +472,14 @@ internal Vec2_f32 file_buffer_point_difference(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, Buffer_Point a, Buffer_Point b){ - f32 y_difference = file_line_y_difference(tctx, models, file, - layout_func, width, face, - a.line_number, b.line_number); + f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, a.line_number, b.line_number); Vec2_f32 result = a.pixel_shift - b.pixel_shift; result.y += y_difference; return(result); } internal Line_Shift_Character -file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, - Layout_Function *layout_func, f32 width, Face *face, - i64 line_number, i64 character_delta){ +file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 line_number, i64 character_delta){ Line_Shift_Character result = {}; i64 line_character = 0; @@ -516,9 +499,7 @@ file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *f line_number = 1; break; } - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - line_number); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number); line_character -= line.character_count; } if (!has_result){ @@ -531,9 +512,7 @@ file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *f b32 has_result = false; i64 line_count = buffer_line_count(&file->state.buffer); for (;;line_number += 1){ - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - line_number); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number); i64 next_character = line_character + line.character_count; if (character_delta < next_character){ has_result = true; @@ -556,15 +535,12 @@ file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *f } internal i64 -file_line_character_difference(Thread_Context *tctx, Models *models, Editing_File *file, - Layout_Function *layout_func, f32 width, Face *face, - i64 line_a, i64 line_b){ +file_line_character_difference(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 line_a, i64 line_b){ i64 result = 0; if (line_a != line_b){ Interval_i64 line_range = Ii64(line_a, line_b); for (i64 i = line_range.min; i < line_range.max; i += 1){ - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, i); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, i); result += line.character_count; } if (line_a < line_b){ @@ -578,26 +554,19 @@ internal i64 file_pos_from_relative_character(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 base_line, i64 relative_character){ - Line_Shift_Character shift = file_line_shift_characters(tctx, models, file, - layout_func, width, face, - base_line, relative_character); + Line_Shift_Character shift = file_line_shift_characters(tctx, models, file, layout_func, width, face, base_line, relative_character); relative_character -= shift.character_delta; - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - shift.line); - return(buffer_layout_get_pos_at_character(line, relative_character)); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, shift.line); + return(layout_get_pos_at_character(line, relative_character)); } internal i64 file_relative_character_from_pos(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 base_line, i64 pos){ i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1; - Layout_Item_List line = file_get_line_layout(tctx, models, file, - layout_func, width, face, - line_number); - i64 result = buffer_layout_character_from_pos(line, pos); - result += file_line_character_difference(tctx, models, file, - layout_func, width, face, line_number, base_line); + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number); + i64 result = layout_character_from_pos(line, pos); + result += file_line_character_difference(tctx, models, file, layout_func, width, face, line_number, base_line); return(result); } diff --git a/custom/4coder_code_index.cpp b/custom/4coder_code_index.cpp index fa81b98c..217767f2 100644 --- a/custom/4coder_code_index.cpp +++ b/custom/4coder_code_index.cpp @@ -225,16 +225,16 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content } function Code_Index_Nest* -generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state, i64 indentation); +generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state); function Code_Index_Nest* -generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 indentation); +generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state); function Code_Index_Nest* -generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state, i64 indentation); +generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state); function Code_Index_Nest* -generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state, i64 indentation){ +generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state){ Token *token = token_it_read(&state->it); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); result->kind = CodeIndexNest_Statement; @@ -242,10 +242,6 @@ generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state, i64 result->close = Ii64(max_i64); result->file = index; - result->open_indentation = indentation; - result->interior_indentation = indentation + 4; - result->close_indentation = indentation + 4; - state->in_statement = true; for (;;){ @@ -296,7 +292,7 @@ generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state, i64 } function Code_Index_Nest* -generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state, i64 indentation){ +generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ Token *token = token_it_read(&state->it); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); result->kind = CodeIndexNest_Preprocessor; @@ -304,11 +300,6 @@ generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state, i result->close = Ii64(max_i64); result->file = index; - result->open_indentation = 0; - result->interior_indentation = 0; - result->close_indentation = 0; - indentation = 0; - state->in_preprocessor = true; generic_parse_inc(state); @@ -327,14 +318,14 @@ generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state, i } if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state, indentation); + Code_Index_Nest *nest = generic_parse_scope(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; } if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state, indentation); + Code_Index_Nest *nest = generic_parse_paren(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; @@ -351,7 +342,7 @@ generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state, i } function Code_Index_Nest* -generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 indentation){ +generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ Token *token = token_it_read(&state->it); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); result->kind = CodeIndexNest_Scope; @@ -359,11 +350,6 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 inde result->close = Ii64(max_i64); result->file = index; - result->open_indentation = indentation; - result->interior_indentation = indentation + 4; - result->close_indentation = indentation; - indentation = result->interior_indentation; - state->scope_counter += 1; generic_parse_inc(state); @@ -382,7 +368,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 inde } else{ if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state, indentation); + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); code_index_push_nest(&index->nest_list, nest); continue; } @@ -396,14 +382,14 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 inde } if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state, indentation); + Code_Index_Nest *nest = generic_parse_scope(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; } if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state, indentation); + Code_Index_Nest *nest = generic_parse_paren(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; @@ -415,7 +401,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 inde } { - Code_Index_Nest *nest = generic_parse_statement(index, state, indentation); + Code_Index_Nest *nest = generic_parse_statement(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); } @@ -429,7 +415,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state, i64 inde } function Code_Index_Nest* -generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state, i64 indentation){ +generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ Token *token = token_it_read(&state->it); Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); result->kind = CodeIndexNest_Paren; @@ -451,12 +437,6 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state, i64 inde manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; } - indentation += manifested_characters_on_line; - - result->open_indentation = indentation; - result->interior_indentation = indentation; - result->close_indentation = indentation; - state->paren_counter += 1; generic_parse_inc(state); @@ -475,7 +455,7 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state, i64 inde } else{ if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state, indentation); + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); code_index_push_nest(&index->nest_list, nest); continue; } @@ -493,14 +473,14 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state, i64 inde } if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state, indentation); + Code_Index_Nest *nest = generic_parse_scope(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; } if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state, indentation); + Code_Index_Nest *nest = generic_parse_paren(index, state); nest->parent = result; code_index_push_nest(&result->nest_list, nest); continue; @@ -520,7 +500,6 @@ function b32 generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ b32 result = false; - i64 indentation = 0; i64 first_index = token_it_index(&state->it); i64 one_past_last_index = first_index + limit; for (;;){ @@ -533,15 +512,15 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta } if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state, indentation); + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); code_index_push_nest(&index->nest_list, nest); } else if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state, indentation); + Code_Index_Nest *nest = generic_parse_scope(index, state); code_index_push_nest(&index->nest_list, nest); } else if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state, indentation); + Code_Index_Nest *nest = generic_parse_paren(index, state); code_index_push_nest(&index->nest_list, nest); } else{ @@ -580,28 +559,49 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content //////////////////////////////// -function i64 -layout_index_indent(Code_Index_File *file, i64 pos){ - i64 indent = 0; - Code_Index_Nest *nest = code_index_get_nest(file, pos); +function f32 +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 space_advance){ + f32 result = 0.f; if (nest != 0){ - if (pos == nest->open.min && pos == nest->open.max){ - indent = nest->open_indentation; - } - else if (pos == nest->close.min){ - indent = nest->close_indentation; - } - else{ - indent = nest->interior_indentation; + switch (nest->kind){ + case CodeIndexNest_Scope: + case CodeIndexNest_Preprocessor: + { + + result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += 4.f*space_advance; + } + }break; + + case CodeIndexNest_Statement: + { + result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += 4.f*space_advance; + } + }break; + + case CodeIndexNest_Paren: + { + Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1); + result = box.x1; + }break; } } - return(indent); + return(result); } function f32 -layout_index_x_shift(Code_Index_File *file, i64 pos, f32 space_advance){ - i64 indent = layout_index_indent(file, pos); - return(((f32)indent)*space_advance); +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 space_advance){ + f32 indent = 0; + Code_Index_Nest *nest = code_index_get_nest(file, pos); + if (nest != 0){ + indent = layout_index_x_shift(app, reflex, nest, pos, space_advance); + } + return(indent); } function Layout_Item_List @@ -617,6 +617,8 @@ layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID bu f32 wrap_align_x = width - metrics.normal_advance; + Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); + if (text.size == 0){ lr_tb_write_blank(&pos_vars, arena, &list, range.start); } @@ -681,13 +683,13 @@ layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID bu lr_tb_write_ghost(&pos_vars, arena, &list, index, '\\'); lr_tb_next_line(&pos_vars); - f32 shift = layout_index_x_shift(file, index, metrics.space_advance); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); lr_tb_advance_x_without_item(&pos_vars, shift); } } else{ i64 index = layout_index_from_ptr(word.str, text.str, range.first); - f32 shift = layout_index_x_shift(file, index, metrics.space_advance); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); lr_tb_advance_x_without_item(&pos_vars, shift); } @@ -735,7 +737,7 @@ layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID bu case '\n': { if (first_of_the_line){ - f32 shift = layout_index_x_shift(file, index, + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); lr_tb_advance_x_without_item(&pos_vars, shift); } @@ -754,7 +756,7 @@ layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID bu if (newline_layout_consume_finish(&newline_vars)){ i64 index = layout_index_from_ptr(ptr, text.str, range.first); if (first_of_the_line){ - f32 shift = layout_index_x_shift(file, index, + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); lr_tb_advance_x_without_item(&pos_vars, shift); } diff --git a/custom/4coder_code_index.h b/custom/4coder_code_index.h index e49e2770..a46a14fd 100644 --- a/custom/4coder_code_index.h +++ b/custom/4coder_code_index.h @@ -34,10 +34,6 @@ struct Code_Index_Nest{ Range_i64 open; Range_i64 close; - i64 open_indentation; - i64 interior_indentation; - i64 close_indentation; - struct Code_Index_File *file; Code_Index_Nest *parent; diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index 04559df2..5652819e 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -59,6 +59,7 @@ #define DYNAMIC_LINK_API #include "generated/system_api.cpp" #include "4coder_system_helpers.cpp" +#include "4coder_layout.cpp" #include "4coder_profile.cpp" #include "4coder_profile_static_enable.cpp" #include "4coder_events.cpp" diff --git a/custom/4coder_layout.cpp b/custom/4coder_layout.cpp new file mode 100644 index 00000000..912003f4 --- /dev/null +++ b/custom/4coder_layout.cpp @@ -0,0 +1,237 @@ +/* +4coder_layout.cpp - Implementation of basic lookup routines on line layout data. +*/ + +// TOP + +internal i64 +layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ + i64 closest_match = 0; + if (p.y < 0.f){ + closest_match = list.manifested_index_range.min; + } + else if (p.y >= list.height){ + closest_match = list.manifested_index_range.max; + } + else{ + if (0.f < p.x && p.x < max_f32){ + f32 bottom_padding = list.bottom_padding; + f32 closest_x = -max_f32; + for (Layout_Item_Block *block = list.first; + block != 0; + block = block->next){ + i64 count = block->item_count; + Layout_Item *item = block->items; + for (i32 i = 0; i < count; i += 1, item += 1){ + if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ + continue; + } + // NOTE(allen): This only works if we build layouts in y-sorted order. + if (p.y < item->rect.y0){ + goto double_break; + } + if (item->rect.y1 + bottom_padding <= p.y){ + continue; + } + f32 dist0 = p.x - item->rect.x0; + f32 dist1 = item->rect.x1 - p.x; + if (dist0 >= 0.f && dist1 > 0.f){ + closest_match = item->index; + goto double_break; + } + // NOTE(allen): One of dist0 and dist1 are negative, but certainly not both. + // 1. Take the negative one. + // 2. If the negative distance is larger than closest_x, then this is closer. + f32 neg_dist = min(dist0, dist1); + if (closest_x < neg_dist){ + closest_x = neg_dist; + closest_match = item->index; + } + } + } + double_break:; + } + else{ + + if (p.x == max_f32){ + Layout_Item *prev_item = 0; + for (Layout_Item_Block *block = list.first; + block != 0; + block = block->next){ + i64 count = block->item_count; + Layout_Item *item = block->items; + for (i32 i = 0; i < count; i += 1, item += 1){ + if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ + continue; + } + if (p.y < item->rect.y0){ + goto double_break_2; + } + prev_item = item; + if (item->rect.y1 <= p.y){ + continue; + } + } + } + + double_break_2:; + if (prev_item != 0){ + closest_match = prev_item->index; + } + else{ + closest_match = list.manifested_index_range.max; + } + } + else{ + Layout_Item *closest_item = 0; + for (Layout_Item_Block *block = list.first; + block != 0; + block = block->next){ + i64 count = block->item_count; + Layout_Item *item = block->items; + for (i32 i = 0; i < count; i += 1, item += 1){ + if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ + continue; + } + // NOTE(allen): This only works if we build layouts in y-sorted order. + if (p.y < item->rect.y0){ + goto double_break_3; + } + if (item->rect.y1 <= p.y){ + continue; + } + closest_item = item; + goto double_break_3; + } + } + + double_break_3:; + if (closest_item != 0){ + closest_match = closest_item->index; + } + else{ + closest_match = list.manifested_index_range.min; + } + } + + } + } + return(closest_match); +} + +internal Layout_Item* +layout_get_first_with_index(Layout_Item_List list, i64 index){ + Layout_Item *result = 0; + Layout_Item *prev = 0; + for (Layout_Item_Block *block = list.first; + block != 0; + block = block->next){ + i64 count = block->item_count; + Layout_Item *item = block->items; + for (i32 i = 0; i < count; i += 1, item += 1){ + if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ + continue; + } + if (item->index > index){ + result = prev; + goto done; + } + if (item->index == index){ + result = item; + goto done; + } + prev = item; + } + } + if (result == 0){ + result = prev; + } + done:; + return(result); +} + +internal Rect_f32 +layout_box_of_pos(Layout_Item_List list, i64 index){ + Rect_f32 result = {}; + Layout_Item *item = layout_get_first_with_index(list, index); + if (item != 0){ + result = item->rect; + } + return(result); +} + +internal i64 +layout_get_pos_at_character(Layout_Item_List list, i64 character){ + i64 result = 0; + if (character <= 0){ + result = list.manifested_index_range.min; + } + else if (character >= list.character_count){ + result = list.manifested_index_range.max; + } + else{ + i64 counter = 0; + i64 next_counter = 0; + for (Layout_Item_Block *node = list.first; + node != 0; + node = node->next, counter = next_counter){ + next_counter = counter + node->character_count; + if (character >= next_counter){ + continue; + } + + i64 count = node->item_count; + i64 relative_character = character - counter; + i64 relative_character_counter = 0; + + Layout_Item *item = node->items; + for (i64 i = 0; i < count; i += 1, item += 1){ + if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){ + continue; + } + if (relative_character_counter == relative_character){ + result = item->index; + break; + } + relative_character_counter += 1; + } + + break; + } + } + return(result); +} + +internal i64 +layout_character_from_pos(Layout_Item_List list, i64 index){ + i64 result = 0; + i64 prev_index = -1; + if (index <= list.manifested_index_range.first){ + result = 0; + } + else if (index > list.manifested_index_range.one_past_last){ + result = list.character_count - 1; + } + else{ + for (Layout_Item_Block *node = list.first; + node != 0; + node = node->next){ + Layout_Item *item = node->items; + i64 count = node->item_count; + for (i64 i = 0; i < count; i += 1, item += 1){ + if (item->index >= index){ + goto double_break; + } + if (item->index > prev_index){ + prev_index = item->index; + result += 1; + } + } + } + } + double_break:; + return(result); +} + +// BOTTOM + diff --git a/custom/4coder_layout_rule.cpp b/custom/4coder_layout_rule.cpp index f593f664..d8aecb23 100644 --- a/custom/4coder_layout_rule.cpp +++ b/custom/4coder_layout_rule.cpp @@ -4,6 +4,31 @@ // TOP +function Layout_Reflex +get_layout_reflex(Layout_Item_List *list, Buffer_ID buffer, f32 width, Face_ID face){ + Layout_Reflex reflex = {}; + reflex.list = list; + reflex.buffer = buffer; + reflex.width = width; + reflex.face = face; + return(reflex); +} + +function Rect_f32 +layout_reflex_get_rect(Application_Links *app, Layout_Reflex *reflex, i64 pos){ + Rect_f32 rect = {}; + if (range_contains(reflex->list->input_index_range, pos)){ + rect = layout_box_of_pos(*reflex->list, pos); + } + else{ + Buffer_Cursor cursor = buffer_compute_cursor(app, reflex->buffer, seek_pos(pos)); + rect = buffer_relative_box_of_pos(app, reflex->buffer, reflex->width, reflex->face, cursor.line, cursor.pos); + } + return(rect); +} + +//////////////////////////////// + function i64 layout_index_from_ptr(u8 *ptr, u8 *string_base, i64 index_base){ return((i64)(ptr - string_base) + index_base); diff --git a/custom/4coder_layout_rule.h b/custom/4coder_layout_rule.h index 71dad86c..0fd1cc43 100644 --- a/custom/4coder_layout_rule.h +++ b/custom/4coder_layout_rule.h @@ -26,6 +26,13 @@ struct LefRig_TopBot_Layout_Vars{ f32 width; }; +struct Layout_Reflex{ + Layout_Item_List *list; + Buffer_ID buffer; + f32 width; + Face_ID face; +}; + #endif // BOTTOM diff --git a/custom/4coder_string_match.cpp b/custom/4coder_string_match.cpp index 7e4f981e..f79739bf 100644 --- a/custom/4coder_string_match.cpp +++ b/custom/4coder_string_match.cpp @@ -138,7 +138,7 @@ string_match_list_merge_nearest(String_Match_List *a, String_Match_List *b, Rang internal String_Match_List string_match_list_merge_front_to_back(String_Match_List *a, String_Match_List *b){ - return(string_match_list_merge_nearest(a, b, Ii64(0))); + return(string_match_list_merge_nearest(a, b, Ii64((i64)0))); } // BOTTOM