REFACTOR: removed Display members: cursorX, cursorY, foreground, background
This commit is contained in:
parent
8bbddc3bb8
commit
d57ef636f2
@ -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 {
|
||||
|
||||
@ -1,10 +1,37 @@
|
||||
#ifndef PATRIX_DISPLAY_H
|
||||
#define PATRIX_DISPLAY_H
|
||||
#ifndef PATRIX_DISPLAY_height
|
||||
#define PATRIX_DISPLAY_height
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
#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<double>(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<int>(round(offset + x * m));
|
||||
setPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto m = static_cast<double>(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<int>(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<bool *>(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<bool *>(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<bool *>(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<bool *>(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<bool *>(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<bool *>(FONT_CHAR_SPACE), countof(FONT_CHAR_SPACE[0]), countof(FONT_CHAR_SPACE), color);
|
||||
case '-': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_MINUS), countof(FONT_CHAR_MINUS[0]), countof(FONT_CHAR_MINUS), color);
|
||||
case '+': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_PLUS), countof(FONT_CHAR_PLUS[0]), countof(FONT_CHAR_PLUS), color);
|
||||
case '_': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_UNDERLINE), countof(FONT_CHAR_UNDERLINE[0]), countof(FONT_CHAR_UNDERLINE), color);
|
||||
case '%': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_PERCENT), countof(FONT_CHAR_PERCENT[0]), countof(FONT_CHAR_PERCENT), color);
|
||||
case '?': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_QUESTION), countof(FONT_CHAR_QUESTION[0]), countof(FONT_CHAR_QUESTION), color);
|
||||
case '!': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_EXCLAMATION), countof(FONT_CHAR_EXCLAMATION[0]), countof(FONT_CHAR_EXCLAMATION), color);
|
||||
case '.': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_POINT), countof(FONT_CHAR_POINT[0]), countof(FONT_CHAR_POINT), color);
|
||||
case ',': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_COMMA), countof(FONT_CHAR_COMMA[0]), countof(FONT_CHAR_COMMA), color);
|
||||
case ';': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_SEMICOLON), countof(FONT_CHAR_SEMICOLON[0]), countof(FONT_CHAR_SEMICOLON), color);
|
||||
case ':': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_COLON), countof(FONT_CHAR_COLON[0]), countof(FONT_CHAR_COLON), color);
|
||||
case '#': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_SHARP), countof(FONT_CHAR_SHARP[0]), countof(FONT_CHAR_SHARP), color);
|
||||
case '~': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_TILDE), countof(FONT_CHAR_TILDE[0]), countof(FONT_CHAR_TILDE), color);
|
||||
case '*': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_ASTERISK), countof(FONT_CHAR_ASTERISK[0]), countof(FONT_CHAR_ASTERISK), color);
|
||||
case '"': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_QUOTE_DOUBLE), countof(FONT_CHAR_QUOTE_DOUBLE[0]), countof(FONT_CHAR_QUOTE_DOUBLE), color);
|
||||
case '\'': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_QUOTE_SINGLE), countof(FONT_CHAR_QUOTE_SINGLE[0]), countof(FONT_CHAR_QUOTE_SINGLE), color);
|
||||
case '=': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_EQUALS), countof(FONT_CHAR_EQUALS[0]), countof(FONT_CHAR_EQUALS), color);
|
||||
case '(': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_PAR_L), countof(FONT_CHAR_PAR_L[0]), countof(FONT_CHAR_PAR_L), color);
|
||||
case ')': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_PAR_R), countof(FONT_CHAR_PAR_R[0]), countof(FONT_CHAR_PAR_R), color);
|
||||
case '[': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_BRACKET_L), countof(FONT_CHAR_BRACKET_L[0]), countof(FONT_CHAR_BRACKET_L), color);
|
||||
case ']': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_BRACKET_R), countof(FONT_CHAR_BRACKET_R[0]), countof(FONT_CHAR_BRACKET_R), color);
|
||||
case '{': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_CURL_L), countof(FONT_CHAR_CURL_L[0]), countof(FONT_CHAR_CURL_L), color);
|
||||
case '}': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_CURL_R), countof(FONT_CHAR_CURL_R[0]), countof(FONT_CHAR_CURL_R), color);
|
||||
case '/': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_SLASH), countof(FONT_CHAR_SLASH[0]), countof(FONT_CHAR_SLASH), color);
|
||||
case '\\': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_BACKSLASH), countof(FONT_CHAR_BACKSLASH[0]), countof(FONT_CHAR_BACKSLASH), color);
|
||||
case '&': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_AND), countof(FONT_CHAR_AND[0]), countof(FONT_CHAR_AND), color);
|
||||
case '|': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_PIPE), countof(FONT_CHAR_PIPE[0]), countof(FONT_CHAR_PIPE), color);
|
||||
case '$': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_DOLLAR), countof(FONT_CHAR_DOLLAR[0]), countof(FONT_CHAR_DOLLAR), color);
|
||||
case '@': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_AT), countof(FONT_CHAR_AT[0]), countof(FONT_CHAR_AT), color);
|
||||
case '<': return print(x, y, reinterpret_cast<bool *>(FONT_CHAR_LT), countof(FONT_CHAR_LT[0]), countof(FONT_CHAR_LT), color);
|
||||
case '>': return print(x, y, reinterpret_cast<bool *>(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<bool *>(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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,98 +1,32 @@
|
||||
#ifndef DISPLAY_MATRIX_H
|
||||
#define DISPLAY_MATRIX_H
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
#include "Display.h"
|
||||
|
||||
template<int W, int H>
|
||||
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 <patrix/display/DisplayMatrix_draw.h>
|
||||
|
||||
// ReSharper disable once CppUnusedIncludeDirective
|
||||
#include <patrix/display/DisplayMatrix_print.h>
|
||||
|
||||
#endif
|
||||
|
||||
@ -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,_},
|
||||
},
|
||||
};
|
||||
@ -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
|
||||
@ -1,4 +1,4 @@
|
||||
#include "DisplayMatrix_FontNumber.h"
|
||||
#include "DisplayMatrix_FontCommon.h"
|
||||
|
||||
Symbol4 FONT_NUMBER_SEGMENTS[] = {
|
||||
{
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
#ifndef DISPLAY_MATRIX_DRAW_H
|
||||
#define DISPLAY_MATRIX_DRAW_H
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::clear() {
|
||||
const auto backup = foreground;
|
||||
foreground = Black;
|
||||
cursorX = 0;
|
||||
cursorY = 0;
|
||||
fillRect(W, H);
|
||||
foreground = backup;
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::setPixel(const int x, const int y) {
|
||||
setPixel(x, y, foreground);
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::setPixel(int x, int y, RGBA color) {
|
||||
if (x < 0 || x >= W || y < 0 || y >= H) {
|
||||
return;
|
||||
}
|
||||
matrix[y][x] = color;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::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<int W, int H>
|
||||
void DisplayMatrix<W, H>::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<int W, int H>
|
||||
void DisplayMatrix<W, H>::drawLineWH(const int w, const int h, const int thickness) {
|
||||
if (w < 1 && h < 1) {
|
||||
return;
|
||||
}
|
||||
if (w >= h) {
|
||||
const auto m = static_cast<double>(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<int>(round(offset + x * m));
|
||||
setPixel(cursorY + y, cursorX + x);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto m = static_cast<double>(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<int>(round(offset + y * m));
|
||||
setPixel(cursorY + y, cursorX + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -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<int W, int H>
|
||||
void DisplayMatrix<W, H>::printf(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
printf(false, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::printf(const bool segments, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
printf(segments, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::printf(const bool segments, const char *format, const va_list args) {
|
||||
char buffer[64];
|
||||
vsnprintf(buffer, sizeof buffer, format, args);
|
||||
print(segments, buffer);
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::print(const char *message) {
|
||||
print(false, message);
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::print(const bool segments, const char *message) {
|
||||
while (*message != '\0') {
|
||||
print(segments, &message);
|
||||
cursorX += 2; // space between characters
|
||||
}
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::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<bool *>(FONT_CHAR_DEGREE), countof(FONT_CHAR_DEGREE[0]), countof(FONT_CHAR_DEGREE));
|
||||
default: return print(reinterpret_cast<bool *>(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<bool *>(FONT_CHAR_EURO), countof(FONT_CHAR_EURO[0]), countof(FONT_CHAR_EURO));
|
||||
default: return print(reinterpret_cast<bool *>(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_));
|
||||
}
|
||||
default: return print(reinterpret_cast<bool *>(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_));
|
||||
}
|
||||
}
|
||||
|
||||
if ('a' <= a && a <= 'z') {
|
||||
return print(reinterpret_cast<bool *>(FONT_LOWER[a - 'a']), countof(FONT_LOWER[a - 'a'][0]), countof(FONT_LOWER[a - 'a']));
|
||||
}
|
||||
if ('A' <= a && a <= 'Z') {
|
||||
return print(reinterpret_cast<bool *>(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<bool *>(FONT_NUMBER[a - '0']), countof(FONT_NUMBER[a - '0'][0]), countof(FONT_NUMBER[a - '0']));
|
||||
}
|
||||
return print(reinterpret_cast<bool *>(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<bool *>(FONT_CHAR_SPACE), countof(FONT_CHAR_SPACE[0]), countof(FONT_CHAR_SPACE));
|
||||
case '-': return print(reinterpret_cast<bool *>(FONT_CHAR_MINUS), countof(FONT_CHAR_MINUS[0]), countof(FONT_CHAR_MINUS));
|
||||
case '+': return print(reinterpret_cast<bool *>(FONT_CHAR_PLUS), countof(FONT_CHAR_PLUS[0]), countof(FONT_CHAR_PLUS));
|
||||
case '_': return print(reinterpret_cast<bool *>(FONT_CHAR_UNDERLINE), countof(FONT_CHAR_UNDERLINE[0]), countof(FONT_CHAR_UNDERLINE));
|
||||
case '%': return print(reinterpret_cast<bool *>(FONT_CHAR_PERCENT), countof(FONT_CHAR_PERCENT[0]), countof(FONT_CHAR_PERCENT));
|
||||
case '?': return print(reinterpret_cast<bool *>(FONT_CHAR_QUESTION), countof(FONT_CHAR_QUESTION[0]), countof(FONT_CHAR_QUESTION));
|
||||
case '!': return print(reinterpret_cast<bool *>(FONT_CHAR_EXCLAMATION), countof(FONT_CHAR_EXCLAMATION[0]), countof(FONT_CHAR_EXCLAMATION));
|
||||
case '.': return print(reinterpret_cast<bool *>(FONT_CHAR_POINT), countof(FONT_CHAR_POINT[0]), countof(FONT_CHAR_POINT));
|
||||
case ',': return print(reinterpret_cast<bool *>(FONT_CHAR_COMMA), countof(FONT_CHAR_COMMA[0]), countof(FONT_CHAR_COMMA));
|
||||
case ';': return print(reinterpret_cast<bool *>(FONT_CHAR_SEMICOLON), countof(FONT_CHAR_SEMICOLON[0]), countof(FONT_CHAR_SEMICOLON));
|
||||
case ':': return print(reinterpret_cast<bool *>(FONT_CHAR_COLON), countof(FONT_CHAR_COLON[0]), countof(FONT_CHAR_COLON));
|
||||
case '#': return print(reinterpret_cast<bool *>(FONT_CHAR_SHARP), countof(FONT_CHAR_SHARP[0]), countof(FONT_CHAR_SHARP));
|
||||
case '~': return print(reinterpret_cast<bool *>(FONT_CHAR_TILDE), countof(FONT_CHAR_TILDE[0]), countof(FONT_CHAR_TILDE));
|
||||
case '*': return print(reinterpret_cast<bool *>(FONT_CHAR_ASTERISK), countof(FONT_CHAR_ASTERISK[0]), countof(FONT_CHAR_ASTERISK));
|
||||
case '"': return print(reinterpret_cast<bool *>(FONT_CHAR_QUOTE_DOUBLE), countof(FONT_CHAR_QUOTE_DOUBLE[0]), countof(FONT_CHAR_QUOTE_DOUBLE));
|
||||
case '\'': return print(reinterpret_cast<bool *>(FONT_CHAR_QUOTE_SINGLE), countof(FONT_CHAR_QUOTE_SINGLE[0]), countof(FONT_CHAR_QUOTE_SINGLE));
|
||||
case '=': return print(reinterpret_cast<bool *>(FONT_CHAR_EQUALS), countof(FONT_CHAR_EQUALS[0]), countof(FONT_CHAR_EQUALS));
|
||||
case '(': return print(reinterpret_cast<bool *>(FONT_CHAR_PAR_L), countof(FONT_CHAR_PAR_L[0]), countof(FONT_CHAR_PAR_L));
|
||||
case ')': return print(reinterpret_cast<bool *>(FONT_CHAR_PAR_R), countof(FONT_CHAR_PAR_R[0]), countof(FONT_CHAR_PAR_R));
|
||||
case '[': return print(reinterpret_cast<bool *>(FONT_CHAR_BRACKET_L), countof(FONT_CHAR_BRACKET_L[0]), countof(FONT_CHAR_BRACKET_L));
|
||||
case ']': return print(reinterpret_cast<bool *>(FONT_CHAR_BRACKET_R), countof(FONT_CHAR_BRACKET_R[0]), countof(FONT_CHAR_BRACKET_R));
|
||||
case '{': return print(reinterpret_cast<bool *>(FONT_CHAR_CURL_L), countof(FONT_CHAR_CURL_L[0]), countof(FONT_CHAR_CURL_L));
|
||||
case '}': return print(reinterpret_cast<bool *>(FONT_CHAR_CURL_R), countof(FONT_CHAR_CURL_R[0]), countof(FONT_CHAR_CURL_R));
|
||||
case '/': return print(reinterpret_cast<bool *>(FONT_CHAR_SLASH), countof(FONT_CHAR_SLASH[0]), countof(FONT_CHAR_SLASH));
|
||||
case '\\': return print(reinterpret_cast<bool *>(FONT_CHAR_BACKSLASH), countof(FONT_CHAR_BACKSLASH[0]), countof(FONT_CHAR_BACKSLASH));
|
||||
case '&': return print(reinterpret_cast<bool *>(FONT_CHAR_AND), countof(FONT_CHAR_AND[0]), countof(FONT_CHAR_AND));
|
||||
case '|': return print(reinterpret_cast<bool *>(FONT_CHAR_PIPE), countof(FONT_CHAR_PIPE[0]), countof(FONT_CHAR_PIPE));
|
||||
case '$': return print(reinterpret_cast<bool *>(FONT_CHAR_DOLLAR), countof(FONT_CHAR_DOLLAR[0]), countof(FONT_CHAR_DOLLAR));
|
||||
case '@': return print(reinterpret_cast<bool *>(FONT_CHAR_AT), countof(FONT_CHAR_AT[0]), countof(FONT_CHAR_AT));
|
||||
case '<': return print(reinterpret_cast<bool *>(FONT_CHAR_LT), countof(FONT_CHAR_LT[0]), countof(FONT_CHAR_LT));
|
||||
case '>': return print(reinterpret_cast<bool *>(FONT_CHAR_GT), countof(FONT_CHAR_GT[0]), countof(FONT_CHAR_GT));
|
||||
default: return print(reinterpret_cast<bool *>(FONT_ERROR_), countof(FONT_ERROR_[0]), countof(FONT_ERROR_));
|
||||
}
|
||||
}
|
||||
|
||||
template<int W, int H>
|
||||
void DisplayMatrix<W, H>::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<int W, int H>
|
||||
void DisplayMatrix<W, H>::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
|
||||
Loading…
Reference in New Issue
Block a user