streaming

master
Allen Webster 2015-10-24 18:14:33 -04:00
parent 083b4409c5
commit d3d02da40e
8 changed files with 5333 additions and 733 deletions

105
4ed.cpp
View File

@ -213,37 +213,12 @@ COMMAND_DECL(write_character){
view->file->cursor_pos = view->cursor.pos;
}
internal i32
seek_whitespace_right(u8 *data, i32 size, i32 pos){
while (pos < size && char_is_whitespace(data[pos])){
++pos;
}
while (pos < size && !char_is_whitespace(data[pos])){
++pos;
}
return pos;
}
internal i32
seek_whitespace_left(u8 *data, i32 pos){
--pos;
while (pos > 0 && char_is_whitespace(data[pos])){
--pos;
}
while (pos >= 0 && !char_is_whitespace(data[pos])){
--pos;
}
++pos;
return pos;
}
COMMAND_DECL(seek_whitespace_right){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = seek_whitespace_right(
(u8*)file->buffer.data, file->buffer.size, view->cursor.pos);
i32 pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
}
@ -253,14 +228,13 @@ COMMAND_DECL(seek_whitespace_left){
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 pos = seek_whitespace_left(
(u8*)file->buffer.data, view->cursor.pos);
i32 pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
}
// TODO(allen): see if this becomes better by using buffer procudures directly
COMMAND_DECL(seek_whitespace_up){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -286,9 +260,11 @@ COMMAND_DECL(seek_whitespace_up){
if (pos != 0) ++pos;
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(seek_whitespace_down){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -320,6 +296,7 @@ COMMAND_DECL(seek_whitespace_down){
else pos = prev_endline+1;
view_cursor_move(view, pos);
#endif
}
internal i32
@ -374,6 +351,7 @@ COMMAND_DECL(seek_token_right){
}
COMMAND_DECL(seek_white_or_token_right){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -383,11 +361,13 @@ COMMAND_DECL(seek_white_or_token_right){
if (file->tokens_complete){
token_pos = seek_token_right(&file->token_stack, view->cursor.pos);
}
white_pos = seek_whitespace_right((u8*)file->buffer.data, file->buffer.size, view->cursor.pos);
white_pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos);
view_cursor_move(view, Min(token_pos, white_pos));
#endif
}
COMMAND_DECL(seek_white_or_token_left){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -397,8 +377,9 @@ COMMAND_DECL(seek_white_or_token_left){
if (file->tokens_complete){
token_pos = seek_token_left(&file->token_stack, view->cursor.pos);
}
white_pos = seek_whitespace_left((u8*)file->buffer.data, view->cursor.pos);
white_pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos);
view_cursor_move(view, Max(token_pos, white_pos));
#endif
}
internal i32
@ -426,6 +407,7 @@ seek_alphanumeric_left(u8 *data, i32 pos){
}
COMMAND_DECL(seek_alphanumeric_right){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -433,6 +415,7 @@ COMMAND_DECL(seek_alphanumeric_right){
i32 pos = seek_alphanumeric_right(
(u8*)file->buffer.data, file->buffer.size, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
COMMAND_DECL(seek_alphanumeric_left){
@ -446,6 +429,7 @@ COMMAND_DECL(seek_alphanumeric_left){
}
COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -467,6 +451,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
}
view_cursor_move(view, camel_pos);
#endif
}
COMMAND_DECL(seek_alphanumeric_or_camel_left){
@ -552,6 +537,7 @@ COMMAND_DECL(copy){
}
COMMAND_DECL(cut){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -571,6 +557,7 @@ COMMAND_DECL(cut){
view_measure_wraps(&mem->general, view);
view_cursor_move(view, next_cursor_pos);
}
#endif
}
COMMAND_DECL(paste){
@ -647,6 +634,7 @@ COMMAND_DECL(paste_next){
}
COMMAND_DECL(delete_chunk){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -661,6 +649,7 @@ COMMAND_DECL(delete_chunk){
view_cursor_move(view, next_cursor_pos);
view->mark = range.start;
}
#endif
}
COMMAND_DECL(timeline_scrub){
@ -811,9 +800,11 @@ app_open_file(App_Vars *vars, General_Memory *general, Panel *panel,
command_data->view = old_view;
new_view->map = app_get_map(vars, target_file->base_map_id);
#if BUFFER_EXPERIMENT_SCALPEL
if (created_file && target_file->tokens_exist)
file_first_lex_parallel(general, target_file);
#endif
}
return result;
@ -886,8 +877,10 @@ COMMAND_DECL(reopen){
*file = temp_file;
file->source_path.str = file->source_path_;
file->live_name.str = file->live_name_;
#if BUFFER_EXPERIMENT_SCALPEL
if (file->tokens_exist)
file_first_lex_parallel(&mem->general, file);
#endif
Partition old_part = command->part;
Temp_Memory temp = begin_temp_memory(&vars->mem.part);
@ -1031,17 +1024,6 @@ COMMAND_DECL(toggle_line_wrap){
view_set_relative_scrolling(view, scrolling);
}
COMMAND_DECL(toggle_endline_mode){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_MEM(mem);
file_measure_starts(&mem->general, view->file);
view->cursor =
view_compute_cursor_from_pos(view, view->cursor.pos);
}
COMMAND_DECL(toggle_show_whitespace){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
@ -1049,6 +1031,7 @@ COMMAND_DECL(toggle_show_whitespace){
}
COMMAND_DECL(toggle_tokens){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1060,6 +1043,7 @@ COMMAND_DECL(toggle_tokens){
else{
file_first_lex_parallel(&mem->general, file);
}
#endif
}
internal void
@ -1084,9 +1068,11 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
data[i] += char_delta;
}
}
#if BUFFER_EXPERIMENT_SCALPEL
if (file->token_stack.tokens)
file_relex_parallel(mem, file, range.start, range.end, 0);
#endif
}
}
@ -1280,9 +1266,7 @@ COMMAND_DECL(move_left){
REQ_FILE(file, view);
i32 pos = view->cursor.pos;
if (pos > 0){
--pos;
}
if (pos > 0) --pos;
view_cursor_move(view, pos);
}
@ -1292,16 +1276,15 @@ COMMAND_DECL(move_right){
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 size = file->buffer.size;
i32 size = buffer_size(&file->buffer);
i32 pos = view->cursor.pos;
if (pos < size){
++pos;
}
if (pos < size) ++pos;
view_cursor_move(view, pos);
}
COMMAND_DECL(delete){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1322,9 +1305,11 @@ COMMAND_DECL(delete){
view_cursor_move(view, next_cursor_pos);
if (view->mark >= end) view->mark -= shift;
}
#endif
}
COMMAND_DECL(backspace){
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -1346,6 +1331,7 @@ COMMAND_DECL(backspace){
view_cursor_move(view, next_cursor_pos);
if (view->mark >= end) view->mark -= shift;
}
#endif
}
COMMAND_DECL(move_up){
@ -1536,6 +1522,7 @@ COMMAND_DECL(set_settings){
REQ_FILE(file, view);
USE_VARS(vars);
USE_MEM(mem);
AllowLocal(mem);
Command_Parameter *end = param_stack_end(&command->part);
Command_Parameter *param = param_stack_first(&command->part, end);
@ -1544,6 +1531,7 @@ COMMAND_DECL(set_settings){
switch (p){
case par_lex_as_cpp_file:
{
#if BUFFER_EXPERIMENT_SCALPEL
int v = dynamic_to_bool(&param->param.value);
if (file->tokens_exist){
if (!v) file_kill_tokens(&mem->general, file);
@ -1551,6 +1539,7 @@ COMMAND_DECL(set_settings){
else{
if (v) file_first_lex_parallel(&mem->general, file);
}
#endif
}break;
case par_wrap_lines:
@ -1658,6 +1647,7 @@ extern "C"{
if (view){
Editing_File *file = view->file;
if (file && !file->is_dummy){
#if BUFFER_EXPERIMENT_SCALPEL
Working_Set *working_set = cmd->working_set;
buffer.file_id = (int)(file - working_set->files);
buffer.size = file->buffer.size;
@ -1669,6 +1659,7 @@ extern "C"{
buffer.file_cursor_pos = file->cursor_pos;
buffer.is_lexed = file->tokens_exist;
buffer.map_id = file->base_map_id;
#endif
}
}
@ -1727,8 +1718,8 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, codes->page_up, MDFR_NONE, command_page_up);
map_add(commands, codes->page_down, MDFR_NONE, command_page_down);
map_add(commands, codes->right, MDFR_CTRL, command_seek_white_or_token_right);
map_add(commands, codes->left, MDFR_CTRL, command_seek_white_or_token_left);
map_add(commands, codes->right, MDFR_CTRL, command_seek_whitespace_right);
map_add(commands, codes->left, MDFR_CTRL, command_seek_whitespace_left);
map_add(commands, codes->up, MDFR_CTRL, command_seek_whitespace_up);
map_add(commands, codes->down, MDFR_CTRL, command_seek_whitespace_down);
@ -1748,7 +1739,6 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, 'H', MDFR_CTRL, command_history_forward);
map_add(commands, 'd', MDFR_CTRL, command_delete_chunk);
map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap);
map_add(commands, 'L', MDFR_CTRL, command_toggle_endline_mode);
map_add(commands, '?', MDFR_CTRL, command_toggle_show_whitespace);
map_add(commands, '|', MDFR_CTRL, command_toggle_tokens);
map_add(commands, 'u', MDFR_CTRL, command_to_uppercase);
@ -1850,7 +1840,6 @@ setup_command_table(){
SET(interactive_kill_buffer);
SET(kill_buffer);
SET(toggle_line_wrap);
SET(toggle_endline_mode);
SET(to_uppercase);
SET(to_lowercase);
SET(toggle_show_whitespace);
@ -2603,7 +2592,9 @@ app_step(Thread_Context *thread, Key_Codes *codes,
if (!view_->is_active) continue;
File_View *view = view_to_file_view(view_);
if (!view) continue;
#if BUFFER_EXPERIMENT_SCALPEL
view_measure_wraps(&vars->mem.general, view);
#endif
view->cursor = view_compute_cursor_from_pos(view, view->cursor.pos);
}
app_result.redraw = 1;
@ -3020,7 +3011,9 @@ app_step(Thread_Context *thread, Key_Codes *codes,
view_set_file(file_view, file.file, style,
vars->hooks[hook_open_file], &command_data, app_links);
new_view->map = app_get_map(vars, file.file->base_map_id);
#if BUFFER_EXPERIMENT_SCALPEL
if (file.file->tokens_exist) file_first_lex_parallel(general, file.file);
#endif
}break;
case DACT_SWITCH:
@ -3131,12 +3124,14 @@ app_step(Thread_Context *thread, Key_Codes *codes,
if (vars->style.font_changed){
vars->style.font_changed = 0;
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = vars->working_set.files;
for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){
if (file->buffer.data && !file->is_dummy){
file_measure_widths(&vars->mem.general, file, vars->style.font);
}
}
#endif
Panel *panel = panels;
for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){

View File

@ -9,7 +9,9 @@
// TOP
#include "buffer/4coder_golden_array.cpp"
#include "buffer/4coder_shared.cpp"
#include "buffer/4coder_gap_buffer.cpp"
#include "buffer/4coder_buffer_abstract.cpp"
struct Range{
i32 start, end;
@ -70,7 +72,7 @@ struct Undo_Data{
};
struct Editing_File{
Buffer buffer;
Gap_Buffer buffer;
Undo_Data undo;
@ -1008,7 +1010,7 @@ struct File_View_Widget{
struct File_View{
View view_base;
Delay *delay;
Editing_Layout *layout;
@ -1108,19 +1110,17 @@ internal bool32
file_save(Partition *part, Editing_File *file, u8 *filename){
bool32 result = 0;
Temp_Memory temp = begin_temp_memory(part);
Buffer temp_buffer;
temp_buffer.max = partition_remaining(part);
temp_buffer.size = 0;
temp_buffer.data = push_array(part, char, temp_buffer.max);
// TODO(allen): What about using this stringify loop to convert out?
for (Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, file->buffer.size, file->buffer.size);
i32 max = partition_remaining(part);
i32 size = 0;
char *data = push_array(part, char, max);
i32 data_size = buffer_size(&file->buffer);
for (Gap_Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, data_size, data_size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
memcpy(temp_buffer.data, loop.data, loop.size);
temp_buffer.size += loop.size;
buffer_eol_convert_out(&temp_buffer);
result = system_save_file(filename, temp_buffer.data, temp_buffer.size);
memcpy(data + size, loop.data, loop.size);
size += loop.size;
}
result = system_save_file(filename, data, size);
end_temp_memory(temp);
file_synchronize_times(file, filename);
return result;
@ -1322,18 +1322,11 @@ view_measure_wraps(General_Memory *general, File_View *view){
general_memory_allocate(general, sizeof(real32)*max, BUBBLE_WRAPS);
}
}
Font *font = view->style->font;
real32 line_height = (real32)font->height;
real32 max_width = view_compute_width(view);
real32 *line_widths = file->buffer.line_widths;
real32 *line_wraps = view->line_wrap_y;
i32 y_pos = 0;
for (i32 i = 0; i < line_count; ++i){
line_wraps[i] = y_pos*line_height;
i32 line_span = view_wrapped_line_span(line_widths[i], max_width);
y_pos += line_span;
}
buffer_measure_wrap_y(&file->buffer, view->line_wrap_y, line_height, max_width);
view->line_count = line_count;
}
@ -1351,22 +1344,15 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
*file = {};
file->buffer.data = (char*)data;
file->buffer.size = val.size;
file->buffer.max = request_size;
if (val.size > 0){
memcpy(data, val.str, val.size);
buffer_eol_convert_in(&file->buffer);
}
data[val.size] = 0;
gap_buffer_initialize(&file->buffer, val.str, val.size);
file_synchronize_times(file, filename);
file_init_strings(file);
file_set_name(file, filename);
file->base_map_id = mapid_file;
file_measure_starts(general, file);
file_measure_widths(general, file, font);
file->font = font;
@ -1471,7 +1457,7 @@ file_close(General_Memory *general, Editing_File *file){
internal void
file_get_dummy(Editing_File *file){
*file = {};
file->buffer.data = (char*)&file->buffer.size;
file->buffer.data = (char*)&file->buffer.size1;
file->is_dummy = 1;
}
@ -1479,6 +1465,7 @@ struct Shift_Information{
i32 start, end, amount;
};
#if BUFFER_EXPERIMENT_SCALPEL
internal
JOB_CALLBACK(job_full_lex){
Editing_File *file = (Editing_File*)data[0];
@ -1541,6 +1528,7 @@ JOB_CALLBACK(job_full_lex){
file->tokens_complete = 1;
file->still_lexing = 0;
}
#endif
internal void
file_kill_tokens(General_Memory *general, Editing_File *file){
@ -1555,9 +1543,9 @@ file_kill_tokens(General_Memory *general, Editing_File *file){
file->token_stack = {};
}
#if BUFFER_EXPERIMENT_SCALPEL
internal void
file_first_lex_parallel(General_Memory *general, Editing_File *file){
#if 1
Assert(file->token_stack.tokens == 0);
file->tokens_complete = 0;
@ -1570,9 +1558,6 @@ file_first_lex_parallel(General_Memory *general, Editing_File *file){
job.data[1] = general;
job.memory_request = Kbytes(64);
file->lex_job = system_post_job(BACKGROUND_THREADS, job);
#else
file_kill_tokens(general, file);
#endif
}
internal void
@ -1659,17 +1644,18 @@ file_relex_parallel(Mem_Options *mem, Editing_File *file,
file->lex_job = system_post_job(BACKGROUND_THREADS, job);
}
}
#endif
internal bool32
file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_size){
bool32 result = 1;
i32 target_size = file->buffer.size + additional_size + 1;
i32 size = buffer_size(&file->buffer);
i32 target_size = size + additional_size + 1;
if (target_size >= file->buffer.max){
i32 request_size = LargeRoundUp(target_size*2, Kbytes(256));
char *new_data = (char*)
general_memory_reallocate(general, file->buffer.data, file->buffer.size, request_size, BUBBLE_BUFFER);
general_memory_reallocate(general, file->buffer.data, size, request_size, BUBBLE_BUFFER);
if (new_data){
new_data[file->buffer.size] = 0;
file->buffer.data = new_data;
file->buffer.max = request_size;
}
@ -1754,6 +1740,7 @@ struct Edit_Spec{
Edit_Step step;
};
#if BUFFER_EXPERIMENT_SCALPEL
internal Edit_Step*
file_post_undo(General_Memory *general, Editing_File *file,
Edit_Step step, bool32 do_merge, bool32 can_merge){
@ -1957,6 +1944,7 @@ file_post_history(General_Memory *general, Editing_File *file,
return result;
}
#endif
inline Full_Cursor
view_compute_cursor_from_pos(File_View *view, i32 pos){
@ -2066,11 +2054,12 @@ view_set_file(File_View *view, Editing_File *file, Style *style,
view->file = file;
General_Memory *general = &view->view_base.mem->general;
AllowLocal(general);
Font *font = style->font;
view->style = style;
view->font_advance = font->advance;
view->font_height = font->height;
view_measure_wraps(general, view);
view->cursor = {};
@ -2219,6 +2208,7 @@ enum History_Mode{
internal void
view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str,
History_Mode history_mode, i32 next_cursor){
#if BUFFER_EXPERIMENT_SCALPEL
General_Memory *general = &mem->general;
#if FRED_SLOW
@ -2387,6 +2377,7 @@ view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
}
if (history_mode == hist_normal) file->undo.edit_history_cursor = file->undo.history.edit_count;
#endif
}
inline b32
@ -2431,28 +2422,36 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
i32 str_len = spec.step.edit.len;
i32 shift_amount;
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount))
while (gap_buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount))
file_grow_as_needed(general, file, shift_amount);
// NOTE(allen): fixing stuff afterwards
#if BUFFER_EXPERIMENT_SCALPEL
if (file->tokens_exist)
file_relex_parallel(mem, file, start, end, shift_amount);
#endif
i32 line_start = buffer_get_line_index(&file->buffer, start, 0, file->buffer.line_count);
i32 line_end = buffer_get_line_index(&file->buffer, end, 0, file->buffer.line_count);
i32 replaced_line_count = line_end - line_start;
// TODO(allen): check this
i32 new_line_count = file_count_newlines(file, start, start+str_len);
i32 line_shift = new_line_count - replaced_line_count;
file_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount);
file_remeasure_widths(general, file, file->font, line_start, line_end, line_shift);
Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
i32 panel_count = layout->panel_count;
Panel *current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_measure_wraps(general, current_view);
}
}
#if BUFFER_EXPERIMENT_SCALPEL
i32 cursor_count = 0;
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);
@ -2490,11 +2489,13 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
}
end_temp_memory(cursor_temp);
#endif
}
internal void
view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
#if BUFFER_EXPERIMENT_SCALPEL
Assert(file);
ProfileMomentFunction();
@ -2586,6 +2587,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
}
end_temp_memory(cursor_temp);
}
#endif
}
inline void
@ -2709,15 +2711,18 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
// TODO(allen): should these still be view operations?
internal i32
view_find_end_of_line(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = view->file;
char *data = file->buffer.data;
while (pos < file->buffer.size && data[pos] != '\n') ++pos;
if (pos > file->buffer.size) pos = file->buffer.size;
#endif
return pos;
}
internal i32
view_find_beginning_of_line(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = view->file;
char *data = file->buffer.data;
if (pos > 0){
@ -2725,11 +2730,13 @@ view_find_beginning_of_line(File_View *view, i32 pos){
while (pos > 0 && data[pos] != '\n') --pos;
if (pos != 0) ++pos;
}
#endif
return pos;
}
internal i32
view_find_beginning_of_next_line(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = view->file;
char *data = file->buffer.data;
while (pos < file->buffer.size &&
@ -2739,6 +2746,7 @@ view_find_beginning_of_next_line(File_View *view, i32 pos){
if (pos < file->buffer.size){
++pos;
}
#endif
return pos;
}
@ -2847,6 +2855,7 @@ enum Endline_Convert_Type{
internal void
view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = view->file;
Assert(file && !file->is_dummy);
Partition *part = &mem->part;
@ -2917,6 +2926,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
}
end_temp_memory(temp);
#endif
}
internal u32*
@ -3469,14 +3479,14 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
#if 1
Partition *part = &view_->mem->part;
Temp_Memory temp = begin_temp_memory(part);
partition_align(part, 4);
i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item);
Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max);
i32 count;
buffer_get_render_data(&file->buffer, view->line_wrap_y, items, max, &count,
(real32)rect.x0, (real32)rect.y0, view->scroll_x, view->scroll_y, view->unwrapped_lines,
(real32)rect.x0, (real32)rect.y0, view->scroll_x, view->scroll_y, !view->unwrapped_lines,
(real32)max_x, (real32)max_y, opad.data, opad.stride, (real32)font->height);
Assert(count > 0);
@ -3494,7 +3504,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
cursor_color = style->main.cursor_color;
at_cursor_color = style->main.at_cursor_color;
}
i32 token_i = 0;
u32 main_color = style->main.default_color;
if (tokens_use){
@ -3502,7 +3512,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
main_color = *style_get_color(style, token_stack.tokens[result.token_index]);
token_i = result.token_index + 1;
}
u32 mark_color = style->main.mark_color;
Buffer_Render_Item *item = items;
i32 prev_ind = -1;
@ -3523,7 +3533,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}
}
#if 0
#if BUFFER_EXPERIMENT_SCALPEL
if (current_token.type == CPP_TOKEN_JUNK &&
i >= current_token.start && i <= current_token.start + current_token.size){
highlight_color = style->main.highlight_junk_color;
@ -3863,6 +3873,7 @@ internal
HANDLE_COMMAND_SIG(handle_command_file_view){
File_View *file_view = (File_View*)(view);
Editing_File *file = file_view->file;
AllowLocal(file);
switch (file_view->widget.type){
case FWIDG_NONE:
@ -3878,6 +3889,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
case FWIDG_SEARCH:
{
#if BUFFER_EXPERIMENT_SCALPEL
String *string = &file_view->isearch.str;
Single_Line_Input_Step result =
app_single_line_input_step(codes, key, string);
@ -3965,6 +3977,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
file_view->show_temp_highlight = 0;
view_set_widget(file_view, FWIDG_NONE);
}
#endif
}break;
case FWIDG_GOTO_LINE:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,541 @@
/*
* Mr. 4th Dimention - Allen Webster
* Four Tech
*
* public domain -- no warranty is offered or implied; use this code at your own risk
*
* 16.10.2015
*
* Buffer data object
* type - Golden Array
*
*/
// TOP
#if BUFFER_EXPERIMENT_SCALPEL
#define Buffer_Type Buffer
#else
#define Buffer_Type Gap_Buffer
#endif
#define CAT_(a,b) a##b
#define CAT(a,b) CAT_(a,b)
#define Buffer_Stringify_Type CAT(Buffer_Type, _Stringify_Loop)
#define Buffer_Backify_Type CAT(Buffer_Type, _Backify_Loop)
internal_4tech int
buffer_count_newlines(Buffer_Type *buffer, int start, int end){
Buffer_Stringify_Type loop;
int i;
int count;
assert_4tech(0 <= start);
assert_4tech(start <= end);
assert_4tech(end < buffer_size(buffer));
count = 0;
for (loop = buffer_stringify_loop(buffer, start, end, end - start);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
for (i = 0; i < loop.size; ++i){
count += (loop.data[i] == '\n');
}
}
return(count);
}
internal_4tech int
buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
char *data;
int end;
int size;
size = buffer_size(buffer);
loop = buffer_stringify_loop(buffer, pos, size, size);
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && is_whitespace(data[pos]); ++pos);
if (!is_whitespace(data[pos])) break;
}
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && !is_whitespace(data[pos]); ++pos);
if (is_whitespace(data[pos])) break;
}
return(pos);
}
internal_4tech int
buffer_seek_whitespace_left(Buffer_Type *buffer, int pos){
Buffer_Backify_Type loop;
char *data;
int end;
int size;
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 0, size);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos > end && is_whitespace(data[pos]); --pos);
if (!is_whitespace(data[pos])) break;
}
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos > end && !is_whitespace(data[pos]); --pos);
if (is_whitespace(data[pos])) break;
}
return(pos);
}
typedef struct{
int i;
int count;
int start;
} Buffer_Measure_Starts;
internal_4tech int
buffer_measure_starts(Buffer_Measure_Starts *state, Buffer_Type *buffer){
Buffer_Stringify_Type loop;
int *starts;
int max;
char *data;
int size, end;
int start, count, i;
int result;
size = buffer_size(buffer);
starts = buffer->line_starts;
max = buffer->line_max;
result = 0;
i = state->i;
count = state->count;
start = state->start;
for (loop = buffer_stringify_loop(buffer, i, size, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; i < end; ++i){
if (data[i] == '\n'){
if (count == max){
result = 1;
goto buffer_measure_starts_end;
}
starts[count++] = start;
start = i + 1;
}
}
}
if (i == size){
starts[count++] = start;
}
buffer_measure_starts_end:
state->i = i;
state->count = count;
state->start = start;
return(result);
}
internal_4tech void
buffer_remeasure_starts(Buffer_Type *buffer, int line_start, int line_end, int line_shift, int text_shift){
Buffer_Stringify_Type loop;
int *starts;
int line_count;
char *data;
int size, end;
int line_i, char_i, start;
starts = buffer->line_starts;
line_count = buffer->line_count;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_end < line_count);
assert_4tech(line_count + line_shift <= buffer->line_max);
++line_end;
if (text_shift != 0){
line_i = line_end;
starts += line_i;
for (; line_i < line_count; ++line_i, ++starts){
*starts += text_shift;
}
starts = buffer->line_starts;
}
if (line_shift != 0){
memmove_4tech(starts + line_end + line_shift, starts + line_end,
sizeof(int)*(line_count - line_end));
line_count += line_shift;
}
line_end += line_shift;
size = buffer_size(buffer);
char_i = starts[line_start];
line_i = line_start;
start = char_i;
for (loop = buffer_stringify_loop(buffer, char_i, size, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; char_i < end; ++char_i){
if (data[char_i] == '\n'){
starts[line_i++] = start;
start = char_i + 1;
if (line_i >= line_end && start == starts[line_i]) goto buffer_remeasure_starts_end;
}
}
}
if (char_i == size){
starts[line_i++] = start;
}
buffer_remeasure_starts_end:
assert_4tech(line_count >= 1);
buffer->line_count = line_count;
}
internal_4tech void
buffer_remeasure_widths(Buffer_Type *buffer, void *advance_data, int stride,
int line_start, int line_end, int line_shift){
Buffer_Stringify_Type loop;
int *starts;
float *widths;
int line_count;
char *data;
int size, end;
int i, j;
float width;
char ch;
starts = buffer->line_starts;
widths = buffer->line_widths;
line_count = buffer->line_count;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_end < line_count);
assert_4tech(line_count <= buffer->widths_max);
++line_end;
if (line_shift != 0){
memmove_4tech(widths + line_end + line_shift, widths + line_end,
sizeof(float)*(line_count - line_end));
}
line_end += line_shift;
i = line_start;
j = starts[i];
if (line_end == line_count) size = buffer_size(buffer);
else size = starts[line_end];
width = 0;
for (loop = buffer_stringify_loop(buffer, j, size, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; j < end; ++j){
ch = data[j];
if (ch == '\n'){
widths[i] = width;
++i;
assert_4tech(j + 1 == starts[i]);
width = 0;
}
else{
width += measure_character(advance_data, stride, ch);
}
}
}
}
inline_4tech void
buffer_measure_widths(Buffer_Type *buffer, void *advance_data, int stride){
assert_4tech(buffer->line_count >= 1);
buffer_remeasure_widths(buffer, advance_data, stride, 0, buffer->line_count-1, 0);
}
internal_4tech void
buffer_measure_wrap_y(Buffer_Type *buffer, float *wraps,
float font_height, float max_width){
float *widths;
float y_pos;
int i, line_count;
line_count = buffer->line_count;
widths = buffer->line_widths;
y_pos = 0;
for (i = 0; i < line_count; ++i){
wraps[i] = y_pos;
if (widths[i] == 0) y_pos += font_height;
else y_pos += font_height*ceil_4tech(widths[i]/max_width);
}
}
internal_4tech int
buffer_get_line_index(Buffer_Type *buffer, int pos, int l_bound, int u_bound){
int *lines;
int start, end;
int i;
assert_4tech(0 <= l_bound);
assert_4tech(l_bound <= u_bound);
assert_4tech(u_bound <= buffer->line_count);
lines = buffer->line_starts;
start = l_bound;
end = u_bound;
for (;;){
i = (start + end) >> 1;
if (lines[i] < pos) start = i;
else if (lines[i] > pos) end = i;
else{
start = i;
break;
}
assert_4tech(start < end);
if (start == end - 1) break;
}
return(start);
}
internal_4tech int
buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, int l_bound, int u_bound){
int start, end, i, result;
start = l_bound;
end = u_bound;
for (;;){
i = (start + end) / 2;
if (wraps[i]+font_height <= y) start = i;
else if (wraps[i] > y) end = i;
else{
result = i;
break;
}
if (start >= end - 1){
result = start;
break;
}
}
return(result);
}
inline_4tech Full_Cursor
make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height){
Full_Cursor hint;
hint.pos = starts[line_index];
hint.line = line_index + 1;
hint.character = 1;
hint.unwrapped_y = (f32)(line_index * font_height);
hint.unwrapped_x = 0;
hint.wrapped_y = wrap_ys[line_index];
hint.wrapped_x = 0;
return(hint);
}
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
line_index = buffer_get_line_index(buffer, pos, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height,
advance_data, stride, result);
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, float x, float y, int round_down, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
line_index = (int)(y / font_height);
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_unwrapped_xy(x, y, round_down), max_width, font_height,
advance_data, stride, result);
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, float x, float y, int round_down, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
line_index = buffer_get_line_index_from_wrapped_y(wraps, y, font_height, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_wrapped_xy(x, y, round_down), max_width, font_height,
advance_data, stride, result);
return(result);
}
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, Full_Cursor start_cursor, int wrapped,
float width, float height, void *advance_data, int stride, float font_height){
Buffer_Stringify_Type loop;
Buffer_Render_Item *item;
char *data;
int size, end;
float shift_x, shift_y;
float x, y;
int i, item_i;
float ch_width, ch_width_sub;
char ch;
size = buffer_size(buffer);
shift_x = port_x - scroll_x;
shift_y = port_y - scroll_y;
if (wrapped) shift_y += start_cursor.wrapped_y;
else shift_y += start_cursor.unwrapped_y;
x = shift_x;
y = shift_y;
item_i = 0;
item = items + item_i;
for (loop = buffer_stringify_loop(buffer, start_cursor.pos, size, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (i = loop.absolute_pos; i < end; ++i){
ch = data[i];
ch_width = measure_character(advance_data, stride, ch);
if (ch_width + x > width + shift_x && wrapped){
x = shift_x;
y += font_height;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
++item_i;
++item;
x = shift_x;
y += font_height;
break;
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
++item_i;
++item;
x += ch_width;
break;
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
}
}
buffer_get_render_data_end:
// TODO(allen): handle this with a control state
assert_4tech(item_i <= max);
*count = item_i;
}
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,
float width, float height, void *advance_data, int stride, float font_height){
Full_Cursor start_cursor;
if (wrapped){
start_cursor = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data, stride);
}
else{
start_cursor = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data, stride);
}
buffer_get_render_data(buffer, wraps, items, max, count,
port_x, port_y, scroll_x, scroll_y, start_cursor, wrapped,
width, height, advance_data, stride, font_height);
}
// BOTTOM

