basic apparent character positioning working
parent
7b66fad3b8
commit
0da0013df6
|
@ -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>§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>§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>§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>§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>§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.
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue