driving wrap positions through a metadata system

master
Allen Webster 2016-09-29 14:29:00 -04:00
parent 7d31bb986d
commit 40d9aebd64
3 changed files with 90 additions and 68 deletions

View File

@ -116,6 +116,12 @@ struct Editing_File_State{
f32 *line_indents; f32 *line_indents;
i32 line_indent_max; i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
Undo_Data undo; Undo_Data undo;
Cpp_Token_Array token_array; Cpp_Token_Array token_array;

View File

@ -9,11 +9,11 @@
// TOP // TOP
#define VWHITE 0 #define VWHITE 1
internal i32 internal i32
get_or_add_map_index(Models *models, i32 mapid){ get_or_add_map_index(Models *models, i32 mapid){
i32 result; i32 result = 0;
i32 user_map_count = models->user_map_count; i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table; i32 *map_id_table = models->map_id_table;
for (result = 0; result < user_map_count; ++result){ for (result = 0; result < user_map_count; ++result){
@ -30,7 +30,7 @@ get_or_add_map_index(Models *models, i32 mapid){
internal i32 internal i32
get_map_index(Models *models, i32 mapid){ get_map_index(Models *models, i32 mapid){
i32 result; i32 result = 0;
i32 user_map_count = models->user_map_count; i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table; i32 *map_id_table = models->map_id_table;
for (result = 0; result < user_map_count; ++result){ 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; f32 line_shift = 0.f;
b32 do_wrap = 0; b32 do_wrap = 0;
i32 wrap_unit_end = 0; i32 wrap_unit_end = 0;
b32 first_wrap_determination = 1;
i32 wrap_array_index = 0;
do{ do{
stop = buffer_cursor_seek(&state, params, line_shift, do_wrap, wrap_unit_end); stop = buffer_cursor_seek(&state, params, line_shift, do_wrap, wrap_unit_end);
switch (stop.status){ switch (stop.status){
case BLStatus_NeedWrapDetermination: case BLStatus_NeedWrapDetermination:
{ {
i32 rounded_pos = stop.pos - (stop.pos%11); if (first_wrap_determination){
if ((rounded_pos % 2) == 1){ wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count);
do_wrap = 1; ++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{ 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; }break;
case BLStatus_NeedWrapLineShift: 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)); 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 internal void
file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv){ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv){
file_allocate_wraps_as_needed(&models->mem.general, file); 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_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; Buffer_Measure_Wrap_Params params;
params.buffer = &file->state.buffer; 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; b32 do_wrap = 0;
i32 wrap_unit_end = 0; i32 wrap_unit_end = 0;
i32 wrap_position_index = 0;
file->state.wrap_positions[wrap_position_index++] = 0;
do{ do{
stop = buffer_measure_wrap_y(&state, params, stop = buffer_measure_wrap_y(&state, params, line_shift, do_wrap, wrap_unit_end);
line_shift, do_wrap, wrap_unit_end);
switch (stop.status){ switch (stop.status){
case BLStatus_NeedWrapDetermination: case BLStatus_NeedWrapDetermination:
{ {
i32 rounded_pos = stop.pos - (stop.pos%11); i32 rounded_pos = stop.pos - (stop.pos%11);
if ((rounded_pos % 2) == 1){ if ((rounded_pos % 2) == 1){
do_wrap = 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{ else{
do_wrap = 0; 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.line_indents[stop.wrap_line_index] = line_shift;
file->state.wrap_line_count = stop.wrap_line_index;
}break; }break;
} }
}while(stop.status != BLStatus_Finished); }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); 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; b32 do_wrap = 0;
i32 wrap_unit_end = 0; i32 wrap_unit_end = 0;
b32 first_wrap_determination = 1;
i32 wrap_array_index = 0;
do{ do{
stop = buffer_render_data(&state, params, line_shift, do_wrap, wrap_unit_end); stop = buffer_render_data(&state, params, line_shift, do_wrap, wrap_unit_end);
switch (stop.status){ switch (stop.status){
case BLStatus_NeedWrapDetermination: case BLStatus_NeedWrapDetermination:
{ {
i32 rounded_pos = stop.pos - (stop.pos%11); if (first_wrap_determination){
if ((rounded_pos % 2) == 1){ wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count);
do_wrap = 1; ++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{ 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; }break;
case BLStatus_NeedWrapLineShift: case BLStatus_NeedWrapLineShift:

View File

@ -592,23 +592,16 @@ buffer_remeasure_wrap_y(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l
} }
internal_4tech i32 internal_4tech i32
buffer_get_line_index_range(Buffer_Type *buffer, i32 pos, i32 l_bound, i32 u_bound){ binary_search(i32 *array, i32 value, i32 l_bound, i32 u_bound){
i32 *lines = buffer->line_starts;
i32 start = l_bound, end = u_bound; i32 start = l_bound, end = u_bound;
i32 i = 0; 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 (;;){ for (;;){
i = (start + end) >> 1; i = (start + end) >> 1;
if (lines[i] < pos){ if (array[i] < value){
start = i; start = i;
} }
else if (lines[i] > pos){ else if (array[i] > value){
end = i; end = i;
} }
else{ else{
@ -624,61 +617,34 @@ buffer_get_line_index_range(Buffer_Type *buffer, i32 pos, i32 l_bound, i32 u_bou
return(i); 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 inline_4tech i32
buffer_get_line_index(Buffer_Type *buffer, i32 pos){ buffer_get_line_index(Buffer_Type *buffer, i32 pos){
i32 result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); i32 result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
return(result); return(result);
} }
// TODO(allen): Merge all these binary searches. inline_4tech i32
internal_4tech i32
buffer_get_line_index_from_character_pos(i32 *character_starts, i32 pos, i32 l_bound, i32 u_bound){ 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 = binary_search(character_starts, pos, l_bound, 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;
}
}
return(i); 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){ 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 wrap_index = FLOOR32(y/line_height);
i32 start = l_bound, end = u_bound; i32 i = binary_search(wrap_line_index, wrap_index, l_bound, 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;
}
}
return(i); return(i);
} }