| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -11,6 +11,7 @@ Changes:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- Font Parser & Glyph Shaper are abstracted to their own interface
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- Font Face parser info stored separately from entries
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- ve_fontcache_loadfile not ported (just use odin's core:os or os2), then call load_font
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				- Macro defines have been made into runtime parameters
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				package VEFontCache
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -21,12 +22,13 @@ Colour :: [4]f32
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Vec2   :: [2]f32
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Vec2i  :: [2]u32
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				AtlasRegionKind :: enum {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					A = 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					B = 1,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					C = 2,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					D = 3,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					E = 4,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				AtlasRegionKind :: enum u8 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					None = 0x00,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					A    = 0x41,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					B    = 0x42,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					C    = 0x43,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					D    = 0x44,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					E    = 0x45,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Vertex :: struct {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -34,15 +36,6 @@ Vertex :: struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					u, v : f32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// GlyphDrawBuffer :: struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// 	over_sample : Vec2,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// 	batch   : i32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// 	width   : i32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// 	height  : i32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// 	padding : i32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ShapedText :: struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					glyphs         : Array(Glyph),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					positions      : Array(Vec2),
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -97,6 +90,7 @@ Context :: struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas       : Atlas,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					shape_cache : ShapedTextCache,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					curve_quality  : u32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					text_shape_adv : b32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					debug_print_verbose : b32
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -150,15 +144,15 @@ InitAtlasParams_Default :: InitAtlasParams {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				InitGlyphDrawParams :: struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					over_sample  : Vec2i,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					buffer_batch : u32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					padding      : u32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					over_sample   : Vec2,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					buffer_batch  : u32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					draw_padding  : u32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				InitGlyphDrawParams_Default :: InitGlyphDrawParams {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					over_sample  = { 4, 4 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					buffer_batch = 4,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					padding      = InitAtlasParams_Default.glyph_padding,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					over_sample   = { 4, 4 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					buffer_batch  = 4,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					draw_padding  = InitAtlasParams_Default.glyph_padding,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				InitShapeCacheParams :: struct {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -177,6 +171,7 @@ init :: proc( ctx : ^Context,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas_params                := InitAtlasParams_Default,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					glyph_draw_params           := InitGlyphDrawParams_Default,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					shape_cache_params          := InitShapeCacheParams_Default,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					curve_quality               : u32 = 6,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					advance_snap_smallfont_size : u32 = 12,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					entires_reserve             : u32 = Kilobyte,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					temp_path_reserve           : u32 = Kilobyte,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -189,6 +184,8 @@ init :: proc( ctx : ^Context,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ctx.backing       = allocator
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					context.allocator = ctx.backing
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ctx.curve_quality = curve_quality
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					error : AllocatorError
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					entries, error = make( Array(Entry), u64(entires_reserve) )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert(error == .None, "VEFontCache.init : Failed to allocate entries")
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -233,6 +230,10 @@ init :: proc( ctx : ^Context,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					init_atlas_region( & atlas.region_c, atlas_params, atlas_params.region_c )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					init_atlas_region( & atlas.region_d, atlas_params, atlas_params.region_d )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.width         = atlas_params.width
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.height        = atlas_params.height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.glyph_padding = atlas_params.glyph_padding
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.region_b.offset.y = atlas.region_a.size.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.region_c.offset.x = atlas.region_a.size.x
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas.region_d.offset.x = atlas.width / 2
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -251,6 +252,12 @@ init :: proc( ctx : ^Context,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Note(From original author): We can actually go over VE_FONTCACHE_GLYPHDRAW_BUFFER_BATCH batches due to smart packing!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						using atlas
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						over_sample   = glyph_draw_params.over_sample
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buffer_batch  = glyph_draw_params.buffer_batch
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buffer_width  = region_d.width  * u32(over_sample.x) * buffer_batch
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buffer_height = region_d.height * u32(over_sample.y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						draw_padding  = glyph_draw_params.draw_padding
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						draw_list.calls, error = make( Array(DrawCall), cast(u64) glyph_draw_params.buffer_batch * 2 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						assert( error != .None, "VEFontCache.init : Failed to allocate calls for draw_list" )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -348,53 +355,6 @@ configure_snap :: proc( ctx : ^Context, snap_width, snap_height : u32 ) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ctx.snap_height = snap_height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_drawlist
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				get_draw_list :: proc( ctx : ^Context ) -> ^DrawList {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert( ctx != nil )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return & ctx.draw_list
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_clear_drawlist
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				clear_draw_list :: proc( draw_list : ^DrawList ) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clear( draw_list.calls )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clear( draw_list.indices )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clear( draw_list.vertices )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_merge_drawlist
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				merge_draw_list :: proc( dst, src : ^DrawList )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					error : AllocatorError
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					v_offset := cast(u32) dst.vertices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// for index : u32 = 0; index < cast(u32) src.vertices.num; index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// 	error = append( & dst.vertices, src.vertices.data[index] )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// 	assert( error == .None )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					error = append( & dst.vertices, src.vertices )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert( error == .None )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					i_offset := cast(u32) dst.indices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for index : u32 = 0; index < cast(u32) src.indices.num; index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						error = append( & dst.indices, src.indices.data[index] + v_offset )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						assert( error == .None )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for index : u32 = 0; index < cast(u32) src.calls.num; index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						src_call := src.calls.data[ index ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						src_call.start_index += i_offset
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						src_call.end_index   += i_offset
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( & dst.calls, src_call )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						assert( error == .None )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_flush_drawlist
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				flush_draw_list :: proc( ctx : ^Context ) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert( ctx != nil )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clear_draw_list( & ctx.draw_list )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// For a provided alpha value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// allows the function to calculate the position of a point along the curve at any given fraction of its total length
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_eval_bezier (quadratic)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -422,92 +382,6 @@ eval_point_on_bezier4 :: proc( p0, p1, p2, p3 : Vec2, alpha : f32 ) -> Vec2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return point
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Constructs a triangle fan to fill a shape using the provided path
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// outside_point represents the center point of the fan.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				//
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Note(Original Author):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// WARNING: doesn't actually append drawcall; caller is responsible for actually appending the drawcall.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// ve_fontcache_draw_filled_path
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				draw_filled_path :: proc( draw_list : ^DrawList, outside_point : Vec2, path : []Vec2,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					scale     := Vec2 { 1, 1 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					translate := Vec2 { 0, 0 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					debug_print_verbose : b32 = false
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if debug_print_verbose
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						log("outline_path: \n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for point in path {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							logf("    %.2f %.2f\n", point.x * scale )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					v_offset := cast(u32) draw_list.vertices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for point in path {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						vertex := Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							pos = point * scale + translate,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							u = 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v = 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					outside_vertex := cast(u32) draw_list.vertices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						vertex := Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							pos = outside_point * scale + translate,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							u = 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v = 0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for index : u32 = 1; index < u32(len(path)); index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						indices := & draw_list.indices
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( indices, outside_vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( indices, v_offset + index - 1 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( indices, v_offset + index )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				blit_quad :: proc( draw_list : ^DrawList, p0, p1 : Vec2, uv0, uv1 : Vec2 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					v_offset := cast(u32) draw_list.vertices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					vertex := Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{p0.x, p0.y},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv0.x,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv0.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					vertex = Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{p0.x, p1.y},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv0.x,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv1.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					vertex = Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{p1.x, p0.y},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv1.x,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv0.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					vertex = Vertex {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{p1.x, p1.y},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv1.x,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uv1.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					append( & draw_list.vertices, vertex )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					quad_indices : []u32 = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						0, 1, 2,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						2, 1, 3
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for index : i32 = 0; index < 6; index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append( & draw_list.indices, v_offset + quad_indices[ index ] )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale, translate : Vec2  ) -> b32
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert( ctx != nil )
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -531,7 +405,24 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if ctx.debug_print_verbose
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						log( "shape: \n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// for 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for vertex in shape
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if vertex.type == .Move {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								logf("move_to %d %d\n", vertex.x, vertex.y )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else if vertex.type == .Line {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								logf("line_to %d %d\n", vertex.x, vertex.y )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else if vertex.type == .Curve {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								logf("curve_to %d %d through %d %d\n", vertex.x, vertex.y, vertex.contour_x0, vertex.contour_y0 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else if vertex.type == .Cubic {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								logf("cubic_to %d %d through %d %d and %d %d\n",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									vertex.x, vertex.y,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									vertex.contour_x0, vertex.contour_y0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									vertex.contour_x1, vertex.contour_y1 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/*
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -556,16 +447,130 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Instead of involving fragment shader code we simply make use of modern GPU ability to crunch triangles and brute force curve definitions.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					path := ctx.temp_path
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clear(path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for vertex in shape {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for edge in shape	do switch edge.type
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case .Move:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if path.num > 0 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								draw_filled_path( & ctx.draw_list, outside, array_to_slice(path), scale, translate )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							clear(path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fallthrough
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case .Line:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							append( & path, Vec2{ f32(edge.x), f32(edge.y) })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case .Curve:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							assert( path.num > 0 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p0 := path.data[ path.num - 1 ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p1 := Vec2{ f32(edge.contour_x0), f32(edge.contour_y0) }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p2 := Vec2{ f32(edge.x), f32(edge.y) }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							step  := 1.0 / f32(ctx.curve_quality)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							alpha := step
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							for index := i32(0); index < i32(ctx.curve_quality); index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								append( & path, eval_point_on_bezier3( p0, p1, p2, alpha ))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								alpha += step
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case .Cubic:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							assert( path.num > 0 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p0 := path.data[ path.num - 1]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p1 := Vec2{ f32(edge.contour_x0), f32(edge.contour_y0) }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p2 := Vec2{ f32(edge.contour_x1), f32(edge.contour_y1) }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							p3 := Vec2{ f32(edge.x), f32(edge.y) }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							step  := 1.0 / f32(ctx.curve_quality)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							alpha := step
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							for index := i32(0); index < i32(ctx.curve_quality); index += 1 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								append( & path, eval_point_on_bezier4( p0, p1, p2, p3, alpha ))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								alpha += step
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case .None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							assert(false, "Unknown edge type or invalid")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if path.num > 0 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						draw_filled_path( & ctx.draw_list, outside, array_to_slice(path), scale, translate )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Note(Original Author): Apend the draw call
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					draw.end_index = cast(u32) ctx.draw_list.indices.num
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if draw.end_index > draw.start_index {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						append(& ctx.draw_list.calls, draw)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					parser_free_shape( entry.parser_info, shape )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return false
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				decide_codepoint_region :: proc() -> AtlasRegionKind
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				decide_codepoint_region :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				) -> (region : AtlasRegionKind, state : ^LRU_Cache, next_idx : ^u32, over_sample : ^Vec2)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return {}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if parser_is_glyph_empty( entry.parser_info, glyph_index ) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region = .None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bounds_0, bounds_1 := parser_get_glyph_box( entry.parser_info, glyph_index )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bounds_width  := bounds_1.x - bounds_0.x
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bounds_height := bounds_1.y - bounds_0.y
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					atlas := & ctx.atlas
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bounds_width_scaled  := cast(u32) (f32(bounds_width)  * entry.size_scale + 2.0 * f32(atlas.glyph_padding))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bounds_height_scaled := cast(u32) (f32(bounds_height) * entry.size_scale + 2.0 * f32(atlas.glyph_padding))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if bounds_width_scaled <= atlas.region_a.width && bounds_height_scaled <= atlas.region_a.height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Region A for small glyphs. These are good for things such as punctuation.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region   = .A
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						state    = & atlas.region_a.state
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next_idx = & atlas.region_a.next_idx
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else if bounds_width_scaled <= atlas.region_b.width && bounds_height_scaled <= atlas.region_b.height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Region B for tall glyphs. These are good for things such as european alphabets.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region   = .B
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						state    = & atlas.region_b.state
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next_idx = & atlas.region_b.next_idx
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else if bounds_width_scaled <= atlas.region_c.width && bounds_height_scaled <= atlas.region_c.height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Region C for big glyphs. These are good for things such as asian typography.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region   = .C
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						state    = & atlas.region_c.state
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next_idx = & atlas.region_c.next_idx
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else if bounds_width_scaled <= atlas.region_d.width && bounds_height_scaled <= atlas.region_d.height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Region D for huge glyphs. These are good for things such as titles and 4k.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region   = .D
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						state    = & atlas.region_d.state
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next_idx = & atlas.region_d.next_idx
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else if bounds_width_scaled <= atlas.buffer_width && bounds_height_scaled <= atlas.buffer_height
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// Region 'E' for massive glyphs. These are rendered uncached and un-oversampled.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region   = .E
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						state    = nil
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						next_idx = nil
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if bounds_width_scaled <= atlas.buffer_width / 2 && bounds_height_scaled <= atlas.buffer_height / 2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							(over_sample^) = { 2.0, 2.0 }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							(over_sample^) = { 1.0, 1.0 }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						region = .None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert(state    != nil)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					assert(next_idx != nil)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				flush_glyph_buffer_to_atlas :: proc()
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |