diff --git a/.gitignore b/.gitignore index fc37a2d..257aa8c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ Sectr.sublime-project Sectr.sublime-workspace ols.json .vscode/settings.json -thirdparty +# thirdparty # toolchain diff --git a/code/font/vefontcache/draw.odin b/code/font/vefontcache/draw.odin index dccff18..8f612fc 100644 --- a/code/font/vefontcache/draw.odin +++ b/code/font/vefontcache/draw.odin @@ -470,18 +470,18 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List, f32_allocated_x := cast(f32) glyph_buffer.allocated_x // Resolve how much space this glyph will allocate in the buffer - buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph_buffer.over_sample + glyph.over_sample + buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph_buffer.over_sample // Allocate a glyph glyph render target region (FBO) - to_allocate_x := buffer_size.x + to_allocate_x := buffer_size.x + 2.0 // If allocation would exceed buffer's bounds the buffer must be flush before this glyph can be rendered. glyph.flush_glyph_buffer = i32(f32_allocated_x + to_allocate_x) >= i32(glyph_buffer_size.x) - glyph.buffer_x = glyph.flush_glyph_buffer ? 0 : f32_allocated_x + glyph.buffer_x = f32_allocated_x * f32( i32( ! glyph.flush_glyph_buffer ) ) // The glyph buffer space transform for generate_glyph_pass_draw_list draw_transform := & glyph.draw_transform draw_transform.scale = font_scale * glyph_buffer.over_sample - draw_transform.pos = -1 * (glyph.bounds.p0) * draw_transform.scale + atlas.glyph_padding + draw_transform.pos = -1 * (glyph.bounds.p0) * draw_transform.scale + glyph_buffer.draw_padding draw_transform.pos.x += glyph.buffer_x to_glyph_buffer_space( & draw_transform.pos, & draw_transform.scale, glyph_buffer_size ) @@ -506,20 +506,15 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List, f32_allocated_x := cast(f32) glyph_buffer.allocated_x // Resolve how much space this glyph will allocate in the buffer - buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph.over_sample + glyph.over_sample + buffer_size := (glyph.bounds_size_scaled + glyph_buffer.draw_padding) * glyph.over_sample // Allocate a glyph glyph render target region (FBO) - to_allocate_x := buffer_size.x + to_allocate_x := buffer_size.x + 2.0 glyph_buffer.allocated_x += i32(to_allocate_x) // If allocation would exceed buffer's bounds the buffer must be flush before this glyph can be rendered. glyph.flush_glyph_buffer = i32(f32_allocated_x + to_allocate_x) >= i32(glyph_buffer_size.x) - // glyph.buffer_x = f32_allocated_x * f32( i32( glyph.flush_glyph_buffer ) ) - glyph.buffer_x = glyph.flush_glyph_buffer ? 0 : f32_allocated_x - // } - // for id, index in oversized - // { - // glyph := & glyph_pack[id] + glyph.buffer_x = f32_allocated_x * f32( i32( ! glyph.flush_glyph_buffer ) ) // Quad to for drawing atlas slot to target draw_quad := & glyph.draw_quad @@ -531,9 +526,9 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List, draw_quad.dst_scale = (glyph.bounds_size_scaled + glyph_padding) * target_scale // The glyph buffer space transform for generate_glyph_pass_draw_list - draw_transform := & glyph.draw_transform - draw_transform.scale = font_scale * glyph.over_sample - draw_transform.pos = -1 * glyph.bounds.p0 * draw_transform.scale + vec2(atlas.glyph_padding) + draw_transform := & glyph.draw_transform + draw_transform.scale = font_scale * glyph.over_sample + draw_transform.pos = -1 * glyph.bounds.p0 * draw_transform.scale + vec2(atlas.glyph_padding) draw_transform.pos.x += glyph.buffer_x to_glyph_buffer_space( & draw_transform.pos, & draw_transform.scale, glyph_buffer_size ) @@ -615,8 +610,8 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List, & glyph_buffer.allocated_x ) - dst_region_pos := glyph.region_pos - dst_region_size := glyph.region_size + dst_region_pos := glyph.region_pos + dst_region_size := glyph.region_size to_glyph_buffer_space( & dst_region_pos, & dst_region_size, atlas_size ) clear_target_region : Draw_Call @@ -634,12 +629,14 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List, end_index = cast(u32) len(glyph_buffer.clear_draw_list.indices) } - dst_glyph_pos := glyph.region_pos - dst_glyph_size := (glyph.bounds_size_scaled) + atlas.glyph_padding - to_glyph_buffer_space( & dst_glyph_pos, & dst_glyph_size, atlas_size ) + dst_glyph_pos := glyph.region_pos + dst_glyph_size := glyph.bounds_size_scaled + atlas.glyph_padding + // dst_glyph_size.y = ceil(dst_glyph_size.y) // Note(Ed): Seems to improve hinting + to_glyph_buffer_space( & dst_glyph_pos, & dst_glyph_size, atlas_size ) - src_position := Vec2 { glyph.buffer_x, 0 } - src_size := (glyph.bounds_size_scaled + atlas.glyph_padding) * glyph_buffer.over_sample + src_position := Vec2 { glyph.buffer_x, 0 } + src_size := (glyph.bounds_size_scaled + atlas.glyph_padding) * glyph_buffer.over_sample + // src_size.y = ceil(src_size.y) // Note(Ed): Seems to improve hinting to_target_space( & src_position, & src_size, glyph_buffer_size ) diff --git a/code/font/vefontcache/parser.odin b/code/font/vefontcache/parser.odin index e3e5f84..17ec818 100644 --- a/code/font/vefontcache/parser.odin +++ b/code/font/vefontcache/parser.odin @@ -74,23 +74,22 @@ parser_shutdown :: proc( ctx : ^Parser_Context ) { // TODO(Ed): Implement } -parser_load_font :: proc( ctx : ^Parser_Context, label : string, data : []byte ) -> (font : Parser_Font_Info) +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 := freetype.new_memory_face( ctx.ft_library, raw_data(data), cast(i32) len(data), 0, & font.freetype_info ) - // if error != .Ok do return + // 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 != .Ok do return + // if error_status != .Ok do error = true // } // case .STB_TrueType: - success := stbtt.InitFont( & font.stbtt_info, raw_data(data), 0 ) - if ! success do return + error = ! stbtt.InitFont( & font.stbtt_info, raw_data(data), 0 ) // } font.label = label @@ -298,10 +297,8 @@ parser_is_glyph_empty :: #force_inline proc "contextless" ( font : Parser_Font_I parser_scale :: #force_inline proc "contextless" ( font : Parser_Font_Info, size : f32 ) -> f32 { 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 = 1.0 + // 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 } diff --git a/code/font/vefontcache/shaper.odin b/code/font/vefontcache/shaper.odin index 7cda16b..2bf94d8 100644 --- a/code/font/vefontcache/shaper.odin +++ b/code/font/vefontcache/shaper.odin @@ -82,7 +82,7 @@ shaper_shape_harfbuzz :: #force_inline proc( ctx : ^Shaper_Context, text_utf8 : ascent := entry.ascent descent := entry.descent - line_gap :=entry.line_gap + line_gap := entry.line_gap max_line_width := f32(0) line_count := 1 @@ -226,7 +226,13 @@ shaper_shape_harfbuzz :: #force_inline proc( ctx : ^Shaper_Context, text_utf8 : return } -shaper_shape_text_uncached_advanced :: #force_inline proc( ctx : ^Shaper_Context, entry : Entry, font_px_size : f32, font_scale : f32, text_utf8 : string, output : ^Shaped_Text ) +shaper_shape_text_uncached_advanced :: #force_inline proc( ctx : ^Shaper_Context, + entry : Entry, + font_px_size : f32, + font_scale : f32, + text_utf8 : string, + output : ^Shaped_Text +) { profile(#procedure) assert( ctx != nil ) @@ -237,7 +243,13 @@ shaper_shape_text_uncached_advanced :: #force_inline proc( ctx : ^Shaper_Context shaper_shape_harfbuzz( ctx, text_utf8, entry, font_px_size, font_scale, output ) } -shaper_shape_text_latin :: #force_inline proc( ctx : ^Shaper_Context, entry : Entry, font_px_Size, font_scale : f32, text_utf8 : string, output : ^Shaped_Text ) +shaper_shape_text_latin :: #force_inline proc( ctx : ^Shaper_Context, + entry : Entry, + font_px_Size : f32, + font_scale : f32, + text_utf8 : string, + output : ^Shaped_Text +) { profile(#procedure) assert( ctx != nil ) @@ -278,8 +290,8 @@ shaper_shape_text_latin :: #force_inline proc( ctx : ^Shaper_Context, entry : En { append( & output.glyphs, glyph_index) append( & output.positions, Vec2 { - floor(position.x), - floor(position.y) + ceil(position.x), + ceil(position.y) }) } diff --git a/code/font/vefontcache/vefontcache.odin b/code/font/vefontcache/vefontcache.odin index 220d792..415be65 100644 --- a/code/font/vefontcache/vefontcache.odin +++ b/code/font/vefontcache/vefontcache.odin @@ -15,6 +15,11 @@ DISABLE_PROFILING :: true Font_ID :: distinct i32 Glyph :: distinct i32 +Load_Font_Error :: enum(i32) { + None, + Parser_Failed, +} + Entry :: struct { parser_info : Parser_Font_Info, shaper_info : Shaper_Info, @@ -54,22 +59,25 @@ Context :: struct { calls_offset : int, }, + debug_print : b32, + debug_print_verbose : b32, + + //TODO(Ed): Add a push/pop stack for the below + // Helps with hinting snap_width : f32, snap_height : f32, - colour : Colour, // Color used in draw interface - cursor_pos : Vec2, - alpha_scalar : f32, // Will apply a multiplier to the colour's alpha which provides some sharpening of the edges. + // camera : Camera, // TODO(Ed): Add camera support + colour : Colour, // Color used in draw interface + cursor_pos : Vec2, + alpha_sharpen : f32, // Will apply a boost scalar (1.0 + alpha sharpen) to the colour's alpha which provides some sharpening of the edges. // Used by draw interface to super-scale the text by // upscaling px_size with px_scalar and then down-scaling // the draw_list result by the same amount. - px_scalar : f32, + px_scalar : f32, // Used to upscale which font size is used to render (improves hinting) default_curve_quality : i32, - - debug_print : b32, - debug_print_verbose : b32, } Init_Atlas_Region_Params :: struct { @@ -135,7 +143,7 @@ Init_Shaper_Params :: struct { } Init_Shaper_Params_Default :: Init_Shaper_Params { - snap_glyph_position = true, + snap_glyph_position = false, adv_snap_small_font_threshold = 0, } @@ -158,7 +166,9 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, glyph_draw_params := Init_Glyph_Draw_Params_Default, shape_cache_params := Init_Shape_Cache_Params_Default, shaper_params := Init_Shaper_Params_Default, - alpha_sharpen := 0.2, + alpha_sharpen : f32 = 0.2, + px_scalar : f32 = 1.0, + // Curve quality to use for a font when unspecified, // Affects step size for bezier curve passes in generate_glyph_pass_draw_list default_curve_quality : u32 = 3, @@ -170,7 +180,9 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, ctx.backing = allocator context.allocator = ctx.backing - ctx.colour = { 1, 1, 1, 1 } + ctx.colour = { 1, 1, 1, 1 } + ctx.alpha_sharpen = alpha_sharpen + ctx.px_scalar = px_scalar shaper_ctx := & ctx.shaper_ctx shaper_ctx.adv_snap_small_font_threshold = f32(shaper_params.adv_snap_small_font_threshold) @@ -292,7 +304,7 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, glyph_buffer.shape_gen_scratch, error = make( [dynamic]Vertex, len = 0, cap = 4 * Kilobyte ) assert(error == .None, "VEFontCache.init : Failed to allocate shape_gen_scratch") - batch_cache := & glyph_buffer.batch_cache + batch_cache := & glyph_buffer.batch_cache batch_cache.cap = i32(glyph_draw_params.batch_glyph_limit) batch_cache.num = 0 batch_cache.table, error = make( map[u32]b8, uint(glyph_draw_params.shape_gen_scratch_reserve) ) @@ -314,12 +326,25 @@ hot_reload :: proc( ctx : ^Context, allocator : Allocator ) ctx.backing = allocator context.allocator = ctx.backing using ctx + // using ctx.atlas reload_array( & entries, allocator ) - reload_array( & draw_list.vertices, allocator) - reload_array( & draw_list.indices, allocator ) - reload_array( & draw_list.calls, allocator ) + reload_array( & glyph_buffer.draw_list.calls, allocator ) + reload_array( & glyph_buffer.draw_list.indices, allocator ) + reload_array( & glyph_buffer.draw_list.vertices, allocator ) + + reload_array( & glyph_buffer.clear_draw_list.calls, allocator ) + reload_array( & glyph_buffer.clear_draw_list.indices, allocator ) + reload_array( & glyph_buffer.clear_draw_list.vertices, allocator ) + + reload_map( & glyph_buffer.batch_cache.table, allocator ) + reload_array( & glyph_buffer.shape_gen_scratch, allocator ) + + reload_array_soa( & glyph_buffer.glyph_pack, allocator ) + reload_array( & glyph_buffer.oversized, allocator ) + reload_array( & glyph_buffer.to_cache, allocator ) + reload_array( & glyph_buffer.cached, allocator ) lru_reload( & atlas.region_a.state, allocator) lru_reload( & atlas.region_b.state, allocator) @@ -330,28 +355,14 @@ hot_reload :: proc( ctx : ^Context, allocator : Allocator ) for idx : i32 = 0; idx < i32(len(shape_cache.storage)); idx += 1 { stroage_entry := & shape_cache.storage[idx] using stroage_entry - - reload_array( & glyphs, allocator ) + reload_array( & glyphs, allocator ) reload_array( & positions, allocator ) } - - reload_array( & glyph_buffer.draw_list.calls, allocator ) - reload_array( & glyph_buffer.draw_list.indices, allocator ) - reload_array( & glyph_buffer.draw_list.vertices, allocator ) - - reload_array( & glyph_buffer.clear_draw_list.calls, allocator ) - reload_array( & glyph_buffer.clear_draw_list.indices, allocator ) - reload_array( & glyph_buffer.clear_draw_list.vertices, allocator ) - - reload_array_soa( & glyph_buffer.glyph_pack, allocator ) - reload_array( & glyph_buffer.oversized, allocator ) - reload_array( & glyph_buffer.to_cache, allocator ) - reload_array( & glyph_buffer.cached, allocator ) - - reload_array( & glyph_buffer.shape_gen_scratch, allocator ) - reload_map( & glyph_buffer.batch_cache.table, allocator ) - reload_array( & shape_cache.storage, allocator ) + + reload_array( & draw_list.vertices, allocator) + reload_array( & draw_list.indices, allocator ) + reload_array( & draw_list.calls, allocator ) } shutdown :: proc( ctx : ^Context ) @@ -363,12 +374,23 @@ shutdown :: proc( ctx : ^Context ) for & entry in entries { unload_font( ctx, entry.id ) } - delete( entries ) + + delete( glyph_buffer.draw_list.vertices ) + delete( glyph_buffer.draw_list.indices ) + delete( glyph_buffer.draw_list.calls ) - delete( draw_list.vertices ) - delete( draw_list.indices ) - delete( draw_list.calls ) + delete( glyph_buffer.clear_draw_list.vertices ) + delete( glyph_buffer.clear_draw_list.indices ) + delete( glyph_buffer.clear_draw_list.calls ) + + delete( glyph_buffer.batch_cache.table ) + delete( glyph_buffer.shape_gen_scratch ) + + delete_soa( glyph_buffer.glyph_pack) + delete( glyph_buffer.oversized) + delete( glyph_buffer.to_cache) + delete( glyph_buffer.cached) lru_free( & atlas.region_a.state ) lru_free( & atlas.region_b.state ) @@ -383,28 +405,16 @@ shutdown :: proc( ctx : ^Context ) delete( positions ) } lru_free( & shape_cache.state ) - - delete( glyph_buffer.draw_list.vertices ) - delete( glyph_buffer.draw_list.indices ) - delete( glyph_buffer.draw_list.calls ) - - delete( glyph_buffer.clear_draw_list.vertices ) - delete( glyph_buffer.clear_draw_list.indices ) - delete( glyph_buffer.clear_draw_list.calls ) - - delete_soa( glyph_buffer.glyph_pack) - delete( glyph_buffer.oversized) - delete( glyph_buffer.to_cache) - delete( glyph_buffer.cached) - - delete( glyph_buffer.shape_gen_scratch ) - delete( glyph_buffer.batch_cache.table ) + + delete( draw_list.vertices ) + delete( draw_list.indices ) + delete( draw_list.calls ) shaper_shutdown( & shaper_ctx ) parser_shutdown( & parser_ctx ) } -load_font :: proc( ctx : ^Context, label : string, data : []byte, size_px : f32, glyph_curve_quality : u32 = 0 ) -> (font_id : Font_ID) +load_font :: proc( ctx : ^Context, label : string, data : []byte, glyph_curve_quality : u32 = 0 ) -> (font_id : Font_ID, error : Load_Font_Error) { profile(#procedure) assert( ctx != nil ) @@ -430,7 +440,12 @@ load_font :: proc( ctx : ^Context, label : string, data : []byte, size_px : f32, entry.used = true profile_begin("calling loaders") - entry.parser_info = parser_load_font( & parser_ctx, label, data ) + parser_error : b32 + entry.parser_info, parser_error = parser_load_font( & parser_ctx, label, data ) + if parser_error { + error = .Parser_Failed + return + } entry.shaper_info = shaper_load_font( & shaper_ctx, label, data ) profile_end() @@ -459,7 +474,6 @@ unload_font :: proc( ctx : ^Context, font : Font_ID ) assert( font >= 0 && int(font) < len(ctx.entries) ) context.allocator = ctx.backing - using ctx entry := & ctx.entries[ font ] entry.used = false @@ -477,17 +491,20 @@ configure_snap :: #force_inline proc( ctx : ^Context, snap_width, snap_height : ctx.snap_height = f32(snap_height) } -get_cursor_pos :: #force_inline proc( ctx : ^Context ) -> Vec2 { assert(ctx != nil); return ctx.cursor_pos } -set_alpha_scalar :: #force_inline proc( ctx : ^Context, scalar : f32 ) { assert(ctx != nil); ctx.alpha_scalar = scalar } -set_colour :: #force_inline proc( ctx : ^Context, colour : Colour ) { assert(ctx != nil); ctx.colour = colour } +get_cursor_pos :: #force_inline proc( ctx : ^Context ) -> Vec2 { assert(ctx != nil); return ctx.cursor_pos } +set_alpha_scalar :: #force_inline proc( ctx : ^Context, scalar : f32 ) { assert(ctx != nil); ctx.alpha_sharpen = scalar } +set_px_scalar :: #force_inline proc( ctx : ^Context, scalar : f32 ) { assert(ctx != nil); ctx.px_scalar = scalar } +set_colour :: #force_inline proc( ctx : ^Context, colour : Colour ) { assert(ctx != nil); ctx.colour = colour } -draw_text :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, text_utf8 : string ) -> b32 +draw_text :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, text_utf8 : string ) { profile(#procedure) assert( ctx != nil ) assert( font >= 0 && int(font) < len(ctx.entries) ) assert( len(text_utf8) > 0 ) + entry := ctx.entries[ font ] + ctx.cursor_pos = {} position := position @@ -495,49 +512,57 @@ draw_text :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position.y = ceil(position.y * ctx.snap_height) / ctx.snap_height colour := ctx.colour - colour.a = 1.0 + ctx.alpha_scalar + colour.a = 1.0 + ctx.alpha_sharpen - // TODO(Ed): Test this. - // px_size_scalar :: 2 - // px_size := px_size * px_size_scalar - // scale := scale * (1 / px_size_scalar) + font_scale := parser_scale( entry.parser_info, px_size ) - entry := ctx.entries[ font ] - font_scale := parser_scale( entry.parser_info, px_size ) - shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_uncached_advanced ) + px_upscale := px_size * ctx.px_scalar + downscale := scale * (1 / ctx.px_scalar) + font_scale_upscale := parser_scale( entry.parser_info, px_upscale ) + + shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, + font, + entry, + px_upscale, + font_scale_upscale, + shaper_shape_text_uncached_advanced + ) ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, - font_scale, - position, - scale, + font_scale_upscale, + position, + downscale, ctx.snap_width, ctx.snap_height ) - return true } -draw_text_no_snap :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, text_utf8 : string ) -> b32 -{ - profile(#procedure) - assert( ctx != nil ) - assert( font >= 0 && int(font) < len(ctx.entries) ) - assert( len(text_utf8) > 0 ) +// draw_text_no_snap :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, text_utf8 : string ) +// { +// profile(#procedure) +// assert( ctx != nil ) +// assert( font >= 0 && int(font) < len(ctx.entries) ) +// assert( len(text_utf8) > 0 ) - ctx.cursor_pos = {} +// ctx.cursor_pos = {} - colour := ctx.colour - colour.a = 1.0 + ctx.alpha_scalar +// entry := ctx.entries[ font ] - entry := ctx.entries[ font ] - font_scale := parser_scale( entry.parser_info, px_size ) - shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_latin ) - ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, font_scale, position, scale, ctx.snap_width, ctx.snap_height ) - return true -} +// colour := ctx.colour +// colour.a = 1.0 + ctx.alpha_sharpen + +// px_size_upscaled := px_size * ctx.px_scalar +// scale_downsample := scale * (1 / ctx.px_scalar) +// font_scale_upscale := parser_scale( entry.parser_info, px_size_upscaled ) + +// font_scale := parser_scale( entry.parser_info, -px_size ) +// shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_latin ) +// ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, font_scale, position, scale, ctx.snap_width, ctx.snap_height ) +// } // Resolve the shape and track it to reduce iteration overhead -draw_text_shape :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, shape : Shaped_Text ) -> b32 +draw_text_shape :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, shape : Shaped_Text ) { profile(#procedure) assert( ctx != nil ) @@ -546,30 +571,45 @@ draw_text_shape :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : position.x = ceil(position.x * ctx.snap_width ) / ctx.snap_width position.y = ceil(position.y * ctx.snap_height) / ctx.snap_height - colour := ctx.colour - colour.a = 1.0 + ctx.alpha_scalar + entry := ctx.entries[ font ] - entry := ctx.entries[ font ] - font_scale := parser_scale( entry.parser_info, px_size ) - ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, font_scale, position, scale, ctx.snap_width, ctx.snap_height ) - return true + colour := ctx.colour + colour.a = 1.0 + ctx.alpha_sharpen + + font_scale := parser_scale( entry.parser_info, px_size ) + + px_upscale := px_size * ctx.px_scalar + downscale := scale * (1 / ctx.px_scalar) + font_scale_upscale := parser_scale( entry.parser_info, px_upscale ) + + ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, + colour, + entry, + font_scale_upscale, + position, + downscale, + ctx.snap_width, + ctx.snap_height + ) } // Resolve the shape and track it to reduce iteration overhead -draw_text_shape_no_snap :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, shape : Shaped_Text ) -> b32 -{ - profile(#procedure) - assert( ctx != nil ) - assert( font >= 0 && int(font) < len(ctx.entries) ) +// draw_text_shape_no_snap :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, position, scale : Vec2, shape : Shaped_Text ) +// { +// profile(#procedure) +// assert( ctx != nil ) +// assert( font >= 0 && int(font) < len(ctx.entries) ) - colour := ctx.colour - colour.a = 1.0 + ctx.alpha_scalar +// colour := ctx.colour +// colour.a = 1.0 + ctx.alpha_sharpen - entry := ctx.entries[ font ] - font_scale := parser_scale( entry.parser_info, px_size ) - ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, font_scale, position, scale, ctx.snap_width, ctx.snap_height ) - return true -} +// px_size_upscaled := px_size * ctx.px_scalar +// scale := scale * (1 / ctx.px_scalar) + +// entry := ctx.entries[ font ] +// font_scale := parser_scale( entry.parser_info, px_size ) +// ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer, colour, entry, font_scale, position, scale, ctx.snap_width, ctx.snap_height ) +// } get_draw_list :: #force_inline proc( ctx : ^Context, optimize_before_returning := true ) -> ^Draw_List { assert( ctx != nil ) @@ -613,20 +653,28 @@ measure_text_size :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size assert( ctx != nil ) assert( font >= 0 && int(font) < len(ctx.entries) ) - entry := ctx.entries[font] - font_scale := parser_scale( entry.parser_info, px_size ) - shaped := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_uncached_advanced ) + entry := ctx.entries[font] + + px_size_upscaled := px_size * ctx.px_scalar + font_scale_upscaled := parser_scale( entry.parser_info, px_size_upscaled ) + + // font_scale := parser_scale( entry.parser_info, px_size ) + shaped := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size_upscaled, font_scale_upscaled, shaper_shape_text_uncached_advanced ) return shaped.size } -get_font_vertical_metrics :: #force_inline proc ( ctx : ^Context, font : Font_ID, px_szie : 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 ) { assert( ctx != nil ) assert( font >= 0 && int(font) < len(ctx.entries) ) - entry := & ctx.entries[ font ] - // ascent_i32, descent_i32, line_gap_i32 := parser_get_font_vertical_metrics( entry.parser_info ) - font_scale := parser_scale( entry.parser_info, px_szie ) + entry := ctx.entries[ font ] + + font_scale := parser_scale( entry.parser_info, px_size ) + + px_size_upscaled := px_size * ctx.px_scalar + downscale := 1 / px_size_upscaled + font_scale_upscaled := parser_scale( entry.parser_info, px_size_upscaled ) ascent = font_scale * entry.ascent descent = font_scale * entry.descent @@ -643,8 +691,19 @@ shape_text_latin :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size profile(#procedure) assert( len(text_utf8) > 0 ) entry := ctx.entries[ font ] + font_scale := parser_scale( entry.parser_info, px_size ) - return shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_latin ) + + px_size_upscaled := px_size * ctx.px_scalar + font_scale_upscaled := parser_scale( entry.parser_info, px_size_upscaled ) + + return shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, + font, + entry, + px_size_upscaled, + font_scale_upscaled, + shaper_shape_text_latin + ) } shape_text_advanced :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, text_utf8 : string ) -> Shaped_Text @@ -652,20 +711,33 @@ shape_text_advanced :: #force_inline proc( ctx : ^Context, font : Font_ID, px_si profile(#procedure) assert( len(text_utf8) > 0 ) entry := ctx.entries[ font ] + font_scale := parser_scale( entry.parser_info, px_size ) - return shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, font, entry, px_size, font_scale, shaper_shape_text_uncached_advanced ) + + px_size_upscaled := px_size * ctx.px_scalar + font_scale_upscaled := parser_scale( entry.parser_info, px_size_upscaled ) + + return shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, + font, + entry, + px_size_upscaled, + font_scale_upscaled, + shaper_shape_text_uncached_advanced + ) } // User handled shaped text. Will not be cached -shape_text_latin_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, text_utf8 : string, entry : ^Entry, allocator := context.allocator ) -> Shaped_Text +shape_text_latin_uncached :: #force_inline proc( ctx : ^Context, font : Font_ID, text_utf8 : string, entry : ^Entry, shape : ^Shaped_Text ) { - return {} + assert(false) + return } // User handled shaped text. Will not be cached -shape_text_advanced_uncahed :: #force_inline proc( ctx : ^Context, font : Font_ID, text_utf8 : string, entry : ^Entry, allocator := context.allocator ) -> Shaped_Text +shape_text_advanced_uncahed :: #force_inline proc( ctx : ^Context, font : Font_ID, text_utf8 : string, entry : ^Entry, shape : ^Shaped_Text ) { - return {} + assert(false) + return } //#endregion("shaping") diff --git a/code/sectr/app/scratch.odin b/code/sectr/app/scratch.odin index 09fd51e..4f944db 100644 --- a/code/sectr/app/scratch.odin +++ b/code/sectr/app/scratch.odin @@ -4,7 +4,7 @@ package sectr import sokol_gfx "thirdparty:sokol/gfx" -DebugData :: struct { +ScratchData :: struct { square_size : i32, square_pos : Vec2, @@ -33,11 +33,4 @@ DebugData :: struct { path_lorem : string, lorem_content : []byte, lorem_parse : PWS_ParseResult, - - gfx_clear_demo_pass_action : sokol_gfx.Pass_Action, - gfx_tri_demo_state : struct { - pipeline : sokol_gfx.Pipeline, - bindings : sokol_gfx.Bindings, - pass_action : sokol_gfx.Pass_Action, - }, } diff --git a/code/sectr/app/state.odin b/code/sectr/app/state.odin index d96a857..514d005 100644 --- a/code/sectr/app/state.odin +++ b/code/sectr/app/state.odin @@ -221,7 +221,7 @@ State :: struct { staged_input_events : Array(InputEvent), // TODO(Ed): Add a multi-threaded guard for accessing or mutating staged_input_events. - debug : DebugData, + debug : ScratchData, project : Project, @@ -252,7 +252,6 @@ State :: struct { font_rec_mono_semicasual_reg : FontID, default_font : FontID, - // Context tracking // These are used as implicit contextual states when doing immediate mode interfaces // or for event callbacks that need their context assigned @@ -281,7 +280,7 @@ frametime_delta32 :: #force_inline proc "contextless" () -> f32 { app_config :: #force_inline proc "contextless" () -> AppConfig { return get_state().config } app_color_theme :: #force_inline proc "contextless" () -> AppColorTheme { return get_state().config.color_theme } -debug_data :: #force_inline proc "contextless" () -> DebugData { return get_state().debug } +debug_data :: #force_inline proc "contextless" () -> ScratchData { return get_state().debug } get_frametime :: #force_inline proc "contextless" () -> FrameTime { return get_state().frametime } get_default_font :: #force_inline proc "contextless" () -> FontID { return get_state().default_font } get_input_state :: #force_inline proc "contextless" () -> InputState { return (get_state().input ^) } diff --git a/code/sectr/engine/client_api.odin b/code/sectr/engine/client_api.odin index ed924a9..7db5104 100644 --- a/code/sectr/engine/client_api.odin +++ b/code/sectr/engine/client_api.odin @@ -152,8 +152,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem color_theme = App_Thm_Dusk - font_size_screen_scalar = 2.0 - font_size_canvas_scalar = 2.0 + font_size_screen_scalar = 1.0 + font_size_canvas_scalar = 1.0 } Desired_OS_Scheduler_MS :: 1 @@ -265,43 +265,44 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem if true { font_provider_startup( & font_provider_ctx ) - path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" }) - font_rec_mono_semicasual_reg = font_load( path_rec_mono_semicasual_reg, 16.0, "RecMonoSemiCasual_Regular" ) - // path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } ) - // font_squidgy_slimes = font_load( path_squidgy_slimes, 32.0, "Squidgy_Slime" ) + // Load default font + path_fira_cousine := strings.concatenate( { Path_Assets, "FiraCousine-Regular.ttf" } ) + font_fira_cousine = font_load( path_fira_cousine, "Fira Cousine", 16.0 ) + default_font = font_fira_cousine + + // Aysnc load the others + + // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) + // font_arial_unicode_ms = font_load( path_arial_unicode_ms, "Arial_Unicode_MS", 16.0 ) // path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } ) - // font_firacode = font_load( path_firacode, 16.0, "FiraCode" ) - - path_fira_cousine := strings.concatenate( { Path_Assets, "FiraCousine-Regular.ttf" } ) - font_fira_cousine = font_load( path_fira_cousine, 16.0, "Fira Cousine" ) - - // path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } ) - // font_open_sans = font_load( path_open_sans, 16.0, "OpenSans" ) - - // path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) - // font_noto_sans = font_load( path_noto_sans, 16.0, "NotoSans" ) + // font_firacode = font_load( path_firacode, "FiraCode", 16.0 ) // path_neodgm_code := strings.concatenate( { Path_Assets, "neodgm_code.ttf"} ) - // font_neodgm_code = font_load( path_neodgm_code, 32.0, "NeoDunggeunmo Code" ) + // font_neodgm_code = font_load( path_neodgm_code, "NeoDunggeunmo Code", 32.0 ) + + // path_noto_sans := strings.concatenate( { Path_Assets, "NotoSans-Regular.ttf" } ) + // font_noto_sans = font_load( path_noto_sans, "NotoSans", 16.0 ) + + // path_open_sans := strings.concatenate( { Path_Assets, "OpenSans-Regular.ttf" } ) + // font_open_sans = font_load( path_open_sans, "OpenSans", 16.0 ) // path_rec_mono_linear := strings.concatenate( { Path_Assets, "RecMonoLinear-Regular-1.084.ttf" }) - // font_rec_mono_linear = font_load( path_rec_mono_linear, 16.0, "RecMonoLinear Regular" ) + // font_rec_mono_linear = font_load( path_rec_mono_linear, "RecMonoLinear Regular", 32.0 ) // path_roboto_regular := strings.concatenate( { Path_Assets, "Roboto-Regular.ttf"} ) - // font_roboto_regular = font_load( path_roboto_regular, 32.0, "Roboto Regular" ) + // font_roboto_regular = font_load( path_roboto_regular, "Roboto Regular", 32.0 ) // path_roboto_mono_regular := strings.concatenate( { Path_Assets, "RobotoMono-Regular.ttf"} ) - // font_roboto_mono_regular = font_load( path_roboto_mono_regular, 32.0, "Roboto Mono Regular" ) + // font_roboto_mono_regular = font_load( path_roboto_mono_regular, "Roboto Mono Regular", 32.0 ) - // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) - // font_arial_unicode_ms = font_load( path_arial_unicode_ms, 16.0, "Arial_Unicode_MS" ) + // path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" }) + // font_rec_mono_semicasual_reg = font_load( path_rec_mono_semicasual_reg, "RecMonoSemiCasual_Regular", 16 ) - // path_arial_unicode_ms := strings.concatenate( { Path_Assets, "Arial Unicode MS.ttf" } ) - // font_arial_unicode_ms = font_load( path_arial_unicode_ms, 16.0, "Arial_Unicode_MS" ) + // path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } ) + // font_squidgy_slimes = font_load( path_squidgy_slimes, "Squidgy_Slime", 32.0 ) - default_font = font_fira_cousine log( "Default font loaded" ) } @@ -451,6 +452,9 @@ hot_reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_ slab_reload( persistent_slab, persistent_allocator() ) + str_cache_reload( & string_cache, persistent_allocator(), persistent_allocator() ) + str_cache_set_module_ctx( & string_cache ) + // input_reload() { using input_events @@ -463,9 +467,6 @@ hot_reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_ font_provider_reload( & font_provider_ctx ) - str_cache_reload( & string_cache, persistent_allocator(), persistent_allocator() ) - str_cache_set_module_ctx( & string_cache ) - slab_reload( frame_slab, frame_allocator()) slab_reload( transient_slab, transient_allocator()) @@ -532,8 +533,8 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32 // config.engine_refresh_hz = 165 // config.color_theme = App_Thm_Light - config.color_theme = App_Thm_Dusk - // config.color_theme = App_Thm_Dark + // config.color_theme = App_Thm_Dusk + config.color_theme = App_Thm_Dark sokol_width := sokol_app.widthf() sokol_height := sokol_app.heightf() diff --git a/code/sectr/engine/render.odin b/code/sectr/engine/render.odin index 8026e78..184fb06 100644 --- a/code/sectr/engine/render.odin +++ b/code/sectr/engine/render.odin @@ -116,7 +116,7 @@ render_mode_2d_workspace :: proc( screen_extent : Vec2, cam : Camera, input : In } } -render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State, ve_ctx : ^ve.Context, ve_render : VE_RenderData, config : AppConfig, debug : ^DebugData ) +render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State, ve_ctx : ^ve.Context, ve_render : VE_RenderData, config : AppConfig, debug : ^ScratchData ) { profile(#procedure) screen_size := screen_extent * 2 @@ -158,7 +158,7 @@ render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State font := font if font.key == Font_Default.key do font = default_font - shape := shape_text_cached( content, font, size, app_config().font_size_screen_scalar ) + shape := shape_text_cached( content, font, size, 1.0 ) draw_text_shape_pos_extent( shape, font, size, pos, color ) } @@ -174,14 +174,14 @@ render_mode_screenspace :: proc( screen_extent : Extents2, screen_ui : ^UI_State position.y -= debug.draw_debug_text_y content := str_fmt( format, ..args ) - text_size := measure_text_size( content, default_font, 14.0, 0.0 ) - debug_draw_text( content, position, 12.0 ) + text_size := measure_text_size( content, default_font, 16.0, 0.0 ) + debug_draw_text( content, position, 16.0 ) debug.draw_debug_text_y += text_size.y } profile("debug_text_vis") if true { - fps_size : f32 = 14.0 + fps_size : f32 = 20.0 fps_msg := str_fmt( "FPS: %0.2f", fps_avg) fps_msg_size := measure_text_size( fps_msg, default_font, fps_size, 0.0 ) fps_msg_pos := screen_get_corners().top_right - { fps_msg_size.x, fps_msg_size.y } @@ -906,13 +906,16 @@ draw_text_string_pos_norm :: #force_inline proc( text : string, id : FontID, fon width := app_window.extent.x * 2 height := app_window.extent.y * 2 - ve_id, resolved_size := font_provider_resolve_draw_id( id, font_size * config.font_size_screen_scalar ) + ve_id, resolved_size := font_provider_resolve_draw_id( id, font_size ) color_norm := normalize_rgba8(color) - screen_size_norm := Vec2{1 / width, 1 / height} + screen_size_norm := 1 / Vec2 { width, height } + draw_scale := screen_size_norm * scale + + // ve.set_px_scalar( & font_provider_ctx.ve_ctx, config.font_size_screen_scalar ) ve.set_colour( & font_provider_ctx.ve_ctx, color_norm ) - ve.draw_text( & font_provider_ctx.ve_ctx, ve_id, f32(resolved_size), pos, screen_size_norm * scale * (1 / config.font_size_screen_scalar), text ) + ve.draw_text( & font_provider_ctx.ve_ctx, ve_id, f32(resolved_size), pos, draw_scale, text ) return } @@ -934,13 +937,14 @@ draw_text_shape_pos_norm :: #force_inline proc( shape : ShapedText, id : FontID, width := app_window.extent.x * 2 height := app_window.extent.y * 2 - ve_id, resolved_size := font_provider_resolve_draw_id( id, font_size * config.font_size_screen_scalar ) + ve_id, resolved_size := font_provider_resolve_draw_id( id, font_size ) color_norm := normalize_rgba8(color) screen_size_norm := Vec2 { 1 / width, 1 / height } + // ve.set_px_scalar( & font_provider_ctx.ve_ctx, config.font_size_screen_scalar ) ve.set_colour( & font_provider_ctx.ve_ctx, color_norm ) - ve.draw_text_shape( & font_provider_ctx.ve_ctx, ve_id, f32(resolved_size), pos, screen_size_norm * scale * (1 / config.font_size_screen_scalar), shape ) + ve.draw_text_shape( & font_provider_ctx.ve_ctx, ve_id, f32(resolved_size), pos, screen_size_norm * scale, shape ) return } @@ -964,8 +968,8 @@ draw_text_string_pos_extent_zoomed :: #force_inline proc( text : string, id : Fo zoom_adjust_size := size * zoom // Over-sample font-size for any render under a camera - over_sample : f32 = f32(config.font_size_canvas_scalar) - zoom_adjust_size *= over_sample + // over_sample : f32 = f32(config.font_size_canvas_scalar) + // zoom_adjust_size *= over_sample pos_offset := (pos + cam_offset) render_pos := ws_view_to_render_pos(pos) @@ -984,9 +988,10 @@ draw_text_string_pos_extent_zoomed :: #force_inline proc( text : string, id : Fo } // Down-sample back - text_scale /= over_sample + // text_scale /= over_sample color_norm := normalize_rgba8(color) + // ve.set_px_scalar( & get_state().font_provider_ctx.ve_ctx, config.font_size_canvas_scalar ) ve.set_colour( & get_state().font_provider_ctx.ve_ctx, color_norm ) ve.draw_text( & get_state().font_provider_ctx.ve_ctx, ve_id, f32(resolved_size), normalized_pos, text_scale, text ) } @@ -1000,7 +1005,7 @@ draw_text_shape_pos_extent_zoomed :: #force_inline proc( shape : ShapedText, id // Over-sample font-size for any render under a camera over_sample : f32 = f32(state.config.font_size_canvas_scalar) - zoom_adjust_size *= over_sample + // zoom_adjust_size *= over_sample pos_offset := (pos + cam_offset) render_pos := ws_view_to_render_pos(pos) @@ -1019,9 +1024,10 @@ draw_text_shape_pos_extent_zoomed :: #force_inline proc( shape : ShapedText, id } // Down-sample back - text_scale /= over_sample + // text_scale /= over_sample color_norm := normalize_rgba8(color) + // ve.set_px_scalar( & get_state().font_provider_ctx.ve_ctx, config.font_size_canvas_scalar ) ve.set_colour( & font_provider_ctx.ve_ctx, color_norm ) ve.draw_text_shape( & font_provider_ctx.ve_ctx, ve_id, f32_resolved_size, normalized_pos, text_scale, shape ) } diff --git a/code/sectr/engine/update.odin b/code/sectr/engine/update.odin index 27814eb..d2792d8 100644 --- a/code/sectr/engine/update.odin +++ b/code/sectr/engine/update.odin @@ -302,11 +302,13 @@ update :: proc( delta_time : f64 ) -> b32 // TODO(Ed): We need input buffer so that we can consume input actions based on the UI with priority + font_provider_set_px_scalar( app_config().font_size_screen_scalar ) ui_screen_tick( & get_state().screen_ui ) //region WorkspaceImgui Tick if true { + font_provider_set_px_scalar( app_config().font_size_canvas_scalar ) profile("Workspace Imgui") // Creates the root box node, set its as the first parent. diff --git a/code/sectr/font/provider.odin b/code/sectr/font/provider.odin index 99db79a..9c1e72d 100644 --- a/code/sectr/font/provider.odin +++ b/code/sectr/font/provider.odin @@ -66,8 +66,8 @@ font_provider_shutdown :: proc( ctx : ^FontProviderContext ) } font_load :: proc(path_file : string, + desired_id : string = Font_Load_Gen_ID, default_size : i32 = Font_Load_Use_Default_Size, - desired_id : string = Font_Load_Gen_ID ) -> FontID { provider_data := & get_state().font_provider_ctx; using provider_data @@ -108,7 +108,7 @@ font_load :: proc(path_file : string, // logf("Loading at size %v", font_size) id := (font_size / Font_Size_Interval) + (font_size % Font_Size_Interval) ve_id := & def.size_table[id - 1] - ve_ret_id := ve.load_font( & ve_ctx, desired_id, font_data, f32(font_size) ) + ve_ret_id, error := ve.load_font( & ve_ctx, desired_id, font_data ) (ve_id^) = ve_ret_id } @@ -116,6 +116,10 @@ font_load :: proc(path_file : string, return fid } +font_provider_set_px_scalar :: #force_inline proc( scalar : f32 ) { + ve.set_px_scalar( & get_state().font_provider_ctx.ve_ctx, scalar ) +} + Font_Use_Default_Size :: f32(0.0) font_provider_resolve_draw_id :: #force_inline proc( id : FontID, size := Font_Use_Default_Size ) -> (ve_id :ve.Font_ID, resolved_size : i32) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 55626ee..5d7a531 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -222,7 +222,9 @@ push-location $path_root # $build_args += $flag_sanitize_address # $build_args += $flag_sanitize_memory # $build_args += $flag_show_debug_messages - write-host $build_args + foreach ($arg in $build_args) { + write-host `t $arg -ForegroundColor Cyan + } if ( Test-Path $module_dll) { $module_dll_pre_build_hash = get-filehash -path $module_dll -Algorithm MD5 @@ -299,6 +301,9 @@ push-location $path_root $build_args += ($flag_max_error_count + '10') # $build_args += $flag_sanitize_address # $build_args += $flag_sanitize_memory + foreach ($arg in $build_args) { + write-host `t $arg -ForegroundColor Cyan + } if ( Test-Path $executable) { $executable_pre_build_hash = get-filehash -path $executable -Algorithm MD5