View File

@ -0,0 +1,302 @@
/*
* Mr. 4th Dimention - Allen Webster
* Four Tech
*
* public domain -- no warranty is offered or implied; use this code at your own risk
*
* 23.10.2015
*
* Buffer data object
* type - Gap Buffer
*
*/
// TOP
typedef struct{
char *data;
int size1, gap_size, size2, max;
float *line_widths;
int *line_starts;
int line_count;
int line_max;
int widths_max;
} Gap_Buffer;
inline_4tech void
gap_buffer_initialize(Gap_Buffer *buffer, char *data, int size){
int size1, size2, gap_size;
assert_4tech(buffer->max >= size);
size1 = size >> 1;
size2 = size - size1;
gap_size = buffer->max - size1 - size2;
buffer->size1 = size1;
buffer->size2 = size2;
buffer->gap_size = gap_size;
if (buffer->size1 > 0){
memcpy_4tech(buffer->data, data, size1);
}
if (buffer->size2 > 0){
memcpy_4tech(buffer->data + size1 + gap_size, data + size1, size2);
}
}
inline_4tech int
buffer_size(Gap_Buffer *buffer){
int size;
size = buffer->size1 + buffer->size2;
return(size);
}
typedef struct{
Gap_Buffer *buffer;
char *data, *base;
int absolute_pos;
int pos, end;
int size;
int page_size;
int separated;
} Gap_Buffer_Stringify_Loop;
inline_4tech Gap_Buffer_Stringify_Loop
buffer_stringify_loop(Gap_Buffer *buffer, int start, int end, int page_size){
Gap_Buffer_Stringify_Loop result;
if (0 <= start && start < end && end <= buffer->size1 + buffer->size2){
result.buffer = buffer;
result.base = buffer->data;
result.page_size = page_size;
result.absolute_pos = start;
if (end <= buffer->size1) result.end = end;
else result.end = end + buffer->gap_size;
if (start < buffer->size1){
if (end <= buffer->size1) result.separated = 0;
else result.separated = 1;
result.pos = start;
}
else{
result.separated = 0;
result.pos = start + buffer->gap_size;
}
if (result.separated) result.size = buffer->size1 - start;
else result.size = end - start;
if (result.size > page_size) result.size = page_size;
result.data = buffer->data + result.pos;
}
else result.buffer = 0;
return(result);
}
inline_4tech int
buffer_stringify_good(Gap_Buffer_Stringify_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
inline_4tech void
buffer_stringify_next(Gap_Buffer_Stringify_Loop *loop){
int size1, temp_end;
if (loop->separated){
size1 = loop->buffer->size1;
if (loop->pos + loop->size == size1){
loop->separated = 0;
loop->pos = loop->buffer->gap_size + size1;
loop->absolute_pos = size1;
temp_end = loop->end;
}
else{
loop->pos += loop->page_size;
loop->absolute_pos += loop->page_size;
temp_end = size1;
}
}
else{
if (loop->pos + loop->size == loop->end){
loop->buffer = 0;
temp_end = loop->pos;
}
else{
loop->pos += loop->page_size;
loop->absolute_pos += loop->page_size;
temp_end = loop->end;
}
}
loop->size = temp_end - loop->pos;
if (loop->size > loop->page_size) loop->size = loop->page_size;
loop->data = loop->base + loop->pos;
}
typedef struct{
Gap_Buffer *buffer;
char *data, *base;
int pos, end;
int size;
int absolute_pos;
int page_size;
int separated;
} Gap_Buffer_Backify_Loop;
inline_4tech Gap_Buffer_Backify_Loop
buffer_backify_loop(Gap_Buffer *buffer, int start, int end, int page_size){
Gap_Buffer_Backify_Loop result;
int chunk2_start;
if (0 <= end && end < start && start <= buffer->size1 + buffer->size2){
chunk2_start = buffer->size1 + buffer->gap_size;
result.buffer = buffer;
result.base = buffer->data;
result.page_size = page_size;
if (end < buffer->size1) result.end = end;
else result.end = end + buffer->gap_size;
if (start <= buffer->size1){
result.separated = 0;
result.pos = start - page_size;
}
else{
if (end < buffer->size1) result.separated = 1;
else result.separated = 0;
result.pos = start - page_size + buffer->gap_size;
}
if (result.separated){
if (result.pos < chunk2_start) result.pos = chunk2_start;
}
else{
if (result.pos < result.end) result.pos = result.end;
}
result.size = start - result.pos;
result.absolute_pos = result.pos;
if (result.absolute_pos > buffer->size1) result.absolute_pos -= buffer->gap_size;
result.data = result.base + result.pos;
}
else result.buffer = 0;
return(result);
}
inline_4tech int
buffer_backify_good(Gap_Buffer_Backify_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
inline_4tech void
buffer_backify_next(Gap_Buffer_Backify_Loop *loop){
Gap_Buffer *buffer;
int temp_end;
int chunk2_start;
buffer = loop->buffer;
chunk2_start = buffer->size1 + buffer->gap_size;
if (loop->separated){
if (loop->pos == chunk2_start){
loop->separated = 0;
temp_end = buffer->size1;
loop->pos = temp_end - loop->page_size;
loop->absolute_pos = loop->pos;
if (loop->pos < loop->end){
loop->absolute_pos += (loop->end - loop->pos);
loop->pos = loop->end;
}
}
else{
temp_end = loop->pos;
loop->pos -= loop->page_size;
loop->absolute_pos -= loop->page_size;
if (loop->pos < chunk2_start){
loop->pos = chunk2_start;
loop->absolute_pos = buffer->size1;
}
}
}
else{
if (loop->pos == loop->end){
temp_end = 0;
loop->buffer = 0;
}
else{
temp_end = loop->pos;
loop->pos -= loop->page_size;
loop->absolute_pos -= loop->page_size;
if (loop->pos < loop->end){
loop->absolute_pos += (loop->end - loop->pos);
loop->pos = loop->end;
}
}
}
loop->size = temp_end - loop->pos;
loop->data = loop->base + loop->pos;
}
inline_4tech void
buffer_stringify(Gap_Buffer *buffer, int start, int end, char *out){
for (Gap_Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
memcpy_4tech(out, loop.data, loop.size);
out += loop.size;
}
}
internal_4tech Full_Cursor
buffer_cursor_seek(Gap_Buffer *buffer, Buffer_Seek seek, float max_width, float font_height,
void *advance_data, int stride, Full_Cursor cursor){
char *data;
int size1, size2, gap_size;
int total_size, end, i;
int step;
int result;
Seek_State state;
char *advances;
int xy_seek;
char ch;
data = buffer->data;
size1 = buffer->size1;
gap_size = buffer->gap_size;
size2 = buffer->size2;
total_size = size1 + gap_size + size2;
advances = (char*)advance_data;
xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy);
state.cursor = cursor;
result = 1;
i = cursor.pos;
end = size1;
for (step = 0; step < 2; ++step){
for (; i < end && result; ++i){
ch = data[i];
result = cursor_seek_step(&state, seek, xy_seek, max_width, font_height,
advances, stride, size1 + size2, ch);
}
end = total_size;
i += gap_size;
}
if (result){
result = cursor_seek_step(&state, seek, xy_seek, max_width, font_height,
advances, stride, size1 + size2, 0);
assert_4tech(result == 0);
}
return(state.cursor);
}
// TODO(allen): unfinished below here
internal_4tech int
gap_buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){
return(0);
}
// BOTTOM

