Progress on porting fontstash

This commit is contained in:
Edward R. Gonzalez 2024-06-02 17:29:27 -04:00
parent 9ba718254c
commit 33ddd420b7
10 changed files with 115 additions and 38 deletions

View File

@ -1,6 +1,7 @@
package fontstash
import "base:runtime"
import "core:slice"
// Legacy of original implementation
// Not sure going to use
@ -15,12 +16,12 @@ Params :: struct {
render_delete : RenderDelete,
}
CB_Resize :: #type proc(data : rawptr, width, height : u32 )
CB_Update :: #type proc(data : rawptr, dirty_rect : Rect, texture_data : rawptr )
OnResizeProc :: #type proc(data : rawptr, width, height : u32 )
OnUpdateProc :: #type proc(data : rawptr, dirty_rect : Rect, texture_data : rawptr )
Callbacks :: struct {
resize : CB_Resize,
update : CB_Update,
resize : OnResizeProc,
update : OnUpdateProc,
}
Context :: struct {
@ -29,6 +30,7 @@ Context :: struct {
// params : Params,
parser_kind : ParserKind,
parser_ctx : ParserContext,
fonts : Array(Font),
@ -46,13 +48,13 @@ Context :: struct {
vis_stack : StackFixed(VisState, Max_VisStates),
quad_location : QuadLocation,
quad_loc : QuadLocation,
// dirty rectangle of the texture regnion that was updated
dirty_rect : Rect,
handle_error : HandleErrorProc,
error_uptr : rawptr,
handle_error : HandleErrorProc,
error_userdata : rawptr,
using callbacks : Callbacks,
}
@ -64,11 +66,18 @@ destroy_context :: proc()
{
using Module_Context
// for & font in array_to_slice(fonts) {
// }
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.
@ -80,14 +89,60 @@ reload_context :: proc( ctx : ^Context )
callstack_ctx = context
}
startup_context :: proc( ctx : ^Context, parser_kind : ParserKind, width, height : u32, quad_location : QuadLocation )
{
Module_Context = ctx
rest :: proc() {
using Module_Context
callstack_ctx = 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()
}

View File

@ -7,6 +7,15 @@ So The code was small enough that I mine as well learn it by porting for my use
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

View File

@ -14,13 +14,14 @@ verify :: grime.verify
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_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
@ -64,4 +65,8 @@ to_slice :: proc {
array_to_slice,
}
underlying_slice :: proc {
array_underlying_slice,
}
//#endregion("Proc overload mappings")

View File

@ -29,12 +29,12 @@ Array :: struct ( $ Type : typeid ) {
array_underlying_slice :: proc(slice: []($ Type)) -> Array(Type)
{
if len(slice) == 0 {
return nil
return {nil}
}
array_size := size_of( Array(Type))
raw_data := & slice[0]
array_ptr := cast( ^Array(Type)) ( uintptr(first_element_ptr) - uintptr(array_size))
return array_ptr ^
header_size := size_of( ArrayHeader(Type))
raw_data := & slice[0]
array := transmute( Array(Type)) ( uintptr(raw_data) - uintptr(header_size))
return array
}
array_to_slice :: #force_inline proc( using self : Array($ Type) ) -> []Type { return slice_ptr( data, int(num)) }
@ -180,7 +180,10 @@ array_append_at_slice :: proc( using self : ^Array( $ Type ), items : []Type, id
return AllocatorError.None
}
// array_back :: proc( )
array_back :: proc( self : Array($Type) ) -> Type {
value := self.data[self.num - 1]
return value
}
// array_push_back :: proc( using self : Array( $ Type)) -> b32 {
// if num == capacity {

View File

@ -5,6 +5,7 @@ import "core:fmt"
import "core:os"
import "base:runtime"
// TODO(Ed): Make an async option...
file_copy_sync :: proc( path_src, path_dst: string, allocator := context.allocator ) -> b32
{
file_size : i64

View File

@ -70,15 +70,16 @@ render :: proc()
// learnopengl.com/In-Practice/Text-Rendering
if true
{
profile("learngl_text_render_pass")
using font_provider_data
green_value := debug.gfx_clear_demo_pass_action.colors[0].clear_value.g + 0.01
debug.gfx_clear_demo_pass_action.colors[0].clear_value.g = green_value > 1.0 ? 0.0 : green_value
sokol_gfx.begin_pass( sokol_gfx.Pass {
action = debug.gfx_clear_demo_pass_action,
swapchain = sokol_glue.swapchain()
})
// sokol_gfx.begin_pass(sokol_gfx.Pass { action = pass_actions.bg_clear_black, swapchain = sokol_glue.swapchain() })
// green_value := debug.gfx_clear_demo_pass_action.colors[0].clear_value.g + 0.01
// debug.gfx_clear_demo_pass_action.colors[0].clear_value.g = green_value > 1.0 ? 0.0 : green_value
// sokol_gfx.begin_pass( sokol_gfx.Pass {
// action = debug.gfx_clear_demo_pass_action,
// swapchain = sokol_glue.swapchain()
// })
sokol_gfx.begin_pass(sokol_gfx.Pass { action = pass_actions.bg_clear_black, swapchain = sokol_glue.swapchain() })
sokol_gfx.apply_pipeline( gfx_pipeline )
// sokol_gfx.update_buffer( gfx_vbuffer, sokol_gfx.Range{ , Font_Provider_Ggfx_Buffer_Size } )
@ -131,7 +132,7 @@ render :: proc()
5 = { 1.0, 0.0 },
}
color : Vec3 = { 0.2, 0.2, 0.2 }
color : Vec3 = { 1.0, 1.0, 1.0 }
fs_uniform := Font_Glyph_Fs_Params {
glyph_color = color
}

View File

@ -1,6 +1,8 @@
/* Space
Provides various definitions for converting from one standard of measurement to another.
Provides constructs and transformations in reguards to space.
Ultimately the user's window ppcm (pixels-per-centimeter) determins how all virtual metric conventions are handled.
*/

View File

@ -41,7 +41,7 @@ function check-ModuleForChanges
param( [string]$path_module, [array]$excludes )
$module_name = split-path $path_module -leaf
$path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv")
$path_csv = Join-Path $path_build ("module_" + $module_name + "_hashes.csv")
$csv_file_hashes = $null
if ( test-path $path_csv ) {
@ -76,7 +76,7 @@ function mark-ModuleDirty {
param( [string]$path_module )
$module_name = split-path $path_module -leaf
$path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv")
$path_csv = Join-Path $path_build ("module_" + $module_name + "_hashes.csv")
remove-item -Force -Path $path_csv
}

1
thirdparty/harfbuzz vendored Submodule

@ -0,0 +1 @@
Subproject commit 6781256b374ddafc42eed265e7b8377099b36919

@ -1 +1 @@
Subproject commit 389e12a78580362cae32d522ac021d74187d02b5
Subproject commit 66c85cb42c0b926b93d0e00891cef24883b7f68a