This commit is contained in:
2023-02-22 01:31:05 +01:00
commit 8260fb60f8
151 changed files with 124509 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
#include "ufb/fb_7seg.h"
#include "ufb/progmem.h"
enum SevenSegBars {
T = 1, RT = 2, RB = 4, B = 8, LB = 16, LT = 32, M = 64
};
static const uint8_t PROGMEM seven[] = {
[0] = T | RT | RB | B | LB | LT,
[1] = RT | RB,
[2] = T | RT | M | LB | B,
[3] = T | RT | M | RB | B,
[4] = RT | RB | M | LT,
[5] = T | LT | M | RB | B,
[6] = T | LT | LB | B | RB | M,
[7] = T | RT | RB,
[8] = T | LT | RT | LB | RB | B | M,
[9] = T | LT | RT | RB | B | M,
};
fbpos_t fb_7seg_dig(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t digit, fbcolor_t color)
{
const uint8_t mask = digit > 9 ? 0 : pgm_read_byte(&seven[digit]);
const fbpos_t wi = w - th * 2;
const fbpos_t hi = (h - th * 3) / 2;
bool bcolor = !color; // changed for XOR
fb_rect(x + th,
y,
wi,
th, bcolor ^ (bool) (mask & T));
fb_rect(x + th,
y + th + hi,
wi,
th, bcolor ^ (bool) (mask & M));
fb_rect(x + th,
y + th * 2 + hi * 2,
wi,
th, bcolor ^ (bool) (mask & B));
fb_rect(x,
y + th,
th,
hi, bcolor ^ (bool) (mask & LT));
fb_rect(x + th + wi,
y + hi + th,
th,
hi, bcolor ^ (bool) (mask & LB));
fb_rect(x + th + wi,
y + th,
th,
hi, bcolor ^ (bool) (mask & RT));
fb_rect(x + th + wi,
y + th * 2 + hi,
th,
hi, bcolor ^ (bool) (mask & RB));
return w;
}
fbpos_t fb_7seg_period(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, fbcolor_t color)
{
const fbpos_t hi = (h - th * 3) / 2;
fb_rect(x, y + hi * 2 + th * 2, th, th, color);
return th;
}
+96
View File
@@ -0,0 +1,96 @@
/**
* TODO file description
*/
#include "ufb/fb_text.h"
#include "ufb/framebuffer.h"
#include "ufb/utf8.h"
#include "ufb/font.h"
void fb_text_P_or_RAM(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbcolor_t color, bool is_pgmem) {
struct Utf8Iterator iter;
Utf8Iterator_Init(&iter, text);
iter.is_progmem = is_pgmem;
struct Utf8Char uchar;
uint8_t symw;
uint8_t symh;
if (flags & FONT_4X5) {
symw = 4;
symh = 5;
} else if (flags & FONT_3X5) {
symw = 3;
symh = 5;
} else {
symw = 5;
symh = 7;
}
while ((uchar = Utf8Iterator_Next(&iter)).uint) {
const uint8_t *data;
if (flags & FONT_4X5) {
const font4x_bitmap_t *sym = font45_getsym(&uchar);
data = sym->data;
} else if (flags & FONT_3X5) {
const font3x_bitmap_t *sym = font35_getsym(&uchar);
data = sym->data;
} else{
const font5x_bitmap_t *sym = font57_getsym(&uchar);
data = sym->data;
}
if (0 == (flags & FONT_DOUBLE)) {
// no double, using normal format
#if IS_AVR
fb_bitmap_ex_P(x, y, symw, symh, data, color);
#else
fb_bitmap_ex(x, y, symw, symh, data, color);
#endif
if (flags & FONT_BOLD) {
x++;
#if IS_AVR
fb_bitmap_ex_P(x, y, symw, symh, data, color);
#else
fb_bitmap_ex(x, y, symw, symh, data, color);
#endif
x += symw+2;
} else {
x += symw+1;
}
} else {
// slow, pixel-by-pixel drawing
const uint8_t pxw = (flags & FONT_DOUBLEW) ? 2 : 1;
const uint8_t pxh = (flags & FONT_DOUBLEH) ? 2 : 1;
for(fbpos_t xx = 0; xx < symw; xx++) {
uint8_t column = pgm_read_byte(&data[xx]);
for(fbpos_t yy = 0; yy < symh; yy++) {
if (column & (1 << yy)) {
fb_rect(x + xx * pxw, y + yy * pxh, pxw, pxh, color);
if (flags & FONT_BOLD) {
fb_rect(x + (xx + 1) * pxw, y + yy * pxh, pxw, pxh, color);
}
}
}
}
if (flags & FONT_BOLD) {
x += (symw+2) * pxw;
} else {
x += (symw+1) * pxw;
}
}
}
}
void fb_text_P(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbcolor_t color)
{
fb_text_P_or_RAM(x, y, text, flags, color, true);
}
void fb_text(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbcolor_t color) {
fb_text_P_or_RAM(x, y, text, flags, color, false);
}
+81
View File
@@ -0,0 +1,81 @@
#include "ufb/font.h"
#include "ufb/utf8.h"
#include "ufb/progmem.h"
#include <stdint.h>
union utf_lookup {
const char symbol[4];
/// symbol as uint, but not decoded - just for matching!
const uint32_t uint;
};
struct utf_glyph5x {
union utf_lookup utf;
font5x_bitmap_t graphic;
};
struct utf_glyph4x {
union utf_lookup utf;
font4x_bitmap_t graphic;
};
struct utf_glyph3x {
union utf_lookup utf;
font3x_bitmap_t graphic;
};
#include "font_35.inc.c"
#include "font_45.inc.c"
#include "font_57.inc.c"
#define ASCII_START 0x20
#define ASCII_END 0x7e
#define FONT_GETSYM_IMPL(rettype, symtype, fontname) \
const rettype *fontname##_getsym(const struct Utf8Char *ch) { \
const uint8_t byte0 = ch->bytes[0]; \
if (byte0 < ASCII_START) { \
goto fail; \
} \
if (byte0 <= ASCII_END) { \
return &fontname##_ascii[byte0 - ASCII_START]; \
} \
for (uint8_t i = 0; i < sizeof(fontname##_extra) / sizeof(fontname##_extra[0]); i++) { \
const struct symtype *sym = &fontname##_extra[i]; \
const uint32_t table_ch = pgm_read_dword(&sym->utf.uint); \
if (table_ch == ch->uint) { \
return &sym->graphic; \
} \
} \
fail: return &fontname ## _extra[0].graphic; \
}
FONT_GETSYM_IMPL(font5x_bitmap_t, utf_glyph5x, font57)
FONT_GETSYM_IMPL(font4x_bitmap_t, utf_glyph4x, font45)
FONT_GETSYM_IMPL(font3x_bitmap_t, utf_glyph3x, font35)
#if 0
const font5x_bitmap_t *font57_getsym(const struct Utf8Char *ch)
{
const uint8_t byte0 = ch->bytes[0];
if (byte0 < ASCII_START) {
goto fail;
}
if (byte0 <= ASCII_END) {
return &font57_ascii[byte0 - ASCII_START];
}
for (uint8_t i = 0; i < sizeof(font57_extra) / sizeof(font57_extra[0]); i++) {
const struct utf_glyph5x *sym = &font57_extra[i];
const uint32_t table_ch = pgm_read_dword(&sym->uint);
if (table_ch == ch->uint) {
return &sym->graphic;
}
}
fail:
return &font57_extra[0].graphic; // replacement character
}
#endif
+102
View File
@@ -0,0 +1,102 @@
static const font3x_bitmap_t PROGMEM font35_ascii[] = {
{{0x00, 0x00, 0x00}},
{{0x00, 0x17, 0x00}},
{{0x03, 0x00, 0x03}},
{{0x0a, 0x1f, 0x0a}},
{{0x16, 0x1f, 0x1a}},
{{0x19, 0x04, 0x13}},
{{0x1d, 0x17, 0x19}},
{{0x00, 0x03, 0x00}},
{{0x0e, 0x11, 0x00}},
{{0x11, 0x0e, 0x00}},
{{0x05, 0x02, 0x05}},
{{0x04, 0x0e, 0x04}},
{{0x10, 0x08, 0x00}},
{{0x04, 0x04, 0x04}},
{{0x18, 0x18, 0x00}},
{{0x18, 0x04, 0x03}},
{{0x1f, 0x11, 0x1f}},
{{0x12, 0x1f, 0x10}},
{{0x1d, 0x15, 0x17}},
{{0x11, 0x15, 0x1f}},
{{0x07, 0x04, 0x1f}},
{{0x17, 0x15, 0x1d}},
{{0x1f, 0x15, 0x1d}},
{{0x03, 0x01, 0x1f}},
{{0x1f, 0x15, 0x1f}},
{{0x17, 0x15, 0x1f}},
{{0x00, 0x0a, 0x00}},
{{0x10, 0x0a, 0x00}},
{{0x04, 0x0a, 0x11}},
{{0x0a, 0x0a, 0x0a}},
{{0x11, 0x0a, 0x04}},
{{0x01, 0x15, 0x07}},
{{0x0f, 0x11, 0x17}},
{{0x1f, 0x05, 0x1f}},
{{0x1f, 0x15, 0x1e}},
{{0x1f, 0x11, 0x11}},
{{0x1f, 0x11, 0x0e}},
{{0x1f, 0x15, 0x11}},
{{0x1f, 0x05, 0x01}},
{{0x1f, 0x11, 0x1d}},
{{0x1f, 0x04, 0x1f}},
{{0x11, 0x1f, 0x11}},
{{0x19, 0x11, 0x1f}},
{{0x1f, 0x04, 0x1b}},
{{0x1f, 0x10, 0x10}},
{{0x1f, 0x03, 0x1f}},
{{0x1f, 0x01, 0x1e}},
{{0x1f, 0x11, 0x1f}},
{{0x1f, 0x05, 0x07}},
{{0x0f, 0x09, 0x1f}},
{{0x1f, 0x0d, 0x17}},
{{0x17, 0x15, 0x1d}},
{{0x01, 0x1f, 0x01}},
{{0x1f, 0x10, 0x1f}},
{{0x0f, 0x10, 0x0f}},
{{0x1f, 0x18, 0x1f}},
{{0x1b, 0x04, 0x1b}},
{{0x07, 0x1c, 0x07}},
{{0x19, 0x15, 0x13}},
{{0x00, 0x1f, 0x11}},
{{0x03, 0x04, 0x18}},
{{0x11, 0x1f, 0x00}},
{{0x02, 0x01, 0x02}},
{{0x10, 0x10, 0x10}},
{{0x01, 0x02, 0x00}},
{{0x1d, 0x15, 0x1e}},
{{0x1f, 0x14, 0x1c}},
{{0x1c, 0x14, 0x14}},
{{0x1c, 0x14, 0x1f}},
{{0x0f, 0x15, 0x17}},
{{0x04, 0x1f, 0x05}},
{{0x17, 0x15, 0x0f}},
{{0x1f, 0x04, 0x1c}},
{{0x14, 0x1d, 0x10}},
{{0x18, 0x10, 0x1d}},
{{0x1f, 0x08, 0x14}},
{{0x11, 0x1f, 0x10}},
{{0x1c, 0x0c, 0x1c}},
{{0x1c, 0x04, 0x18}},
{{0x1c, 0x14, 0x1c}},
{{0x1e, 0x0a, 0x0e}},
{{0x0e, 0x0a, 0x1e}},
{{0x1c, 0x04, 0x04}},
{{0x16, 0x16, 0x1a}},
{{0x02, 0x1f, 0x12}},
{{0x1e, 0x10, 0x1e}},
{{0x0e, 0x10, 0x0e}},
{{0x1c, 0x18, 0x1c}},
{{0x14, 0x08, 0x14}},
{{0x16, 0x14, 0x1e}},
{{0x1a, 0x16, 0x16}},
{{0x04, 0x0e, 0x11}},
{{0x00, 0x1f, 0x00}},
{{0x11, 0x0e, 0x04}},
{{0x04, 0x02, 0x06}},
};
static const struct utf_glyph3x PROGMEM font35_extra[] = {
{.utf={.symbol=""}, {{0x1f, 0x1f, 0x1f}}},
{.utf={.symbol="°"}, {{0x07, 0x05, 0x07}}},
};
+102
View File
@@ -0,0 +1,102 @@
static const font4x_bitmap_t PROGMEM font45_ascii[] = {
{{0x00, 0x00, 0x00, 0x00}},
{{0x00, 0x17, 0x17, 0x00}},
{{0x03, 0x00, 0x03, 0x00}},
{{0x0a, 0x1f, 0x0a, 0x1f}},
{{0x12, 0x1d, 0x17, 0x09}},
{{0x12, 0x08, 0x04, 0x12}},
{{0x1f, 0x15, 0x1f, 0x14}},
{{0x00, 0x03, 0x00, 0x00}},
{{0x00, 0x0e, 0x11, 0x00}},
{{0x00, 0x11, 0x0e, 0x00}},
{{0x05, 0x02, 0x02, 0x05}},
{{0x04, 0x0e, 0x04, 0x00}},
{{0x00, 0x10, 0x08, 0x00}},
{{0x00, 0x04, 0x04, 0x04}},
{{0x00, 0x18, 0x18, 0x00}},
{{0x10, 0x08, 0x04, 0x02}},
{{0x0e, 0x11, 0x11, 0x0e}},
{{0x04, 0x12, 0x1f, 0x10}},
{{0x12, 0x19, 0x15, 0x12}},
{{0x0a, 0x11, 0x15, 0x0a}},
{{0x07, 0x04, 0x1e, 0x04}},
{{0x17, 0x15, 0x15, 0x09}},
{{0x0e, 0x15, 0x15, 0x09}},
{{0x11, 0x09, 0x05, 0x03}},
{{0x0a, 0x15, 0x15, 0x0a}},
{{0x12, 0x15, 0x15, 0x0a}},
{{0x00, 0x00, 0x0a, 0x00}},
{{0x00, 0x10, 0x0a, 0x00}},
{{0x04, 0x0a, 0x11, 0x00}},
{{0x0a, 0x0a, 0x0a, 0x00}},
{{0x11, 0x0a, 0x04, 0x00}},
{{0x01, 0x01, 0x15, 0x02}},
{{0x1f, 0x11, 0x17, 0x16}},
{{0x1e, 0x05, 0x05, 0x1e}},
{{0x1f, 0x15, 0x15, 0x0a}},
{{0x0e, 0x11, 0x11, 0x0a}},
{{0x1f, 0x11, 0x11, 0x0e}},
{{0x1f, 0x15, 0x15, 0x11}},
{{0x1f, 0x05, 0x05, 0x01}},
{{0x0e, 0x11, 0x15, 0x0d}},
{{0x1f, 0x04, 0x04, 0x1f}},
{{0x00, 0x11, 0x1f, 0x11}},
{{0x09, 0x11, 0x11, 0x0f}},
{{0x1f, 0x04, 0x0a, 0x11}},
{{0x1f, 0x10, 0x10, 0x10}},
{{0x1f, 0x03, 0x01, 0x1f}},
{{0x1f, 0x02, 0x04, 0x1f}},
{{0x0e, 0x11, 0x11, 0x0e}},
{{0x1f, 0x05, 0x05, 0x02}},
{{0x0e, 0x11, 0x19, 0x1e}},
{{0x1f, 0x05, 0x0d, 0x12}},
{{0x12, 0x15, 0x15, 0x09}},
{{0x01, 0x1f, 0x01, 0x00}},
{{0x0f, 0x10, 0x10, 0x0f}},
{{0x07, 0x08, 0x10, 0x1f}},
{{0x1f, 0x08, 0x18, 0x1f}},
{{0x1b, 0x04, 0x0c, 0x13}},
{{0x03, 0x1c, 0x04, 0x03}},
{{0x19, 0x15, 0x15, 0x13}},
{{0x00, 0x1f, 0x11, 0x00}},
{{0x02, 0x04, 0x08, 0x10}},
{{0x00, 0x11, 0x1f, 0x00}},
{{0x02, 0x01, 0x02, 0x00}},
{{0x10, 0x10, 0x10, 0x10}},
{{0x00, 0x01, 0x02, 0x00}},
{{0x19, 0x15, 0x15, 0x1e}},
{{0x1f, 0x14, 0x14, 0x08}},
{{0x0c, 0x12, 0x12, 0x12}},
{{0x08, 0x14, 0x14, 0x1f}},
{{0x0e, 0x15, 0x15, 0x16}},
{{0x04, 0x1e, 0x05, 0x01}},
{{0x13, 0x15, 0x15, 0x0f}},
{{0x1f, 0x04, 0x04, 0x18}},
{{0x00, 0x14, 0x1d, 0x10}},
{{0x18, 0x10, 0x1d, 0x00}},
{{0x1f, 0x08, 0x14, 0x12}},
{{0x11, 0x1f, 0x10, 0x00}},
{{0x1e, 0x06, 0x06, 0x1e}},
{{0x1e, 0x02, 0x02, 0x1c}},
{{0x0c, 0x12, 0x12, 0x0c}},
{{0x1f, 0x05, 0x05, 0x02}},
{{0x02, 0x05, 0x05, 0x1f}},
{{0x1e, 0x04, 0x02, 0x06}},
{{0x10, 0x16, 0x1a, 0x02}},
{{0x02, 0x0f, 0x12, 0x10}},
{{0x0e, 0x10, 0x10, 0x1e}},
{{0x06, 0x08, 0x10, 0x0e}},
{{0x1e, 0x18, 0x18, 0x1e}},
{{0x12, 0x0c, 0x0c, 0x12}},
{{0x17, 0x14, 0x14, 0x0f}},
{{0x12, 0x1a, 0x16, 0x12}},
{{0x00, 0x04, 0x1f, 0x11}},
{{0x00, 0x00, 0x1f, 0x00}},
{{0x00, 0x11, 0x1f, 0x04}},
{{0x02, 0x04, 0x02, 0x04}},
};
static const struct utf_glyph4x PROGMEM font45_extra[] = {
{.utf={.symbol=""}, {{0x1f, 0x11, 0x11, 0x1f}}},
{.utf={.symbol="°"}, {{0x07, 0x05, 0x07, 0x00}}},
};
+116
View File
@@ -0,0 +1,116 @@
static const font5x_bitmap_t PROGMEM font57_ascii[] = {
{{0x00, 0x00, 0x00, 0x00, 0x00}},
{{0x00, 0x00, 0x5f, 0x00, 0x00}},
{{0x00, 0x07, 0x00, 0x07, 0x00}},
{{0x14, 0x7f, 0x14, 0x7f, 0x14}},
{{0x24, 0x2a, 0x7f, 0x2a, 0x12}},
{{0x23, 0x13, 0x08, 0x64, 0x62}},
{{0x36, 0x49, 0x55, 0x22, 0x50}},
{{0x00, 0x05, 0x03, 0x00, 0x00}},
{{0x00, 0x1c, 0x22, 0x41, 0x00}},
{{0x00, 0x41, 0x22, 0x1c, 0x00}},
{{0x14, 0x08, 0x3e, 0x08, 0x14}},
{{0x08, 0x08, 0x3e, 0x08, 0x08}},
{{0x00, 0x50, 0x30, 0x00, 0x00}},
{{0x08, 0x08, 0x08, 0x08, 0x08}},
{{0x00, 0x60, 0x60, 0x00, 0x00}},
{{0x20, 0x10, 0x08, 0x04, 0x02}},
{{0x3e, 0x51, 0x49, 0x45, 0x3e}},
{{0x00, 0x42, 0x7f, 0x40, 0x00}},
{{0x42, 0x61, 0x51, 0x49, 0x46}},
{{0x21, 0x41, 0x45, 0x4b, 0x31}},
{{0x18, 0x14, 0x12, 0x7f, 0x10}},
{{0x27, 0x45, 0x45, 0x45, 0x39}},
{{0x3c, 0x4a, 0x49, 0x49, 0x30}},
{{0x01, 0x71, 0x09, 0x05, 0x03}},
{{0x36, 0x49, 0x49, 0x49, 0x36}},
{{0x06, 0x49, 0x49, 0x29, 0x1e}},
{{0x00, 0x36, 0x36, 0x00, 0x00}},
{{0x00, 0x56, 0x36, 0x00, 0x00}},
{{0x08, 0x14, 0x22, 0x41, 0x00}},
{{0x14, 0x14, 0x14, 0x14, 0x14}},
{{0x00, 0x41, 0x22, 0x14, 0x08}},
{{0x02, 0x01, 0x51, 0x09, 0x06}},
{{0x32, 0x49, 0x79, 0x41, 0x3e}},
{{0x7e, 0x11, 0x11, 0x11, 0x7e}},
{{0x7f, 0x49, 0x49, 0x49, 0x36}},
{{0x3e, 0x41, 0x41, 0x41, 0x22}},
{{0x7f, 0x41, 0x41, 0x22, 0x1c}},
{{0x7f, 0x49, 0x49, 0x49, 0x41}},
{{0x7f, 0x09, 0x09, 0x09, 0x01}},
{{0x3e, 0x41, 0x49, 0x49, 0x7a}},
{{0x7f, 0x08, 0x08, 0x08, 0x7f}},
{{0x00, 0x41, 0x7f, 0x41, 0x00}},
{{0x20, 0x40, 0x41, 0x3f, 0x01}},
{{0x7f, 0x08, 0x14, 0x22, 0x41}},
{{0x7f, 0x40, 0x40, 0x40, 0x40}},
{{0x7f, 0x02, 0x0c, 0x02, 0x7f}},
{{0x7f, 0x04, 0x08, 0x10, 0x7f}},
{{0x3e, 0x41, 0x41, 0x41, 0x3e}},
{{0x7f, 0x09, 0x09, 0x09, 0x06}},
{{0x3e, 0x41, 0x51, 0x21, 0x5e}},
{{0x7f, 0x09, 0x19, 0x29, 0x46}},
{{0x46, 0x49, 0x49, 0x49, 0x31}},
{{0x01, 0x01, 0x7f, 0x01, 0x01}},
{{0x3f, 0x40, 0x40, 0x40, 0x3f}},
{{0x1f, 0x20, 0x40, 0x20, 0x1f}},
{{0x3f, 0x40, 0x38, 0x40, 0x3f}},
{{0x63, 0x14, 0x08, 0x14, 0x63}},
{{0x07, 0x08, 0x70, 0x08, 0x07}},
{{0x61, 0x51, 0x49, 0x45, 0x43}},
{{0x00, 0x7f, 0x41, 0x41, 0x00}},
{{0x02, 0x04, 0x08, 0x10, 0x20}},
{{0x00, 0x41, 0x41, 0x7f, 0x00}},
{{0x04, 0x02, 0x01, 0x02, 0x04}},
{{0x40, 0x40, 0x40, 0x40, 0x40}},
{{0x00, 0x01, 0x02, 0x04, 0x00}},
{{0x20, 0x54, 0x54, 0x54, 0x78}},
{{0x7f, 0x48, 0x44, 0x44, 0x38}},
{{0x38, 0x44, 0x44, 0x44, 0x20}},
{{0x38, 0x44, 0x44, 0x48, 0x7f}},
{{0x38, 0x54, 0x54, 0x54, 0x18}},
{{0x08, 0x7e, 0x09, 0x01, 0x02}},
{{0x0c, 0x52, 0x52, 0x52, 0x3e}},
{{0x7f, 0x08, 0x04, 0x04, 0x78}},
{{0x00, 0x44, 0x7d, 0x40, 0x00}},
{{0x20, 0x40, 0x44, 0x3d, 0x00}},
{{0x7f, 0x10, 0x28, 0x44, 0x00}},
{{0x00, 0x41, 0x7f, 0x40, 0x00}},
{{0x7c, 0x04, 0x18, 0x04, 0x78}},
{{0x7c, 0x08, 0x04, 0x04, 0x78}},
{{0x38, 0x44, 0x44, 0x44, 0x38}},
{{0x7c, 0x14, 0x14, 0x14, 0x08}},
{{0x08, 0x14, 0x14, 0x18, 0x7c}},
{{0x7c, 0x08, 0x04, 0x04, 0x08}},
{{0x48, 0x54, 0x54, 0x54, 0x20}},
{{0x04, 0x3f, 0x44, 0x40, 0x20}},
{{0x3c, 0x40, 0x40, 0x20, 0x7c}},
{{0x1c, 0x20, 0x40, 0x20, 0x1c}},
{{0x3c, 0x40, 0x30, 0x40, 0x3c}},
{{0x44, 0x28, 0x10, 0x28, 0x44}},
{{0x0c, 0x50, 0x50, 0x50, 0x3c}},
{{0x44, 0x64, 0x54, 0x4c, 0x44}},
{{0x00, 0x08, 0x36, 0x41, 0x00}},
{{0x00, 0x00, 0x7f, 0x00, 0x00}},
{{0x00, 0x41, 0x36, 0x08, 0x00}},
{{0x10, 0x08, 0x08, 0x10, 0x08}},
};
static const struct utf_glyph5x PROGMEM font57_extra[] = {
{.utf={.symbol=""}, {{0x7f, 0x41, 0x41, 0x41, 0x7f}}},
{.utf={.symbol="×"}, {{0x22, 0x14, 0x08, 0x14, 0x22}}},
{.utf={.symbol=""}, {{0x08, 0x04, 0x3e, 0x04, 0x08}}},
{.utf={.symbol=""}, {{0x08, 0x10, 0x3e, 0x10, 0x08}}},
{.utf={.symbol=""}, {{0x08, 0x1c, 0x2a, 0x08, 0x08}}},
{.utf={.symbol=""}, {{0x08, 0x08, 0x2a, 0x1c, 0x08}}},
{.utf={.symbol=""}, {{0x1c, 0x22, 0x2e, 0x2a, 0x1c}}},
{.utf={.symbol=""}, {{0x63, 0x55, 0x4d, 0x55, 0x63}}},
{.utf={.symbol=""}, {{0x1c, 0x22, 0x2a, 0x22, 0x1c}}},
{.utf={.symbol=""}, {{0x10, 0x38, 0x54, 0x10, 0x1e}}},
{.utf={.symbol="🌡"}, {{0x20, 0x7e, 0x79, 0x7e, 0x2a}}},
{.utf={.symbol="°"}, {{0x00, 0x07, 0x05, 0x07, 0x00}}},
{.utf={.symbol="μ"}, {{0x7c, 0x20, 0x20, 0x10, 0x3c}}},
{.utf={.symbol="🔙"}, {{0x04, 0x4e, 0x55, 0x44, 0x38}}},
{.utf={.symbol=""}, {{0x7f, 0x3e, 0x1c, 0x08, 0x00}}},
{.utf={.symbol=""}, {{0x00, 0x08, 0x1c, 0x3e, 0x7f}}},
};
+598
View File
@@ -0,0 +1,598 @@
#define FONT_W 3
#define FONT_H 5
const char* font_ascii[] = {
// 32 " "
" ",
" ",
" ",
" ",
" ",
// 33 "!"
" X ",
" X ",
" X ",
" ",
" X ",
// 34 """
"X X",
"X X",
" ",
" ",
" ",
// 35 "#"
" X ",
"XXX",
" X ",
"XXX",
" X ",
// 36 "$"
" X ",
"XXX",
"XX ",
" XX",
"XXX",
// 37 "%"
"X X",
" X",
" X ",
"X ",
"X x",
// 38 "&"
"xxx",
" x ",
"xx ",
"x x",
"xxx",
// 39 "'"
" x ",
" x ",
" ",
" ",
" ",
// 40 "("
" x ",
"x ",
"x ",
"x ",
" x ",
// 41 ")"
"x ",
" x ",
" x ",
" x ",
"x ",
// 42 "*"
"x x",
" x ",
"x x",
" ",
" ",
// 43 "+"
" ",
" x ",
"xxx",
" x ",
" ",
// 44 ","
" ",
" ",
" ",
" x ",
"x ",
// 45 "-"
" ",
" ",
"xxx",
" ",
" ",
// 46 "."
" ",
" ",
" ",
"xx ",
"xx ",
// 47 "/"
" x",
" x",
" x ",
"x ",
"x ",
// 48 "0"
"xxx",
"x x",
"x x",
"x x",
"xxx",
// 49 "1"
" x ",
"xx ",
" x ",
" x ",
"xxx",
// 50 "2"
"xxx",
" x",
"xxx",
"x ",
"xxx",
// 51 "3"
"xxx",
" x",
" xx",
" x",
"xxx",
// 52 "4"
"x x",
"x x",
"xxx",
" x",
" x",
// 53 "5"
"xxx",
"x ",
"xxx",
" x",
"xxx",
// 54 "6"
"xxx",
"x ",
"xxx",
"x x",
"xxx",
// 55 "7"
"xxx",
"x x",
" x",
" x",
" x",
// 56 "8"
"xxx",
"x x",
"xxx",
"x x",
"xxx",
// 57 "9"
"xxx",
"x x",
"xxx",
" x",
"xxx",
// 58 ":"
" ",
" x ",
" ",
" x ",
" ",
// 59 ";"
" ",
" x ",
" ",
" x ",
"x ",
// 60 "<"
" x",
" x ",
"x ",
" x ",
" x",
// 61 "="
" ",
"xxx",
" ",
"xxx",
" ",
// 62 ">"
"x ",
" x ",
" x",
" x ",
"x ",
// 63 "?"
"xxx",
" x",
" xx",
" ",
" x ",
// 64 "@"
"xxx",
"x x",
"x x",
"x ",
" xx",
// 65 "A"
"xxx",
"x x",
"xxx",
"x x",
"x x",
// 66 "B"
"xx ",
"x x",
"xxx",
"x x",
"xxx",
// 67 "C"
"xxx",
"x ",
"x ",
"x ",
"xxx",
// 68 "D"
"xx ",
"x x",
"x x",
"x x",
"xx ",
// 69 "E"
"xxx",
"x ",
"xx ",
"x ",
"xxx",
// 70 "F"
"xxx",
"x ",
"xx ",
"x ",
"x ",
// 71 "G"
"xxx",
"x ",
"x x",
"x x",
"xxx",
// 72 "H"
"x x",
"x x",
"xxx",
"x x",
"x x",
// 73 "I"
"xxx",
" x ",
" x ",
" x ",
"xxx",
// 74 "J"
"xxx",
" x",
" x",
"x x",
"xxx",
// 75 "K"
"x x",
"x x",
"xx ",
"x x",
"x x",
// 76 "L"
"x ",
"x ",
"x ",
"x ",
"xxx",
// 77 "M"
"xxx",
"xxx",
"x x",
"x x",
"x x",
// 78 "N"
"xx ",
"x x",
"x x",
"x x",
"x x",
// 79 "O"
"xxx",
"x x",
"x x",
"x x",
"xxx",
// 80 "P"
"xxx",
"x x",
"xxx",
"x ",
"x ",
// 81 "Q"
"xxx",
"x x",
"x x",
"xxx",
" x",
// 82 "R"
"xxx",
"x x",
"xxx",
"xx ",
"x x",
// 83 "S"
"xxx",
"x ",
"xxx",
" x",
"xxx",
// 84 "T"
"xxx",
" x ",
" x ",
" x ",
" x ",
// 85 "U"
"x x",
"x x",
"x x",
"x x",
"xxx",
// 86 "V"
"x x",
"x x",
"x x",
"x x",
" x ",
// 87 "W"
"x x",
"x x",
"x x",
"xxx",
"xxx",
// 88 "X"
"x x",
"x x",
" x ",
"x x",
"x x",
// 89 "Y"
"x x",
"x x",
"xxx",
" x ",
" x ",
// 90 "Z"
"xxx",
" x",
" x ",
"x ",
"xxx",
// 91 "["
" xx",
" x ",
" x ",
" x ",
" xx",
// 92 "\"
"x ",
"x ",
" x ",
" x",
" x",
// 93 "]"
"xx ",
" x ",
" x ",
" x ",
"xx ",
// 94 "^"
" x ",
"x x",
" ",
" ",
" ",
// 95 "_"
" ",
" ",
" ",
" ",
"xxx",
// 96 "`"
"x ",
" x ",
" ",
" ",
" ",
// 97 "a"
"xx ",
" x",
"xxx",
"x x",
"xxx",
// 98 "b"
"x ",
"x ",
"xxx",
"x x",
"xxx",
// 99 "c"
" ",
" ",
"xxx",
"x ",
"xxx",
// 100 "d"
" x",
" x",
"xxx",
"x x",
"xxx",
// 101 "e"
"xxx",
"x x",
"xxx",
"x ",
" xx",
// 102 "f"
" xx",
" x ",
"xxx",
" x ",
" x ",
// 103 "g"
"xxx",
"x x",
"xxx",
" x",
"xx ",
// 104 "h"
"x ",
"x ",
"xxx",
"x x",
"x x",
// 105 "i"
" x ",
" ",
"xx ",
" x ",
"xxx",
// 106 "j"
" x",
" ",
" x",
"x x",
"xxx",
// 107 "k"
"x ",
"x ",
"x x",
"xx ",
"x x",
// 108 "l"
"xx ",
" x ",
" x ",
" x ",
"xxx",
// 109 "m"
" ",
" ",
"xxx",
"xxx",
"x x",
// 110 "n"
" ",
" ",
"xx ",
"x x",
"x x",
// 111 "o"
" ",
" ",
"xxx",
"x x",
"xxx",
// 112 "p"
" ",
"xxx",
"x x",
"xxx",
"x ",
// 113 "q"
" ",
"xxx",
"x x",
"xxx",
" x",
// 114 "r"
" ",
" ",
"xxx",
"x ",
"x ",
// 115 "s"
" ",
"xxx",
"xx ",
" x",
"xxx",
// 116 "t"
" x ",
"xxx",
" x ",
" x ",
" xx",
// 117 "u"
" ",
"x z",
"x x",
"x x",
"xxx",
// 118 "v"
" ",
"x x",
"x x",
"x x",
" x ",
// 119 "w"
" ",
" ",
"x x",
"xxx",
"xxx",
// 120 "x"
" ",
" ",
"x x",
" x ",
"x x",
// 121 "y"
" ",
"x x",
"xxx",
" x",
"xxx",
// 122 "z"
" ",
"xxx",
" xx",
"x ",
"xxx",
// 123 "{"
" x",
" x ",
"xx ",
" x ",
" x",
// 124 "|"
" x ",
" x ",
" x ",
" x ",
" x ",
// 125 "}"
"x ",
" x ",
" xx",
" x ",
"x ",
// 126 "~"
" ",
" xx",
"x x",
" ",
" ",
};
const char *font_extras[] = {
// Extras
// Extra 0 "°"
"xxx",
"xxx",
"xxx",
"xxx",
"xxx",
// Extra 1 "°"
"xxx",
"x x",
"xxx",
" ",
" ",
};
const char *font_extras_utf[] = {
"",
"°",
};
#include "fontedit_render.inc.c"
+598
View File
@@ -0,0 +1,598 @@
#define FONT_W 4
#define FONT_H 5
const char *font_ascii[] = {
// 32 " "
" ",
" ",
" ",
" ",
" ",
// 33 "!"
" xx ",
" xx ",
" xx ",
" ",
" xx ",
// 34 """
"x x ",
"x x ",
" ",
" ",
" ",
// 35 "#"
" x x",
"xxxx",
" x x",
"xxxx",
" x x",
// 36 "$"
" xxx",
"x x ",
" xx ",
" x x",
"xxx ",
// 37 "%"
" ",
"x x",
" x ",
" x ",
"x x",
// 38 "&"
"xxx ",
"x x ",
"xxxx",
"x x ",
"xxxx",
// 39 "'"
" x ",
" x ",
" ",
" ",
" ",
// 40 "("
" x ",
" x ",
" x ",
" x ",
" x ",
// 41 ")"
" x ",
" x ",
" x ",
" x ",
" x ",
// 42 "*"
"x x",
" xx ",
"x x",
" ",
" ",
// 43 "+"
" ",
" x ",
"xxx ",
" x ",
" ",
// 44 ","
" ",
" ",
" ",
" x ",
" x ",
// 45 "-"
" ",
" ",
" ###",
" ",
" ",
// 46 "."
" ",
" ",
" ",
" ## ",
" ## ",
// 47 "/"
" ",
" x",
" x ",
" x ",
"x ",
// 48 "0"
" ## ",
"# #",
"# #",
"# #",
" ## ",
// 49 "1"
" # ",
" ## ",
"# # ",
" # ",
" ###",
// 50 "2"
" ## ",
"# #",
" # ",
" # ",
"####",
// 51 "3"
" ## ",
"# #",
" # ",
"# #",
" ## ",
// 52 "4"
"# ",
"# # ",
"####",
" # ",
" # ",
// 53 "5"
"####",
"# ",
"### ",
" #",
"### ",
// 54 "6"
" ###",
"# ",
"### ",
"# #",
" ## ",
// 55 "7"
"####",
" #",
" # ",
" # ",
"# ",
// 56 "8"
" ## ",
"# #",
" ## ",
"# #",
" ## ",
// 57 "9"
" ## ",
"# #",
" ## ",
" #",
"### ",
// 58 ":"
" ",
" x ",
" ",
" x ",
" ",
// 59 ";"
" ",
" x ",
" ",
" x ",
" x ",
// 60 "<"
" x ",
" x ",
"x ",
" x ",
" x ",
// 61 "="
" ",
"xxx ",
" ",
"xxx ",
" ",
// 62 ">"
"x ",
" x ",
" x ",
" x ",
"x ",
// 63 "?"
"xxx ",
" x",
" x ",
" ",
" x ",
// 64 "@"
"xxx ",
"x xx",
"x xx",
"x ",
"xxxx",
// 65 "A"
" xx ",
"x x",
"xxxx",
"x x",
"x x",
// 66 "B"
"xxx ",
"x x",
"xxx ",
"x x",
"xxx ",
// 67 "C"
" ## ",
"# #",
"# ",
"# #",
" ## ",
// 68 "D"
"xxx ",
"x x",
"x x",
"x x",
"xxx ",
// 69 "E"
"xxxx",
"x ",
"xxx ",
"x ",
"xxxx",
// 70 "F"
"xxxx",
"x ",
"xxx ",
"x ",
"x ",
// 71 "G"
" xxx",
"x ",
"x xx",
"x x",
" xx ",
// 72 "H"
"x x",
"x x",
"xxxx",
"x x",
"x x",
// 73 "I"
" xxx",
" x ",
" x ",
" x ",
" xxx",
// 74 "J"
"xxxx",
" x",
" x",
"x x",
" xx ",
// 75 "K"
"x x",
"x x ",
"xx ",
"x x ",
"x x",
// 76 "L"
"x ",
"x ",
"x ",
"x ",
"xxxx",
// 77 "M"
"#XX#",
"#X #",
"# #",
"# #",
"# #",
// 78 "N"
"x x",
"xx x",
"x xx",
"x x",
"x x",
// 79 "O"
" xx ",
"x x",
"x x",
"x x",
" xx ",
// 80 "P"
"### ",
"# #",
"### ",
"# ",
"# ",
// 81 "Q"
" xx ",
"x x",
"x x",
"x xx",
" xxx",
// 82 "R"
"xxx ",
"x x",
"xxx ",
"X x ",
"X x",
// 83 "S"
" xxx",
"x ",
" xx ",
" x",
"xxx ",
// 84 "T"
"xxx ",
" x ",
" x ",
" x ",
" x ",
// 85 "U"
"x x",
"x x",
"x x",
"x x",
" xx ",
// 86 "V"
"x x",
"x x",
"x x",
" x x",
" xx",
// 87 "W"
"x x",
"x x",
"x x",
"xxxx",
"x xx",
// 88 "X"
"x x",
"x x",
" xx ",
"x x ",
"x x",
// 89 "Y"
"x x",
"x x",
" xx ",
" x ",
" x ",
// 90 "Z"
"xxxx",
" x",
" xx ",
"x ",
"xxxx",
// 91 "["
" xx ",
" x ",
" x ",
" x ",
" xx ",
// 92 "\"
" ",
"x ",
" x ",
" x ",
" x",
// 93 "]"
" xx ",
" x ",
" x ",
" x ",
" xx ",
// 94 "^"
" x ",
"x x ",
" ",
" ",
" ",
// 95 "_"
" ",
" ",
" ",
" ",
"xxxx",
// 96 "`"
" x ",
" x ",
" ",
" ",
" ",
// 97 "a"
"xxx ",
" x",
" xxx",
"x x",
"xxxx",
// 98 "b"
"x ",
"x ",
"xxx ",
"x x",
"xxx ",
// 99 "c"
" ",
" xxx",
"x ",
"x ",
" xxx",
// 100 "d"
" x",
" x",
" xxx",
"x x",
" xxx",
// 101 "e"
" xx ",
"x x",
"xxxx",
"x ",
" xxx",
// 102 "f"
" xx",
" x ",
"xxx ",
" x ",
" x ",
// 103 "g"
"xxxx",
"x x",
" xxx",
" x",
"xxx ",
// 104 "h"
"x ",
"x ",
"xxx ",
"x x",
"x x",
// 105 "i"
" x ",
" ",
" xx ",
" x ",
" xxx",
// 106 "j"
" x ",
" ",
" x ",
"x x ",
"xxx ",
// 107 "k"
"x ",
"x x",
"x x ",
"xx ",
"x xx",
// 108 "l"
"xx ",
" x ",
" x ",
" x ",
"xxx ",
// 109 "m"
" ",
"xxxx",
"xxxx",
"x x",
"x x",
// 110 "n"
" ",
"xxx ",
"x x",
"x x",
"x x",
// 111 "o"
" ",
" xx ",
"x x",
"x x",
" xx ",
// 112 "p"
"xxx ",
"x x",
"xxx ",
"x ",
"x ",
// 113 "q"
" xxx",
"x x",
" xxx",
" x",
" x",
// 114 "r"
" ",
"x xx",
"xx x",
"x ",
"x ",
// 115 "s"
" ",
" xxx",
" x ",
" x ",
"xxx ",
// 116 "t"
" x ",
"xxx ",
" x ",
" x ",
" xx",
// 117 "u"
" ",
"x x",
"x x",
"x x",
" xxx",
// 118 "v"
" ",
"x x",
"x x",
" x x",
" x ",
// 119 "w"
" ",
"x x",
"x x",
"xxxx",
"xxxx",
// 120 "x"
" ",
"x x",
" xx ",
" xx ",
"x x",
// 121 "y"
"x x",
"x x",
"xxxx",
" x",
"xxx ",
// 122 "z"
" ",
"xxxx",
" x ",
" x ",
"xxxx",
// 123 "{"
" xx",
" x ",
" xx ",
" x ",
" xx",
// 124 "|"
" x ",
" x ",
" x ",
" x ",
" x ",
// 125 "}"
" xx ",
" x ",
" xx",
" x ",
" xx ",
// 126 "~"
" ",
"x x ",
" x x",
" ",
" ",
};
const char *font_extras[] = {
// Extra 0 - unknown symbol
"####",
"# #",
"# #",
"# #",
"####",
// Extra 1 "°"
"xxx ",
"# # ",
"xxx ",
" ",
" ",
};
const char *font_extras_utf[] = {
"",
"°",
};
#include "fontedit_render.inc.c"
+919
View File
@@ -0,0 +1,919 @@
#define FONT_W 5
#define FONT_H 7
const char *font_ascii[] = {
// 32 " "
" ",
" ",
" ",
" ",
" ",
" ",
" ",
// 33 "!"
" # ",
" # ",
" # ",
" # ",
" # ",
" ",
" # ",
// 34 """
" # # ",
" # # ",
" # # ",
" ",
" ",
" ",
" ",
// 35 "#"
" # # ",
" # # ",
"#####",
" # # ",
"#####",
" # # ",
" # # ",
// 36 "$"
" # ",
" ####",
"# # ",
" ### ",
" # #",
"#### ",
" # ",
// 37 "%"
"## ",
"## #",
" # ",
" # ",
" # ",
"# ##",
" ##",
// 38 "&"
" ## ",
"# # ",
"# # ",
" # ",
"# # #",
"# # ",
" ## #",
// 39 "'"
" ## ",
" # ",
" # ",
" ",
" ",
" ",
" ",
// 40 "("
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 41 ")"
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 42 "*"
" ",
" # ",
"# # #",
" ### ",
"# # #",
" # ",
" ",
// 43 "+"
" ",
" # ",
" # ",
"#####",
" # ",
" # ",
" ",
// 44 ","
" ",
" ",
" ",
" ",
" ## ",
" # ",
" # ",
// 45 "-"
" ",
" ",
" ",
"#####",
" ",
" ",
" ",
// 46 "."
" ",
" ",
" ",
" ",
" ",
" ## ",
" ## ",
// 47 "/"
" ",
" #",
" # ",
" # ",
" # ",
"# ",
" ",
// 48 "0"
" ### ",
"# #",
"# ##",
"# # #",
"## #",
"# #",
" ### ",
// 49 "1"
" # ",
" ## ",
" # ",
" # ",
" # ",
" # ",
" ### ",
// 50 "2"
" ### ",
"# #",
" #",
" # ",
" # ",
" # ",
"#####",
// 51 "3"
"#####",
" # ",
" # ",
" # ",
" #",
"# #",
" ### ",
// 52 "4"
" # ",
" ## ",
" # # ",
"# # ",
"#####",
" # ",
" # ",
// 53 "5"
"#####",
"# ",
"#### ",
" #",
" #",
"# #",
" ### ",
// 54 "6"
" ## ",
" # ",
"# ",
"#### ",
"# #",
"# #",
" ### ",
// 55 "7"
"#####",
" #",
" # ",
" # ",
" # ",
" # ",
" # ",
// 56 "8"
" ### ",
"# #",
"# #",
" ### ",
"# #",
"# #",
" ### ",
// 57 "9"
" ### ",
"# #",
"# #",
" ####",
" #",
" # ",
" ## ",
// 58 ":"
" ",
" ## ",
" ## ",
" ",
" ## ",
" ## ",
" ",
// 59 ";"
" ",
" ## ",
" ## ",
" ",
" ## ",
" # ",
" # ",
// 60 "<"
" # ",
" # ",
" # ",
"# ",
" # ",
" # ",
" # ",
// 61 "="
" ",
" ",
"#####",
" ",
"#####",
" ",
" ",
// 62 ">"
" # ",
" # ",
" # ",
" #",
" # ",
" # ",
" # ",
// 63 "?"
" ### ",
"# #",
" #",
" # ",
" # ",
" ",
" # ",
// 64 "@"
" ### ",
"# #",
" #",
" ## #",
"# # #",
"# # #",
" ### ",
// 65 "A"
" ### ",
"# #",
"# #",
"# #",
"#####",
"# #",
"# #",
// 66 "B"
"#### ",
"# #",
"# #",
"#### ",
"# #",
"# #",
"#### ",
// 67 "C"
" ### ",
"# #",
"# ",
"# ",
"# ",
"# #",
" ### ",
// 68 "D"
"### ",
"# # ",
"# #",
"# #",
"# #",
"# # ",
"### ",
// 69 "E"
"#####",
"# ",
"# ",
"#### ",
"# ",
"# ",
"#####",
// 70 "F"
"#####",
"# ",
"# ",
"#### ",
"# ",
"# ",
"# ",
// 71 "G"
" ### ",
"# #",
"# ",
"# ###",
"# #",
"# #",
" ####",
// 72 "H"
"# #",
"# #",
"# #",
"#####",
"# #",
"# #",
"# #",
// 73 "I"
" ### ",
" # ",
" # ",
" # ",
" # ",
" # ",
" ### ",
// 74 "J"
" ###",
" # ",
" # ",
" # ",
" # ",
"# # ",
" ## ",
// 75 "K"
"# #",
"# # ",
"# # ",
"## ",
"# # ",
"# # ",
"# #",
// 76 "L"
"# ",
"# ",
"# ",
"# ",
"# ",
"# ",
"#####",
// 77 "M"
"# #",
"## ##",
"# # #",
"# # #",
"# #",
"# #",
"# #",
// 78 "N"
"# #",
"# #",
"## #",
"# # #",
"# ##",
"# #",
"# #",
// 79 "O"
" ### ",
"# #",
"# #",
"# #",
"# #",
"# #",
" ### ",
// 80 "P"
"#### ",
"# #",
"# #",
"#### ",
"# ",
"# ",
"# ",
// 81 "Q"
" ### ",
"# #",
"# #",
"# #",
"# # #",
"# # ",
" ## #",
// 82 "R"
"#### ",
"# #",
"# #",
"#### ",
"# # ",
"# # ",
"# #",
// 83 "S"
" ####",
"# ",
"# ",
" ### ",
" #",
" #",
"#### ",
// 84 "T"
"#####",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 85 "U"
"# #",
"# #",
"# #",
"# #",
"# #",
"# #",
" ### ",
// 86 "V"
"# #",
"# #",
"# #",
"# #",
"# #",
" # # ",
" # ",
// 87 "W"
"# #",
"# #",
"# #",
"# # #",
"# # #",
"# # #",
" # # ",
// 88 "X"
"# #",
"# #",
" # # ",
" # ",
" # # ",
"# #",
"# #",
// 89 "Y"
"# #",
"# #",
"# #",
" # # ",
" # ",
" # ",
" # ",
// 90 "Z"
"#####",
" #",
" # ",
" # ",
" # ",
"# ",
"#####",
// 91 "["
" ### ",
" # ",
" # ",
" # ",
" # ",
" # ",
" ### ",
// 92 "\"
" ",
"# ",
" # ",
" # ",
" # ",
" #",
" ",
// 93 "]"
" ### ",
" # ",
" # ",
" # ",
" # ",
" # ",
" ### ",
// 94 "^"
" # ",
" # # ",
"# #",
" ",
" ",
" ",
" ",
// 95 "_"
" ",
" ",
" ",
" ",
" ",
" ",
"#####",
// 96 "`"
" # ",
" # ",
" # ",
" ",
" ",
" ",
" ",
// 97 "a"
" ",
" ",
" ### ",
" #",
" ####",
"# #",
" ####",
// 98 "b"
"# ",
"# ",
"# ## ",
"## #",
"# #",
"# #",
"#### ",
// 99 "c"
" ",
" ",
" ### ",
"# ",
"# ",
"# #",
" ### ",
// 100 "d"
" #",
" #",
" ## #",
"# ##",
"# #",
"# #",
" ####",
// 101 "e"
" ",
" ",
" ### ",
"# #",
"#####",
"# ",
" ### ",
// 102 "f"
" ## ",
" # #",
" # ",
"### ",
" # ",
" # ",
" # ",
// 103 "g"
" ",
" ####",
"# #",
"# #",
" ####",
" #",
" ### ",
// 104 "h"
"# ",
"# ",
"# ## ",
"## #",
"# #",
"# #",
"# #",
// 105 "i"
" # ",
" ",
" ## ",
" # ",
" # ",
" # ",
" ### ",
// 106 "j"
" # ",
" ",
" ## ",
" # ",
" # ",
"# # ",
" ## ",
// 107 "k"
"# ",
"# ",
"# # ",
"# # ",
"## ",
"# # ",
"# # ",
// 108 "l"
" ## ",
" # ",
" # ",
" # ",
" # ",
" # ",
" ### ",
// 109 "m"
" ",
" ",
"## # ",
"# # #",
"# # #",
"# #",
"# #",
// 110 "n"
" ",
" ",
"# ## ",
"## #",
"# #",
"# #",
"# #",
// 111 "o"
" ",
" ",
" ### ",
"# #",
"# #",
"# #",
" ### ",
// 112 "p"
" ",
" ",
"#### ",
"# #",
"#### ",
"# ",
"# ",
// 113 "q"
" ",
" ",
" ## #",
"# ##",
" ####",
" #",
" #",
// 114 "r"
" ",
" ",
"# ## ",
"## #",
"# ",
"# ",
"# ",
// 115 "s"
" ",
" ",
" ### ",
"# ",
" ### ",
" #",
"#### ",
// 116 "t"
" # ",
" # ",
"### ",
" # ",
" # ",
" # #",
" ## ",
// 117 "u"
" ",
" ",
"# #",
"# #",
"# #",
"# ##",
" ## #",
// 118 "v"
" ",
" ",
"# #",
"# #",
"# #",
" # # ",
" # ",
// 119 "w"
" ",
" ",
"# #",
"# #",
"# # #",
"# # #",
" # # ",
// 120 "x"
" ",
" ",
"# #",
" # # ",
" # ",
" # # ",
"# #",
// 121 "y"
" ",
" ",
"# #",
"# #",
" ####",
" #",
" ### ",
// 122 "z"
" ",
" ",
"#####",
" # ",
" # ",
" # ",
"#####",
// 123 "{"
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 124 "|"
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 125 "}"
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
" # ",
// 126 "~"
" ",
" ",
" ",
" ## #",
"# # ",
" ",
" ",
};
const char *font_extras[] = {
// Extras
// Extra 0
"#####",
"# #",
"# #",
"# #",
"# #",
"# #",
"#####",
// Extra 1
" ",
"# #",
" # # ",
" # ",
" # # ",
"# #",
" ",
// Extra 2
" ",
" # ",
" ### ",
"# # #",
" # ",
" # ",
" ",
// Extra 3
" ",
" # ",
" # ",
"# # #",
" ### ",
" # ",
" ",
// Extra 4
" ",
" # ",
" # ",
"#####",
" # ",
" # ",
" ",
// Extra 5
" ",
" # ",
" # ",
"#####",
" # ",
" # ",
" ",
// Extra 6
" ",
" ### ",
"# # #",
"# ###",
"# #",
" ### ",
" ",
// Extra 7
"#####",
"# #",
" ### ",
" # ",
" # # ",
"# #",
"#####",
// Extra 8
" ",
" ### ",
"# #",
"# # #",
"# #",
" ### ",
" ",
// Extra 9
" ",
" #",
" # #",
" # #",
"#####",
" # ",
" # ",
// Extra 10
" # ",
" # ##",
" # # ",
" ####",
" ### ",
"#####",
" ### ",
// Extra 11
" ### ",
" # # ",
" ### ",
" ",
" ",
" ",
" ",
// Extra 12
" ",
" ",
"# #",
"# #",
"# ##",
"### #",
"# ",
// Extra 13
" # ",
" # ",
"#### ",
" # #",
" # #",
" #",
" ### ",
// Extra 14
"# ",
"## ",
"### ",
"#### ",
"### ",
"## ",
"# ",
// Extra 15
" #",
" ##",
" ###",
" ####",
" ###",
" ##",
" #",
};
const char *font_extras_utf[] = {
"",
"×",
"",
"",
"",
"",
"", // clock
"",
"",
"",
"🌡",
"°",
"μ",
"🔙", // back
"",
"",
};
#include "fontedit_render.inc.c"
+14
View File
@@ -0,0 +1,14 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
void main() {
printf("const char* symbols[] = {\n");
for(int c = 32; c < 127; c++) {
printf(" // %d \"%c\"\n", c, c);
for(int j=0;j<5;j++){
printf(" \" \",\n");
}
}
printf("};\n");
}
+48
View File
@@ -0,0 +1,48 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
void generate_glyph_tables() {
printf("static const font%dx_bitmap_t PROGMEM font%d%d_ascii[] = {\n", FONT_W, FONT_W, FONT_H);
for (int i = 32; i < 127; i++) {
uint8_t line[8] = {};
for(int j = 0; j < FONT_H; j++) {
const char *row = font_ascii[(i - 32)*FONT_H + j];
for(int k = 0; k < FONT_W; k++) {
line[k] |= (row[k] != 32) << j;
}
}
printf(" {{");
for(int k = 0; k < FONT_W; k++) {
if (k > 0) printf(", ");
printf("0x%02x", line[k]);
}
printf("}},\n");
}
printf("};\n\n");
printf("static const struct utf_glyph%dx PROGMEM font%d%d_extra[] = {\n", FONT_W, FONT_W, FONT_H);
for (int i = 0; i < sizeof(font_extras) / (sizeof(font_extras[0]) * FONT_H); i++) {
uint8_t line[8] = {};
for(int j = 0; j < FONT_H; j++) {
const char *row = font_extras[i*FONT_H + j];
for(int k = 0; k < FONT_W; k++) {
line[k] |= (row[k] != 32) << j;
}
}
printf(" {.utf={.symbol=\"%s\"}, {{", font_extras_utf[i]);
for(int k = 0; k < FONT_W; k++) {
if (k > 0) printf(", ");
printf("0x%02x", line[k]);
}
printf("}}},\n");
}
printf("};\n");
}
void main() {
generate_glyph_tables();
}
+282
View File
@@ -0,0 +1,282 @@
//
// Created by MightyPork on 2022/11/12.
//
#include "ufb/framebuffer.h"
#include "ufb/progmem.h"
#define MIN(a, b) ((a)>(b)?(b):(a))
#define MAX(a, b) ((a)>(b)?(a):(b))
#include <string.h>
uint8_t fb[FB_LEN];
/** Fill with a vertical pattern, 1 byte */
void fb_fill(uint8_t pattern)
{
memset(fb, pattern, sizeof(fb));
}
static void draw_mask(fbsize_t idx, uint8_t mask, fbcolor_t color)
{
if (color != 0) {
fb[idx] |= mask;
} else {
fb[idx] &= ~mask;
}
}
void fb_fill_pattern(const uint8_t *pattern, uint8_t pattern_len, fbcolor_t color)
{
uint8_t p = 0;
for (fbsize_t i = 0; i < FB_LEN; i++) {
draw_mask(i, pattern[p], color);
p++;
if (p >= pattern_len) {
p = 0;
}
}
}
void fb_invert()
{
for (fbsize_t i = 0; i < FB_LEN; i++) {
fb[i] ^= 0xFF;
}
}
void fb_px(fbpos_t x, fbpos_t y, fbcolor_t color)
{
if (x >= FBW || y >= FBH || x < 0 || y < 0) { return; }
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
draw_mask(cell, 1 << rowrem, color);
}
uint8_t fb_getpx(fbpos_t x, fbpos_t y)
{
if (x >= FBW || y >= FBH) { return 0; }
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (fb[cell] & (1 << rowrem)) {
return 0xFF;
} else {
return 0x00;
}
}
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, fbcolor_t color)
{
if (x >= FBW || y >= FBH) { return; }
w = MIN(FBW - x, w);
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
for (uint8_t i = 0; i < w; i++) {
draw_mask(cell, 1 << rowrem, color);
cell++;
}
}
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, fbcolor_t color)
{
if (x >= FBW || y >= FBH) { return; }
h = MIN(FBH - y - 1, h);
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
if (rowrem + h < 8) {
// all within one cell
const uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
draw_mask(cell, mask, color);
return;
} else {
// First
draw_mask(cell, 0xFF << rowrem, color);
h -= (rowrem == 0 ? 8 : (8 - rowrem));
const fbpos_t whole_cells = h / 8;
if (whole_cells > 0) {
h -= whole_cells * 8;
for (fbpos_t i = 0; i < whole_cells; i++) {
cell += FBW;
draw_mask(cell, 0xFF, color);
}
}
// last
cell += FBW;
draw_mask(cell, 0xFF >> (8 - h), color);
}
}
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbcolor_t color)
{
if (x >= FBW || y >= FBH) { return; }
w = MIN(FBW - x, w);
h = MIN(FBH - y, h);
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (w == 1 && h == 1) {
fb_px(x, y, color);
} else if (w == 1) {
fb_vline(x, y, h, color);
} else if (h == 1) {
fb_hline(x, y, w, color);
} else if (rowrem + h <= 8) {
// all within one cell
uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
return;
} else {
// First
uint8_t mask = (0xFF << rowrem);
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
h -= 8 - rowrem;
const fbpos_t whole_cells = h / 8;
if (whole_cells > 0) {
h -= whole_cells * 8;
for (fbpos_t j = 0; j < whole_cells; j++) {
cell += FBW;
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, 0xFF, color);
}
}
}
cell += FBW;
// last
mask = (0xFF >> (8 - h));
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
}
}
void fb_frame(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t thickness, fbcolor_t color)
{
if (thickness == 0) {
return;
} else if (thickness == 1) {
fb_hline(x, y, w, color);
fb_vline(x, y, h, color);
fb_hline(x, y + h - 1, w, color);
fb_vline(x + w - 1, y, h, color);
} else {
fb_rect(x, y, w, thickness, color);
fb_rect(x, y + h - thickness, w, thickness, color);
fb_rect(x, y + thickness, thickness, h - 2 * thickness, color);
fb_rect(x + w - thickness, y + thickness, thickness, h - 2 * thickness, color);
}
}
// setCircle draws a circle centered around x0,y0 with a defined
// radius. The circle can be black or white. And have a line
// thickness ranging from 1 to the radius of the circle.
// This function was grabbed from the SparkFun ColorLCDShield
// library.
void fb_circle(fbpos_t x0, fbpos_t y0, fbpos_t radius, uint8_t thickness, fbcolor_t color)
{
for (uint8_t r = 0; r < thickness; r++) {
int8_t f = 1 - radius;
fbpos_t ddF_x = 0;
int8_t ddF_y = -2 * radius;
fbpos_t x = 0;
fbpos_t y = radius;
fb_px(x0, y0 + radius, color);
fb_px(x0 + radius, y0, color);
if (y0 >= radius) {
fb_px(x0, y0 - radius, color);
}
if (x0 >= radius) {
fb_px(x0 - radius, y0, color);
}
while (x < y) {
if (f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
fb_px(x0 + x, y0 + y, color);
fb_px(x0 - x, y0 + y, color);
fb_px(x0 + x, y0 - y, color);
fb_px(x0 - x, y0 - y, color);
fb_px(x0 + y, y0 + x, color);
fb_px(x0 - y, y0 + x, color);
fb_px(x0 + y, y0 - x, color);
fb_px(x0 - y, y0 - x, color);
}
radius--;
}
}
#if IS_AVR
void fb_bitmap_ex_P(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, fbcolor_t color)
#else
void fb_bitmap_ex(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, fbcolor_t color)
#endif
{
if (x >= FBW || y >= FBH) { return; }
const fbpos_t w0 = w;
w = MIN(FBW - x - 1, w);
h = MIN(FBH - y - 1, h);
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (rowrem + h <= 8) {
for (fbpos_t i = 0; i < w; i++) {
// all within one cell
const uint8_t mask = (pgm_read_byte(&map[i]) & (0xFF >> (8 - h))) << rowrem;
draw_mask(cell + i, mask, color);
}
return;
} else {
fbsize_t mapc0 = 0;
// Draw the bitmap slice-by-slice based on how rows of the bitmap intersect with rows of the canvas.
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
while (h > 0) {
for (fbpos_t i = 0; i < w; i++) {
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF >> rowrem)) << rowrem;
draw_mask(cell + i, mask, color);
}
cell += FBW;
if (rowrem != 0) {
for (fbpos_t i = 0; i < w; i++) {
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF << (8 - rowrem))) >> (8 - rowrem);
draw_mask(cell + i, mask, color);
}
}
if (h > 8) {
h -= 8;
} else {
break;
}
mapc0 += w0;
}
}
}
+164
View File
@@ -0,0 +1,164 @@
#include <stdlib.h>
#include <stdio.h>
#include "ufb/framebuffer.h"
#include "ufb/font.h"
#include "ufb/fb_7seg.h"
#include "ufb/fb_text.h"
void main() {
fb_clear();
const uint8_t ryba[14] = {
0b11000011,
0b01100110,
0b01111110,
0b00111100,
0b00011000,
0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111011,
0b11111111,
0b01111110,
0b00111100,
0b00011000,
};
#define ZIR_W 12
#define ZIR_H 24
const uint8_t zirafa[(ZIR_H/8) * ZIR_W] = {
// levo
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00011001,
0b00011111,
0b11111000,
0b00011111,
0b00001000,
//
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b10000000,
0b11111111,
0b00100000,
0b00010000,
//
0b00110000,
0b10001000,
0b11111000,
0b00011000,
0b11111000,
0b10011000,
0b00011000,
0b10011000,
0b11111000,
0b00011111,
0b11111000,
0b10000000,
};
//fb_bitmap(0, pos, 14, 8, ryba, 1);
// fb_bitmap(0, 0, ZIR_W, ZIR_H, zirafa, 1);
// fb_bitmap(ZIR_W+2, 12, ZIR_W, ZIR_H, zirafa, 1);
// fb_bitmap((ZIR_W + 2) * 2, 2, ZIR_W, ZIR_H, zirafa, 1);
fb_frame(0, 0, 128, 64, 2, 1);
// uint8_t x = 3;
// uint8_t w = 7;
// uint8_t h = 10;
// uint8_t th = 1;
// uint8_t sp = 3;
// x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 7, /*color*/ 1) + sp;
// x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 9, /*color*/ 1) + sp;
// x += fb_7seg_period(x, 3, w, h, th, /*color*/ 1) + sp;
// x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 5, /*color*/ 1) + sp;
//fb_circle(60, 15, 10, 1, 1);
// fb_circle(60, 15, 5, 1, 1);
//fb_fill_pattern("\xAA\x55", 2, 0);
//fb_invert();
// fb_text(40, 12, "▶Ahoj→!", FONT_BOLD, 1);
fb_text(15, 15, "MEOW", FONT_DOUBLEH, 1);
fb_text(40, 15, "MEOW", FONT_DOUBLEW, 1);
fb_text(40, 23, "MEOW", FONT_BOLD, 1);
fb_text(5, 5, "Tiny 3x5", FONT_3X5, 1);
fb_text(40, 5, "Tiny 4x5 MEOW", FONT_4X5, 1);
fb_frame(12,12,80,20,1,1);
// fb_text(36, 5, "-123456789.0 CPM°", FONT_TINY, 1);
// struct Utf8Iterator iter;
//// Utf8Iterator_Init_P(&iter, str);
// Utf8Iterator_Init(&iter, str);
//
// struct Utf8Char uchar;
// x = 3;
// while ((uchar = Utf8Iterator_Next(&iter)).uint) {
// const font_bitmap_t *sym = font_getsym(&uchar);
// fb_bitmap_P(x, 15, 5, 8, sym->data, 1);
// x += 7;
// }
//
//uint8_t xx[] = {
// 0x1f, 0x11, 0x11, 0x1f,
// 0x02, 0x05, 0x02, 0x00,
// 0x00, 0x04, 0x04, 0x04,
// 0x0e, 0x11, 0x11, 0x0a,
// 0x1f, 0x05, 0x05, 0x02,
// 0x1f, 0x01, 0x02, 0x1f,
// 0x00, 0x18, 0x18, 0x00,
//};
//
//for(int i=0;i<sizeof(xx);i++) {
// uint8_t v = xx[i];
// uint8_t out = 0;
// for(int i=0;i<8;i++) {
// out |= ((v>>i) & 1) << (7-i);
// }
//
// if(i%4==0) printf("\n");
// printf("0x%02x, ", out);
//}
fb_blit();
}
void fb_blit() {
for(int y = 0; y < FBH; y++) {
for(int x = 0; x < FBW; x++) {
bool b = fb[(y/8)*FBW + x] & (1 << (y%8));
if (b) {
printf("\x1b[1;32m█\x1b[m");
} else {
if (y%8 == 0) {
printf("\x1b[34m.\x1b[m");
} else {
printf(".");
}
}
}
printf("\r\n");
}
printf("\r\n");
}
+129
View File
@@ -0,0 +1,129 @@
#include <stdint.h>
#include "ufb/utf8.h"
//
// Created by MightyPork on 2017/08/20.
//
// UTF-8 parser - collects bytes of a code point before writing them
// into a screen cell.
//
const struct Utf8Char EMPTY_CHAR = (struct Utf8Char) {.uint = 0};
// Code Points First Byte Second Byte Third Byte Fourth Byte
// U+0000 - U+007F 00 - 7F
// U+0080 - U+07FF C2 - DF 80 - BF
// U+0800 - U+0FFF E0 *A0 - BF 80 - BF
// U+1000 - U+CFFF E1 - EC 80 - BF 80 - BF
// U+D000 - U+D7FF ED 80 - *9F 80 - BF
// U+E000 - U+FFFF EE - EF 80 - BF 80 - BF
// U+10000 - U+3FFFF F0 *90 - BF 80 - BF 80 - BF
// U+40000 - U+FFFFF F1 - F3 80 - BF 80 - BF 80 - BF
// U+100000 - U+10FFFF F4 80 - *8F 80 - BF 80 - BF
size_t utf8_strlen(const char *text)
{
// TODO optimize
struct Utf8Iterator iter;
Utf8Iterator_Init(&iter, text);
size_t num = 0;
while ((Utf8Iterator_Next(&iter)).uint) {
num++;
}
return num;
}
/**
* Handle a received character
*/
struct Utf8Char Utf8Parser_Handle(struct Utf8Parser *self, char c)
{
uint8_t *bytes = self->buffer.bytes;
uint8_t uc = (uint8_t) c;
// collecting unicode glyphs...
if (uc & 0x80) {
if (self->utf_len == 0) {
bytes[0] = uc;
self->utf_j = 1;
// start
if (uc == 0xC0 || uc == 0xC1 || uc > 0xF4) {
// forbidden start codes
goto fail;
}
if ((uc & 0xE0) == 0xC0) {
self->utf_len = 2;
}
else if ((uc & 0xF0) == 0xE0) {
self->utf_len = 3;
}
else if ((uc & 0xF8) == 0xF0) {
self->utf_len = 4;
}
else {
// chars over 127 that don't start unicode sequences
goto fail;
}
}
else {
if ((uc & 0xC0) != 0x80) {
bytes[self->utf_j++] = uc;
goto fail;
}
else {
bytes[self->utf_j++] = uc;
if (self->utf_j >= self->utf_len) {
// check for bad sequences - overlong or some other problem
if (bytes[0] == 0xF4 && bytes[1] > 0x8F) goto fail;
if (bytes[0] == 0xF0 && bytes[1] < 0x90) goto fail;
if (bytes[0] == 0xED && bytes[1] > 0x9F) goto fail;
if (bytes[0] == 0xE0 && bytes[1] < 0xA0) goto fail;
// trap for surrogates - those break javascript
if (bytes[0] == 0xED && bytes[1] >= 0xA0 && bytes[1] <= 0xBF) goto fail;
goto success;
}
}
}
}
else {
bytes[0] = uc;
goto success;
}
return EMPTY_CHAR;
success:;
struct Utf8Char result = self->buffer;
self->buffer.uint = 0; // erase the buffer
self->utf_len = 0;
return result;
fail:
self->buffer.uint = 0; // erase the buffer
self->utf_len = 0;
return EMPTY_CHAR;
}
struct Utf8Char Utf8Iterator_Next(struct Utf8Iterator *self)
{
char c;
struct Utf8Char uchar;
while (1) {
if (self->is_progmem) {
c = pgm_read_byte(self->source++);
} else {
c = *self->source++;
}
if (!c) break;
uchar = Utf8Parser_Handle(&self->parser, c);
if (uchar.uint) {
return uchar;
}
}
return EMPTY_CHAR;
}