diff --git a/code/font/RFont/RFont.odin b/code/font/RFont/RFont.odin deleted file mode 100644 index b9eed91..0000000 --- a/code/font/RFont/RFont.odin +++ /dev/null @@ -1,2 +0,0 @@ -package RFont - diff --git a/code/font/fontstash/atlas.odin b/code/font/fontstash/atlas.odin deleted file mode 100644 index 8c26bd3..0000000 --- a/code/font/fontstash/atlas.odin +++ /dev/null @@ -1,131 +0,0 @@ -package fontstash - -atlas_add_rect :: proc( ctx : ^Context, ) -{ - -} - -atlas_add_skyline_level :: proc (ctx : ^Context, id : u64, x, y, width, height : i32 ) -> (error : AllocatorError) -{ - error = atlas_insert( ctx, id, x, y + height, width) - if error != AllocatorError.None { - ensure( false, "Failed to insert into atlas") - return - } - - // Delete skyline segments that fall under the shadow of the new segment. - for sky_id := id; sky_id < ctx.atlas.num; sky_id += 1 - { - curr := & ctx.atlas.data[sky_id ] - next := & ctx.atlas.data[sky_id + 1] - if curr.x >= next.x + next.width do break - - shrink := i16(next.x + next.width - curr.x) - curr.x += shrink - curr.width -= shrink - - if curr.width > 0 do break - - atlas_remove(ctx, sky_id) - sky_id -= 1 - } - - // Merge same height skyline segments that are next to each other. - for sky_id := id; sky_id < ctx.atlas.num - 1; - { - curr := & ctx.atlas.data[sky_id ] - next := & ctx.atlas.data[sky_id + 1] - - if curr.y == next.y { - curr.width += next.width - atlas_remove(ctx, sky_id + 1) - } - else { - sky_id += 1 - } - } - return -} - -atlas_delete :: proc () { - delete(Module_Context.atlas) -} - -atlas_expand :: proc( ctx : ^Context, width, height : i32 ) -{ - if width > ctx.width { - atlas_insert( ctx, ctx.atlas.num, ctx.width, 0, width - ctx.width ) - } - - ctx.width = width - ctx.height = height -} - -atlas_init :: proc( ctx : ^Context, width, height : i32, num_nodes : u32 = Init_Atlas_Nodes ) -{ - error : AllocatorError - 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 - - append( & ctx.atlas, AtlasNode{ width = i16(width)} ) -} - -atlas_insert :: proc( ctx : ^Context, id : u64, x, y, width : i32 ) -> (error : AllocatorError) -{ - error = append_at( & ctx.atlas, AtlasNode{ i16(x), i16(y), i16(width) }, id ) - return -} - -atlas_remove :: #force_inline proc( ctx : ^Context, id : u64 ) { remove_at( ctx.atlas, id ) } - -atlas_reset :: proc( ctx : ^Context, width, height : i32 ) -{ - ctx.width = width - ctx.height = height - clear( ctx.atlas ) - - append( & ctx.atlas, AtlasNode{ width = i16(width)} ) -} - -atlas_rect_fits :: proc( ctx : ^Context, location, width, height : i32 ) -> (max_height : i32) -{ - // Checks if there is enough space at the location of skyline span 'i', - // and return the max height of all skyline spans under that at that location, - // (think tetris block being dropped at that position). Or -1 if no space found. - atlas := to_slice(ctx.atlas) - node := atlas[location] - - space_left : i32 - if i32(node.x) + width > ctx.width { - max_height = -1 - return - } - - space_left = width; - - y := i32(node.y) - location := location - for ; space_left > 0; - { - if u64(location) == ctx.atlas.num { - max_height = -1 - return - } - - node := atlas[location] - - y := max(y, i32(node.y)) - if y + height > ctx.height { - max_height = -1 - return - } - - space_left -= i32(node.width) - location += 1 - } - max_height = y - return -} diff --git a/code/font/fontstash/context.odin b/code/font/fontstash/context.odin deleted file mode 100644 index d7665fd..0000000 --- a/code/font/fontstash/context.odin +++ /dev/null @@ -1,148 +0,0 @@ -package fontstash - -import "base:runtime" -import "core:slice" - -// 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, -} - -OnResizeProc :: #type proc(data : rawptr, width, height : u32 ) -OnUpdateProc :: #type proc(data : rawptr, dirty_rect : Rect, texture_data : rawptr ) - -Callbacks :: struct { - resize : OnResizeProc, - update : OnUpdateProc, -} - -Context :: struct { - callstack_ctx : runtime.Context, - - // params : Params, - - parser_kind : ParserKind, - parser_ctx : ParserContext, - - 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_loc : QuadLocation, - - // dirty rectangle of the texture regnion that was updated - dirty_rect : Rect, - - handle_error : HandleErrorProc, - error_userdata : 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) { - if font.free_data { - // delete(font.data) - } - - // delete(font.name) - delete(font.glyphs) - } - delete( fonts ) - delete( atlas ) - delete( array_underlying_slice(texture_data) ) - // delete( vis_stack ) -} - -// 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 -} - -rest :: proc() { - using Module_Context - - // atlas_reset() - // dirty_rect_reset() - slice.zero(texture_data) - - for & font in array_to_slice(fonts) { - // font_lut_reset( & font ) - } - - // atlas_add_white_rect(2, 2) - // push_vis_state() - // clear_vis_state() -} - -// Its recommmended to use an allocator that can handle resizing efficiently for the atlas nodes & texture (at least) -startup_context :: proc( ctx : ^Context, parser_kind : ParserKind, - atlas_texture_width, atlas_texture_height : u32, quad_origin_location : QuadLocation, - allocator := context.allocator ) -{ - Module_Context = ctx - using Module_Context - - width = cast(i32) atlas_texture_width - height = cast(i32) atlas_texture_height - quad_loc = quad_origin_location - - context.allocator = allocator - callstack_ctx = context - - error : AllocatorError - fonts, error = make( Array(Font), 8 ) - assert( error == AllocatorError.None, "Failed to allocate fonts array" ) - - texture_data_array : Array(byte) - texture_data_array, error = make( Array(byte), u64(width * height) ) - assert( error == AllocatorError.None, "Failed to allocate fonts array" ) - texture_data = array_to_slice(texture_data_array) - - // TODO(Ed): Verfiy and remove - { - quick_check := underlying_slice(texture_data) - assert( & texture_data_array.header == & quick_check ) - } - - atlas, error = make( Array(AtlasNode), Init_Atlas_Nodes ) - assert( error == AllocatorError.None, "Failed to allocate fonts array" ) - // dirty_rect_reset() - - append(& atlas, AtlasNode { width = i16(width) }) - - // atlas_add_white_rect(2, 2) - - // push_vis_state() - // clear_vis_state() -} diff --git a/code/font/fontstash/fontstash.odin b/code/font/fontstash/fontstash.odin deleted file mode 100644 index aa0b39e..0000000 --- a/code/font/fontstash/fontstash.odin +++ /dev/null @@ -1,196 +0,0 @@ -/* -Yet another port of fontstash. - -I decided to use this instead of the odin port as it deviated from the original, making it difficult to sift through. -So The code was small enough that I mine as well learn it by porting for my use case. - -TODO(Ed): Add docs here and throughout -TODO(Ed): This is unfinished... - -Changes from fontstash: -* This was setup & tested for single-threaded tasks -* There is an assumed runtime context assigned on startup (user decides where the context memory is) -Influnce from Odin's vendor Port: -* Manages a lookup table for frequent glyphs -* Atlas can resize -* No scratch allocation, user can specify allocator -* Supports rendering with nanovg - -Original author's copyright for fonstash.h: ------------------------------------------------------------------------------- - Copyright (c) 2009-2013 Mikko Mononen memon@inside.org - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. ------------------------------------------------------------------------------- -*/ -package fontstash - -Range2_i16 :: struct #raw_union { - using pts : Vec2_i16, - using xy : struct { - x0, y0, x1, y1 : i16, - } -} - -Vec2 :: [2]f32 -Vec2_i16 :: [2]i16 -Rect :: [4]f32 - -Invalid :: -1 - -Hash_Lut_Size :: 256 -Max_Fallbacks :: 20 -Max_VisStates :: 20 -Vertex_Count :: 1024 -Init_Atlas_Nodes :: 256 - -FontLuts :: [Hash_Lut_Size]i32 -FontFallbacks :: [Max_Fallbacks]i32 - -HandleErrorProc :: #type proc( uptr : rawptr, error, val : i32 ) - -RenderCreateProc :: #type proc( uptr : rawptr, width, height : i32 ) -RenderResizeProc :: #type proc( uptr : rawptr, width, height : i32 ) -RenderUpdateProc :: #type proc( uptr : rawptr, rect : ^i32, data : ^u8 ) -RenderDrawProc :: #type proc( uptr : rawptr, verts : ^f32, tcoords : ^f32, colors : ^i32, num_verts : i32 ) -RenderDelete :: #type proc( uptr : rawptr ) - -AlignFlag :: enum u32 { - Left, - Center, - Right, - Top, - Middle, - Bottom, - Baseline, -} -AlignFlags :: bit_set[ AlignFlag; u32 ] - -// FONSflags -QuadLocation :: enum u32 { - Top_Left = 1, - Bottom_Left = 2, -} - -Atlas :: struct { - dud : i32, -} - -AtlasNode :: struct { - x, y, width : i16, -} - -ErrorCode :: enum u32 { - Atlas_Full, - Scratch_Full, - States_Overflow, - States_Underflow, -} - -Quad :: struct { - x0, y0, s0, t0 : f32, - x1, y1, s1, t1 : f32, -} - -Glyph :: struct { - codepoint : rune, - index, next : i32, - size, blur : i16, - x_advance : i16, - box : Range2_i16, - offset : Vec2_i16, -} - -Font :: struct { - parser_data : ParserData, - name : string, - data : []byte, - free_data : bool, - - ascender : f32, - descender : f32, - line_height : f32, - - glyphs : Array(Glyph), - lut : FontLuts, - fallbacks : FontFallbacks, - num_fallbacks : i32, -} - -// Visible State tracking used for sharing font visualization preferences. -VisState :: struct { - font : i32, - alignment : i32, - size : f32, - color : [4]u8, - blur : f32, - spacing : f32, -} - -TextIter :: struct { - x, y : f32, - next_x, next_y : f32, - scale, spacing : f32, - - isize, iblur : i16, - - font : ^Font, - prev_glyph_id : i32, - - codepoint : rune, - utf8_state : rune, - - str : string, - next : string, - end : string, -} - -decode_utf8 :: proc( state : ^rune, codepoint : ^rune, to_decode : byte ) -> bool -{ - UTF8_Accept :: 0 - UTF8_Reject :: 1 - - @static UTF8_Decode_Table := [?]u8 { - // The first part of the table maps bytes to character classes that - // to reduce the size of the transition table and create bitmasks. - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1F - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3F - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5F - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7F - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9F - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // A0..BF - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // C0..DF - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, // E0..FF - - // The second part is a transition table that maps a combination - // of a state of the automaton and a character class to a state. - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12, - } - - to_decode_rune := rune(to_decode) - type := UTF8_Decode_Table[to_decode_rune] - - // Update codepoint otherwise initialize it. - (codepoint^) = ((state^) != UTF8_Accept) ? \ - ((to_decode_rune & 0x3F) | ((codepoint^) << 6)) \ - : ((0xFF >> type) & (to_decode_rune)) - - (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 deleted file mode 100644 index 0fb313c..0000000 --- a/code/font/fontstash/mappings.odin +++ /dev/null @@ -1,72 +0,0 @@ -package fontstash - -import "core:mem" - -AllocatorError :: mem.Allocator_Error - -import "codebase:grime" - -// asserts -ensure :: grime.ensure -verify :: grime.verify - -// container - -Array :: grime.Array - -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 -array_underlying_slice :: grime.array_underlying_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") - -append :: proc { - grime.array_append_array, - grime.array_append_slice, - grime.array_append_value, -} - -append_at :: proc { - grime.array_append_at_slice, - grime.array_append_at_value, -} - -clear :: proc { - array_clear, -} - -delete :: proc { - array_free, -} - -make :: proc { - array_init, -} - -remove_at :: proc { - array_remove_at, -} - -to_slice :: proc { - array_to_slice, -} - -underlying_slice :: proc { - array_underlying_slice, -} - -//#endregion("Proc overload mappings") diff --git a/code/font/fontstash/parser.odin b/code/font/fontstash/parser.odin deleted file mode 100644 index 3556812..0000000 --- a/code/font/fontstash/parser.odin +++ /dev/null @@ -1,75 +0,0 @@ -package fontstash - -import stbtt "vendor:stb/truetype" -import freetype "thirdparty:freetype" - -ParserKind :: enum u32 { - stb_true_type, - freetype, -} - -ParserData :: struct #raw_union { - stbtt_info : stbtt.fontinfo, - // freetype_info : -} - -ParserContext :: struct { - ft_library : freetype.Library -} - -//#region("freetype") - -ft_init :: proc() -> i32 { - using Module_Context - return 1 -} - - - -//#endregion("freetype") - -//#region("stb_truetype") - -tt_init :: proc() -> i32 { return 1 } - -tt_load_font :: proc( parser_data : ^ParserData, data : []byte ) -> b32 -{ - parser_data.stbtt_info.userdata = Module_Context - stb_error := stbtt.InitFont( & parser_data.stbtt_info, & data[0], 0 ) - return stb_error -} - -tt_get_font_metrics :: proc( parser_data : ^ParserData, ascent, descent, line_gap : ^i32 ) { - stbtt.GetFontVMetrics( & parser_data.stbtt_info, ascent, descent, line_gap ) -} - -tt_get_pixel_height_scale :: proc( parser_data : ^ParserData, size : f32 ) -> f32 -{ - return stbtt.ScaleForPixelHeight( & parser_data.stbtt_info, size ) -} - -tt_get_glyph_index :: proc( parser_data : ^ParserData, codepoint : rune ) -> i32 -{ - return stbtt.FindGlyphIndex( & parser_data.stbtt_info, codepoint ) -} - -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 ) - stbtt.GetGlyphBitmapBox( & parser_data.stbtt_info, glyph_index, scale, scale, x0, y0, x1, y1 ) - return 1 -} - -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 ) -} - -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 ) -} - -//#endregion("stb_truetype")