#include #include #include #include "../libleds.h" #include "chars.h" #include "space.xbm" #include "0.xbm" #include "1.xbm" #include "2.xbm" #include "3.xbm" #include "4.xbm" #include "5.xbm" #include "6.xbm" #include "7.xbm" #include "8.xbm" #include "9.xbm" static unsigned char *get_char_bits(char c) { switch (c) { case ' ': return cspace_bits; case '0': return c0_bits; case '1': return c1_bits; case '2': return c2_bits; case '3': return c3_bits; case '4': return c4_bits; case '5': return c5_bits; case '6': return c6_bits; case '7': return c7_bits; case '8': return c8_bits; case '9': return c9_bits; default: return NULL; } } static char is_active(unsigned char const *bits, unsigned int const i) { /* * The first led is in the top left corner. * After that it goes down the column, then up the next and so on. * * This means all columns with an even index count down. * Those with an odd index count up. * * * With a height of 8 the led numbers would look like this: * * 00 0F 10 1F 20 ... * 01 0E 11 1E 21 ... * 02 0D 12 1D ... * 03 0C 13 1C ... * 04 0B 14 1B ... * 05 0A 15 1A ... * 06 09 16 19 ... * 07 08 17 18 ... */ unsigned int const bytes_per_row = ceil(char_width / 8.0); unsigned int col = i / char_height; unsigned int row = i % char_height; if (col % 2) row = char_height - 1 - row; // calculate byte to access unsigned int byte = row * bytes_per_row; byte += col / 8; unsigned char data = bits[byte]; unsigned char mask = 1<<(col % 8); return data & mask; } static char leds_write_char(const struct led_color color, char c, struct led_color *buf) { unsigned char *bits = get_char_bits(c); if (bits == NULL) return 0; for (unsigned int i = 0; i < char_length; i++) { if (is_active(bits, i)) buf[i] = color; else buf[i] = (struct led_color){0, 0, 0}; } return 1; } struct led_color *leds_text(struct led_color const color, const char *text) { unsigned int const len = strlen(text); struct led_color *buf = calloc( sizeof(struct led_color), len * char_length ); for (unsigned int i = 0; i < len; i++) { if (!leds_write_char(color, text[i], buf + i*char_length)) { // Invalid char free(buf); return NULL; } } return buf; }