From 7d31bb986d17357b7caf776d75a5ae63460b743d Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 28 Sep 2016 21:07:14 -0400 Subject: [PATCH] arbitrary line wrapping working --- 4ed.cpp | 2 +- 4ed_api_implementation.cpp | 8 +- 4ed_file_view.cpp | 85 ++++++-- buffer/4coder_buffer_abstract.cpp | 342 ++++++++++++++++++------------ buildsuper.bat | 2 +- 5 files changed, 276 insertions(+), 163 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 7c309c96..aaa3de2a 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -394,7 +394,7 @@ COMMAND_DECL(reopen){ int32_t character = column_number[i]; *vptrs[i]->edit_pos = edit_poss[i]; - Full_Cursor cursor = view_compute_cursor(vptrs[i], seek_line_char(line, character)); + Full_Cursor cursor = view_compute_cursor(vptrs[i], seek_line_char(line, character), 0); view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines); diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 4a70c5df..ed644be6 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -81,7 +81,7 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ view->buffer_id = buffer_id; - view->mark = view_compute_cursor(vptr, seek_pos(vptr->edit_pos->mark)); + view->mark = view_compute_cursor(vptr, seek_pos(vptr->edit_pos->mark), 0); view->cursor = vptr->edit_pos->cursor; view->preferred_x = vptr->edit_pos->preferred_x; @@ -1514,7 +1514,7 @@ DOC_SEE(Full_Cursor) seek.character = 1; } result = true; - *cursor_out = view_compute_cursor(vptr, seek); + *cursor_out = view_compute_cursor(vptr, seek, 0); fill_view_summary(view, vptr, cmd); } } @@ -1549,7 +1549,7 @@ DOC_SEE(Buffer_Seek) if (seek.type == buffer_seek_line_char && seek.character <= 0){ seek.character = 1; } - Full_Cursor cursor = view_compute_cursor(vptr, seek); + Full_Cursor cursor = view_compute_cursor(vptr, seek, 0); view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines); fill_view_summary(view, vptr, cmd); } @@ -1599,7 +1599,7 @@ DOC_SEE(Buffer_Seek) if (file && !file->is_loading){ result = true; if (seek.type != buffer_seek_pos){ - cursor = view_compute_cursor(vptr, seek); + cursor = view_compute_cursor(vptr, seek, 0); vptr->edit_pos->mark = cursor.pos; } else{ diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 8cc76406..19ede35b 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -9,7 +9,7 @@ // TOP -#define VWHITE 1 +#define VWHITE 0 internal i32 get_or_add_map_index(Models *models, i32 mapid){ @@ -394,12 +394,14 @@ view_cursor_limits(View *view){ return(limits); } -inline Full_Cursor -view_compute_cursor(View *view, Buffer_Seek seek){ +internal Full_Cursor +view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ Editing_File *file = view->file_data.file; Models *models = view->persistent.models; Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font; + Full_Cursor result = {0}; + Buffer_Cursor_Seek_Params params; params.buffer = &file->state.buffer; params.seek = seek; @@ -409,15 +411,30 @@ view_compute_cursor(View *view, Buffer_Seek seek){ params.wrap_line_index = file->state.wrap_line_index; params.character_starts = file->state.character_starts; params.virtual_white = VWHITE; + params.return_hint = return_hint; + params.cursor_out = &result; Buffer_Cursor_Seek_State state = {0}; - Full_Cursor result = {0}; Buffer_Layout_Stop stop = {0}; f32 line_shift = 0.f; + b32 do_wrap = 0; + i32 wrap_unit_end = 0; do{ - stop = buffer_cursor_seek(&state, params, line_shift, &result); + stop = buffer_cursor_seek(&state, params, line_shift, do_wrap, wrap_unit_end); switch (stop.status){ + case BLStatus_NeedWrapDetermination: + { + i32 rounded_pos = stop.pos - (stop.pos%11); + if ((rounded_pos % 2) == 1){ + do_wrap = 1; + } + else{ + do_wrap = 0; + } + wrap_unit_end = rounded_pos + 11; + }break; + case BLStatus_NeedWrapLineShift: case BLStatus_NeedLineShift: { @@ -439,7 +456,7 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ seek = seek_wrapped_xy(seek_x, seek_y, 0); } - Full_Cursor result = view_compute_cursor(view, seek); + Full_Cursor result = view_compute_cursor(view, seek, 0); return(result); } @@ -608,7 +625,7 @@ view_set_cursor_and_scroll(View *view, inline void view_set_temp_highlight(View *view, i32 pos, i32 end_pos){ - view->file_data.temp_highlight = view_compute_cursor(view, seek_pos(pos)); + view->file_data.temp_highlight = view_compute_cursor(view, seek_pos(pos), 0); view->file_data.temp_highlight_end_pos = end_pos; view->file_data.show_temp_highlight = 1; @@ -856,7 +873,7 @@ file_update_cursor_positions(Models *models, Editing_File *file){ i32 pos = view_get_cursor_pos(iter.view); if (!iter.view->file_data.show_temp_highlight){ - Full_Cursor cursor = view_compute_cursor(iter.view, seek_pos(pos)); + Full_Cursor cursor = view_compute_cursor(iter.view, seek_pos(pos), 0); view_set_cursor(iter.view, cursor, 1, iter.view->file_data.file->settings.unwrapped_lines); } else{ @@ -965,7 +982,7 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv params.virtual_white = VWHITE; Buffer_Measure_Wrap_State state = {0}; - Buffer_Layout_Measure_Stop stop = {0}; + Buffer_Layout_Stop stop = {0}; f32 edge_tolerance = 50.f; if (edge_tolerance > params.width){ @@ -973,9 +990,25 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv } f32 line_shift = 0.f; + b32 do_wrap = 0; + i32 wrap_unit_end = 0; + do{ - stop = buffer_measure_wrap_y(&state, params, line_shift); + stop = buffer_measure_wrap_y(&state, params, + line_shift, do_wrap, wrap_unit_end); switch (stop.status){ + case BLStatus_NeedWrapDetermination: + { + i32 rounded_pos = stop.pos - (stop.pos%11); + if ((rounded_pos % 2) == 1){ + do_wrap = 1; + } + else{ + do_wrap = 0; + } + wrap_unit_end = rounded_pos + 11; + }break; + case BLStatus_NeedWrapLineShift: case BLStatus_NeedLineShift: { @@ -994,7 +1027,6 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv } }while(stop.status != BLStatus_Finished); - buffer_measure_wrap_y(&state, params, 0.f); file_update_cursor_positions(models, file); } @@ -1747,7 +1779,7 @@ view_cursor_move(View *view, Full_Cursor cursor){ inline void view_cursor_move(View *view, i32 pos){ - Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos)); + Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), 0); view_cursor_move(view, cursor); } @@ -1761,13 +1793,13 @@ view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){ seek = seek_wrapped_xy(x, y, round_down); } - Full_Cursor cursor = view_compute_cursor(view, seek); + Full_Cursor cursor = view_compute_cursor(view, seek, 0); view_cursor_move(view, cursor); } inline void view_cursor_move(View *view, i32 line, i32 character){ - Full_Cursor cursor = view_compute_cursor(view, seek_line_char(line, character)); + Full_Cursor cursor = view_compute_cursor(view, seek_line_char(line, character), 0); view_cursor_move(view, cursor); } @@ -2025,7 +2057,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Assert(view->edit_pos); i32 cursor_pos = cursors[cursor_count++].pos; - Full_Cursor new_cursor = view_compute_cursor(view, seek_pos(cursor_pos)); + Full_Cursor new_cursor = view_compute_cursor(view, seek_pos(cursor_pos), 0); GUI_Scroll_Vars scroll = view->edit_pos->scroll; @@ -2034,7 +2066,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, if (view->edit_pos->scroll_i != new_scroll_i){ view->edit_pos->scroll_i = new_scroll_i; - Full_Cursor temp_cursor = view_compute_cursor(view, seek_pos(view->edit_pos->scroll_i)); + Full_Cursor temp_cursor = view_compute_cursor(view, seek_pos(view->edit_pos->scroll_i), 0); f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height); f32 y_position = temp_cursor.wrapped_y; @@ -4882,10 +4914,10 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target Full_Cursor render_cursor; if (!file->settings.unwrapped_lines){ - render_cursor = view_compute_cursor(view, seek_wrapped_xy(0, scroll_y, 0)); + render_cursor = view_compute_cursor(view, seek_wrapped_xy(0, scroll_y, 0), 1); } else{ - render_cursor = view_compute_cursor(view, seek_unwrapped_xy(0, scroll_y, 0)); + render_cursor = view_compute_cursor(view, seek_unwrapped_xy(0, scroll_y, 0), 1); } view->edit_pos->scroll_i = render_cursor.pos; @@ -4921,9 +4953,24 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target } f32 line_shift = 0.f; + b32 do_wrap = 0; + i32 wrap_unit_end = 0; + do{ - stop = buffer_render_data(&state, params, line_shift); + stop = buffer_render_data(&state, params, line_shift, do_wrap, wrap_unit_end); switch (stop.status){ + case BLStatus_NeedWrapDetermination: + { + i32 rounded_pos = stop.pos - (stop.pos%11); + if ((rounded_pos % 2) == 1){ + do_wrap = 1; + } + else{ + do_wrap = 0; + } + wrap_unit_end = rounded_pos + 11; + }break; + case BLStatus_NeedWrapLineShift: case BLStatus_NeedLineShift: { diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 3b0c8ad5..24fc21ce 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -179,6 +179,21 @@ buffer_measure_character_starts(Buffer_Type *buffer, i32 *character_starts, i32 assert_4tech(line_index-1 == buffer->line_count); } +enum{ + BLStatus_Finished, + BLStatus_NeedWrapLineShift, + BLStatus_NeedLineShift, + BLStatus_NeedWrapDetermination, +}; + +struct Buffer_Layout_Stop{ + u32 status; + i32 line_index; + i32 wrap_line_index; + i32 pos; + f32 x; +}; + struct Buffer_Measure_Wrap_Params{ Buffer_Type *buffer; i32 *wrap_line_index; @@ -191,6 +206,8 @@ struct Buffer_Measure_Wrap_State{ Buffer_Stream_Type stream; i32 i; i32 size; + b32 still_looping; + i32 line_index; i32 current_wrap_index; @@ -198,8 +215,9 @@ struct Buffer_Measure_Wrap_State{ f32 x; b32 skipping_whitespace; - - b32 still_looping; + i32 wrap_unit_end; + b32 did_wrap; + b32 first_of_the_line; u8 ch; @@ -211,38 +229,21 @@ struct Buffer_Measure_Wrap_State{ #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } -enum{ - BLStatus_Finished, - BLStatus_NeedWrapLineShift, - BLStatus_NeedLineShift -}; - -struct Buffer_Layout_Stop{ - u32 status; - i32 line_index; - i32 wrap_line_index; -}; - -struct Buffer_Layout_Measure_Stop{ - u32 status; - i32 line_index; - i32 wrap_line_index; - i32 pos; -}; - -internal_4tech Buffer_Layout_Measure_Stop -buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Params params, f32 line_shift){ +internal_4tech Buffer_Layout_Stop +buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Params params, + f32 line_shift, b32 do_wrap, i32 wrap_unit_end){ Buffer_Measure_Wrap_State S = *S_ptr; - Buffer_Layout_Measure_Stop S_stop; - - S.size = buffer_size(params.buffer); + Buffer_Layout_Stop S_stop; switch (S.__pc__){ DrCase(1); DrCase(2); DrCase(3); + DrCase(4); } + S.size = buffer_size(params.buffer); + if (params.virtual_white){ S_stop.status = BLStatus_NeedLineShift; S_stop.line_index = S.line_index; @@ -258,6 +259,7 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para S.skipping_whitespace = 1; } + S.first_of_the_line = 1; if (buffer_stringify_loop(&S.stream, params.buffer, S.i, S.size)){ S.still_looping = 0; do{ @@ -268,10 +270,10 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para params.wrap_line_index[S.line_index++] = S.current_wrap_index; if (params.virtual_white){ - S_stop.status = BLStatus_NeedLineShift; - S_stop.line_index = S.line_index - 1; + S_stop.status = BLStatus_NeedLineShift; + S_stop.line_index = S.line_index - 1; S_stop.wrap_line_index = S.current_wrap_index; - S_stop.pos = S.i+1; + S_stop.pos = S.i+1; DrYield(2, S_stop); } @@ -280,6 +282,7 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para if (params.virtual_white){ S.skipping_whitespace = 1; } + S.first_of_the_line = 1; } else{ if (S.ch != ' ' && S.ch != '\t'){ @@ -288,22 +291,39 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para if (!S.skipping_whitespace){ S.current_adv = params.adv[S.ch]; - if (S.x + S.current_adv > params.width){ - ++S.current_wrap_index; + + S.did_wrap = 0; + if (S.i >= S.wrap_unit_end){ + S_stop.status = BLStatus_NeedWrapDetermination; + S_stop.line_index = S.line_index - 1; + S_stop.wrap_line_index = S.current_wrap_index; + S_stop.pos = S.i; + S_stop.x = S.x; + DrYield(4, S_stop); - if (params.virtual_white){ - S_stop.status = BLStatus_NeedWrapLineShift; - S_stop.line_index = S.line_index - 1; - S_stop.wrap_line_index = S.current_wrap_index; - S_stop.pos = S.i+1; - DrYield(3, S_stop); + S.wrap_unit_end = wrap_unit_end; + + if (do_wrap && !S.first_of_the_line){ + S.did_wrap = 1; + ++S.current_wrap_index; + + if (params.virtual_white){ + S_stop.status = BLStatus_NeedWrapLineShift; + S_stop.line_index = S.line_index - 1; + S_stop.wrap_line_index = S.current_wrap_index; + S_stop.pos = S.i+1; + DrYield(3, S_stop); + } + + S.x = line_shift + S.current_adv; } - - S.x = line_shift + S.current_adv; } - else{ + + if (!S.did_wrap){ S.x += S.current_adv; } + + S.first_of_the_line = 0; } } } @@ -721,31 +741,37 @@ struct Buffer_Cursor_Seek_Params{ i32 *wrap_line_index; i32 *character_starts; b32 virtual_white; + b32 return_hint; + Full_Cursor *cursor_out; }; struct Buffer_Cursor_Seek_State{ - Full_Cursor cursor; + Full_Cursor next_cursor; + Full_Cursor this_cursor; Full_Cursor prev_cursor; + Buffer_Stream_Type stream; b32 still_looping; i32 i; i32 size; - b32 xy_seek; + i32 wrap_unit_end; + b32 first_of_the_line; + b32 xy_seek; f32 ch_width; u8 ch; i32 __pc__; }; -// duff-routine defines +// dialogical-routine defines #define DrCase(PC) case PC: goto resumespot_##PC #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } internal_4tech Buffer_Layout_Stop buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params params, - f32 line_shift, Full_Cursor *cursor_out){ + f32 line_shift, b32 do_wrap, i32 wrap_unit_end){ Buffer_Cursor_Seek_State S = *S_ptr; Buffer_Layout_Stop S_stop; @@ -753,6 +779,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa DrCase(1); DrCase(2); DrCase(3); + DrCase(4); } S.xy_seek = (params.seek.type == buffer_seek_wrapped_xy || params.seek.type == buffer_seek_unwrapped_xy); @@ -821,15 +848,15 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa // Build the cursor hint { - S.cursor.pos = params.buffer->line_starts[line_index]; - S.cursor.character_pos = params.character_starts[line_index]; - S.cursor.line = line_index + 1; - S.cursor.character = 1; - S.cursor.wrap_line = params.wrap_line_index[line_index] + 1; - S.cursor.unwrapped_y = (f32)(line_index * params.font_height); - S.cursor.unwrapped_x = 0; - S.cursor.wrapped_y = (f32)(params.wrap_line_index[line_index] * params.font_height); - S.cursor.wrapped_x = 0; + S.next_cursor.pos = params.buffer->line_starts[line_index]; + S.next_cursor.character_pos = params.character_starts[line_index]; + S.next_cursor.line = line_index + 1; + S.next_cursor.character = 1; + S.next_cursor.wrap_line = params.wrap_line_index[line_index] + 1; + S.next_cursor.unwrapped_y = (f32)(line_index * params.font_height); + S.next_cursor.unwrapped_x = 0; + S.next_cursor.wrapped_y = (f32)(params.wrap_line_index[line_index] * params.font_height); + S.next_cursor.wrapped_x = 0; } // Get the initial line shift. @@ -837,25 +864,25 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa // non-virtual character of the line. if (params.virtual_white){ S_stop.status = BLStatus_NeedLineShift; - S_stop.line_index = S.cursor.line-1; - S_stop.wrap_line_index = S.cursor.wrap_line-1; + S_stop.line_index = S.next_cursor.line-1; + S_stop.wrap_line_index = S.next_cursor.wrap_line-1; DrYield(1, S_stop); - S.cursor.unwrapped_x += line_shift; - S.cursor.wrapped_x += line_shift; + S.next_cursor.unwrapped_x += line_shift; + S.next_cursor.wrapped_x += line_shift; S.stream.use_termination_character = 1; S.stream.terminator = '\n'; - if (buffer_stringify_loop(&S.stream, params.buffer, S.cursor.pos, S.size)){ + if (buffer_stringify_loop(&S.stream, params.buffer, S.next_cursor.pos, S.size)){ do{ - for (; S.cursor.pos < S.stream.end; ++S.cursor.pos){ - S.ch = (u8)S.stream.data[S.cursor.pos]; + for (; S.next_cursor.pos < S.stream.end; ++S.next_cursor.pos){ + S.ch = (u8)S.stream.data[S.next_cursor.pos]; if (S.ch != ' ' && S.ch != '\t'){ goto double_break_vwhite; } else{ - ++S.cursor.character; + ++S.next_cursor.character; } } S.still_looping = buffer_stringify_next(&S.stream); @@ -865,170 +892,192 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa double_break_vwhite:; } + // If the user just wants the hint, return that now. + if (params.return_hint){ + *params.cursor_out = S.next_cursor; + S_stop.status = BLStatus_Finished; + DrReturn(S_stop); + } + // If we are already passed the point we want to be at, then just take this. + S.this_cursor = S.next_cursor; switch (params.seek.type){ case buffer_seek_pos: { - if (S.cursor.pos >= params.seek.pos){ + if (S.next_cursor.pos >= params.seek.pos){ goto buffer_cursor_seek_end; } }break; case buffer_seek_character_pos: { - if (S.cursor.character_pos >= params.seek.pos){ + if (S.next_cursor.character_pos >= params.seek.pos){ goto buffer_cursor_seek_end; } }break; case buffer_seek_line_char: { - if ((S.cursor.line == params.seek.line && - S.cursor.character >= params.seek.character) || - S.cursor.line > params.seek.line){ + if ((S.next_cursor.line == params.seek.line && + S.next_cursor.character >= params.seek.character) || + S.next_cursor.line > params.seek.line){ goto buffer_cursor_seek_end; } }break; case buffer_seek_unwrapped_xy: { - if (S.cursor.unwrapped_y > params.seek.y){ + if (S.next_cursor.unwrapped_y > params.seek.y){ goto buffer_cursor_seek_end; } }break; case buffer_seek_wrapped_xy: { - if (S.cursor.wrapped_y > params.seek.y){ + if (S.next_cursor.wrapped_y > params.seek.y){ goto buffer_cursor_seek_end; } }break; } // Main seek loop - S.i = S.cursor.pos; + S.i = S.next_cursor.pos; S.stream = null_buffer_stream; S.stream.use_termination_character = 1; S.stream.terminator = 0; + + S.first_of_the_line = 1; if (buffer_stringify_loop(&S.stream, params.buffer, S.i, S.size)){ S.still_looping = 0; do{ for (; S.i < S.stream.end; ++S.i){ S.ch = (u8)S.stream.data[S.i]; - S.prev_cursor = S.cursor; + S.prev_cursor = S.this_cursor; + S.this_cursor = S.next_cursor; switch (S.ch){ case '\n': { - ++S.cursor.character_pos; - ++S.cursor.line; - ++S.cursor.wrap_line; - S.cursor.unwrapped_y += params.font_height; - S.cursor.wrapped_y += params.font_height; - S.cursor.character = 1; - S.cursor.unwrapped_x = 0; + ++S.next_cursor.character_pos; + ++S.next_cursor.line; + ++S.next_cursor.wrap_line; + S.next_cursor.unwrapped_y += params.font_height; + S.next_cursor.wrapped_y += params.font_height; + S.next_cursor.character = 1; + S.next_cursor.unwrapped_x = 0; if (params.virtual_white){ S_stop.status = BLStatus_NeedLineShift; - S_stop.line_index = S.cursor.line-1; - S_stop.wrap_line_index = S.cursor.wrap_line-1; + S_stop.line_index = S.next_cursor.line-1; + S_stop.wrap_line_index = S.next_cursor.wrap_line-1; DrYield(2, S_stop); } - S.cursor.wrapped_x = line_shift; + S.next_cursor.wrapped_x = line_shift; + S.first_of_the_line = 1; }break; default: { S.ch_width = params.adv[S.ch]; - if (S.cursor.wrapped_x + S.ch_width > params.width){ - S.cursor.wrapped_y += params.font_height; + if (S.i >= S.wrap_unit_end){ + S_stop.status = BLStatus_NeedWrapDetermination; + S_stop.line_index = S.next_cursor.line-1; + S_stop.wrap_line_index = S.next_cursor.wrap_line-1; + S_stop.pos = S.i; + S_stop.x = S.next_cursor.wrapped_x; + DrYield(4, S_stop); - ++S.cursor.wrap_line; - if (params.virtual_white){ - S_stop.status = BLStatus_NeedWrapLineShift; - S_stop.line_index = S.cursor.line-1; - S_stop.wrap_line_index = S.cursor.wrap_line-1; - DrYield(3, S_stop); + S.wrap_unit_end = wrap_unit_end; + + if (do_wrap && !S.first_of_the_line){ + S.next_cursor.wrapped_y += params.font_height; + + ++S.next_cursor.wrap_line; + if (params.virtual_white){ + S_stop.status = BLStatus_NeedWrapLineShift; + S_stop.line_index = S.next_cursor.line-1; + S_stop.wrap_line_index = S.next_cursor.wrap_line-1; + DrYield(3, S_stop); + } + + S.next_cursor.wrapped_x = line_shift; + S.this_cursor = S.next_cursor; } - - S.cursor.wrapped_x = line_shift; - S.prev_cursor = S.cursor; } - ++S.cursor.character_pos; - ++S.cursor.character; - S.cursor.unwrapped_x += S.ch_width; - S.cursor.wrapped_x += S.ch_width; + ++S.next_cursor.character_pos; + ++S.next_cursor.character; + S.next_cursor.unwrapped_x += S.ch_width; + S.next_cursor.wrapped_x += S.ch_width; + + S.first_of_the_line = 0; }break; } - ++S.cursor.pos; + ++S.next_cursor.pos; - if (S.cursor.pos > S.size){ - S.cursor = S.prev_cursor; + if (S.next_cursor.pos > S.size){ goto buffer_cursor_seek_end; } - f32 x = 0, px = 0, y = 0; + f32 x = 0, px = 0, y = 0, py = 0; switch (params.seek.type){ case buffer_seek_pos: - if (S.cursor.pos > params.seek.pos){ - S.cursor = S.prev_cursor; + if (S.this_cursor.pos >= params.seek.pos){ goto buffer_cursor_seek_end; }break; case buffer_seek_character_pos: - { - if (S.cursor.character_pos > params.seek.pos){ - S.cursor = S.prev_cursor; - goto buffer_cursor_seek_end; - }break; + if (S.this_cursor.character_pos >= params.seek.pos){ + goto buffer_cursor_seek_end; }break; case buffer_seek_wrapped_xy: { - x = S.cursor.wrapped_x; px = S.prev_cursor.wrapped_x; - y = S.cursor.wrapped_y; + x = S.this_cursor.wrapped_x; + px = S.prev_cursor.wrapped_x; + y = S.this_cursor.wrapped_y; + py = S.prev_cursor.wrapped_y; }break; case buffer_seek_unwrapped_xy: { - x = S.cursor.unwrapped_x; px = S.prev_cursor.unwrapped_x; - y = S.cursor.unwrapped_y; + x = S.this_cursor.unwrapped_x; + px = S.prev_cursor.unwrapped_x; + y = S.this_cursor.unwrapped_y; + py = S.prev_cursor.wrapped_y; }break; case buffer_seek_line_char: - if (S.cursor.line == params.seek.line && S.cursor.character >= params.seek.character){ + if (S.this_cursor.line == params.seek.line && S.this_cursor.character >= params.seek.character){ goto buffer_cursor_seek_end; } - else if (S.cursor.line > params.seek.line){ - S.cursor = S.prev_cursor; + else if (S.this_cursor.line > params.seek.line){ + S.this_cursor = S.prev_cursor; goto buffer_cursor_seek_end; }break; } if (S.xy_seek){ if (y > params.seek.y){ - S.cursor = S.prev_cursor; + S.this_cursor = S.prev_cursor; goto buffer_cursor_seek_end; } if (y > params.seek.y - params.font_height && x >= params.seek.x){ if (!params.seek.round_down){ - if (S.ch != '\n' && (params.seek.x - px) < (x - params.seek.x)){ - S.cursor = S.prev_cursor; + if (py >= y && S.ch != '\n' && (params.seek.x - px) < (x - params.seek.x)){ + S.this_cursor = S.prev_cursor; } goto buffer_cursor_seek_end; } - if (x > params.seek.x){ - S.cursor = S.prev_cursor; - goto buffer_cursor_seek_end; - } + S.this_cursor = S.prev_cursor; + goto buffer_cursor_seek_end; } } } @@ -1039,7 +1088,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa InvalidCodePath; buffer_cursor_seek_end:; - *cursor_out = S.cursor; + *params.cursor_out = S.this_cursor; S_stop.status = BLStatus_Finished; DrReturn(S_stop); } @@ -1177,6 +1226,8 @@ struct Buffer_Render_State{ i32 line; i32 wrap_line; b32 skipping_whitespace; + b32 first_of_the_line; + i32 wrap_unit_end; i32 __pc__; }; @@ -1187,7 +1238,8 @@ struct Buffer_Render_State{ #define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } internal_4tech Buffer_Layout_Stop -buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 line_shift){ +buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, + f32 line_shift, b32 do_wrap, i32 wrap_unit_end){ Buffer_Render_State S = *S_ptr; Buffer_Layout_Stop S_stop; @@ -1208,6 +1260,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 DrCase(1); DrCase(2); DrCase(3); + DrCase(4); } S.line = params.start_cursor.line - 1; @@ -1232,6 +1285,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.skipping_whitespace = 1; } + S.first_of_the_line = 1; S.i = params.start_cursor.pos; if (buffer_stringify_loop(&S.stream, params.buffer, S.i, size)){ do{ @@ -1239,21 +1293,34 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.ch = (u8)S.stream.data[S.i]; S.ch_width = params.adv[S.ch]; - if (S.ch_width + S.write.x > params.width + shift_x && S.ch != '\n' && params.wrapped){ - if (params.virtual_white){ - S_stop.status = BLStatus_NeedWrapLineShift; - S_stop.line_index = S.line; - S_stop.wrap_line_index = S.wrap_line + 1; - DrYield(2, S_stop); + if (S.ch != '\n' && S.i >= S.wrap_unit_end){ + S_stop.status = BLStatus_NeedWrapDetermination; + S_stop.line_index = S.line; + S_stop.wrap_line_index = S.wrap_line; + S_stop.pos = S.i; + S_stop.x = S.write.x - shift_x; + DrYield(4, S_stop); + + S.wrap_unit_end = wrap_unit_end; + + if (do_wrap && !S.first_of_the_line){ + if (params.virtual_white){ + S_stop.status = BLStatus_NeedWrapLineShift; + S_stop.line_index = S.line; + S_stop.wrap_line_index = S.wrap_line + 1; + DrYield(2, S_stop); + } + + ++S.wrap_line; + + if (params.wrapped){ + S.write.x = shift_x + line_shift; + S.write.y += params.font_height; + } } - - ++S.wrap_line; - - S.write.x = shift_x + line_shift; - S.write.y += params.font_height; } - if (S.write.y > params.height + shift_y){ + if (S.write.y > params.height + params.port_y){ goto buffer_get_render_data_end; } @@ -1262,6 +1329,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } if (!S.skipping_whitespace){ + S.first_of_the_line = 0; switch (S.ch){ case '\n': if (S.write.item < item_end){ @@ -1281,6 +1349,8 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.x = shift_x + line_shift; S.write.y += params.font_height; + + S.first_of_the_line = 1; } break; @@ -1334,10 +1404,6 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 break; } } - - if (S.write.y > params.height + shift_y){ - goto buffer_get_render_data_end; - } } S.still_looping = buffer_stringify_next(&S.stream); }while(S.still_looping); diff --git a/buildsuper.bat b/buildsuper.bat index 45c02c1f..e8f4d306 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -7,7 +7,7 @@ REM SET clset=64 SET SRC=%1 if "%SRC%" == "" SET SRC=4coder_default_bindings.cpp -SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX +SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4457 /WX SET OPTS=%OPTS% /GR- /nologo /FC SET DEBUG=/Zi SET BUILD_DLL=/LD /link /INCREMENTAL:NO /OPT:REF