smeargle-gd/src/font.c

108 lines
2.4 KiB
C
Raw Normal View History

2023-11-27 21:38:00 +00:00
#include <toml.h>
#include "util.h"
#include "font.h"
2023-11-27 23:33:40 +00:00
font_t font_create(char *font_name, char *filename) {
2023-11-27 21:38:00 +00:00
FILE *fp;
font_t font;
2023-11-27 23:33:40 +00:00
char errbuf[200];
map_t *map;
2023-11-27 21:38:00 +00:00
2023-11-27 23:33:40 +00:00
printf("Processing %s...\n", font_name);
2023-11-27 21:38:00 +00:00
fp = fopen(filename, "r");
if (!fp) {
2023-11-27 23:33:40 +00:00
char str[200];
snprintf(str, 200, "can't open %s: ", filename);
error(str, strerror(errno));
2023-11-27 21:38:00 +00:00
}
2023-11-27 23:33:40 +00:00
toml_table_t *table = toml_parse_file(fp, errbuf, 200);
2023-11-27 21:38:00 +00:00
fclose(fp);
2023-11-27 23:33:40 +00:00
#define TOML_GET_KEY(var, key, func) toml_datum_t (var) = func(table, (key));\
2023-11-27 23:21:09 +00:00
if (!(var).ok) {\
2023-11-27 23:33:40 +00:00
char str[200];\
snprintf(str, 200, "key '%s' missing from", (key)); \
error(str, filename); \
2023-11-27 21:38:00 +00:00
}
TOML_GET_KEY(name, "name", toml_string_in)
TOML_GET_KEY(image_filename, "filename", toml_string_in)
TOML_GET_KEY(bpp, "bits_per_pixel", toml_int_in)
TOML_GET_KEY(width, "width", toml_int_in)
TOML_GET_KEY(height, "height", toml_int_in)
#undef TOML_GET_KEY
2023-11-27 23:33:40 +00:00
toml_table_t *mapping = toml_table_in(table, "map");
2023-11-27 21:38:00 +00:00
font.name = name.u.s;
font.image_filename = image_filename.u.s;
2023-11-27 23:33:40 +00:00
font.bits_per_pixel = bpp.u.i;
font.width = width.u.i;
font.height = height.u.i;
font.map_entries = map_create(mapping, &map);
2023-11-27 23:21:09 +00:00
font.map = map;
2023-11-27 21:38:00 +00:00
return font;
}
2023-11-27 23:21:09 +00:00
void font_destroy(font_t font) {
map_destroy(font.map);
free(font.name);
2023-11-27 23:33:40 +00:00
free(font.toml_filename);
2023-11-27 23:21:09 +00:00
}
2023-11-27 21:38:00 +00:00
unsigned int map_create(toml_table_t *table, map_t **map) {
map_t *node;
map_t *next;
unsigned int nodes;
map_t *root = malloc(sizeof(map_t*));
toml_array_t *space = toml_array_in(table, " ");
toml_datum_t spcidx = toml_int_at(space, 0);
toml_datum_t spcwid = toml_int_at(space, 1);
if (!spcidx.ok) {
2023-11-27 23:33:40 +00:00
error("missing or inappropriate index for glyph: ' '", "");
2023-11-27 21:38:00 +00:00
}
if (!spcwid.ok) {
2023-11-27 23:33:40 +00:00
error("missing or inappropriate index for glyph: ' '", "");
2023-11-27 21:38:00 +00:00
}
node = root;
for (nodes = 1; ; nodes++) {
2023-11-27 23:33:40 +00:00
const char *key = toml_key_in(table, nodes);
2023-11-27 21:38:00 +00:00
if (!key) break;
toml_array_t *val = toml_array_in(table, key);
toml_datum_t index = toml_int_at(val, 0);
toml_datum_t width = toml_int_at(val, 1);
if (!index.ok) {
error("missing or inappropriate index for glyph: ", key);
}
if (!width.ok) {
error("missing or inappropriate width for glyph: ", key);
}
next = malloc(sizeof(map_t *));
next->glyph = key;
next->index = index.u.i;
next->width = width.u.i;
node->next = next;
node = next;
}
2023-11-27 23:21:09 +00:00
node->next = NULL;
*map = root;
return nodes;
}
void map_destroy(map_t *map) {
map_t *node = map;
map_t *next;
while ((next = node->next) != NULL) {
free(node);
node = next;
}
2023-11-27 21:38:00 +00:00
}