Rough version of virtual whitespace up and running
This commit is contained in:
parent
46241c4450
commit
09acacd3cf
4
4ed.cpp
4
4ed.cpp
|
@ -264,9 +264,7 @@ models_init(void){
|
|||
}
|
||||
|
||||
internal void
|
||||
app_load_vtables(API_VTable_system *vtable_system,
|
||||
API_VTable_font *vtable_font,
|
||||
API_VTable_graphics *vtable_graphics){
|
||||
app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){
|
||||
system_api_read_vtable(vtable_system);
|
||||
font_api_read_vtable(vtable_font);
|
||||
graphics_api_read_vtable(vtable_graphics);
|
||||
|
|
|
@ -656,7 +656,7 @@ buffer_set_layout(Application_Links *app, Buffer_ID buffer_id, Layout_Function *
|
|||
}
|
||||
|
||||
api(custom) function b32
|
||||
file_clear_layout_cache(Application_Links *app, Buffer_ID buffer_id){
|
||||
buffer_clear_layout_cache(Application_Links *app, Buffer_ID buffer_id){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer_id);
|
||||
b32 result = false;
|
||||
|
@ -2844,7 +2844,7 @@ text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id){
|
|||
return(result);
|
||||
}
|
||||
|
||||
api(custom) function Interval_i64
|
||||
api(custom) function Range_i64
|
||||
text_layout_get_visible_range(Application_Links *app, Text_Layout_ID text_layout_id){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Range_i64 result = {};
|
||||
|
@ -2943,7 +2943,9 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id
|
|||
for (i32 i = 0; i < count; i += 1, item_ptr += 1){
|
||||
i64 index = item_ptr->index;
|
||||
if (index == pos){
|
||||
if (!HasFlag(item_ptr->flags, LayoutItemFlag_Ghost_Character)){
|
||||
result = rect_union(result, item_ptr->rect);
|
||||
}
|
||||
}
|
||||
else if (index > pos){
|
||||
break;
|
||||
|
|
|
@ -875,6 +875,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
i64 count = block->count;
|
||||
Layout_Item *item = block->items;
|
||||
for (i32 i = 0; i < count; i += 1, item += 1){
|
||||
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
||||
continue;
|
||||
}
|
||||
// NOTE(allen): This only works if we build layouts in y-sorted order.
|
||||
if (p.y < item->rect.y0){
|
||||
goto double_break;
|
||||
|
@ -901,6 +904,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
double_break:;
|
||||
}
|
||||
else{
|
||||
|
||||
if (p.x == max_f32){
|
||||
Layout_Item *prev_item = 0;
|
||||
for (Layout_Item_Block *block = list.first;
|
||||
|
@ -909,6 +913,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
i64 count = block->count;
|
||||
Layout_Item *item = block->items;
|
||||
for (i32 i = 0; i < count; i += 1, item += 1){
|
||||
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
||||
continue;
|
||||
}
|
||||
if (p.y < item->rect.y0){
|
||||
goto double_break_2;
|
||||
}
|
||||
|
@ -918,6 +925,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
double_break_2:;
|
||||
if (prev_item != 0){
|
||||
closest_match = prev_item->index;
|
||||
|
@ -934,6 +942,9 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
i64 count = block->count;
|
||||
Layout_Item *item = block->items;
|
||||
for (i32 i = 0; i < count; i += 1, item += 1){
|
||||
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
||||
continue;
|
||||
}
|
||||
// NOTE(allen): This only works if we build layouts in y-sorted order.
|
||||
if (p.y < item->rect.y0){
|
||||
goto double_break_3;
|
||||
|
@ -945,6 +956,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
goto double_break_3;
|
||||
}
|
||||
}
|
||||
|
||||
double_break_3:;
|
||||
if (closest_item != 0){
|
||||
closest_match = closest_item->index;
|
||||
|
@ -953,6 +965,7 @@ buffer_layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){
|
|||
closest_match = list.manifested_index_range.min;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return(closest_match);
|
||||
|
@ -980,6 +993,9 @@ buffer_layout_get_pos_at_character(Layout_Item_List list, i64 character){
|
|||
i64 prev_index = -1;
|
||||
Layout_Item *item = node->items;
|
||||
for (i64 i = 0; i < count; i += 1, item += 1){
|
||||
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
||||
continue;
|
||||
}
|
||||
if (prev_index != item->index){
|
||||
prev_index = item->index;
|
||||
if (relative_character_counter == relative_character){
|
||||
|
@ -1007,6 +1023,9 @@ buffer_layout_get_first_with_index(Layout_Item_List list, i64 index){
|
|||
i64 count = block->count;
|
||||
Layout_Item *item = block->items;
|
||||
for (i32 i = 0; i < count; i += 1, item += 1){
|
||||
if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
||||
continue;
|
||||
}
|
||||
if (item->index > index){
|
||||
result = prev;
|
||||
goto done;
|
||||
|
|
|
@ -72,7 +72,6 @@ code_index_unlock(void){
|
|||
function void
|
||||
code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){
|
||||
Code_Index_File_Storage *storage = 0;
|
||||
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file,
|
||||
buffer);
|
||||
if (lookup.found_match){
|
||||
|
@ -92,8 +91,7 @@ code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){
|
|||
|
||||
function void
|
||||
code_index_erase_file(Buffer_ID buffer){
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file,
|
||||
buffer);
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer);
|
||||
if (lookup.found_match){
|
||||
u64 val = 0;
|
||||
table_read(&global_code_index.buffer_to_index_file, lookup, &val);
|
||||
|
@ -107,12 +105,12 @@ code_index_erase_file(Buffer_ID buffer){
|
|||
function Code_Index_File*
|
||||
code_index_get_file(Buffer_ID buffer){
|
||||
Code_Index_File *result = 0;
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file,
|
||||
buffer);
|
||||
Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer);
|
||||
if (lookup.found_match){
|
||||
u64 val = 0;
|
||||
table_read(&global_code_index.buffer_to_index_file, lookup, &val);
|
||||
result = (Code_Index_File*)IntAsPtr(val);
|
||||
Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val);
|
||||
result = storage->file;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -124,7 +122,7 @@ code_index_get_nest(Code_Index_Nest_Ptr_Array *array, i64 pos){
|
|||
Code_Index_Nest **nest_ptrs = array->ptrs;
|
||||
for (i32 i = 0; i < count; i += 1){
|
||||
Code_Index_Nest *nest = nest_ptrs[i];
|
||||
if (nest->open.max <= pos && pos < nest->close.min){
|
||||
if (nest->open.max <= pos && pos <= nest->close.min){
|
||||
Code_Index_Nest *sub_nest =
|
||||
code_index_get_nest(&nest->nest_array, pos);
|
||||
if (sub_nest != 0){
|
||||
|
@ -149,6 +147,39 @@ code_index_get_nest(Code_Index_File *file, i64 pos){
|
|||
return(code_index_get_nest(&file->nest_array, pos));
|
||||
}
|
||||
|
||||
function void
|
||||
index_shift(i64 *ptr, Range_i64 old_range, umem new_size){
|
||||
i64 i = *ptr;
|
||||
if (old_range.min <= i && i < old_range.max){
|
||||
*ptr = old_range.first;
|
||||
}
|
||||
else if (old_range.max <= i){
|
||||
*ptr = i + new_size - (old_range.max - old_range.min);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
code_index_shift(Code_Index_Nest_Ptr_Array *array,
|
||||
Range_i64 old_range, umem new_size){
|
||||
i32 count = array->count;
|
||||
Code_Index_Nest **nest_ptr = array->ptrs;
|
||||
for (i32 i = 0; i < count; i += 1, nest_ptr += 1){
|
||||
Code_Index_Nest *nest = *nest_ptr;
|
||||
index_shift(&nest->open.min, old_range, new_size);
|
||||
index_shift(&nest->open.max, old_range, new_size);
|
||||
if (nest->is_closed){
|
||||
index_shift(&nest->close.min, old_range, new_size);
|
||||
index_shift(&nest->close.max, old_range, new_size);
|
||||
}
|
||||
code_index_shift(&nest->nest_array, old_range, new_size);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
code_index_shift(Code_Index_File *file, Range_i64 old_range, umem new_size){
|
||||
code_index_shift(&file->nest_array, old_range, new_size);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function void
|
||||
|
@ -164,8 +195,6 @@ generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *stat
|
|||
for (;token != 0 && !state->finished;){
|
||||
if (token->kind == TokenBaseKind_Comment){
|
||||
state->handle_comment(state->app, state->arena, index, token, state->contents);
|
||||
token_it_inc_non_whitespace(&state->it);
|
||||
token = token_it_read(&state->it);
|
||||
}
|
||||
else if (token->kind == TokenBaseKind_Whitespace){
|
||||
Range_i64 range = Ii64(token);
|
||||
|
@ -188,7 +217,8 @@ generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *stat
|
|||
}
|
||||
|
||||
function void
|
||||
generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens,
|
||||
generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents,
|
||||
Token_Array *tokens,
|
||||
Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){
|
||||
state->app = app;
|
||||
state->arena = arena;
|
||||
|
@ -199,8 +229,8 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content
|
|||
}
|
||||
|
||||
function Code_Index_Nest*
|
||||
generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
|
||||
i64 indentation);
|
||||
generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state,
|
||||
i64 indentation);
|
||||
|
||||
function Code_Index_Nest*
|
||||
generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
|
||||
|
@ -209,6 +239,7 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
|
|||
Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1);
|
||||
result->kind = CodeIndexNest_Scope;
|
||||
result->open = Ii64(token);
|
||||
result->close = Ii64(max_i64);
|
||||
result->file = index;
|
||||
|
||||
result->interior_indentation = indentation + 4;
|
||||
|
@ -229,8 +260,8 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
|
|||
code_index_push_nest(&result->nest_list, nest);
|
||||
}
|
||||
else if (token->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Code_Index_Nest *nest = generic_parse_parenthical(index, state,
|
||||
indentation);
|
||||
Code_Index_Nest *nest = generic_parse_paren(index, state,
|
||||
indentation);
|
||||
nest->parent = result;
|
||||
code_index_push_nest(&result->nest_list, nest);
|
||||
}
|
||||
|
@ -245,19 +276,19 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state,
|
|||
}
|
||||
}
|
||||
|
||||
result->nest_array =
|
||||
code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
|
||||
result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
function Code_Index_Nest*
|
||||
generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
|
||||
i64 indentation){
|
||||
generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state,
|
||||
i64 indentation){
|
||||
Token *token = token_it_read(&state->it);
|
||||
Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1);
|
||||
result->kind = CodeIndexNest_Paren;
|
||||
result->open = Ii64(token);
|
||||
result->close = Ii64(max_i64);
|
||||
result->file = index;
|
||||
|
||||
i64 manifested_characters_on_line = 0;
|
||||
|
@ -292,8 +323,7 @@ generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
|
|||
code_index_push_nest(&result->nest_list, nest);
|
||||
}
|
||||
else if (token->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Code_Index_Nest *nest = generic_parse_parenthical(index, state,
|
||||
indentation);
|
||||
Code_Index_Nest *nest = generic_parse_paren(index, state, indentation);
|
||||
nest->parent = result;
|
||||
code_index_push_nest(&result->nest_list, nest);
|
||||
}
|
||||
|
@ -303,13 +333,15 @@ generic_parse_parenthical(Code_Index_File *index, Generic_Parse_State *state,
|
|||
generic_parse_inc(state);
|
||||
break;
|
||||
}
|
||||
else if (token->kind == TokenBaseKind_ScopeClose){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
generic_parse_inc(state);
|
||||
}
|
||||
}
|
||||
|
||||
result->nest_array =
|
||||
code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
|
||||
result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
@ -335,7 +367,7 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta
|
|||
code_index_push_nest(&index->nest_list, nest);
|
||||
}
|
||||
else if (token->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Code_Index_Nest *nest = generic_parse_parenthical(index, state, indentation);
|
||||
Code_Index_Nest *nest = generic_parse_paren(index, state, indentation);
|
||||
code_index_push_nest(&index->nest_list, nest);
|
||||
}
|
||||
else{
|
||||
|
@ -353,8 +385,7 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta
|
|||
}
|
||||
|
||||
if (result){
|
||||
index->nest_array =
|
||||
code_index_nest_ptr_array_from_list(state->arena, &index->nest_list);
|
||||
index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list);
|
||||
}
|
||||
|
||||
return(result);
|
||||
|
@ -374,6 +405,210 @@ generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 content
|
|||
generic_parse_init(app, arena, contents, tokens, default_comment_index, state);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function i64
|
||||
layout_index_indent(Code_Index_File *file, i64 pos){
|
||||
i64 indent = 0;
|
||||
Code_Index_Nest *nest = code_index_get_nest(file, pos);
|
||||
if (nest != 0){
|
||||
if (pos == nest->close.min){
|
||||
indent = nest->close_indentation;
|
||||
}
|
||||
else{
|
||||
indent = nest->interior_indentation;
|
||||
}
|
||||
}
|
||||
return(indent);
|
||||
}
|
||||
|
||||
function f32
|
||||
layout_index_x_shift(Code_Index_File *file, i64 pos, f32 space_advance){
|
||||
i64 indent = layout_index_indent(file, pos);
|
||||
return(((f32)indent)*space_advance);
|
||||
}
|
||||
|
||||
function Layout_Item_List
|
||||
layout_index_unwrapped__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file){
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
Layout_Item_List list = get_empty_item_list(range);
|
||||
String_Const_u8 text = push_buffer_range(app, scratch, buffer, range);
|
||||
|
||||
Face_Advance_Map advance_map = get_face_advance_map(app, face);
|
||||
Face_Metrics metrics = get_face_metrics(app, face);
|
||||
LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width);
|
||||
|
||||
f32 wrap_align_x = width - metrics.normal_advance;
|
||||
|
||||
if (text.size == 0){
|
||||
lr_tb_write_blank(&pos_vars, arena, &list, range.start);
|
||||
}
|
||||
else{
|
||||
b32 first_of_the_line = true;
|
||||
Newline_Layout_Vars newline_vars = get_newline_layout_vars();
|
||||
|
||||
u8 *ptr = text.str;
|
||||
u8 *end_ptr = ptr + text.size;
|
||||
u8 *word_ptr = ptr;
|
||||
|
||||
if (!character_is_whitespace(*ptr)){
|
||||
goto consuming_non_whitespace;
|
||||
}
|
||||
|
||||
skipping_leading_whitespace:
|
||||
for (;ptr < end_ptr; ptr += 1){
|
||||
if (!character_is_whitespace(*ptr)){
|
||||
word_ptr = ptr;
|
||||
goto consuming_non_whitespace;
|
||||
}
|
||||
if (*ptr == '\n'){
|
||||
goto consuming_normal_whitespace;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr == end_ptr){
|
||||
goto finish;
|
||||
}
|
||||
|
||||
consuming_non_whitespace:
|
||||
for (;ptr <= end_ptr; ptr += 1){
|
||||
if (ptr == end_ptr || character_is_whitespace(*ptr)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
newline_layout_consume_default(&newline_vars);
|
||||
|
||||
String_Const_u8 word = SCu8(word_ptr, ptr);
|
||||
u8 *word_end = ptr;
|
||||
|
||||
if (!first_of_the_line){
|
||||
f32 total_advance = 0.f;
|
||||
ptr = word.str;
|
||||
for (;ptr < word_end;){
|
||||
Character_Consume_Result consume =
|
||||
utf8_consume(ptr, (umem)(word_end - ptr));
|
||||
if (consume.codepoint != max_u32){
|
||||
total_advance += lr_tb_advance(&pos_vars, consume.codepoint);
|
||||
}
|
||||
else{
|
||||
total_advance += lr_tb_advance_byte(&pos_vars);
|
||||
}
|
||||
ptr += consume.inc;
|
||||
}
|
||||
|
||||
if (lr_tb_crosses_width(&pos_vars, total_advance)){
|
||||
i64 index = layout_index_from_ptr(word.str, text.str, range.first);
|
||||
lr_tb_align_rightward(&pos_vars, wrap_align_x);
|
||||
lr_tb_write_ghost(&pos_vars, arena, &list, index, '\\');
|
||||
|
||||
lr_tb_next_line(&pos_vars);
|
||||
f32 shift = layout_index_x_shift(file, index, metrics.space_advance);
|
||||
lr_tb_advance_x_without_item(&pos_vars, shift);
|
||||
}
|
||||
}
|
||||
else{
|
||||
i64 index = layout_index_from_ptr(word.str, text.str, range.first);
|
||||
f32 shift = layout_index_x_shift(file, index, metrics.space_advance);
|
||||
lr_tb_advance_x_without_item(&pos_vars, shift);
|
||||
}
|
||||
|
||||
ptr = word.str;
|
||||
|
||||
for (;ptr < word_end;){
|
||||
Character_Consume_Result consume =
|
||||
utf8_consume(ptr, (umem)(word_end - ptr));
|
||||
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
|
||||
|
||||
if (consume.codepoint != max_u32){
|
||||
lr_tb_write(&pos_vars, arena, &list, index, consume.codepoint);
|
||||
}
|
||||
else{
|
||||
lr_tb_write_byte(&pos_vars, arena, &list, index, *ptr);
|
||||
}
|
||||
|
||||
ptr += consume.inc;
|
||||
}
|
||||
|
||||
first_of_the_line = false;
|
||||
}
|
||||
|
||||
consuming_normal_whitespace:
|
||||
for (; ptr < end_ptr; ptr += 1){
|
||||
if (!character_is_whitespace(*ptr)){
|
||||
word_ptr = ptr;
|
||||
goto consuming_non_whitespace;
|
||||
}
|
||||
|
||||
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
|
||||
switch (*ptr){
|
||||
default:
|
||||
{
|
||||
newline_layout_consume_default(&newline_vars);
|
||||
lr_tb_write(&pos_vars, arena, &list, index, *ptr);
|
||||
first_of_the_line = false;
|
||||
}break;
|
||||
|
||||
case '\r':
|
||||
{
|
||||
newline_layout_consume_CR(&newline_vars, index);
|
||||
}break;
|
||||
|
||||
case '\n':
|
||||
{
|
||||
if (first_of_the_line){
|
||||
f32 shift = layout_index_x_shift(file, index,
|
||||
metrics.space_advance);
|
||||
lr_tb_advance_x_without_item(&pos_vars, shift);
|
||||
}
|
||||
|
||||
u64 newline_index = newline_layout_consume_LF(&newline_vars, index);
|
||||
lr_tb_write_blank(&pos_vars, arena, &list, newline_index);
|
||||
lr_tb_next_line(&pos_vars);
|
||||
first_of_the_line = true;
|
||||
ptr += 1;
|
||||
goto skipping_leading_whitespace;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (newline_layout_consume_finish(&newline_vars)){
|
||||
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
|
||||
if (first_of_the_line){
|
||||
f32 shift = layout_index_x_shift(file, index,
|
||||
metrics.space_advance);
|
||||
lr_tb_advance_x_without_item(&pos_vars, shift);
|
||||
}
|
||||
lr_tb_write_blank(&pos_vars, arena, &list, index);
|
||||
}
|
||||
}
|
||||
|
||||
layout_item_list_finish(&list, -pos_vars.line_to_text_shift);
|
||||
|
||||
return(list);
|
||||
}
|
||||
|
||||
function Layout_Item_List
|
||||
layout_virt_indent_index_unwrapped(Application_Links *app, Arena *arena,
|
||||
Buffer_ID buffer, Range_i64 range, Face_ID face,
|
||||
f32 width){
|
||||
Layout_Item_List result = {};
|
||||
|
||||
code_index_lock();
|
||||
Code_Index_File *file = code_index_get_file(buffer);
|
||||
if (file != 0){
|
||||
result = layout_index_unwrapped__inner(app, arena, buffer, range, face, width, file);
|
||||
}
|
||||
code_index_unlock();
|
||||
if (file == 0){
|
||||
result = layout_virt_indent_literal_unwrapped(app, arena, buffer, range, face, width);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -460,6 +460,7 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam
|
|||
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" ));
|
||||
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
|
||||
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
|
||||
buffer_parse_task = managed_id_declare(app, SCu8("DEFAULT.buffer_parse_task"));
|
||||
|
||||
sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle"));
|
||||
attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens"));
|
||||
|
|
|
@ -46,6 +46,7 @@ global Managed_ID view_word_complete_menu = 0;
|
|||
global Managed_ID buffer_map_id = 0;
|
||||
global Managed_ID buffer_eol_setting = 0;
|
||||
global Managed_ID buffer_lex_task = 0;
|
||||
global Managed_ID buffer_parse_task = 0;
|
||||
|
||||
global Managed_ID sticky_jump_marker_handle = 0;
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ CUSTOM_DOC("Default command for responding to a try-exit event")
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
CUSTOM_COMMAND_SIG(default_view_input_handler)
|
||||
CUSTOM_DOC("Input consumption loop for default view behavior")
|
||||
{
|
||||
|
@ -281,6 +280,48 @@ default_buffer_region(Application_Links *app, View_ID view_id, Rect_f32 region){
|
|||
return(region);
|
||||
}
|
||||
|
||||
function void
|
||||
recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range,
|
||||
Code_Index_Nest_Ptr_Array *array, i32 counter){
|
||||
Code_Index_Nest **ptr = array->ptrs;
|
||||
Code_Index_Nest **ptr_end = ptr + array->count;
|
||||
|
||||
for (;ptr < ptr_end; ptr += 1){
|
||||
Code_Index_Nest *nest = *ptr;
|
||||
if (!nest->is_closed){
|
||||
break;
|
||||
}
|
||||
if (range.first <= nest->close.max){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FColor t_colors[] = {
|
||||
fcolor_id(Stag_Text_Cycle_1), fcolor_id(Stag_Text_Cycle_2),
|
||||
fcolor_id(Stag_Text_Cycle_3), fcolor_id(Stag_Text_Cycle_4),
|
||||
};
|
||||
FColor t_color = t_colors[counter%ArrayCount(t_colors)];
|
||||
|
||||
for (;ptr < ptr_end; ptr += 1){
|
||||
Code_Index_Nest *nest = *ptr;
|
||||
if (range.max <= nest->open.min){
|
||||
break;
|
||||
}
|
||||
|
||||
paint_text_color(app, layout_id, nest->open, t_color);
|
||||
if (nest->is_closed){
|
||||
paint_text_color(app, layout_id, nest->close, t_color);
|
||||
}
|
||||
recursive_nest_highlight(app, layout_id, range, &nest->nest_array, counter + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range,
|
||||
Code_Index_File *file){
|
||||
recursive_nest_highlight(app, layout_id, range, &file->nest_array, 0);
|
||||
}
|
||||
|
||||
function void
|
||||
default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id,
|
||||
Buffer_ID buffer, Text_Layout_ID text_layout_id,
|
||||
|
@ -581,6 +622,45 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
|
|||
}
|
||||
}
|
||||
|
||||
function void
|
||||
parse_async__inner(Async_Context *actx, Buffer_ID buffer_id,
|
||||
String_Const_u8 contents, Token_Array *tokens, i32 limit_factor){
|
||||
Application_Links *app = actx->app;
|
||||
ProfileBlock(app, "async parse");
|
||||
|
||||
Arena arena = make_arena_system(KB(16));
|
||||
Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1);
|
||||
index->buffer = buffer_id;
|
||||
|
||||
Generic_Parse_State state = {};
|
||||
generic_parse_init(app, &arena, contents, tokens, &state);
|
||||
|
||||
b32 canceled = false;
|
||||
|
||||
for (;;){
|
||||
if (generic_parse_full_input_breaks(index, &state, limit_factor)){
|
||||
break;
|
||||
}
|
||||
if (async_check_canceled(actx)){
|
||||
canceled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canceled){
|
||||
Thread_Context *tctx = get_thread_context(app);
|
||||
system_acquire_global_frame_mutex(tctx);
|
||||
code_index_lock();
|
||||
code_index_set_file(buffer_id, arena, index);
|
||||
code_index_unlock();
|
||||
buffer_clear_layout_cache(app, buffer_id);
|
||||
system_release_global_frame_mutex(tctx);
|
||||
}
|
||||
else{
|
||||
linalloc_clear(&arena);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
|
||||
Application_Links *app = actx->app;
|
||||
|
@ -600,10 +680,8 @@ do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
|
|||
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens,
|
||||
Token_Array);
|
||||
base_free(allocator, tokens_ptr->tokens);
|
||||
block_zero_struct(tokens_ptr);
|
||||
}
|
||||
code_index_lock();
|
||||
code_index_erase_file(buffer_id);
|
||||
code_index_unlock();
|
||||
|
||||
contents = push_whole_buffer(app, scratch, buffer_id);
|
||||
system_release_global_frame_mutex(tctx);
|
||||
|
@ -650,32 +728,7 @@ do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
|
|||
}
|
||||
|
||||
if (tokens.count > 0){
|
||||
ProfileBlock(app, "async parse");
|
||||
Arena arena = make_arena_system(KB(16));
|
||||
Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1);
|
||||
index->buffer = buffer_id;
|
||||
|
||||
Generic_Parse_State state = {};
|
||||
generic_parse_init(app, &arena, contents, &tokens, &state);
|
||||
|
||||
for (;;){
|
||||
if (generic_parse_full_input_breaks(index, &state, limit_factor)){
|
||||
break;
|
||||
}
|
||||
if (async_check_canceled(actx)){
|
||||
canceled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canceled){
|
||||
code_index_lock();
|
||||
code_index_set_file(buffer_id, arena, index);
|
||||
code_index_unlock();
|
||||
}
|
||||
else{
|
||||
linalloc_clear(&arena);
|
||||
}
|
||||
parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,6 +740,49 @@ do_full_lex_and_parse_async(Async_Context *actx, Data data){
|
|||
}
|
||||
}
|
||||
|
||||
function void
|
||||
do_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){
|
||||
Application_Links *app = actx->app;
|
||||
ProfileScope(app, "async lex");
|
||||
Thread_Context *tctx = get_thread_context(app);
|
||||
Scratch_Block scratch(tctx);
|
||||
|
||||
String_Const_u8 contents = {};
|
||||
Token_Array tokens = {};
|
||||
{
|
||||
ProfileBlock(app, "async parse contents (before mutex)");
|
||||
system_acquire_global_frame_mutex(tctx);
|
||||
ProfileBlock(app, "async parse contents (after mutex)");
|
||||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
|
||||
if (scope != 0){
|
||||
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens,
|
||||
Token_Array);
|
||||
tokens.count = tokens_ptr->count;
|
||||
tokens.tokens = push_array_write(scratch, Token, tokens.count, tokens_ptr->tokens);
|
||||
if (tokens.count > 0){
|
||||
contents = push_whole_buffer(app, scratch, buffer_id);
|
||||
}
|
||||
}
|
||||
|
||||
system_release_global_frame_mutex(tctx);
|
||||
}
|
||||
|
||||
i32 limit_factor = 10000;
|
||||
|
||||
if (tokens.count > 0){
|
||||
parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
do_parse_async(Async_Context *actx, Data data){
|
||||
if (data.size == sizeof(Buffer_ID)){
|
||||
Buffer_ID buffer = *(Buffer_ID*)data.data;
|
||||
do_parse_async__inner(actx, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
BUFFER_HOOK_SIG(default_begin_buffer){
|
||||
ProfileScope(app, "begin buffer");
|
||||
|
||||
|
@ -774,6 +870,7 @@ BUFFER_HOOK_SIG(default_begin_buffer){
|
|||
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id"));
|
||||
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
|
||||
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
|
||||
buffer_parse_task = managed_id_declare(app, SCu8("DEFAULT.buffer_parse_task"));
|
||||
}
|
||||
|
||||
Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file);
|
||||
|
@ -810,7 +907,13 @@ BUFFER_HOOK_SIG(default_begin_buffer){
|
|||
|
||||
if (wrap_lines){
|
||||
if (use_virtual_whitespace){
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_unwrapped);
|
||||
if (use_lexer){
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_index_unwrapped);
|
||||
//buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
|
||||
}
|
||||
else{
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
|
||||
}
|
||||
}
|
||||
else{
|
||||
buffer_set_layout(app, buffer_id, layout_wrap_whitespace);
|
||||
|
@ -818,7 +921,13 @@ BUFFER_HOOK_SIG(default_begin_buffer){
|
|||
}
|
||||
else{
|
||||
if (use_virtual_whitespace){
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_unwrapped);
|
||||
if (use_lexer){
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_index_unwrapped);
|
||||
//buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
|
||||
}
|
||||
else{
|
||||
buffer_set_layout(app, buffer_id, layout_virt_indent_literal_unwrapped);
|
||||
}
|
||||
}
|
||||
else{
|
||||
buffer_set_layout(app, buffer_id, layout_unwrapped);
|
||||
|
@ -865,7 +974,17 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
|
|||
// buffer_id, new_range, original_size
|
||||
ProfileScope(app, "default edit range");
|
||||
|
||||
Interval_i64 old_range = Ii64(new_range.first, new_range.first + original_size);
|
||||
Range_i64 old_range = Ii64(new_range.first, new_range.first + original_size);
|
||||
|
||||
{
|
||||
code_index_lock();
|
||||
Code_Index_File *file = code_index_get_file(buffer_id);
|
||||
if (file != 0){
|
||||
code_index_shift(file, old_range, range_size(new_range));
|
||||
}
|
||||
code_index_unlock();
|
||||
}
|
||||
|
||||
i64 insert_size = range_size(new_range);
|
||||
i64 text_shift = replace_range_shift(old_range, insert_size);
|
||||
|
||||
|
@ -873,93 +992,99 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
|
|||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
|
||||
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
|
||||
Async_Task *parse_task_ptr = scope_attachment(app, scope, buffer_parse_task, Async_Task);
|
||||
|
||||
Base_Allocator *allocator = managed_scope_allocator(app, scope);
|
||||
b32 do_full_relex = false;
|
||||
|
||||
if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){
|
||||
async_task_cancel(&global_async_system, *lex_task_ptr);
|
||||
*lex_task_ptr = async_task_no_dep(&global_async_system,
|
||||
do_full_lex_and_parse_async,
|
||||
make_data_struct(&buffer_id));
|
||||
do_full_relex = true;
|
||||
*lex_task_ptr = 0;
|
||||
}
|
||||
else{
|
||||
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
if (ptr != 0 && ptr->tokens != 0){
|
||||
ProfileBlockNamed(app, "attempt resync", profile_attempt_resync);
|
||||
if (async_task_is_running_or_pending(&global_async_system, *parse_task_ptr)){
|
||||
async_task_cancel(&global_async_system, *parse_task_ptr);
|
||||
*parse_task_ptr = 0;
|
||||
}
|
||||
|
||||
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
if (ptr != 0 && ptr->tokens != 0){
|
||||
ProfileBlockNamed(app, "attempt resync", profile_attempt_resync);
|
||||
|
||||
i64 token_index_first = token_relex_first(ptr, old_range.first, 1);
|
||||
i64 token_index_resync_guess =
|
||||
token_relex_resync(ptr, old_range.one_past_last, 16);
|
||||
|
||||
if (token_index_resync_guess - token_index_first >= 4000){
|
||||
do_full_relex = true;
|
||||
}
|
||||
else{
|
||||
Token *token_first = ptr->tokens + token_index_first;
|
||||
Token *token_resync = ptr->tokens + token_index_resync_guess;
|
||||
|
||||
Base_Allocator *allocator = managed_scope_allocator(app, scope);
|
||||
Range_i64 relex_range =
|
||||
Ii64(token_first->pos,
|
||||
token_resync->pos + token_resync->size + text_shift);
|
||||
String_Const_u8 partial_text = push_buffer_range(app, scratch,
|
||||
buffer_id,
|
||||
relex_range);
|
||||
|
||||
b32 do_full_relex = false;
|
||||
i64 token_index_first = token_relex_first(ptr, old_range.first, 1);
|
||||
i64 token_index_resync_guess =
|
||||
token_relex_resync(ptr, old_range.one_past_last, 16);
|
||||
Token_List relex_list = lex_full_input_cpp(scratch, partial_text);
|
||||
if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){
|
||||
token_drop_eof(&relex_list);
|
||||
}
|
||||
|
||||
if (token_index_resync_guess - token_index_first >= 4000){
|
||||
Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift,
|
||||
ptr->tokens, token_index_first, token_index_resync_guess);
|
||||
|
||||
ProfileCloseNow(profile_attempt_resync);
|
||||
|
||||
if (!relex.successful_resync){
|
||||
do_full_relex = true;
|
||||
}
|
||||
else{
|
||||
Token *token_first = ptr->tokens + token_index_first;
|
||||
Token *token_resync = ptr->tokens + token_index_resync_guess;
|
||||
ProfileBlock(app, "apply resync");
|
||||
|
||||
Range_i64 relex_range =
|
||||
Ii64(token_first->pos,
|
||||
token_resync->pos + token_resync->size + text_shift);
|
||||
String_Const_u8 partial_text = push_buffer_range(app, scratch,
|
||||
buffer_id,
|
||||
relex_range);
|
||||
i64 token_index_resync = relex.first_resync_index;
|
||||
|
||||
Token_List relex_list = lex_full_input_cpp(scratch, partial_text);
|
||||
if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){
|
||||
token_drop_eof(&relex_list);
|
||||
Interval_i64 head = Ii64(0, token_index_first);
|
||||
Interval_i64 replaced = Ii64(token_index_first, token_index_resync);
|
||||
Interval_i64 tail = Ii64(token_index_resync, ptr->count);
|
||||
i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync;
|
||||
i64 relexed_count = relex_list.total_count - resynced_count;
|
||||
i64 tail_shift = relexed_count - (token_index_resync - token_index_first);
|
||||
|
||||
i64 new_tokens_count = ptr->count + tail_shift;
|
||||
Token *new_tokens = base_array(allocator, Token, new_tokens_count);
|
||||
|
||||
Token *old_tokens = ptr->tokens;
|
||||
block_copy_array_shift(new_tokens, old_tokens, head, 0);
|
||||
token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count);
|
||||
for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){
|
||||
new_tokens[index].pos += relex_range.first;
|
||||
}
|
||||
|
||||
Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift,
|
||||
ptr->tokens, token_index_first, token_index_resync_guess);
|
||||
|
||||
ProfileCloseNow(profile_attempt_resync);
|
||||
|
||||
if (relex.successful_resync){
|
||||
ProfileBlock(app, "apply resync");
|
||||
|
||||
i64 token_index_resync = relex.first_resync_index;
|
||||
|
||||
Interval_i64 head = Ii64(0, token_index_first);
|
||||
Interval_i64 replaced = Ii64(token_index_first, token_index_resync);
|
||||
Interval_i64 tail = Ii64(token_index_resync, ptr->count);
|
||||
i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync;
|
||||
i64 relexed_count = relex_list.total_count - resynced_count;
|
||||
i64 tail_shift = relexed_count - (token_index_resync - token_index_first);
|
||||
|
||||
i64 new_tokens_count = ptr->count + tail_shift;
|
||||
Token *new_tokens = base_array(allocator, Token, new_tokens_count);
|
||||
|
||||
Token *old_tokens = ptr->tokens;
|
||||
block_copy_array_shift(new_tokens, old_tokens, head, 0);
|
||||
token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count);
|
||||
for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){
|
||||
new_tokens[index].pos += relex_range.first;
|
||||
}
|
||||
for (i64 i = tail.first; i < tail.one_past_last; i += 1){
|
||||
old_tokens[i].pos += text_shift;
|
||||
}
|
||||
block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift);
|
||||
|
||||
base_free(allocator, ptr->tokens);
|
||||
|
||||
ptr->tokens = new_tokens;
|
||||
ptr->count = new_tokens_count;
|
||||
ptr->max = new_tokens_count;
|
||||
for (i64 i = tail.first; i < tail.one_past_last; i += 1){
|
||||
old_tokens[i].pos += text_shift;
|
||||
}
|
||||
else{
|
||||
do_full_relex = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_full_relex){
|
||||
*lex_task_ptr = async_task_no_dep(&global_async_system,
|
||||
do_full_lex_and_parse_async,
|
||||
make_data_struct(&buffer_id));
|
||||
block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift);
|
||||
|
||||
base_free(allocator, ptr->tokens);
|
||||
|
||||
ptr->tokens = new_tokens;
|
||||
ptr->count = new_tokens_count;
|
||||
ptr->max = new_tokens_count;
|
||||
|
||||
*parse_task_ptr = async_task_no_dep(&global_async_system, do_parse_async,
|
||||
make_data_struct(&buffer_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_full_relex){
|
||||
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_and_parse_async,
|
||||
make_data_struct(&buffer_id));
|
||||
}
|
||||
|
||||
// no meaning for return
|
||||
return(0);
|
||||
}
|
||||
|
@ -970,6 +1095,10 @@ BUFFER_HOOK_SIG(default_end_buffer){
|
|||
if (lex_task_ptr != 0){
|
||||
async_task_cancel(&global_async_system, *lex_task_ptr);
|
||||
}
|
||||
Async_Task *lex_parse_ptr = scope_attachment(app, scope, buffer_parse_task, Async_Task);
|
||||
if (lex_parse_ptr != 0){
|
||||
async_task_cancel(&global_async_system, *lex_parse_ptr);
|
||||
}
|
||||
code_index_lock();
|
||||
code_index_erase_file(buffer_id);
|
||||
code_index_unlock();
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include "4coder_profile.h"
|
||||
#include "4coder_async_tasks.h"
|
||||
#include "4coder_token.h"
|
||||
#include "4coder_code_index.h"
|
||||
#include "generated/lexer_cpp.h"
|
||||
#include "4coder_string_match.h"
|
||||
#include "4coder_helper.h"
|
||||
#include "4coder_delta_rule.h"
|
||||
#include "4coder_layout_rule.h"
|
||||
#include "4coder_code_index.h"
|
||||
#include "4coder_draw.h"
|
||||
#include "4coder_insertion.h"
|
||||
#include "4coder_lister_base.h"
|
||||
|
@ -72,13 +72,13 @@
|
|||
#include "4coder_buffer_seek_constructors.cpp"
|
||||
|
||||
#include "4coder_token.cpp"
|
||||
#include "4coder_code_index.cpp"
|
||||
#include "generated/lexer_cpp.cpp"
|
||||
#include "4coder_command_map.cpp"
|
||||
#include "4coder_default_framework_variables.cpp"
|
||||
#include "4coder_helper.cpp"
|
||||
#include "4coder_delta_rule.cpp"
|
||||
#include "4coder_layout_rule.cpp"
|
||||
#include "4coder_code_index.cpp"
|
||||
#include "4coder_fancy.cpp"
|
||||
#include "4coder_draw.cpp"
|
||||
#include "4coder_font_helper.cpp"
|
||||
|
|
|
@ -24,8 +24,7 @@ layout_item_list_finish(Layout_Item_List *list, f32 bottom_padding){
|
|||
}
|
||||
|
||||
function void
|
||||
layout_write(Arena *arena, Layout_Item_List *list,
|
||||
i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect){
|
||||
layout_write(Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect){
|
||||
Temp_Memory restore_point = begin_temp(arena);
|
||||
Layout_Item *item = push_array(arena, Layout_Item, 1);
|
||||
|
||||
|
@ -140,37 +139,45 @@ lr_tb_advance(LefRig_TopBot_Layout_Vars *vars, u32 codepoint){
|
|||
}
|
||||
|
||||
function void
|
||||
lr_tb_write_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance,
|
||||
Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
|
||||
lr_tb_write_with_advance_with_flags(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint, Layout_Item_Flag flags){
|
||||
if (codepoint == '\t'){
|
||||
codepoint = ' ';
|
||||
}
|
||||
vars->p.x = f32_ceil32(vars->p.x);
|
||||
f32 next_x = vars->p.x + advance;
|
||||
layout_write(arena, list, index, codepoint, 0,
|
||||
layout_write(arena, list, index, codepoint, flags,
|
||||
Rf32(vars->p, V2f32(next_x, vars->text_y)));
|
||||
vars->p.x = next_x;
|
||||
}
|
||||
|
||||
function void
|
||||
lr_tb_write(LefRig_TopBot_Layout_Vars *vars,
|
||||
Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
|
||||
lr_tb_write_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
|
||||
lr_tb_write_with_advance_with_flags(vars, advance, arena, list, index, codepoint, 0);
|
||||
}
|
||||
|
||||
function void
|
||||
lr_tb_write(LefRig_TopBot_Layout_Vars *vars, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
|
||||
f32 advance = lr_tb_advance(vars, codepoint);
|
||||
lr_tb_write_with_advance(vars, advance, arena, list, index, codepoint);
|
||||
}
|
||||
|
||||
function void
|
||||
lr_tb_write_ghost(LefRig_TopBot_Layout_Vars *vars, Arena *arena, Layout_Item_List *list, i64 index, u32 codepoint){
|
||||
f32 advance = lr_tb_advance(vars, codepoint);
|
||||
lr_tb_write_with_advance_with_flags(vars, advance, arena, list, index, codepoint, LayoutItemFlag_Ghost_Character);
|
||||
}
|
||||
|
||||
function f32
|
||||
lr_tb_advance_byte(LefRig_TopBot_Layout_Vars *vars){
|
||||
return(vars->metrics->byte_advance);
|
||||
}
|
||||
|
||||
function void
|
||||
lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance,
|
||||
Arena *arena, Layout_Item_List *list, i64 index, u8 byte){
|
||||
lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance, Arena *arena, Layout_Item_List *list, i64 index, u8 byte){
|
||||
Face_Metrics *metrics = vars->metrics;
|
||||
|
||||
f32 final_next_x = vars->p.x + advance;
|
||||
u32 lo = ((u32)byte)&0xF;
|
||||
u32 lo = ((u32)byte )&0xF;
|
||||
u32 hi = ((u32)byte >> 4)&0xF;
|
||||
|
||||
Vec2_f32 p = vars->p;
|
||||
|
@ -178,15 +185,17 @@ lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, f32 advance,
|
|||
f32 next_x = p.x + metrics->byte_sub_advances[0];
|
||||
f32 text_y = vars->text_y;
|
||||
|
||||
layout_write(arena, list, index, '\\', 0,
|
||||
Layout_Item_Flag flags = LayoutItemFlag_Special_Character;
|
||||
|
||||
layout_write(arena, list, index, '\\', flags,
|
||||
Rf32(p, V2f32(next_x, text_y)));
|
||||
p.x = next_x;
|
||||
next_x += metrics->byte_sub_advances[1];
|
||||
layout_write(arena, list, index, integer_symbols[hi], 0,
|
||||
layout_write(arena, list, index, integer_symbols[hi], flags,
|
||||
Rf32(p, V2f32(next_x, text_y)));
|
||||
p.x = next_x;
|
||||
next_x += metrics->byte_sub_advances[2];
|
||||
layout_write(arena, list, index, integer_symbols[lo], 0,
|
||||
layout_write(arena, list, index, integer_symbols[lo], flags,
|
||||
Rf32(p, V2f32(next_x, text_y)));
|
||||
|
||||
vars->p.x = final_next_x;
|
||||
|
@ -234,6 +243,11 @@ lr_tb_advance_x_without_item(LefRig_TopBot_Layout_Vars *vars, f32 advance){
|
|||
vars->p.x += advance;
|
||||
}
|
||||
|
||||
function void
|
||||
lr_tb_align_rightward(LefRig_TopBot_Layout_Vars *vars, f32 align_x){
|
||||
vars->p.x = clamp_bot(align_x, vars->p.x);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function Layout_Item_List
|
||||
|
@ -517,7 +531,7 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
|
|||
if (!first_of_the_line){
|
||||
f32 total_advance = 0.f;
|
||||
ptr = word.str;
|
||||
for (; ptr < word_end;){
|
||||
for (;ptr < word_end;){
|
||||
Character_Consume_Result consume =
|
||||
utf8_consume(ptr, (umem)(word_end - ptr));
|
||||
if (consume.codepoint != max_u32){
|
||||
|
@ -536,7 +550,7 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
|
|||
|
||||
ptr = word.str;
|
||||
|
||||
for (; ptr < word_end;){
|
||||
for (;ptr < word_end;){
|
||||
Character_Consume_Result consume =
|
||||
utf8_consume(ptr, (umem)(word_end - ptr));
|
||||
i64 index = layout_index_from_ptr(ptr, text.str, range.first);
|
||||
|
@ -602,9 +616,9 @@ layout_wrap_whitespace(Application_Links *app, Arena *arena, Buffer_ID buffer,
|
|||
}
|
||||
|
||||
function Layout_Item_List
|
||||
layout_virt_indent_unwrapped(Application_Links *app, Arena *arena,
|
||||
Buffer_ID buffer, Range_i64 range, Face_ID face,
|
||||
f32 width){
|
||||
layout_virt_indent_literal_unwrapped(Application_Links *app, Arena *arena,
|
||||
Buffer_ID buffer, Range_i64 range, Face_ID face,
|
||||
f32 width){
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
Layout_Item_List list = get_empty_item_list(range);
|
||||
|
|
|
@ -582,32 +582,25 @@ struct Buffer_Name_Conflict_Entry{
|
|||
};
|
||||
|
||||
typedef void Buffer_Name_Resolver_Function(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, i32 conflict_count);
|
||||
#define BUFFER_NAME_RESOLVER_SIG(n) \
|
||||
void n(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, \
|
||||
i32 conflict_count)
|
||||
#define BUFFER_NAME_RESOLVER_SIG(n) void n(Application_Links *app, Buffer_Name_Conflict_Entry *conflicts, i32 conflict_count)
|
||||
|
||||
typedef i32 Buffer_Hook_Function(Application_Links *app, Buffer_ID buffer_id);
|
||||
#define BUFFER_HOOK_SIG(name) i32 name(Application_Links *app, Buffer_ID buffer_id)
|
||||
|
||||
typedef i32 Buffer_Edit_Range_Function(Application_Links *app, Buffer_ID buffer_id,
|
||||
Range_i64 new_range, umem original_size);
|
||||
#define BUFFER_EDIT_RANGE_SIG(name) \
|
||||
i32 name(Application_Links *app, Buffer_ID buffer_id, \
|
||||
Interval_i64 new_range, umem original_size)
|
||||
#define BUFFER_EDIT_RANGE_SIG(name) i32 name(Application_Links *app, Buffer_ID buffer_id, Interval_i64 new_range, umem original_size)
|
||||
|
||||
typedef Vec2_f32 Delta_Rule_Function(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data);
|
||||
#define DELTA_RULE_SIG(name) \
|
||||
Vec2_f32 name(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data)
|
||||
#define DELTA_RULE_SIG(name) Vec2_f32 name(Vec2_f32 pending, b32 is_new_target, f32 dt, void *data)
|
||||
|
||||
typedef Rect_f32 Buffer_Region_Function(Application_Links *app, View_ID view_id, Rect_f32 region);
|
||||
|
||||
typedef void New_Clipboard_Contents_Function(Application_Links *app, String_Const_u8 contents);
|
||||
#define NEW_CLIPBOARD_CONTENTS_SIG(name) \
|
||||
void name(Application_Links *app, String_Const_u8 contents)
|
||||
#define NEW_CLIPBOARD_CONTENTS_SIG(name) void name(Application_Links *app, String_Const_u8 contents)
|
||||
|
||||
typedef void Render_Caller_Function(Application_Links *app, Frame_Info frame_info, View_ID view);
|
||||
#define RENDER_CALLER_SIG(name) \
|
||||
void name(Application_Links *app, Frame_Info frame_info, View_ID view)
|
||||
#define RENDER_CALLER_SIG(name) void name(Application_Links *app, Frame_Info frame_info, View_ID view)
|
||||
|
||||
typedef u32 Layout_Item_Flag;
|
||||
enum{
|
||||
|
|
|
@ -236,7 +236,7 @@ i32 source_name_len;
|
|||
i32 line_number;
|
||||
};
|
||||
static Command_Metadata fcoder_metacmd_table[214] = {
|
||||
{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 57 },
|
||||
{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 },
|
||||
{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 207 },
|
||||
{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 214 },
|
||||
{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 221 },
|
||||
|
|
|
@ -43,7 +43,7 @@ vtable->push_buffer_file_name = push_buffer_file_name;
|
|||
vtable->buffer_get_dirty_state = buffer_get_dirty_state;
|
||||
vtable->buffer_set_dirty_state = buffer_set_dirty_state;
|
||||
vtable->buffer_set_layout = buffer_set_layout;
|
||||
vtable->file_clear_layout_cache = file_clear_layout_cache;
|
||||
vtable->buffer_clear_layout_cache = buffer_clear_layout_cache;
|
||||
vtable->buffer_get_layout = buffer_get_layout;
|
||||
vtable->buffer_get_setting = buffer_get_setting;
|
||||
vtable->buffer_set_setting = buffer_set_setting;
|
||||
|
@ -223,7 +223,7 @@ push_buffer_file_name = vtable->push_buffer_file_name;
|
|||
buffer_get_dirty_state = vtable->buffer_get_dirty_state;
|
||||
buffer_set_dirty_state = vtable->buffer_set_dirty_state;
|
||||
buffer_set_layout = vtable->buffer_set_layout;
|
||||
file_clear_layout_cache = vtable->file_clear_layout_cache;
|
||||
buffer_clear_layout_cache = vtable->buffer_clear_layout_cache;
|
||||
buffer_get_layout = vtable->buffer_get_layout;
|
||||
buffer_get_setting = vtable->buffer_get_setting;
|
||||
buffer_set_setting = vtable->buffer_set_setting;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define custom_buffer_get_dirty_state_sig() Dirty_State custom_buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id)
|
||||
#define custom_buffer_set_dirty_state_sig() b32 custom_buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state)
|
||||
#define custom_buffer_set_layout_sig() b32 custom_buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func)
|
||||
#define custom_file_clear_layout_cache_sig() b32 custom_file_clear_layout_cache(Application_Links* app, Buffer_ID buffer)
|
||||
#define custom_buffer_clear_layout_cache_sig() b32 custom_buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id)
|
||||
#define custom_buffer_get_layout_sig() Layout_Function* custom_buffer_get_layout(Application_Links* app, Buffer_ID buffer_id)
|
||||
#define custom_buffer_get_setting_sig() b32 custom_buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out)
|
||||
#define custom_buffer_set_setting_sig() b32 custom_buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value)
|
||||
|
@ -164,7 +164,7 @@
|
|||
#define custom_text_layout_create_sig() Text_Layout_ID custom_text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point)
|
||||
#define custom_text_layout_region_sig() Rect_f32 custom_text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id)
|
||||
#define custom_text_layout_get_buffer_sig() Buffer_ID custom_text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id)
|
||||
#define custom_text_layout_get_visible_range_sig() Interval_i64 custom_text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id)
|
||||
#define custom_text_layout_get_visible_range_sig() Range_i64 custom_text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id)
|
||||
#define custom_text_layout_line_on_screen_sig() Range_f32 custom_text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number)
|
||||
#define custom_text_layout_character_on_screen_sig() Rect_f32 custom_text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos)
|
||||
#define custom_paint_text_color_sig() void custom_paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color)
|
||||
|
@ -217,7 +217,7 @@ typedef String_Const_u8 custom_push_buffer_file_name_type(Application_Links* app
|
|||
typedef Dirty_State custom_buffer_get_dirty_state_type(Application_Links* app, Buffer_ID buffer_id);
|
||||
typedef b32 custom_buffer_set_dirty_state_type(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
|
||||
typedef b32 custom_buffer_set_layout_type(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
|
||||
typedef b32 custom_file_clear_layout_cache_type(Application_Links* app, Buffer_ID buffer);
|
||||
typedef b32 custom_buffer_clear_layout_cache_type(Application_Links* app, Buffer_ID buffer_id);
|
||||
typedef Layout_Function* custom_buffer_get_layout_type(Application_Links* app, Buffer_ID buffer_id);
|
||||
typedef b32 custom_buffer_get_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
|
||||
typedef b32 custom_buffer_set_setting_type(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
|
||||
|
@ -340,7 +340,7 @@ typedef Rect_f32 custom_draw_set_clip_type(Application_Links* app, Rect_f32 new_
|
|||
typedef Text_Layout_ID custom_text_layout_create_type(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
|
||||
typedef Rect_f32 custom_text_layout_region_type(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
typedef Buffer_ID custom_text_layout_get_buffer_type(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
typedef Interval_i64 custom_text_layout_get_visible_range_type(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
typedef Range_i64 custom_text_layout_get_visible_range_type(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
typedef Range_f32 custom_text_layout_line_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
|
||||
typedef Rect_f32 custom_text_layout_character_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
|
||||
typedef void custom_paint_text_color_type(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);
|
||||
|
@ -394,7 +394,7 @@ custom_push_buffer_file_name_type *push_buffer_file_name;
|
|||
custom_buffer_get_dirty_state_type *buffer_get_dirty_state;
|
||||
custom_buffer_set_dirty_state_type *buffer_set_dirty_state;
|
||||
custom_buffer_set_layout_type *buffer_set_layout;
|
||||
custom_file_clear_layout_cache_type *file_clear_layout_cache;
|
||||
custom_buffer_clear_layout_cache_type *buffer_clear_layout_cache;
|
||||
custom_buffer_get_layout_type *buffer_get_layout;
|
||||
custom_buffer_get_setting_type *buffer_get_setting;
|
||||
custom_buffer_set_setting_type *buffer_set_setting;
|
||||
|
@ -572,7 +572,7 @@ internal String_Const_u8 push_buffer_file_name(Application_Links* app, Arena* ar
|
|||
internal Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id);
|
||||
internal b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
|
||||
internal b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
|
||||
internal b32 file_clear_layout_cache(Application_Links* app, Buffer_ID buffer);
|
||||
internal b32 buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id);
|
||||
internal Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id);
|
||||
internal b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
|
||||
internal b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
|
||||
|
@ -695,7 +695,7 @@ internal Rect_f32 draw_set_clip(Application_Links* app, Rect_f32 new_clip);
|
|||
internal Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
|
||||
internal Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
internal Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
internal Interval_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
internal Range_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
internal Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
|
||||
internal Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
|
||||
internal void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);
|
||||
|
@ -750,7 +750,7 @@ global custom_push_buffer_file_name_type *push_buffer_file_name = 0;
|
|||
global custom_buffer_get_dirty_state_type *buffer_get_dirty_state = 0;
|
||||
global custom_buffer_set_dirty_state_type *buffer_set_dirty_state = 0;
|
||||
global custom_buffer_set_layout_type *buffer_set_layout = 0;
|
||||
global custom_file_clear_layout_cache_type *file_clear_layout_cache = 0;
|
||||
global custom_buffer_clear_layout_cache_type *buffer_clear_layout_cache = 0;
|
||||
global custom_buffer_get_layout_type *buffer_get_layout = 0;
|
||||
global custom_buffer_get_setting_type *buffer_get_setting = 0;
|
||||
global custom_buffer_set_setting_type *buffer_set_setting = 0;
|
||||
|
|
|
@ -41,7 +41,7 @@ api(custom) function String_Const_u8 push_buffer_file_name(Application_Links* ap
|
|||
api(custom) function Dirty_State buffer_get_dirty_state(Application_Links* app, Buffer_ID buffer_id);
|
||||
api(custom) function b32 buffer_set_dirty_state(Application_Links* app, Buffer_ID buffer_id, Dirty_State dirty_state);
|
||||
api(custom) function b32 buffer_set_layout(Application_Links* app, Buffer_ID buffer_id, Layout_Function* layout_func);
|
||||
api(custom) function b32 file_clear_layout_cache(Application_Links* app, Buffer_ID buffer);
|
||||
api(custom) function b32 buffer_clear_layout_cache(Application_Links* app, Buffer_ID buffer_id);
|
||||
api(custom) function Layout_Function* buffer_get_layout(Application_Links* app, Buffer_ID buffer_id);
|
||||
api(custom) function b32 buffer_get_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64* value_out);
|
||||
api(custom) function b32 buffer_set_setting(Application_Links* app, Buffer_ID buffer_id, Buffer_Setting_ID setting, i64 value);
|
||||
|
@ -164,7 +164,7 @@ api(custom) function Rect_f32 draw_set_clip(Application_Links* app, Rect_f32 new
|
|||
api(custom) function Text_Layout_ID text_layout_create(Application_Links* app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point);
|
||||
api(custom) function Rect_f32 text_layout_region(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
api(custom) function Buffer_ID text_layout_get_buffer(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
api(custom) function Interval_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
api(custom) function Range_i64 text_layout_get_visible_range(Application_Links* app, Text_Layout_ID text_layout_id);
|
||||
api(custom) function Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number);
|
||||
api(custom) function Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos);
|
||||
api(custom) function void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Interval_i64 range, FColor color);
|
||||
|
|
Loading…
Reference in New Issue