mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-14 16:12:24 -07:00
f -> fnt
This commit is contained in:
+126
-126
@@ -10,16 +10,16 @@
|
||||
#include "third_party/blake2/blake2b.c"
|
||||
#endif
|
||||
|
||||
internal F_Hash
|
||||
f_hash_from_string(String8 string)
|
||||
internal U128
|
||||
fnt_hash_from_string(String8 string)
|
||||
{
|
||||
F_Hash result = {0};
|
||||
U128 result = {0};
|
||||
blake2b((U8 *)&result.u64[0], sizeof(result), string.str, string.size, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
f_little_hash_from_string(String8 string)
|
||||
fnt_little_hash_from_string(String8 string)
|
||||
{
|
||||
U64 result = 5381;
|
||||
for(U64 i = 0; i < string.size; i += 1)
|
||||
@@ -30,7 +30,7 @@ f_little_hash_from_string(String8 string)
|
||||
}
|
||||
|
||||
internal Vec2S32
|
||||
f_vertex_from_corner(Corner corner)
|
||||
fnt_vertex_from_corner(Corner corner)
|
||||
{
|
||||
Vec2S32 result = {0};
|
||||
switch(corner)
|
||||
@@ -47,27 +47,27 @@ f_vertex_from_corner(Corner corner)
|
||||
////////////////////////////////
|
||||
//~ rjf: Font Tags
|
||||
|
||||
internal F_Tag
|
||||
f_tag_zero(void)
|
||||
internal FNT_Tag
|
||||
fnt_tag_zero(void)
|
||||
{
|
||||
F_Tag result = {0};
|
||||
FNT_Tag result = {0};
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
f_tag_match(F_Tag a, F_Tag b)
|
||||
fnt_tag_match(FNT_Tag a, FNT_Tag b)
|
||||
{
|
||||
return a.u64[0] == b.u64[0] && a.u64[1] == b.u64[1];
|
||||
}
|
||||
|
||||
internal FP_Handle
|
||||
f_handle_from_tag(F_Tag tag)
|
||||
fnt_handle_from_tag(FNT_Tag tag)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size;
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&tag, &n->tag))
|
||||
{
|
||||
@@ -86,13 +86,13 @@ f_handle_from_tag(F_Tag tag)
|
||||
}
|
||||
|
||||
internal FP_Metrics
|
||||
f_fp_metrics_from_tag(F_Tag tag)
|
||||
fnt_fp_metrics_from_tag(FNT_Tag tag)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size;
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&tag, &n->tag))
|
||||
{
|
||||
@@ -110,15 +110,15 @@ f_fp_metrics_from_tag(F_Tag tag)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal F_Tag
|
||||
f_tag_from_path(String8 path)
|
||||
internal FNT_Tag
|
||||
fnt_tag_from_path(String8 path)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
//- rjf: produce tag from hash of path
|
||||
F_Tag result = {0};
|
||||
FNT_Tag result = {0};
|
||||
{
|
||||
F_Hash hash = f_hash_from_string(path);
|
||||
U128 hash = fnt_hash_from_string(path);
|
||||
MemoryCopy(&result, &hash, sizeof(result));
|
||||
result.u64[1] |= bit64;
|
||||
}
|
||||
@@ -127,9 +127,9 @@ f_tag_from_path(String8 path)
|
||||
U64 slot_idx = result.u64[1] % f_state->font_hash_table_size;
|
||||
|
||||
//- rjf: slot * tag -> existing node
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&result, &n->tag))
|
||||
{
|
||||
@@ -140,11 +140,11 @@ f_tag_from_path(String8 path)
|
||||
}
|
||||
|
||||
//- rjf: allocate & push new node if we don't have an existing one
|
||||
F_FontHashNode *new_node = 0;
|
||||
FNT_FontHashNode *new_node = 0;
|
||||
if(existing_node == 0)
|
||||
{
|
||||
F_FontHashSlot *slot = &f_state->font_hash_table[slot_idx];
|
||||
new_node = push_array(f_state->arena, F_FontHashNode, 1);
|
||||
FNT_FontHashSlot *slot = &f_state->font_hash_table[slot_idx];
|
||||
new_node = push_array(f_state->arena, FNT_FontHashNode, 1);
|
||||
new_node->tag = result;
|
||||
new_node->handle = fp_font_open(path);
|
||||
new_node->metrics = fp_metrics_from_font(new_node->handle);
|
||||
@@ -157,15 +157,15 @@ f_tag_from_path(String8 path)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal F_Tag
|
||||
f_tag_from_static_data_string(String8 *data_ptr)
|
||||
internal FNT_Tag
|
||||
fnt_tag_from_static_data_string(String8 *data_ptr)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
//- rjf: produce tag hash of ptr
|
||||
F_Tag result = {0};
|
||||
FNT_Tag result = {0};
|
||||
{
|
||||
F_Hash hash = f_hash_from_string(str8((U8 *)&data_ptr, sizeof(String8 *)));
|
||||
U128 hash = fnt_hash_from_string(str8((U8 *)&data_ptr, sizeof(String8 *)));
|
||||
MemoryCopy(&result, &hash, sizeof(result));
|
||||
result.u64[1] &= ~bit64;
|
||||
}
|
||||
@@ -174,9 +174,9 @@ f_tag_from_static_data_string(String8 *data_ptr)
|
||||
U64 slot_idx = result.u64[1] % f_state->font_hash_table_size;
|
||||
|
||||
//- rjf: slot * tag -> existing node
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&result, &n->tag))
|
||||
{
|
||||
@@ -187,11 +187,11 @@ f_tag_from_static_data_string(String8 *data_ptr)
|
||||
}
|
||||
|
||||
//- rjf: allocate & push new node if we don't have an existing one
|
||||
F_FontHashNode *new_node = 0;
|
||||
FNT_FontHashNode *new_node = 0;
|
||||
if(existing_node == 0)
|
||||
{
|
||||
F_FontHashSlot *slot = &f_state->font_hash_table[slot_idx];
|
||||
new_node = push_array(f_state->arena, F_FontHashNode, 1);
|
||||
FNT_FontHashSlot *slot = &f_state->font_hash_table[slot_idx];
|
||||
new_node = push_array(f_state->arena, FNT_FontHashNode, 1);
|
||||
new_node->tag = result;
|
||||
new_node->handle = fp_font_open_from_static_data_string(data_ptr);
|
||||
new_node->metrics = fp_metrics_from_font(new_node->handle);
|
||||
@@ -205,15 +205,15 @@ f_tag_from_static_data_string(String8 *data_ptr)
|
||||
}
|
||||
|
||||
internal String8
|
||||
f_path_from_tag(F_Tag tag)
|
||||
fnt_path_from_tag(FNT_Tag tag)
|
||||
{
|
||||
//- rjf: tag -> slot index
|
||||
U64 slot_idx = tag.u64[1] % f_state->font_hash_table_size;
|
||||
|
||||
//- rjf: slot * tag -> existing node
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&tag, &n->tag))
|
||||
{
|
||||
@@ -237,7 +237,7 @@ f_path_from_tag(F_Tag tag)
|
||||
//~ rjf: Atlas
|
||||
|
||||
internal Rng2S16
|
||||
f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
fnt_atlas_region_alloc(Arena *arena, FNT_Atlas *atlas, Vec2S16 needed_size)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -245,13 +245,13 @@ f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
Vec2S16 region_p0 = {0};
|
||||
Vec2S16 region_sz = {0};
|
||||
Corner node_corner = Corner_Invalid;
|
||||
F_AtlasRegionNode *node = 0;
|
||||
FNT_AtlasRegionNode *node = 0;
|
||||
{
|
||||
Vec2S16 n_supported_size = atlas->root_dim;
|
||||
for(F_AtlasRegionNode *n = atlas->root, *next = 0; n != 0; n = next, next = 0)
|
||||
for(FNT_AtlasRegionNode *n = atlas->root, *next = 0; n != 0; n = next, next = 0)
|
||||
{
|
||||
// rjf: we've traversed to a taken node.
|
||||
if(n->flags & F_AtlasRegionNodeFlag_Taken)
|
||||
if(n->flags & FNT_AtlasRegionNodeFlag_Taken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -269,14 +269,14 @@ f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
Vec2S16 child_size = v2s16(n_supported_size.x/2, n_supported_size.y/2);
|
||||
|
||||
// rjf: find best next child
|
||||
F_AtlasRegionNode *best_child = 0;
|
||||
FNT_AtlasRegionNode *best_child = 0;
|
||||
if(child_size.x >= needed_size.x && child_size.y >= needed_size.y)
|
||||
{
|
||||
for(Corner corner = (Corner)0; corner < Corner_COUNT; corner = (Corner)(corner+1))
|
||||
{
|
||||
if(n->children[corner] == 0)
|
||||
{
|
||||
n->children[corner] = push_array(arena, F_AtlasRegionNode, 1);
|
||||
n->children[corner] = push_array(arena, FNT_AtlasRegionNode, 1);
|
||||
n->children[corner]->parent = n;
|
||||
n->children[corner]->max_free_size[Corner_00] =
|
||||
n->children[corner]->max_free_size[Corner_01] =
|
||||
@@ -288,7 +288,7 @@ f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
{
|
||||
best_child = n->children[corner];
|
||||
node_corner = corner;
|
||||
Vec2S32 side_vertex = f_vertex_from_corner(corner);
|
||||
Vec2S32 side_vertex = fnt_vertex_from_corner(corner);
|
||||
region_p0.x += side_vertex.x*child_size.x;
|
||||
region_p0.y += side_vertex.y*child_size.y;
|
||||
break;
|
||||
@@ -313,15 +313,15 @@ f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
//- rjf: we're taking the subtree rooted by `node`. mark up all parents
|
||||
if(node != 0 && node_corner != Corner_Invalid)
|
||||
{
|
||||
node->flags |= F_AtlasRegionNodeFlag_Taken;
|
||||
node->flags |= FNT_AtlasRegionNodeFlag_Taken;
|
||||
if(node->parent != 0)
|
||||
{
|
||||
MemoryZeroStruct(&node->parent->max_free_size[node_corner]);
|
||||
}
|
||||
for(F_AtlasRegionNode *p = node->parent; p != 0; p = p->parent)
|
||||
for(FNT_AtlasRegionNode *p = node->parent; p != 0; p = p->parent)
|
||||
{
|
||||
p->num_allocated_descendants += 1;
|
||||
F_AtlasRegionNode *parent = p->parent;
|
||||
FNT_AtlasRegionNode *parent = p->parent;
|
||||
if(parent != 0)
|
||||
{
|
||||
Corner p_corner = (p == parent->children[Corner_00] ? Corner_00 :
|
||||
@@ -354,7 +354,7 @@ f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size)
|
||||
}
|
||||
|
||||
internal void
|
||||
f_atlas_region_release(F_Atlas *atlas, Rng2S16 region)
|
||||
fnt_atlas_region_release(FNT_Atlas *atlas, Rng2S16 region)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -363,12 +363,12 @@ f_atlas_region_release(F_Atlas *atlas, Rng2S16 region)
|
||||
|
||||
//- rjf: map region to associated node
|
||||
Vec2S16 calc_region_size = {0};
|
||||
F_AtlasRegionNode *node = 0;
|
||||
FNT_AtlasRegionNode *node = 0;
|
||||
Corner node_corner = Corner_Invalid;
|
||||
{
|
||||
Vec2S16 n_p0 = v2s16(0, 0);
|
||||
Vec2S16 n_sz = atlas->root_dim;
|
||||
for(F_AtlasRegionNode *n = atlas->root, *next = 0; n != 0; n = next)
|
||||
for(FNT_AtlasRegionNode *n = atlas->root, *next = 0; n != 0; n = next)
|
||||
{
|
||||
// rjf: is the region within this node's boundaries? (either this node, or a descendant)
|
||||
if(n_p0.x <= region.p0.x && region.p0.x < n_p0.x+n_sz.x &&
|
||||
@@ -410,7 +410,7 @@ f_atlas_region_release(F_Atlas *atlas, Rng2S16 region)
|
||||
node_corner = next_corner;
|
||||
n_sz.x /= 2;
|
||||
n_sz.y /= 2;
|
||||
Vec2S32 side_vertex = f_vertex_from_corner(node_corner);
|
||||
Vec2S32 side_vertex = fnt_vertex_from_corner(node_corner);
|
||||
n_p0.x += side_vertex.x*n_sz.x;
|
||||
n_p0.y += side_vertex.y*n_sz.y;
|
||||
}
|
||||
@@ -425,15 +425,15 @@ f_atlas_region_release(F_Atlas *atlas, Rng2S16 region)
|
||||
//- rjf: free node
|
||||
if(node != 0 && node_corner != Corner_Invalid)
|
||||
{
|
||||
node->flags &= ~F_AtlasRegionNodeFlag_Taken;
|
||||
node->flags &= ~FNT_AtlasRegionNodeFlag_Taken;
|
||||
if(node->parent != 0)
|
||||
{
|
||||
node->parent->max_free_size[node_corner] = calc_region_size;
|
||||
}
|
||||
for(F_AtlasRegionNode *p = node->parent; p != 0; p = p->parent)
|
||||
for(FNT_AtlasRegionNode *p = node->parent; p != 0; p = p->parent)
|
||||
{
|
||||
p->num_allocated_descendants -= 1;
|
||||
F_AtlasRegionNode *parent = p->parent;
|
||||
FNT_AtlasRegionNode *parent = p->parent;
|
||||
if(parent != 0)
|
||||
{
|
||||
Corner p_corner = (p == parent->children[Corner_00] ? Corner_00 :
|
||||
@@ -462,61 +462,61 @@ f_atlas_region_release(F_Atlas *atlas, Rng2S16 region)
|
||||
////////////////////////////////
|
||||
//~ rjf: Piece Type Functions
|
||||
|
||||
internal F_Piece *
|
||||
f_piece_chunk_list_push_new(Arena *arena, F_PieceChunkList *list, U64 cap)
|
||||
internal FNT_Piece *
|
||||
fnt_piece_chunk_list_push_new(Arena *arena, FNT_PieceChunkList *list, U64 cap)
|
||||
{
|
||||
F_PieceChunkNode *node = list->last;
|
||||
FNT_PieceChunkNode *node = list->last;
|
||||
if(node == 0 || node->count >= node->cap)
|
||||
{
|
||||
node = push_array(arena, F_PieceChunkNode, 1);
|
||||
node->v = push_array_no_zero(arena, F_Piece, cap);
|
||||
node = push_array(arena, FNT_PieceChunkNode, 1);
|
||||
node->v = push_array_no_zero(arena, FNT_Piece, cap);
|
||||
node->cap = cap;
|
||||
SLLQueuePush(list->first, list->last, node);
|
||||
list->node_count += 1;
|
||||
}
|
||||
F_Piece *result = node->v + node->count;
|
||||
FNT_Piece *result = node->v + node->count;
|
||||
node->count += 1;
|
||||
list->total_piece_count += 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
f_piece_chunk_list_push(Arena *arena, F_PieceChunkList *list, U64 cap, F_Piece *piece)
|
||||
fnt_piece_chunk_list_push(Arena *arena, FNT_PieceChunkList *list, U64 cap, FNT_Piece *piece)
|
||||
{
|
||||
F_Piece *new_piece = f_piece_chunk_list_push_new(arena, list, cap);
|
||||
FNT_Piece *new_piece = fnt_piece_chunk_list_push_new(arena, list, cap);
|
||||
MemoryCopyStruct(new_piece, piece);
|
||||
}
|
||||
|
||||
internal F_PieceArray
|
||||
f_piece_array_from_chunk_list(Arena *arena, F_PieceChunkList *list)
|
||||
internal FNT_PieceArray
|
||||
fnt_piece_array_from_chunk_list(Arena *arena, FNT_PieceChunkList *list)
|
||||
{
|
||||
F_PieceArray array = {0};
|
||||
FNT_PieceArray array = {0};
|
||||
array.count = list->total_piece_count;
|
||||
array.v = push_array_no_zero(arena, F_Piece, array.count);
|
||||
array.v = push_array_no_zero(arena, FNT_Piece, array.count);
|
||||
U64 write_idx = 0;
|
||||
for(F_PieceChunkNode *node = list->first; node != 0; node = node->next)
|
||||
for(FNT_PieceChunkNode *node = list->first; node != 0; node = node->next)
|
||||
{
|
||||
MemoryCopy(array.v + write_idx, node->v, node->count * sizeof(F_Piece));
|
||||
MemoryCopy(array.v + write_idx, node->v, node->count * sizeof(FNT_Piece));
|
||||
write_idx += node->count;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
internal F_PieceArray
|
||||
f_piece_array_copy(Arena *arena, F_PieceArray *src)
|
||||
internal FNT_PieceArray
|
||||
fnt_piece_array_copy(Arena *arena, FNT_PieceArray *src)
|
||||
{
|
||||
F_PieceArray dst = {0};
|
||||
FNT_PieceArray dst = {0};
|
||||
dst.count = src->count;
|
||||
dst.v = push_array_no_zero(arena, F_Piece, dst.count);
|
||||
MemoryCopy(dst.v, src->v, sizeof(F_Piece)*dst.count);
|
||||
dst.v = push_array_no_zero(arena, FNT_Piece, dst.count);
|
||||
MemoryCopy(dst.v, src->v, sizeof(FNT_Piece)*dst.count);
|
||||
return dst;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Rasterization Cache
|
||||
|
||||
internal F_Hash2StyleRasterCacheNode *
|
||||
f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags)
|
||||
internal FNT_Hash2StyleRasterCacheNode *
|
||||
fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags)
|
||||
{
|
||||
//- rjf: tag * size -> style hash
|
||||
U64 style_hash = {0};
|
||||
@@ -529,16 +529,16 @@ f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags)
|
||||
*(U64 *)(&size_f64),
|
||||
(U64)flags,
|
||||
};
|
||||
style_hash = f_little_hash_from_string(str8((U8 *)buffer, sizeof(buffer)));
|
||||
style_hash = fnt_little_hash_from_string(str8((U8 *)buffer, sizeof(buffer)));
|
||||
}
|
||||
|
||||
//- rjf: style hash -> style node
|
||||
F_Hash2StyleRasterCacheNode *hash2style_node = 0;
|
||||
FNT_Hash2StyleRasterCacheNode *hash2style_node = 0;
|
||||
{
|
||||
ProfBegin("style hash -> style node");
|
||||
U64 slot_idx = style_hash%f_state->hash2style_slots_count;
|
||||
F_Hash2StyleRasterCacheSlot *slot = &f_state->hash2style_slots[slot_idx];
|
||||
for(F_Hash2StyleRasterCacheNode *n = slot->first;
|
||||
FNT_Hash2StyleRasterCacheSlot *slot = &f_state->hash2style_slots[slot_idx];
|
||||
for(FNT_Hash2StyleRasterCacheNode *n = slot->first;
|
||||
n != 0;
|
||||
n = n->hash_next)
|
||||
{
|
||||
@@ -550,15 +550,15 @@ f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags)
|
||||
}
|
||||
if(Unlikely(hash2style_node == 0))
|
||||
{
|
||||
F_Metrics metrics = f_metrics_from_tag_size(tag, size);
|
||||
hash2style_node = push_array(f_state->arena, F_Hash2StyleRasterCacheNode, 1);
|
||||
FNT_Metrics metrics = fnt_metrics_from_tag_size(tag, size);
|
||||
hash2style_node = push_array(f_state->arena, FNT_Hash2StyleRasterCacheNode, 1);
|
||||
DLLPushBack_NP(slot->first, slot->last, hash2style_node, hash_next, hash_prev);
|
||||
hash2style_node->style_hash = style_hash;
|
||||
hash2style_node->ascent = metrics.ascent;
|
||||
hash2style_node->descent= metrics.descent;
|
||||
hash2style_node->utf8_class1_direct_map = push_array_no_zero(f_state->arena, F_RasterCacheInfo, 256);
|
||||
hash2style_node->hash2info_slots_count = 1024;
|
||||
hash2style_node->hash2info_slots = push_array(f_state->arena, F_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count);
|
||||
hash2style_node->hash2info_slots = push_array(f_state->arena, FNT_Hash2InfoRasterCacheSlot, hash2style_node->hash2info_slots_count);
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -566,17 +566,17 @@ f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags)
|
||||
return hash2style_node;
|
||||
}
|
||||
|
||||
internal F_Run
|
||||
f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RasterFlags flags, String8 string)
|
||||
internal FNT_Run
|
||||
fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
//- rjf: map tag/size to style node
|
||||
F_Hash2StyleRasterCacheNode *hash2style_node = f_hash2style_from_tag_size_flags(tag, size, flags);
|
||||
FNT_Hash2StyleRasterCacheNode *hash2style_node = fnt_hash2style_from_tag_size_flags(tag, size, flags);
|
||||
|
||||
//- rjf: decode string & produce run pieces
|
||||
B32 first = 1;
|
||||
F_PieceChunkList piece_chunks = {0};
|
||||
FNT_PieceChunkList piece_chunks = {0};
|
||||
Vec2F32 dim = {0};
|
||||
B32 font_handle_mapped_on_miss = 0;
|
||||
FP_Handle font_handle = {0};
|
||||
@@ -636,9 +636,9 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
// rjf: more general, slower path for other glyphs
|
||||
if(piece_substring.size > 1)
|
||||
{
|
||||
piece_hash = f_little_hash_from_string(piece_substring);
|
||||
piece_hash = fnt_little_hash_from_string(piece_substring);
|
||||
U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count;
|
||||
F_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx];
|
||||
FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx];
|
||||
for(F_Hash2InfoRasterCacheNode *node = slot->first; node != 0; node = node->hash_next)
|
||||
{
|
||||
if(node->hash == piece_hash)
|
||||
@@ -665,9 +665,9 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
U64 font_slot_idx = tag.u64[1] % f_state->font_hash_table_size;
|
||||
|
||||
// rjf: tag * slot -> existing node
|
||||
F_FontHashNode *existing_node = 0;
|
||||
FNT_FontHashNode *existing_node = 0;
|
||||
{
|
||||
for(F_FontHashNode *n = f_state->font_hash_table[font_slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
for(FNT_FontHashNode *n = f_state->font_hash_table[font_slot_idx].first; n != 0 ; n = n->hash_next)
|
||||
{
|
||||
if(MemoryMatchStruct(&n->tag, &tag))
|
||||
{
|
||||
@@ -689,27 +689,27 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
if(size > 0)
|
||||
{
|
||||
FP_RasterFlags fp_flags = 0;
|
||||
if(flags & F_RasterFlag_Smooth) { fp_flags |= FP_RasterFlag_Smooth; }
|
||||
if(flags & F_RasterFlag_Hinted) { fp_flags |= FP_RasterFlag_Hinted; }
|
||||
if(flags & FNT_RasterFlag_Smooth) { fp_flags |= FP_RasterFlag_Smooth; }
|
||||
if(flags & FNT_RasterFlag_Hinted) { fp_flags |= FP_RasterFlag_Hinted; }
|
||||
raster = fp_raster(scratch.arena, font_handle, floor_f32(size), flags, piece_substring);
|
||||
}
|
||||
|
||||
// rjf: allocate portion of an atlas to upload the rasterization
|
||||
S16 chosen_atlas_num = 0;
|
||||
F_Atlas *chosen_atlas = 0;
|
||||
FNT_Atlas *chosen_atlas = 0;
|
||||
Rng2S16 chosen_atlas_region = {0};
|
||||
if(raster.atlas_dim.x != 0 && raster.atlas_dim.y != 0)
|
||||
{
|
||||
U64 num_atlases = 0;
|
||||
for(F_Atlas *atlas = f_state->first_atlas;; atlas = atlas->next, num_atlases += 1)
|
||||
for(FNT_Atlas *atlas = f_state->first_atlas;; atlas = atlas->next, num_atlases += 1)
|
||||
{
|
||||
// rjf: create atlas if needed
|
||||
if(atlas == 0 && num_atlases < 64)
|
||||
{
|
||||
atlas = push_array(f_state->arena, F_Atlas, 1);
|
||||
atlas = push_array(f_state->arena, FNT_Atlas, 1);
|
||||
DLLPushBack(f_state->first_atlas, f_state->last_atlas, atlas);
|
||||
atlas->root_dim = v2s16(1024, 1024);
|
||||
atlas->root = push_array(f_state->arena, F_AtlasRegionNode, 1);
|
||||
atlas->root = push_array(f_state->arena, FNT_AtlasRegionNode, 1);
|
||||
atlas->root->max_free_size[Corner_00] =
|
||||
atlas->root->max_free_size[Corner_01] =
|
||||
atlas->root->max_free_size[Corner_10] =
|
||||
@@ -721,7 +721,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
if(atlas != 0)
|
||||
{
|
||||
Vec2S16 needed_dimensions = v2s16(raster.atlas_dim.x + 2, raster.atlas_dim.y + 2);
|
||||
chosen_atlas_region = f_atlas_region_alloc(f_state->arena, atlas, needed_dimensions);
|
||||
chosen_atlas_region = fnt_atlas_region_alloc(f_state->arena, atlas, needed_dimensions);
|
||||
if(chosen_atlas_region.x1 != chosen_atlas_region.x0)
|
||||
{
|
||||
chosen_atlas = atlas;
|
||||
@@ -759,7 +759,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
else
|
||||
{
|
||||
U64 slot_idx = piece_hash%hash2style_node->hash2info_slots_count;
|
||||
F_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx];
|
||||
FNT_Hash2InfoRasterCacheSlot *slot = &hash2style_node->hash2info_slots[slot_idx];
|
||||
F_Hash2InfoRasterCacheNode *node = push_array_no_zero(f_state->arena, F_Hash2InfoRasterCacheNode, 1);
|
||||
DLLPushBack_NP(slot->first, slot->last, node, hash_next, hash_prev);
|
||||
node->hash = piece_hash;
|
||||
@@ -782,12 +782,12 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
if(info != 0)
|
||||
{
|
||||
// rjf: find atlas
|
||||
F_Atlas *atlas = 0;
|
||||
FNT_Atlas *atlas = 0;
|
||||
{
|
||||
if(info->subrect.x1 != 0 && info->subrect.y1 != 0)
|
||||
{
|
||||
S32 num = 0;
|
||||
for(F_Atlas *a = f_state->first_atlas; a != 0; a = a->next, num += 1)
|
||||
for(FNT_Atlas *a = f_state->first_atlas; a != 0; a = a->next, num += 1)
|
||||
{
|
||||
if(info->atlas_num == num)
|
||||
{
|
||||
@@ -807,7 +807,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
|
||||
// rjf: push piece
|
||||
{
|
||||
F_Piece *piece = f_piece_chunk_list_push_new(arena, &piece_chunks, string.size);
|
||||
FNT_Piece *piece = fnt_piece_chunk_list_push_new(arena, &piece_chunks, string.size);
|
||||
{
|
||||
piece->texture = atlas ? atlas->texture : r_handle_zero();
|
||||
piece->subrect = r2s16p(info->subrect.x0,
|
||||
@@ -826,7 +826,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
}
|
||||
|
||||
//- rjf: tighten & return
|
||||
F_Run run = {0};
|
||||
FNT_Run run = {0};
|
||||
{
|
||||
if(piece_chunks.node_count == 1)
|
||||
{
|
||||
@@ -835,7 +835,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
}
|
||||
else
|
||||
{
|
||||
run.pieces = f_piece_array_from_chunk_list(arena, &piece_chunks);
|
||||
run.pieces = fnt_piece_array_from_chunk_list(arena, &piece_chunks);
|
||||
}
|
||||
run.dim = dim;
|
||||
run.ascent = hash2style_node->ascent;
|
||||
@@ -847,23 +847,23 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
|
||||
}
|
||||
|
||||
internal String8List
|
||||
f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max)
|
||||
fnt_wrapped_string_lines_from_font_size_string_max(Arena *arena, FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max)
|
||||
{
|
||||
String8List list = {0};
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string);
|
||||
FNT_Run run = fnt_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string);
|
||||
F32 off_px = 0;
|
||||
U64 off_bytes = 0;
|
||||
U64 line_start_off_bytes = 0;
|
||||
U64 line_end_off_bytes = 0;
|
||||
B32 seeking_word_end = 0;
|
||||
F32 word_start_off_px = 0;
|
||||
F_Piece *last_word_start_piece = 0;
|
||||
FNT_Piece *last_word_start_piece = 0;
|
||||
U64 last_word_start_off_bytes = 0;
|
||||
F_Piece *pieces_first = run.pieces.v;
|
||||
F_Piece *pieces_opl = run.pieces.v + run.pieces.count;
|
||||
for(F_Piece *piece = pieces_first, *next = 0; piece != 0 && piece <= pieces_opl; piece = next)
|
||||
FNT_Piece *pieces_first = run.pieces.v;
|
||||
FNT_Piece *pieces_opl = run.pieces.v + run.pieces.count;
|
||||
for(FNT_Piece *piece = pieces_first, *next = 0; piece != 0 && piece <= pieces_opl; piece = next)
|
||||
{
|
||||
if(piece != 0) {next = piece+1;}
|
||||
|
||||
@@ -960,12 +960,12 @@ f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 s
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string)
|
||||
fnt_dim_from_tag_size_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Vec2F32 result = {0};
|
||||
F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string);
|
||||
FNT_Run run = fnt_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string);
|
||||
result = run.dim;
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
@@ -973,13 +973,13 @@ f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list)
|
||||
fnt_dim_from_tag_size_string_list(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Vec2F32 sum = {0};
|
||||
for(String8Node *n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, n->string);
|
||||
Vec2F32 str_dim = fnt_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, n->string);
|
||||
sum.x += str_dim.x;
|
||||
sum.y = Max(sum.y, str_dim.y);
|
||||
}
|
||||
@@ -988,21 +988,21 @@ f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_
|
||||
}
|
||||
|
||||
internal F32
|
||||
f_column_size_from_tag_size(F_Tag tag, F32 size)
|
||||
fnt_column_size_from_tag_size(FNT_Tag tag, F32 size)
|
||||
{
|
||||
F32 result = f_dim_from_tag_size_string(tag, size, 0, 0, str8_lit("H")).x;
|
||||
F32 result = fnt_dim_from_tag_size_string(tag, size, 0, 0, str8_lit("H")).x;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p)
|
||||
fnt_char_pos_from_tag_size_string_p(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 best_offset_bytes = 0;
|
||||
F32 best_offset_px = inf32();
|
||||
U64 offset_bytes = 0;
|
||||
F32 offset_px = 0.f;
|
||||
F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string);
|
||||
FNT_Run run = fnt_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string);
|
||||
for(U64 idx = 0; idx <= run.pieces.count; idx += 1)
|
||||
{
|
||||
F32 this_piece_offset_px = abs_f32(offset_px - p);
|
||||
@@ -1013,7 +1013,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 ta
|
||||
}
|
||||
if(idx < run.pieces.count)
|
||||
{
|
||||
F_Piece *piece = &run.pieces.v[idx];
|
||||
FNT_Piece *piece = &run.pieces.v[idx];
|
||||
offset_px += piece->advance;
|
||||
offset_bytes += piece->decode_size;
|
||||
}
|
||||
@@ -1025,12 +1025,12 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 ta
|
||||
////////////////////////////////
|
||||
//~ rjf: Metrics
|
||||
|
||||
internal F_Metrics
|
||||
f_metrics_from_tag_size(F_Tag tag, F32 size)
|
||||
internal FNT_Metrics
|
||||
fnt_metrics_from_tag_size(FNT_Tag tag, F32 size)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
FP_Metrics metrics = f_fp_metrics_from_tag(tag);
|
||||
F_Metrics result = {0};
|
||||
FP_Metrics metrics = fnt_fp_metrics_from_tag(tag);
|
||||
FNT_Metrics result = {0};
|
||||
{
|
||||
result.ascent = floor_f32(size) * metrics.ascent / metrics.design_units_per_em;
|
||||
result.descent = floor_f32(size) * metrics.descent / metrics.design_units_per_em;
|
||||
@@ -1042,7 +1042,7 @@ f_metrics_from_tag_size(F_Tag tag, F32 size)
|
||||
}
|
||||
|
||||
internal F32
|
||||
f_line_height_from_metrics(F_Metrics *metrics)
|
||||
fnt_line_height_from_metrics(FNT_Metrics *metrics)
|
||||
{
|
||||
return metrics->ascent + metrics->descent + metrics->line_gap;
|
||||
}
|
||||
@@ -1051,13 +1051,13 @@ f_line_height_from_metrics(F_Metrics *metrics)
|
||||
//~ rjf: Main Calls
|
||||
|
||||
internal void
|
||||
f_init(void)
|
||||
fnt_init(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
f_state = push_array(arena, F_State, 1);
|
||||
f_state = push_array(arena, FNT_State, 1);
|
||||
f_state->arena = arena;
|
||||
f_state->font_hash_table_size = 64;
|
||||
f_state->font_hash_table = push_array(arena, F_FontHashSlot, f_state->font_hash_table_size);
|
||||
f_state->font_hash_table = push_array(arena, FNT_FontHashSlot, f_state->font_hash_table_size);
|
||||
f_state->hash2style_slots_count = 1024;
|
||||
f_state->hash2style_slots = push_array(arena, F_Hash2StyleRasterCacheSlot, f_state->hash2style_slots_count);
|
||||
f_state->hash2style_slots = push_array(arena, FNT_Hash2StyleRasterCacheSlot, f_state->hash2style_slots_count);
|
||||
}
|
||||
|
||||
+87
-93
@@ -7,24 +7,18 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Rasterization Flags
|
||||
|
||||
typedef U32 F_RasterFlags;
|
||||
typedef U32 FNT_RasterFlags;
|
||||
enum
|
||||
{
|
||||
F_RasterFlag_Smooth = (1<<0),
|
||||
F_RasterFlag_Hinted = (1<<1),
|
||||
FNT_RasterFlag_Smooth = (1<<0),
|
||||
FNT_RasterFlag_Hinted = (1<<1),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handles & Tags
|
||||
|
||||
typedef struct F_Hash F_Hash;
|
||||
struct F_Hash
|
||||
{
|
||||
U64 u64[2];
|
||||
};
|
||||
|
||||
typedef struct F_Tag F_Tag;
|
||||
struct F_Tag
|
||||
typedef struct FNT_Tag FNT_Tag;
|
||||
struct FNT_Tag
|
||||
{
|
||||
U64 u64[2];
|
||||
};
|
||||
@@ -32,8 +26,8 @@ struct F_Tag
|
||||
////////////////////////////////
|
||||
//~ rjf: Draw Package Types (For Cache Queries)
|
||||
|
||||
typedef struct F_Piece F_Piece;
|
||||
struct F_Piece
|
||||
typedef struct FNT_Piece FNT_Piece;
|
||||
struct FNT_Piece
|
||||
{
|
||||
R_Handle texture;
|
||||
Rng2S16 subrect;
|
||||
@@ -42,35 +36,35 @@ struct F_Piece
|
||||
U16 decode_size;
|
||||
};
|
||||
|
||||
typedef struct F_PieceChunkNode F_PieceChunkNode;
|
||||
struct F_PieceChunkNode
|
||||
typedef struct FNT_PieceChunkNode FNT_PieceChunkNode;
|
||||
struct FNT_PieceChunkNode
|
||||
{
|
||||
F_PieceChunkNode *next;
|
||||
F_Piece *v;
|
||||
FNT_PieceChunkNode *next;
|
||||
FNT_Piece *v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
};
|
||||
|
||||
typedef struct F_PieceChunkList F_PieceChunkList;
|
||||
struct F_PieceChunkList
|
||||
typedef struct FNT_PieceChunkList FNT_PieceChunkList;
|
||||
struct FNT_PieceChunkList
|
||||
{
|
||||
F_PieceChunkNode *first;
|
||||
F_PieceChunkNode *last;
|
||||
FNT_PieceChunkNode *first;
|
||||
FNT_PieceChunkNode *last;
|
||||
U64 node_count;
|
||||
U64 total_piece_count;
|
||||
};
|
||||
|
||||
typedef struct F_PieceArray F_PieceArray;
|
||||
struct F_PieceArray
|
||||
typedef struct FNT_PieceArray FNT_PieceArray;
|
||||
struct FNT_PieceArray
|
||||
{
|
||||
F_Piece *v;
|
||||
FNT_Piece *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct F_Run F_Run;
|
||||
struct F_Run
|
||||
typedef struct FNT_Run FNT_Run;
|
||||
struct FNT_Run
|
||||
{
|
||||
F_PieceArray pieces;
|
||||
FNT_PieceArray pieces;
|
||||
Vec2F32 dim;
|
||||
F32 ascent;
|
||||
F32 descent;
|
||||
@@ -79,21 +73,21 @@ struct F_Run
|
||||
////////////////////////////////
|
||||
//~ rjf: Font Path -> Handle * Metrics * Path Cache Types
|
||||
|
||||
typedef struct F_FontHashNode F_FontHashNode;
|
||||
struct F_FontHashNode
|
||||
typedef struct FNT_FontHashNode FNT_FontHashNode;
|
||||
struct FNT_FontHashNode
|
||||
{
|
||||
F_FontHashNode *hash_next;
|
||||
F_Tag tag;
|
||||
FNT_FontHashNode *hash_next;
|
||||
FNT_Tag tag;
|
||||
FP_Handle handle;
|
||||
FP_Metrics metrics;
|
||||
String8 path;
|
||||
};
|
||||
|
||||
typedef struct F_FontHashSlot F_FontHashSlot;
|
||||
struct F_FontHashSlot
|
||||
typedef struct FNT_FontHashSlot FNT_FontHashSlot;
|
||||
struct FNT_FontHashSlot
|
||||
{
|
||||
F_FontHashNode *first;
|
||||
F_FontHashNode *last;
|
||||
FNT_FontHashNode *first;
|
||||
FNT_FontHashNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -117,18 +111,18 @@ struct F_Hash2InfoRasterCacheNode
|
||||
F_RasterCacheInfo info;
|
||||
};
|
||||
|
||||
typedef struct F_Hash2InfoRasterCacheSlot F_Hash2InfoRasterCacheSlot;
|
||||
struct F_Hash2InfoRasterCacheSlot
|
||||
typedef struct FNT_Hash2InfoRasterCacheSlot FNT_Hash2InfoRasterCacheSlot;
|
||||
struct FNT_Hash2InfoRasterCacheSlot
|
||||
{
|
||||
F_Hash2InfoRasterCacheNode *first;
|
||||
F_Hash2InfoRasterCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct F_Hash2StyleRasterCacheNode F_Hash2StyleRasterCacheNode;
|
||||
struct F_Hash2StyleRasterCacheNode
|
||||
typedef struct FNT_Hash2StyleRasterCacheNode FNT_Hash2StyleRasterCacheNode;
|
||||
struct FNT_Hash2StyleRasterCacheNode
|
||||
{
|
||||
F_Hash2StyleRasterCacheNode *hash_next;
|
||||
F_Hash2StyleRasterCacheNode *hash_prev;
|
||||
FNT_Hash2StyleRasterCacheNode *hash_next;
|
||||
FNT_Hash2StyleRasterCacheNode *hash_prev;
|
||||
U64 style_hash;
|
||||
F32 ascent;
|
||||
F32 descent;
|
||||
@@ -136,50 +130,50 @@ struct F_Hash2StyleRasterCacheNode
|
||||
F_RasterCacheInfo *utf8_class1_direct_map;
|
||||
U64 utf8_class1_direct_map_mask[4];
|
||||
U64 hash2info_slots_count;
|
||||
F_Hash2InfoRasterCacheSlot *hash2info_slots;
|
||||
FNT_Hash2InfoRasterCacheSlot *hash2info_slots;
|
||||
};
|
||||
|
||||
typedef struct F_Hash2StyleRasterCacheSlot F_Hash2StyleRasterCacheSlot;
|
||||
struct F_Hash2StyleRasterCacheSlot
|
||||
typedef struct FNT_Hash2StyleRasterCacheSlot FNT_Hash2StyleRasterCacheSlot;
|
||||
struct FNT_Hash2StyleRasterCacheSlot
|
||||
{
|
||||
F_Hash2StyleRasterCacheNode *first;
|
||||
F_Hash2StyleRasterCacheNode *last;
|
||||
FNT_Hash2StyleRasterCacheNode *first;
|
||||
FNT_Hash2StyleRasterCacheNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Atlas Types
|
||||
|
||||
typedef U32 F_AtlasRegionNodeFlags;
|
||||
typedef U32 FNT_AtlasRegionNodeFlags;
|
||||
enum
|
||||
{
|
||||
F_AtlasRegionNodeFlag_Taken = (1<<0),
|
||||
FNT_AtlasRegionNodeFlag_Taken = (1<<0),
|
||||
};
|
||||
|
||||
typedef struct F_AtlasRegionNode F_AtlasRegionNode;
|
||||
struct F_AtlasRegionNode
|
||||
typedef struct FNT_AtlasRegionNode FNT_AtlasRegionNode;
|
||||
struct FNT_AtlasRegionNode
|
||||
{
|
||||
F_AtlasRegionNode *parent;
|
||||
F_AtlasRegionNode *children[Corner_COUNT];
|
||||
FNT_AtlasRegionNode *parent;
|
||||
FNT_AtlasRegionNode *children[Corner_COUNT];
|
||||
Vec2S16 max_free_size[Corner_COUNT];
|
||||
F_AtlasRegionNodeFlags flags;
|
||||
FNT_AtlasRegionNodeFlags flags;
|
||||
U64 num_allocated_descendants;
|
||||
};
|
||||
|
||||
typedef struct F_Atlas F_Atlas;
|
||||
struct F_Atlas
|
||||
typedef struct FNT_Atlas FNT_Atlas;
|
||||
struct FNT_Atlas
|
||||
{
|
||||
F_Atlas *next;
|
||||
F_Atlas *prev;
|
||||
FNT_Atlas *next;
|
||||
FNT_Atlas *prev;
|
||||
R_Handle texture;
|
||||
Vec2S16 root_dim;
|
||||
F_AtlasRegionNode *root;
|
||||
FNT_AtlasRegionNode *root;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Metrics
|
||||
|
||||
typedef struct F_Metrics F_Metrics;
|
||||
struct F_Metrics
|
||||
typedef struct FNT_Metrics FNT_Metrics;
|
||||
struct FNT_Metrics
|
||||
{
|
||||
F32 ascent;
|
||||
F32 descent;
|
||||
@@ -190,81 +184,81 @@ struct F_Metrics
|
||||
////////////////////////////////
|
||||
//~ rjf: Main State Type
|
||||
|
||||
typedef struct F_State F_State;
|
||||
struct F_State
|
||||
typedef struct FNT_State FNT_State;
|
||||
struct FNT_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: font table
|
||||
U64 font_hash_table_size;
|
||||
F_FontHashSlot *font_hash_table;
|
||||
FNT_FontHashSlot *font_hash_table;
|
||||
|
||||
// rjf: hash -> raster cache table
|
||||
U64 hash2style_slots_count;
|
||||
F_Hash2StyleRasterCacheSlot *hash2style_slots;
|
||||
FNT_Hash2StyleRasterCacheSlot *hash2style_slots;
|
||||
|
||||
// rjf: atlas list
|
||||
F_Atlas *first_atlas;
|
||||
F_Atlas *last_atlas;
|
||||
FNT_Atlas *first_atlas;
|
||||
FNT_Atlas *last_atlas;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global F_State *f_state = 0;
|
||||
global FNT_State *f_state = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Functions
|
||||
|
||||
internal F_Hash f_hash_from_string(String8 string);
|
||||
internal U64 f_little_hash_from_string(String8 string);
|
||||
internal Vec2S32 f_vertex_from_corner(Corner corner);
|
||||
internal U128 fnt_hash_from_string(String8 string);
|
||||
internal U64 fnt_little_hash_from_string(String8 string);
|
||||
internal Vec2S32 fnt_vertex_from_corner(Corner corner);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Font Tags
|
||||
|
||||
internal F_Tag f_tag_zero(void);
|
||||
internal B32 f_tag_match(F_Tag a, F_Tag b);
|
||||
internal FP_Handle f_handle_from_tag(F_Tag tag);
|
||||
internal FP_Metrics f_fp_metrics_from_tag(F_Tag tag);
|
||||
internal F_Tag f_tag_from_path(String8 path);
|
||||
internal F_Tag f_tag_from_static_data_string(String8 *data_ptr);
|
||||
internal String8 f_path_from_tag(F_Tag tag);
|
||||
internal FNT_Tag fnt_tag_zero(void);
|
||||
internal B32 fnt_tag_match(FNT_Tag a, FNT_Tag b);
|
||||
internal FP_Handle fnt_handle_from_tag(FNT_Tag tag);
|
||||
internal FP_Metrics fnt_fp_metrics_from_tag(FNT_Tag tag);
|
||||
internal FNT_Tag fnt_tag_from_path(String8 path);
|
||||
internal FNT_Tag fnt_tag_from_static_data_string(String8 *data_ptr);
|
||||
internal String8 fnt_path_from_tag(FNT_Tag tag);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Atlas
|
||||
|
||||
internal Rng2S16 f_atlas_region_alloc(Arena *arena, F_Atlas *atlas, Vec2S16 needed_size);
|
||||
internal void f_atlas_region_release(F_Atlas *atlas, Rng2S16 region);
|
||||
internal Rng2S16 fnt_atlas_region_alloc(Arena *arena, FNT_Atlas *atlas, Vec2S16 needed_size);
|
||||
internal void fnt_atlas_region_release(FNT_Atlas *atlas, Rng2S16 region);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Piece Type Functions
|
||||
|
||||
internal F_Piece *f_piece_chunk_list_push_new(Arena *arena, F_PieceChunkList *list, U64 cap);
|
||||
internal void f_piece_chunk_list_push(Arena *arena, F_PieceChunkList *list, U64 cap, F_Piece *piece);
|
||||
internal F_PieceArray f_piece_array_from_chunk_list(Arena *arena, F_PieceChunkList *list);
|
||||
internal F_PieceArray f_piece_array_copy(Arena *arena, F_PieceArray *src);
|
||||
internal FNT_Piece *fnt_piece_chunk_list_push_new(Arena *arena, FNT_PieceChunkList *list, U64 cap);
|
||||
internal void fnt_piece_chunk_list_push(Arena *arena, FNT_PieceChunkList *list, U64 cap, FNT_Piece *piece);
|
||||
internal FNT_PieceArray fnt_piece_array_from_chunk_list(Arena *arena, FNT_PieceChunkList *list);
|
||||
internal FNT_PieceArray fnt_piece_array_copy(Arena *arena, FNT_PieceArray *src);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Rasterization Cache
|
||||
|
||||
internal F_Hash2StyleRasterCacheNode *f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags);
|
||||
internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RasterFlags flags, String8 string);
|
||||
internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max);
|
||||
internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string);
|
||||
internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list);
|
||||
internal F32 f_column_size_from_tag_size(F_Tag tag, F32 size);
|
||||
internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p);
|
||||
internal FNT_Hash2StyleRasterCacheNode *fnt_hash2style_from_tag_size_flags(FNT_Tag tag, F32 size, FNT_RasterFlags flags);
|
||||
internal FNT_Run fnt_push_run_from_string(Arena *arena, FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, String8 string);
|
||||
internal String8List fnt_wrapped_string_lines_from_font_size_string_max(Arena *arena, FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max);
|
||||
internal Vec2F32 fnt_dim_from_tag_size_string(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string);
|
||||
internal Vec2F32 fnt_dim_from_tag_size_string_list(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list);
|
||||
internal F32 fnt_column_size_from_tag_size(FNT_Tag tag, F32 size);
|
||||
internal U64 fnt_char_pos_from_tag_size_string_p(FNT_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Metrics
|
||||
|
||||
internal F_Metrics f_metrics_from_tag_size(F_Tag tag, F32 size);
|
||||
internal F32 f_line_height_from_metrics(F_Metrics *metrics);
|
||||
internal FNT_Metrics fnt_metrics_from_tag_size(FNT_Tag tag, F32 size);
|
||||
internal F32 fnt_line_height_from_metrics(FNT_Metrics *metrics);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Calls
|
||||
|
||||
internal void f_init(void);
|
||||
internal void fnt_init(void);
|
||||
|
||||
#endif // FONT_CACHE_H
|
||||
|
||||
Reference in New Issue
Block a user