Fix font rendering on mac

This commit is contained in:
Peter Slattery 2025-07-07 13:54:26 -07:00
parent 6469fe5a0f
commit 9e58435637
2 changed files with 158 additions and 134 deletions

View File

@ -164,10 +164,10 @@ ft__bad_rect_pack_next(Bad_Rect_Pack *pack, Vec2_i32 dim){
// NOTE(simon, 28/02/24): We are now sure that the character will fit. // NOTE(simon, 28/02/24): We are now sure that the character will fit.
pack->current_line_h = Max(pack->current_line_h, dim.y); pack->current_line_h = Max(pack->current_line_h, dim.y);
result = pack->p; result = pack->p;
pack->p.x += dim.x; pack->p.x += dim.x;
pack->dim.x = Max( pack->dim.x, pack->p.x ); pack->dim.x = Max( pack->dim.x, pack->p.x );
} }
return(result); return(result);
} }
@ -330,55 +330,66 @@ ft__font_make_face(Arena *arena, Face_Description *description, f32 scale_factor
Texture_Kind texture_kind = TextureKind_Mono; Texture_Kind texture_kind = TextureKind_Mono;
u32 texture = graphics_get_texture(pack.dim, texture_kind); u32 texture = graphics_get_texture(pack.dim, texture_kind);
Vec3_f32 texture_dim = V3f32(pack.dim); /* NOTE simon (06/01/25): This assumes that every platforms don't use 0 as a valid texture id.
face->texture_dim = texture_dim; This is valid for OpenGL and the DX11 implementaion. Someone needs to check the MAC versions. */
if (texture != 0 ){
{ face->texture_kind = texture_kind;
Vec3_i32 p = V3i32((i32)face->white.uv.x0, (i32)face->white.uv.y0, (i32)face->white.w); face->texture = texture;
Vec3_i32 dim = V3i32(white.dim.x, white.dim.y, 1);
graphics_fill_texture(texture_kind, texture, p, dim, white.data);
face->white.uv.x1 = (face->white.uv.x0 + face->white.uv.x1)/texture_dim.x;
face->white.uv.y1 = (face->white.uv.y0 + face->white.uv.y1)/texture_dim.y;
face->white.uv.x0 = face->white.uv.x0/texture_dim.x;
face->white.uv.y0 = face->white.uv.y0/texture_dim.y;
face->white.w /= texture_dim.z;
}
for (u16 i = 0; i < index_count; i += 1){ Vec3_f32 texture_dim = V3f32(pack.dim);
Vec3_i32 p = V3i32((i32)face->bounds[i].uv.x0, (i32)face->bounds[i].uv.y0, (i32)face->bounds[i].w); face->texture_dim = texture_dim;
Vec3_i32 dim = V3i32(glyph_bitmaps[i].dim.x, glyph_bitmaps[i].dim.y, 1);
graphics_fill_texture(texture_kind, texture, p, dim, glyph_bitmaps[i].data);
face->bounds[i].uv.x1 = (face->bounds[i].uv.x0 + face->bounds[i].uv.x1)/texture_dim.x;
face->bounds[i].uv.y1 = (face->bounds[i].uv.y0 + face->bounds[i].uv.y1)/texture_dim.y;
face->bounds[i].uv.x0 = face->bounds[i].uv.x0/texture_dim.x;
face->bounds[i].uv.y0 = face->bounds[i].uv.y0/texture_dim.y;
}
{ {
Face_Advance_Map *advance_map = &face->advance_map; Vec3_i32 p = V3i32((i32)face->white.uv.x0, (i32)face->white.uv.y0, (i32)face->white.w);
Vec3_i32 dim = V3i32(white.dim.x, white.dim.y, 1);
graphics_fill_texture(texture_kind, texture, p, dim, white.data);
face->white.uv.x1 = (face->white.uv.x0 + face->white.uv.x1)/texture_dim.x;
face->white.uv.y1 = (face->white.uv.y0 + face->white.uv.y1)/texture_dim.y;
face->white.uv.x0 = face->white.uv.x0/texture_dim.x;
face->white.uv.y0 = face->white.uv.y0/texture_dim.y;
}
met->space_advance = font_get_glyph_advance(advance_map, met, ' ', 0); for (u16 i = 0; i < index_count; i += 1){
met->decimal_digit_advance = Vec3_i32 p = V3i32((i32)face->bounds[i].uv.x0, (i32)face->bounds[i].uv.y0, (i32)face->bounds[i].w);
font_get_max_glyph_advance_range(advance_map, met, '0', '9', 0); Vec3_i32 dim = V3i32(glyph_bitmaps[i].dim.x, glyph_bitmaps[i].dim.y, 1);
met->hex_digit_advance = graphics_fill_texture(texture_kind, texture, p, dim, glyph_bitmaps[i].data);
font_get_max_glyph_advance_range(advance_map, met, 'A', 'F', 0); face->bounds[i].uv.x1 = (face->bounds[i].uv.x0 + face->bounds[i].uv.x1)/texture_dim.x;
met->hex_digit_advance = face->bounds[i].uv.y1 = (face->bounds[i].uv.y0 + face->bounds[i].uv.y1)/texture_dim.y;
Max(met->hex_digit_advance, met->decimal_digit_advance); face->bounds[i].uv.x0 = face->bounds[i].uv.x0/texture_dim.x;
met->byte_sub_advances[0] = face->bounds[i].uv.y0 = face->bounds[i].uv.y0/texture_dim.y;
font_get_glyph_advance(advance_map, met, '\\', 0); }
met->byte_sub_advances[1] = met->hex_digit_advance;
met->byte_sub_advances[2] = met->hex_digit_advance; {
met->byte_advance = Face_Advance_Map *advance_map = &face->advance_map;
met->byte_sub_advances[0] +
met->byte_sub_advances[1] + met->space_advance = font_get_glyph_advance(advance_map, met, ' ', 0);
met->byte_sub_advances[2]; met->decimal_digit_advance =
met->normal_lowercase_advance = font_get_max_glyph_advance_range(advance_map, met, '0', '9', 0);
font_get_average_glyph_advance_range(advance_map, met, 'a', 'z', 0); met->hex_digit_advance =
met->normal_uppercase_advance = font_get_max_glyph_advance_range(advance_map, met, 'A', 'F', 0);
font_get_average_glyph_advance_range(advance_map, met, 'A', 'Z', 0); met->hex_digit_advance =
met->normal_advance = (26*met->normal_lowercase_advance + Max(met->hex_digit_advance, met->decimal_digit_advance);
26*met->normal_uppercase_advance + met->byte_sub_advances[0] =
10*met->decimal_digit_advance)/62.f; font_get_glyph_advance(advance_map, met, '\\', 0);
met->byte_sub_advances[1] = met->hex_digit_advance;
met->byte_sub_advances[2] = met->hex_digit_advance;
met->byte_advance =
met->byte_sub_advances[0] +
met->byte_sub_advances[1] +
met->byte_sub_advances[2];
met->normal_lowercase_advance =
font_get_average_glyph_advance_range(advance_map, met, 'a', 'z', 0);
met->normal_uppercase_advance =
font_get_average_glyph_advance_range(advance_map, met, 'A', 'Z', 0);
met->normal_advance = (26*met->normal_lowercase_advance +
26*met->normal_uppercase_advance +
10*met->decimal_digit_advance)/62.f;
}
} else {
pop_array(arena, Face, 1);
face = 0;
} }
} }
@ -388,4 +399,3 @@ ft__font_make_face(Arena *arena, Face_Description *description, f32 scale_factor
} }
// BOTTOM // BOTTOM

