basic apparent character positioning working

master
Allen Webster 2016-09-24 20:13:24 -04:00
parent 7b66fad3b8
commit 0da0013df6
6 changed files with 131 additions and 85 deletions

View File

@ -181,10 +181,10 @@ for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_
and keeping the preferred x.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>x</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The x coordinate for xy type seeks.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>y</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The y coordinate for xy type seeks.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>line</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The line number of a line-character type seek.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The character number of a line-character type seek.<br><br></div></div></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#Buffer_Seek_Type_doc'>Buffer_Seek_Type</a></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr><div id='Full_Cursor_doc' style='margin-bottom: 1cm;'><h4>&sect;3.4.35: Full_Cursor</h4><div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Full_Cursor {<br><div style='margin-left: 8mm;'>int32_t pos;<br>int32_t character_pos;<br>int32_t line;<br>int32_t character;<br>float unwrapped_x;<br>float unwrapped_y;<br>float wrapped_x;<br>float wrapped_y;<br></div>};<br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Full_Cursor describes the position of a cursor in every buffer
coordinate system supported by 4coder. This cursor type requires that
the buffer is associated with a view to give the x/y values meaning.<br><br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>pos</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in absolute byte index positioning.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character_pos</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in apparent character index positioning.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>line</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the line where the cursor is located. This field is one based.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the character from the beginninf of the line
where the cursor is located. This field is one based.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>unwrapped_x</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the x position measured with unwrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>unwrapped_y</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the y position measured with unwrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>wrapped_x</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the x position measured with wrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>wrapped_y</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the y position measured with wrapped lines.<br><br></div></div></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr><div id='Partial_Cursor_doc' style='margin-bottom: 1cm;'><h4>&sect;3.4.36: Partial_Cursor</h4><div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Partial_Cursor {<br><div style='margin-left: 8mm;'>int32_t pos;<br>int32_t character_pos;<br>int32_t line;<br>int32_t character;<br></div>};<br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Partial_Cursor describes the position of a cursor in all of
where the cursor is located. This field is one based.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>unwrapped_x</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the x position measured with unwrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>unwrapped_y</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the y position measured with unwrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>wrapped_x</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the x position measured with wrapped lines.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>wrapped_y</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the y position measured with wrapped lines.<br><br></div></div></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr><div id='Partial_Cursor_doc' style='margin-bottom: 1cm;'><h4>&sect;3.4.36: Partial_Cursor</h4><div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Partial_Cursor {<br><div style='margin-left: 8mm;'>int32_t pos;<br>int32_t line;<br>int32_t character;<br></div>};<br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Partial_Cursor describes the position of a cursor in all of
the coordinate systems that a invariant to the View. In other words
the coordinate systems available here can be used on a buffer that is
not currently associated with a View.<br><br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>pos</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in absolute byte index positioning.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character_pos</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in apparent character index positioning.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>line</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the character from the beginninf of the line
not currently associated with a View.<br><br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>pos</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the cursor's position in absolute byte index positioning.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>line</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the character from the beginninf of the line
where the cursor is located. This field is one based.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>character</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field contains the number of the column where the cursor is located. This field is one based.<br><br></div></div></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>See Also</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'><a href='#4coder_Buffer_Positioning_System_doc'>4coder_Buffer_Positioning_System</a></div></div><hr><div id='Buffer_Edit_doc' style='margin-bottom: 1cm;'><h4>&sect;3.4.37: Buffer_Edit</h4><div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Edit {<br><div style='margin-left: 8mm;'>int32_t str_start;<br>int32_t len;<br>int32_t start;<br>int32_t end;<br></div>};<br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Buffer_Edit describes a range of a buffer and string to replace that range.
A Buffer_Edit has to be paired with a string that contains the actual text that
will be replaced into the buffer.<br><br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>str_start</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The str_start field specifies the first character in the accompanying string that corresponds with this edit.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>len</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The len field specifies the length of the string being written into the buffer.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>start</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The start field specifies the start of the range in the buffer to replace in absolute position.<br><br></div></div></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>end</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>The end field specifies one past the end of the range in the buffer to replace in absolute position.<br><br></div></div></div></div><hr><div id='Buffer_Summary_doc' style='margin-bottom: 1cm;'><h4>&sect;3.4.38: Buffer_Summary</h4><div style='font-family: "Courier New", Courier, monospace; text-align: left; margin-top: 3mm; margin-bottom: 3mm; font-size: .95em; background: #DFDFDF; padding: 0.25em;'>struct Buffer_Summary {<br><div style='margin-left: 8mm;'>bool32 exists;<br>bool32 ready;<br>int32_t buffer_id;<br>Access_Flag lock_flags;<br>int32_t size;<br>int32_t line_count;<br>char * file_name;<br>int32_t file_name_len;<br>char * buffer_name;<br>int32_t buffer_name_len;<br>Dirty_State dirty;<br>bool32 is_lexed;<br>bool32 tokens_are_ready;<br>int32_t map_id;<br>bool32 unwrapped_lines;<br></div>};<br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Description</i></b></div><div style='margin-left: 5mm; margin-right: 5mm;'>Buffer_Summary acts as a handle to a buffer and describes the state of the buffer.<br><br></div><div style='margin-top: 3mm; margin-bottom: 3mm; color: #309030;'><b><i>Fields</i></b></div><div><div style='font-family: "Courier New", Courier, monospace; text-align: left;'><span style='font-weight: 600;'>exists</span></div><div style='margin-bottom: 6mm;'><div style='margin-left: 5mm; margin-right: 5mm;'>This field indicates whether the Buffer_Summary describes a buffer that is open in 4coder.

