extend font provider backend with ability to independently toggle hinting & full anti-aliasing; fix up ui text measurement/placement; introduce per-window settings for adjusting font rendering parameters

This commit is contained in:
Ryan Fleury
2024-06-28 15:31:27 -07:00
parent b0259b7a49
commit 38090b6273
22 changed files with 903 additions and 614 deletions
+17 -19
View File
@@ -516,7 +516,7 @@ f_piece_array_copy(Arena *arena, F_PieceArray *src)
//~ rjf: Rasterization Cache
internal F_Hash2StyleRasterCacheNode *
f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RunFlags flags)
f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RasterFlags flags)
{
//- rjf: tag * size -> style hash
U64 style_hash = {0};
@@ -567,7 +567,7 @@ f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RunFlags 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_RunFlags flags, String8 string)
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)
{
ProfBeginFunction();
@@ -575,13 +575,13 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
F_Hash2StyleRasterCacheNode *hash2style_node = f_hash2style_from_tag_size_flags(tag, size, flags);
//- rjf: decode string & produce run pieces
B32 first = 1;
F_PieceChunkList piece_chunks = {0};
Vec2F32 dim = {0};
F32 last_piece_end_pad = 0;
B32 font_handle_mapped_on_miss = 0;
FP_Handle font_handle = {0};
U64 piece_substring_start_idx = 0;
for(U64 idx = 0; idx < string.size;)
for(U64 idx = 0; idx < string.size; first = 0)
{
//- rjf: decode next codepoint & get piece substring, or continuation rule
String8 piece_substring;
@@ -688,7 +688,10 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
FP_RasterResult raster = {0};
if(size > 0)
{
raster = fp_raster(scratch.arena, font_handle, floor_f32(size), (flags & F_RunFlag_Smooth) ? FP_RasterMode_Smooth : FP_RasterMode_Sharp, piece_substring);
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; }
raster = fp_raster(scratch.arena, font_handle, floor_f32(size), flags, piece_substring);
}
// rjf: allocate portion of an atlas to upload the rasterization
@@ -701,7 +704,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
for(F_Atlas *atlas = f_state->first_atlas;; atlas = atlas->next, num_atlases += 1)
{
// rjf: create atlas if needed
if(atlas == 0 && num_atlases < 16)
if(atlas == 0 && num_atlases < 64)
{
atlas = push_array(f_state->arena, F_Atlas, 1);
DLLPushBack(f_state->first_atlas, f_state->last_atlas, atlas);
@@ -738,10 +741,10 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
{
Rng2S32 subregion =
{
chosen_atlas_region.x0 + 1,
chosen_atlas_region.y0 + 1,
chosen_atlas_region.x0 + raster.atlas_dim.x + 1,
chosen_atlas_region.y0 + raster.atlas_dim.y + 1
chosen_atlas_region.x0,
chosen_atlas_region.y0,
chosen_atlas_region.x0 + raster.atlas_dim.x,
chosen_atlas_region.y0 + raster.atlas_dim.y
};
r_fill_tex2d_region(chosen_atlas->texture, subregion, raster.atlas);
}
@@ -764,11 +767,10 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
}
if(info != 0)
{
info->subrect = chosen_atlas_region;
info->bounding_box = raster.bounding_box;
info->atlas_num = chosen_atlas_num;
info->subrect = chosen_atlas_region;
info->atlas_num = chosen_atlas_num;
info->raster_dim = raster.atlas_dim;
info->advance = raster.advance;
info->advance = raster.advance;
}
}
@@ -814,13 +816,11 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
info->subrect.y0 + info->raster_dim.y);
piece->advance = advance;
piece->decode_size = piece_substring.size;
piece->offset = v2s16(0, -hash2style_node->ascent - 4);
piece->offset = v2s16(0, -(hash2style_node->ascent + hash2style_node->descent));
}
base_align_px += advance;
dim.x += piece->advance;
dim.y = Max(dim.y, info->raster_dim.y);
last_piece_end_pad = ((F32)piece->offset.x+(F32)dim_2s16(info->bounding_box).x) - piece->advance;
last_piece_end_pad = ClampBot(0, last_piece_end_pad);
}
}
}
@@ -838,8 +838,6 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32
run.pieces = f_piece_array_from_chunk_list(arena, &piece_chunks);
}
run.dim = dim;
run.dim.x += last_piece_end_pad;
run.end_pad = last_piece_end_pad;
run.ascent = hash2style_node->ascent;
run.descent = hash2style_node->descent;
}
+5 -6
View File
@@ -7,10 +7,11 @@
////////////////////////////////
//~ rjf: Rasterization Flags
typedef U32 F_RunFlags;
typedef U32 F_RasterFlags;
enum
{
F_RunFlag_Smooth = (1<<0),
F_RasterFlag_Smooth = (1<<0),
F_RasterFlag_Hinted = (1<<1),
};
////////////////////////////////
@@ -71,7 +72,6 @@ struct F_Run
{
F_PieceArray pieces;
Vec2F32 dim;
F32 end_pad;
F32 ascent;
F32 descent;
};
@@ -103,7 +103,6 @@ typedef struct F_RasterCacheInfo F_RasterCacheInfo;
struct F_RasterCacheInfo
{
Rng2S16 subrect;
Rng2S16 bounding_box;
Vec2S16 raster_dim;
S16 atlas_num;
F32 advance;
@@ -249,8 +248,8 @@ internal F_PieceArray f_piece_array_copy(Arena *arena, F_PieceArray *src);
////////////////////////////////
//~ rjf: Rasterization Cache
internal F_Hash2StyleRasterCacheNode *f_hash2style_from_tag_size_flags(F_Tag tag, F32 size, F_RunFlags 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_RunFlags flags, String8 string);
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);