src/font.c

changeset 66
8297afa1c29c
parent 65
9c44c55d327a
child 67
0b96fe6d6b5e
--- a/src/font.c	Thu Apr 18 22:53:55 2024 +0200
+++ b/src/font.c	Fri Apr 19 22:28:29 2024 +0200
@@ -29,6 +29,14 @@
 #include "ascension/context.h"
 #include "ascension/error.h"
 
+#include <assert.h>
+#include <cx/array_list.h>
+
+void asc_font(enum AscFontStyle style, int size) {
+    asc_context.active_font.style = style;
+    asc_context.active_font.size = size;
+}
+
 static char const *asc_font_filename(enum AscFontStyle style) {
     // TODO: do not assume we are running from the program dir
     switch (style) {
@@ -43,31 +51,49 @@
     }
 }
 
-void asc_font(enum AscFontStyle style, int size) {
-    for (unsigned int i = 0 ; i < asc_context.fonts_loaded ; i++) {
-        AscFont *font = &asc_context.fonts[i];
-        if (font->size == size && font->style == style) {
-            asc_context.active_font = i;
-            return;
+struct asc_font_cache_entry {
+    AscFont font;
+    TTF_Font *ttf;
+};
+
+static CxList *asc_font_cache;
+
+static void asc_font_unload(struct asc_font_cache_entry *entry) {
+    TTF_CloseFont(entry->ttf);
+    asc_dprintf("Closed font size %u, style %u", entry->font.size, entry->font.style);
+}
+
+void asc_font_cache_init(void) {
+    assert(asc_font_cache == NULL);
+    asc_font_cache = cxArrayListCreateSimple(
+            sizeof(struct asc_font_cache_entry), 16
+    );
+    asc_font_cache->simple_destructor = (cx_destructor_func) asc_font_unload;
+}
+
+void asc_font_cache_destroy(void) {
+    assert(asc_font_cache != NULL);
+    cxListDestroy(asc_font_cache);
+}
+
+
+TTF_Font *asc_font_load(AscFont font) {
+    CxIterator iter = cxListIterator(asc_font_cache);
+    cx_foreach(struct asc_font_cache_entry*, cache, iter) {
+        if (cache->font.style == font.style && cache->font.size == font.size) {
+            return cache->ttf;
         }
     }
 
-    if (asc_context.fonts_loaded == ASC_MAX_FONTS) {
-        asc_error("Too many fonts. Cannot load more until cache is repaired.");
-        asc_context.active_font = ASC_MAX_FONTS;
-        return;
-    }
-
-    unsigned int slot = asc_context.fonts_loaded++;
-    AscFont *font = &asc_context.fonts[slot];
-    font->size = size;
-    font->style = style;
-    font->ptr = TTF_OpenFont(asc_font_filename(style), size);
-    if (font->ptr == NULL) {
-        asc_context.fonts_loaded--;
+    struct asc_font_cache_entry entry;
+    entry.font = font;
+    entry.ttf = TTF_OpenFont(asc_font_filename(font.style), font.size);
+    if (entry.ttf == NULL) {
         asc_error(TTF_GetError());
+        return NULL;
     } else {
-        asc_dprintf("Loaded font size %u, style %u in slot %u", size, style, slot);
-        asc_context.active_font = slot;
+        cxListAdd(asc_font_cache, &entry);
+        asc_dprintf("Loaded font size %d, style %d from disk", font.size, font.style);
+        return entry.ttf;
     }
 }

mercurial