View File

@ -63,13 +63,13 @@ view_open_file(Application_Links *app,
char *filename,
int32_t filename_len,
int32_t never_new){
int32_t result = false;
int32_t result = 0;
if (view){
Buffer_Summary buffer = {0};
if (open_file(app, &buffer, filename, filename_len, false, never_new)){
view_set_buffer(app, view, buffer.buffer_id, 0);
result = true;
result = 1;
}
}
@ -744,8 +744,8 @@ CUSTOM_COMMAND_SIG(delete_char){
int32_t start = view.cursor.pos;
Partial_Cursor cursor;
buffer_compute_cursor(app, &buffer, seek_character_pos(view.cursor.character_pos+1), &cursor);
Full_Cursor cursor;
view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos+1), &cursor);
int32_t end = cursor.pos;
if (0 <= start && start < buffer.size){
@ -760,8 +760,8 @@ CUSTOM_COMMAND_SIG(backspace_char){
int32_t end = view.cursor.pos;
Partial_Cursor cursor;
buffer_compute_cursor(app, &buffer, seek_character_pos(view.cursor.character_pos-1), &cursor);
Full_Cursor cursor;
view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos-1), &cursor);
int32_t start = cursor.pos;
if (0 < end && end <= buffer.size){
@ -858,10 +858,7 @@ CUSTOM_COMMAND_SIG(click_set_cursor){
Mouse_State mouse = get_mouse_state(app);
float rx = 0, ry = 0;
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
view_set_cursor(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines),
true);
view_set_cursor(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines), 1);
}
}
@ -872,10 +869,7 @@ CUSTOM_COMMAND_SIG(click_set_mark){
Mouse_State mouse = get_mouse_state(app);
float rx = 0, ry = 0;
if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){
view_set_mark(app, &view,
seek_xy(rx, ry, true,
view.unwrapped_lines)
);
view_set_mark(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines));
}
}
@ -887,9 +881,7 @@ move_vertical(Application_Links *app, float line_multiplier){
float new_y = get_view_y(view) + line_multiplier*view.line_height;
float x = view.preferred_x;
view_set_cursor(app, &view,
seek_xy(x, new_y, false, view.unwrapped_lines),
false);
view_set_cursor(app, &view, seek_xy(x, new_y, 0, view.unwrapped_lines), 0);
}
CUSTOM_COMMAND_SIG(move_up){

View File

@ -575,8 +575,6 @@ DOC_SEE(4coder_Buffer_Positioning_System) */
struct Partial_Cursor{
/* DOC(This field contains the cursor's position in absolute byte index positioning.) */
int32_t pos;
/* DOC(This field contains the cursor's position in apparent character index positioning.) */
int32_t character_pos;
/* DOC(This field contains the number of the character from the beginninf of the line
where the cursor is located. This field is one based.) */
int32_t line;

View File

@ -9,6 +9,8 @@
// TOP
#define VWHITE 1
internal i32
get_or_add_map_index(Models *models, i32 mapid){
i32 result;
@ -391,17 +393,18 @@ view_compute_cursor(View *view, Buffer_Seek seek){
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
Buffer_Cursor_Seek_Params params;
params.buffer = &file->state.buffer;
params.seek = seek;
params.width = view_file_display_width(view);
params.font_height = (f32)font->height;
params.adv = font->advance_data;
params.wraps = file->state.wraps;
params.virtual_white = 0;
params.buffer = &file->state.buffer;
params.seek = seek;
params.width = view_file_display_width(view);
params.font_height = (f32)font->height;
params.adv = font->advance_data;
params.wraps = file->state.wraps;
params.character_starts = file->state.character_starts;
params.virtual_white = VWHITE;
Buffer_Cursor_Seek_State state = {0};
Full_Cursor result;
Buffer_Layout_Stop stop;
Full_Cursor result = {0};
Buffer_Layout_Stop stop = {0};
f32 edge_tolerance = 50.f;
if (edge_tolerance > params.width){
@ -930,7 +933,7 @@ file_allocate_character_starts_as_needed(General_Memory *general, Editing_File *
internal void
file_measure_character_starts(Models *models, Editing_File *file){
file_allocate_character_starts_as_needed(&models->mem.general, file);
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, 1);
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, VWHITE);
file_update_cursor_positions(models, file);
}
@ -2056,7 +2059,7 @@ file_do_single_edit(System_Functions *system,
// TODO(allen): write the remeasurement version
file_allocate_character_starts_as_needed(general, file);
buffer_measure_character_starts(buffer, file->state.character_starts, 0, 1);
buffer_measure_character_starts(buffer, file->state.character_starts, 0, VWHITE);
file_allocate_wraps_as_needed(general, file);
buffer_remeasure_wrap_y(buffer, line_start, line_end, line_shift,
@ -4852,10 +4855,10 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
params.wrapped = wrapped;
params.font_height = (f32)line_height;
params.adv = advance_data;
params.virtual_white = 0;
params.virtual_white = VWHITE;
Buffer_Render_State state = {0};
Buffer_Layout_Stop stop;
Buffer_Layout_Stop stop = {0};
f32 edge_tolerance = 50.f;
if (edge_tolerance > params.width){

View File

@ -140,8 +140,14 @@ buffer_measure_character_starts(Buffer_Type *buffer, i32 *character_starts, i32
i32 line_index = 0;
i32 character_index = 0;
b32 skipping_whitespace = 0;
character_starts[line_index++] = character_index;
if (virtual_whitespace){
skipping_whitespace = 1;
}
if (buffer_stringify_loop(&stream, buffer, i, size)){
b32 still_looping = 0;
do{
@ -150,9 +156,18 @@ buffer_measure_character_starts(Buffer_Type *buffer, i32 *character_starts, i32
if (ch == '\n'){
++character_index;
character_starts[line_index++] = character_index;
if (virtual_whitespace){
skipping_whitespace = 1;
}
}
else{
++character_index;
if (ch != ' ' && ch != '\t'){
skipping_whitespace = 0;
}
if (!skipping_whitespace){
++character_index;
}
}
}
still_looping = buffer_stringify_next(&stream);
@ -403,25 +418,54 @@ buffer_get_line_index(Buffer_Type *buffer, i32 pos){
return(result);
}
// TODO(allen): Try to merge this with the other line start binary search.
internal_4tech i32
buffer_get_line_index_from_wrapped_y(f32 *wraps, f32 y, f32 font_height, i32 l_bound, i32 u_bound){
i32 start, end, i, result;
start = l_bound;
end = u_bound;
buffer_get_line_index_from_character_pos(i32 *character_starts, i32 pos, i32 l_bound, i32 u_bound){
i32 start = l_bound, end = u_bound;
i32 i = 0;
for (;;){
i = (start + end) / 2;
if (wraps[i]+font_height <= y) start = i;
else if (wraps[i] > y) end = i;
i = (start + end) >> 1;
if (character_starts[i] < pos){
start = i;
}
else if (character_starts[i] > pos){
end = i;
}
else{
result = i;
start = i;
break;
}
if (start >= end - 1){
result = start;
assert_4tech(start < end);
if (start == end - 1){
break;
}
}
return(result);
return(start);
}
internal_4tech i32
buffer_get_line_index_from_wrapped_y(f32 *wraps, f32 y, f32 font_height, i32 l_bound, i32 u_bound){
i32 start = l_bound, end = u_bound;
i32 i = 0;
for (;;){
i = (start + end) / 2;
if (wraps[i]+font_height <= y){
start = i;
}
else if (wraps[i] > y){
end = i;
}
else{
break;
}
if (start >= end - 1){
i = start;
break;
}
}
return(i);
}
internal_4tech Partial_Cursor
@ -481,6 +525,7 @@ struct Buffer_Cursor_Seek_Params{
f32 font_height;
f32 *adv;
f32 *wraps;
i32 *character_starts;
b32 virtual_white;
};
@ -528,6 +573,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
S.size = buffer_size(params.buffer);
// Get cursor hint
i32 line_index = 0;
switch (params.seek.type){
case buffer_seek_pos:
{
@ -538,52 +584,67 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
params.seek.pos = 0;
}
i32 line_index = buffer_get_line_index_range(params.buffer, params.seek.pos, 0, params.buffer->line_count);
S.cursor = make_cursor_hint(line_index, params.buffer->line_starts, params.wraps, params.font_height);
line_index = buffer_get_line_index(params.buffer, params.seek.pos);
}break;
case buffer_seek_character_pos:
{
NotImplemented;
i32 line_count = params.buffer->line_count;
i32 max_character = params.character_starts[line_count] - 1;
if (params.seek.pos > max_character){
params.seek.pos = max_character;
}
if (params.seek.pos < 0){
params.seek.pos = 0;
}
line_index = buffer_get_line_index_from_character_pos(params.character_starts, params.seek.pos,
0, params.buffer->line_count);
}break;
case buffer_seek_line_char:
{
i32 line_index = params.seek.line - 1;
line_index = params.seek.line - 1;
if (line_index >= params.buffer->line_count){
line_index = params.buffer->line_count - 1;
}
if (line_index < 0){
line_index = 0;
}
S.cursor = make_cursor_hint(line_index, params.buffer->line_starts, params.wraps, params.font_height);
}break;
case buffer_seek_unwrapped_xy:
{
i32 line_index = (i32)(params.seek.y / params.font_height);
line_index = (i32)(params.seek.y / params.font_height);
if (line_index >= params.buffer->line_count){
line_index = params.buffer->line_count - 1;
}
if (line_index < 0){
line_index = 0;
}
S.cursor = make_cursor_hint(line_index, params.buffer->line_starts, params.wraps, params.font_height);
}break;
case buffer_seek_wrapped_xy:
{
i32 line_index = buffer_get_line_index_from_wrapped_y(params.wraps, params.seek.y,
params.font_height, 0, params.buffer->line_count);
S.cursor = make_cursor_hint(line_index, params.buffer->line_starts, params.wraps, params.font_height);
line_index = buffer_get_line_index_from_wrapped_y(params.wraps, params.seek.y,
params.font_height, 0, params.buffer->line_count);
}break;
default: InvalidCodePath;
}
// 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.unwrapped_y = (f32)(line_index * params.font_height);
S.cursor.unwrapped_x = 0;
S.cursor.wrapped_y = params.wraps[line_index];
S.cursor.wrapped_x = 0;
}
// Get the initial line shift.
// Adjust the non-screen based coordinates to point to the first
// non-virtual character of the line.
@ -674,6 +735,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
switch (S.ch){
case '\n':
{
++S.cursor.character_pos;
++S.cursor.line;
S.cursor.unwrapped_y += params.font_height;
S.cursor.wrapped_y += params.font_height;
@ -714,6 +776,14 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
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;
}break;
case buffer_seek_wrapped_xy:
{
x = S.cursor.wrapped_x; px = S.prev_cursor.wrapped_x;

View File

@ -82,21 +82,9 @@ typedef struct Buffer_Batch_State{
i32 shift_total;
} Buffer_Batch_State;
inline_4tech Full_Cursor
make_cursor_hint(i32 line_index, i32 *starts, f32 *wrap_ys, f32 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);
}
typedef struct Cursor_With_Index{
i32 pos, index;
i32 pos;
i32 index;
} Cursor_With_Index;
inline_4tech void
@ -110,12 +98,9 @@ write_cursor_with_index(Cursor_With_Index *positions, i32 *count, i32 pos){
internal_4tech void
buffer_quick_sort_cursors(Cursor_With_Index *positions, i32 start, i32 pivot){
i32 i, mid;
i32 pivot_pos;
mid = start;
pivot_pos = positions[pivot].pos;
for (i = mid; i < pivot; ++i){
i32 mid = start;
i32 pivot_pos = positions[pivot].pos;
for (i32 i = mid; i < pivot; ++i){
if (positions[i].pos < pivot_pos){
CursorSwap__(positions[mid], positions[i]);
++mid;
@ -127,14 +112,12 @@ buffer_quick_sort_cursors(Cursor_With_Index *positions, i32 start, i32 pivot){
if (mid + 1 < pivot) buffer_quick_sort_cursors(positions, mid + 1, pivot);
}
// TODO(allen): Rewrite this without being a dumbass.
internal_4tech void
buffer_quick_unsort_cursors(Cursor_With_Index *positions, i32 start, i32 pivot){
i32 i, mid;
i32 pivot_index;
mid = start;
pivot_index = positions[pivot].index;
for (i = mid; i < pivot; ++i){
i32 mid = start;
i32 pivot_index = positions[pivot].index;
for (i32 i = mid; i < pivot; ++i){
if (positions[i].index < pivot_index){
CursorSwap__(positions[mid], positions[i]);
++mid;