From 7d3196a057c813eb2725418ae362a8798754010a Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 13 Feb 2015 17:42:23 +0100 Subject: [PATCH] correctly skip utf-8 characters --- firmware/layout2.c | 6 +++--- gen/fonts.c | 8 ++++---- gen/fonts/font.png | Bin 1196 -> 1796 bytes gen/fonts/generate.py | 22 +++++++++++----------- layout.c | 12 ++++++------ oled.c | 24 +++++++++++++++++++++--- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/firmware/layout2.c b/firmware/layout2.c index 6ea2b0a..739c233 100644 --- a/firmware/layout2.c +++ b/firmware/layout2.c @@ -252,9 +252,9 @@ void layoutAddress(const char *address) oledDrawString(68, 3 * 9, str[3]); static const char *btnYes = "Continue"; - oledDrawString(OLED_WIDTH - fontCharWidth('\xff') - 1, OLED_HEIGHT - 8, "\xff"); - oledDrawString(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\xff') - 3, OLED_HEIGHT - 8, btnYes); - oledInvert(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\xff') - 4, OLED_HEIGHT - 9, OLED_WIDTH - 1, OLED_HEIGHT - 1); + oledDrawString(OLED_WIDTH - fontCharWidth('\x06') - 1, OLED_HEIGHT - 8, "\x06"); + oledDrawString(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\x06') - 3, OLED_HEIGHT - 8, btnYes); + oledInvert(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\x06') - 4, OLED_HEIGHT - 9, OLED_WIDTH - 1, OLED_HEIGHT - 1); oledRefresh(); } diff --git a/gen/fonts.c b/gen/fonts.c index af05044..a82be16 100644 --- a/gen/fonts.c +++ b/gen/fonts.c @@ -7,7 +7,7 @@ const uint8_t *font_data[256] = { /* 0x03 _ */ (uint8_t *)"\x01\x00", /* 0x04 _ */ (uint8_t *)"\x01\x00", /* 0x05 _ */ (uint8_t *)"\x01\x00", - /* 0x06 _ */ (uint8_t *)"\x01\x00", + /* 0x06 _ */ (uint8_t *)"\x07\x18\x1c\x0e\x18\x30\x40\x80", /* 0x07 _ */ (uint8_t *)"\x01\x00", /* 0x08 _ */ (uint8_t *)"\x01\x00", /* 0x09 _ */ (uint8_t *)"\x01\x00", @@ -22,7 +22,7 @@ const uint8_t *font_data[256] = { /* 0x12 _ */ (uint8_t *)"\x01\x00", /* 0x13 _ */ (uint8_t *)"\x01\x00", /* 0x14 _ */ (uint8_t *)"\x01\x00", - /* 0x15 _ */ (uint8_t *)"\x01\x00", + /* 0x15 _ */ (uint8_t *)"\x07\x44\xee\x7c\x38\x7c\xee\x44", /* 0x16 _ */ (uint8_t *)"\x01\x00", /* 0x17 _ */ (uint8_t *)"\x01\x00", /* 0x18 _ */ (uint8_t *)"\x01\x00", @@ -255,8 +255,8 @@ const uint8_t *font_data[256] = { /* 0xfb _ */ (uint8_t *)"\x01\x00", /* 0xfc _ */ (uint8_t *)"\x01\x00", /* 0xfd _ */ (uint8_t *)"\x01\x00", - /* 0xfe _ */ (uint8_t *)"\x07\x44\xee\x7c\x38\x7c\xee\x44", - /* 0xff _ */ (uint8_t *)"\x07\x18\x1c\x0e\x18\x30\x40\x80", + /* 0xfe _ */ (uint8_t *)"\x01\x00", + /* 0xff _ */ (uint8_t *)"\x01\x00", }; int fontCharWidth(char c) { diff --git a/gen/fonts/font.png b/gen/fonts/font.png index 9537b46f12633f8ce0ff830b8a014b8aa4573762..b78c0931689d508291c31dc5e0d75cd6b4321c6d 100644 GIT binary patch literal 1796 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 32 and idx <= 126 else '_' - print '\t/* 0x%02x %c */ (uint8_t *)"%s",' % (idx, ch , cur) - cur = '' - idx += 1 - continue - val = img.pixel(i, 0) + img.pixel(i, 1) + img.pixel(i, 2) + img.pixel(i, 3) + img.pixel(i, 4) + img.pixel(i, 5) + img.pixel(i, 6) + img.pixel(i, 7) - cur += '\\x%02x' % int(val, 2) +for i in range(256): + x = (i % 16) * 10 + y = (i / 16) * 10 + cur = '' + while img.pixel(x, y) != None: + val = ''.join(img.pixel(x, y + j) for j in range(8)) + x += 1 + cur += '\\x%02x' % int(val, 2) + cur = '\\x%02x' % (len(cur) / 4) + cur + ch = chr(i) if i >= 32 and i <= 126 else '_' + print '\t/* 0x%02x %c */ (uint8_t *)"%s",' % (i, ch , cur) diff --git a/layout.c b/layout.c index 2d7f277..7848b49 100644 --- a/layout.c +++ b/layout.c @@ -67,14 +67,14 @@ void layoutDialog(LayoutDialogIcon icon, const char *btnNo, const char *btnYes, } } if (btnNo) { - oledDrawString(1, OLED_HEIGHT - 8, "\xfe"); - oledDrawString(fontCharWidth('\xfe') + 3, OLED_HEIGHT - 8, btnNo); - oledInvert(0, OLED_HEIGHT - 9, fontCharWidth('\xfe') + oledStringWidth(btnNo) + 2, OLED_HEIGHT - 1); + oledDrawString(1, OLED_HEIGHT - 8, "\x15"); + oledDrawString(fontCharWidth('\x15') + 3, OLED_HEIGHT - 8, btnNo); + oledInvert(0, OLED_HEIGHT - 9, fontCharWidth('\x15') + oledStringWidth(btnNo) + 2, OLED_HEIGHT - 1); } if (btnYes) { - oledDrawString(OLED_WIDTH - fontCharWidth('\xff') - 1, OLED_HEIGHT - 8, "\xff"); - oledDrawString(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\xff') - 3, OLED_HEIGHT - 8, btnYes); - oledInvert(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\xff') - 4, OLED_HEIGHT - 9, OLED_WIDTH - 1, OLED_HEIGHT - 1); + oledDrawString(OLED_WIDTH - fontCharWidth('\x06') - 1, OLED_HEIGHT - 8, "\x06"); + oledDrawString(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\x06') - 3, OLED_HEIGHT - 8, btnYes); + oledInvert(OLED_WIDTH - oledStringWidth(btnYes) - fontCharWidth('\x06') - 4, OLED_HEIGHT - 9, OLED_WIDTH - 1, OLED_HEIGHT - 1); } oledRefresh(); } diff --git a/oled.c b/oled.c index 00405c0..6b3ef56 100644 --- a/oled.c +++ b/oled.c @@ -207,11 +207,25 @@ void oledDrawChar(int x, int y, char c) } } +char oledConvertChar(const char c) { + uint8_t a = c; + if (a < 0x80) return c; + // UTF-8 handling: https://en.wikipedia.org/wiki/UTF-8#Description + // bytes 11xxxxxx are first byte of UTF-8 characters + // bytes 10xxxxxx are successive UTF-8 characters + if (a >= 0xC0) return '_'; + return 0; +} + int oledStringWidth(const char *text) { if (!text) return 0; int l = 0; + char c; for (; *text; text++) { - l += fontCharWidth(*text) + 1; + c = oledConvertChar(*text); + if (c) { + l += fontCharWidth(c) + 1; + } } return l; } @@ -220,9 +234,13 @@ void oledDrawString(int x, int y, const char* text) { if (!text) return; int l = 0; + char c; for (; *text; text++) { - oledDrawChar(x + l, y, *text); - l += fontCharWidth(*text) + 1; + c = oledConvertChar(*text); + if (c) { + oledDrawChar(x + l, y, c); + l += fontCharWidth(c) + 1; + } } }