Some progress on fontstash
This commit is contained in:
parent
f415eada0d
commit
d63242ac9c
@ -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)
|
||||
|
93
code/font/fontstash/context.odin
Normal file
93
code/font/fontstash/context.odin
Normal file
@ -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" )
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 )
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user