src/font.c

changeset 66
8297afa1c29c
parent 65
9c44c55d327a
equal deleted inserted replaced
65:9c44c55d327a 66:8297afa1c29c
27 27
28 #include "ascension/ui/font.h" 28 #include "ascension/ui/font.h"
29 #include "ascension/context.h" 29 #include "ascension/context.h"
30 #include "ascension/error.h" 30 #include "ascension/error.h"
31 31
32 #include <assert.h>
33 #include <cx/array_list.h>
34
35 void asc_font(enum AscFontStyle style, int size) {
36 asc_context.active_font.style = style;
37 asc_context.active_font.size = size;
38 }
39
32 static char const *asc_font_filename(enum AscFontStyle style) { 40 static char const *asc_font_filename(enum AscFontStyle style) {
33 // TODO: do not assume we are running from the program dir 41 // TODO: do not assume we are running from the program dir
34 switch (style) { 42 switch (style) {
35 case ASC_FONT_REGULAR: 43 case ASC_FONT_REGULAR:
36 return "fonts/OpenSans-Regular.ttf"; 44 return "fonts/OpenSans-Regular.ttf";
41 case ASC_FONT_BOLD_ITALIC: 49 case ASC_FONT_BOLD_ITALIC:
42 return "fonts/OpenSans-BoldItalic.ttf"; 50 return "fonts/OpenSans-BoldItalic.ttf";
43 } 51 }
44 } 52 }
45 53
46 void asc_font(enum AscFontStyle style, int size) { 54 struct asc_font_cache_entry {
47 for (unsigned int i = 0 ; i < asc_context.fonts_loaded ; i++) { 55 AscFont font;
48 AscFont *font = &asc_context.fonts[i]; 56 TTF_Font *ttf;
49 if (font->size == size && font->style == style) { 57 };
50 asc_context.active_font = i; 58
51 return; 59 static CxList *asc_font_cache;
60
61 static void asc_font_unload(struct asc_font_cache_entry *entry) {
62 TTF_CloseFont(entry->ttf);
63 asc_dprintf("Closed font size %u, style %u", entry->font.size, entry->font.style);
64 }
65
66 void asc_font_cache_init(void) {
67 assert(asc_font_cache == NULL);
68 asc_font_cache = cxArrayListCreateSimple(
69 sizeof(struct asc_font_cache_entry), 16
70 );
71 asc_font_cache->simple_destructor = (cx_destructor_func) asc_font_unload;
72 }
73
74 void asc_font_cache_destroy(void) {
75 assert(asc_font_cache != NULL);
76 cxListDestroy(asc_font_cache);
77 }
78
79
80 TTF_Font *asc_font_load(AscFont font) {
81 CxIterator iter = cxListIterator(asc_font_cache);
82 cx_foreach(struct asc_font_cache_entry*, cache, iter) {
83 if (cache->font.style == font.style && cache->font.size == font.size) {
84 return cache->ttf;
52 } 85 }
53 } 86 }
54 87
55 if (asc_context.fonts_loaded == ASC_MAX_FONTS) { 88 struct asc_font_cache_entry entry;
56 asc_error("Too many fonts. Cannot load more until cache is repaired."); 89 entry.font = font;
57 asc_context.active_font = ASC_MAX_FONTS; 90 entry.ttf = TTF_OpenFont(asc_font_filename(font.style), font.size);
58 return; 91 if (entry.ttf == NULL) {
59 }
60
61 unsigned int slot = asc_context.fonts_loaded++;
62 AscFont *font = &asc_context.fonts[slot];
63 font->size = size;
64 font->style = style;
65 font->ptr = TTF_OpenFont(asc_font_filename(style), size);
66 if (font->ptr == NULL) {
67 asc_context.fonts_loaded--;
68 asc_error(TTF_GetError()); 92 asc_error(TTF_GetError());
93 return NULL;
69 } else { 94 } else {
70 asc_dprintf("Loaded font size %u, style %u in slot %u", size, style, slot); 95 cxListAdd(asc_font_cache, &entry);
71 asc_context.active_font = slot; 96 asc_dprintf("Loaded font size %d, style %d from disk", font.size, font.style);
97 return entry.ttf;
72 } 98 }
73 } 99 }

mercurial