diff --git a/src/demo/NodeTest.h b/src/demo/NodeTest.h index a46d463..8e1019f 100644 --- a/src/demo/NodeTest.h +++ b/src/demo/NodeTest.h @@ -21,16 +21,9 @@ public: config.read(); display.setup(); display.setBrightness(6); - display.clear(); - - display.foreground = Blue; - display.printf("Test"); - - display.foreground = Red; - display.cursorX = 0; - display.cursorY = 7; - display.drawLineWH(32, 0, 1); + display.printf(1, 1, Blue, "Test"); + display.drawLine(0, 7, 32, 0, 1, Red); } void loop() override { diff --git a/src/patrix/display/Display.h b/src/patrix/display/Display.h index 8c73d27..55848ee 100644 --- a/src/patrix/display/Display.h +++ b/src/patrix/display/Display.h @@ -1,10 +1,37 @@ -#ifndef PATRIX_DISPLAY_H -#define PATRIX_DISPLAY_H +#ifndef PATRIX_DISPLAY_height +#define PATRIX_DISPLAY_height + +#include #include "DisplayMatrix_FontCommon.h" +#include "DisplayMatrix_FontLower.h" +#include "DisplayMatrix_FontNumberSegments.h" +#include "DisplayMatrix_FontSpecial.h" +#include "DisplayMatrix_FontUpper.h" + +inline void fixRect(int& x0, int& y0, int& w, int& h) { + if (w < 0) { + x0 += w; + w = -w; + } + if (h < 0) { + y0 += h; + h = -h; + } +} class Display { + Adafruit_NeoPixel leds; + + bool dirty = true; + +protected: + + virtual RGB _read_pixel_(int x, int y) = 0; + + virtual void _write_pixel_(int x, int y, RGBA color) = 0; + public: const uint8_t width; @@ -13,15 +40,11 @@ public: const uint16_t pixelCount; - RGBA foreground = White; - - RGBA background = Transparent; - - int cursorX = 0; - - int cursorY = 0; - - Display(const uint8_t width, const uint8_t height): width(width), height(height), pixelCount(width * height) { + Display(const int16_t pin, const uint8_t width, const uint8_t height) + : leds(width * height, pin), + width(width), + height(height), + pixelCount(width * height) { // } @@ -29,45 +52,220 @@ public: // basic ---------------------------------------------------------------------------------------- - virtual void setup() {} + void setup() { + leds.begin(); + leds.setBrightness(10); + clear(); + } - virtual void loop() {} + void loop() { + if (dirty) { + for (auto y = 0; y < height; y++) { + for (auto x = 0; x < width; x++) { + const auto rgb = _read_pixel_(x, y); + const auto index = y * width + (y % 2 == 0 ? x : width - x - 1); + leds.setPixelColor(index, rgb.r, rgb.g, rgb.b); + } + } + leds.show(); + dirty = false; + } + } - virtual void setBrightness(uint8_t brightness) {} + void setBrightness(const uint8_t brightness) { + if (leds.getBrightness() != brightness) { + leds.setBrightness(brightness); + dirty = true; + } + } - virtual uint8_t getBrightness(); + uint8_t getBrightness() const { + return leds.getBrightness(); + } // draw ----------------------------------------------------------------------------------------- - virtual void clear() {} + void clear() { + fillRect(0, 0, width, height, Black); + } - virtual void setPixel(int x, int y, RGBA color) {} + void setPixel(const int x, const int y, const RGBA color) { + if (x < 0 || x >= width || y < 0 || y >= height) { + return; + } + _write_pixel_(x, y, color); + dirty = true; + } - virtual void setPixel(int x, int y) {} + void fillRect(int x0, int y0, int w, int h, const RGBA color) { + fixRect(x0, y0, w, h); + for (auto y = y0; y < y0 + h; ++y) { + for (auto x = x0; x < x0 + w; ++x) { + setPixel(x, y, color); + } + } + } - virtual void fillRect(int w, int h) {} - - virtual void drawLineWH(int x, int y, int w, int h, int thickness) {} - - virtual void drawLineWH(int w, int h, int thickness) {} + void drawLine(int x0, int y0, int w, int h, const int thickness, const RGBA color) { + fixRect(x0, y0, w, h); + if (h == 0) { + for (auto x = x0; x < x0 + w; ++x) { + setPixel(x, y0, color); + } + } else if (w == 0) { + for (auto y = y0; y < y0 + w; ++y) { + setPixel(x0, y, color); + } + } else if (w >= h) { + const auto m = static_cast(h) / w; + for (auto t = 0; t < thickness; ++t) { + const auto offset = t % 2 == 0 ? t / 2 : -t / 2; + for (auto x = x0; x < x0 + w; ++x) { + const auto y = static_cast(round(offset + x * m)); + setPixel(x, y, color); + } + } + } else { + const auto m = static_cast(w) / h; + for (auto t = 0; t < thickness; ++t) { + const auto offset = t % 2 == 0 ? t / 2 : -t / 2; + for (auto y = y0; y < y0 + w; ++y) { + const auto x = static_cast(round(offset + y * m)); + setPixel(x, y, color); + } + } + } + } // print ---------------------------------------------------------------------------------------- - virtual void printf(const char *format, ...) {} + void printf(const int x, const int y, const RGBA color, const char *format, ...) { + va_list args; + va_start(args, format); + printf(x, y, color, format, args); + va_end(args); + } - virtual void printf(const bool segments, const char *format, ...) {} + void printf(const int x, const int y, const RGBA color, const char *format, const va_list args) { + char buffer[64]; + vsnprintf(buffer, sizeof buffer, format, args); + print(x, y, color, buffer); + } - virtual void printf(bool segments, const char *format, const va_list args) {} + void print(int x, int y, const RGBA color, const char *message) { + while (*message != '\0') { + print(&x, &y, color, &message); + x += 2; // space between characters + } + } - virtual void print(const char *str) {} + void print(int *x, int *y, const RGBA color, const char **cPP) { + const auto character = *(*cPP)++; - virtual void print(const bool segments, const char *str) {} + if ('0' <= character && character <= '9') { + return print(x, y, reinterpret_cast(FONT_NUMBER_SEGMENTS[character - '0']), countof(FONT_NUMBER_SEGMENTS[character - '0'][0]), countof(FONT_NUMBER_SEGMENTS[character - '0']), color); + } + if ('A' <= character && character <= 'Z') { + return print(x, y, reinterpret_cast(FONT_UPPER[character - 'A']), countof(FONT_UPPER[character - 'A'][0]), countof(FONT_UPPER[character - 'A']), color); + } + if ('a' <= character && character <= 'z') { + return print(x, y, reinterpret_cast(FONT_LOWER[character - 'a']), countof(FONT_LOWER[character - 'a'][0]), countof(FONT_LOWER[character - 'a']), color); + } - virtual void print(const bool segments, const char **cPP) {} + if (character == 0xC2) { + const auto secondCharacter = *(*cPP)++; + if (secondCharacter == 0xB0) { + return print(x, y, reinterpret_cast(FONT_CHAR_DEGREE), countof(FONT_CHAR_DEGREE[0]), countof(FONT_CHAR_DEGREE), color); + } + return printERROR(x, y, color); + } - virtual void print(bool *s, size_t w, size_t h) {} + if (character == 0xE2) { + const auto secondCharacter = *(*cPP)++; + if (secondCharacter == 0x82) { + const auto thirdCharacter = *(*cPP)++; + if (thirdCharacter == 0xAC) { + return print(x, y, reinterpret_cast(FONT_CHAR_EURO), countof(FONT_CHAR_EURO[0]), countof(FONT_CHAR_EURO), color); + } + return printERROR(x, y, color); + } + return printERROR(x, y, color); + } - virtual void print(RGBA *s, size_t w, size_t h) {} + if (character == '\n') { + *y += 6; + return; + } + + switch (character) { + case ' ': return print(x, y, reinterpret_cast(FONT_CHAR_SPACE), countof(FONT_CHAR_SPACE[0]), countof(FONT_CHAR_SPACE), color); + case '-': return print(x, y, reinterpret_cast(FONT_CHAR_MINUS), countof(FONT_CHAR_MINUS[0]), countof(FONT_CHAR_MINUS), color); + case '+': return print(x, y, reinterpret_cast(FONT_CHAR_PLUS), countof(FONT_CHAR_PLUS[0]), countof(FONT_CHAR_PLUS), color); + case '_': return print(x, y, reinterpret_cast(FONT_CHAR_UNDERLINE), countof(FONT_CHAR_UNDERLINE[0]), countof(FONT_CHAR_UNDERLINE), color); + case '%': return print(x, y, reinterpret_cast(FONT_CHAR_PERCENT), countof(FONT_CHAR_PERCENT[0]), countof(FONT_CHAR_PERCENT), color); + case '?': return print(x, y, reinterpret_cast(FONT_CHAR_QUESTION), countof(FONT_CHAR_QUESTION[0]), countof(FONT_CHAR_QUESTION), color); + case '!': return print(x, y, reinterpret_cast(FONT_CHAR_EXCLAMATION), countof(FONT_CHAR_EXCLAMATION[0]), countof(FONT_CHAR_EXCLAMATION), color); + case '.': return print(x, y, reinterpret_cast(FONT_CHAR_POINT), countof(FONT_CHAR_POINT[0]), countof(FONT_CHAR_POINT), color); + case ',': return print(x, y, reinterpret_cast(FONT_CHAR_COMMA), countof(FONT_CHAR_COMMA[0]), countof(FONT_CHAR_COMMA), color); + case ';': return print(x, y, reinterpret_cast(FONT_CHAR_SEMICOLON), countof(FONT_CHAR_SEMICOLON[0]), countof(FONT_CHAR_SEMICOLON), color); + case ':': return print(x, y, reinterpret_cast(FONT_CHAR_COLON), countof(FONT_CHAR_COLON[0]), countof(FONT_CHAR_COLON), color); + case '#': return print(x, y, reinterpret_cast(FONT_CHAR_SHARP), countof(FONT_CHAR_SHARP[0]), countof(FONT_CHAR_SHARP), color); + case '~': return print(x, y, reinterpret_cast(FONT_CHAR_TILDE), countof(FONT_CHAR_TILDE[0]), countof(FONT_CHAR_TILDE), color); + case '*': return print(x, y, reinterpret_cast(FONT_CHAR_ASTERISK), countof(FONT_CHAR_ASTERISK[0]), countof(FONT_CHAR_ASTERISK), color); + case '"': return print(x, y, reinterpret_cast(FONT_CHAR_QUOTE_DOUBLE), countof(FONT_CHAR_QUOTE_DOUBLE[0]), countof(FONT_CHAR_QUOTE_DOUBLE), color); + case '\'': return print(x, y, reinterpret_cast(FONT_CHAR_QUOTE_SINGLE), countof(FONT_CHAR_QUOTE_SINGLE[0]), countof(FONT_CHAR_QUOTE_SINGLE), color); + case '=': return print(x, y, reinterpret_cast(FONT_CHAR_EQUALS), countof(FONT_CHAR_EQUALS[0]), countof(FONT_CHAR_EQUALS), color); + case '(': return print(x, y, reinterpret_cast(FONT_CHAR_PAR_L), countof(FONT_CHAR_PAR_L[0]), countof(FONT_CHAR_PAR_L), color); + case ')': return print(x, y, reinterpret_cast(FONT_CHAR_PAR_R), countof(FONT_CHAR_PAR_R[0]), countof(FONT_CHAR_PAR_R), color); + case '[': return print(x, y, reinterpret_cast(FONT_CHAR_BRACKET_L), countof(FONT_CHAR_BRACKET_L[0]), countof(FONT_CHAR_BRACKET_L), color); + case ']': return print(x, y, reinterpret_cast(FONT_CHAR_BRACKET_R), countof(FONT_CHAR_BRACKET_R[0]), countof(FONT_CHAR_BRACKET_R), color); + case '{': return print(x, y, reinterpret_cast(FONT_CHAR_CURL_L), countof(FONT_CHAR_CURL_L[0]), countof(FONT_CHAR_CURL_L), color); + case '}': return print(x, y, reinterpret_cast(FONT_CHAR_CURL_R), countof(FONT_CHAR_CURL_R[0]), countof(FONT_CHAR_CURL_R), color); + case '/': return print(x, y, reinterpret_cast(FONT_CHAR_SLASH), countof(FONT_CHAR_SLASH[0]), countof(FONT_CHAR_SLASH), color); + case '\\': return print(x, y, reinterpret_cast(FONT_CHAR_BACKSLASH), countof(FONT_CHAR_BACKSLASH[0]), countof(FONT_CHAR_BACKSLASH), color); + case '&': return print(x, y, reinterpret_cast(FONT_CHAR_AND), countof(FONT_CHAR_AND[0]), countof(FONT_CHAR_AND), color); + case '|': return print(x, y, reinterpret_cast(FONT_CHAR_PIPE), countof(FONT_CHAR_PIPE[0]), countof(FONT_CHAR_PIPE), color); + case '$': return print(x, y, reinterpret_cast(FONT_CHAR_DOLLAR), countof(FONT_CHAR_DOLLAR[0]), countof(FONT_CHAR_DOLLAR), color); + case '@': return print(x, y, reinterpret_cast(FONT_CHAR_AT), countof(FONT_CHAR_AT[0]), countof(FONT_CHAR_AT), color); + case '<': return print(x, y, reinterpret_cast(FONT_CHAR_LT), countof(FONT_CHAR_LT[0]), countof(FONT_CHAR_LT), color); + case '>': return print(x, y, reinterpret_cast(FONT_CHAR_GT), countof(FONT_CHAR_GT[0]), countof(FONT_CHAR_GT), color); + default: return printERROR(x, y, color); + } + } + + void printERROR(int *x, const int *y, const RGBA color) { + return print(x, y, reinterpret_cast(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_), color); + } + + void print(int *x0, const int *y0, const bool *s, const int w, const int h, const RGBA color) { + auto maxWidth = 0; + for (auto y = 0; y < h; y++) { + for (auto x = 0; x < w; x++) { + const auto symbolIndex = y * w + x; + const auto active = *(s + symbolIndex); + const auto pixelX = *x0 + x; + const auto pixelY = *y0 + y; + if (active) { + setPixel(pixelX, pixelY, color); + maxWidth = max(x, maxWidth); + } + } + } + *x0 += maxWidth; + } + + void print(int *x0, const int *y0, const RGBA *s, const int w, const int h) { + for (auto y = 0; y < h; y++) { + for (auto x = 0; x < w; x++) { + const auto symbolIndex = y * w + x; + const auto color = *(s + symbolIndex); + const auto pixelX = *x0 + x; + const auto pixelY = *y0 + y; + setPixel(pixelX, pixelY, color); + } + } + *x0 += w; + } }; diff --git a/src/patrix/display/DisplayMatrix.h b/src/patrix/display/DisplayMatrix.h index f9aabd2..3c94591 100644 --- a/src/patrix/display/DisplayMatrix.h +++ b/src/patrix/display/DisplayMatrix.h @@ -1,98 +1,32 @@ #ifndef DISPLAY_MATRIX_H #define DISPLAY_MATRIX_H -#include - #include "Display.h" template class DisplayMatrix final : public Display { - Adafruit_NeoPixel leds; - RGB matrix[H][W] = {}; - bool dirty = true; +protected: + + RGB _read_pixel_(int x, int y) override { + return matrix[y][x]; + } + + void _write_pixel_(const int x, const int y, const RGBA color) override { + matrix[y][x] = color; + } public: - explicit DisplayMatrix(const int16_t pin): Display(W, H), leds(W * H, pin) { + explicit DisplayMatrix(const int16_t pin) + : Display(pin, W, H) { // } ~DisplayMatrix() override = default; - // basic ---------------------------------------------------------------------------------------- - - void setup() override { - leds.begin(); - leds.setBrightness(10); - clear(); - } - - void loop() override { - if (dirty) { - for (auto y = 0; y < H; y++) { - for (auto x = 0; x < W; x++) { - auto rgb = matrix[y][x]; - const auto index = y * W + (y % 2 == 0 ? x : W - x - 1); - leds.setPixelColor(index, rgb.r, rgb.g, rgb.b); - } - } - leds.show(); - dirty = false; - } - } - - void setBrightness(const uint8_t brightness) override { - if (leds.getBrightness() != brightness) { - leds.setBrightness(brightness); - dirty = true; - } - } - - uint8_t getBrightness() override { - return leds.getBrightness(); - } - - // draw ----------------------------------------------------------------------------------------- - - void clear() override; - - void setPixel(int x, int y) override; - - void setPixel(int x, int y, RGBA color) override; - - void fillRect(int w, int h) override; - - void drawLineWH(int x, int y, int w, int h, int thickness) override; - - void drawLineWH(int w, int h, int thickness) override; - - // print ---------------------------------------------------------------------------------------- - - void printf(const char *format, ...) override; - - void printf(bool segments, const char *format, ...) override; - - void printf(bool segments, const char *format, va_list args) override; - - void print(const char *message) override; - - void print(bool segments, const char *message) override; - - void print(bool segments, const char **cPP) override; - - void print(bool *s, size_t w, size_t h) override; - - void print(RGBA *s, size_t w, size_t h) override; - }; -// ReSharper disable once CppUnusedIncludeDirective -#include - -// ReSharper disable once CppUnusedIncludeDirective -#include - #endif diff --git a/src/patrix/display/DisplayMatrix_FontNumber.cpp b/src/patrix/display/DisplayMatrix_FontNumber.cpp deleted file mode 100644 index 56fa73a..0000000 --- a/src/patrix/display/DisplayMatrix_FontNumber.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "DisplayMatrix_FontNumber.h" - -Symbol4 FONT_NUMBER[] = { - { - {_,X,X,_}, - {X,_,_,X}, - {X,_,_,X}, - {X,_,_,X}, - {_,X,X,_}, - }, - { - {_,_,X,_}, - {_,X,X,_}, - {X,_,X,_}, - {_,_,X,_}, - {_,_,X,_}, - }, - { - {_,X,X,_}, - {X,_,_,X}, - {_,_,X,_}, - {_,X,_,_}, - {X,X,X,X}, - }, - { - {_,X,X,_}, - {X,_,_,X}, - {_,_,X,_}, - {X,_,_,X}, - {_,X,X,_}, - }, - { - {X,_,_,X}, - {X,_,_,X}, - {X,X,X,X}, - {_,_,_,X}, - {_,_,_,X}, - }, - { - {X,X,X,X}, - {X,_,_,_}, - {X,X,X,_}, - {_,_,_,X}, - {X,X,X,_}, - }, - { - {_,X,X,_}, - {X,_,_,_}, - {X,X,X,_}, - {X,_,_,X}, - {_,X,X,_}, - }, - { - {X,X,X,X}, - {_,_,_,X}, - {_,_,X,_}, - {_,X,_,_}, - {X,_,_,_}, - }, - { - {_,X,X,_}, - {X,_,_,X}, - {_,X,X,_}, - {X,_,_,X}, - {_,X,X,_}, - }, - { - {_,X,X,_}, - {X,_,_,X}, - {_,X,X,X}, - {_,_,_,X}, - {_,X,X,_}, - }, -}; diff --git a/src/patrix/display/DisplayMatrix_FontNumber.h b/src/patrix/display/DisplayMatrix_FontNumber.h deleted file mode 100644 index d2f160d..0000000 --- a/src/patrix/display/DisplayMatrix_FontNumber.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DISPLAY_MATRIX_FONT_NUMBER_H -#define DISPLAY_MATRIX_FONT_NUMBER_H - -#include "DisplayMatrix_FontCommon.h" - -extern Symbol4 FONT_NUMBER[]; - -#endif diff --git a/src/patrix/display/DisplayMatrix_FontNumberSegments.cpp b/src/patrix/display/DisplayMatrix_FontNumberSegments.cpp index c5a11dd..3b41fb2 100644 --- a/src/patrix/display/DisplayMatrix_FontNumberSegments.cpp +++ b/src/patrix/display/DisplayMatrix_FontNumberSegments.cpp @@ -1,4 +1,4 @@ -#include "DisplayMatrix_FontNumber.h" +#include "DisplayMatrix_FontCommon.h" Symbol4 FONT_NUMBER_SEGMENTS[] = { { diff --git a/src/patrix/display/DisplayMatrix_draw.h b/src/patrix/display/DisplayMatrix_draw.h deleted file mode 100644 index 9c0fc78..0000000 --- a/src/patrix/display/DisplayMatrix_draw.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef DISPLAY_MATRIX_DRAW_H -#define DISPLAY_MATRIX_DRAW_H - -template -void DisplayMatrix::clear() { - const auto backup = foreground; - foreground = Black; - cursorX = 0; - cursorY = 0; - fillRect(W, H); - foreground = backup; -} - -template -void DisplayMatrix::setPixel(const int x, const int y) { - setPixel(x, y, foreground); -} - -template -void DisplayMatrix::setPixel(int x, int y, RGBA color) { - if (x < 0 || x >= W || y < 0 || y >= H) { - return; - } - matrix[y][x] = color; - dirty = true; -} - -template -void DisplayMatrix::fillRect(const int w, const int h) { - if (w < 1 || h < 1) { - return; - } - for (auto y = cursorY; y < cursorY + h; ++y) { - for (auto x = cursorX; x < cursorX + w; ++x) { - setPixel(x, y); - } - } - dirty = true; -} - -template -void DisplayMatrix::drawLineWH(int x, int y, int w, int h, const int thickness) { - if (w < 0) { - x -= w; - w = -w; - } - if (h < 0) { - y -= h; - h = -h; - } - cursorX = x; - cursorY = y; - drawLineWH(w, h, thickness); -} - -template -void DisplayMatrix::drawLineWH(const int w, const int h, const int thickness) { - if (w < 1 && h < 1) { - return; - } - if (w >= h) { - const auto m = static_cast(h) / w; - for (auto t = 0; t < thickness; ++t) { - const auto offset = t % 2 == 0 ? t / 2 : -t / 2; - for (auto x = 0; x < w; ++x) { - const auto y = static_cast(round(offset + x * m)); - setPixel(cursorY + y, cursorX + x); - } - } - } else { - const auto m = static_cast(w) / h; - for (auto t = 0; t < thickness; ++t) { - const auto offset = t % 2 == 0 ? t / 2 : -t / 2; - for (auto y = 0; y < w; ++y) { - const auto x = static_cast(round(offset + y * m)); - setPixel(cursorY + y, cursorX + x); - } - } - } - dirty = true; -} - -#endif diff --git a/src/patrix/display/DisplayMatrix_print.h b/src/patrix/display/DisplayMatrix_print.h deleted file mode 100644 index 0103c7e..0000000 --- a/src/patrix/display/DisplayMatrix_print.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef DISPLAYMATRIX_PRINT_H -#define DISPLAYMATRIX_PRINT_H - -#include "DisplayMatrix_FontLower.h" -#include "DisplayMatrix_FontNumber.h" -#include "DisplayMatrix_FontNumberSegments.h" -#include "DisplayMatrix_FontSpecial.h" -#include "DisplayMatrix_FontUpper.h" - -template -void DisplayMatrix::printf(const char *format, ...) { - va_list args; - va_start(args, format); - printf(false, format, args); - va_end(args); -} - -template -void DisplayMatrix::printf(const bool segments, const char *format, ...) { - va_list args; - va_start(args, format); - printf(segments, format, args); - va_end(args); -} - -template -void DisplayMatrix::printf(const bool segments, const char *format, const va_list args) { - char buffer[64]; - vsnprintf(buffer, sizeof buffer, format, args); - print(segments, buffer); -} - -template -void DisplayMatrix::print(const char *message) { - print(false, message); -} - -template -void DisplayMatrix::print(const bool segments, const char *message) { - while (*message != '\0') { - print(segments, &message); - cursorX += 2; // space between characters - } -} - -template -void DisplayMatrix::print(const bool segments, const char **cPP) { - const auto a = *(*cPP)++; - auto b = '\0'; - if (a == 0xC2) { - b = *(*cPP)++; - switch (b) { // NOLINT(*-multiway-paths-covered) - case 0xB0: return print(reinterpret_cast(FONT_CHAR_DEGREE), countof(FONT_CHAR_DEGREE[0]), countof(FONT_CHAR_DEGREE)); - default: return print(reinterpret_cast(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_)); - } - } - if (a == 0xE2) { - auto c = '\0'; - b = *(*cPP)++; - switch (b) { // NOLINT(*-multiway-paths-covered) - case 0x82: - c = *(*cPP)++; - switch (c) { // NOLINT(*-multiway-paths-covered) - case 0xAC: return print(reinterpret_cast(FONT_CHAR_EURO), countof(FONT_CHAR_EURO[0]), countof(FONT_CHAR_EURO)); - default: return print(reinterpret_cast(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_)); - } - default: return print(reinterpret_cast(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_)); - } - } - - if ('a' <= a && a <= 'z') { - return print(reinterpret_cast(FONT_LOWER[a - 'a']), countof(FONT_LOWER[a - 'a'][0]), countof(FONT_LOWER[a - 'a'])); - } - if ('A' <= a && a <= 'Z') { - return print(reinterpret_cast(FONT_UPPER[a - 'A']), countof(FONT_UPPER[a - 'A'][0]), countof(FONT_UPPER[a - 'A'])); - } - if ('0' <= a && a <= '9') { - if (segments){ - return print(reinterpret_cast(FONT_NUMBER[a - '0']), countof(FONT_NUMBER[a - '0'][0]), countof(FONT_NUMBER[a - '0'])); - } - return print(reinterpret_cast(FONT_NUMBER_SEGMENTS[a - '0']), countof(FONT_NUMBER_SEGMENTS[a - '0'][0]), countof(FONT_NUMBER_SEGMENTS[a - '0'])); - } - switch (a) { - case ' ': return print(reinterpret_cast(FONT_CHAR_SPACE), countof(FONT_CHAR_SPACE[0]), countof(FONT_CHAR_SPACE)); - case '-': return print(reinterpret_cast(FONT_CHAR_MINUS), countof(FONT_CHAR_MINUS[0]), countof(FONT_CHAR_MINUS)); - case '+': return print(reinterpret_cast(FONT_CHAR_PLUS), countof(FONT_CHAR_PLUS[0]), countof(FONT_CHAR_PLUS)); - case '_': return print(reinterpret_cast(FONT_CHAR_UNDERLINE), countof(FONT_CHAR_UNDERLINE[0]), countof(FONT_CHAR_UNDERLINE)); - case '%': return print(reinterpret_cast(FONT_CHAR_PERCENT), countof(FONT_CHAR_PERCENT[0]), countof(FONT_CHAR_PERCENT)); - case '?': return print(reinterpret_cast(FONT_CHAR_QUESTION), countof(FONT_CHAR_QUESTION[0]), countof(FONT_CHAR_QUESTION)); - case '!': return print(reinterpret_cast(FONT_CHAR_EXCLAMATION), countof(FONT_CHAR_EXCLAMATION[0]), countof(FONT_CHAR_EXCLAMATION)); - case '.': return print(reinterpret_cast(FONT_CHAR_POINT), countof(FONT_CHAR_POINT[0]), countof(FONT_CHAR_POINT)); - case ',': return print(reinterpret_cast(FONT_CHAR_COMMA), countof(FONT_CHAR_COMMA[0]), countof(FONT_CHAR_COMMA)); - case ';': return print(reinterpret_cast(FONT_CHAR_SEMICOLON), countof(FONT_CHAR_SEMICOLON[0]), countof(FONT_CHAR_SEMICOLON)); - case ':': return print(reinterpret_cast(FONT_CHAR_COLON), countof(FONT_CHAR_COLON[0]), countof(FONT_CHAR_COLON)); - case '#': return print(reinterpret_cast(FONT_CHAR_SHARP), countof(FONT_CHAR_SHARP[0]), countof(FONT_CHAR_SHARP)); - case '~': return print(reinterpret_cast(FONT_CHAR_TILDE), countof(FONT_CHAR_TILDE[0]), countof(FONT_CHAR_TILDE)); - case '*': return print(reinterpret_cast(FONT_CHAR_ASTERISK), countof(FONT_CHAR_ASTERISK[0]), countof(FONT_CHAR_ASTERISK)); - case '"': return print(reinterpret_cast(FONT_CHAR_QUOTE_DOUBLE), countof(FONT_CHAR_QUOTE_DOUBLE[0]), countof(FONT_CHAR_QUOTE_DOUBLE)); - case '\'': return print(reinterpret_cast(FONT_CHAR_QUOTE_SINGLE), countof(FONT_CHAR_QUOTE_SINGLE[0]), countof(FONT_CHAR_QUOTE_SINGLE)); - case '=': return print(reinterpret_cast(FONT_CHAR_EQUALS), countof(FONT_CHAR_EQUALS[0]), countof(FONT_CHAR_EQUALS)); - case '(': return print(reinterpret_cast(FONT_CHAR_PAR_L), countof(FONT_CHAR_PAR_L[0]), countof(FONT_CHAR_PAR_L)); - case ')': return print(reinterpret_cast(FONT_CHAR_PAR_R), countof(FONT_CHAR_PAR_R[0]), countof(FONT_CHAR_PAR_R)); - case '[': return print(reinterpret_cast(FONT_CHAR_BRACKET_L), countof(FONT_CHAR_BRACKET_L[0]), countof(FONT_CHAR_BRACKET_L)); - case ']': return print(reinterpret_cast(FONT_CHAR_BRACKET_R), countof(FONT_CHAR_BRACKET_R[0]), countof(FONT_CHAR_BRACKET_R)); - case '{': return print(reinterpret_cast(FONT_CHAR_CURL_L), countof(FONT_CHAR_CURL_L[0]), countof(FONT_CHAR_CURL_L)); - case '}': return print(reinterpret_cast(FONT_CHAR_CURL_R), countof(FONT_CHAR_CURL_R[0]), countof(FONT_CHAR_CURL_R)); - case '/': return print(reinterpret_cast(FONT_CHAR_SLASH), countof(FONT_CHAR_SLASH[0]), countof(FONT_CHAR_SLASH)); - case '\\': return print(reinterpret_cast(FONT_CHAR_BACKSLASH), countof(FONT_CHAR_BACKSLASH[0]), countof(FONT_CHAR_BACKSLASH)); - case '&': return print(reinterpret_cast(FONT_CHAR_AND), countof(FONT_CHAR_AND[0]), countof(FONT_CHAR_AND)); - case '|': return print(reinterpret_cast(FONT_CHAR_PIPE), countof(FONT_CHAR_PIPE[0]), countof(FONT_CHAR_PIPE)); - case '$': return print(reinterpret_cast(FONT_CHAR_DOLLAR), countof(FONT_CHAR_DOLLAR[0]), countof(FONT_CHAR_DOLLAR)); - case '@': return print(reinterpret_cast(FONT_CHAR_AT), countof(FONT_CHAR_AT[0]), countof(FONT_CHAR_AT)); - case '<': return print(reinterpret_cast(FONT_CHAR_LT), countof(FONT_CHAR_LT[0]), countof(FONT_CHAR_LT)); - case '>': return print(reinterpret_cast(FONT_CHAR_GT), countof(FONT_CHAR_GT[0]), countof(FONT_CHAR_GT)); - default: return print(reinterpret_cast(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_)); - } -} - -template -void DisplayMatrix::print(bool *s, const size_t w, const size_t h) { - auto symbolMaxX = 0; - for (auto symbolY = 0; symbolY < h; symbolY++) { - for (auto symbolX = 0; symbolX < w; symbolX++) { - const auto symbolIndex = symbolY * w + symbolX; - const auto active = *(s + symbolIndex); - const auto pixelX = cursorX + symbolX; - const auto pixelY = cursorY + symbolY; - if (active) { - setPixel(pixelX, pixelY); - symbolMaxX = max(symbolX, symbolMaxX); - } else { - setPixel(pixelX, pixelY, background); - } - } - } - cursorX += symbolMaxX; -} - -template -void DisplayMatrix::print(RGBA *s, const size_t w, const size_t h) { - for (auto symbolY = 0; symbolY < h; symbolY++) { - for (auto symbolX = 0; symbolX < w; symbolX++) { - const auto symbolIndex = symbolY * w + symbolX; - const auto color = *(s + symbolIndex); - const auto pixelX = cursorX + symbolX; - const auto pixelY = cursorY + symbolY; - setPixel(pixelX, pixelY, color); - } - } - cursorX += w; -} - -#endif