adjust imgui font system
authorhgn <hgodden00@gmail.com>
Sun, 14 Apr 2024 13:16:35 +0000 (14:16 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 14 Apr 2024 13:16:35 +0000 (14:16 +0100)
.gitignore
src/fonts/vg_font_thin_3.png [new file with mode: 0644]
src/fonts/vg_font_thin_3.xcf [new file with mode: 0644]
vg_build.h
vg_build_font.h [new file with mode: 0644]
vg_console.c
vg_engine.c
vg_font.h [new file with mode: 0644]
vg_imgui.c
vg_imgui.h

index a9d0441cb9265535395007b034ea2973138aa560..9b172f38333fcbabbeb3ef4b5b2b7a3ec6da026a 100755 (executable)
@@ -2,5 +2,7 @@
 *.so
 *.dll
 *.swp
+*.gc
+*.gh
 
 bin/
diff --git a/src/fonts/vg_font_thin_3.png b/src/fonts/vg_font_thin_3.png
new file mode 100644 (file)
index 0000000..1989a44
Binary files /dev/null and b/src/fonts/vg_font_thin_3.png differ
diff --git a/src/fonts/vg_font_thin_3.xcf b/src/fonts/vg_font_thin_3.xcf
new file mode 100644 (file)
index 0000000..8275f06
Binary files /dev/null and b/src/fonts/vg_font_thin_3.xcf differ
index 7dd34b9b224f887a32e1297e68cd196ff976fb6b..b40ecd3c23545040484f0ed8bb560f085ce3f7a9 100644 (file)
@@ -9,6 +9,7 @@
 #include "vg_opt.h"
 #include "vg_log.h"
 #include "vg_string.h"
+#include "vg_build_font.h"
 
 /* we dont free dynamic vg_strs in this program. so, we dont care.. */
 const char *__asan_default_options() { return "detect_leaks=0"; }
@@ -448,6 +449,9 @@ vg_engine_default_config = {
 
 void vg_add_engine( struct vg_project *proj, struct vg_engine_config *config )
 {
+   /* building assets */
+   vg_build_default_font();
+
    if( !config ) config = &vg_engine_default_config;
    vg_str config_string;
    vg_strnull( &config_string, NULL, -1 );
diff --git a/vg_build_font.h b/vg_build_font.h
new file mode 100644 (file)
index 0000000..5f0fd3b
--- /dev/null
@@ -0,0 +1,148 @@
+#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 );
+}
index ccc39f7b3c078aab83b43699e520e0806fb11833..561bb63463e92fc92e11f375cad64232a822cc42 100644 (file)
@@ -593,7 +593,7 @@ void vg_console_draw(void)
    SDL_AtomicLock( &vg_log.print_sl );
 
        int ptr = vg_log.log_line_current;
-   int const fh = vg_ui.font->line_height, log_lines = 32;
+   int const fh = vg_ui.font->sy, log_lines = 32;
    int console_lines = VG_MIN( log_lines, vg_log.log_line_count );
 
    ui_rect rect_log   = { 0, 0,                vg.window_x, log_lines*fh },
@@ -638,9 +638,9 @@ void vg_console_draw(void)
       ui_rect rect_suggest;
       rect_copy( rect_input, rect_suggest );
 
-      rect_suggest[0] += 6 + vg_ui.font->spacing*vg_console.suggestion_pastepos;
+      rect_suggest[0] += 6 + vg_ui.font->sx*vg_console.suggestion_pastepos;
       rect_suggest[1] += rect_input[3];
-      rect_suggest[2]  = vg_ui.font->spacing * vg_console.suggestion_maxlen;
+      rect_suggest[2]  = vg_ui.font->sx * vg_console.suggestion_maxlen;
       rect_suggest[3]  = vg_console.suggestion_count * fh;
 
       ui_fill( rect_suggest, bg_colour );
index 0e59528a47c61328ded87fe6703013905cd4722c..1723c70f3c26ce22e8a6856e4e0b9a31f828b04e 100644 (file)
@@ -887,7 +887,7 @@ void vg_settings_ui_header( ui_rect inout_panel, const char *name )
 bool vg_settings_apply_button( ui_rect inout_panel, bool validated )
 {
    ui_rect last_row;
-   ui_px height = (vg_ui.font->glyph_height + 18) * k_ui_scale;
+   ui_px height = (vg_ui.font->sy + 18) * k_ui_scale;
    ui_split( inout_panel, k_ui_axis_h, -height, k_ui_padding, 
              inout_panel, last_row );
 
@@ -1130,7 +1130,8 @@ static void vg_settings_gui(void)
    ui_rect quit_button;
    ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
 
-   if( ui_button_text( quit_button, "X", 1 ) == 1 ){
+   if( ui_button_text( quit_button, "X", 1 ) == k_ui_button_click )
+   {
       vg_settings_close();
       return;
    }
diff --git a/vg_font.h b/vg_font.h
new file mode 100644 (file)
index 0000000..5fcb29b
--- /dev/null
+++ b/vg_font.h
@@ -0,0 +1,22 @@
+typedef struct vg_font_char vg_font_char;
+typedef struct vg_font_face vg_font_face;
+typedef struct vg_font_sheet vg_font_sheet;
+
+struct vg_font_char
+{
+   i16 x, y;
+};
+
+struct vg_font_face
+{
+   const char *name;
+   i16 cw, ch, sx, sy, baseline;
+   vg_font_char map[256];
+};
+
+struct vg_font_sheet
+{
+   i16 w, h;
+   u32 bitmap[];
+};
+
index 08209b7d2ef44c1d3259416f529df2da3ab2ce0f..a4af9aecb3c922005ef90081792be4fc3747cd92 100644 (file)
@@ -24,26 +24,7 @@ ui_px k_ui_widget_height = 28,
       k_ui_scale = 1,
       k_ui_padding = 8;
 
-ui_font vg_ui_font_small = {
-   .glyph_width    = 8,
-   .glyph_height   = 14,
-   .glyph_baseline = 4,
-   .line_height    = 14,
-   .sheet_size     = 256,
-   .spacing        = 8,
-   .ascii_start    = ' ',
-   .offset_y = 0
-},
-vg_ui_font_big = {
-   .glyph_width  = 12,
-   .glyph_height = 21,
-   .glyph_baseline = 6,
-   .line_height = 21,
-   .sheet_size = 256,
-   .spacing = 10,
-   .ascii_start = ' ',
-   .offset_y = 84
-};
+#include "vg/vg_default_font.gc"
 
 struct vg_imgui vg_ui = {
    .scheme = {
@@ -82,7 +63,7 @@ struct vg_imgui vg_ui = {
       [ k_ui_purple + k_ui_brighter ] = UI_RGB( 0xd3869b ),
       [ k_ui_gray   + k_ui_brighter ] = UI_RGB( 0xa89984 ),
    },
-   .font = &vg_ui_font_small,
+   .font = &vgf_default_small,
    .colour = {1.0f,1.0f,1.0f,1.0f},
    .bg_inverse_ratio = {1,1}
 };
@@ -97,6 +78,7 @@ static struct vg_shader _shader_ui ={
        "layout (location=2) in vec4 a_colour;"
        "uniform mat3 uPv;"
    "uniform vec2 uBGInverseRatio;"
+   "uniform vec2 uInverseFontSheet;"
        ""
        "out vec4 aTexCoords;"
        "out vec4 aColour;"
@@ -104,7 +86,7 @@ static struct vg_shader _shader_ui ={
        "void main(){"
       "vec4 proj_pos = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
                "gl_Position = proj_pos;"
-               "aTexCoords = vec4( a_uv * 0.00390625, "
+               "aTexCoords = vec4( a_uv * uInverseFontSheet, "
                         " (proj_pos.xy*0.5+0.5) * uBGInverseRatio );"
                "aColour = a_colour;"
        "}",
@@ -312,28 +294,36 @@ void vg_ui_init(void)
     */
    
        /* Load default font */
-   u32 compressed[] = {
-      #include "vg/vg_pxfont_thin.h"
-   };
 
-   u32 pixels = 0, total = 256*256, data = 0;
-   u8 image[256*256];
+   vg_font_sheet *sheet = &vg_default_font_sheet;
+   u32 pixels = 0, 
+       total = sheet->w*sheet->h,
+       data = 0;
+
+   vg_linear_clear( vg_mem.scratch );
+   u8 *image = vg_linear_alloc( vg_mem.scratch, total );
    
-   while( pixels < total ){
-      for( int b = 31; b >= 0; b-- ){
-         image[ pixels ++ ] = (compressed[data] & (0x1u << b))? 0xffu: 0x00u;
+   while( pixels < total )
+   {
+      for( int b = 31; b >= 0; b-- )
+      {
+         image[ pixels ++ ] = (sheet->bitmap[data] & (0x1u << b))? 0xffu: 0x00u;
          
-         if( pixels >= total ){
+         if( pixels >= total )
+         {
             total = 0;
             break;
          }
       }
       data++;
    }
+
+   vg_ui.inverse_font_sheet[0] = 1.0/(f64)sheet->w;
+   vg_ui.inverse_font_sheet[1] = 1.0/(f64)sheet->h;
    
    glGenTextures( 1, &vg_ui.tex_glyphs );
    glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs );
-   glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, 
+   glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, sheet->w, sheet->h, 0, 
                  GL_RED, GL_UNSIGNED_BYTE, image );
 
    VG_CHECK_GL_ERR();
@@ -411,6 +401,8 @@ void ui_flush( enum ui_shader shader, f32 w, f32 h ){
                    vg_ui.frosting );
       glUniform2fv( glGetUniformLocation( _shader_ui.id, "uBGInverseRatio" ),
                      1, vg_ui.bg_inverse_ratio );
+      glUniform2fv( glGetUniformLocation( _shader_ui.id, "uInverseFontSheet" ),
+                     1, vg_ui.inverse_font_sheet );
    }
    else if( shader == k_ui_shader_image ){
       glUseProgram( _shader_ui_image.id );
@@ -604,7 +596,7 @@ ui_px ui_text_line_width( const char *str )
       else if( c == '\n' ) break;
    }
 
-   return length * vg_ui.font->spacing;
+   return length * vg_ui.font->sx;
 }
 
 ui_px ui_text_string_height( const char *str )
@@ -613,11 +605,12 @@ ui_px ui_text_string_height( const char *str )
    const char *_c = str;
    u8 c;
 
-   while( (c = *(_c ++)) ){
+   while( (c = *(_c ++)) )
+   {
       if( c == '\n' ) height ++;
    }
 
-   return height * 14;
+   return height * vg_ui.font->sy;
 }
 
 ui_px ui_text_aligned_x( const char *str, ui_rect rect, ui_px scale,
@@ -782,18 +775,15 @@ u32 v4f_u32_colour( v4f colour )
    return r | (g<<8) | (b<<16) | (a<<24);
 }
 
-static void ui_text_glyph( const struct ui_font *font, ui_px scale,
-                           u8 glyph, ui_rect out_texcoords ){
-   glyph -= font->ascii_start;
+static void ui_text_glyph( const struct vg_font_face *ff,
+                           u8 glyph, ui_rect out_texcoords )
+{
+   const vg_font_char *ch = &ff->map[ glyph ];
 
-   ui_px per_row = font->sheet_size / font->glyph_width,
-         column  = (ui_px)glyph % per_row,
-         row     = (glyph - column) / per_row;
-   
-   out_texcoords[0] = column * font->glyph_width;
-   out_texcoords[1] = row * font->glyph_height + font->offset_y;
-   out_texcoords[2] = out_texcoords[0] + font->glyph_width;
-   out_texcoords[3] = out_texcoords[1] + font->glyph_height;
+   out_texcoords[0] = ch->x;
+   out_texcoords[1] = ch->y;
+   out_texcoords[2] = ch->x + ff->cw;
+   out_texcoords[3] = ch->y + ff->ch;
 }
 
 u32 ui_opacity( u32 colour, f32 opacity )
@@ -815,12 +805,13 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale,
 
    text_cursor[0] = ui_text_aligned_x( str, rect, scale, align );
        text_cursor[1] = rect[1];
-       text_cursor[2] = vg_ui.font->glyph_width*scale;
-       text_cursor[3] = vg_ui.font->glyph_height*scale;
+       text_cursor[2] = vg_ui.font->cw*scale;
+       text_cursor[3] = vg_ui.font->ch*scale;
 
    u32 printed_chars = 0;
 
-   if( align & (k_ui_align_middle|k_ui_align_bottom) ){
+   if( align & (k_ui_align_middle|k_ui_align_bottom) )
+   {
       ui_px height = ui_text_string_height( str ) * scale;
 
       if( align & k_ui_align_bottom )
@@ -829,41 +820,50 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale,
          text_cursor[1] += (rect[3]-height)/2;
    }
 
-       while( (c = *(_c ++)) ){
-      if( printed_chars >= len ){
+       while( (c = *(_c ++)) )
+   {
+      if( printed_chars >= len )
+      {
          printed_chars = 0;
-                       text_cursor[1] += vg_ui.font->line_height*scale;
+                       text_cursor[1] += vg_ui.font->sy*scale;
          text_cursor[0] = ui_text_aligned_x( _c, rect, scale, align );
-         text_cursor[0] -= vg_ui.font->spacing*scale;
+         text_cursor[0] -= vg_ui.font->sx*scale;
 
          ui_rect glyph;
-         ui_text_glyph( vg_ui.font, scale, '\xb6' /*FIXME*/, glyph );
+         ui_text_glyph( vg_ui.font, '\xb6' /*FIXME*/, glyph );
          ui_fill_rect( text_cursor, 0x00ffffff, glyph );
-         text_cursor[0] += vg_ui.font->spacing*scale;
+         text_cursor[0] += vg_ui.font->sx*scale;
       }
 
-               if( c == '\n' ){
-                       text_cursor[1] += vg_ui.font->line_height*scale;
+               if( c == '\n' )
+      {
+                       text_cursor[1] += vg_ui.font->sy*scale;
          text_cursor[0] = ui_text_aligned_x( _c, rect, scale, align );
          printed_chars = 0;
                        continue;
                }
-               else if( c >= 33 ){
+               else if( c >= 33 )
+      {
          ui_rect glyph;
-         ui_text_glyph( vg_ui.font, scale, c, glyph );
+         ui_text_glyph( vg_ui.font, c, glyph );
 
          ui_rect cursor_clipped;
-         if( ui_clip( rect, text_cursor, cursor_clipped ) ){
+         if( ui_clip( rect, text_cursor, cursor_clipped ) )
+         {
             ui_fill_rect( cursor_clipped, colour, glyph );
          }
                }
-               else if( c == '\x1B' ){
+               else if( c == '\x1B' )
+      {
          /* vt codes */
                        _c ++;
                        u16 colour_id = 0;
-                       for( int i=0; i<3; i ++ ){
-                               if( _c[i] ){
-                                       if( _c[i] == 'm' ){
+                       for( int i=0; i<3; i ++ )
+         {
+                               if( _c[i] )
+            {
+                                       if( _c[i] == 'm' )
+               {
                                                _c = _c + i + 1;
                                                
                                                switch( colour_id ){
@@ -884,7 +884,8 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale,
                                        
                                        colour_id |= _c[i] << (i*8);
                                } 
-                               else{
+                               else
+            {
                                        _c = _c +i;
                                        break;
                                }
@@ -892,13 +893,14 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale,
 
          continue;
                }
-      else if( c == '\t' ){
-         text_cursor[0] += vg_ui.font->spacing*scale*4;
+      else if( c == '\t' )
+      {
+         text_cursor[0] += vg_ui.font->sx*scale*4;
          printed_chars += 4;
          continue;
       }
                
-       text_cursor[0] += vg_ui.font->spacing*scale;
+       text_cursor[0] += vg_ui.font->sx*scale;
       printed_chars ++;
        }
 
@@ -911,6 +913,11 @@ void ui_text( ui_rect rect, const char *str, ui_px scale,
    ui_ntext( rect, str, 1024, scale, align, colour );
 }
 
+void ui_font_face( vg_font_face *ff )
+{
+   vg_ui.font = ff;
+}
+
 /*
  * Standard layout stuff
  * -----------------------------------------------------------------------------
@@ -928,14 +935,14 @@ void ui_label( ui_rect rect, const char *text, ui_px size,
                ui_px gap, ui_rect r )
 {
    ui_rect l;
-   ui_px width = (ui_text_line_width(text)+vg_ui.font->spacing) * size;
+   ui_px width = (ui_text_line_width(text)+vg_ui.font->sx) * size;
    ui_split( rect, k_ui_axis_v, width, gap, l, r );
    ui_text( l, text, 1, k_ui_align_middle_left, 0 );
 }
 
 void ui_standard_widget( ui_rect inout_panel, ui_rect out_rect, ui_px count )
 {
-   ui_px height = (count * vg_ui.font->glyph_height + 18) * k_ui_scale;
+   ui_px height = (count * vg_ui.font->sy + 18) * k_ui_scale;
    ui_split( inout_panel, k_ui_axis_h, height, k_ui_padding, 
              out_rect, inout_panel );
 }
@@ -1122,8 +1129,8 @@ void ui_postrender(void)
       
       ui_rect row0, row1, btn;
       ui_split_ratio( message, k_ui_axis_h, 0.5f, 0, row0, row1 );
-      row0[0] += vg_ui.font->spacing;
-      ui_ntext( row0, vg_ui.modal.message, (box[2]/vg_ui.font->spacing)-2, 1, 
+      row0[0] += vg_ui.font->sx;
+      ui_ntext( row0, vg_ui.modal.message, (box[2]/vg_ui.font->sx)-2, 1, 
                 k_ui_align_left, colour );
 
       rect_copy( row1, btn );
@@ -1877,7 +1884,7 @@ int ui_textbox( ui_rect inout_panel, const char *label,
    rect_copy( rect, text_rect );
 
    if( flags & UI_TEXTBOX_MULTILINE ) text_rect[3] = rect[3]-16;
-   else text_rect[3] = vg_ui.font->line_height;
+   else text_rect[3] = vg_ui.font->sy;
 
    text_rect[2] -= 16;
    ui_rect_center( rect, text_rect );
@@ -1885,41 +1892,47 @@ int ui_textbox( ui_rect inout_panel, const char *label,
    ui_px wrap_length = 1024;
 
    if( flags & UI_TEXTBOX_WRAP ) 
-      wrap_length = text_rect[2] / vg_ui.font->spacing;
+      wrap_length = text_rect[2] / vg_ui.font->sx;
 
-   if( hover ){
+   if( hover )
+   {
       vg_ui.cursor = k_ui_cursor_ibeam;
    }
 
-   if( vg_ui.focused_control_id == buf ){
+   if( vg_ui.focused_control_id == buf )
+   {
       ui_fill( rect, col_base );
       ui_ntext( text_rect, buf, wrap_length, 1, k_ui_align_left, 0 );
 
-      if( !(flags & UI_TEXTBOX_AUTOFOCUS) && ((clickup||clickdown) && !target)){
+      if( !(flags & UI_TEXTBOX_AUTOFOCUS) && ((clickup||clickdown) && !target))
+      {
          ui_defocus_all();
       }
-      else{
+      else
+      {
          vg_ui.focused_control_hit = 1;
          if( click && target ){
             int p0[3] ={
-               (vg_ui.mouse_click[0] - text_rect[0]) / vg_ui.font->spacing,
-               (vg_ui.mouse_click[1] - text_rect[1]) / vg_ui.font->line_height,
+               (vg_ui.mouse_click[0] - text_rect[0]) / vg_ui.font->sx,
+               (vg_ui.mouse_click[1] - text_rect[1]) / vg_ui.font->sy,
                -1
             }, 
             p1[3] = {
-               (vg_ui.mouse[0] - text_rect[0]) / vg_ui.font->spacing,
-               (vg_ui.mouse[1] - text_rect[1]) / vg_ui.font->line_height,
+               (vg_ui.mouse[0] - text_rect[0]) / vg_ui.font->sx,
+               (vg_ui.mouse[1] - text_rect[1]) / vg_ui.font->sy,
                -1
             };
 
-            if( flags & UI_TEXTBOX_MULTILINE ){
+            if( flags & UI_TEXTBOX_MULTILINE )
+            {
                _ui_textbox_calc_index_from_grid( p0, wrap_length );
                _ui_textbox_calc_index_from_grid( p1, wrap_length );
 
                vg_ui.textbox.cursor_pos = p0[2];
                vg_ui.textbox.cursor_user = p1[2];
             }
-            else{
+            else
+            {
                int max = strlen( buf );
                vg_ui.textbox.cursor_pos = VG_MAX( 0, VG_MIN( max, p0[0] )),
                vg_ui.textbox.cursor_user = VG_MAX( 0, VG_MIN( max, p1[0] ));
@@ -1936,28 +1949,32 @@ int ui_textbox( ui_rect inout_panel, const char *label,
              end   = VG_MAX( c0, c1 ),
              chars = end-start;
 
-         if( flags & (UI_TEXTBOX_WRAP|UI_TEXTBOX_MULTILINE) ){
+         if( flags & (UI_TEXTBOX_WRAP|UI_TEXTBOX_MULTILINE) )
+         {
             int pos[3], remaining = chars;
 
             pos[2] = start;
             _ui_textbox_index_calc_coords( pos, wrap_length );
 
-            if( start==end ){
-               cursor[0] = text_rect[0] + pos[0]*vg_ui.font->spacing-1;
+            if( start==end )
+            {
+               cursor[0] = text_rect[0] + pos[0]*vg_ui.font->sx-1;
                cursor[1] = text_rect[1] + pos[1]*14;
                cursor[2] = 2;
                cursor[3] = 13;
                ui_fill( cursor, col_cursor );
                rect_copy( cursor, vg_ui.click_fader_end );
             }
-            else{
-               while( remaining ){
+            else
+            {
+               while( remaining )
+               {
                   int run = _ui_textbox_run_remaining( pos, wrap_length );
                       run = VG_MIN( run, remaining );
 
-                  cursor[0] = text_rect[0] + pos[0]*vg_ui.font->spacing-1;
+                  cursor[0] = text_rect[0] + pos[0]*vg_ui.font->sx-1;
                   cursor[1] = text_rect[1] + pos[1]*14;
-                  cursor[2] = (float)(run)*(float)vg_ui.font->spacing;
+                  cursor[2] = (float)(run)*(float)vg_ui.font->sx;
                   cursor[3] = 13;
 
                   ui_fill( cursor, col_cursor );
@@ -1970,20 +1987,24 @@ int ui_textbox( ui_rect inout_panel, const char *label,
                rect_copy( cursor, vg_ui.click_fader_end );
             }
          }
-         else{
-            cursor[0] = text_rect[0] + start*vg_ui.font->spacing-1;
+         else
+         {
+            cursor[0] = text_rect[0] + start*vg_ui.font->sx-1;
             cursor[1] = text_rect[1];
             cursor[3] = 13;
 
-            if( start==end ){
+            if( start==end )
+            {
                cursor[2] = 2;
             }
-            else{
-               cursor[2] = (float)(chars)*(float)vg_ui.font->spacing;
+            else
+            {
+               cursor[2] = (float)(chars)*(float)vg_ui.font->sx;
             }
 
             if( (vg_ui.click_fade_opacity<=0.0f) && 
-                 ui_clip( rect, cursor, cursor ) ){
+                 ui_clip( rect, cursor, cursor ) )
+            {
                ui_fill( cursor, col_cursor );
             }
 
@@ -1994,8 +2015,10 @@ int ui_textbox( ui_rect inout_panel, const char *label,
       return 0;
    }
 
-   if( click || (flags & UI_TEXTBOX_AUTOFOCUS) ){
-      if( (target && hover) || (flags & UI_TEXTBOX_AUTOFOCUS) ){
+   if( click || (flags & UI_TEXTBOX_AUTOFOCUS) )
+   {
+      if( (target && hover) || (flags & UI_TEXTBOX_AUTOFOCUS) )
+      {
          ui_defocus_all();
 
          ui_fill( rect, col_highlight );
@@ -2012,10 +2035,12 @@ int ui_textbox( ui_rect inout_panel, const char *label,
          vg_ui.textbox.cursor_pos = 0;
          vg_ui.textbox.cursor_user = 0;
 
-         if( callbacks ){
+         if( callbacks )
+         {
             vg_ui.textbox.callbacks = *callbacks;
          }
-         else{
+         else
+         {
             vg_ui.textbox.callbacks.change = NULL;
             vg_ui.textbox.callbacks.down = NULL;
             vg_ui.textbox.callbacks.up = NULL;
@@ -2028,7 +2053,8 @@ int ui_textbox( ui_rect inout_panel, const char *label,
 
    ui_fill( rect, col_base );
 
-   if( hover ){
+   if( hover )
+   {
       ui_outline( rect, -1, col_highlight, 0 );
    }
 
@@ -2062,7 +2088,8 @@ void ui_tabs( ui_rect inout_panel, ui_rect out_content_panel,
    ui_rect_pad( out_content_panel, (ui_px[2]){ k_ui_padding, k_ui_padding } );
 
    /* place buttons */
-   for( i32 i=0; i<count; i++ ){
+   for( i32 i=0; i<count; i++ )
+   {
       ui_rect button = {
          bar[0] + ((f32)i*width),
          bar[1],
@@ -2071,7 +2098,8 @@ void ui_tabs( ui_rect inout_panel, ui_rect out_content_panel,
       };
 
       enum ui_scheme_colour colour = k_ui_bg+4;
-      if( i == cur_page ){
+      if( i == cur_page )
+      {
          colour = k_ui_bg+2;
          ui_outline( button, 1, ui_colour( k_ui_bg+5 ), 
                      UI_TOP|UI_LEFT|UI_RIGHT );
index f2d4f05cdaecf84679823c21784bed8667c5dc43..955f365975794c31b0d773e7bed1ff4205c40593 100644 (file)
 #include "vg_engine.h"
 #include "vg_tex.h"
 #include "vg_shader.h"
+#include "vg_font.h"
+
+extern vg_font_sheet vg_default_font_sheet;
+extern vg_font_face vgf_default_small, vgf_default_large, vgf_default_title;
 
 typedef i16                            ui_px;
 typedef ui_px                          ui_rect[4];
@@ -83,21 +87,6 @@ extern ui_px k_ui_widget_height,
 
 typedef u32 ui_scheme[8*4];
 
-struct ui_font {
-   ui_px glyph_width,
-         glyph_height,
-         glyph_baseline,
-         line_height,
-         sheet_size,
-         spacing,
-         offset_y;
-
-   u8 ascii_start;
-};
-typedef struct ui_font ui_font;
-
-extern ui_font vg_ui_font_small, vg_ui_font_big;
-
 #define UI_RGB( STDHEX )          0xff000000       |\
                          ((STDHEX&0x000000ff)<<16) |\
                          ((STDHEX&0x0000ff00)    ) |\
@@ -200,7 +189,8 @@ struct vg_imgui
    f32 frosting;
 
    ui_scheme scheme;
-   const ui_font *font;
+   const vg_font_face *font;
+   v2f inverse_font_sheet;
 
    enum ui_cursor{
       k_ui_cursor_default,
@@ -260,6 +250,7 @@ void ui_hex_to_norm( u32 hex, v4f norm );
 u32 v4f_u32_colour( v4f colour );
 
 u32 ui_opacity( u32 colour, f32 opacity );
+void ui_font_face( vg_font_face *ff );
 u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale, 
               enum ui_align align, u32 colour );
 void ui_text( ui_rect rect, const char *str, ui_px scale,