firmware/src/graphics/niche/InkHUD/AppletFont.cpp
todd-herbert e6a98b1d6b
InkHUD refactoring (#6216)
* chore: todo.txt
* chore: comments
* fix: no fast refresh on VME290
Reverts a line of code which was accidentally committed
* refactor: god class
Divide the behavior from the old WindowManager class into several subclasses which each have a clear role.
* refactor: cppcheck medium warnings
Enough to pass github CI for now
* refactor: updateType selection
* refactor: don't use a setter for the shared AppletFonts
* fix: update prioritization
forceUpdate calls weren't being prioritized
* refactor: remove unhelpful logging
getTimeString is used for parsing our own time, but also the timestamps of messages. The "one time only" log printing will likely fire in unhelpful situations.
* fix: " "
* refactor: get rid of types.h file for enums
* Keep that sneaky todo file out of commits
2025-03-06 11:25:41 +01:00

221 lines
7.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./AppletFont.h"
using namespace NicheGraphics;
InkHUD::AppletFont::AppletFont()
{
// Default constructor uses the in-built AdafruitGFX font
}
InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont) : gfxFont(&adafruitGFXFont)
{
// AdafruitGFX fonts are drawn relative to a "cursor line";
// they print as if the glyphs are resting on the line of piece of ruled paper.
// The glyphs also each have a different height.
// To simplify drawing, we will scan the entire font now, and determine an appropriate height for a line of text
// We also need to know where that "cursor line" sits inside this "line height";
// we need this additional info in order to align text by top-left, bottom-right, etc
// AdafruitGFX fonts do declare a line-height, but this seems to include a certain amount of padding,
// which we'd rather not deal with. If we want padding, we'll add it manually.
// Scan each glyph in the AdafruitGFX font
for (uint16_t i = 0; i <= (gfxFont->last - gfxFont->first); i++) {
uint8_t glyphHeight = gfxFont->glyph[i].height; // Height of glyph
this->height = max(this->height, glyphHeight); // Store if it's a new max
// Calculate how far the glyph rises the cursor line
// Store if new max value
// Caution: signed and unsigned types
int8_t glyphAscender = 0 - gfxFont->glyph[i].yOffset;
if (glyphAscender > 0)
this->ascenderHeight = max(this->ascenderHeight, (uint8_t)glyphAscender);
}
// Determine how far characters may hang "below the line"
descenderHeight = height - ascenderHeight;
// Find how far the cursor advances when we "print" a space character
spaceCharWidth = gfxFont->glyph[(uint8_t)' ' - gfxFont->first].xAdvance;
}
/*
▲ ##### # ▲
│ # # │
lineHeight │ ### # │
│ # # # # │ heightAboveCursor
│ # # # # │
│ # # #### │
│ -----------------#----
│ # │ heightBelowCursor
▼ ### ▼
*/
uint8_t InkHUD::AppletFont::lineHeight()
{
return this->height;
}
// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
// This value is the height of the font, above that imaginary line.
// Used to calculate the true height of the font
uint8_t InkHUD::AppletFont::heightAboveCursor()
{
return this->ascenderHeight;
}
// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
// This value is the height of the font, below that imaginary line.
// Used to calculate the true height of the font
uint8_t InkHUD::AppletFont::heightBelowCursor()
{
return this->descenderHeight;
}
// Width of the space character
// Used with Applet::printWrapped
uint8_t InkHUD::AppletFont::widthBetweenWords()
{
return this->spaceCharWidth;
}
// Add to the list of substituted glyphs
// This "find and replace" operation will be run before text is printed
// Used to swap out UTF8 special characters, either with a custom font, or with a suitable ASCII approximation
void InkHUD::AppletFont::addSubstitution(const char *from, const char *to)
{
substitutions.push_back({.from = from, .to = to});
}
// Run all registered substitutions on a string
// Used to swap out UTF8 special chars
void InkHUD::AppletFont::applySubstitutions(std::string *text)
{
// For each substitution
for (Substitution s : substitutions) {
// Find and replace
// - search for Substitution::from
// - replace with Substitution::to
size_t i = text->find(s.from);
while (i != std::string::npos) {
text->replace(i, strlen(s.from), s.to);
i = text->find(s.from, i); // Continue looking from last position
}
}
}
// Apply a set of substitutions which remap UTF8 for a Windows-1251 font
// Windows-1251 is an 8-bit character encoding, suitable for several languages which use the Cyrillic script
void InkHUD::AppletFont::addSubstitutionsWin1251()
{
addSubstitution("Ђ", "\x80");
addSubstitution("Ѓ", "\x81");
addSubstitution("ѓ", "\x83");
addSubstitution("", "\x88");
addSubstitution("Љ", "\x8A");
addSubstitution("Њ", "\x8C");
addSubstitution("Ќ", "\x8D");
addSubstitution("Ћ", "\x8E");
addSubstitution("Џ", "\x8F");
addSubstitution("ђ", "\x90");
addSubstitution("љ", "\x9A");
addSubstitution("њ", "\x9C");
addSubstitution("ќ", "\x9D");
addSubstitution("ћ", "\x9E");
addSubstitution("џ", "\x9F");
addSubstitution("Ў", "\xA1");
addSubstitution("ў", "\xA2");
addSubstitution("Ј", "\xA3");
addSubstitution("Ґ", "\xA5");
addSubstitution("Ё", "\xA8");
addSubstitution("Є", "\xAA");
addSubstitution("Ї", "\xAF");
addSubstitution("І", "\xB2");
addSubstitution("і", "\xB3");
addSubstitution("ґ", "\xB4");
addSubstitution("ё", "\xB8");
addSubstitution("", "\xB9");
addSubstitution("є", "\xBA");
addSubstitution("ј", "\xBC");
addSubstitution("Ѕ", "\xBD");
addSubstitution("ѕ", "\xBE");
addSubstitution("ї", "\xBF");
addSubstitution("А", "\xC0");
addSubstitution("Б", "\xC1");
addSubstitution("В", "\xC2");
addSubstitution("Г", "\xC3");
addSubstitution("Д", "\xC4");
addSubstitution("Е", "\xC5");
addSubstitution("Ж", "\xC6");
addSubstitution("З", "\xC7");
addSubstitution("И", "\xC8");
addSubstitution("Й", "\xC9");
addSubstitution("К", "\xCA");
addSubstitution("Л", "\xCB");
addSubstitution("М", "\xCC");
addSubstitution("Н", "\xCD");
addSubstitution("О", "\xCE");
addSubstitution("П", "\xCF");
addSubstitution("Р", "\xD0");
addSubstitution("С", "\xD1");
addSubstitution("Т", "\xD2");
addSubstitution("У", "\xD3");
addSubstitution("Ф", "\xD4");
addSubstitution("Х", "\xD5");
addSubstitution("Ц", "\xD6");
addSubstitution("Ч", "\xD7");
addSubstitution("Ш", "\xD8");
addSubstitution("Щ", "\xD9");
addSubstitution("Ъ", "\xDA");
addSubstitution("Ы", "\xDB");
addSubstitution("Ь", "\xDC");
addSubstitution("Э", "\xDD");
addSubstitution("Ю", "\xDE");
addSubstitution("Я", "\xDF");
addSubstitution("а", "\xE0");
addSubstitution("б", "\xE1");
addSubstitution("в", "\xE2");
addSubstitution("г", "\xE3");
addSubstitution("д", "\xE4");
addSubstitution("е", "\xE5");
addSubstitution("ж", "\xE6");
addSubstitution("з", "\xE7");
addSubstitution("и", "\xE8");
addSubstitution("й", "\xE9");
addSubstitution("к", "\xEA");
addSubstitution("л", "\xEB");
addSubstitution("м", "\xEC");
addSubstitution("н", "\xED");
addSubstitution("о", "\xEE");
addSubstitution("п", "\xEF");
addSubstitution("р", "\xF0");
addSubstitution("с", "\xF1");
addSubstitution("т", "\xF2");
addSubstitution("у", "\xF3");
addSubstitution("ф", "\xF4");
addSubstitution("х", "\xF5");
addSubstitution("ц", "\xF6");
addSubstitution("ч", "\xF7");
addSubstitution("ш", "\xF8");
addSubstitution("щ", "\xF9");
addSubstitution("ъ", "\xFA");
addSubstitution("ы", "\xFB");
addSubstitution("ь", "\xFC");
addSubstitution("э", "\xFD");
addSubstitution("ю", "\xFE");
addSubstitution("я", "\xFF");
}
#endif