2019-04-01 00:36:09 +00:00
|
|
|
/*
|
|
|
|
* Mr. 4th Dimention - Allen Webster
|
|
|
|
*
|
|
|
|
* 31.03.2019
|
|
|
|
*
|
|
|
|
* Text layout representation
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TOP
|
|
|
|
|
|
|
|
internal void
|
2019-10-22 04:10:29 +00:00
|
|
|
text_layout_init(Thread_Context *tctx, Text_Layout_Container *container){
|
2019-04-01 00:36:09 +00:00
|
|
|
block_zero_struct(container);
|
2019-10-22 04:10:29 +00:00
|
|
|
container->node_arena = reserve_arena(tctx);
|
|
|
|
container->table = make_table_u64_u64(tctx->allocator, 20);
|
2019-04-01 00:36:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal Text_Layout*
|
|
|
|
text_layout_new__alloc_layout(Text_Layout_Container *container){
|
2019-09-02 18:59:36 +00:00
|
|
|
Text_Layout *node = container->free_nodes;
|
2019-04-01 00:36:09 +00:00
|
|
|
if (node == 0){
|
2019-10-01 02:06:21 +00:00
|
|
|
node = push_array(container->node_arena, Text_Layout, 1);
|
2019-04-01 00:36:09 +00:00
|
|
|
}
|
|
|
|
else{
|
2019-09-02 18:59:36 +00:00
|
|
|
sll_stack_pop(container->free_nodes);
|
2019-04-01 00:36:09 +00:00
|
|
|
}
|
2019-09-02 18:59:36 +00:00
|
|
|
return(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void
|
2019-10-22 04:10:29 +00:00
|
|
|
text_layout_release(Thread_Context *tctx, Models *models, Text_Layout_Container *container, Text_Layout *layout){
|
|
|
|
release_arena(tctx, layout->arena);
|
2019-09-02 18:59:36 +00:00
|
|
|
sll_stack_push(container->free_nodes, layout);
|
2019-04-01 00:36:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal Text_Layout_ID
|
2019-10-01 02:06:21 +00:00
|
|
|
text_layout_new(Text_Layout_Container *container, Arena *arena,
|
2019-09-02 18:59:36 +00:00
|
|
|
Buffer_ID buffer_id, Buffer_Point point,
|
2019-10-29 04:27:20 +00:00
|
|
|
Range_i64 visible_range, Interval_i64 visible_line_number_range,
|
|
|
|
Rect_f32 rect, FColor *item_colors, Layout_Function *layout_func){
|
2019-04-01 00:36:09 +00:00
|
|
|
Text_Layout *new_layout_data = text_layout_new__alloc_layout(container);
|
2019-09-02 18:59:36 +00:00
|
|
|
new_layout_data->arena = arena;
|
2019-04-01 00:36:09 +00:00
|
|
|
new_layout_data->buffer_id = buffer_id;
|
|
|
|
new_layout_data->point = point;
|
2019-09-02 18:59:36 +00:00
|
|
|
new_layout_data->visible_range = visible_range;
|
|
|
|
new_layout_data->visible_line_number_range = visible_line_number_range;
|
|
|
|
new_layout_data->rect = rect;
|
2019-08-01 03:16:53 +00:00
|
|
|
new_layout_data->item_colors = item_colors;
|
2019-10-29 04:27:20 +00:00
|
|
|
new_layout_data->layout_func = layout_func;
|
2019-04-01 00:36:09 +00:00
|
|
|
Text_Layout_ID new_id = ++container->id_counter;
|
2019-09-02 18:59:36 +00:00
|
|
|
table_insert(&container->table, new_id, (u64)PtrAsInt(new_layout_data));
|
2019-04-01 00:36:09 +00:00
|
|
|
return(new_id);
|
|
|
|
}
|
|
|
|
|
2019-09-02 18:59:36 +00:00
|
|
|
internal Text_Layout*
|
|
|
|
text_layout_get(Text_Layout_Container *container, Text_Layout_ID id){
|
|
|
|
Text_Layout *result = 0;
|
|
|
|
Table_Lookup lookup = table_lookup(&container->table, id);
|
|
|
|
if (lookup.found_match){
|
|
|
|
u64 ptr_val = 0;
|
|
|
|
table_read(&container->table, lookup, &ptr_val);
|
|
|
|
result = (Text_Layout*)IntAsPtr(ptr_val);
|
2019-04-01 00:36:09 +00:00
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal b32
|
2019-10-22 04:10:29 +00:00
|
|
|
text_layout_erase(Thread_Context *tctx, Models *models, Text_Layout_Container *container, Text_Layout_ID id){
|
2019-04-01 00:36:09 +00:00
|
|
|
b32 result = false;
|
2019-09-02 18:59:36 +00:00
|
|
|
Table_Lookup lookup = table_lookup(&container->table, id);
|
|
|
|
if (lookup.found_match){
|
|
|
|
u64 ptr_val = 0;
|
|
|
|
table_read(&container->table, lookup, &ptr_val);
|
|
|
|
Text_Layout *ptr = (Text_Layout*)IntAsPtr(ptr_val);
|
2019-10-22 04:10:29 +00:00
|
|
|
text_layout_release(tctx, models, container, ptr);
|
2019-09-02 18:59:36 +00:00
|
|
|
table_erase(&container->table, lookup);
|
2019-04-01 00:36:09 +00:00
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2019-09-02 18:59:36 +00:00
|
|
|
////////////////////////////////
|
|
|
|
|
|
|
|
internal void
|
2019-10-22 04:10:29 +00:00
|
|
|
text_layout_render(Thread_Context *tctx, Models *models, Text_Layout *layout){
|
2019-09-02 18:59:36 +00:00
|
|
|
Editing_File *file = imp_get_file(models, layout->buffer_id);
|
|
|
|
if (file != 0){
|
|
|
|
Render_Target *target = models->target;
|
|
|
|
Color_Table color_table = models->color_table;
|
2019-09-02 21:32:52 +00:00
|
|
|
Face *face = file_get_face(models, file);
|
2019-09-02 18:59:36 +00:00
|
|
|
f32 width = rect_width(layout->rect);
|
|
|
|
|
2019-10-23 01:25:40 +00:00
|
|
|
ARGB_Color special_color = color_table.vals[Stag_Special_Character];
|
|
|
|
ARGB_Color ghost_color = color_table.vals[Stag_Ghost_Character];
|
2019-09-02 18:59:36 +00:00
|
|
|
|
|
|
|
Vec2_f32 shift_p = layout->rect.p0 - layout->point.pixel_shift;
|
|
|
|
i64 first_index = layout->visible_range.first;
|
|
|
|
i64 line_number = layout->visible_line_number_range.min;
|
|
|
|
i64 line_number_last = layout->visible_line_number_range.max;
|
2019-10-29 04:27:20 +00:00
|
|
|
Layout_Function *layout_func = layout->layout_func;
|
2019-09-02 18:59:36 +00:00
|
|
|
for (;line_number <= line_number_last; line_number += 1){
|
2019-10-29 04:27:20 +00:00
|
|
|
Layout_Item_List line = file_get_line_layout(tctx, models, file,
|
|
|
|
layout_func, width, face,
|
|
|
|
line_number);
|
|
|
|
for (Layout_Item_Block *block = line.first;
|
2019-09-02 18:59:36 +00:00
|
|
|
block != 0;
|
|
|
|
block = block->next){
|
2019-10-29 04:27:20 +00:00
|
|
|
Layout_Item *item = block->items;
|
2019-09-02 18:59:36 +00:00
|
|
|
i64 count = block->count;
|
2019-10-23 01:25:40 +00:00
|
|
|
FColor *item_colors = layout->item_colors;
|
2019-09-02 18:59:36 +00:00
|
|
|
for (i32 i = 0; i < count; i += 1, item += 1){
|
|
|
|
if (item->codepoint != 0){
|
2019-10-23 01:25:40 +00:00
|
|
|
ARGB_Color color = 0;
|
2019-10-29 04:27:20 +00:00
|
|
|
if (HasFlag(item->flags, LayoutItemFlag_Special_Character)){
|
2019-10-23 01:25:40 +00:00
|
|
|
color = special_color;
|
|
|
|
}
|
2019-10-29 04:27:20 +00:00
|
|
|
else if (HasFlag(item->flags, LayoutItemFlag_Ghost_Character)){
|
2019-10-23 01:25:40 +00:00
|
|
|
color = ghost_color;
|
2019-09-02 18:59:36 +00:00
|
|
|
}
|
|
|
|
else{
|
2019-10-23 01:25:40 +00:00
|
|
|
FColor fcolor = item_colors[item->index - first_index];
|
|
|
|
color = finalize_color(color_table, fcolor);
|
2019-09-02 18:59:36 +00:00
|
|
|
}
|
|
|
|
Vec2_f32 p = item->rect.p0 + shift_p;
|
2019-10-23 01:25:40 +00:00
|
|
|
draw_font_glyph(target, face, item->codepoint,
|
|
|
|
p, color, GlyphFlag_None);
|
2019-09-02 18:59:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shift_p.y += line.height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-01 00:36:09 +00:00
|
|
|
// BOTTOM
|