View File

@ -13,31 +13,26 @@
// TOP
#ifndef defines_4tech
#define inline_4tech inline
#define internal_4tech static
#define memset_4tech memset
#define memcpy_4tech memcpy
#define memmove_4tech memmove
#define defines_4tech 1
#define debug_4tech(x) x
#define assert_4tech assert
#endif
typedef struct{
char *data;
int size, max;
float *line_widths;
int *line_starts;
float *line_widths;
int line_count;
int line_max;
int widths_max;
} Buffer;
inline_4tech int
buffer_size(Buffer *buffer){
return buffer->size;
}
typedef struct{
Buffer *buffer;
char *data, *end;
int absolute_pos;
int size;
int page_size;
} Buffer_Stringify_Loop;
@ -47,6 +42,7 @@ buffer_stringify_loop(Buffer *buffer, int start, int end, int page_size){
Buffer_Stringify_Loop result;
if (0 <= start && start < end && end <= buffer->size){
result.buffer = buffer;
result.absolute_pos = start;
result.data = buffer->data + start;
result.size = end - start;
result.end = buffer->data + end;
@ -69,11 +65,59 @@ buffer_stringify_next(Buffer_Stringify_Loop *loop){
if (loop->data + loop->size == loop->end) loop->buffer = 0;
else{
loop->data += loop->page_size;
loop->absolute_pos += loop->page_size;
loop->size = (int)(loop->end - loop->data);
if (loop->size > loop->page_size) loop->size = loop->page_size;
}
}
typedef struct{
Buffer *buffer;
char *data, *end;
int absolute_pos;
int size;
int page_size;
} Buffer_Backify_Loop;
inline_4tech Buffer_Backify_Loop
buffer_backify_loop(Buffer *buffer, int start, int end, int page_size){
Buffer_Backify_Loop result;
if (0 <= end && end < start && start <= buffer->size){
result.buffer = buffer;
result.end = buffer->data + end;
result.page_size = page_size;
result.size = start - end;
if (result.size > page_size) result.size = page_size;
result.absolute_pos = start - result.size;
result.data = buffer->data + result.absolute_pos;
}
else result.buffer = 0;
return(result);
}
inline_4tech int
buffer_backify_good(Buffer_Backify_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
inline_4tech void
buffer_backify_next(Buffer_Backify_Loop *loop){
char *old_data;
if (loop->data == loop->end) loop->buffer = 0;
else{
old_data = loop->data;
loop->data -= loop->page_size;
loop->absolute_pos -= loop->page_size;
if (loop->data < loop->end){
loop->size = (int)(old_data - loop->end);
loop->data = loop->end;
loop->absolute_pos = 0;
}
}
}
inline_4tech void
buffer_stringify(Buffer *buffer, int start, int end, char *out){
for (Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start);
@ -84,227 +128,25 @@ buffer_stringify(Buffer *buffer, int start, int end, char *out){
}
}
internal_4tech int
buffer_count_newlines(Buffer *buffer, int start, int end){
char *data;
int i;
int count;
assert_4tech(0 <= start);
assert_4tech(start <= end);
assert_4tech(end < buffer->size);
data = buffer->data;
count = 0;
for (i = start; i < end; ++i){
count += (data[i] == '\n');
}
return(count);
}
typedef struct{
int i;
int count;
int start;
} Buffer_Measure_Starts;
internal_4tech int
buffer_measure_starts(Buffer_Measure_Starts *state, Buffer *buffer){
int *starts;
int max;
char *data;
int size;
int start, count, i;
int result;
starts = buffer->line_starts;
max = buffer->line_max;
data = buffer->data;
size = buffer->size;
assert_4tech(size < buffer->max);
data[size] = '\n';
result = 0;
i = state->i;
count = state->count;
start = state->start;
for (; i <= size; ++i){
if (data[i] == '\n'){
if (count == max){
result = 1;
break;
}
starts[count++] = start;
start = i + 1;
}
}
state->i = i;
state->count = count;
state->start = start;
return(result);
}
#if 0
internal_4tech void
buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_shift, int text_shift){
int *starts;
int line_count;
char *data;
int size;
int line_i, char_i, start;
starts = buffer->line_starts;
line_count = buffer->line_count;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_end < line_count);
assert_4tech(line_count + line_shift <= buffer->line_max);
++line_end;
if (text_shift != 0){
line_i = line_end;
starts += line_i;
for (; line_i < line_count; ++line_i, ++starts){
*starts += text_shift;
}
starts = buffer->line_starts;
}
if (line_shift != 0){
memmove_4tech(starts + line_end + line_shift, starts + line_end,
sizeof(int)*(line_count - line_end));
line_count += line_shift;
}
size = buffer->size;
data = buffer->data;
char_i = starts[line_start];
line_i = line_start;
assert_4tech(size < buffer->max);
data[size] = '\n';
start = char_i;
line_end += line_shift;
for (; char_i <= size; ++char_i){
if (data[char_i] == '\n'){
starts[line_i++] = start;
start = char_i + 1;
if (line_i >= line_end && start == starts[line_i]) break;
}
}
assert_4tech(line_count >= 1);
buffer->line_count = line_count;
}
inline_4tech float
measure_character(void *advance_data, int stride, char character){
char *advances;
float width;
advances = (char*)advance_data;
switch (character){
case 0: width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '0'); break;
case '\n': width = 0; break;
case '\r': width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '\r'); break;
default: width = *(float*)(advances + stride * character);
}
return(width);
}
internal_4tech void
buffer_remeasure_widths(Buffer *buffer, void *advance_data, int stride,
int line_start, int line_end, int line_shift){
int *starts;
buffer_measure_wrap_y(Buffer *buffer, float *wraps,
float font_height, float max_width){
float *widths;
int line_count;
char *data;
int i, j;
float width;
char ch;
starts = buffer->line_starts;
widths = buffer->line_widths;
float y_pos;
int i, line_count;
line_count = buffer->line_count;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_end < line_count);
assert_4tech(line_count <= buffer->widths_max);
widths = buffer->line_widths;
y_pos = 0;
++line_end;
if (line_shift != 0){
memmove_4tech(widths + line_end + line_shift, widths + line_end,
sizeof(float)*(line_count - line_end));
line_count += line_shift;
}
data = buffer->data;
assert_4tech(buffer->size < buffer->max);
data[buffer->size] = '\n';
i = line_start;
j = starts[i];
line_end += line_shift;
for (; i < line_end; ++i){
assert_4tech(j == starts[i]);
width = 0;
for (ch = data[j]; ch != '\n'; ch = data[++j]){
width += measure_character(advance_data, stride, ch);
}
++j;
widths[i] = width;
for (i = 0; i < line_count; ++i){
wraps[i] = y_pos;
if (widths[i] == 0) y_pos += font_height;
else y_pos += font_height*ceil_4tech(widths[i]/max_width);
}
}
inline_4tech void
buffer_measure_widths(Buffer *buffer, void *advance_data, int stride){
assert_4tech(buffer->line_count >= 1);
buffer_remeasure_widths(buffer, advance_data, stride, 0, buffer->line_count-1, 0);
}
internal_4tech int
buffer_get_line_index(Buffer *buffer, int pos, int l_bound, int u_bound){
int *lines;
int start, end;
int i;
assert_4tech(0 <= l_bound);
assert_4tech(l_bound <= u_bound);
assert_4tech(u_bound <= buffer->line_count);
start = l_bound;
end = u_bound;
lines = buffer->line_starts;
for (;;){
i = (start + end) >> 1;
if (lines[i] < pos) start = i;
else if (lines[i] > pos) end = i;
else{
start = i;
break;
}
assert_4tech(start < end);
if (start == end - 1) break;
}
return(start);
}
#endif
internal_4tech int
buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){
@ -405,78 +247,17 @@ buffer_update_cursors(Cursor_With_Index *sorted_positions, int count, int start,
for (; position >= sorted_positions && position->pos >= start; --position) position->pos = start;
}
typedef enum{
buffer_seek_pos,
buffer_seek_wrapped_xy,
buffer_seek_unwrapped_xy,
buffer_seek_line_char
} Buffer_Seek_Type;
typedef struct{
Buffer_Seek_Type type;
union{
struct { int pos; };
struct { int round_down; float x, y; };
struct { int line, character; };
};
} Buffer_Seek;
inline_4tech Buffer_Seek
seek_pos(int pos){
Buffer_Seek result;
result.type = buffer_seek_pos;
result.pos = pos;
return(result);
}
inline_4tech Buffer_Seek
seek_wrapped_xy(float x, float y, int round_down){
Buffer_Seek result;
result.type = buffer_seek_wrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
inline_4tech Buffer_Seek
seek_unwrapped_xy(float x, float y, int round_down){
Buffer_Seek result;
result.type = buffer_seek_unwrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
inline_4tech Buffer_Seek
seek_line_char(int line, int character){
Buffer_Seek result;
result.type = buffer_seek_line_char;
result.line = line;
result.character = character;
return(result);
}
typedef struct{
int pos;
int line, character;
float unwrapped_x, unwrapped_y;
float wrapped_x, wrapped_y;
} Full_Cursor;
internal_4tech Full_Cursor
buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, float max_width, float font_height,
void *advance_data, int stride, Full_Cursor cursor){
Full_Cursor prev_cursor;
char *data, *advances;
char *data;
int size;
char ch;
float ch_width;
int get_out;
Seek_State state;
char *advances;
char ch;
int xy_seek;
float x, y, px;
int result;
data = buffer->data;
size = buffer->size;
@ -484,182 +265,18 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, float max_width, float font
data[size] = 0;
advances = (char*)advance_data;
x = 0;
y = 0;
px = 0;
xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy);
state.cursor = cursor;
for (;;){
prev_cursor = cursor;
ch = data[cursor.pos];
switch (ch){
case '\n':
++cursor.line;
cursor.unwrapped_y += font_height;
cursor.wrapped_y += font_height;
cursor.character = 0;
cursor.unwrapped_x = 0;
cursor.wrapped_x = 0;
break;
default:
++cursor.character;
if (ch == '\r') ch_width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * 'r');
else ch_width = *(float*)(advances + stride * ch);
if (cursor.wrapped_x + ch_width >= max_width){
cursor.wrapped_y += font_height;
cursor.wrapped_x = 0;
prev_cursor = cursor;
}
cursor.unwrapped_x += ch_width;
cursor.wrapped_x += ch_width;
break;
}
++cursor.pos;
if (cursor.pos > size){
cursor = prev_cursor;
break;
}
get_out = 0;
switch (seek.type){
case buffer_seek_pos:
if (cursor.pos > seek.pos){
cursor = prev_cursor;
get_out = 1;
}break;
case buffer_seek_wrapped_xy:
x = cursor.wrapped_x; px = prev_cursor.wrapped_x;
y = cursor.wrapped_y; break;
case buffer_seek_unwrapped_xy:
x = cursor.unwrapped_x; px = prev_cursor.unwrapped_x;
y = cursor.unwrapped_y; break;
case buffer_seek_line_char:
if (cursor.line == seek.line && cursor.character >= seek.character){
get_out = 1;
}
else if (cursor.line > seek.line){
cursor = prev_cursor;
get_out = 1;
}break;
}
if (get_out) break;
if (xy_seek){
if (y > seek.y){
cursor = prev_cursor;
break;
}
if (y > seek.y - font_height && x >= seek.x){
if (!seek.round_down){
if ((seek.x - px) < (x - seek.x)) cursor = prev_cursor;
break;
}
if (x > seek.x){
cursor = prev_cursor;
break;
}
}
}
}
do{
ch = data[state.cursor.pos];
result = cursor_seek_step(&state, seek, xy_seek, max_width, font_height,
advances, stride, size, ch);
}while(result);
return(cursor);
return(state.cursor);
}
inline_4tech Full_Cursor
make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height){
Full_Cursor hint;
hint.pos = starts[line_index];
hint.line = line_index + 1;
hint.character = 1;
hint.unwrapped_y = (f32)(line_index * font_height);
hint.unwrapped_x = 0;
hint.wrapped_y = wrap_ys[line_index];
hint.wrapped_x = 0;
return(hint);
}
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer *buffer, int pos, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
line_index = buffer_get_line_index(buffer, pos, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height,
advance_data, stride, result);
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_unwrapped_xy(Buffer *buffer, float x, float y, int round_down, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
line_index = (int)(y / font_height);
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_unwrapped_xy(x, y, round_down), max_width, font_height,
advance_data, stride, result);
return(result);
}
internal_4tech Full_Cursor
buffer_cursor_from_wrapped_xy(Buffer *buffer, float x, float y, int round_down, float *wraps,
float max_width, float font_height, void *advance_data, int stride){
Full_Cursor result;
int line_index;
int start, end, i;
// NOTE(allen): binary search lines on wrapped y position
// TODO(allen): pull this out once other wrap handling code is ready
start = 0;
end = buffer->line_count;
for (;;){
i = (start + end) / 2;
if (wraps[i]+font_height <= y) start = i;
else if (wraps[i] > y) end = i;
else{
line_index = i;
break;
}
if (start >= end - 1){
line_index = start;
break;
}
}
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_wrapped_xy(x, y, round_down), max_width, font_height,
advance_data, stride, result);
return(result);
}
typedef struct{
int str_start, len;
int start, end;
} Buffer_Edit;
internal_4tech void
buffer_invert_edit_shift(Buffer *buffer, Buffer_Edit edit, Buffer_Edit *inverse, char *strings, int *str_pos, int max, int shift_amount){
int pos;
@ -916,166 +533,5 @@ buffer_eol_convert_out(Buffer *buffer){
buffer->size = size;
}
typedef struct{
int index;
int glyphid;
float x0, y0;
float x1, y1;
} Buffer_Render_Item;
internal_4tech void
buffer_get_render_data(Buffer *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,
float width, float height, void *advance_data, int stride, float font_height){
Full_Cursor start_cursor;
Buffer_Render_Item *item;
char *data;
int size;
float shift_x, shift_y;
float x, y;
int i, item_i;
float ch_width;
char ch;
data = buffer->data;
size = buffer->size;
assert_4tech(size < buffer->max);
data[size] = 0;
shift_x = port_x - scroll_x;
shift_y = port_y - scroll_y;
if (wrapped){
start_cursor = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data, stride);
shift_y += start_cursor.wrapped_y;
}
else{
start_cursor = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
width, font_height, advance_data, stride);
shift_y += start_cursor.unwrapped_y;
}
i = start_cursor.pos;
x = shift_x;
y = shift_y;
item_i = 0;
item = items + item_i;
for (; i <= size; ++i){
ch = data[i];
ch_width = measure_character(advance_data, stride, ch);
if (ch_width + x > width + shift_x && wrapped){
x = shift_x;
y += font_height;
}
if (y > height + shift_y) break;
switch (ch){
case '\n':
ch_width = measure_character(advance_data, stride, ' ');
item->index = i;
item->glyphid = ' ';
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x = shift_x;
y += font_height;
break;
case 0:
ch_width = measure_character(advance_data, stride, '\\');
item->index = i;
item->glyphid = '\\';
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
ch_width = measure_character(advance_data, stride, '0');
item->index = i;
item->glyphid = '0';
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
break;
case '\r':
ch_width = measure_character(advance_data, stride, '\\');
item->index = i;
item->glyphid = '\\';
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
ch_width = measure_character(advance_data, stride, 'r');
item->index = i;
item->glyphid = 'r';
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
break;
case '\t':
item->index = i;
item->glyphid = '\\';
item->x0 = x;
item->y0 = y;
item->x1 = x + measure_character(advance_data, stride, '\\');
item->y1 = y + font_height;
++item_i;
++item;
item->index = i;
item->glyphid = 't';
item->x0 = (item-1)->x1;
item->y0 = y;
item->x1 = item->x0 + measure_character(advance_data, stride, 't');
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
break;
default:
item->index = i;
item->glyphid = ch;
item->x0 = x;
item->y0 = y;
item->x1 = x + ch_width;
item->y1 = y + font_height;
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) break;
}
// TODO(allen): handle this with a control state
assert_4tech(item_i <= max);
*count = item_i;
}
// BOTTOM

