#include "aplos.h" static const uint8_t font_data[] = { #embed "../external/spleen/spleen-8x16.psfu" // #embed "../external/spleen/spleen-12x24.psfu" // #embed "../external/spleen/spleen-16x32.psfu" }; static uint32_t header_size; static uint32_t glyph_count; static uint32_t bytes_per_glyph; static uint32_t char_height; static uint32_t char_width; static void font_init_psf1(void); static void font_init_psf2(void); static const uint8_t *font_bitmap(char8_t *c); static uint64_t lookup_psf1(char8_t *); static uint64_t lookup_psf2(char8_t *); static uint64_t (*lookup)(char8_t *); void font_init(void) { if(read_uint16_le(font_data) == 0x0436) font_init_psf1(); else if(read_uint32_le(font_data) == 0x864AB572) font_init_psf2(); else halt(); } static void font_init_psf1(void) { header_size = 4; glyph_count = (font_data[2] & 1) ? 512 : 256; bytes_per_glyph = font_data[3]; char_height = bytes_per_glyph; char_width = 8; lookup = lookup_psf1; } static void font_init_psf2(void) { header_size = read_uint32_le(font_data+8); glyph_count = read_uint32_le(font_data+16); bytes_per_glyph = read_uint32_le(font_data+20); char_height = read_uint32_le(font_data+24); char_width = read_uint32_le(font_data+28); lookup = lookup_psf2; } void font_draw(char8_t *c, uint32_t row, uint32_t col, uint32_t bg, uint32_t fg) { uint32_t x0 = char_width * col; uint32_t y0 = char_height * row; const uint8_t *data = font_bitmap(c); data--; for(uint32_t y = 0; y < char_height; y++){ int shift = 0; for(uint32_t x = 0; x < char_width; x++){ if(shift == 0){ shift = 8; data++; } shift--; uint8_t val = *data; uint8_t mask = 1< UINT16_MAX) return 0; const uint8_t *p = font_data + header_size + glyph_count * bytes_per_glyph; while(p < &font_data[nelem(font_data)]){ uint16_t x = read_uint16_le(p); p += 2; if(x == 0xFFFF) offset++; else if(x == v) return offset; } return UINT64_MAX; } static uint64_t lookup_psf2(char8_t *c) { int char_len = utf8_char_length(c); uint64_t offset = 0; const uint8_t *p = font_data + header_size + glyph_count * bytes_per_glyph; while(p < &font_data[nelem(font_data)]){ if(*p == 0xFF){ offset++; p++; }else if(memcmp(p, c, char_len) == 0){ return offset; }else if(*p == 0xFE){ p++; }else{ p += utf8_char_length(p); } } return UINT64_MAX; }