From 5fc89ba45a150afb2bb377e5fdc5b83885cb975a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 31 Mar 2019 23:40:24 -0700 Subject: [PATCH] buffer space <-> layout space conversions; on screen range and height in text layout --- 4coder_base_types.cpp | 5 ++++ 4coder_default_hooks.cpp | 30 ++++++++++++------- 4coder_generated/app_functions.h | 20 +++++++++++-- 4ed_api_implementation.cpp | 50 ++++++++++++++++++++++++-------- 4ed_buffer.cpp | 1 + 4ed_buffer.h | 1 + 4ed_text_layout.cpp | 4 ++- 4ed_text_layout.h | 2 ++ 8 files changed, 87 insertions(+), 26 deletions(-) diff --git a/4coder_base_types.cpp b/4coder_base_types.cpp index 5eb1a70a..56039428 100644 --- a/4coder_base_types.cpp +++ b/4coder_base_types.cpp @@ -1034,6 +1034,11 @@ rect_width(f32_Rect rect){ return(rect.x1 - rect.x0); } +static Vec2 +rect_dim(f32_Rect rect){ + return(V2(rect.x1 - rect.x0, rect.y1 - rect.y0)); +} + static i32_Rect intersection_of(i32_Rect a, i32_Rect b) { diff --git a/4coder_default_hooks.cpp b/4coder_default_hooks.cpp index 1938ceb2..cd45ffc8 100644 --- a/4coder_default_hooks.cpp +++ b/4coder_default_hooks.cpp @@ -333,6 +333,16 @@ buffer_position_from_scroll_position(Application_Links *app, View_ID view_id, Ve return(result); } +static i32 +abs_position_from_buffer_point(Application_Links *app, View_ID view_id, Buffer_Point buffer_point){ + Full_Cursor cursor = {}; + view_compute_cursor(app, view_id, seek_line_char(buffer_point.line_number, 0), &cursor); + view_compute_cursor(app, view_id, seek_wrapped_xy(buffer_point.pixel_shift.x, + buffer_point.pixel_shift.y + cursor.wrapped_y, false), + &cursor); + return(cursor.pos); +} + static void default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View_ID view_id, Rect_i32 view_inner_rect){ Buffer_ID buffer_id = 0; @@ -340,22 +350,22 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View Rect_i32 sub_region = i32R(0, 0, rect_width(view_inner_rect), rect_height(view_inner_rect)); sub_region = default_view_buffer_region(app, view_id, sub_region); - Rect_i32 buffer_rect = {}; - buffer_rect.p0 = view_inner_rect.p0 + sub_region.p0; - buffer_rect.p1 = view_inner_rect.p0 + sub_region.p1; - buffer_rect.x1 = clamp_top(buffer_rect.x1, view_inner_rect.x1); - buffer_rect.y1 = clamp_top(buffer_rect.y1, view_inner_rect.y1); - buffer_rect.x0 = clamp_top(buffer_rect.x0, buffer_rect.x1); - buffer_rect.y0 = clamp_top(buffer_rect.y0, buffer_rect.y1); + Rect_f32 buffer_rect = {}; + buffer_rect.p0 = V2(view_inner_rect.p0 + sub_region.p0); + buffer_rect.p1 = V2(view_inner_rect.p0 + sub_region.p1); + buffer_rect = intersection_of(buffer_rect, f32R(view_inner_rect)); GUI_Scroll_Vars scroll = {}; view_get_scroll_vars(app, view_id, &scroll); Buffer_Point buffer_point = buffer_position_from_scroll_position(app, view_id, scroll.scroll_p); - Range on_screen_range = {}; Text_Layout_ID text_layout_id = 0; - compute_render_layout(app, view_id, buffer_id, buffer_rect, buffer_point, - &on_screen_range, &text_layout_id); + + compute_render_layout(app, view_id, buffer_id, buffer_rect.p0, rect_dim(buffer_rect), buffer_point, + max_i32, &text_layout_id); + + Range on_screen_range = {}; + text_layout_get_on_screen_range(app, view_id, &on_screen_range); View_Summary view = get_view(app, view_id, AccessAll); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessAll); diff --git a/4coder_generated/app_functions.h b/4coder_generated/app_functions.h index 2a8b8e98..4e8fba9b 100644 --- a/4coder_generated/app_functions.h +++ b/4coder_generated/app_functions.h @@ -171,8 +171,10 @@ struct Application_Links; #define TEXT_LAYOUT_GET_BUFFER_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out) #define TEXT_LAYOUT_BUFFER_POINT_TO_LAYOUT_POINT_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out) #define TEXT_LAYOUT_LAYOUT_POINT_TO_BUFFER_POINT_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out) +#define TEXT_LAYOUT_GET_ON_SCREEN_RANGE_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Range *on_screen_range_out) +#define TEXT_LAYOUT_GET_HEIGHT_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, f32 *height_out) #define TEXT_LAYOUT_FREE_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id) -#define COMPUTE_RENDER_LAYOUT_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Rect_i32 screen_rect, Buffer_Point buffer_point, Range *on_screen_range_out, Text_Layout_ID *text_layout_id_out) +#define COMPUTE_RENDER_LAYOUT_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last, Text_Layout_ID *text_layout_id_out) #define DRAW_RENDER_LAYOUT_SIG(n) void n(Application_Links *app, View_ID view_id) #define OPEN_COLOR_PICKER_SIG(n) void n(Application_Links *app, color_picker *picker) #define ANIMATE_IN_N_MILLISECONDS_SIG(n) void n(Application_Links *app, u32 n) @@ -350,6 +352,8 @@ typedef GET_DEFAULT_FONT_FOR_VIEW_SIG(Get_Default_Font_For_View_Function); typedef TEXT_LAYOUT_GET_BUFFER_SIG(Text_Layout_Get_Buffer_Function); typedef TEXT_LAYOUT_BUFFER_POINT_TO_LAYOUT_POINT_SIG(Text_Layout_Buffer_Point_To_Layout_Point_Function); typedef TEXT_LAYOUT_LAYOUT_POINT_TO_BUFFER_POINT_SIG(Text_Layout_Layout_Point_To_Buffer_Point_Function); +typedef TEXT_LAYOUT_GET_ON_SCREEN_RANGE_SIG(Text_Layout_Get_On_Screen_Range_Function); +typedef TEXT_LAYOUT_GET_HEIGHT_SIG(Text_Layout_Get_Height_Function); typedef TEXT_LAYOUT_FREE_SIG(Text_Layout_Free_Function); typedef COMPUTE_RENDER_LAYOUT_SIG(Compute_Render_Layout_Function); typedef DRAW_RENDER_LAYOUT_SIG(Draw_Render_Layout_Function); @@ -531,6 +535,8 @@ Get_Default_Font_For_View_Function *get_default_font_for_view; Text_Layout_Get_Buffer_Function *text_layout_get_buffer; Text_Layout_Buffer_Point_To_Layout_Point_Function *text_layout_buffer_point_to_layout_point; Text_Layout_Layout_Point_To_Buffer_Point_Function *text_layout_layout_point_to_buffer_point; +Text_Layout_Get_On_Screen_Range_Function *text_layout_get_on_screen_range; +Text_Layout_Get_Height_Function *text_layout_get_height; Text_Layout_Free_Function *text_layout_free; Compute_Render_Layout_Function *compute_render_layout; Draw_Render_Layout_Function *draw_render_layout; @@ -711,6 +717,8 @@ Get_Default_Font_For_View_Function *get_default_font_for_view_; Text_Layout_Get_Buffer_Function *text_layout_get_buffer_; Text_Layout_Buffer_Point_To_Layout_Point_Function *text_layout_buffer_point_to_layout_point_; Text_Layout_Layout_Point_To_Buffer_Point_Function *text_layout_layout_point_to_buffer_point_; +Text_Layout_Get_On_Screen_Range_Function *text_layout_get_on_screen_range_; +Text_Layout_Get_Height_Function *text_layout_get_height_; Text_Layout_Free_Function *text_layout_free_; Compute_Render_Layout_Function *compute_render_layout_; Draw_Render_Layout_Function *draw_render_layout_; @@ -899,6 +907,8 @@ app_links->get_default_font_for_view_ = Get_Default_Font_For_View;\ app_links->text_layout_get_buffer_ = Text_Layout_Get_Buffer;\ app_links->text_layout_buffer_point_to_layout_point_ = Text_Layout_Buffer_Point_To_Layout_Point;\ app_links->text_layout_layout_point_to_buffer_point_ = Text_Layout_Layout_Point_To_Buffer_Point;\ +app_links->text_layout_get_on_screen_range_ = Text_Layout_Get_On_Screen_Range;\ +app_links->text_layout_get_height_ = Text_Layout_Get_Height;\ app_links->text_layout_free_ = Text_Layout_Free;\ app_links->compute_render_layout_ = Compute_Render_Layout;\ app_links->draw_render_layout_ = Draw_Render_Layout;\ @@ -1079,8 +1089,10 @@ static Face_ID get_default_font_for_view(Application_Links *app, View_ID view_id static b32 text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out){return(app->text_layout_get_buffer(app, text_layout_id, buffer_id_out));} static b32 text_layout_buffer_point_to_layout_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out){return(app->text_layout_buffer_point_to_layout_point(app, text_layout_id, buffer_relative_p, p_out));} static b32 text_layout_layout_point_to_buffer_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out){return(app->text_layout_layout_point_to_buffer_point(app, text_layout_id, layout_relative_p, p_out));} +static b32 text_layout_get_on_screen_range(Application_Links *app, Text_Layout_ID text_layout_id, Range *on_screen_range_out){return(app->text_layout_get_on_screen_range(app, text_layout_id, on_screen_range_out));} +static b32 text_layout_get_height(Application_Links *app, Text_Layout_ID text_layout_id, f32 *height_out){return(app->text_layout_get_height(app, text_layout_id, height_out));} static b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_free(app, text_layout_id));} -static b32 compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Rect_i32 screen_rect, Buffer_Point buffer_point, Range *on_screen_range_out, Text_Layout_ID *text_layout_id_out){return(app->compute_render_layout(app, view_id, buffer_id, screen_rect, buffer_point, on_screen_range_out, text_layout_id_out));} +static b32 compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last, Text_Layout_ID *text_layout_id_out){return(app->compute_render_layout(app, view_id, buffer_id, screen_p, layout_dim, buffer_point, one_past_last, text_layout_id_out));} static void draw_render_layout(Application_Links *app, View_ID view_id){(app->draw_render_layout(app, view_id));} static void open_color_picker(Application_Links *app, color_picker *picker){(app->open_color_picker(app, picker));} static void animate_in_n_milliseconds(Application_Links *app, u32 n){(app->animate_in_n_milliseconds(app, n));} @@ -1259,8 +1271,10 @@ static Face_ID get_default_font_for_view(Application_Links *app, View_ID view_id static b32 text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out){return(app->text_layout_get_buffer_(app, text_layout_id, buffer_id_out));} static b32 text_layout_buffer_point_to_layout_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out){return(app->text_layout_buffer_point_to_layout_point_(app, text_layout_id, buffer_relative_p, p_out));} static b32 text_layout_layout_point_to_buffer_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out){return(app->text_layout_layout_point_to_buffer_point_(app, text_layout_id, layout_relative_p, p_out));} +static b32 text_layout_get_on_screen_range(Application_Links *app, Text_Layout_ID text_layout_id, Range *on_screen_range_out){return(app->text_layout_get_on_screen_range_(app, text_layout_id, on_screen_range_out));} +static b32 text_layout_get_height(Application_Links *app, Text_Layout_ID text_layout_id, f32 *height_out){return(app->text_layout_get_height_(app, text_layout_id, height_out));} static b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_free_(app, text_layout_id));} -static b32 compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Rect_i32 screen_rect, Buffer_Point buffer_point, Range *on_screen_range_out, Text_Layout_ID *text_layout_id_out){return(app->compute_render_layout_(app, view_id, buffer_id, screen_rect, buffer_point, on_screen_range_out, text_layout_id_out));} +static b32 compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last, Text_Layout_ID *text_layout_id_out){return(app->compute_render_layout_(app, view_id, buffer_id, screen_p, layout_dim, buffer_point, one_past_last, text_layout_id_out));} static void draw_render_layout(Application_Links *app, View_ID view_id){(app->draw_render_layout_(app, view_id));} static void open_color_picker(Application_Links *app, color_picker *picker){(app->open_color_picker_(app, picker));} static void animate_in_n_milliseconds(Application_Links *app, u32 n){(app->animate_in_n_milliseconds_(app, n));} diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 05e38e62..a3839822 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -4664,6 +4664,30 @@ Text_Layout_Layout_Point_To_Buffer_Point(Application_Links *app, Text_Layout_ID return(result); } +API_EXPORT b32 +Text_Layout_Get_On_Screen_Range(Application_Links *app, Text_Layout_ID text_layout_id, Range *on_screen_range_out){ + Models *models = (Models*)app->cmd_context; + Text_Layout layout = {}; + b32 result = false; + if (text_layout_get(&models->text_layouts, text_layout_id, &layout)){ + *on_screen_range_out = layout.on_screen_range; + result = true; + } + return(result); +} + +API_EXPORT b32 +Text_Layout_Get_Height(Application_Links *app, Text_Layout_ID text_layout_id, f32 *height_out){ + Models *models = (Models*)app->cmd_context; + Text_Layout layout = {}; + b32 result = false; + if (text_layout_get(&models->text_layouts, text_layout_id, &layout)){ + *height_out = layout.height; + result = true; + } + return(result); +} + API_EXPORT b32 Text_Layout_Free(Application_Links *app, Text_Layout_ID text_layout_id){ Models *models = (Models*)app->cmd_context; @@ -4671,22 +4695,22 @@ Text_Layout_Free(Application_Links *app, Text_Layout_ID text_layout_id){ } API_EXPORT b32 -Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Rect_i32 screen_rect, Buffer_Point buffer_point, Range *on_screen_range_out, Text_Layout_ID *text_layout_id_out){ +Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last, Text_Layout_ID *text_layout_id_out){ Models *models = (Models*)app->cmd_context; System_Functions *system = models->system; View *view = imp_get_view(models, view_id); Editing_File *file = imp_get_file(models, buffer_id); b32 result = false; if (view_api_check_view(view) && buffer_api_check_file(file)){ - i32 line_height = view->line_height; + f32 line_height = (f32)view->line_height; f32 max_x = (f32)file->settings.display_width; - i32 max_y = screen_rect.y1 - screen_rect.y0 + line_height; + f32 max_y = layout_dim.y + line_height; f32 left_side_space = 0; // TODO(allen): Don't force me to over-allocate! Write a looser buffer render thingy. - f32 screen_width = (f32)rect_width(screen_rect); - f32 screen_height = (f32)rect_height(screen_rect); + f32 screen_width = layout_dim.x; + f32 screen_height = layout_dim.y; f32 smallest_char_width = 6.f; f32 smallest_char_height = 8.f; i32 max = (i32)(screen_width*screen_height/(smallest_char_width*smallest_char_height))*2; @@ -4727,8 +4751,8 @@ Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_ params.items = items; params.max = max; params.count = &item_count; - params.port_x = (f32)screen_rect.x0 + left_side_space; - params.port_y = (f32)screen_rect.y0; + params.port_x = (f32)screen_p.x + left_side_space; + params.port_y = (f32)screen_p.y; params.clip_w = view_width(models, view) - left_side_space; params.scroll_x = scroll_x; params.scroll_y = scroll_y; @@ -4740,6 +4764,7 @@ Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_ params.font = font; params.virtual_white = file->settings.virtual_white; params.wrap_slashes = file->settings.wrap_indicator; + params.one_past_last_abs_pos = one_past_last; Buffer_Render_State state = {}; Buffer_Layout_Stop stop = {}; @@ -4791,17 +4816,18 @@ Compute_Render_Layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_ Range range = {render_cursor.pos, end_pos}; view->render.view_rect = view->panel->rect_inner; - view->render.buffer_rect = screen_rect; + view->render.buffer_rect = i32R(f32R(screen_p.x, screen_p.y, + screen_p.x + layout_dim.x, screen_p.y + layout_dim.y)); view->render.cursor = render_cursor; view->render.range = range; view->render.items = items; view->render.item_count = item_count; - if (on_screen_range_out != 0){ - *on_screen_range_out = range; - } if (text_layout_id_out != 0){ - *text_layout_id_out = text_layout_new(&models->mem.heap, &models->text_layouts, buffer_id, buffer_point); + Buffer_Render_Item *render_item_first = items; + Buffer_Render_Item *render_item_last = items + item_count - 1; + f32 height = render_item_last->y1 - render_item_first->y0; + *text_layout_id_out = text_layout_new(&models->mem.heap, &models->text_layouts, buffer_id, buffer_point, range, height); } } return(result); diff --git a/4ed_buffer.cpp b/4ed_buffer.cpp index 33c36f1b..4866092a 100644 --- a/4ed_buffer.cpp +++ b/4ed_buffer.cpp @@ -1660,6 +1660,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } S.size = buffer_size(params.buffer); + S.size = Min(S.size, params.one_past_last_abs_pos); S.shift_x = params.port_x - params.scroll_x; S.shift_y = params.port_y - params.scroll_y; diff --git a/4ed_buffer.h b/4ed_buffer.h index cb251d51..f63a1eec 100644 --- a/4ed_buffer.h +++ b/4ed_buffer.h @@ -203,6 +203,7 @@ struct Buffer_Render_Params{ Font_Pointers font; b32 virtual_white; i32 wrap_slashes; + i32 one_past_last_abs_pos; }; struct Buffer_Render_State{ diff --git a/4ed_text_layout.cpp b/4ed_text_layout.cpp index 0492f653..0f660a78 100644 --- a/4ed_text_layout.cpp +++ b/4ed_text_layout.cpp @@ -28,10 +28,12 @@ text_layout_new__alloc_layout(Text_Layout_Container *container){ } internal Text_Layout_ID -text_layout_new(Heap *heap, Text_Layout_Container *container, Buffer_ID buffer_id, Buffer_Point point){ +text_layout_new(Heap *heap, Text_Layout_Container *container, Buffer_ID buffer_id, Buffer_Point point, Range on_screen_range, f32 height){ Text_Layout *new_layout_data = text_layout_new__alloc_layout(container); new_layout_data->buffer_id = buffer_id; new_layout_data->point = point; + new_layout_data->on_screen_range = on_screen_range; + new_layout_data->height = height; Text_Layout_ID new_id = ++container->id_counter; insert_u32_Ptr_table(heap, &container->table, new_id, new_layout_data); return(new_id); diff --git a/4ed_text_layout.h b/4ed_text_layout.h index f3b8dde4..29986479 100644 --- a/4ed_text_layout.h +++ b/4ed_text_layout.h @@ -21,6 +21,8 @@ struct Text_Layout{ // system that attempts to query the layout for hit testing. Buffer_ID buffer_id; Buffer_Point point; + Range on_screen_range; + f32 height; }; union Text_Layout_Node{