Use readable 6px message font and keep 5px on tiny panels
This commit is contained in:
1 parent
5fe6f299f3
commit
272dc9aa4b
14 files changed
+1550
-93
No files matched your search
@@ -30,17 +30,11 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "SmallFontGlyph.h"
|
||||
|
||||
namespace mesh {
|
||||
namespace ui {
|
||||
|
||||
struct Pixel5Glyph {
|
||||
uint16_t bitmap_offset;
|
||||
uint8_t width, height, advance;
|
||||
int8_t x_offset, y_offset;
|
||||
};
|
||||
|
||||
static const uint8_t pixel5Bitmaps[] = {
|
||||
0xE8, 0xB4, 0x57, 0xD5, 0xF5, 0x00, 0x4E, 0x3E, 0x80, 0xA5, 0x4A, 0x4A,
|
||||
0x5A, 0x50, 0xC0, 0x6A, 0x40, 0x95, 0x80, 0xAA, 0x80, 0x5D, 0x00, 0x60,
|
||||
@@ -58,7 +52,7 @@ static const uint8_t pixel5Bitmaps[] = {
|
||||
0x90, 0xE8, 0x71, 0xE0, 0xBA, 0x40, 0xB5, 0x80, 0xB5, 0x00, 0x8D, 0x54,
|
||||
0xAA, 0x80, 0xAC, 0xE0, 0xE5, 0x70, 0x6A, 0x26, 0xFC, 0xC8, 0xAC, 0x5A};
|
||||
|
||||
static const Pixel5Glyph pixel5Glyphs[] = {{0, 0, 0, 2, 0, 1}, // 0x20 ' '
|
||||
static const SmallFontGlyph pixel5Glyphs[] = {{0, 0, 0, 2, 0, 1}, // 0x20 ' '
|
||||
{0, 1, 5, 2, 0, -4}, // 0x21 '!'
|
||||
{1, 3, 2, 4, 0, -4}, // 0x22 '"'
|
||||
{2, 5, 5, 6, 0, -4}, // 0x23 '#'
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mesh {
|
||||
namespace ui {
|
||||
|
||||
// Packed monochrome bitmap metrics, with GFX-style baseline offsets.
|
||||
struct SmallFontGlyph {
|
||||
uint16_t bitmap_offset;
|
||||
uint8_t width, height, advance;
|
||||
int8_t x_offset, y_offset;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace mesh
|
||||
@@ -3,25 +3,40 @@
|
||||
#include "DisplayDriver.h"
|
||||
#include "DisplayTextLayout.h"
|
||||
#include "Pixel5FontData.h"
|
||||
#include "Squeezed6FontData.h"
|
||||
|
||||
namespace mesh {
|
||||
namespace ui {
|
||||
|
||||
// Draw through the common pixel interface so OLED, TFT and U8g2 panels use
|
||||
// identical glyphs. This stack wrapper leaves the driver's normal font alone.
|
||||
class Pixel5Text : public DisplayDriver {
|
||||
class SmallMessageText : public DisplayDriver {
|
||||
DisplayDriver& _display;
|
||||
const bool _six_pixel;
|
||||
int _x = 0, _y = 0;
|
||||
|
||||
static const Pixel5Glyph& glyph(uint8_t c) {
|
||||
return pixel5Glyphs[(c >= 32 && c <= 126 ? c : '?') - 32];
|
||||
const SmallFontGlyph& glyph(uint8_t c) const {
|
||||
const int index = (c >= 32 && c <= 126 ? c : '?') - 32;
|
||||
return _six_pixel ? squeezed6Glyphs[index] : pixel5Glyphs[index];
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Pixel5Text(DisplayDriver& display)
|
||||
: DisplayDriver(display.width(), display.height()), _display(display) {}
|
||||
static constexpr int line_height = 7;
|
||||
static constexpr int glyph_height = 6; // 5px capitals plus descenders
|
||||
explicit SmallMessageText(DisplayDriver& display)
|
||||
: DisplayDriver(display.width(), display.height()), _display(display),
|
||||
_six_pixel((width() >= 128 && height() >= 64)
|
||||
|| (width() >= 64 && height() >= 128)) {}
|
||||
|
||||
// Preserve Picopixel on very tiny panels, including rotated 72x40 and
|
||||
// 128x32 screens. This wrapper is used only by the compact message UI.
|
||||
int capitalHeight() const { return _six_pixel ? 6 : 5; }
|
||||
int glyphHeight() const { return capitalHeight() + 1; } // descenders
|
||||
int lineHeight() const { return glyphHeight() + 1; } // blank row
|
||||
int lineCount(int y, int bottom = -1) const {
|
||||
if (bottom < 0 || bottom > height()) bottom = height();
|
||||
const int remaining = bottom - y;
|
||||
return remaining < glyphHeight() ? 0
|
||||
: 1 + (remaining - glyphHeight()) / lineHeight();
|
||||
}
|
||||
|
||||
bool isOn() override { return _display.isOn(); }
|
||||
void turnOn() override { _display.turnOn(); }
|
||||
@@ -48,13 +63,14 @@ public:
|
||||
}
|
||||
void print(const char* str) override {
|
||||
while (*str) {
|
||||
const Pixel5Glyph& g = glyph((uint8_t)*str++);
|
||||
const SmallFontGlyph& g = glyph((uint8_t)*str++);
|
||||
const uint8_t* bitmap = _six_pixel ? squeezed6Bitmaps : pixel5Bitmaps;
|
||||
for (int row = 0; row < g.height; ++row) {
|
||||
const int y = _y + 4 + g.y_offset + row;
|
||||
const int y = _y + capitalHeight() - 1 + g.y_offset + row;
|
||||
if (y < 0 || y >= height()) continue;
|
||||
for (int col = 0; col < g.width; ++col) {
|
||||
const int bit = row * g.width + col;
|
||||
if (!(pixel5Bitmaps[g.bitmap_offset + bit / 8]
|
||||
if (!(bitmap[g.bitmap_offset + bit / 8]
|
||||
& (0x80 >> (bit % 8)))) continue;
|
||||
const int x = _x + g.x_offset + col;
|
||||
if (x >= 0 && x < width()) _display.fillRect(x, y, 1, 1);
|
||||
@@ -65,32 +81,23 @@ public:
|
||||
}
|
||||
void printWordWrap(const char* str, int max_width) override {
|
||||
if (max_width > width() - _x) max_width = width() - _x;
|
||||
const int lines = (height() - _y + line_height - glyph_height) / line_height;
|
||||
drawTextWrapped(*this, _x, _y, max_width, line_height, lines, str);
|
||||
drawTextWrapped(*this, _x, _y, max_width, lineHeight(), lineCount(_y), str);
|
||||
}
|
||||
};
|
||||
|
||||
inline int smallMessageLineCount(int height, int message_y) {
|
||||
const int remaining = height - message_y;
|
||||
return remaining < Pixel5Text::glyph_height ? 0
|
||||
: (remaining + Pixel5Text::line_height - Pixel5Text::glyph_height)
|
||||
/ Pixel5Text::line_height;
|
||||
}
|
||||
|
||||
inline void drawSmallMessageBody(DisplayDriver& display, const char* origin,
|
||||
const char* message, int origin_y = 14,
|
||||
int message_y = 21, int bottom = -1) {
|
||||
Pixel5Text text(display);
|
||||
int bottom = -1) {
|
||||
SmallMessageText text(display);
|
||||
const int message_y = origin_y + text.lineHeight();
|
||||
char translated[161];
|
||||
text.translateUTF8ToBlocks(translated, origin, sizeof(translated));
|
||||
text.setColor(UIColor::secondary_txt);
|
||||
text.drawTextEllipsized(0, origin_y, display.width(), translated);
|
||||
text.translateUTF8ToBlocks(translated, message, sizeof(translated));
|
||||
text.setColor(UIColor::primary_txt);
|
||||
const int height = bottom < 0 || bottom > display.height()
|
||||
? display.height() : bottom;
|
||||
drawTextWrapped(text, 0, message_y, display.width(), Pixel5Text::line_height,
|
||||
smallMessageLineCount(height, message_y), translated);
|
||||
drawTextWrapped(text, 0, message_y, display.width(), text.lineHeight(),
|
||||
text.lineCount(message_y, bottom), translated);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
// Squeezed Regular 6 by Oliver Kraus. Public domain.
|
||||
// Lossless conversion of the ASCII glyphs from the upstream BDF.
|
||||
// Source: https://raw.githubusercontent.com/olikraus/u8g2/57d191014bebc263868526491e7f7c33ddcf6042/tools/font/bdf/u8g2_squeezed_regular_6.bdf
|
||||
// BDF SHA-256: a50740bd62accaa104e52da98210b3db10e03d75c6fbac1a31010177fad92277
|
||||
// Reference: test/fixtures/small_message_font/squeezed6.bdf
|
||||
|
||||
#include "SmallFontGlyph.h"
|
||||
|
||||
namespace mesh {
|
||||
namespace ui {
|
||||
|
||||
static const uint8_t squeezed6Bitmaps[] = {
|
||||
0xF4, 0xB4, 0x57, 0xD5, 0xF5, 0x00, 0x23, 0xE8, 0xE2, 0xF8, 0x80, 0xA5,
|
||||
0x29, 0x40, 0x4A, 0x4A, 0xA5, 0xC0, 0x6A, 0x90, 0x95, 0x60, 0xAB, 0xAA,
|
||||
0x5D, 0x00, 0xC0, 0xC0, 0x80, 0x25, 0x29, 0x00, 0x56, 0xDA, 0x80, 0x75,
|
||||
0x50, 0x96, 0xB0, 0xD9, 0x60, 0xB7, 0x92, 0x40, 0xE9, 0x60, 0x53, 0x5A,
|
||||
0x80, 0xE5, 0x24, 0x80, 0x55, 0x5A, 0x80, 0x55, 0x92, 0x80, 0xA0, 0x98,
|
||||
0x64, 0xCC, 0x98, 0x9A, 0x20, 0x69, 0xBB, 0x87, 0x57, 0xDB, 0x40, 0xD7,
|
||||
0x5B, 0x80, 0x6A, 0x90, 0xD6, 0xDB, 0x80, 0xEE, 0xB0, 0xEE, 0xA0, 0x72,
|
||||
0xDA, 0xC0, 0xB7, 0xDB, 0x40, 0xFC, 0x55, 0x70, 0xB7, 0x5B, 0x40, 0xAA,
|
||||
0xB0, 0x8E, 0xEB, 0x18, 0xC4, 0x9D, 0xB9, 0x99, 0x56, 0xDA, 0x80, 0xD7,
|
||||
0x49, 0x00, 0x56, 0xDA, 0xC0, 0xD7, 0x5B, 0x40, 0x69, 0x60, 0xE9, 0x24,
|
||||
0x80, 0xB6, 0xDB, 0xC0, 0xB6, 0xD4, 0x80, 0x8C, 0x63, 0x5A, 0xA8, 0xB5,
|
||||
0x2B, 0x40, 0xB6, 0xA4, 0x80, 0xD6, 0xB0, 0xEA, 0xB0, 0x91, 0x22, 0x40,
|
||||
0xD5, 0x70, 0x54, 0xC0, 0x90, 0x76, 0xB0, 0x93, 0x5B, 0x80, 0x69, 0x25,
|
||||
0xDA, 0xC0, 0x57, 0x30, 0x6E, 0xA0, 0x75, 0x9C, 0x93, 0x5B, 0x40, 0xBC,
|
||||
0x45, 0x58, 0x92, 0xEB, 0x40, 0xFC, 0xF5, 0x6B, 0x50, 0xD6, 0xD0, 0x56,
|
||||
0xA0, 0xD6, 0xE8, 0x76, 0xB2, 0xBA, 0x40, 0x66, 0xAE, 0x90, 0xB6, 0xF0,
|
||||
0xB6, 0xE0, 0x8D, 0x6A, 0xA0, 0xA9, 0x50, 0xB5, 0x94, 0xDB, 0x2B, 0x24,
|
||||
0x40, 0xFC, 0x89, 0xA5, 0x00, 0x5A,
|
||||
};
|
||||
|
||||
static const SmallFontGlyph squeezed6Glyphs[] = {
|
||||
{0, 0, 0, 2, 0, 1}, // ASCII 32
|
||||
{0, 1, 6, 2, 0, -5}, // ASCII 33
|
||||
{1, 3, 2, 4, 0, -5}, // ASCII 34
|
||||
{2, 5, 5, 6, 0, -4}, // ASCII 35
|
||||
{6, 5, 7, 6, 0, -5}, // ASCII 36
|
||||
{11, 3, 6, 4, 0, -5}, // ASCII 37
|
||||
{14, 4, 6, 5, 0, -5}, // ASCII 38
|
||||
{17, 1, 2, 2, 0, -5}, // ASCII 39
|
||||
{18, 2, 6, 3, 0, -5}, // ASCII 40
|
||||
{20, 2, 6, 3, 0, -5}, // ASCII 41
|
||||
{22, 3, 5, 4, 0, -5}, // ASCII 42
|
||||
{24, 3, 3, 4, 0, -4}, // ASCII 43
|
||||
{26, 1, 2, 2, 0, 0}, // ASCII 44
|
||||
{27, 2, 1, 3, 0, -3}, // ASCII 45
|
||||
{28, 1, 1, 2, 0, 0}, // ASCII 46
|
||||
{29, 3, 6, 4, 0, -5}, // ASCII 47
|
||||
{32, 3, 6, 4, 0, -5}, // ASCII 48
|
||||
{35, 2, 6, 3, 0, -5}, // ASCII 49
|
||||
{37, 2, 6, 3, 0, -5}, // ASCII 50
|
||||
{39, 2, 6, 3, 0, -5}, // ASCII 51
|
||||
{41, 3, 6, 4, 0, -5}, // ASCII 52
|
||||
{44, 2, 6, 3, 0, -5}, // ASCII 53
|
||||
{46, 3, 6, 4, 0, -5}, // ASCII 54
|
||||
{49, 3, 6, 4, 0, -5}, // ASCII 55
|
||||
{52, 3, 6, 4, 0, -5}, // ASCII 56
|
||||
{55, 3, 6, 4, 0, -5}, // ASCII 57
|
||||
{58, 1, 3, 2, 0, -3}, // ASCII 58
|
||||
{59, 1, 5, 2, 0, -3}, // ASCII 59
|
||||
{60, 2, 3, 3, 0, -4}, // ASCII 60
|
||||
{61, 2, 3, 3, 0, -4}, // ASCII 61
|
||||
{62, 2, 3, 3, 0, -4}, // ASCII 62
|
||||
{63, 2, 6, 3, 0, -5}, // ASCII 63
|
||||
{65, 4, 6, 5, 0, -5}, // ASCII 64
|
||||
{68, 3, 6, 4, 0, -5}, // ASCII 65
|
||||
{71, 3, 6, 4, 0, -5}, // ASCII 66
|
||||
{74, 2, 6, 3, 0, -5}, // ASCII 67
|
||||
{76, 3, 6, 4, 0, -5}, // ASCII 68
|
||||
{79, 2, 6, 3, 0, -5}, // ASCII 69
|
||||
{81, 2, 6, 3, 0, -5}, // ASCII 70
|
||||
{83, 3, 6, 4, 0, -5}, // ASCII 71
|
||||
{86, 3, 6, 4, 0, -5}, // ASCII 72
|
||||
{89, 1, 6, 2, 0, -5}, // ASCII 73
|
||||
{90, 2, 6, 3, 0, -5}, // ASCII 74
|
||||
{92, 3, 6, 4, 0, -5}, // ASCII 75
|
||||
{95, 2, 6, 3, 0, -5}, // ASCII 76
|
||||
{97, 5, 6, 6, 0, -5}, // ASCII 77
|
||||
{101, 4, 6, 5, 0, -5}, // ASCII 78
|
||||
{104, 3, 6, 4, 0, -5}, // ASCII 79
|
||||
{107, 3, 6, 4, 0, -5}, // ASCII 80
|
||||
{110, 3, 6, 4, 0, -5}, // ASCII 81
|
||||
{113, 3, 6, 4, 0, -5}, // ASCII 82
|
||||
{116, 2, 6, 3, 0, -5}, // ASCII 83
|
||||
{118, 3, 6, 4, 0, -5}, // ASCII 84
|
||||
{121, 3, 6, 4, 0, -5}, // ASCII 85
|
||||
{124, 3, 6, 4, 0, -5}, // ASCII 86
|
||||
{127, 5, 6, 6, 0, -5}, // ASCII 87
|
||||
{131, 3, 6, 4, 0, -5}, // ASCII 88
|
||||
{134, 3, 6, 4, 0, -5}, // ASCII 89
|
||||
{137, 2, 6, 3, 0, -5}, // ASCII 90
|
||||
{139, 2, 6, 3, 0, -5}, // ASCII 91
|
||||
{141, 3, 6, 4, 0, -5}, // ASCII 92
|
||||
{144, 2, 6, 3, 0, -5}, // ASCII 93
|
||||
{146, 3, 2, 4, 0, -5}, // ASCII 94
|
||||
{147, 2, 1, 3, 0, 0}, // ASCII 95
|
||||
{148, 2, 2, 3, 0, -5}, // ASCII 96
|
||||
{149, 3, 4, 4, 0, -3}, // ASCII 97
|
||||
{151, 3, 6, 4, 0, -5}, // ASCII 98
|
||||
{154, 2, 4, 3, 0, -3}, // ASCII 99
|
||||
{155, 3, 6, 4, 0, -5}, // ASCII 100
|
||||
{158, 3, 4, 4, 0, -3}, // ASCII 101
|
||||
{160, 2, 6, 3, 0, -5}, // ASCII 102
|
||||
{162, 3, 5, 4, 0, -3}, // ASCII 103
|
||||
{164, 3, 6, 4, 0, -5}, // ASCII 104
|
||||
{167, 1, 6, 2, 0, -5}, // ASCII 105
|
||||
{168, 2, 7, 3, 0, -5}, // ASCII 106
|
||||
{170, 3, 6, 4, 0, -5}, // ASCII 107
|
||||
{173, 1, 6, 2, 0, -5}, // ASCII 108
|
||||
{174, 5, 4, 6, 0, -3}, // ASCII 109
|
||||
{177, 3, 4, 4, 0, -3}, // ASCII 110
|
||||
{179, 3, 4, 4, 0, -3}, // ASCII 111
|
||||
{181, 3, 5, 4, 0, -3}, // ASCII 112
|
||||
{183, 3, 5, 4, 0, -3}, // ASCII 113
|
||||
{185, 3, 4, 4, 0, -3}, // ASCII 114
|
||||
{187, 2, 4, 3, 0, -3}, // ASCII 115
|
||||
{188, 2, 6, 3, 0, -5}, // ASCII 116
|
||||
{190, 3, 4, 4, 0, -3}, // ASCII 117
|
||||
{192, 3, 4, 4, 0, -3}, // ASCII 118
|
||||
{194, 5, 4, 6, 0, -3}, // ASCII 119
|
||||
{197, 3, 4, 4, 0, -3}, // ASCII 120
|
||||
{199, 3, 5, 4, 0, -3}, // ASCII 121
|
||||
{201, 2, 4, 3, 0, -3}, // ASCII 122
|
||||
{202, 3, 6, 4, 0, -5}, // ASCII 123
|
||||
{205, 1, 6, 2, 0, -5}, // ASCII 124
|
||||
{206, 3, 6, 4, 0, -5}, // ASCII 125
|
||||
{209, 4, 2, 5, 0, -5}, // ASCII 126
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace mesh
|
||||
Reference in new issue
Block a user