--- /dev/null
+#include "vg_font.h"
+
+#define STB_IMAGE_IMPLEMENTATION
+#include "submodules/stb/stb_image.h"
+
+void vg_build_font_face_run( vg_font_face *face,
+ char first, char last, i16 x, i16 y )
+{
+ u32 count = (u32)last - (u32)first;
+ for( u32 i=0; i<=count; i ++ )
+ {
+ u32 index = (u32)first + i;
+ face->map[index].x = x+(i*face->cw);
+ face->map[index].y = y;
+ }
+}
+
+void vg_build_write_font_face( FILE *fp, vg_font_face *face )
+{
+ fprintf( fp, "vg_font_face %s = {\n", face->name );
+ fprintf( fp, " .name=\"%s\",\n", face->name );
+ fprintf( fp, " .cw=%hd,.ch=%hd,\n", face->cw,face->ch );
+ fprintf( fp, " .sx=%hd,.sy=%hd,\n", face->sx,face->sy );
+ fprintf( fp, " .baseline=%hd,\n", face->baseline );
+ fprintf( fp, " .map={\n" );
+
+ u32 chars = 0;
+
+ for( u32 i=0; i<256; i ++ )
+ {
+ if( face->map[i].x || face->map[i].y )
+ {
+ chars += fprintf( fp, "[%u]={%hd,%hd},",
+ i, face->map[i].x, face->map[i].y );
+
+ if( chars > 80 )
+ {
+ fprintf( fp, "\n" );
+ chars = 0;
+ }
+ }
+ }
+
+ fprintf( fp, "\n}};\n\n" );
+}
+
+void vg_build_font_sheet( FILE *fp, char *name, const char *source )
+{
+ int x,y,n;
+ unsigned char *data = stbi_load( source, &x, &y, &n, 4 );
+
+ if( !data )
+ {
+ vg_error( "Couldn't open source file\n" );
+ return;
+ }
+
+ fprintf( fp, "vg_font_sheet %s = {\n", name );
+ fprintf( fp, " .w=%d, .h=%d,\n", x,y );
+ fprintf( fp, " .bitmap={\n" );
+
+ u32 pixel_max = x*y;
+ u32 pixel = 0, chars = 0;
+ while( pixel_max )
+ {
+ u32 buff = 0;
+ for( int b = 31; b >= 0; b-- )
+ {
+ buff |= data[pixel*4]>128?0x1<<b:0;
+ pixel++;
+
+ if( pixel >= pixel_max )
+ {
+ pixel_max = 0;
+ break;
+ }
+ }
+
+ chars += fprintf( fp, "%#x,", buff );
+ if( chars > 80 )
+ {
+ fprintf( fp, "\n" );
+ chars = 0;
+ }
+ }
+
+ fprintf( fp, "\n}};\n" );
+ free( data );
+}
+
+void vg_build_default_font(void)
+{
+ FILE *fp = fopen( "vg/vg_default_font.gc", "w" );
+ vg_build_font_sheet( fp, "vg_default_font_sheet",
+ "vg/src/fonts/vg_font_thin_3.png" );
+ vg_font_face small =
+ {
+ .name = "vgf_default_small",
+ .cw=8, .ch=14,
+ .sx=8, .sy=14,
+ .baseline = 4
+ };
+ vg_build_font_face_run( &small, '!', '/', 8, 0 );
+ vg_build_font_face_run( &small, '[', '`', 128,0 );
+ vg_build_font_face_run( &small, '{', '~', 176,0 );
+ vg_build_font_face_run( &small, ':', '@', 208,0 );
+ vg_build_font_face_run( &small, 'A', 'Z', 0, 14 );
+ vg_build_font_face_run( &small, 'a', 'z', 0, 28 );
+ vg_build_font_face_run( &small, '0', '9', 208,14 );
+ vg_build_write_font_face( fp, &small );
+
+ vg_font_face large =
+ {
+ .name = "vgf_default_large",
+ .cw=12, .ch=21,
+ .sx=12, .sy=21,
+ .baseline=6,
+ };
+ vg_build_font_face_run( &large, '!', '/', 12, 56 );
+ vg_build_font_face_run( &large, '[', '`', 192,56 );
+ vg_build_font_face_run( &large, '{', '~', 264,56 );
+ vg_build_font_face_run( &large, ':', '@', 324,56 );
+ vg_build_font_face_run( &large, 'A', 'Z', 0, 77 );
+ vg_build_font_face_run( &large, 'a', 'z', 0, 98 );
+ vg_build_font_face_run( &large, '0', '9', 312,77 );
+ vg_build_write_font_face( fp, &large );
+
+ vg_font_face title =
+ {
+ .name = "vgf_default_title",
+ .cw=24, .ch=42,
+ .sx=24, .sy=42,
+ .baseline=12,
+ };
+ vg_build_font_face_run( &title, '!', '/', 24, 140 );
+ vg_build_font_face_run( &title, '[', '_', 384,140 );
+ vg_build_font_face_run( &title, '`', '`', 0, 182 );
+ vg_build_font_face_run( &title, '{', '~', 24, 182 );
+ vg_build_font_face_run( &title, ':', '@', 120,182 );
+ vg_build_font_face_run( &title, 'A', 'U', 0, 224 );
+ vg_build_font_face_run( &title, 'V', 'Z', 0, 308 );
+ vg_build_font_face_run( &title, 'a', 'u', 0, 266 );
+ vg_build_font_face_run( &title, 'v', 'z', 0, 350 );
+ vg_build_font_face_run( &title, '0', '9', 120,308 );
+ vg_build_write_font_face( fp, &title );
+
+ fclose( fp );
+}