Progress on cleanup

This commit is contained in:
2025-01-10 09:52:44 -05:00
parent 77cf07ce16
commit ddfd529993
8 changed files with 68 additions and 259 deletions

View File

@@ -35,8 +35,8 @@ Upcoming:
* Support for which triangulation method used on a by font basis? * Support for which triangulation method used on a by font basis?
* Multi-threading supported job queue. * Multi-threading supported job queue.
* Lift heavy-lifting portion of the library's context into a thread context. * Lift heavy-lifting portion of the library's context into a thread context.
* Synchronize threads by merging their generated layered drawlist into a file draw-list for processing on the user's render thread. * Synchronize threads by merging their generated layered draw list into a finished draw-list for processing on the user's render thread.
* User defines how context's are distributed for drawing (a basic quandrant basic selector procedure will be provided.) * User defines how thread context's are distributed for drawing (a basic quandrant based selector procedure will be provided.)
See: [docs/Readme.md](docs/Readme.md) for the library's interface. See: [docs/Readme.md](docs/Readme.md) for the library's interface.

View File

@@ -12,7 +12,6 @@ Atlas_Region_Kind :: enum u8 {
Ignore = 0xFF, // ve_fontcache_cache_glyph_to_atlas uses a -1 value in clear draw call Ignore = 0xFF, // ve_fontcache_cache_glyph_to_atlas uses a -1 value in clear draw call
} }
// Note(Ed): Using 16 bit hash had collision failures and no observable performance improvement (tried several 16-bit hashers)
Atlas_Key :: u32 Atlas_Key :: u32
// TODO(Ed) It might perform better with a tailored made hashtable implementation for the LRU_Cache or dedicated array struct/procs for the Atlas. // TODO(Ed) It might perform better with a tailored made hashtable implementation for the LRU_Cache or dedicated array struct/procs for the Atlas.

View File

