Commit 68ebc839 authored by Robey Pointer's avatar Robey Pointer
Browse files

add the bizcat font, and implement invert.

parent 3101cd6d
/* column data, little-endian (smallest bit on top) */
#include <stdint.h>
#include <avr/pgmspace.h>
const uint16_t bizcat_reform_font_data[1024] PROGMEM = {
0x03e0, 0x03e0, 0x1e3c, 0x1e3c, 0x180c, 0x180c, 0x180c, 0x180c,
0x03e0, 0x03e0, 0x1ffc, 0x1ffc, 0x180c, 0x180c, 0x180c, 0x180c,
0x03e0, 0x03e0, 0x1ffc, 0x1ffc, 0x1ffc, 0x180c, 0x180c, 0x180c,
0x03e0, 0x03e0, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x180c, 0x180c,
0x03e0, 0x03e0, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x180c,
0x03e0, 0x03e0, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, /* 5 */
0x180c, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ffc, 0x1ffc, 0x0000,
0x1ffc, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ffc, 0x1ffc, 0x0000,
0x1ffc, 0x1ffc, 0x180c, 0x180c, 0x180c, 0x1ffc, 0x1ffc, 0x0000,
0x1ffc, 0x1ffc, 0x1ffc, 0x180c, 0x180c, 0x1ffc, 0x1ffc, 0x0000,
0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x180c, 0x1ffc, 0x1ffc, 0x0000, /* 10 */
0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x1ffc, 0x0000,
0x03e0, 0x03e0, 0x1e3c, 0x1e3c, 0x180c, 0x180c, 0x180c, 0x1aec,
0x1aec, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ffc, 0x1ffc, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000, /* 15 */
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000, /* 20 */
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000, /* 25 */
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000, /* 30 */
0x7fff, 0x0815, 0x03c2, 0x0a55, 0x03c2, 0x0815, 0x7fff, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1bf8, 0x1bf8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x007c, 0x007c, 0x0000, 0x007c, 0x007c, 0x0000, 0x0000,
0x0660, 0x1ff8, 0x1ff8, 0x0660, 0x1ff8, 0x1ff8, 0x0660, 0x0000, /* 35 */
0x0ce0, 0x0df0, 0x3dbc, 0x3dbc, 0x0fb0, 0x0730, 0x0000, 0x0000,
0x0638, 0x0728, 0x03b8, 0x01c0, 0x0ee0, 0x0a70, 0x0e30, 0x0000,
0x0f70, 0x1ff8, 0x19d8, 0x1bf8, 0x0f70, 0x1f80, 0x1980, 0x0000,
0x0000, 0x0000, 0x0060, 0x007c, 0x003c, 0x0000, 0x0000, 0x0000,
0x0000, 0x07e0, 0x1ff8, 0x3c3c, 0x300c, 0x0000, 0x0000, 0x0000, /* 40 */
0x0000, 0x300c, 0x3c3c, 0x1ff8, 0x07e0, 0x0000, 0x0000, 0x0000,
0x0300, 0x1b60, 0x1fe0, 0x0780, 0x1fe0, 0x1b60, 0x0300, 0x0000,
0x0300, 0x0300, 0x1fe0, 0x1fe0, 0x0300, 0x0300, 0x0000, 0x0000,
0x0000, 0x0000, 0x6000, 0x7c00, 0x3c00, 0x0000, 0x0000, 0x0000,
0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0000, /* 45 */
0x0000, 0x0000, 0x0000, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000,
0x3000, 0x3c00, 0x0f00, 0x03c0, 0x00f0, 0x003c, 0x000c, 0x0000,
0x0ff0, 0x1ff8, 0x1b18, 0x1998, 0x18d8, 0x1ff8, 0x0ff0, 0x0000,
0x0000, 0x0060, 0x0030, 0x1ff8, 0x1ff8, 0x0000, 0x0000, 0x0000,
0x1c30, 0x1e38, 0x1f18, 0x1b98, 0x19d8, 0x18f8, 0x1870, 0x0000, /* 50 */
0x0c18, 0x1c18, 0x1898, 0x18d8, 0x19f8, 0x1fb8, 0x0f18, 0x0000,
0x0780, 0x07c0, 0x06e0, 0x0670, 0x1ff8, 0x1ff8, 0x0600, 0x0000,
0x0cf8, 0x1cf8, 0x18d8, 0x18d8, 0x18d8, 0x1fd8, 0x0f98, 0x0000,
0x0fe0, 0x1ff0, 0x19b8, 0x1998, 0x1998, 0x1f98, 0x0f00, 0x0000,
0x0018, 0x0018, 0x1e18, 0x1f98, 0x03d8, 0x00f8, 0x0078, 0x0000, /* 55 */
0x0f70, 0x1ff8, 0x1998, 0x1998, 0x1998, 0x1ff8, 0x0f70, 0x0000,
0x00f0, 0x19f8, 0x1998, 0x1998, 0x1d98, 0x0ff8, 0x07f0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0cc0, 0x0cc0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x6000, 0x7cc0, 0x3cc0, 0x0000, 0x0000, 0x0000,
0x0180, 0x03c0, 0x07e0, 0x0e70, 0x1c38, 0x1818, 0x0000, 0x0000, /* 60 */
0x0660, 0x0660, 0x0660, 0x0660, 0x0660, 0x0660, 0x0660, 0x0000,
0x1818, 0x1c38, 0x0e70, 0x07e0, 0x03c0, 0x0180, 0x0000, 0x0000,
0x0030, 0x0038, 0x1b18, 0x1b18, 0x0198, 0x01f8, 0x00f0, 0x0000,
0x0ff0, 0x1ff8, 0x1818, 0x1bd8, 0x1b98, 0x1bf8, 0x01f0, 0x0000,
0x1f00, 0x1fc0, 0x06f0, 0x0638, 0x06f0, 0x1fc0, 0x1f00, 0x0000, /* 65 */
0x1818, 0x1ff8, 0x1ff8, 0x1998, 0x1998, 0x1ff8, 0x0f70, 0x0000,
0x07e0, 0x0ff0, 0x1c38, 0x1818, 0x1818, 0x1c38, 0x0c30, 0x0000,
0x1ff8, 0x1ff8, 0x1818, 0x1818, 0x1c38, 0x0ff0, 0x03c0, 0x0000,
0x1ff8, 0x1ff8, 0x1998, 0x1998, 0x1998, 0x1998, 0x1818, 0x0000,
0x1ff8, 0x1ff8, 0x0198, 0x0198, 0x0198, 0x0198, 0x0018, 0x0000, /* 70 */
0x07e0, 0x0ff0, 0x1c38, 0x1998, 0x1998, 0x1fb8, 0x0fb0, 0x0000,
0x1ff8, 0x1ff8, 0x0180, 0x0180, 0x0180, 0x1ff8, 0x1ff8, 0x0000,
0x1818, 0x1818, 0x1ff8, 0x1ff8, 0x1818, 0x1818, 0x0000, 0x0000,
0x0c00, 0x1c00, 0x1800, 0x1800, 0x1c00, 0x0ff8, 0x07f8, 0x0000,
0x1ff8, 0x1ff8, 0x03c0, 0x07e0, 0x0e70, 0x1c38, 0x1818, 0x0000, /* 75 */
0x1ff8, 0x1ff8, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x0000,
0x1ff8, 0x1ff8, 0x00e0, 0x03c0, 0x00e0, 0x1ff8, 0x1ff8, 0x0000,
0x1ff8, 0x1ff8, 0x00e0, 0x03c0, 0x0700, 0x1ff8, 0x1ff8, 0x0000,
0x07e0, 0x0ff0, 0x1c38, 0x1818, 0x1c38, 0x0ff0, 0x07e0, 0x0000,
0x1ff8, 0x1ff8, 0x0198, 0x0198, 0x0198, 0x01f8, 0x00f0, 0x0000, /* 80 */
0x0ff0, 0x1ff8, 0x1818, 0x1b18, 0x0f18, 0x1ff8, 0x1bf0, 0x0000,
0x1ff8, 0x1ff8, 0x0398, 0x0798, 0x0f98, 0x1df8, 0x18f0, 0x0000,
0x0c70, 0x1cf8, 0x19d8, 0x1998, 0x1b98, 0x1f38, 0x0e30, 0x0000,
0x0018, 0x0018, 0x1ff8, 0x1ff8, 0x0018, 0x0018, 0x0000, 0x0000,
0x0ff8, 0x1ff8, 0x1800, 0x1800, 0x1800, 0x1ff8, 0x0ff8, 0x0000, /* 85 */
0x0078, 0x03f8, 0x1f80, 0x1c00, 0x1f80, 0x03f8, 0x0078, 0x0000,
0x03f8, 0x1ff8, 0x1e00, 0x07e0, 0x1e00, 0x1ff8, 0x03f8, 0x0000,
0x1818, 0x1e78, 0x07e0, 0x0180, 0x07e0, 0x1e78, 0x1818, 0x0000,
0x0038, 0x00f8, 0x1fc0, 0x1fc0, 0x00f8, 0x0038, 0x0000, 0x0000,
0x1c18, 0x1e18, 0x1b18, 0x1998, 0x18d8, 0x1878, 0x1838, 0x0000, /* 90 */
0x0000, 0x3ffc, 0x3ffc, 0x300c, 0x300c, 0x300c, 0x0000, 0x0000,
0x000c, 0x003c, 0x00f0, 0x03c0, 0x0f00, 0x3c00, 0x3000, 0x0000,
0x0000, 0x300c, 0x300c, 0x300c, 0x3ffc, 0x3ffc, 0x0000, 0x0000,
0x0060, 0x0070, 0x0038, 0x001c, 0x0038, 0x0070, 0x0060, 0x0000,
0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, /* 95 */
0x0000, 0x0000, 0x003c, 0x007c, 0x0060, 0x0000, 0x0000, 0x0000,
0x0e00, 0x1f40, 0x1b60, 0x1b60, 0x1b60, 0x1fe0, 0x1fc0, 0x0000,
0x1ffc, 0x1ffc, 0x0cc0, 0x1860, 0x1ce0, 0x0fc0, 0x0780, 0x0000,
0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x1860, 0x1ce0, 0x0cc0, 0x0000,
0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x0cc0, 0x1ffc, 0x1ffc, 0x0000, /* 100 */
0x0780, 0x0fc0, 0x1b60, 0x1b60, 0x1b60, 0x1bc0, 0x0380, 0x0000,
0x0060, 0x0060, 0x1ff8, 0x1ffc, 0x006c, 0x006c, 0x000c, 0x0000,
0x0780, 0xcfc0, 0xdce0, 0xd860, 0xecc0, 0x7fe0, 0x3fe0, 0x0000,
0x1ffc, 0x1ffc, 0x00c0, 0x0060, 0x0060, 0x1fe0, 0x1fc0, 0x0000,
0x0000, 0x0060, 0x0060, 0x1fec, 0x1fec, 0x0000, 0x0000, 0x0000, /* 105 */
0xc000, 0xc000, 0xc060, 0xe060, 0x7fec, 0x3fec, 0x0000, 0x0000,
0x1ffc, 0x1ffc, 0x0300, 0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x0000,
0x0000, 0x000c, 0x000c, 0x1ffc, 0x1ffc, 0x0000, 0x0000, 0x0000,
0x1fe0, 0x1fe0, 0x0060, 0x1fc0, 0x0060, 0x1fe0, 0x1fc0, 0x0000,
0x1fe0, 0x1fe0, 0x00c0, 0x0060, 0x0060, 0x1fe0, 0x1fc0, 0x0000, /* 110 */
0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x1ce0, 0x0fc0, 0x0780, 0x0000,
0xffe0, 0xffe0, 0x0cc0, 0x1860, 0x1ce0, 0x0fc0, 0x0780, 0x0000,
0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x0cc0, 0xffe0, 0xffe0, 0x0000,
0x1fe0, 0x1fe0, 0x00c0, 0x0060, 0x0060, 0x00e0, 0x00c0, 0x0000,
0x09c0, 0x1be0, 0x1b60, 0x1b60, 0x1b60, 0x1f60, 0x0e40, 0x0000, /* 115 */
0x0060, 0x0060, 0x0ffc, 0x1ffc, 0x1860, 0x1860, 0x1860, 0x0000,
0x0fe0, 0x1fe0, 0x1800, 0x1800, 0x0c00, 0x1fe0, 0x1fe0, 0x0000,
0x00e0, 0x03e0, 0x0f00, 0x1c00, 0x0f00, 0x03e0, 0x00e0, 0x0000,
0x07e0, 0x1fe0, 0x1c00, 0x0780, 0x1c00, 0x1fe0, 0x07e0, 0x0000,
0x1860, 0x1ce0, 0x0fc0, 0x0780, 0x0fc0, 0x1ce0, 0x1860, 0x0000, /* 120 */
0xc0e0, 0xc7e0, 0xef00, 0x7c00, 0x3f00, 0x07e0, 0x00e0, 0x0000,
0x1860, 0x1c60, 0x1e60, 0x1b60, 0x19e0, 0x18e0, 0x1860, 0x0000,
0x0180, 0x0180, 0x03c0, 0x1ff8, 0x3e7c, 0x300c, 0x300c, 0x0000,
0x0000, 0x0000, 0x3ffc, 0x3ffc, 0x0000, 0x0000, 0x0000, 0x0000,
0x300c, 0x300c, 0x3e7c, 0x1ff8, 0x03c0, 0x0180, 0x0180, 0x0000, /* 125 */
0x01c0, 0x01e0, 0x0060, 0x00c0, 0x0180, 0x01e0, 0x00e0, 0x0000,
0x1998, 0x1998, 0x0660, 0x0660, 0x1998, 0x1998, 0x0000, 0x0000,
};
......@@ -11,7 +11,10 @@
#include "text_display.h"
#include "oranj_reform.h"
const monospace_font_t font_oranj = {oranj_reform_font_data, 8, 6};
#include "bizcat_reform.h"
const monospace_font_t font_oranj = { oranj_reform_font_data, 8, 6 };
const monospace_font_t font_bizcat = { bizcat_reform_font_data, 16, 8 };
void text_display_init(text_display_t *display, const monospace_font_t *font) {
display->font = font;
......@@ -25,12 +28,29 @@ void text_display_clear(text_display_t *display) {
memset(display->invert, 0, sizeof(display->invert));
display->cursor = 0;
display->dirty = true;
display->inverting = false;
display->roll = 0;
}
void text_display_clear_line(text_display_t *display, uint8_t line) {
memset(display->cells + line * display->width, ' ', display->width);
for (int i = line * display->width; i < (line + 1) * display->width; i++) {
display->invert[i >> 3] &= ~(1 << (i & 7));
}
}
// scroll up one line.
void text_display_scroll(text_display_t *display) {
memmove(display->cells, display->cells + display->width, (display->height - 1) * display->width);
memset(display->cells + (display->height - 1) * display->width, ' ', display->width);
// this is a pain: scroll the invert bits too.
uint8_t bytes = display->width >> 3;
uint8_t bits = display->width & 7;
for (int i = 0; i < (display->width * (display->height - 1) + 7) >> 3; i++) {
display->invert[i] = (display->invert[i + bytes] >> bits) + (display->invert[i + bytes + 1] << (8 - bits));
}
text_display_clear_line(display, display->height - 1);
display->dirty = true;
}
......@@ -40,29 +60,54 @@ void text_display_putc(text_display_t *display, uint8_t c) {
text_display_scroll(display);
}
display->cells[display->cursor] = c;
uint8_t invert_bit = 1 << (display->cursor & 7);
display->invert[display->cursor >> 3] &= ~invert_bit;
display->invert[display->cursor >> 3] |= display->inverting ? invert_bit : 0;
display->cursor++;
display->dirty = true;
}
void text_display_write(text_display_t *display, const char *text) {
while (*text) {
if (*text == '\n') {
display->cursor = ((display->cursor / display->width) + 1) * display->width;
} else {
text_display_putc(display, *text);
void text_display_write_len(text_display_t *display, const char *text, int len) {
for (int i = 0; i < len; i++) {
switch (text[i]) {
case '\n':
display->cursor = ((display->cursor / display->width) + 1) * display->width;
break;
case 0x0c:
// clear
text_display_clear(display);
break;
case 0x0e:
// "shift out": invert
display->inverting = true;
break;
case 0x0f:
// "shift in": normal
display->inverting = false;
break;
default:
text_display_putc(display, text[i]);
}
text++;
}
}
void text_display_write(text_display_t *display, const char *text) {
text_display_write_len(display, text, strlen(text));
}
void text_display_move(text_display_t *display, uint8_t x, uint8_t y) {
display->cursor = display->width * y + x;
if (display->cursor >= display->width * display->height) display->cursor = 0;
}
void text_display_invert(text_display_t *display, bool invert) {
display->inverting = invert;
}
void text_display_flush(text_display_t *display) {
if (!display->dirty) return;
uint8_t x_offset = (DisplayWidth - display->width * display->font->width) / 2;
int stride = (display->font->height + 7) / 8;
oled_on();
oled_home();
......@@ -70,18 +115,33 @@ void text_display_flush(text_display_t *display) {
uint8_t cursor = 0;
for (uint8_t y = 0; y < display->height; y++) {
for (uint8_t pad = 0; pad < x_offset; pad++) oled_render(0);
for (uint8_t x = 0; x < display->width; x++) {
const uint8_t *glyph = display->font->glyphs + (display->cells[cursor] & 0x7f) * display->font->width;
for (uint8_t column = 0; column < display->font->width; column++) {
uint8_t data = pgm_read_byte(glyph + column);
if (display->invert[cursor >> 3] & (1 << (cursor & 7))) data = ~data;
oled_render(data);
if (y < display->roll) {
// skip row
for (uint8_t x = 0; x < DisplayWidth; x++) oled_render(0);
continue;
}
for (uint8_t row = 0; row < stride; row++) {
// back up if we're drawing the later row of a tall font
if (row > 0) cursor -= display->width;
for (uint8_t pad = 0; pad < x_offset; pad++) oled_render(0);
for (uint8_t x = 0; x < display->width; x++) {
int offset = (display->cells[cursor] & 0x7f) * display->font->width * stride;
for (uint8_t column = 0; column < display->font->width; column++) {
uint8_t pixels = pgm_read_byte((uint8_t *)display->font->glyphs + offset + column * stride + row);
if (display->invert[cursor >> 3] & (1 << (cursor & 7))) pixels = ~pixels;
oled_render(pixels);
}
cursor++;
}
cursor++;
}
for (uint8_t pad = 0; pad < x_offset; pad++) oled_render(0);
}
if (display->roll == 1 && display->font->height > 8) {
// skip row
for (uint8_t x = 0; x < DisplayWidth; x++) oled_render(0);
}
oled_finish_render();
display->dirty = false;
......
......@@ -20,7 +20,7 @@
* having LSB at the top. Width and height are in pixels.
*/
typedef struct {
const uint8_t *glyphs;
const void *glyphs;
uint8_t height;
uint8_t width;
} monospace_font_t;
......@@ -32,15 +32,21 @@ typedef struct {
uint8_t height;
uint8_t cursor;
uint8_t dirty;
uint8_t inverting;
uint8_t roll; // special mode for centering one line in large-font mode
const monospace_font_t *font;
} text_display_t;
extern const monospace_font_t font_oranj;
extern const monospace_font_t font_bizcat;
void text_display_init(text_display_t *display, const monospace_font_t *font);
void text_display_clear(text_display_t *display);
void text_display_clear_line(text_display_t *display, uint8_t line);
void text_display_scroll(text_display_t *display);
void text_display_putc(text_display_t *display, uint8_t c);
void text_display_write_len(text_display_t *display, const char *text, int len);
void text_display_write(text_display_t *display, const char *text);
void text_display_move(text_display_t *display, uint8_t x, uint8_t y);
void text_display_invert(text_display_t *display, bool invert);
void text_display_flush(text_display_t *display);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment