// rendering characters in the framebuffer #include #include #include #include "internal/engine_internal.h" /* * each character has 8 rows * only the lower 4 bits of each byte are used */ static const uint8_t font[128][FONT_ROWS] = { [' '] = { 0, 0, 0, 0, 0, 0, 0 }, ['A'] = { 0x0E, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11 }, ['B'] = { 0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E }, ['C'] = { 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F }, ['D'] = { 0x1E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1E }, ['E'] = { 0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F }, ['F'] = { 0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10 }, ['G'] = { 0x0F, 0x10, 0x10, 0x17, 0x11, 0x11, 0x0F }, ['H'] = { 0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11 }, ['I'] = { 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F }, ['J'] = { 0x01, 0x01, 0x01, 0x01, 0x11, 0x11, 0x0E }, ['K'] = { 0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11 }, ['L'] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F }, ['M'] = { 0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11 }, ['N'] = { 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x11 }, ['O'] = { 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E }, ['P'] = { 0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10 }, ['Q'] = { 0x0E, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0D }, ['R'] = { 0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11 }, ['S'] = { 0x0F, 0x10, 0x10, 0x0E, 0x01, 0x01, 0x1E }, ['T'] = { 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }, ['U'] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E }, ['V'] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04 }, ['W'] = { 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0A }, ['X'] = { 0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11 }, ['Y'] = { 0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04 }, ['Z'] = { 0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F }, ['0'] = { 0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E }, ['1'] = { 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E }, ['2'] = { 0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F }, ['3'] = { 0x1E, 0x01, 0x01, 0x0E, 0x01, 0x01, 0x1E }, ['4'] = { 0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02 }, ['5'] = { 0x1F, 0x10, 0x10, 0x1E, 0x01, 0x01, 0x1E }, ['6'] = { 0x0E, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x0E }, ['7'] = { 0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08 }, ['8'] = { 0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E }, ['9'] = { 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x0E }, ['.'] = { 0, 0, 0, 0, 0, 0x0C, 0x0C }, [','] = { 0, 0, 0, 0, 0, 0x0C, 0x08 }, [':'] = { 0, 0x0C, 0x0C, 0, 0, 0x0C, 0x0C }, [';'] = { 0, 0x0C, 0x0C, 0, 0, 0x0C, 0x08 }, ['!'] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0, 0x04 }, ['?'] = { 0x0E, 0x11, 0x01, 0x02, 0x04, 0, 0x04 }, ['-'] = { 0, 0, 0, 0x1F, 0, 0, 0 }, ['_'] = { 0, 0, 0, 0, 0, 0, 0x1F }, ['+'] = { 0, 0x04, 0x04, 0x1F, 0x04, 0x04, 0 }, ['='] = { 0, 0x1F, 0, 0, 0x1F, 0, 0 }, ['/'] = { 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10 }, ['\\'] = { 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01 }, ['('] = { 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02 }, [')'] = { 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08 }, ['['] = { 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E }, [']'] = { 0x0E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E }, ['<'] = { 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02 }, ['>'] = { 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08 }, ['*'] = { 0, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0 }, ['#'] = { 0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A }, ['%'] = { 0x19, 0x19, 0x02, 0x04, 0x08, 0x13, 0x13 }, ['@'] = { 0x0E, 0x11, 0x17, 0x15, 0x17, 0x10, 0x0F } }; /** * put a char 'c' on 'x' and 'y' in the framebuffer * with a foreground color of 'color' */ void put_char( framebuffer_e framebuffer, char c, uint32_t x, uint32_t y, uint32_t size, uint32_t fg_color, uint32_t bg_color ) { // convert lowercase letters to uppercase if (c >= 'a' && c <= 'z') { c -= 'a' - 'A'; } // avoid indexing outside font[128] if ((unsigned char)c >= 128) { c = '?'; } for (uint32_t row = 0; row < FONT_ROWS; row++) { uint8_t bits = font[(unsigned char)c][row]; for (uint32_t col = 0; col < FONT_COLS; col++) { uint32_t color = bits & (1u << (FONT_COLS - 1 - col)) ? fg_color : bg_color; put_rect( framebuffer, x + col * size, y + row * size, size, size, color ); } } mark_dirty_rect(x, y, size, size); } void put_string( framebuffer_e framebuffer, const char *text, uint32_t x, uint32_t y, uint32_t size, uint32_t spacing, uint32_t line_spacing, uint32_t fg_color, uint32_t bg_color ) { uint32_t start_x = x; while (*text) { if (*text == '\n') { x = start_x; y += (FONT_ROWS + line_spacing) * size; } else { put_char(framebuffer, *text, x, y, size, fg_color, bg_color); x += (FONT_COLS + spacing) * size; } text++; } }