@@ -3,7 +3,7 @@ package vefontcache
when false { when false {
// TODO(Ed): Freetype support // TODO(Ed): Freetype support
// TODO(Ed): glyph caching cannot be handled in a 'font parser' abstraction. Just going to have explicit procedures to grab info neatly... // TODO(Ed): glyph triangulation cannot be handled in a 'font parser' abstraction. Just going to have explicit procedures to grab info neatly...
cache_glyph_freetype :: proc(ctx: ^Context, font: Font_ID, glyph_index: Glyph, entry: ^Entry, bounds_0, bounds_1: Vec2, scale, translate: Vec2) -> b32 cache_glyph_freetype :: proc(ctx: ^Context, font: Font_ID, glyph_index: Glyph, entry: ^Entry, bounds_0, bounds_1: Vec2, scale, translate: Vec2) -> b32
{ {
draw_filled_path_freetype :: proc( draw_list : ^Draw_List, outside_point : Vec2, path : []Vertex, draw_filled_path_freetype :: proc( draw_list : ^Draw_List, outside_point : Vec2, path : []Vertex,

View File

@@ -12,7 +12,7 @@ Freetype isn't really supported and its not a high priority (pretty sure its too
STB_Truetype: STB_Truetype:
* Has macros for its allocation unfortuantely. * Has macros for its allocation unfortuantely.
TODO(Ed): Just keep a local version of stb_truetype and modify it to support a sokol/odin compatible allocator. TODO(Ed): Just keep a local version of stb_truetype and modify it to support a sokol/odin compatible allocator.
Already wanted to do so anyway to evaluate the glyph point shape implementation on its side. Already wanted to do so anyway to evaluate the shape generation implementation.
*/ */
import "base:runtime" import "base:runtime"
@@ -24,7 +24,7 @@ import stbtt "vendor:stb/truetype"
Parser_Kind :: enum u32 { Parser_Kind :: enum u32 {
STB_TrueType, STB_TrueType,
Freetype, Freetype, // Currently not implemented.
} }
Parser_Font_Info :: struct { Parser_Font_Info :: struct {
@@ -63,40 +63,16 @@ Parser_Context :: struct {
parser_init :: proc( ctx : ^Parser_Context, kind : Parser_Kind ) parser_init :: proc( ctx : ^Parser_Context, kind : Parser_Kind )
{ {
// switch kind
// {
// case .Freetype:
// result := freetype.init_free_type( & ctx.ft_library )
// assert( result == freetype.Error.Ok, "VEFontCache.parser_init: Failed to initialize freetype" )
// case .STB_TrueType:
// Do nothing intentional
// }
ctx.kind = kind ctx.kind = kind
} }
parser_shutdown :: proc( ctx : ^Parser_Context ) { parser_shutdown :: proc( ctx : ^Parser_Context ) {
// TODO(Ed): Implement // Note: Not necesssary for stb_truetype
} }
parser_load_font :: proc( ctx : ^Parser_Context, label : string, data : []byte ) -> (font : Parser_Font_Info, error : b32) parser_load_font :: proc( ctx : ^Parser_Context, label : string, data : []byte ) -> (font : Parser_Font_Info, error : b32)
{ {
// switch ctx.kind
// {
// case .Freetype:
// when ODIN_OS == .Windows {
// error_status := freetype.new_memory_face( ctx.ft_library, raw_data(data), cast(i32) len(data), 0, & font.freetype_info )
// if error != .Ok do error = true
// }
// else when ODIN_OS == .Linux {
// error := freetype.new_memory_face( ctx.ft_library, raw_data(data), cast(i64) len(data), 0, & font.freetype_info )
// if error_status != .Ok do error = true
// }
// case .STB_TrueType:
error = ! stbtt.InitFont( & font.stbtt_info, raw_data(data), 0 ) error = ! stbtt.InitFont( & font.stbtt_info, raw_data(data), 0 )
// }
font.label = label font.label = label
font.data = data font.data = data
@@ -106,122 +82,36 @@ parser_load_font :: proc( ctx : ^Parser_Context, label : string, data : []byte )
parser_unload_font :: proc( font : ^Parser_Font_Info ) parser_unload_font :: proc( font : ^Parser_Font_Info )
{ {
// switch font.kind {
// case .Freetype:
// error := freetype.done_face( font.freetype_info )
// assert( error == .Ok, "VEFontCache.parser_unload_font: Failed to unload freetype face" )
// case .STB_TrueType: // case .STB_TrueType:
// Do Nothing // Do Nothing
// }
} }
parser_find_glyph_index :: #force_inline proc "contextless" ( font : Parser_Font_Info, codepoint : rune ) -> (glyph_index : Glyph) parser_find_glyph_index :: #force_inline proc "contextless" ( font : Parser_Font_Info, codepoint : rune ) -> (glyph_index : Glyph)
{ {
// profile(#procedure)
// switch font.kind
// {
// case .Freetype:
// when ODIN_OS == .Windows {
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, transmute(u32) codepoint )
// }
// else when ODIN_OS == .Linux {
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, cast(u64) codepoint )
// }
// return
// case .STB_TrueType:
glyph_index = transmute(Glyph) stbtt.FindGlyphIndex( font.stbtt_info, codepoint ) glyph_index = transmute(Glyph) stbtt.FindGlyphIndex( font.stbtt_info, codepoint )
return return
// }
// return Glyph(-1)
} }
parser_free_shape :: #force_inline proc( font : Parser_Font_Info, shape : Parser_Glyph_Shape ) parser_free_shape :: #force_inline proc( font : Parser_Font_Info, shape : Parser_Glyph_Shape )
{ {
// switch font.kind
// {
// case .Freetype:
// delete(shape)
// case .STB_TrueType:
stbtt.FreeShape( font.stbtt_info, transmute( [^]stbtt.vertex) raw_data(shape) ) stbtt.FreeShape( font.stbtt_info, transmute( [^]stbtt.vertex) raw_data(shape) )
// }
} }
parser_get_codepoint_horizontal_metrics :: #force_inline proc "contextless" ( font : Parser_Font_Info, codepoint : rune ) -> ( advance, to_left_side_glyph : i32 ) parser_get_codepoint_horizontal_metrics :: #force_inline proc "contextless" ( font : Parser_Font_Info, codepoint : rune ) -> ( advance, to_left_side_glyph : i32 )
{ {
// switch font.kind
// {
// case .Freetype:
// glyph_index : Glyph
// when ODIN_OS == .Windows {
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, transmute(u32) codepoint )
// }
// else when ODIN_OS == .Linux {
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, cast(u64) codepoint )
// }
// if glyph_index != 0
// {
// freetype.load_glyph( font.freetype_info, c.uint(codepoint), { .No_Bitmap, .No_Hinting, .No_Scale } )
// advance = i32(font.freetype_info.glyph.advance.x) >> 6
// to_left_side_glyph = i32(font.freetype_info.glyph.metrics.hori_bearing_x) >> 6
// }
// else
// {
// advance = 0
// to_left_side_glyph = 0
// }
// case .STB_TrueType:
stbtt.GetCodepointHMetrics( font.stbtt_info, codepoint, & advance, & to_left_side_glyph ) stbtt.GetCodepointHMetrics( font.stbtt_info, codepoint, & advance, & to_left_side_glyph )
// }
return return
} }
parser_get_codepoint_kern_advance :: #force_inline proc "contextless" ( font : Parser_Font_Info, prev_codepoint, codepoint : rune ) -> i32 parser_get_codepoint_kern_advance :: #force_inline proc "contextless" ( font : Parser_Font_Info, prev_codepoint, codepoint : rune ) -> i32
{ {
// switch font.kind
// {
// case .Freetype:
// prev_glyph_index : Glyph
// glyph_index : Glyph
// when ODIN_OS == .Windows {
// prev_glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, transmute(u32) prev_codepoint )
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, transmute(u32) codepoint )
// }
// else when ODIN_OS == .Linux {
// prev_glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, cast(u64) prev_codepoint )
// glyph_index = transmute(Glyph) freetype.get_char_index( font.freetype_info, cast(u64) codepoint )
// }
// if prev_glyph_index != 0 && glyph_index != 0
// {
// kerning : freetype.Vector
// font.freetype_info.driver.clazz.get_kerning( font.freetype_info, transmute(u32) prev_codepoint, transmute(u32) codepoint, & kerning )
// }
// case .STB_TrueType:
kern := stbtt.GetCodepointKernAdvance( font.stbtt_info, prev_codepoint, codepoint ) kern := stbtt.GetCodepointKernAdvance( font.stbtt_info, prev_codepoint, codepoint )
return kern return kern
// }
// return -1
} }
parser_get_font_vertical_metrics :: #force_inline proc "contextless" ( font : Parser_Font_Info ) -> (ascent, descent, line_gap : i32 ) parser_get_font_vertical_metrics :: #force_inline proc "contextless" ( font : Parser_Font_Info ) -> (ascent, descent, line_gap : i32 )
{ {
// switch font.kind
// {
// case .Freetype:
// info := font.freetype_info
// ascent = i32(info.ascender)
// descent = i32(info.descender)
// line_gap = i32(info.height) - (ascent - descent)
// case .STB_TrueType:
stbtt.GetFontVMetrics( font.stbtt_info, & ascent, & descent, & line_gap ) stbtt.GetFontVMetrics( font.stbtt_info, & ascent, & descent, & line_gap )
// }
return return
} }
@@ -230,37 +120,17 @@ parser_get_bounds :: #force_inline proc "contextless" ( font : Parser_Font_Info,
// profile(#procedure) // profile(#procedure)
bounds_0, bounds_1 : Vec2i bounds_0, bounds_1 : Vec2i
// switch font.kind
// {
// case .Freetype:
// freetype.load_glyph( font.freetype_info, c.uint(glyph_index), { .No_Bitmap, .No_Hinting, .No_Scale } )
// metrics := font.freetype_info.glyph.metrics
// bounds_0 = {i32(metrics.hori_bearing_x), i32(metrics.hori_bearing_y - metrics.height)}
// bounds_1 = {i32(metrics.hori_bearing_x + metrics.width), i32(metrics.hori_bearing_y)}
// case .STB_TrueType:
x0, y0, x1, y1 : i32 x0, y0, x1, y1 : i32
success := cast(bool) stbtt.GetGlyphBox( font.stbtt_info, i32(glyph_index), & x0, & y0, & x1, & y1 ) success := cast(bool) stbtt.GetGlyphBox( font.stbtt_info, i32(glyph_index), & x0, & y0, & x1, & y1 )
// assert( success )
bounds_0 = { x0, y0 } bounds_0 = { x0, y0 }
bounds_1 = { x1, y1 } bounds_1 = { x1, y1 }
// }
bounds = { vec2(bounds_0), vec2(bounds_1) } bounds = { vec2(bounds_0), vec2(bounds_1) }
return return
} }
parser_get_glyph_shape :: #force_inline proc ( font : Parser_Font_Info, glyph_index : Glyph ) -> (shape : Parser_Glyph_Shape, error : Allocator_Error) parser_get_glyph_shape :: #force_inline proc ( font : Parser_Font_Info, glyph_index : Glyph ) -> (shape : Parser_Glyph_Shape, error : Allocator_Error)
{ {
// switch font.kind
// {
// case .Freetype:
// // TODO(Ed): Don't do this, going a completely different route for handling shapes.
// // This abstraction fails to be time-saving or performant.
// case .STB_TrueType:
stb_shape : [^]stbtt.vertex stb_shape : [^]stbtt.vertex
nverts := stbtt.GetGlyphShape( font.stbtt_info, cast(i32) glyph_index, & stb_shape ) nverts := stbtt.GetGlyphShape( font.stbtt_info, cast(i32) glyph_index, & stb_shape )
@@ -270,82 +140,27 @@ parser_get_glyph_shape :: #force_inline proc ( font : Parser_Font_Info, glyph_in
shape_raw.cap = int(nverts) shape_raw.cap = int(nverts)
shape_raw.allocator = runtime.nil_allocator() shape_raw.allocator = runtime.nil_allocator()
error = Allocator_Error.None error = Allocator_Error.None
// return
// }
return return
} }
parser_is_glyph_empty :: #force_inline proc "contextless" ( font : Parser_Font_Info, glyph_index : Glyph ) -> b32 parser_is_glyph_empty :: #force_inline proc "contextless" ( font : Parser_Font_Info, glyph_index : Glyph ) -> b32
{ {
// switch font.kind
// {
// case .Freetype:
// error := freetype.load_glyph( font.freetype_info, cast(u32) glyph_index, { .No_Bitmap, .No_Hinting, .No_Scale } )
// if error == .Ok
// {
// if font.freetype_info.glyph.format == .Outline {
// return font.freetype_info.glyph.outline.n_points == 0
// }
// else if font.freetype_info.glyph.format == .Bitmap {
// return font.freetype_info.glyph.bitmap.width == 0 && font.freetype_info.glyph.bitmap.rows == 0;
// }
// }
// return false
// case .STB_TrueType:
return stbtt.IsGlyphEmpty( font.stbtt_info, cast(c.int) glyph_index ) return stbtt.IsGlyphEmpty( font.stbtt_info, cast(c.int) glyph_index )
// }
// return false
} }
parser_scale :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32 parser_scale :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32
{ {
// profile(#procedure) // profile(#procedure)
// size_scale := size < 0.0 ? parser_scale_for_pixel_height( font, -size ) : parser_scale_for_mapping_em_to_pixels( font, size )
size_scale := size > 0.0 ? parser_scale_for_pixel_height( font, size ) : parser_scale_for_mapping_em_to_pixels( font, -size ) size_scale := size > 0.0 ? parser_scale_for_pixel_height( font, size ) : parser_scale_for_mapping_em_to_pixels( font, -size )
return size_scale return size_scale
} }
parser_scale_for_pixel_height :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32 parser_scale_for_pixel_height :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32
{ {
// switch font.kind {
// case .Freetype:
// freetype.set_pixel_sizes( font.freetype_info, 0, cast(u32) size )
// size_scale := size / cast(f32)font.freetype_info.units_per_em
// return size_scale
// case.STB_TrueType:
return stbtt.ScaleForPixelHeight( font.stbtt_info, size ) return stbtt.ScaleForPixelHeight( font.stbtt_info, size )
// }
// return 0
} }
parser_scale_for_mapping_em_to_pixels :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32 parser_scale_for_mapping_em_to_pixels :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32
{ {
// switch font.kind {
// case .Freetype:
// Inches_To_CM :: cast(f32) 2.54
// Points_Per_CM :: cast(f32) 28.3465
// CM_Per_Point :: cast(f32) 1.0 / DPT_DPCM
// CM_Per_Pixel :: cast(f32) 1.0 / DPT_PPCM
// DPT_DPCM :: cast(f32) 72.0 * Inches_To_CM // 182.88 points/dots per cm
// DPT_PPCM :: cast(f32) 96.0 * Inches_To_CM // 243.84 pixels per cm
// DPT_DPI :: cast(f32) 72.0
// // TODO(Ed): Don't assume the dots or pixels per inch.
// system_dpi :: DPT_DPI
// FT_Font_Size_Point_Unit :: 1.0 / 64.0
// FT_Point_10 :: 64.0
// points_per_em := (size / system_dpi ) * DPT_DPI
// freetype.set_char_size( font.freetype_info, 0, cast(freetype.F26Dot6) f32(points_per_em * FT_Point_10), cast(u32) DPT_DPI, cast(u32) DPT_DPI )
// size_scale := f32(f64(size) / cast(f64) font.freetype_info.units_per_em)
// return size_scale
// case .STB_TrueType:
return stbtt.ScaleForMappingEmToPixels( font.stbtt_info, size ) return stbtt.ScaleForMappingEmToPixels( font.stbtt_info, size )
// }
// return 0
} }

View File

@@ -136,22 +136,4 @@ vec2_64 :: proc {
vec2_64_from_vec2, vec2_64_from_vec2,
} }
import "../../grime"
@(deferred_none = profile_end, disabled = DISABLE_PROFILING)
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
grime.profile_begin(name, loc)
}
@(disabled = DISABLE_PROFILING)
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
grime.profile_begin(name, loc)
}
@(disabled = DISABLE_PROFILING)
profile_end :: #force_inline proc "contextless" () {
grime.profile_end()
}
//#endregion("Proc overload mappings") //#endregion("Proc overload mappings")

