/* * Mr. 4th Dimention - Allen Webster * * 23.07.2019 * * Type for organizating the set of all loaded font faces. * */ // TOP internal Face_ID font_set__alloc_face_id(Font_Set *set){ Face_ID result = 0; if (set->free_ids != 0){ Font_Face_ID_Node *node = set->free_ids; result = node->id; sll_stack_pop(set->free_ids); sll_stack_push(set->free_id_nodes, node); } else{ result = set->next_id_counter; set->next_id_counter += 1; } return(result); } internal void font_set__free_face_id(Font_Set *set, Face_ID id){ if (id + 1 == set->next_id_counter){ set->next_id_counter -= 1; } else{ Font_Face_ID_Node *node = 0; if (set->free_id_nodes == 0){ node = push_array(&set->arena, Font_Face_ID_Node, 1); } else{ node = set->free_id_nodes; sll_stack_pop(set->free_id_nodes); } sll_stack_push(set->free_ids, node); node->id = id; } } internal Font_Face_Slot* font_set__alloc_face_slot(Font_Set *set){ Font_Face_Slot *result = 0; if (set->free_face_slots == 0){ result = push_array(&set->arena, Font_Face_Slot, 1); } else{ result = set->free_face_slots; sll_stack_pop(set->free_face_slots); } return(result); } internal void font_set__free_face_slot(Font_Set *set, Font_Face_Slot *slot){ if (slot->arena.base_allocator != 0){ linalloc_clear(&slot->arena); } block_zero_struct(slot); sll_stack_push(set->free_face_slots, slot); } internal void font_set_init(System_Functions *system, Font_Set *set){ block_zero_struct(set); set->system = system; set->arena = make_arena_system(system); set->next_id_counter = 1; set->id_to_slot_table = make_table_u64_u64(set->arena.base_allocator, 40); } internal Face_ID font_set_new_face(Font_Set *set, Face_Description *description){ Face_ID result = 0; Arena arena = make_arena_system(set->system); Face *face = set->system->font_make_face(&arena, description); if (face != 0){ Font_Face_Slot *slot = font_set__alloc_face_slot(set); slot->arena = arena; slot->face = face; result = font_set__alloc_face_id(set); table_insert(&set->id_to_slot_table, result, (u64)slot); } else{ linalloc_clear(&arena); } return(result); } internal Font_Face_Slot* font_set__get_face_slot(Font_Set *set, Face_ID id){ Font_Face_Slot *result = 0; u64 slot_ptr_u64 = 0; if (table_read(&set->id_to_slot_table, id, &slot_ptr_u64)){ result = (Font_Face_Slot*)slot_ptr_u64; } return(result); } internal b32 font_set_release_face(Font_Set *set, Face_ID id){ b32 result = false; Font_Face_Slot *slot = font_set__get_face_slot(set, id); if (slot != 0){ table_erase(&set->id_to_slot_table, id); font_set__free_face_slot(set, slot); font_set__free_face_id(set, id); result = true; } return(result); } internal Face* font_set_face_from_id(Font_Set *set, Face_ID id){ Face *result = 0; Font_Face_Slot *slot = font_set__get_face_slot(set, id); if (slot != 0){ result = slot->face; } return(result); } internal Face_ID font_set_get_fallback_face(Font_Set *set){ Face_ID result = 0; for (Face_ID i = 1; i < set->next_id_counter; i += 1){ if (font_set__get_face_slot(set, i) != 0){ result = i; break; } } return(result); } internal Face_ID font_set_get_largest_id(Font_Set *set){ return(set->next_id_counter - 1); } internal b32 font_set_modify_face(Font_Set *set, Face_ID id, Face_Description *description){ b32 result = false; Font_Face_Slot *slot = font_set__get_face_slot(set, id); if (slot != 0){ Arena arena = make_arena_system(set->system); Face *face = set->system->font_make_face(&arena, description); if (face != 0){ linalloc_clear(&slot->arena); slot->arena = arena; slot->face = face; result = true; } else{ linalloc_clear(&arena); } } return(result); } // BOTTOM