rope edits
This commit is contained in:
parent
cab1801465
commit
7b3c7094f8
16
4ed.cpp
16
4ed.cpp
|
@ -229,7 +229,7 @@ COMMAND_DECL(write_character){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -240,7 +240,7 @@ COMMAND_DECL(seek_whitespace_right){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -251,7 +251,7 @@ COMMAND_DECL(seek_whitespace_left){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_up){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -262,7 +262,7 @@ COMMAND_DECL(seek_whitespace_up){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_down){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -356,7 +356,7 @@ COMMAND_DECL(seek_white_or_token_left){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -367,7 +367,7 @@ COMMAND_DECL(seek_alphanumeric_right){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -378,7 +378,7 @@ COMMAND_DECL(seek_alphanumeric_left){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_or_camel_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -390,7 +390,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_or_camel_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
|
|
@ -1148,7 +1148,7 @@ file_synchronize_times(Editing_File *file, u8 *filename){
|
|||
internal b32
|
||||
file_save(Partition *part, Editing_File *file, char *filename){
|
||||
b32 result = 0;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
i32 max = partition_remaining(part);
|
||||
if (file->dos_write_mode){
|
||||
|
@ -1199,7 +1199,7 @@ enum File_Bubble_Type{
|
|||
internal i32
|
||||
file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
|
||||
bool32 result = GROW_NOT_NEEDED;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 max = buffer->line_max;
|
||||
i32 count = buffer->line_count;
|
||||
i32 target_lines = count + additional_lines;
|
||||
|
@ -1223,7 +1223,7 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
|
|||
|
||||
internal void
|
||||
file_measure_starts(General_Memory *general, Buffer_Type *buffer){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
if (!buffer->line_starts){
|
||||
i32 max = buffer->line_max = Kbytes(1);
|
||||
|
@ -1256,7 +1256,7 @@ internal void
|
|||
file_remeasure_starts(General_Memory *general, Buffer_Type *buffer,
|
||||
i32 line_start, i32 line_end, i32 line_shift,
|
||||
i32 character_shift){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
Assert(buffer->line_starts);
|
||||
file_grow_starts_as_needed(general, buffer, line_shift);
|
||||
|
@ -1279,7 +1279,7 @@ get_opaque_font_advance(Font *font){
|
|||
|
||||
internal void
|
||||
file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 line_count = buffer->line_count;
|
||||
if (line_count > buffer->widths_max || buffer->widths_max == 0){
|
||||
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
|
||||
|
@ -1300,7 +1300,7 @@ file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
|
|||
|
||||
internal void
|
||||
file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
file_grow_widths_as_needed(general, buffer);
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
|
@ -1311,7 +1311,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
|
|||
internal void
|
||||
file_remeasure_widths(General_Memory *general, Buffer_Type *buffer, Font *font,
|
||||
i32 line_start, i32 line_end, i32 line_shift){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
file_grow_widths_as_needed(general, buffer);
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
|
@ -1329,7 +1329,7 @@ view_wrapped_line_span(real32 line_width, real32 max_width){
|
|||
internal i32
|
||||
view_compute_lowest_line(File_View *view){
|
||||
i32 lowest_line = 0;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 last_line = view->line_count - 1;
|
||||
if (last_line > 0){
|
||||
if (view->unwrapped_lines){
|
||||
|
@ -1355,7 +1355,7 @@ view_compute_lowest_line(File_View *view){
|
|||
|
||||
internal void
|
||||
view_measure_wraps(General_Memory *general, File_View *view){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
ProfileMomentFunction();
|
||||
Buffer_Type *buffer;
|
||||
|
||||
|
@ -2019,7 +2019,7 @@ file_post_history(General_Memory *general, Editing_File *file,
|
|||
|
||||
inline Full_Cursor
|
||||
view_compute_cursor_from_pos(File_View *view, i32 pos){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
@ -2037,7 +2037,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){
|
|||
inline Full_Cursor
|
||||
view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||
bool32 round_down = 0){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
@ -2055,7 +2055,7 @@ view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 see
|
|||
inline Full_Cursor
|
||||
view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||
bool32 round_down = 0){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
@ -2491,17 +2491,21 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
|
|||
file_pre_edit_maintenance(file);
|
||||
|
||||
// NOTE(allen): actual text replacement
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 shift_amount = 0;
|
||||
General_Memory *general = &mem->general;
|
||||
Partition *part = &mem->part;
|
||||
|
||||
char *str = (char*)spec.str;
|
||||
i32 start = spec.step.edit.start;
|
||||
i32 end = spec.step.edit.end;
|
||||
i32 str_len = spec.step.edit.len;
|
||||
|
||||
i32 scratch_size = partition_remaining(part);
|
||||
Assert(scratch_size > 0);
|
||||
i32 request_amount = 0;
|
||||
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount, &request_amount)){
|
||||
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount,
|
||||
part->base + part->pos, scratch_size, &request_amount)){
|
||||
void *new_data = 0;
|
||||
if (request_amount > 0){
|
||||
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
|
||||
|
@ -2539,7 +2543,7 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
|
|||
file_relex_parallel(mem, file, start, end, shift_amount);
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
|
||||
i32 cursor_max = layout->panel_max_count * 2;
|
||||
Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max);
|
||||
|
@ -2946,7 +2950,7 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
|||
|
||||
internal void
|
||||
clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editing_File *file){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 size = range.end - range.start;
|
||||
String *dest = working_set_next_clipboard_string(general, working, size);
|
||||
buffer_stringify(&file->buffer, range.start, range.end, dest->str);
|
||||
|
@ -3820,7 +3824,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
bar.rect.y1 = bar.rect.y0 + font->height + 2;
|
||||
rect.y0 += font->height + 2;
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
i32 max_x = rect.x1 - rect.x0;
|
||||
i32 max_y = rect.y1 - rect.y0 + font->height;
|
||||
|
||||
|
@ -3895,17 +3899,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
i32 prev_ind = -1;
|
||||
u32 highlight_color = 0;
|
||||
|
||||
u32 chunk_highlights[] = {
|
||||
0x22FF0000,
|
||||
0x22FFFF00,
|
||||
0x2200FF00,
|
||||
0x2200FFFF,
|
||||
0x220000FF,
|
||||
0x22FF00FF
|
||||
};
|
||||
|
||||
i32 current_chunk = item->chunk_i;
|
||||
u32 chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
|
||||
for (i32 i = 0; i < count; ++i, ++item){
|
||||
i32 ind = item->index;
|
||||
if (tokens_use && ind != prev_ind){
|
||||
|
@ -3930,11 +3923,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
}
|
||||
u32 char_color = main_color;
|
||||
|
||||
if (item->chunk_i > current_chunk){
|
||||
current_chunk = item->chunk_i;
|
||||
chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
|
||||
}
|
||||
|
||||
if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
|
||||
if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
|
||||
else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
|
||||
|
@ -3943,9 +3931,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
else if (highlight_color){
|
||||
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color);
|
||||
}
|
||||
else if (chunk_highlight){
|
||||
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), chunk_highlight);
|
||||
}
|
||||
|
||||
u32 fade_color = 0xFFFF00FF;
|
||||
f32 fade_amount = 0.f;
|
||||
|
@ -4126,7 +4111,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
|
|||
|
||||
case FWIDG_SEARCH:
|
||||
{
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
String *string = &file_view->isearch.str;
|
||||
Single_Line_Input_Step result =
|
||||
app_single_line_input_step(codes, key, string);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
|
||||
#define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
inline_4tech void
|
||||
buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){
|
||||
for (Buffer_Stringify_Type loop = buffer_stringify_loop(buffer, start, end);
|
||||
|
@ -72,7 +72,7 @@ buffer_count_newlines(Buffer_Type *buffer, int start, int end){
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
internal_4tech int
|
||||
buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){
|
||||
Buffer_Stringify_Type loop;
|
||||
|
@ -479,8 +479,8 @@ buffer_rfind_string_end:
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
typedef struct{
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
typedef struct Buffer_Measure_Starts{
|
||||
int i;
|
||||
int count;
|
||||
int start;
|
||||
|
@ -742,8 +742,9 @@ buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, i
|
|||
#endif
|
||||
|
||||
#ifndef NON_ABSTRACT_4TECH
|
||||
typedef struct{
|
||||
Full_Cursor cursor, prev_cursor;
|
||||
typedef struct Seek_State{
|
||||
Full_Cursor cursor;
|
||||
Full_Cursor prev_cursor;
|
||||
} Seek_State;
|
||||
|
||||
internal_4tech int
|
||||
|
@ -854,7 +855,7 @@ cursor_seek_step_end:
|
|||
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
internal_4tech Full_Cursor
|
||||
buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width, float font_height,
|
||||
void *advance_data, int stride, Full_Cursor cursor){
|
||||
|
@ -940,7 +941,7 @@ buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, float x, float y, int round_d
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
internal_4tech void
|
||||
buffer_invert_edit_shift(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse, char *strings,
|
||||
int *str_pos, int max, int shift_amount){
|
||||
|
@ -965,7 +966,7 @@ buffer_invert_edit(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse,
|
|||
buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Invert_Batch{
|
||||
int i;
|
||||
int shift_amount;
|
||||
int len;
|
||||
|
@ -1004,7 +1005,7 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
internal_4tech void
|
||||
buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
|
||||
Buffer_Batch_State state;
|
||||
|
@ -1021,7 +1022,7 @@ buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 3
|
||||
internal_4tech void
|
||||
buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count,
|
||||
float port_x, float port_y, float scroll_x, float scroll_y, int wrapped,
|
||||
|
@ -1077,9 +1078,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
|||
switch (ch){
|
||||
case '\n':
|
||||
write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
|
||||
|
@ -1089,17 +1087,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
|||
|
||||
case 0:
|
||||
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
||||
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
@ -1107,17 +1099,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
|||
|
||||
case '\r':
|
||||
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
||||
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
@ -1125,16 +1111,10 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
|||
|
||||
case '\t':
|
||||
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
|
||||
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
@ -1142,9 +1122,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
|||
|
||||
default:
|
||||
write_render_item(item, i, ch, x, y, ch_width, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
@ -1160,9 +1137,6 @@ buffer_get_render_data_end:
|
|||
ch = 0;
|
||||
ch_width = measure_character(advance_data, stride, ' ');
|
||||
write_render_item(item, size, ch, x, y, ch_width, font_height);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
item->chunk_i = -1;
|
||||
#endif
|
||||
++item_i;
|
||||
++item;
|
||||
x += ch_width;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
typedef struct{
|
||||
typedef struct Gap_Buffer{
|
||||
char *data;
|
||||
int size1, gap_size, size2, max;
|
||||
|
||||
|
@ -39,7 +39,7 @@ buffer_size(Gap_Buffer *buffer){
|
|||
return(size);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Gap_Buffer_Init{
|
||||
Gap_Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
|
@ -110,7 +110,7 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, int scratch_size){
|
|||
return(result);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Gap_Buffer_Stringify_Loop{
|
||||
Gap_Buffer *buffer;
|
||||
char *data, *base;
|
||||
int absolute_pos;
|
||||
|
@ -172,7 +172,7 @@ buffer_stringify_next(Gap_Buffer_Stringify_Loop *loop){
|
|||
loop->data = loop->base + loop->pos;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Gap_Buffer_Backify_Loop{
|
||||
Gap_Buffer *buffer;
|
||||
char *data, *base;
|
||||
int pos, end;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer{
|
||||
char *data;
|
||||
int size, max;
|
||||
|
||||
|
@ -37,7 +37,7 @@ buffer_size(Buffer *buffer){
|
|||
return buffer->size;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Init{
|
||||
Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
|
@ -92,7 +92,7 @@ buffer_end_init(Buffer_Init *init, void *scratch, int scratch_size){
|
|||
return(result);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Stringify_Loop{
|
||||
Buffer *buffer;
|
||||
char *data, *end;
|
||||
int absolute_pos;
|
||||
|
@ -125,7 +125,7 @@ buffer_stringify_next(Buffer_Stringify_Loop *loop){
|
|||
loop->buffer = 0;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Backify_Loop{
|
||||
Buffer *buffer;
|
||||
char *data, *end;
|
||||
int absolute_pos;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
typedef struct{
|
||||
typedef struct Fixed_Width_Gap_Buffer{
|
||||
char *data;
|
||||
int size1, gap_size, size2;
|
||||
int start_pos;
|
||||
|
@ -25,7 +25,7 @@ typedef struct{
|
|||
#define fixed_width_buffer_size Kbytes(8)
|
||||
#define fixed_width_buffer_half_size Kbytes(4)
|
||||
|
||||
typedef struct{
|
||||
typedef struct Multi_Gap_Buffer{
|
||||
Fixed_Width_Gap_Buffer *gaps;
|
||||
int chunk_count;
|
||||
int chunk_alloced;
|
||||
|
@ -57,7 +57,7 @@ buffer_size(Multi_Gap_Buffer *buffer){
|
|||
return(size);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Multi_Gap_Buffer_Init{
|
||||
Multi_Gap_Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
|
@ -202,7 +202,7 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
|
|||
return(m);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Multi_Gap_Buffer_Stringify_Loop{
|
||||
Multi_Gap_Buffer *buffer;
|
||||
Fixed_Width_Gap_Buffer *gaps;
|
||||
char *data;
|
||||
|
@ -290,7 +290,7 @@ buffer_stringify_next(Multi_Gap_Buffer_Stringify_Loop *loop){
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Multi_Gap_Buffer_Backify_Loop{
|
||||
Multi_Gap_Buffer *buffer;
|
||||
Fixed_Width_Gap_Buffer *gaps;
|
||||
char *data;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
typedef struct Rope_Node{
|
||||
int left, right, parent;
|
||||
int left_total, total;
|
||||
int left_weight, weight;
|
||||
int str_start;
|
||||
} Rope_Node;
|
||||
|
||||
|
@ -26,6 +26,10 @@ typedef struct Rope_String{
|
|||
#define rope_string_full_size 256
|
||||
#define rope_string_width (rope_string_full_size-sizeof(Rope_String))
|
||||
|
||||
typedef struct Rope_Buffer_Edit_State{
|
||||
int left, right, throw_away, middle;
|
||||
} Rope_Buffer_Edit_State;
|
||||
|
||||
typedef struct Rope_Buffer{
|
||||
void *data;
|
||||
int free_rope_string;
|
||||
|
@ -41,6 +45,10 @@ typedef struct Rope_Buffer{
|
|||
int widths_count;
|
||||
int line_max;
|
||||
int widths_max;
|
||||
|
||||
int grow_string_memory;
|
||||
int edit_stage;
|
||||
Rope_Buffer_Edit_State edit_state;
|
||||
} Rope_Buffer;
|
||||
|
||||
inline_4tech int
|
||||
|
@ -53,7 +61,7 @@ buffer_good(Rope_Buffer *buffer){
|
|||
inline_4tech int
|
||||
buffer_size(Rope_Buffer *buffer){
|
||||
int size;
|
||||
size = buffer->nodes->left_total;
|
||||
size = buffer->nodes->left_weight;
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
@ -195,26 +203,106 @@ buffer_construct_stage(int parent, int right, int weight){
|
|||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
|
||||
buffer_build_tree(Rope_Buffer *buffer, char *str, int len, int root,
|
||||
void *scratch, int scratch_size, int *request_amount){
|
||||
Rope_Construct_Stage *stack, *stage;
|
||||
Rope_Node *node, *nodes;
|
||||
char *dest;
|
||||
int stack_max, top;
|
||||
int result;
|
||||
int node_index;
|
||||
int is_right_side;
|
||||
int read_pos;
|
||||
|
||||
nodes = buffer->nodes;
|
||||
stack = (Rope_Construct_Stage*)scratch;
|
||||
stack_max = scratch_size / sizeof(Rope_Construct_Stage);
|
||||
top = 0;
|
||||
result = 1;
|
||||
read_pos = 0;
|
||||
|
||||
stack[top++] = buffer_construct_stage(root, 0, len);
|
||||
for (;top > 0;){
|
||||
stage = stack + (--top);
|
||||
|
||||
if (buffer_alloc_rope_node(buffer, &node_index)){
|
||||
node = nodes + node_index;
|
||||
node->parent = stage->parent_index;
|
||||
node->weight = stage->weight;
|
||||
node->left = 0;
|
||||
node->right = 0;
|
||||
is_right_side = stage->is_right_side;
|
||||
|
||||
if (stage->weight > rope_string_width){
|
||||
node->str_start = 0;
|
||||
node->left_weight = stage->weight / 2;
|
||||
assert_4tech(top < stack_max);
|
||||
stack[top++] = buffer_construct_stage(node_index, 1, node->weight - node->left_weight);
|
||||
assert_4tech(top < stack_max);
|
||||
stack[top++] = buffer_construct_stage(node_index, 0, node->left_weight);
|
||||
}
|
||||
else{
|
||||
node->left_weight = 0;
|
||||
if (buffer_alloc_rope_string(buffer, &node->str_start)){
|
||||
dest = (char*)buffer->data + node->str_start;
|
||||
assert_4tech(read_pos < len);
|
||||
memcpy_4tech(dest, str + read_pos, node->weight);
|
||||
read_pos += node->weight;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
if (request_amount){
|
||||
buffer->grow_string_memory = 1;
|
||||
*request_amount = buffer->string_count*rope_string_full_size*2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
node = nodes + node->parent;
|
||||
if (is_right_side) node->right = node_index;
|
||||
else node->left = node_index;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
if (request_amount){
|
||||
buffer->grow_string_memory = 0;
|
||||
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result && request_amount){
|
||||
top = 0;
|
||||
stack[top++] = buffer_construct_stage(nodes[root].left, 0, 0);
|
||||
|
||||
for (;top > 0;){
|
||||
stage = stack + (--top);
|
||||
node_index = stage->parent_index;
|
||||
node = nodes + node_index;
|
||||
if (node->left) stack[top++] = buffer_construct_stage(node->left, 0, 0);
|
||||
if (node->right) stack[top++] = buffer_construct_stage(node->right, 0, 0);
|
||||
if (node->str_start) buffer_free_rope_string(buffer, node->str_start);
|
||||
buffer_free_rope_node(buffer, node_index);
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
|
||||
Rope_Buffer *buffer;
|
||||
Rope_String *rope_string;
|
||||
Rope_Node *node;
|
||||
char *src, *dest;
|
||||
int node_index;
|
||||
int i, top, stack_max, is_right_side;
|
||||
int read_pos, read_end;
|
||||
int i;
|
||||
int result;
|
||||
int count;
|
||||
|
||||
src = init->data;
|
||||
read_pos = 0;
|
||||
read_end = init->size;
|
||||
|
||||
result = 0;
|
||||
buffer = init->buffer;
|
||||
if (buffer->nodes && buffer->data){
|
||||
// NOTE(allen): initialize free lists
|
||||
buffer->string_count = init->rope_string_count;
|
||||
buffer->free_rope_string = 0;
|
||||
|
||||
|
@ -231,66 +319,550 @@ buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
|
|||
|
||||
node = buffer->nodes + 1;
|
||||
count = init->node_count;
|
||||
for (i = 1; i < count; ++i, ++node){
|
||||
for (i = 1; i < count-1; ++i, ++node){
|
||||
node->parent = i+1;
|
||||
}
|
||||
node->parent = 0;
|
||||
|
||||
result = 1;
|
||||
|
||||
// NOTE(allen): initialize tree
|
||||
node = buffer->nodes;
|
||||
node->parent = 0;
|
||||
node->total = init->size;
|
||||
node->left_total = init->size;
|
||||
node->weight = init->size;
|
||||
node->left_weight = init->size;
|
||||
|
||||
result = buffer_build_tree(buffer, init->data, init->size, 0, scratch, scratch_size, 0);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_find_node(Rope_Buffer *buffer, int pos, int *node_start){
|
||||
Rope_Node *nodes, *node;
|
||||
*node_start = 0;
|
||||
nodes = buffer->nodes;
|
||||
node = nodes + nodes->left;
|
||||
for (;node->str_start == 0;){
|
||||
if (pos < node->left_weight){
|
||||
node = nodes + node->left;
|
||||
}
|
||||
else{
|
||||
*node_start += node->left_weight;
|
||||
pos -= node->left_weight;
|
||||
node = nodes + node->right;
|
||||
}
|
||||
}
|
||||
return (int)(node - nodes);
|
||||
}
|
||||
|
||||
typedef struct Rope_Buffer_Stringify_Loop{
|
||||
Rope_Buffer *buffer;
|
||||
char *data;
|
||||
int absolute_pos;
|
||||
int size;
|
||||
int pos, end_pos;
|
||||
int node, node_end;
|
||||
} Rope_Buffer_Stringify_Loop;
|
||||
|
||||
internal_4tech Rope_Buffer_Stringify_Loop
|
||||
buffer_stringify_loop(Rope_Buffer *buffer, int start, int end){
|
||||
Rope_Buffer_Stringify_Loop result;
|
||||
Rope_Node *node;
|
||||
int size, node_start_pos, temp_end;
|
||||
|
||||
size = buffer_size(buffer);
|
||||
if (0 <= start && start < end && end <= size){
|
||||
result.buffer = buffer;
|
||||
result.absolute_pos = start;
|
||||
|
||||
stack = (Rope_Construct_Stage*)scratch;
|
||||
stack_max = scratch_size / sizeof(Rope_Construct_Stage);
|
||||
top = 0;
|
||||
result.node = buffer_find_node(buffer, start, &node_start_pos);
|
||||
result.pos = start - node_start_pos;
|
||||
|
||||
stack[top++] = buffer_construct_stage(0, 0, init->size);
|
||||
for (;top > 0;){
|
||||
stage = stack + (--top);
|
||||
|
||||
if (buffer_alloc_rope_node(buffer, &node_index)){
|
||||
node = buffer->nodes + node_index;
|
||||
node->parent = stage->parent_index;
|
||||
node->total = stage->weight;
|
||||
is_right_side = stage->is_right_side;
|
||||
if (stage->weight > rope_string_width){
|
||||
node->left_total = stage->weight / 2;
|
||||
assert_4tech(top < stack_max);
|
||||
stack[top++] = buffer_construct_stage(node_index, 1, node->total - node->left_total);
|
||||
assert_4tech(top < stack_max);
|
||||
stack[top++] = buffer_construct_stage(node_index, 0, node->left_total);
|
||||
}
|
||||
else{
|
||||
node->left_total = 0;
|
||||
node->left = 0;
|
||||
node->right = 0;
|
||||
if (buffer_alloc_rope_string(buffer, &node->str_start)){
|
||||
dest = (char*)buffer->data + node->str_start;
|
||||
assert_4tech(read_pos < read_end);
|
||||
memcpy_4tech(dest, src + read_pos, node->total);
|
||||
read_pos += node->total;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = buffer->nodes + node->parent;
|
||||
if (is_right_side) node->right = node_index;
|
||||
else node->left = node_index;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
result.node_end = buffer_find_node(buffer, end, &node_start_pos);
|
||||
result.end_pos = end - node_start_pos;
|
||||
|
||||
node = buffer->nodes + result.node;
|
||||
temp_end = node->weight;
|
||||
if (result.node == result.node_end) temp_end = result.end_pos;
|
||||
|
||||
result.data = (char*)buffer->data + node->str_start + result.pos;
|
||||
result.size = temp_end - result.pos;
|
||||
}
|
||||
else result.buffer = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_stringify_good(Rope_Buffer_Stringify_Loop *loop){
|
||||
int result;
|
||||
result = (loop->buffer != 0);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void
|
||||
buffer_stringify_next(Rope_Buffer_Stringify_Loop *loop){
|
||||
Rope_Node *node, *child, *nodes;
|
||||
int temp_end;
|
||||
|
||||
if (loop->node == loop->node_end && loop->pos + loop->size == loop->end_pos){
|
||||
loop->buffer = 0;
|
||||
}
|
||||
else{
|
||||
nodes = loop->buffer->nodes;
|
||||
node = nodes + loop->node;
|
||||
|
||||
for (;;){
|
||||
assert_4tech(node->parent != 0);
|
||||
child = node;
|
||||
node = nodes + node->parent;
|
||||
if (nodes + node->left == child){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
assert_4tech(nodes + node->right == child);
|
||||
}
|
||||
}
|
||||
|
||||
node = nodes + node->right;
|
||||
|
||||
for (;node->left;){
|
||||
node = nodes + node->left;
|
||||
}
|
||||
|
||||
loop->pos = 0;
|
||||
loop->node = (int)(node - nodes);
|
||||
loop->absolute_pos += loop->size;
|
||||
temp_end = node->weight;
|
||||
if (loop->node == loop->node_end) temp_end = loop->end_pos;
|
||||
loop->size = temp_end;
|
||||
loop->data = (char*)loop->buffer->data + node->str_start;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct Rope_Buffer_Backify_Loop{
|
||||
Rope_Buffer *buffer;
|
||||
char *data;
|
||||
int absolute_pos;
|
||||
int size;
|
||||
int pos, end_pos;
|
||||
int node, node_end;
|
||||
} Rope_Buffer_Backify_Loop;
|
||||
|
||||
internal_4tech Rope_Buffer_Backify_Loop
|
||||
buffer_backify_loop(Rope_Buffer *buffer, int start, int end){
|
||||
Rope_Buffer_Backify_Loop result;
|
||||
int size, node_start_pos, temp_end;
|
||||
|
||||
size = buffer_size(buffer);
|
||||
++start;
|
||||
if (0 <= end && end < start && start <= size){
|
||||
result.buffer = buffer;
|
||||
|
||||
result.node_end = buffer_find_node(buffer, end, &node_start_pos);
|
||||
result.end_pos = end - node_start_pos;
|
||||
|
||||
result.node = buffer_find_node(buffer, start, &node_start_pos);
|
||||
temp_end = start - node_start_pos;
|
||||
|
||||
if (result.node_end == result.node){
|
||||
result.pos = result.end_pos;
|
||||
result.absolute_pos = end;
|
||||
}
|
||||
else{
|
||||
result.pos = 0;
|
||||
result.absolute_pos = node_start_pos;
|
||||
}
|
||||
|
||||
result.size = temp_end - result.pos;
|
||||
result.data = (char*)buffer->data + buffer->nodes[result.node].str_start + result.pos;
|
||||
}
|
||||
else result.buffer = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_backify_good(Rope_Buffer_Backify_Loop *loop){
|
||||
int result;
|
||||
result = (loop->buffer != 0);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void
|
||||
buffer_backify_next(Rope_Buffer_Backify_Loop *loop){
|
||||
Rope_Node *node, *child, *nodes;
|
||||
int temp_start;
|
||||
|
||||
if (loop->node == loop->node_end && loop->pos == loop->end_pos){
|
||||
loop->buffer = 0;
|
||||
}
|
||||
else{
|
||||
nodes = loop->buffer->nodes;
|
||||
node = nodes + loop->node;
|
||||
|
||||
for (;;){
|
||||
assert_4tech(node->parent != 0);
|
||||
child = node;
|
||||
node = nodes + node->parent;
|
||||
if (nodes + node->right == child){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
assert_4tech(nodes + node->left == child);
|
||||
}
|
||||
}
|
||||
|
||||
node = nodes + node->left;
|
||||
|
||||
for (;node->right;){
|
||||
node = nodes + node->right;
|
||||
}
|
||||
|
||||
loop->pos = 0;
|
||||
loop->node = (int)(node - nodes);
|
||||
loop->absolute_pos -= node->weight;
|
||||
temp_start = 0;
|
||||
if (loop->node == loop->node_end) temp_start = loop->end_pos;
|
||||
loop->size = node->weight - temp_start;
|
||||
loop->data = (char*)loop->buffer->data + node->str_start;
|
||||
}
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_concat(Rope_Buffer *buffer, int node_a, int node_b, int *root, int *request_amount){
|
||||
Rope_Node *r, *a, *b, *nodes;
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
if (buffer_alloc_rope_node(buffer, root)){
|
||||
nodes = buffer->nodes;
|
||||
|
||||
r = nodes + *root;
|
||||
a = nodes + node_a;
|
||||
b = nodes + node_b;
|
||||
|
||||
r->left = node_a;
|
||||
r->right = node_b;
|
||||
r->weight = a->weight + b->weight;
|
||||
r->left_weight = a->weight;
|
||||
r->str_start = 0;
|
||||
r->parent = 0;
|
||||
|
||||
a->parent = *root;
|
||||
b->parent = *root;
|
||||
}
|
||||
else{
|
||||
result = 1;
|
||||
buffer->grow_string_memory = 0;
|
||||
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_string_split(Rope_Buffer *buffer, int *node_index, int pos, int *request_amount){
|
||||
Rope_Node *node, *a, *b;
|
||||
int node_a, node_b;
|
||||
int new_string_start, string_start;
|
||||
int result;
|
||||
result = 0;
|
||||
|
||||
if (pos > 0){
|
||||
if (buffer_alloc_rope_string(buffer, &new_string_start)){
|
||||
if (buffer_alloc_rope_node(buffer, &node_a)){
|
||||
if (buffer_alloc_rope_node(buffer, &node_b)){
|
||||
node = buffer->nodes + *node_index;
|
||||
string_start = node->str_start;
|
||||
memcpy_4tech((char*)buffer->data + new_string_start, (char*)buffer->data + string_start + pos, node->weight - pos);
|
||||
node->str_start = 0;
|
||||
node->left_weight = pos;
|
||||
node->left = node_a;
|
||||
node->right = node_b;
|
||||
|
||||
a = buffer->nodes + node_a;
|
||||
b = buffer->nodes + node_b;
|
||||
|
||||
a->parent = *node_index;
|
||||
a->left = 0;
|
||||
a->right = 0;
|
||||
a->left_weight = 0;
|
||||
a->weight = pos;
|
||||
a->str_start = string_start;
|
||||
|
||||
b->parent = *node_index;;
|
||||
b->left = 0;
|
||||
b->right = 0;
|
||||
b->left_weight = 0;
|
||||
b->weight = node->weight - pos;
|
||||
b->str_start = new_string_start;
|
||||
|
||||
*node_index = node_b;
|
||||
}
|
||||
else{
|
||||
buffer_free_rope_string(buffer, new_string_start);
|
||||
buffer_free_rope_node(buffer, node_a);
|
||||
result = 1;
|
||||
buffer->grow_string_memory = 0;
|
||||
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
buffer_free_rope_string(buffer, new_string_start);
|
||||
result = 1;
|
||||
buffer->grow_string_memory = 0;
|
||||
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = 1;
|
||||
buffer->grow_string_memory = 1;
|
||||
*request_amount = buffer->string_count*rope_string_full_size*2;
|
||||
}
|
||||
}
|
||||
|
||||
assert_4tech(!result || read_pos == read_end);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void
|
||||
buffer_reduce_node(Rope_Buffer *buffer, int node_index){
|
||||
Rope_Node *parent, *child, *node, *nodes;
|
||||
int child_index;
|
||||
|
||||
nodes = buffer->nodes;
|
||||
node = nodes + node_index;
|
||||
parent = nodes + node->parent;
|
||||
child_index = node->left;
|
||||
if (child_index == 0) child_index = node->right;
|
||||
assert_4tech(child_index != 0);
|
||||
child = nodes + child_index;
|
||||
|
||||
if (parent->left == node_index) parent->left = child_index;
|
||||
else parent->right = child_index;
|
||||
child->parent = node->parent;
|
||||
|
||||
for (;parent != nodes;){
|
||||
parent->weight = nodes[parent->left].weight + nodes[parent->right].weight;
|
||||
parent->left_weight = nodes[parent->left].weight;
|
||||
parent = nodes + parent->parent;
|
||||
}
|
||||
|
||||
parent->weight = parent->left_weight = nodes[parent->left].weight;
|
||||
|
||||
buffer_free_rope_node(buffer, node_index);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_split(Rope_Buffer *buffer, int pos, int *node_a, int *node_b, int *request_amount){
|
||||
Rope_Node *node, *nodes, *child;
|
||||
int node_index, node_start_pos, split_root;
|
||||
int result;
|
||||
debug_4tech(int dbg_check);
|
||||
|
||||
result = 0;
|
||||
node_index = buffer_find_node(buffer, pos, &node_start_pos);
|
||||
|
||||
if (node_start_pos < pos){
|
||||
if (buffer_string_split(buffer, &node_index, pos - node_start_pos, request_amount)){
|
||||
result = 1;
|
||||
goto buffer_split_end;
|
||||
}
|
||||
}
|
||||
|
||||
split_root = 0;
|
||||
nodes = buffer->nodes;
|
||||
node = nodes + node_index;
|
||||
for (;;){
|
||||
child = node;
|
||||
node = nodes + node->parent;
|
||||
if (child == nodes + node->right){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
assert_4tech(child == nodes + node->left);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;){
|
||||
if (split_root == 0){
|
||||
split_root = node->right;
|
||||
}
|
||||
else{
|
||||
debug_4tech(dbg_check =)
|
||||
buffer_concat(buffer, split_root, node->right, &split_root, request_amount);
|
||||
assert_4tech(!dbg_check);
|
||||
}
|
||||
|
||||
node_index = (int)(node - nodes);
|
||||
node->right = 0;
|
||||
node = nodes + node->left;
|
||||
buffer_reduce_node(buffer, node_index);
|
||||
|
||||
for (;;){
|
||||
child = node;
|
||||
node = nodes + child->parent;
|
||||
if (nodes + node->left == child){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
assert_4tech(nodes + node->right == child);
|
||||
}
|
||||
}
|
||||
|
||||
if (node == nodes) break;
|
||||
}
|
||||
|
||||
*node_a = nodes->left;
|
||||
*node_b = split_root;
|
||||
|
||||
buffer_split_end:
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_build_tree_floating(Rope_Buffer *buffer, char *str, int len, int *out,
|
||||
void *scratch, int scratch_size, int *request_amount){
|
||||
int result;
|
||||
int super_root;
|
||||
|
||||
result = 0;
|
||||
if (buffer_alloc_rope_node(buffer, &super_root)){
|
||||
if (buffer_build_tree(buffer, str, len, super_root, scratch, scratch_size, request_amount)){
|
||||
*out = buffer->nodes[super_root].left;
|
||||
buffer_free_rope_node(buffer, super_root);
|
||||
}
|
||||
else{
|
||||
result = 1;
|
||||
buffer_free_rope_node(buffer, super_root);
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = 1;
|
||||
buffer->grow_string_memory = 0;
|
||||
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_replace_range(Rope_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount,
|
||||
void *scratch, int scratch_size, int *request_amount){
|
||||
Rope_Node *nodes;
|
||||
Rope_Buffer_Edit_State state;
|
||||
int result;
|
||||
|
||||
state = buffer->edit_state;
|
||||
|
||||
*shift_amount = (len - (end - start));
|
||||
result = 0;
|
||||
|
||||
for (; buffer->edit_stage < 6; ++buffer->edit_stage){
|
||||
switch (buffer->edit_stage){
|
||||
case 0:
|
||||
if (buffer_split(buffer, end, &state.throw_away, &state.right, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
} break;
|
||||
|
||||
case 1:
|
||||
if (start == end){
|
||||
state.left = state.throw_away;
|
||||
}
|
||||
else{
|
||||
if (buffer_split(buffer, start, &state.left, &state.throw_away, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
}
|
||||
}
|
||||
if (len == 0){
|
||||
buffer->edit_stage = 5 - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (buffer_build_tree_floating(buffer, str, len, &state.middle, scratch, scratch_size, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
} break;
|
||||
|
||||
case 3:
|
||||
if (buffer_concat(buffer, state.left, state.middle, &state.throw_away, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
} break;
|
||||
|
||||
case 4:
|
||||
if (buffer_concat(buffer, state.throw_away, state.right, &state.middle, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
}
|
||||
buffer->edit_stage = 6;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (buffer_concat(buffer, state.left, state.right, &state.middle, request_amount)){
|
||||
result = 1;
|
||||
goto rope_buffer_replace_range_end;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer->edit_stage = 0;
|
||||
nodes = buffer->nodes;
|
||||
nodes->left = state.middle;
|
||||
nodes->weight = nodes->left_weight = nodes[state.middle].weight;
|
||||
|
||||
state = {};
|
||||
|
||||
rope_buffer_replace_range_end:
|
||||
buffer->edit_state = state;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void*
|
||||
buffer_edit_provide_memory(Rope_Buffer *buffer, void *new_data, int size){
|
||||
void *result;
|
||||
Rope_String *rope_string;
|
||||
Rope_Node *node;
|
||||
int start, end, i;
|
||||
|
||||
if (buffer->grow_string_memory){
|
||||
assert_4tech(size >= buffer->string_count * rope_string_full_size);
|
||||
result = buffer->data;
|
||||
memcpy_4tech(new_data, buffer->data, buffer->string_count * rope_string_full_size);
|
||||
|
||||
buffer->data = new_data;
|
||||
start = buffer->string_count*rope_string_full_size;
|
||||
end = size/rope_string_full_size;
|
||||
buffer->string_count = end;
|
||||
end = (end-1)*rope_string_full_size;
|
||||
for (i = start; i < end; i += rope_string_full_size){
|
||||
rope_string = (Rope_String*)((char*)new_data + i);
|
||||
rope_string->next_free = i + rope_string_full_size;
|
||||
}
|
||||
rope_string = (Rope_String*)((char*)new_data + i);
|
||||
rope_string->next_free = buffer->free_rope_string;
|
||||
buffer->free_rope_string = start;
|
||||
}
|
||||
else{
|
||||
assert_4tech(size >= buffer->node_count * sizeof(Rope_Node));
|
||||
result = buffer->nodes;
|
||||
memcpy_4tech(new_data, buffer->nodes, buffer->node_count * sizeof(Rope_Node));
|
||||
|
||||
buffer->nodes = (Rope_Node*)new_data;
|
||||
start = buffer->node_count;
|
||||
end = size/sizeof(Rope_Node);
|
||||
buffer->node_count = end;
|
||||
end -= 1;
|
||||
node = buffer->nodes + start;
|
||||
for (i = start; i < end; ++i, ++node){
|
||||
node->parent = i+1;
|
||||
}
|
||||
node->parent = buffer->free_rope_node;
|
||||
buffer->free_rope_node = start;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -86,12 +86,12 @@ measure_character(void *advance_data, int stride, char character){
|
|||
return(width);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Edit{
|
||||
int str_start, len;
|
||||
int start, end;
|
||||
} Buffer_Edit;
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Batch_State{
|
||||
int i;
|
||||
int shift_total;
|
||||
} Buffer_Batch_State;
|
||||
|
@ -103,7 +103,7 @@ typedef enum{
|
|||
buffer_seek_line_char
|
||||
} Buffer_Seek_Type;
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Seek{
|
||||
Buffer_Seek_Type type;
|
||||
union{
|
||||
struct { int pos; };
|
||||
|
@ -149,20 +149,18 @@ seek_line_char(int line, int character){
|
|||
return(result);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Full_Cursor{
|
||||
int pos;
|
||||
int line, character;
|
||||
float unwrapped_x, unwrapped_y;
|
||||
float wrapped_x, wrapped_y;
|
||||
} Full_Cursor;
|
||||
|
||||
typedef struct{
|
||||
typedef struct Buffer_Render_Item{
|
||||
int index;
|
||||
int glyphid;
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
|
||||
int chunk_i;
|
||||
} Buffer_Render_Item;
|
||||
|
||||
inline_4tech void
|
||||
|
@ -198,7 +196,7 @@ make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height)
|
|||
return(hint);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
typedef struct Cursor_With_Index{
|
||||
int pos, index;
|
||||
} Cursor_With_Index;
|
||||
|
||||
|
|
Loading…
Reference in New Issue