You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
toaster-oven-bluepill/Lib/ufb/Src/font.c

82 lines
2.1 KiB

2 years ago
#include "ufb/font.h"
#include "ufb/utf8.h"
#include "ufb/progmem.h"
#include <stdint.h>
union utf_lookup {
const char symbol[4];
/// symbol as uint, but not decoded - just for matching!
const uint32_t uint;
};
struct utf_glyph5x {
union utf_lookup utf;
font5x_bitmap_t graphic;
};
struct utf_glyph4x {
union utf_lookup utf;
font4x_bitmap_t graphic;
};
struct utf_glyph3x {
union utf_lookup utf;
font3x_bitmap_t graphic;
};
#include "font_35.inc.c"
#include "font_45.inc.c"
#include "font_57.inc.c"
#define ASCII_START 0x20
#define ASCII_END 0x7e
#define FONT_GETSYM_IMPL(rettype, symtype, fontname) \
const rettype *fontname##_getsym(const struct Utf8Char *ch) { \
const uint8_t byte0 = ch->bytes[0]; \
if (byte0 < ASCII_START) { \
goto fail; \
} \
if (byte0 <= ASCII_END) { \
return &fontname##_ascii[byte0 - ASCII_START]; \
} \
for (uint8_t i = 0; i < sizeof(fontname##_extra) / sizeof(fontname##_extra[0]); i++) { \
const struct symtype *sym = &fontname##_extra[i]; \
const uint32_t table_ch = pgm_read_dword(&sym->utf.uint); \
if (table_ch == ch->uint) { \
return &sym->graphic; \
} \
} \
fail: return &fontname ## _extra[0].graphic; \
}
FONT_GETSYM_IMPL(font5x_bitmap_t, utf_glyph5x, font57)
FONT_GETSYM_IMPL(font4x_bitmap_t, utf_glyph4x, font45)
FONT_GETSYM_IMPL(font3x_bitmap_t, utf_glyph3x, font35)
#if 0
const font5x_bitmap_t *font57_getsym(const struct Utf8Char *ch)
{
const uint8_t byte0 = ch->bytes[0];
if (byte0 < ASCII_START) {
goto fail;
}
if (byte0 <= ASCII_END) {
return &font57_ascii[byte0 - ASCII_START];
}
for (uint8_t i = 0; i < sizeof(font57_extra) / sizeof(font57_extra[0]); i++) {
const struct utf_glyph5x *sym = &font57_extra[i];
const uint32_t table_ch = pgm_read_dword(&sym->uint);
if (table_ch == ch->uint) {
return &sym->graphic;
}
}
fail:
return &font57_extra[0].graphic; // replacement character
}
#endif