diff --git a/4ed_file.cpp b/4ed_file.cpp index 800469be..4eefb0ae 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -116,6 +116,12 @@ struct Editing_File_State{ f32 *line_indents; i32 line_indent_max; + i32 wrap_line_count; + + i32 *wrap_positions; + i32 wrap_position_count; + i32 wrap_position_max; + Undo_Data undo; Cpp_Token_Array token_array; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 19ede35b..c47344b6 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -9,11 +9,11 @@ // TOP -#define VWHITE 0 +#define VWHITE 1 internal i32 get_or_add_map_index(Models *models, i32 mapid){ - i32 result; + i32 result = 0; i32 user_map_count = models->user_map_count; i32 *map_id_table = models->map_id_table; for (result = 0; result < user_map_count; ++result){ @@ -30,7 +30,7 @@ get_or_add_map_index(Models *models, i32 mapid){ internal i32 get_map_index(Models *models, i32 mapid){ - i32 result; + i32 result = 0; i32 user_map_count = models->user_map_count; i32 *map_id_table = models->map_id_table; for (result = 0; result < user_map_count; ++result){ @@ -420,19 +420,34 @@ view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ f32 line_shift = 0.f; b32 do_wrap = 0; i32 wrap_unit_end = 0; + + b32 first_wrap_determination = 1; + i32 wrap_array_index = 0; + do{ stop = buffer_cursor_seek(&state, params, line_shift, do_wrap, wrap_unit_end); switch (stop.status){ case BLStatus_NeedWrapDetermination: { - i32 rounded_pos = stop.pos - (stop.pos%11); - if ((rounded_pos % 2) == 1){ - do_wrap = 1; + if (first_wrap_determination){ + wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count); + ++wrap_array_index; + if (file->state.wrap_positions[wrap_array_index] == stop.pos){ + do_wrap = 1; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; + } + else{ + do_wrap = 0; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; + } + first_wrap_determination = 0; } else{ - do_wrap = 0; + assert_4tech(stop.pos == wrap_unit_end); + do_wrap = 1; + ++wrap_array_index; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; } - wrap_unit_end = rounded_pos + 11; }break; case BLStatus_NeedWrapLineShift: @@ -969,10 +984,19 @@ file_allocate_wraps_as_needed(General_Memory *general, Editing_File *file){ file->state.buffer.line_count, sizeof(f32)); } +inline void +file_allocate_wrap_positions_as_needed(General_Memory *general, Editing_File *file, i32 min_amount){ + file_allocate_metadata_as_needed(general, &file->state.buffer, + (void**)&file->state.wrap_positions, + &file->state.wrap_position_max, + min_amount, sizeof(f32)); +} + internal void file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv){ file_allocate_wraps_as_needed(&models->mem.general, file); file_allocate_indents_as_needed(&models->mem.general, file, file->state.buffer.line_count); + file_allocate_wrap_positions_as_needed(&models->mem.general, file, file->state.buffer.line_count); Buffer_Measure_Wrap_Params params; params.buffer = &file->state.buffer; @@ -993,15 +1017,20 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv b32 do_wrap = 0; i32 wrap_unit_end = 0; + i32 wrap_position_index = 0; + file->state.wrap_positions[wrap_position_index++] = 0; + do{ - stop = buffer_measure_wrap_y(&state, params, - line_shift, do_wrap, wrap_unit_end); + stop = buffer_measure_wrap_y(&state, params, line_shift, do_wrap, wrap_unit_end); + switch (stop.status){ case BLStatus_NeedWrapDetermination: { i32 rounded_pos = stop.pos - (stop.pos%11); if ((rounded_pos % 2) == 1){ do_wrap = 1; + file_allocate_wrap_positions_as_needed(&models->mem.general, file, wrap_position_index); + file->state.wrap_positions[wrap_position_index++] = stop.pos; } else{ do_wrap = 0; @@ -1023,10 +1052,17 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv } file->state.line_indents[stop.wrap_line_index] = line_shift; + file->state.wrap_line_count = stop.wrap_line_index; }break; } }while(stop.status != BLStatus_Finished); + ++file->state.wrap_line_count; + + file_allocate_wrap_positions_as_needed(&models->mem.general, file, wrap_position_index); + file->state.wrap_positions[wrap_position_index++] = buffer_size(&file->state.buffer); + file->state.wrap_position_count = wrap_position_index; + file_update_cursor_positions(models, file); } @@ -4956,19 +4992,33 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target b32 do_wrap = 0; i32 wrap_unit_end = 0; + b32 first_wrap_determination = 1; + i32 wrap_array_index = 0; + do{ stop = buffer_render_data(&state, params, line_shift, do_wrap, wrap_unit_end); switch (stop.status){ case BLStatus_NeedWrapDetermination: { - i32 rounded_pos = stop.pos - (stop.pos%11); - if ((rounded_pos % 2) == 1){ - do_wrap = 1; + if (first_wrap_determination){ + wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count); + ++wrap_array_index; + if (file->state.wrap_positions[wrap_array_index] == stop.pos){ + do_wrap = 1; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; + } + else{ + do_wrap = 0; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; + } + first_wrap_determination = 0; } else{ - do_wrap = 0; + assert_4tech(stop.pos == wrap_unit_end); + do_wrap = 1; + ++wrap_array_index; + wrap_unit_end = file->state.wrap_positions[wrap_array_index]; } - wrap_unit_end = rounded_pos + 11; }break; case BLStatus_NeedWrapLineShift: diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 24fc21ce..a82a3d32 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -592,23 +592,16 @@ buffer_remeasure_wrap_y(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l } internal_4tech i32 -buffer_get_line_index_range(Buffer_Type *buffer, i32 pos, i32 l_bound, i32 u_bound){ - i32 *lines = buffer->line_starts; +binary_search(i32 *array, i32 value, i32 l_bound, i32 u_bound){ i32 start = l_bound, end = u_bound; i32 i = 0; - assert_4tech(0 <= l_bound); - assert_4tech(l_bound <= u_bound); - assert_4tech(u_bound <= buffer->line_count); - - assert_4tech(lines != 0); - for (;;){ i = (start + end) >> 1; - if (lines[i] < pos){ + if (array[i] < value){ start = i; } - else if (lines[i] > pos){ + else if (array[i] > value){ end = i; } else{ @@ -624,61 +617,34 @@ buffer_get_line_index_range(Buffer_Type *buffer, i32 pos, i32 l_bound, i32 u_bou return(i); } +inline_4tech i32 +buffer_get_line_index_range(Buffer_Type *buffer, i32 pos, i32 l_bound, i32 u_bound){ + assert_4tech(0 <= l_bound); + assert_4tech(l_bound <= u_bound); + assert_4tech(u_bound <= buffer->line_count); + + assert_4tech(buffer->line_starts != 0); + + i32 i = binary_search(buffer->line_starts, pos, l_bound, u_bound); + return(i); +} + inline_4tech i32 buffer_get_line_index(Buffer_Type *buffer, i32 pos){ i32 result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); return(result); } -// TODO(allen): Merge all these binary searches. -internal_4tech i32 +inline_4tech i32 buffer_get_line_index_from_character_pos(i32 *character_starts, i32 pos, i32 l_bound, i32 u_bound){ - i32 start = l_bound, end = u_bound; - i32 i = 0; - - for (;;){ - i = (start + end) >> 1; - if (character_starts[i] < pos){ - start = i; - } - else if (character_starts[i] > pos){ - end = i; - } - else{ - break; - } - assert_4tech(start < end); - if (start == end - 1){ - i = start; - break; - } - } - + i32 i = binary_search(character_starts, pos, l_bound, u_bound); return(i); } -internal_4tech i32 +inline_4tech i32 buffer_get_line_index_from_wrapped_y(i32 *wrap_line_index, f32 y, f32 line_height, i32 l_bound, i32 u_bound){ i32 wrap_index = FLOOR32(y/line_height); - i32 start = l_bound, end = u_bound; - i32 i = 0; - for (;;){ - i = (start + end) >> 1; - if (wrap_line_index[i] < wrap_index){ - start = i; - } - else if (wrap_line_index[i] > wrap_index){ - end = i; - } - else{ - break; - } - assert_4tech(start < end); - if (start == end - 1){ - i = start; - break; - } - } + i32 i = binary_search(wrap_line_index, wrap_index, l_bound, u_bound); return(i); }