introduced first pass version of character start measuring

master
Allen Webster 2016-09-24 13:25:11 -04:00
parent fcd6f703b4
commit 249c6f5e4a
4 changed files with 130 additions and 80 deletions

View File

@ -944,19 +944,15 @@ CUSTOM_COMMAND_SIG(page_down){
CUSTOM_COMMAND_SIG(move_left){
uint32_t access = AccessProtected;
View_Summary view = get_active_view(app, access);
int32_t new_pos = view.cursor.pos - 1;
view_set_cursor(app, &view,
seek_pos(new_pos),
true);
int32_t new_pos = view.cursor.character_pos - 1;
view_set_cursor(app, &view, seek_character_pos(new_pos), 1);
}
CUSTOM_COMMAND_SIG(move_right){
uint32_t access = AccessProtected;
View_Summary view = get_active_view(app, access);
int32_t new_pos = view.cursor.pos + 1;
view_set_cursor(app, &view,
seek_pos(new_pos),
true);
int32_t new_pos = view.cursor.character_pos + 1;
view_set_cursor(app, &view, seek_character_pos(new_pos), 1);
}
//

View File

@ -110,6 +110,9 @@ struct Editing_File_State{
f32 *wraps;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
Undo_Data undo;
Cpp_Token_Array token_array;
@ -329,54 +332,6 @@ edit_pos_get_new(Editing_File *file, i32 index){
return(result);
}
//
// Buffer Metadata Measuring
//
internal void
file_measure_starts(System_Functions *system, General_Memory *general, Buffer_Type *buffer){
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
TentativeAssert(buffer->line_starts);
// TODO(allen): when unable to allocate?
}
Buffer_Measure_Starts state = {0};
while (buffer_measure_starts(&state, buffer)){
i32 count = state.count;
i32 max = buffer->line_max;
max = ((max + 1) << 1);
{
i32 *new_lines = (i32*)general_memory_reallocate(
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max);
// TODO(allen): when unable to grow?
TentativeAssert(new_lines);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
}
buffer->line_count = state.count;
}
internal i32
file_compute_lowest_line(Editing_File *file, f32 font_height){
i32 lowest_line = 0;
Buffer_Type *buffer = &file->state.buffer;
if (file->settings.unwrapped_lines){
lowest_line = buffer->line_count - 1;
}
else{
f32 term_line_y = file->state.wraps[buffer->line_count];
lowest_line = CEIL32((term_line_y/font_height) - 1);
}
return(lowest_line);
}
//
// File Cursor Seeking
//
@ -415,8 +370,6 @@ file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor
return(result);
}
//
// Working_Set stuff
//

View File

@ -448,6 +448,22 @@ view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){
return(CEIL32(max_target_y));
}
internal i32
file_compute_lowest_line(Editing_File *file, f32 font_height){
i32 lowest_line = 0;
Buffer_Type *buffer = &file->state.buffer;
if (file->settings.unwrapped_lines){
lowest_line = buffer->line_count;
}
else{
f32 term_line_y = file->state.wraps[buffer->line_count];
lowest_line = CEIL32(term_line_y/font_height);
}
return(lowest_line);
}
inline i32
view_compute_max_target_y(View *view){
i32 line_height = view->line_height;
@ -848,34 +864,83 @@ file_update_cursor_positions(Models *models, Editing_File *file){
}
}
// NOTE(allen): This call assumes that the buffer's line starts are already correct,
//
// File Metadata Measuring
//
internal void
file_measure_starts(System_Functions *system, General_Memory *general, Buffer_Type *buffer){
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
TentativeAssert(buffer->line_starts);
// TODO(allen): when unable to allocate?
}
Buffer_Measure_Starts state = {0};
while (buffer_measure_starts(&state, buffer)){
i32 count = state.count;
i32 max = buffer->line_max;
max = ((max + 1) << 1);
{
i32 *new_lines = (i32*)general_memory_reallocate(
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max);
// TODO(allen): when unable to grow?
TentativeAssert(new_lines);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
}
buffer->line_count = state.count;
}
// NOTE(allen): These calls assumes that the buffer's line starts are already correct,
// and that the buffer's line_count is correct.
internal void
file_allocate_wraps_as_needed(General_Memory *general, Editing_File *file){
Buffer_Type *buffer = &file->state.buffer;
if (file->state.wraps == 0){
file_allocate_metadata_as_needed(General_Memory *general, Buffer_Type *buffer,
void **mem, i32 *mem_max_count, i32 item_size){
if (*mem == 0){
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
file->state.wraps = (f32*)general_memory_allocate(general, max*sizeof(f32));
file->state.wrap_max = max;
max = (max+(0x3FF))&(~(0x3FF));
*mem = general_memory_allocate(general, max*item_size);
*mem_max_count = max;
}
else if (file->state.wrap_max < buffer->line_count){
i32 old_max = file->state.wrap_max;
else if (*mem_max_count < buffer->line_count){
i32 old_max = *mem_max_count;
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
max = (max+(0x3FF))&(~(0x3FF));
f32 *new_wraps = (f32*)general_memory_reallocate(
general, file->state.wraps, sizeof(f32)*old_max, sizeof(f32)*max);
void *new_mem = general_memory_reallocate(general, *mem, item_size*old_max, item_size*max);
TentativeAssert(new_wraps);
file->state.wraps = new_wraps;
file->state.wrap_max = max;
TentativeAssert(new_mem);
*mem = new_mem;
*mem_max_count = max;
}
}
// NOTE(allen): This call assumes that the buffer's line starts are already correct,
// and that the buffer's line_count is correct.
inline void
file_allocate_character_starts_as_needed(General_Memory *general, Editing_File *file){
file_allocate_metadata_as_needed(general, &file->state.buffer,
(void**)&file->state.character_starts,
&file->state.character_start_max, sizeof(i32));
}
internal void
file_measure_character_starts(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, 1);
file_update_cursor_positions(models, file);
}
inline void
file_allocate_wraps_as_needed(General_Memory *general, Editing_File *file){
file_allocate_metadata_as_needed(general, &file->state.buffer,
(void**)&file->state.wraps,
&file->state.wrap_max, 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);
@ -884,14 +949,16 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
file_update_cursor_positions(models, file);
}
// NOTE(allen): This call assumes that the buffer's line starts are already correct,
// and that the buffer's line_count is correct.
internal void
file_set_display_width(Models *models, Editing_File *file, i32 display_width, f32 font_height, f32 *adv){
file->settings.display_width = display_width;
file_measure_wraps(models, file, font_height, adv);
}
//
//
//
internal void
file_create_from_string(System_Functions *system, Models *models,
Editing_File *file, String val, b8 read_only = 0){
@ -922,8 +989,12 @@ file_create_from_string(System_Functions *system, Models *models,
}
file_synchronize_times(system, file);
// TODO(allen): batch some of these together so we can avoid
// making so many passes over the buffer?
file_measure_starts(system, general, &file->state.buffer);
file_measure_character_starts(models, file);
i16 font_id = models->global_font.font_id;
file->settings.font_id = font_id;
Render_Font *font = get_font_info(font_set, font_id)->font;
@ -1983,6 +2054,10 @@ file_do_single_edit(System_Functions *system,
file_grow_starts_as_needed(general, buffer, line_shift);
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
// TODO(allen): write the remeasurement version
file_allocate_character_starts_as_needed(general, file);
buffer_measure_character_starts(buffer, file->state.character_starts, 0, 1);
file_allocate_wraps_as_needed(general, file);
buffer_remeasure_wrap_y(buffer, line_start, line_end, line_shift,
file->state.wraps, (f32)font->height, font->advance_data,
@ -2049,6 +2124,9 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
Buffer_Measure_Starts measure_state = {};
buffer_measure_starts(&measure_state, &file->state.buffer);
// TODO(allen): write the remeasurement version
file_measure_character_starts(models, file);
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_measure_wraps(models, file, (f32)font->height, font->advance_data);

View File

@ -129,7 +129,6 @@ buffer_measure_starts(Buffer_Measure_Starts *state, Buffer_Type *buffer){
return(result);
}
#if 0
internal_4tech void
buffer_measure_character_starts(Buffer_Type *buffer, i32 *character_starts, i32 mode, i32 virtual_whitespace){
assert_4tech(mode == 0);
@ -139,8 +138,32 @@ buffer_measure_character_starts(Buffer_Type *buffer, i32 *character_starts, i32
i32 size = buffer_size(buffer);
i32 line_index = 0;
i32 character_index = 0;
character_starts[line_index++] = character_index;
if (buffer_stringify_loop(&stream, buffer, i, size)){
b32 still_looping = 0;
do{
for (; i < stream.end; ++i){
u8 ch = (u8)stream.data[i];
if (ch == '\n'){
++character_index;
character_starts[line_index++] = character_index;
}
else{
++character_index;
}
}
still_looping = buffer_stringify_next(&stream);
}while(still_looping);
}
++character_index;
character_starts[line_index++] = character_index;
assert_4tech(line_index-1 == buffer->line_count);
}
#endif
internal_4tech void
buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps, f32 font_height, f32 *adv, f32 max_width){