View File

@ -57,7 +57,7 @@ struct Metal_Texture_Slot_List{
Metal_Texture_Slot *last_free_slot; Metal_Texture_Slot *last_free_slot;
}; };
global_const u32 metal__invalid_texture_slot_locator = (u32)-1; global_const u32 metal__invalid_texture_slot_locator = 0;
//////////////////////////////// ////////////////////////////////
@ -67,6 +67,7 @@ global_const u32 metal__invalid_texture_slot_locator = (u32)-1;
- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind;
- (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; - (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data;
- (void)bind_texture:(u32)handle encoder:(id<MTLRenderCommandEncoder>)render_encoder; - (void)bind_texture:(u32)handle encoder:(id<MTLRenderCommandEncoder>)render_encoder;
- (void)free_texture:(u32)handle;
- (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator; - (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator;
- (Metal_Texture_Slot*)get_texture_slot_at_handle:(u32)handle; - (Metal_Texture_Slot*)get_texture_slot_at_handle:(u32)handle;
@ -284,6 +285,11 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
// NOTE(yuval): Initialize the texture slot list // NOTE(yuval): Initialize the texture slot list
block_zero_struct(&_texture_slots); block_zero_struct(&_texture_slots);
// NOTE(simon): Other platforms use 0 as invalid handle, so we allocate the first texture here (it should be 0),
// and never use it so we can use 0 as the invalid handle.
u32 reserved_texture_slot_do_not_use = [self get_texture_of_dim:V3i32(2, 2, 1) kind:TextureKind_Mono];
Assert( reserved_texture_slot_do_not_use == 0 );
// NOTE(yuval): Create the fallback texture // NOTE(yuval): Create the fallback texture
_target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) _target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1)
kind:TextureKind_Mono]; kind:TextureKind_Mono];
@ -565,6 +571,14 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
} }
} }
- (void)free_texture:(u32)handle{
Metal_Texture_Slot *texture_slot = [self get_texture_slot_at_handle:handle];
if (texture_slot){
sll_queue_push(_texture_slots.first_free_slot, _texture_slots.last_free_slot, texture_slot);
}
}
- (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator{ - (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator{
Metal_Texture_Slot *result = 0; Metal_Texture_Slot *result = 0;