View File

@@ -0,0 +1,17 @@
package vefontcache
// Add profiling hookup here
// import ""
@(deferred_none = profile_end, disabled = DISABLE_PROFILING)
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
}
@(disabled = DISABLE_PROFILING)
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
}
@(disabled = DISABLE_PROFILING)
profile_end :: #force_inline proc "contextless" () {
}

View File

@@ -13,15 +13,14 @@ Shape_Key :: u32
Traditionally a shape only refers to resolving which glyph and Traditionally a shape only refers to resolving which glyph and
its position should be used for rendering. its position should be used for rendering.
For this library's case it also involes keeping any content For this library's case it also resolves any content that does not have to be done
that does not have to be resolved once again in the later stage of processing: on a per-frame basis for draw list generation.
* Resolve atlas lru codes * Resolve atlas lru codes
* Resolve glyph bounds and scale * Resolve glyph bounds and scale
* Resolve atlas region the glyph is associated with. * Resolve atlas region the glyph is associated with.
Ideally the user should resolve this shape once and cache/store it on their side. Ideally the user should resolve this shape once and cache/store it on their side.
They have the best ability to avoid costly lookups to streamline They have the best ability to avoid costly lookups.
a hot path to only focusing on draw list generation that must be computed every frame.
*/ */
Shaped_Text :: struct #packed { Shaped_Text :: struct #packed {
glyph : [dynamic]Glyph, glyph : [dynamic]Glyph,

