Сделан русский текст
This commit is contained in:
@@ -1,10 +1,26 @@
|
||||
#include "Display.h"
|
||||
#include "Config.h"
|
||||
#include "Font_Cyrillic.h"
|
||||
#include "Log.h"
|
||||
#include <Wire.h>
|
||||
#include <esp_log.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace {
|
||||
uint32_t nextUtf8Codepoint(const char *&text) {
|
||||
const uint8_t first = static_cast<uint8_t>(*text++);
|
||||
if (first < 0x80U) return first;
|
||||
if ((first & 0xE0U) == 0xC0U) {
|
||||
const uint8_t second = static_cast<uint8_t>(*text);
|
||||
if ((second & 0xC0U) == 0x80U) {
|
||||
++text;
|
||||
return ((first & 0x1FU) << 6) | (second & 0x3FU);
|
||||
}
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
Display::Display() : oled_(128, 32, &Wire, -1) {}
|
||||
|
||||
bool Display::begin() {
|
||||
@@ -37,25 +53,38 @@ void Display::setPower(bool enabled) {
|
||||
Log::printf("OLED", "display power %s", enabled ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
void Display::fit(char *s) {
|
||||
int16_t x, y; uint16_t w, h;
|
||||
while (*s) {
|
||||
oled_.getTextBounds(s, 0, 0, &x, &y, &w, &h);
|
||||
if (w <= 128) break;
|
||||
s[strlen(s) - 1] = '\0';
|
||||
void Display::drawTextLine(const char *text, int16_t y) {
|
||||
int16_t x = 0;
|
||||
while (text && *text && x + CyrillicFont::WIDTH <= oled_.width()) {
|
||||
const uint32_t codepoint = nextUtf8Codepoint(text);
|
||||
const uint8_t *glyph = CyrillicFont::glyph(codepoint);
|
||||
if (glyph) {
|
||||
for (uint8_t row = 0; row < CyrillicFont::HEIGHT; ++row) {
|
||||
const uint8_t pixels = pgm_read_byte(glyph + row);
|
||||
for (uint8_t column = 0; column < CyrillicFont::WIDTH; ++column)
|
||||
if (pixels & (1U << (CyrillicFont::WIDTH - 1U - column)))
|
||||
oled_.drawPixel(x + column, y + row, SSD1306_WHITE);
|
||||
}
|
||||
} else if (codepoint < 0x100U) {
|
||||
oled_.drawChar(x, y, static_cast<unsigned char>(codepoint),
|
||||
SSD1306_WHITE, SSD1306_BLACK, 1);
|
||||
} else {
|
||||
oled_.drawChar(x, y, '?', SSD1306_WHITE, SSD1306_BLACK, 1);
|
||||
}
|
||||
x += CyrillicFont::ADVANCE;
|
||||
}
|
||||
}
|
||||
|
||||
void Display::show(const char *a, const char *b, uint32_t progress, uint32_t progressTotal) {
|
||||
char one[32], two[32];
|
||||
char one[64], two[64];
|
||||
snprintf(one, sizeof(one), "%s", a ? a : ""); snprintf(two, sizeof(two), "%s", b ? b : "");
|
||||
// Serial is the primary UI mirror and remains available when OLED is absent.
|
||||
Log::printf("UI", "%s | %s", one, two);
|
||||
if (!ok_) return;
|
||||
setPower(true);
|
||||
fit(one); fit(two);
|
||||
oled_.clearDisplay(); oled_.setCursor(0, 3); oled_.print(one);
|
||||
oled_.setCursor(0, 19); oled_.print(two);
|
||||
oled_.clearDisplay();
|
||||
drawTextLine(one, 3);
|
||||
drawTextLine(two, 19);
|
||||
if (progressTotal) {
|
||||
if (progress > progressTotal) progress = progressTotal;
|
||||
const uint16_t width = static_cast<uint16_t>(
|
||||
|
||||
Reference in New Issue
Block a user