finalized dynamic font loading
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 15 Jul 2021 14:03:03 +0000 (09:03 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 15 Jul 2021 14:03:03 +0000 (09:03 -0500)
site/js/js_events.js
src/config.onyx
src/debug_log.onyx
src/main.onyx

index 8363914596fa0ed0eea3e667e2e4a1ec4e568935..4ef84a11c0e180db98ed536747bd9cb807f6f8d4 100644 (file)
@@ -140,6 +140,7 @@ window.ONYX_MODULES.push({
 
         var path_memory = new Uint8Array(ONYX_MEMORY.buffer, filename_ptr, filename_len);
         var path = new TextDecoder("utf-8").decode(path_memory);
+        console.log(`Requesting file '${path}'`);
 
         fetch(path)
             .then(response => response.arrayBuffer())
index 885adf8d7b6abd32768bcd9e49774c70827bd7ce..0d7e4100efc25cc68cf2ce964036a37527227137 100644 (file)
@@ -26,12 +26,15 @@ Colors : struct {
 }
 
 
-Fonts :: struct {
+// This should be #private at some point, however right now it cannot be as this symbol is needed to query the fonts to load.
+Fonts_Container :: struct {
     FontData :: struct (index: i32, fnt_file: str, tex_file: str) {}
 
     Calibri:  FontData(0, "/res/fonts/Calibri.fnt", "/res/fonts/Calibri_0.data");
     FiraCode: FontData(1, "/res/fonts/test.fnt",    "/res/fonts/test_0.data");
 }
 
+Fonts : Fonts_Container;
+
 
 }
index ca8b3092166c4c4a969f567145ac7f61436069c0..49bb74f99d950141fdd9b0779f988b700b475c79 100644 (file)
@@ -65,13 +65,14 @@ draw_debug_log :: (r: ui.Rectangle, y_scroll: ^f32 = null, site := #callsite) {
 
     ui.draw_rect(r, color=.{0,0,0,0.8});
 
-    y_offset := line_spacing + *y_scroll;
+    scale :: 1f;
+    y_offset := line_spacing * scale + *y_scroll;
 
     while i := log_buffer.lines.count - 1; cast(i32) i >= 0 {
         defer i -= 1;
 
-        ui.draw_text_raw(log_buffer.lines[i], x, y - y_offset, color=.{ 0.2, 1.0, 0.2 });
-        y_offset += line_spacing;
+        ui.draw_text_raw(log_buffer.lines[i], x, y - y_offset, color=.{ 0.2, 1.0, 0.2 }, font=1, size=scale);
+        y_offset += line_spacing * scale;
     }
 }
 
index 12585b25470fcc2b8b87daaeed7191e1e240ca64..6974ab986fc5795ba661df5821677d4bb0300ed1 100644 (file)
@@ -23,18 +23,6 @@ debug_log_y_offset_target := 0.0f;
 main :: (args: [] cstr) {
     init();
 
-    for ^member: (cast(^type_info.Type_Info_Struct) type_info.get_type_info(config.Fonts)).members {
-        info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(member.type);
-
-        printf("{}\n", member.name);
-        for p: info.parameters {
-            buffer: [128] u8;
-            s := conv.str_format_va("{} ", ~~buffer, ~~any.[ p ]);
-            printf("{} ", s);
-        }
-        print("\n");
-    }
-
     start_loop :: () -> void #foreign "decompiler" "start_loop" ---
     start_loop();
 }
@@ -53,6 +41,8 @@ init :: () {
     color_file := events.request_file(config.color_scheme_file);
     map.put(^on_file_load_callbacks, color_file, load_colors);
 
+    load_fonts();
+
     search_buffer = string.buffer_make(memory.make_slice(u8, 256));
 
     gl.enable(gl.BLEND);
@@ -226,7 +216,10 @@ draw :: () {
         ui.window_start(^test_window);
         defer ui.window_end();
 
-        if ui.button(.{ 0, 0, 400, 300 }, "Top-Left") do search_buffer.count = 0;
+        test_button_theme := ui.default_button_theme;
+        test_button_theme.font = config.Fonts.Calibri.index;
+
+        if ui.button(.{ 0, 0, 400, 300 }, "Top-Left", theme=^test_button_theme) do search_buffer.count = 0;
         ui.textbox(.{ 0, 300, 400, 350 }, ^search_buffer);
     }
 
@@ -264,6 +257,7 @@ draw_menu_bar :: (menu_bar_: ^ui.Rectangle) {
     menu_button_theme := ui.default_button_theme;
     menu_button_theme.border_width = 2;
     menu_button_theme.font_size = .9;
+    menu_button_theme.font = 0;
 
     menu_textbox_theme := ui.default_textbox_theme;
     menu_textbox_theme.border_width = 2;
@@ -353,3 +347,76 @@ load_colors :: (event: ^events.Event) {
 
     debug_log(.Info, "Successfully loaded colorscheme.", null);
 }
+
+@Relocate
+#private_file
+load_fonts :: () {
+    use type_info;
+
+    // Dumb check to see if the array is uninitialized
+    if fonts_loading.capacity == 0 do array.init(^fonts_loading, 4);
+
+    fonts_info := cast(^Type_Info_Struct) get_type_info(config.Fonts_Container);
+    for ^member: fonts_info.members {
+        info := cast(^Type_Info_Struct) get_type_info(member.type);
+
+        font_name := member.name;
+
+        font_index    := *cast(^i32) info.parameters[0].data;
+        fnt_file_name := *cast(^str) info.parameters[1].data;
+        tex_file_name := *cast(^str) info.parameters[2].data;
+
+        debug_log(.Info, "Loading font '{}' with index {} from '{}' and '{}'\n", font_name, font_index, fnt_file_name, tex_file_name);
+
+        fnt_file_id := events.request_file(fnt_file_name);
+        tex_file_id := events.request_file(tex_file_name);
+
+        map.put(^on_file_load_callbacks, fnt_file_id, font_file_loaded);
+        map.put(^on_file_load_callbacks, tex_file_id, font_file_loaded);
+
+        array.push(^fonts_loading, .{ font_index, font_name, fnt_file_id, tex_file_id });
+    }
+
+    Loading_Font :: struct {
+        font_index  : u32;
+        font_name   : str;
+
+        fnt_file_id : u32;
+        tex_file_id : u32;
+
+        fnt_file_size := cast(u32) 0;
+        tex_file_size := cast(u32) 0;
+    }
+    #persist fonts_loading : [..] Loading_Font;
+
+    font_file_loaded :: (ev: ^events.Event) {
+        lf: ^Loading_Font = null;
+
+        for ^entry: fonts_loading {
+            if entry.fnt_file_id == ev.file.file_id { entry.fnt_file_size = ev.file.size; lf = entry; }
+            if entry.tex_file_id == ev.file.file_id { entry.tex_file_size = ev.file.size; lf = entry; }
+        }
+
+        assert(lf != null, "Loaded a file for a font that was not registered.");
+
+        if lf.fnt_file_size > 0 && lf.tex_file_size > 0 {
+            fnt_data := memory.make_slice(u8, lf.fnt_file_size);
+            tex_data := memory.make_slice(u8, lf.tex_file_size);
+            defer {
+                cfree(fnt_data.data); 
+                cfree(tex_data.data); 
+            }
+
+            @ErrorHandling
+            assert(events.get_requested_file_data(lf.fnt_file_id, fnt_data), "Failed to get bmfont file data.");
+            assert(events.get_requested_file_data(lf.tex_file_id, tex_data), "Failed to get texture data.");
+
+            font := ui.create_font(fnt_data, tex_data);
+            ui.register_font(lf.font_index, font);
+
+            debug_log(.Info, "Successfully loaded font '{}'.", lf.font_name);
+
+            ui.use_font(lf.font_index);
+        }
+    }
+}
\ No newline at end of file