4coder/buffer/4coder_test_abstract.cpp

185 lines
6.6 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
* Four Tech
*
* public domain -- no warranty is offered or implied; use this code at your own risk
*
* 08.11.2015
*
* Buffer experiment testing layer, abstract portion
*
*/
// TOP
#define Buffer_Init_Type cat_4tech(Buffer_Type, _Init)
#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
#define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
void
init_buffer(Buffer_Type *buffer, File_Data file, void *scratch, int scratch_size){
memzero_4tech(*buffer);
Buffer_Init_Type init;
for (init = buffer_begin_init(buffer, file.data, file.size);
buffer_init_need_more(&init);){
int page_size = buffer_init_page_size(&init);
void *page = malloc(page_size);
buffer_init_provide_page(&init, page, page_size);
}
debug_4tech(int result =)
buffer_end_init(&init, scratch, scratch_size);
assert_4tech(result);
}
void
measure_starts_widths(Buffer_Type *buffer, float *font_widths){
if (buffer->line_max == 0){
assert_4tech(buffer->line_starts == 0);
assert_4tech(buffer->line_widths == 0);
assert_4tech(buffer->widths_max == 0);
int max = 1 << 10;
buffer->line_starts = (int*)malloc(max*sizeof(int));
buffer->line_max = max;
buffer->line_widths = (float*)malloc(max*sizeof(float));
buffer->widths_max = max;
}
assert_4tech(buffer->line_starts != 0);
assert_4tech(buffer->widths_max != 0);
assert_4tech(buffer->line_widths != 0);
Buffer_Measure_Starts state;
memzero_4tech(state);
for (;buffer_measure_starts_widths(&state, buffer, font_widths);){
int max = buffer->line_max;
int count = state.count;
int target = count + 1;
max = target*2;
int *new_lines = (int*)malloc(max*sizeof(int));
memcpy_4tech(new_lines, buffer->line_starts, count*sizeof(int));
free(buffer->line_starts);
buffer->line_starts = new_lines;
buffer->line_max = max;
float *new_widths = (float*)malloc(max*sizeof(float));
memcpy_4tech(new_widths, buffer->line_widths, count*sizeof(int));
free(buffer->line_widths);
buffer->line_widths = new_widths;
buffer->widths_max = max;
}
buffer->line_count = state.count;
buffer->widths_count = state.count;
}
void
edit(Buffer_Type *buffer, int start, int end, char *word, int len,
float *advance_data, void *scratch, int scratch_size){
int shift_amount, request_amount;
for (;buffer_replace_range(buffer, start, end, word, len, &shift_amount,
scratch, scratch_size, &request_amount);){
void *new_data = 0;
if (request_amount > 0) new_data = malloc(request_amount);
void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
if (old_data) free(old_data);
}
int line_start = buffer_get_line_index(buffer, start);
int line_end = buffer_get_line_index(buffer, end);
int replaced_line_count = line_end - line_start;
int new_line_count = buffer_count_newlines(buffer, start, start+len);
int line_shift = new_line_count - replaced_line_count;
{
assert_4tech(buffer->line_starts);
int count = buffer->line_count;
if (count + line_shift > buffer->line_max){
int new_max = round_up_4tech(buffer->line_max + line_shift, 1 << 10);
int *new_lines = (int*)malloc(sizeof(int)*new_max);
memcpy_4tech(new_lines, buffer->line_starts, sizeof(int)*count);
free(buffer->line_starts);
buffer->line_starts = new_lines;
buffer->line_max = new_max;
}
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
}
{
assert_4tech(buffer->line_widths);
if (buffer->line_count > buffer->widths_max){
int new_max = round_up_4tech(buffer->line_max, 1 << 10);
float *new_widths = (float*)malloc(sizeof(float)*new_max);
memcpy_4tech(new_widths, buffer->line_widths, sizeof(float)*buffer->widths_count);
free(buffer->line_widths);
buffer->line_widths = new_widths;
buffer->widths_max = new_max;
}
buffer_remeasure_widths(buffer, advance_data, line_start, line_end, line_shift);
}
}
void
insert_bottom(Buffer_Type *buffer, char *word, int len, float *advance_data, void *scratch, int scratch_size){
int size;
size = buffer_size(buffer);
edit(buffer, size, size, word, len, advance_data, scratch, scratch_size);
}
void
insert_top(Buffer_Type *buffer, char *word, int len, float *advance_data, void *scratch, int scratch_size){
edit(buffer, 0, 0, word, len, advance_data, scratch, scratch_size);
}
void
delete_bottom(Buffer_Type *buffer, int len, float *advance_data, void *scratch, int scratch_size){
int size;
size = buffer_size(buffer);
edit(buffer, size - len, size, 0, 0, advance_data, scratch, scratch_size);
}
void
delete_top(Buffer_Type *buffer, int len, float *advance_data, void *scratch, int scratch_size){
edit(buffer, 0, len, 0, 0, advance_data, scratch, scratch_size);
}
void
natural_edits(Buffer_Type *buffer, float *advance_data, Replay *replay, int pos, void *scratch, int scratch_size){
Edit_Step *steps = replay->replay.edits;
char *base_str = replay->replay.strings;
int edit_count = replay->replay.count;
for (int i = 0; i < edit_count; ++i){
Edit_Step step = steps[i];
if (step.child_count == 0 && step.edit.end <= buffer_size(buffer)){
edit(buffer, pos + step.edit.start, pos + step.edit.end, base_str + step.edit.str_start, step.edit.len,
advance_data, scratch, scratch_size);
}
}
}
void
batch_edit(Buffer_Type *buffer, float *advance_data, Buffer_Edit *batch, char *str_base, int batch_size,
void *scratch, int scratch_size){
Buffer_Batch_State state;
int request_amount;
memzero_4tech(state);
for (;buffer_batch_edit_step(&state, buffer, batch, str_base, batch_size,
scratch, scratch_size, &request_amount);){
void *new_data = 0;
if (request_amount > 0) new_data = malloc(request_amount);
void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
if (old_data) free(old_data);
}
measure_starts_widths(buffer, advance_data);
}
// BOTTOM