:: commit ee3131bdfa0c8ad3531fe58a9a4df8cdb5f7290f

mintsuki <mintsuki@protonmail.com> — 2021-08-20 20:18

parents: cefc4a76ca

gterm: Rearrange logic to determine font properties

diff --git a/stage23/lib/gterm.c b/stage23/lib/gterm.c
index 86a9b2ec..6223fb06 100644
--- a/stage23/lib/gterm.c
+++ b/stage23/lib/gterm.c
@@ -19,6 +19,7 @@
 #define DEFAULT_FONT_WIDTH 8
 #define DEFAULT_FONT_HEIGHT 16
 
+static size_t last_vga_font_bool = 0;
 static size_t vga_font_width;
 static size_t vga_font_height;
 static size_t glyph_width = 8;
@@ -662,93 +663,98 @@ bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height) {
     gterm_pitch       = fbinfo.framebuffer_pitch;
 
     vga_font_width = DEFAULT_FONT_WIDTH, vga_font_height = DEFAULT_FONT_HEIGHT;
+    size_t font_bytes = (vga_font_width * vga_font_height * VGA_FONT_GLYPHS) / 8;
 
-    size_t font_width = DEFAULT_FONT_WIDTH, font_height = DEFAULT_FONT_HEIGHT;
+    if (vga_font_bits == NULL) {
+        vga_font_bits = ext_mem_alloc(VGA_FONT_MAX);
+    }
+
+    memcpy(vga_font_bits, (void *)_binary_font_bin_start, VGA_FONT_MAX);
+
+    size_t tmp_font_width, tmp_font_height;
 
     char *menu_font_size = config_get_value(NULL, 0, "MENU_FONT_SIZE");
-    if (menu_font_size == NULL) {
+    if (menu_font_size == NULL)
         menu_font_size = config_get_value(NULL, 0, "TERMINAL_FONT_SIZE");
-    }
     if (menu_font_size != NULL) {
-        parse_resolution(&font_width, &font_height, NULL, menu_font_size);
-    }
-
-    size_t font_bytes = (font_width * font_height * VGA_FONT_GLYPHS) / 8;
-
-    if (vga_font_bits == NULL) {
-        vga_font_bits = ext_mem_alloc(VGA_FONT_MAX);
+        parse_resolution(&tmp_font_width, &tmp_font_height, NULL, menu_font_size);
 
-        memcpy(vga_font_bits, (void *)_binary_font_bin_start, VGA_FONT_MAX);
-    }
+        size_t tmp_font_bytes = (tmp_font_width * tmp_font_height * VGA_FONT_GLYPHS) / 8;
 
-    char *menu_font = NULL;
+        if (tmp_font_bytes > VGA_FONT_MAX) {
+            print("Font would be too large (%u bytes, %u bytes allowed). Not loading.\n", tmp_font_bytes, VGA_FONT_MAX);
+            goto no_load_font;
+        }
 
-    if (font_bytes > VGA_FONT_MAX) {
-        print("Font would be too large (%x bytes, %x bytes allowed). Not loading.\n", font_bytes, VGA_FONT_MAX);
-    } else {
-        menu_font = config_get_value(NULL, 0, "MENU_FONT");
-        if (menu_font == NULL)
-            menu_font = config_get_value(NULL, 0, "TERMINAL_FONT");
+        font_bytes = tmp_font_bytes;
     }
 
+    char *menu_font = config_get_value(NULL, 0, "MENU_FONT");
+    if (menu_font == NULL)
+        menu_font = config_get_value(NULL, 0, "TERMINAL_FONT");
     if (menu_font != NULL) {
         struct file_handle f;
         if (!uri_open(&f, menu_font)) {
             print("menu: Could not open font file.\n");
         } else {
             if (fread(&f, vga_font_bits, 0, font_bytes) == 0) {
-                vga_font_width = font_width;
-                vga_font_height = font_height;
+                if (menu_font_size != NULL) {
+                    vga_font_width = tmp_font_width;
+                    vga_font_height = tmp_font_height;
+                }
             }
         }
     }
 
+no_load_font:;
     size_t font_spacing = 1;
     char *font_spacing_str = config_get_value(NULL, 0, "MENU_FONT_SPACING");
-    if (font_spacing_str == NULL) {
+    if (font_spacing_str == NULL)
         font_spacing_str = config_get_value(NULL, 0, "TERMINAL_FONT_SPACING");
-    }
     if (font_spacing_str != NULL) {
         font_spacing = strtoui(font_spacing_str, NULL, 10);
     }
 
     vga_font_width += font_spacing;
 
-    // if not loaded (stage2) or custom font (stage3), load font
-    if (vga_font_bool == NULL || menu_font != NULL) {
-        vga_font_bool = ext_mem_alloc(VGA_FONT_GLYPHS * vga_font_height * vga_font_width * sizeof(bool));
-
-        size_t bitwidth = vga_font_width > 8 ? 8 : vga_font_width;
-        for (size_t i = 0; i < VGA_FONT_GLYPHS; i++) {
-            uint8_t *glyph = &vga_font_bits[i * vga_font_height];
-
-            for (size_t y = 0; y < vga_font_height; y++) {
-                // NOTE: the characters in VGA fonts are always one byte wide.
-                // 9 dot wide fonts have 8 dots and one empty column, except
-                // characters 0xC0-0xDF replicate column 9.
-                for (size_t x = 0; x < bitwidth; x++) {
-                    size_t offset = i * vga_font_height * vga_font_width + y * vga_font_width + x;
-
-                    if ((glyph[y] & (0x80 >> x))) {
-                        vga_font_bool[offset] = true;
-                    } else {
-                        vga_font_bool[offset] = false;
-                    }
+    size_t this_vga_font_bool = VGA_FONT_GLYPHS * vga_font_height * vga_font_width * sizeof(bool);
+    if (last_vga_font_bool < this_vga_font_bool) {
+        vga_font_bool = ext_mem_alloc(this_vga_font_bool);
+        last_vga_font_bool = this_vga_font_bool;
+    }
+
+    for (size_t i = 0; i < VGA_FONT_GLYPHS; i++) {
+        uint8_t *glyph = &vga_font_bits[i * vga_font_height];
+
+        for (size_t y = 0; y < vga_font_height; y++) {
+            // NOTE: the characters in VGA fonts are always one byte wide.
+            // 9 dot wide fonts have 8 dots and one empty column, except
+            // characters 0xC0-0xDF replicate column 9.
+            for (size_t x = 0; x < 8; x++) {
+                size_t offset = i * vga_font_height * vga_font_width + y * vga_font_width + x;
+
+                if ((glyph[y] & (0x80 >> x))) {
+                    vga_font_bool[offset] = true;
+                } else {
+                    vga_font_bool[offset] = false;
                 }
-                // fill columns above 8 like VGA Line Graphics Mode does
-                for (size_t x = 8; x < vga_font_width; x++) {
-                    size_t offset = i * vga_font_height * vga_font_width + y *  vga_font_width + x;
-
-                    if (i >= 0xC0 && i <= 0xDF) {
-                        vga_font_bool[offset] = (glyph[y] & 1);
-                    } else {
-                        vga_font_bool[offset] = false;
-                    }
+            }
+            // fill columns above 8 like VGA Line Graphics Mode does
+            for (size_t x = 8; x < vga_font_width; x++) {
+                size_t offset = i * vga_font_height * vga_font_width + y *  vga_font_width + x;
+
+                if (i >= 0xC0 && i <= 0xDF) {
+                    vga_font_bool[offset] = (glyph[y] & 1);
+                } else {
+                    vga_font_bool[offset] = false;
                 }
             }
         }
     }
 
+    vga_font_scale_x = 1;
+    vga_font_scale_y = 1;
+
     char *menu_font_scale = config_get_value(NULL, 0, "MENU_FONT_SCALE");
     if (menu_font_scale == NULL) {
         menu_font_scale = config_get_value(NULL, 0, "TERMINAL_FONT_SCALE");
@@ -759,10 +765,11 @@ bool gterm_init(size_t *_rows, size_t *_cols, size_t width, size_t height) {
             vga_font_scale_x = 1;
             vga_font_scale_y = 1;
         }
-        glyph_width = vga_font_width * vga_font_scale_x;
-        glyph_height = vga_font_height * vga_font_scale_y;
     }
 
+    glyph_width = vga_font_width * vga_font_scale_x;
+    glyph_height = vga_font_height * vga_font_scale_y;
+
     *_cols = cols = (gterm_width - margin * 2) / glyph_width;
     *_rows = rows = (gterm_height - margin * 2) / glyph_height;
 
tab: 248 wrap: offon