/* * 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){ table_free(&slot->face->advance_map.codepoint_to_index.table); linalloc_clear(&slot->arena); } block_zero_struct(slot); sll_stack_push(set->free_face_slots, slot); } internal void font_set_init(Font_Set *set){ block_zero_struct(set); set->arena = make_arena_system(); set->next_id_counter = 1; set->id_to_slot_table = make_table_u64_u64(set->arena.base_allocator, 40); set->scale_factor = system_get_screen_scale_factor(); } internal Face* font_set_new_face(Font_Set *set, Face_Description *description){ Arena arena = make_arena_system(); Face *face = font_make_face(&arena, description, set->scale_factor); if (face != 0){ Font_Face_Slot *slot = font_set__alloc_face_slot(set); slot->arena = arena; slot->face = face; Face_ID new_id = font_set__alloc_face_id(set); face->id = new_id; table_insert(&set->id_to_slot_table, new_id, (u64)slot); } else{ linalloc_clear(&arena); } return(face); } 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){ i32 version_number = slot->face->version_number; Arena arena = make_arena_system(); Face *face = font_make_face(&arena, description, set->scale_factor); if (face != 0){ linalloc_clear(&slot->arena); slot->arena = arena; slot->face = face; face->version_number = version_number + 1; face->id = id; result = true; } else{ linalloc_clear(&arena); } } return(result); } // BOTTOM