diff --git a/code/font/fontstash/atlas.odin b/code/font/fontstash/atlas.odin index 9e17735..fc38893 100644 --- a/code/font/fontstash/atlas.odin +++ b/code/font/fontstash/atlas.odin @@ -47,9 +47,8 @@ atlas_add_skyline_level :: proc (ctx : ^Context, id : u64, x, y, width, height : return } -atlas_delete :: proc ( ctx : ^Context ) { - using ctx - array_free( ctx.atlas ) +atlas_delete :: proc () { + delete(Module_Context.atlas) } atlas_expand :: proc( ctx : ^Context, width, height : i32 ) @@ -65,18 +64,18 @@ atlas_expand :: proc( ctx : ^Context, width, height : i32 ) atlas_init :: proc( ctx : ^Context, width, height : i32, num_nodes : u32 = Init_Atlas_Nodes ) { error : AllocatorError - ctx.atlas, error = init_reserve( AtlasNode, context.allocator, u64(num_nodes), dbg_name = "font atlas" ) + ctx.atlas, error = make( Array(AtlasNode), u64(num_nodes), dbg_name = "font atlas" ) ensure(error != AllocatorError.None, "Failed to allocate font atlas") ctx.width = width ctx.height = height - array_append( & ctx.atlas, AtlasNode{ width = i16(width)} ) + append( & ctx.atlas, AtlasNode{ width = i16(width)} ) } atlas_insert :: proc( ctx : ^Context, id : u64, x, y, width : i32 ) -> (error : AllocatorError) { - error = array_append_at( & ctx.atlas, AtlasNode{ i16(x), i16(y), i16(width) }, id ) + error = append_at( & ctx.atlas, AtlasNode{ i16(x), i16(y), i16(width) }, id ) return } @@ -88,7 +87,7 @@ atlas_reset :: proc( ctx : ^Context, width, height : i32 ) ctx.height = height clear( ctx.atlas ) - array_append( & ctx.atlas, AtlasNode{ width = i16(width)} ) + append( & ctx.atlas, AtlasNode{ width = i16(width)} ) } atlas_rect_fits :: proc( ctx : ^Context, location, width, height : i32 ) -> (max_height : i32) diff --git a/code/font/fontstash/context.odin b/code/font/fontstash/context.odin new file mode 100644 index 0000000..db1fbc6 --- /dev/null +++ b/code/font/fontstash/context.odin @@ -0,0 +1,93 @@ +package fontstash + +import "base:runtime" + +// Legacy of original implementation +// Not sure going to use +Params :: struct { + parser_kind : ParserKind, + width, height : i32, + quad_location : QuadLocation, // (flags) + render_create : RenderCreateProc, + render_resize : RenderResizeProc, + render_update : RenderUpdateProc, + render_draw : RenderDrawProc, + render_delete : RenderDelete, +} + +CB_Resize :: #type proc(data : rawptr, width, height : u32 ) +CB_Update :: #type proc(data : rawptr, dirty_rect : Rect, texture_data : rawptr ) + +Callbacks :: struct { + resize : CB_Resize, + update : CB_Update, +} + +Context :: struct { + callstack_ctx : runtime.Context, + + // params : Params, + + parser_kind : ParserKind, + + fonts : Array(Font), + +// Atlas + atlas : Array(AtlasNode), + texture_data : []byte, + width, height : i32, +// ---- + + normalized_size : Vec2, + + verts : [Vertex_Count * 2]f32, + tcoords : [Vertex_Count * 2]f32, + colors : [Vertex_Count ]f32, + + vis_stack : StackFixed(VisState, Max_VisStates), + + quad_location : QuadLocation, + + // dirty rectangle of the texture regnion that was updated + dirty_rect : Rect, + + handle_error : HandleErrorProc, + error_uptr : rawptr, + + using callbacks : Callbacks, +} + +// The package assumes this will exist so long as the owning runtime module is loaded and it has been initialized before usage. +Module_Context : ^Context + +destroy_context :: proc() +{ + using Module_Context + + // for & font in array_to_slice(fonts) { + // } + delete( fonts ) + delete( atlas ) + +} + +// For usage during hot-reload, when the instance reference of a context is lost. +reload_context :: proc( ctx : ^Context ) +{ + Module_Context = ctx + using Module_Context + + callstack_ctx = context +} + +startup_context :: proc( ctx : ^Context, parser_kind : ParserKind, width, height : u32, quad_location : QuadLocation ) +{ + Module_Context = ctx + using Module_Context + + callstack_ctx = context + + error : AllocatorError + fonts, error = make( Array(Font), 8 ) + assert( error == AllocatorError.None, "Failed to allocate fonts array" ) +} diff --git a/code/font/fontstash/fontstash.odin b/code/font/fontstash/fontstash.odin index 91b0dc8..d7f1349 100644 --- a/code/font/fontstash/fontstash.odin +++ b/code/font/fontstash/fontstash.odin @@ -35,15 +35,15 @@ Range2_i16 :: struct #raw_union { } } -Vec2 :: [2]f32 - +Vec2 :: [2]f32 Vec2_i16 :: [2]i16 +Rect :: [4]f32 Invalid :: -1 Hash_Lut_Size :: 256 Max_Fallbacks :: 20 -Max_States :: 20 +Max_VisStates :: 20 Vertex_Count :: 1024 Init_Atlas_Nodes :: 256 @@ -105,7 +105,6 @@ Glyph :: struct { } Font :: struct { - parser_kind : ParserKind, parser_data : ParserData, name : string, data : []byte, @@ -121,17 +120,8 @@ Font :: struct { num_fallbacks : i32, } -Params :: struct { - width, height : i32, - quad_location : QuadLocation, // (flags) - render_create : RenderCreateProc, - render_resize : RenderResizeProc, - render_update : RenderUpdateProc, - render_draw : RenderDrawProc, - render_delete : RenderDelete, -} - -State :: struct { +// Visible State tracking used for sharing font visualization preferences. +VisState :: struct { font : i32, alignment : i32, size : f32, @@ -158,28 +148,6 @@ TextIter :: struct { end : string, } -Context :: struct { - params : Params, - -// Atlas - atlas : Array(AtlasNode), - texture_data : []byte, - width, height : i32, -// ---- - - normalized_size : Vec2, - - verts : [Vertex_Count * 2]f32, - tcoords : [Vertex_Count * 2]f32, - colors : [Vertex_Count ]f32, - - states : [Max_States]State, - num_states : i32, - - handle_error : HandleErrorProc, - error_uptr : rawptr, -} - decode_utf8 :: proc( state : ^rune, codepoint : ^rune, to_decode : byte ) -> bool { UTF8_Accept :: 0 @@ -217,4 +185,3 @@ decode_utf8 :: proc( state : ^rune, codepoint : ^rune, to_decode : byte ) -> boo (state^) = cast(rune)(UTF8_Decode_Table[256 + (state^) * 16 + rune(type)]) return (state^) == UTF8_Accept } - diff --git a/code/font/fontstash/mappings.odin b/code/font/fontstash/mappings.odin index 73c8948..21ab4c0 100644 --- a/code/font/fontstash/mappings.odin +++ b/code/font/fontstash/mappings.odin @@ -1,7 +1,5 @@ package fontstash - - import "core:mem" AllocatorError :: mem.Allocator_Error @@ -10,18 +8,28 @@ import "codebase:grime" // asserts ensure :: grime.ensure +verify :: grime.verify // container Array :: grime.Array -array_init_reserve :: grime.array_init_reserve -array_append :: grime.array_append -array_append_at :: grime.array_append_at -array_clear :: grime.array_clear -array_free :: grime.array_free -array_remove_at :: grime.array_remove_at -array_to_slice :: grime.array_to_slice +array_init :: grime.array_init +array_append :: grime.array_append +array_append_at :: grime.array_append_at +array_clear :: grime.array_clear +array_free :: grime.array_free +array_remove_at :: grime.array_remove_at +array_to_slice :: grime.array_to_slice + +StackFixed :: grime.StackFixed + +stack_clear :: grime.stack_clear +stack_push :: grime.stack_push +stack_pop :: grime.stack_pop +stack_peek_ref :: grime.stack_peek_ref +stack_peek :: grime.stack_peek +stack_push_contextless :: grime.stack_push_contextless //#region("Proc overload mappings") @@ -32,19 +40,20 @@ append :: proc { } append_at :: proc { - array_append_at, + grime.array_append_at_slice, + grime.array_append_at_value, } clear :: proc { array_clear, } -free :: proc { +delete :: proc { array_free, } -init_reserve :: proc { - array_init_reserve, +make :: proc { + array_init, } remove_at :: proc { diff --git a/code/font/fontstash/parser.odin b/code/font/fontstash/parser.odin index 900440c..3556812 100644 --- a/code/font/fontstash/parser.odin +++ b/code/font/fontstash/parser.odin @@ -10,41 +10,50 @@ ParserKind :: enum u32 { ParserData :: struct #raw_union { stbtt_info : stbtt.fontinfo, - // freetype_info : + // freetype_info : +} + +ParserContext :: struct { + ft_library : freetype.Library } //#region("freetype") +ft_init :: proc() -> i32 { + using Module_Context + return 1 +} + //#endregion("freetype") //#region("stb_truetype") -fstash_tt_init :: proc( ctx : ^Context ) -> i32 { return 1 } +tt_init :: proc() -> i32 { return 1 } -fstash_tt_load_font :: proc( ctx : ^Context, parser_data : ^ParserData, data : []byte ) -> b32 +tt_load_font :: proc( parser_data : ^ParserData, data : []byte ) -> b32 { - parser_data.stbtt_info.userdata = ctx + parser_data.stbtt_info.userdata = Module_Context stb_error := stbtt.InitFont( & parser_data.stbtt_info, & data[0], 0 ) return stb_error } -fstash_tt_get_font_metrics :: proc( parser_data : ^ParserData, ascent, descent, line_gap : ^i32 ) { +tt_get_font_metrics :: proc( parser_data : ^ParserData, ascent, descent, line_gap : ^i32 ) { stbtt.GetFontVMetrics( & parser_data.stbtt_info, ascent, descent, line_gap ) } -fstash_tt_get_pixel_height_scale :: proc( parser_data : ^ParserData, size : f32 ) -> f32 +tt_get_pixel_height_scale :: proc( parser_data : ^ParserData, size : f32 ) -> f32 { return stbtt.ScaleForPixelHeight( & parser_data.stbtt_info, size ) } -fstash_tt_get_glyph_index :: proc( parser_data : ^ParserData, codepoint : rune ) -> i32 +tt_get_glyph_index :: proc( parser_data : ^ParserData, codepoint : rune ) -> i32 { return stbtt.FindGlyphIndex( & parser_data.stbtt_info, codepoint ) } -fstash_tt_build_glyph_bitmap :: proc( parser_data : ^ParserData, glyph_index : i32, +tt_build_glyph_bitmap :: proc( parser_data : ^ParserData, glyph_index : i32, size, scale : f32, advance, left_side_bearing, x0, y0, x1, y1 : ^i32 ) -> i32 { stbtt.GetGlyphHMetrics( & parser_data.stbtt_info, glyph_index, advance, left_side_bearing ) @@ -52,13 +61,13 @@ fstash_tt_build_glyph_bitmap :: proc( parser_data : ^ParserData, glyph_index : i return 1 } -fstash_tt_render_glyph_bitmap :: proc( parser_data : ^ParserData, output : [^]byte, +tt_render_glyph_bitmap :: proc( parser_data : ^ParserData, output : [^]byte, out_width, out_height, out_stride : i32, scale_x, scale_y : f32, glyph_index : i32 ) { stbtt.MakeGlyphBitmap( & parser_data.stbtt_info, output, out_width, out_height, out_stride, scale_x, scale_y, glyph_index ) } -fstash_tt_get_glyph_kern_advance :: proc( parser_data : ^ParserData, glyph_1, glyph_2 : i32 ) -> i32 +tt_get_glyph_kern_advance :: proc( parser_data : ^ParserData, glyph_1, glyph_2 : i32 ) -> i32 { return stbtt.GetGlyphKernAdvance( & parser_data.stbtt_info, glyph_1, glyph_2 ) }