View File

@@ -94,7 +94,8 @@ Context :: struct {
stack : Scope_Stack, stack : Scope_Stack,
cursor_pos : Vec2, // TODO(Ed): Review this (most likely not being used properly right now) colour : RGBAN, // Color used in draw interface TODO(Ed): use the stack
cursor_pos : Vec2, // TODO(Ed): Review this, no longer used much at all... (still useful I guess)
// Will apply a boost scalar (1.0 + alpha sharpen) to the colour's alpha which provides some sharpening of the edges. // Will apply a boost scalar (1.0 + alpha sharpen) to the colour's alpha which provides some sharpening of the edges.
// Has a boldening side-effect. If overblown will look smeared. // Has a boldening side-effect. If overblown will look smeared.
alpha_sharpen : f32, alpha_sharpen : f32,
@@ -647,11 +648,9 @@ get_cursor_pos :: #force_inline proc "contextless" ( ctx : Context ) -> Vec2 { r
get_snapped_position :: #force_inline proc "contextless" ( position : Vec2, view : Vec2 ) -> (snapped_position : Vec2) { get_snapped_position :: #force_inline proc "contextless" ( position : Vec2, view : Vec2 ) -> (snapped_position : Vec2) {
snap_quotient := 1 / Vec2 { max(view.x, 1), max(view.y, 1) } snap_quotient := 1 / Vec2 { max(view.x, 1), max(view.y, 1) }
should_snap := view * snap_quotient should_snap := view * snap_quotient
snapped_position = position snapped_position = position
snapped_position.x = ceil(position.x * view.x) * snap_quotient.x snapped_position.x = ceil(position.x * view.x) * snap_quotient.x
snapped_position.y = ceil(position.y * view.y) * snap_quotient.y snapped_position.y = ceil(position.y * view.y) * snap_quotient.y
snapped_position *= should_snap snapped_position *= should_snap
snapped_position.x = max(snapped_position.x, position.x) snapped_position.x = max(snapped_position.x, position.x)
snapped_position.y = max(snapped_position.y, position.y) snapped_position.y = max(snapped_position.y, position.y)
@@ -763,7 +762,7 @@ draw_text_normalized_space :: proc( ctx : ^Context,
} }
// Equivalent to draw_text_shape_normalized_space, however position's units is scaled to view and must be normalized. // Equivalent to draw_text_shape_normalized_space, however position's units is scaled to view and must be normalized.
@(optimization_mode="favor_size") // @(optimization_mode="favor_size")
draw_text_shape_view_space :: #force_inline proc( ctx : ^Context, draw_text_shape_view_space :: #force_inline proc( ctx : ^Context,
font : Font_ID, font : Font_ID,
px_size : f32, px_size : f32,
@@ -805,13 +804,13 @@ draw_text_shape_view_space :: #force_inline proc( ctx : ^Context,
} }
// Equivalent to draw_text_normalized_space, however position's units is scaled to view and must be normalized. // Equivalent to draw_text_normalized_space, however position's units is scaled to view and must be normalized.
@(optimization_mode = "favor_size") // @(optimization_mode = "favor_size")
draw_text_view_space :: proc(ctx : ^Context, draw_text_view_space :: proc(ctx : ^Context,
font : Font_ID, font : Font_ID,
px_size : f32, px_size : f32,
colour : RGBAN, colour : RGBAN,
view : Vec2, view : Vec2,
view_position : Vec2, position : Vec2,
scale : Vec2, scale : Vec2,
zoom : f32, // TODO(Ed): Implement Zoom support zoom : f32, // TODO(Ed): Implement Zoom support
text_utf8 : string text_utf8 : string
@@ -855,7 +854,7 @@ draw_text_view_space :: proc(ctx : ^Context,
) )
} }
@(optimization_mode = "favor_size") // @(optimization_mode = "favor_size")
draw_shape :: proc( ctx : ^Context, position, scale : Vec2, shape : Shaped_Text ) draw_shape :: proc( ctx : ^Context, position, scale : Vec2, shape : Shaped_Text )
{ {
profile(#procedure) profile(#procedure)
@@ -908,7 +907,7 @@ draw_shape :: proc( ctx : ^Context, position, scale : Vec2, shape : Shaped_Text
) )
} }
@(optimization_mode = "favor_size") // @(optimization_mode = "favor_size")
draw_text :: proc( ctx : ^Context, position, scale : Vec2, text_utf8 : string ) draw_text :: proc( ctx : ^Context, position, scale : Vec2, text_utf8 : string )
{ {
profile(#procedure) profile(#procedure)
@@ -1020,7 +1019,7 @@ measure_text_size :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size
entry := ctx.entries[font] entry := ctx.entries[font]
downscale := 1 / ctx.px_scalar target_scale := 1 / ctx.px_scalar
target_px_size := px_size * ctx.px_scalar target_px_size := px_size * ctx.px_scalar
target_font_scale := parser_scale( entry.parser_info, target_px_size ) target_font_scale := parser_scale( entry.parser_info, target_px_size )
@@ -1035,7 +1034,7 @@ measure_text_size :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size
target_font_scale, target_font_scale,
shaper_shape_text_uncached_advanced shaper_shape_text_uncached_advanced
) )
return shaped.size * downscale return shaped.size * target_scale
} }
get_font_vertical_metrics :: #force_inline proc ( ctx : ^Context, font : Font_ID, px_size : f32 ) -> ( ascent, descent, line_gap : f32 ) get_font_vertical_metrics :: #force_inline proc ( ctx : ^Context, font : Font_ID, px_size : f32 ) -> ( ascent, descent, line_gap : f32 )
@@ -1102,7 +1101,6 @@ shape_text_advanced :: #force_inline proc( ctx : ^Context, font : Font_ID, px_si
} }
// User handled shaped text. Will not be cached // User handled shaped text. Will not be cached
// @(disabled = true)
shape_text_latin_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size: f32, text_utf8 : string, shape : ^Shaped_Text ) shape_text_latin_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size: f32, text_utf8 : string, shape : ^Shaped_Text )
{ {
profile(#procedure) profile(#procedure)
@@ -1125,7 +1123,6 @@ shape_text_latin_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID,
} }
// User handled shaped text. Will not be cached // User handled shaped text. Will not be cached
// @(disabled = true)
shape_text_advanced_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size: f32, text_utf8 : string, shape : ^Shaped_Text ) shape_text_advanced_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size: f32, text_utf8 : string, shape : ^Shaped_Text )
{ {
profile(#procedure) profile(#procedure)