Font table compression

This commit is contained in:
Alex Voinea 2023-09-22 22:14:52 +02:00
parent 64e31fd7f4
commit 245a2852ac
4 changed files with 71 additions and 29 deletions

View File

@ -42,13 +42,25 @@ fontTable = [
def generateLineInTable(index, chars):
pixels = chars[index]["PIXELS"].split(',')
# Generate the rows binary data
rows = []
for i in range(8):
rows.append(0)
for j in range(5):
rows[i] |= (1 << (5 - j - 1)) if pixels[j * 8 + i] == "0" else 0
line = "{{"
for r in rows:
# compress the rows data
colByte = 0
compressedRows = []
for i in range(4):
rowByte = ((rows[i * 2 + 1] >> 1) & 0xF) | (((rows[i * 2 + 0] >> 1) & 0xF) << 4)
colByte |= (1 << i * 2 + 0) if (rows[i * 2 + 0] & 0x1) else 0
colByte |= (1 << i * 2 + 1) if (rows[i * 2 + 1] & 0x1) else 0
compressedRows.append(rowByte)
line = f"{{0x{colByte:02X}, {{"
for r in compressedRows:
line += f"0x{r:02X}, "
line += f"}}, '{fontTable[index].alternate}'}}, // '{fontTable[index].utf}', \\x{fontTable[index].default:02X}"
return line

View File

@ -1,18 +1,18 @@
{{0x00, 0x1F, 0x15, 0x11, 0x15, 0x1F, 0x00, 0x00, }, 'H'}, // '🄷', \x80
{{0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, }, '\xdf'}, // '°', \x81
{{0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x11, 0x0E, }, 'h'}, // '🌡', \x82
{{0x04, 0x0E, 0x1F, 0x04, 0x1C, 0x00, 0x00, 0x00, }, '^'}, // '⬏', \x83
{{0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0C, 0x00, }, '\xf3'}, // '🔃', \x84
{{0x00, 0x1C, 0x1F, 0x11, 0x11, 0x1F, 0x00, 0x00, }, '\xdb'}, // '🗀', \x85
{{0x00, 0x04, 0x12, 0x09, 0x12, 0x04, 0x00, 0x00, }, '>'}, // '»', \x86
{{0x00, 0x0E, 0x13, 0x15, 0x11, 0x0E, 0x00, 0x00, }, '\xe5'}, // '🕑', \x87
{{0x00, 0x00, 0x11, 0x0A, 0x04, 0x11, 0x0A, 0x04, }, '\x7e'}, // '⏬', \x88
{{0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00, }, '\x7e'}, // '✔', \x89
{{0x11, 0x0E, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, }, 'a'}, // 'ă', \x8A
{{0x04, 0x0A, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, }, 'a'}, // 'â', \x8B
{{0x04, 0x0A, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x0E, }, 'i'}, // 'î', \x8C
{{0x00, 0x0E, 0x10, 0x0E, 0x01, 0x1E, 0x04, 0x08, }, 's'}, // 'ș', \x8D
{{0x08, 0x1C, 0x08, 0x08, 0x09, 0x06, 0x04, 0x08, }, 't'}, // 'ț', \x8E
{{0x04, 0x0A, 0x00, 0x0E, 0x04, 0x04, 0x04, 0x0E, }, 'I'}, // 'Î', \x8F
{{0x0E, 0x11, 0x0C, 0x06, 0x11, 0x0E, 0x04, 0x08, }, 'S'}, // 'Ș', \x90
{{0x1F, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x08, }, 'T'}, // 'Ț', \x91
{0x3E, {0x0F, 0xA8, 0xAF, 0x00, }, 'H'}, // '🄷', \x80
{0x00, {0x69, 0x96, 0x00, 0x00, }, '\xdf'}, // '°', \x81
{0x60, {0x25, 0x55, 0x58, 0x87, }, 'h'}, // '🌡', \x82
{0x04, {0x27, 0xF2, 0xE0, 0x00, }, '^'}, // '⬏', \x83
{0x34, {0x03, 0xCC, 0x19, 0x60, }, '\xf3'}, // '🔃', \x84
{0x3C, {0x0E, 0xF8, 0x8F, 0x00, }, '\xdb'}, // '🗀', \x85
{0x08, {0x02, 0x94, 0x92, 0x00, }, '>'}, // '»', \x86
{0x1C, {0x07, 0x9A, 0x87, 0x00, }, '\xe5'}, // '🕑', \x87
{0x24, {0x00, 0x85, 0x28, 0x52, }, '\x7e'}, // '⏬', \x88
{0x06, {0x00, 0x1B, 0xE4, 0x00, }, '\x7e'}, // '✔', \x89
{0xF1, {0x87, 0x07, 0x07, 0x87, }, 'a'}, // 'ă', \x8A
{0xF0, {0x25, 0x07, 0x07, 0x87, }, 'a'}, // 'â', \x8B
{0x00, {0x25, 0x06, 0x22, 0x27, }, 'i'}, // 'î', \x8C
{0x10, {0x07, 0x87, 0x0F, 0x24, }, 's'}, // 'ș', \x8D
{0x10, {0x4E, 0x44, 0x43, 0x24, }, 't'}, // 'ț', \x8E
{0x00, {0x25, 0x07, 0x22, 0x27, }, 'I'}, // 'Î', \x8F
{0x12, {0x78, 0x63, 0x87, 0x24, }, 'S'}, // 'Ș', \x90
{0x01, {0xF2, 0x22, 0x20, 0x24, }, 'T'}, // 'Ț', \x91

View File

@ -376,13 +376,42 @@ void lcd_set_cursor_column(uint8_t col)
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void lcd_createChar_P(uint8_t location, const uint8_t* charmap)
void lcd_createChar_P(uint8_t location, const CustomCharacter *char_p)
{
location &= 0x7; // we only have 8 locations 0-7
lcd_command(LCD_SETCGRAMADDR | (location << 3));
for (uint8_t i = 0; i < 8; i++)
lcd_send(pgm_read_byte(&charmap[i]), HIGH);
lcd_command(LCD_SETDDRAMADDR | lcd_ddram_address); // no need for masking the address
uint8_t charmap[8];
uint8_t temp;
uint8_t colByte;
__asm__ __volatile__ (
// load colByte
"lpm %1, Z+" "\n\t"
// begin for loop
"ldi %0, 8" "\n\t"
"mov __zero_reg__, %0" "\n\t" // use zero_reg as loop counter
"forBegin_%=: " "\n\t"
"sbrs __zero_reg__, 0" "\n\t" // test LSB of counter. Fetch new data if counter is even
"lpm __tmp_reg__, Z+" "\n\t" // load next data byte from progmem, increment
"swap __tmp_reg__" "\n\t" // swap the nibbles
"mov %0, __tmp_reg__" "\n\t" // copy row data to temp
"andi %0, 0xF" "\n\t" // mask lower nibble
"ror %1" "\n\t" // consume LSB of colByte and push it to the carry
"rol %0" "\n\t" // insert the column LSB from carry
"st %a3+, %0" "\n\t" // push the generated row data to the output
// end for loop
"dec __zero_reg__" "\n\t"
"brne forBegin_%=" "\n\t"
: "=&d" (temp), "=&r" (colByte)
: "z" (char_p), "e" (charmap)
);
lcd_command(LCD_SETCGRAMADDR | (location << 3));
for (uint8_t i = 0; i < 8; i++) {
lcd_send(charmap[i], HIGH);
}
lcd_command(LCD_SETDDRAMADDR | lcd_ddram_address); // no need for masking the address
}
#ifdef VT100
@ -854,7 +883,7 @@ static void lcd_print_custom(uint8_t c) {
// try to find a slot where it could be placed
for (uint8_t i = 0; i < 8; i++) {
if (lcd_custom_characters[i] == 0x7F) { //found an empty slot. create a new custom character and send it
lcd_createChar_P(i, Font[c - 0x80].data);
lcd_createChar_P(i, &Font[c - 0x80]);
lcd_custom_characters[i] = c; // mark the custom character as used
#ifdef DEBUG_CUSTOM_CHARACTERS
printf_P(PSTR("created char %02x at slot %u\n"), c, i);

View File

@ -186,8 +186,9 @@ private:
#define LCD_STR_SOLID_BLOCK "\xFF" //from the default character set
struct CustomCharacter {
const uint8_t data[8];
const char alternate;
uint8_t colByte;
uint8_t rowData[4];
char alternate;
};
extern void lcd_frame_start();