#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
#include <state.h>
#include <font.h>
static font_t *font_load(uint32_t, char *, unsigned int, unsigned int);
static font_t *font_new(void);
+static void font_append(state_t *, font_t *);
static void font_free(font_t *);
static ftable_t *ftable_init(const uint32_t *, int, font_t *);
static ftable_t *ftable_new(font_t *);
static void ftable_free(ftable_t *);
+static void ftable_append(state_t *, ftable_t *);
static void *font_glyph_new(state_t *, uint32_t);
font_free(font_t *font)
{
+ if (font == NULL) {
+#ifndef NDEBUG
+ (void)fprintf(stderr, "font_free(NULL)\n");
+#endif
+ return;
+ }
+
if (font->pixels != NULL)
free(font->pixels);
if (font->glyphs != NULL) {
free(font);
}
+static void
+font_append(state_t *st, font_t *f)
+{
+ font_t *n, *o;
+
+#ifndef NDEBUG
+ (void)fprintf(stderr, "font_append(%p)\n", f);
+#endif
+
+ f->next = NULL;
+ if (st->font == NULL) {
+ st->font = f;
+ return;
+ }
+
+ for (n = st->font; n != NULL; n = n->next)
+ o = n;
+ o->next = f;
+}
+
static ftable_t *
ftable_init(const uint32_t *c, int n, font_t *f)
{
ftable_free(ftable_t *t)
{
+ if (t == NULL) {
+#ifndef NDEBUG
+ (void)fprintf(stderr, "ftable_free(NULL)\n");
+#endif
+ return;
+ }
+
if (t->user && t->code != NULL) {
free(t->code);
t->code = NULL;
free(t);
}
+static void
+ftable_append(state_t *st, ftable_t *t)
+{
+ ftable_t *n, *o;
+
+#ifndef NDEBUG
+ (void)fprintf(stderr, "ftable_append(%p)\n", t);
+#endif
+
+ t->next = NULL;
+ if (st->ftable == NULL) {
+ st->ftable = t;
+ return;
+ }
+
+ for (n = st->ftable; n != NULL; n = n->next)
+ o = n;
+ o->next = t;
+}
+
/* We could use a slab allocator if we really needed performance allocating
* many new characters. Font loading is however not really performance
* criticial, so let's keep memory compact for locality and faster refresh.
state->font_user = font_new();
- state->ftable = ftable_init(latin2_characters,
- sizeof(latin2_characters) / sizeof(uint32_t), state->font_latin2);
- state->ftable->next = ftable_init(latin3_characters,
- sizeof(latin3_characters) / sizeof(uint32_t), state->font_latin3);
- state->ftable->next->next = ftable_init(latin4_characters,
- sizeof(latin4_characters) / sizeof(uint32_t), state->font_latin4);
- state->ftable->next->next->next = ftable_init(iso8859_14_characters,
+ state->ftable = NULL;
+ ftable_append(state, ftable_init(latin2_characters,
+ sizeof(latin2_characters) / sizeof(uint32_t), state->font_latin2));
+ ftable_append(state, ftable_init(latin3_characters,
+ sizeof(latin3_characters) / sizeof(uint32_t), state->font_latin3));
+ ftable_append(state, ftable_init(latin4_characters,
+ sizeof(latin4_characters) / sizeof(uint32_t), state->font_latin4));
+ ftable_append(state, ftable_init(iso8859_14_characters,
sizeof(iso8859_14_characters) / sizeof(uint32_t),
- state->font_iso8859_14);
- state->ftable->next->next->next->next = ftable_init(misc_characters,
- sizeof(misc_characters) / sizeof(uint32_t), state->font_misc);
+ state->font_iso8859_14));
+ ftable_append(state, ftable_init(misc_characters,
+ sizeof(misc_characters) / sizeof(uint32_t), state->font_misc));
state->ftable_user = ftable_new(state->font_user);
- state->ftable->next->next->next->next->next = state->ftable_user;
+ ftable_append(state, state->ftable_user);
/* Contiguous block sets */
- state->font = font_load(32, analogterm_ascii_9_bits,
- analogterm_ascii_9_width, analogterm_ascii_9_height);
- state->font->next = font_load(160, analogterm_latin_9_bits,
- analogterm_latin_9_width, analogterm_latin_9_height);
- state->font->next->next = font_load(9472, analogterm_graphics1_9_bits,
- analogterm_graphics1_9_width, analogterm_graphics1_9_height);
- state->font->next->next->next = font_load(129896,
- analogterm_graphics2_9_bits, analogterm_graphics2_9_width,
- analogterm_graphics2_9_height);
- state->font->next->next->next->next = font_load(130032,
- analogterm_graphics3_9_bits, analogterm_graphics3_9_width,
- analogterm_graphics3_9_height);
+ state->font = NULL;
+ font_append(state, font_load(32, analogterm_ascii_9_bits,
+ analogterm_ascii_9_width, analogterm_ascii_9_height));
+ font_append(state, font_load(160, analogterm_latin_9_bits,
+ analogterm_latin_9_width, analogterm_latin_9_height));
+ font_append(state, font_load(9472, analogterm_graphics1_9_bits,
+ analogterm_graphics1_9_width, analogterm_graphics1_9_height));
+ font_append(state, font_load(129896, analogterm_graphics2_9_bits,
+ analogterm_graphics2_9_width, analogterm_graphics2_9_height));
+ font_append(state, font_load(130032, analogterm_graphics3_9_bits,
+ analogterm_graphics3_9_width, analogterm_graphics3_9_height));
/*
* If font is not the default size, programmatically regenerate
map_reset();
}
+#define CLEANUP_NSIZE 64
+
void
font_cleanup(state_t *state)
{
+ void *ptrs[CLEANUP_NSIZE];
+ int nptrs = 0;
+ ftable_t *t;
+ font_t *f;
map_reset();
- ftable_free(state->ftable->next->next->next->next->next);
- state->ftable->next->next->next->next->next = NULL;
- state->ftable_user = NULL;
-
- ftable_free(state->ftable->next->next->next->next);
- state->ftable->next->next->next->next = NULL;
- ftable_free(state->ftable->next->next->next);
- state->ftable->next->next->next = NULL;
- ftable_free(state->ftable->next->next);
- state->ftable->next->next = NULL;
- ftable_free(state->ftable->next);
- state->ftable->next = NULL;
- ftable_free(state->ftable);
+ /* Collect ftables and free in reverse order */
+ for (nptrs = 0, t = state->ftable; t != NULL; t = t->next) {
+ if (nptrs == CLEANUP_NSIZE)
+ err(EXIT_FAILURE,
+ "font_cleanup() - increase CLEANUP_NSIZE");
+ ptrs[nptrs++] = t;
+ }
+ for (; nptrs > 0; nptrs--) {
+#ifndef NDEBUG
+ (void)fprintf(stderr, "ftable_free(%d, %p)\n",
+ nptrs, ptrs[nptrs - 1]);
+#endif
+ ftable_free(ptrs[nptrs - 1]);
+ }
+
state->ftable = NULL;
+ state->ftable_user = NULL; /* Was in above list */
+
+ /* Collect font structs and free in reverse order */
+ for (nptrs = 0, f = state->font; f != NULL; f = f->next) {
+ if (nptrs == CLEANUP_NSIZE)
+ err(EXIT_FAILURE,
+ "font_cleanup() - increase CLEANUP_NSIZE");
+ ptrs[nptrs++] = f;
+ }
+ for (; nptrs > 0; nptrs--) {
+#ifndef NDEBUG
+ (void)fprintf(stderr, "font_free(%d, %p)\n",
+ nptrs, ptrs[nptrs - 1]);
+#endif
+ font_free(ptrs[nptrs - 1]);
+ }
- state->font->next->next->next->next->next = NULL;
- font_free(state->font->next->next->next->next);
- state->font->next->next->next->next = NULL;
- font_free(state->font->next->next->next);
- state->font->next->next->next = NULL;
- font_free(state->font->next->next);
- state->font->next->next = NULL;
- font_free(state->font->next);
- state->font->next = NULL;
- font_free(state->font);
state->font = NULL;
+ /* Glyph-order sets not in list */
font_free(state->font_user);
state->font_user = NULL;
-
font_free(state->font_misc);
state->font_misc = NULL;
font_free(state->font_iso8859_14);