joeylib2/examples/common/exampleFont.c
2026-10-19 15:46:47 -05:00

122 lines
5.1 KiB
C

// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
// See LICENSE.md for license information.
// SPDX-License-Identifier: MIT
//
// exampleFont.c - the examples' 5x7 font (exampleFont.h). Each glyph is seven
// rows, the left pixel in each row's top bit.
#include <string.h>
#include "exampleFont.h"
#define GLYPH_SPACE 0
#define GLYPH_DIGIT_BASE 1
#define GLYPH_ALPHA_BASE 11
#define GLYPH_PUNCT_BASE 37
#define GLYPH_UNKNOWN 52
#define GLYPH_TOP_BIT 0x80u
static uint8_t glyphIndex(char c);
// The punctuation the font draws, in the order of its glyphs from
// GLYPH_PUNCT_BASE.
static const char kPunctuation[] = ".,:!?-'\"/;=+_()";
static const uint8_t kGlyphs[][EXAMPLE_FONT_H] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0 space
{ 0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70 }, // 1 '0'
{ 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 2 '1'
{ 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8 }, // 3 '2'
{ 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70 }, // 4 '3'
{ 0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10 }, // 5 '4'
{ 0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70 }, // 6 '5'
{ 0x30, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70 }, // 7 '6'
{ 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40 }, // 8 '7'
{ 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70 }, // 9 '8'
{ 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60 }, // 10 '9'
{ 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88 }, // 11 'A'
{ 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0 }, // 12 'B'
{ 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70 }, // 13 'C'
{ 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0 }, // 14 'D'
{ 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8 }, // 15 'E'
{ 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80 }, // 16 'F'
{ 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x70 }, // 17 'G'
{ 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88 }, // 18 'H'
{ 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 19 'I'
{ 0x38, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60 }, // 20 'J'
{ 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88 }, // 21 'K'
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8 }, // 22 'L'
{ 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88 }, // 23 'M'
{ 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x88 }, // 24 'N'
{ 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 25 'O'
{ 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80 }, // 26 'P'
{ 0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68 }, // 27 'Q'
{ 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88 }, // 28 'R'
{ 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70 }, // 29 'S'
{ 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, // 30 'T'
{ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 31 'U'
{ 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20 }, // 32 'V'
{ 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xD8, 0x88 }, // 33 'W'
{ 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88 }, // 34 'X'
{ 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20 }, // 35 'Y'
{ 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8 }, // 36 'Z'
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 }, // 37 '.'
{ 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x40 }, // 38 ','
{ 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00 }, // 39 ':'
{ 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20 }, // 40 '!'
{ 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20 }, // 41 '?'
{ 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00 }, // 42 '-'
{ 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 43 '\''
{ 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 44 '"'
{ 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00 }, // 45 '/'
{ 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x40 }, // 46 ';'
{ 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00 }, // 47 '='
{ 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00 }, // 48 '+'
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8 }, // 49 '_'
{ 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10 }, // 50 '('
{ 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40 }, // 51 ')'
{ 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF8 } // 52 unknown box
};
// The glyph that draws c.
static uint8_t glyphIndex(char c) {
const char *punct;
if (c == ' ') {
return GLYPH_SPACE;
}
if (c >= '0' && c <= '9') {
return (uint8_t)(GLYPH_DIGIT_BASE + (c - '0'));
}
if (c >= 'A' && c <= 'Z') {
return (uint8_t)(GLYPH_ALPHA_BASE + (c - 'A'));
}
if (c >= 'a' && c <= 'z') {
return (uint8_t)(GLYPH_ALPHA_BASE + (c - 'a'));
}
punct = strchr(kPunctuation, c);
if (c != '\0' && punct != NULL) {
return (uint8_t)(GLYPH_PUNCT_BASE + (punct - kPunctuation));
}
return GLYPH_UNKNOWN;
}
void exampleFontDraw(jlSurfaceT *s, int16_t x, int16_t y, const char *text, uint8_t color) {
const uint8_t *glyph;
int16_t row;
int16_t col;
for (; *text != '\0' && x <= JL_SURFACE_WIDTH - EXAMPLE_FONT_W; text++) {
glyph = kGlyphs[glyphIndex(*text)];
for (row = 0; row < EXAMPLE_FONT_H; row++) {
for (col = 0; col < EXAMPLE_FONT_W; col++) {
if ((glyph[row] & (GLYPH_TOP_BIT >> col)) != 0u) {
jlDrawPixel(s, (int16_t)(x + col), (int16_t)(y + row), color);
}
}
}
x = (int16_t)(x + EXAMPLE_FONT_ADVANCE);
}
}