256
buffer/4coder_shared.cpp Normal file
View File

@ -0,0 +1,256 @@
/*
* Mr. 4th Dimention - Allen Webster
* Four Tech
*
* public domain -- no warranty is offered or implied; use this code at your own risk
*
* 23.10.2015
*
* Items shared by gap buffer types
*
*/
// TOP
#ifndef defines_4tech
#define inline_4tech inline
#define internal_4tech static
#define memset_4tech memset
#define memcpy_4tech memcpy
#define memmove_4tech memmove
#define defines_4tech 1
#define debug_4tech(x) x
#define assert_4tech assert
#define ceil_4tech CEIL32
#endif
inline_4tech float
measure_character(void *advance_data, int stride, char character){
char *advances;
float width;
advances = (char*)advance_data;
switch (character){
case 0: width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '0'); break;
case '\n': width = 0; break;
case '\r': width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '\r'); break;
default: width = *(float*)(advances + stride * character);
}
return(width);
}
typedef struct{
int str_start, len;
int start, end;
} Buffer_Edit;
typedef enum{
buffer_seek_pos,
buffer_seek_wrapped_xy,
buffer_seek_unwrapped_xy,
buffer_seek_line_char
} Buffer_Seek_Type;
typedef struct{
Buffer_Seek_Type type;
union{
struct { int pos; };
struct { int round_down; float x, y; };
struct { int line, character; };
};
} Buffer_Seek;
inline_4tech Buffer_Seek
seek_pos(int pos){
Buffer_Seek result;
result.type = buffer_seek_pos;
result.pos = pos;
return(result);
}
inline_4tech Buffer_Seek
seek_wrapped_xy(float x, float y, int round_down){
Buffer_Seek result;
result.type = buffer_seek_wrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
inline_4tech Buffer_Seek
seek_unwrapped_xy(float x, float y, int round_down){
Buffer_Seek result;
result.type = buffer_seek_unwrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
inline_4tech Buffer_Seek
seek_line_char(int line, int character){
Buffer_Seek result;
result.type = buffer_seek_line_char;
result.line = line;
result.character = character;
return(result);
}
typedef struct{
int pos;
int line, character;
float unwrapped_x, unwrapped_y;
float wrapped_x, wrapped_y;
} Full_Cursor;
typedef struct{
int index;
int glyphid;
float x0, y0;
float x1, y1;
} Buffer_Render_Item;
inline_4tech void
write_render_item(Buffer_Render_Item *item, int index, int glyphid,
float x, float y, float w, float h){
item->index = index;
item->glyphid = glyphid;
item->x0 = x;
item->y0 = y;
item->x1 = x + w;
item->y1 = y + h;
}
inline_4tech float
write_render_item_inline(Buffer_Render_Item *item, int index, int glyphid,
float x, float y, void *advance_data, int stride, float h){
float ch_width;
ch_width = measure_character(advance_data, stride, (char)glyphid);
write_render_item(item, index, glyphid, x, y, ch_width, h);
return(ch_width);
}
typedef struct{
Full_Cursor cursor, prev_cursor;
} Seek_State;
internal_4tech int
cursor_seek_step(Seek_State *state, Buffer_Seek seek, int xy_seek, float max_width, float font_height,
char *advances, int stride, int size, char ch){
Full_Cursor cursor, prev_cursor;
float ch_width;
int result;
float x, px, y;
cursor = state->cursor;
prev_cursor = state->prev_cursor;
result = 1;
prev_cursor = cursor;
switch (ch){
case '\n':
++cursor.line;
cursor.unwrapped_y += font_height;
cursor.wrapped_y += font_height;
cursor.character = 1;
cursor.unwrapped_x = 0;
cursor.wrapped_x = 0;
break;
default:
++cursor.character;
if (ch == '\r') ch_width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * 'r');
else ch_width = *(float*)(advances + stride * ch);
if (cursor.wrapped_x + ch_width >= max_width){
cursor.wrapped_y += font_height;
cursor.wrapped_x = 0;
prev_cursor = cursor;
}
cursor.unwrapped_x += ch_width;
cursor.wrapped_x += ch_width;
break;
}
++cursor.pos;
if (cursor.pos > size){
cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}
x = y = px = 0;
switch (seek.type){
case buffer_seek_pos:
if (cursor.pos > seek.pos){
cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}break;
case buffer_seek_wrapped_xy:
x = cursor.wrapped_x; px = prev_cursor.wrapped_x;
y = cursor.wrapped_y; break;
case buffer_seek_unwrapped_xy:
x = cursor.unwrapped_x; px = prev_cursor.unwrapped_x;
y = cursor.unwrapped_y; break;
case buffer_seek_line_char:
if (cursor.line == seek.line && cursor.character >= seek.character){
result = 0;
goto cursor_seek_step_end;
}
else if (cursor.line > seek.line){
cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}break;
}
if (xy_seek){
if (y > seek.y){
cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}
if (y > seek.y - font_height && x >= seek.x){
if (!seek.round_down){
if (ch != '\n' && (seek.x - px) < (x - seek.x)) cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}
if (x > seek.x){
cursor = prev_cursor;
result = 0;
goto cursor_seek_step_end;
}
}
}
cursor_seek_step_end:
state->cursor = cursor;
state->prev_cursor = prev_cursor;
return(result);
}
inline_4tech int
is_whitespace(char c){
int result;
result = (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\f' || c == '\v');
return(result);
}
// BOTTOM

View File

@ -54,6 +54,8 @@
#define FPS 30
#define FRAME_TIME (1000000 / FPS)
#define BUFFER_EXPERIMENT_SCALPEL 0
#include "4ed_meta.h"
#define FCPP_FORBID_MALLOC
@ -91,7 +93,11 @@ struct Sys_Bubble : public Bubble{
#include "4ed_command.cpp"
#include "4ed_layout.cpp"
#include "4ed_style.cpp"
#if BUFFER_EXPERIMENT_SCALPEL
#include "4ed_file_view_golden_array.cpp"
#else
#include "4ed_file_view.cpp"
#endif
#include "4ed_color_view.cpp"
#include "4ed_interactive_view.cpp"
#include "4ed_menu_view.cpp"