Removing fontstash and RFont from codebase
Planning to instead just focus on using VEFontCache.
This commit is contained in:
		| @@ -1,2 +0,0 @@ | ||||
| package RFont | ||||
|  | ||||
| @@ -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 | ||||
| } | ||||
| @@ -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() | ||||
| } | ||||
| @@ -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 | ||||
| } | ||||
| @@ -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") | ||||
| @@ -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") | ||||
		Reference in New Issue
	
	Block a user