From 83cbc17d3ac1988ccffb669279c48d0d89bed77e Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 15 May 2022 17:56:48 +0200 Subject: [PATCH 01/32] [AdaGFX] Add optional Roboto fonts --- docs/source/Plugin/AdaGFX_commands.repl | 14 + src/src/Helpers/AdafruitGFX_helper.cpp | 72 ++++ src/src/Helpers/AdafruitGFX_helper.h | 18 +- .../Fonts/RobotoCondensed_Regular12pt7b.h | 247 ++++++++++++ .../Fonts/RobotoCondensed_Regular16pt7b.h | 340 ++++++++++++++++ .../Fonts/RobotoCondensed_Regular8pt7b.h | 172 ++++++++ .../Static/Fonts/RobotoMono_Regular12pt7b.h | 265 +++++++++++++ .../Static/Fonts/RobotoMono_Regular16pt7b.h | 369 +++++++++++++++++ .../Static/Fonts/RobotoMono_Regular8pt7b.h | 180 +++++++++ src/src/Static/Fonts/Roboto_Regular12pt7b.h | 265 +++++++++++++ src/src/Static/Fonts/Roboto_Regular16pt7b.h | 371 ++++++++++++++++++ src/src/Static/Fonts/Roboto_Regular8pt7b.h | 183 +++++++++ 12 files changed, 2493 insertions(+), 3 deletions(-) create mode 100644 src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h create mode 100644 src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h create mode 100644 src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h create mode 100644 src/src/Static/Fonts/RobotoMono_Regular12pt7b.h create mode 100644 src/src/Static/Fonts/RobotoMono_Regular16pt7b.h create mode 100644 src/src/Static/Fonts/RobotoMono_Regular8pt7b.h create mode 100644 src/src/Static/Fonts/Roboto_Regular12pt7b.h create mode 100644 src/src/Static/Fonts/Roboto_Regular16pt7b.h create mode 100644 src/src/Static/Fonts/Roboto_Regular8pt7b.h diff --git a/docs/source/Plugin/AdaGFX_commands.repl b/docs/source/Plugin/AdaGFX_commands.repl index dd86b1a34..877638ddd 100644 --- a/docs/source/Plugin/AdaGFX_commands.repl +++ b/docs/source/Plugin/AdaGFX_commands.repl @@ -108,16 +108,30 @@ * *unispace8pt* A modern 12 * 24 font * *unispaceitalic8pt* A modern italic (slanted) 12 * 24 font * *whiterabbit8pt* A modern 12 * 24 font + * *robotomono8pt* A modern 8 * 10 font * *angelina12prop* A proportional, handwriting, 8 * 24 font * *novamono12pt* A modern 13 * 34 font * *repetitionscrolling12pt* A modern 13 * 24 font * *unispace12pt* A modern 13 * 18 font * *unispaceitalic12pt* A modern italic (slanted) 13 * 18 font * *whiterabbit12pt* A modern 13 * 18 font + * *robotomono12pt* A modern 13 * 18 font * *amerikasans16pt* A proportional 17 * 20 font * *whiterabbit16pt* A modern 16 * 20 font + * *robotomono16pt* A modern 16 * 20 font * *whiterabbit18pt* A modern 18 * 22 font * *whiterabbit20pt* A modern 20 * 24 font + + Standard disabled fonts (even on MAX builds), that can be enabled in a custom build: + + * *roboto8pt* A modern 9 * 16 font (proportionally spaced) + * *roboto12pt* A modern 13 * 18 font (proportionally spaced) + * *roboto16pt* A modern 16 * 20 font (proportionally spaced) + * *robotocond8pt* A modern 9 * 16 font (Roboto Condensed, proportionally spaced) + * *robotocond12pt* A modern 13 * 18 font (Roboto Condensed, proportionally spaced) + * *robotocond16pt* A modern 16 * 20 font (Roboto Condensed, proportionally spaced) + + NB: Roboto is used as the default Android font since Android 4.1. " " ``,l,,,,,`` diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 3069c25a5..3db5c60b3 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -19,6 +19,15 @@ # include "src/Static/Fonts/unispace8pt7b.h" # include "src/Static/Fonts/unispace_italic8pt7b.h" # include "src/Static/Fonts/whitrabt8pt7b.h" +# ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO +# include "src/Static/Fonts/Roboto_Regular8pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO +# ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED +# include "src/Static/Fonts/RobotoCondensed_Regular8pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED +# ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO +# include "src/Static/Fonts/RobotoMono_Regular8pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED # include "src/Static/Fonts/angelina12pt7b.h" @@ -27,10 +36,28 @@ # include "src/Static/Fonts/unispace12pt7b.h" # include "src/Static/Fonts/unispace_italic12pt7b.h" # include "src/Static/Fonts/whitrabt12pt7b.h" +# ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO +# include "src/Static/Fonts/Roboto_Regular12pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO +# ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED +# include "src/Static/Fonts/RobotoCondensed_Regular12pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED +# ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO +# include "src/Static/Fonts/RobotoMono_Regular12pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # include "src/Static/Fonts/AmerikaSans16pt7b.h" # include "src/Static/Fonts/whitrabt16pt7b.h" +# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# include "src/Static/Fonts/Roboto_Regular16pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# include "src/Static/Fonts/RobotoCondensed_Regular16pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# include "src/Static/Fonts/RobotoMono_Regular16pt7b.h" +# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_18PT_INCLUDED # include "src/Static/Fonts/whitrabt18pt7b.h" @@ -796,6 +823,21 @@ bool AdafruitGFX_helper::processCommand(const String& string) { _display->setFont(&whitrabt8pt7b); calculateTextMetrics(10, 16, 12); # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_WHITERABBiT + # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO + } else if (sParams[0].equals(F("roboto8pt"))) { // Proportional font! + _display->setFont(&Roboto_Regular8pt7b); + calculateTextMetrics(10, 16, 12, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO + # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED + } else if (sParams[0].equals(F("robotocond8pt"))) { // Proportional font! + _display->setFont(&RobotoCondensed_Regular8pt7b); + calculateTextMetrics(9, 16, 12, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED + # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO + } else if (sParams[0].equals(F("robotomono8pt"))) { + _display->setFont(&RobotoMono_Regular8pt7b); + calculateTextMetrics(10, 16, 12); + # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_INCLUDED // Extra 12pt fonts: # ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED @@ -829,6 +871,21 @@ bool AdafruitGFX_helper::processCommand(const String& string) { _display->setFont(&whitrabt12pt7b); calculateTextMetrics(13, 20, 16); # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_WHITERABBiT + # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO + } else if (sParams[0].equals(F("roboto12pt"))) { // Proportional font! + _display->setFont(&Roboto_Regular12pt7b); + calculateTextMetrics(13, 20, 16, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO + # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED + } else if (sParams[0].equals(F("robotocond12pt"))) { // Proportional font! + _display->setFont(&RobotoCondensed_Regular12pt7b); + calculateTextMetrics(13, 20, 16, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED + # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO + } else if (sParams[0].equals(F("robotomono12pt"))) { + _display->setFont(&RobotoMono_Regular12pt7b); + calculateTextMetrics(13, 20, 16); + # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_16PT_AMERIKASANS @@ -841,6 +898,21 @@ bool AdafruitGFX_helper::processCommand(const String& string) { _display->setFont(&whitrabt16pt7b); calculateTextMetrics(18, 26, 22); # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_WHITERABBiT + # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO + } else if (sParams[0].equals(F("roboto16pt"))) { // Proportional font! + _display->setFont(&Roboto_Regular16pt7b); + calculateTextMetrics(18, 27, 23, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO + # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED + } else if (sParams[0].equals(F("robotocond16pt"))) { // Proportional font! + _display->setFont(&RobotoCondensed_Regular16pt7b); + calculateTextMetrics(18, 27, 23, true); + # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED + # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO + } else if (sParams[0].equals(F("robotomono16pt"))) { + _display->setFont(&RobotoMono_Regular16pt7b); + calculateTextMetrics(18, 27, 23); + # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_18PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_18PT_WHITERABBiT diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 34f93c337..dc5a60b21 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -45,9 +45,9 @@ # define ADAGFX_ENABLE_BMP_DISPLAY 1 // Enable subcommands for displaying .bmp files on supported displays (color) # endif // ifndef ADAGFX_ENABLE_BMP_DISPLAY -// # define ADAGFX_FONTS_EXTRA_8PT_INCLUDED // 5 extra 8pt fonts, should probably only be enabled in a private custom build, adds ~10,4 kB -// # define ADAGFX_FONTS_EXTRA_12PT_INCLUDED // 6 extra 12pt fonts, should probably only be enabled in a private custom build, adds ~19,8 kB -// # define ADAGFX_FONTS_EXTRA_16PT_INCLUDED // 2 extra 16pt fonts, should probably only be enabled in a private custom build, adds ~7.7 kB +// # define ADAGFX_FONTS_EXTRA_8PT_INCLUDED // 8 extra 8pt fonts, should probably only be enabled in a private custom build, adds ~15.4 kB +// # define ADAGFX_FONTS_EXTRA_12PT_INCLUDED // 9 extra 12pt fonts, should probably only be enabled in a private custom build, adds ~28 kB +// # define ADAGFX_FONTS_EXTRA_16PT_INCLUDED // 5 extra 16pt fonts, should probably only be enabled in a private custom build, adds ~19.9 kB // # define ADAGFX_FONTS_EXTRA_18PT_INCLUDED // 1 extra 18pt fonts, should probably only be enabled in a private custom build, adds ~4.3 kB // # define ADAGFX_FONTS_EXTRA_20PT_INCLUDED // 1 extra 20pt fonts, should probably only be enabled in a private custom build, adds ~5.3 kB @@ -58,6 +58,10 @@ # define ADAGFX_FONTS_EXTRA_8PT_UNISPACEITALIC # define ADAGFX_FONTS_EXTRA_8PT_WHITERABBiT +// # define ADAGFX_FONTS_EXTRA_8PT_ROBOTO // This font is proportinally spaced! +// # define ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED // This font is proportinally spaced! +# define ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO + // To enable/disable 12pt fonts separately: (will only be enabled if ADAGFX_FONTS_EXTRA_12PT_INCLUDED is defined) # define ADAGFX_FONTS_EXTRA_12PT_ANGELINA // This font is proportinally spaced! # define ADAGFX_FONTS_EXTRA_12PT_NOVAMONO @@ -66,10 +70,18 @@ # define ADAGFX_FONTS_EXTRA_12PT_UNISPACEITALIC # define ADAGFX_FONTS_EXTRA_12PT_WHITERABBiT +// # define ADAGFX_FONTS_EXTRA_12PT_ROBOTO // This font is proportinally spaced! +// # define ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED // This font is proportinally spaced! +# define ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO + // To enable/disable 16pt fonts separately: (will only be enabled if ADAGFX_FONTS_EXTRA_16PT_INCLUDED is defined) # define ADAGFX_FONTS_EXTRA_16PT_AMERIKASANS // This font is proportinally spaced! # define ADAGFX_FONTS_EXTRA_16PT_WHITERABBiT +// # define ADAGFX_FONTS_EXTRA_16PT_ROBOTO // This font is proportinally spaced! +// # define ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED // This font is proportinally spaced! +# define ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO + // To enable/disable 18pt fonts separately: (will only be enabled if ADAGFX_FONTS_EXTRA_18PT_INCLUDED is defined) # define ADAGFX_FONTS_EXTRA_18PT_WHITERABBiT diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h new file mode 100644 index 000000000..9e4303ca1 --- /dev/null +++ b/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h @@ -0,0 +1,247 @@ +const uint8_t RobotoCondensed_Regular12pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xDE, 0xF7, 0xB9, 0xC8, 0x0C, 0x81, + 0x30, 0x66, 0x0C, 0xCF, 0xFF, 0xFF, 0xC4, 0x40, 0x98, 0x33, 0x06, 0x63, + 0xFF, 0x7F, 0xE3, 0x20, 0x44, 0x09, 0x83, 0x30, 0x66, 0x00, 0x0C, 0x03, + 0x00, 0xC0, 0x78, 0x3F, 0x1C, 0xE6, 0x19, 0x87, 0x60, 0x1C, 0x03, 0xC0, + 0x7C, 0x07, 0x80, 0x60, 0x1F, 0x07, 0xE1, 0xD8, 0xE7, 0xF8, 0xF8, 0x0C, + 0x03, 0x00, 0x38, 0x01, 0xF0, 0x0C, 0xC6, 0x31, 0x10, 0xC4, 0xC3, 0x32, + 0x07, 0xD8, 0x0E, 0x40, 0x03, 0x00, 0x09, 0xC0, 0x6F, 0x81, 0x33, 0x0D, + 0x8C, 0x26, 0x31, 0x8C, 0xC4, 0x3E, 0x00, 0x70, 0x1E, 0x03, 0xF0, 0x73, + 0x86, 0x18, 0x63, 0x87, 0x30, 0x36, 0x03, 0xC0, 0x3C, 0x07, 0xE3, 0xE6, + 0x3C, 0x76, 0xC3, 0xEC, 0x1E, 0xE1, 0xC7, 0xFE, 0x3E, 0x70, 0xFF, 0xA0, + 0x08, 0x31, 0x8C, 0x31, 0x86, 0x18, 0x63, 0x8E, 0x38, 0xE3, 0x8E, 0x18, + 0x61, 0x86, 0x0C, 0x30, 0x60, 0x83, 0x43, 0x06, 0x0C, 0x30, 0x61, 0x86, + 0x18, 0x71, 0xC3, 0x1C, 0x71, 0xC6, 0x18, 0x61, 0x8C, 0x31, 0x84, 0x30, + 0x0C, 0x06, 0x03, 0x0D, 0xBF, 0xF8, 0xE0, 0x70, 0x6C, 0x33, 0x31, 0x00, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, + 0x00, 0xC0, 0x30, 0xFF, 0x6D, 0x00, 0xFF, 0xC0, 0xF0, 0x03, 0x06, 0x06, + 0x06, 0x0C, 0x0C, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x20, 0x60, + 0x60, 0x40, 0xC0, 0x1E, 0x0F, 0xC7, 0x39, 0x86, 0xE1, 0xB8, 0x7E, 0x1F, + 0x87, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0x98, 0x67, 0x38, 0xFC, 0x1E, + 0x00, 0x1F, 0xFE, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, + 0x3E, 0x1F, 0xC6, 0x3B, 0x86, 0xC1, 0x80, 0x60, 0x18, 0x0E, 0x07, 0x01, + 0x80, 0xE0, 0x70, 0x38, 0x0C, 0x07, 0x03, 0xFF, 0xFF, 0xC0, 0x3E, 0x3F, + 0xB8, 0xFC, 0x3C, 0x18, 0x0C, 0x0E, 0x3E, 0x1F, 0x01, 0xC0, 0x60, 0x3C, + 0x1E, 0x0F, 0x8E, 0xFE, 0x3E, 0x00, 0x03, 0x01, 0xC0, 0xF0, 0x3C, 0x1B, + 0x06, 0xC3, 0x30, 0xCC, 0x63, 0x18, 0xCC, 0x33, 0xFF, 0xFF, 0xC0, 0xC0, + 0x30, 0x0C, 0x03, 0x00, 0x7F, 0x9F, 0xE6, 0x01, 0x80, 0x60, 0x18, 0x06, + 0xE1, 0xFE, 0x63, 0x88, 0x60, 0x1C, 0x07, 0xE1, 0xF8, 0x67, 0x39, 0xFC, + 0x1E, 0x00, 0x0F, 0x0F, 0xE7, 0x11, 0x80, 0xE0, 0x38, 0x0E, 0xF3, 0xFE, + 0xE3, 0xB8, 0x7E, 0x1F, 0x83, 0xE1, 0xD8, 0x77, 0x38, 0xFE, 0x1E, 0x00, + 0xFF, 0xFF, 0xF0, 0x18, 0x0E, 0x03, 0x01, 0x80, 0x60, 0x38, 0x0C, 0x03, + 0x01, 0xC0, 0x70, 0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x00, 0x1E, 0x1F, + 0xC7, 0x3B, 0x86, 0xE1, 0x98, 0x67, 0x38, 0xFC, 0x3F, 0x18, 0xEE, 0x1B, + 0x07, 0xC1, 0xF8, 0x7E, 0x39, 0xFE, 0x1E, 0x00, 0x1E, 0x3F, 0x98, 0xFC, + 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE1, 0xB1, 0xDF, 0xE7, 0xB0, 0x18, 0x0C, + 0x0E, 0xFE, 0x3E, 0x00, 0xF0, 0x00, 0x03, 0xC0, 0x6C, 0x00, 0x00, 0x01, + 0xB7, 0xB6, 0x03, 0x0F, 0x1E, 0x78, 0xE0, 0xE0, 0x78, 0x1E, 0x0F, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x78, 0x0F, 0x01, 0xE0, + 0x38, 0x1C, 0x3C, 0x78, 0xF0, 0x60, 0x00, 0x3C, 0xFE, 0xE7, 0xC3, 0x03, + 0x03, 0x03, 0x07, 0x0E, 0x0C, 0x18, 0x18, 0x38, 0x00, 0x00, 0x38, 0x38, + 0x03, 0xF0, 0x07, 0xFE, 0x07, 0x03, 0x87, 0x00, 0xE3, 0x00, 0x33, 0x0F, + 0x09, 0x8F, 0xC6, 0x86, 0x63, 0xC6, 0x31, 0xE3, 0x18, 0x71, 0x8C, 0x38, + 0x86, 0x3C, 0xC3, 0x1E, 0x61, 0x8F, 0x19, 0xCD, 0x8F, 0xFE, 0x63, 0x9C, + 0x30, 0x00, 0x0C, 0x00, 0x07, 0x82, 0x01, 0xFF, 0x00, 0x3F, 0x00, 0x07, + 0x00, 0x38, 0x01, 0xE0, 0x1F, 0x00, 0xD8, 0x06, 0xE0, 0x33, 0x03, 0x98, + 0x18, 0xC0, 0xC7, 0x0E, 0x18, 0x7F, 0xC3, 0xFF, 0x38, 0x19, 0xC0, 0xCC, + 0x07, 0xE0, 0x38, 0xFE, 0x3F, 0xEC, 0x3B, 0x06, 0xC1, 0xF0, 0x6C, 0x3B, + 0xFC, 0xFF, 0xB0, 0x6C, 0x1F, 0x03, 0xC0, 0xF0, 0x7C, 0x1F, 0xFE, 0xFF, + 0x00, 0x1F, 0x07, 0xF9, 0xC7, 0x70, 0x7E, 0x0F, 0x80, 0x30, 0x06, 0x00, + 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0E, 0x0E, 0xC1, 0xDC, 0x71, 0xFE, 0x1F, + 0x00, 0xFE, 0x1F, 0xE3, 0x0E, 0x60, 0xEC, 0x0D, 0x81, 0xB0, 0x36, 0x07, + 0xC0, 0xF8, 0x1F, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0xB0, 0xE7, 0xF8, 0xFE, + 0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xFF, 0x60, + 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xF0, + 0x18, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, + 0x03, 0x01, 0x80, 0xC0, 0x00, 0x1F, 0x87, 0xF9, 0xC3, 0xB0, 0x3E, 0x07, + 0xC0, 0x38, 0x07, 0x00, 0xE3, 0xFC, 0x7F, 0x81, 0xF0, 0x3E, 0x06, 0xC0, + 0xDC, 0x39, 0xFE, 0x0F, 0x80, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, + 0x80, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, + 0xF0, 0x1E, 0x03, 0xC0, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0x80, + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, + 0x1E, 0x1F, 0x8C, 0xFE, 0x3E, 0x00, 0xC0, 0xF8, 0x3B, 0x0E, 0x61, 0x8C, + 0x71, 0x9C, 0x33, 0x07, 0xE0, 0xFC, 0x19, 0x83, 0x18, 0x63, 0x8C, 0x31, + 0x87, 0x30, 0x76, 0x0E, 0xC0, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, + 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0xFF, + 0xFF, 0x80, 0xE0, 0x1F, 0x80, 0xFE, 0x03, 0xFC, 0x0F, 0xF0, 0x6F, 0xC1, + 0xBD, 0x86, 0xF6, 0x17, 0xD8, 0xDF, 0x23, 0x7C, 0xCD, 0xF3, 0x67, 0xCD, + 0x9F, 0x1E, 0x7C, 0x71, 0xF1, 0xC7, 0xC3, 0x1C, 0xC0, 0x7C, 0x0F, 0x81, + 0xF8, 0x3F, 0x07, 0xB0, 0xF6, 0x1E, 0x63, 0xCC, 0x78, 0xCF, 0x19, 0xE1, + 0xBC, 0x37, 0x83, 0xF0, 0x7E, 0x07, 0xC0, 0xE0, 0x1F, 0x03, 0xFC, 0x70, + 0xEE, 0x06, 0xE0, 0x6C, 0x06, 0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, + 0x7C, 0x06, 0xE0, 0x6E, 0x06, 0x70, 0xE3, 0xFC, 0x1F, 0x00, 0xFF, 0x3F, + 0xEC, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x07, 0xFF, 0xBF, 0xCC, 0x03, + 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x1F, 0x01, 0xFE, 0x1C, + 0x38, 0xC0, 0xCE, 0x06, 0x60, 0x3B, 0x01, 0xD8, 0x0E, 0xC0, 0x76, 0x03, + 0xB0, 0x1D, 0x80, 0xEE, 0x06, 0x70, 0x31, 0xC3, 0x87, 0xF8, 0x1F, 0xE0, + 0x03, 0x80, 0x0E, 0xFF, 0x1F, 0xF3, 0x07, 0x60, 0xEC, 0x0D, 0x81, 0xB0, + 0x76, 0x0C, 0xFF, 0x1F, 0xF3, 0x07, 0x60, 0xEC, 0x0D, 0x81, 0xB0, 0x36, + 0x06, 0xC0, 0xE0, 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7E, 0x0F, 0xC0, 0x1C, + 0x01, 0xF0, 0x1F, 0x80, 0x78, 0x03, 0x00, 0x7C, 0x0F, 0xC1, 0xDC, 0x73, + 0xFE, 0x1F, 0x00, 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x06, 0x00, 0x60, 0x06, 0x00, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, + 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x06, 0xC1, + 0xDC, 0x39, 0xFE, 0x1F, 0x00, 0xE0, 0x3B, 0x01, 0x98, 0x0C, 0xE0, 0xE3, + 0x06, 0x18, 0x30, 0xE1, 0x83, 0x1C, 0x18, 0xC0, 0xC6, 0x07, 0x30, 0x1B, + 0x00, 0xD8, 0x06, 0xC0, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0xE0, 0xC1, 0xD8, + 0x30, 0x66, 0x1E, 0x19, 0x87, 0x86, 0x71, 0xE3, 0x8C, 0x78, 0xE3, 0x1F, + 0x30, 0xCC, 0xCC, 0x33, 0x33, 0x0E, 0xCD, 0xC1, 0xB3, 0xF0, 0x78, 0x78, + 0x1E, 0x1E, 0x07, 0x87, 0x81, 0xE1, 0xE0, 0x30, 0x38, 0x0C, 0x0C, 0x00, + 0xE0, 0xEE, 0x0E, 0x71, 0xC3, 0x1C, 0x39, 0x81, 0xB8, 0x1B, 0x00, 0xE0, + 0x0E, 0x00, 0xF0, 0x1B, 0x03, 0xB8, 0x31, 0x87, 0x1C, 0x70, 0xCE, 0x0E, + 0xE0, 0xF0, 0xE0, 0x3B, 0x83, 0x9C, 0x18, 0x61, 0xC3, 0x8E, 0x0C, 0x60, + 0x77, 0x01, 0xB0, 0x0F, 0x80, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, + 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0E, 0x03, + 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x06, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0E, + 0x03, 0xFF, 0xFF, 0xC0, 0xFF, 0xF9, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, + 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0xFF, 0xE0, 0x30, 0x18, 0x0E, 0x03, + 0x01, 0x80, 0xE0, 0x30, 0x18, 0x0E, 0x03, 0x01, 0x80, 0xE0, 0x30, 0x18, + 0x0E, 0x03, 0x01, 0xC0, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0xFF, 0x30, 0x70, 0xE3, 0x46, 0xCD, 0xB1, 0x63, 0xC6, + 0xFF, 0xFF, 0xC0, 0xE3, 0x8E, 0x3E, 0x3F, 0xB8, 0xFC, 0x70, 0x39, 0xFD, + 0xFF, 0xC7, 0xC3, 0xE1, 0xF8, 0xEF, 0xB3, 0x98, 0xE0, 0x38, 0x0E, 0x03, + 0x80, 0xE0, 0x38, 0x0E, 0xF3, 0xFE, 0xF3, 0xB8, 0x6E, 0x1F, 0x87, 0xE1, + 0xF8, 0x7E, 0x1F, 0x87, 0xF3, 0xBF, 0xEC, 0xF0, 0x3E, 0x3F, 0x98, 0xFC, + 0x3C, 0x1E, 0x03, 0x01, 0x80, 0xC0, 0x70, 0xD8, 0xEF, 0xE3, 0xE0, 0x01, + 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0xF6, 0xFF, 0x63, 0xF0, 0xF0, 0x78, + 0x3C, 0x1E, 0x0F, 0x07, 0xC3, 0x63, 0xBF, 0xCF, 0x60, 0x1E, 0x3F, 0x98, + 0xFC, 0x3C, 0x1F, 0xFF, 0xFF, 0x80, 0xC0, 0x70, 0x1C, 0x4F, 0xF1, 0xE0, + 0x1C, 0xF7, 0x1C, 0x71, 0xCF, 0xFF, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, + 0x71, 0xC7, 0x00, 0x3D, 0xBF, 0xD8, 0xFC, 0x3C, 0x1E, 0x0F, 0x07, 0x83, + 0xC1, 0xF0, 0xF8, 0xEF, 0xF3, 0xD8, 0x0C, 0x06, 0x87, 0x7F, 0x1F, 0x00, + 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0xBD, 0xFF, 0xF3, 0xF0, 0xF8, + 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x60, 0xF0, 0x3F, + 0xFF, 0xFF, 0xF0, 0x18, 0xC0, 0x00, 0x0C, 0x63, 0x18, 0xC6, 0x31, 0x8C, + 0x63, 0x18, 0xC6, 0x33, 0xFB, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, + 0x38, 0x0E, 0x3B, 0x8C, 0xE7, 0x39, 0x8E, 0xC3, 0xF0, 0xFC, 0x3B, 0x8E, + 0x63, 0x9C, 0xE3, 0x38, 0xEE, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xEE, + 0x3C, 0xFF, 0x7E, 0xE3, 0xCE, 0xE1, 0x86, 0xE1, 0x86, 0xE1, 0x87, 0xE1, + 0x87, 0xE1, 0x87, 0xE1, 0x87, 0xE1, 0x87, 0xE1, 0x87, 0xE1, 0x87, 0xE1, + 0x87, 0xEF, 0x7F, 0xFC, 0xFC, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, + 0xF8, 0x7C, 0x3E, 0x18, 0x1E, 0x1F, 0xC6, 0x3B, 0x86, 0xC1, 0xF0, 0x7C, + 0x1F, 0x07, 0xC1, 0xF8, 0x66, 0x39, 0xFC, 0x1E, 0x00, 0xEE, 0x3F, 0xEF, + 0x3B, 0x86, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xF8, 0x7E, 0x3B, 0xFE, + 0xEF, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x00, 0x3D, 0xBF, 0xD8, 0xFC, + 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xF0, 0xF8, 0xEF, 0xF3, 0xD8, 0x0C, + 0x06, 0x03, 0x01, 0x80, 0xC0, 0xEF, 0xFE, 0x38, 0xE3, 0x8E, 0x38, 0xE3, + 0x8E, 0x38, 0xE0, 0x3E, 0x3F, 0xB8, 0xD8, 0x7E, 0x03, 0xC0, 0xF8, 0x0E, + 0x03, 0xE1, 0xF8, 0xCF, 0xE3, 0xE0, 0x30, 0x60, 0xC7, 0xEF, 0xC6, 0x0C, + 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x0F, 0x8F, 0xE1, 0xF0, 0xF8, 0x7C, + 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xD8, 0xEF, 0xF3, 0xD8, 0xE0, + 0xD8, 0x76, 0x19, 0xC6, 0x31, 0x8C, 0xE3, 0x30, 0x6C, 0x1B, 0x07, 0x81, + 0xE0, 0x38, 0x0C, 0x00, 0xE1, 0x8E, 0xC7, 0x19, 0x8E, 0x33, 0x1C, 0x67, + 0x3C, 0xC6, 0xDB, 0x8D, 0xB6, 0x1B, 0x2C, 0x36, 0x78, 0x38, 0xF0, 0x71, + 0xC0, 0xE1, 0x81, 0xC3, 0x00, 0x61, 0xDC, 0x63, 0x38, 0xEC, 0x1F, 0x07, + 0x80, 0xE0, 0x78, 0x1F, 0x0E, 0xC3, 0x39, 0xC6, 0xE1, 0xC0, 0xE1, 0xD8, + 0x76, 0x19, 0xC6, 0x33, 0x8C, 0xE3, 0x30, 0x6C, 0x1F, 0x07, 0x81, 0xE0, + 0x38, 0x0C, 0x03, 0x00, 0xC0, 0x70, 0x78, 0x1C, 0x00, 0xFF, 0xFF, 0x07, + 0x06, 0x0C, 0x1C, 0x18, 0x38, 0x30, 0x60, 0xE0, 0xFF, 0xFF, 0x08, 0x73, + 0x0C, 0x30, 0xC3, 0x0C, 0x71, 0xCE, 0x30, 0x61, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0x30, 0x60, 0xC0, 0xFF, 0xFF, 0xF0, 0x43, 0x83, 0x0C, 0x30, 0xC3, + 0x0C, 0x30, 0xE1, 0xC3, 0x18, 0xE3, 0x0C, 0x30, 0xC3, 0x0C, 0x31, 0x8C, + 0x00, 0x38, 0x4F, 0x87, 0x39, 0xE3, 0xF0, 0x1C }; + +const GFXglyph RobotoCondensed_Regular12pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' + { 6, 5, 6, 7, 1, -18 }, // 0x22 '"' + { 10, 11, 17, 13, 1, -16 }, // 0x23 '#' + { 34, 10, 22, 12, 1, -19 }, // 0x24 '$' + { 62, 14, 17, 16, 1, -16 }, // 0x25 '%' + { 92, 12, 17, 14, 1, -16 }, // 0x26 '&' + { 118, 2, 6, 4, 1, -18 }, // 0x27 ''' + { 120, 6, 24, 7, 1, -18 }, // 0x28 '(' + { 138, 6, 24, 7, 0, -18 }, // 0x29 ')' + { 156, 9, 10, 9, 0, -16 }, // 0x2A '*' + { 168, 10, 12, 12, 1, -13 }, // 0x2B '+' + { 183, 3, 6, 5, 1, -2 }, // 0x2C ',' + { 186, 5, 2, 7, 1, -7 }, // 0x2D '-' + { 188, 2, 2, 6, 2, -1 }, // 0x2E '.' + { 189, 8, 18, 8, 0, -16 }, // 0x2F '/' + { 207, 10, 17, 12, 1, -16 }, // 0x30 '0' + { 229, 5, 17, 12, 2, -16 }, // 0x31 '1' + { 240, 10, 17, 12, 1, -16 }, // 0x32 '2' + { 262, 9, 17, 12, 1, -16 }, // 0x33 '3' + { 282, 10, 17, 12, 1, -16 }, // 0x34 '4' + { 304, 10, 17, 12, 1, -16 }, // 0x35 '5' + { 326, 10, 17, 12, 1, -16 }, // 0x36 '6' + { 348, 10, 17, 12, 1, -16 }, // 0x37 '7' + { 370, 10, 17, 12, 1, -16 }, // 0x38 '8' + { 392, 9, 17, 12, 1, -16 }, // 0x39 '9' + { 412, 2, 13, 6, 2, -12 }, // 0x3A ':' + { 416, 3, 16, 6, 1, -12 }, // 0x3B ';' + { 422, 8, 10, 11, 1, -10 }, // 0x3C '<' + { 432, 8, 7, 12, 2, -10 }, // 0x3D '=' + { 439, 9, 10, 11, 1, -10 }, // 0x3E '>' + { 451, 8, 17, 10, 1, -16 }, // 0x3F '?' + { 468, 17, 22, 19, 1, -16 }, // 0x40 '@' + { 515, 13, 17, 13, 0, -16 }, // 0x41 'A' + { 543, 10, 17, 13, 2, -16 }, // 0x42 'B' + { 565, 11, 17, 13, 1, -16 }, // 0x43 'C' + { 589, 11, 17, 14, 2, -16 }, // 0x44 'D' + { 613, 9, 17, 12, 2, -16 }, // 0x45 'E' + { 633, 9, 17, 12, 2, -16 }, // 0x46 'F' + { 653, 11, 17, 14, 1, -16 }, // 0x47 'G' + { 677, 11, 17, 15, 2, -16 }, // 0x48 'H' + { 701, 2, 17, 6, 2, -16 }, // 0x49 'I' + { 706, 9, 17, 12, 1, -16 }, // 0x4A 'J' + { 726, 11, 17, 13, 2, -16 }, // 0x4B 'K' + { 750, 9, 17, 11, 2, -16 }, // 0x4C 'L' + { 770, 14, 17, 17, 2, -16 }, // 0x4D 'M' + { 800, 11, 17, 15, 2, -16 }, // 0x4E 'N' + { 824, 12, 17, 14, 1, -16 }, // 0x4F 'O' + { 850, 10, 17, 13, 2, -16 }, // 0x50 'P' + { 872, 13, 19, 14, 1, -16 }, // 0x51 'Q' + { 903, 11, 17, 14, 2, -16 }, // 0x52 'R' + { 927, 11, 17, 13, 1, -16 }, // 0x53 'S' + { 951, 12, 17, 12, 0, -16 }, // 0x54 'T' + { 977, 11, 17, 14, 1, -16 }, // 0x55 'U' + { 1001, 13, 17, 13, 0, -16 }, // 0x56 'V' + { 1029, 18, 17, 18, 0, -16 }, // 0x57 'W' + { 1068, 12, 17, 13, 1, -16 }, // 0x58 'X' + { 1094, 13, 17, 13, 0, -16 }, // 0x59 'Y' + { 1122, 10, 17, 12, 1, -16 }, // 0x5A 'Z' + { 1144, 5, 24, 6, 1, -19 }, // 0x5B '[' + { 1159, 9, 18, 9, 0, -16 }, // 0x5C '\' + { 1180, 4, 24, 6, 0, -19 }, // 0x5D ']' + { 1192, 7, 9, 9, 1, -16 }, // 0x5E '^' + { 1200, 9, 2, 9, 0, 1 }, // 0x5F '_' + { 1203, 5, 3, 7, 1, -16 }, // 0x60 '`' + { 1205, 9, 13, 11, 1, -12 }, // 0x61 'a' + { 1220, 10, 19, 12, 1, -18 }, // 0x62 'b' + { 1244, 9, 13, 11, 1, -12 }, // 0x63 'c' + { 1259, 9, 19, 12, 1, -18 }, // 0x64 'd' + { 1281, 9, 13, 11, 1, -12 }, // 0x65 'e' + { 1296, 6, 19, 7, 1, -18 }, // 0x66 'f' + { 1311, 9, 18, 12, 1, -12 }, // 0x67 'g' + { 1332, 9, 19, 12, 1, -18 }, // 0x68 'h' + { 1354, 2, 18, 5, 2, -17 }, // 0x69 'i' + { 1359, 5, 23, 5, -1, -17 }, // 0x6A 'j' + { 1374, 10, 19, 11, 1, -18 }, // 0x6B 'k' + { 1398, 2, 19, 5, 2, -18 }, // 0x6C 'l' + { 1403, 16, 13, 18, 1, -12 }, // 0x6D 'm' + { 1429, 9, 13, 12, 1, -12 }, // 0x6E 'n' + { 1444, 10, 13, 12, 1, -12 }, // 0x6F 'o' + { 1461, 10, 18, 12, 1, -12 }, // 0x70 'p' + { 1484, 9, 18, 12, 1, -12 }, // 0x71 'q' + { 1505, 6, 13, 7, 1, -12 }, // 0x72 'r' + { 1515, 9, 13, 10, 1, -12 }, // 0x73 's' + { 1530, 7, 16, 7, 0, -15 }, // 0x74 't' + { 1544, 9, 13, 12, 1, -12 }, // 0x75 'u' + { 1559, 10, 13, 10, 0, -12 }, // 0x76 'v' + { 1576, 15, 13, 15, 0, -12 }, // 0x77 'w' + { 1601, 10, 13, 10, 0, -12 }, // 0x78 'x' + { 1618, 10, 18, 10, 0, -12 }, // 0x79 'y' + { 1641, 8, 13, 10, 1, -12 }, // 0x7A 'z' + { 1654, 6, 23, 7, 1, -18 }, // 0x7B '{' + { 1672, 1, 20, 5, 2, -16 }, // 0x7C '|' + { 1675, 6, 23, 7, 0, -18 }, // 0x7D '}' + { 1693, 11, 5, 14, 1, -9 } }; // 0x7E '~' + +const GFXfont RobotoCondensed_Regular12pt7b PROGMEM = { + (uint8_t *)RobotoCondensed_Regular12pt7bBitmaps, + (GFXglyph *)RobotoCondensed_Regular12pt7bGlyphs, + 0x20, 0x7E, 31 }; + +// Approx. 2372 bytes diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h new file mode 100644 index 000000000..7e5506ce3 --- /dev/null +++ b/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h @@ -0,0 +1,340 @@ +const uint8_t RobotoCondensed_Regular16pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0xEF, 0xDF, + 0xBF, 0x7C, 0xF9, 0xB3, 0x66, 0x06, 0x30, 0x18, 0xC0, 0x63, 0x01, 0x8C, + 0x06, 0x30, 0x39, 0xC7, 0xFF, 0xDF, 0xFF, 0x0C, 0x60, 0x31, 0x80, 0xC6, + 0x03, 0x18, 0x18, 0xC0, 0x63, 0x0F, 0xFF, 0xBF, 0xFE, 0x18, 0xC0, 0x63, + 0x03, 0x9C, 0x0C, 0x60, 0x31, 0x80, 0xC6, 0x00, 0x03, 0x00, 0x18, 0x00, + 0xC0, 0x06, 0x00, 0xF8, 0x0F, 0xF0, 0xE3, 0xCF, 0x0E, 0x70, 0x73, 0x83, + 0xDC, 0x0E, 0xE0, 0x03, 0x80, 0x1E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xE0, + 0x07, 0x80, 0x1D, 0xC0, 0x7F, 0x03, 0xB8, 0x3D, 0xC1, 0xCF, 0x1E, 0x3F, + 0xE0, 0x7E, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x00, 0x1E, 0x00, 0x1F, 0xC0, + 0x06, 0x30, 0xC1, 0x8E, 0x30, 0xE3, 0x9C, 0x38, 0xE6, 0x06, 0x3B, 0x01, + 0x8C, 0xC0, 0x7F, 0x60, 0x07, 0x98, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x01, + 0x8F, 0x00, 0x67, 0xE0, 0x33, 0x9C, 0x0C, 0xC3, 0x06, 0x30, 0xC3, 0x8C, + 0x30, 0xC3, 0x0C, 0x30, 0xE7, 0x00, 0x1F, 0x80, 0x03, 0xC0, 0x0F, 0x80, + 0x1F, 0xC0, 0x3C, 0xE0, 0x38, 0x60, 0x38, 0x60, 0x38, 0x60, 0x38, 0xE0, + 0x39, 0xE0, 0x1F, 0xC0, 0x1F, 0x00, 0x0E, 0x00, 0x3F, 0x00, 0x7F, 0x86, + 0x73, 0xC6, 0xE1, 0xC6, 0xE0, 0xEE, 0xE0, 0xFE, 0xE0, 0x7C, 0xF0, 0x38, + 0x78, 0x7C, 0x3F, 0xFE, 0x1F, 0x8F, 0xFF, 0xFD, 0xB6, 0x04, 0x1C, 0x30, + 0xC3, 0x86, 0x1C, 0x38, 0x61, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, + 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x30, 0x70, 0xE0, 0xC1, 0xC1, 0x81, 0x83, + 0x82, 0x41, 0xC1, 0xC1, 0x83, 0x83, 0x07, 0x0E, 0x0C, 0x1C, 0x38, 0x70, + 0xE1, 0xC1, 0x83, 0x06, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x86, 0x1C, 0x38, + 0x61, 0xC3, 0x0E, 0x38, 0x20, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x66, + 0x67, 0xFF, 0xBF, 0xC0, 0xF0, 0x0F, 0x01, 0x98, 0x39, 0xC3, 0x0C, 0x10, + 0x80, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, + 0x1F, 0xFF, 0xFF, 0xF8, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, + 0x1C, 0x00, 0xE0, 0x77, 0x76, 0xEC, 0xC0, 0xFF, 0xFC, 0xFF, 0x80, 0x01, + 0xC0, 0x60, 0x18, 0x0E, 0x03, 0x00, 0xC0, 0x70, 0x1C, 0x06, 0x01, 0x80, + 0xE0, 0x30, 0x0C, 0x07, 0x01, 0x80, 0x60, 0x38, 0x0E, 0x03, 0x01, 0xC0, + 0x70, 0x18, 0x06, 0x03, 0x80, 0x0F, 0x80, 0xFE, 0x0E, 0x38, 0xE0, 0xE7, + 0x07, 0x38, 0x39, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, + 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xEE, 0x07, 0x70, 0x73, 0x83, 0x9C, 0x1C, + 0x71, 0xC1, 0xFC, 0x07, 0xC0, 0x0F, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x81, 0xFF, 0x1E, 0x38, 0xE0, 0xEF, 0x07, 0x70, + 0x3B, 0x81, 0xC0, 0x0E, 0x00, 0x70, 0x07, 0x00, 0x38, 0x03, 0x80, 0x3C, + 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1E, 0x01, 0xE0, 0x0E, 0x00, 0xF0, 0x07, + 0xFF, 0xBF, 0xFC, 0x0F, 0x81, 0xFE, 0x1E, 0x38, 0xE0, 0xEF, 0x07, 0x70, + 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x07, 0x03, 0xF0, 0x1F, 0x80, 0x0E, + 0x00, 0x38, 0x01, 0xC0, 0x0F, 0xE0, 0x7F, 0x03, 0x9C, 0x1C, 0xF1, 0xE3, + 0xFE, 0x07, 0xC0, 0x00, 0xE0, 0x0F, 0x00, 0xF8, 0x07, 0xC0, 0x7E, 0x03, + 0x70, 0x3B, 0x81, 0x9C, 0x1C, 0xE0, 0xC7, 0x0E, 0x38, 0xE1, 0xC7, 0x0E, + 0x70, 0x73, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0, + 0x0E, 0x00, 0x70, 0x7F, 0xE7, 0xFE, 0x70, 0x07, 0x00, 0x70, 0x06, 0x00, + 0x60, 0x06, 0x00, 0xEF, 0x8F, 0xFC, 0xF1, 0xEE, 0x0E, 0x00, 0xE0, 0x07, + 0x00, 0x70, 0x07, 0xE0, 0x7E, 0x0E, 0xE0, 0xE7, 0x1E, 0x7F, 0xC1, 0xF0, + 0x0F, 0xC1, 0xFC, 0x38, 0x47, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0xF8, + 0xFF, 0xCF, 0x1E, 0xE0, 0xEE, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, + 0xE0, 0x7E, 0x07, 0x70, 0xE7, 0x9E, 0x3F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, + 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x07, 0x00, 0x38, 0x03, 0x80, + 0x1C, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x0E, + 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x0F, 0x81, 0xFF, + 0x0E, 0x38, 0xE0, 0xE7, 0x07, 0x38, 0x39, 0xC1, 0xCE, 0x0E, 0x70, 0x71, + 0xC7, 0x07, 0xF0, 0x3F, 0x83, 0x8E, 0x38, 0x39, 0xC0, 0xFC, 0x07, 0xE0, + 0x3F, 0x81, 0xDC, 0x1C, 0xF1, 0xE3, 0xFE, 0x07, 0xC0, 0x0F, 0x80, 0xFE, + 0x0E, 0x38, 0xE0, 0xE7, 0x07, 0x70, 0x3B, 0x81, 0xDC, 0x0F, 0xE0, 0x7F, + 0x03, 0xDC, 0x1E, 0xE0, 0xF7, 0x8F, 0x9F, 0xFC, 0x7D, 0xE0, 0x0E, 0x00, + 0x70, 0x03, 0x80, 0x3C, 0x43, 0xC3, 0xFC, 0x0F, 0x80, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x3F, 0xE0, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x77, 0x66, 0xE0, 0x00, 0x20, 0x1C, 0x07, 0x83, 0xE1, 0xF0, 0xF8, 0x3C, + 0x07, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF0, 0x0E, 0x00, 0x40, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x18, + 0x03, 0xC0, 0x7E, 0x01, 0xF0, 0x0F, 0x80, 0x78, 0x0F, 0x07, 0xC3, 0xE3, + 0xF0, 0x78, 0x0C, 0x01, 0x00, 0x00, 0x1F, 0x0F, 0xF3, 0xC7, 0x70, 0x7E, + 0x0F, 0xC1, 0xC0, 0x38, 0x07, 0x01, 0xE0, 0x38, 0x0E, 0x03, 0xC0, 0xF0, + 0x1C, 0x03, 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x01, 0xE0, 0x3C, + 0x00, 0x00, 0x7E, 0x00, 0x07, 0xFF, 0x80, 0x1E, 0x07, 0x80, 0x70, 0x03, + 0x81, 0xC0, 0x03, 0x03, 0x00, 0x03, 0x0E, 0x00, 0x06, 0x18, 0x1E, 0x06, + 0x70, 0x7F, 0x0C, 0xC1, 0xC6, 0x19, 0x87, 0x0C, 0x33, 0x0C, 0x18, 0x6E, + 0x18, 0x30, 0xDC, 0x70, 0xE1, 0xB8, 0xE1, 0xC3, 0x71, 0xC3, 0x86, 0xE3, + 0x86, 0x0D, 0xC7, 0x0C, 0x1B, 0x8E, 0x18, 0x63, 0x1C, 0x79, 0xC6, 0x1F, + 0xBF, 0x0C, 0x1E, 0x3C, 0x1C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x3C, 0x0C, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3F, 0x00, + 0x3B, 0x80, 0x1D, 0xC0, 0x0E, 0x60, 0x06, 0x38, 0x07, 0x1C, 0x03, 0x8E, + 0x01, 0xC3, 0x81, 0xC1, 0xC0, 0xE0, 0xE0, 0x7F, 0xF8, 0x7F, 0xFC, 0x38, + 0x0E, 0x1C, 0x03, 0x9C, 0x01, 0xCE, 0x00, 0xE7, 0x00, 0x77, 0x80, 0x1C, + 0xFF, 0x83, 0xFF, 0x8E, 0x0F, 0x38, 0x1C, 0xE0, 0x3B, 0x80, 0xEE, 0x03, + 0xB8, 0x0E, 0xE0, 0x73, 0x83, 0xCF, 0xFE, 0x3F, 0xFC, 0xE0, 0x7B, 0x80, + 0xEE, 0x03, 0xB8, 0x07, 0xE0, 0x1F, 0x80, 0xEE, 0x03, 0xB8, 0x1E, 0xFF, + 0xF3, 0xFF, 0x00, 0x07, 0xE0, 0x7F, 0xC3, 0xC7, 0x9E, 0x07, 0x70, 0x1D, + 0xC0, 0x7F, 0x01, 0xF8, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, + 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x3C, 0x07, 0x70, 0x1D, 0xC0, 0x77, 0x81, + 0xCF, 0x0E, 0x1F, 0xF0, 0x1F, 0x80, 0xFF, 0x83, 0xFF, 0x8E, 0x0F, 0x38, + 0x1E, 0xE0, 0x3B, 0x80, 0xFE, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, + 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x3F, + 0x80, 0xEE, 0x07, 0xB8, 0x3C, 0xFF, 0xE3, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, + 0xF8, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, + 0x00, 0x3F, 0xF9, 0xFF, 0xCE, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, + 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0F, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, + 0xF8, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, + 0x00, 0x3F, 0xF9, 0xFF, 0xCE, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, + 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x00, 0x0F, 0xC0, 0xFF, + 0xC7, 0x87, 0xBC, 0x0E, 0xE0, 0x1F, 0x80, 0x7E, 0x00, 0x38, 0x00, 0xE0, + 0x03, 0x80, 0x0E, 0x00, 0x38, 0x7F, 0xE1, 0xFF, 0x80, 0x7E, 0x01, 0xF8, + 0x07, 0xE0, 0x1F, 0x80, 0x7F, 0x01, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80, + 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, + 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7E, 0x00, + 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, + 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, + 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, + 0x00, 0x70, 0x07, 0xE0, 0x7E, 0x07, 0xF0, 0xE7, 0x1E, 0x3F, 0xC1, 0xF0, + 0xE0, 0x1F, 0xC0, 0x7B, 0x81, 0xE7, 0x03, 0x8E, 0x0F, 0x1C, 0x1C, 0x38, + 0x70, 0x71, 0xE0, 0xE3, 0x81, 0xCE, 0x03, 0xFC, 0x07, 0xF8, 0x0E, 0x38, + 0x1C, 0x78, 0x38, 0x70, 0x70, 0xF0, 0xE0, 0xF1, 0xC0, 0xE3, 0x81, 0xE7, + 0x01, 0xCE, 0x03, 0xDC, 0x03, 0xC0, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFC, 0x00, 0xFF, 0x80, 0x3F, 0xE0, 0x1F, + 0xF8, 0x07, 0xFF, 0x01, 0xBF, 0xC0, 0x6F, 0xB0, 0x3B, 0xEC, 0x0D, 0xFB, + 0x83, 0x7E, 0x61, 0xDF, 0x98, 0x77, 0xE7, 0x19, 0xF8, 0xC6, 0x7E, 0x33, + 0x9F, 0x8C, 0xC7, 0xE3, 0xB1, 0xF8, 0x7C, 0x7E, 0x1E, 0x1F, 0x87, 0x87, + 0xE0, 0xE1, 0xF8, 0x30, 0x70, 0xE0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0xC0, + 0x7F, 0xC0, 0xFF, 0x81, 0xFB, 0x83, 0xF7, 0x07, 0xE7, 0x0F, 0xCE, 0x1F, + 0x8E, 0x3F, 0x1C, 0x7E, 0x1C, 0xFC, 0x39, 0xF8, 0x3B, 0xF0, 0x77, 0xE0, + 0x7F, 0xC0, 0xFF, 0x80, 0xFF, 0x01, 0xFE, 0x01, 0xFC, 0x03, 0xC0, 0x07, + 0xE0, 0x3F, 0xE0, 0xF0, 0xE3, 0xC0, 0xE7, 0x00, 0xEE, 0x01, 0xFC, 0x03, + 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, + 0x01, 0xF8, 0x03, 0xF0, 0x07, 0x70, 0x0E, 0xE0, 0x1D, 0xE0, 0x71, 0xE1, + 0xC1, 0xFF, 0x00, 0xFC, 0x00, 0xFF, 0xC3, 0xFF, 0xCE, 0x07, 0xB8, 0x0E, + 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0xEE, 0x07, + 0xBF, 0xFC, 0xFF, 0xC3, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, + 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x07, 0xE0, 0x0F, 0xF8, + 0x0F, 0x0E, 0x0F, 0x03, 0x87, 0x00, 0xE3, 0x80, 0x73, 0xC0, 0x39, 0xC0, + 0x1C, 0xE0, 0x0E, 0x70, 0x07, 0x38, 0x03, 0x9C, 0x01, 0xCE, 0x00, 0xE7, + 0x00, 0x73, 0xC0, 0x39, 0xE0, 0x1C, 0x70, 0x0E, 0x38, 0x07, 0x1E, 0x07, + 0x07, 0x87, 0x81, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, + 0x02, 0x00, 0xFF, 0xC3, 0xFF, 0xCE, 0x07, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, + 0xFE, 0x03, 0xF8, 0x0E, 0xE0, 0x3B, 0x81, 0xCF, 0xFE, 0x3F, 0xFC, 0xE0, + 0x7B, 0x80, 0xEE, 0x03, 0xB8, 0x0F, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, + 0x07, 0xE0, 0x1F, 0x80, 0x70, 0x07, 0xC0, 0x7F, 0xC3, 0x87, 0x9C, 0x0F, + 0x70, 0x1D, 0xC0, 0x77, 0x00, 0x1C, 0x00, 0x78, 0x00, 0xF8, 0x01, 0xF8, + 0x01, 0xF8, 0x00, 0xF8, 0x00, 0xE0, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0xC0, + 0x77, 0x01, 0xCE, 0x0E, 0x1F, 0xF0, 0x3F, 0x80, 0xFF, 0xFF, 0xFF, 0xF0, + 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, + 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, + 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0xE0, + 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, + 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, + 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0xEF, 0x03, 0x9E, 0x1C, 0x3F, 0xE0, + 0x3F, 0x00, 0xF0, 0x07, 0xB8, 0x03, 0x9C, 0x01, 0xCF, 0x01, 0xE3, 0x80, + 0xE1, 0xC0, 0x70, 0xE0, 0x38, 0x38, 0x38, 0x1C, 0x1C, 0x0E, 0x0E, 0x03, + 0x06, 0x01, 0xC7, 0x00, 0xE3, 0x80, 0x71, 0xC0, 0x18, 0xC0, 0x0E, 0xE0, + 0x07, 0x70, 0x01, 0xB0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x1C, 0x00, 0x0E, + 0x00, 0xE0, 0x70, 0x1F, 0x81, 0xC0, 0xEE, 0x07, 0x83, 0xB8, 0x1E, 0x0E, + 0x60, 0xF8, 0x39, 0xC3, 0xE0, 0xE7, 0x0F, 0x83, 0x1C, 0x37, 0x1C, 0x71, + 0xDC, 0x70, 0xC7, 0x71, 0xC3, 0x9C, 0xC7, 0x0E, 0x63, 0x98, 0x3B, 0x8E, + 0xE0, 0xEE, 0x3B, 0x81, 0xB8, 0x6E, 0x07, 0xC1, 0xF8, 0x1F, 0x07, 0xC0, + 0x7C, 0x1F, 0x01, 0xF0, 0x3C, 0x03, 0xC0, 0xF0, 0x0E, 0x03, 0xC0, 0x38, + 0x0E, 0x00, 0xF0, 0x1E, 0xE0, 0x39, 0xE0, 0xF1, 0xC1, 0xC3, 0xC7, 0x83, + 0x8E, 0x07, 0x3C, 0x07, 0x70, 0x0F, 0xE0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, + 0x00, 0x7C, 0x01, 0xDC, 0x03, 0xB8, 0x0E, 0x38, 0x1C, 0x70, 0x70, 0xF0, + 0xE0, 0xE3, 0xC1, 0xE7, 0x01, 0xDE, 0x03, 0xC0, 0xF0, 0x07, 0x70, 0x0F, + 0x78, 0x0E, 0x38, 0x1E, 0x3C, 0x1C, 0x1C, 0x1C, 0x1E, 0x38, 0x0E, 0x38, + 0x0E, 0x70, 0x07, 0x70, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x01, 0xC0, + 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, + 0x01, 0xC0, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0xC0, 0x1E, 0x00, 0xE0, 0x0F, + 0x00, 0x70, 0x07, 0x80, 0x38, 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x0E, 0x00, + 0xE0, 0x07, 0x00, 0x70, 0x03, 0x80, 0x38, 0x01, 0xC0, 0x1C, 0x00, 0xE0, + 0x0F, 0xFF, 0xFF, 0xFC, 0xFF, 0xF9, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, + 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCF, 0xFC, 0xF0, + 0x0E, 0x01, 0xC0, 0x18, 0x03, 0x80, 0x70, 0x0E, 0x00, 0xE0, 0x1C, 0x03, + 0x80, 0x38, 0x07, 0x00, 0xE0, 0x0E, 0x01, 0xC0, 0x38, 0x03, 0x80, 0x70, + 0x0E, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x38, 0x07, 0xFF, 0xF1, 0xC7, 0x1C, + 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, + 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0xFF, 0xF0, 0x1C, 0x07, 0x01, 0xE0, 0xF8, + 0x36, 0x0D, 0xC7, 0x31, 0xCC, 0x63, 0xB8, 0x6E, 0x1C, 0xFF, 0xFF, 0xFF, + 0xF1, 0xE3, 0x87, 0x0F, 0x83, 0xFC, 0x78, 0xE7, 0x0E, 0x70, 0x70, 0x07, + 0x00, 0x71, 0xFF, 0x3F, 0xF7, 0x87, 0xF0, 0x7E, 0x07, 0xE0, 0x7F, 0x0F, + 0x71, 0xF7, 0xF7, 0x1E, 0x70, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xE0, 0x0E, 0xF8, 0xFF, 0xCF, 0x1E, 0xE0, 0xEE, 0x0F, 0xE0, + 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, + 0xEF, 0x1E, 0xFF, 0xCC, 0xF8, 0x0F, 0x83, 0xFC, 0x78, 0xE7, 0x07, 0x70, + 0x7E, 0x07, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x07, 0x70, + 0x77, 0x07, 0x78, 0xE3, 0xFC, 0x0F, 0x80, 0x00, 0x70, 0x07, 0x00, 0x70, + 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0xF7, 0x3F, 0xF3, 0x8F, 0x70, 0x77, + 0x07, 0xF0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x77, + 0x07, 0x70, 0x77, 0x8F, 0x3F, 0xF1, 0xF7, 0x0F, 0x83, 0xFC, 0x38, 0xE7, + 0x0F, 0x70, 0x7E, 0x07, 0xE0, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0xE0, 0x0E, + 0x00, 0x70, 0x07, 0x02, 0x38, 0x63, 0xFF, 0x0F, 0xC0, 0x0F, 0x8F, 0x8F, + 0x07, 0x03, 0x81, 0xC0, 0xE1, 0xFE, 0xFF, 0x1C, 0x0E, 0x07, 0x03, 0x81, + 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, + 0x1F, 0x33, 0xFF, 0x78, 0xF7, 0x07, 0x70, 0x7E, 0x07, 0xE0, 0x7E, 0x07, + 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xF0, 0x77, 0x07, 0x78, 0xF3, 0xFF, + 0x1F, 0x70, 0x07, 0x00, 0x70, 0x07, 0x30, 0xE3, 0xFC, 0x1F, 0x80, 0xE0, + 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x3C, 0xEF, 0xDE, + 0x3F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, + 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xFF, 0x80, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0x71, 0xC0, 0x00, 0x00, 0x07, 0x1C, + 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, + 0x71, 0xCF, 0xFB, 0xC0, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, + 0x00, 0xE0, 0x0E, 0x1E, 0xE1, 0xCE, 0x3C, 0xE3, 0x8E, 0x78, 0xE7, 0x0E, + 0xE0, 0xFE, 0x0F, 0xE0, 0xEF, 0x0E, 0x70, 0xE7, 0x8E, 0x38, 0xE1, 0xCE, + 0x1E, 0xE0, 0xEE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE7, 0x87, 0x9F, 0xF9, 0xFB, 0xC7, 0x47, 0xF0, 0x78, 0x7E, 0x0E, + 0x0F, 0xC1, 0xC1, 0xF8, 0x38, 0x3F, 0x07, 0x07, 0xE0, 0xE0, 0xFC, 0x1C, + 0x1F, 0x83, 0x83, 0xF0, 0x70, 0x7E, 0x0E, 0x0F, 0xC1, 0xC1, 0xF8, 0x38, + 0x3F, 0x07, 0x07, 0xE0, 0xE0, 0xE0, 0xE7, 0x9D, 0xFB, 0xC7, 0xF0, 0x7E, + 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, + 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xE0, 0x0F, 0x81, 0xFF, 0x0E, 0x38, 0xE0, + 0xE7, 0x07, 0x70, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, + 0xC0, 0x77, 0x07, 0x38, 0x38, 0xE3, 0xC7, 0xFC, 0x0F, 0x80, 0xEF, 0x8F, + 0xFC, 0xF1, 0xEE, 0x0E, 0xE0, 0xEE, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, + 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0xFE, 0x0E, 0xF1, 0xEF, 0xFC, 0xEF, 0x8E, + 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x00, 0x1F, 0x73, 0xFF, + 0x78, 0xF7, 0x07, 0x70, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, + 0xE0, 0x7E, 0x07, 0xF0, 0x77, 0x07, 0x78, 0xF3, 0xFF, 0x1F, 0x70, 0x07, + 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0xEF, 0xFF, 0xFF, 0x8E, + 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x1F, + 0x07, 0xF9, 0xC7, 0xB8, 0x7E, 0x0E, 0xE0, 0x1E, 0x01, 0xE0, 0x1F, 0x80, + 0xF8, 0x07, 0x80, 0x7E, 0x0F, 0xC1, 0xDC, 0x79, 0xFE, 0x1F, 0x80, 0x1C, + 0x0E, 0x07, 0x03, 0x8F, 0xF7, 0xF8, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, + 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0xF0, 0xF8, 0xE0, + 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, + 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xFC, 0x7B, 0xFF, 0x3E, 0x60, 0xE0, + 0x7E, 0x07, 0xE0, 0xE7, 0x0E, 0x70, 0xE7, 0x0C, 0x71, 0xC3, 0x1C, 0x39, + 0xC3, 0x98, 0x1B, 0x81, 0xB8, 0x1F, 0x01, 0xF0, 0x0F, 0x00, 0xF0, 0x0E, + 0x00, 0xE0, 0xC1, 0xF8, 0x70, 0x7E, 0x1E, 0x1F, 0x87, 0x86, 0x61, 0xE3, + 0x9C, 0xF8, 0xE7, 0x3F, 0x39, 0xCD, 0xCC, 0x73, 0x33, 0x0D, 0xCD, 0xC3, + 0xF3, 0xF0, 0xF8, 0xFC, 0x3E, 0x1E, 0x07, 0x87, 0x81, 0xE1, 0xE0, 0x70, + 0x78, 0x1C, 0x0C, 0x00, 0xE0, 0xFF, 0x0E, 0x71, 0xE7, 0x9C, 0x3B, 0xC1, + 0xB8, 0x1F, 0x00, 0xF0, 0x0F, 0x01, 0xF0, 0x1F, 0x83, 0xB8, 0x39, 0xC7, + 0x1C, 0x71, 0xEF, 0x0E, 0xE0, 0xF0, 0xF0, 0x3B, 0x83, 0xDC, 0x1C, 0xF0, + 0xE3, 0x87, 0x1C, 0x78, 0xE3, 0x83, 0x9C, 0x1C, 0xE0, 0xEE, 0x03, 0x70, + 0x1F, 0x80, 0xF8, 0x03, 0xC0, 0x1E, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, + 0xC0, 0x1C, 0x00, 0xE0, 0x1E, 0x01, 0xE0, 0x00, 0xFF, 0xFF, 0xFC, 0x07, + 0x01, 0xE0, 0x38, 0x0F, 0x01, 0xC0, 0x78, 0x0E, 0x03, 0xC0, 0x70, 0x1C, + 0x03, 0x80, 0xE0, 0x3C, 0x07, 0xFF, 0xFF, 0xE0, 0x02, 0x0E, 0x1C, 0x1C, + 0x18, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x78, 0xF0, 0xE0, 0x60, + 0x30, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x18, 0x1C, 0x0C, + 0x0F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x40, 0x70, 0xB8, + 0x38, 0x18, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x0F, 0x0F, + 0x06, 0x0C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x18, 0x38, 0x38, + 0x30, 0xF0, 0x40, 0x38, 0x01, 0xF8, 0x3E, 0x70, 0xF0, 0xE6, 0xC1, 0xF8, + 0x03, 0xC0 }; + +const GFXglyph RobotoCondensed_Regular16pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 7, 0, 0 }, // 0x20 ' ' + { 1, 3, 22, 7, 2, -21 }, // 0x21 '!' + { 10, 7, 8, 9, 1, -23 }, // 0x22 '"' + { 17, 14, 22, 16, 1, -21 }, // 0x23 '#' + { 56, 13, 29, 15, 1, -25 }, // 0x24 '$' + { 104, 18, 22, 20, 1, -21 }, // 0x25 '%' + { 154, 16, 22, 18, 1, -21 }, // 0x26 '&' + { 198, 3, 8, 5, 1, -23 }, // 0x27 ''' + { 201, 7, 32, 9, 2, -24 }, // 0x28 '(' + { 229, 7, 32, 9, 0, -24 }, // 0x29 ')' + { 257, 12, 13, 12, 0, -21 }, // 0x2A '*' + { 277, 13, 16, 15, 1, -18 }, // 0x2B '+' + { 303, 4, 7, 6, 1, -2 }, // 0x2C ',' + { 307, 7, 2, 9, 1, -10 }, // 0x2D '-' + { 309, 3, 3, 8, 2, -2 }, // 0x2E '.' + { 311, 10, 24, 10, 0, -21 }, // 0x2F '/' + { 341, 13, 22, 15, 1, -21 }, // 0x30 '0' + { 377, 8, 22, 15, 2, -21 }, // 0x31 '1' + { 399, 13, 22, 15, 1, -21 }, // 0x32 '2' + { 435, 13, 22, 15, 1, -21 }, // 0x33 '3' + { 471, 13, 22, 15, 1, -21 }, // 0x34 '4' + { 507, 12, 22, 15, 2, -21 }, // 0x35 '5' + { 540, 12, 22, 15, 2, -21 }, // 0x36 '6' + { 573, 13, 22, 15, 1, -21 }, // 0x37 '7' + { 609, 13, 22, 15, 1, -21 }, // 0x38 '8' + { 645, 13, 22, 15, 1, -21 }, // 0x39 '9' + { 681, 3, 17, 7, 2, -16 }, // 0x3A ':' + { 688, 4, 21, 7, 1, -16 }, // 0x3B ';' + { 699, 11, 14, 14, 1, -15 }, // 0x3C '<' + { 719, 11, 8, 15, 2, -13 }, // 0x3D '=' + { 730, 11, 14, 14, 2, -15 }, // 0x3E '>' + { 750, 11, 22, 13, 1, -21 }, // 0x3F '?' + { 781, 23, 29, 25, 1, -21 }, // 0x40 '@' + { 865, 17, 22, 17, 0, -21 }, // 0x41 'A' + { 912, 14, 22, 17, 2, -21 }, // 0x42 'B' + { 951, 14, 22, 16, 1, -21 }, // 0x43 'C' + { 990, 14, 22, 17, 2, -21 }, // 0x44 'D' + { 1029, 13, 22, 15, 2, -21 }, // 0x45 'E' + { 1065, 13, 22, 15, 2, -21 }, // 0x46 'F' + { 1101, 14, 22, 18, 2, -21 }, // 0x47 'G' + { 1140, 15, 22, 19, 2, -21 }, // 0x48 'H' + { 1182, 3, 22, 8, 2, -21 }, // 0x49 'I' + { 1191, 12, 22, 15, 1, -21 }, // 0x4A 'J' + { 1224, 15, 22, 17, 2, -21 }, // 0x4B 'K' + { 1266, 12, 22, 14, 2, -21 }, // 0x4C 'L' + { 1299, 18, 22, 22, 2, -21 }, // 0x4D 'M' + { 1349, 15, 22, 19, 2, -21 }, // 0x4E 'N' + { 1391, 15, 22, 18, 1, -21 }, // 0x4F 'O' + { 1433, 14, 22, 17, 2, -21 }, // 0x50 'P' + { 1472, 17, 25, 18, 1, -21 }, // 0x51 'Q' + { 1526, 14, 22, 18, 2, -21 }, // 0x52 'R' + { 1565, 14, 22, 16, 1, -21 }, // 0x53 'S' + { 1604, 14, 22, 15, 1, -21 }, // 0x54 'T' + { 1643, 14, 22, 18, 2, -21 }, // 0x55 'U' + { 1682, 17, 22, 17, 0, -21 }, // 0x56 'V' + { 1729, 22, 22, 23, 1, -21 }, // 0x57 'W' + { 1790, 15, 22, 17, 1, -21 }, // 0x58 'X' + { 1832, 16, 22, 17, 0, -21 }, // 0x59 'Y' + { 1876, 13, 22, 15, 1, -21 }, // 0x5A 'Z' + { 1912, 5, 30, 8, 2, -24 }, // 0x5B '[' + { 1931, 11, 24, 11, 0, -21 }, // 0x5C '\' + { 1964, 6, 30, 8, 0, -24 }, // 0x5D ']' + { 1987, 10, 11, 11, 1, -21 }, // 0x5E '^' + { 2001, 12, 2, 12, 0, 1 }, // 0x5F '_' + { 2004, 6, 4, 9, 1, -21 }, // 0x60 '`' + { 2007, 12, 17, 14, 1, -16 }, // 0x61 'a' + { 2033, 12, 24, 15, 2, -23 }, // 0x62 'b' + { 2069, 12, 17, 14, 1, -16 }, // 0x63 'c' + { 2095, 12, 24, 15, 1, -23 }, // 0x64 'd' + { 2131, 12, 17, 14, 1, -16 }, // 0x65 'e' + { 2157, 9, 24, 9, 1, -23 }, // 0x66 'f' + { 2184, 12, 23, 15, 1, -16 }, // 0x67 'g' + { 2219, 11, 24, 15, 2, -23 }, // 0x68 'h' + { 2252, 3, 24, 7, 2, -23 }, // 0x69 'i' + { 2261, 6, 30, 7, -1, -23 }, // 0x6A 'j' + { 2284, 12, 24, 14, 2, -23 }, // 0x6B 'k' + { 2320, 3, 24, 7, 2, -23 }, // 0x6C 'l' + { 2329, 19, 17, 23, 2, -16 }, // 0x6D 'm' + { 2370, 11, 17, 15, 2, -16 }, // 0x6E 'n' + { 2394, 13, 17, 15, 1, -16 }, // 0x6F 'o' + { 2422, 12, 23, 15, 2, -16 }, // 0x70 'p' + { 2457, 12, 23, 15, 1, -16 }, // 0x71 'q' + { 2492, 7, 17, 10, 2, -16 }, // 0x72 'r' + { 2507, 11, 17, 13, 1, -16 }, // 0x73 's' + { 2531, 9, 21, 10, 0, -20 }, // 0x74 't' + { 2555, 11, 17, 15, 2, -16 }, // 0x75 'u' + { 2579, 12, 17, 14, 1, -16 }, // 0x76 'v' + { 2605, 18, 17, 20, 1, -16 }, // 0x77 'w' + { 2644, 12, 17, 14, 1, -16 }, // 0x78 'x' + { 2670, 13, 23, 14, 0, -16 }, // 0x79 'y' + { 2708, 11, 17, 13, 1, -16 }, // 0x7A 'z' + { 2732, 8, 30, 9, 1, -23 }, // 0x7B '{' + { 2762, 2, 26, 7, 2, -21 }, // 0x7C '|' + { 2769, 8, 30, 9, 0, -23 }, // 0x7D '}' + { 2799, 14, 6, 18, 2, -11 } }; // 0x7E '~' + +const GFXfont RobotoCondensed_Regular16pt7b PROGMEM = { + (uint8_t *)RobotoCondensed_Regular16pt7bBitmaps, + (GFXglyph *)RobotoCondensed_Regular16pt7bGlyphs, + 0x20, 0x7E, 41 }; + +// Approx. 3482 bytes diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h new file mode 100644 index 000000000..e38dcd61c --- /dev/null +++ b/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h @@ -0,0 +1,172 @@ +const uint8_t RobotoCondensed_Regular8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0x0F, 0xB6, 0xD0, 0x12, 0x12, 0x12, 0x14, 0x7F, 0x14, + 0x24, 0x24, 0xFE, 0x2C, 0x28, 0x68, 0x11, 0xEC, 0xF3, 0xCF, 0x06, 0x0E, + 0x0E, 0x38, 0xF3, 0x78, 0x82, 0x00, 0xE0, 0x48, 0x24, 0x92, 0x8E, 0x40, + 0x40, 0x20, 0x2E, 0x14, 0x92, 0x59, 0x20, 0xE0, 0x78, 0x48, 0xC8, 0xC8, + 0x78, 0x70, 0x70, 0xDA, 0x9A, 0x8E, 0xCE, 0x7B, 0xF0, 0x25, 0x2D, 0xA4, + 0x92, 0x6C, 0x91, 0x20, 0x84, 0x62, 0x23, 0x33, 0x33, 0x33, 0x22, 0x64, + 0x80, 0x10, 0x4D, 0x5E, 0x31, 0xA4, 0x80, 0x30, 0xC3, 0x3F, 0x30, 0xC3, + 0x0C, 0x56, 0xE0, 0xF0, 0x08, 0xC4, 0x21, 0x10, 0x84, 0x62, 0x10, 0x88, + 0x00, 0x7B, 0x2C, 0xE3, 0x8E, 0x38, 0xE3, 0x8F, 0x3C, 0x9E, 0x3F, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x7B, 0x28, 0xE3, 0x0C, 0x21, 0x8C, 0x21, 0x8C, + 0x3F, 0x7B, 0x38, 0xC3, 0x08, 0xC0, 0xC3, 0x0E, 0x3C, 0x9E, 0x0C, 0x18, + 0x50, 0xA3, 0x44, 0x99, 0x22, 0xFE, 0x08, 0x10, 0x20, 0x7D, 0x0C, 0x30, + 0xFB, 0x30, 0xC3, 0x0F, 0x3C, 0xDE, 0x39, 0x0C, 0x20, 0xBB, 0x38, 0x61, + 0x87, 0x14, 0xCE, 0xFC, 0x30, 0x86, 0x10, 0x43, 0x08, 0x20, 0x82, 0x18, + 0x7B, 0x3C, 0xF3, 0xC8, 0xCC, 0xE3, 0x86, 0x3C, 0xDE, 0x73, 0x28, 0xE3, + 0x8E, 0x3C, 0xDF, 0x0C, 0x38, 0xBC, 0xF0, 0x03, 0xC0, 0xF0, 0x03, 0xE8, + 0x04, 0x77, 0x30, 0x70, 0x70, 0x40, 0xFC, 0x00, 0x3F, 0x83, 0x83, 0x83, + 0x3B, 0x88, 0x00, 0x79, 0x3C, 0x41, 0x0C, 0x61, 0x0C, 0x00, 0x03, 0x0C, + 0x1F, 0x06, 0x11, 0x01, 0x27, 0x19, 0x93, 0x22, 0x64, 0xCC, 0x99, 0x92, + 0x32, 0x6A, 0x77, 0x40, 0x04, 0x00, 0xC2, 0x07, 0x80, 0x08, 0x0E, 0x05, + 0x02, 0x83, 0x61, 0xB0, 0x88, 0x44, 0x7F, 0x31, 0x90, 0x58, 0x30, 0xF9, + 0x8B, 0x1E, 0x3C, 0x5F, 0x31, 0xE3, 0xC7, 0x8F, 0x1F, 0xE0, 0x79, 0x8B, + 0x1C, 0x38, 0x10, 0x20, 0x40, 0x87, 0x8F, 0x13, 0xC0, 0xF9, 0x8B, 0x1E, + 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x8F, 0x17, 0xC0, 0xFF, 0x83, 0x06, 0x0C, + 0x1F, 0xB0, 0x60, 0xC1, 0x83, 0x07, 0xF0, 0xFF, 0x83, 0x06, 0x0C, 0x1F, + 0xB0, 0x60, 0xC1, 0x83, 0x06, 0x00, 0x3C, 0x8F, 0x0C, 0x08, 0x10, 0x23, + 0xC1, 0x83, 0x85, 0x19, 0xE0, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0x06, 0x0C, 0x18, 0x30, + 0x60, 0xC1, 0x83, 0x07, 0x8D, 0x91, 0xC0, 0xC7, 0xC6, 0xCC, 0xC8, 0xD8, + 0xF0, 0xD0, 0xC8, 0xCC, 0xC4, 0xC6, 0xC3, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, + 0x30, 0xC3, 0x0C, 0x3F, 0xC1, 0xF8, 0x7E, 0x1F, 0x87, 0xE3, 0xFC, 0xBD, + 0x2F, 0x5B, 0xD4, 0xF3, 0x3C, 0xCF, 0x23, 0xC3, 0xC3, 0xE3, 0xE3, 0xF3, + 0xD3, 0xDB, 0xCB, 0xCF, 0xC7, 0xC7, 0xC3, 0x39, 0x8F, 0x0C, 0x18, 0x30, + 0x60, 0xC1, 0x83, 0x87, 0x19, 0xC0, 0xFD, 0x8F, 0x0E, 0x1C, 0x38, 0xFF, + 0x60, 0xC1, 0x83, 0x06, 0x00, 0x3C, 0x46, 0xC2, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0xC2, 0xC6, 0x3E, 0x03, 0x02, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, + 0xC6, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC3, 0x79, 0x8B, 0x1E, 0x3C, 0x0C, + 0x07, 0x03, 0x87, 0x0F, 0x1B, 0xE0, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, + 0xC1, 0x83, 0x8F, 0x19, 0xE0, 0xC1, 0xA0, 0x90, 0xCC, 0x66, 0x21, 0x10, + 0x98, 0x68, 0x14, 0x0A, 0x07, 0x03, 0x00, 0xC6, 0x34, 0x62, 0x46, 0x24, + 0x62, 0x6F, 0x66, 0xD6, 0x29, 0x62, 0x94, 0x29, 0xC3, 0x9C, 0x30, 0xC1, + 0x0C, 0xE3, 0x63, 0x26, 0x36, 0x1C, 0x1C, 0x1C, 0x14, 0x36, 0x26, 0x63, + 0xC3, 0xC3, 0x63, 0x62, 0x26, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x18, + 0x18, 0xFC, 0x30, 0x86, 0x10, 0xC3, 0x18, 0x63, 0x0C, 0x3F, 0xFB, 0x6D, + 0xB6, 0xDB, 0x6D, 0xB7, 0xC1, 0x06, 0x18, 0x20, 0x83, 0x04, 0x10, 0x61, + 0x82, 0x0C, 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDF, 0x30, 0xC3, 0x16, 0x4B, + 0x30, 0xFC, 0xCC, 0x73, 0x28, 0xC3, 0x7F, 0x38, 0xE7, 0xEC, 0xC3, 0x0C, + 0x3E, 0xCF, 0x3C, 0x71, 0xC7, 0x3C, 0xEE, 0x73, 0x28, 0xE0, 0x82, 0x08, + 0xF2, 0x70, 0x0C, 0x30, 0xDF, 0xCE, 0x38, 0xE3, 0x8E, 0x3C, 0xDF, 0x73, + 0x28, 0xE3, 0xFE, 0x08, 0x32, 0x7C, 0x39, 0x19, 0xF6, 0x31, 0x8C, 0x63, + 0x18, 0xC0, 0x7F, 0x38, 0xE3, 0x8E, 0x38, 0xF3, 0x7C, 0x38, 0xE2, 0x70, + 0x82, 0x08, 0x2E, 0xCE, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0xF0, 0xFF, 0xFF, + 0xC0, 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x32, 0xE0, 0xC3, 0x0C, + 0x33, 0xDB, 0x4F, 0x3C, 0xF3, 0x6C, 0xB3, 0xFF, 0xFF, 0xFF, 0xBB, 0xB3, + 0x38, 0xCE, 0x33, 0x8C, 0xE3, 0x38, 0xCE, 0x33, 0x8C, 0xC0, 0xBB, 0x38, + 0xE3, 0x8E, 0x38, 0xE3, 0x8C, 0x7B, 0x38, 0xE1, 0x86, 0x18, 0xF3, 0x78, + 0xBB, 0x3C, 0xF1, 0xC7, 0x1C, 0xF3, 0xFB, 0x0C, 0x30, 0xC0, 0x7F, 0x38, + 0xE3, 0x8E, 0x38, 0xF3, 0x7C, 0x30, 0xC3, 0x0C, 0xBC, 0xCC, 0xCC, 0xCC, + 0xC0, 0x39, 0xB4, 0x58, 0x38, 0x34, 0x51, 0x38, 0x63, 0x3C, 0xC6, 0x31, + 0x8C, 0x63, 0x0E, 0x8E, 0x38, 0xE3, 0x8E, 0x3C, 0xF3, 0x7C, 0xC6, 0x89, + 0x13, 0x62, 0x85, 0x0A, 0x1C, 0x10, 0xCC, 0xD3, 0x34, 0xC9, 0x3A, 0x7A, + 0x8C, 0xE3, 0x30, 0xCC, 0x31, 0x00, 0xC6, 0xD8, 0xA1, 0xC1, 0x07, 0x0A, + 0x36, 0xC6, 0xC6, 0x89, 0x33, 0x66, 0xC5, 0x0A, 0x1C, 0x10, 0x20, 0xC1, + 0x86, 0x00, 0xF8, 0xCC, 0x66, 0x33, 0x18, 0xF8, 0x13, 0x22, 0x26, 0xE4, + 0x22, 0x22, 0x23, 0x10, 0xFF, 0xFC, 0xC6, 0x66, 0x66, 0x32, 0x26, 0x66, + 0x64, 0x80, 0x63, 0x26, 0x30 }; + +const GFXglyph RobotoCondensed_Regular8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 3, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' + { 4, 3, 4, 5, 1, -11 }, // 0x22 '"' + { 6, 8, 12, 8, 0, -11 }, // 0x23 '#' + { 18, 6, 15, 8, 1, -12 }, // 0x24 '$' + { 30, 9, 12, 11, 1, -11 }, // 0x25 '%' + { 44, 8, 12, 9, 1, -11 }, // 0x26 '&' + { 56, 1, 4, 3, 1, -11 }, // 0x27 ''' + { 57, 3, 17, 5, 1, -12 }, // 0x28 '(' + { 64, 4, 17, 5, 0, -12 }, // 0x29 ')' + { 73, 6, 7, 6, 0, -11 }, // 0x2A '*' + { 79, 6, 8, 8, 1, -8 }, // 0x2B '+' + { 85, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 86, 3, 1, 5, 1, -4 }, // 0x2D '-' + { 87, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 88, 5, 13, 5, 0, -11 }, // 0x2F '/' + { 97, 6, 12, 8, 1, -11 }, // 0x30 '0' + { 106, 4, 12, 8, 1, -11 }, // 0x31 '1' + { 112, 6, 12, 8, 1, -11 }, // 0x32 '2' + { 121, 6, 12, 8, 1, -11 }, // 0x33 '3' + { 130, 7, 12, 8, 0, -11 }, // 0x34 '4' + { 141, 6, 12, 8, 1, -11 }, // 0x35 '5' + { 150, 6, 12, 8, 1, -11 }, // 0x36 '6' + { 159, 6, 12, 8, 1, -11 }, // 0x37 '7' + { 168, 6, 12, 8, 1, -11 }, // 0x38 '8' + { 177, 6, 12, 8, 1, -11 }, // 0x39 '9' + { 186, 2, 9, 4, 1, -8 }, // 0x3A ':' + { 189, 2, 11, 4, 1, -8 }, // 0x3B ';' + { 192, 6, 7, 7, 0, -7 }, // 0x3C '<' + { 198, 6, 4, 8, 1, -6 }, // 0x3D '=' + { 201, 6, 7, 7, 1, -7 }, // 0x3E '>' + { 207, 6, 12, 7, 0, -11 }, // 0x3F '?' + { 216, 11, 15, 13, 1, -10 }, // 0x40 '@' + { 237, 9, 12, 9, 0, -11 }, // 0x41 'A' + { 251, 7, 12, 9, 1, -11 }, // 0x42 'B' + { 262, 7, 12, 8, 1, -11 }, // 0x43 'C' + { 273, 7, 12, 9, 1, -11 }, // 0x44 'D' + { 284, 7, 12, 8, 1, -11 }, // 0x45 'E' + { 295, 7, 12, 8, 1, -11 }, // 0x46 'F' + { 306, 7, 12, 9, 1, -11 }, // 0x47 'G' + { 317, 8, 12, 10, 1, -11 }, // 0x48 'H' + { 329, 2, 12, 4, 1, -11 }, // 0x49 'I' + { 332, 7, 12, 8, 0, -11 }, // 0x4A 'J' + { 343, 8, 12, 9, 1, -11 }, // 0x4B 'K' + { 355, 6, 12, 7, 1, -11 }, // 0x4C 'L' + { 364, 10, 12, 12, 1, -11 }, // 0x4D 'M' + { 379, 8, 12, 10, 1, -11 }, // 0x4E 'N' + { 391, 7, 12, 9, 1, -11 }, // 0x4F 'O' + { 402, 7, 12, 9, 1, -11 }, // 0x50 'P' + { 413, 8, 14, 9, 1, -11 }, // 0x51 'Q' + { 427, 8, 12, 9, 1, -11 }, // 0x52 'R' + { 439, 7, 12, 9, 1, -11 }, // 0x53 'S' + { 450, 8, 12, 8, 0, -11 }, // 0x54 'T' + { 462, 7, 12, 9, 1, -11 }, // 0x55 'U' + { 473, 9, 12, 9, 0, -11 }, // 0x56 'V' + { 487, 12, 12, 12, 0, -11 }, // 0x57 'W' + { 505, 8, 12, 9, 0, -11 }, // 0x58 'X' + { 517, 8, 12, 9, 0, -11 }, // 0x59 'Y' + { 529, 6, 12, 8, 1, -11 }, // 0x5A 'Z' + { 538, 3, 16, 4, 1, -12 }, // 0x5B '[' + { 544, 6, 13, 6, 0, -11 }, // 0x5C '\' + { 554, 3, 16, 4, 0, -12 }, // 0x5D ']' + { 560, 6, 6, 6, 0, -11 }, // 0x5E '^' + { 565, 6, 1, 6, 0, 1 }, // 0x5F '_' + { 566, 3, 2, 5, 1, -11 }, // 0x60 '`' + { 567, 6, 9, 7, 1, -8 }, // 0x61 'a' + { 574, 6, 12, 8, 1, -11 }, // 0x62 'b' + { 583, 6, 9, 7, 1, -8 }, // 0x63 'c' + { 590, 6, 12, 8, 1, -11 }, // 0x64 'd' + { 599, 6, 9, 7, 1, -8 }, // 0x65 'e' + { 606, 5, 12, 5, 0, -11 }, // 0x66 'f' + { 614, 6, 13, 8, 1, -8 }, // 0x67 'g' + { 624, 6, 12, 8, 1, -11 }, // 0x68 'h' + { 633, 2, 13, 4, 1, -12 }, // 0x69 'i' + { 637, 4, 17, 4, -1, -12 }, // 0x6A 'j' + { 646, 6, 12, 7, 1, -11 }, // 0x6B 'k' + { 655, 2, 12, 4, 1, -11 }, // 0x6C 'l' + { 658, 10, 9, 12, 1, -8 }, // 0x6D 'm' + { 670, 6, 9, 8, 1, -8 }, // 0x6E 'n' + { 677, 6, 9, 8, 1, -8 }, // 0x6F 'o' + { 684, 6, 13, 8, 1, -8 }, // 0x70 'p' + { 694, 6, 13, 8, 1, -8 }, // 0x71 'q' + { 704, 4, 9, 5, 1, -8 }, // 0x72 'r' + { 709, 6, 9, 7, 0, -8 }, // 0x73 's' + { 716, 5, 11, 5, 0, -10 }, // 0x74 't' + { 723, 6, 9, 8, 1, -8 }, // 0x75 'u' + { 730, 7, 9, 7, 0, -8 }, // 0x76 'v' + { 738, 10, 9, 10, 0, -8 }, // 0x77 'w' + { 750, 7, 9, 7, 0, -8 }, // 0x78 'x' + { 758, 7, 13, 7, 0, -8 }, // 0x79 'y' + { 770, 5, 9, 7, 1, -8 }, // 0x7A 'z' + { 776, 4, 15, 5, 0, -11 }, // 0x7B '{' + { 784, 1, 14, 3, 1, -11 }, // 0x7C '|' + { 786, 4, 15, 5, 0, -11 }, // 0x7D '}' + { 794, 7, 3, 9, 1, -5 } }; // 0x7E '~' + +const GFXfont RobotoCondensed_Regular8pt7b PROGMEM = { + (uint8_t *)RobotoCondensed_Regular8pt7bBitmaps, + (GFXglyph *)RobotoCondensed_Regular8pt7bGlyphs, + 0x20, 0x7E, 21 }; + +// Approx. 1469 bytes diff --git a/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h new file mode 100644 index 000000000..b8112a755 --- /dev/null +++ b/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h @@ -0,0 +1,265 @@ +const uint8_t RobotoMono_Regular12pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xC0, 0xCF, 0x3C, 0xF3, 0xCF, 0x30, 0x06, + 0x20, 0x23, 0x03, 0x18, 0x18, 0xC0, 0xC6, 0x3F, 0xFD, 0xFF, 0xE3, 0x18, + 0x18, 0xC0, 0xC4, 0x3F, 0xFD, 0xFF, 0xE3, 0x18, 0x18, 0xC0, 0xC6, 0x06, + 0x20, 0x23, 0x00, 0x06, 0x00, 0xC0, 0x38, 0x1F, 0xC7, 0x1C, 0xC1, 0x98, + 0x3B, 0x07, 0x60, 0x0F, 0x00, 0xF8, 0x07, 0xC0, 0x3C, 0x01, 0xC0, 0x1E, + 0x03, 0xC0, 0xEC, 0x39, 0xFE, 0x0F, 0x80, 0x40, 0x08, 0x00, 0x70, 0x07, + 0xC0, 0x23, 0x11, 0x19, 0x88, 0xC8, 0x7C, 0xC1, 0xE4, 0x00, 0x60, 0x06, + 0x00, 0x37, 0x03, 0x7C, 0x13, 0x31, 0x91, 0x98, 0x8C, 0x04, 0x60, 0x3E, + 0x00, 0xE0, 0x0F, 0x01, 0xFC, 0x0C, 0x60, 0x61, 0x83, 0x18, 0x19, 0xC0, + 0x7C, 0x03, 0xC0, 0x3E, 0x03, 0xB0, 0xD8, 0xCD, 0xC7, 0x6C, 0x1F, 0x70, + 0x71, 0x83, 0x8F, 0xFE, 0x1F, 0x38, 0xFF, 0xE0, 0x04, 0x31, 0x8C, 0x31, + 0x86, 0x18, 0x63, 0x0C, 0x30, 0xC3, 0x0C, 0x38, 0x61, 0x86, 0x0C, 0x30, + 0x60, 0xC3, 0x04, 0x83, 0x06, 0x0C, 0x30, 0x61, 0x86, 0x1C, 0x30, 0xC3, + 0x0C, 0x30, 0xC7, 0x18, 0x61, 0x8C, 0x31, 0x86, 0x30, 0x80, 0x0E, 0x00, + 0x80, 0x10, 0x42, 0x1F, 0x4E, 0xFF, 0xC3, 0x80, 0xD0, 0x1B, 0x06, 0x31, + 0xC7, 0x00, 0x80, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, + 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x77, + 0x76, 0x6C, 0x40, 0xFF, 0xFF, 0xC0, 0xFF, 0x80, 0x01, 0x81, 0x80, 0xC0, + 0x60, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x03, 0x03, 0x01, 0x81, + 0x80, 0xC0, 0x60, 0x60, 0x00, 0x1F, 0x0F, 0xF1, 0x87, 0x60, 0x6C, 0x0F, + 0x81, 0xF0, 0x7E, 0x3B, 0xCE, 0x7B, 0x0F, 0xC1, 0xF0, 0x3C, 0x0F, 0x81, + 0x98, 0x73, 0xFC, 0x1F, 0x00, 0x06, 0x3F, 0xFF, 0x30, 0x60, 0xC1, 0x83, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x1F, 0x07, 0xFC, 0x60, + 0xCC, 0x0E, 0xC0, 0x60, 0x0E, 0x00, 0xC0, 0x1C, 0x01, 0x80, 0x30, 0x06, + 0x00, 0xC0, 0x1C, 0x03, 0x80, 0x70, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0x0F, + 0xF9, 0x83, 0x70, 0x70, 0x0E, 0x01, 0xC0, 0x30, 0x7C, 0x0F, 0x80, 0x38, + 0x03, 0x80, 0x3C, 0x07, 0xC1, 0xD8, 0x33, 0xFE, 0x1F, 0x00, 0x01, 0xC0, + 0x1C, 0x03, 0xC0, 0x6C, 0x06, 0xC0, 0xCC, 0x18, 0xC1, 0x8C, 0x30, 0xC6, + 0x0C, 0x60, 0xCF, 0xFF, 0xFF, 0xF0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, + 0x3F, 0xC7, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x1F, 0xC3, 0xFE, 0x61, + 0xC0, 0x1C, 0x01, 0x80, 0x3C, 0x07, 0xC1, 0xD8, 0x31, 0xFE, 0x1F, 0x00, + 0x07, 0x07, 0xC3, 0x81, 0x80, 0x60, 0x33, 0x8F, 0xFB, 0xC7, 0xC0, 0xF0, + 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x36, 0x1D, 0xFE, 0x1F, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x60, 0x06, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x18, 0x03, 0x80, + 0x30, 0x07, 0x00, 0x60, 0x06, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x38, 0x00, + 0x1F, 0x0F, 0xF1, 0x83, 0x30, 0x6E, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x3F, + 0x8C, 0x1B, 0x83, 0xE0, 0x3C, 0x07, 0xC1, 0xD8, 0x33, 0xFE, 0x1F, 0x00, + 0x1E, 0x1F, 0xEE, 0x1B, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xE1, 0xDF, + 0xF3, 0xEC, 0x03, 0x00, 0xC0, 0x60, 0x38, 0xFC, 0x3C, 0x00, 0x6F, 0x60, + 0x00, 0x00, 0x00, 0x6F, 0x60, 0x6F, 0x60, 0x00, 0x00, 0x00, 0x66, 0x66, + 0xEC, 0x40, 0x00, 0x40, 0x70, 0xFC, 0xF8, 0xF8, 0x30, 0x07, 0x80, 0x7C, + 0x07, 0xC0, 0x70, 0x04, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xF8, 0x80, 0x3C, 0x07, 0xC0, 0x7C, 0x03, 0xC0, 0x30, 0x7C, 0x78, + 0xF8, 0x38, 0x08, 0x00, 0x1F, 0x1F, 0xE6, 0x1F, 0x03, 0x00, 0xC0, 0x30, + 0x1C, 0x0E, 0x07, 0x03, 0x80, 0xC0, 0x30, 0x00, 0x00, 0x00, 0xC0, 0x30, + 0x0C, 0x00, 0x0F, 0x80, 0xFF, 0x0C, 0x18, 0xC6, 0x64, 0x79, 0x66, 0x4B, + 0x62, 0x73, 0x13, 0x98, 0x9C, 0xCC, 0xA6, 0x65, 0x3D, 0xEC, 0xEE, 0x20, + 0x01, 0x80, 0x07, 0xF0, 0x0F, 0x00, 0x06, 0x00, 0x38, 0x01, 0xC0, 0x1E, + 0x00, 0xD8, 0x06, 0xC0, 0x66, 0x03, 0x18, 0x18, 0xC1, 0xC6, 0x0C, 0x38, + 0x7F, 0xC7, 0xFE, 0x30, 0x39, 0x80, 0xDC, 0x06, 0xC0, 0x38, 0xFF, 0x1F, + 0xF3, 0x03, 0x60, 0x7C, 0x0F, 0x81, 0xF0, 0x77, 0xFC, 0xFF, 0x98, 0x1B, + 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x37, 0xFE, 0xFF, 0x00, 0x0F, 0x83, + 0xFC, 0x30, 0x66, 0x07, 0x60, 0x3E, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, + 0x00, 0xC0, 0x0E, 0x00, 0x60, 0x36, 0x07, 0x30, 0x63, 0xFC, 0x0F, 0x80, + 0xFE, 0x1F, 0xF3, 0x07, 0x60, 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, + 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x0F, 0x81, 0xB0, 0x77, 0xFC, 0xFE, 0x00, + 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x07, 0xFC, 0xFF, + 0x98, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x07, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, + 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x00, + 0x0F, 0x83, 0xFC, 0x30, 0x66, 0x07, 0x60, 0x3E, 0x00, 0xC0, 0x0C, 0x00, + 0xC1, 0xFC, 0x1F, 0xC0, 0x3E, 0x03, 0x60, 0x36, 0x03, 0x30, 0x71, 0xFE, + 0x0F, 0x80, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1F, + 0xFF, 0xFF, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, + 0xC0, 0x60, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC3, 0xFF, 0xFF, 0xC0, + 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, + 0x60, 0x0C, 0x01, 0x80, 0x3C, 0x07, 0xC0, 0xDC, 0x31, 0xFE, 0x1F, 0x00, + 0xC0, 0xFC, 0x0C, 0xC1, 0xCC, 0x38, 0xC7, 0x0C, 0x60, 0xCC, 0x0D, 0xC0, + 0xFC, 0x0F, 0xE0, 0xE7, 0x0C, 0x30, 0xC3, 0x8C, 0x1C, 0xC0, 0xCC, 0x0E, + 0xC0, 0x70, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, + 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x07, 0xFF, + 0xFF, 0xE0, 0xE0, 0xFC, 0x1F, 0x87, 0xF8, 0xFF, 0x17, 0xE6, 0xF6, 0xDE, + 0xD3, 0xDE, 0x79, 0xCF, 0x31, 0xE6, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, + 0xC0, 0x60, 0xC0, 0x7C, 0x0F, 0x81, 0xF8, 0x3F, 0x07, 0xF0, 0xF6, 0x3E, + 0x67, 0xCC, 0xF8, 0xDF, 0x1B, 0xE1, 0xFC, 0x3F, 0x83, 0xF0, 0x7E, 0x07, + 0xC0, 0xE0, 0x0F, 0x83, 0xFC, 0x30, 0xE6, 0x06, 0x60, 0x3E, 0x03, 0xC0, + 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x03, 0x60, 0x36, 0x06, 0x30, + 0xE3, 0xFC, 0x0F, 0x80, 0xFF, 0x1F, 0xFB, 0x03, 0xE0, 0x3C, 0x07, 0x80, + 0xF0, 0x1E, 0x07, 0xFF, 0xDF, 0xE3, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, + 0x06, 0x00, 0xC0, 0x00, 0x0F, 0x81, 0xFE, 0x0C, 0x38, 0xC0, 0xC6, 0x03, + 0x70, 0x1B, 0x00, 0xD8, 0x06, 0xC0, 0x36, 0x01, 0xB0, 0x0D, 0x80, 0x66, + 0x03, 0x30, 0x30, 0xC3, 0x87, 0xF8, 0x0F, 0xC0, 0x03, 0x80, 0x0E, 0x00, + 0x20, 0xFF, 0x1F, 0xF3, 0x03, 0x60, 0x7C, 0x07, 0x80, 0xF0, 0x3E, 0x06, + 0xFF, 0x9F, 0xE3, 0x0C, 0x61, 0xCC, 0x19, 0x83, 0xB0, 0x36, 0x07, 0xC0, + 0x60, 0x0F, 0x83, 0xFE, 0x70, 0x66, 0x07, 0x60, 0x36, 0x00, 0x70, 0x03, + 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0x70, 0x03, 0xE0, 0x36, 0x03, 0x70, 0x73, + 0xFE, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xC1, 0x80, 0x0C, 0x00, 0x60, 0x03, + 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, + 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0xC0, 0x78, 0x0F, 0x01, 0xE0, + 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, + 0x0F, 0x81, 0x98, 0x73, 0xFC, 0x1F, 0x00, 0xC0, 0x3E, 0x03, 0x60, 0x76, + 0x06, 0x60, 0x63, 0x06, 0x30, 0xC3, 0x0C, 0x18, 0xC1, 0x98, 0x19, 0x81, + 0xD8, 0x0F, 0x80, 0xF0, 0x0F, 0x00, 0x70, 0x06, 0x00, 0xC6, 0x1E, 0x38, + 0xF1, 0xC7, 0x8E, 0x6C, 0x73, 0x26, 0x99, 0xB4, 0xCD, 0xB6, 0x6D, 0xB3, + 0x4D, 0x9A, 0x6C, 0xF1, 0x47, 0x8E, 0x1C, 0x70, 0xE3, 0x86, 0x1C, 0x30, + 0xE0, 0xE0, 0x3B, 0x83, 0x8C, 0x18, 0x71, 0xC1, 0x8C, 0x0E, 0xC0, 0x3E, + 0x00, 0xE0, 0x07, 0x00, 0x78, 0x03, 0x60, 0x3B, 0x01, 0x8C, 0x1C, 0x71, + 0xC1, 0x8C, 0x0E, 0xE0, 0x38, 0xC0, 0x3E, 0x07, 0x60, 0x67, 0x0E, 0x30, + 0xC3, 0x9C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, + 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0xEF, 0xFE, 0x00, 0xE0, + 0x0C, 0x01, 0xC0, 0x38, 0x03, 0x00, 0x70, 0x06, 0x00, 0xC0, 0x1C, 0x01, + 0x80, 0x38, 0x07, 0x00, 0x60, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xF1, 0x8C, + 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7F, 0xE0, + 0xC0, 0x60, 0x18, 0x0C, 0x06, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x03, + 0x01, 0x80, 0x40, 0x30, 0x18, 0x06, 0x03, 0x01, 0xC0, 0xFF, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0, 0x18, 0x0E, 0x0F, + 0x07, 0x83, 0x63, 0x31, 0x8D, 0x86, 0xC3, 0x80, 0xFF, 0xFF, 0xFC, 0xE3, + 0x8E, 0x1F, 0x0F, 0xF3, 0x87, 0x60, 0x60, 0x0C, 0x3F, 0x9F, 0xF7, 0x06, + 0xC0, 0xD8, 0x1B, 0x87, 0x3F, 0xE3, 0xEE, 0xC0, 0x18, 0x03, 0x00, 0x60, + 0x0C, 0x01, 0x9E, 0x3F, 0xE7, 0x0E, 0xC0, 0xD8, 0x1F, 0x01, 0xE0, 0x3C, + 0x07, 0x81, 0xF0, 0x37, 0x0E, 0xFF, 0x99, 0xE0, 0x1F, 0x0F, 0xF1, 0x83, + 0x60, 0x6C, 0x07, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x1D, 0x83, 0x3F, + 0xC1, 0xF0, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC7, 0xB7, 0xFD, 0x87, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0D, 0x87, 0x7F, 0xC7, + 0xB0, 0x1F, 0x07, 0xF1, 0x87, 0x60, 0x6C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, + 0xC0, 0x1C, 0x09, 0x83, 0xBF, 0xE1, 0xF0, 0x03, 0xC0, 0xFC, 0x38, 0x0E, + 0x01, 0x80, 0x30, 0x3F, 0xF7, 0xFE, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, + 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x00, 0x1E, 0xDF, + 0xF6, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x1D, + 0xFF, 0x1E, 0xC0, 0x34, 0x0F, 0x87, 0x7F, 0x8F, 0xC0, 0xC0, 0x18, 0x03, + 0x00, 0x60, 0x0C, 0x01, 0x9E, 0x37, 0xF7, 0x06, 0xC0, 0xD8, 0x1B, 0x03, + 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xC0, 0xF8, 0x1C, 0x06, 0x01, + 0xC0, 0x18, 0x00, 0x0F, 0xE1, 0xFC, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, + 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x87, 0xFF, 0xFF, 0xE0, 0x03, 0x07, + 0x03, 0x00, 0x7F, 0x7F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x07, 0x06, 0x7E, 0xF8, 0xC0, 0x18, 0x03, 0x00, + 0x60, 0x0C, 0x01, 0x83, 0xB0, 0xE6, 0x38, 0xCE, 0x1B, 0x83, 0x60, 0x7E, + 0x0E, 0xE1, 0x8E, 0x30, 0xE6, 0x0C, 0xC1, 0xD8, 0x1C, 0xFE, 0x1F, 0xC0, + 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, + 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0xFF, 0xFF, 0xFC, 0xDC, 0xEF, + 0xFF, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, + 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x30, 0xCF, 0x37, 0xFE, 0x0F, 0x03, 0xC0, + 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x0F, + 0x83, 0xFC, 0x70, 0xE6, 0x06, 0x60, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0x60, + 0x36, 0x06, 0x70, 0xE3, 0xFC, 0x0F, 0x80, 0xDF, 0x1F, 0xF3, 0x87, 0x60, + 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0xF8, 0x1B, 0x87, 0x7F, 0xCD, + 0xF1, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00, 0x1E, 0xDF, 0xF6, 0x1F, + 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x1D, 0xFF, 0x1E, + 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xCF, 0xFF, 0xB8, 0x1C, 0x0C, + 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x1F, 0x0F, + 0xF9, 0x83, 0x70, 0x76, 0x00, 0xF0, 0x07, 0xE0, 0x1E, 0x00, 0xF8, 0x1F, + 0x83, 0x3F, 0xE1, 0xF0, 0x18, 0x06, 0x01, 0x83, 0xFF, 0xFF, 0xC6, 0x01, + 0x80, 0x60, 0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x07, 0x00, 0xFC, 0x1F, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, + 0x36, 0x1D, 0xFF, 0x3E, 0xC0, 0xE0, 0x36, 0x07, 0x60, 0x63, 0x06, 0x30, + 0xC3, 0x0C, 0x18, 0xC1, 0x98, 0x0D, 0x80, 0xD0, 0x0F, 0x00, 0x70, 0x06, + 0x00, 0xC6, 0x1E, 0x30, 0xF1, 0xC5, 0x8E, 0x6C, 0xF3, 0x26, 0x99, 0xB6, + 0xCD, 0x34, 0x79, 0xA1, 0xC7, 0x0E, 0x38, 0x61, 0xC3, 0x0C, 0x00, 0xE0, + 0x73, 0x06, 0x38, 0xC1, 0x9C, 0x0F, 0x80, 0xF0, 0x07, 0x00, 0xF0, 0x0D, + 0x81, 0x9C, 0x38, 0xC7, 0x06, 0xE0, 0x70, 0xC0, 0x3F, 0x01, 0x98, 0x18, + 0xE0, 0xC3, 0x0E, 0x1C, 0x60, 0x63, 0x03, 0x30, 0x0D, 0x80, 0x78, 0x03, + 0xC0, 0x0E, 0x00, 0x60, 0x03, 0x00, 0x30, 0x03, 0x80, 0x78, 0x03, 0x80, + 0x00, 0xFF, 0xDF, 0xF8, 0x07, 0x01, 0xC0, 0x70, 0x0C, 0x03, 0x00, 0xE0, + 0x38, 0x0E, 0x01, 0x80, 0x7F, 0xFF, 0xFE, 0x07, 0x0F, 0x0C, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0, 0x30, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1C, 0x0C, 0x0F, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0xC0, 0xE0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x18, 0x0F, 0x0F, + 0x1C, 0x18, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0xE0, 0xC0, 0x30, + 0x07, 0xE0, 0xF1, 0x87, 0x07, 0xE0, 0x1E, 0x00 }; + +const GFXglyph RobotoMono_Regular12pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 14, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 14, 6, -16 }, // 0x21 '!' + { 6, 6, 6, 14, 4, -17 }, // 0x22 '"' + { 11, 13, 17, 14, 1, -16 }, // 0x23 '#' + { 39, 11, 22, 14, 2, -19 }, // 0x24 '$' + { 70, 13, 17, 14, 1, -16 }, // 0x25 '%' + { 98, 13, 17, 14, 1, -16 }, // 0x26 '&' + { 126, 2, 6, 14, 6, -17 }, // 0x27 ''' + { 128, 6, 25, 14, 4, -18 }, // 0x28 '(' + { 147, 6, 25, 14, 4, -18 }, // 0x29 ')' + { 166, 11, 12, 14, 2, -13 }, // 0x2A '*' + { 183, 12, 13, 14, 1, -14 }, // 0x2B '+' + { 203, 4, 7, 14, 4, -2 }, // 0x2C ',' + { 207, 9, 2, 14, 3, -8 }, // 0x2D '-' + { 210, 3, 3, 14, 6, -2 }, // 0x2E '.' + { 212, 9, 18, 14, 3, -16 }, // 0x2F '/' + { 233, 11, 17, 14, 2, -16 }, // 0x30 '0' + { 257, 7, 17, 14, 2, -16 }, // 0x31 '1' + { 272, 12, 17, 14, 1, -16 }, // 0x32 '2' + { 298, 11, 17, 14, 1, -16 }, // 0x33 '3' + { 322, 12, 17, 14, 1, -16 }, // 0x34 '4' + { 348, 11, 17, 14, 2, -16 }, // 0x35 '5' + { 372, 10, 17, 14, 2, -16 }, // 0x36 '6' + { 394, 12, 17, 14, 1, -16 }, // 0x37 '7' + { 420, 11, 17, 14, 2, -16 }, // 0x38 '8' + { 444, 10, 17, 14, 2, -16 }, // 0x39 '9' + { 466, 4, 13, 14, 6, -12 }, // 0x3A ':' + { 473, 4, 17, 14, 6, -12 }, // 0x3B ';' + { 482, 10, 11, 14, 2, -12 }, // 0x3C '<' + { 496, 11, 7, 14, 2, -10 }, // 0x3D '=' + { 506, 10, 11, 14, 2, -12 }, // 0x3E '>' + { 520, 10, 17, 14, 2, -16 }, // 0x3F '?' + { 542, 13, 17, 14, 1, -16 }, // 0x40 '@' + { 570, 13, 17, 14, 1, -16 }, // 0x41 'A' + { 598, 11, 17, 14, 2, -16 }, // 0x42 'B' + { 622, 12, 17, 14, 1, -16 }, // 0x43 'C' + { 648, 11, 17, 14, 2, -16 }, // 0x44 'D' + { 672, 11, 17, 14, 2, -16 }, // 0x45 'E' + { 696, 11, 17, 14, 2, -16 }, // 0x46 'F' + { 720, 12, 17, 14, 1, -16 }, // 0x47 'G' + { 746, 11, 17, 14, 2, -16 }, // 0x48 'H' + { 770, 10, 17, 14, 2, -16 }, // 0x49 'I' + { 792, 11, 17, 14, 1, -16 }, // 0x4A 'J' + { 816, 12, 17, 14, 2, -16 }, // 0x4B 'K' + { 842, 11, 17, 14, 2, -16 }, // 0x4C 'L' + { 866, 11, 17, 14, 2, -16 }, // 0x4D 'M' + { 890, 11, 17, 14, 2, -16 }, // 0x4E 'N' + { 914, 12, 17, 14, 1, -16 }, // 0x4F 'O' + { 940, 11, 17, 14, 2, -16 }, // 0x50 'P' + { 964, 13, 20, 14, 1, -16 }, // 0x51 'Q' + { 997, 11, 17, 14, 2, -16 }, // 0x52 'R' + { 1021, 12, 17, 14, 1, -16 }, // 0x53 'S' + { 1047, 13, 17, 14, 1, -16 }, // 0x54 'T' + { 1075, 11, 17, 14, 2, -16 }, // 0x55 'U' + { 1099, 12, 17, 14, 1, -16 }, // 0x56 'V' + { 1125, 13, 17, 14, 1, -16 }, // 0x57 'W' + { 1153, 13, 17, 14, 1, -16 }, // 0x58 'X' + { 1181, 12, 17, 14, 1, -16 }, // 0x59 'Y' + { 1207, 12, 17, 14, 1, -16 }, // 0x5A 'Z' + { 1233, 5, 23, 14, 5, -18 }, // 0x5B '[' + { 1248, 9, 18, 14, 3, -16 }, // 0x5C '\' + { 1269, 4, 23, 14, 5, -18 }, // 0x5D ']' + { 1281, 9, 9, 14, 3, -16 }, // 0x5E '^' + { 1292, 11, 2, 14, 2, 1 }, // 0x5F '_' + { 1295, 5, 3, 14, 5, -17 }, // 0x60 '`' + { 1297, 11, 13, 14, 2, -12 }, // 0x61 'a' + { 1315, 11, 18, 14, 2, -17 }, // 0x62 'b' + { 1340, 11, 13, 14, 2, -12 }, // 0x63 'c' + { 1358, 10, 18, 14, 2, -17 }, // 0x64 'd' + { 1381, 11, 13, 14, 2, -12 }, // 0x65 'e' + { 1399, 11, 19, 14, 2, -18 }, // 0x66 'f' + { 1426, 10, 18, 14, 2, -12 }, // 0x67 'g' + { 1449, 11, 18, 14, 2, -17 }, // 0x68 'h' + { 1474, 11, 17, 14, 2, -16 }, // 0x69 'i' + { 1498, 8, 22, 14, 2, -16 }, // 0x6A 'j' + { 1520, 11, 18, 14, 2, -17 }, // 0x6B 'k' + { 1545, 11, 18, 14, 2, -17 }, // 0x6C 'l' + { 1570, 12, 13, 14, 1, -12 }, // 0x6D 'm' + { 1590, 10, 13, 14, 2, -12 }, // 0x6E 'n' + { 1607, 12, 13, 14, 1, -12 }, // 0x6F 'o' + { 1627, 11, 18, 14, 2, -12 }, // 0x70 'p' + { 1652, 10, 18, 14, 2, -12 }, // 0x71 'q' + { 1675, 9, 13, 14, 4, -12 }, // 0x72 'r' + { 1690, 11, 13, 14, 2, -12 }, // 0x73 's' + { 1708, 10, 16, 14, 2, -15 }, // 0x74 't' + { 1728, 10, 13, 14, 2, -12 }, // 0x75 'u' + { 1745, 12, 13, 14, 1, -12 }, // 0x76 'v' + { 1765, 13, 13, 14, 1, -12 }, // 0x77 'w' + { 1787, 12, 13, 14, 1, -12 }, // 0x78 'x' + { 1807, 13, 18, 14, 1, -12 }, // 0x79 'y' + { 1837, 11, 13, 14, 2, -12 }, // 0x7A 'z' + { 1855, 8, 23, 14, 4, -18 }, // 0x7B '{' + { 1878, 2, 22, 14, 6, -16 }, // 0x7C '|' + { 1884, 8, 23, 14, 4, -18 }, // 0x7D '}' + { 1907, 13, 5, 14, 1, -9 } }; // 0x7E '~' + +const GFXfont RobotoMono_Regular12pt7b PROGMEM = { + (uint8_t *)RobotoMono_Regular12pt7bBitmaps, + (GFXglyph *)RobotoMono_Regular12pt7bGlyphs, + 0x20, 0x7E, 31 }; + +// Approx. 2588 bytes diff --git a/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h new file mode 100644 index 000000000..2c1fcf670 --- /dev/null +++ b/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h @@ -0,0 +1,369 @@ +const uint8_t RobotoMono_Regular16pt7bBitmaps[] PROGMEM = { + 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x00, 0x06, 0xF6, + 0xE3, 0xE3, 0xE3, 0xE3, 0xC3, 0xC3, 0xC3, 0x01, 0x86, 0x01, 0x87, 0x00, + 0xC3, 0x00, 0x61, 0x80, 0x30, 0xC0, 0x38, 0x61, 0xFF, 0xFE, 0xFF, 0xFF, + 0x06, 0x18, 0x03, 0x0C, 0x01, 0x86, 0x01, 0xC7, 0x00, 0xC3, 0x80, 0x61, + 0x83, 0xFF, 0xFD, 0xFF, 0xFE, 0x1C, 0x30, 0x0C, 0x38, 0x06, 0x18, 0x03, + 0x0C, 0x01, 0x86, 0x01, 0xC7, 0x00, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, + 0x0C, 0x00, 0xFF, 0x03, 0xFF, 0x0F, 0x0E, 0x1C, 0x0E, 0x70, 0x1C, 0xE0, + 0x39, 0xC0, 0x31, 0xC0, 0x03, 0xC0, 0x03, 0xE0, 0x03, 0xF0, 0x03, 0xF8, + 0x00, 0xF8, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6E, 0x00, 0xEE, 0x01, 0x9C, + 0x07, 0x3C, 0x1E, 0x3F, 0xF8, 0x1F, 0xE0, 0x0E, 0x00, 0x1C, 0x00, 0x38, + 0x00, 0x3C, 0x00, 0x7F, 0x00, 0x39, 0xC0, 0x18, 0x61, 0x8C, 0x31, 0x86, + 0x19, 0xC3, 0x9C, 0xC1, 0xFC, 0xC0, 0x3C, 0x60, 0x00, 0x60, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x39, 0xE0, 0x19, 0xF8, 0x19, 0xCE, 0x0C, 0xC3, 0x0C, + 0x61, 0x8E, 0x30, 0xC2, 0x18, 0x60, 0x0E, 0x70, 0x03, 0xF0, 0x00, 0xF0, + 0x0F, 0x80, 0x1F, 0xE0, 0x3C, 0xE0, 0x38, 0x70, 0x30, 0x70, 0x30, 0x70, + 0x38, 0xE0, 0x39, 0xE0, 0x1F, 0xC0, 0x1F, 0x00, 0x0E, 0x00, 0x3F, 0x00, + 0x7F, 0x86, 0xF3, 0xC6, 0xE1, 0xC6, 0xE0, 0xEE, 0xC0, 0x7C, 0xE0, 0x7C, + 0xE0, 0x3C, 0x79, 0xFC, 0x7F, 0xEE, 0x1F, 0x8F, 0xFF, 0xFF, 0xF8, 0x01, + 0x03, 0x06, 0x0E, 0x1C, 0x18, 0x38, 0x38, 0x30, 0x70, 0x70, 0x70, 0x60, + 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x60, 0x60, 0x70, 0x70, 0x70, 0x30, 0x38, + 0x38, 0x18, 0x1C, 0x0E, 0x06, 0x03, 0x01, 0xC0, 0xE0, 0x70, 0x30, 0x38, + 0x18, 0x1C, 0x0C, 0x0E, 0x0E, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x06, 0x06, 0x0E, 0x0E, 0x0C, 0x1C, 0x18, 0x38, 0x30, + 0x60, 0xE0, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x06, 0x00, 0x0C, 0x04, 0x18, + 0x4E, 0x33, 0xFF, 0xFF, 0x8F, 0xFC, 0x03, 0x80, 0x0F, 0x80, 0x3B, 0x80, + 0x63, 0x81, 0xC7, 0x07, 0x07, 0x02, 0x0C, 0x00, 0x03, 0x80, 0x07, 0x00, + 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x7F, 0xFF, 0xFF, + 0xFE, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, + 0x01, 0xC0, 0x39, 0xCE, 0x73, 0xB9, 0xDC, 0x20, 0xFF, 0xFF, 0xFF, 0xEF, + 0xFE, 0x00, 0x70, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0xC0, 0x18, 0x01, 0x80, + 0x38, 0x03, 0x00, 0x70, 0x07, 0x00, 0x60, 0x0E, 0x00, 0xC0, 0x0C, 0x01, + 0xC0, 0x18, 0x03, 0x80, 0x38, 0x03, 0x00, 0x70, 0x06, 0x00, 0x60, 0x0E, + 0x00, 0x0F, 0xC0, 0x7F, 0xC3, 0xCF, 0x9C, 0x0E, 0x70, 0x1F, 0x80, 0x7E, + 0x00, 0xF8, 0x0F, 0xE0, 0x7F, 0x83, 0xBE, 0x3C, 0xF9, 0xE3, 0xEE, 0x0F, + 0xF0, 0x3F, 0x00, 0xF8, 0x07, 0xE0, 0x1D, 0xC0, 0x77, 0x03, 0x8F, 0x3E, + 0x1F, 0xF0, 0x3F, 0x00, 0x03, 0x87, 0xDF, 0xFF, 0x7E, 0x38, 0x1C, 0x0E, + 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, + 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x07, 0xC0, 0x3F, 0xE0, 0xF3, 0xE3, 0x81, + 0xE7, 0x01, 0xDC, 0x03, 0xB8, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x70, + 0x01, 0xC0, 0x07, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, + 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x07, 0xFF, 0xEF, 0xFF, 0xC0, 0x0F, + 0xC0, 0x7F, 0xC3, 0xC7, 0x9C, 0x07, 0x70, 0x1D, 0x80, 0x70, 0x01, 0xC0, + 0x07, 0x00, 0x78, 0x1F, 0xC0, 0x7F, 0x00, 0x3E, 0x00, 0x3C, 0x00, 0x70, + 0x00, 0xC0, 0x03, 0xE0, 0x1D, 0xC0, 0x77, 0x01, 0xCF, 0x1E, 0x1F, 0xF0, + 0x3F, 0x00, 0x00, 0x38, 0x00, 0x78, 0x00, 0xF8, 0x00, 0xF8, 0x01, 0xF8, + 0x03, 0xB8, 0x03, 0xB8, 0x07, 0x38, 0x06, 0x38, 0x0E, 0x38, 0x1C, 0x38, + 0x18, 0x38, 0x38, 0x38, 0x70, 0x38, 0x60, 0x38, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x3F, 0xF8, + 0xFF, 0xE7, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0xF0, + 0x7F, 0xE1, 0xE7, 0xC6, 0x07, 0x80, 0x0E, 0x00, 0x1C, 0x00, 0x70, 0x01, + 0xC0, 0x07, 0xE0, 0x1F, 0x80, 0xE7, 0x03, 0x9F, 0x3C, 0x3F, 0xE0, 0x3F, + 0x00, 0x01, 0xE0, 0x1F, 0x81, 0xF8, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x07, + 0x00, 0x19, 0xF0, 0xEF, 0xF3, 0xF3, 0xEF, 0x03, 0xBC, 0x07, 0xE0, 0x1F, + 0x80, 0x7E, 0x01, 0xF8, 0x07, 0x60, 0x1D, 0xC0, 0x77, 0x83, 0x8F, 0x3E, + 0x1F, 0xF0, 0x1F, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x30, 0x00, 0xE0, + 0x01, 0x80, 0x07, 0x00, 0x0C, 0x00, 0x38, 0x00, 0x60, 0x01, 0xC0, 0x03, + 0x80, 0x0E, 0x00, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x01, 0x80, 0x07, 0x00, + 0x0C, 0x00, 0x38, 0x00, 0x70, 0x01, 0xC0, 0x03, 0x80, 0x00, 0x0F, 0xC0, + 0xFF, 0x87, 0x8F, 0x1C, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0x9C, 0x0E, + 0x78, 0x70, 0xFF, 0x81, 0xFE, 0x1F, 0x3C, 0x70, 0x3B, 0x80, 0xEE, 0x01, + 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0xEF, 0x03, 0x9F, 0x3C, 0x3F, 0xE0, 0x3F, + 0x00, 0x0F, 0xC0, 0x7F, 0x83, 0xCF, 0x1C, 0x0E, 0x70, 0x3B, 0x80, 0x7E, + 0x01, 0xF8, 0x07, 0xE0, 0x1D, 0x80, 0x77, 0x03, 0xDE, 0x1F, 0x3F, 0xFC, + 0x7F, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x38, 0x00, 0xE0, 0x0F, 0x01, 0xF8, + 0x1F, 0xC0, 0x7C, 0x00, 0x77, 0xFE, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3B, 0xFF, 0x70, 0x39, 0xE7, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x8E, 0x38, 0xE3, 0x9C, 0x73, 0x82, 0x00, 0x00, 0x10, 0x07, + 0x01, 0xF0, 0x7E, 0x1F, 0x8F, 0xC0, 0xF0, 0x0F, 0x00, 0xFC, 0x01, 0xF8, + 0x07, 0xE0, 0x1F, 0x00, 0x70, 0x01, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x80, 0x07, 0x00, + 0x3E, 0x00, 0xFE, 0x00, 0xFC, 0x01, 0xF8, 0x01, 0xE0, 0x0F, 0x03, 0xF0, + 0x7E, 0x1F, 0xC1, 0xF0, 0x0E, 0x00, 0x40, 0x00, 0x1F, 0x81, 0xFF, 0x1E, + 0x3D, 0xC0, 0xFE, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x70, 0x07, + 0x80, 0x78, 0x07, 0x80, 0x78, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0xF0, 0x03, 0x80, 0x03, 0xF0, 0x03, 0xFC, + 0x07, 0x8F, 0x03, 0x00, 0xC3, 0x0E, 0x33, 0x9F, 0x99, 0x8E, 0xCC, 0xCC, + 0x62, 0xC6, 0x31, 0xE3, 0x18, 0xF3, 0x0C, 0x79, 0x86, 0x2C, 0xC3, 0x16, + 0x61, 0x1B, 0x39, 0xCD, 0x8F, 0xFC, 0x67, 0x9C, 0x30, 0x00, 0x1C, 0x00, + 0x07, 0xC6, 0x01, 0xFF, 0x00, 0x3F, 0x00, 0x01, 0xC0, 0x00, 0xE0, 0x00, + 0x70, 0x00, 0x7C, 0x00, 0x36, 0x00, 0x1B, 0x00, 0x1D, 0xC0, 0x0C, 0x60, + 0x06, 0x30, 0x07, 0x1C, 0x03, 0x8E, 0x01, 0x83, 0x01, 0xC1, 0xC0, 0xE0, + 0xE0, 0x7F, 0xF0, 0x7F, 0xFC, 0x38, 0x0E, 0x18, 0x03, 0x1C, 0x01, 0xCE, + 0x00, 0xE6, 0x00, 0x77, 0x00, 0x1C, 0xFF, 0x83, 0xFF, 0x8C, 0x0F, 0x30, + 0x0E, 0xC0, 0x3B, 0x00, 0xEC, 0x03, 0xB0, 0x0E, 0xC0, 0x73, 0xFF, 0x8F, + 0xFE, 0x30, 0x3C, 0xC0, 0x3B, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, + 0x00, 0x7C, 0x03, 0xB0, 0x3E, 0xFF, 0xF3, 0xFF, 0x00, 0x07, 0xC0, 0x3F, + 0xE0, 0xF3, 0xE3, 0x80, 0xE7, 0x01, 0xDC, 0x01, 0xF8, 0x03, 0xF0, 0x00, + 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x38, + 0x00, 0x70, 0x07, 0xE0, 0x0E, 0xE0, 0x39, 0xC0, 0x71, 0xE3, 0xC1, 0xFF, + 0x00, 0xF8, 0x00, 0xFF, 0x81, 0xFF, 0xC3, 0x87, 0xC7, 0x01, 0xCE, 0x01, + 0xDC, 0x03, 0xB8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, + 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x1D, 0xC0, + 0x3B, 0x80, 0xE7, 0x0F, 0x8F, 0xFE, 0x1F, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, + 0xF8, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, + 0xFF, 0xBF, 0xFD, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, + 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0F, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, + 0xF8, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, + 0x00, 0x3F, 0xFD, 0xFF, 0xEE, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, + 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x00, 0x07, 0xC0, 0x3F, + 0xE0, 0xF1, 0xE3, 0x80, 0xE7, 0x01, 0xDC, 0x01, 0xF8, 0x00, 0x70, 0x00, + 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x07, 0xFC, 0x0F, 0xF8, 0x01, 0xF8, + 0x03, 0xF0, 0x07, 0xE0, 0x0E, 0xE0, 0x1D, 0xE0, 0x39, 0xF1, 0xE1, 0xFF, + 0x80, 0xFC, 0x00, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, + 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, + 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, + 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x30, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0x0E, + 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0, + 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, + 0xC0, 0x0E, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, + 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, + 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0xF0, 0x07, + 0x60, 0x0E, 0xE0, 0x39, 0xE0, 0x71, 0xF3, 0xC1, 0xFF, 0x00, 0xF8, 0x00, + 0xC0, 0x1D, 0x80, 0x73, 0x01, 0xE6, 0x07, 0x8C, 0x1E, 0x18, 0x38, 0x30, + 0xE0, 0x63, 0xC0, 0xCF, 0x01, 0x9C, 0x03, 0x78, 0x07, 0xF8, 0x0F, 0x78, + 0x1E, 0x70, 0x38, 0x70, 0x60, 0xF0, 0xC0, 0xE1, 0x80, 0xE3, 0x01, 0xE6, + 0x01, 0xCC, 0x01, 0xD8, 0x03, 0xC0, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, + 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, + 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, + 0x80, 0x0E, 0x00, 0x38, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x1F, 0xE0, + 0x3F, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x0F, 0xFF, 0x1B, 0xF6, 0x37, + 0xEC, 0xEF, 0xDD, 0x9F, 0x9F, 0x3F, 0x3E, 0x7E, 0x78, 0xFC, 0x71, 0xF8, + 0xE3, 0xF1, 0x87, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, + 0xFC, 0x01, 0xC0, 0xE0, 0x0F, 0xC0, 0x3F, 0x00, 0xFE, 0x03, 0xF8, 0x0F, + 0xF0, 0x3F, 0xC0, 0xFB, 0x83, 0xEE, 0x0F, 0x9C, 0x3E, 0x30, 0xF8, 0xE3, + 0xE1, 0xCF, 0x87, 0x3E, 0x0E, 0xF8, 0x3B, 0xE0, 0x7F, 0x81, 0xFE, 0x03, + 0xF8, 0x0F, 0xE0, 0x1F, 0x80, 0x70, 0x07, 0xC0, 0x3F, 0xE0, 0xF3, 0xE3, + 0x81, 0xC7, 0x01, 0xDC, 0x03, 0xB8, 0x03, 0xF0, 0x07, 0xC0, 0x0F, 0x80, + 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF8, 0x03, 0xF0, 0x07, + 0xE0, 0x1C, 0xE0, 0x39, 0xC0, 0xE1, 0xE7, 0xC1, 0xFF, 0x00, 0xF8, 0x00, + 0xFF, 0xC3, 0xFF, 0xCE, 0x0F, 0xB8, 0x0F, 0xE0, 0x1F, 0x80, 0x7E, 0x00, + 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0xFE, 0x0F, 0xBF, 0xFC, 0xFF, 0xC3, 0x80, + 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, + 0x03, 0x80, 0x00, 0x03, 0xE0, 0x07, 0xFC, 0x07, 0x9F, 0x07, 0x03, 0x83, + 0x00, 0xE3, 0x80, 0x31, 0xC0, 0x1C, 0xC0, 0x0E, 0xE0, 0x07, 0x70, 0x03, + 0xB8, 0x01, 0xDC, 0x00, 0xEE, 0x00, 0x73, 0x00, 0x39, 0x80, 0x1C, 0xE0, + 0x0E, 0x70, 0x06, 0x18, 0x07, 0x0E, 0x07, 0x83, 0xCF, 0x80, 0xFF, 0x80, + 0x1F, 0xE0, 0x00, 0x78, 0x00, 0x1F, 0x00, 0x03, 0x00, 0x01, 0x00, 0xFF, + 0x83, 0xFF, 0x8E, 0x1F, 0x38, 0x0E, 0xE0, 0x3B, 0x80, 0x7E, 0x01, 0xF8, + 0x07, 0xE0, 0x3B, 0x80, 0xEE, 0x1F, 0x3F, 0xF8, 0xFF, 0xC3, 0x87, 0x0E, + 0x0E, 0x38, 0x38, 0xE0, 0x73, 0x81, 0xCE, 0x03, 0xB8, 0x0E, 0xE0, 0x1F, + 0x80, 0x70, 0x07, 0xC0, 0x3F, 0xE0, 0xF1, 0xE3, 0x80, 0xE7, 0x00, 0xFC, + 0x01, 0xF8, 0x00, 0x38, 0x00, 0x78, 0x00, 0x7E, 0x00, 0x7F, 0x00, 0x3F, + 0x80, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x80, 0x07, 0xE0, 0x0F, 0xC0, 0x1D, + 0xC0, 0x7B, 0xE3, 0xE1, 0xFF, 0x80, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, + 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, + 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, + 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0xE0, 0x0D, 0xC0, 0x1B, 0x80, + 0x37, 0x00, 0x6E, 0x00, 0xDC, 0x01, 0xB8, 0x03, 0x70, 0x06, 0xE0, 0x0D, + 0xC0, 0x1B, 0x80, 0x37, 0x00, 0x6E, 0x00, 0xDC, 0x01, 0xB8, 0x03, 0xF0, + 0x06, 0xE0, 0x1C, 0xE0, 0x39, 0xC0, 0xE1, 0xE7, 0xC1, 0xFF, 0x01, 0xF8, + 0x00, 0xE0, 0x07, 0x70, 0x07, 0x70, 0x07, 0x70, 0x0E, 0x70, 0x0E, 0x38, + 0x0E, 0x38, 0x1C, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x18, 0x1C, 0x38, 0x0C, + 0x38, 0x0E, 0x30, 0x0E, 0x70, 0x06, 0x70, 0x07, 0x70, 0x07, 0x60, 0x03, + 0xE0, 0x03, 0xE0, 0x03, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0xE1, 0xC3, 0xF0, + 0xE1, 0xF8, 0x70, 0xEC, 0x38, 0x66, 0x3E, 0x33, 0x1F, 0x19, 0x8D, 0x8C, + 0xE6, 0xCE, 0x73, 0x67, 0x39, 0xB3, 0x9D, 0xDD, 0xC6, 0xE6, 0xE3, 0x63, + 0x61, 0xB1, 0xB0, 0xD8, 0xD8, 0x6C, 0x6C, 0x3E, 0x3E, 0x1E, 0x0F, 0x0F, + 0x07, 0x87, 0x83, 0xC1, 0xC1, 0xC0, 0xE0, 0xE0, 0xF0, 0x07, 0xBC, 0x07, + 0x8E, 0x03, 0x83, 0x83, 0x81, 0xC1, 0xC0, 0x71, 0xC0, 0x38, 0xE0, 0x0E, + 0xE0, 0x07, 0x70, 0x01, 0xF0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x3E, 0x00, + 0x3B, 0x80, 0x1D, 0xC0, 0x1C, 0x70, 0x0E, 0x38, 0x0E, 0x0E, 0x0F, 0x07, + 0x87, 0x01, 0xC7, 0x00, 0x77, 0x80, 0x3C, 0xE0, 0x07, 0x70, 0x0F, 0x70, + 0x0E, 0x38, 0x0E, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x38, 0x0E, 0x38, 0x0E, + 0x70, 0x06, 0x70, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xC0, 0x01, 0xC0, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0xC0, 0x0E, 0x00, 0x70, + 0x01, 0xC0, 0x0E, 0x00, 0x78, 0x01, 0xC0, 0x0E, 0x00, 0x38, 0x01, 0xC0, + 0x0E, 0x00, 0x38, 0x01, 0xC0, 0x0F, 0x00, 0x38, 0x01, 0xC0, 0x07, 0x00, + 0x38, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x38, 0xE3, 0x8E, 0x38, + 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, + 0xE3, 0x8E, 0x38, 0xFF, 0xF0, 0xE0, 0x07, 0x00, 0x70, 0x03, 0x00, 0x38, + 0x01, 0x80, 0x18, 0x01, 0xC0, 0x0C, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, + 0x00, 0x30, 0x03, 0x00, 0x38, 0x01, 0x80, 0x1C, 0x01, 0xC0, 0x0C, 0x00, + 0xE0, 0x06, 0x00, 0x60, 0x07, 0xFF, 0xF1, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, + 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, + 0x71, 0xC7, 0xFF, 0xF0, 0x06, 0x00, 0x70, 0x0F, 0x00, 0xF8, 0x0F, 0x81, + 0xD8, 0x19, 0xC3, 0x8C, 0x38, 0xE7, 0x0E, 0x70, 0x7E, 0x07, 0xFF, 0xFF, + 0xFF, 0xF0, 0xF0, 0xE1, 0x83, 0x0F, 0xC0, 0xFF, 0xC7, 0xCF, 0x9C, 0x0E, + 0x70, 0x1C, 0x00, 0x70, 0x01, 0xC7, 0xFF, 0x3F, 0xFD, 0xE0, 0x77, 0x01, + 0xF8, 0x07, 0xE0, 0x1D, 0xC0, 0xF7, 0x8F, 0xCF, 0xF7, 0x1F, 0x9C, 0xC0, + 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0xF8, 0x37, + 0xF8, 0xF8, 0xF3, 0x81, 0xEE, 0x03, 0xB0, 0x0E, 0xC0, 0x1B, 0x00, 0x6C, + 0x01, 0xF0, 0x07, 0xC0, 0x1B, 0x00, 0xEE, 0x03, 0xB8, 0x1E, 0xF9, 0xF3, + 0x7F, 0x8C, 0xF8, 0x00, 0x07, 0xC0, 0x7F, 0xC3, 0xC7, 0x9E, 0x07, 0x70, + 0x1F, 0x80, 0x3E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, + 0x03, 0x70, 0x1D, 0xE0, 0x73, 0xC7, 0x87, 0xFC, 0x07, 0xC0, 0x00, 0x1C, + 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0xF9, 0xC7, 0xFF, + 0x3C, 0x7D, 0xC0, 0xF7, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, + 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x77, 0x01, 0xDC, 0x0F, 0x3E, 0x7C, 0x7F, + 0xF0, 0xF9, 0xC0, 0x07, 0xC0, 0x3F, 0xE0, 0xFB, 0xE3, 0xC1, 0xE7, 0x01, + 0xDC, 0x03, 0xB8, 0x03, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x80, 0x07, + 0x00, 0x07, 0x00, 0x8F, 0x01, 0x8F, 0x8F, 0x0F, 0xFC, 0x07, 0xE0, 0x00, + 0xFE, 0x07, 0xFC, 0x0E, 0x08, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, + 0x7F, 0xFE, 0xFF, 0xFC, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, + 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, + 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x0F, 0x9C, 0x7F, 0xF3, + 0xC7, 0xDC, 0x0F, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, + 0x80, 0x7E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xC0, 0xF3, 0xE7, 0xC7, 0xFF, + 0x0F, 0x9C, 0x00, 0x70, 0x01, 0xC8, 0x0E, 0x78, 0xF8, 0xFF, 0xC0, 0xFC, + 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x1F, + 0x19, 0xFE, 0xD8, 0xF7, 0x81, 0xF8, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, + 0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, + 0x1F, 0x00, 0xE0, 0x03, 0x00, 0x1E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, + 0xFC, 0x0F, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, + 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, + 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0xC0, 0x70, 0x1C, 0x00, 0x00, + 0x0F, 0xF3, 0xFC, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, + 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, + 0x03, 0x81, 0xEF, 0xF3, 0xF0, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, + 0xC0, 0x03, 0x00, 0x0C, 0x07, 0xB0, 0x3C, 0xC1, 0xE3, 0x0F, 0x0C, 0x78, + 0x33, 0xC0, 0xCE, 0x03, 0x78, 0x0F, 0xF0, 0x3D, 0xC0, 0xE3, 0x83, 0x0F, + 0x0C, 0x1E, 0x30, 0x38, 0xC0, 0x73, 0x01, 0xEC, 0x03, 0xC0, 0xFF, 0x03, + 0xFC, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, + 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, + 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x03, 0xFF, + 0xFF, 0xFF, 0xC0, 0xEF, 0x3C, 0xFF, 0xFF, 0xFB, 0xE7, 0xE1, 0xC7, 0xE1, + 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, + 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, 0xC3, 0xE1, + 0xC3, 0xC7, 0xC6, 0xFF, 0xB6, 0x3D, 0xE0, 0x7E, 0x03, 0xE0, 0x1F, 0x00, + 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, + 0x00, 0xF8, 0x07, 0xC0, 0x38, 0x07, 0xC0, 0x3F, 0xE0, 0xF1, 0xE3, 0x81, + 0xE7, 0x01, 0xDC, 0x03, 0xB8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, + 0x80, 0x3F, 0x00, 0xE7, 0x01, 0xCE, 0x07, 0x8F, 0xBE, 0x0F, 0xF8, 0x07, + 0xC0, 0xCF, 0x86, 0xFF, 0x3E, 0x7D, 0xC0, 0xEC, 0x03, 0xE0, 0x1F, 0x00, + 0xF8, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xF0, 0x3B, + 0xE7, 0xDB, 0xFC, 0xCF, 0xC6, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, + 0x03, 0x00, 0x00, 0x0F, 0x9C, 0x7F, 0xF3, 0xC7, 0xDE, 0x0F, 0x70, 0x1F, + 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, + 0x70, 0x1D, 0xE0, 0xF3, 0xE7, 0xC7, 0xFF, 0x0F, 0x9C, 0x00, 0x70, 0x01, + 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0xE3, 0xFD, 0xFF, 0xF0, + 0xF8, 0x0F, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, + 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x00, 0x0F, 0xC1, 0xFF, 0x1E, + 0x3D, 0xC0, 0x7E, 0x03, 0xF0, 0x01, 0xC0, 0x0F, 0xE0, 0x1F, 0xE0, 0x1F, + 0x80, 0x1E, 0x00, 0x7E, 0x03, 0xF0, 0x1D, 0xE3, 0xE7, 0xFE, 0x0F, 0xC0, + 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xF0, 0xE0, + 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, + 0x00, 0xE0, 0x03, 0x80, 0x06, 0x00, 0x1C, 0x00, 0x78, 0xC0, 0xFF, 0x01, + 0xF8, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, + 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x3D, + 0xE7, 0xEF, 0xFF, 0x1F, 0x38, 0xF0, 0x07, 0x70, 0x06, 0x70, 0x0E, 0x38, + 0x0E, 0x38, 0x0C, 0x18, 0x1C, 0x1C, 0x18, 0x1C, 0x38, 0x0C, 0x38, 0x0E, + 0x30, 0x06, 0x70, 0x07, 0x70, 0x07, 0x60, 0x03, 0xE0, 0x03, 0xC0, 0x01, + 0xC0, 0x01, 0xC0, 0xC1, 0x83, 0xE0, 0xE1, 0xF8, 0x70, 0xFC, 0x38, 0x66, + 0x3C, 0x33, 0x1B, 0x19, 0x8D, 0x9C, 0xE6, 0xCE, 0x77, 0x66, 0x1B, 0x3B, + 0x0D, 0x8D, 0x86, 0xC6, 0xC3, 0x63, 0xC1, 0xE1, 0xE0, 0x70, 0x70, 0x38, + 0x38, 0x1C, 0x1C, 0x00, 0xE0, 0x1E, 0xE0, 0x38, 0xE0, 0xE1, 0xE3, 0xC1, + 0xC7, 0x01, 0xDC, 0x01, 0xF0, 0x03, 0xE0, 0x03, 0x80, 0x0F, 0x80, 0x3F, + 0x00, 0x77, 0x01, 0xC7, 0x07, 0x07, 0x1E, 0x0E, 0x38, 0x0E, 0xE0, 0x0E, + 0xE0, 0x07, 0xB8, 0x03, 0x9C, 0x03, 0x87, 0x01, 0xC3, 0x80, 0xE1, 0xC0, + 0xE0, 0x70, 0x70, 0x38, 0x70, 0x0E, 0x38, 0x07, 0x18, 0x01, 0xDC, 0x00, + 0xEC, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0x80, + 0x01, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x01, 0xE0, + 0x00, 0x7F, 0xFD, 0xFF, 0xF0, 0x03, 0x80, 0x1E, 0x00, 0xF0, 0x03, 0x80, + 0x1C, 0x00, 0xF0, 0x07, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x3C, 0x01, + 0xE0, 0x07, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x01, 0xC0, 0xF0, 0x70, 0x1C, + 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x1C, 0x1F, + 0x0F, 0x03, 0xE0, 0x3C, 0x07, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, + 0x38, 0x0E, 0x03, 0x80, 0x70, 0x1F, 0x03, 0xC0, 0x30, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3C, 0x03, 0x80, 0xE0, 0x1C, 0x07, 0x01, + 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x0E, 0x03, 0xE0, 0x3C, 0x1F, + 0x0F, 0x03, 0x81, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, + 0x03, 0x83, 0xE0, 0xF0, 0x30, 0x00, 0x3E, 0x00, 0x3F, 0x80, 0xF9, 0xF0, + 0xF8, 0x3E, 0xEC, 0x0F, 0xF0, 0x01, 0xE0 }; + +const GFXglyph RobotoMono_Regular16pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 19, 0, 0 }, // 0x20 ' ' + { 1, 4, 22, 19, 7, -21 }, // 0x21 '!' + { 12, 8, 7, 19, 5, -22 }, // 0x22 '"' + { 19, 17, 22, 19, 1, -21 }, // 0x23 '#' + { 66, 15, 29, 19, 2, -25 }, // 0x24 '$' + { 121, 17, 22, 19, 1, -21 }, // 0x25 '%' + { 168, 16, 22, 19, 2, -21 }, // 0x26 '&' + { 212, 3, 7, 19, 7, -22 }, // 0x27 ''' + { 215, 8, 32, 19, 5, -24 }, // 0x28 '(' + { 247, 8, 32, 19, 5, -24 }, // 0x29 ')' + { 279, 15, 15, 19, 2, -18 }, // 0x2A '*' + { 308, 15, 16, 19, 2, -17 }, // 0x2B '+' + { 338, 5, 9, 19, 5, -2 }, // 0x2C ',' + { 344, 12, 2, 19, 3, -10 }, // 0x2D '-' + { 347, 4, 4, 19, 8, -3 }, // 0x2E '.' + { 349, 12, 24, 19, 4, -21 }, // 0x2F '/' + { 385, 14, 22, 19, 2, -21 }, // 0x30 '0' + { 424, 9, 22, 19, 3, -21 }, // 0x31 '1' + { 449, 15, 22, 19, 1, -21 }, // 0x32 '2' + { 491, 14, 22, 19, 1, -21 }, // 0x33 '3' + { 530, 16, 22, 19, 1, -21 }, // 0x34 '4' + { 574, 14, 22, 19, 3, -21 }, // 0x35 '5' + { 613, 14, 22, 19, 2, -21 }, // 0x36 '6' + { 652, 15, 22, 19, 2, -21 }, // 0x37 '7' + { 694, 14, 22, 19, 3, -21 }, // 0x38 '8' + { 733, 14, 22, 19, 2, -21 }, // 0x39 '9' + { 772, 5, 17, 19, 8, -16 }, // 0x3A ':' + { 783, 6, 23, 19, 7, -16 }, // 0x3B ';' + { 801, 12, 14, 19, 3, -16 }, // 0x3C '<' + { 822, 13, 9, 19, 3, -14 }, // 0x3D '=' + { 837, 13, 14, 19, 3, -16 }, // 0x3E '>' + { 860, 13, 22, 19, 3, -21 }, // 0x3F '?' + { 896, 17, 22, 19, 1, -21 }, // 0x40 '@' + { 943, 17, 22, 19, 1, -21 }, // 0x41 'A' + { 990, 14, 22, 19, 3, -21 }, // 0x42 'B' + { 1029, 15, 22, 19, 2, -21 }, // 0x43 'C' + { 1071, 15, 22, 19, 2, -21 }, // 0x44 'D' + { 1113, 13, 22, 19, 3, -21 }, // 0x45 'E' + { 1149, 13, 22, 19, 3, -21 }, // 0x46 'F' + { 1185, 15, 22, 19, 2, -21 }, // 0x47 'G' + { 1227, 14, 22, 19, 2, -21 }, // 0x48 'H' + { 1266, 13, 22, 19, 3, -21 }, // 0x49 'I' + { 1302, 15, 22, 19, 1, -21 }, // 0x4A 'J' + { 1344, 15, 22, 19, 3, -21 }, // 0x4B 'K' + { 1386, 14, 22, 19, 3, -21 }, // 0x4C 'L' + { 1425, 15, 22, 19, 2, -21 }, // 0x4D 'M' + { 1467, 14, 22, 19, 2, -21 }, // 0x4E 'N' + { 1506, 15, 22, 19, 2, -21 }, // 0x4F 'O' + { 1548, 14, 22, 19, 3, -21 }, // 0x50 'P' + { 1587, 17, 26, 19, 1, -21 }, // 0x51 'Q' + { 1643, 14, 22, 19, 3, -21 }, // 0x52 'R' + { 1682, 15, 22, 19, 2, -21 }, // 0x53 'S' + { 1724, 17, 22, 19, 1, -21 }, // 0x54 'T' + { 1771, 15, 22, 19, 2, -21 }, // 0x55 'U' + { 1813, 16, 22, 19, 1, -21 }, // 0x56 'V' + { 1857, 17, 22, 19, 1, -21 }, // 0x57 'W' + { 1904, 17, 22, 19, 1, -21 }, // 0x58 'X' + { 1951, 16, 22, 19, 1, -21 }, // 0x59 'Y' + { 1995, 14, 22, 19, 2, -21 }, // 0x5A 'Z' + { 2034, 6, 30, 19, 6, -24 }, // 0x5B '[' + { 2057, 12, 24, 19, 3, -21 }, // 0x5C '\' + { 2093, 6, 30, 19, 6, -24 }, // 0x5D ']' + { 2116, 12, 12, 19, 3, -21 }, // 0x5E '^' + { 2134, 14, 2, 19, 2, 1 }, // 0x5F '_' + { 2138, 6, 4, 19, 6, -22 }, // 0x60 '`' + { 2141, 14, 17, 19, 2, -16 }, // 0x61 'a' + { 2171, 14, 23, 19, 3, -22 }, // 0x62 'b' + { 2212, 14, 17, 19, 2, -16 }, // 0x63 'c' + { 2242, 14, 23, 19, 2, -22 }, // 0x64 'd' + { 2283, 15, 17, 19, 2, -16 }, // 0x65 'e' + { 2315, 15, 24, 19, 2, -23 }, // 0x66 'f' + { 2360, 14, 23, 19, 2, -16 }, // 0x67 'g' + { 2401, 13, 23, 19, 3, -22 }, // 0x68 'h' + { 2439, 14, 22, 19, 3, -21 }, // 0x69 'i' + { 2478, 10, 28, 19, 3, -21 }, // 0x6A 'j' + { 2513, 14, 23, 19, 3, -22 }, // 0x6B 'k' + { 2554, 14, 23, 19, 3, -22 }, // 0x6C 'l' + { 2595, 16, 17, 19, 1, -16 }, // 0x6D 'm' + { 2629, 13, 17, 19, 3, -16 }, // 0x6E 'n' + { 2657, 15, 17, 19, 2, -16 }, // 0x6F 'o' + { 2689, 13, 23, 19, 3, -16 }, // 0x70 'p' + { 2727, 14, 23, 19, 2, -16 }, // 0x71 'q' + { 2768, 11, 17, 19, 5, -16 }, // 0x72 'r' + { 2792, 13, 17, 19, 3, -16 }, // 0x73 's' + { 2820, 14, 21, 19, 2, -20 }, // 0x74 't' + { 2857, 13, 17, 19, 3, -16 }, // 0x75 'u' + { 2885, 16, 17, 19, 1, -16 }, // 0x76 'v' + { 2919, 17, 17, 19, 1, -16 }, // 0x77 'w' + { 2956, 15, 17, 19, 2, -16 }, // 0x78 'x' + { 2988, 17, 23, 19, 1, -16 }, // 0x79 'y' + { 3037, 14, 17, 19, 2, -16 }, // 0x7A 'z' + { 3067, 10, 30, 19, 5, -23 }, // 0x7B '{' + { 3105, 2, 28, 19, 8, -21 }, // 0x7C '|' + { 3112, 10, 30, 19, 5, -23 }, // 0x7D '}' + { 3150, 17, 6, 19, 1, -11 } }; // 0x7E '~' + +const GFXfont RobotoMono_Regular16pt7b PROGMEM = { + (uint8_t *)RobotoMono_Regular16pt7bBitmaps, + (GFXglyph *)RobotoMono_Regular16pt7bGlyphs, + 0x20, 0x7E, 41 }; + +// Approx. 3835 bytes diff --git a/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h new file mode 100644 index 000000000..30d1c45b6 --- /dev/null +++ b/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h @@ -0,0 +1,180 @@ +const uint8_t RobotoMono_Regular8pt7bBitmaps[] PROGMEM = { + 0x00, 0xAA, 0xAA, 0x03, 0x99, 0x99, 0x09, 0x04, 0x86, 0x4F, 0xF1, 0x20, + 0x90, 0x49, 0xFF, 0x26, 0x12, 0x09, 0x04, 0x80, 0x18, 0x18, 0x3C, 0x66, + 0x42, 0x40, 0x60, 0x3C, 0x06, 0x02, 0xC3, 0x42, 0x7E, 0x18, 0x18, 0x70, + 0x68, 0x26, 0xDA, 0x47, 0x40, 0x20, 0x20, 0x17, 0x14, 0x9A, 0x41, 0x20, + 0x70, 0x38, 0x6C, 0x44, 0x44, 0x68, 0x30, 0x70, 0xD9, 0x8F, 0x86, 0xC6, + 0x7B, 0xF0, 0x32, 0x44, 0xC8, 0x88, 0x88, 0x8C, 0xC4, 0x62, 0x10, 0xC3, + 0x08, 0x61, 0x08, 0x63, 0x18, 0xC4, 0x21, 0x18, 0x88, 0x80, 0x18, 0x18, + 0x99, 0xFF, 0x18, 0x3C, 0x64, 0x26, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, + 0x18, 0x18, 0x18, 0xFE, 0x80, 0xFC, 0xF0, 0x04, 0x20, 0x86, 0x10, 0x43, + 0x08, 0x21, 0x84, 0x10, 0x80, 0x3C, 0x66, 0xC2, 0xC2, 0xC6, 0xCB, 0xF3, + 0xE2, 0xC2, 0xC2, 0x66, 0x3C, 0x1F, 0x91, 0x11, 0x11, 0x11, 0x11, 0x79, + 0x9A, 0x1C, 0x30, 0x60, 0x82, 0x0C, 0x30, 0xC3, 0x07, 0xF0, 0x79, 0x8A, + 0x18, 0x30, 0x47, 0x03, 0x03, 0x07, 0x0F, 0x13, 0xC0, 0x0C, 0x0C, 0x1C, + 0x14, 0x24, 0x64, 0x44, 0x84, 0xFF, 0x04, 0x04, 0x04, 0x7E, 0x60, 0x60, + 0x40, 0x7C, 0x66, 0x02, 0x03, 0x83, 0x42, 0x66, 0x3C, 0x1C, 0x61, 0x82, + 0x0F, 0xDC, 0xF0, 0xE1, 0xC3, 0x85, 0x99, 0xE0, 0xFF, 0x02, 0x06, 0x04, + 0x04, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x20, 0x60, 0x3C, 0x66, 0x42, 0x42, + 0x66, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0x66, 0x3C, 0x3C, 0xCB, 0x1E, 0x1C, + 0x38, 0x51, 0xBD, 0x02, 0x0C, 0x31, 0xC0, 0xF8, 0x00, 0x07, 0xC0, 0xF0, + 0x03, 0xFA, 0x02, 0x1C, 0xE6, 0x07, 0x03, 0x81, 0x80, 0xFE, 0x00, 0x07, + 0xF0, 0x81, 0xE0, 0x70, 0x30, 0xEF, 0x30, 0x00, 0x3C, 0xCF, 0x08, 0x10, + 0x60, 0x83, 0x0C, 0x10, 0x00, 0x00, 0xC0, 0x1E, 0x19, 0x9B, 0xAB, 0x55, + 0x2A, 0x95, 0x4A, 0xA9, 0x5B, 0x20, 0x08, 0x83, 0xC0, 0x18, 0x18, 0x18, + 0x3C, 0x2C, 0x24, 0x64, 0x66, 0x7E, 0xC2, 0xC3, 0x81, 0xFC, 0xC6, 0xC2, + 0xC2, 0xC6, 0xFC, 0xC6, 0xC3, 0xC3, 0xC3, 0xC6, 0xFC, 0x3C, 0x66, 0xC2, + 0x83, 0x80, 0x80, 0x80, 0x80, 0x83, 0xC2, 0x66, 0x3C, 0xF8, 0xCE, 0xC2, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC2, 0xCE, 0xF8, 0xFF, 0x83, 0x06, + 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x83, 0x07, 0xF0, 0xFF, 0x83, 0x06, 0x0C, + 0x18, 0x3F, 0xE0, 0xC1, 0x83, 0x06, 0x00, 0x3C, 0x66, 0xC3, 0x83, 0x80, + 0x80, 0x8F, 0x83, 0xC3, 0xC3, 0x63, 0x3C, 0x83, 0x83, 0x83, 0x83, 0x83, + 0xFF, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0xFE, 0x30, 0x60, 0xC1, 0x83, + 0x06, 0x0C, 0x18, 0x30, 0x67, 0xF0, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, + 0x81, 0x83, 0x0F, 0x11, 0xC0, 0xC3, 0xC6, 0xCC, 0xC8, 0xD8, 0xF0, 0xF8, + 0xC8, 0xCC, 0xC6, 0xC2, 0xC3, 0x81, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, + 0x81, 0x02, 0x07, 0xF0, 0xC3, 0xC7, 0xE7, 0xA7, 0xAF, 0xFB, 0xDB, 0xDB, + 0xD3, 0xC3, 0xC3, 0xC3, 0xC3, 0x87, 0x8F, 0x1F, 0x3A, 0x76, 0xE5, 0xCF, + 0x8F, 0x1E, 0x10, 0x3C, 0x66, 0xC2, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0xC2, 0x66, 0x3C, 0xFC, 0xC6, 0xC3, 0xC3, 0xC3, 0xC2, 0xFE, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0x3C, 0x66, 0xC2, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0xC2, 0x66, 0x3C, 0x03, 0x01, 0xFC, 0xC6, 0xC2, 0xC3, 0xC3, 0xC6, 0xFC, + 0xCC, 0xC4, 0xC6, 0xC2, 0xC3, 0x3C, 0x66, 0xC3, 0xC0, 0x60, 0x78, 0x1E, + 0x03, 0x83, 0xC3, 0x66, 0x3C, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x83, 0x83, 0x83, 0x83, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC2, 0xC2, 0x66, 0x3C, 0x83, 0xC3, 0xC2, 0x46, 0x46, 0x64, 0x24, + 0x2C, 0x38, 0x38, 0x18, 0x18, 0x99, 0x99, 0x99, 0x99, 0x9B, 0xBF, 0xEE, + 0xE6, 0x66, 0x66, 0x66, 0x66, 0xC3, 0x42, 0x66, 0x2C, 0x3C, 0x18, 0x18, + 0x3C, 0x24, 0x66, 0x42, 0xC3, 0xC1, 0xB0, 0x88, 0xC6, 0x41, 0x60, 0xE0, + 0x30, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0xFE, 0x0C, 0x10, 0x60, 0x83, + 0x0C, 0x10, 0x60, 0x83, 0x07, 0xF0, 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB7, + 0x83, 0x04, 0x10, 0x60, 0x82, 0x04, 0x10, 0x60, 0x82, 0x0C, 0xE4, 0x92, + 0x49, 0x24, 0x92, 0x4F, 0x20, 0xC7, 0x16, 0x4B, 0x30, 0xFE, 0xC4, 0x3D, + 0x8C, 0x09, 0xF6, 0x38, 0x70, 0xA7, 0x7A, 0xC0, 0xC0, 0xC0, 0xFC, 0xE6, + 0xC2, 0xC2, 0xC3, 0xC2, 0xC2, 0xE6, 0xFC, 0x3C, 0xCF, 0x0E, 0x0C, 0x18, + 0x30, 0xB3, 0x3C, 0x02, 0x04, 0x09, 0xD6, 0x78, 0x70, 0xE1, 0xC3, 0x85, + 0x99, 0xD0, 0x3C, 0x66, 0xC2, 0xC2, 0xFF, 0xC0, 0xC0, 0x62, 0x3C, 0x0F, + 0x19, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x3A, 0xCF, 0x0E, 0x1C, 0x38, 0x70, 0xB3, 0x3A, 0x05, 0x19, 0xE0, 0xC1, + 0x83, 0x06, 0xEE, 0x78, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x10, 0x30, 0x00, + 0x07, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC7, 0xF0, 0x18, 0x01, 0xF1, + 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x9B, 0x80, 0xC0, 0xC0, 0xC0, 0xC6, 0xCC, + 0xD8, 0xF0, 0xF0, 0xD8, 0xCC, 0xC6, 0xC3, 0xF0, 0x60, 0xC1, 0x83, 0x06, + 0x0C, 0x18, 0x30, 0x60, 0xC7, 0xF0, 0xF6, 0x9B, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x99, 0xDD, 0xCF, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC2, 0x3C, + 0x66, 0xC2, 0x83, 0x83, 0x83, 0xC2, 0x66, 0x3C, 0xFC, 0xE6, 0xC2, 0xC2, + 0xC3, 0xC2, 0xC2, 0xE6, 0xFC, 0xC0, 0xC0, 0xC0, 0x3A, 0xCF, 0x0E, 0x1C, + 0x38, 0x70, 0xB3, 0x3A, 0x04, 0x08, 0x10, 0xBE, 0x21, 0x08, 0x42, 0x10, + 0x80, 0x3C, 0xCD, 0x0B, 0x03, 0xC0, 0xF0, 0xB3, 0x3C, 0x30, 0x63, 0xF9, + 0x83, 0x06, 0x0C, 0x18, 0x30, 0x20, 0x78, 0xC3, 0x87, 0x0E, 0x1C, 0x38, + 0x50, 0xB3, 0x3A, 0x83, 0xC2, 0x46, 0x44, 0x24, 0x2C, 0x38, 0x18, 0x18, + 0xC8, 0xA6, 0x53, 0x29, 0xB5, 0x53, 0x98, 0xCC, 0x66, 0x23, 0x00, 0xC3, + 0x66, 0x2C, 0x38, 0x18, 0x38, 0x24, 0x66, 0xC3, 0x83, 0xC2, 0x46, 0x66, + 0x24, 0x2C, 0x38, 0x18, 0x10, 0x30, 0x20, 0xE0, 0xFE, 0x0C, 0x30, 0x41, + 0x86, 0x18, 0x20, 0xFE, 0x19, 0x88, 0x42, 0x10, 0x8C, 0xC3, 0x08, 0x42, + 0x10, 0xC3, 0xFF, 0xFE, 0x86, 0x10, 0xC6, 0x31, 0x84, 0x19, 0x18, 0xC6, + 0x31, 0x18, 0x70, 0xA6, 0x61, 0xC0 }; + +const GFXglyph RobotoMono_Regular8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 10, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 10, 4, -11 }, // 0x21 '!' + { 4, 4, 4, 10, 3, -11 }, // 0x22 '"' + { 6, 9, 12, 10, 0, -11 }, // 0x23 '#' + { 20, 8, 15, 10, 1, -12 }, // 0x24 '$' + { 35, 9, 12, 10, 0, -11 }, // 0x25 '%' + { 49, 8, 12, 10, 1, -11 }, // 0x26 '&' + { 61, 1, 4, 10, 4, -11 }, // 0x27 ''' + { 62, 4, 17, 10, 3, -12 }, // 0x28 '(' + { 71, 5, 17, 10, 2, -12 }, // 0x29 ')' + { 82, 8, 8, 10, 1, -9 }, // 0x2A '*' + { 90, 8, 9, 10, 1, -9 }, // 0x2B '+' + { 99, 2, 5, 10, 3, -1 }, // 0x2C ',' + { 101, 6, 1, 10, 2, -5 }, // 0x2D '-' + { 102, 2, 2, 10, 4, -1 }, // 0x2E '.' + { 103, 6, 13, 10, 2, -11 }, // 0x2F '/' + { 113, 8, 12, 10, 1, -11 }, // 0x30 '0' + { 125, 4, 12, 10, 2, -11 }, // 0x31 '1' + { 131, 7, 12, 10, 1, -11 }, // 0x32 '2' + { 142, 7, 12, 10, 1, -11 }, // 0x33 '3' + { 153, 8, 12, 10, 1, -11 }, // 0x34 '4' + { 165, 8, 12, 10, 1, -11 }, // 0x35 '5' + { 177, 7, 12, 10, 1, -11 }, // 0x36 '6' + { 188, 8, 12, 10, 1, -11 }, // 0x37 '7' + { 200, 8, 12, 10, 1, -11 }, // 0x38 '8' + { 212, 7, 12, 10, 1, -11 }, // 0x39 '9' + { 223, 3, 9, 10, 4, -8 }, // 0x3A ':' + { 227, 2, 12, 10, 4, -8 }, // 0x3B ';' + { 230, 7, 7, 10, 1, -8 }, // 0x3C '<' + { 237, 7, 4, 10, 1, -6 }, // 0x3D '=' + { 241, 7, 7, 10, 1, -8 }, // 0x3E '>' + { 248, 7, 12, 10, 1, -11 }, // 0x3F '?' + { 259, 9, 12, 10, 0, -11 }, // 0x40 '@' + { 273, 8, 12, 10, 1, -11 }, // 0x41 'A' + { 285, 8, 12, 10, 1, -11 }, // 0x42 'B' + { 297, 8, 12, 10, 1, -11 }, // 0x43 'C' + { 309, 8, 12, 10, 1, -11 }, // 0x44 'D' + { 321, 7, 12, 10, 1, -11 }, // 0x45 'E' + { 332, 7, 12, 10, 1, -11 }, // 0x46 'F' + { 343, 8, 12, 10, 1, -11 }, // 0x47 'G' + { 355, 8, 12, 10, 1, -11 }, // 0x48 'H' + { 367, 7, 12, 10, 1, -11 }, // 0x49 'I' + { 378, 7, 12, 10, 1, -11 }, // 0x4A 'J' + { 389, 8, 12, 10, 1, -11 }, // 0x4B 'K' + { 401, 7, 12, 10, 2, -11 }, // 0x4C 'L' + { 412, 8, 12, 10, 1, -11 }, // 0x4D 'M' + { 424, 7, 12, 10, 1, -11 }, // 0x4E 'N' + { 435, 8, 12, 10, 1, -11 }, // 0x4F 'O' + { 447, 8, 12, 10, 1, -11 }, // 0x50 'P' + { 459, 8, 14, 10, 1, -11 }, // 0x51 'Q' + { 473, 8, 12, 10, 1, -11 }, // 0x52 'R' + { 485, 8, 12, 10, 1, -11 }, // 0x53 'S' + { 497, 8, 12, 10, 1, -11 }, // 0x54 'T' + { 509, 8, 12, 10, 1, -11 }, // 0x55 'U' + { 521, 8, 12, 10, 1, -11 }, // 0x56 'V' + { 533, 8, 12, 10, 1, -11 }, // 0x57 'W' + { 545, 8, 12, 10, 1, -11 }, // 0x58 'X' + { 557, 9, 12, 10, 0, -11 }, // 0x59 'Y' + { 571, 7, 12, 10, 1, -11 }, // 0x5A 'Z' + { 582, 3, 16, 10, 3, -13 }, // 0x5B '[' + { 588, 6, 13, 10, 2, -11 }, // 0x5C '\' + { 598, 3, 16, 10, 3, -13 }, // 0x5D ']' + { 604, 6, 6, 10, 2, -11 }, // 0x5E '^' + { 609, 7, 1, 10, 1, 1 }, // 0x5F '_' + { 610, 3, 2, 10, 3, -11 }, // 0x60 '`' + { 611, 7, 9, 10, 1, -8 }, // 0x61 'a' + { 619, 8, 12, 10, 1, -11 }, // 0x62 'b' + { 631, 7, 9, 10, 1, -8 }, // 0x63 'c' + { 639, 7, 12, 10, 1, -11 }, // 0x64 'd' + { 650, 8, 9, 10, 1, -8 }, // 0x65 'e' + { 659, 8, 13, 10, 1, -12 }, // 0x66 'f' + { 672, 7, 12, 10, 1, -8 }, // 0x67 'g' + { 683, 7, 12, 10, 1, -11 }, // 0x68 'h' + { 694, 7, 12, 10, 2, -11 }, // 0x69 'i' + { 705, 5, 15, 10, 2, -11 }, // 0x6A 'j' + { 715, 8, 12, 10, 1, -11 }, // 0x6B 'k' + { 727, 7, 12, 10, 2, -11 }, // 0x6C 'l' + { 738, 8, 9, 10, 1, -8 }, // 0x6D 'm' + { 747, 7, 9, 10, 1, -8 }, // 0x6E 'n' + { 755, 8, 9, 10, 1, -8 }, // 0x6F 'o' + { 764, 8, 12, 10, 1, -8 }, // 0x70 'p' + { 776, 7, 12, 10, 1, -8 }, // 0x71 'q' + { 787, 5, 9, 10, 3, -8 }, // 0x72 'r' + { 793, 7, 9, 10, 1, -8 }, // 0x73 's' + { 801, 7, 11, 10, 1, -10 }, // 0x74 't' + { 811, 7, 9, 10, 1, -8 }, // 0x75 'u' + { 819, 8, 9, 10, 1, -8 }, // 0x76 'v' + { 828, 9, 9, 10, 0, -8 }, // 0x77 'w' + { 839, 8, 9, 10, 1, -8 }, // 0x78 'x' + { 848, 8, 12, 10, 1, -8 }, // 0x79 'y' + { 860, 7, 9, 10, 1, -8 }, // 0x7A 'z' + { 868, 5, 16, 10, 3, -12 }, // 0x7B '{' + { 878, 1, 15, 10, 4, -11 }, // 0x7C '|' + { 880, 5, 16, 10, 3, -12 }, // 0x7D '}' + { 890, 9, 3, 10, 0, -6 } }; // 0x7E '~' + +const GFXfont RobotoMono_Regular8pt7b PROGMEM = { + (uint8_t *)RobotoMono_Regular8pt7bBitmaps, + (GFXglyph *)RobotoMono_Regular8pt7bGlyphs, + 0x20, 0x7E, 21 }; + +// Approx. 1566 bytes diff --git a/src/src/Static/Fonts/Roboto_Regular12pt7b.h b/src/src/Static/Fonts/Roboto_Regular12pt7b.h new file mode 100644 index 000000000..2bff96b05 --- /dev/null +++ b/src/src/Static/Fonts/Roboto_Regular12pt7b.h @@ -0,0 +1,265 @@ +const uint8_t Roboto_Regular12pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0xC0, 0xCF, 0x3C, 0xF3, 0xCA, 0x20, 0x06, + 0x30, 0x23, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x3F, 0xFD, 0xFF, 0xE1, 0x18, + 0x18, 0xC0, 0xC6, 0x06, 0x31, 0xFF, 0xEF, 0xFF, 0x18, 0xC0, 0xC6, 0x06, + 0x30, 0x33, 0x00, 0x06, 0x00, 0xC0, 0x18, 0x0F, 0x83, 0xFC, 0xE1, 0x98, + 0x3B, 0x03, 0x60, 0x6E, 0x00, 0xF0, 0x0F, 0xC0, 0x3C, 0x01, 0xC0, 0x1F, + 0x03, 0x60, 0x6E, 0x1C, 0xFF, 0x0F, 0xC0, 0x60, 0x0C, 0x00, 0x3C, 0x00, + 0x66, 0x00, 0xC6, 0x10, 0xC2, 0x38, 0xC2, 0x30, 0xC6, 0x60, 0x66, 0x40, + 0x3C, 0xC0, 0x01, 0x80, 0x01, 0x3C, 0x03, 0x66, 0x06, 0x42, 0x06, 0xC3, + 0x0C, 0xC3, 0x08, 0x42, 0x18, 0x66, 0x00, 0x3C, 0x1F, 0x01, 0xFC, 0x1C, + 0x70, 0xE1, 0x87, 0x1C, 0x18, 0xC0, 0xFC, 0x03, 0xC0, 0x3C, 0x03, 0xF0, + 0xF9, 0xC7, 0x87, 0x3C, 0x1F, 0x60, 0x7B, 0x83, 0x8F, 0xFE, 0x3F, 0x38, + 0xFF, 0xE0, 0x04, 0x71, 0x8C, 0x61, 0x8E, 0x30, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0x30, 0xC3, 0x86, 0x18, 0x30, 0x61, 0xC1, 0x83, 0x06, 0x0C, 0x38, + 0x61, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x71, 0x86, 0x31, + 0x8E, 0x20, 0x0C, 0x03, 0x00, 0xC1, 0xB3, 0xFF, 0xC7, 0x81, 0xE0, 0xEC, + 0x33, 0x18, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x0F, 0xFF, + 0xFF, 0xF0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0xFF, 0xED, 0x00, + 0xFF, 0xF0, 0xF0, 0x01, 0x80, 0xC0, 0xC0, 0x60, 0x20, 0x30, 0x18, 0x18, + 0x0C, 0x06, 0x06, 0x03, 0x03, 0x01, 0x80, 0xC0, 0xC0, 0x60, 0x60, 0x00, + 0x1F, 0x07, 0xF9, 0xC7, 0x30, 0x7E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, + 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x06, 0xC1, 0xDC, 0x71, 0xFE, 0x1F, 0x00, + 0x1F, 0xFF, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0x1F, 0x07, 0xF9, 0xC7, 0x70, 0x7C, 0x06, 0x01, 0xC0, 0x30, 0x06, + 0x01, 0x80, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0xFF, 0xFF, + 0xE0, 0x1F, 0x07, 0xF9, 0xC7, 0x70, 0x7E, 0x0E, 0x01, 0xC0, 0x70, 0x7C, + 0x0F, 0x80, 0x18, 0x03, 0x80, 0x3C, 0x07, 0xC1, 0xDC, 0x73, 0xFE, 0x1F, + 0x00, 0x01, 0xC0, 0x3C, 0x03, 0xC0, 0x7C, 0x0F, 0xC0, 0xDC, 0x19, 0xC3, + 0x9C, 0x31, 0xC6, 0x1C, 0xC1, 0xCF, 0xFF, 0xFF, 0xF0, 0x1C, 0x01, 0xC0, + 0x1C, 0x01, 0xC0, 0x7F, 0xDF, 0xF6, 0x01, 0x80, 0x60, 0x38, 0x0D, 0xF3, + 0xFE, 0xE1, 0xF0, 0x70, 0x0C, 0x03, 0xC0, 0xF0, 0x7E, 0x1D, 0xFE, 0x3E, + 0x00, 0x1F, 0x87, 0xF1, 0xC2, 0x70, 0x0C, 0x01, 0x80, 0x37, 0xC7, 0xFC, + 0xE1, 0xD8, 0x1B, 0x03, 0xE0, 0x7C, 0x0F, 0xC1, 0x9C, 0x73, 0xFC, 0x1F, + 0x00, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x60, 0x1C, 0x03, 0x00, 0xC0, 0x18, + 0x06, 0x00, 0xC0, 0x38, 0x06, 0x00, 0xC0, 0x18, 0x07, 0x00, 0xE0, 0x1C, + 0x00, 0x1F, 0x07, 0xF9, 0xC7, 0x30, 0x76, 0x06, 0xC1, 0xDC, 0x31, 0xFC, + 0x3F, 0x8E, 0x19, 0x81, 0xF0, 0x3E, 0x07, 0xC0, 0xDC, 0x3B, 0xFE, 0x1F, + 0x00, 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1F, 0x03, + 0x71, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x0E, 0x01, 0x90, 0x71, 0xFC, 0x7F, + 0x00, 0xF0, 0x00, 0x03, 0xC0, 0x6C, 0x00, 0x00, 0x01, 0xB6, 0xF6, 0x01, + 0x83, 0xC7, 0xCF, 0x8E, 0x07, 0x01, 0xF0, 0x3E, 0x07, 0x80, 0xC0, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0xC0, 0x3C, 0x07, 0xC0, + 0x3E, 0x03, 0xC0, 0xF0, 0xF9, 0xF0, 0xF0, 0x30, 0x00, 0x3E, 0x3F, 0xB8, + 0xF8, 0x30, 0x18, 0x0C, 0x0E, 0x06, 0x07, 0x07, 0x07, 0x03, 0x81, 0x80, + 0x00, 0x00, 0x38, 0x1C, 0x00, 0x01, 0xFC, 0x00, 0x70, 0x70, 0x0C, 0x01, + 0x81, 0x80, 0x0C, 0x30, 0x00, 0x42, 0x0F, 0x86, 0x61, 0x8C, 0x66, 0x10, + 0xC2, 0x43, 0x0C, 0x2C, 0x30, 0xC2, 0xC3, 0x0C, 0x2C, 0x60, 0x82, 0xC6, + 0x18, 0x6C, 0x71, 0x86, 0x43, 0x18, 0xC4, 0x3E, 0xFC, 0x61, 0xCF, 0x06, + 0x00, 0x00, 0x30, 0x00, 0x01, 0x80, 0x00, 0x0E, 0x0C, 0x00, 0x3F, 0x80, + 0x01, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x3E, 0x00, 0x6E, 0x00, 0xCC, 0x03, + 0x98, 0x06, 0x38, 0x0C, 0x30, 0x30, 0x60, 0x60, 0xE1, 0xFF, 0xC3, 0xFF, + 0xC6, 0x01, 0x9C, 0x03, 0x30, 0x07, 0xE0, 0x06, 0xFF, 0x8F, 0xFC, 0xC0, + 0xEC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0xEF, 0xFC, 0xFF, 0xCC, 0x06, 0xC0, + 0x7C, 0x03, 0xC0, 0x3C, 0x07, 0xC0, 0xFF, 0xFE, 0xFF, 0x80, 0x0F, 0xC0, + 0xFF, 0x0E, 0x1C, 0xE0, 0x76, 0x01, 0xF0, 0x0F, 0x80, 0x1C, 0x00, 0xE0, + 0x07, 0x00, 0x38, 0x00, 0xC0, 0x36, 0x01, 0xB8, 0x1C, 0xE1, 0xC3, 0xFC, + 0x0F, 0xC0, 0xFF, 0x07, 0xFE, 0x30, 0x39, 0x80, 0xEC, 0x03, 0x60, 0x1F, + 0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0x60, + 0x3B, 0x03, 0x9F, 0xF8, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, + 0x01, 0x80, 0x30, 0x07, 0xFE, 0xFF, 0xD8, 0x03, 0x00, 0x60, 0x0C, 0x01, + 0x80, 0x30, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, + 0x01, 0x80, 0x30, 0x07, 0xFE, 0xFF, 0xD8, 0x03, 0x00, 0x60, 0x0C, 0x01, + 0x80, 0x30, 0x06, 0x00, 0xC0, 0x00, 0x0F, 0xC0, 0xFF, 0x8E, 0x1E, 0xE0, + 0x36, 0x01, 0xF0, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x0F, 0xF8, 0x7E, + 0xC0, 0x36, 0x01, 0xB8, 0x0C, 0xE0, 0xE3, 0xFF, 0x07, 0xE0, 0xC0, 0x1E, + 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7F, 0xFF, 0xFF, + 0xFE, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, + 0xC0, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xC0, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, + 0xC0, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x00, 0xC0, 0x3E, 0x03, 0xB0, 0x39, + 0x83, 0x8C, 0x38, 0x63, 0x83, 0x18, 0x1F, 0xC0, 0xFE, 0x06, 0x38, 0x30, + 0xC1, 0x87, 0x0C, 0x1C, 0x60, 0x73, 0x01, 0x98, 0x0E, 0xC0, 0x38, 0xC0, + 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, + 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x07, 0xFF, 0xFF, 0xE0, 0xE0, + 0x03, 0xF8, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0xFD, 0x80, 0xDE, 0xC0, 0x6F, + 0x70, 0x77, 0x98, 0x33, 0xCC, 0x19, 0xE3, 0x18, 0xF1, 0x8C, 0x78, 0x6E, + 0x3C, 0x36, 0x1E, 0x1B, 0x0F, 0x07, 0x07, 0x83, 0x83, 0xC0, 0xC1, 0x80, + 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xF0, 0x3D, 0x81, 0xEE, 0x0F, 0x38, 0x78, + 0xC3, 0xC7, 0x1E, 0x18, 0xF0, 0x67, 0x83, 0xBC, 0x0D, 0xE0, 0x3F, 0x01, + 0xF8, 0x07, 0xC0, 0x38, 0x0F, 0xC0, 0x7F, 0xC3, 0x87, 0x9C, 0x06, 0x60, + 0x1F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, + 0x03, 0x60, 0x1D, 0xC0, 0x63, 0x87, 0x87, 0xFC, 0x0F, 0xC0, 0xFF, 0x8F, + 0xFE, 0xC0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x07, 0xFF, 0xEF, + 0xF8, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00, + 0x0F, 0xC0, 0x3F, 0xE0, 0xE1, 0xE3, 0x80, 0xC6, 0x01, 0xDC, 0x01, 0xB8, + 0x03, 0x70, 0x06, 0xE0, 0x0D, 0xC0, 0x1B, 0x80, 0x37, 0x00, 0x66, 0x01, + 0xCE, 0x03, 0x0E, 0x1C, 0x0F, 0xF8, 0x0F, 0xF8, 0x00, 0x38, 0x00, 0x38, + 0xFF, 0x87, 0xFF, 0x30, 0x3D, 0x80, 0xEC, 0x03, 0x60, 0x1B, 0x01, 0xD8, + 0x1C, 0xFF, 0xC7, 0xFF, 0x30, 0x39, 0x80, 0xEC, 0x03, 0x60, 0x1B, 0x00, + 0xD8, 0x06, 0xC0, 0x38, 0x0F, 0x81, 0xFF, 0x1C, 0x1C, 0xC0, 0x66, 0x03, + 0xB0, 0x01, 0xC0, 0x07, 0xC0, 0x1F, 0xC0, 0x1F, 0x00, 0x1C, 0x00, 0x7E, + 0x03, 0xF0, 0x1D, 0xC1, 0xC7, 0xFC, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, + 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, + 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, + 0x03, 0x00, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, + 0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0x70, + 0x19, 0xC3, 0xCF, 0xFC, 0x1F, 0x80, 0xE0, 0x0E, 0xC0, 0x19, 0xC0, 0x31, + 0x80, 0xE3, 0x01, 0x87, 0x03, 0x06, 0x0E, 0x0C, 0x18, 0x1C, 0x70, 0x18, + 0xC0, 0x31, 0x80, 0x37, 0x00, 0x6C, 0x00, 0xD8, 0x00, 0xF0, 0x01, 0xC0, + 0x03, 0x80, 0xC0, 0xE0, 0x78, 0x1C, 0x0F, 0x83, 0x81, 0xF0, 0x78, 0x76, + 0x1B, 0x0C, 0xC3, 0x61, 0x98, 0x6C, 0x33, 0x9C, 0xCE, 0x33, 0x19, 0x86, + 0x63, 0x30, 0xCC, 0x76, 0x1F, 0x06, 0xC1, 0xE0, 0xF0, 0x3C, 0x1E, 0x07, + 0x81, 0xC0, 0xE0, 0x38, 0x0C, 0x06, 0x00, 0xE0, 0x39, 0xC0, 0xC7, 0x07, + 0x0E, 0x38, 0x18, 0xE0, 0x77, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x00, 0x1E, + 0x00, 0xF8, 0x07, 0x70, 0x18, 0xE0, 0xE1, 0x87, 0x07, 0x18, 0x0E, 0xE0, + 0x3C, 0xE0, 0x0D, 0xC0, 0x73, 0x03, 0x8E, 0x0E, 0x18, 0x70, 0x71, 0x80, + 0xCE, 0x03, 0xB0, 0x07, 0xC0, 0x1E, 0x00, 0x38, 0x00, 0xC0, 0x03, 0x00, + 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x60, + 0x0E, 0x01, 0xC0, 0x18, 0x03, 0x80, 0x70, 0x06, 0x00, 0xE0, 0x1C, 0x01, + 0x80, 0x30, 0x07, 0x00, 0x60, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFF, 0xE0, 0x18, 0x07, + 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x70, 0x0C, 0x03, 0x00, 0x60, 0x18, + 0x07, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x70, 0xFF, 0xCE, 0x73, 0x9C, + 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9F, 0xFF, 0x18, + 0x18, 0x3C, 0x3C, 0x66, 0x66, 0x66, 0xC3, 0xC3, 0xFF, 0xFF, 0xFC, 0xE3, + 0x8E, 0x1F, 0x07, 0xF9, 0xC7, 0x00, 0x60, 0x0E, 0x3F, 0xDF, 0xFB, 0x87, + 0xE0, 0xFC, 0x1F, 0x87, 0xBF, 0xF3, 0xEE, 0xC0, 0x18, 0x03, 0x00, 0x60, + 0x0C, 0x01, 0xBE, 0x3F, 0xE7, 0x0E, 0xC1, 0xD8, 0x1B, 0x03, 0x60, 0x6C, + 0x0F, 0x81, 0xB0, 0x37, 0x0E, 0xFF, 0x9B, 0xE0, 0x1F, 0x07, 0xF9, 0xC3, + 0x30, 0x7E, 0x07, 0xC0, 0x30, 0x06, 0x00, 0xE0, 0x0C, 0x0D, 0xC3, 0x1F, + 0xE1, 0xF0, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xDB, + 0x8F, 0x60, 0xFC, 0x0F, 0x81, 0xE0, 0x3C, 0x07, 0xC0, 0xD8, 0x3B, 0x8F, + 0x3F, 0xE3, 0xCC, 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x7E, 0x0F, 0xFF, 0xFF, + 0xFF, 0x00, 0xE0, 0x0C, 0x01, 0xC3, 0x1F, 0xE1, 0xF8, 0x0E, 0x7C, 0xE1, + 0x83, 0x06, 0x3F, 0xFF, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, + 0x60, 0xC0, 0x1F, 0x67, 0xFD, 0xC3, 0xB0, 0x3E, 0x07, 0xC0, 0xF0, 0x1E, + 0x03, 0xE0, 0x6C, 0x1D, 0xC3, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x39, 0x06, + 0x3F, 0xC3, 0xE0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCF, 0xFB, + 0x87, 0xC1, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, + 0xF0, 0x30, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x18, 0xC0, 0x00, 0x0C, 0x63, + 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xFF, 0xC0, 0xC0, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x7C, 0x3B, 0x1C, 0xCE, 0x33, 0x0F, 0xC3, + 0xF0, 0xCE, 0x31, 0x8C, 0x73, 0x0E, 0xC1, 0xB0, 0x70, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0xDF, 0x1E, 0x7F, 0xDF, 0xB8, 0xF8, 0xF8, 0x38, 0x3C, 0x1C, + 0x1E, 0x0E, 0x0F, 0x07, 0x07, 0x83, 0x83, 0xC1, 0xC1, 0xE0, 0xE0, 0xF0, + 0x70, 0x78, 0x38, 0x3C, 0x1C, 0x18, 0xDF, 0x3F, 0xEE, 0x1F, 0x07, 0xC0, + 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x1F, + 0x03, 0xFC, 0x70, 0xC6, 0x0E, 0xE0, 0x6E, 0x06, 0xC0, 0x7C, 0x06, 0xE0, + 0x66, 0x0E, 0x70, 0xE3, 0xFC, 0x1F, 0x00, 0xDF, 0x3F, 0xEE, 0x3F, 0x07, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3E, 0x1F, 0xFE, 0xDF, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00, 0x1F, 0x67, 0xFD, 0xC7, 0xB0, 0x7E, + 0x0F, 0xC1, 0xF0, 0x3E, 0x07, 0xE0, 0xEC, 0x1D, 0xC7, 0x9F, 0xF1, 0xEE, + 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0xDF, 0xFE, 0x30, 0xC3, 0x0C, + 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x1F, 0x0F, 0xE7, 0x1D, 0x83, 0x60, 0x1E, + 0x03, 0xF0, 0x1F, 0x00, 0xF8, 0x36, 0x1D, 0xFE, 0x1F, 0x00, 0x38, 0x70, + 0xE7, 0xFF, 0xE7, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x07, 0x87, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, + 0x7E, 0x3D, 0xFB, 0x3C, 0xC0, 0xC0, 0xF8, 0x1B, 0x83, 0x30, 0xC6, 0x18, + 0x63, 0x0C, 0xC1, 0x98, 0x1B, 0x03, 0xC0, 0x78, 0x07, 0x00, 0xC0, 0xC1, + 0x83, 0xE0, 0xC1, 0xB0, 0xF0, 0xCC, 0x78, 0xE6, 0x3C, 0x63, 0x33, 0x31, + 0x99, 0x98, 0x6C, 0xD8, 0x34, 0x3C, 0x1E, 0x1E, 0x0F, 0x0F, 0x03, 0x83, + 0x01, 0x81, 0x80, 0xE1, 0xD8, 0x67, 0x38, 0xCC, 0x1E, 0x07, 0x80, 0xC0, + 0x78, 0x3F, 0x0C, 0xC7, 0x39, 0x87, 0xE0, 0xC0, 0x60, 0x76, 0x06, 0x70, + 0xE3, 0x0C, 0x30, 0xC3, 0x9C, 0x19, 0x81, 0x98, 0x0F, 0x80, 0xF0, 0x0F, + 0x00, 0x70, 0x06, 0x00, 0x60, 0x0E, 0x00, 0xC0, 0x78, 0x07, 0x00, 0xFF, + 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x80, 0xC0, 0x60, 0x38, 0x1C, 0x06, + 0x03, 0xFF, 0xFF, 0xC0, 0x06, 0x1C, 0x61, 0xC3, 0x87, 0x0E, 0x1C, 0x30, + 0x61, 0xC7, 0x0F, 0x0E, 0x0C, 0x1C, 0x38, 0x70, 0xE1, 0xC1, 0x83, 0xC1, + 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0xC0, 0xC1, 0xC1, 0x83, 0x06, + 0x0C, 0x18, 0x30, 0x70, 0x31, 0xE3, 0x86, 0x0C, 0x18, 0x30, 0x61, 0xC3, + 0x0E, 0x30, 0x00, 0x3C, 0x01, 0xFC, 0x36, 0x39, 0xD0, 0x7E, 0x80, 0xF0 }; + +const GFXglyph Roboto_Regular12pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' + { 6, 6, 6, 8, 1, -17 }, // 0x22 '"' + { 11, 13, 17, 15, 1, -16 }, // 0x23 '#' + { 39, 11, 22, 14, 1, -19 }, // 0x24 '$' + { 70, 16, 17, 18, 1, -16 }, // 0x25 '%' + { 104, 13, 17, 15, 1, -16 }, // 0x26 '&' + { 132, 2, 6, 4, 1, -17 }, // 0x27 ''' + { 134, 6, 24, 8, 2, -18 }, // 0x28 '(' + { 152, 6, 24, 8, 0, -18 }, // 0x29 ')' + { 170, 10, 10, 10, 0, -16 }, // 0x2A '*' + { 183, 12, 12, 14, 1, -13 }, // 0x2B '+' + { 201, 3, 6, 5, 1, -2 }, // 0x2C ',' + { 204, 6, 2, 7, 0, -7 }, // 0x2D '-' + { 206, 2, 2, 6, 2, -1 }, // 0x2E '.' + { 207, 9, 18, 10, 0, -16 }, // 0x2F '/' + { 228, 11, 17, 14, 1, -16 }, // 0x30 '0' + { 252, 6, 17, 14, 2, -16 }, // 0x31 '1' + { 265, 11, 17, 14, 1, -16 }, // 0x32 '2' + { 289, 11, 17, 14, 1, -16 }, // 0x33 '3' + { 313, 12, 17, 14, 1, -16 }, // 0x34 '4' + { 339, 10, 17, 14, 2, -16 }, // 0x35 '5' + { 361, 11, 17, 14, 2, -16 }, // 0x36 '6' + { 385, 11, 17, 14, 1, -16 }, // 0x37 '7' + { 409, 11, 17, 14, 1, -16 }, // 0x38 '8' + { 433, 11, 17, 14, 1, -16 }, // 0x39 '9' + { 457, 2, 13, 6, 2, -12 }, // 0x3A ':' + { 461, 3, 16, 6, 1, -12 }, // 0x3B ';' + { 467, 9, 10, 12, 1, -10 }, // 0x3C '<' + { 479, 10, 7, 14, 2, -11 }, // 0x3D '=' + { 488, 10, 10, 13, 2, -10 }, // 0x3E '>' + { 501, 9, 17, 11, 1, -16 }, // 0x3F '?' + { 521, 20, 22, 21, 1, -16 }, // 0x40 '@' + { 576, 15, 17, 16, 0, -16 }, // 0x41 'A' + { 608, 12, 17, 15, 2, -16 }, // 0x42 'B' + { 634, 13, 17, 15, 1, -16 }, // 0x43 'C' + { 662, 13, 17, 16, 2, -16 }, // 0x44 'D' + { 690, 11, 17, 14, 2, -16 }, // 0x45 'E' + { 714, 11, 17, 14, 2, -16 }, // 0x46 'F' + { 738, 13, 17, 16, 1, -16 }, // 0x47 'G' + { 766, 13, 17, 17, 2, -16 }, // 0x48 'H' + { 794, 3, 17, 7, 2, -16 }, // 0x49 'I' + { 801, 10, 17, 13, 1, -16 }, // 0x4A 'J' + { 823, 13, 17, 15, 2, -16 }, // 0x4B 'K' + { 851, 11, 17, 13, 2, -16 }, // 0x4C 'L' + { 875, 17, 17, 21, 2, -16 }, // 0x4D 'M' + { 912, 13, 17, 17, 2, -16 }, // 0x4E 'N' + { 940, 14, 17, 16, 1, -16 }, // 0x4F 'O' + { 970, 12, 17, 15, 2, -16 }, // 0x50 'P' + { 996, 15, 19, 16, 1, -16 }, // 0x51 'Q' + { 1032, 13, 17, 16, 2, -16 }, // 0x52 'R' + { 1060, 13, 17, 15, 1, -16 }, // 0x53 'S' + { 1088, 14, 17, 14, 0, -16 }, // 0x54 'T' + { 1118, 13, 17, 16, 2, -16 }, // 0x55 'U' + { 1146, 15, 17, 15, 0, -16 }, // 0x56 'V' + { 1178, 19, 17, 21, 1, -16 }, // 0x57 'W' + { 1219, 14, 17, 15, 1, -16 }, // 0x58 'X' + { 1249, 14, 17, 15, 0, -16 }, // 0x59 'Y' + { 1279, 12, 17, 14, 1, -16 }, // 0x5A 'Z' + { 1305, 4, 24, 6, 2, -19 }, // 0x5B '[' + { 1317, 10, 18, 10, 0, -16 }, // 0x5C '\' + { 1340, 5, 24, 6, 0, -19 }, // 0x5D ']' + { 1355, 8, 9, 10, 1, -16 }, // 0x5E '^' + { 1364, 11, 2, 11, 0, 1 }, // 0x5F '_' + { 1367, 5, 3, 8, 1, -17 }, // 0x60 '`' + { 1369, 11, 13, 13, 1, -12 }, // 0x61 'a' + { 1387, 11, 18, 14, 2, -17 }, // 0x62 'b' + { 1412, 11, 13, 13, 1, -12 }, // 0x63 'c' + { 1430, 11, 18, 14, 1, -17 }, // 0x64 'd' + { 1455, 11, 13, 13, 1, -12 }, // 0x65 'e' + { 1473, 7, 19, 8, 1, -18 }, // 0x66 'f' + { 1490, 11, 18, 14, 1, -12 }, // 0x67 'g' + { 1515, 10, 18, 14, 2, -17 }, // 0x68 'h' + { 1538, 2, 18, 6, 2, -17 }, // 0x69 'i' + { 1543, 5, 23, 6, -1, -17 }, // 0x6A 'j' + { 1558, 10, 18, 12, 2, -17 }, // 0x6B 'k' + { 1581, 2, 18, 6, 2, -17 }, // 0x6C 'l' + { 1586, 17, 13, 21, 2, -12 }, // 0x6D 'm' + { 1614, 10, 13, 14, 2, -12 }, // 0x6E 'n' + { 1631, 12, 13, 14, 1, -12 }, // 0x6F 'o' + { 1651, 10, 18, 14, 2, -12 }, // 0x70 'p' + { 1674, 11, 18, 14, 1, -12 }, // 0x71 'q' + { 1699, 6, 13, 8, 2, -12 }, // 0x72 'r' + { 1709, 10, 13, 13, 1, -12 }, // 0x73 's' + { 1726, 7, 16, 8, 0, -15 }, // 0x74 't' + { 1740, 10, 13, 14, 2, -12 }, // 0x75 'u' + { 1757, 11, 13, 12, 1, -12 }, // 0x76 'v' + { 1775, 17, 13, 18, 1, -12 }, // 0x77 'w' + { 1803, 10, 13, 12, 1, -12 }, // 0x78 'x' + { 1820, 12, 18, 12, 0, -12 }, // 0x79 'y' + { 1847, 10, 13, 12, 1, -12 }, // 0x7A 'z' + { 1864, 7, 23, 8, 1, -18 }, // 0x7B '{' + { 1885, 2, 20, 6, 2, -16 }, // 0x7C '|' + { 1890, 7, 23, 8, 0, -18 }, // 0x7D '}' + { 1911, 14, 5, 16, 1, -8 } }; // 0x7E '~' + +const GFXfont Roboto_Regular12pt7b PROGMEM = { + (uint8_t *)Roboto_Regular12pt7bBitmaps, + (GFXglyph *)Roboto_Regular12pt7bGlyphs, + 0x20, 0x7E, 31 }; + +// Approx. 2592 bytes diff --git a/src/src/Static/Fonts/Roboto_Regular16pt7b.h b/src/src/Static/Fonts/Roboto_Regular16pt7b.h new file mode 100644 index 000000000..2f50dfc7d --- /dev/null +++ b/src/src/Static/Fonts/Roboto_Regular16pt7b.h @@ -0,0 +1,371 @@ +const uint8_t Roboto_Regular16pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0xE7, 0xE7, + 0xE7, 0xE7, 0xE7, 0xE6, 0xC6, 0xC6, 0x01, 0x86, 0x01, 0xC3, 0x00, 0xE3, + 0x80, 0x61, 0x80, 0x30, 0xC0, 0x18, 0x61, 0xFF, 0xFE, 0xFF, 0xFF, 0x06, + 0x18, 0x03, 0x0C, 0x01, 0x86, 0x01, 0xC3, 0x00, 0xE3, 0x80, 0x61, 0xC3, + 0xFF, 0xFD, 0xFF, 0xFE, 0x0C, 0x30, 0x0E, 0x38, 0x06, 0x1C, 0x03, 0x0C, + 0x01, 0x86, 0x01, 0xC3, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x03, 0xF0, + 0x3F, 0xF1, 0xE1, 0xE7, 0x03, 0x9C, 0x0E, 0x70, 0x1D, 0xC0, 0x77, 0x00, + 0x1E, 0x00, 0x3E, 0x00, 0x7F, 0x00, 0xFE, 0x00, 0x7E, 0x00, 0x78, 0x00, + 0xF0, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0xE7, 0x87, 0x9F, 0xFC, 0x1F, + 0xC0, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x3C, 0x00, 0x0F, 0xE0, 0x03, 0x8C, + 0x08, 0x61, 0xC3, 0x8C, 0x38, 0xE1, 0x87, 0x18, 0x30, 0xE6, 0x07, 0x18, + 0xC0, 0x7F, 0x30, 0x07, 0x8E, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x1C, + 0x78, 0x03, 0x3F, 0x80, 0xC6, 0x38, 0x39, 0xC3, 0x06, 0x30, 0x61, 0xC6, + 0x0C, 0x30, 0xE1, 0x8C, 0x0C, 0x70, 0x01, 0xFC, 0x00, 0x0F, 0x00, 0x07, + 0xC0, 0x07, 0xF8, 0x03, 0xC7, 0x00, 0xE0, 0xE0, 0x38, 0x38, 0x0E, 0x0E, + 0x03, 0x87, 0x00, 0xF3, 0xC0, 0x1D, 0xE0, 0x03, 0xE0, 0x00, 0xF0, 0x00, + 0xFE, 0x00, 0x7B, 0xC3, 0x9C, 0x78, 0xEE, 0x0F, 0x3B, 0x81, 0xCE, 0xE0, + 0x3F, 0x38, 0x0F, 0xC7, 0x01, 0xE1, 0xE0, 0xFC, 0x3F, 0xFF, 0x03, 0xF0, + 0xF0, 0xFF, 0xFF, 0xB6, 0x01, 0x07, 0x06, 0x0E, 0x1C, 0x38, 0x38, 0x70, + 0x70, 0x70, 0x60, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, + 0xE0, 0x60, 0x70, 0x70, 0x70, 0x38, 0x38, 0x1C, 0x0C, 0x06, 0x07, 0x01, + 0xC0, 0xE0, 0x70, 0x30, 0x38, 0x1C, 0x1C, 0x0E, 0x0E, 0x0E, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x0E, + 0x0E, 0x1C, 0x1C, 0x38, 0x30, 0x70, 0xE0, 0xC0, 0x07, 0x00, 0x18, 0x00, + 0xC0, 0x06, 0x07, 0x33, 0x3F, 0xFE, 0xFF, 0xC0, 0xE0, 0x0F, 0x80, 0xEE, + 0x06, 0x30, 0x71, 0xC1, 0x04, 0x00, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, + 0x1C, 0x00, 0x38, 0x00, 0x70, 0x3F, 0xFF, 0xFF, 0xFF, 0x03, 0x80, 0x07, + 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00, 0x77, + 0x76, 0xEC, 0xC0, 0xFF, 0xFC, 0xFF, 0x80, 0x00, 0x70, 0x06, 0x00, 0xE0, + 0x0E, 0x00, 0xC0, 0x1C, 0x01, 0x80, 0x18, 0x03, 0x80, 0x30, 0x07, 0x00, + 0x70, 0x06, 0x00, 0xE0, 0x0C, 0x01, 0xC0, 0x1C, 0x01, 0x80, 0x38, 0x03, + 0x80, 0x30, 0x07, 0x00, 0x60, 0x0E, 0x00, 0x0F, 0x80, 0xFF, 0x87, 0x87, + 0x1C, 0x0E, 0xE0, 0x3B, 0x80, 0x6E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, + 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, + 0x1B, 0x80, 0xE7, 0x03, 0x9E, 0x1C, 0x3F, 0xE0, 0x3F, 0x00, 0x0F, 0xFF, + 0xF8, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, + 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x07, 0xE0, 0x3F, 0xE0, 0xE0, 0xE3, + 0x80, 0xE7, 0x01, 0xCC, 0x03, 0xB8, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, + 0x70, 0x01, 0xE0, 0x07, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, + 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0xFF, 0xEF, 0xFF, 0xC0, + 0x0F, 0xC0, 0x7F, 0xC3, 0x87, 0x9C, 0x07, 0x70, 0x1D, 0xC0, 0x70, 0x01, + 0xC0, 0x07, 0x00, 0x18, 0x00, 0xE0, 0x7E, 0x01, 0xFC, 0x00, 0x38, 0x00, + 0x70, 0x01, 0xC0, 0x07, 0xE0, 0x1D, 0xC0, 0x77, 0x01, 0xCE, 0x0E, 0x1F, + 0xF0, 0x3F, 0x80, 0x00, 0x78, 0x00, 0x78, 0x00, 0xF8, 0x01, 0xF8, 0x01, + 0xF8, 0x03, 0xB8, 0x07, 0x38, 0x07, 0x38, 0x0E, 0x38, 0x0E, 0x38, 0x1C, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x70, 0x38, 0xE0, 0x38, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x3F, + 0xF8, 0xFF, 0xE3, 0x00, 0x0C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, + 0x00, 0x77, 0xC1, 0xFF, 0xC7, 0x87, 0x9C, 0x0E, 0x60, 0x38, 0x00, 0x70, + 0x01, 0xC0, 0x07, 0xE0, 0x1F, 0x80, 0xE7, 0x03, 0x9E, 0x1C, 0x3F, 0xF0, + 0x3F, 0x00, 0x07, 0xF0, 0x3F, 0xC3, 0xC1, 0x0E, 0x00, 0x70, 0x01, 0x80, + 0x0E, 0x00, 0x39, 0xF8, 0xFF, 0xF3, 0xE1, 0xEF, 0x03, 0xF8, 0x07, 0xE0, + 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1D, 0xC0, 0x77, 0x03, 0x8F, + 0x1E, 0x1F, 0xF0, 0x1F, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x38, 0x00, + 0xE0, 0x03, 0x80, 0x06, 0x00, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x03, 0x80, + 0x07, 0x00, 0x0C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x03, 0x80, 0x07, + 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x01, 0xC0, 0x00, 0x0F, + 0xC0, 0xFF, 0x87, 0x8F, 0x1C, 0x0E, 0xE0, 0x3B, 0x80, 0xEE, 0x03, 0xB8, + 0x0E, 0x70, 0x39, 0xE1, 0xC1, 0xFE, 0x07, 0xF8, 0x78, 0x73, 0x80, 0xEE, + 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x03, 0x9E, 0x1E, 0x3F, 0xF0, + 0x7F, 0x00, 0x07, 0xC0, 0x3F, 0xE0, 0xF1, 0xE3, 0x81, 0xE7, 0x01, 0xDC, + 0x03, 0xB8, 0x07, 0x70, 0x0E, 0xE0, 0x0F, 0xC0, 0x1D, 0xC0, 0x7B, 0x80, + 0xF3, 0x87, 0xE3, 0xFD, 0xC3, 0xF7, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, + 0x00, 0xE1, 0x03, 0xC3, 0xFF, 0x03, 0xF8, 0x00, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x3F, 0xE0, 0x73, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE7, 0x7B, 0x9C, 0xCE, 0x00, 0x00, 0x10, 0x03, 0x00, 0xF0, 0x7F, 0x1F, + 0xC7, 0xE0, 0xF8, 0x0F, 0x00, 0x7E, 0x01, 0xF8, 0x07, 0xF0, 0x0F, 0x00, + 0x30, 0x01, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0x00, 0x3E, 0x00, 0xFC, 0x01, 0xFC, 0x01, + 0xF8, 0x01, 0xE0, 0x1F, 0x03, 0xF0, 0xFE, 0x1F, 0x81, 0xF0, 0x0E, 0x00, + 0x40, 0x00, 0x1F, 0x87, 0xFE, 0xF0, 0xFE, 0x07, 0xE0, 0x70, 0x07, 0x00, + 0x70, 0x07, 0x00, 0xF0, 0x0E, 0x01, 0xC0, 0x3C, 0x07, 0x80, 0x70, 0x0E, + 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x00, + 0x3F, 0x80, 0x00, 0x7F, 0xF8, 0x00, 0xF0, 0x1E, 0x00, 0xE0, 0x03, 0x80, + 0xE0, 0x00, 0xE0, 0xE0, 0x00, 0x38, 0x60, 0x00, 0x0C, 0x70, 0x3E, 0x06, + 0x30, 0x3F, 0xC1, 0x98, 0x38, 0x60, 0xDC, 0x18, 0x30, 0x6C, 0x1C, 0x18, + 0x36, 0x0C, 0x0C, 0x1B, 0x0E, 0x0E, 0x0D, 0x87, 0x07, 0x06, 0xC3, 0x83, + 0x83, 0x61, 0xC1, 0xC1, 0xB0, 0xE0, 0xC0, 0xD8, 0x70, 0x60, 0xCC, 0x1C, + 0x78, 0xC7, 0x0F, 0xEF, 0xE1, 0x83, 0xC3, 0xC0, 0xC0, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0xE0, 0x30, 0x00, + 0x7F, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x70, 0x00, 0x0F, 0x00, 0x00, + 0xF0, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x19, 0x80, 0x03, 0x9C, 0x00, + 0x39, 0xC0, 0x03, 0x0E, 0x00, 0x70, 0xE0, 0x07, 0x06, 0x00, 0xE0, 0x70, + 0x0E, 0x07, 0x00, 0xE0, 0x38, 0x1F, 0xFF, 0x81, 0xFF, 0xF8, 0x38, 0x01, + 0xC3, 0x80, 0x1C, 0x38, 0x00, 0xC7, 0x00, 0x0E, 0x70, 0x00, 0xEF, 0x00, + 0x07, 0xFF, 0xC1, 0xFF, 0xE3, 0x81, 0xE7, 0x00, 0xEE, 0x01, 0xDC, 0x03, + 0xB8, 0x07, 0x70, 0x0E, 0xE0, 0x39, 0xFF, 0xE3, 0xFF, 0xC7, 0x01, 0xCE, + 0x01, 0xDC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, + 0x7F, 0x01, 0xEF, 0xFF, 0x9F, 0xFC, 0x00, 0x07, 0xF0, 0x1F, 0xFC, 0x3C, + 0x1E, 0x78, 0x0F, 0x70, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x00, 0xE0, + 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, + 0x00, 0xE0, 0x07, 0xE0, 0x07, 0x70, 0x07, 0x78, 0x0F, 0x3C, 0x1E, 0x1F, + 0xFC, 0x07, 0xF0, 0xFF, 0xC0, 0xFF, 0xF0, 0xE0, 0x78, 0xE0, 0x1C, 0xE0, + 0x0E, 0xE0, 0x0E, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, + 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, + 0x0E, 0xE0, 0x0E, 0xE0, 0x1C, 0xE0, 0x78, 0xFF, 0xF0, 0xFF, 0xC0, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, + 0x00, 0xE0, 0x03, 0xFF, 0xEF, 0xFF, 0xB8, 0x00, 0xE0, 0x03, 0x80, 0x0E, + 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xFF, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, + 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0xFF, 0xBF, 0xFE, 0xE0, + 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, + 0x00, 0xE0, 0x03, 0x80, 0x00, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x8F, + 0x01, 0xE7, 0x00, 0x77, 0x00, 0x3B, 0x80, 0x0F, 0xC0, 0x00, 0xE0, 0x00, + 0x70, 0x00, 0x38, 0x00, 0x1C, 0x0F, 0xFE, 0x07, 0xFF, 0x00, 0x1F, 0x80, + 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xB8, 0x01, 0xDE, 0x00, 0xE7, 0x81, 0xE0, + 0xFF, 0xE0, 0x1F, 0xC0, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, + 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, + 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1C, 0x00, + 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, + 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, + 0x07, 0xE0, 0x1F, 0x80, 0xEF, 0x03, 0x9E, 0x1C, 0x3F, 0xE0, 0x7F, 0x00, + 0xE0, 0x0F, 0x70, 0x07, 0x38, 0x07, 0x1C, 0x07, 0x8E, 0x07, 0x87, 0x03, + 0x83, 0x83, 0x81, 0xC3, 0x80, 0xE3, 0xC0, 0x73, 0xC0, 0x3F, 0xC0, 0x1F, + 0xE0, 0x0E, 0x38, 0x07, 0x1E, 0x03, 0x87, 0x81, 0xC1, 0xE0, 0xE0, 0x70, + 0x70, 0x1C, 0x38, 0x0F, 0x1C, 0x03, 0xCE, 0x00, 0xF7, 0x00, 0x3C, 0xE0, + 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, + 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, + 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0F, 0xFF, 0xFF, 0xFC, 0xF0, + 0x00, 0x7F, 0x80, 0x03, 0xFE, 0x00, 0x1F, 0xF0, 0x01, 0xFD, 0x80, 0x0F, + 0xEE, 0x00, 0xEF, 0x70, 0x07, 0x7D, 0x80, 0x33, 0xEE, 0x03, 0x9F, 0x30, + 0x1C, 0xF9, 0xC0, 0xC7, 0xCE, 0x0E, 0x3E, 0x30, 0x61, 0xF1, 0xC7, 0x0F, + 0x86, 0x38, 0x7C, 0x39, 0x83, 0xE1, 0xDC, 0x1F, 0x06, 0xC0, 0xF8, 0x3E, + 0x07, 0xC0, 0xF0, 0x3E, 0x07, 0x01, 0xF0, 0x38, 0x0C, 0xE0, 0x07, 0xF0, + 0x07, 0xF0, 0x07, 0xF8, 0x07, 0xFC, 0x07, 0xFC, 0x07, 0xEE, 0x07, 0xEE, + 0x07, 0xE7, 0x07, 0xE3, 0x87, 0xE3, 0x87, 0xE1, 0xC7, 0xE1, 0xE7, 0xE0, + 0xE7, 0xE0, 0x77, 0xE0, 0x77, 0xE0, 0x3F, 0xE0, 0x1F, 0xE0, 0x1F, 0xE0, + 0x0F, 0xE0, 0x0F, 0xE0, 0x07, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x8F, + 0x01, 0xE7, 0x00, 0x77, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, + 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, + 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xB8, 0x03, 0x9E, 0x03, 0xC7, 0x83, 0xC1, + 0xFF, 0xC0, 0x3F, 0x00, 0xFF, 0xE0, 0xFF, 0xF8, 0xE0, 0x3C, 0xE0, 0x0E, + 0xE0, 0x0E, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0E, 0xE0, 0x0E, + 0xE0, 0x3C, 0xFF, 0xF8, 0xFF, 0xE0, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, + 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, + 0x07, 0xF0, 0x07, 0xFF, 0x03, 0xC1, 0xE1, 0xE0, 0x3C, 0x70, 0x07, 0x38, + 0x00, 0xEE, 0x00, 0x3B, 0x80, 0x0E, 0xE0, 0x03, 0xB8, 0x00, 0xEE, 0x00, + 0x3B, 0x80, 0x0E, 0xE0, 0x03, 0xB8, 0x00, 0xEE, 0x00, 0x3B, 0x80, 0x0E, + 0xE0, 0x03, 0x9C, 0x01, 0xC7, 0x80, 0xF0, 0xF0, 0x78, 0x1F, 0xFE, 0x01, + 0xFF, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01, 0x80, 0xFF, 0xE0, 0xFF, + 0xF8, 0xE0, 0x3C, 0xE0, 0x1E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, + 0x0E, 0xE0, 0x1E, 0xE0, 0x3C, 0xFF, 0xF8, 0xFF, 0xF8, 0xE0, 0x3C, 0xE0, + 0x1E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, 0x0E, 0xE0, + 0x0E, 0xE0, 0x0E, 0xE0, 0x07, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x87, + 0x00, 0xE7, 0x00, 0x73, 0x80, 0x1D, 0xC0, 0x00, 0x70, 0x00, 0x3C, 0x00, + 0x0F, 0xC0, 0x01, 0xFC, 0x00, 0x1F, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, + 0x1C, 0x00, 0x07, 0x60, 0x03, 0xB8, 0x01, 0xDC, 0x01, 0xC7, 0x81, 0xE1, + 0xFF, 0xC0, 0x3F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x38, + 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, + 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, + 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, + 0x00, 0x0E, 0x00, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x7E, + 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, + 0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, + 0x07, 0xE0, 0x03, 0xB8, 0x03, 0x9C, 0x01, 0xC7, 0x83, 0xC1, 0xFF, 0xC0, + 0x3F, 0x80, 0xF0, 0x00, 0xEE, 0x00, 0x1D, 0xC0, 0x07, 0x1C, 0x00, 0xE3, + 0x80, 0x3C, 0x70, 0x07, 0x07, 0x00, 0xE0, 0xE0, 0x38, 0x1E, 0x07, 0x01, + 0xC0, 0xE0, 0x38, 0x38, 0x03, 0x87, 0x00, 0x70, 0xE0, 0x0E, 0x38, 0x00, + 0xE7, 0x00, 0x1C, 0xE0, 0x03, 0xB8, 0x00, 0x3F, 0x00, 0x07, 0xC0, 0x00, + 0x78, 0x00, 0x0F, 0x00, 0x01, 0xC0, 0x00, 0xE0, 0x1C, 0x03, 0xF0, 0x0E, + 0x01, 0xF8, 0x07, 0x80, 0xEE, 0x07, 0xC0, 0x77, 0x03, 0xE0, 0x73, 0x81, + 0xB0, 0x39, 0xC1, 0xDC, 0x1C, 0x70, 0xEE, 0x0E, 0x38, 0x73, 0x0E, 0x1C, + 0x31, 0xC7, 0x0E, 0x38, 0xE3, 0x83, 0x1C, 0x71, 0xC1, 0xCE, 0x18, 0xC0, + 0xEE, 0x0E, 0xE0, 0x77, 0x07, 0x70, 0x1B, 0x81, 0xB8, 0x0D, 0x80, 0xD8, + 0x07, 0xC0, 0x7C, 0x03, 0xE0, 0x3E, 0x00, 0xF0, 0x0F, 0x00, 0x70, 0x07, + 0x00, 0x38, 0x03, 0x80, 0xF0, 0x03, 0xDE, 0x01, 0xE3, 0x80, 0xF0, 0xF0, + 0x38, 0x1C, 0x1E, 0x03, 0x87, 0x00, 0xF3, 0x80, 0x1D, 0xE0, 0x03, 0xF0, + 0x00, 0xFC, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x03, 0xF0, 0x01, 0xFC, 0x00, + 0x73, 0x80, 0x3C, 0xF0, 0x0E, 0x1C, 0x07, 0x07, 0x83, 0xC0, 0xE0, 0xE0, + 0x1C, 0x78, 0x07, 0xBC, 0x00, 0xF0, 0xF0, 0x01, 0xEE, 0x00, 0x78, 0xE0, + 0x0E, 0x1C, 0x03, 0xC1, 0xC0, 0x70, 0x3C, 0x1E, 0x03, 0x83, 0x80, 0x78, + 0xF0, 0x07, 0x1C, 0x00, 0xF7, 0x80, 0x0E, 0xE0, 0x00, 0xF8, 0x00, 0x1F, + 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, + 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x7F, + 0xFF, 0x7F, 0xFF, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x38, 0x00, + 0x78, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, + 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x38, + 0x00, 0x70, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x38, 0xE3, 0x8E, + 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, + 0x38, 0xE3, 0x8E, 0x38, 0xFF, 0xF0, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, + 0x70, 0x03, 0x80, 0x38, 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x0C, 0x00, 0xE0, + 0x0E, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x01, 0xC0, 0x1C, + 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x07, 0xFF, 0xF1, 0xC7, 0x1C, 0x71, 0xC7, + 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, + 0x1C, 0x71, 0xC7, 0xFF, 0xF0, 0x0E, 0x01, 0xC0, 0x7C, 0x0F, 0x81, 0xB0, + 0x77, 0x0C, 0xE3, 0x8E, 0x71, 0xCC, 0x1B, 0x83, 0x80, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xE1, 0x83, 0x0F, 0xC1, 0xFF, 0x1E, 0x3C, 0xE0, 0xFE, 0x03, + 0x80, 0x1C, 0x00, 0xE3, 0xFF, 0x7F, 0xFF, 0x81, 0xF8, 0x0F, 0xC0, 0x7E, + 0x03, 0xF0, 0x3F, 0xC3, 0xEF, 0xF7, 0x3E, 0x38, 0xE0, 0x03, 0x80, 0x0E, + 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x39, 0xF0, 0xEF, 0xF3, + 0xE1, 0xEF, 0x03, 0xB8, 0x0E, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, + 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xF0, 0x3B, 0xE1, 0xEF, 0xFF, + 0x39, 0xF0, 0x07, 0xE0, 0x7F, 0xE3, 0xC3, 0x8E, 0x07, 0x70, 0x1D, 0xC0, + 0x37, 0x00, 0x3C, 0x00, 0xE0, 0x03, 0x80, 0x07, 0x00, 0x1C, 0x00, 0x70, + 0x1C, 0xE0, 0x73, 0xC3, 0x87, 0xFC, 0x07, 0xE0, 0x00, 0x1C, 0x00, 0x70, + 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC3, 0xE7, 0x1F, 0xFC, + 0xF0, 0xF3, 0x81, 0xDC, 0x07, 0x70, 0x1D, 0xC0, 0x77, 0x01, 0xF8, 0x07, + 0xE0, 0x1D, 0xC0, 0x77, 0x01, 0xDC, 0x07, 0x78, 0x1C, 0xF0, 0xF1, 0xFE, + 0xC3, 0xF3, 0x07, 0xC0, 0x7F, 0xC3, 0xC7, 0x8E, 0x0E, 0x70, 0x1D, 0xC0, + 0x77, 0x01, 0xDF, 0xFF, 0xFF, 0xFD, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, + 0x00, 0xE0, 0x23, 0xC1, 0x87, 0xFF, 0x07, 0xE0, 0x07, 0xC3, 0xF1, 0xC0, + 0x70, 0x38, 0x0E, 0x03, 0x83, 0xFE, 0xFF, 0x8E, 0x03, 0x80, 0xE0, 0x38, + 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, + 0x80, 0xE0, 0x0F, 0x99, 0xFE, 0xDE, 0x1E, 0xE0, 0x7E, 0x03, 0xF0, 0x1F, + 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF8, + 0x1D, 0xE1, 0xE7, 0xFF, 0x1F, 0xB8, 0x01, 0xC0, 0x0E, 0x00, 0x72, 0x07, + 0x1F, 0xF1, 0x7F, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, + 0x03, 0x80, 0x0E, 0x00, 0x38, 0xF8, 0xEF, 0xF3, 0xE1, 0xEF, 0x03, 0xB8, + 0x0E, 0xE0, 0x3B, 0x80, 0x6E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, + 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xFF, 0x80, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x1C, 0x38, 0x00, 0x00, + 0x00, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, + 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x70, 0xEF, 0x9E, 0x00, 0xE0, 0x03, + 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x1E, + 0xE0, 0x73, 0x83, 0x8E, 0x1E, 0x38, 0x70, 0xE3, 0x83, 0x9C, 0x0F, 0xF0, + 0x3F, 0xC0, 0xE7, 0x83, 0x8E, 0x0E, 0x1C, 0x38, 0x78, 0xE0, 0xE3, 0x81, + 0xCE, 0x07, 0xB8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE7, 0xC1, 0xF1, 0xDF, 0xE7, 0xF3, 0xE3, 0xD8, 0xF7, 0x83, 0xE0, + 0xEE, 0x03, 0x80, 0xFC, 0x07, 0x01, 0xF8, 0x0E, 0x03, 0xF0, 0x1C, 0x07, + 0xE0, 0x38, 0x0F, 0xC0, 0x70, 0x1F, 0x80, 0xE0, 0x3F, 0x01, 0xC0, 0x7E, + 0x03, 0x80, 0xFC, 0x07, 0x01, 0xF8, 0x0E, 0x03, 0xF0, 0x1C, 0x07, 0xE0, + 0x38, 0x0E, 0xE7, 0xC7, 0x7F, 0xBE, 0x1F, 0xE0, 0x7E, 0x03, 0xF0, 0x1F, + 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, + 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x38, 0x07, 0xE0, 0x3F, 0xE0, 0xF0, 0xE1, + 0xC0, 0xE7, 0x01, 0xCE, 0x01, 0xDC, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, + 0x1D, 0xC0, 0x3B, 0x80, 0x77, 0x01, 0xC7, 0x03, 0x8F, 0x0E, 0x0F, 0xF8, + 0x07, 0xE0, 0xE7, 0xC3, 0xFF, 0xCF, 0x87, 0x3C, 0x0E, 0xE0, 0x3B, 0x80, + 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, + 0x3F, 0xC0, 0xEF, 0x87, 0xBB, 0xFC, 0xE7, 0xC3, 0x80, 0x0E, 0x00, 0x38, + 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x00, 0x0F, 0xCC, 0x7F, 0xB3, 0xC3, + 0xCE, 0x07, 0x70, 0x1D, 0xC0, 0x77, 0x01, 0xDC, 0x07, 0xE0, 0x1F, 0x80, + 0x77, 0x01, 0xDC, 0x07, 0x70, 0x1D, 0xE0, 0x73, 0xC3, 0xC7, 0xFF, 0x0F, + 0x9C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, + 0xE7, 0xEF, 0xFF, 0xF8, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, + 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x1F, 0x81, 0xFF, 0x1C, 0x3D, 0xC0, 0xEE, + 0x07, 0x70, 0x01, 0xC0, 0x07, 0xE0, 0x1F, 0xC0, 0x0F, 0x80, 0x1C, 0x00, + 0x7E, 0x03, 0xF0, 0x39, 0xC3, 0xCF, 0xFC, 0x1F, 0x80, 0x38, 0x38, 0x38, + 0x38, 0xFF, 0xFF, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x3C, 0x1F, 0x0F, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, + 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, + 0xC0, 0x7E, 0x03, 0xB8, 0x1D, 0xC1, 0xE7, 0xFB, 0x1F, 0x18, 0xE0, 0x1F, + 0x80, 0x77, 0x03, 0x9C, 0x0E, 0x70, 0x38, 0xE1, 0xC3, 0x87, 0x0E, 0x18, + 0x18, 0xE0, 0x73, 0x81, 0xCC, 0x03, 0x70, 0x0F, 0xC0, 0x1E, 0x00, 0x78, + 0x01, 0xE0, 0x03, 0x00, 0xE0, 0x70, 0x1F, 0x81, 0xC0, 0xEE, 0x07, 0x83, + 0x9C, 0x3E, 0x0E, 0x70, 0xD8, 0x31, 0xC3, 0x71, 0xC3, 0x0D, 0xC7, 0x0E, + 0x73, 0x1C, 0x39, 0x8C, 0x60, 0xE6, 0x3B, 0x81, 0xB8, 0x6E, 0x06, 0xC1, + 0xB8, 0x1F, 0x06, 0xC0, 0x7C, 0x1F, 0x00, 0xF0, 0x3C, 0x03, 0x80, 0xE0, + 0x0E, 0x03, 0x80, 0xF0, 0x3D, 0xC1, 0xE7, 0x87, 0x0E, 0x38, 0x1C, 0xE0, + 0x77, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x3E, 0x00, 0xFC, 0x07, 0x70, + 0x1C, 0xE0, 0xE3, 0xC7, 0x87, 0x1C, 0x0E, 0xE0, 0x3C, 0xF0, 0x0E, 0xE0, + 0x3D, 0xE0, 0x71, 0xC0, 0xE3, 0x83, 0xC7, 0x87, 0x07, 0x0E, 0x0E, 0x38, + 0x0E, 0x70, 0x1C, 0xE0, 0x3B, 0x80, 0x37, 0x00, 0x7E, 0x00, 0x78, 0x00, + 0xF0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0C, 0x00, 0x38, 0x00, 0xE0, + 0x07, 0xC0, 0x0E, 0x00, 0x00, 0x7F, 0xFB, 0xFF, 0xC0, 0x1C, 0x01, 0xE0, + 0x0E, 0x00, 0xE0, 0x0F, 0x00, 0x70, 0x07, 0x00, 0x78, 0x03, 0x80, 0x38, + 0x03, 0xC0, 0x1C, 0x01, 0xC0, 0x1F, 0xFF, 0xFF, 0xF8, 0x01, 0x83, 0xC3, + 0xC1, 0xC1, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC1, + 0xC3, 0xC1, 0xE0, 0x38, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, + 0x1C, 0x0E, 0x03, 0x81, 0xE0, 0x78, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x40, 0x3C, 0x03, 0x80, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, + 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x0E, 0x03, 0xC0, 0x7C, 0x1F, 0x0F, 0x03, + 0x81, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, + 0xE0, 0xF0, 0x10, 0x00, 0x3E, 0x00, 0x3F, 0x80, 0xF8, 0xF0, 0x78, 0x3C, + 0x6C, 0x07, 0xF0, 0x01, 0xF0 }; + +const GFXglyph Roboto_Regular16pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' + { 1, 3, 22, 8, 3, -21 }, // 0x21 '!' + { 10, 8, 8, 10, 1, -23 }, // 0x22 '"' + { 18, 17, 22, 19, 1, -21 }, // 0x23 '#' + { 65, 14, 28, 17, 2, -24 }, // 0x24 '$' + { 114, 19, 22, 23, 2, -21 }, // 0x25 '%' + { 167, 18, 22, 19, 1, -21 }, // 0x26 '&' + { 217, 3, 8, 5, 1, -23 }, // 0x27 ''' + { 220, 8, 32, 10, 2, -24 }, // 0x28 '(' + { 252, 8, 32, 10, 0, -24 }, // 0x29 ')' + { 284, 13, 13, 13, 0, -21 }, // 0x2A '*' + { 306, 15, 15, 18, 1, -17 }, // 0x2B '+' + { 335, 4, 7, 6, 1, -2 }, // 0x2C ',' + { 339, 7, 2, 8, 1, -9 }, // 0x2D '-' + { 341, 3, 3, 8, 2, -2 }, // 0x2E '.' + { 343, 12, 24, 13, 0, -21 }, // 0x2F '/' + { 379, 14, 22, 17, 2, -21 }, // 0x30 '0' + { 418, 7, 22, 17, 3, -21 }, // 0x31 '1' + { 438, 15, 22, 17, 1, -21 }, // 0x32 '2' + { 480, 14, 22, 17, 1, -21 }, // 0x33 '3' + { 519, 16, 22, 17, 1, -21 }, // 0x34 '4' + { 563, 14, 22, 17, 2, -21 }, // 0x35 '5' + { 602, 14, 22, 17, 2, -21 }, // 0x36 '6' + { 641, 15, 22, 17, 1, -21 }, // 0x37 '7' + { 683, 14, 22, 17, 2, -21 }, // 0x38 '8' + { 722, 15, 22, 17, 1, -21 }, // 0x39 '9' + { 764, 3, 17, 8, 2, -16 }, // 0x3A ':' + { 771, 5, 21, 8, 1, -16 }, // 0x3B ';' + { 785, 12, 14, 16, 1, -14 }, // 0x3C '<' + { 806, 13, 8, 17, 2, -14 }, // 0x3D '=' + { 819, 13, 14, 16, 2, -14 }, // 0x3E '>' + { 842, 12, 22, 15, 1, -21 }, // 0x3F '?' + { 875, 25, 29, 28, 1, -21 }, // 0x40 '@' + { 966, 20, 22, 20, 0, -21 }, // 0x41 'A' + { 1021, 15, 22, 20, 3, -21 }, // 0x42 'B' + { 1063, 16, 22, 20, 2, -21 }, // 0x43 'C' + { 1107, 16, 22, 20, 3, -21 }, // 0x44 'D' + { 1151, 14, 22, 18, 3, -21 }, // 0x45 'E' + { 1190, 14, 22, 18, 3, -21 }, // 0x46 'F' + { 1229, 17, 22, 21, 2, -21 }, // 0x47 'G' + { 1276, 16, 22, 22, 3, -21 }, // 0x48 'H' + { 1320, 3, 22, 9, 3, -21 }, // 0x49 'I' + { 1329, 14, 22, 17, 1, -21 }, // 0x4A 'J' + { 1368, 17, 22, 20, 3, -21 }, // 0x4B 'K' + { 1415, 13, 22, 17, 3, -21 }, // 0x4C 'L' + { 1451, 21, 22, 27, 3, -21 }, // 0x4D 'M' + { 1509, 16, 22, 22, 3, -21 }, // 0x4E 'N' + { 1553, 17, 22, 21, 2, -21 }, // 0x4F 'O' + { 1600, 16, 22, 20, 3, -21 }, // 0x50 'P' + { 1644, 18, 25, 21, 2, -21 }, // 0x51 'Q' + { 1701, 16, 22, 21, 3, -21 }, // 0x52 'R' + { 1745, 17, 22, 19, 1, -21 }, // 0x53 'S' + { 1792, 17, 22, 18, 1, -21 }, // 0x54 'T' + { 1839, 17, 22, 21, 2, -21 }, // 0x55 'U' + { 1886, 19, 22, 20, 0, -21 }, // 0x56 'V' + { 1939, 25, 22, 27, 1, -21 }, // 0x57 'W' + { 2008, 18, 22, 20, 1, -21 }, // 0x58 'X' + { 2058, 19, 22, 19, 0, -21 }, // 0x59 'Y' + { 2111, 16, 22, 19, 1, -21 }, // 0x5A 'Z' + { 2155, 6, 30, 8, 2, -24 }, // 0x5B '[' + { 2178, 12, 24, 13, 1, -21 }, // 0x5C '\' + { 2214, 6, 30, 8, 0, -24 }, // 0x5D ']' + { 2237, 11, 11, 13, 1, -21 }, // 0x5E '^' + { 2253, 14, 2, 14, 0, 1 }, // 0x5F '_' + { 2257, 6, 4, 10, 1, -22 }, // 0x60 '`' + { 2260, 13, 17, 17, 2, -16 }, // 0x61 'a' + { 2288, 14, 24, 18, 2, -23 }, // 0x62 'b' + { 2330, 14, 17, 16, 1, -16 }, // 0x63 'c' + { 2360, 14, 24, 18, 1, -23 }, // 0x64 'd' + { 2402, 14, 17, 16, 1, -16 }, // 0x65 'e' + { 2432, 10, 24, 11, 1, -23 }, // 0x66 'f' + { 2462, 13, 23, 18, 2, -16 }, // 0x67 'g' + { 2500, 14, 24, 18, 2, -23 }, // 0x68 'h' + { 2542, 3, 24, 8, 2, -23 }, // 0x69 'i' + { 2551, 7, 30, 8, -1, -23 }, // 0x6A 'j' + { 2578, 14, 24, 16, 2, -23 }, // 0x6B 'k' + { 2620, 3, 24, 8, 2, -23 }, // 0x6C 'l' + { 2629, 23, 17, 27, 2, -16 }, // 0x6D 'm' + { 2678, 13, 17, 18, 2, -16 }, // 0x6E 'n' + { 2706, 15, 17, 18, 1, -16 }, // 0x6F 'o' + { 2738, 14, 23, 18, 2, -16 }, // 0x70 'p' + { 2779, 14, 23, 18, 1, -16 }, // 0x71 'q' + { 2820, 8, 17, 11, 2, -16 }, // 0x72 'r' + { 2837, 13, 17, 16, 2, -16 }, // 0x73 's' + { 2865, 8, 21, 11, 1, -20 }, // 0x74 't' + { 2886, 13, 17, 18, 2, -16 }, // 0x75 'u' + { 2914, 14, 17, 16, 1, -16 }, // 0x76 'v' + { 2944, 22, 17, 23, 1, -16 }, // 0x77 'w' + { 2991, 14, 17, 16, 1, -16 }, // 0x78 'x' + { 3021, 15, 23, 16, 0, -16 }, // 0x79 'y' + { 3065, 13, 17, 16, 1, -16 }, // 0x7A 'z' + { 3093, 9, 30, 11, 1, -23 }, // 0x7B '{' + { 3127, 2, 26, 8, 3, -21 }, // 0x7C '|' + { 3134, 10, 30, 11, 0, -23 }, // 0x7D '}' + { 3172, 17, 6, 21, 2, -11 } }; // 0x7E '~' + +const GFXfont Roboto_Regular16pt7b PROGMEM = { + (uint8_t *)Roboto_Regular16pt7bBitmaps, + (GFXglyph *)Roboto_Regular16pt7bGlyphs, + 0x20, 0x7E, 41 }; + +// Approx. 3857 bytes diff --git a/src/src/Static/Fonts/Roboto_Regular8pt7b.h b/src/src/Static/Fonts/Roboto_Regular8pt7b.h new file mode 100644 index 000000000..f98d6833e --- /dev/null +++ b/src/src/Static/Fonts/Roboto_Regular8pt7b.h @@ -0,0 +1,183 @@ +const uint8_t Roboto_Regular8pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0x0F, 0xBB, 0xAA, 0x12, 0x12, 0x12, 0x32, 0xFF, 0x24, + 0x24, 0x24, 0xFF, 0x4C, 0x48, 0x48, 0x10, 0x20, 0xF2, 0x3C, 0x78, 0x10, + 0x38, 0x1C, 0x0C, 0x0C, 0x1C, 0x6F, 0x84, 0x00, 0x70, 0x24, 0x09, 0x92, + 0x48, 0x72, 0x01, 0x00, 0xC0, 0x2E, 0x16, 0x4D, 0x12, 0x64, 0x0E, 0x1C, + 0x09, 0x82, 0x21, 0x98, 0x3C, 0x06, 0x06, 0x89, 0x32, 0x46, 0xB0, 0xE6, + 0x38, 0xF3, 0xF0, 0x13, 0x24, 0x4C, 0xCC, 0xCC, 0xCC, 0x44, 0x23, 0x10, + 0x84, 0x62, 0x33, 0x11, 0x11, 0x13, 0x32, 0x64, 0x80, 0x10, 0x23, 0x53, + 0xF3, 0x8D, 0x13, 0x00, 0x10, 0x20, 0x47, 0xF1, 0x02, 0x04, 0x08, 0x57, + 0xF0, 0xF0, 0x04, 0x30, 0x82, 0x18, 0x43, 0x08, 0x21, 0x84, 0x10, 0xC0, + 0x38, 0x8B, 0x1C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x8D, 0x11, 0xC0, 0x3F, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x79, 0x8A, 0x1C, 0x30, 0x61, 0x82, 0x0C, + 0x30, 0xC3, 0x07, 0xF0, 0x79, 0x8A, 0x18, 0x30, 0x67, 0x81, 0x03, 0x07, + 0x0F, 0x13, 0xC0, 0x06, 0x03, 0x02, 0x83, 0x41, 0x21, 0x11, 0x88, 0x84, + 0xFF, 0x81, 0x00, 0x80, 0x40, 0x7E, 0x81, 0x02, 0x04, 0x0F, 0xB1, 0x83, + 0x03, 0x8D, 0x19, 0xE0, 0x3C, 0xC1, 0x06, 0x0F, 0xD8, 0xF0, 0xE1, 0xC3, + 0x85, 0x99, 0xE0, 0xFE, 0x0C, 0x10, 0x60, 0x83, 0x04, 0x08, 0x30, 0x60, + 0x81, 0x00, 0x7D, 0x8F, 0x1E, 0x34, 0x47, 0x11, 0x61, 0x83, 0x07, 0x1B, + 0xE0, 0x79, 0x8A, 0x1C, 0x38, 0x70, 0xF1, 0xBF, 0x06, 0x0C, 0x33, 0xC0, + 0xF0, 0x03, 0xC0, 0xF0, 0x03, 0xE8, 0x04, 0x77, 0x20, 0x70, 0x70, 0x40, + 0xFE, 0x00, 0x07, 0xF0, 0x81, 0xC0, 0x70, 0x33, 0xDC, 0x20, 0x00, 0x3C, + 0x8F, 0x18, 0x30, 0x61, 0x86, 0x08, 0x00, 0x00, 0x40, 0x80, 0x0F, 0x81, + 0x83, 0x08, 0x0C, 0x8E, 0x2C, 0xC9, 0x44, 0x4A, 0x66, 0x33, 0x32, 0x99, + 0x94, 0xCC, 0xA3, 0xB9, 0x80, 0x04, 0x00, 0x18, 0x40, 0x7C, 0x00, 0x0C, + 0x03, 0x00, 0xA0, 0x68, 0x12, 0x04, 0xC3, 0x10, 0x86, 0x7F, 0x98, 0x24, + 0x0F, 0x03, 0xFC, 0xC3, 0xC3, 0xC3, 0xC3, 0xFC, 0xC3, 0xC1, 0xC1, 0xC1, + 0xC3, 0xFE, 0x3E, 0x31, 0xB0, 0x58, 0x28, 0x04, 0x02, 0x01, 0x00, 0xC1, + 0x60, 0x98, 0xC7, 0xC0, 0xFC, 0x61, 0xB0, 0x58, 0x3C, 0x1E, 0x0F, 0x07, + 0x83, 0xC1, 0xE0, 0xB0, 0xDF, 0x80, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x3E, 0x31, 0xB0, 0x58, 0x18, 0x04, + 0x02, 0x1F, 0x03, 0xC1, 0xE0, 0xD8, 0x47, 0xC0, 0xC1, 0xE0, 0xF0, 0x78, + 0x3C, 0x1F, 0xFF, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x30, 0xFF, 0xFF, + 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x42, 0x66, + 0x3C, 0xC1, 0xE1, 0xB1, 0x99, 0x8C, 0x87, 0xC3, 0x21, 0x98, 0xC6, 0x61, + 0x30, 0xD8, 0x30, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, + 0x07, 0xF0, 0xE0, 0x7E, 0x07, 0xE0, 0x7D, 0x0B, 0xD0, 0xBD, 0x0B, 0xC9, + 0x3C, 0x93, 0xC9, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC1, 0xF0, 0xF8, 0x7A, + 0x3D, 0x1E, 0x4F, 0x37, 0x8B, 0xC3, 0xE1, 0xF0, 0x78, 0x30, 0x3E, 0x31, + 0xB0, 0x58, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0xC1, 0xE0, 0x98, 0xC7, 0xC0, + 0xFE, 0x61, 0xB0, 0x58, 0x3C, 0x16, 0x1B, 0xF9, 0x80, 0xC0, 0x60, 0x30, + 0x18, 0x00, 0x3E, 0x31, 0xB0, 0x58, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0xC1, + 0xE0, 0xD8, 0xC7, 0xE0, 0x18, 0x04, 0xFE, 0x61, 0xB0, 0x58, 0x2C, 0x16, + 0x1B, 0xF9, 0x86, 0xC1, 0x60, 0xB0, 0x58, 0x30, 0x3C, 0x43, 0xC3, 0xC0, + 0x40, 0x38, 0x0E, 0x03, 0x01, 0x81, 0xC3, 0x3C, 0xFF, 0x84, 0x02, 0x01, + 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0xC1, 0xE0, + 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xD8, 0xC7, 0xC0, + 0xC0, 0xD0, 0x26, 0x09, 0x86, 0x21, 0x0C, 0x43, 0x30, 0x48, 0x12, 0x03, + 0x80, 0xC0, 0x30, 0xC3, 0x0D, 0x0C, 0x24, 0x30, 0x98, 0xE6, 0x64, 0x98, + 0x92, 0x42, 0x49, 0x09, 0x24, 0x38, 0x70, 0x61, 0x81, 0x86, 0x06, 0x18, + 0xC3, 0xA1, 0x99, 0x84, 0x83, 0xC0, 0xC0, 0x60, 0x68, 0x26, 0x31, 0x30, + 0xD8, 0x30, 0xC0, 0xD8, 0x66, 0x10, 0xCC, 0x12, 0x05, 0x80, 0xC0, 0x30, + 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xFF, 0x02, 0x06, 0x0C, 0x08, 0x18, 0x10, + 0x30, 0x60, 0x40, 0xC0, 0xFF, 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB8, 0xC0, + 0x81, 0x81, 0x02, 0x06, 0x04, 0x0C, 0x18, 0x10, 0x30, 0x20, 0x60, 0xE4, + 0x92, 0x49, 0x24, 0x92, 0x78, 0x10, 0xC2, 0x9A, 0x4F, 0x10, 0xFE, 0xCC, + 0x38, 0x8B, 0x18, 0x37, 0xF8, 0xE1, 0xE7, 0x76, 0xC1, 0x83, 0x07, 0xEC, + 0x78, 0xF0, 0xE1, 0xC3, 0x87, 0x1D, 0xE0, 0x3C, 0x8F, 0x1C, 0x08, 0x10, + 0x31, 0xA3, 0x3C, 0x06, 0x0C, 0x1B, 0xF4, 0x78, 0xE1, 0xC3, 0x87, 0x8F, + 0x1B, 0xD0, 0x38, 0x8B, 0x1C, 0x3F, 0xF0, 0x30, 0x22, 0x3E, 0x1C, 0x82, + 0x3E, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x7A, 0x8F, 0x1C, 0x38, 0x70, + 0xF1, 0xE3, 0x7E, 0x0C, 0x1C, 0x27, 0x80, 0xC1, 0x83, 0x07, 0xEC, 0x78, + 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x30, 0xF0, 0xFF, 0xFF, 0xC0, 0x33, 0x00, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC1, 0x83, 0x06, 0x3C, 0xD9, + 0x36, 0x78, 0xD9, 0x93, 0x36, 0x30, 0xFF, 0xFF, 0xFF, 0xFD, 0xEC, 0x62, + 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x30, 0xFD, + 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC6, 0x38, 0x8F, 0x1C, 0x18, 0x30, + 0x71, 0xA3, 0x38, 0xBD, 0x8F, 0x1E, 0x1C, 0x38, 0x70, 0xE3, 0xFD, 0x83, + 0x06, 0x0C, 0x00, 0x7A, 0x8F, 0x1C, 0x38, 0x70, 0xF1, 0xE3, 0x7E, 0x0C, + 0x18, 0x30, 0x60, 0xFC, 0xCC, 0xCC, 0xCC, 0xC0, 0x79, 0x9B, 0x16, 0x03, + 0x80, 0xA1, 0xE2, 0x78, 0x21, 0x3E, 0x42, 0x10, 0x84, 0x21, 0x0E, 0xC7, + 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xA3, 0x7A, 0xC3, 0x42, 0x62, 0x26, 0x24, + 0x34, 0x1C, 0x18, 0x18, 0xC6, 0x34, 0x62, 0x46, 0x26, 0xD6, 0x29, 0x42, + 0x94, 0x29, 0x43, 0x0C, 0x10, 0x80, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x18, + 0x24, 0x66, 0xC3, 0xC3, 0x42, 0x66, 0x66, 0x24, 0x24, 0x3C, 0x18, 0x18, + 0x18, 0x10, 0x30, 0x60, 0xFC, 0x31, 0x84, 0x31, 0x86, 0x30, 0xFC, 0x08, + 0x8C, 0x63, 0x18, 0x98, 0x21, 0x8C, 0x63, 0x08, 0x20, 0xFF, 0xFF, 0xFF, + 0xF0, 0xC3, 0x08, 0x42, 0x10, 0xC3, 0x31, 0x08, 0x42, 0x33, 0x00, 0x70, + 0xC4, 0xE1, 0xC0 }; + +const GFXglyph Roboto_Regular8pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' + { 4, 4, 4, 5, 1, -11 }, // 0x22 '"' + { 6, 8, 12, 10, 1, -11 }, // 0x23 '#' + { 18, 7, 15, 9, 1, -13 }, // 0x24 '$' + { 32, 10, 12, 12, 1, -11 }, // 0x25 '%' + { 47, 10, 12, 10, 0, -11 }, // 0x26 '&' + { 62, 1, 4, 3, 1, -11 }, // 0x27 ''' + { 63, 4, 17, 5, 1, -12 }, // 0x28 '(' + { 72, 4, 17, 5, 0, -12 }, // 0x29 ')' + { 81, 7, 7, 7, 0, -11 }, // 0x2A '*' + { 88, 7, 8, 9, 1, -8 }, // 0x2B '+' + { 95, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 96, 4, 1, 4, 0, -4 }, // 0x2D '-' + { 97, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 98, 6, 13, 7, 0, -11 }, // 0x2F '/' + { 108, 7, 12, 9, 1, -11 }, // 0x30 '0' + { 119, 4, 12, 9, 1, -11 }, // 0x31 '1' + { 125, 7, 12, 9, 1, -11 }, // 0x32 '2' + { 136, 7, 12, 9, 1, -11 }, // 0x33 '3' + { 147, 9, 12, 9, 0, -11 }, // 0x34 '4' + { 161, 7, 12, 9, 1, -11 }, // 0x35 '5' + { 172, 7, 12, 9, 1, -11 }, // 0x36 '6' + { 183, 7, 12, 9, 1, -11 }, // 0x37 '7' + { 194, 7, 12, 9, 1, -11 }, // 0x38 '8' + { 205, 7, 12, 9, 1, -11 }, // 0x39 '9' + { 216, 2, 9, 4, 1, -8 }, // 0x3A ':' + { 219, 2, 11, 4, 1, -8 }, // 0x3B ';' + { 222, 6, 7, 8, 1, -7 }, // 0x3C '<' + { 228, 7, 4, 9, 1, -6 }, // 0x3D '=' + { 232, 7, 7, 8, 1, -7 }, // 0x3E '>' + { 239, 7, 12, 8, 0, -11 }, // 0x3F '?' + { 250, 13, 15, 14, 1, -10 }, // 0x40 '@' + { 275, 10, 12, 10, 0, -11 }, // 0x41 'A' + { 290, 8, 12, 10, 1, -11 }, // 0x42 'B' + { 302, 9, 12, 10, 1, -11 }, // 0x43 'C' + { 316, 9, 12, 11, 1, -11 }, // 0x44 'D' + { 330, 8, 12, 9, 1, -11 }, // 0x45 'E' + { 342, 8, 12, 9, 1, -11 }, // 0x46 'F' + { 354, 9, 12, 11, 1, -11 }, // 0x47 'G' + { 368, 9, 12, 11, 1, -11 }, // 0x48 'H' + { 382, 2, 12, 5, 1, -11 }, // 0x49 'I' + { 385, 8, 12, 9, 0, -11 }, // 0x4A 'J' + { 397, 9, 12, 10, 1, -11 }, // 0x4B 'K' + { 411, 7, 12, 9, 1, -11 }, // 0x4C 'L' + { 422, 12, 12, 14, 1, -11 }, // 0x4D 'M' + { 440, 9, 12, 11, 1, -11 }, // 0x4E 'N' + { 454, 9, 12, 11, 1, -11 }, // 0x4F 'O' + { 468, 9, 12, 10, 1, -11 }, // 0x50 'P' + { 482, 9, 14, 11, 1, -11 }, // 0x51 'Q' + { 498, 9, 12, 11, 1, -11 }, // 0x52 'R' + { 512, 8, 12, 10, 1, -11 }, // 0x53 'S' + { 524, 9, 12, 9, 0, -11 }, // 0x54 'T' + { 538, 9, 12, 11, 1, -11 }, // 0x55 'U' + { 552, 10, 12, 10, 0, -11 }, // 0x56 'V' + { 567, 14, 12, 14, 0, -11 }, // 0x57 'W' + { 588, 9, 12, 10, 1, -11 }, // 0x58 'X' + { 602, 10, 12, 10, 0, -11 }, // 0x59 'Y' + { 617, 8, 12, 10, 1, -11 }, // 0x5A 'Z' + { 629, 3, 15, 4, 1, -12 }, // 0x5B '[' + { 635, 7, 13, 7, 0, -11 }, // 0x5C '\' + { 647, 3, 15, 4, 0, -12 }, // 0x5D ']' + { 653, 6, 6, 7, 0, -11 }, // 0x5E '^' + { 658, 7, 1, 7, 0, 1 }, // 0x5F '_' + { 659, 3, 2, 5, 1, -11 }, // 0x60 '`' + { 660, 7, 9, 9, 1, -8 }, // 0x61 'a' + { 668, 7, 12, 9, 1, -11 }, // 0x62 'b' + { 679, 7, 9, 9, 1, -8 }, // 0x63 'c' + { 687, 7, 12, 9, 1, -11 }, // 0x64 'd' + { 698, 7, 9, 8, 1, -8 }, // 0x65 'e' + { 706, 6, 12, 6, 0, -11 }, // 0x66 'f' + { 715, 7, 13, 9, 1, -8 }, // 0x67 'g' + { 727, 7, 12, 9, 1, -11 }, // 0x68 'h' + { 738, 2, 13, 4, 1, -12 }, // 0x69 'i' + { 742, 4, 17, 4, -1, -12 }, // 0x6A 'j' + { 751, 7, 12, 8, 1, -11 }, // 0x6B 'k' + { 762, 2, 12, 4, 1, -11 }, // 0x6C 'l' + { 765, 12, 9, 14, 1, -8 }, // 0x6D 'm' + { 779, 7, 9, 9, 1, -8 }, // 0x6E 'n' + { 787, 7, 9, 9, 1, -8 }, // 0x6F 'o' + { 795, 7, 13, 9, 1, -8 }, // 0x70 'p' + { 807, 7, 13, 9, 1, -8 }, // 0x71 'q' + { 819, 4, 9, 5, 1, -8 }, // 0x72 'r' + { 824, 7, 9, 8, 1, -8 }, // 0x73 's' + { 832, 5, 11, 6, 0, -10 }, // 0x74 't' + { 839, 7, 9, 9, 1, -8 }, // 0x75 'u' + { 847, 8, 9, 8, 0, -8 }, // 0x76 'v' + { 856, 12, 9, 12, 0, -8 }, // 0x77 'w' + { 870, 8, 9, 8, 0, -8 }, // 0x78 'x' + { 879, 8, 13, 8, 0, -8 }, // 0x79 'y' + { 892, 6, 9, 8, 1, -8 }, // 0x7A 'z' + { 899, 5, 15, 5, 0, -11 }, // 0x7B '{' + { 909, 2, 14, 4, 1, -11 }, // 0x7C '|' + { 913, 5, 15, 5, 0, -11 }, // 0x7D '}' + { 923, 9, 3, 11, 1, -5 } }; // 0x7E '~' + +const GFXfont Roboto_Regular8pt7b PROGMEM = { + (uint8_t *)Roboto_Regular8pt7bBitmaps, + (GFXglyph *)Roboto_Regular8pt7bGlyphs, + 0x20, 0x7E, 21 }; + +// Approx. 1599 bytes From ed75ccc109a56f1335db60d9a0a5abc7a22cffb3 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 15 May 2022 20:22:45 +0200 Subject: [PATCH 02/32] [AdaGFX] Fix typos in #ifdef --- src/src/Helpers/AdafruitGFX_helper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 3db5c60b3..95586fc8d 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -52,12 +52,12 @@ # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO # include "src/Static/Fonts/Roboto_Regular16pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO -# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED # include "src/Static/Fonts/RobotoCondensed_Regular16pt7b.h" -# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO -# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED +# ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO # include "src/Static/Fonts/RobotoMono_Regular16pt7b.h" -# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO +# endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_18PT_INCLUDED # include "src/Static/Fonts/whitrabt18pt7b.h" From 20ce9609c43658eb338cf2f2364ee11b42b7e7ca Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 15 May 2022 21:11:00 +0200 Subject: [PATCH 03/32] [AdaGFX] Small documentation updates --- docs/source/Plugin/AdaGFX_commands.repl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/source/Plugin/AdaGFX_commands.repl b/docs/source/Plugin/AdaGFX_commands.repl index 877638ddd..a463a145e 100644 --- a/docs/source/Plugin/AdaGFX_commands.repl +++ b/docs/source/Plugin/AdaGFX_commands.repl @@ -9,6 +9,8 @@ * If a text has comma's or spaces, then it should be 'wrapped' in either double quotes ``^"``, single quotes ``^'`` or back-ticks ``^```. * For ``color`` arguments, see how colors can be defined in the ``txc`` subcommand description. + + * Commands and subcommands are not case-sensitive. " " ``,clear[,]`` @@ -67,6 +69,8 @@ ``,txs,`` "," Set font scaling option. Only values from 0 to 10 are accepted. 0 assumes 1 by default. + + Some display types may limit or extend the maximum accepted size. " " ``,txtfull,,,,,,`` @@ -101,7 +105,7 @@ * *sevenseg18* A somewhat less large 7-segment 16 * 34 font * *freesans* A sans-serif 10 * 21 font - Usually disabled fonts: (can be enabled in a Custom build, default included in the MAX builds) + Usually disabled fonts: (can be enabled in a Custom build, default enabled in the MAX builds) * *angelina8prop* A proportional, handwriting, 6 * 16 font * *novamono8pt* A modern 9 * 16 font @@ -131,7 +135,7 @@ * *robotocond12pt* A modern 13 * 18 font (Roboto Condensed, proportionally spaced) * *robotocond16pt* A modern 16 * 20 font (Roboto Condensed, proportionally spaced) - NB: Roboto is used as the default Android font since Android 4.1. + NB: Roboto is used as the default Android font since Android 4.1, and very readable, even when using small fonts on a small display. " " ``,l,,,,,`` From 0ce1a1efbe2e75243a693228f2e3a5cd182dbeb4 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 1 May 2022 21:57:26 +0200 Subject: [PATCH 04/32] [AdaGFX] Add support for `btn` subcommand to draw button-like objects (cherry picked from commit 3546699cea6216b58b5683441d702ababd194dba) --- src/src/Helpers/AdafruitGFX_helper.cpp | 327 ++++++++++++++++++++++++- src/src/Helpers/AdafruitGFX_helper.h | 68 ++++- 2 files changed, 376 insertions(+), 19 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 1b6cad5c9..caf6576c7 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -8,6 +8,7 @@ # if defined(FEATURE_SD) && defined(ADAGFX_ENABLE_BMP_DISPLAY) # include # endif // if defined(FEATURE_SD) && defined(ADAGFX_ENABLE_BMP_DISPLAY) +# include # if ADAGFX_FONTS_INCLUDED # include "src/Static/Fonts/Seven_Segment24pt7b.h" @@ -99,6 +100,49 @@ const __FlashStringHelper* toString(AdaGFXColorDepth colorDepth) { return F("None"); } +# if ADAGFX_ENABLE_BUTTON_DRAW + +/****************************************************************************************** + * get the display text for a button type enum value + *****************************************************************************************/ +const __FlashStringHelper* toString(Button_type_e button) { + switch (button) { + case Button_type_e::None: return F("None"); + case Button_type_e::Square: return F("Square"); + case Button_type_e::Rounded: return F("Rounded"); + case Button_type_e::Circle: return F("Circle"); + case Button_type_e::ArrowLeft: return F("Arrow, left"); + case Button_type_e::ArrowUp: return F("Arrow, up"); + case Button_type_e::ArrowRight: return F("Arrow, right"); + case Button_type_e::ArrowDown: return F("Arrow, down"); + case Button_type_e::Button_MAX: break; + } + return F("Unsupported!"); +} + +/****************************************************************************************** + * get the display text for a button layout enum value + *****************************************************************************************/ +const __FlashStringHelper* toString(Button_layout_e layout) { + switch (layout) { + case Button_layout_e::CenterAligned: return F("Centered"); + case Button_layout_e::LeftAligned: return F("Left-aligned"); + case Button_layout_e::TopAligned: return F("Top-aligned"); + case Button_layout_e::RightAligned: return F("Right-aligned"); + case Button_layout_e::BottomAligned: return F("Bottom-aligned"); + case Button_layout_e::LeftTopAligned: return F("Left-Top-aligned"); + case Button_layout_e::RightTopAligned: return F("Right-Top-aligned"); + case Button_layout_e::RightBottomAligned: return F("Right-Bottom-aligned"); + case Button_layout_e::LeftBottomAligned: return F("Left-Bottom-aligned"); + case Button_layout_e::NoCaption: return F("No Caption"); + case Button_layout_e::Bitmap: return F("Bitmap image"); + case Button_layout_e::Alignment_MAX: break; + } + return F("Unsupported!"); +} + +# endif // if ADAGFX_ENABLE_BUTTON_DRAW + /***************************************************************************************** * Show a selector for all available 'Text print mode' options, for use in PLUGIN_WEBFORM_LOAD ****************************************************************************************/ @@ -261,7 +305,7 @@ void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, /**************************************************************************** * AdaGFXparseTemplate: Replace variables and adjust unicode special characters to Adafruit font ***************************************************************************/ -String AdaGFXparseTemplate(String & tmpString, +String AdaGFXparseTemplate(const String & tmpString, uint8_t lineSize, AdafruitGFX_helper *gfxHelper) { // Änderung WDS: Tabelle vorerst Abgeschaltet !!!! @@ -469,7 +513,10 @@ AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, _useValidation(useValidation), _textBackFill(textBackFill) { _display = _tft; - addLog(LOG_LEVEL_INFO, F("AdaGFX_helper: TFT Init.")); + String log = F("AdaGFX_helper: TFT Init. "); + + log += getFeatures(); + addLog(LOG_LEVEL_INFO, log); initialize(); } @@ -493,6 +540,8 @@ void AdafruitGFX_helper::initialize() { log += static_cast(_colorDepth); log += F(", trigger: "); log += _trigger; + log += F(", "); + log += getFeatures(); addLogMove(ADAGFX_LOG_LEVEL, log); } # endif // ifndef BUILD_NO_DEBUG @@ -509,6 +558,24 @@ void AdafruitGFX_helper::initialize() { } } +String AdafruitGFX_helper::getFeatures() { + String log = F("Features:"); + + # if (defined(ADAGFX_USE_ASCIITABLE) && ADAGFX_USE_ASCIITABLE) + log += F(" asciitable,"); + # endif // if (defined(ADAGFX_USE_ASCIITABLE) && ADAGFX_USE_ASCIITABLE) + # if (defined(ADAGFX_ENABLE_EXTRA_CMDS) && ADAGFX_ENABLE_EXTRA_CMDS) + log += F(" lm/lmr,"); + # endif // if (defined(ADAGFX_ENABLE_EXTRA_CMDS) && ADAGFX_ENABLE_EXTRA_CMDS) + # if (defined(ADAGFX_ENABLE_BMP_DISPLAY) && ADAGFX_ENABLE_BMP_DISPLAY) + log += F(" bmp,"); + # endif // if (defined(ADAGFX_ENABLE_BMP_DISPLAY) && ADAGFX_ENABLE_BMP_DISPLAY) + # if (defined(ADAGFX_ENABLE_BUTTON_DRAW) && ADAGFX_ENABLE_BUTTON_DRAW) + log += F(" btn,"); + # endif // if (defined(ADAGFX_ENABLE_BUTTON_DRAW) && ADAGFX_ENABLE_BUTTON_DRAW) + return log; +} + /**************************************************************************** * getCursorXY: get the current (text) cursor coordinates, either in pixels or cols/rows, depending on related setting ***************************************************************************/ @@ -538,13 +605,14 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (!cmd.equals(_trigger) || subcommand.isEmpty()) { return success; } // Only support own trigger, and at least a non=empty subcommand String log; - String sParams[ADAGFX_PARSE_MAX_ARGS + 1]; - int nParams[ADAGFX_PARSE_MAX_ARGS + 1]; - int argCount = 0; - bool loop = true; + std::vector sParams; + std::vector nParams; + int argCount = 0; + bool loop = true; - while (argCount <= ADAGFX_PARSE_MAX_ARGS && loop) { - sParams[argCount] = parseStringKeepCase(string, argCount + 3); // 0-offset + 1st and 2nd argument used by trigger/subcommand + while (loop) { // Process all provided arguments + sParams.push_back(parseStringKeepCase(string, argCount + 3)); // 0-offset + 1st and 2nd argument used by trigger/subcommand + nParams.push_back(0); validIntFromString(sParams[argCount], nParams[argCount]); loop = !sParams[argCount].isEmpty(); @@ -561,6 +629,15 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (loop) { argCount++; } } + { // Guarantee minimal nParams/sParams size + int args = argCount; + + while (args <= ADAGFX_PARSE_MAX_ARGS) { + sParams.push_back(EMPTY_STRING); + nParams.push_back(0); + args++; + } + } success = true; // If we get this far, we'll flip the flag if something wrong is found # ifndef BUILD_NO_DEBUG @@ -1265,6 +1342,240 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } } # endif // if ADAGFX_ENABLE_BMP_DISPLAY + # if ADAGFX_ENABLE_BUTTON_DRAW + else if (subcommand.equals(F("btn")) && (argCount >= 7) && (nParams[6] != 0)) + { // btn,state,x,y,w,h,id,type[,ONclr,OFFclr,Captionclr,fontscale,ONcaption,OFFcapt,Borderclr,DisabClr,DisabCaptclr],TaskIndex,Group,SelGrp,objectname + // ev: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17,18,19,20 + // nP: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16,17,18,19 + // : Draw a button + // state: -2 = disabled, -1 = initial (off), 0 = off, 1 = on + // type & 0x0F: 0 = none, < 0 = clear area, 1 = rectangle, 2 = rounded rect., 3 = circle, + // type & 0xF0 = CenterAligned, LeftAligned, TopAligned, RightAligned, BottomAligned, LeftTopAligned, RightTopAligned, + // RightBottomAligned, LeftBottomAligned, NoCaption + // (*clr = color, TaskIndex, Group and SelGrp are ignored) + # if ADAGFX_ARGUMENT_VALIDATION + + if (invalidCoordinates(nParams[1], nParams[2]) || + invalidCoordinates(nParams[1] + nParams[3], nParams[2] + nParams[4])) { + success = false; + } else + # endif // if ADAGFX_ARGUMENT_VALIDATION + { + // All checked out OK + // Default values + uint16_t onColor = ADAGFX_GREEN; + uint16_t offColor = ADAGFX_RED; + uint16_t captionColor = ADAGFX_WHITE; + uint8_t fontScale = 2; + uint16_t borderColor = ADAGFX_WHITE; + uint16_t disabledColor = 0x9410; + uint16_t disabledCaptionColor = 0x5A69; + + if (!sParams[7].isEmpty()) { onColor = AdaGFXparseColor(sParams[7], _colorDepth); } + + if (!sParams[8].isEmpty()) { offColor = AdaGFXparseColor(sParams[8], _colorDepth); } + + if (!sParams[9].isEmpty()) { captionColor = AdaGFXparseColor(sParams[9], _colorDepth); } + + if (nParams[12] > 0) { fontScale = nParams[12]; } + + if (!sParams[13].isEmpty()) { borderColor = AdaGFXparseColor(sParams[13], _colorDepth); } + + if (!sParams[14].isEmpty()) { disabledColor = AdaGFXparseColor(sParams[14], _colorDepth); } + + if (!sParams[15].isEmpty()) { disabledCaptionColor = AdaGFXparseColor(sParams[15], _colorDepth); } + + uint16_t fillColor = onColor; + uint16_t textColor = captionColor; + bool clearArea = nParams[6] < 0; + nParams[6] = std::abs(nParams[6]); + + // Check state: -2, -1, 0, 1 to select used colors + if ((nParams[0] == 0) || (nParams[0] == -1)) { + fillColor = offColor; + } else if (nParams[0] == -2) { + fillColor = disabledColor; + textColor = disabledCaptionColor; + } else if (clearArea) { + fillColor = _bgcolor; // + borderColor = _bgcolor; + } + + if ((static_cast(nParams[6] & 0x0F) != Button_type_e::None) || + clearArea) { + _display->fillRect(nParams[1], nParams[2], nParams[3], nParams[4], _bgcolor); + } + + // Check button-type bits (mask: 0x0F) to draw correct shape + if (!clearArea) { + switch (static_cast(nParams[6] & 0x0F)) { + case Button_type_e::Square: // Rectangle + { + _display->fillRect(nParams[1], nParams[2], nParams[3], nParams[4], fillColor); + _display->drawRect(nParams[1], nParams[2], nParams[3], nParams[4], borderColor); + break; + } + case Button_type_e::Rounded: // Rounded Rectangle + { + int16_t radius = (nParams[3] + nParams[4]) / 20; // 10 % corner radius + _display->fillRoundRect(nParams[1], nParams[2], nParams[3], nParams[4], radius, fillColor); + _display->drawRoundRect(nParams[1], nParams[2], nParams[3], nParams[4], radius, borderColor); + break; + } + case Button_type_e::Circle: // Circle + { + int16_t radius = (nParams[3] + nParams[4]) / 4; // average radius + _display->fillCircle(nParams[1] + (nParams[3] / 2), nParams[2] + (nParams[4] / 2), radius, fillColor); + _display->drawCircle(nParams[1] + (nParams[3] / 2), nParams[2] + (nParams[4] / 2), radius, borderColor); + break; + } + case Button_type_e::ArrowLeft: + { // draw: left-center, right-top, right-bottom + _display->fillTriangle(nParams[1], nParams[2] + nParams[4] / 2, nParams[1] + nParams[3], nParams[2], + nParams[1] + nParams[3], nParams[2] + nParams[4], fillColor); + _display->drawTriangle(nParams[1], nParams[2] + nParams[4] / 2, nParams[1] + nParams[3], nParams[2], + nParams[1] + nParams[3], nParams[2] + nParams[4], borderColor); + break; + } + case Button_type_e::ArrowUp: + { // draw: top-center, right-bottom, left-bottom + _display->fillTriangle(nParams[1] + nParams[3] / 2, nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4], + nParams[1], nParams[2] + nParams[4], fillColor); + _display->drawTriangle(nParams[1] + nParams[3] / 2, nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4], + nParams[1], nParams[2] + nParams[4], borderColor); + break; + } + case Button_type_e::ArrowRight: + { // draw: left-top, right-center, left-bottom + _display->fillTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4] / 2, + nParams[1], nParams[2] + nParams[4], fillColor); + _display->drawTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4] / 2, + nParams[1], nParams[2] + nParams[4], borderColor); + break; + } + case Button_type_e::ArrowDown: + { // draw: left-top, right-top, bottom-center + _display->fillTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2], + nParams[1] + nParams[3] / 2, nParams[2] + nParams[4], fillColor); + _display->drawTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2], + nParams[1] + nParams[3] / 2, nParams[2] + nParams[4], borderColor); + break; + } + case Button_type_e::None: + case Button_type_e::Button_MAX: + break; + } + } + + // Display caption? (or bitmap) + if (!clearArea && + !(static_cast(nParams[6] & 0xF0) == Button_layout_e::NoCaption)) { + int16_t x1, y1; + uint16_t w1, h1, w2, h2; + String newString; + + // Determine alignment parameters + if (nParams[0] == 1) { + newString = sParams[11].isEmpty() ? sParams[5] : sParams[11]; + } else { + newString = sParams[12].isEmpty() ? sParams[5] : sParams[12]; + } + newString = AdaGFXparseTemplate(newString, 20); + + if ((nParams[10] > 0) && (nParams[10] <= 10)) { _display->setTextSize(nParams[10]); } // set scaling + _display->getTextBounds(newString, 0, 0, &x1, &y1, &w1, &h1); // get caption length and height in pixels + _display->getTextBounds(F(" "), 0, 0, &x1, &y1, &w2, &h2); // measure space width for little margins + + // Check button-alignment bits (mask 0xF0) for caption placement, modifies the x/y arguments passed! + // Little margin is: from left/right: half of the width of a space, from top/bottom: half of height of the font used + Button_layout_e buttonLayout = static_cast(nParams[6] & 0xF0); + + switch (buttonLayout) { + case Button_layout_e::CenterAligned: + nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically + nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + break; + case Button_layout_e::LeftAligned: + nParams[1] += w2 / 2; // A little margin from left + nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + break; + case Button_layout_e::TopAligned: + nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically + nParams[2] += h1 / 2; // A little margin from top + break; + case Button_layout_e::RightAligned: + nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin + nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + break; + case Button_layout_e::BottomAligned: + nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically + nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + break; + case Button_layout_e::LeftTopAligned: + nParams[1] += w2 / 2; // A little margin from left + nParams[2] += h1 / 2; // A little margin from top + break; + case Button_layout_e::RightTopAligned: + nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin + nParams[2] += h1 / 2; // A little margin from top + break; + case Button_layout_e::RightBottomAligned: + nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin + nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + break; + case Button_layout_e::LeftBottomAligned: + nParams[1] += w2 / 2; // A little margin from left + nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + break; + case Button_layout_e::Bitmap: + { // Use ON/OFF caption to specify (full) bitmap filename + # if ADAGFX_ENABLE_BMP_DISPLAY + + if (!newString.isEmpty()) { + int offX = 0; // Allow optional arguments for x and y offset values, usage: + int offY = 0; // [x,[y,]]filename.bmp + + if (newString.indexOf(',') > -1) { + String tmp = parseString(newString, 1); + validIntFromString(tmp, offX); + newString = parseStringToEndKeepCase(newString, 2); + + if (newString.indexOf(',') > -1) { + tmp = parseString(newString, 1); + validIntFromString(tmp, offY); + newString = parseStringToEndKeepCase(newString, 2); + } + } + success = showBmp(newString, nParams[1] + offX, nParams[2] + offY); + } else + # endif // if ADAGFX_ENABLE_BMP_DISPLAY + { + success = false; + } + break; + } + case Button_layout_e::NoCaption: + case Button_layout_e::Alignment_MAX: + break; + } + + if ((buttonLayout != Button_layout_e::NoCaption) && + (buttonLayout != Button_layout_e::Bitmap)) { + // Set position and colors, then print + _display->setCursor(nParams[1], nParams[2]); + _display->setTextColor(captionColor, captionColor); // transparent bg results in button color + _display->print(newString); + + // restore colors + _display->setTextColor(_fgcolor, _bgcolor); + } + + // restore font scaling + if ((nParams[10] > 0) && (nParams[10] <= 10)) { _display->setTextSize(_fontscaling); } + } + } + } + # endif // if ADAGFX_ENABLE_BUTTON_DRAW else { success = false; } diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 7485b6ec1..dba0426a7 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -22,28 +22,31 @@ # include "../Helpers/ESPEasy_Storage.h" # include "../ESPEasyCore/ESPEasy_Log.h" -# define ADAGFX_PARSE_MAX_ARGS 7 // Maximum number of arguments needed and supported (corrected) +# define ADAGFX_PARSE_MAX_ARGS 7 // Maximum number of arguments needed and supported (corrected) # ifndef ADAGFX_ARGUMENT_VALIDATION -# define ADAGFX_ARGUMENT_VALIDATION 1 // Validate command arguments +# define ADAGFX_ARGUMENT_VALIDATION 1 // Validate command arguments # endif // ifndef ADAGFX_ARGUMENT_VALIDATION # ifndef ADAGFX_USE_ASCIITABLE -# define ADAGFX_USE_ASCIITABLE 1 // Enable 'asciitable' command (useful for debugging/development) +# define ADAGFX_USE_ASCIITABLE 1 // Enable 'asciitable' command (useful for debugging/development) # endif // ifndef ADAGFX_USE_ASCIITABLE # ifndef ADAGFX_SUPPORT_7COLOR -# define ADAGFX_SUPPORT_7COLOR 1 // Do we support 7-Color displays? +# define ADAGFX_SUPPORT_7COLOR 1 // Do we support 7-Color displays? # endif // ifndef ADAGFX_SUPPORT_7COLOR # ifndef ADAGFX_FONTS_INCLUDED -# define ADAGFX_FONTS_INCLUDED 1 // 3 extra fonts, also controls enable/disable of below 8pt/12pt fonts +# define ADAGFX_FONTS_INCLUDED 1 // 3 extra fonts, also controls enable/disable of below 8pt/12pt fonts # endif // ifndef ADAGFX_FONTS_INCLUDED # ifndef ADAGFX_PARSE_SUBCOMMAND -# define ADAGFX_PARSE_SUBCOMMAND 1 // Enable parsing of subcommands (pre/postfix below) to be executed by the helper +# define ADAGFX_PARSE_SUBCOMMAND 1 // Enable parsing of subcommands (pre/postfix below) to be executed by the helper # endif // ifndef ADAGFX_PARSE_SUBCOMMAND # ifndef ADAGFX_ENABLE_EXTRA_CMDS -# define ADAGFX_ENABLE_EXTRA_CMDS 1 // Enable extra subcommands like lm (line-multi) and lmr (line-multi, relative) +# define ADAGFX_ENABLE_EXTRA_CMDS 1 // Enable extra subcommands like lm (line-multi) and lmr (line-multi, relative) # endif // ifndef ADAGFX_ENABLE_EXTRA_CMDS # ifndef ADAGFX_ENABLE_BMP_DISPLAY -# define ADAGFX_ENABLE_BMP_DISPLAY 1 // Enable subcommands for displaying .bmp files on supported displays (color) +# define ADAGFX_ENABLE_BMP_DISPLAY 1 // Enable subcommands for displaying .bmp files on supported displays (color) # endif // ifndef ADAGFX_ENABLE_BMP_DISPLAY +# ifndef ADAGFX_ENABLE_BUTTON_DRAW +# define ADAGFX_ENABLE_BUTTON_DRAW 1 // Enable subcommands for displaying button-like shapes +# endif // ifndef ADAGFX_ENABLE_BUTTON_DRAW // # define ADAGFX_FONTS_EXTRA_8PT_INCLUDED // 8 extra 8pt fonts, should probably only be enabled in a private custom build, adds ~15.4 kB // # define ADAGFX_FONTS_EXTRA_12PT_INCLUDED // 9 extra 12pt fonts, should probably only be enabled in a private custom build, adds ~28 kB @@ -101,6 +104,9 @@ // # ifdef ADAGFX_ENABLE_BMP_DISPLAY // # undef ADAGFX_ENABLE_BMP_DISPLAY // # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY +// # ifdef ADAGFX_ENABLE_BUTTON_DRAW +// # undef ADAGFX_ENABLE_BUTTON_DRAW +// # endif // ifdef ADAGFX_ENABLE_BUTTON_DRAW # endif // ifdef LIMIT_BUILD_SIZE # ifdef PLUGIN_SET_MAX // Include all fonts in MAX builds @@ -199,7 +205,45 @@ enum class AdaGFXColorDepth : uint16_t { FullColor = 65535u // 65535 colors (max. supported by RGB565) }; -class AdafruitGFX_helper; // Forward declaration +# if ADAGFX_ENABLE_BUTTON_DRAW + +// Only bits 0..3 can be used, masked with: 0x0F +// stored combined with Button_layout_e value +enum class Button_type_e : uint8_t { + None = 0x00, + Square = 0x01, + Rounded = 0x02, + Circle = 0x03, + ArrowLeft = 0x04, + ArrowUp = 0x05, + ArrowRight = 0x06, + ArrowDown = 0x07, + Button_MAX // must be last value in enum, max possible values: 16 +}; + +// Only bits 4..7 can be used, masked with: 0xF0 +// stored combined with Button_type_e value +enum class Button_layout_e : uint8_t { + CenterAligned = 0x00, + LeftAligned = 0x10, + TopAligned = 0x20, + RightAligned = 0x30, + BottomAligned = 0x40, + LeftTopAligned = 0x50, + RightTopAligned = 0x60, + RightBottomAligned = 0x70, + LeftBottomAligned = 0x80, + NoCaption = 0x90, + Bitmap = 0xA0, + Alignment_MAX = 11u // options-count +}; + +const __FlashStringHelper* toString(Button_type_e button); +const __FlashStringHelper* toString(Button_layout_e layout); + +# endif // if ADAGFX_ENABLE_BUTTON_DRAW + +class AdafruitGFX_helper; // Forward declaration // Some generic AdafruitGFX_helper support functions const __FlashStringHelper* toString(AdaGFXTextPrintMode mode); @@ -235,7 +279,7 @@ void AdaGFXFormDisplayButton(const __FlashStringHelper *buttonPinId, void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, uint8_t fontScaling, uint8_t maxScale = 10); -String AdaGFXparseTemplate(String & tmpString, +String AdaGFXparseTemplate(const String & tmpString, uint8_t lineSize, AdafruitGFX_helper *gfxHelper = nullptr); uint16_t AdaGFXparseColor(String & s, @@ -280,7 +324,9 @@ public: # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY virtual ~AdafruitGFX_helper() {} - bool processCommand(const String& string); // Parse the string for recognized commands and apply them on the graphics display + String getFeatures(); + + bool processCommand(const String& string); // Parse the string for recognized commands and apply them on the graphics display void printText(const char *string, int16_t X, From 80e0ca1729c427089aeed6f9dcb6a58146b02c0e Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 4 Jun 2022 12:47:12 +0200 Subject: [PATCH 05/32] [AdaGFX] Improve btn subcommand, slim down bin size, other minor improvements (cherry picked from commit 8deee266b67a207e5c9c308692965126455bc62a) --- docs/source/Plugin/AdaGFX_commands.repl | 44 ++++ src/src/CustomBuild/define_plugin_sets.h | 3 - src/src/Helpers/AdafruitGFX_helper.cpp | 319 ++++++++++++++--------- src/src/Helpers/AdafruitGFX_helper.h | 43 ++- 4 files changed, 282 insertions(+), 127 deletions(-) diff --git a/docs/source/Plugin/AdaGFX_commands.repl b/docs/source/Plugin/AdaGFX_commands.repl index a463a145e..67c8eb96d 100644 --- a/docs/source/Plugin/AdaGFX_commands.repl +++ b/docs/source/Plugin/AdaGFX_commands.repl @@ -239,3 +239,47 @@ The file can be read from SD-card, when available, and the bmp file is not found on the internal file storage. " + " + ``,btn,,,,,,,,,,,,,,,,,,,,,`` + "," + As a companion to the ESPEasy_TouchHelper, the AdafruitGFX_helper takes care of drawing button objects via this subcommand. + + All arguments *must* be provided, though most can be empty, but all separator-commas must still be provided. + + * ``state`` : 0 = off, 1 = on, -1 = off + disabled, -2 = on + disabled. + + * ``mode`` : 0 = normal, -1 = initial, -2 = clear button area. + + * ``x,y,w,h`` : button left-top coordinate, width and height. + + * ``id`` : object id nr. Not used for drawing the button, but passed to be used in rules from the ESPEasy_TouchHelper. + + * ``type`` : combination (addition/and operation) of ``button type`` (bits 0..3) and ``button layout`` (bits 4..7), when negative (multiplied by -1) will clear the button area. + + * ``button types`` : 0 = none, 0x01 = rectangle, 0x02 = rounded rectangle, 0x03 = circle, 0x04 = left arrow, 0x05 = up arrow, 0x06 = right arrow, 0x07 = down arrow. + + * ``button layouts`` : 0 = center aligned, 0x10 = left aligned, 0x20 = top aligned, 0x30 = right aligned, 0x40 = bottom aligned, 0x50 = left top aligned, 0x60 = right top aligned, 0x70 = right bottom aligned, 0x80 = left bottom aligned, 0x90 = no caption, 0xA0 = ``bitmap`` (see ``ONcaption`` / ``OFFcaption``). + + * ``ONcolor`` / ``OFFcolor`` : fill color when button state is on or off and enabled. + + * ``CaptionColor`` : color used for caption text. + + * ``fontsize`` : size of the font for writing the caption, range 1..10. + + * ``ONcaption`` / ``OFFcaption`` : The caption to show when state is on or off, when empty the objectname will be used. For ``button layout`` = ``bitmap`` a .bmp filename should be entered, that is available on the filesystem, optionally *prefixed* with an ``x`` and ``y`` offset, in pixels, to enable f.e. drawing a small bitmap centered on a button. The format with these optional arguments is: ``[[,],]bmpfile.bmp`` + + * If a caption contains space(s), comma(s) or quote(s), it *must* be quoted with a different quote (double/single/backtick). + * Captions can use variables as available in rules, like plugin values via ``[taskname#valuename]``, ``%vNN%``, ``%%`` and ``{}`` formats. + + * ``BorderColor``, ``DisabledColor``, ``DisabledCaptionColor`` : A separate border color can be specified, and a fill-color and caption color for disabled buttons. + + * ``TaskIndex`` : The Task number for the display the button is to be drawn on. Not used, but passed to be used in rules from the ESPEasy_TouchHelper. + + * ``Group`` : The group this button is a member of. Not used for drawing the button, but passed to be used in rules from the ESPEasy_TouchHelper. + + * ``SelectGroup`` : The group that will be activated by this button. Not used for drawing the button, but passed to be used in rules from the ESPEasy_TouchHelper. + + * ``objectname`` : **Required** The name of the button object, will be used as a caption if no ``ONcaption`` and/or ``OFFcaption`` are provided. *Not required* if both an ``ONcaption`` and ``OFFcaption`` are provided. + + NB: This command wil only *draw* a button, it will not respond to any action. The action is usually provided by a touch screen like :ref:`P099_page` and :ref:`P123_page`. + " diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 11f3d611f..d6af1b49c 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1250,9 +1250,6 @@ To create/register a plugin, you have to : #if !defined(LIMIT_BUILD_SIZE) && (defined(ESP8266) || !(ESP_IDF_VERSION_MAJOR > 3)) #define LIMIT_BUILD_SIZE // Reduce buildsize (on ESP8266 / pre-IDF4.x) to fit in all Display plugins #endif - #ifndef USES_ADAFRUITGFX_HELPER - #define USES_ADAFRUITGFX_HELPER - #endif #ifndef USES_P012 #define USES_P012 // LCD #endif diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index caf6576c7..620c36e88 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -219,7 +219,9 @@ void AdaGFXFormRotation(const __FlashStringHelper *id, void AdaGFXFormTextBackgroundFill(const __FlashStringHelper *id, uint8_t selectedIndex) { addFormCheckBox(F("Background-fill for text"), id, selectedIndex); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("Fill entire line-height with background color.")); + # endif // ifndef LIMIT_BUILD_SIZE } /***************************************************************************************** @@ -228,7 +230,9 @@ void AdaGFXFormTextBackgroundFill(const __FlashStringHelper *id, void AdaGFXFormTextColRowMode(const __FlashStringHelper *id, bool selectedState) { addFormCheckBox(F("Text Coordinates in col/row"), id, selectedState); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("Unchecked: Coordinates in pixels. Applies only to 'txp', 'txz' and 'txtfull' subcommands.")); + # endif // ifndef LIMIT_BUILD_SIZE } /***************************************************************************************** @@ -237,7 +241,9 @@ void AdaGFXFormTextColRowMode(const __FlashStringHelper *id, void AdaGFXFormOnePixelCompatibilityOption(const __FlashStringHelper *id, uint8_t selectedIndex) { addFormCheckBox(F("Use -1px offset for txp & txtfull"), id, selectedIndex); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("This is for compatibility with the original plugin implementation.")); + # endif // ifndef LIMIT_BUILD_SIZE } /***************************************************************************************** @@ -254,8 +260,12 @@ void AdaGFXFormForeAndBackColors(const __FlashStringHelper *foregroundId, addFormTextBox(F("Foreground color"), foregroundId, color, 11); color = AdaGFXcolorToString(backgroundColor, colorDepth); addFormTextBox(F("Background color"), backgroundId, color, 11); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("Use Color name, '#RGB565' (# + 1..4 hex nibbles) or '#RRGGBB' (# + 6 hex nibbles RGB color).")); addFormNote(F("NB: Colors stored as RGB565 value!")); + # else // ifndef LIMIT_BUILD_SIZE + addFormNote(F("Use Color name, # + 1..4 hex RGB565 or # + 6 hex nibbles RGB color.")); + # endif // ifndef LIMIT_BUILD_SIZE } /***************************************************************************************** @@ -308,9 +318,6 @@ void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, String AdaGFXparseTemplate(const String & tmpString, uint8_t lineSize, AdafruitGFX_helper *gfxHelper) { - // Änderung WDS: Tabelle vorerst Abgeschaltet !!!! - // Perform some specific changes for LCD display - // https://www.letscontrolit.com/forum/viewtopic.php?t=2368 # if ADAGFX_PARSE_SUBCOMMAND String result = tmpString; @@ -412,6 +419,23 @@ String AdaGFXparseTemplate(const String & tmpString, const char quart[3] = { 0xc2, 0xbc, 0 }; // Unicode quart 1/4 symbol const char quart_ascii[2] = { 0xac, 0 }; // quart 1/4 symbol result.replace(quart, quart_ascii); + + const char sup2[3] = { 0xc2, 0xb2, 0 }; // Unicode superscript 2 symbol + const char sup2_ascii[2] = { 0xfc, 0 }; // superscript 2 symbol + result.replace(sup2, sup2_ascii); + + // Unsupported characters, replace by something useful + const char sup1[3] = { 0xc2, 0xb9, 0 }; // Unicode superscript 1 symbol + const char sup1_ascii[2] = { 0x31, 0 }; // regular 1 (missing from font) + result.replace(sup1, sup1_ascii); + + const char sup3[3] = { 0xc2, 0xb3, 0 }; // Unicode superscript 3 symbol + const char sup3_ascii[2] = { 0x33, 0 }; // regular 3 (missing from font) + result.replace(sup3, sup3_ascii); + + const char frac34[3] = { 0xc2, 0xbe, 0 }; // Unicode fraction 3/4 symbol + const char frac34_ascii[2] = { 0x5c, 0 }; // regular \ (missing from font) + result.replace(frac34, frac34_ascii); delay(0); } @@ -449,11 +473,42 @@ String AdaGFXparseTemplate(const String & tmpString, result.replace(divide_uni, divide_ascii); const char umlaut_sz_uni[3] = { 0xc3, 0x9f, 0 }; // Unicode Umlaute sz - const char umlaut_sz_ascii[2] = { 0xe0, 0 }; // Umlaute + const char umlaut_sz_ascii[2] = { 0xe0, 0 }; // Umlaute B result.replace(umlaut_sz_uni, umlaut_sz_ascii); + + // Unsupported characters, replace by something useful + const char times[3] = { 0xc3, 0x97, 0 }; // Unicode multiplication symbol + const char times_ascii[2] = { 0x78, 0 }; // regular x (missing from font) + result.replace(times, times_ascii); delay(0); } + // Handle '{0xNN...}' hex values in template, where NN can be any hex value from 01..FF (practically 20..FF). + int16_t hexPrefix = 0; + int16_t hexPostfix; + const String hexSeparators = F(" ,.:;-"); + + while (((hexPrefix = result.indexOf(F("{0x"), hexPrefix)) > -1) && + ((hexPostfix = result.indexOf('}', hexPrefix)) > -1)) { + String replace; + + for (int16_t ci = hexPrefix + 3; ci < hexPostfix - 1; ci += 2) { // Multiple of 2 only + uint32_t hexValue = hexToUL(result.substring(ci, ci + 2)); + + if (hexValue > 0) { + replace += static_cast(hexValue); + } + + while (hexSeparators.indexOf(result.substring(ci + 2, ci + 3)) > -1 && ci < hexPostfix) { + ci++; + } + } + + if (!replace.isEmpty()) { + result.replace(result.substring(hexPrefix, hexPostfix + 1), replace); + } + } + for (uint16_t l = result.length(); l > 0 && isSpace(result[l - 1]); l--) { // Right-trim result.remove(l - 1); } @@ -1343,57 +1398,64 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } # endif // if ADAGFX_ENABLE_BMP_DISPLAY # if ADAGFX_ENABLE_BUTTON_DRAW - else if (subcommand.equals(F("btn")) && (argCount >= 7) && (nParams[6] != 0)) - { // btn,state,x,y,w,h,id,type[,ONclr,OFFclr,Captionclr,fontscale,ONcaption,OFFcapt,Borderclr,DisabClr,DisabCaptclr],TaskIndex,Group,SelGrp,objectname - // ev: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17,18,19,20 - // nP: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16,17,18,19 + else if (subcommand.equals(F("btn")) && (argCount >= 8) && (nParams[7] != 0)) + { // btn,state,m,x,y,w,h,id,type[,ONclr,OFFclr,Captionclr,fontscale,ONcaption,OFFcapt,Borderclr,DisabClr,DisabCaptclr],TaskIndex,Group,SelGrp,objectname + // ev: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17,18,19,20,21 + // nP: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16,17,18,19,20 // : Draw a button - // state: -2 = disabled, -1 = initial (off), 0 = off, 1 = on - // type & 0x0F: 0 = none, < 0 = clear area, 1 = rectangle, 2 = rounded rect., 3 = circle, + // m=mode: -2 = disabled, -1 = initial, 0 = default + // state: 0 = off, 1 = on, -2 = off + disabled, -1 = on + disabled + // id: < 0 = clear area + // type & 0x0F: 0 = none, 1 = rectangle, 2 = rounded rect., 3 = circle, // type & 0xF0 = CenterAligned, LeftAligned, TopAligned, RightAligned, BottomAligned, LeftTopAligned, RightTopAligned, // RightBottomAligned, LeftBottomAligned, NoCaption // (*clr = color, TaskIndex, Group and SelGrp are ignored) # if ADAGFX_ARGUMENT_VALIDATION - if (invalidCoordinates(nParams[1], nParams[2]) || - invalidCoordinates(nParams[1] + nParams[3], nParams[2] + nParams[4])) { + if (invalidCoordinates(nParams[2], nParams[3]) || + invalidCoordinates(nParams[2] + nParams[4], nParams[3] + nParams[5])) { success = false; } else # endif // if ADAGFX_ARGUMENT_VALIDATION { // All checked out OK // Default values - uint16_t onColor = ADAGFX_GREEN; + uint16_t onColor = ADAGFX_BLUE; uint16_t offColor = ADAGFX_RED; uint16_t captionColor = ADAGFX_WHITE; - uint8_t fontScale = 2; + uint8_t fontScale = 0; uint16_t borderColor = ADAGFX_WHITE; - uint16_t disabledColor = 0x9410; - uint16_t disabledCaptionColor = 0x5A69; + uint16_t disabledColor = 0x9410; // Medium grey + uint16_t disabledCaptionColor = 0x5A69; // Dark grey - if (!sParams[7].isEmpty()) { onColor = AdaGFXparseColor(sParams[7], _colorDepth); } + if (!sParams[8].isEmpty()) { onColor = AdaGFXparseColor(sParams[8], _colorDepth); } - if (!sParams[8].isEmpty()) { offColor = AdaGFXparseColor(sParams[8], _colorDepth); } + if (!sParams[9].isEmpty()) { offColor = AdaGFXparseColor(sParams[9], _colorDepth); } - if (!sParams[9].isEmpty()) { captionColor = AdaGFXparseColor(sParams[9], _colorDepth); } + if (!sParams[10].isEmpty()) { captionColor = AdaGFXparseColor(sParams[10], _colorDepth); } - if (nParams[12] > 0) { fontScale = nParams[12]; } + if (nParams[11] > 0) { fontScale = nParams[11]; } - if (!sParams[13].isEmpty()) { borderColor = AdaGFXparseColor(sParams[13], _colorDepth); } + if (!sParams[14].isEmpty()) { borderColor = AdaGFXparseColor(sParams[14], _colorDepth); } - if (!sParams[14].isEmpty()) { disabledColor = AdaGFXparseColor(sParams[14], _colorDepth); } + if (!sParams[15].isEmpty()) { disabledColor = AdaGFXparseColor(sParams[15], _colorDepth); } - if (!sParams[15].isEmpty()) { disabledCaptionColor = AdaGFXparseColor(sParams[15], _colorDepth); } + if (!sParams[16].isEmpty()) { disabledCaptionColor = AdaGFXparseColor(sParams[16], _colorDepth); } uint16_t fillColor = onColor; uint16_t textColor = captionColor; - bool clearArea = nParams[6] < 0; - nParams[6] = std::abs(nParams[6]); + bool clearArea = nParams[7] < 0; + nParams[7] = std::abs(nParams[7]); - // Check state: -2, -1, 0, 1 to select used colors - if ((nParams[0] == 0) || (nParams[0] == -1)) { + Button_type_e buttonType = static_cast(nParams[7] & 0x0F); + Button_layout_e buttonLayout = static_cast(nParams[7] & 0xF0); + + // Check mode & state: -2, -1, 0, 1 to select used colors + if (nParams[0] == 0) { fillColor = offColor; - } else if (nParams[0] == -2) { + } + + if ((nParams[1] == -2) || (nParams[0] < 0)) { fillColor = disabledColor; textColor = disabledCaptionColor; } else if (clearArea) { @@ -1401,131 +1463,79 @@ bool AdafruitGFX_helper::processCommand(const String& string) { borderColor = _bgcolor; } - if ((static_cast(nParams[6] & 0x0F) != Button_type_e::None) || + // Clear the area? + if ((buttonType != Button_type_e::None) || clearArea) { - _display->fillRect(nParams[1], nParams[2], nParams[3], nParams[4], _bgcolor); + drawButtonShape(buttonType, + nParams[2], nParams[3], nParams[4], nParams[5], + _bgcolor, _bgcolor); } // Check button-type bits (mask: 0x0F) to draw correct shape if (!clearArea) { - switch (static_cast(nParams[6] & 0x0F)) { - case Button_type_e::Square: // Rectangle - { - _display->fillRect(nParams[1], nParams[2], nParams[3], nParams[4], fillColor); - _display->drawRect(nParams[1], nParams[2], nParams[3], nParams[4], borderColor); - break; - } - case Button_type_e::Rounded: // Rounded Rectangle - { - int16_t radius = (nParams[3] + nParams[4]) / 20; // 10 % corner radius - _display->fillRoundRect(nParams[1], nParams[2], nParams[3], nParams[4], radius, fillColor); - _display->drawRoundRect(nParams[1], nParams[2], nParams[3], nParams[4], radius, borderColor); - break; - } - case Button_type_e::Circle: // Circle - { - int16_t radius = (nParams[3] + nParams[4]) / 4; // average radius - _display->fillCircle(nParams[1] + (nParams[3] / 2), nParams[2] + (nParams[4] / 2), radius, fillColor); - _display->drawCircle(nParams[1] + (nParams[3] / 2), nParams[2] + (nParams[4] / 2), radius, borderColor); - break; - } - case Button_type_e::ArrowLeft: - { // draw: left-center, right-top, right-bottom - _display->fillTriangle(nParams[1], nParams[2] + nParams[4] / 2, nParams[1] + nParams[3], nParams[2], - nParams[1] + nParams[3], nParams[2] + nParams[4], fillColor); - _display->drawTriangle(nParams[1], nParams[2] + nParams[4] / 2, nParams[1] + nParams[3], nParams[2], - nParams[1] + nParams[3], nParams[2] + nParams[4], borderColor); - break; - } - case Button_type_e::ArrowUp: - { // draw: top-center, right-bottom, left-bottom - _display->fillTriangle(nParams[1] + nParams[3] / 2, nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4], - nParams[1], nParams[2] + nParams[4], fillColor); - _display->drawTriangle(nParams[1] + nParams[3] / 2, nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4], - nParams[1], nParams[2] + nParams[4], borderColor); - break; - } - case Button_type_e::ArrowRight: - { // draw: left-top, right-center, left-bottom - _display->fillTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4] / 2, - nParams[1], nParams[2] + nParams[4], fillColor); - _display->drawTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2] + nParams[4] / 2, - nParams[1], nParams[2] + nParams[4], borderColor); - break; - } - case Button_type_e::ArrowDown: - { // draw: left-top, right-top, bottom-center - _display->fillTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2], - nParams[1] + nParams[3] / 2, nParams[2] + nParams[4], fillColor); - _display->drawTriangle(nParams[1], nParams[2], nParams[1] + nParams[3], nParams[2], - nParams[1] + nParams[3] / 2, nParams[2] + nParams[4], borderColor); - break; - } - case Button_type_e::None: - case Button_type_e::Button_MAX: - break; - } + drawButtonShape(buttonType, + nParams[2], nParams[3], nParams[4], nParams[5], + fillColor, borderColor); } // Display caption? (or bitmap) if (!clearArea && - !(static_cast(nParams[6] & 0xF0) == Button_layout_e::NoCaption)) { + (buttonLayout != Button_layout_e::NoCaption)) { int16_t x1, y1; uint16_t w1, h1, w2, h2; String newString; // Determine alignment parameters - if (nParams[0] == 1) { - newString = sParams[11].isEmpty() ? sParams[5] : sParams[11]; + if ((nParams[0] == 1) || (nParams[0] == -1)) { // 1 = on+enabled, -1 = on+disabled + newString = sParams[12].isEmpty() ? sParams[6] : sParams[12]; } else { - newString = sParams[12].isEmpty() ? sParams[5] : sParams[12]; + newString = sParams[13].isEmpty() ? sParams[6] : sParams[13]; } newString = AdaGFXparseTemplate(newString, 20); - if ((nParams[10] > 0) && (nParams[10] <= 10)) { _display->setTextSize(nParams[10]); } // set scaling + if ((nParams[11] > 0) && (nParams[11] <= 10)) { _display->setTextSize(nParams[11]); } // set scaling _display->getTextBounds(newString, 0, 0, &x1, &y1, &w1, &h1); // get caption length and height in pixels _display->getTextBounds(F(" "), 0, 0, &x1, &y1, &w2, &h2); // measure space width for little margins // Check button-alignment bits (mask 0xF0) for caption placement, modifies the x/y arguments passed! // Little margin is: from left/right: half of the width of a space, from top/bottom: half of height of the font used - Button_layout_e buttonLayout = static_cast(nParams[6] & 0xF0); switch (buttonLayout) { case Button_layout_e::CenterAligned: - nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically - nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + nParams[2] += (nParams[4] / 2 - w1 / 2); // center horizontically + nParams[3] += (nParams[5] / 2 - h1 / 2); // center vertically break; case Button_layout_e::LeftAligned: - nParams[1] += w2 / 2; // A little margin from left - nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + nParams[2] += w2 / 2; // A little margin from left + nParams[3] += (nParams[5] / 2 - h1 / 2); // center vertically break; case Button_layout_e::TopAligned: - nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically - nParams[2] += h1 / 2; // A little margin from top + nParams[2] += (nParams[4] / 2 - w1 / 2); // center horizontically + nParams[3] += h1 / 2; // A little margin from top break; case Button_layout_e::RightAligned: - nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin - nParams[2] += (nParams[4] / 2 - h1 / 2); // center vertically + nParams[2] += (nParams[4] - w1) - w2 / 2; // right-align + a little margin + nParams[3] += (nParams[5] / 2 - h1 / 2); // center vertically break; case Button_layout_e::BottomAligned: - nParams[1] += (nParams[3] / 2 - w1 / 2); // center horizontically - nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + nParams[2] += (nParams[4] / 2 - w1 / 2); // center horizontically + nParams[3] += (nParams[5] - h1 * 1.5); // bottom align + a little margin break; case Button_layout_e::LeftTopAligned: - nParams[1] += w2 / 2; // A little margin from left - nParams[2] += h1 / 2; // A little margin from top + nParams[2] += w2 / 2; // A little margin from left + nParams[3] += h1 / 2; // A little margin from top break; case Button_layout_e::RightTopAligned: - nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin - nParams[2] += h1 / 2; // A little margin from top + nParams[2] += (nParams[4] - w1) - w2 / 2; // right-align + a little margin + nParams[3] += h1 / 2; // A little margin from top break; case Button_layout_e::RightBottomAligned: - nParams[1] += (nParams[3] - w1) - w2 / 2; // right-align + a little margin - nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + nParams[2] += (nParams[4] - w1) - w2 / 2; // right-align + a little margin + nParams[3] += (nParams[5] - h1 * 1.5); // bottom align + a little margin break; case Button_layout_e::LeftBottomAligned: - nParams[1] += w2 / 2; // A little margin from left - nParams[2] += (nParams[4] - h1 * 1.5); // bottom align + a little margin + nParams[2] += w2 / 2; // A little margin from left + nParams[3] += (nParams[5] - h1 * 1.5); // bottom align + a little margin break; case Button_layout_e::Bitmap: { // Use ON/OFF caption to specify (full) bitmap filename @@ -1546,7 +1556,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { newString = parseStringToEndKeepCase(newString, 2); } } - success = showBmp(newString, nParams[1] + offX, nParams[2] + offY); + success = showBmp(newString, nParams[2] + offX, nParams[3] + offY); } else # endif // if ADAGFX_ENABLE_BMP_DISPLAY { @@ -1562,7 +1572,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if ((buttonLayout != Button_layout_e::NoCaption) && (buttonLayout != Button_layout_e::Bitmap)) { // Set position and colors, then print - _display->setCursor(nParams[1], nParams[2]); + _display->setCursor(nParams[2], nParams[3]); _display->setTextColor(captionColor, captionColor); // transparent bg results in button color _display->print(newString); @@ -1571,7 +1581,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } // restore font scaling - if ((nParams[10] > 0) && (nParams[10] <= 10)) { _display->setTextSize(_fontscaling); } + if ((nParams[11] > 0) && (nParams[11] <= 10)) { _display->setTextSize(_fontscaling); } } } } @@ -1583,6 +1593,75 @@ bool AdafruitGFX_helper::processCommand(const String& string) { return success; } +/**************************************************************************** + * draw a button shape with provided color, can also clear a previously drawn button + ***************************************************************************/ +void AdafruitGFX_helper::drawButtonShape(Button_type_e buttonType, + int x, + int y, + int w, + int h, + uint16_t fillColor, + uint16_t borderColor) { + switch (buttonType) { + case Button_type_e::Square: // Rectangle + { + _display->fillRect(x, y, w, h, fillColor); + _display->drawRect(x, y, w, h, borderColor); + break; + } + case Button_type_e::Rounded: // Rounded Rectangle + { + int16_t radius = (w + h) / 20; // average 10 % corner radius w/h + _display->fillRoundRect(x, y, w, h, radius, fillColor); + _display->drawRoundRect(x, y, w, h, radius, borderColor); + break; + } + case Button_type_e::Circle: // Circle + { + int16_t radius = (w + h) / 4; // average radius + _display->fillCircle(x + (w / 2), y + (h / 2), radius, fillColor); + _display->drawCircle(x + (w / 2), y + (h / 2), radius, borderColor); + break; + } + case Button_type_e::ArrowLeft: + { // draw: left-center, right-top, right-bottom + _display->fillTriangle(x, y + h / 2, x + w, y, + x + w, y + h, fillColor); + _display->drawTriangle(x, y + h / 2, x + w, y, + x + w, y + h, borderColor); + break; + } + case Button_type_e::ArrowUp: + { // draw: top-center, right-bottom, left-bottom + _display->fillTriangle(x + w / 2, y, x + w, y + h, + x, y + h, fillColor); + _display->drawTriangle(x + w / 2, y, x + w, y + h, + x, y + h, borderColor); + break; + } + case Button_type_e::ArrowRight: + { // draw: left-top, right-center, left-bottom + _display->fillTriangle(x, y, x + w, y + h / 2, + x, y + h, fillColor); + _display->drawTriangle(x, y, x + w, y + h / 2, + x, y + h, borderColor); + break; + } + case Button_type_e::ArrowDown: + { // draw: left-top, right-top, bottom-center + _display->fillTriangle(x, y, x + w, y, + x + w / 2, y + h, fillColor); + _display->drawTriangle(x, y, x + w, y, + x + w / 2, y + h, borderColor); + break; + } + case Button_type_e::None: + case Button_type_e::Button_MAX: + break; + } +} + /**************************************************************************** * printText: Print text on display at a specific pixel or column/row location ***************************************************************************/ @@ -1690,7 +1769,9 @@ void AdafruitGFX_helper::printText(const char *string, /**************************************************************************** * color565: convert r, g, b colors to rgb565 (by bit-shifting) ***************************************************************************/ -uint16_t color565(uint8_t red, uint8_t green, uint8_t blue) { +uint16_t color565(uint8_t red, + uint8_t green, + uint8_t blue) { return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); } @@ -1704,7 +1785,9 @@ uint16_t color565(uint8_t red, uint8_t green, uint8_t blue) { // Param [in] colorDepth: The requiresed color depth, default: FullColor // param [in] defaultWhite: Return White color if empty, default: true // return : color (default ADAGFX_WHITE) -uint16_t AdaGFXparseColor(String& s, AdaGFXColorDepth colorDepth, bool emptyIsBlack) { +uint16_t AdaGFXparseColor(String & s, + AdaGFXColorDepth colorDepth, + bool emptyIsBlack) { s.toLowerCase(); int32_t result = -1; // No result yet @@ -1839,7 +1922,7 @@ uint16_t AdaGFXparseColor(String& s, AdaGFXColorDepth colorDepth, bool emptyIsBl break; } } - return result; + return static_cast(result); } const __FlashStringHelper* AdaGFXcolorToString_internal(uint16_t color, @@ -2358,7 +2441,7 @@ bool AdafruitGFX_helper::showBmp(const String& filename, if (loglevelActiveFor(LOG_LEVEL_INFO)) { log.clear(); - log += F("showBmp: x: "); + log += F("showBmp: x:"); log += x; log += F(", y:"); log += y; diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index dba0426a7..28d5e5955 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -10,6 +10,17 @@ /**************************************************************************** * helper class and functions for displays that use Adafruit_GFX library ***************************************************************************/ +/************ + * Changelog: + * 2022-06-02 tonhuisman: Leave out some Notes from UI to save a few bytes from size limited builds + * 2022-05-27 tonhuisman: Change btn subcommand to split state and mode arguments, state = 0/1, -2/-1, mode = -2, -1, 0 + * 2022-05-27 tonhuisman: Fix a few character mappings in AdaGFXparseTemplate, add surrogates for chars not in font + * Add support for {0xNN...} to insert any ascii character in template, supports multiple 2-digit hex values > 00 + * space, comma, dot, colon, semicolon or dash (' ,.:;-') as separators in hex value are allowed + * 2022-05-23 tonhuisman: Fix cast for returned value from AdaGFXparseColor + * Make 8 and 16 color support optional to squeeze a few bytes from size limited builds + * 2022-05-23 tonhuisman: Add changelog, older changes have not been logged. + ***************************************************************************/ # include # include # include @@ -22,16 +33,21 @@ # include "../Helpers/ESPEasy_Storage.h" # include "../ESPEasyCore/ESPEasy_Log.h" -# define ADAGFX_PARSE_MAX_ARGS 7 // Maximum number of arguments needed and supported (corrected) +# define ADAGFX_PARSE_MAX_ARGS 7 // Maximum number of arguments needed and supported (corrected) # ifndef ADAGFX_ARGUMENT_VALIDATION -# define ADAGFX_ARGUMENT_VALIDATION 1 // Validate command arguments +# define ADAGFX_ARGUMENT_VALIDATION 1 // Validate command arguments # endif // ifndef ADAGFX_ARGUMENT_VALIDATION # ifndef ADAGFX_USE_ASCIITABLE -# define ADAGFX_USE_ASCIITABLE 1 // Enable 'asciitable' command (useful for debugging/development) +# define ADAGFX_USE_ASCIITABLE 1 // Enable 'asciitable' command (useful for debugging/development) # endif // ifndef ADAGFX_USE_ASCIITABLE # ifndef ADAGFX_SUPPORT_7COLOR -# define ADAGFX_SUPPORT_7COLOR 1 // Do we support 7-Color displays? + +// # define ADAGFX_SUPPORT_7COLOR 1 // Do we support 7-Color displays? # endif // ifndef ADAGFX_SUPPORT_7COLOR +# ifndef ADAGFX_SUPPORT_8and16COLOR + +// # define ADAGFX_SUPPORT_8and16COLOR 1 // Do we support 8 and 16-Color displays? +# endif // ifndef ADAGFX_SUPPORT_8and16COLOR # ifndef ADAGFX_FONTS_INCLUDED # define ADAGFX_FONTS_INCLUDED 1 // 3 extra fonts, also controls enable/disable of below 8pt/12pt fonts # endif // ifndef ADAGFX_FONTS_INCLUDED @@ -125,6 +141,12 @@ # ifndef ADAGFX_FONTS_EXTRA_20PT_INCLUDED # define ADAGFX_FONTS_EXTRA_20PT_INCLUDED # endif // ifndef ADAGFX_FONTS_EXTRA_20PT_INCLUDED +# ifndef ADAGFX_SUPPORT_7COLOR +# define ADAGFX_SUPPORT_7COLOR 1 +# endif // ifndef ADAGFX_SUPPORT_7COLOR +# ifndef ADAGFX_SUPPORT_8and16COLOR +# define ADAGFX_SUPPORT_8and16COLOR 1 +# endif // ifndef ADAGFX_SUPPORT_8and16COLOR # endif // ifdef PLUGIN_SET_MAX # define ADAGFX_PARSE_PREFIX F("~") // Subcommand-trigger prefix and postfix strings @@ -218,7 +240,7 @@ enum class Button_type_e : uint8_t { ArrowUp = 0x05, ArrowRight = 0x06, ArrowDown = 0x07, - Button_MAX // must be last value in enum, max possible values: 16 + Button_MAX = 8u // must be last value in enum, max possible values: 16 }; // Only bits 4..7 can be used, masked with: 0xF0 @@ -235,7 +257,7 @@ enum class Button_layout_e : uint8_t { LeftBottomAligned = 0x80, NoCaption = 0x90, Bitmap = 0xA0, - Alignment_MAX = 11u // options-count + Alignment_MAX = 11u // options-count, max possible values: 16 }; const __FlashStringHelper* toString(Button_type_e button); @@ -385,6 +407,15 @@ private: int Y, bool colRowMode = false); # endif // if ADAGFX_ARGUMENT_VALIDATION + # if ADAGFX_ENABLE_BUTTON_DRAW + void drawButtonShape(Button_type_e buttonType, + int x, + int y, + int w, + int h, + uint16_t fillColor, + uint16_t borderColor); + # endif // if ADAGFX_ENABLE_BUTTON_DRAW Adafruit_GFX *_display = nullptr; Adafruit_SPITFT *_tft = nullptr; From b0209e23957534aa8175152958b8398f22da9b58 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 6 Jun 2022 15:05:15 +0200 Subject: [PATCH 06/32] [AdaGFX] Add support for confined windows to print/draw in [AdaGFX] Add support for getting config values (cherry picked from commit 6899e94586fb4c8f12ca6c8eeabe7ff7030ce2c8) --- src/src/Helpers/AdafruitGFX_helper.cpp | 580 +++++++++++++++++++++---- src/src/Helpers/AdafruitGFX_helper.h | 88 +++- 2 files changed, 573 insertions(+), 95 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 620c36e88..eaf585dee 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -551,7 +551,7 @@ AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, initialize(); } -# ifdef ADAGFX_ENABLE_BMP_DISPLAY +# if ADAGFX_ENABLE_BMP_DISPLAY AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, const String & trigger, uint16_t res_x, @@ -575,7 +575,7 @@ AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, initialize(); } -# endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY +# endif // if ADAGFX_ENABLE_BMP_DISPLAY /**************************************************************************** * common initialization, called from constructors @@ -604,6 +604,10 @@ void AdafruitGFX_helper::initialize() { _display_x = _res_x; // Store initial resolution _display_y = _res_y; + # if ADAGFX_ENABLE_FRAMED_WINDOW + defineWindow(0, 0, _res_x, _res_y, 0, 0); // Add window 0 at rotation 0 + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + if (_fontscaling < 1) { _fontscaling = 1; } if (nullptr != _display) { @@ -613,6 +617,9 @@ void AdafruitGFX_helper::initialize() { } } +/**************************************************************************** + * Show enabled features of the helper + ***************************************************************************/ String AdafruitGFX_helper::getFeatures() { String log = F("Features:"); @@ -627,7 +634,17 @@ String AdafruitGFX_helper::getFeatures() { # endif // if (defined(ADAGFX_ENABLE_BMP_DISPLAY) && ADAGFX_ENABLE_BMP_DISPLAY) # if (defined(ADAGFX_ENABLE_BUTTON_DRAW) && ADAGFX_ENABLE_BUTTON_DRAW) log += F(" btn,"); - # endif // if (defined(ADAGFX_ENABLE_BUTTON_DRAW) && ADAGFX_ENABLE_BUTTON_DRAW) + # endif // if (defined(ADAGFX_ENABLE_BUTTON_DRAW) && ADAGFX_ENABLE_BUTTON_DRAW)` + # if (defined(ADAGFX_ENABLE_FRAMED_WINDOW) && ADAGFX_ENABLE_FRAMED_WINDOW) + log += F(" win,"); + # endif // if (defined(ADAGFX_ENABLE_FRAMED_WINDOW) && ADAGFX_ENABLE_FRAMED_WINDOW) + # if (defined(ADAGFX_ENABLE_GET_CONFIG_VALUE) && ADAGFX_ENABLE_GET_CONFIG_VALUE) + log += F(" getconf,"); + # endif // if (defined(ADAGFX_ENABLE_GET_CONFIG_VALUE) && ADAGFX_ENABLE_GET_CONFIG_VALUE) + + if (log.endsWith(F(","))) { + log.remove(log.length() - 1); + } return log; } @@ -654,8 +671,16 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if ((nullptr == _display) || _trigger.isEmpty()) { return success; } - String cmd = parseString(string, 1); // lower case - String subcommand = parseString(string, 2); + String cmd = parseString(string, 1); // lower case + String subcommand = parseString(string, 2); + uint16_t res_x = _res_x; + uint16_t res_y = _res_y; + uint16_t _xo = 0, _yo = 0; + + # if ADAGFX_ENABLE_FRAMED_WINDOW + getWindowLimits(res_x, res_y); + getWindowOffsets(_xo, _yo); + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW if (!cmd.equals(_trigger) || subcommand.isEmpty()) { return success; } // Only support own trigger, and at least a non=empty subcommand @@ -726,7 +751,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (_columnRowMode) { _display->setCursor(nParams[0] * _fontwidth, nParams[1] * _fontheight); } else { - _display->setCursor(nParams[0] - _p095_compensation, nParams[1] - _p095_compensation); + _display->setCursor(nParams[0] + _xo - _p095_compensation, nParams[1] + _yo - _p095_compensation); } } } @@ -742,7 +767,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (_columnRowMode) { _display->setCursor(nParams[0] * _fontwidth, nParams[1] * _fontheight); } else { - _display->setCursor(nParams[0], nParams[1]); + _display->setCursor(nParams[0] + _xo, nParams[1] + _yo); } _display->println(parseStringToEndKeepCase(string, 5)); // Print entire rest of provided line } @@ -781,8 +806,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[2].c_str(), - nParams[0] - _p095_compensation, - nParams[1] - _p095_compensation, + nParams[0] + _xo - _p095_compensation, + nParams[1] + _yo - _p095_compensation, _fontscaling, _fgcolor, _fgcolor); // transparent bg @@ -798,8 +823,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[3].c_str(), - nParams[0] - _p095_compensation, - nParams[1] - _p095_compensation, + nParams[0] + _xo - _p095_compensation, + nParams[1] + _yo - _p095_compensation, nParams[2], _fgcolor, _fgcolor); // transparent bg @@ -816,8 +841,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { { uint16_t color = AdaGFXparseColor(sParams[3], _colorDepth); printText(sParams[4].c_str(), - nParams[0] - _p095_compensation, - nParams[1] - _p095_compensation, + nParams[0] + _xo - _p095_compensation, + nParams[1] + _yo - _p095_compensation, nParams[2], color, color); // transparent bg @@ -833,8 +858,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[5].c_str(), - nParams[0] - _p095_compensation, - nParams[1] - _p095_compensation, + nParams[0] + _xo - _p095_compensation, + nParams[1] + _yo - _p095_compensation, nParams[2], AdaGFXparseColor(sParams[3], _colorDepth), AdaGFXparseColor(sParams[4], _colorDepth)); @@ -877,11 +902,22 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else if (subcommand.equals(F("clear"))) // Clear display { - if (argCount >= 1) { - _display->fillScreen(AdaGFXparseColor(sParams[0], _colorDepth)); - } else { - _display->fillScreen(_bgcolor); + # if ADAGFX_ENABLE_FRAMED_WINDOW + + if (_window == 0) + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + { + _display->fillScreen(argCount == 0 ? _bgcolor : AdaGFXparseColor(sParams[0], _colorDepth)); } + # if ADAGFX_ENABLE_FRAMED_WINDOW + else { + // logWindows(F("clear ")); // Use for debugging only + uint16_t _w = 0, _h = 0; + getWindowLimits(_w, _h); + _display->fillRect(_xo, _yo, _w, _h, + argCount == 0 ? _bgcolor : AdaGFXparseColor(sParams[0], _colorDepth)); + } + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW } else if (subcommand.equals(F("rot")) && (argCount == 1)) // Rotation { @@ -1114,29 +1150,29 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawLine(nParams[0], nParams[1], nParams[2], nParams[3], AdaGFXparseColor(sParams[4], _colorDepth)); + _display->drawLine(nParams[0] + _xo, nParams[1] + _yo, nParams[2] + _xo, nParams[3] + _yo, AdaGFXparseColor(sParams[4], _colorDepth)); } } else if (subcommand.equals(F("lh")) && (argCount == 3)) { // lh: Horizontal line # if ADAGFX_ARGUMENT_VALIDATION - if ((nParams[0] < 0) || (nParams[0] > _res_x)) { + if ((nParams[0] < 0) || (nParams[0] > res_x)) { success = false; } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawFastHLine(0, nParams[0], nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); + _display->drawFastHLine(_xo, nParams[0] + _yo, nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); } } else if (subcommand.equals(F("lv")) && (argCount == 3)) { // lv: Vertical line # if ADAGFX_ARGUMENT_VALIDATION - if ((nParams[0] < 0) || (nParams[0] > _res_y)) { + if ((nParams[0] < 0) || (nParams[0] > res_y)) { success = false; } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawFastVLine(nParams[0], 0, nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); + _display->drawFastVLine(nParams[0] + _xo, _yo, nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); } } # if ADAGFX_ENABLE_EXTRA_CMDS @@ -1202,7 +1238,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { log += AdaGFXcolorToString(mcolor, _colorDepth); addLog(LOG_LEVEL_INFO, log); # endif // ifndef BUILD_NO_DEBUG - _display->drawLine(nParams[0], nParams[1], nParams[2], nParams[3], mcolor); + _display->drawLine(nParams[0] + _xo, nParams[1] + _yo, nParams[2] + _xo, nParams[3] + _yo, mcolor); if ((cx == -1) && (cy == -1)) { cx = nParams[0]; @@ -1225,7 +1261,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawRect(nParams[0], nParams[1], nParams[2], nParams[3], AdaGFXparseColor(sParams[4], _colorDepth)); + _display->drawRect(nParams[0] + _xo, nParams[1] + _yo, nParams[2], nParams[3], AdaGFXparseColor(sParams[4], _colorDepth)); } } else if (subcommand.equals(F("rf")) && (argCount == 6)) { // rf: Rectangled, filled @@ -1237,8 +1273,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->fillRect(nParams[0], nParams[1], nParams[2], nParams[3], AdaGFXparseColor(sParams[5], _colorDepth)); - _display->drawRect(nParams[0], nParams[1], nParams[2], nParams[3], AdaGFXparseColor(sParams[4], _colorDepth)); + _display->fillRect(nParams[0] + _xo, nParams[1] + _yo, nParams[2], nParams[3], AdaGFXparseColor(sParams[5], _colorDepth)); + _display->drawRect(nParams[0] + _xo, nParams[1] + _yo, nParams[2], nParams[3], AdaGFXparseColor(sParams[4], _colorDepth)); } } else if (subcommand.equals(F("c")) && (argCount == 4)) { // c: Circle @@ -1250,7 +1286,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawCircle(nParams[0], nParams[1], nParams[2], AdaGFXparseColor(sParams[3], _colorDepth)); + _display->drawCircle(nParams[0] + _xo, nParams[1] + _yo, nParams[2], AdaGFXparseColor(sParams[3], _colorDepth)); } } else if (subcommand.equals(F("cf")) && (argCount == 5)) { // cf: Circle, filled @@ -1262,8 +1298,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->fillCircle(nParams[0], nParams[1], nParams[2], AdaGFXparseColor(sParams[4], _colorDepth)); - _display->drawCircle(nParams[0], nParams[1], nParams[2], AdaGFXparseColor(sParams[3], _colorDepth)); + _display->fillCircle(nParams[0] + _xo, nParams[1] + _yo, nParams[2], AdaGFXparseColor(sParams[4], _colorDepth)); + _display->drawCircle(nParams[0] + _xo, nParams[1] + _yo, nParams[2], AdaGFXparseColor(sParams[3], _colorDepth)); } } else if (subcommand.equals(F("t")) && (argCount == 7)) { // t: Triangle @@ -1276,7 +1312,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawTriangle(nParams[0], nParams[1], nParams[2], nParams[3], nParams[4], nParams[5], + _display->drawTriangle(nParams[0] + _xo, nParams[1] + _yo, nParams[2] + _xo, nParams[3] + _yo, nParams[4] + _xo, nParams[5] + _yo, AdaGFXparseColor(sParams[6], _colorDepth)); } } @@ -1290,19 +1326,19 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->fillTriangle(nParams[0], - nParams[1], - nParams[2], - nParams[3], - nParams[4], - nParams[5], + _display->fillTriangle(nParams[0] + _xo, + nParams[1] + _yo, + nParams[2] + _xo, + nParams[3] + _yo, + nParams[4] + _xo, + nParams[5] + _yo, AdaGFXparseColor(sParams[7], _colorDepth)); - _display->drawTriangle(nParams[0], - nParams[1], - nParams[2], - nParams[3], - nParams[4], - nParams[5], + _display->drawTriangle(nParams[0] + _xo, + nParams[1] + _yo, + nParams[2] + _xo, + nParams[3] + _yo, + nParams[4] + _xo, + nParams[5] + _yo, AdaGFXparseColor(sParams[6], _colorDepth)); } } @@ -1316,7 +1352,12 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawRoundRect(nParams[0], nParams[1], nParams[2], nParams[3], nParams[4], AdaGFXparseColor(sParams[5], _colorDepth)); + _display->drawRoundRect(nParams[0] + _xo, + nParams[1] + _yo, + nParams[2], + nParams[3], + nParams[4], + AdaGFXparseColor(sParams[5], _colorDepth)); } } else if (subcommand.equals(F("rrf")) && (argCount == 7)) { // rrf: Rounded rectangle, filled @@ -1329,8 +1370,18 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->fillRoundRect(nParams[0], nParams[1], nParams[2], nParams[3], nParams[4], AdaGFXparseColor(sParams[6], _colorDepth)); - _display->drawRoundRect(nParams[0], nParams[1], nParams[2], nParams[3], nParams[4], AdaGFXparseColor(sParams[5], _colorDepth)); + _display->fillRoundRect(nParams[0] + _xo, + nParams[1] + _yo, + nParams[2], + nParams[3], + nParams[4], + AdaGFXparseColor(sParams[6], _colorDepth)); + _display->drawRoundRect(nParams[0] + _xo, + nParams[1] + _yo, + nParams[2], + nParams[3], + nParams[4], + AdaGFXparseColor(sParams[5], _colorDepth)); } } else if (subcommand.equals(F("px")) && (argCount == 3)) { // px: Pixel @@ -1341,7 +1392,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else # endif // if ADAGFX_ARGUMENT_VALIDATION { - _display->drawPixel(nParams[0], nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); + _display->drawPixel(nParams[0] + _xo, nParams[1] + _yo, AdaGFXparseColor(sParams[2], _colorDepth)); } } else if ((subcommand.equals(F("pxh")) || subcommand.equals(F("pxv"))) && (argCount > 2)) { // pxh/pxv: Pixels, hor./vert. incremented @@ -1353,7 +1404,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { _display->startWrite(); - _display->writePixel(nParams[0], nParams[1], AdaGFXparseColor(sParams[2], _colorDepth)); + _display->writePixel(nParams[0] + _xo, nParams[1] + _yo, AdaGFXparseColor(sParams[2], _colorDepth)); loop = true; uint8_t h = 0; uint8_t v = 0; @@ -1370,12 +1421,12 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (color.isEmpty() # if ADAGFX_ARGUMENT_VALIDATION - || invalidCoordinates(nParams[0] + h, nParams[1] + v) + || invalidCoordinates(nParams[0] + h + _xo, nParams[1] + v + _yo) # endif // if ADAGFX_ARGUMENT_VALIDATION ) { loop = false; } else { - _display->writePixel(nParams[0] + h, nParams[1] + v, AdaGFXparseColor(color, _colorDepth)); + _display->writePixel(nParams[0] + h + _xo, nParams[1] + v + _yo, AdaGFXparseColor(color, _colorDepth)); if (isPxh) { h++; @@ -1391,7 +1442,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # if ADAGFX_ENABLE_BMP_DISPLAY else if (subcommand.equals(F("bmp")) && (argCount == 3)) { // bmp,x,y,filename.bmp : show bmp from file if (!sParams[2].isEmpty()) { - success = showBmp(sParams[2], nParams[0], nParams[1]); + success = showBmp(sParams[2], nParams[0] + _xo, nParams[1] + _yo); } else { success = false; } @@ -1434,7 +1485,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if (!sParams[10].isEmpty()) { captionColor = AdaGFXparseColor(sParams[10], _colorDepth); } - if (nParams[11] > 0) { fontScale = nParams[11]; } + if ((nParams[11] > 0) && (nParams[11] <= 10)) { fontScale = nParams[11]; } if (!sParams[14].isEmpty()) { borderColor = AdaGFXparseColor(sParams[14], _colorDepth); } @@ -1467,14 +1518,14 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if ((buttonType != Button_type_e::None) || clearArea) { drawButtonShape(buttonType, - nParams[2], nParams[3], nParams[4], nParams[5], + nParams[2] + _xo, nParams[3] + _yo, nParams[4], nParams[5], _bgcolor, _bgcolor); } // Check button-type bits (mask: 0x0F) to draw correct shape if (!clearArea) { drawButtonShape(buttonType, - nParams[2], nParams[3], nParams[4], nParams[5], + nParams[2] + _xo, nParams[3] + _yo, nParams[4], nParams[5], fillColor, borderColor); } @@ -1493,7 +1544,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } newString = AdaGFXparseTemplate(newString, 20); - if ((nParams[11] > 0) && (nParams[11] <= 10)) { _display->setTextSize(nParams[11]); } // set scaling + _display->setTextSize(fontScale); // set scaling _display->getTextBounds(newString, 0, 0, &x1, &y1, &w1, &h1); // get caption length and height in pixels _display->getTextBounds(F(" "), 0, 0, &x1, &y1, &w2, &h2); // measure space width for little margins @@ -1556,7 +1607,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { newString = parseStringToEndKeepCase(newString, 2); } } - success = showBmp(newString, nParams[2] + offX, nParams[3] + offY); + success = showBmp(newString, nParams[2] + _xo + offX, nParams[3] + _yo + offY); } else # endif // if ADAGFX_ENABLE_BMP_DISPLAY { @@ -1572,8 +1623,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if ((buttonLayout != Button_layout_e::NoCaption) && (buttonLayout != Button_layout_e::Bitmap)) { // Set position and colors, then print - _display->setCursor(nParams[2], nParams[3]); - _display->setTextColor(captionColor, captionColor); // transparent bg results in button color + _display->setCursor(nParams[2] + _xo, nParams[3] + _yo); + _display->setTextColor(textColor, textColor); // transparent bg results in button color _display->print(newString); // restore colors @@ -1581,11 +1632,73 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } // restore font scaling - if ((nParams[11] > 0) && (nParams[11] <= 10)) { _display->setTextSize(_fontscaling); } + _display->setTextSize(_fontscaling); } } } # endif // if ADAGFX_ENABLE_BUTTON_DRAW + # if ADAGFX_ENABLE_FRAMED_WINDOW + else if (subcommand.equals(F("win")) && (argCount >= 1) && (argCount <= 2)) { // win: select window by id + success = selectWindow(nParams[0], nParams[1]); + } + else if (subcommand.equals(F("defwin")) && (argCount >= 5) && (argCount <= 6)) { // defwin: define window + int8_t rot = _rotation; + # if ADAGFX_ARGUMENT_VALIDATION + int16_t curWin = getWindow(); + + if (curWin != 0) { selectWindow(0); } // Validate against raw window coordinates + + if (argCount == 6) { setRotation(nParams[5]); } // Use requested rotation + + if (invalidCoordinates(nParams[0], nParams[1]) || + invalidCoordinates(nParams[0] + nParams[2], nParams[1] + nParams[3])) { + success = false; + + if (curWin != 0) { selectWindow(curWin); } // restore current window + + if (rot != _rotation) { setRotation(rot); } // Restore rotation + } else + # endif // if ADAGFX_ARGUMENT_VALIDATION + { + # if ADAGFX_ARGUMENT_VALIDATION + + if (curWin != 0) { selectWindow(curWin); } // restore current window + # endif // if ADAGFX_ARGUMENT_VALIDATION + + if (nParams[4] > 0) { // Window 0 is the raw window, having the full size, created at initialization of this helper instance + # ifndef BUILD_NO_DEBUG + int16_t win = // avoid compiler warning + # endif // ifndef BUILD_NO_DEBUG + defineWindow(nParams[0], + nParams[1], + nParams[2], + nParams[3], + nParams[4], + argCount == 6 ? nParams[5] : _rotation); + # ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("AdaGFX defined window id: "); + log += win; + addLogMove(LOG_LEVEL_INFO, log); + } + # endif // ifndef BUILD_NO_DEBUG + + if (rot != _rotation) { setRotation(rot); } // Restore rotation, also update new window + } else { + success = false; + } + // logWindows(F(" deFwin ")); // Use for debugging only? + } + } + else if (subcommand.equals(F("delwin")) && (argCount == 1)) { // delwin: delete window + // logWindows(F(" deLwin ")); // use for debugging only + + if (nParams[0] > 0) { // don't delete window 0 + success = deleteWindow(nParams[0]); + } + } + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW else { success = false; } @@ -1593,6 +1706,73 @@ bool AdafruitGFX_helper::processCommand(const String& string) { return success; } +/**************************************************************************** + * Get a config value from the plugin + ***************************************************************************/ +# if ADAGFX_ENABLE_GET_CONFIG_VALUE +bool AdafruitGFX_helper::pluginGetConfigValue(String& string) { + bool success = false; + String command = parseString(string, 1); + + if (command == F("win")) { // win: get current window id + # if ADAGFX_ENABLE_FRAMED_WINDOW // if feature enabled + string = getWindow(); + success = true; + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + } else if (command == F("iswin")) { // iswin: check if windows exists + # if ADAGFX_ENABLE_FRAMED_WINDOW // if feature enabled + command = parseString(string, 2); + int win = 0; + + if (validIntFromString(command, win)) { + string = validWindow(static_cast(win)); + } else { + string = '0'; + } + success = true; // Always correct, just return 'false' if wrong + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + } else if ((command == F("width")) || // width/height: get window width or height + (command == F("height"))) { + # if ADAGFX_ENABLE_FRAMED_WINDOW // if feature enabled + uint16_t w = 0, h = 0; + getWindowLimits(w, h); + + if (command == F("width")) { + string = w; + } else { + string = h; + } + success = true; + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + } else if ((command == F("length")) || // length/textheight: get text length or height + (command == F("textheight"))) { + int16_t x1, y1; + uint16_t w1, h1; + String newString = parseStringToEndKeepCase(string, 2); + _display->getTextBounds(newString, 0, 0, &x1, &y1, &w1, &h1); // Count length and height + + if (command == F("length")) { + string = w1; + } else { + string = h1; + } + success = true; + } else if (command == F("rot")) { // rot: get current rotation setting + string = _rotation; + success = true; + } else if (command == F("txs")) { // txs: get current text scaling setting + string = _fontscaling; + success = true; + } else if (command == F("tpm")) { // tpm: get current text print mode setting + string = static_cast(_textPrintMode); + success = true; + } + + return success; +} + +# endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE + /**************************************************************************** * draw a button shape with provided color, can also clear a previously drawn button ***************************************************************************/ @@ -1680,6 +1860,13 @@ void AdafruitGFX_helper::printText(const char *string, int16_t ot = 0, ob = 0, ol = 0; uint16_t res_x = _res_x; String newString = string; + uint16_t res_y = _res_y; + uint16_t xo = 0, yo = 0; + + # if ADAGFX_ENABLE_FRAMED_WINDOW + getWindowLimits(res_x, res_y); + getWindowOffsets(xo, yo); + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW if (_columnRowMode) { _x = X * (_fontwidth * textSize); // We need this multiple times @@ -1691,18 +1878,11 @@ void AdafruitGFX_helper::printText(const char *string, _display->setTextSize(textSize); if (_textPrintMode != AdaGFXTextPrintMode::ContinueToNextLine) { - if (_isProportional) { // Proportional font. This is rather slow! - _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Count length + _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Count length - while ((newString.length() > 0) && ((_x + w1) > res_x)) { - newString.remove(newString.length() - 1); // Cut last character off - _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Re-count length - } - } - else { // Fixed width font - if (newString.length() > static_cast(_textcols - (_x / (_fontwidth * textSize)))) { - newString = newString.substring(0, _textcols - (_x / (_fontwidth * textSize))); - } + while ((newString.length() > 0) && ((_x + w1) > (res_x + xo))) { + newString.remove(newString.length() - 1); // Cut last character off + _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Re-count length } } @@ -2166,8 +2346,12 @@ void AdafruitGFX_helper::getTextMetrics(uint16_t& textcols, fontheight = _fontheight; fontscaling = _fontscaling; heightOffset = _heightOffset; - xpix = _res_x; - ypix = _res_y; + # if ADAGFX_ENABLE_FRAMED_WINDOW + getWindowLimits(xpix, ypix); + # else // if ADAGFX_ENABLE_FRAMED_WINDOW + xpix = _res_x; + ypix = _res_y; + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW } /**************************************************************************** @@ -2186,12 +2370,19 @@ void AdafruitGFX_helper::calculateTextMetrics(uint8_t fontwidth, uint8_t fontheight, int8_t heightOffset, bool isProportional) { + uint16_t res_x = _res_x; + uint16_t res_y = _res_y; + + # if ADAGFX_ENABLE_FRAMED_WINDOW + getWindowLimits(res_x, res_y); + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + _fontwidth = fontwidth; _fontheight = fontheight; _heightOffset = heightOffset; _isProportional = isProportional; - _textcols = _res_x / (_fontwidth * _fontscaling); - _textrows = _res_y / ((_fontheight + _heightOffset) * _fontscaling); + _textcols = res_x / (_fontwidth * _fontscaling); + _textrows = res_y / ((_fontheight + _heightOffset) * _fontscaling); # ifndef BUILD_NO_DEBUG @@ -2205,9 +2396,9 @@ void AdafruitGFX_helper::calculateTextMetrics(uint8_t fontwidth, log += _trigger; } log += F(" x: "); - log += _res_x; + log += res_x; log += F(", y: "); - log += _res_y; + log += res_y; log += F(", text columns: "); log += _textcols; log += F(" rows: "); @@ -2228,6 +2419,13 @@ void AdafruitGFX_helper::calculateTextMetrics(uint8_t fontwidth, bool AdafruitGFX_helper::invalidCoordinates(int X, int Y, bool colRowMode) { + uint16_t res_x = _res_x; + uint16_t res_y = _res_y; + + # if ADAGFX_ENABLE_FRAMED_WINDOW + getWindowLimits(res_x, res_y); + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW + # ifndef BUILD_NO_DEBUG if (loglevelActiveFor(ADAGFX_LOG_LEVEL)) { @@ -2237,11 +2435,11 @@ bool AdafruitGFX_helper::invalidCoordinates(int X, log += F("invalidCoordinates: X:"); log += X; log += '/'; - log += (colRowMode ? _textcols : _res_x); + log += (colRowMode ? _textcols : res_x); log += F(" Y:"); log += Y; log += '/'; - log += (colRowMode ? _textrows : _res_y); + log += (colRowMode ? _textrows : res_y); addLogMove(ADAGFX_LOG_LEVEL, log); } # endif // ifndef BUILD_NO_DEBUG @@ -2253,20 +2451,24 @@ bool AdafruitGFX_helper::invalidCoordinates(int X, (Y >= 0) && (Y <= _textrows)); } else { if (Y == 0) { // Y == 0: Accept largest x/y size value for x - return !((X >= 0) && (X <= std::max(_res_x, _res_y))); + return !((X >= 0) && (X <= std::max(res_x, res_y))); } else { - return !((X >= 0) && (X <= _res_x) && - (Y >= 0) && (Y <= _res_y)); + return !((X >= 0) && (X <= res_x) && + (Y >= 0) && (Y <= res_y)); } } } # endif // if ADAGFX_ARGUMENT_VALIDATION +/**************************************************************************** + * rotate the display (and all windows) + ***************************************************************************/ void AdafruitGFX_helper::setRotation(uint8_t m) { uint8_t rotation = m & 3; _display->setRotation(m); // Set rotation 0/1/2/3 + _rotation = rotation; switch (rotation) { case 0: @@ -2280,18 +2482,52 @@ void AdafruitGFX_helper::setRotation(uint8_t m) { _res_y = _display_x; break; } + # if ADAGFX_ENABLE_FRAMED_WINDOW + + for (uint8_t i = 0; i < _windows.size(); i++) { // Swap x/y for all matching windows + switch (rotation) { + case 0: // 0 degrees + _windows[i].top_left.x = _windows[i].org_top_left.x; // All original + _windows[i].top_left.y = _windows[i].org_top_left.y; + _windows[i].width_height.x = _windows[i].org_width_height.x; + _windows[i].width_height.y = _windows[i].org_width_height.y; + break; + case 1: // +90 degrees + _windows[i].top_left.x = _windows[i].org_top_left.y; + _windows[i].top_left.y = _display_x - (_windows[i].org_top_left.x + _windows[i].org_width_height.x); + _windows[i].width_height.x = _windows[i].org_width_height.y; // swapped width/height + _windows[i].width_height.y = _windows[i].org_width_height.x; + break; + case 2: // +180 degrees + _windows[i].top_left.x = _display_x - (_windows[i].org_top_left.x + _windows[i].org_width_height.x); + _windows[i].top_left.y = _display_y - (_windows[i].org_top_left.y + _windows[i].org_width_height.y); + _windows[i].width_height.x = _windows[i].org_width_height.x; + _windows[i].width_height.y = _windows[i].org_width_height.y; + break; + case 3: // +270 degrees + _windows[i].top_left.x = _display_y - (_windows[i].org_top_left.y + _windows[i].org_width_height.y); + _windows[i].top_left.y = _windows[i].org_top_left.x; + _windows[i].width_height.x = _windows[i].org_width_height.y; // swapped width/height + _windows[i].width_height.y = _windows[i].org_width_height.x; + break; + } + _windows[i].rotation = rotation; + } + + // logWindows(F("rot ")); // For debugging only + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW calculateTextMetrics(_fontwidth, _fontheight, _heightOffset, _isProportional); } # if ADAGFX_ENABLE_BMP_DISPLAY -/** +/**************************************************************************** * CPA (Copy/paste/adapt) from Adafruit_ImageReader::coreBMP() * Changes: * - No 'load to memory' feature * - No special handling of SD Filesystem/FAT, but File only * - Adds support for non-SPI displays (like NeoPixel Matrix, and possibly I2C displays, once supported) - */ + ***************************************************************************/ bool AdafruitGFX_helper::showBmp(const String& filename, int16_t x, int16_t y) { @@ -2645,4 +2881,180 @@ uint32_t AdafruitGFX_helper::readLE32(void) { # endif // if ADAGFX_ENABLE_BMP_DISPLAY +# if ADAGFX_ENABLE_FRAMED_WINDOW + +/**************************************************************************** + * Check if the requested id is a valid window id + ***************************************************************************/ +bool AdafruitGFX_helper::validWindow(uint8_t windowId) { + return getWindowIndex(windowId) != -1; +} + +/**************************************************************************** + * Select this window id as the default + ***************************************************************************/ +bool AdafruitGFX_helper::selectWindow(uint8_t windowId, + int8_t rotation) { + int16_t result = getWindowIndex(windowId); + + if (result != -1) { + _windowIndex = result; + _window = windowId; + } + return result != -1; +} + +/**************************************************************************** + * Return the index of the windowId in _windows, -1 if not found + ***************************************************************************/ +int16_t AdafruitGFX_helper::getWindowIndex(int16_t windowId) { + size_t result = 0; + + for (auto win = _windows.begin(); win != _windows.end(); win++, result++) { + if ((*win).id == windowId) { + break; + } + } + return result == _windows.size() ? -1 : result; +} + +/**************************************************************************** + * Get the offset for the currently active window + ***************************************************************************/ +void AdafruitGFX_helper::getWindowOffsets(uint16_t& xOffset, + uint16_t& yOffset) { + xOffset = _windows[_windowIndex].top_left.x; + yOffset = _windows[_windowIndex].top_left.y; +} + +/**************************************************************************** + * Get the limits for the currently active window + ***************************************************************************/ +void AdafruitGFX_helper::getWindowLimits(uint16_t& xLimit, + uint16_t& yLimit) { + xLimit = _windows[_windowIndex].width_height.x; + yLimit = _windows[_windowIndex].width_height.y; +} + +/**************************************************************************** + * Define a window and return the ID + ***************************************************************************/ +uint8_t AdafruitGFX_helper::defineWindow(int16_t x, + int16_t y, + int16_t w, + int16_t h, + int16_t windowId, + int8_t rotation) { + int16_t result = getWindowIndex(windowId); + + if (result < 0) { + result = _windows.size(); // previous size + _windows.push_back(tWindowObject()); // add new + + if (windowId < 0) { + windowId = 0; + + for (auto it = _windows.begin(); it != _windows.end(); it++) { + if ((*it).id == windowId) { windowId++; } // Generate a new window id + } + } + _windows[result].id = windowId; + } + _windows[result].top_left.x = x; + _windows[result].top_left.y = y; + _windows[result].width_height.x = w; + _windows[result].width_height.y = h; + + if (rotation >= 0) { + _windows[result].rotation = rotation & 3; + } else { + _windows[result].rotation = _rotation; + } + + // Adjust original coordinate/sizes based on rotation + switch (_windows[result].rotation) { + case 0: // 0 degrees + _windows[result].org_top_left.x = x; // All original + _windows[result].org_top_left.y = y; + _windows[result].org_width_height.x = w; + _windows[result].org_width_height.y = h; + break; + case 1: // +90 degrees + _windows[result].org_top_left.x = _display_x - (y + h); // swapped x/y + _windows[result].org_top_left.y = x; + _windows[result].org_width_height.x = h; // swapped width/height + _windows[result].org_width_height.y = w; + break; + case 2: // +180 degrees + _windows[result].org_top_left.x = _display_x - (x + w); + _windows[result].org_top_left.y = _display_y - (y + h); + _windows[result].org_width_height.x = w; // unchanged + _windows[result].org_width_height.y = h; + break; + case 3: // +270 degrees + _windows[result].org_top_left.x = y; + _windows[result].org_top_left.y = _display_x - (x + w); + _windows[result].org_width_height.x = h; // swapped width/height + _windows[result].org_width_height.y = w; + break; + } + + return _windows[result].id; +} + +/**************************************************************************** + * Remove a window definition + ***************************************************************************/ +bool AdafruitGFX_helper::deleteWindow(uint8_t windowId) { + int16_t result = getWindowIndex(windowId); + + if (result > -1) { + _windows.erase(_windows.begin() + result); + return true; + } + return false; +} + +/**************************************************************************** + * log all current known window definitions + ***************************************************************************/ +void AdafruitGFX_helper::logWindows(const String& prefix) { + # ifndef BUILD_NO_DEBUG + String log; + + log.reserve(50); + + for (auto it = _windows.begin(); it != _windows.end(); it++) { + log.clear(); + log += F("AdaGFX window "); + log += prefix; + log += F(": "); + log += (*it).id; + log += F(", x:"); + log += (*it).top_left.x; + log += F(", y:"); + log += (*it).top_left.y; + log += F(", w:"); + log += (*it).width_height.x; + log += F(", h:"); + log += (*it).width_height.y; + log += F(", rot:"); + log += (*it).rotation; + log += F(", current: "); + log += getWindow(); + log += F(", org x:"); + log += (*it).org_top_left.x; + log += F(", y:"); + log += (*it).org_top_left.y; + log += F(", w:"); + log += (*it).org_width_height.x; + log += F(", h:"); + log += (*it).org_width_height.y; + addLogMove(LOG_LEVEL_INFO, log); + } + # endif // ifndef BUILD_NO_DEBUG +} + +# endif // if ADAGFX_ENABLE_FRAMED_WINDOW + #endif // ifdef PLUGIN_USES_ADAFRUITGFX diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 28d5e5955..5e30f5891 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -12,6 +12,10 @@ ***************************************************************************/ /************ * Changelog: + * 2022-06-05 tonhuisman: Add support for getting config values: win (current window id), iswin (exists?), width and height (current window), + * (text)length and textheight of a provided text, rot (current rotation), txs (fontscaling), tpm (textprintmode) + * 2022-06-04 tonhuisman: Add Window support for drawing and printing within confined areas (windows) + * Always use exact font calculation for determining allowable text length * 2022-06-02 tonhuisman: Leave out some Notes from UI to save a few bytes from size limited builds * 2022-05-27 tonhuisman: Change btn subcommand to split state and mode arguments, state = 0/1, -2/-1, mode = -2, -1, 0 * 2022-05-27 tonhuisman: Fix a few character mappings in AdaGFXparseTemplate, add surrogates for chars not in font @@ -25,6 +29,7 @@ # include # include # include +# include // Used for bmp support # define BUFPIXELS 200 ///< 200 * 5 = 1000 bytes @@ -49,20 +54,26 @@ // # define ADAGFX_SUPPORT_8and16COLOR 1 // Do we support 8 and 16-Color displays? # endif // ifndef ADAGFX_SUPPORT_8and16COLOR # ifndef ADAGFX_FONTS_INCLUDED -# define ADAGFX_FONTS_INCLUDED 1 // 3 extra fonts, also controls enable/disable of below 8pt/12pt fonts +# define ADAGFX_FONTS_INCLUDED 1 // 3 extra fonts, also controls enable/disable of below 8pt/12pt fonts # endif // ifndef ADAGFX_FONTS_INCLUDED # ifndef ADAGFX_PARSE_SUBCOMMAND -# define ADAGFX_PARSE_SUBCOMMAND 1 // Enable parsing of subcommands (pre/postfix below) to be executed by the helper +# define ADAGFX_PARSE_SUBCOMMAND 1 // Enable parsing of subcommands (pre/postfix below) to be executed by the helper # endif // ifndef ADAGFX_PARSE_SUBCOMMAND # ifndef ADAGFX_ENABLE_EXTRA_CMDS -# define ADAGFX_ENABLE_EXTRA_CMDS 1 // Enable extra subcommands like lm (line-multi) and lmr (line-multi, relative) +# define ADAGFX_ENABLE_EXTRA_CMDS 1 // Enable extra subcommands like lm (line-multi) and lmr (line-multi, relative) # endif // ifndef ADAGFX_ENABLE_EXTRA_CMDS # ifndef ADAGFX_ENABLE_BMP_DISPLAY -# define ADAGFX_ENABLE_BMP_DISPLAY 1 // Enable subcommands for displaying .bmp files on supported displays (color) +# define ADAGFX_ENABLE_BMP_DISPLAY 1 // Enable subcommands for displaying .bmp files on supported displays (color) # endif // ifndef ADAGFX_ENABLE_BMP_DISPLAY # ifndef ADAGFX_ENABLE_BUTTON_DRAW -# define ADAGFX_ENABLE_BUTTON_DRAW 1 // Enable subcommands for displaying button-like shapes +# define ADAGFX_ENABLE_BUTTON_DRAW 1 // Enable subcommands for displaying button-like shapes # endif // ifndef ADAGFX_ENABLE_BUTTON_DRAW +# ifndef ADAGFX_ENABLE_FRAMED_WINDOW +# define ADAGFX_ENABLE_FRAMED_WINDOW 1 // Enable framed window features +# endif // ifndef ADAGFX_ENABLE_BUTTON_DRAW +# ifndef ADAGFX_ENABLE_GET_CONFIG_VALUE +# define ADAGFX_ENABLE_GET_CONFIG_VALUE 1 // Enable getting values features +# endif // ifndef ADAGFX_ENABLE_GET_CONFIG_VALUE // # define ADAGFX_FONTS_EXTRA_8PT_INCLUDED // 8 extra 8pt fonts, should probably only be enabled in a private custom build, adds ~15.4 kB // # define ADAGFX_FONTS_EXTRA_12PT_INCLUDED // 9 extra 12pt fonts, should probably only be enabled in a private custom build, adds ~28 kB @@ -123,6 +134,12 @@ // # ifdef ADAGFX_ENABLE_BUTTON_DRAW // # undef ADAGFX_ENABLE_BUTTON_DRAW // # endif // ifdef ADAGFX_ENABLE_BUTTON_DRAW +// # ifdef ADAGFX_ENABLE_FRAMED_WINDOW +// # undef ADAGFX_ENABLE_FRAMED_WINDOW +// # endif // ifdef ADAGFX_ENABLE_FRAMED_WINDOW +// # ifdef ADAGFX_ENABLE_GET_CONFIG_VALUE +// # undef ADAGFX_ENABLE_GET_CONFIG_VALUE +// # endif // ifdef ADAGFX_ENABLE_GET_CONFIG_VALUE # endif // ifdef LIMIT_BUILD_SIZE # ifdef PLUGIN_SET_MAX // Include all fonts in MAX builds @@ -265,6 +282,22 @@ const __FlashStringHelper* toString(Button_layout_e layout); # endif // if ADAGFX_ENABLE_BUTTON_DRAW +# if ADAGFX_ENABLE_FRAMED_WINDOW + +struct tWindowPoint { + uint16_t x = 0; + uint16_t y = 0; +}; +struct tWindowObject { + tWindowPoint top_left; + tWindowPoint width_height; + tWindowPoint org_top_left; + tWindowPoint org_width_height; + uint8_t id = 0u; + int8_t rotation = 0; +}; +# endif // if ADAGFX_ENABLE_FRAMED_WINDOW + class AdafruitGFX_helper; // Forward declaration // Some generic AdafruitGFX_helper support functions @@ -331,7 +364,7 @@ public: uint16_t bgcolor = ADAGFX_BLACK, bool useValidation = true, bool textBackFill = false); - # ifdef ADAGFX_ENABLE_BMP_DISPLAY + # if ADAGFX_ENABLE_BMP_DISPLAY AdafruitGFX_helper(Adafruit_SPITFT *display, const String & trigger, uint16_t res_x, @@ -343,13 +376,17 @@ public: uint16_t bgcolor = ADAGFX_BLACK, bool useValidation = true, bool textBackFill = false); - # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY + # endif // if ADAGFX_ENABLE_BMP_DISPLAY virtual ~AdafruitGFX_helper() {} String getFeatures(); bool processCommand(const String& string); // Parse the string for recognized commands and apply them on the graphics display + # if ADAGFX_ENABLE_GET_CONFIG_VALUE + bool pluginGetConfigValue(String& string); // Get a config value from the plugin + # endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE + void printText(const char *string, int16_t X, int16_t Y, @@ -392,11 +429,28 @@ public: return trigger.equalsIgnoreCase(ADAGFX_UNIVERSAL_TRIGGER); } - # ifdef ADAGFX_ENABLE_BMP_DISPLAY + # if ADAGFX_ENABLE_BMP_DISPLAY bool showBmp(const String& filename, int16_t x, int16_t y); - # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY + # endif // if ADAGFX_ENABLE_BMP_DISPLAY + + # if ADAGFX_ENABLE_FRAMED_WINDOW + uint8_t getWindow() { + return _window; + } + + bool validWindow(uint8_t windowId); + bool selectWindow(uint8_t windowId, + int8_t rotation = -1); + uint8_t defineWindow(int16_t x, + int16_t y, + int16_t w, + int16_t h, + int16_t windowId = -1, + int8_t rotation = -1); + bool deleteWindow(uint8_t windowId); + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW private: @@ -439,14 +493,26 @@ private: bool _isProportional = false; uint8_t _p095_compensation = 0; bool _columnRowMode = false; + int8_t _rotation = 0; uint16_t _display_x; uint16_t _display_y; - # ifdef ADAGFX_ENABLE_BMP_DISPLAY + # if ADAGFX_ENABLE_BMP_DISPLAY uint16_t readLE16(void); uint32_t readLE32(void); fs::File file; - # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY + # endif // if ADAGFX_ENABLE_BMP_DISPLAY + # if ADAGFX_ENABLE_FRAMED_WINDOW + int16_t getWindowIndex(int16_t windowId); + void logWindows(const String& prefix = EMPTY_STRING); + void getWindowOffsets(uint16_t& xOffset, + uint16_t& yOffset); + void getWindowLimits(uint16_t& xLimit, + uint16_t& yLimit); + std::vector_windows; + uint8_t _window = 0; // current window + uint8_t _windowIndex = 0; // current window Index + # endif // if ADAGFX_ENABLE_FRAMED_WINDOW }; #endif // ifdef PLUGIN_USES_ADAFRUITGFX From eed4b6d26a0b9a471e5383e99007cb105181439b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 6 Jun 2022 21:51:16 +0200 Subject: [PATCH 07/32] [AdaGFX] Process like template for length and textheight values (cherry picked from commit bcc772bab857a13b3b3eb89dac9fd13d70cace5d) --- src/src/Helpers/AdafruitGFX_helper.cpp | 2 +- src/src/Helpers/AdafruitGFX_helper.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index eaf585dee..ce3dd24a9 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -1748,7 +1748,7 @@ bool AdafruitGFX_helper::pluginGetConfigValue(String& string) { (command == F("textheight"))) { int16_t x1, y1; uint16_t w1, h1; - String newString = parseStringToEndKeepCase(string, 2); + String newString = AdaGFXparseTemplate(parseStringToEndKeepCase(string, 2), 0); _display->getTextBounds(newString, 0, 0, &x1, &y1, &w1, &h1); // Count length and height if (command == F("length")) { diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 5e30f5891..38a029ef6 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -12,6 +12,7 @@ ***************************************************************************/ /************ * Changelog: + * 2022-06-06 tonhuisman: Process any special characters for lenght and textheight values for correct sizing * 2022-06-05 tonhuisman: Add support for getting config values: win (current window id), iswin (exists?), width and height (current window), * (text)length and textheight of a provided text, rot (current rotation), txs (fontscaling), tpm (textprintmode) * 2022-06-04 tonhuisman: Add Window support for drawing and printing within confined areas (windows) From 60719b303134cd939718366858bfaa41d7ec47dd Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 6 Jun 2022 21:52:14 +0200 Subject: [PATCH 08/32] [AdaGFX] Add/update documentation for window commands and config values (cherry picked from commit 0cc64f1708c9c9a9c7666973363fb7c630b86edf) --- docs/source/Plugin/AdaGFX_commands.repl | 62 ++++++++++++++++ docs/source/Plugin/AdaGFX_values.repl | 94 +++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 docs/source/Plugin/AdaGFX_values.repl diff --git a/docs/source/Plugin/AdaGFX_commands.repl b/docs/source/Plugin/AdaGFX_commands.repl index 67c8eb96d..fe13ed448 100644 --- a/docs/source/Plugin/AdaGFX_commands.repl +++ b/docs/source/Plugin/AdaGFX_commands.repl @@ -35,6 +35,7 @@ * 0 : Continue to next line (wrap text onto the next line) * 1 : Truncate exceeding message (cut-off text that won't fit on the screen width) * 2 : Clear then truncate exceeding message (Clear to width of screen, then print the message) + * 3 : Truncate, centered if maxWidth set (like 1, but allows to center when used via ``txtfull`` subcommand) " " ``,txt,`` @@ -283,3 +284,64 @@ NB: This command wil only *draw* a button, it will not respond to any action. The action is usually provided by a touch screen like :ref:`P099_page` and :ref:`P123_page`. " + " + ``,defwin,,,,,[,]`` + + Example: (Display Task is named ``st7796``, using trigger ``st77xx``) + + .. code:: none + + on window1 do + if %eventvalue1|1%=1 // on = default + st77xx,defwin,20,50,390,219,1,1 // Window 1, using rotation 1 + st77xx,win,1 // Select window + st77xx,rot,1 // Select rotation + st77xx,clear // Clear area + st77xx,r,0,0,[st7796#width],[st7796#height],white // Draw a white border + st77xx,win,0 // Return to Window 0 + else + asyncevent,removewindow=1 // Remove Window 1 + endif + endon + on removewindow do + if [st7796#iswin,%eventvalue1|-1%]=1 // Does the Window exist? + st77xx,win,%eventvalue1% // Select window + st77xx,clear // Clear area + st77xx,delwin,%eventvalue1% // Delete Window + st77xx,win,0 // Return to Window 0 + endif + endon + + "," + Define Window. + + When enabled, the Window feature of the plugin can be used to define custom areas of the screen as a window. Any printing and drawing can then be limited to that area, having a coordinate system from ``0,0`` to ``,``. + + Window 0 is the default window, having the native size of the display. The coordinates, width and height for the ``defwin`` subcommand must be specified in pixels. + + * ``x,y``: The top-left coordinate of the window, according to the native resolution of the screen. This coordinate will become the ``0,0`` coordinate of the new window. + + * ``w,h``: The width and height of the window. + + * ``windowId``: The Id of the new window, can be any value from 1 to 255. When re-using an Id, the previous definition will be overwritten. + + * ``rotation``: Optional. The rotation, identical to the ``rot`` subcommand, that the window dimensions are related to. When not specified, the current rotation setting will be used. Internally, the dimensions are transformed to the dimensions for rotation 0, and on each change of ``rot``, all windows will be re-calculated to have the dimensions corresponding with the new rotation setting. + " + " + ``,delwin,`` + "," + Delete Window. + + When no longer needed, a window definition can be deleted using this subcommand. + + * ``windowId``: The window Id of a previously defined window. + " + " + ``,win,`` + "," + Select Window. + + To make a window active, is must be selected using this subcommand. + + * ``windowId``: The window Id of a previously defined window. + " diff --git a/docs/source/Plugin/AdaGFX_values.repl b/docs/source/Plugin/AdaGFX_values.repl new file mode 100644 index 000000000..ecfd4797f --- /dev/null +++ b/docs/source/Plugin/AdaGFX_values.repl @@ -0,0 +1,94 @@ +.. csv-table:: + :escape: ^ + :widths: 20, 30 + + " + Generic variables, available for all ``AdafruitGFX_Helper`` enabled plugins, currently: :ref:`P095_page`, :ref:`P096_page`, :ref:`P116_page` and :ref:`P131_page`. + "," + Generic notes: + + * If an argument has comma's or spaces, then that part should be 'wrapped' in either double quotes ``^"``, single quotes ``^'`` or back-ticks ``^```. + * The ```` part is the name of the Device task. + * True(1)/False(0) values can optionally return -1 to indicate an invalid request, like a missing Window Id. + * All sizes, lengths etc. are returned in pixels. + " + " + ``[#win]`` + "," + Get the currently active Window Id, expected range: 0..255. + " + " + ``[#iswin,]`` + "," + Is the request Window Id valid, expected result: 1 = true, 0 = false. + " + " + ``[#width]`` + "," + Get the width of the currently active Window and rotation, expected range 0... + " + " + ``[#height]`` + "," + Get the height of the currently active Window and rotation, expected range 0... + " + " + ``[#length,^"^"]`` + "," + Get the length of the text in pixels for the current font and text scaling. Needs quotes if text contains space(s), comma(s) or quote(s). + " + " + ``[#textheight,^"^"]`` + "," + Get the height of the text in pixels for the current font and text scaling. Needs quotes if the text contains space(s), comma(s) or quote(s). + " + " + ``[#rot]`` + "," + Get the currently active rotation, expected range 0..3 (0 = 0 degrees, 1 = +90 degrees, 2 = +180 degrees, 3 = +270 degrees). + " + " + ``[#txs]`` + "," + Get the currently active text scaling, expected range 1..10, limited to the max. font scaling allowed for the display. + " + " + ``[#tpm]`` + "," + Get the currently active text print mode, expected range 0..3, see the ``tpm`` subcommand for details. + " + +.. csv-table:: + :escape: ^ + :widths: 20, 10 + + " + Example rules for centering a value (time) in a window: + + .. code:: none + + on centertime do // NB: Comments & extra spaces should be removed to reduce rules size! + if [st7796#iswin,%eventvalue1|2%]=1 // default window: 2 + let,120,[st7796#win] // store current window + st77xx,win,%eventvalue1|2% // switch to window + let,121,[st7796#txs] // store textscaling + st77xx,txs,3 // set text scaling + let,122,[st7796#rot] // store rotation + st77xx,rot,%eventvalue2|0% // set rotation, default: 0 + let,123,([st7796#width]-[st7796#length,%systm_hm%])/2 // (width - textlength)/2 + let,124,([st7796#height]-[st7796#textheight,%systm_hm%])/2 // (height - textheight)/2 + st77xx,txtfull,[int#123],[int#124],3,red,black,%systm_hm% // Display time red on black + st77xx,rot,%v122% // restore rotation + st77xx,txs,%v121% // restore text scaling + st77xx,win,%v120% // restore window + endif + endon + on Clock#Time=All,**:** do + asyncevent,centertime=2 // Update the display every minute + endon + + "," + Display Task is named ``st7796``, using trigger ``st77xx`` + + Usage: ``asyncevent,centertime[=[,]]`` + " From f1a8fa2d74eab334157b4197cb22309a19c73b1d Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 7 Jun 2022 22:55:14 +0200 Subject: [PATCH 09/32] [AdaGFX] Code improvements, initialization, const, move window offset into printText() (cherry picked from commit 8ce3690709e2af10b53e9637a3d9f9148734df7d) --- src/src/Helpers/AdafruitGFX_helper.cpp | 323 +++++++++++++------------ src/src/Helpers/AdafruitGFX_helper.h | 126 +++++----- 2 files changed, 234 insertions(+), 215 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index ce3dd24a9..ee02ff1c7 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -71,7 +71,7 @@ /****************************************************************************************** * get the display text for a 'text print mode' enum value *****************************************************************************************/ -const __FlashStringHelper* toString(AdaGFXTextPrintMode mode) { +const __FlashStringHelper* toString(const AdaGFXTextPrintMode mode) { switch (mode) { case AdaGFXTextPrintMode::ContinueToNextLine: return F("Continue to next line"); case AdaGFXTextPrintMode::TruncateExceedingMessage: return F("Truncate exceeding message"); @@ -85,7 +85,7 @@ const __FlashStringHelper* toString(AdaGFXTextPrintMode mode) { /****************************************************************************************** * get the display text for a color depth enum value *****************************************************************************************/ -const __FlashStringHelper* toString(AdaGFXColorDepth colorDepth) { +const __FlashStringHelper* toString(const AdaGFXColorDepth colorDepth) { switch (colorDepth) { case AdaGFXColorDepth::Monochrome: return F("Monochrome"); case AdaGFXColorDepth::BlackWhiteRed: return F("Monochrome + 1 color"); @@ -105,7 +105,7 @@ const __FlashStringHelper* toString(AdaGFXColorDepth colorDepth) { /****************************************************************************************** * get the display text for a button type enum value *****************************************************************************************/ -const __FlashStringHelper* toString(Button_type_e button) { +const __FlashStringHelper* toString(const Button_type_e button) { switch (button) { case Button_type_e::None: return F("None"); case Button_type_e::Square: return F("Square"); @@ -123,7 +123,7 @@ const __FlashStringHelper* toString(Button_type_e button) { /****************************************************************************************** * get the display text for a button layout enum value *****************************************************************************************/ -const __FlashStringHelper* toString(Button_layout_e layout) { +const __FlashStringHelper* toString(const Button_layout_e layout) { switch (layout) { case Button_layout_e::CenterAligned: return F("Centered"); case Button_layout_e::LeftAligned: return F("Left-aligned"); @@ -254,9 +254,8 @@ void AdaGFXFormForeAndBackColors(const __FlashStringHelper *foregroundId, const __FlashStringHelper *backgroundId, uint16_t backgroundColor, AdaGFXColorDepth colorDepth) { - String color; + String color = AdaGFXcolorToString(foregroundColor, colorDepth); - color = AdaGFXcolorToString(foregroundColor, colorDepth); addFormTextBox(F("Foreground color"), foregroundId, color, 11); color = AdaGFXcolorToString(backgroundColor, colorDepth); addFormTextBox(F("Background color"), backgroundId, color, 11); @@ -316,7 +315,7 @@ void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, * AdaGFXparseTemplate: Replace variables and adjust unicode special characters to Adafruit font ***************************************************************************/ String AdaGFXparseTemplate(const String & tmpString, - uint8_t lineSize, + const uint8_t lineSize, AdafruitGFX_helper *gfxHelper) { # if ADAGFX_PARSE_SUBCOMMAND @@ -532,17 +531,17 @@ String AdaGFXparseTemplate(const String & tmpString, /**************************************************************************** * parameterized constructors ***************************************************************************/ -AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, - const String & trigger, - uint16_t res_x, - uint16_t res_y, - AdaGFXColorDepth colorDepth, - AdaGFXTextPrintMode textPrintMode, - uint8_t fontscaling, - uint16_t fgcolor, - uint16_t bgcolor, - bool useValidation, - bool textBackFill) +AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth colorDepth, + const AdaGFXTextPrintMode textPrintMode, + const uint8_t fontscaling, + const uint16_t fgcolor, + const uint16_t bgcolor, + const bool useValidation, + const bool textBackFill) : _display(display), _trigger(trigger), _res_x(res_x), _res_y(res_y), _colorDepth(colorDepth), _textPrintMode(textPrintMode), _fontscaling(fontscaling), _fgcolor(fgcolor), _bgcolor(bgcolor), _useValidation(useValidation), _textBackFill(textBackFill) @@ -552,17 +551,17 @@ AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, } # if ADAGFX_ENABLE_BMP_DISPLAY -AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, - const String & trigger, - uint16_t res_x, - uint16_t res_y, - AdaGFXColorDepth colorDepth, - AdaGFXTextPrintMode textPrintMode, - uint8_t fontscaling, - uint16_t fgcolor, - uint16_t bgcolor, - bool useValidation, - bool textBackFill) +AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth colorDepth, + const AdaGFXTextPrintMode textPrintMode, + const uint8_t fontscaling, + const uint16_t fgcolor, + const uint16_t bgcolor, + const bool useValidation, + const bool textBackFill) : _tft(display), _trigger(trigger), _res_x(res_x), _res_y(res_y), _colorDepth(colorDepth), _textPrintMode(textPrintMode), _fontscaling(fontscaling), _fgcolor(fgcolor), _bgcolor(bgcolor), _useValidation(useValidation), _textBackFill(textBackFill) @@ -671,11 +670,12 @@ bool AdafruitGFX_helper::processCommand(const String& string) { if ((nullptr == _display) || _trigger.isEmpty()) { return success; } - String cmd = parseString(string, 1); // lower case + String cmd = parseString(string, 1); // lower case String subcommand = parseString(string, 2); - uint16_t res_x = _res_x; - uint16_t res_y = _res_y; - uint16_t _xo = 0, _yo = 0; + uint16_t res_x = _res_x; + uint16_t res_y = _res_y; + uint16_t _xo = 0; + uint16_t _yo = 0; # if ADAGFX_ENABLE_FRAMED_WINDOW getWindowLimits(res_x, res_y); @@ -806,8 +806,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[2].c_str(), - nParams[0] + _xo - _p095_compensation, - nParams[1] + _yo - _p095_compensation, + nParams[0] - _p095_compensation, + nParams[1] - _p095_compensation, _fontscaling, _fgcolor, _fgcolor); // transparent bg @@ -823,8 +823,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[3].c_str(), - nParams[0] + _xo - _p095_compensation, - nParams[1] + _yo - _p095_compensation, + nParams[0] - _p095_compensation, + nParams[1] - _p095_compensation, nParams[2], _fgcolor, _fgcolor); // transparent bg @@ -841,8 +841,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { { uint16_t color = AdaGFXparseColor(sParams[3], _colorDepth); printText(sParams[4].c_str(), - nParams[0] + _xo - _p095_compensation, - nParams[1] + _yo - _p095_compensation, + nParams[0] - _p095_compensation, + nParams[1] - _p095_compensation, nParams[2], color, color); // transparent bg @@ -858,8 +858,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { printText(sParams[5].c_str(), - nParams[0] + _xo - _p095_compensation, - nParams[1] + _yo - _p095_compensation, + nParams[0] - _p095_compensation, + nParams[1] - _p095_compensation, nParams[2], AdaGFXparseColor(sParams[3], _colorDepth), AdaGFXparseColor(sParams[4], _colorDepth)); @@ -939,10 +939,10 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # if ADAGFX_USE_ASCIITABLE else if (subcommand.equals(F("asciitable"))) // Show ASCII table { - String line; - int16_t start = 0x80 + (argCount >= 1 && nParams[0] >= -4 && nParams[0] < 4 ? nParams[0] * 0x20 : 0); - uint8_t scale = (argCount == 2 && nParams[1] > 0 && nParams[1] <= 10 ? nParams[1] : 2); - uint8_t currentScale = _fontscaling; + String line; + const int16_t start = 0x80 + (argCount >= 1 && nParams[0] >= -4 && nParams[0] < 4 ? nParams[0] * 0x20 : 0); + const uint8_t scale = (argCount == 2 && nParams[1] > 0 && nParams[1] <= 10 ? nParams[1] : 2); + const uint8_t currentScale = _fontscaling; if (_fontscaling != scale) { // Set fontscaling _fontscaling = scale; @@ -951,8 +951,8 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } line.reserve(_textcols); _display->setCursor(0, 0); - int16_t row = 0; - bool colMode = _columnRowMode; + int16_t row = 0; + const bool colMode = _columnRowMode; _columnRowMode = true; for (int16_t i = start; i <= 0xFF && row < _textrows; i++) { @@ -1642,11 +1642,11 @@ bool AdafruitGFX_helper::processCommand(const String& string) { success = selectWindow(nParams[0], nParams[1]); } else if (subcommand.equals(F("defwin")) && (argCount >= 5) && (argCount <= 6)) { // defwin: define window - int8_t rot = _rotation; + const int8_t rot = _rotation; # if ADAGFX_ARGUMENT_VALIDATION - int16_t curWin = getWindow(); + const int16_t curWin = getWindow(); - if (curWin != 0) { selectWindow(0); } // Validate against raw window coordinates + if (curWin != 0) { selectWindow(0); } // Validate against raw window coordinates if (argCount == 6) { setRotation(nParams[5]); } // Use requested rotation @@ -1845,27 +1845,34 @@ void AdafruitGFX_helper::drawButtonShape(Button_type_e buttonType, /**************************************************************************** * printText: Print text on display at a specific pixel or column/row location ***************************************************************************/ -void AdafruitGFX_helper::printText(const char *string, - int16_t X, - int16_t Y, - uint8_t textSize, - uint16_t color, - uint16_t bkcolor, - uint16_t maxWidth) { - int16_t _x = X; - int16_t _y = Y + (_heightOffset * textSize); - uint16_t _w = 0; - int16_t x1 = 0, y1 = 0; - uint16_t w1 = 0, h1 = 0; - int16_t ot = 0, ob = 0, ol = 0; +void AdafruitGFX_helper::printText(const char *string, + const int16_t X, + const int16_t Y, + const uint8_t textSize, + const uint16_t color, + uint16_t bkcolor, + const uint16_t maxWidth) { + int16_t _x = X; + int16_t _y = Y + (_heightOffset * textSize); + uint16_t _w = 0; + int16_t xText = 0; + int16_t yText = 0; + uint16_t wText = 0; + uint16_t hText = 0; + int16_t oTop = 0; + int16_t oBottom = 0; + int16_t oLeft = 0; uint16_t res_x = _res_x; + uint16_t res_y = _res_y; + uint16_t xOffset = 0; + uint16_t yOffset = 0; String newString = string; - uint16_t res_y = _res_y; - uint16_t xo = 0, yo = 0; # if ADAGFX_ENABLE_FRAMED_WINDOW getWindowLimits(res_x, res_y); - getWindowOffsets(xo, yo); + getWindowOffsets(xOffset, yOffset); + _x += xOffset; + _y += yOffset; # endif // if ADAGFX_ENABLE_FRAMED_WINDOW if (_columnRowMode) { @@ -1878,32 +1885,32 @@ void AdafruitGFX_helper::printText(const char *string, _display->setTextSize(textSize); if (_textPrintMode != AdaGFXTextPrintMode::ContinueToNextLine) { - _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Count length + _display->getTextBounds(newString, _x, _y, &xText, &yText, &wText, &hText); // Count length - while ((newString.length() > 0) && ((_x + w1) > (res_x + xo))) { - newString.remove(newString.length() - 1); // Cut last character off - _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Re-count length + while ((newString.length() > 0) && (((_x - xOffset) + wText) > res_x)) { + newString.remove(newString.length() - 1); // Cut last character off + _display->getTextBounds(newString, _x, _y, &xText, &yText, &wText, &hText); // Re-count length } } - _display->getTextBounds(newString, _x, _y, &x1, &y1, &w1, &h1); // Count length + _display->getTextBounds(newString, _x, _y, &xText, &yText, &wText, &hText); // Count length - if ((maxWidth > 0) && (_x + maxWidth <= _res_x)) { - res_x = _x + maxWidth; + if ((maxWidth > 0) && ((_x - xOffset) + maxWidth <= res_x)) { + res_x = (_x - xOffset) + maxWidth; _w = maxWidth; if ((_textPrintMode == AdaGFXTextPrintMode::TruncateExceedingCentered) && - (maxWidth > w1)) { - ol = (_w - (w1 + 2 * (x1 - _x))) / 2; + (maxWidth > wText)) { + oLeft = (_w - (wText + 2 * (xText - _x))) / 2; } } else { - _w = w1 + 2 * (x1 - _x); + _w = wText + 2 * (xText - _x); } if (_textBackFill && (color != bkcolor)) { // Fill extra space above and below text - ot -= textSize; - ob += textSize; - _y += textSize; + oTop -= textSize; + oBottom += textSize; + _y += textSize; } if ((_textPrintMode == AdaGFXTextPrintMode::ClearThenTruncate) || @@ -1913,16 +1920,20 @@ void AdafruitGFX_helper::printText(const char *string, if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { String log = F("printText: clear: _x:"); log += _x; + log += F(", oTop:"); + log += oTop; log += F(", _y:"); log += _y; - log += F(", x1:"); - log += x1; - log += F(", y1:"); - log += y1; - log += F(", w1:"); - log += w1; - log += F(", h1:"); - log += h1; + log += F(", xTx:"); + log += xText; + log += F(", yTx:"); + log += yText; + log += F(", wTx:"); + log += wText; + log += F(", hTx:"); + log += hText; + log += F(", oBot:"); + log += oBottom; log += F(", _res_x/max:"); log += _res_x; log += '/'; @@ -1934,24 +1945,24 @@ void AdafruitGFX_helper::printText(const char *string, # endif // ifndef BUILD_NO_DEBUG if (_textPrintMode == AdaGFXTextPrintMode::ClearThenTruncate) { - _display->fillRect(_x + ot, y1, res_x - _x, h1 + ob, bkcolor); // Clear text area to right edge of screen + _display->fillRect(_x + oTop, yText, res_x - (_x - xOffset), hText + oBottom, bkcolor); // Clear text area to right edge of screen } else { - _display->fillRect(_x + ot, y1, _w, h1 + ob, bkcolor); // Clear text area + _display->fillRect(_x + oTop, yText, _w, hText + oBottom, bkcolor); // Clear text area } delay(0); } - _display->setCursor(_x + ol, _y); // add left offset to center, _y may be updated + _display->setCursor(_x + oLeft, _y); // add left offset to center, _y may be updated _display->print(newString); } /**************************************************************************** * color565: convert r, g, b colors to rgb565 (by bit-shifting) ***************************************************************************/ -uint16_t color565(uint8_t red, - uint8_t green, - uint8_t blue) { +uint16_t color565(const uint8_t red, + const uint8_t green, + const uint8_t blue) { return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); } @@ -1965,9 +1976,9 @@ uint16_t color565(uint8_t red, // Param [in] colorDepth: The requiresed color depth, default: FullColor // param [in] defaultWhite: Return White color if empty, default: true // return : color (default ADAGFX_WHITE) -uint16_t AdaGFXparseColor(String & s, - AdaGFXColorDepth colorDepth, - bool emptyIsBlack) { +uint16_t AdaGFXparseColor(String & s, + const AdaGFXColorDepth colorDepth, + const bool emptyIsBlack) { s.toLowerCase(); int32_t result = -1; // No result yet @@ -2055,7 +2066,7 @@ uint16_t AdaGFXparseColor(String & s, // Parse default hex #RRGGBB string (must be 6 hex nibbles!) if ((result == -1) && (s.length() == 7) && (s[0] == '#')) { // convrt to long value in base16, then split up into r, g, b values - uint32_t number = hexToUL(&s[1]); + const uint32_t number = hexToUL(&s[1]); // uint32_t r = number >> 16 & 0xFF; // uint32_t g = number >> 8 & 0xFF; @@ -2127,7 +2138,7 @@ void AdaGFXaddHtmlDataListColorOptionValue(uint16_t color, * Generate a html 'datalist' of the colors available for selected colorDepth, with id provided ****************************************************************************************/ void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, - AdaGFXColorDepth colorDepth) { + const AdaGFXColorDepth colorDepth) { addHtml(F("")); @@ -2188,9 +2199,9 @@ void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, /***************************************************************************************** * Convert an RGB565 color (number) to it's name or the #rgb565 hex string, based on depth ****************************************************************************************/ -String AdaGFXcolorToString(uint16_t color, - AdaGFXColorDepth colorDepth, - bool blackIsEmpty) { +String AdaGFXcolorToString(const uint16_t color, + const AdaGFXColorDepth colorDepth, + bool blackIsEmpty) { String result = AdaGFXcolorToString_internal(color, colorDepth, blackIsEmpty); if (result.equals(F("*"))) { @@ -2279,18 +2290,17 @@ const __FlashStringHelper* AdaGFXcolorToString_internal(uint16_t color, * AdaGFXrgb565ToColor7: Convert a rgb565 color to the 7 colors supported by 7-color eInk displays * Borrowed from https://github.com/ZinggJM/GxEPD2 color7() routine ***************************************************************************/ -uint16_t AdaGFXrgb565ToColor7(uint16_t color) { - uint16_t cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_WHITE); // Default = white - - uint16_t red = (color & 0xF800); - uint16_t green = (color & 0x07E0) << 5; - uint16_t blue = (color & 0x001F) << 11; +uint16_t AdaGFXrgb565ToColor7(const uint16_t color) { + const uint16_t red = (color & 0xF800); + const uint16_t green = (color & 0x07E0) << 5; + const uint16_t blue = (color & 0x001F) << 11; + uint16_t cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_WHITE); // Default = white if ((red < 0x8000) && (green < 0x8000) && (blue < 0x8000)) { - cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_BLACK); // black + cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_BLACK); // black } else if ((red >= 0x8000) && (green >= 0x8000) && (blue >= 0x8000)) { - cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_WHITE); // white + cv7 = static_cast(AdaGFX7Colors::ADAGFX7C_WHITE); // white } else if ((red >= 0x8000) && (blue >= 0x8000)) { if (red > blue) { @@ -2366,10 +2376,10 @@ void AdafruitGFX_helper::getColors(uint16_t& fgcolor, /**************************************************************************** * calculateTextMetrics: Recalculate the text mertics based on supplied font parameters ***************************************************************************/ -void AdafruitGFX_helper::calculateTextMetrics(uint8_t fontwidth, - uint8_t fontheight, - int8_t heightOffset, - bool isProportional) { +void AdafruitGFX_helper::calculateTextMetrics(const uint8_t fontwidth, + const uint8_t fontheight, + const int8_t heightOffset, + const bool isProportional) { uint16_t res_x = _res_x; uint16_t res_y = _res_y; @@ -2416,9 +2426,9 @@ void AdafruitGFX_helper::calculateTextMetrics(uint8_t fontwidth, * If Y == 0 then X is allowed the max. value of the display size. * *** Returns TRUE when invalid !! *** ***************************************************************************/ -bool AdafruitGFX_helper::invalidCoordinates(int X, - int Y, - bool colRowMode) { +bool AdafruitGFX_helper::invalidCoordinates(const int X, + const int Y, + const bool colRowMode) { uint16_t res_x = _res_x; uint16_t res_y = _res_y; @@ -2465,7 +2475,7 @@ bool AdafruitGFX_helper::invalidCoordinates(int X, * rotate the display (and all windows) ***************************************************************************/ void AdafruitGFX_helper::setRotation(uint8_t m) { - uint8_t rotation = m & 3; + const uint8_t rotation = m & 3; _display->setRotation(m); // Set rotation 0/1/2/3 _rotation = rotation; @@ -2531,36 +2541,43 @@ void AdafruitGFX_helper::setRotation(uint8_t m) { bool AdafruitGFX_helper::showBmp(const String& filename, int16_t x, int16_t y) { - bool transact = true; // Enable transaction support to work proper with SD czrd, when enabled - bool status = false; // IMAGE_SUCCESS on valid file + uint32_t offset; // Start of image data in file + uint32_t headerSize; // Indicates BMP version + uint32_t compression = 0; // BMP compression mode + uint32_t colors = 0; // Number of colors in palette + uint32_t rowSize; // >bmpWidth if scanline padding + uint8_t sdbuf[3 * BUFPIXELS]; // BMP read buf (R+G+B/pixel) + + uint32_t destidx = 0; + uint32_t bmpPos = 0; // Next pixel position in file + int bmpWidth; // BMP width & height in pixels + int bmpHeight; + int loadWidth; + int loadHeight; // Region being loaded (clipped) + int loadX; + int loadY; // " + int row; // Current pixel pos. + int col; + uint16_t *quantized = NULL; // 16-bit 5/6/5 color palette uint16_t tftbuf[BUFPIXELS]; - uint16_t *dest = tftbuf; // TFT working buffer, or NULL if to canvas - uint32_t offset; // Start of image data in file - uint32_t headerSize; // Indicates BMP version - uint8_t planes; // BMP planes - uint8_t depth; // BMP bit depth - uint32_t compression = 0; // BMP compression mode - uint32_t colors = 0; // Number of colors in palette - uint16_t *quantized = NULL; // 16-bit 5/6/5 color palette - uint32_t rowSize; // >bmpWidth if scanline padding - uint8_t sdbuf[3 * BUFPIXELS]; // BMP read buf (R+G+B/pixel) - int bmpWidth, bmpHeight; // BMP width & height in pixels + uint16_t *dest = tftbuf; // TFT working buffer, or NULL if to canvas + int16_t drow = 0; + int16_t dcol = 0; + uint8_t planes; // BMP planes + uint8_t depth; // BMP bit depth + uint8_t r; // Current pixel colors + uint8_t g; + uint8_t b; + uint8_t bitIn = 0; // Bit number for 1-bit data in # if ((3 * BUFPIXELS) <= 255) - uint8_t srcidx = sizeof sdbuf; // Current position in sdbuf + uint8_t srcidx = sizeof sdbuf; // Current position in sdbuf # else // if ((3 * BUFPIXELS) <= 255) uint16_t srcidx = sizeof sdbuf; # endif // if ((3 * BUFPIXELS) <= 255) - uint32_t destidx = 0; - bool flip = true; // BMP is stored bottom-to-top - uint32_t bmpPos = 0; // Next pixel position in file - int loadWidth, loadHeight, // Region being loaded (clipped) - loadX, loadY; // " - int row, col; // Current pixel pos. - uint8_t r, g, b; // Current pixel color - uint8_t bitIn = 0; // Bit number for 1-bit data in - int16_t drow = 0; - int16_t dcol = 0; + bool flip = true; // BMP is stored bottom-to-top + bool transact = true; // Enable transaction support to work proper with SD czrd, when enabled + bool status = false; // IMAGE_SUCCESS on valid file bool canTransact = (nullptr != _tft); @@ -2893,9 +2910,9 @@ bool AdafruitGFX_helper::validWindow(uint8_t windowId) { /**************************************************************************** * Select this window id as the default ***************************************************************************/ -bool AdafruitGFX_helper::selectWindow(uint8_t windowId, - int8_t rotation) { - int16_t result = getWindowIndex(windowId); +bool AdafruitGFX_helper::selectWindow(const uint8_t windowId, + const int8_t rotation) { + const int16_t result = getWindowIndex(windowId); if (result != -1) { _windowIndex = result; @@ -2907,7 +2924,7 @@ bool AdafruitGFX_helper::selectWindow(uint8_t windowId, /**************************************************************************** * Return the index of the windowId in _windows, -1 if not found ***************************************************************************/ -int16_t AdafruitGFX_helper::getWindowIndex(int16_t windowId) { +int16_t AdafruitGFX_helper::getWindowIndex(const int16_t windowId) { size_t result = 0; for (auto win = _windows.begin(); win != _windows.end(); win++, result++) { @@ -2939,12 +2956,12 @@ void AdafruitGFX_helper::getWindowLimits(uint16_t& xLimit, /**************************************************************************** * Define a window and return the ID ***************************************************************************/ -uint8_t AdafruitGFX_helper::defineWindow(int16_t x, - int16_t y, - int16_t w, - int16_t h, - int16_t windowId, - int8_t rotation) { +uint8_t AdafruitGFX_helper::defineWindow(const int16_t x, + const int16_t y, + const int16_t w, + const int16_t h, + int16_t windowId, + const int8_t rotation) { int16_t result = getWindowIndex(windowId); if (result < 0) { @@ -3005,8 +3022,8 @@ uint8_t AdafruitGFX_helper::defineWindow(int16_t x, /**************************************************************************** * Remove a window definition ***************************************************************************/ -bool AdafruitGFX_helper::deleteWindow(uint8_t windowId) { - int16_t result = getWindowIndex(windowId); +bool AdafruitGFX_helper::deleteWindow(const uint8_t windowId) { + const int16_t result = getWindowIndex(windowId); if (result > -1) { _windows.erase(_windows.begin() + result); diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 38a029ef6..6f42a75d6 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -12,8 +12,9 @@ ***************************************************************************/ /************ * Changelog: + * 2022-06-07 tonhuisman: Code improvements in initialization, move offset calculation to printText() function * 2022-06-06 tonhuisman: Process any special characters for lenght and textheight values for correct sizing - * 2022-06-05 tonhuisman: Add support for getting config values: win (current window id), iswin (exists?), width and height (current window), + * 2022-06-05 tonhuisman: Add support for getting config values: win (current window id), iswin (exists?), width & height (current window), * (text)length and textheight of a provided text, rot (current rotation), txs (fontscaling), tpm (textprintmode) * 2022-06-04 tonhuisman: Add Window support for drawing and printing within confined areas (windows) * Always use exact font calculation for determining allowable text length @@ -278,8 +279,8 @@ enum class Button_layout_e : uint8_t { Alignment_MAX = 11u // options-count, max possible values: 16 }; -const __FlashStringHelper* toString(Button_type_e button); -const __FlashStringHelper* toString(Button_layout_e layout); +const __FlashStringHelper* toString(const Button_type_e button); +const __FlashStringHelper* toString(const Button_layout_e layout); # endif // if ADAGFX_ENABLE_BUTTON_DRAW @@ -302,8 +303,8 @@ struct tWindowObject { class AdafruitGFX_helper; // Forward declaration // Some generic AdafruitGFX_helper support functions -const __FlashStringHelper* toString(AdaGFXTextPrintMode mode); -const __FlashStringHelper* toString(AdaGFXColorDepth colorDepth); +const __FlashStringHelper* toString(const AdaGFXTextPrintMode mode); +const __FlashStringHelper* toString(const AdaGFXColorDepth colorDepth); void AdaGFXFormTextPrintMode(const __FlashStringHelper *id, uint8_t selectedIndex); void AdaGFXFormColorDepth(const __FlashStringHelper *id, @@ -336,47 +337,48 @@ void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, uint8_t fontScaling, uint8_t maxScale = 10); String AdaGFXparseTemplate(const String & tmpString, - uint8_t lineSize, + const uint8_t lineSize, AdafruitGFX_helper *gfxHelper = nullptr); -uint16_t AdaGFXparseColor(String & s, - AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - bool emptyIsBlack = false); // Parse either a color by name, 6 digit hex rrggbb color, or 1..4 digit - // #rgb565 color (hex with # prefix) +uint16_t AdaGFXparseColor(String & s, + const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, + const bool emptyIsBlack = false); // Parse either a color by name, 6 digit hex rrggbb color, + // or 1..4 digit + // #rgb565 color (hex with # prefix) void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, - AdaGFXColorDepth colorDepth); -String AdaGFXcolorToString(uint16_t color, - AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - bool blackIsEmpty = false); + const AdaGFXColorDepth colorDepth); +String AdaGFXcolorToString(const uint16_t color, + const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, + bool blackIsEmpty = false); # if ADAGFX_SUPPORT_7COLOR -uint16_t AdaGFXrgb565ToColor7(uint16_t color); // Convert rgb565 color to 7-color +uint16_t AdaGFXrgb565ToColor7(const uint16_t color); // Convert rgb565 color to 7-color # endif // if ADAGFX_SUPPORT_7COLOR class AdafruitGFX_helper { public: - AdafruitGFX_helper(Adafruit_GFX *display, - const String & trigger, - uint16_t res_x, - uint16_t res_y, - AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, - uint8_t fontscaling = 1, - uint16_t fgcolor = ADAGFX_WHITE, - uint16_t bgcolor = ADAGFX_BLACK, - bool useValidation = true, - bool textBackFill = false); + AdafruitGFX_helper(Adafruit_GFX *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, + const AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, + const uint8_t fontscaling = 1, + const uint16_t fgcolor = ADAGFX_WHITE, + const uint16_t bgcolor = ADAGFX_BLACK, + const bool useValidation = true, + const bool textBackFill = false); # if ADAGFX_ENABLE_BMP_DISPLAY - AdafruitGFX_helper(Adafruit_SPITFT *display, - const String & trigger, - uint16_t res_x, - uint16_t res_y, - AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, - uint8_t fontscaling = 1, - uint16_t fgcolor = ADAGFX_WHITE, - uint16_t bgcolor = ADAGFX_BLACK, - bool useValidation = true, - bool textBackFill = false); + AdafruitGFX_helper(Adafruit_SPITFT *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, + const AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, + const uint8_t fontscaling = 1, + const uint16_t fgcolor = ADAGFX_WHITE, + const uint16_t bgcolor = ADAGFX_BLACK, + const bool useValidation = true, + const bool textBackFill = false); # endif // if ADAGFX_ENABLE_BMP_DISPLAY virtual ~AdafruitGFX_helper() {} @@ -388,17 +390,17 @@ public: bool pluginGetConfigValue(String& string); // Get a config value from the plugin # endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE - void printText(const char *string, - int16_t X, - int16_t Y, - uint8_t textSize = 0, - uint16_t color = ADAGFX_WHITE, - uint16_t bkcolor = ADAGFX_BLACK, - uint16_t maxWidth = 0); - void calculateTextMetrics(uint8_t fontwidth, - uint8_t fontheight, - int8_t heightOffset = 0, - bool isProportional = false); + void printText(const char *string, + const int16_t X, + const int16_t Y, + const uint8_t textSize = 0, + const uint16_t color = ADAGFX_WHITE, + uint16_t bkcolor = ADAGFX_BLACK, + const uint16_t maxWidth = 0); + void calculateTextMetrics(const uint8_t fontwidth, + const uint8_t fontheight, + const int8_t heightOffset = 0, + const bool isProportional = false); void getTextMetrics(uint16_t& textcols, uint16_t& textrows, uint8_t & fontwidth, @@ -441,16 +443,16 @@ public: return _window; } - bool validWindow(uint8_t windowId); - bool selectWindow(uint8_t windowId, - int8_t rotation = -1); - uint8_t defineWindow(int16_t x, - int16_t y, - int16_t w, - int16_t h, - int16_t windowId = -1, - int8_t rotation = -1); - bool deleteWindow(uint8_t windowId); + bool validWindow(const uint8_t windowId); + bool selectWindow(const uint8_t windowId, + const int8_t rotation = -1); + uint8_t defineWindow(const int16_t x, + const int16_t y, + const int16_t w, + const int16_t h, + int16_t windowId = -1, + const int8_t rotation = -1); + bool deleteWindow(const uint8_t windowId); # endif // if ADAGFX_ENABLE_FRAMED_WINDOW private: @@ -458,9 +460,9 @@ private: void initialize(); # if ADAGFX_ARGUMENT_VALIDATION - bool invalidCoordinates(int X, - int Y, - bool colRowMode = false); + bool invalidCoordinates(const int X, + const int Y, + const bool colRowMode = false); # endif // if ADAGFX_ARGUMENT_VALIDATION # if ADAGFX_ENABLE_BUTTON_DRAW void drawButtonShape(Button_type_e buttonType, @@ -504,7 +506,7 @@ private: fs::File file; # endif // if ADAGFX_ENABLE_BMP_DISPLAY # if ADAGFX_ENABLE_FRAMED_WINDOW - int16_t getWindowIndex(int16_t windowId); + int16_t getWindowIndex(const int16_t windowId); void logWindows(const String& prefix = EMPTY_STRING); void getWindowOffsets(uint16_t& xOffset, uint16_t& yOffset); From 16f2be76a60dbf9c5a28fb1cbb572526d4a52028 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 8 Jun 2022 22:27:35 +0200 Subject: [PATCH 10/32] [AdaGFX] Code improvements as suggested by feedback (cherry picked from commit 555e30d261ccd8d57d7af83e85821709a3e650f5) --- src/src/Helpers/AdafruitGFX_helper.cpp | 134 ++++++++++++------------- src/src/Helpers/AdafruitGFX_helper.h | 118 +++++++++++----------- 2 files changed, 126 insertions(+), 126 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index ee02ff1c7..ed62e34ef 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -71,7 +71,7 @@ /****************************************************************************************** * get the display text for a 'text print mode' enum value *****************************************************************************************/ -const __FlashStringHelper* toString(const AdaGFXTextPrintMode mode) { +const __FlashStringHelper* toString(const AdaGFXTextPrintMode& mode) { switch (mode) { case AdaGFXTextPrintMode::ContinueToNextLine: return F("Continue to next line"); case AdaGFXTextPrintMode::TruncateExceedingMessage: return F("Truncate exceeding message"); @@ -85,7 +85,7 @@ const __FlashStringHelper* toString(const AdaGFXTextPrintMode mode) { /****************************************************************************************** * get the display text for a color depth enum value *****************************************************************************************/ -const __FlashStringHelper* toString(const AdaGFXColorDepth colorDepth) { +const __FlashStringHelper* toString(const AdaGFXColorDepth& colorDepth) { switch (colorDepth) { case AdaGFXColorDepth::Monochrome: return F("Monochrome"); case AdaGFXColorDepth::BlackWhiteRed: return F("Monochrome + 1 color"); @@ -531,17 +531,17 @@ String AdaGFXparseTemplate(const String & tmpString, /**************************************************************************** * parameterized constructors ***************************************************************************/ -AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, - const String & trigger, - const uint16_t res_x, - const uint16_t res_y, - const AdaGFXColorDepth colorDepth, - const AdaGFXTextPrintMode textPrintMode, - const uint8_t fontscaling, - const uint16_t fgcolor, - const uint16_t bgcolor, - const bool useValidation, - const bool textBackFill) +AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth & colorDepth, + const AdaGFXTextPrintMode& textPrintMode, + const uint8_t fontscaling, + const uint16_t fgcolor, + const uint16_t bgcolor, + const bool useValidation, + const bool textBackFill) : _display(display), _trigger(trigger), _res_x(res_x), _res_y(res_y), _colorDepth(colorDepth), _textPrintMode(textPrintMode), _fontscaling(fontscaling), _fgcolor(fgcolor), _bgcolor(bgcolor), _useValidation(useValidation), _textBackFill(textBackFill) @@ -551,17 +551,17 @@ AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_GFX *display, } # if ADAGFX_ENABLE_BMP_DISPLAY -AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, - const String & trigger, - const uint16_t res_x, - const uint16_t res_y, - const AdaGFXColorDepth colorDepth, - const AdaGFXTextPrintMode textPrintMode, - const uint8_t fontscaling, - const uint16_t fgcolor, - const uint16_t bgcolor, - const bool useValidation, - const bool textBackFill) +AdafruitGFX_helper::AdafruitGFX_helper(Adafruit_SPITFT *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth & colorDepth, + const AdaGFXTextPrintMode& textPrintMode, + const uint8_t fontscaling, + const uint16_t fgcolor, + const uint16_t bgcolor, + const bool useValidation, + const bool textBackFill) : _tft(display), _trigger(trigger), _res_x(res_x), _res_y(res_y), _colorDepth(colorDepth), _textPrintMode(textPrintMode), _fontscaling(fontscaling), _fgcolor(fgcolor), _bgcolor(bgcolor), _useValidation(useValidation), _textBackFill(textBackFill) @@ -1646,7 +1646,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # if ADAGFX_ARGUMENT_VALIDATION const int16_t curWin = getWindow(); - if (curWin != 0) { selectWindow(0); } // Validate against raw window coordinates + if (curWin != 0) { selectWindow(0); } // Validate against raw window coordinates if (argCount == 6) { setRotation(nParams[5]); } // Use requested rotation @@ -1776,13 +1776,13 @@ bool AdafruitGFX_helper::pluginGetConfigValue(String& string) { /**************************************************************************** * draw a button shape with provided color, can also clear a previously drawn button ***************************************************************************/ -void AdafruitGFX_helper::drawButtonShape(Button_type_e buttonType, - int x, - int y, - int w, - int h, - uint16_t fillColor, - uint16_t borderColor) { +void AdafruitGFX_helper::drawButtonShape(const Button_type_e& buttonType, + const int & x, + const int & y, + const int & w, + const int & h, + const uint16_t & fillColor, + const uint16_t & borderColor) { switch (buttonType) { case Button_type_e::Square: // Rectangle { @@ -1845,13 +1845,13 @@ void AdafruitGFX_helper::drawButtonShape(Button_type_e buttonType, /**************************************************************************** * printText: Print text on display at a specific pixel or column/row location ***************************************************************************/ -void AdafruitGFX_helper::printText(const char *string, - const int16_t X, - const int16_t Y, - const uint8_t textSize, - const uint16_t color, - uint16_t bkcolor, - const uint16_t maxWidth) { +void AdafruitGFX_helper::printText(const char *string, + const int16_t & X, + const int16_t & Y, + const uint8_t & textSize, + const uint16_t& color, + uint16_t bkcolor, + const uint16_t& maxWidth) { int16_t _x = X; int16_t _y = Y + (_heightOffset * textSize); uint16_t _w = 0; @@ -1960,9 +1960,9 @@ void AdafruitGFX_helper::printText(const char *string, /**************************************************************************** * color565: convert r, g, b colors to rgb565 (by bit-shifting) ***************************************************************************/ -uint16_t color565(const uint8_t red, - const uint8_t green, - const uint8_t blue) { +uint16_t color565(const uint8_t& red, + const uint8_t& green, + const uint8_t& blue) { return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); } @@ -1976,9 +1976,9 @@ uint16_t color565(const uint8_t red, // Param [in] colorDepth: The requiresed color depth, default: FullColor // param [in] defaultWhite: Return White color if empty, default: true // return : color (default ADAGFX_WHITE) -uint16_t AdaGFXparseColor(String & s, - const AdaGFXColorDepth colorDepth, - const bool emptyIsBlack) { +uint16_t AdaGFXparseColor(String & s, + const AdaGFXColorDepth& colorDepth, + const bool emptyIsBlack) { s.toLowerCase(); int32_t result = -1; // No result yet @@ -2116,9 +2116,9 @@ uint16_t AdaGFXparseColor(String & s, return static_cast(result); } -const __FlashStringHelper* AdaGFXcolorToString_internal(uint16_t color, - AdaGFXColorDepth colorDepth, - bool blackIsEmpty); +const __FlashStringHelper* AdaGFXcolorToString_internal(const uint16_t & color, + const AdaGFXColorDepth& colorDepth, + bool blackIsEmpty); // Add a single optionvalue of a color to a datalist (internal/private) void AdaGFXaddHtmlDataListColorOptionValue(uint16_t color, @@ -2138,7 +2138,7 @@ void AdaGFXaddHtmlDataListColorOptionValue(uint16_t color, * Generate a html 'datalist' of the colors available for selected colorDepth, with id provided ****************************************************************************************/ void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, - const AdaGFXColorDepth colorDepth) { + const AdaGFXColorDepth & colorDepth) { addHtml(F("")); @@ -2199,9 +2199,9 @@ void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, /***************************************************************************************** * Convert an RGB565 color (number) to it's name or the #rgb565 hex string, based on depth ****************************************************************************************/ -String AdaGFXcolorToString(const uint16_t color, - const AdaGFXColorDepth colorDepth, - bool blackIsEmpty) { +String AdaGFXcolorToString(const uint16_t & color, + const AdaGFXColorDepth& colorDepth, + bool blackIsEmpty) { String result = AdaGFXcolorToString_internal(color, colorDepth, blackIsEmpty); if (result.equals(F("*"))) { @@ -2212,9 +2212,9 @@ String AdaGFXcolorToString(const uint16_t color, return result; } -const __FlashStringHelper* AdaGFXcolorToString_internal(uint16_t color, - AdaGFXColorDepth colorDepth, - bool blackIsEmpty) { +const __FlashStringHelper* AdaGFXcolorToString_internal(const uint16_t & color, + const AdaGFXColorDepth& colorDepth, + bool blackIsEmpty) { switch (colorDepth) { case AdaGFXColorDepth::Monochrome: case AdaGFXColorDepth::BlackWhiteRed: @@ -2290,7 +2290,7 @@ const __FlashStringHelper* AdaGFXcolorToString_internal(uint16_t color, * AdaGFXrgb565ToColor7: Convert a rgb565 color to the 7 colors supported by 7-color eInk displays * Borrowed from https://github.com/ZinggJM/GxEPD2 color7() routine ***************************************************************************/ -uint16_t AdaGFXrgb565ToColor7(const uint16_t color) { +uint16_t AdaGFXrgb565ToColor7(const uint16_t& color) { const uint16_t red = (color & 0xF800); const uint16_t green = (color & 0x07E0) << 5; const uint16_t blue = (color & 0x001F) << 11; @@ -2903,15 +2903,15 @@ uint32_t AdafruitGFX_helper::readLE32(void) { /**************************************************************************** * Check if the requested id is a valid window id ***************************************************************************/ -bool AdafruitGFX_helper::validWindow(uint8_t windowId) { +bool AdafruitGFX_helper::validWindow(const uint8_t& windowId) { return getWindowIndex(windowId) != -1; } /**************************************************************************** * Select this window id as the default ***************************************************************************/ -bool AdafruitGFX_helper::selectWindow(const uint8_t windowId, - const int8_t rotation) { +bool AdafruitGFX_helper::selectWindow(const uint8_t& windowId, + const int8_t & rotation) { const int16_t result = getWindowIndex(windowId); if (result != -1) { @@ -2924,7 +2924,7 @@ bool AdafruitGFX_helper::selectWindow(const uint8_t windowId, /**************************************************************************** * Return the index of the windowId in _windows, -1 if not found ***************************************************************************/ -int16_t AdafruitGFX_helper::getWindowIndex(const int16_t windowId) { +int16_t AdafruitGFX_helper::getWindowIndex(const int16_t& windowId) { size_t result = 0; for (auto win = _windows.begin(); win != _windows.end(); win++, result++) { @@ -2956,12 +2956,12 @@ void AdafruitGFX_helper::getWindowLimits(uint16_t& xLimit, /**************************************************************************** * Define a window and return the ID ***************************************************************************/ -uint8_t AdafruitGFX_helper::defineWindow(const int16_t x, - const int16_t y, - const int16_t w, - const int16_t h, - int16_t windowId, - const int8_t rotation) { +uint8_t AdafruitGFX_helper::defineWindow(const int16_t& x, + const int16_t& y, + const int16_t& w, + const int16_t& h, + int16_t windowId, + const int8_t & rotation) { int16_t result = getWindowIndex(windowId); if (result < 0) { @@ -3022,7 +3022,7 @@ uint8_t AdafruitGFX_helper::defineWindow(const int16_t x, /**************************************************************************** * Remove a window definition ***************************************************************************/ -bool AdafruitGFX_helper::deleteWindow(const uint8_t windowId) { +bool AdafruitGFX_helper::deleteWindow(const uint8_t& windowId) { const int16_t result = getWindowIndex(windowId); if (result > -1) { diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index 6f42a75d6..c879da64d 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -303,8 +303,8 @@ struct tWindowObject { class AdafruitGFX_helper; // Forward declaration // Some generic AdafruitGFX_helper support functions -const __FlashStringHelper* toString(const AdaGFXTextPrintMode mode); -const __FlashStringHelper* toString(const AdaGFXColorDepth colorDepth); +const __FlashStringHelper* toString(const AdaGFXTextPrintMode& mode); +const __FlashStringHelper* toString(const AdaGFXColorDepth& colorDepth); void AdaGFXFormTextPrintMode(const __FlashStringHelper *id, uint8_t selectedIndex); void AdaGFXFormColorDepth(const __FlashStringHelper *id, @@ -339,46 +339,46 @@ void AdaGFXFormFontScaling(const __FlashStringHelper *fontScalingId, String AdaGFXparseTemplate(const String & tmpString, const uint8_t lineSize, AdafruitGFX_helper *gfxHelper = nullptr); -uint16_t AdaGFXparseColor(String & s, - const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - const bool emptyIsBlack = false); // Parse either a color by name, 6 digit hex rrggbb color, - // or 1..4 digit - // #rgb565 color (hex with # prefix) +uint16_t AdaGFXparseColor(String & s, + const AdaGFXColorDepth& colorDepth = AdaGFXColorDepth::FullColor, + const bool emptyIsBlack = false); // Parse either a color by name, 6 digit hex rrggbb color, + // or 1..4 digit + // #rgb565 color (hex with # prefix) void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, - const AdaGFXColorDepth colorDepth); -String AdaGFXcolorToString(const uint16_t color, - const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - bool blackIsEmpty = false); + const AdaGFXColorDepth & colorDepth); +String AdaGFXcolorToString(const uint16_t & color, + const AdaGFXColorDepth& colorDepth = AdaGFXColorDepth::FullColor, + bool blackIsEmpty = false); # if ADAGFX_SUPPORT_7COLOR -uint16_t AdaGFXrgb565ToColor7(const uint16_t color); // Convert rgb565 color to 7-color +uint16_t AdaGFXrgb565ToColor7(const uint16_t& color); // Convert rgb565 color to 7-color # endif // if ADAGFX_SUPPORT_7COLOR class AdafruitGFX_helper { public: - AdafruitGFX_helper(Adafruit_GFX *display, - const String & trigger, - const uint16_t res_x, - const uint16_t res_y, - const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - const AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, - const uint8_t fontscaling = 1, - const uint16_t fgcolor = ADAGFX_WHITE, - const uint16_t bgcolor = ADAGFX_BLACK, - const bool useValidation = true, - const bool textBackFill = false); + AdafruitGFX_helper(Adafruit_GFX *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth & colorDepth = AdaGFXColorDepth::FullColor, + const AdaGFXTextPrintMode& textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, + const uint8_t fontscaling = 1, + const uint16_t fgcolor = ADAGFX_WHITE, + const uint16_t bgcolor = ADAGFX_BLACK, + const bool useValidation = true, + const bool textBackFill = false); # if ADAGFX_ENABLE_BMP_DISPLAY - AdafruitGFX_helper(Adafruit_SPITFT *display, - const String & trigger, - const uint16_t res_x, - const uint16_t res_y, - const AdaGFXColorDepth colorDepth = AdaGFXColorDepth::FullColor, - const AdaGFXTextPrintMode textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, - const uint8_t fontscaling = 1, - const uint16_t fgcolor = ADAGFX_WHITE, - const uint16_t bgcolor = ADAGFX_BLACK, - const bool useValidation = true, - const bool textBackFill = false); + AdafruitGFX_helper(Adafruit_SPITFT *display, + const String & trigger, + const uint16_t res_x, + const uint16_t res_y, + const AdaGFXColorDepth & colorDepth = AdaGFXColorDepth::FullColor, + const AdaGFXTextPrintMode& textPrintMode = AdaGFXTextPrintMode::ContinueToNextLine, + const uint8_t fontscaling = 1, + const uint16_t fgcolor = ADAGFX_WHITE, + const uint16_t bgcolor = ADAGFX_BLACK, + const bool useValidation = true, + const bool textBackFill = false); # endif // if ADAGFX_ENABLE_BMP_DISPLAY virtual ~AdafruitGFX_helper() {} @@ -390,13 +390,13 @@ public: bool pluginGetConfigValue(String& string); // Get a config value from the plugin # endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE - void printText(const char *string, - const int16_t X, - const int16_t Y, - const uint8_t textSize = 0, - const uint16_t color = ADAGFX_WHITE, - uint16_t bkcolor = ADAGFX_BLACK, - const uint16_t maxWidth = 0); + void printText(const char *string, + const int16_t & X, + const int16_t & Y, + const uint8_t & textSize = 0, + const uint16_t& color = ADAGFX_WHITE, + uint16_t bkcolor = ADAGFX_BLACK, + const uint16_t& maxWidth = 0); void calculateTextMetrics(const uint8_t fontwidth, const uint8_t fontheight, const int8_t heightOffset = 0, @@ -443,16 +443,16 @@ public: return _window; } - bool validWindow(const uint8_t windowId); - bool selectWindow(const uint8_t windowId, - const int8_t rotation = -1); - uint8_t defineWindow(const int16_t x, - const int16_t y, - const int16_t w, - const int16_t h, - int16_t windowId = -1, - const int8_t rotation = -1); - bool deleteWindow(const uint8_t windowId); + bool validWindow(const uint8_t& windowId); + bool selectWindow(const uint8_t& windowId, + const int8_t & rotation = -1); + uint8_t defineWindow(const int16_t& x, + const int16_t& y, + const int16_t& w, + const int16_t& h, + int16_t windowId = -1, + const int8_t & rotation = -1); + bool deleteWindow(const uint8_t& windowId); # endif // if ADAGFX_ENABLE_FRAMED_WINDOW private: @@ -465,13 +465,13 @@ private: const bool colRowMode = false); # endif // if ADAGFX_ARGUMENT_VALIDATION # if ADAGFX_ENABLE_BUTTON_DRAW - void drawButtonShape(Button_type_e buttonType, - int x, - int y, - int w, - int h, - uint16_t fillColor, - uint16_t borderColor); + void drawButtonShape(const Button_type_e& buttonType, + const int & x, + const int & y, + const int & w, + const int & h, + const uint16_t & fillColor, + const uint16_t & borderColor); # endif // if ADAGFX_ENABLE_BUTTON_DRAW Adafruit_GFX *_display = nullptr; @@ -506,7 +506,7 @@ private: fs::File file; # endif // if ADAGFX_ENABLE_BMP_DISPLAY # if ADAGFX_ENABLE_FRAMED_WINDOW - int16_t getWindowIndex(const int16_t windowId); + int16_t getWindowIndex(const int16_t& windowId); void logWindows(const String& prefix = EMPTY_STRING); void getWindowOffsets(uint16_t& xOffset, uint16_t& yOffset); From d2b1a5c45ce2589fab2245408445f2b4de43276a Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 9 Jun 2022 20:23:09 +0200 Subject: [PATCH 11/32] [AdaGFX] Correct font include paths, add #ifndef filename checks to fonts (cherry picked from commit 6c25b139aaa639b2098fa0a20148114a0baaa9e1) --- src/src/Helpers/AdafruitGFX_helper.cpp | 57 +-- src/src/Static/Fonts/AmerikaSans16pt7b.h | 195 ++++----- src/src/Static/Fonts/FreeSans9pt7b.h | 391 +++++++++--------- src/src/Static/Fonts/NovaMono12pt7b.h | 195 ++++----- src/src/Static/Fonts/NovaMono8pt7b.h | 195 ++++----- .../Static/Fonts/RepetitionScrolling12pt7b.h | 195 ++++----- .../Fonts/RobotoCondensed_Regular12pt7b.h | 195 ++++----- .../Fonts/RobotoCondensed_Regular16pt7b.h | 195 ++++----- .../Fonts/RobotoCondensed_Regular8pt7b.h | 195 ++++----- .../Static/Fonts/RobotoMono_Regular12pt7b.h | 195 ++++----- .../Static/Fonts/RobotoMono_Regular16pt7b.h | 195 ++++----- .../Static/Fonts/RobotoMono_Regular8pt7b.h | 195 ++++----- src/src/Static/Fonts/Roboto_Regular12pt7b.h | 195 ++++----- src/src/Static/Fonts/Roboto_Regular16pt7b.h | 195 ++++----- src/src/Static/Fonts/Roboto_Regular8pt7b.h | 195 ++++----- src/src/Static/Fonts/Seven_Segment18pt7b.h | 195 ++++----- src/src/Static/Fonts/Seven_Segment24pt7b.h | 195 ++++----- src/src/Static/Fonts/angelina12pt7b.h | 195 ++++----- src/src/Static/Fonts/angelina8pt7b.h | 195 ++++----- src/src/Static/Fonts/unispace12pt7b.h | 195 ++++----- src/src/Static/Fonts/unispace8pt7b.h | 195 ++++----- src/src/Static/Fonts/unispace_italic12pt7b.h | 195 ++++----- src/src/Static/Fonts/unispace_italic8pt7b.h | 195 ++++----- src/src/Static/Fonts/whitrabt12pt7b.h | 195 ++++----- src/src/Static/Fonts/whitrabt16pt7b.h | 195 ++++----- src/src/Static/Fonts/whitrabt18pt7b.h | 195 ++++----- src/src/Static/Fonts/whitrabt20pt7b.h | 195 ++++----- src/src/Static/Fonts/whitrabt8pt7b.h | 195 ++++----- 28 files changed, 2800 insertions(+), 2718 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index ed62e34ef..72bab020e 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -11,60 +11,60 @@ # include # if ADAGFX_FONTS_INCLUDED -# include "src/Static/Fonts/Seven_Segment24pt7b.h" -# include "src/Static/Fonts/Seven_Segment18pt7b.h" -# include "src/Static/Fonts/FreeSans9pt7b.h" +# include "../Static/Fonts/Seven_Segment24pt7b.h" +# include "../Static/Fonts/Seven_Segment18pt7b.h" +# include "../Static/Fonts/FreeSans9pt7b.h" # ifdef ADAGFX_FONTS_EXTRA_8PT_INCLUDED -# include "src/Static/Fonts/angelina8pt7b.h" -# include "src/Static/Fonts/NovaMono8pt7b.h" -# include "src/Static/Fonts/unispace8pt7b.h" -# include "src/Static/Fonts/unispace_italic8pt7b.h" -# include "src/Static/Fonts/whitrabt8pt7b.h" +# include "../Static/Fonts/angelina8pt7b.h" +# include "../Static/Fonts/NovaMono8pt7b.h" +# include "../Static/Fonts/unispace8pt7b.h" +# include "../Static/Fonts/unispace_italic8pt7b.h" +# include "../Static/Fonts/whitrabt8pt7b.h" # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO -# include "src/Static/Fonts/Roboto_Regular8pt7b.h" +# include "../Static/Fonts/Roboto_Regular8pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTO # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED -# include "src/Static/Fonts/RobotoCondensed_Regular8pt7b.h" +# include "../Static/Fonts/RobotoCondensed_Regular8pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOCONDENSED # ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO -# include "src/Static/Fonts/RobotoMono_Regular8pt7b.h" +# include "../Static/Fonts/RobotoMono_Regular8pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_8PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED -# include "src/Static/Fonts/angelina12pt7b.h" -# include "src/Static/Fonts/NovaMono12pt7b.h" -# include "src/Static/Fonts/RepetitionScrolling12pt7b.h" -# include "src/Static/Fonts/unispace12pt7b.h" -# include "src/Static/Fonts/unispace_italic12pt7b.h" -# include "src/Static/Fonts/whitrabt12pt7b.h" +# include "../Static/Fonts/angelina12pt7b.h" +# include "../Static/Fonts/NovaMono12pt7b.h" +# include "../Static/Fonts/RepetitionScrolling12pt7b.h" +# include "../Static/Fonts/unispace12pt7b.h" +# include "../Static/Fonts/unispace_italic12pt7b.h" +# include "../Static/Fonts/whitrabt12pt7b.h" # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO -# include "src/Static/Fonts/Roboto_Regular12pt7b.h" +# include "../Static/Fonts/Roboto_Regular12pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTO # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED -# include "src/Static/Fonts/RobotoCondensed_Regular12pt7b.h" +# include "../Static/Fonts/RobotoCondensed_Regular12pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOCONDENSED # ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO -# include "src/Static/Fonts/RobotoMono_Regular12pt7b.h" +# include "../Static/Fonts/RobotoMono_Regular12pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_12PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED -# include "src/Static/Fonts/AmerikaSans16pt7b.h" -# include "src/Static/Fonts/whitrabt16pt7b.h" +# include "../Static/Fonts/AmerikaSans16pt7b.h" +# include "../Static/Fonts/whitrabt16pt7b.h" # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO -# include "src/Static/Fonts/Roboto_Regular16pt7b.h" +# include "../Static/Fonts/Roboto_Regular16pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTO # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED -# include "src/Static/Fonts/RobotoCondensed_Regular16pt7b.h" +# include "../Static/Fonts/RobotoCondensed_Regular16pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOCONDENSED # ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO -# include "src/Static/Fonts/RobotoMono_Regular16pt7b.h" +# include "../Static/Fonts/RobotoMono_Regular16pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_ROBOTOMONO # endif // ifdef ADAGFX_FONTS_EXTRA_16PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_18PT_INCLUDED -# include "src/Static/Fonts/whitrabt18pt7b.h" +# include "../Static/Fonts/whitrabt18pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_18PT_INCLUDED # ifdef ADAGFX_FONTS_EXTRA_20PT_INCLUDED -# include "src/Static/Fonts/whitrabt20pt7b.h" +# include "../Static/Fonts/whitrabt20pt7b.h" # endif // ifdef ADAGFX_FONTS_EXTRA_20PT_INCLUDED # endif // if ADAGFX_FONTS_INCLUDED @@ -1688,6 +1688,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { } else { success = false; } + // logWindows(F(" deFwin ")); // Use for debugging only? } } @@ -1947,7 +1948,7 @@ void AdafruitGFX_helper::printText(const char *string, if (_textPrintMode == AdaGFXTextPrintMode::ClearThenTruncate) { _display->fillRect(_x + oTop, yText, res_x - (_x - xOffset), hText + oBottom, bkcolor); // Clear text area to right edge of screen } else { - _display->fillRect(_x + oTop, yText, _w, hText + oBottom, bkcolor); // Clear text area + _display->fillRect(_x + oTop, yText, _w, hText + oBottom, bkcolor); // Clear text area } delay(0); diff --git a/src/src/Static/Fonts/AmerikaSans16pt7b.h b/src/src/Static/Fonts/AmerikaSans16pt7b.h index d98ffd03f..138bb4538 100644 --- a/src/src/Static/Fonts/AmerikaSans16pt7b.h +++ b/src/src/Static/Fonts/AmerikaSans16pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_AMERIKASANS16PT7B_H +#define FONTS_AMERIKASANS16PT7B_H const uint8_t AmerikaSans16pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0xE6, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x60, 0xE7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x62, 0x03, 0x0C, 0x02, 0x08, @@ -302,105 +304,106 @@ const uint8_t AmerikaSans16pt7bBitmaps[] PROGMEM = { 0x3E, 0x0B, 0xFF, 0xF0, 0x7C, 0x01, 0xC0 }; const GFXglyph AmerikaSans16pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 11, 0, 0 }, // 0x20 ' ' - { 1, 4, 23, 7, 2, -22 }, // 0x21 '!' - { 13, 8, 7, 9, 1, -22 }, // 0x22 '"' - { 20, 16, 15, 18, 1, -22 }, // 0x23 '#' - { 50, 13, 23, 15, 1, -22 }, // 0x24 '$' - { 88, 24, 23, 27, 2, -22 }, // 0x25 '%' - { 157, 17, 23, 19, 2, -22 }, // 0x26 '&' - { 206, 3, 7, 5, 1, -22 }, // 0x27 ''' - { 209, 10, 27, 10, 1, -24 }, // 0x28 '(' - { 243, 10, 27, 10, -1, -24 }, // 0x29 ')' - { 277, 10, 11, 13, 2, -22 }, // 0x2A '*' - { 291, 14, 14, 16, 1, -17 }, // 0x2B '+' - { 316, 4, 8, 7, 2, -3 }, // 0x2C ',' - { 320, 8, 2, 12, 2, -8 }, // 0x2D '-' - { 322, 4, 4, 6, 1, -3 }, // 0x2E '.' - { 324, 18, 26, 15, -1, -23 }, // 0x2F '/' - { 383, 18, 23, 21, 2, -22 }, // 0x30 '0' - { 435, 7, 23, 9, 1, -22 }, // 0x31 '1' - { 456, 16, 23, 18, 1, -22 }, // 0x32 '2' - { 502, 14, 23, 17, 2, -22 }, // 0x33 '3' - { 543, 17, 23, 19, 1, -22 }, // 0x34 '4' - { 592, 15, 23, 16, 1, -22 }, // 0x35 '5' - { 636, 16, 23, 19, 2, -22 }, // 0x36 '6' - { 682, 14, 23, 17, 2, -22 }, // 0x37 '7' - { 723, 16, 23, 19, 2, -22 }, // 0x38 '8' - { 769, 16, 23, 19, 2, -22 }, // 0x39 '9' - { 815, 4, 12, 6, 1, -11 }, // 0x3A ':' - { 821, 4, 16, 6, 1, -11 }, // 0x3B ';' - { 829, 15, 14, 16, 1, -15 }, // 0x3C '<' - { 856, 12, 8, 13, 1, -13 }, // 0x3D '=' - { 868, 15, 14, 16, 1, -15 }, // 0x3E '>' - { 895, 15, 23, 17, 1, -22 }, // 0x3F '?' - { 939, 27, 27, 30, 2, -22 }, // 0x40 '@' - { 1031, 18, 23, 21, 2, -22 }, // 0x41 'A' - { 1083, 16, 23, 17, 1, -22 }, // 0x42 'B' - { 1129, 21, 23, 23, 2, -22 }, // 0x43 'C' - { 1190, 18, 23, 20, 1, -22 }, // 0x44 'D' - { 1242, 16, 23, 18, 1, -22 }, // 0x45 'E' - { 1288, 12, 23, 14, 2, -22 }, // 0x46 'F' - { 1323, 19, 29, 22, 2, -22 }, // 0x47 'G' - { 1392, 15, 23, 17, 1, -22 }, // 0x48 'H' - { 1436, 4, 23, 6, 1, -22 }, // 0x49 'I' - { 1448, 10, 29, 7, -4, -22 }, // 0x4A 'J' - { 1485, 17, 23, 19, 1, -22 }, // 0x4B 'K' - { 1534, 16, 23, 18, 1, -22 }, // 0x4C 'L' - { 1580, 24, 26, 26, 1, -25 }, // 0x4D 'M' - { 1658, 19, 23, 21, 1, -22 }, // 0x4E 'N' - { 1713, 19, 23, 21, 1, -22 }, // 0x4F 'O' - { 1768, 19, 23, 20, 1, -22 }, // 0x50 'P' - { 1823, 19, 29, 21, 1, -22 }, // 0x51 'Q' - { 1892, 20, 23, 22, 1, -22 }, // 0x52 'R' - { 1950, 16, 23, 18, 1, -22 }, // 0x53 'S' - { 1996, 20, 23, 20, 0, -22 }, // 0x54 'T' - { 2054, 19, 23, 21, 1, -22 }, // 0x55 'U' - { 2109, 21, 23, 22, 1, -22 }, // 0x56 'V' - { 2170, 24, 23, 26, 1, -22 }, // 0x57 'W' - { 2239, 16, 23, 19, 2, -22 }, // 0x58 'X' - { 2285, 19, 23, 21, 1, -22 }, // 0x59 'Y' - { 2340, 21, 23, 22, 1, -22 }, // 0x5A 'Z' - { 2401, 9, 23, 11, 2, -22 }, // 0x5B '[' - { 2427, 18, 27, 15, -1, -24 }, // 0x5C '\' - { 2488, 9, 23, 11, 1, -22 }, // 0x5D ']' - { 2514, 12, 8, 13, 1, -21 }, // 0x5E '^' - { 2526, 12, 2, 13, 1, 0 }, // 0x5F '_' - { 2529, 8, 5, 20, 6, -30 }, // 0x60 '`' - { 2534, 17, 16, 18, 1, -15 }, // 0x61 'a' - { 2568, 16, 23, 18, 2, -22 }, // 0x62 'b' - { 2614, 14, 16, 17, 2, -15 }, // 0x63 'c' - { 2642, 17, 23, 18, 1, -22 }, // 0x64 'd' - { 2691, 15, 15, 18, 2, -14 }, // 0x65 'e' - { 2720, 12, 29, 14, 1, -22 }, // 0x66 'f' - { 2764, 19, 21, 21, 1, -14 }, // 0x67 'g' - { 2814, 15, 23, 18, 2, -22 }, // 0x68 'h' - { 2858, 5, 23, 7, 2, -22 }, // 0x69 'i' - { 2873, 10, 29, 7, -3, -22 }, // 0x6A 'j' - { 2910, 17, 29, 20, 2, -22 }, // 0x6B 'k' - { 2972, 9, 23, 10, 2, -22 }, // 0x6C 'l' - { 2998, 28, 16, 30, 1, -15 }, // 0x6D 'm' - { 3054, 16, 15, 18, 1, -14 }, // 0x6E 'n' - { 3084, 17, 16, 18, 1, -15 }, // 0x6F 'o' - { 3118, 17, 22, 18, 1, -15 }, // 0x70 'p' - { 3165, 19, 21, 21, 1, -14 }, // 0x71 'q' - { 3215, 11, 16, 12, 1, -15 }, // 0x72 'r' - { 3237, 11, 16, 13, 1, -15 }, // 0x73 's' - { 3259, 12, 23, 11, 0, -22 }, // 0x74 't' - { 3294, 16, 16, 18, 1, -15 }, // 0x75 'u' - { 3326, 15, 16, 16, 1, -15 }, // 0x76 'v' - { 3356, 28, 16, 30, 1, -15 }, // 0x77 'w' - { 3412, 13, 16, 16, 2, -15 }, // 0x78 'x' - { 3438, 16, 22, 18, 1, -15 }, // 0x79 'y' - { 3482, 15, 16, 17, 1, -15 }, // 0x7A 'z' - { 3512, 13, 23, 15, 1, -22 }, // 0x7B '{' - { 3550, 3, 31, 7, 2, -26 }, // 0x7C '|' - { 3562, 13, 23, 15, 1, -22 }, // 0x7D '}' - { 3600, 13, 4, 15, 1, -18 } }; // 0x7E '~' + { 0, 1, 1, 11, 0, 0 }, // 0x20 ' ' + { 1, 4, 23, 7, 2, -22 }, // 0x21 '!' + { 13, 8, 7, 9, 1, -22 }, // 0x22 '"' + { 20, 16, 15, 18, 1, -22 }, // 0x23 '#' + { 50, 13, 23, 15, 1, -22 }, // 0x24 '$' + { 88, 24, 23, 27, 2, -22 }, // 0x25 '%' + { 157, 17, 23, 19, 2, -22 }, // 0x26 '&' + { 206, 3, 7, 5, 1, -22 }, // 0x27 ''' + { 209, 10, 27, 10, 1, -24 }, // 0x28 '(' + { 243, 10, 27, 10, -1, -24 }, // 0x29 ')' + { 277, 10, 11, 13, 2, -22 }, // 0x2A '*' + { 291, 14, 14, 16, 1, -17 }, // 0x2B '+' + { 316, 4, 8, 7, 2, -3 }, // 0x2C ',' + { 320, 8, 2, 12, 2, -8 }, // 0x2D '-' + { 322, 4, 4, 6, 1, -3 }, // 0x2E '.' + { 324, 18, 26, 15, -1, -23 }, // 0x2F '/' + { 383, 18, 23, 21, 2, -22 }, // 0x30 '0' + { 435, 7, 23, 9, 1, -22 }, // 0x31 '1' + { 456, 16, 23, 18, 1, -22 }, // 0x32 '2' + { 502, 14, 23, 17, 2, -22 }, // 0x33 '3' + { 543, 17, 23, 19, 1, -22 }, // 0x34 '4' + { 592, 15, 23, 16, 1, -22 }, // 0x35 '5' + { 636, 16, 23, 19, 2, -22 }, // 0x36 '6' + { 682, 14, 23, 17, 2, -22 }, // 0x37 '7' + { 723, 16, 23, 19, 2, -22 }, // 0x38 '8' + { 769, 16, 23, 19, 2, -22 }, // 0x39 '9' + { 815, 4, 12, 6, 1, -11 }, // 0x3A ':' + { 821, 4, 16, 6, 1, -11 }, // 0x3B ';' + { 829, 15, 14, 16, 1, -15 }, // 0x3C '<' + { 856, 12, 8, 13, 1, -13 }, // 0x3D '=' + { 868, 15, 14, 16, 1, -15 }, // 0x3E '>' + { 895, 15, 23, 17, 1, -22 }, // 0x3F '?' + { 939, 27, 27, 30, 2, -22 }, // 0x40 '@' + { 1031, 18, 23, 21, 2, -22 }, // 0x41 'A' + { 1083, 16, 23, 17, 1, -22 }, // 0x42 'B' + { 1129, 21, 23, 23, 2, -22 }, // 0x43 'C' + { 1190, 18, 23, 20, 1, -22 }, // 0x44 'D' + { 1242, 16, 23, 18, 1, -22 }, // 0x45 'E' + { 1288, 12, 23, 14, 2, -22 }, // 0x46 'F' + { 1323, 19, 29, 22, 2, -22 }, // 0x47 'G' + { 1392, 15, 23, 17, 1, -22 }, // 0x48 'H' + { 1436, 4, 23, 6, 1, -22 }, // 0x49 'I' + { 1448, 10, 29, 7, -4, -22 }, // 0x4A 'J' + { 1485, 17, 23, 19, 1, -22 }, // 0x4B 'K' + { 1534, 16, 23, 18, 1, -22 }, // 0x4C 'L' + { 1580, 24, 26, 26, 1, -25 }, // 0x4D 'M' + { 1658, 19, 23, 21, 1, -22 }, // 0x4E 'N' + { 1713, 19, 23, 21, 1, -22 }, // 0x4F 'O' + { 1768, 19, 23, 20, 1, -22 }, // 0x50 'P' + { 1823, 19, 29, 21, 1, -22 }, // 0x51 'Q' + { 1892, 20, 23, 22, 1, -22 }, // 0x52 'R' + { 1950, 16, 23, 18, 1, -22 }, // 0x53 'S' + { 1996, 20, 23, 20, 0, -22 }, // 0x54 'T' + { 2054, 19, 23, 21, 1, -22 }, // 0x55 'U' + { 2109, 21, 23, 22, 1, -22 }, // 0x56 'V' + { 2170, 24, 23, 26, 1, -22 }, // 0x57 'W' + { 2239, 16, 23, 19, 2, -22 }, // 0x58 'X' + { 2285, 19, 23, 21, 1, -22 }, // 0x59 'Y' + { 2340, 21, 23, 22, 1, -22 }, // 0x5A 'Z' + { 2401, 9, 23, 11, 2, -22 }, // 0x5B '[' + { 2427, 18, 27, 15, -1, -24 }, // 0x5C '\' + { 2488, 9, 23, 11, 1, -22 }, // 0x5D ']' + { 2514, 12, 8, 13, 1, -21 }, // 0x5E '^' + { 2526, 12, 2, 13, 1, 0 }, // 0x5F '_' + { 2529, 8, 5, 20, 6, -30 }, // 0x60 '`' + { 2534, 17, 16, 18, 1, -15 }, // 0x61 'a' + { 2568, 16, 23, 18, 2, -22 }, // 0x62 'b' + { 2614, 14, 16, 17, 2, -15 }, // 0x63 'c' + { 2642, 17, 23, 18, 1, -22 }, // 0x64 'd' + { 2691, 15, 15, 18, 2, -14 }, // 0x65 'e' + { 2720, 12, 29, 14, 1, -22 }, // 0x66 'f' + { 2764, 19, 21, 21, 1, -14 }, // 0x67 'g' + { 2814, 15, 23, 18, 2, -22 }, // 0x68 'h' + { 2858, 5, 23, 7, 2, -22 }, // 0x69 'i' + { 2873, 10, 29, 7, -3, -22 }, // 0x6A 'j' + { 2910, 17, 29, 20, 2, -22 }, // 0x6B 'k' + { 2972, 9, 23, 10, 2, -22 }, // 0x6C 'l' + { 2998, 28, 16, 30, 1, -15 }, // 0x6D 'm' + { 3054, 16, 15, 18, 1, -14 }, // 0x6E 'n' + { 3084, 17, 16, 18, 1, -15 }, // 0x6F 'o' + { 3118, 17, 22, 18, 1, -15 }, // 0x70 'p' + { 3165, 19, 21, 21, 1, -14 }, // 0x71 'q' + { 3215, 11, 16, 12, 1, -15 }, // 0x72 'r' + { 3237, 11, 16, 13, 1, -15 }, // 0x73 's' + { 3259, 12, 23, 11, 0, -22 }, // 0x74 't' + { 3294, 16, 16, 18, 1, -15 }, // 0x75 'u' + { 3326, 15, 16, 16, 1, -15 }, // 0x76 'v' + { 3356, 28, 16, 30, 1, -15 }, // 0x77 'w' + { 3412, 13, 16, 16, 2, -15 }, // 0x78 'x' + { 3438, 16, 22, 18, 1, -15 }, // 0x79 'y' + { 3482, 15, 16, 17, 1, -15 }, // 0x7A 'z' + { 3512, 13, 23, 15, 1, -22 }, // 0x7B '{' + { 3550, 3, 31, 7, 2, -26 }, // 0x7C '|' + { 3562, 13, 23, 15, 1, -22 }, // 0x7D '}' + { 3600, 13, 4, 15, 1, -18 } }; // 0x7E '~' const GFXfont AmerikaSans16pt7b PROGMEM = { (uint8_t *)AmerikaSans16pt7bBitmaps, (GFXglyph *)AmerikaSans16pt7bGlyphs, - 0x20, 0x7E, 40 }; + 0x20, 0x7E, 40 }; // Approx. 4279 bytes +#endif // ifndef FONTS_AMERIKASANS16PT7B_H diff --git a/src/src/Static/Fonts/FreeSans9pt7b.h b/src/src/Static/Fonts/FreeSans9pt7b.h index f151f326d..ea02fce7c 100644 --- a/src/src/Static/Fonts/FreeSans9pt7b.h +++ b/src/src/Static/Fonts/FreeSans9pt7b.h @@ -1,200 +1,203 @@ +#ifndef FONTS_FREESANS9PT7B_H +#define FONTS_FREESANS9PT7B_H const uint8_t FreeSans9pt7bBitmaps[] PROGMEM = { - 0xFF, 0xFF, 0xF8, 0xC0, 0xDE, 0xF7, 0x20, 0x09, 0x86, 0x41, 0x91, 0xFF, - 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, 0x10, 0x1F, - 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, - 0x33, 0xF0, 0x40, 0x20, 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, - 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, - 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C, 0x0E, 0x06, 0x60, 0xCC, 0x19, 0x81, - 0xE0, 0x18, 0x0F, 0x03, 0x36, 0xC2, 0xD8, 0x73, 0x06, 0x31, 0xE3, 0xC4, - 0xFE, 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, 0x8C, 0x46, - 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, 0x25, 0x7E, 0xA5, 0x00, 0x30, - 0xC3, 0x3F, 0x30, 0xC3, 0x0C, 0xD6, 0xF0, 0xC0, 0x08, 0x44, 0x21, 0x10, - 0x84, 0x42, 0x11, 0x08, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, - 0x30, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, - 0x10, 0x08, 0x07, 0xF8, 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, - 0x03, 0xC3, 0xC3, 0x66, 0x3C, 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, - 0xFE, 0x18, 0x30, 0x60, 0xC0, 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, - 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, 0x1E, 0x31, 0x98, 0x78, - 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, 0xFF, - 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30, - 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, - 0x6C, 0x63, 0xE0, 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, - 0x03, 0xC2, 0x66, 0x3C, 0xC0, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x64, 0xA0, - 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, 0xFF, - 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x18, 0x38, 0x71, - 0xC0, 0x80, 0x00, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, - 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, - 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, - 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, - 0x70, 0x40, 0x0F, 0xE0, 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, - 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30, - 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, - 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, - 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, - 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, - 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, - 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, 0xFF, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0F, 0x83, - 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, - 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, - 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, - 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, - 0x8F, 0x1E, 0x27, 0x80, 0xC0, 0xD8, 0x33, 0x0C, 0x63, 0x0C, 0xC1, 0xB8, - 0x3F, 0x07, 0x30, 0xC3, 0x18, 0x63, 0x06, 0x60, 0x6C, 0x0C, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xE0, - 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, - 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80, 0xE0, 0x7C, 0x0F, - 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, - 0xE0, 0x7C, 0x0E, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, - 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, - 0x00, 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, - 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, - 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, - 0x60, 0xC0, 0xFB, 0x00, 0x08, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, - 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, - 0x70, 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, - 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, - 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0xC0, 0x78, 0x0F, - 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, - 0xB0, 0x61, 0xF0, 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, - 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, 0xC1, 0x81, 0x30, - 0xE1, 0x98, 0x70, 0xCC, 0x28, 0x66, 0x26, 0x21, 0x13, 0x30, 0xC8, 0x98, - 0x6C, 0x4C, 0x14, 0x34, 0x0A, 0x1A, 0x07, 0x07, 0x03, 0x03, 0x80, 0x81, - 0x80, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x0F, 0x00, 0xE0, 0x06, 0x00, - 0xF0, 0x19, 0x01, 0x98, 0x30, 0xC6, 0x0E, 0x60, 0x60, 0xC0, 0x36, 0x06, - 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, - 0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, - 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, 0xFB, 0x6D, - 0xB6, 0xDB, 0x6D, 0xB6, 0xE0, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, - 0x10, 0x80, 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, 0x30, 0x60, 0xA2, - 0x44, 0xD8, 0xA1, 0x80, 0xFF, 0xC0, 0xC6, 0x30, 0x7E, 0x71, 0xB0, 0xC0, - 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, 0xC0, 0x60, 0x30, 0x1B, - 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, 0x3C, - 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x03, 0x03, 0x03, - 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x3C, 0x66, - 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x36, 0x6F, 0x66, 0x66, - 0x66, 0x66, 0x60, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, - 0x3B, 0x03, 0x03, 0xC6, 0x7C, 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC0, 0x30, 0x03, - 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x4C, - 0x46, 0x63, 0x61, 0xF0, 0xEC, 0x62, 0x31, 0x98, 0x6C, 0x30, 0xFF, 0xFF, - 0xFF, 0xC0, 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, - 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0x66, 0x3C, 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, - 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, 0xDF, 0x31, 0x8C, 0x63, 0x18, - 0xC6, 0x00, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, - 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC7, 0x7B, 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, - 0x28, 0x1C, 0x0C, 0x00, 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, - 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, 0x43, 0x62, 0x36, - 0x1C, 0x18, 0x1C, 0x3C, 0x26, 0x62, 0x43, 0xC1, 0x21, 0x98, 0xCC, 0x42, - 0x61, 0xB0, 0xD0, 0x38, 0x1C, 0x0C, 0x06, 0x03, 0x01, 0x03, 0x00, 0xFE, - 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, 0x36, 0x66, 0x66, 0x6E, - 0xCE, 0x66, 0x66, 0x66, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC6, 0x66, - 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, 0x61, 0x24, 0x38}; + 0xFF, 0xFF, 0xF8, 0xC0, 0xDE, 0xF7, 0x20, 0x09, 0x86, 0x41, 0x91, 0xFF, + 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, 0x10, 0x1F, + 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, + 0x33, 0xF0, 0x40, 0x20, 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, + 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, + 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C, 0x0E, 0x06, 0x60, 0xCC, 0x19, 0x81, + 0xE0, 0x18, 0x0F, 0x03, 0x36, 0xC2, 0xD8, 0x73, 0x06, 0x31, 0xE3, 0xC4, + 0xFE, 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, 0x8C, 0x46, + 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, 0x25, 0x7E, 0xA5, 0x00, 0x30, + 0xC3, 0x3F, 0x30, 0xC3, 0x0C, 0xD6, 0xF0, 0xC0, 0x08, 0x44, 0x21, 0x10, + 0x84, 0x42, 0x11, 0x08, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, + 0x30, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, + 0x10, 0x08, 0x07, 0xF8, 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, + 0x03, 0xC3, 0xC3, 0x66, 0x3C, 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, + 0xFE, 0x18, 0x30, 0x60, 0xC0, 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, + 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, 0x1E, 0x31, 0x98, 0x78, + 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, 0xFF, + 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30, + 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, + 0x6C, 0x63, 0xE0, 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, + 0x03, 0xC2, 0x66, 0x3C, 0xC0, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x64, 0xA0, + 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, 0xFF, + 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x18, 0x38, 0x71, + 0xC0, 0x80, 0x00, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, + 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, + 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, + 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, + 0x70, 0x40, 0x0F, 0xE0, 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, + 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30, + 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, + 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, + 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, + 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, + 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, + 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, 0xFF, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0F, 0x83, + 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, + 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, + 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, + 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, + 0x8F, 0x1E, 0x27, 0x80, 0xC0, 0xD8, 0x33, 0x0C, 0x63, 0x0C, 0xC1, 0xB8, + 0x3F, 0x07, 0x30, 0xC3, 0x18, 0x63, 0x06, 0x60, 0x6C, 0x0C, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xE0, + 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, + 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80, 0xE0, 0x7C, 0x0F, + 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, + 0xE0, 0x7C, 0x0E, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, + 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, + 0x00, 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, + 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, + 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, + 0x60, 0xC0, 0xFB, 0x00, 0x08, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, + 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, + 0x70, 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, + 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, + 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0xC0, 0x78, 0x0F, + 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, + 0xB0, 0x61, 0xF0, 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, + 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, 0xC1, 0x81, 0x30, + 0xE1, 0x98, 0x70, 0xCC, 0x28, 0x66, 0x26, 0x21, 0x13, 0x30, 0xC8, 0x98, + 0x6C, 0x4C, 0x14, 0x34, 0x0A, 0x1A, 0x07, 0x07, 0x03, 0x03, 0x80, 0x81, + 0x80, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x0F, 0x00, 0xE0, 0x06, 0x00, + 0xF0, 0x19, 0x01, 0x98, 0x30, 0xC6, 0x0E, 0x60, 0x60, 0xC0, 0x36, 0x06, + 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, + 0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, + 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, 0xFB, 0x6D, + 0xB6, 0xDB, 0x6D, 0xB6, 0xE0, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, + 0x10, 0x80, 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, 0x30, 0x60, 0xA2, + 0x44, 0xD8, 0xA1, 0x80, 0xFF, 0xC0, 0xC6, 0x30, 0x7E, 0x71, 0xB0, 0xC0, + 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, 0xC0, 0x60, 0x30, 0x1B, + 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, 0x3C, + 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x03, 0x03, 0x03, + 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x3C, 0x66, + 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x36, 0x6F, 0x66, 0x66, + 0x66, 0x66, 0x60, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, + 0x3B, 0x03, 0x03, 0xC6, 0x7C, 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC0, 0x30, 0x03, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x4C, + 0x46, 0x63, 0x61, 0xF0, 0xEC, 0x62, 0x31, 0x98, 0x6C, 0x30, 0xFF, 0xFF, + 0xFF, 0xC0, 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, + 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0x66, 0x3C, 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, + 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, 0xDF, 0x31, 0x8C, 0x63, 0x18, + 0xC6, 0x00, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, + 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0xC7, 0x7B, 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, + 0x28, 0x1C, 0x0C, 0x00, 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, + 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, 0x43, 0x62, 0x36, + 0x1C, 0x18, 0x1C, 0x3C, 0x26, 0x62, 0x43, 0xC1, 0x21, 0x98, 0xCC, 0x42, + 0x61, 0xB0, 0xD0, 0x38, 0x1C, 0x0C, 0x06, 0x03, 0x01, 0x03, 0x00, 0xFE, + 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, 0x36, 0x66, 0x66, 0x6E, + 0xCE, 0x66, 0x66, 0x66, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC6, 0x66, + 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, 0x61, 0x24, 0x38 }; const GFXglyph FreeSans9pt7bGlyphs[] PROGMEM = { - {0, 0, 0, 5, 0, 1}, // 0x20 ' ' - {0, 2, 13, 6, 2, -12}, // 0x21 '!' - {4, 5, 4, 6, 1, -12}, // 0x22 '"' - {7, 10, 12, 10, 0, -11}, // 0x23 '#' - {22, 9, 16, 10, 1, -13}, // 0x24 '$' - {40, 16, 13, 16, 1, -12}, // 0x25 '%' - {66, 11, 13, 12, 1, -12}, // 0x26 '&' - {84, 2, 4, 4, 1, -12}, // 0x27 ''' - {85, 4, 17, 6, 1, -12}, // 0x28 '(' - {94, 4, 17, 6, 1, -12}, // 0x29 ')' - {103, 5, 5, 7, 1, -12}, // 0x2A '*' - {107, 6, 8, 11, 3, -7}, // 0x2B '+' - {113, 2, 4, 5, 2, 0}, // 0x2C ',' - {114, 4, 1, 6, 1, -4}, // 0x2D '-' - {115, 2, 1, 5, 1, 0}, // 0x2E '.' - {116, 5, 13, 5, 0, -12}, // 0x2F '/' - {125, 8, 13, 10, 1, -12}, // 0x30 '0' - {138, 4, 13, 10, 3, -12}, // 0x31 '1' - {145, 9, 13, 10, 1, -12}, // 0x32 '2' - {160, 8, 13, 10, 1, -12}, // 0x33 '3' - {173, 7, 13, 10, 2, -12}, // 0x34 '4' - {185, 9, 13, 10, 1, -12}, // 0x35 '5' - {200, 9, 13, 10, 1, -12}, // 0x36 '6' - {215, 8, 13, 10, 0, -12}, // 0x37 '7' - {228, 9, 13, 10, 1, -12}, // 0x38 '8' - {243, 8, 13, 10, 1, -12}, // 0x39 '9' - {256, 2, 10, 5, 1, -9}, // 0x3A ':' - {259, 3, 12, 5, 1, -8}, // 0x3B ';' - {264, 9, 9, 11, 1, -8}, // 0x3C '<' - {275, 9, 4, 11, 1, -5}, // 0x3D '=' - {280, 9, 9, 11, 1, -8}, // 0x3E '>' - {291, 9, 13, 10, 1, -12}, // 0x3F '?' - {306, 17, 16, 18, 1, -12}, // 0x40 '@' - {340, 12, 13, 12, 0, -12}, // 0x41 'A' - {360, 11, 13, 12, 1, -12}, // 0x42 'B' - {378, 11, 13, 13, 1, -12}, // 0x43 'C' - {396, 11, 13, 13, 1, -12}, // 0x44 'D' - {414, 9, 13, 11, 1, -12}, // 0x45 'E' - {429, 8, 13, 11, 1, -12}, // 0x46 'F' - {442, 12, 13, 14, 1, -12}, // 0x47 'G' - {462, 11, 13, 13, 1, -12}, // 0x48 'H' - {480, 2, 13, 5, 2, -12}, // 0x49 'I' - {484, 7, 13, 10, 1, -12}, // 0x4A 'J' - {496, 11, 13, 12, 1, -12}, // 0x4B 'K' - {514, 8, 13, 10, 1, -12}, // 0x4C 'L' - {527, 13, 13, 15, 1, -12}, // 0x4D 'M' - {549, 11, 13, 13, 1, -12}, // 0x4E 'N' - {567, 13, 13, 14, 1, -12}, // 0x4F 'O' - {589, 10, 13, 12, 1, -12}, // 0x50 'P' - {606, 13, 14, 14, 1, -12}, // 0x51 'Q' - {629, 12, 13, 13, 1, -12}, // 0x52 'R' - {649, 10, 13, 12, 1, -12}, // 0x53 'S' - {666, 9, 13, 11, 1, -12}, // 0x54 'T' - {681, 11, 13, 13, 1, -12}, // 0x55 'U' - {699, 11, 13, 12, 0, -12}, // 0x56 'V' - {717, 17, 13, 17, 0, -12}, // 0x57 'W' - {745, 12, 13, 12, 0, -12}, // 0x58 'X' - {765, 12, 13, 12, 0, -12}, // 0x59 'Y' - {785, 10, 13, 11, 1, -12}, // 0x5A 'Z' - {802, 3, 17, 5, 1, -12}, // 0x5B '[' - {809, 5, 13, 5, 0, -12}, // 0x5C '\' - {818, 3, 17, 5, 0, -12}, // 0x5D ']' - {825, 7, 7, 8, 1, -12}, // 0x5E '^' - {832, 10, 1, 10, 0, 3}, // 0x5F '_' - {834, 4, 3, 5, 0, -12}, // 0x60 '`' - {836, 9, 10, 10, 1, -9}, // 0x61 'a' - {848, 9, 13, 10, 1, -12}, // 0x62 'b' - {863, 8, 10, 9, 1, -9}, // 0x63 'c' - {873, 8, 13, 10, 1, -12}, // 0x64 'd' - {886, 8, 10, 10, 1, -9}, // 0x65 'e' - {896, 4, 13, 5, 1, -12}, // 0x66 'f' - {903, 8, 14, 10, 1, -9}, // 0x67 'g' - {917, 8, 13, 10, 1, -12}, // 0x68 'h' - {930, 2, 13, 4, 1, -12}, // 0x69 'i' - {934, 4, 17, 4, 0, -12}, // 0x6A 'j' - {943, 9, 13, 9, 1, -12}, // 0x6B 'k' - {958, 2, 13, 4, 1, -12}, // 0x6C 'l' - {962, 13, 10, 15, 1, -9}, // 0x6D 'm' - {979, 8, 10, 10, 1, -9}, // 0x6E 'n' - {989, 8, 10, 10, 1, -9}, // 0x6F 'o' - {999, 9, 13, 10, 1, -9}, // 0x70 'p' - {1014, 8, 13, 10, 1, -9}, // 0x71 'q' - {1027, 5, 10, 6, 1, -9}, // 0x72 'r' - {1034, 8, 10, 9, 1, -9}, // 0x73 's' - {1044, 4, 12, 5, 1, -11}, // 0x74 't' - {1050, 8, 10, 10, 1, -9}, // 0x75 'u' - {1060, 9, 10, 9, 0, -9}, // 0x76 'v' - {1072, 13, 10, 13, 0, -9}, // 0x77 'w' - {1089, 8, 10, 9, 0, -9}, // 0x78 'x' - {1099, 9, 14, 9, 0, -9}, // 0x79 'y' - {1115, 7, 10, 9, 1, -9}, // 0x7A 'z' - {1124, 4, 17, 6, 1, -12}, // 0x7B '{' - {1133, 2, 17, 4, 2, -12}, // 0x7C '|' - {1138, 4, 17, 6, 1, -12}, // 0x7D '}' - {1147, 7, 3, 9, 1, -7}}; // 0x7E '~' + { 0, 0, 0, 5, 0, 1 }, // 0x20 ' ' + { 0, 2, 13, 6, 2, -12 }, // 0x21 '!' + { 4, 5, 4, 6, 1, -12 }, // 0x22 '"' + { 7, 10, 12, 10, 0, -11 }, // 0x23 '#' + { 22, 9, 16, 10, 1, -13 }, // 0x24 '$' + { 40, 16, 13, 16, 1, -12 }, // 0x25 '%' + { 66, 11, 13, 12, 1, -12 }, // 0x26 '&' + { 84, 2, 4, 4, 1, -12 }, // 0x27 ''' + { 85, 4, 17, 6, 1, -12 }, // 0x28 '(' + { 94, 4, 17, 6, 1, -12 }, // 0x29 ')' + { 103, 5, 5, 7, 1, -12 }, // 0x2A '*' + { 107, 6, 8, 11, 3, -7 }, // 0x2B '+' + { 113, 2, 4, 5, 2, 0 }, // 0x2C ',' + { 114, 4, 1, 6, 1, -4 }, // 0x2D '-' + { 115, 2, 1, 5, 1, 0 }, // 0x2E '.' + { 116, 5, 13, 5, 0, -12 }, // 0x2F '/' + { 125, 8, 13, 10, 1, -12 }, // 0x30 '0' + { 138, 4, 13, 10, 3, -12 }, // 0x31 '1' + { 145, 9, 13, 10, 1, -12 }, // 0x32 '2' + { 160, 8, 13, 10, 1, -12 }, // 0x33 '3' + { 173, 7, 13, 10, 2, -12 }, // 0x34 '4' + { 185, 9, 13, 10, 1, -12 }, // 0x35 '5' + { 200, 9, 13, 10, 1, -12 }, // 0x36 '6' + { 215, 8, 13, 10, 0, -12 }, // 0x37 '7' + { 228, 9, 13, 10, 1, -12 }, // 0x38 '8' + { 243, 8, 13, 10, 1, -12 }, // 0x39 '9' + { 256, 2, 10, 5, 1, -9 }, // 0x3A ':' + { 259, 3, 12, 5, 1, -8 }, // 0x3B ';' + { 264, 9, 9, 11, 1, -8 }, // 0x3C '<' + { 275, 9, 4, 11, 1, -5 }, // 0x3D '=' + { 280, 9, 9, 11, 1, -8 }, // 0x3E '>' + { 291, 9, 13, 10, 1, -12 }, // 0x3F '?' + { 306, 17, 16, 18, 1, -12 }, // 0x40 '@' + { 340, 12, 13, 12, 0, -12 }, // 0x41 'A' + { 360, 11, 13, 12, 1, -12 }, // 0x42 'B' + { 378, 11, 13, 13, 1, -12 }, // 0x43 'C' + { 396, 11, 13, 13, 1, -12 }, // 0x44 'D' + { 414, 9, 13, 11, 1, -12 }, // 0x45 'E' + { 429, 8, 13, 11, 1, -12 }, // 0x46 'F' + { 442, 12, 13, 14, 1, -12 }, // 0x47 'G' + { 462, 11, 13, 13, 1, -12 }, // 0x48 'H' + { 480, 2, 13, 5, 2, -12 }, // 0x49 'I' + { 484, 7, 13, 10, 1, -12 }, // 0x4A 'J' + { 496, 11, 13, 12, 1, -12 }, // 0x4B 'K' + { 514, 8, 13, 10, 1, -12 }, // 0x4C 'L' + { 527, 13, 13, 15, 1, -12 }, // 0x4D 'M' + { 549, 11, 13, 13, 1, -12 }, // 0x4E 'N' + { 567, 13, 13, 14, 1, -12 }, // 0x4F 'O' + { 589, 10, 13, 12, 1, -12 }, // 0x50 'P' + { 606, 13, 14, 14, 1, -12 }, // 0x51 'Q' + { 629, 12, 13, 13, 1, -12 }, // 0x52 'R' + { 649, 10, 13, 12, 1, -12 }, // 0x53 'S' + { 666, 9, 13, 11, 1, -12 }, // 0x54 'T' + { 681, 11, 13, 13, 1, -12 }, // 0x55 'U' + { 699, 11, 13, 12, 0, -12 }, // 0x56 'V' + { 717, 17, 13, 17, 0, -12 }, // 0x57 'W' + { 745, 12, 13, 12, 0, -12 }, // 0x58 'X' + { 765, 12, 13, 12, 0, -12 }, // 0x59 'Y' + { 785, 10, 13, 11, 1, -12 }, // 0x5A 'Z' + { 802, 3, 17, 5, 1, -12 }, // 0x5B '[' + { 809, 5, 13, 5, 0, -12 }, // 0x5C '\' + { 818, 3, 17, 5, 0, -12 }, // 0x5D ']' + { 825, 7, 7, 8, 1, -12 }, // 0x5E '^' + { 832, 10, 1, 10, 0, 3 }, // 0x5F '_' + { 834, 4, 3, 5, 0, -12 }, // 0x60 '`' + { 836, 9, 10, 10, 1, -9 }, // 0x61 'a' + { 848, 9, 13, 10, 1, -12 }, // 0x62 'b' + { 863, 8, 10, 9, 1, -9 }, // 0x63 'c' + { 873, 8, 13, 10, 1, -12 }, // 0x64 'd' + { 886, 8, 10, 10, 1, -9 }, // 0x65 'e' + { 896, 4, 13, 5, 1, -12 }, // 0x66 'f' + { 903, 8, 14, 10, 1, -9 }, // 0x67 'g' + { 917, 8, 13, 10, 1, -12 }, // 0x68 'h' + { 930, 2, 13, 4, 1, -12 }, // 0x69 'i' + { 934, 4, 17, 4, 0, -12 }, // 0x6A 'j' + { 943, 9, 13, 9, 1, -12 }, // 0x6B 'k' + { 958, 2, 13, 4, 1, -12 }, // 0x6C 'l' + { 962, 13, 10, 15, 1, -9 }, // 0x6D 'm' + { 979, 8, 10, 10, 1, -9 }, // 0x6E 'n' + { 989, 8, 10, 10, 1, -9 }, // 0x6F 'o' + { 999, 9, 13, 10, 1, -9 }, // 0x70 'p' + { 1014, 8, 13, 10, 1, -9 }, // 0x71 'q' + { 1027, 5, 10, 6, 1, -9 }, // 0x72 'r' + { 1034, 8, 10, 9, 1, -9 }, // 0x73 's' + { 1044, 4, 12, 5, 1, -11 }, // 0x74 't' + { 1050, 8, 10, 10, 1, -9 }, // 0x75 'u' + { 1060, 9, 10, 9, 0, -9 }, // 0x76 'v' + { 1072, 13, 10, 13, 0, -9 }, // 0x77 'w' + { 1089, 8, 10, 9, 0, -9 }, // 0x78 'x' + { 1099, 9, 14, 9, 0, -9 }, // 0x79 'y' + { 1115, 7, 10, 9, 1, -9 }, // 0x7A 'z' + { 1124, 4, 17, 6, 1, -12 }, // 0x7B '{' + { 1133, 2, 17, 4, 2, -12 }, // 0x7C '|' + { 1138, 4, 17, 6, 1, -12 }, // 0x7D '}' + { 1147, 7, 3, 9, 1, -7 } }; // 0x7E '~' -const GFXfont FreeSans9pt7b PROGMEM = {(uint8_t *)FreeSans9pt7bBitmaps, - (GFXglyph *)FreeSans9pt7bGlyphs, 0x20, - 0x7E, 22}; +const GFXfont FreeSans9pt7b PROGMEM = { (uint8_t *)FreeSans9pt7bBitmaps, + (GFXglyph *)FreeSans9pt7bGlyphs,0x20, + 0x7E, 22 }; // Approx. 1822 bytes +#endif // ifndef FONTS_FREESANS9PT7B_H diff --git a/src/src/Static/Fonts/NovaMono12pt7b.h b/src/src/Static/Fonts/NovaMono12pt7b.h index c3c818419..f6adbad8d 100644 --- a/src/src/Static/Fonts/NovaMono12pt7b.h +++ b/src/src/Static/Fonts/NovaMono12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_NOVAMONO12PT7B_H +#define FONTS_NOVAMONO12PT7B_H const uint8_t NovaMono12pt7bBitmaps[] PROGMEM = { 0x00, 0x5B, 0x6D, 0xB6, 0xDB, 0x6D, 0x06, 0xF8, 0x47, 0x3C, 0xF3, 0xCE, 0x20, 0x19, 0x81, 0x98, 0x19, 0x8F, 0xFF, 0xFF, 0xF1, 0x98, 0x19, 0x8F, @@ -159,105 +161,106 @@ const uint8_t NovaMono12pt7bBitmaps[] PROGMEM = { 0x00, 0x38, 0x2F, 0xCD, 0x9F, 0x61, 0xC0 }; const GFXglyph NovaMono12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' - { 1, 3, 18, 13, 5, -17 }, // 0x21 '!' - { 8, 6, 6, 13, 4, -17 }, // 0x22 '"' - { 13, 12, 12, 13, 1, -14 }, // 0x23 '#' - { 31, 11, 26, 13, 1, -21 }, // 0x24 '$' - { 67, 12, 18, 13, 1, -17 }, // 0x25 '%' - { 94, 13, 18, 13, 0, -17 }, // 0x26 '&' - { 124, 2, 6, 13, 6, -17 }, // 0x27 ''' - { 126, 6, 26, 13, 5, -21 }, // 0x28 '(' - { 146, 6, 26, 13, 2, -21 }, // 0x29 ')' - { 166, 10, 10, 13, 2, -17 }, // 0x2A '*' - { 179, 10, 10, 13, 2, -13 }, // 0x2B '+' - { 192, 3, 6, 13, 5, -2 }, // 0x2C ',' - { 195, 10, 2, 13, 2, -9 }, // 0x2D '-' - { 198, 3, 3, 13, 5, -2 }, // 0x2E '.' - { 200, 12, 26, 13, 1, -21 }, // 0x2F '/' - { 239, 11, 18, 13, 1, -17 }, // 0x30 '0' - { 264, 6, 18, 13, 2, -17 }, // 0x31 '1' - { 278, 11, 18, 13, 1, -17 }, // 0x32 '2' - { 303, 11, 18, 13, 1, -17 }, // 0x33 '3' - { 328, 12, 18, 13, 1, -17 }, // 0x34 '4' - { 355, 11, 18, 13, 1, -17 }, // 0x35 '5' - { 380, 11, 18, 13, 1, -17 }, // 0x36 '6' - { 405, 11, 18, 13, 1, -17 }, // 0x37 '7' - { 430, 11, 18, 13, 1, -17 }, // 0x38 '8' - { 455, 11, 18, 13, 1, -17 }, // 0x39 '9' - { 480, 3, 10, 13, 5, -9 }, // 0x3A ':' - { 484, 3, 13, 13, 5, -9 }, // 0x3B ';' - { 489, 10, 10, 13, 2, -13 }, // 0x3C '<' - { 502, 10, 6, 13, 2, -11 }, // 0x3D '=' - { 510, 10, 10, 13, 2, -13 }, // 0x3E '>' - { 523, 11, 18, 13, 1, -17 }, // 0x3F '?' - { 548, 10, 18, 13, 2, -12 }, // 0x40 '@' - { 571, 11, 18, 13, 1, -17 }, // 0x41 'A' - { 596, 11, 18, 13, 1, -17 }, // 0x42 'B' - { 621, 11, 18, 13, 1, -17 }, // 0x43 'C' - { 646, 11, 18, 13, 1, -17 }, // 0x44 'D' - { 671, 10, 18, 13, 2, -17 }, // 0x45 'E' - { 694, 9, 18, 13, 2, -17 }, // 0x46 'F' - { 715, 11, 18, 13, 1, -17 }, // 0x47 'G' - { 740, 11, 18, 13, 1, -17 }, // 0x48 'H' - { 765, 10, 18, 13, 2, -17 }, // 0x49 'I' - { 788, 11, 18, 13, 1, -17 }, // 0x4A 'J' - { 813, 11, 18, 13, 1, -17 }, // 0x4B 'K' - { 838, 10, 18, 13, 2, -17 }, // 0x4C 'L' - { 861, 11, 18, 13, 1, -17 }, // 0x4D 'M' - { 886, 11, 18, 13, 1, -17 }, // 0x4E 'N' - { 911, 11, 18, 13, 1, -17 }, // 0x4F 'O' - { 936, 11, 18, 13, 1, -17 }, // 0x50 'P' - { 961, 11, 20, 13, 1, -17 }, // 0x51 'Q' - { 989, 11, 18, 13, 1, -17 }, // 0x52 'R' - { 1014, 11, 18, 13, 1, -17 }, // 0x53 'S' - { 1039, 12, 18, 13, 1, -17 }, // 0x54 'T' - { 1066, 11, 18, 13, 1, -17 }, // 0x55 'U' - { 1091, 12, 18, 13, 1, -17 }, // 0x56 'V' - { 1118, 11, 18, 13, 1, -17 }, // 0x57 'W' - { 1143, 11, 18, 13, 1, -17 }, // 0x58 'X' - { 1168, 11, 18, 13, 1, -17 }, // 0x59 'Y' - { 1193, 11, 18, 13, 1, -17 }, // 0x5A 'Z' - { 1218, 6, 26, 13, 5, -21 }, // 0x5B '[' - { 1238, 12, 26, 13, 1, -21 }, // 0x5C '\' - { 1277, 6, 26, 13, 2, -21 }, // 0x5D ']' - { 1297, 9, 5, 13, 2, -17 }, // 0x5E '^' - { 1303, 10, 2, 13, 2, -1 }, // 0x5F '_' - { 1306, 5, 6, 13, 4, -17 }, // 0x60 '`' - { 1310, 9, 13, 13, 2, -12 }, // 0x61 'a' - { 1325, 9, 18, 13, 2, -17 }, // 0x62 'b' - { 1346, 9, 13, 13, 2, -12 }, // 0x63 'c' - { 1361, 9, 18, 13, 2, -17 }, // 0x64 'd' - { 1382, 9, 13, 13, 2, -12 }, // 0x65 'e' - { 1397, 10, 18, 13, 1, -17 }, // 0x66 'f' - { 1420, 9, 18, 13, 2, -12 }, // 0x67 'g' - { 1441, 9, 18, 13, 2, -17 }, // 0x68 'h' - { 1462, 9, 18, 13, 2, -17 }, // 0x69 'i' - { 1483, 10, 23, 13, 2, -17 }, // 0x6A 'j' - { 1512, 9, 18, 13, 2, -17 }, // 0x6B 'k' - { 1533, 9, 18, 13, 2, -17 }, // 0x6C 'l' - { 1554, 11, 13, 13, 1, -12 }, // 0x6D 'm' - { 1572, 9, 13, 13, 2, -12 }, // 0x6E 'n' - { 1587, 9, 13, 13, 2, -12 }, // 0x6F 'o' - { 1602, 9, 18, 13, 2, -12 }, // 0x70 'p' - { 1623, 12, 18, 13, 2, -12 }, // 0x71 'q' - { 1650, 9, 13, 13, 2, -12 }, // 0x72 'r' - { 1665, 9, 13, 13, 2, -12 }, // 0x73 's' - { 1680, 10, 18, 13, 1, -17 }, // 0x74 't' - { 1703, 9, 13, 13, 2, -12 }, // 0x75 'u' - { 1718, 12, 13, 13, 1, -12 }, // 0x76 'v' - { 1738, 11, 13, 13, 1, -12 }, // 0x77 'w' - { 1756, 11, 13, 13, 1, -12 }, // 0x78 'x' - { 1774, 9, 18, 13, 2, -12 }, // 0x79 'y' - { 1795, 10, 13, 13, 2, -12 }, // 0x7A 'z' - { 1812, 10, 26, 13, 1, -21 }, // 0x7B '{' - { 1845, 2, 26, 13, 6, -21 }, // 0x7C '|' - { 1852, 10, 26, 13, 2, -21 }, // 0x7D '}' - { 1885, 11, 4, 13, 1, -10 } }; // 0x7E '~' + { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' + { 1, 3, 18, 13, 5, -17 }, // 0x21 '!' + { 8, 6, 6, 13, 4, -17 }, // 0x22 '"' + { 13, 12, 12, 13, 1, -14 }, // 0x23 '#' + { 31, 11, 26, 13, 1, -21 }, // 0x24 '$' + { 67, 12, 18, 13, 1, -17 }, // 0x25 '%' + { 94, 13, 18, 13, 0, -17 }, // 0x26 '&' + { 124, 2, 6, 13, 6, -17 }, // 0x27 ''' + { 126, 6, 26, 13, 5, -21 }, // 0x28 '(' + { 146, 6, 26, 13, 2, -21 }, // 0x29 ')' + { 166, 10, 10, 13, 2, -17 }, // 0x2A '*' + { 179, 10, 10, 13, 2, -13 }, // 0x2B '+' + { 192, 3, 6, 13, 5, -2 }, // 0x2C ',' + { 195, 10, 2, 13, 2, -9 }, // 0x2D '-' + { 198, 3, 3, 13, 5, -2 }, // 0x2E '.' + { 200, 12, 26, 13, 1, -21 }, // 0x2F '/' + { 239, 11, 18, 13, 1, -17 }, // 0x30 '0' + { 264, 6, 18, 13, 2, -17 }, // 0x31 '1' + { 278, 11, 18, 13, 1, -17 }, // 0x32 '2' + { 303, 11, 18, 13, 1, -17 }, // 0x33 '3' + { 328, 12, 18, 13, 1, -17 }, // 0x34 '4' + { 355, 11, 18, 13, 1, -17 }, // 0x35 '5' + { 380, 11, 18, 13, 1, -17 }, // 0x36 '6' + { 405, 11, 18, 13, 1, -17 }, // 0x37 '7' + { 430, 11, 18, 13, 1, -17 }, // 0x38 '8' + { 455, 11, 18, 13, 1, -17 }, // 0x39 '9' + { 480, 3, 10, 13, 5, -9 }, // 0x3A ':' + { 484, 3, 13, 13, 5, -9 }, // 0x3B ';' + { 489, 10, 10, 13, 2, -13 }, // 0x3C '<' + { 502, 10, 6, 13, 2, -11 }, // 0x3D '=' + { 510, 10, 10, 13, 2, -13 }, // 0x3E '>' + { 523, 11, 18, 13, 1, -17 }, // 0x3F '?' + { 548, 10, 18, 13, 2, -12 }, // 0x40 '@' + { 571, 11, 18, 13, 1, -17 }, // 0x41 'A' + { 596, 11, 18, 13, 1, -17 }, // 0x42 'B' + { 621, 11, 18, 13, 1, -17 }, // 0x43 'C' + { 646, 11, 18, 13, 1, -17 }, // 0x44 'D' + { 671, 10, 18, 13, 2, -17 }, // 0x45 'E' + { 694, 9, 18, 13, 2, -17 }, // 0x46 'F' + { 715, 11, 18, 13, 1, -17 }, // 0x47 'G' + { 740, 11, 18, 13, 1, -17 }, // 0x48 'H' + { 765, 10, 18, 13, 2, -17 }, // 0x49 'I' + { 788, 11, 18, 13, 1, -17 }, // 0x4A 'J' + { 813, 11, 18, 13, 1, -17 }, // 0x4B 'K' + { 838, 10, 18, 13, 2, -17 }, // 0x4C 'L' + { 861, 11, 18, 13, 1, -17 }, // 0x4D 'M' + { 886, 11, 18, 13, 1, -17 }, // 0x4E 'N' + { 911, 11, 18, 13, 1, -17 }, // 0x4F 'O' + { 936, 11, 18, 13, 1, -17 }, // 0x50 'P' + { 961, 11, 20, 13, 1, -17 }, // 0x51 'Q' + { 989, 11, 18, 13, 1, -17 }, // 0x52 'R' + { 1014, 11, 18, 13, 1, -17 }, // 0x53 'S' + { 1039, 12, 18, 13, 1, -17 }, // 0x54 'T' + { 1066, 11, 18, 13, 1, -17 }, // 0x55 'U' + { 1091, 12, 18, 13, 1, -17 }, // 0x56 'V' + { 1118, 11, 18, 13, 1, -17 }, // 0x57 'W' + { 1143, 11, 18, 13, 1, -17 }, // 0x58 'X' + { 1168, 11, 18, 13, 1, -17 }, // 0x59 'Y' + { 1193, 11, 18, 13, 1, -17 }, // 0x5A 'Z' + { 1218, 6, 26, 13, 5, -21 }, // 0x5B '[' + { 1238, 12, 26, 13, 1, -21 }, // 0x5C '\' + { 1277, 6, 26, 13, 2, -21 }, // 0x5D ']' + { 1297, 9, 5, 13, 2, -17 }, // 0x5E '^' + { 1303, 10, 2, 13, 2, -1 }, // 0x5F '_' + { 1306, 5, 6, 13, 4, -17 }, // 0x60 '`' + { 1310, 9, 13, 13, 2, -12 }, // 0x61 'a' + { 1325, 9, 18, 13, 2, -17 }, // 0x62 'b' + { 1346, 9, 13, 13, 2, -12 }, // 0x63 'c' + { 1361, 9, 18, 13, 2, -17 }, // 0x64 'd' + { 1382, 9, 13, 13, 2, -12 }, // 0x65 'e' + { 1397, 10, 18, 13, 1, -17 }, // 0x66 'f' + { 1420, 9, 18, 13, 2, -12 }, // 0x67 'g' + { 1441, 9, 18, 13, 2, -17 }, // 0x68 'h' + { 1462, 9, 18, 13, 2, -17 }, // 0x69 'i' + { 1483, 10, 23, 13, 2, -17 }, // 0x6A 'j' + { 1512, 9, 18, 13, 2, -17 }, // 0x6B 'k' + { 1533, 9, 18, 13, 2, -17 }, // 0x6C 'l' + { 1554, 11, 13, 13, 1, -12 }, // 0x6D 'm' + { 1572, 9, 13, 13, 2, -12 }, // 0x6E 'n' + { 1587, 9, 13, 13, 2, -12 }, // 0x6F 'o' + { 1602, 9, 18, 13, 2, -12 }, // 0x70 'p' + { 1623, 12, 18, 13, 2, -12 }, // 0x71 'q' + { 1650, 9, 13, 13, 2, -12 }, // 0x72 'r' + { 1665, 9, 13, 13, 2, -12 }, // 0x73 's' + { 1680, 10, 18, 13, 1, -17 }, // 0x74 't' + { 1703, 9, 13, 13, 2, -12 }, // 0x75 'u' + { 1718, 12, 13, 13, 1, -12 }, // 0x76 'v' + { 1738, 11, 13, 13, 1, -12 }, // 0x77 'w' + { 1756, 11, 13, 13, 1, -12 }, // 0x78 'x' + { 1774, 9, 18, 13, 2, -12 }, // 0x79 'y' + { 1795, 10, 13, 13, 2, -12 }, // 0x7A 'z' + { 1812, 10, 26, 13, 1, -21 }, // 0x7B '{' + { 1845, 2, 26, 13, 6, -21 }, // 0x7C '|' + { 1852, 10, 26, 13, 2, -21 }, // 0x7D '}' + { 1885, 11, 4, 13, 1, -10 } }; // 0x7E '~' const GFXfont NovaMono12pt7b PROGMEM = { (uint8_t *)NovaMono12pt7bBitmaps, (GFXglyph *)NovaMono12pt7bGlyphs, - 0x20, 0x7E, 33 }; + 0x20, 0x7E, 33 }; // Approx. 2563 bytes +#endif // ifndef FONTS_NOVAMONO12PT7B_H diff --git a/src/src/Static/Fonts/NovaMono8pt7b.h b/src/src/Static/Fonts/NovaMono8pt7b.h index aca048532..c5598b61c 100644 --- a/src/src/Static/Fonts/NovaMono8pt7b.h +++ b/src/src/Static/Fonts/NovaMono8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_NOVAMONO8PT7B_H +#define FONTS_NOVAMONO8PT7B_H const uint8_t NovaMono8pt7bBitmaps[] PROGMEM = { 0x00, 0x55, 0x55, 0x4F, 0xB6, 0xD0, 0x28, 0x53, 0xF9, 0x42, 0x9F, 0xCA, 0x14, 0x00, 0x20, 0x41, 0x87, 0xD2, 0xA4, 0x68, 0x78, 0x38, 0x4C, 0x99, @@ -69,105 +71,106 @@ const uint8_t NovaMono8pt7bBitmaps[] PROGMEM = { 0x40, 0x81, 0x02, 0x04, 0x18, 0xE0, 0x73, 0x38 }; const GFXglyph NovaMono8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 9, 0, 0 }, // 0x20 ' ' - { 1, 2, 12, 9, 3, -11 }, // 0x21 '!' - { 4, 3, 4, 9, 3, -11 }, // 0x22 '"' - { 6, 7, 8, 9, 1, -9 }, // 0x23 '#' - { 13, 7, 18, 9, 1, -14 }, // 0x24 '$' - { 29, 8, 12, 9, 0, -11 }, // 0x25 '%' - { 41, 9, 11, 9, 0, -10 }, // 0x26 '&' - { 54, 1, 4, 9, 4, -11 }, // 0x27 ''' - { 55, 3, 18, 9, 3, -14 }, // 0x28 '(' - { 62, 3, 18, 9, 2, -14 }, // 0x29 ')' - { 69, 7, 7, 9, 1, -11 }, // 0x2A '*' - { 76, 7, 7, 9, 1, -8 }, // 0x2B '+' - { 83, 2, 4, 9, 3, -1 }, // 0x2C ',' - { 84, 7, 1, 9, 1, -5 }, // 0x2D '-' - { 85, 2, 2, 9, 3, -1 }, // 0x2E '.' - { 86, 9, 18, 9, 0, -14 }, // 0x2F '/' - { 107, 7, 12, 9, 1, -11 }, // 0x30 '0' - { 118, 4, 12, 9, 1, -11 }, // 0x31 '1' - { 124, 7, 12, 9, 1, -11 }, // 0x32 '2' - { 135, 7, 11, 9, 1, -10 }, // 0x33 '3' - { 145, 7, 12, 9, 1, -11 }, // 0x34 '4' - { 156, 7, 11, 9, 1, -10 }, // 0x35 '5' - { 166, 7, 12, 9, 1, -11 }, // 0x36 '6' - { 177, 7, 11, 9, 1, -10 }, // 0x37 '7' - { 187, 7, 12, 9, 1, -11 }, // 0x38 '8' - { 198, 7, 12, 9, 1, -11 }, // 0x39 '9' - { 209, 2, 7, 9, 3, -6 }, // 0x3A ':' - { 211, 2, 9, 9, 3, -6 }, // 0x3B ';' - { 214, 7, 6, 9, 1, -8 }, // 0x3C '<' - { 220, 7, 4, 9, 1, -7 }, // 0x3D '=' - { 224, 7, 6, 9, 1, -8 }, // 0x3E '>' - { 230, 7, 12, 9, 1, -11 }, // 0x3F '?' - { 241, 6, 12, 9, 1, -8 }, // 0x40 '@' - { 250, 7, 12, 9, 1, -11 }, // 0x41 'A' - { 261, 7, 11, 9, 1, -10 }, // 0x42 'B' - { 271, 7, 12, 9, 1, -11 }, // 0x43 'C' - { 282, 7, 11, 9, 1, -10 }, // 0x44 'D' - { 292, 7, 11, 9, 2, -10 }, // 0x45 'E' - { 302, 6, 11, 9, 2, -10 }, // 0x46 'F' - { 311, 7, 12, 9, 1, -11 }, // 0x47 'G' - { 322, 7, 12, 9, 1, -11 }, // 0x48 'H' - { 333, 7, 11, 9, 1, -10 }, // 0x49 'I' - { 343, 7, 11, 9, 1, -10 }, // 0x4A 'J' - { 353, 7, 12, 9, 1, -11 }, // 0x4B 'K' - { 364, 7, 12, 9, 1, -11 }, // 0x4C 'L' - { 375, 7, 12, 9, 1, -11 }, // 0x4D 'M' - { 386, 7, 12, 9, 1, -11 }, // 0x4E 'N' - { 397, 7, 12, 9, 1, -11 }, // 0x4F 'O' - { 408, 7, 11, 9, 1, -10 }, // 0x50 'P' - { 418, 7, 13, 9, 1, -11 }, // 0x51 'Q' - { 430, 7, 11, 9, 1, -10 }, // 0x52 'R' - { 440, 7, 12, 9, 1, -11 }, // 0x53 'S' - { 451, 9, 11, 9, 0, -10 }, // 0x54 'T' - { 464, 7, 12, 9, 1, -11 }, // 0x55 'U' - { 475, 9, 12, 9, 0, -11 }, // 0x56 'V' - { 489, 7, 12, 9, 1, -11 }, // 0x57 'W' - { 500, 7, 12, 9, 1, -11 }, // 0x58 'X' - { 511, 7, 12, 9, 1, -11 }, // 0x59 'Y' - { 522, 7, 11, 9, 1, -10 }, // 0x5A 'Z' - { 532, 4, 17, 9, 3, -13 }, // 0x5B '[' - { 541, 9, 18, 9, 0, -14 }, // 0x5C '\' - { 562, 4, 17, 9, 1, -13 }, // 0x5D ']' - { 571, 7, 3, 9, 1, -11 }, // 0x5E '^' - { 574, 7, 1, 9, 1, 0 }, // 0x5F '_' - { 575, 3, 4, 9, 3, -11 }, // 0x60 '`' - { 577, 5, 9, 9, 2, -8 }, // 0x61 'a' - { 583, 5, 12, 9, 2, -11 }, // 0x62 'b' - { 591, 5, 9, 9, 2, -8 }, // 0x63 'c' - { 597, 5, 12, 9, 2, -11 }, // 0x64 'd' - { 605, 5, 9, 9, 2, -8 }, // 0x65 'e' - { 611, 6, 12, 9, 1, -11 }, // 0x66 'f' - { 620, 5, 12, 9, 2, -8 }, // 0x67 'g' - { 628, 5, 12, 9, 2, -11 }, // 0x68 'h' - { 636, 6, 12, 9, 1, -11 }, // 0x69 'i' - { 645, 5, 15, 9, 2, -11 }, // 0x6A 'j' - { 655, 5, 12, 9, 2, -11 }, // 0x6B 'k' - { 663, 5, 12, 9, 2, -11 }, // 0x6C 'l' - { 671, 7, 9, 9, 1, -8 }, // 0x6D 'm' - { 679, 5, 9, 9, 2, -8 }, // 0x6E 'n' - { 685, 5, 9, 9, 2, -8 }, // 0x6F 'o' - { 691, 5, 12, 9, 2, -8 }, // 0x70 'p' - { 699, 7, 12, 9, 2, -8 }, // 0x71 'q' - { 710, 5, 9, 9, 2, -8 }, // 0x72 'r' - { 716, 6, 9, 9, 1, -8 }, // 0x73 's' - { 723, 6, 12, 9, 1, -11 }, // 0x74 't' - { 732, 5, 9, 9, 2, -8 }, // 0x75 'u' - { 738, 7, 9, 9, 1, -8 }, // 0x76 'v' - { 746, 7, 9, 9, 1, -8 }, // 0x77 'w' - { 754, 7, 9, 9, 1, -8 }, // 0x78 'x' - { 762, 5, 12, 9, 2, -8 }, // 0x79 'y' - { 770, 7, 8, 9, 1, -7 }, // 0x7A 'z' - { 777, 7, 17, 9, 0, -13 }, // 0x7B '{' - { 792, 1, 18, 9, 4, -14 }, // 0x7C '|' - { 795, 7, 17, 9, 1, -13 }, // 0x7D '}' - { 810, 7, 2, 9, 1, -6 } }; // 0x7E '~' + { 0, 1, 1, 9, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 9, 3, -11 }, // 0x21 '!' + { 4, 3, 4, 9, 3, -11 }, // 0x22 '"' + { 6, 7, 8, 9, 1, -9 }, // 0x23 '#' + { 13, 7, 18, 9, 1, -14 }, // 0x24 '$' + { 29, 8, 12, 9, 0, -11 }, // 0x25 '%' + { 41, 9, 11, 9, 0, -10 }, // 0x26 '&' + { 54, 1, 4, 9, 4, -11 }, // 0x27 ''' + { 55, 3, 18, 9, 3, -14 }, // 0x28 '(' + { 62, 3, 18, 9, 2, -14 }, // 0x29 ')' + { 69, 7, 7, 9, 1, -11 }, // 0x2A '*' + { 76, 7, 7, 9, 1, -8 }, // 0x2B '+' + { 83, 2, 4, 9, 3, -1 }, // 0x2C ',' + { 84, 7, 1, 9, 1, -5 }, // 0x2D '-' + { 85, 2, 2, 9, 3, -1 }, // 0x2E '.' + { 86, 9, 18, 9, 0, -14 }, // 0x2F '/' + { 107, 7, 12, 9, 1, -11 }, // 0x30 '0' + { 118, 4, 12, 9, 1, -11 }, // 0x31 '1' + { 124, 7, 12, 9, 1, -11 }, // 0x32 '2' + { 135, 7, 11, 9, 1, -10 }, // 0x33 '3' + { 145, 7, 12, 9, 1, -11 }, // 0x34 '4' + { 156, 7, 11, 9, 1, -10 }, // 0x35 '5' + { 166, 7, 12, 9, 1, -11 }, // 0x36 '6' + { 177, 7, 11, 9, 1, -10 }, // 0x37 '7' + { 187, 7, 12, 9, 1, -11 }, // 0x38 '8' + { 198, 7, 12, 9, 1, -11 }, // 0x39 '9' + { 209, 2, 7, 9, 3, -6 }, // 0x3A ':' + { 211, 2, 9, 9, 3, -6 }, // 0x3B ';' + { 214, 7, 6, 9, 1, -8 }, // 0x3C '<' + { 220, 7, 4, 9, 1, -7 }, // 0x3D '=' + { 224, 7, 6, 9, 1, -8 }, // 0x3E '>' + { 230, 7, 12, 9, 1, -11 }, // 0x3F '?' + { 241, 6, 12, 9, 1, -8 }, // 0x40 '@' + { 250, 7, 12, 9, 1, -11 }, // 0x41 'A' + { 261, 7, 11, 9, 1, -10 }, // 0x42 'B' + { 271, 7, 12, 9, 1, -11 }, // 0x43 'C' + { 282, 7, 11, 9, 1, -10 }, // 0x44 'D' + { 292, 7, 11, 9, 2, -10 }, // 0x45 'E' + { 302, 6, 11, 9, 2, -10 }, // 0x46 'F' + { 311, 7, 12, 9, 1, -11 }, // 0x47 'G' + { 322, 7, 12, 9, 1, -11 }, // 0x48 'H' + { 333, 7, 11, 9, 1, -10 }, // 0x49 'I' + { 343, 7, 11, 9, 1, -10 }, // 0x4A 'J' + { 353, 7, 12, 9, 1, -11 }, // 0x4B 'K' + { 364, 7, 12, 9, 1, -11 }, // 0x4C 'L' + { 375, 7, 12, 9, 1, -11 }, // 0x4D 'M' + { 386, 7, 12, 9, 1, -11 }, // 0x4E 'N' + { 397, 7, 12, 9, 1, -11 }, // 0x4F 'O' + { 408, 7, 11, 9, 1, -10 }, // 0x50 'P' + { 418, 7, 13, 9, 1, -11 }, // 0x51 'Q' + { 430, 7, 11, 9, 1, -10 }, // 0x52 'R' + { 440, 7, 12, 9, 1, -11 }, // 0x53 'S' + { 451, 9, 11, 9, 0, -10 }, // 0x54 'T' + { 464, 7, 12, 9, 1, -11 }, // 0x55 'U' + { 475, 9, 12, 9, 0, -11 }, // 0x56 'V' + { 489, 7, 12, 9, 1, -11 }, // 0x57 'W' + { 500, 7, 12, 9, 1, -11 }, // 0x58 'X' + { 511, 7, 12, 9, 1, -11 }, // 0x59 'Y' + { 522, 7, 11, 9, 1, -10 }, // 0x5A 'Z' + { 532, 4, 17, 9, 3, -13 }, // 0x5B '[' + { 541, 9, 18, 9, 0, -14 }, // 0x5C '\' + { 562, 4, 17, 9, 1, -13 }, // 0x5D ']' + { 571, 7, 3, 9, 1, -11 }, // 0x5E '^' + { 574, 7, 1, 9, 1, 0 }, // 0x5F '_' + { 575, 3, 4, 9, 3, -11 }, // 0x60 '`' + { 577, 5, 9, 9, 2, -8 }, // 0x61 'a' + { 583, 5, 12, 9, 2, -11 }, // 0x62 'b' + { 591, 5, 9, 9, 2, -8 }, // 0x63 'c' + { 597, 5, 12, 9, 2, -11 }, // 0x64 'd' + { 605, 5, 9, 9, 2, -8 }, // 0x65 'e' + { 611, 6, 12, 9, 1, -11 }, // 0x66 'f' + { 620, 5, 12, 9, 2, -8 }, // 0x67 'g' + { 628, 5, 12, 9, 2, -11 }, // 0x68 'h' + { 636, 6, 12, 9, 1, -11 }, // 0x69 'i' + { 645, 5, 15, 9, 2, -11 }, // 0x6A 'j' + { 655, 5, 12, 9, 2, -11 }, // 0x6B 'k' + { 663, 5, 12, 9, 2, -11 }, // 0x6C 'l' + { 671, 7, 9, 9, 1, -8 }, // 0x6D 'm' + { 679, 5, 9, 9, 2, -8 }, // 0x6E 'n' + { 685, 5, 9, 9, 2, -8 }, // 0x6F 'o' + { 691, 5, 12, 9, 2, -8 }, // 0x70 'p' + { 699, 7, 12, 9, 2, -8 }, // 0x71 'q' + { 710, 5, 9, 9, 2, -8 }, // 0x72 'r' + { 716, 6, 9, 9, 1, -8 }, // 0x73 's' + { 723, 6, 12, 9, 1, -11 }, // 0x74 't' + { 732, 5, 9, 9, 2, -8 }, // 0x75 'u' + { 738, 7, 9, 9, 1, -8 }, // 0x76 'v' + { 746, 7, 9, 9, 1, -8 }, // 0x77 'w' + { 754, 7, 9, 9, 1, -8 }, // 0x78 'x' + { 762, 5, 12, 9, 2, -8 }, // 0x79 'y' + { 770, 7, 8, 9, 1, -7 }, // 0x7A 'z' + { 777, 7, 17, 9, 0, -13 }, // 0x7B '{' + { 792, 1, 18, 9, 4, -14 }, // 0x7C '|' + { 795, 7, 17, 9, 1, -13 }, // 0x7D '}' + { 810, 7, 2, 9, 1, -6 } }; // 0x7E '~' const GFXfont NovaMono8pt7b PROGMEM = { (uint8_t *)NovaMono8pt7bBitmaps, (GFXglyph *)NovaMono8pt7bGlyphs, - 0x20, 0x7E, 22 }; + 0x20, 0x7E, 22 }; // Approx. 1484 bytes +#endif // ifndef FONTS_NOVAMONO8PT7B_H diff --git a/src/src/Static/Fonts/RepetitionScrolling12pt7b.h b/src/src/Static/Fonts/RepetitionScrolling12pt7b.h index 776c23890..58f400ef6 100644 --- a/src/src/Static/Fonts/RepetitionScrolling12pt7b.h +++ b/src/src/Static/Fonts/RepetitionScrolling12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_REPETITIONSCROLLING12PT7B_H +#define FONTS_REPETITIONSCROLLING12PT7B_H const uint8_t RepetitionScrolling12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0x3F, 0xFC, 0x0F, 0xC7, 0x8F, 0x1E, 0x30, 0x31, 0x86, 0x30, 0xC6, 0x18, 0xC0, 0x01, 0xEB, 0xFD, 0x79, 0x8C, 0x31, 0x9E, 0xBF, 0xD7, @@ -134,105 +136,106 @@ const uint8_t RepetitionScrolling12pt7bBitmaps[] PROGMEM = { 0xCF, 0x1E, 0x63, 0xC0 }; const GFXglyph RepetitionScrolling12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' - { 1, 2, 16, 13, 5, -15 }, // 0x21 '!' - { 5, 7, 4, 13, 3, -15 }, // 0x22 '"' - { 9, 11, 16, 13, 1, -15 }, // 0x23 '#' - { 31, 11, 16, 13, 1, -15 }, // 0x24 '$' - { 53, 11, 16, 13, 1, -15 }, // 0x25 '%' - { 75, 11, 16, 13, 1, -15 }, // 0x26 '&' - { 97, 2, 4, 13, 5, -15 }, // 0x27 ''' - { 98, 6, 16, 13, 3, -15 }, // 0x28 '(' - { 110, 6, 16, 13, 3, -15 }, // 0x29 ')' - { 122, 6, 7, 13, 3, -15 }, // 0x2A '*' - { 128, 11, 11, 13, 1, -10 }, // 0x2B '+' - { 144, 4, 7, 13, 4, -6 }, // 0x2C ',' - { 148, 6, 2, 13, 3, -6 }, // 0x2D '-' - { 150, 4, 4, 13, 4, -3 }, // 0x2E '.' - { 152, 11, 16, 13, 1, -15 }, // 0x2F '/' - { 174, 11, 16, 13, 1, -15 }, // 0x30 '0' - { 196, 7, 16, 13, 3, -15 }, // 0x31 '1' - { 210, 11, 16, 13, 1, -15 }, // 0x32 '2' - { 232, 11, 16, 13, 1, -15 }, // 0x33 '3' - { 254, 11, 16, 13, 1, -15 }, // 0x34 '4' - { 276, 11, 16, 13, 1, -15 }, // 0x35 '5' - { 298, 11, 16, 13, 1, -15 }, // 0x36 '6' - { 320, 11, 16, 13, 1, -15 }, // 0x37 '7' - { 342, 11, 16, 13, 1, -15 }, // 0x38 '8' - { 364, 11, 16, 13, 1, -15 }, // 0x39 '9' - { 386, 4, 11, 13, 4, -10 }, // 0x3A ':' - { 392, 4, 14, 13, 4, -13 }, // 0x3B ';' - { 399, 9, 16, 13, 2, -15 }, // 0x3C '<' - { 417, 11, 7, 13, 1, -8 }, // 0x3D '=' - { 427, 9, 16, 13, 3, -15 }, // 0x3E '>' - { 445, 11, 16, 13, 1, -15 }, // 0x3F '?' - { 467, 11, 16, 13, 1, -15 }, // 0x40 '@' - { 489, 11, 16, 13, 1, -15 }, // 0x41 'A' - { 511, 11, 16, 13, 1, -15 }, // 0x42 'B' - { 533, 11, 16, 13, 1, -15 }, // 0x43 'C' - { 555, 11, 16, 13, 1, -15 }, // 0x44 'D' - { 577, 11, 16, 13, 1, -15 }, // 0x45 'E' - { 599, 11, 16, 13, 1, -15 }, // 0x46 'F' - { 621, 11, 16, 13, 1, -15 }, // 0x47 'G' - { 643, 11, 16, 13, 1, -15 }, // 0x48 'H' - { 665, 7, 16, 13, 3, -15 }, // 0x49 'I' - { 679, 11, 16, 13, 1, -15 }, // 0x4A 'J' - { 701, 11, 16, 13, 1, -15 }, // 0x4B 'K' - { 723, 11, 16, 13, 1, -15 }, // 0x4C 'L' - { 745, 11, 16, 13, 1, -15 }, // 0x4D 'M' - { 767, 11, 16, 13, 1, -15 }, // 0x4E 'N' - { 789, 11, 16, 13, 1, -15 }, // 0x4F 'O' - { 811, 11, 16, 13, 1, -15 }, // 0x50 'P' - { 833, 11, 16, 13, 1, -15 }, // 0x51 'Q' - { 855, 11, 16, 13, 1, -15 }, // 0x52 'R' - { 877, 11, 16, 13, 1, -15 }, // 0x53 'S' - { 899, 11, 16, 13, 1, -15 }, // 0x54 'T' - { 921, 11, 16, 13, 1, -15 }, // 0x55 'U' - { 943, 11, 16, 13, 1, -15 }, // 0x56 'V' - { 965, 11, 16, 13, 1, -15 }, // 0x57 'W' - { 987, 11, 16, 13, 1, -15 }, // 0x58 'X' - { 1009, 11, 16, 13, 1, -15 }, // 0x59 'Y' - { 1031, 11, 16, 13, 1, -15 }, // 0x5A 'Z' - { 1053, 7, 16, 13, 3, -15 }, // 0x5B '[' - { 1067, 11, 16, 13, 1, -15 }, // 0x5C '\' - { 1089, 7, 16, 13, 3, -15 }, // 0x5D ']' - { 1103, 11, 7, 13, 1, -15 }, // 0x5E '^' - { 1113, 11, 2, 13, 1, -1 }, // 0x5F '_' - { 1116, 4, 4, 13, 4, -15 }, // 0x60 '`' - { 1118, 11, 11, 13, 1, -10 }, // 0x61 'a' - { 1134, 11, 16, 13, 1, -15 }, // 0x62 'b' - { 1156, 11, 11, 13, 1, -10 }, // 0x63 'c' - { 1172, 11, 16, 13, 1, -15 }, // 0x64 'd' - { 1194, 11, 11, 13, 1, -10 }, // 0x65 'e' - { 1210, 11, 16, 13, 1, -15 }, // 0x66 'f' - { 1232, 11, 11, 13, 1, -10 }, // 0x67 'g' - { 1248, 11, 16, 13, 1, -15 }, // 0x68 'h' - { 1270, 2, 16, 13, 5, -15 }, // 0x69 'i' - { 1274, 9, 16, 13, 2, -15 }, // 0x6A 'j' - { 1292, 9, 16, 13, 1, -15 }, // 0x6B 'k' - { 1310, 2, 16, 13, 5, -15 }, // 0x6C 'l' - { 1314, 11, 11, 13, 1, -10 }, // 0x6D 'm' - { 1330, 11, 11, 13, 1, -10 }, // 0x6E 'n' - { 1346, 11, 11, 13, 1, -10 }, // 0x6F 'o' - { 1362, 11, 11, 13, 1, -10 }, // 0x70 'p' - { 1378, 11, 11, 13, 1, -10 }, // 0x71 'q' - { 1394, 11, 11, 13, 1, -10 }, // 0x72 'r' - { 1410, 11, 11, 13, 1, -10 }, // 0x73 's' - { 1426, 11, 14, 13, 1, -13 }, // 0x74 't' - { 1446, 11, 11, 13, 1, -10 }, // 0x75 'u' - { 1462, 11, 11, 13, 1, -10 }, // 0x76 'v' - { 1478, 11, 11, 13, 1, -10 }, // 0x77 'w' - { 1494, 11, 11, 13, 1, -10 }, // 0x78 'x' - { 1510, 11, 11, 13, 1, -10 }, // 0x79 'y' - { 1526, 11, 11, 13, 1, -10 }, // 0x7A 'z' - { 1542, 9, 16, 13, 1, -15 }, // 0x7B '{' - { 1560, 2, 16, 13, 5, -15 }, // 0x7C '|' - { 1564, 9, 16, 13, 3, -15 }, // 0x7D '}' - { 1582, 11, 4, 13, 1, -15 } }; // 0x7E '~' + { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' + { 1, 2, 16, 13, 5, -15 }, // 0x21 '!' + { 5, 7, 4, 13, 3, -15 }, // 0x22 '"' + { 9, 11, 16, 13, 1, -15 }, // 0x23 '#' + { 31, 11, 16, 13, 1, -15 }, // 0x24 '$' + { 53, 11, 16, 13, 1, -15 }, // 0x25 '%' + { 75, 11, 16, 13, 1, -15 }, // 0x26 '&' + { 97, 2, 4, 13, 5, -15 }, // 0x27 ''' + { 98, 6, 16, 13, 3, -15 }, // 0x28 '(' + { 110, 6, 16, 13, 3, -15 }, // 0x29 ')' + { 122, 6, 7, 13, 3, -15 }, // 0x2A '*' + { 128, 11, 11, 13, 1, -10 }, // 0x2B '+' + { 144, 4, 7, 13, 4, -6 }, // 0x2C ',' + { 148, 6, 2, 13, 3, -6 }, // 0x2D '-' + { 150, 4, 4, 13, 4, -3 }, // 0x2E '.' + { 152, 11, 16, 13, 1, -15 }, // 0x2F '/' + { 174, 11, 16, 13, 1, -15 }, // 0x30 '0' + { 196, 7, 16, 13, 3, -15 }, // 0x31 '1' + { 210, 11, 16, 13, 1, -15 }, // 0x32 '2' + { 232, 11, 16, 13, 1, -15 }, // 0x33 '3' + { 254, 11, 16, 13, 1, -15 }, // 0x34 '4' + { 276, 11, 16, 13, 1, -15 }, // 0x35 '5' + { 298, 11, 16, 13, 1, -15 }, // 0x36 '6' + { 320, 11, 16, 13, 1, -15 }, // 0x37 '7' + { 342, 11, 16, 13, 1, -15 }, // 0x38 '8' + { 364, 11, 16, 13, 1, -15 }, // 0x39 '9' + { 386, 4, 11, 13, 4, -10 }, // 0x3A ':' + { 392, 4, 14, 13, 4, -13 }, // 0x3B ';' + { 399, 9, 16, 13, 2, -15 }, // 0x3C '<' + { 417, 11, 7, 13, 1, -8 }, // 0x3D '=' + { 427, 9, 16, 13, 3, -15 }, // 0x3E '>' + { 445, 11, 16, 13, 1, -15 }, // 0x3F '?' + { 467, 11, 16, 13, 1, -15 }, // 0x40 '@' + { 489, 11, 16, 13, 1, -15 }, // 0x41 'A' + { 511, 11, 16, 13, 1, -15 }, // 0x42 'B' + { 533, 11, 16, 13, 1, -15 }, // 0x43 'C' + { 555, 11, 16, 13, 1, -15 }, // 0x44 'D' + { 577, 11, 16, 13, 1, -15 }, // 0x45 'E' + { 599, 11, 16, 13, 1, -15 }, // 0x46 'F' + { 621, 11, 16, 13, 1, -15 }, // 0x47 'G' + { 643, 11, 16, 13, 1, -15 }, // 0x48 'H' + { 665, 7, 16, 13, 3, -15 }, // 0x49 'I' + { 679, 11, 16, 13, 1, -15 }, // 0x4A 'J' + { 701, 11, 16, 13, 1, -15 }, // 0x4B 'K' + { 723, 11, 16, 13, 1, -15 }, // 0x4C 'L' + { 745, 11, 16, 13, 1, -15 }, // 0x4D 'M' + { 767, 11, 16, 13, 1, -15 }, // 0x4E 'N' + { 789, 11, 16, 13, 1, -15 }, // 0x4F 'O' + { 811, 11, 16, 13, 1, -15 }, // 0x50 'P' + { 833, 11, 16, 13, 1, -15 }, // 0x51 'Q' + { 855, 11, 16, 13, 1, -15 }, // 0x52 'R' + { 877, 11, 16, 13, 1, -15 }, // 0x53 'S' + { 899, 11, 16, 13, 1, -15 }, // 0x54 'T' + { 921, 11, 16, 13, 1, -15 }, // 0x55 'U' + { 943, 11, 16, 13, 1, -15 }, // 0x56 'V' + { 965, 11, 16, 13, 1, -15 }, // 0x57 'W' + { 987, 11, 16, 13, 1, -15 }, // 0x58 'X' + { 1009, 11, 16, 13, 1, -15 }, // 0x59 'Y' + { 1031, 11, 16, 13, 1, -15 }, // 0x5A 'Z' + { 1053, 7, 16, 13, 3, -15 }, // 0x5B '[' + { 1067, 11, 16, 13, 1, -15 }, // 0x5C '\' + { 1089, 7, 16, 13, 3, -15 }, // 0x5D ']' + { 1103, 11, 7, 13, 1, -15 }, // 0x5E '^' + { 1113, 11, 2, 13, 1, -1 }, // 0x5F '_' + { 1116, 4, 4, 13, 4, -15 }, // 0x60 '`' + { 1118, 11, 11, 13, 1, -10 }, // 0x61 'a' + { 1134, 11, 16, 13, 1, -15 }, // 0x62 'b' + { 1156, 11, 11, 13, 1, -10 }, // 0x63 'c' + { 1172, 11, 16, 13, 1, -15 }, // 0x64 'd' + { 1194, 11, 11, 13, 1, -10 }, // 0x65 'e' + { 1210, 11, 16, 13, 1, -15 }, // 0x66 'f' + { 1232, 11, 11, 13, 1, -10 }, // 0x67 'g' + { 1248, 11, 16, 13, 1, -15 }, // 0x68 'h' + { 1270, 2, 16, 13, 5, -15 }, // 0x69 'i' + { 1274, 9, 16, 13, 2, -15 }, // 0x6A 'j' + { 1292, 9, 16, 13, 1, -15 }, // 0x6B 'k' + { 1310, 2, 16, 13, 5, -15 }, // 0x6C 'l' + { 1314, 11, 11, 13, 1, -10 }, // 0x6D 'm' + { 1330, 11, 11, 13, 1, -10 }, // 0x6E 'n' + { 1346, 11, 11, 13, 1, -10 }, // 0x6F 'o' + { 1362, 11, 11, 13, 1, -10 }, // 0x70 'p' + { 1378, 11, 11, 13, 1, -10 }, // 0x71 'q' + { 1394, 11, 11, 13, 1, -10 }, // 0x72 'r' + { 1410, 11, 11, 13, 1, -10 }, // 0x73 's' + { 1426, 11, 14, 13, 1, -13 }, // 0x74 't' + { 1446, 11, 11, 13, 1, -10 }, // 0x75 'u' + { 1462, 11, 11, 13, 1, -10 }, // 0x76 'v' + { 1478, 11, 11, 13, 1, -10 }, // 0x77 'w' + { 1494, 11, 11, 13, 1, -10 }, // 0x78 'x' + { 1510, 11, 11, 13, 1, -10 }, // 0x79 'y' + { 1526, 11, 11, 13, 1, -10 }, // 0x7A 'z' + { 1542, 9, 16, 13, 1, -15 }, // 0x7B '{' + { 1560, 2, 16, 13, 5, -15 }, // 0x7C '|' + { 1564, 9, 16, 13, 3, -15 }, // 0x7D '}' + { 1582, 11, 4, 13, 1, -15 } }; // 0x7E '~' const GFXfont RepetitionScrolling12pt7b PROGMEM = { (uint8_t *)RepetitionScrolling12pt7bBitmaps, (GFXglyph *)RepetitionScrolling12pt7bGlyphs, - 0x20, 0x7E, 24 }; + 0x20, 0x7E, 24 }; // Approx. 2260 bytes +#endif // ifndef FONTS_REPETITIONSCROLLING12PT7B_H diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h index 9e4303ca1..8eb1158bf 100644 --- a/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h +++ b/src/src/Static/Fonts/RobotoCondensed_Regular12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOCONDENSED_REGULAR12PT7B_H +#define FONTS_ROBOTOCONDENSED_REGULAR12PT7B_H const uint8_t RobotoCondensed_Regular12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xDE, 0xF7, 0xB9, 0xC8, 0x0C, 0x81, 0x30, 0x66, 0x0C, 0xCF, 0xFF, 0xFF, 0xC4, 0x40, 0x98, 0x33, 0x06, 0x63, @@ -143,105 +145,106 @@ const uint8_t RobotoCondensed_Regular12pt7bBitmaps[] PROGMEM = { 0x00, 0x38, 0x4F, 0x87, 0x39, 0xE3, 0xF0, 0x1C }; const GFXglyph RobotoCondensed_Regular12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' - { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' - { 6, 5, 6, 7, 1, -18 }, // 0x22 '"' - { 10, 11, 17, 13, 1, -16 }, // 0x23 '#' - { 34, 10, 22, 12, 1, -19 }, // 0x24 '$' - { 62, 14, 17, 16, 1, -16 }, // 0x25 '%' - { 92, 12, 17, 14, 1, -16 }, // 0x26 '&' - { 118, 2, 6, 4, 1, -18 }, // 0x27 ''' - { 120, 6, 24, 7, 1, -18 }, // 0x28 '(' - { 138, 6, 24, 7, 0, -18 }, // 0x29 ')' - { 156, 9, 10, 9, 0, -16 }, // 0x2A '*' - { 168, 10, 12, 12, 1, -13 }, // 0x2B '+' - { 183, 3, 6, 5, 1, -2 }, // 0x2C ',' - { 186, 5, 2, 7, 1, -7 }, // 0x2D '-' - { 188, 2, 2, 6, 2, -1 }, // 0x2E '.' - { 189, 8, 18, 8, 0, -16 }, // 0x2F '/' - { 207, 10, 17, 12, 1, -16 }, // 0x30 '0' - { 229, 5, 17, 12, 2, -16 }, // 0x31 '1' - { 240, 10, 17, 12, 1, -16 }, // 0x32 '2' - { 262, 9, 17, 12, 1, -16 }, // 0x33 '3' - { 282, 10, 17, 12, 1, -16 }, // 0x34 '4' - { 304, 10, 17, 12, 1, -16 }, // 0x35 '5' - { 326, 10, 17, 12, 1, -16 }, // 0x36 '6' - { 348, 10, 17, 12, 1, -16 }, // 0x37 '7' - { 370, 10, 17, 12, 1, -16 }, // 0x38 '8' - { 392, 9, 17, 12, 1, -16 }, // 0x39 '9' - { 412, 2, 13, 6, 2, -12 }, // 0x3A ':' - { 416, 3, 16, 6, 1, -12 }, // 0x3B ';' - { 422, 8, 10, 11, 1, -10 }, // 0x3C '<' - { 432, 8, 7, 12, 2, -10 }, // 0x3D '=' - { 439, 9, 10, 11, 1, -10 }, // 0x3E '>' - { 451, 8, 17, 10, 1, -16 }, // 0x3F '?' - { 468, 17, 22, 19, 1, -16 }, // 0x40 '@' - { 515, 13, 17, 13, 0, -16 }, // 0x41 'A' - { 543, 10, 17, 13, 2, -16 }, // 0x42 'B' - { 565, 11, 17, 13, 1, -16 }, // 0x43 'C' - { 589, 11, 17, 14, 2, -16 }, // 0x44 'D' - { 613, 9, 17, 12, 2, -16 }, // 0x45 'E' - { 633, 9, 17, 12, 2, -16 }, // 0x46 'F' - { 653, 11, 17, 14, 1, -16 }, // 0x47 'G' - { 677, 11, 17, 15, 2, -16 }, // 0x48 'H' - { 701, 2, 17, 6, 2, -16 }, // 0x49 'I' - { 706, 9, 17, 12, 1, -16 }, // 0x4A 'J' - { 726, 11, 17, 13, 2, -16 }, // 0x4B 'K' - { 750, 9, 17, 11, 2, -16 }, // 0x4C 'L' - { 770, 14, 17, 17, 2, -16 }, // 0x4D 'M' - { 800, 11, 17, 15, 2, -16 }, // 0x4E 'N' - { 824, 12, 17, 14, 1, -16 }, // 0x4F 'O' - { 850, 10, 17, 13, 2, -16 }, // 0x50 'P' - { 872, 13, 19, 14, 1, -16 }, // 0x51 'Q' - { 903, 11, 17, 14, 2, -16 }, // 0x52 'R' - { 927, 11, 17, 13, 1, -16 }, // 0x53 'S' - { 951, 12, 17, 12, 0, -16 }, // 0x54 'T' - { 977, 11, 17, 14, 1, -16 }, // 0x55 'U' - { 1001, 13, 17, 13, 0, -16 }, // 0x56 'V' - { 1029, 18, 17, 18, 0, -16 }, // 0x57 'W' - { 1068, 12, 17, 13, 1, -16 }, // 0x58 'X' - { 1094, 13, 17, 13, 0, -16 }, // 0x59 'Y' - { 1122, 10, 17, 12, 1, -16 }, // 0x5A 'Z' - { 1144, 5, 24, 6, 1, -19 }, // 0x5B '[' - { 1159, 9, 18, 9, 0, -16 }, // 0x5C '\' - { 1180, 4, 24, 6, 0, -19 }, // 0x5D ']' - { 1192, 7, 9, 9, 1, -16 }, // 0x5E '^' - { 1200, 9, 2, 9, 0, 1 }, // 0x5F '_' - { 1203, 5, 3, 7, 1, -16 }, // 0x60 '`' - { 1205, 9, 13, 11, 1, -12 }, // 0x61 'a' - { 1220, 10, 19, 12, 1, -18 }, // 0x62 'b' - { 1244, 9, 13, 11, 1, -12 }, // 0x63 'c' - { 1259, 9, 19, 12, 1, -18 }, // 0x64 'd' - { 1281, 9, 13, 11, 1, -12 }, // 0x65 'e' - { 1296, 6, 19, 7, 1, -18 }, // 0x66 'f' - { 1311, 9, 18, 12, 1, -12 }, // 0x67 'g' - { 1332, 9, 19, 12, 1, -18 }, // 0x68 'h' - { 1354, 2, 18, 5, 2, -17 }, // 0x69 'i' - { 1359, 5, 23, 5, -1, -17 }, // 0x6A 'j' - { 1374, 10, 19, 11, 1, -18 }, // 0x6B 'k' - { 1398, 2, 19, 5, 2, -18 }, // 0x6C 'l' - { 1403, 16, 13, 18, 1, -12 }, // 0x6D 'm' - { 1429, 9, 13, 12, 1, -12 }, // 0x6E 'n' - { 1444, 10, 13, 12, 1, -12 }, // 0x6F 'o' - { 1461, 10, 18, 12, 1, -12 }, // 0x70 'p' - { 1484, 9, 18, 12, 1, -12 }, // 0x71 'q' - { 1505, 6, 13, 7, 1, -12 }, // 0x72 'r' - { 1515, 9, 13, 10, 1, -12 }, // 0x73 's' - { 1530, 7, 16, 7, 0, -15 }, // 0x74 't' - { 1544, 9, 13, 12, 1, -12 }, // 0x75 'u' - { 1559, 10, 13, 10, 0, -12 }, // 0x76 'v' - { 1576, 15, 13, 15, 0, -12 }, // 0x77 'w' - { 1601, 10, 13, 10, 0, -12 }, // 0x78 'x' - { 1618, 10, 18, 10, 0, -12 }, // 0x79 'y' - { 1641, 8, 13, 10, 1, -12 }, // 0x7A 'z' - { 1654, 6, 23, 7, 1, -18 }, // 0x7B '{' - { 1672, 1, 20, 5, 2, -16 }, // 0x7C '|' - { 1675, 6, 23, 7, 0, -18 }, // 0x7D '}' - { 1693, 11, 5, 14, 1, -9 } }; // 0x7E '~' + { 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' + { 6, 5, 6, 7, 1, -18 }, // 0x22 '"' + { 10, 11, 17, 13, 1, -16 }, // 0x23 '#' + { 34, 10, 22, 12, 1, -19 }, // 0x24 '$' + { 62, 14, 17, 16, 1, -16 }, // 0x25 '%' + { 92, 12, 17, 14, 1, -16 }, // 0x26 '&' + { 118, 2, 6, 4, 1, -18 }, // 0x27 ''' + { 120, 6, 24, 7, 1, -18 }, // 0x28 '(' + { 138, 6, 24, 7, 0, -18 }, // 0x29 ')' + { 156, 9, 10, 9, 0, -16 }, // 0x2A '*' + { 168, 10, 12, 12, 1, -13 }, // 0x2B '+' + { 183, 3, 6, 5, 1, -2 }, // 0x2C ',' + { 186, 5, 2, 7, 1, -7 }, // 0x2D '-' + { 188, 2, 2, 6, 2, -1 }, // 0x2E '.' + { 189, 8, 18, 8, 0, -16 }, // 0x2F '/' + { 207, 10, 17, 12, 1, -16 }, // 0x30 '0' + { 229, 5, 17, 12, 2, -16 }, // 0x31 '1' + { 240, 10, 17, 12, 1, -16 }, // 0x32 '2' + { 262, 9, 17, 12, 1, -16 }, // 0x33 '3' + { 282, 10, 17, 12, 1, -16 }, // 0x34 '4' + { 304, 10, 17, 12, 1, -16 }, // 0x35 '5' + { 326, 10, 17, 12, 1, -16 }, // 0x36 '6' + { 348, 10, 17, 12, 1, -16 }, // 0x37 '7' + { 370, 10, 17, 12, 1, -16 }, // 0x38 '8' + { 392, 9, 17, 12, 1, -16 }, // 0x39 '9' + { 412, 2, 13, 6, 2, -12 }, // 0x3A ':' + { 416, 3, 16, 6, 1, -12 }, // 0x3B ';' + { 422, 8, 10, 11, 1, -10 }, // 0x3C '<' + { 432, 8, 7, 12, 2, -10 }, // 0x3D '=' + { 439, 9, 10, 11, 1, -10 }, // 0x3E '>' + { 451, 8, 17, 10, 1, -16 }, // 0x3F '?' + { 468, 17, 22, 19, 1, -16 }, // 0x40 '@' + { 515, 13, 17, 13, 0, -16 }, // 0x41 'A' + { 543, 10, 17, 13, 2, -16 }, // 0x42 'B' + { 565, 11, 17, 13, 1, -16 }, // 0x43 'C' + { 589, 11, 17, 14, 2, -16 }, // 0x44 'D' + { 613, 9, 17, 12, 2, -16 }, // 0x45 'E' + { 633, 9, 17, 12, 2, -16 }, // 0x46 'F' + { 653, 11, 17, 14, 1, -16 }, // 0x47 'G' + { 677, 11, 17, 15, 2, -16 }, // 0x48 'H' + { 701, 2, 17, 6, 2, -16 }, // 0x49 'I' + { 706, 9, 17, 12, 1, -16 }, // 0x4A 'J' + { 726, 11, 17, 13, 2, -16 }, // 0x4B 'K' + { 750, 9, 17, 11, 2, -16 }, // 0x4C 'L' + { 770, 14, 17, 17, 2, -16 }, // 0x4D 'M' + { 800, 11, 17, 15, 2, -16 }, // 0x4E 'N' + { 824, 12, 17, 14, 1, -16 }, // 0x4F 'O' + { 850, 10, 17, 13, 2, -16 }, // 0x50 'P' + { 872, 13, 19, 14, 1, -16 }, // 0x51 'Q' + { 903, 11, 17, 14, 2, -16 }, // 0x52 'R' + { 927, 11, 17, 13, 1, -16 }, // 0x53 'S' + { 951, 12, 17, 12, 0, -16 }, // 0x54 'T' + { 977, 11, 17, 14, 1, -16 }, // 0x55 'U' + { 1001, 13, 17, 13, 0, -16 }, // 0x56 'V' + { 1029, 18, 17, 18, 0, -16 }, // 0x57 'W' + { 1068, 12, 17, 13, 1, -16 }, // 0x58 'X' + { 1094, 13, 17, 13, 0, -16 }, // 0x59 'Y' + { 1122, 10, 17, 12, 1, -16 }, // 0x5A 'Z' + { 1144, 5, 24, 6, 1, -19 }, // 0x5B '[' + { 1159, 9, 18, 9, 0, -16 }, // 0x5C '\' + { 1180, 4, 24, 6, 0, -19 }, // 0x5D ']' + { 1192, 7, 9, 9, 1, -16 }, // 0x5E '^' + { 1200, 9, 2, 9, 0, 1 }, // 0x5F '_' + { 1203, 5, 3, 7, 1, -16 }, // 0x60 '`' + { 1205, 9, 13, 11, 1, -12 }, // 0x61 'a' + { 1220, 10, 19, 12, 1, -18 }, // 0x62 'b' + { 1244, 9, 13, 11, 1, -12 }, // 0x63 'c' + { 1259, 9, 19, 12, 1, -18 }, // 0x64 'd' + { 1281, 9, 13, 11, 1, -12 }, // 0x65 'e' + { 1296, 6, 19, 7, 1, -18 }, // 0x66 'f' + { 1311, 9, 18, 12, 1, -12 }, // 0x67 'g' + { 1332, 9, 19, 12, 1, -18 }, // 0x68 'h' + { 1354, 2, 18, 5, 2, -17 }, // 0x69 'i' + { 1359, 5, 23, 5, -1, -17 }, // 0x6A 'j' + { 1374, 10, 19, 11, 1, -18 }, // 0x6B 'k' + { 1398, 2, 19, 5, 2, -18 }, // 0x6C 'l' + { 1403, 16, 13, 18, 1, -12 }, // 0x6D 'm' + { 1429, 9, 13, 12, 1, -12 }, // 0x6E 'n' + { 1444, 10, 13, 12, 1, -12 }, // 0x6F 'o' + { 1461, 10, 18, 12, 1, -12 }, // 0x70 'p' + { 1484, 9, 18, 12, 1, -12 }, // 0x71 'q' + { 1505, 6, 13, 7, 1, -12 }, // 0x72 'r' + { 1515, 9, 13, 10, 1, -12 }, // 0x73 's' + { 1530, 7, 16, 7, 0, -15 }, // 0x74 't' + { 1544, 9, 13, 12, 1, -12 }, // 0x75 'u' + { 1559, 10, 13, 10, 0, -12 }, // 0x76 'v' + { 1576, 15, 13, 15, 0, -12 }, // 0x77 'w' + { 1601, 10, 13, 10, 0, -12 }, // 0x78 'x' + { 1618, 10, 18, 10, 0, -12 }, // 0x79 'y' + { 1641, 8, 13, 10, 1, -12 }, // 0x7A 'z' + { 1654, 6, 23, 7, 1, -18 }, // 0x7B '{' + { 1672, 1, 20, 5, 2, -16 }, // 0x7C '|' + { 1675, 6, 23, 7, 0, -18 }, // 0x7D '}' + { 1693, 11, 5, 14, 1, -9 } }; // 0x7E '~' const GFXfont RobotoCondensed_Regular12pt7b PROGMEM = { (uint8_t *)RobotoCondensed_Regular12pt7bBitmaps, (GFXglyph *)RobotoCondensed_Regular12pt7bGlyphs, - 0x20, 0x7E, 31 }; + 0x20, 0x7E, 31 }; // Approx. 2372 bytes +#endif // ifndef FONTS_ROBOTOCONDENSED_REGULAR12PT7B_H diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h index 7e5506ce3..1e86de1f1 100644 --- a/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h +++ b/src/src/Static/Fonts/RobotoCondensed_Regular16pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOCONDENSED_REGULAR16PT7B_H +#define FONTS_ROBOTOCONDENSED_REGULAR16PT7B_H const uint8_t RobotoCondensed_Regular16pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0xEF, 0xDF, 0xBF, 0x7C, 0xF9, 0xB3, 0x66, 0x06, 0x30, 0x18, 0xC0, 0x63, 0x01, 0x8C, @@ -236,105 +238,106 @@ const uint8_t RobotoCondensed_Regular16pt7bBitmaps[] PROGMEM = { 0x03, 0xC0 }; const GFXglyph RobotoCondensed_Regular16pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 7, 0, 0 }, // 0x20 ' ' - { 1, 3, 22, 7, 2, -21 }, // 0x21 '!' - { 10, 7, 8, 9, 1, -23 }, // 0x22 '"' - { 17, 14, 22, 16, 1, -21 }, // 0x23 '#' - { 56, 13, 29, 15, 1, -25 }, // 0x24 '$' - { 104, 18, 22, 20, 1, -21 }, // 0x25 '%' - { 154, 16, 22, 18, 1, -21 }, // 0x26 '&' - { 198, 3, 8, 5, 1, -23 }, // 0x27 ''' - { 201, 7, 32, 9, 2, -24 }, // 0x28 '(' - { 229, 7, 32, 9, 0, -24 }, // 0x29 ')' - { 257, 12, 13, 12, 0, -21 }, // 0x2A '*' - { 277, 13, 16, 15, 1, -18 }, // 0x2B '+' - { 303, 4, 7, 6, 1, -2 }, // 0x2C ',' - { 307, 7, 2, 9, 1, -10 }, // 0x2D '-' - { 309, 3, 3, 8, 2, -2 }, // 0x2E '.' - { 311, 10, 24, 10, 0, -21 }, // 0x2F '/' - { 341, 13, 22, 15, 1, -21 }, // 0x30 '0' - { 377, 8, 22, 15, 2, -21 }, // 0x31 '1' - { 399, 13, 22, 15, 1, -21 }, // 0x32 '2' - { 435, 13, 22, 15, 1, -21 }, // 0x33 '3' - { 471, 13, 22, 15, 1, -21 }, // 0x34 '4' - { 507, 12, 22, 15, 2, -21 }, // 0x35 '5' - { 540, 12, 22, 15, 2, -21 }, // 0x36 '6' - { 573, 13, 22, 15, 1, -21 }, // 0x37 '7' - { 609, 13, 22, 15, 1, -21 }, // 0x38 '8' - { 645, 13, 22, 15, 1, -21 }, // 0x39 '9' - { 681, 3, 17, 7, 2, -16 }, // 0x3A ':' - { 688, 4, 21, 7, 1, -16 }, // 0x3B ';' - { 699, 11, 14, 14, 1, -15 }, // 0x3C '<' - { 719, 11, 8, 15, 2, -13 }, // 0x3D '=' - { 730, 11, 14, 14, 2, -15 }, // 0x3E '>' - { 750, 11, 22, 13, 1, -21 }, // 0x3F '?' - { 781, 23, 29, 25, 1, -21 }, // 0x40 '@' - { 865, 17, 22, 17, 0, -21 }, // 0x41 'A' - { 912, 14, 22, 17, 2, -21 }, // 0x42 'B' - { 951, 14, 22, 16, 1, -21 }, // 0x43 'C' - { 990, 14, 22, 17, 2, -21 }, // 0x44 'D' - { 1029, 13, 22, 15, 2, -21 }, // 0x45 'E' - { 1065, 13, 22, 15, 2, -21 }, // 0x46 'F' - { 1101, 14, 22, 18, 2, -21 }, // 0x47 'G' - { 1140, 15, 22, 19, 2, -21 }, // 0x48 'H' - { 1182, 3, 22, 8, 2, -21 }, // 0x49 'I' - { 1191, 12, 22, 15, 1, -21 }, // 0x4A 'J' - { 1224, 15, 22, 17, 2, -21 }, // 0x4B 'K' - { 1266, 12, 22, 14, 2, -21 }, // 0x4C 'L' - { 1299, 18, 22, 22, 2, -21 }, // 0x4D 'M' - { 1349, 15, 22, 19, 2, -21 }, // 0x4E 'N' - { 1391, 15, 22, 18, 1, -21 }, // 0x4F 'O' - { 1433, 14, 22, 17, 2, -21 }, // 0x50 'P' - { 1472, 17, 25, 18, 1, -21 }, // 0x51 'Q' - { 1526, 14, 22, 18, 2, -21 }, // 0x52 'R' - { 1565, 14, 22, 16, 1, -21 }, // 0x53 'S' - { 1604, 14, 22, 15, 1, -21 }, // 0x54 'T' - { 1643, 14, 22, 18, 2, -21 }, // 0x55 'U' - { 1682, 17, 22, 17, 0, -21 }, // 0x56 'V' - { 1729, 22, 22, 23, 1, -21 }, // 0x57 'W' - { 1790, 15, 22, 17, 1, -21 }, // 0x58 'X' - { 1832, 16, 22, 17, 0, -21 }, // 0x59 'Y' - { 1876, 13, 22, 15, 1, -21 }, // 0x5A 'Z' - { 1912, 5, 30, 8, 2, -24 }, // 0x5B '[' - { 1931, 11, 24, 11, 0, -21 }, // 0x5C '\' - { 1964, 6, 30, 8, 0, -24 }, // 0x5D ']' - { 1987, 10, 11, 11, 1, -21 }, // 0x5E '^' - { 2001, 12, 2, 12, 0, 1 }, // 0x5F '_' - { 2004, 6, 4, 9, 1, -21 }, // 0x60 '`' - { 2007, 12, 17, 14, 1, -16 }, // 0x61 'a' - { 2033, 12, 24, 15, 2, -23 }, // 0x62 'b' - { 2069, 12, 17, 14, 1, -16 }, // 0x63 'c' - { 2095, 12, 24, 15, 1, -23 }, // 0x64 'd' - { 2131, 12, 17, 14, 1, -16 }, // 0x65 'e' - { 2157, 9, 24, 9, 1, -23 }, // 0x66 'f' - { 2184, 12, 23, 15, 1, -16 }, // 0x67 'g' - { 2219, 11, 24, 15, 2, -23 }, // 0x68 'h' - { 2252, 3, 24, 7, 2, -23 }, // 0x69 'i' - { 2261, 6, 30, 7, -1, -23 }, // 0x6A 'j' - { 2284, 12, 24, 14, 2, -23 }, // 0x6B 'k' - { 2320, 3, 24, 7, 2, -23 }, // 0x6C 'l' - { 2329, 19, 17, 23, 2, -16 }, // 0x6D 'm' - { 2370, 11, 17, 15, 2, -16 }, // 0x6E 'n' - { 2394, 13, 17, 15, 1, -16 }, // 0x6F 'o' - { 2422, 12, 23, 15, 2, -16 }, // 0x70 'p' - { 2457, 12, 23, 15, 1, -16 }, // 0x71 'q' - { 2492, 7, 17, 10, 2, -16 }, // 0x72 'r' - { 2507, 11, 17, 13, 1, -16 }, // 0x73 's' - { 2531, 9, 21, 10, 0, -20 }, // 0x74 't' - { 2555, 11, 17, 15, 2, -16 }, // 0x75 'u' - { 2579, 12, 17, 14, 1, -16 }, // 0x76 'v' - { 2605, 18, 17, 20, 1, -16 }, // 0x77 'w' - { 2644, 12, 17, 14, 1, -16 }, // 0x78 'x' - { 2670, 13, 23, 14, 0, -16 }, // 0x79 'y' - { 2708, 11, 17, 13, 1, -16 }, // 0x7A 'z' - { 2732, 8, 30, 9, 1, -23 }, // 0x7B '{' - { 2762, 2, 26, 7, 2, -21 }, // 0x7C '|' - { 2769, 8, 30, 9, 0, -23 }, // 0x7D '}' - { 2799, 14, 6, 18, 2, -11 } }; // 0x7E '~' + { 0, 1, 1, 7, 0, 0 }, // 0x20 ' ' + { 1, 3, 22, 7, 2, -21 }, // 0x21 '!' + { 10, 7, 8, 9, 1, -23 }, // 0x22 '"' + { 17, 14, 22, 16, 1, -21 }, // 0x23 '#' + { 56, 13, 29, 15, 1, -25 }, // 0x24 '$' + { 104, 18, 22, 20, 1, -21 }, // 0x25 '%' + { 154, 16, 22, 18, 1, -21 }, // 0x26 '&' + { 198, 3, 8, 5, 1, -23 }, // 0x27 ''' + { 201, 7, 32, 9, 2, -24 }, // 0x28 '(' + { 229, 7, 32, 9, 0, -24 }, // 0x29 ')' + { 257, 12, 13, 12, 0, -21 }, // 0x2A '*' + { 277, 13, 16, 15, 1, -18 }, // 0x2B '+' + { 303, 4, 7, 6, 1, -2 }, // 0x2C ',' + { 307, 7, 2, 9, 1, -10 }, // 0x2D '-' + { 309, 3, 3, 8, 2, -2 }, // 0x2E '.' + { 311, 10, 24, 10, 0, -21 }, // 0x2F '/' + { 341, 13, 22, 15, 1, -21 }, // 0x30 '0' + { 377, 8, 22, 15, 2, -21 }, // 0x31 '1' + { 399, 13, 22, 15, 1, -21 }, // 0x32 '2' + { 435, 13, 22, 15, 1, -21 }, // 0x33 '3' + { 471, 13, 22, 15, 1, -21 }, // 0x34 '4' + { 507, 12, 22, 15, 2, -21 }, // 0x35 '5' + { 540, 12, 22, 15, 2, -21 }, // 0x36 '6' + { 573, 13, 22, 15, 1, -21 }, // 0x37 '7' + { 609, 13, 22, 15, 1, -21 }, // 0x38 '8' + { 645, 13, 22, 15, 1, -21 }, // 0x39 '9' + { 681, 3, 17, 7, 2, -16 }, // 0x3A ':' + { 688, 4, 21, 7, 1, -16 }, // 0x3B ';' + { 699, 11, 14, 14, 1, -15 }, // 0x3C '<' + { 719, 11, 8, 15, 2, -13 }, // 0x3D '=' + { 730, 11, 14, 14, 2, -15 }, // 0x3E '>' + { 750, 11, 22, 13, 1, -21 }, // 0x3F '?' + { 781, 23, 29, 25, 1, -21 }, // 0x40 '@' + { 865, 17, 22, 17, 0, -21 }, // 0x41 'A' + { 912, 14, 22, 17, 2, -21 }, // 0x42 'B' + { 951, 14, 22, 16, 1, -21 }, // 0x43 'C' + { 990, 14, 22, 17, 2, -21 }, // 0x44 'D' + { 1029, 13, 22, 15, 2, -21 }, // 0x45 'E' + { 1065, 13, 22, 15, 2, -21 }, // 0x46 'F' + { 1101, 14, 22, 18, 2, -21 }, // 0x47 'G' + { 1140, 15, 22, 19, 2, -21 }, // 0x48 'H' + { 1182, 3, 22, 8, 2, -21 }, // 0x49 'I' + { 1191, 12, 22, 15, 1, -21 }, // 0x4A 'J' + { 1224, 15, 22, 17, 2, -21 }, // 0x4B 'K' + { 1266, 12, 22, 14, 2, -21 }, // 0x4C 'L' + { 1299, 18, 22, 22, 2, -21 }, // 0x4D 'M' + { 1349, 15, 22, 19, 2, -21 }, // 0x4E 'N' + { 1391, 15, 22, 18, 1, -21 }, // 0x4F 'O' + { 1433, 14, 22, 17, 2, -21 }, // 0x50 'P' + { 1472, 17, 25, 18, 1, -21 }, // 0x51 'Q' + { 1526, 14, 22, 18, 2, -21 }, // 0x52 'R' + { 1565, 14, 22, 16, 1, -21 }, // 0x53 'S' + { 1604, 14, 22, 15, 1, -21 }, // 0x54 'T' + { 1643, 14, 22, 18, 2, -21 }, // 0x55 'U' + { 1682, 17, 22, 17, 0, -21 }, // 0x56 'V' + { 1729, 22, 22, 23, 1, -21 }, // 0x57 'W' + { 1790, 15, 22, 17, 1, -21 }, // 0x58 'X' + { 1832, 16, 22, 17, 0, -21 }, // 0x59 'Y' + { 1876, 13, 22, 15, 1, -21 }, // 0x5A 'Z' + { 1912, 5, 30, 8, 2, -24 }, // 0x5B '[' + { 1931, 11, 24, 11, 0, -21 }, // 0x5C '\' + { 1964, 6, 30, 8, 0, -24 }, // 0x5D ']' + { 1987, 10, 11, 11, 1, -21 }, // 0x5E '^' + { 2001, 12, 2, 12, 0, 1 }, // 0x5F '_' + { 2004, 6, 4, 9, 1, -21 }, // 0x60 '`' + { 2007, 12, 17, 14, 1, -16 }, // 0x61 'a' + { 2033, 12, 24, 15, 2, -23 }, // 0x62 'b' + { 2069, 12, 17, 14, 1, -16 }, // 0x63 'c' + { 2095, 12, 24, 15, 1, -23 }, // 0x64 'd' + { 2131, 12, 17, 14, 1, -16 }, // 0x65 'e' + { 2157, 9, 24, 9, 1, -23 }, // 0x66 'f' + { 2184, 12, 23, 15, 1, -16 }, // 0x67 'g' + { 2219, 11, 24, 15, 2, -23 }, // 0x68 'h' + { 2252, 3, 24, 7, 2, -23 }, // 0x69 'i' + { 2261, 6, 30, 7, -1, -23 }, // 0x6A 'j' + { 2284, 12, 24, 14, 2, -23 }, // 0x6B 'k' + { 2320, 3, 24, 7, 2, -23 }, // 0x6C 'l' + { 2329, 19, 17, 23, 2, -16 }, // 0x6D 'm' + { 2370, 11, 17, 15, 2, -16 }, // 0x6E 'n' + { 2394, 13, 17, 15, 1, -16 }, // 0x6F 'o' + { 2422, 12, 23, 15, 2, -16 }, // 0x70 'p' + { 2457, 12, 23, 15, 1, -16 }, // 0x71 'q' + { 2492, 7, 17, 10, 2, -16 }, // 0x72 'r' + { 2507, 11, 17, 13, 1, -16 }, // 0x73 's' + { 2531, 9, 21, 10, 0, -20 }, // 0x74 't' + { 2555, 11, 17, 15, 2, -16 }, // 0x75 'u' + { 2579, 12, 17, 14, 1, -16 }, // 0x76 'v' + { 2605, 18, 17, 20, 1, -16 }, // 0x77 'w' + { 2644, 12, 17, 14, 1, -16 }, // 0x78 'x' + { 2670, 13, 23, 14, 0, -16 }, // 0x79 'y' + { 2708, 11, 17, 13, 1, -16 }, // 0x7A 'z' + { 2732, 8, 30, 9, 1, -23 }, // 0x7B '{' + { 2762, 2, 26, 7, 2, -21 }, // 0x7C '|' + { 2769, 8, 30, 9, 0, -23 }, // 0x7D '}' + { 2799, 14, 6, 18, 2, -11 } }; // 0x7E '~' const GFXfont RobotoCondensed_Regular16pt7b PROGMEM = { (uint8_t *)RobotoCondensed_Regular16pt7bBitmaps, (GFXglyph *)RobotoCondensed_Regular16pt7bGlyphs, - 0x20, 0x7E, 41 }; + 0x20, 0x7E, 41 }; // Approx. 3482 bytes +#endif // ifndef FONTS_ROBOTOCONDENSED_REGULAR16PT7B_H diff --git a/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h b/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h index e38dcd61c..e5f923c4c 100644 --- a/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h +++ b/src/src/Static/Fonts/RobotoCondensed_Regular8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOCONDENSED_REGULAR8PT7B_H +#define FONTS_ROBOTOCONDENSED_REGULAR8PT7B_H const uint8_t RobotoCondensed_Regular8pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0x0F, 0xB6, 0xD0, 0x12, 0x12, 0x12, 0x14, 0x7F, 0x14, 0x24, 0x24, 0xFE, 0x2C, 0x28, 0x68, 0x11, 0xEC, 0xF3, 0xCF, 0x06, 0x0E, @@ -68,105 +70,106 @@ const uint8_t RobotoCondensed_Regular8pt7bBitmaps[] PROGMEM = { 0x64, 0x80, 0x63, 0x26, 0x30 }; const GFXglyph RobotoCondensed_Regular8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 3, 0, 0 }, // 0x20 ' ' - { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' - { 4, 3, 4, 5, 1, -11 }, // 0x22 '"' - { 6, 8, 12, 8, 0, -11 }, // 0x23 '#' - { 18, 6, 15, 8, 1, -12 }, // 0x24 '$' - { 30, 9, 12, 11, 1, -11 }, // 0x25 '%' - { 44, 8, 12, 9, 1, -11 }, // 0x26 '&' - { 56, 1, 4, 3, 1, -11 }, // 0x27 ''' - { 57, 3, 17, 5, 1, -12 }, // 0x28 '(' - { 64, 4, 17, 5, 0, -12 }, // 0x29 ')' - { 73, 6, 7, 6, 0, -11 }, // 0x2A '*' - { 79, 6, 8, 8, 1, -8 }, // 0x2B '+' - { 85, 2, 4, 3, 0, -1 }, // 0x2C ',' - { 86, 3, 1, 5, 1, -4 }, // 0x2D '-' - { 87, 2, 2, 4, 1, -1 }, // 0x2E '.' - { 88, 5, 13, 5, 0, -11 }, // 0x2F '/' - { 97, 6, 12, 8, 1, -11 }, // 0x30 '0' - { 106, 4, 12, 8, 1, -11 }, // 0x31 '1' - { 112, 6, 12, 8, 1, -11 }, // 0x32 '2' - { 121, 6, 12, 8, 1, -11 }, // 0x33 '3' - { 130, 7, 12, 8, 0, -11 }, // 0x34 '4' - { 141, 6, 12, 8, 1, -11 }, // 0x35 '5' - { 150, 6, 12, 8, 1, -11 }, // 0x36 '6' - { 159, 6, 12, 8, 1, -11 }, // 0x37 '7' - { 168, 6, 12, 8, 1, -11 }, // 0x38 '8' - { 177, 6, 12, 8, 1, -11 }, // 0x39 '9' - { 186, 2, 9, 4, 1, -8 }, // 0x3A ':' - { 189, 2, 11, 4, 1, -8 }, // 0x3B ';' - { 192, 6, 7, 7, 0, -7 }, // 0x3C '<' - { 198, 6, 4, 8, 1, -6 }, // 0x3D '=' - { 201, 6, 7, 7, 1, -7 }, // 0x3E '>' - { 207, 6, 12, 7, 0, -11 }, // 0x3F '?' - { 216, 11, 15, 13, 1, -10 }, // 0x40 '@' - { 237, 9, 12, 9, 0, -11 }, // 0x41 'A' - { 251, 7, 12, 9, 1, -11 }, // 0x42 'B' - { 262, 7, 12, 8, 1, -11 }, // 0x43 'C' - { 273, 7, 12, 9, 1, -11 }, // 0x44 'D' - { 284, 7, 12, 8, 1, -11 }, // 0x45 'E' - { 295, 7, 12, 8, 1, -11 }, // 0x46 'F' - { 306, 7, 12, 9, 1, -11 }, // 0x47 'G' - { 317, 8, 12, 10, 1, -11 }, // 0x48 'H' - { 329, 2, 12, 4, 1, -11 }, // 0x49 'I' - { 332, 7, 12, 8, 0, -11 }, // 0x4A 'J' - { 343, 8, 12, 9, 1, -11 }, // 0x4B 'K' - { 355, 6, 12, 7, 1, -11 }, // 0x4C 'L' - { 364, 10, 12, 12, 1, -11 }, // 0x4D 'M' - { 379, 8, 12, 10, 1, -11 }, // 0x4E 'N' - { 391, 7, 12, 9, 1, -11 }, // 0x4F 'O' - { 402, 7, 12, 9, 1, -11 }, // 0x50 'P' - { 413, 8, 14, 9, 1, -11 }, // 0x51 'Q' - { 427, 8, 12, 9, 1, -11 }, // 0x52 'R' - { 439, 7, 12, 9, 1, -11 }, // 0x53 'S' - { 450, 8, 12, 8, 0, -11 }, // 0x54 'T' - { 462, 7, 12, 9, 1, -11 }, // 0x55 'U' - { 473, 9, 12, 9, 0, -11 }, // 0x56 'V' - { 487, 12, 12, 12, 0, -11 }, // 0x57 'W' - { 505, 8, 12, 9, 0, -11 }, // 0x58 'X' - { 517, 8, 12, 9, 0, -11 }, // 0x59 'Y' - { 529, 6, 12, 8, 1, -11 }, // 0x5A 'Z' - { 538, 3, 16, 4, 1, -12 }, // 0x5B '[' - { 544, 6, 13, 6, 0, -11 }, // 0x5C '\' - { 554, 3, 16, 4, 0, -12 }, // 0x5D ']' - { 560, 6, 6, 6, 0, -11 }, // 0x5E '^' - { 565, 6, 1, 6, 0, 1 }, // 0x5F '_' - { 566, 3, 2, 5, 1, -11 }, // 0x60 '`' - { 567, 6, 9, 7, 1, -8 }, // 0x61 'a' - { 574, 6, 12, 8, 1, -11 }, // 0x62 'b' - { 583, 6, 9, 7, 1, -8 }, // 0x63 'c' - { 590, 6, 12, 8, 1, -11 }, // 0x64 'd' - { 599, 6, 9, 7, 1, -8 }, // 0x65 'e' - { 606, 5, 12, 5, 0, -11 }, // 0x66 'f' - { 614, 6, 13, 8, 1, -8 }, // 0x67 'g' - { 624, 6, 12, 8, 1, -11 }, // 0x68 'h' - { 633, 2, 13, 4, 1, -12 }, // 0x69 'i' - { 637, 4, 17, 4, -1, -12 }, // 0x6A 'j' - { 646, 6, 12, 7, 1, -11 }, // 0x6B 'k' - { 655, 2, 12, 4, 1, -11 }, // 0x6C 'l' - { 658, 10, 9, 12, 1, -8 }, // 0x6D 'm' - { 670, 6, 9, 8, 1, -8 }, // 0x6E 'n' - { 677, 6, 9, 8, 1, -8 }, // 0x6F 'o' - { 684, 6, 13, 8, 1, -8 }, // 0x70 'p' - { 694, 6, 13, 8, 1, -8 }, // 0x71 'q' - { 704, 4, 9, 5, 1, -8 }, // 0x72 'r' - { 709, 6, 9, 7, 0, -8 }, // 0x73 's' - { 716, 5, 11, 5, 0, -10 }, // 0x74 't' - { 723, 6, 9, 8, 1, -8 }, // 0x75 'u' - { 730, 7, 9, 7, 0, -8 }, // 0x76 'v' - { 738, 10, 9, 10, 0, -8 }, // 0x77 'w' - { 750, 7, 9, 7, 0, -8 }, // 0x78 'x' - { 758, 7, 13, 7, 0, -8 }, // 0x79 'y' - { 770, 5, 9, 7, 1, -8 }, // 0x7A 'z' - { 776, 4, 15, 5, 0, -11 }, // 0x7B '{' - { 784, 1, 14, 3, 1, -11 }, // 0x7C '|' - { 786, 4, 15, 5, 0, -11 }, // 0x7D '}' - { 794, 7, 3, 9, 1, -5 } }; // 0x7E '~' + { 0, 1, 1, 3, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' + { 4, 3, 4, 5, 1, -11 }, // 0x22 '"' + { 6, 8, 12, 8, 0, -11 }, // 0x23 '#' + { 18, 6, 15, 8, 1, -12 }, // 0x24 '$' + { 30, 9, 12, 11, 1, -11 }, // 0x25 '%' + { 44, 8, 12, 9, 1, -11 }, // 0x26 '&' + { 56, 1, 4, 3, 1, -11 }, // 0x27 ''' + { 57, 3, 17, 5, 1, -12 }, // 0x28 '(' + { 64, 4, 17, 5, 0, -12 }, // 0x29 ')' + { 73, 6, 7, 6, 0, -11 }, // 0x2A '*' + { 79, 6, 8, 8, 1, -8 }, // 0x2B '+' + { 85, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 86, 3, 1, 5, 1, -4 }, // 0x2D '-' + { 87, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 88, 5, 13, 5, 0, -11 }, // 0x2F '/' + { 97, 6, 12, 8, 1, -11 }, // 0x30 '0' + { 106, 4, 12, 8, 1, -11 }, // 0x31 '1' + { 112, 6, 12, 8, 1, -11 }, // 0x32 '2' + { 121, 6, 12, 8, 1, -11 }, // 0x33 '3' + { 130, 7, 12, 8, 0, -11 }, // 0x34 '4' + { 141, 6, 12, 8, 1, -11 }, // 0x35 '5' + { 150, 6, 12, 8, 1, -11 }, // 0x36 '6' + { 159, 6, 12, 8, 1, -11 }, // 0x37 '7' + { 168, 6, 12, 8, 1, -11 }, // 0x38 '8' + { 177, 6, 12, 8, 1, -11 }, // 0x39 '9' + { 186, 2, 9, 4, 1, -8 }, // 0x3A ':' + { 189, 2, 11, 4, 1, -8 }, // 0x3B ';' + { 192, 6, 7, 7, 0, -7 }, // 0x3C '<' + { 198, 6, 4, 8, 1, -6 }, // 0x3D '=' + { 201, 6, 7, 7, 1, -7 }, // 0x3E '>' + { 207, 6, 12, 7, 0, -11 }, // 0x3F '?' + { 216, 11, 15, 13, 1, -10 }, // 0x40 '@' + { 237, 9, 12, 9, 0, -11 }, // 0x41 'A' + { 251, 7, 12, 9, 1, -11 }, // 0x42 'B' + { 262, 7, 12, 8, 1, -11 }, // 0x43 'C' + { 273, 7, 12, 9, 1, -11 }, // 0x44 'D' + { 284, 7, 12, 8, 1, -11 }, // 0x45 'E' + { 295, 7, 12, 8, 1, -11 }, // 0x46 'F' + { 306, 7, 12, 9, 1, -11 }, // 0x47 'G' + { 317, 8, 12, 10, 1, -11 }, // 0x48 'H' + { 329, 2, 12, 4, 1, -11 }, // 0x49 'I' + { 332, 7, 12, 8, 0, -11 }, // 0x4A 'J' + { 343, 8, 12, 9, 1, -11 }, // 0x4B 'K' + { 355, 6, 12, 7, 1, -11 }, // 0x4C 'L' + { 364, 10, 12, 12, 1, -11 }, // 0x4D 'M' + { 379, 8, 12, 10, 1, -11 }, // 0x4E 'N' + { 391, 7, 12, 9, 1, -11 }, // 0x4F 'O' + { 402, 7, 12, 9, 1, -11 }, // 0x50 'P' + { 413, 8, 14, 9, 1, -11 }, // 0x51 'Q' + { 427, 8, 12, 9, 1, -11 }, // 0x52 'R' + { 439, 7, 12, 9, 1, -11 }, // 0x53 'S' + { 450, 8, 12, 8, 0, -11 }, // 0x54 'T' + { 462, 7, 12, 9, 1, -11 }, // 0x55 'U' + { 473, 9, 12, 9, 0, -11 }, // 0x56 'V' + { 487, 12, 12, 12, 0, -11 }, // 0x57 'W' + { 505, 8, 12, 9, 0, -11 }, // 0x58 'X' + { 517, 8, 12, 9, 0, -11 }, // 0x59 'Y' + { 529, 6, 12, 8, 1, -11 }, // 0x5A 'Z' + { 538, 3, 16, 4, 1, -12 }, // 0x5B '[' + { 544, 6, 13, 6, 0, -11 }, // 0x5C '\' + { 554, 3, 16, 4, 0, -12 }, // 0x5D ']' + { 560, 6, 6, 6, 0, -11 }, // 0x5E '^' + { 565, 6, 1, 6, 0, 1 }, // 0x5F '_' + { 566, 3, 2, 5, 1, -11 }, // 0x60 '`' + { 567, 6, 9, 7, 1, -8 }, // 0x61 'a' + { 574, 6, 12, 8, 1, -11 }, // 0x62 'b' + { 583, 6, 9, 7, 1, -8 }, // 0x63 'c' + { 590, 6, 12, 8, 1, -11 }, // 0x64 'd' + { 599, 6, 9, 7, 1, -8 }, // 0x65 'e' + { 606, 5, 12, 5, 0, -11 }, // 0x66 'f' + { 614, 6, 13, 8, 1, -8 }, // 0x67 'g' + { 624, 6, 12, 8, 1, -11 }, // 0x68 'h' + { 633, 2, 13, 4, 1, -12 }, // 0x69 'i' + { 637, 4, 17, 4, -1, -12 }, // 0x6A 'j' + { 646, 6, 12, 7, 1, -11 }, // 0x6B 'k' + { 655, 2, 12, 4, 1, -11 }, // 0x6C 'l' + { 658, 10, 9, 12, 1, -8 }, // 0x6D 'm' + { 670, 6, 9, 8, 1, -8 }, // 0x6E 'n' + { 677, 6, 9, 8, 1, -8 }, // 0x6F 'o' + { 684, 6, 13, 8, 1, -8 }, // 0x70 'p' + { 694, 6, 13, 8, 1, -8 }, // 0x71 'q' + { 704, 4, 9, 5, 1, -8 }, // 0x72 'r' + { 709, 6, 9, 7, 0, -8 }, // 0x73 's' + { 716, 5, 11, 5, 0, -10 }, // 0x74 't' + { 723, 6, 9, 8, 1, -8 }, // 0x75 'u' + { 730, 7, 9, 7, 0, -8 }, // 0x76 'v' + { 738, 10, 9, 10, 0, -8 }, // 0x77 'w' + { 750, 7, 9, 7, 0, -8 }, // 0x78 'x' + { 758, 7, 13, 7, 0, -8 }, // 0x79 'y' + { 770, 5, 9, 7, 1, -8 }, // 0x7A 'z' + { 776, 4, 15, 5, 0, -11 }, // 0x7B '{' + { 784, 1, 14, 3, 1, -11 }, // 0x7C '|' + { 786, 4, 15, 5, 0, -11 }, // 0x7D '}' + { 794, 7, 3, 9, 1, -5 } }; // 0x7E '~' const GFXfont RobotoCondensed_Regular8pt7b PROGMEM = { (uint8_t *)RobotoCondensed_Regular8pt7bBitmaps, (GFXglyph *)RobotoCondensed_Regular8pt7bGlyphs, - 0x20, 0x7E, 21 }; + 0x20, 0x7E, 21 }; // Approx. 1469 bytes +#endif // ifndef FONTS_ROBOTOCONDENSED_REGULAR8PT7B_H diff --git a/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h index b8112a755..3e0db9a30 100644 --- a/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h +++ b/src/src/Static/Fonts/RobotoMono_Regular12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOMONO_REGULAR12PT7B_H +#define FONTS_ROBOTOMONO_REGULAR12PT7B_H const uint8_t RobotoMono_Regular12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xC0, 0xCF, 0x3C, 0xF3, 0xCF, 0x30, 0x06, 0x20, 0x23, 0x03, 0x18, 0x18, 0xC0, 0xC6, 0x3F, 0xFD, 0xFF, 0xE3, 0x18, @@ -161,105 +163,106 @@ const uint8_t RobotoMono_Regular12pt7bBitmaps[] PROGMEM = { 0x07, 0xE0, 0xF1, 0x87, 0x07, 0xE0, 0x1E, 0x00 }; const GFXglyph RobotoMono_Regular12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 14, 0, 0 }, // 0x20 ' ' - { 1, 2, 17, 14, 6, -16 }, // 0x21 '!' - { 6, 6, 6, 14, 4, -17 }, // 0x22 '"' - { 11, 13, 17, 14, 1, -16 }, // 0x23 '#' - { 39, 11, 22, 14, 2, -19 }, // 0x24 '$' - { 70, 13, 17, 14, 1, -16 }, // 0x25 '%' - { 98, 13, 17, 14, 1, -16 }, // 0x26 '&' - { 126, 2, 6, 14, 6, -17 }, // 0x27 ''' - { 128, 6, 25, 14, 4, -18 }, // 0x28 '(' - { 147, 6, 25, 14, 4, -18 }, // 0x29 ')' - { 166, 11, 12, 14, 2, -13 }, // 0x2A '*' - { 183, 12, 13, 14, 1, -14 }, // 0x2B '+' - { 203, 4, 7, 14, 4, -2 }, // 0x2C ',' - { 207, 9, 2, 14, 3, -8 }, // 0x2D '-' - { 210, 3, 3, 14, 6, -2 }, // 0x2E '.' - { 212, 9, 18, 14, 3, -16 }, // 0x2F '/' - { 233, 11, 17, 14, 2, -16 }, // 0x30 '0' - { 257, 7, 17, 14, 2, -16 }, // 0x31 '1' - { 272, 12, 17, 14, 1, -16 }, // 0x32 '2' - { 298, 11, 17, 14, 1, -16 }, // 0x33 '3' - { 322, 12, 17, 14, 1, -16 }, // 0x34 '4' - { 348, 11, 17, 14, 2, -16 }, // 0x35 '5' - { 372, 10, 17, 14, 2, -16 }, // 0x36 '6' - { 394, 12, 17, 14, 1, -16 }, // 0x37 '7' - { 420, 11, 17, 14, 2, -16 }, // 0x38 '8' - { 444, 10, 17, 14, 2, -16 }, // 0x39 '9' - { 466, 4, 13, 14, 6, -12 }, // 0x3A ':' - { 473, 4, 17, 14, 6, -12 }, // 0x3B ';' - { 482, 10, 11, 14, 2, -12 }, // 0x3C '<' - { 496, 11, 7, 14, 2, -10 }, // 0x3D '=' - { 506, 10, 11, 14, 2, -12 }, // 0x3E '>' - { 520, 10, 17, 14, 2, -16 }, // 0x3F '?' - { 542, 13, 17, 14, 1, -16 }, // 0x40 '@' - { 570, 13, 17, 14, 1, -16 }, // 0x41 'A' - { 598, 11, 17, 14, 2, -16 }, // 0x42 'B' - { 622, 12, 17, 14, 1, -16 }, // 0x43 'C' - { 648, 11, 17, 14, 2, -16 }, // 0x44 'D' - { 672, 11, 17, 14, 2, -16 }, // 0x45 'E' - { 696, 11, 17, 14, 2, -16 }, // 0x46 'F' - { 720, 12, 17, 14, 1, -16 }, // 0x47 'G' - { 746, 11, 17, 14, 2, -16 }, // 0x48 'H' - { 770, 10, 17, 14, 2, -16 }, // 0x49 'I' - { 792, 11, 17, 14, 1, -16 }, // 0x4A 'J' - { 816, 12, 17, 14, 2, -16 }, // 0x4B 'K' - { 842, 11, 17, 14, 2, -16 }, // 0x4C 'L' - { 866, 11, 17, 14, 2, -16 }, // 0x4D 'M' - { 890, 11, 17, 14, 2, -16 }, // 0x4E 'N' - { 914, 12, 17, 14, 1, -16 }, // 0x4F 'O' - { 940, 11, 17, 14, 2, -16 }, // 0x50 'P' - { 964, 13, 20, 14, 1, -16 }, // 0x51 'Q' - { 997, 11, 17, 14, 2, -16 }, // 0x52 'R' - { 1021, 12, 17, 14, 1, -16 }, // 0x53 'S' - { 1047, 13, 17, 14, 1, -16 }, // 0x54 'T' - { 1075, 11, 17, 14, 2, -16 }, // 0x55 'U' - { 1099, 12, 17, 14, 1, -16 }, // 0x56 'V' - { 1125, 13, 17, 14, 1, -16 }, // 0x57 'W' - { 1153, 13, 17, 14, 1, -16 }, // 0x58 'X' - { 1181, 12, 17, 14, 1, -16 }, // 0x59 'Y' - { 1207, 12, 17, 14, 1, -16 }, // 0x5A 'Z' - { 1233, 5, 23, 14, 5, -18 }, // 0x5B '[' - { 1248, 9, 18, 14, 3, -16 }, // 0x5C '\' - { 1269, 4, 23, 14, 5, -18 }, // 0x5D ']' - { 1281, 9, 9, 14, 3, -16 }, // 0x5E '^' - { 1292, 11, 2, 14, 2, 1 }, // 0x5F '_' - { 1295, 5, 3, 14, 5, -17 }, // 0x60 '`' - { 1297, 11, 13, 14, 2, -12 }, // 0x61 'a' - { 1315, 11, 18, 14, 2, -17 }, // 0x62 'b' - { 1340, 11, 13, 14, 2, -12 }, // 0x63 'c' - { 1358, 10, 18, 14, 2, -17 }, // 0x64 'd' - { 1381, 11, 13, 14, 2, -12 }, // 0x65 'e' - { 1399, 11, 19, 14, 2, -18 }, // 0x66 'f' - { 1426, 10, 18, 14, 2, -12 }, // 0x67 'g' - { 1449, 11, 18, 14, 2, -17 }, // 0x68 'h' - { 1474, 11, 17, 14, 2, -16 }, // 0x69 'i' - { 1498, 8, 22, 14, 2, -16 }, // 0x6A 'j' - { 1520, 11, 18, 14, 2, -17 }, // 0x6B 'k' - { 1545, 11, 18, 14, 2, -17 }, // 0x6C 'l' - { 1570, 12, 13, 14, 1, -12 }, // 0x6D 'm' - { 1590, 10, 13, 14, 2, -12 }, // 0x6E 'n' - { 1607, 12, 13, 14, 1, -12 }, // 0x6F 'o' - { 1627, 11, 18, 14, 2, -12 }, // 0x70 'p' - { 1652, 10, 18, 14, 2, -12 }, // 0x71 'q' - { 1675, 9, 13, 14, 4, -12 }, // 0x72 'r' - { 1690, 11, 13, 14, 2, -12 }, // 0x73 's' - { 1708, 10, 16, 14, 2, -15 }, // 0x74 't' - { 1728, 10, 13, 14, 2, -12 }, // 0x75 'u' - { 1745, 12, 13, 14, 1, -12 }, // 0x76 'v' - { 1765, 13, 13, 14, 1, -12 }, // 0x77 'w' - { 1787, 12, 13, 14, 1, -12 }, // 0x78 'x' - { 1807, 13, 18, 14, 1, -12 }, // 0x79 'y' - { 1837, 11, 13, 14, 2, -12 }, // 0x7A 'z' - { 1855, 8, 23, 14, 4, -18 }, // 0x7B '{' - { 1878, 2, 22, 14, 6, -16 }, // 0x7C '|' - { 1884, 8, 23, 14, 4, -18 }, // 0x7D '}' - { 1907, 13, 5, 14, 1, -9 } }; // 0x7E '~' + { 0, 1, 1, 14, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 14, 6, -16 }, // 0x21 '!' + { 6, 6, 6, 14, 4, -17 }, // 0x22 '"' + { 11, 13, 17, 14, 1, -16 }, // 0x23 '#' + { 39, 11, 22, 14, 2, -19 }, // 0x24 '$' + { 70, 13, 17, 14, 1, -16 }, // 0x25 '%' + { 98, 13, 17, 14, 1, -16 }, // 0x26 '&' + { 126, 2, 6, 14, 6, -17 }, // 0x27 ''' + { 128, 6, 25, 14, 4, -18 }, // 0x28 '(' + { 147, 6, 25, 14, 4, -18 }, // 0x29 ')' + { 166, 11, 12, 14, 2, -13 }, // 0x2A '*' + { 183, 12, 13, 14, 1, -14 }, // 0x2B '+' + { 203, 4, 7, 14, 4, -2 }, // 0x2C ',' + { 207, 9, 2, 14, 3, -8 }, // 0x2D '-' + { 210, 3, 3, 14, 6, -2 }, // 0x2E '.' + { 212, 9, 18, 14, 3, -16 }, // 0x2F '/' + { 233, 11, 17, 14, 2, -16 }, // 0x30 '0' + { 257, 7, 17, 14, 2, -16 }, // 0x31 '1' + { 272, 12, 17, 14, 1, -16 }, // 0x32 '2' + { 298, 11, 17, 14, 1, -16 }, // 0x33 '3' + { 322, 12, 17, 14, 1, -16 }, // 0x34 '4' + { 348, 11, 17, 14, 2, -16 }, // 0x35 '5' + { 372, 10, 17, 14, 2, -16 }, // 0x36 '6' + { 394, 12, 17, 14, 1, -16 }, // 0x37 '7' + { 420, 11, 17, 14, 2, -16 }, // 0x38 '8' + { 444, 10, 17, 14, 2, -16 }, // 0x39 '9' + { 466, 4, 13, 14, 6, -12 }, // 0x3A ':' + { 473, 4, 17, 14, 6, -12 }, // 0x3B ';' + { 482, 10, 11, 14, 2, -12 }, // 0x3C '<' + { 496, 11, 7, 14, 2, -10 }, // 0x3D '=' + { 506, 10, 11, 14, 2, -12 }, // 0x3E '>' + { 520, 10, 17, 14, 2, -16 }, // 0x3F '?' + { 542, 13, 17, 14, 1, -16 }, // 0x40 '@' + { 570, 13, 17, 14, 1, -16 }, // 0x41 'A' + { 598, 11, 17, 14, 2, -16 }, // 0x42 'B' + { 622, 12, 17, 14, 1, -16 }, // 0x43 'C' + { 648, 11, 17, 14, 2, -16 }, // 0x44 'D' + { 672, 11, 17, 14, 2, -16 }, // 0x45 'E' + { 696, 11, 17, 14, 2, -16 }, // 0x46 'F' + { 720, 12, 17, 14, 1, -16 }, // 0x47 'G' + { 746, 11, 17, 14, 2, -16 }, // 0x48 'H' + { 770, 10, 17, 14, 2, -16 }, // 0x49 'I' + { 792, 11, 17, 14, 1, -16 }, // 0x4A 'J' + { 816, 12, 17, 14, 2, -16 }, // 0x4B 'K' + { 842, 11, 17, 14, 2, -16 }, // 0x4C 'L' + { 866, 11, 17, 14, 2, -16 }, // 0x4D 'M' + { 890, 11, 17, 14, 2, -16 }, // 0x4E 'N' + { 914, 12, 17, 14, 1, -16 }, // 0x4F 'O' + { 940, 11, 17, 14, 2, -16 }, // 0x50 'P' + { 964, 13, 20, 14, 1, -16 }, // 0x51 'Q' + { 997, 11, 17, 14, 2, -16 }, // 0x52 'R' + { 1021, 12, 17, 14, 1, -16 }, // 0x53 'S' + { 1047, 13, 17, 14, 1, -16 }, // 0x54 'T' + { 1075, 11, 17, 14, 2, -16 }, // 0x55 'U' + { 1099, 12, 17, 14, 1, -16 }, // 0x56 'V' + { 1125, 13, 17, 14, 1, -16 }, // 0x57 'W' + { 1153, 13, 17, 14, 1, -16 }, // 0x58 'X' + { 1181, 12, 17, 14, 1, -16 }, // 0x59 'Y' + { 1207, 12, 17, 14, 1, -16 }, // 0x5A 'Z' + { 1233, 5, 23, 14, 5, -18 }, // 0x5B '[' + { 1248, 9, 18, 14, 3, -16 }, // 0x5C '\' + { 1269, 4, 23, 14, 5, -18 }, // 0x5D ']' + { 1281, 9, 9, 14, 3, -16 }, // 0x5E '^' + { 1292, 11, 2, 14, 2, 1 }, // 0x5F '_' + { 1295, 5, 3, 14, 5, -17 }, // 0x60 '`' + { 1297, 11, 13, 14, 2, -12 }, // 0x61 'a' + { 1315, 11, 18, 14, 2, -17 }, // 0x62 'b' + { 1340, 11, 13, 14, 2, -12 }, // 0x63 'c' + { 1358, 10, 18, 14, 2, -17 }, // 0x64 'd' + { 1381, 11, 13, 14, 2, -12 }, // 0x65 'e' + { 1399, 11, 19, 14, 2, -18 }, // 0x66 'f' + { 1426, 10, 18, 14, 2, -12 }, // 0x67 'g' + { 1449, 11, 18, 14, 2, -17 }, // 0x68 'h' + { 1474, 11, 17, 14, 2, -16 }, // 0x69 'i' + { 1498, 8, 22, 14, 2, -16 }, // 0x6A 'j' + { 1520, 11, 18, 14, 2, -17 }, // 0x6B 'k' + { 1545, 11, 18, 14, 2, -17 }, // 0x6C 'l' + { 1570, 12, 13, 14, 1, -12 }, // 0x6D 'm' + { 1590, 10, 13, 14, 2, -12 }, // 0x6E 'n' + { 1607, 12, 13, 14, 1, -12 }, // 0x6F 'o' + { 1627, 11, 18, 14, 2, -12 }, // 0x70 'p' + { 1652, 10, 18, 14, 2, -12 }, // 0x71 'q' + { 1675, 9, 13, 14, 4, -12 }, // 0x72 'r' + { 1690, 11, 13, 14, 2, -12 }, // 0x73 's' + { 1708, 10, 16, 14, 2, -15 }, // 0x74 't' + { 1728, 10, 13, 14, 2, -12 }, // 0x75 'u' + { 1745, 12, 13, 14, 1, -12 }, // 0x76 'v' + { 1765, 13, 13, 14, 1, -12 }, // 0x77 'w' + { 1787, 12, 13, 14, 1, -12 }, // 0x78 'x' + { 1807, 13, 18, 14, 1, -12 }, // 0x79 'y' + { 1837, 11, 13, 14, 2, -12 }, // 0x7A 'z' + { 1855, 8, 23, 14, 4, -18 }, // 0x7B '{' + { 1878, 2, 22, 14, 6, -16 }, // 0x7C '|' + { 1884, 8, 23, 14, 4, -18 }, // 0x7D '}' + { 1907, 13, 5, 14, 1, -9 } }; // 0x7E '~' const GFXfont RobotoMono_Regular12pt7b PROGMEM = { (uint8_t *)RobotoMono_Regular12pt7bBitmaps, (GFXglyph *)RobotoMono_Regular12pt7bGlyphs, - 0x20, 0x7E, 31 }; + 0x20, 0x7E, 31 }; // Approx. 2588 bytes +#endif // ifndef FONTS_ROBOTOMONO_REGULAR12PT7B_H diff --git a/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h index 2c1fcf670..1e3839188 100644 --- a/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h +++ b/src/src/Static/Fonts/RobotoMono_Regular16pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOMONO_REGULAR16PT7B_H +#define FONTS_ROBOTOMONO_REGULAR16PT7B_H const uint8_t RobotoMono_Regular16pt7bBitmaps[] PROGMEM = { 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x00, 0x06, 0xF6, 0xE3, 0xE3, 0xE3, 0xE3, 0xC3, 0xC3, 0xC3, 0x01, 0x86, 0x01, 0x87, 0x00, @@ -265,105 +267,106 @@ const uint8_t RobotoMono_Regular16pt7bBitmaps[] PROGMEM = { 0xF8, 0x3E, 0xEC, 0x0F, 0xF0, 0x01, 0xE0 }; const GFXglyph RobotoMono_Regular16pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 19, 0, 0 }, // 0x20 ' ' - { 1, 4, 22, 19, 7, -21 }, // 0x21 '!' - { 12, 8, 7, 19, 5, -22 }, // 0x22 '"' - { 19, 17, 22, 19, 1, -21 }, // 0x23 '#' - { 66, 15, 29, 19, 2, -25 }, // 0x24 '$' - { 121, 17, 22, 19, 1, -21 }, // 0x25 '%' - { 168, 16, 22, 19, 2, -21 }, // 0x26 '&' - { 212, 3, 7, 19, 7, -22 }, // 0x27 ''' - { 215, 8, 32, 19, 5, -24 }, // 0x28 '(' - { 247, 8, 32, 19, 5, -24 }, // 0x29 ')' - { 279, 15, 15, 19, 2, -18 }, // 0x2A '*' - { 308, 15, 16, 19, 2, -17 }, // 0x2B '+' - { 338, 5, 9, 19, 5, -2 }, // 0x2C ',' - { 344, 12, 2, 19, 3, -10 }, // 0x2D '-' - { 347, 4, 4, 19, 8, -3 }, // 0x2E '.' - { 349, 12, 24, 19, 4, -21 }, // 0x2F '/' - { 385, 14, 22, 19, 2, -21 }, // 0x30 '0' - { 424, 9, 22, 19, 3, -21 }, // 0x31 '1' - { 449, 15, 22, 19, 1, -21 }, // 0x32 '2' - { 491, 14, 22, 19, 1, -21 }, // 0x33 '3' - { 530, 16, 22, 19, 1, -21 }, // 0x34 '4' - { 574, 14, 22, 19, 3, -21 }, // 0x35 '5' - { 613, 14, 22, 19, 2, -21 }, // 0x36 '6' - { 652, 15, 22, 19, 2, -21 }, // 0x37 '7' - { 694, 14, 22, 19, 3, -21 }, // 0x38 '8' - { 733, 14, 22, 19, 2, -21 }, // 0x39 '9' - { 772, 5, 17, 19, 8, -16 }, // 0x3A ':' - { 783, 6, 23, 19, 7, -16 }, // 0x3B ';' - { 801, 12, 14, 19, 3, -16 }, // 0x3C '<' - { 822, 13, 9, 19, 3, -14 }, // 0x3D '=' - { 837, 13, 14, 19, 3, -16 }, // 0x3E '>' - { 860, 13, 22, 19, 3, -21 }, // 0x3F '?' - { 896, 17, 22, 19, 1, -21 }, // 0x40 '@' - { 943, 17, 22, 19, 1, -21 }, // 0x41 'A' - { 990, 14, 22, 19, 3, -21 }, // 0x42 'B' - { 1029, 15, 22, 19, 2, -21 }, // 0x43 'C' - { 1071, 15, 22, 19, 2, -21 }, // 0x44 'D' - { 1113, 13, 22, 19, 3, -21 }, // 0x45 'E' - { 1149, 13, 22, 19, 3, -21 }, // 0x46 'F' - { 1185, 15, 22, 19, 2, -21 }, // 0x47 'G' - { 1227, 14, 22, 19, 2, -21 }, // 0x48 'H' - { 1266, 13, 22, 19, 3, -21 }, // 0x49 'I' - { 1302, 15, 22, 19, 1, -21 }, // 0x4A 'J' - { 1344, 15, 22, 19, 3, -21 }, // 0x4B 'K' - { 1386, 14, 22, 19, 3, -21 }, // 0x4C 'L' - { 1425, 15, 22, 19, 2, -21 }, // 0x4D 'M' - { 1467, 14, 22, 19, 2, -21 }, // 0x4E 'N' - { 1506, 15, 22, 19, 2, -21 }, // 0x4F 'O' - { 1548, 14, 22, 19, 3, -21 }, // 0x50 'P' - { 1587, 17, 26, 19, 1, -21 }, // 0x51 'Q' - { 1643, 14, 22, 19, 3, -21 }, // 0x52 'R' - { 1682, 15, 22, 19, 2, -21 }, // 0x53 'S' - { 1724, 17, 22, 19, 1, -21 }, // 0x54 'T' - { 1771, 15, 22, 19, 2, -21 }, // 0x55 'U' - { 1813, 16, 22, 19, 1, -21 }, // 0x56 'V' - { 1857, 17, 22, 19, 1, -21 }, // 0x57 'W' - { 1904, 17, 22, 19, 1, -21 }, // 0x58 'X' - { 1951, 16, 22, 19, 1, -21 }, // 0x59 'Y' - { 1995, 14, 22, 19, 2, -21 }, // 0x5A 'Z' - { 2034, 6, 30, 19, 6, -24 }, // 0x5B '[' - { 2057, 12, 24, 19, 3, -21 }, // 0x5C '\' - { 2093, 6, 30, 19, 6, -24 }, // 0x5D ']' - { 2116, 12, 12, 19, 3, -21 }, // 0x5E '^' - { 2134, 14, 2, 19, 2, 1 }, // 0x5F '_' - { 2138, 6, 4, 19, 6, -22 }, // 0x60 '`' - { 2141, 14, 17, 19, 2, -16 }, // 0x61 'a' - { 2171, 14, 23, 19, 3, -22 }, // 0x62 'b' - { 2212, 14, 17, 19, 2, -16 }, // 0x63 'c' - { 2242, 14, 23, 19, 2, -22 }, // 0x64 'd' - { 2283, 15, 17, 19, 2, -16 }, // 0x65 'e' - { 2315, 15, 24, 19, 2, -23 }, // 0x66 'f' - { 2360, 14, 23, 19, 2, -16 }, // 0x67 'g' - { 2401, 13, 23, 19, 3, -22 }, // 0x68 'h' - { 2439, 14, 22, 19, 3, -21 }, // 0x69 'i' - { 2478, 10, 28, 19, 3, -21 }, // 0x6A 'j' - { 2513, 14, 23, 19, 3, -22 }, // 0x6B 'k' - { 2554, 14, 23, 19, 3, -22 }, // 0x6C 'l' - { 2595, 16, 17, 19, 1, -16 }, // 0x6D 'm' - { 2629, 13, 17, 19, 3, -16 }, // 0x6E 'n' - { 2657, 15, 17, 19, 2, -16 }, // 0x6F 'o' - { 2689, 13, 23, 19, 3, -16 }, // 0x70 'p' - { 2727, 14, 23, 19, 2, -16 }, // 0x71 'q' - { 2768, 11, 17, 19, 5, -16 }, // 0x72 'r' - { 2792, 13, 17, 19, 3, -16 }, // 0x73 's' - { 2820, 14, 21, 19, 2, -20 }, // 0x74 't' - { 2857, 13, 17, 19, 3, -16 }, // 0x75 'u' - { 2885, 16, 17, 19, 1, -16 }, // 0x76 'v' - { 2919, 17, 17, 19, 1, -16 }, // 0x77 'w' - { 2956, 15, 17, 19, 2, -16 }, // 0x78 'x' - { 2988, 17, 23, 19, 1, -16 }, // 0x79 'y' - { 3037, 14, 17, 19, 2, -16 }, // 0x7A 'z' - { 3067, 10, 30, 19, 5, -23 }, // 0x7B '{' - { 3105, 2, 28, 19, 8, -21 }, // 0x7C '|' - { 3112, 10, 30, 19, 5, -23 }, // 0x7D '}' - { 3150, 17, 6, 19, 1, -11 } }; // 0x7E '~' + { 0, 1, 1, 19, 0, 0 }, // 0x20 ' ' + { 1, 4, 22, 19, 7, -21 }, // 0x21 '!' + { 12, 8, 7, 19, 5, -22 }, // 0x22 '"' + { 19, 17, 22, 19, 1, -21 }, // 0x23 '#' + { 66, 15, 29, 19, 2, -25 }, // 0x24 '$' + { 121, 17, 22, 19, 1, -21 }, // 0x25 '%' + { 168, 16, 22, 19, 2, -21 }, // 0x26 '&' + { 212, 3, 7, 19, 7, -22 }, // 0x27 ''' + { 215, 8, 32, 19, 5, -24 }, // 0x28 '(' + { 247, 8, 32, 19, 5, -24 }, // 0x29 ')' + { 279, 15, 15, 19, 2, -18 }, // 0x2A '*' + { 308, 15, 16, 19, 2, -17 }, // 0x2B '+' + { 338, 5, 9, 19, 5, -2 }, // 0x2C ',' + { 344, 12, 2, 19, 3, -10 }, // 0x2D '-' + { 347, 4, 4, 19, 8, -3 }, // 0x2E '.' + { 349, 12, 24, 19, 4, -21 }, // 0x2F '/' + { 385, 14, 22, 19, 2, -21 }, // 0x30 '0' + { 424, 9, 22, 19, 3, -21 }, // 0x31 '1' + { 449, 15, 22, 19, 1, -21 }, // 0x32 '2' + { 491, 14, 22, 19, 1, -21 }, // 0x33 '3' + { 530, 16, 22, 19, 1, -21 }, // 0x34 '4' + { 574, 14, 22, 19, 3, -21 }, // 0x35 '5' + { 613, 14, 22, 19, 2, -21 }, // 0x36 '6' + { 652, 15, 22, 19, 2, -21 }, // 0x37 '7' + { 694, 14, 22, 19, 3, -21 }, // 0x38 '8' + { 733, 14, 22, 19, 2, -21 }, // 0x39 '9' + { 772, 5, 17, 19, 8, -16 }, // 0x3A ':' + { 783, 6, 23, 19, 7, -16 }, // 0x3B ';' + { 801, 12, 14, 19, 3, -16 }, // 0x3C '<' + { 822, 13, 9, 19, 3, -14 }, // 0x3D '=' + { 837, 13, 14, 19, 3, -16 }, // 0x3E '>' + { 860, 13, 22, 19, 3, -21 }, // 0x3F '?' + { 896, 17, 22, 19, 1, -21 }, // 0x40 '@' + { 943, 17, 22, 19, 1, -21 }, // 0x41 'A' + { 990, 14, 22, 19, 3, -21 }, // 0x42 'B' + { 1029, 15, 22, 19, 2, -21 }, // 0x43 'C' + { 1071, 15, 22, 19, 2, -21 }, // 0x44 'D' + { 1113, 13, 22, 19, 3, -21 }, // 0x45 'E' + { 1149, 13, 22, 19, 3, -21 }, // 0x46 'F' + { 1185, 15, 22, 19, 2, -21 }, // 0x47 'G' + { 1227, 14, 22, 19, 2, -21 }, // 0x48 'H' + { 1266, 13, 22, 19, 3, -21 }, // 0x49 'I' + { 1302, 15, 22, 19, 1, -21 }, // 0x4A 'J' + { 1344, 15, 22, 19, 3, -21 }, // 0x4B 'K' + { 1386, 14, 22, 19, 3, -21 }, // 0x4C 'L' + { 1425, 15, 22, 19, 2, -21 }, // 0x4D 'M' + { 1467, 14, 22, 19, 2, -21 }, // 0x4E 'N' + { 1506, 15, 22, 19, 2, -21 }, // 0x4F 'O' + { 1548, 14, 22, 19, 3, -21 }, // 0x50 'P' + { 1587, 17, 26, 19, 1, -21 }, // 0x51 'Q' + { 1643, 14, 22, 19, 3, -21 }, // 0x52 'R' + { 1682, 15, 22, 19, 2, -21 }, // 0x53 'S' + { 1724, 17, 22, 19, 1, -21 }, // 0x54 'T' + { 1771, 15, 22, 19, 2, -21 }, // 0x55 'U' + { 1813, 16, 22, 19, 1, -21 }, // 0x56 'V' + { 1857, 17, 22, 19, 1, -21 }, // 0x57 'W' + { 1904, 17, 22, 19, 1, -21 }, // 0x58 'X' + { 1951, 16, 22, 19, 1, -21 }, // 0x59 'Y' + { 1995, 14, 22, 19, 2, -21 }, // 0x5A 'Z' + { 2034, 6, 30, 19, 6, -24 }, // 0x5B '[' + { 2057, 12, 24, 19, 3, -21 }, // 0x5C '\' + { 2093, 6, 30, 19, 6, -24 }, // 0x5D ']' + { 2116, 12, 12, 19, 3, -21 }, // 0x5E '^' + { 2134, 14, 2, 19, 2, 1 }, // 0x5F '_' + { 2138, 6, 4, 19, 6, -22 }, // 0x60 '`' + { 2141, 14, 17, 19, 2, -16 }, // 0x61 'a' + { 2171, 14, 23, 19, 3, -22 }, // 0x62 'b' + { 2212, 14, 17, 19, 2, -16 }, // 0x63 'c' + { 2242, 14, 23, 19, 2, -22 }, // 0x64 'd' + { 2283, 15, 17, 19, 2, -16 }, // 0x65 'e' + { 2315, 15, 24, 19, 2, -23 }, // 0x66 'f' + { 2360, 14, 23, 19, 2, -16 }, // 0x67 'g' + { 2401, 13, 23, 19, 3, -22 }, // 0x68 'h' + { 2439, 14, 22, 19, 3, -21 }, // 0x69 'i' + { 2478, 10, 28, 19, 3, -21 }, // 0x6A 'j' + { 2513, 14, 23, 19, 3, -22 }, // 0x6B 'k' + { 2554, 14, 23, 19, 3, -22 }, // 0x6C 'l' + { 2595, 16, 17, 19, 1, -16 }, // 0x6D 'm' + { 2629, 13, 17, 19, 3, -16 }, // 0x6E 'n' + { 2657, 15, 17, 19, 2, -16 }, // 0x6F 'o' + { 2689, 13, 23, 19, 3, -16 }, // 0x70 'p' + { 2727, 14, 23, 19, 2, -16 }, // 0x71 'q' + { 2768, 11, 17, 19, 5, -16 }, // 0x72 'r' + { 2792, 13, 17, 19, 3, -16 }, // 0x73 's' + { 2820, 14, 21, 19, 2, -20 }, // 0x74 't' + { 2857, 13, 17, 19, 3, -16 }, // 0x75 'u' + { 2885, 16, 17, 19, 1, -16 }, // 0x76 'v' + { 2919, 17, 17, 19, 1, -16 }, // 0x77 'w' + { 2956, 15, 17, 19, 2, -16 }, // 0x78 'x' + { 2988, 17, 23, 19, 1, -16 }, // 0x79 'y' + { 3037, 14, 17, 19, 2, -16 }, // 0x7A 'z' + { 3067, 10, 30, 19, 5, -23 }, // 0x7B '{' + { 3105, 2, 28, 19, 8, -21 }, // 0x7C '|' + { 3112, 10, 30, 19, 5, -23 }, // 0x7D '}' + { 3150, 17, 6, 19, 1, -11 } }; // 0x7E '~' const GFXfont RobotoMono_Regular16pt7b PROGMEM = { (uint8_t *)RobotoMono_Regular16pt7bBitmaps, (GFXglyph *)RobotoMono_Regular16pt7bGlyphs, - 0x20, 0x7E, 41 }; + 0x20, 0x7E, 41 }; // Approx. 3835 bytes +#endif // ifndef FONTS_ROBOTOMONO_REGULAR16PT7B_H diff --git a/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h b/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h index 30d1c45b6..289e09500 100644 --- a/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h +++ b/src/src/Static/Fonts/RobotoMono_Regular8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTOMONO_REGULAR8PT7B_H +#define FONTS_ROBOTOMONO_REGULAR8PT7B_H const uint8_t RobotoMono_Regular8pt7bBitmaps[] PROGMEM = { 0x00, 0xAA, 0xAA, 0x03, 0x99, 0x99, 0x09, 0x04, 0x86, 0x4F, 0xF1, 0x20, 0x90, 0x49, 0xFF, 0x26, 0x12, 0x09, 0x04, 0x80, 0x18, 0x18, 0x3C, 0x66, @@ -76,105 +78,106 @@ const uint8_t RobotoMono_Regular8pt7bBitmaps[] PROGMEM = { 0x31, 0x18, 0x70, 0xA6, 0x61, 0xC0 }; const GFXglyph RobotoMono_Regular8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 10, 0, 0 }, // 0x20 ' ' - { 1, 2, 12, 10, 4, -11 }, // 0x21 '!' - { 4, 4, 4, 10, 3, -11 }, // 0x22 '"' - { 6, 9, 12, 10, 0, -11 }, // 0x23 '#' - { 20, 8, 15, 10, 1, -12 }, // 0x24 '$' - { 35, 9, 12, 10, 0, -11 }, // 0x25 '%' - { 49, 8, 12, 10, 1, -11 }, // 0x26 '&' - { 61, 1, 4, 10, 4, -11 }, // 0x27 ''' - { 62, 4, 17, 10, 3, -12 }, // 0x28 '(' - { 71, 5, 17, 10, 2, -12 }, // 0x29 ')' - { 82, 8, 8, 10, 1, -9 }, // 0x2A '*' - { 90, 8, 9, 10, 1, -9 }, // 0x2B '+' - { 99, 2, 5, 10, 3, -1 }, // 0x2C ',' - { 101, 6, 1, 10, 2, -5 }, // 0x2D '-' - { 102, 2, 2, 10, 4, -1 }, // 0x2E '.' - { 103, 6, 13, 10, 2, -11 }, // 0x2F '/' - { 113, 8, 12, 10, 1, -11 }, // 0x30 '0' - { 125, 4, 12, 10, 2, -11 }, // 0x31 '1' - { 131, 7, 12, 10, 1, -11 }, // 0x32 '2' - { 142, 7, 12, 10, 1, -11 }, // 0x33 '3' - { 153, 8, 12, 10, 1, -11 }, // 0x34 '4' - { 165, 8, 12, 10, 1, -11 }, // 0x35 '5' - { 177, 7, 12, 10, 1, -11 }, // 0x36 '6' - { 188, 8, 12, 10, 1, -11 }, // 0x37 '7' - { 200, 8, 12, 10, 1, -11 }, // 0x38 '8' - { 212, 7, 12, 10, 1, -11 }, // 0x39 '9' - { 223, 3, 9, 10, 4, -8 }, // 0x3A ':' - { 227, 2, 12, 10, 4, -8 }, // 0x3B ';' - { 230, 7, 7, 10, 1, -8 }, // 0x3C '<' - { 237, 7, 4, 10, 1, -6 }, // 0x3D '=' - { 241, 7, 7, 10, 1, -8 }, // 0x3E '>' - { 248, 7, 12, 10, 1, -11 }, // 0x3F '?' - { 259, 9, 12, 10, 0, -11 }, // 0x40 '@' - { 273, 8, 12, 10, 1, -11 }, // 0x41 'A' - { 285, 8, 12, 10, 1, -11 }, // 0x42 'B' - { 297, 8, 12, 10, 1, -11 }, // 0x43 'C' - { 309, 8, 12, 10, 1, -11 }, // 0x44 'D' - { 321, 7, 12, 10, 1, -11 }, // 0x45 'E' - { 332, 7, 12, 10, 1, -11 }, // 0x46 'F' - { 343, 8, 12, 10, 1, -11 }, // 0x47 'G' - { 355, 8, 12, 10, 1, -11 }, // 0x48 'H' - { 367, 7, 12, 10, 1, -11 }, // 0x49 'I' - { 378, 7, 12, 10, 1, -11 }, // 0x4A 'J' - { 389, 8, 12, 10, 1, -11 }, // 0x4B 'K' - { 401, 7, 12, 10, 2, -11 }, // 0x4C 'L' - { 412, 8, 12, 10, 1, -11 }, // 0x4D 'M' - { 424, 7, 12, 10, 1, -11 }, // 0x4E 'N' - { 435, 8, 12, 10, 1, -11 }, // 0x4F 'O' - { 447, 8, 12, 10, 1, -11 }, // 0x50 'P' - { 459, 8, 14, 10, 1, -11 }, // 0x51 'Q' - { 473, 8, 12, 10, 1, -11 }, // 0x52 'R' - { 485, 8, 12, 10, 1, -11 }, // 0x53 'S' - { 497, 8, 12, 10, 1, -11 }, // 0x54 'T' - { 509, 8, 12, 10, 1, -11 }, // 0x55 'U' - { 521, 8, 12, 10, 1, -11 }, // 0x56 'V' - { 533, 8, 12, 10, 1, -11 }, // 0x57 'W' - { 545, 8, 12, 10, 1, -11 }, // 0x58 'X' - { 557, 9, 12, 10, 0, -11 }, // 0x59 'Y' - { 571, 7, 12, 10, 1, -11 }, // 0x5A 'Z' - { 582, 3, 16, 10, 3, -13 }, // 0x5B '[' - { 588, 6, 13, 10, 2, -11 }, // 0x5C '\' - { 598, 3, 16, 10, 3, -13 }, // 0x5D ']' - { 604, 6, 6, 10, 2, -11 }, // 0x5E '^' - { 609, 7, 1, 10, 1, 1 }, // 0x5F '_' - { 610, 3, 2, 10, 3, -11 }, // 0x60 '`' - { 611, 7, 9, 10, 1, -8 }, // 0x61 'a' - { 619, 8, 12, 10, 1, -11 }, // 0x62 'b' - { 631, 7, 9, 10, 1, -8 }, // 0x63 'c' - { 639, 7, 12, 10, 1, -11 }, // 0x64 'd' - { 650, 8, 9, 10, 1, -8 }, // 0x65 'e' - { 659, 8, 13, 10, 1, -12 }, // 0x66 'f' - { 672, 7, 12, 10, 1, -8 }, // 0x67 'g' - { 683, 7, 12, 10, 1, -11 }, // 0x68 'h' - { 694, 7, 12, 10, 2, -11 }, // 0x69 'i' - { 705, 5, 15, 10, 2, -11 }, // 0x6A 'j' - { 715, 8, 12, 10, 1, -11 }, // 0x6B 'k' - { 727, 7, 12, 10, 2, -11 }, // 0x6C 'l' - { 738, 8, 9, 10, 1, -8 }, // 0x6D 'm' - { 747, 7, 9, 10, 1, -8 }, // 0x6E 'n' - { 755, 8, 9, 10, 1, -8 }, // 0x6F 'o' - { 764, 8, 12, 10, 1, -8 }, // 0x70 'p' - { 776, 7, 12, 10, 1, -8 }, // 0x71 'q' - { 787, 5, 9, 10, 3, -8 }, // 0x72 'r' - { 793, 7, 9, 10, 1, -8 }, // 0x73 's' - { 801, 7, 11, 10, 1, -10 }, // 0x74 't' - { 811, 7, 9, 10, 1, -8 }, // 0x75 'u' - { 819, 8, 9, 10, 1, -8 }, // 0x76 'v' - { 828, 9, 9, 10, 0, -8 }, // 0x77 'w' - { 839, 8, 9, 10, 1, -8 }, // 0x78 'x' - { 848, 8, 12, 10, 1, -8 }, // 0x79 'y' - { 860, 7, 9, 10, 1, -8 }, // 0x7A 'z' - { 868, 5, 16, 10, 3, -12 }, // 0x7B '{' - { 878, 1, 15, 10, 4, -11 }, // 0x7C '|' - { 880, 5, 16, 10, 3, -12 }, // 0x7D '}' - { 890, 9, 3, 10, 0, -6 } }; // 0x7E '~' + { 0, 1, 1, 10, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 10, 4, -11 }, // 0x21 '!' + { 4, 4, 4, 10, 3, -11 }, // 0x22 '"' + { 6, 9, 12, 10, 0, -11 }, // 0x23 '#' + { 20, 8, 15, 10, 1, -12 }, // 0x24 '$' + { 35, 9, 12, 10, 0, -11 }, // 0x25 '%' + { 49, 8, 12, 10, 1, -11 }, // 0x26 '&' + { 61, 1, 4, 10, 4, -11 }, // 0x27 ''' + { 62, 4, 17, 10, 3, -12 }, // 0x28 '(' + { 71, 5, 17, 10, 2, -12 }, // 0x29 ')' + { 82, 8, 8, 10, 1, -9 }, // 0x2A '*' + { 90, 8, 9, 10, 1, -9 }, // 0x2B '+' + { 99, 2, 5, 10, 3, -1 }, // 0x2C ',' + { 101, 6, 1, 10, 2, -5 }, // 0x2D '-' + { 102, 2, 2, 10, 4, -1 }, // 0x2E '.' + { 103, 6, 13, 10, 2, -11 }, // 0x2F '/' + { 113, 8, 12, 10, 1, -11 }, // 0x30 '0' + { 125, 4, 12, 10, 2, -11 }, // 0x31 '1' + { 131, 7, 12, 10, 1, -11 }, // 0x32 '2' + { 142, 7, 12, 10, 1, -11 }, // 0x33 '3' + { 153, 8, 12, 10, 1, -11 }, // 0x34 '4' + { 165, 8, 12, 10, 1, -11 }, // 0x35 '5' + { 177, 7, 12, 10, 1, -11 }, // 0x36 '6' + { 188, 8, 12, 10, 1, -11 }, // 0x37 '7' + { 200, 8, 12, 10, 1, -11 }, // 0x38 '8' + { 212, 7, 12, 10, 1, -11 }, // 0x39 '9' + { 223, 3, 9, 10, 4, -8 }, // 0x3A ':' + { 227, 2, 12, 10, 4, -8 }, // 0x3B ';' + { 230, 7, 7, 10, 1, -8 }, // 0x3C '<' + { 237, 7, 4, 10, 1, -6 }, // 0x3D '=' + { 241, 7, 7, 10, 1, -8 }, // 0x3E '>' + { 248, 7, 12, 10, 1, -11 }, // 0x3F '?' + { 259, 9, 12, 10, 0, -11 }, // 0x40 '@' + { 273, 8, 12, 10, 1, -11 }, // 0x41 'A' + { 285, 8, 12, 10, 1, -11 }, // 0x42 'B' + { 297, 8, 12, 10, 1, -11 }, // 0x43 'C' + { 309, 8, 12, 10, 1, -11 }, // 0x44 'D' + { 321, 7, 12, 10, 1, -11 }, // 0x45 'E' + { 332, 7, 12, 10, 1, -11 }, // 0x46 'F' + { 343, 8, 12, 10, 1, -11 }, // 0x47 'G' + { 355, 8, 12, 10, 1, -11 }, // 0x48 'H' + { 367, 7, 12, 10, 1, -11 }, // 0x49 'I' + { 378, 7, 12, 10, 1, -11 }, // 0x4A 'J' + { 389, 8, 12, 10, 1, -11 }, // 0x4B 'K' + { 401, 7, 12, 10, 2, -11 }, // 0x4C 'L' + { 412, 8, 12, 10, 1, -11 }, // 0x4D 'M' + { 424, 7, 12, 10, 1, -11 }, // 0x4E 'N' + { 435, 8, 12, 10, 1, -11 }, // 0x4F 'O' + { 447, 8, 12, 10, 1, -11 }, // 0x50 'P' + { 459, 8, 14, 10, 1, -11 }, // 0x51 'Q' + { 473, 8, 12, 10, 1, -11 }, // 0x52 'R' + { 485, 8, 12, 10, 1, -11 }, // 0x53 'S' + { 497, 8, 12, 10, 1, -11 }, // 0x54 'T' + { 509, 8, 12, 10, 1, -11 }, // 0x55 'U' + { 521, 8, 12, 10, 1, -11 }, // 0x56 'V' + { 533, 8, 12, 10, 1, -11 }, // 0x57 'W' + { 545, 8, 12, 10, 1, -11 }, // 0x58 'X' + { 557, 9, 12, 10, 0, -11 }, // 0x59 'Y' + { 571, 7, 12, 10, 1, -11 }, // 0x5A 'Z' + { 582, 3, 16, 10, 3, -13 }, // 0x5B '[' + { 588, 6, 13, 10, 2, -11 }, // 0x5C '\' + { 598, 3, 16, 10, 3, -13 }, // 0x5D ']' + { 604, 6, 6, 10, 2, -11 }, // 0x5E '^' + { 609, 7, 1, 10, 1, 1 }, // 0x5F '_' + { 610, 3, 2, 10, 3, -11 }, // 0x60 '`' + { 611, 7, 9, 10, 1, -8 }, // 0x61 'a' + { 619, 8, 12, 10, 1, -11 }, // 0x62 'b' + { 631, 7, 9, 10, 1, -8 }, // 0x63 'c' + { 639, 7, 12, 10, 1, -11 }, // 0x64 'd' + { 650, 8, 9, 10, 1, -8 }, // 0x65 'e' + { 659, 8, 13, 10, 1, -12 }, // 0x66 'f' + { 672, 7, 12, 10, 1, -8 }, // 0x67 'g' + { 683, 7, 12, 10, 1, -11 }, // 0x68 'h' + { 694, 7, 12, 10, 2, -11 }, // 0x69 'i' + { 705, 5, 15, 10, 2, -11 }, // 0x6A 'j' + { 715, 8, 12, 10, 1, -11 }, // 0x6B 'k' + { 727, 7, 12, 10, 2, -11 }, // 0x6C 'l' + { 738, 8, 9, 10, 1, -8 }, // 0x6D 'm' + { 747, 7, 9, 10, 1, -8 }, // 0x6E 'n' + { 755, 8, 9, 10, 1, -8 }, // 0x6F 'o' + { 764, 8, 12, 10, 1, -8 }, // 0x70 'p' + { 776, 7, 12, 10, 1, -8 }, // 0x71 'q' + { 787, 5, 9, 10, 3, -8 }, // 0x72 'r' + { 793, 7, 9, 10, 1, -8 }, // 0x73 's' + { 801, 7, 11, 10, 1, -10 }, // 0x74 't' + { 811, 7, 9, 10, 1, -8 }, // 0x75 'u' + { 819, 8, 9, 10, 1, -8 }, // 0x76 'v' + { 828, 9, 9, 10, 0, -8 }, // 0x77 'w' + { 839, 8, 9, 10, 1, -8 }, // 0x78 'x' + { 848, 8, 12, 10, 1, -8 }, // 0x79 'y' + { 860, 7, 9, 10, 1, -8 }, // 0x7A 'z' + { 868, 5, 16, 10, 3, -12 }, // 0x7B '{' + { 878, 1, 15, 10, 4, -11 }, // 0x7C '|' + { 880, 5, 16, 10, 3, -12 }, // 0x7D '}' + { 890, 9, 3, 10, 0, -6 } }; // 0x7E '~' const GFXfont RobotoMono_Regular8pt7b PROGMEM = { (uint8_t *)RobotoMono_Regular8pt7bBitmaps, (GFXglyph *)RobotoMono_Regular8pt7bGlyphs, - 0x20, 0x7E, 21 }; + 0x20, 0x7E, 21 }; // Approx. 1566 bytes +#endif // ifndef FONTS_ROBOTOMONO_REGULAR8PT7B_H diff --git a/src/src/Static/Fonts/Roboto_Regular12pt7b.h b/src/src/Static/Fonts/Roboto_Regular12pt7b.h index 2bff96b05..edba45710 100644 --- a/src/src/Static/Fonts/Roboto_Regular12pt7b.h +++ b/src/src/Static/Fonts/Roboto_Regular12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTO_REGULAR12PT7B_H +#define FONTS_ROBOTO_REGULAR12PT7B_H const uint8_t Roboto_Regular12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0xC0, 0xCF, 0x3C, 0xF3, 0xCA, 0x20, 0x06, 0x30, 0x23, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x3F, 0xFD, 0xFF, 0xE1, 0x18, @@ -161,105 +163,106 @@ const uint8_t Roboto_Regular12pt7bBitmaps[] PROGMEM = { 0x0E, 0x30, 0x00, 0x3C, 0x01, 0xFC, 0x36, 0x39, 0xD0, 0x7E, 0x80, 0xF0 }; const GFXglyph Roboto_Regular12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' - { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' - { 6, 6, 6, 8, 1, -17 }, // 0x22 '"' - { 11, 13, 17, 15, 1, -16 }, // 0x23 '#' - { 39, 11, 22, 14, 1, -19 }, // 0x24 '$' - { 70, 16, 17, 18, 1, -16 }, // 0x25 '%' - { 104, 13, 17, 15, 1, -16 }, // 0x26 '&' - { 132, 2, 6, 4, 1, -17 }, // 0x27 ''' - { 134, 6, 24, 8, 2, -18 }, // 0x28 '(' - { 152, 6, 24, 8, 0, -18 }, // 0x29 ')' - { 170, 10, 10, 10, 0, -16 }, // 0x2A '*' - { 183, 12, 12, 14, 1, -13 }, // 0x2B '+' - { 201, 3, 6, 5, 1, -2 }, // 0x2C ',' - { 204, 6, 2, 7, 0, -7 }, // 0x2D '-' - { 206, 2, 2, 6, 2, -1 }, // 0x2E '.' - { 207, 9, 18, 10, 0, -16 }, // 0x2F '/' - { 228, 11, 17, 14, 1, -16 }, // 0x30 '0' - { 252, 6, 17, 14, 2, -16 }, // 0x31 '1' - { 265, 11, 17, 14, 1, -16 }, // 0x32 '2' - { 289, 11, 17, 14, 1, -16 }, // 0x33 '3' - { 313, 12, 17, 14, 1, -16 }, // 0x34 '4' - { 339, 10, 17, 14, 2, -16 }, // 0x35 '5' - { 361, 11, 17, 14, 2, -16 }, // 0x36 '6' - { 385, 11, 17, 14, 1, -16 }, // 0x37 '7' - { 409, 11, 17, 14, 1, -16 }, // 0x38 '8' - { 433, 11, 17, 14, 1, -16 }, // 0x39 '9' - { 457, 2, 13, 6, 2, -12 }, // 0x3A ':' - { 461, 3, 16, 6, 1, -12 }, // 0x3B ';' - { 467, 9, 10, 12, 1, -10 }, // 0x3C '<' - { 479, 10, 7, 14, 2, -11 }, // 0x3D '=' - { 488, 10, 10, 13, 2, -10 }, // 0x3E '>' - { 501, 9, 17, 11, 1, -16 }, // 0x3F '?' - { 521, 20, 22, 21, 1, -16 }, // 0x40 '@' - { 576, 15, 17, 16, 0, -16 }, // 0x41 'A' - { 608, 12, 17, 15, 2, -16 }, // 0x42 'B' - { 634, 13, 17, 15, 1, -16 }, // 0x43 'C' - { 662, 13, 17, 16, 2, -16 }, // 0x44 'D' - { 690, 11, 17, 14, 2, -16 }, // 0x45 'E' - { 714, 11, 17, 14, 2, -16 }, // 0x46 'F' - { 738, 13, 17, 16, 1, -16 }, // 0x47 'G' - { 766, 13, 17, 17, 2, -16 }, // 0x48 'H' - { 794, 3, 17, 7, 2, -16 }, // 0x49 'I' - { 801, 10, 17, 13, 1, -16 }, // 0x4A 'J' - { 823, 13, 17, 15, 2, -16 }, // 0x4B 'K' - { 851, 11, 17, 13, 2, -16 }, // 0x4C 'L' - { 875, 17, 17, 21, 2, -16 }, // 0x4D 'M' - { 912, 13, 17, 17, 2, -16 }, // 0x4E 'N' - { 940, 14, 17, 16, 1, -16 }, // 0x4F 'O' - { 970, 12, 17, 15, 2, -16 }, // 0x50 'P' - { 996, 15, 19, 16, 1, -16 }, // 0x51 'Q' - { 1032, 13, 17, 16, 2, -16 }, // 0x52 'R' - { 1060, 13, 17, 15, 1, -16 }, // 0x53 'S' - { 1088, 14, 17, 14, 0, -16 }, // 0x54 'T' - { 1118, 13, 17, 16, 2, -16 }, // 0x55 'U' - { 1146, 15, 17, 15, 0, -16 }, // 0x56 'V' - { 1178, 19, 17, 21, 1, -16 }, // 0x57 'W' - { 1219, 14, 17, 15, 1, -16 }, // 0x58 'X' - { 1249, 14, 17, 15, 0, -16 }, // 0x59 'Y' - { 1279, 12, 17, 14, 1, -16 }, // 0x5A 'Z' - { 1305, 4, 24, 6, 2, -19 }, // 0x5B '[' - { 1317, 10, 18, 10, 0, -16 }, // 0x5C '\' - { 1340, 5, 24, 6, 0, -19 }, // 0x5D ']' - { 1355, 8, 9, 10, 1, -16 }, // 0x5E '^' - { 1364, 11, 2, 11, 0, 1 }, // 0x5F '_' - { 1367, 5, 3, 8, 1, -17 }, // 0x60 '`' - { 1369, 11, 13, 13, 1, -12 }, // 0x61 'a' - { 1387, 11, 18, 14, 2, -17 }, // 0x62 'b' - { 1412, 11, 13, 13, 1, -12 }, // 0x63 'c' - { 1430, 11, 18, 14, 1, -17 }, // 0x64 'd' - { 1455, 11, 13, 13, 1, -12 }, // 0x65 'e' - { 1473, 7, 19, 8, 1, -18 }, // 0x66 'f' - { 1490, 11, 18, 14, 1, -12 }, // 0x67 'g' - { 1515, 10, 18, 14, 2, -17 }, // 0x68 'h' - { 1538, 2, 18, 6, 2, -17 }, // 0x69 'i' - { 1543, 5, 23, 6, -1, -17 }, // 0x6A 'j' - { 1558, 10, 18, 12, 2, -17 }, // 0x6B 'k' - { 1581, 2, 18, 6, 2, -17 }, // 0x6C 'l' - { 1586, 17, 13, 21, 2, -12 }, // 0x6D 'm' - { 1614, 10, 13, 14, 2, -12 }, // 0x6E 'n' - { 1631, 12, 13, 14, 1, -12 }, // 0x6F 'o' - { 1651, 10, 18, 14, 2, -12 }, // 0x70 'p' - { 1674, 11, 18, 14, 1, -12 }, // 0x71 'q' - { 1699, 6, 13, 8, 2, -12 }, // 0x72 'r' - { 1709, 10, 13, 13, 1, -12 }, // 0x73 's' - { 1726, 7, 16, 8, 0, -15 }, // 0x74 't' - { 1740, 10, 13, 14, 2, -12 }, // 0x75 'u' - { 1757, 11, 13, 12, 1, -12 }, // 0x76 'v' - { 1775, 17, 13, 18, 1, -12 }, // 0x77 'w' - { 1803, 10, 13, 12, 1, -12 }, // 0x78 'x' - { 1820, 12, 18, 12, 0, -12 }, // 0x79 'y' - { 1847, 10, 13, 12, 1, -12 }, // 0x7A 'z' - { 1864, 7, 23, 8, 1, -18 }, // 0x7B '{' - { 1885, 2, 20, 6, 2, -16 }, // 0x7C '|' - { 1890, 7, 23, 8, 0, -18 }, // 0x7D '}' - { 1911, 14, 5, 16, 1, -8 } }; // 0x7E '~' + { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' + { 1, 2, 17, 6, 2, -16 }, // 0x21 '!' + { 6, 6, 6, 8, 1, -17 }, // 0x22 '"' + { 11, 13, 17, 15, 1, -16 }, // 0x23 '#' + { 39, 11, 22, 14, 1, -19 }, // 0x24 '$' + { 70, 16, 17, 18, 1, -16 }, // 0x25 '%' + { 104, 13, 17, 15, 1, -16 }, // 0x26 '&' + { 132, 2, 6, 4, 1, -17 }, // 0x27 ''' + { 134, 6, 24, 8, 2, -18 }, // 0x28 '(' + { 152, 6, 24, 8, 0, -18 }, // 0x29 ')' + { 170, 10, 10, 10, 0, -16 }, // 0x2A '*' + { 183, 12, 12, 14, 1, -13 }, // 0x2B '+' + { 201, 3, 6, 5, 1, -2 }, // 0x2C ',' + { 204, 6, 2, 7, 0, -7 }, // 0x2D '-' + { 206, 2, 2, 6, 2, -1 }, // 0x2E '.' + { 207, 9, 18, 10, 0, -16 }, // 0x2F '/' + { 228, 11, 17, 14, 1, -16 }, // 0x30 '0' + { 252, 6, 17, 14, 2, -16 }, // 0x31 '1' + { 265, 11, 17, 14, 1, -16 }, // 0x32 '2' + { 289, 11, 17, 14, 1, -16 }, // 0x33 '3' + { 313, 12, 17, 14, 1, -16 }, // 0x34 '4' + { 339, 10, 17, 14, 2, -16 }, // 0x35 '5' + { 361, 11, 17, 14, 2, -16 }, // 0x36 '6' + { 385, 11, 17, 14, 1, -16 }, // 0x37 '7' + { 409, 11, 17, 14, 1, -16 }, // 0x38 '8' + { 433, 11, 17, 14, 1, -16 }, // 0x39 '9' + { 457, 2, 13, 6, 2, -12 }, // 0x3A ':' + { 461, 3, 16, 6, 1, -12 }, // 0x3B ';' + { 467, 9, 10, 12, 1, -10 }, // 0x3C '<' + { 479, 10, 7, 14, 2, -11 }, // 0x3D '=' + { 488, 10, 10, 13, 2, -10 }, // 0x3E '>' + { 501, 9, 17, 11, 1, -16 }, // 0x3F '?' + { 521, 20, 22, 21, 1, -16 }, // 0x40 '@' + { 576, 15, 17, 16, 0, -16 }, // 0x41 'A' + { 608, 12, 17, 15, 2, -16 }, // 0x42 'B' + { 634, 13, 17, 15, 1, -16 }, // 0x43 'C' + { 662, 13, 17, 16, 2, -16 }, // 0x44 'D' + { 690, 11, 17, 14, 2, -16 }, // 0x45 'E' + { 714, 11, 17, 14, 2, -16 }, // 0x46 'F' + { 738, 13, 17, 16, 1, -16 }, // 0x47 'G' + { 766, 13, 17, 17, 2, -16 }, // 0x48 'H' + { 794, 3, 17, 7, 2, -16 }, // 0x49 'I' + { 801, 10, 17, 13, 1, -16 }, // 0x4A 'J' + { 823, 13, 17, 15, 2, -16 }, // 0x4B 'K' + { 851, 11, 17, 13, 2, -16 }, // 0x4C 'L' + { 875, 17, 17, 21, 2, -16 }, // 0x4D 'M' + { 912, 13, 17, 17, 2, -16 }, // 0x4E 'N' + { 940, 14, 17, 16, 1, -16 }, // 0x4F 'O' + { 970, 12, 17, 15, 2, -16 }, // 0x50 'P' + { 996, 15, 19, 16, 1, -16 }, // 0x51 'Q' + { 1032, 13, 17, 16, 2, -16 }, // 0x52 'R' + { 1060, 13, 17, 15, 1, -16 }, // 0x53 'S' + { 1088, 14, 17, 14, 0, -16 }, // 0x54 'T' + { 1118, 13, 17, 16, 2, -16 }, // 0x55 'U' + { 1146, 15, 17, 15, 0, -16 }, // 0x56 'V' + { 1178, 19, 17, 21, 1, -16 }, // 0x57 'W' + { 1219, 14, 17, 15, 1, -16 }, // 0x58 'X' + { 1249, 14, 17, 15, 0, -16 }, // 0x59 'Y' + { 1279, 12, 17, 14, 1, -16 }, // 0x5A 'Z' + { 1305, 4, 24, 6, 2, -19 }, // 0x5B '[' + { 1317, 10, 18, 10, 0, -16 }, // 0x5C '\' + { 1340, 5, 24, 6, 0, -19 }, // 0x5D ']' + { 1355, 8, 9, 10, 1, -16 }, // 0x5E '^' + { 1364, 11, 2, 11, 0, 1 }, // 0x5F '_' + { 1367, 5, 3, 8, 1, -17 }, // 0x60 '`' + { 1369, 11, 13, 13, 1, -12 }, // 0x61 'a' + { 1387, 11, 18, 14, 2, -17 }, // 0x62 'b' + { 1412, 11, 13, 13, 1, -12 }, // 0x63 'c' + { 1430, 11, 18, 14, 1, -17 }, // 0x64 'd' + { 1455, 11, 13, 13, 1, -12 }, // 0x65 'e' + { 1473, 7, 19, 8, 1, -18 }, // 0x66 'f' + { 1490, 11, 18, 14, 1, -12 }, // 0x67 'g' + { 1515, 10, 18, 14, 2, -17 }, // 0x68 'h' + { 1538, 2, 18, 6, 2, -17 }, // 0x69 'i' + { 1543, 5, 23, 6, -1, -17 }, // 0x6A 'j' + { 1558, 10, 18, 12, 2, -17 }, // 0x6B 'k' + { 1581, 2, 18, 6, 2, -17 }, // 0x6C 'l' + { 1586, 17, 13, 21, 2, -12 }, // 0x6D 'm' + { 1614, 10, 13, 14, 2, -12 }, // 0x6E 'n' + { 1631, 12, 13, 14, 1, -12 }, // 0x6F 'o' + { 1651, 10, 18, 14, 2, -12 }, // 0x70 'p' + { 1674, 11, 18, 14, 1, -12 }, // 0x71 'q' + { 1699, 6, 13, 8, 2, -12 }, // 0x72 'r' + { 1709, 10, 13, 13, 1, -12 }, // 0x73 's' + { 1726, 7, 16, 8, 0, -15 }, // 0x74 't' + { 1740, 10, 13, 14, 2, -12 }, // 0x75 'u' + { 1757, 11, 13, 12, 1, -12 }, // 0x76 'v' + { 1775, 17, 13, 18, 1, -12 }, // 0x77 'w' + { 1803, 10, 13, 12, 1, -12 }, // 0x78 'x' + { 1820, 12, 18, 12, 0, -12 }, // 0x79 'y' + { 1847, 10, 13, 12, 1, -12 }, // 0x7A 'z' + { 1864, 7, 23, 8, 1, -18 }, // 0x7B '{' + { 1885, 2, 20, 6, 2, -16 }, // 0x7C '|' + { 1890, 7, 23, 8, 0, -18 }, // 0x7D '}' + { 1911, 14, 5, 16, 1, -8 } }; // 0x7E '~' const GFXfont Roboto_Regular12pt7b PROGMEM = { (uint8_t *)Roboto_Regular12pt7bBitmaps, (GFXglyph *)Roboto_Regular12pt7bGlyphs, - 0x20, 0x7E, 31 }; + 0x20, 0x7E, 31 }; // Approx. 2592 bytes +#endif // ifndef FONTS_ROBOTO_REGULAR12PT7B_H diff --git a/src/src/Static/Fonts/Roboto_Regular16pt7b.h b/src/src/Static/Fonts/Roboto_Regular16pt7b.h index 2f50dfc7d..14fdb35fb 100644 --- a/src/src/Static/Fonts/Roboto_Regular16pt7b.h +++ b/src/src/Static/Fonts/Roboto_Regular16pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTO_REGULAR16PT7B_H +#define FONTS_ROBOTO_REGULAR16PT7B_H const uint8_t Roboto_Regular16pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xC6, 0xC6, 0x01, 0x86, 0x01, 0xC3, 0x00, 0xE3, @@ -267,105 +269,106 @@ const uint8_t Roboto_Regular16pt7bBitmaps[] PROGMEM = { 0x6C, 0x07, 0xF0, 0x01, 0xF0 }; const GFXglyph Roboto_Regular16pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' - { 1, 3, 22, 8, 3, -21 }, // 0x21 '!' - { 10, 8, 8, 10, 1, -23 }, // 0x22 '"' - { 18, 17, 22, 19, 1, -21 }, // 0x23 '#' - { 65, 14, 28, 17, 2, -24 }, // 0x24 '$' - { 114, 19, 22, 23, 2, -21 }, // 0x25 '%' - { 167, 18, 22, 19, 1, -21 }, // 0x26 '&' - { 217, 3, 8, 5, 1, -23 }, // 0x27 ''' - { 220, 8, 32, 10, 2, -24 }, // 0x28 '(' - { 252, 8, 32, 10, 0, -24 }, // 0x29 ')' - { 284, 13, 13, 13, 0, -21 }, // 0x2A '*' - { 306, 15, 15, 18, 1, -17 }, // 0x2B '+' - { 335, 4, 7, 6, 1, -2 }, // 0x2C ',' - { 339, 7, 2, 8, 1, -9 }, // 0x2D '-' - { 341, 3, 3, 8, 2, -2 }, // 0x2E '.' - { 343, 12, 24, 13, 0, -21 }, // 0x2F '/' - { 379, 14, 22, 17, 2, -21 }, // 0x30 '0' - { 418, 7, 22, 17, 3, -21 }, // 0x31 '1' - { 438, 15, 22, 17, 1, -21 }, // 0x32 '2' - { 480, 14, 22, 17, 1, -21 }, // 0x33 '3' - { 519, 16, 22, 17, 1, -21 }, // 0x34 '4' - { 563, 14, 22, 17, 2, -21 }, // 0x35 '5' - { 602, 14, 22, 17, 2, -21 }, // 0x36 '6' - { 641, 15, 22, 17, 1, -21 }, // 0x37 '7' - { 683, 14, 22, 17, 2, -21 }, // 0x38 '8' - { 722, 15, 22, 17, 1, -21 }, // 0x39 '9' - { 764, 3, 17, 8, 2, -16 }, // 0x3A ':' - { 771, 5, 21, 8, 1, -16 }, // 0x3B ';' - { 785, 12, 14, 16, 1, -14 }, // 0x3C '<' - { 806, 13, 8, 17, 2, -14 }, // 0x3D '=' - { 819, 13, 14, 16, 2, -14 }, // 0x3E '>' - { 842, 12, 22, 15, 1, -21 }, // 0x3F '?' - { 875, 25, 29, 28, 1, -21 }, // 0x40 '@' - { 966, 20, 22, 20, 0, -21 }, // 0x41 'A' - { 1021, 15, 22, 20, 3, -21 }, // 0x42 'B' - { 1063, 16, 22, 20, 2, -21 }, // 0x43 'C' - { 1107, 16, 22, 20, 3, -21 }, // 0x44 'D' - { 1151, 14, 22, 18, 3, -21 }, // 0x45 'E' - { 1190, 14, 22, 18, 3, -21 }, // 0x46 'F' - { 1229, 17, 22, 21, 2, -21 }, // 0x47 'G' - { 1276, 16, 22, 22, 3, -21 }, // 0x48 'H' - { 1320, 3, 22, 9, 3, -21 }, // 0x49 'I' - { 1329, 14, 22, 17, 1, -21 }, // 0x4A 'J' - { 1368, 17, 22, 20, 3, -21 }, // 0x4B 'K' - { 1415, 13, 22, 17, 3, -21 }, // 0x4C 'L' - { 1451, 21, 22, 27, 3, -21 }, // 0x4D 'M' - { 1509, 16, 22, 22, 3, -21 }, // 0x4E 'N' - { 1553, 17, 22, 21, 2, -21 }, // 0x4F 'O' - { 1600, 16, 22, 20, 3, -21 }, // 0x50 'P' - { 1644, 18, 25, 21, 2, -21 }, // 0x51 'Q' - { 1701, 16, 22, 21, 3, -21 }, // 0x52 'R' - { 1745, 17, 22, 19, 1, -21 }, // 0x53 'S' - { 1792, 17, 22, 18, 1, -21 }, // 0x54 'T' - { 1839, 17, 22, 21, 2, -21 }, // 0x55 'U' - { 1886, 19, 22, 20, 0, -21 }, // 0x56 'V' - { 1939, 25, 22, 27, 1, -21 }, // 0x57 'W' - { 2008, 18, 22, 20, 1, -21 }, // 0x58 'X' - { 2058, 19, 22, 19, 0, -21 }, // 0x59 'Y' - { 2111, 16, 22, 19, 1, -21 }, // 0x5A 'Z' - { 2155, 6, 30, 8, 2, -24 }, // 0x5B '[' - { 2178, 12, 24, 13, 1, -21 }, // 0x5C '\' - { 2214, 6, 30, 8, 0, -24 }, // 0x5D ']' - { 2237, 11, 11, 13, 1, -21 }, // 0x5E '^' - { 2253, 14, 2, 14, 0, 1 }, // 0x5F '_' - { 2257, 6, 4, 10, 1, -22 }, // 0x60 '`' - { 2260, 13, 17, 17, 2, -16 }, // 0x61 'a' - { 2288, 14, 24, 18, 2, -23 }, // 0x62 'b' - { 2330, 14, 17, 16, 1, -16 }, // 0x63 'c' - { 2360, 14, 24, 18, 1, -23 }, // 0x64 'd' - { 2402, 14, 17, 16, 1, -16 }, // 0x65 'e' - { 2432, 10, 24, 11, 1, -23 }, // 0x66 'f' - { 2462, 13, 23, 18, 2, -16 }, // 0x67 'g' - { 2500, 14, 24, 18, 2, -23 }, // 0x68 'h' - { 2542, 3, 24, 8, 2, -23 }, // 0x69 'i' - { 2551, 7, 30, 8, -1, -23 }, // 0x6A 'j' - { 2578, 14, 24, 16, 2, -23 }, // 0x6B 'k' - { 2620, 3, 24, 8, 2, -23 }, // 0x6C 'l' - { 2629, 23, 17, 27, 2, -16 }, // 0x6D 'm' - { 2678, 13, 17, 18, 2, -16 }, // 0x6E 'n' - { 2706, 15, 17, 18, 1, -16 }, // 0x6F 'o' - { 2738, 14, 23, 18, 2, -16 }, // 0x70 'p' - { 2779, 14, 23, 18, 1, -16 }, // 0x71 'q' - { 2820, 8, 17, 11, 2, -16 }, // 0x72 'r' - { 2837, 13, 17, 16, 2, -16 }, // 0x73 's' - { 2865, 8, 21, 11, 1, -20 }, // 0x74 't' - { 2886, 13, 17, 18, 2, -16 }, // 0x75 'u' - { 2914, 14, 17, 16, 1, -16 }, // 0x76 'v' - { 2944, 22, 17, 23, 1, -16 }, // 0x77 'w' - { 2991, 14, 17, 16, 1, -16 }, // 0x78 'x' - { 3021, 15, 23, 16, 0, -16 }, // 0x79 'y' - { 3065, 13, 17, 16, 1, -16 }, // 0x7A 'z' - { 3093, 9, 30, 11, 1, -23 }, // 0x7B '{' - { 3127, 2, 26, 8, 3, -21 }, // 0x7C '|' - { 3134, 10, 30, 11, 0, -23 }, // 0x7D '}' - { 3172, 17, 6, 21, 2, -11 } }; // 0x7E '~' + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' + { 1, 3, 22, 8, 3, -21 }, // 0x21 '!' + { 10, 8, 8, 10, 1, -23 }, // 0x22 '"' + { 18, 17, 22, 19, 1, -21 }, // 0x23 '#' + { 65, 14, 28, 17, 2, -24 }, // 0x24 '$' + { 114, 19, 22, 23, 2, -21 }, // 0x25 '%' + { 167, 18, 22, 19, 1, -21 }, // 0x26 '&' + { 217, 3, 8, 5, 1, -23 }, // 0x27 ''' + { 220, 8, 32, 10, 2, -24 }, // 0x28 '(' + { 252, 8, 32, 10, 0, -24 }, // 0x29 ')' + { 284, 13, 13, 13, 0, -21 }, // 0x2A '*' + { 306, 15, 15, 18, 1, -17 }, // 0x2B '+' + { 335, 4, 7, 6, 1, -2 }, // 0x2C ',' + { 339, 7, 2, 8, 1, -9 }, // 0x2D '-' + { 341, 3, 3, 8, 2, -2 }, // 0x2E '.' + { 343, 12, 24, 13, 0, -21 }, // 0x2F '/' + { 379, 14, 22, 17, 2, -21 }, // 0x30 '0' + { 418, 7, 22, 17, 3, -21 }, // 0x31 '1' + { 438, 15, 22, 17, 1, -21 }, // 0x32 '2' + { 480, 14, 22, 17, 1, -21 }, // 0x33 '3' + { 519, 16, 22, 17, 1, -21 }, // 0x34 '4' + { 563, 14, 22, 17, 2, -21 }, // 0x35 '5' + { 602, 14, 22, 17, 2, -21 }, // 0x36 '6' + { 641, 15, 22, 17, 1, -21 }, // 0x37 '7' + { 683, 14, 22, 17, 2, -21 }, // 0x38 '8' + { 722, 15, 22, 17, 1, -21 }, // 0x39 '9' + { 764, 3, 17, 8, 2, -16 }, // 0x3A ':' + { 771, 5, 21, 8, 1, -16 }, // 0x3B ';' + { 785, 12, 14, 16, 1, -14 }, // 0x3C '<' + { 806, 13, 8, 17, 2, -14 }, // 0x3D '=' + { 819, 13, 14, 16, 2, -14 }, // 0x3E '>' + { 842, 12, 22, 15, 1, -21 }, // 0x3F '?' + { 875, 25, 29, 28, 1, -21 }, // 0x40 '@' + { 966, 20, 22, 20, 0, -21 }, // 0x41 'A' + { 1021, 15, 22, 20, 3, -21 }, // 0x42 'B' + { 1063, 16, 22, 20, 2, -21 }, // 0x43 'C' + { 1107, 16, 22, 20, 3, -21 }, // 0x44 'D' + { 1151, 14, 22, 18, 3, -21 }, // 0x45 'E' + { 1190, 14, 22, 18, 3, -21 }, // 0x46 'F' + { 1229, 17, 22, 21, 2, -21 }, // 0x47 'G' + { 1276, 16, 22, 22, 3, -21 }, // 0x48 'H' + { 1320, 3, 22, 9, 3, -21 }, // 0x49 'I' + { 1329, 14, 22, 17, 1, -21 }, // 0x4A 'J' + { 1368, 17, 22, 20, 3, -21 }, // 0x4B 'K' + { 1415, 13, 22, 17, 3, -21 }, // 0x4C 'L' + { 1451, 21, 22, 27, 3, -21 }, // 0x4D 'M' + { 1509, 16, 22, 22, 3, -21 }, // 0x4E 'N' + { 1553, 17, 22, 21, 2, -21 }, // 0x4F 'O' + { 1600, 16, 22, 20, 3, -21 }, // 0x50 'P' + { 1644, 18, 25, 21, 2, -21 }, // 0x51 'Q' + { 1701, 16, 22, 21, 3, -21 }, // 0x52 'R' + { 1745, 17, 22, 19, 1, -21 }, // 0x53 'S' + { 1792, 17, 22, 18, 1, -21 }, // 0x54 'T' + { 1839, 17, 22, 21, 2, -21 }, // 0x55 'U' + { 1886, 19, 22, 20, 0, -21 }, // 0x56 'V' + { 1939, 25, 22, 27, 1, -21 }, // 0x57 'W' + { 2008, 18, 22, 20, 1, -21 }, // 0x58 'X' + { 2058, 19, 22, 19, 0, -21 }, // 0x59 'Y' + { 2111, 16, 22, 19, 1, -21 }, // 0x5A 'Z' + { 2155, 6, 30, 8, 2, -24 }, // 0x5B '[' + { 2178, 12, 24, 13, 1, -21 }, // 0x5C '\' + { 2214, 6, 30, 8, 0, -24 }, // 0x5D ']' + { 2237, 11, 11, 13, 1, -21 }, // 0x5E '^' + { 2253, 14, 2, 14, 0, 1 }, // 0x5F '_' + { 2257, 6, 4, 10, 1, -22 }, // 0x60 '`' + { 2260, 13, 17, 17, 2, -16 }, // 0x61 'a' + { 2288, 14, 24, 18, 2, -23 }, // 0x62 'b' + { 2330, 14, 17, 16, 1, -16 }, // 0x63 'c' + { 2360, 14, 24, 18, 1, -23 }, // 0x64 'd' + { 2402, 14, 17, 16, 1, -16 }, // 0x65 'e' + { 2432, 10, 24, 11, 1, -23 }, // 0x66 'f' + { 2462, 13, 23, 18, 2, -16 }, // 0x67 'g' + { 2500, 14, 24, 18, 2, -23 }, // 0x68 'h' + { 2542, 3, 24, 8, 2, -23 }, // 0x69 'i' + { 2551, 7, 30, 8, -1, -23 }, // 0x6A 'j' + { 2578, 14, 24, 16, 2, -23 }, // 0x6B 'k' + { 2620, 3, 24, 8, 2, -23 }, // 0x6C 'l' + { 2629, 23, 17, 27, 2, -16 }, // 0x6D 'm' + { 2678, 13, 17, 18, 2, -16 }, // 0x6E 'n' + { 2706, 15, 17, 18, 1, -16 }, // 0x6F 'o' + { 2738, 14, 23, 18, 2, -16 }, // 0x70 'p' + { 2779, 14, 23, 18, 1, -16 }, // 0x71 'q' + { 2820, 8, 17, 11, 2, -16 }, // 0x72 'r' + { 2837, 13, 17, 16, 2, -16 }, // 0x73 's' + { 2865, 8, 21, 11, 1, -20 }, // 0x74 't' + { 2886, 13, 17, 18, 2, -16 }, // 0x75 'u' + { 2914, 14, 17, 16, 1, -16 }, // 0x76 'v' + { 2944, 22, 17, 23, 1, -16 }, // 0x77 'w' + { 2991, 14, 17, 16, 1, -16 }, // 0x78 'x' + { 3021, 15, 23, 16, 0, -16 }, // 0x79 'y' + { 3065, 13, 17, 16, 1, -16 }, // 0x7A 'z' + { 3093, 9, 30, 11, 1, -23 }, // 0x7B '{' + { 3127, 2, 26, 8, 3, -21 }, // 0x7C '|' + { 3134, 10, 30, 11, 0, -23 }, // 0x7D '}' + { 3172, 17, 6, 21, 2, -11 } }; // 0x7E '~' const GFXfont Roboto_Regular16pt7b PROGMEM = { (uint8_t *)Roboto_Regular16pt7bBitmaps, (GFXglyph *)Roboto_Regular16pt7bGlyphs, - 0x20, 0x7E, 41 }; + 0x20, 0x7E, 41 }; // Approx. 3857 bytes +#endif // ifndef FONTS_ROBOTO_REGULAR16PT7B_H diff --git a/src/src/Static/Fonts/Roboto_Regular8pt7b.h b/src/src/Static/Fonts/Roboto_Regular8pt7b.h index f98d6833e..03719bdeb 100644 --- a/src/src/Static/Fonts/Roboto_Regular8pt7b.h +++ b/src/src/Static/Fonts/Roboto_Regular8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ROBOTO_REGULAR8PT7B_H +#define FONTS_ROBOTO_REGULAR8PT7B_H const uint8_t Roboto_Regular8pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0x0F, 0xBB, 0xAA, 0x12, 0x12, 0x12, 0x32, 0xFF, 0x24, 0x24, 0x24, 0xFF, 0x4C, 0x48, 0x48, 0x10, 0x20, 0xF2, 0x3C, 0x78, 0x10, @@ -79,105 +81,106 @@ const uint8_t Roboto_Regular8pt7bBitmaps[] PROGMEM = { 0xC4, 0xE1, 0xC0 }; const GFXglyph Roboto_Regular8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' - { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' - { 4, 4, 4, 5, 1, -11 }, // 0x22 '"' - { 6, 8, 12, 10, 1, -11 }, // 0x23 '#' - { 18, 7, 15, 9, 1, -13 }, // 0x24 '$' - { 32, 10, 12, 12, 1, -11 }, // 0x25 '%' - { 47, 10, 12, 10, 0, -11 }, // 0x26 '&' - { 62, 1, 4, 3, 1, -11 }, // 0x27 ''' - { 63, 4, 17, 5, 1, -12 }, // 0x28 '(' - { 72, 4, 17, 5, 0, -12 }, // 0x29 ')' - { 81, 7, 7, 7, 0, -11 }, // 0x2A '*' - { 88, 7, 8, 9, 1, -8 }, // 0x2B '+' - { 95, 2, 4, 3, 0, -1 }, // 0x2C ',' - { 96, 4, 1, 4, 0, -4 }, // 0x2D '-' - { 97, 2, 2, 4, 1, -1 }, // 0x2E '.' - { 98, 6, 13, 7, 0, -11 }, // 0x2F '/' - { 108, 7, 12, 9, 1, -11 }, // 0x30 '0' - { 119, 4, 12, 9, 1, -11 }, // 0x31 '1' - { 125, 7, 12, 9, 1, -11 }, // 0x32 '2' - { 136, 7, 12, 9, 1, -11 }, // 0x33 '3' - { 147, 9, 12, 9, 0, -11 }, // 0x34 '4' - { 161, 7, 12, 9, 1, -11 }, // 0x35 '5' - { 172, 7, 12, 9, 1, -11 }, // 0x36 '6' - { 183, 7, 12, 9, 1, -11 }, // 0x37 '7' - { 194, 7, 12, 9, 1, -11 }, // 0x38 '8' - { 205, 7, 12, 9, 1, -11 }, // 0x39 '9' - { 216, 2, 9, 4, 1, -8 }, // 0x3A ':' - { 219, 2, 11, 4, 1, -8 }, // 0x3B ';' - { 222, 6, 7, 8, 1, -7 }, // 0x3C '<' - { 228, 7, 4, 9, 1, -6 }, // 0x3D '=' - { 232, 7, 7, 8, 1, -7 }, // 0x3E '>' - { 239, 7, 12, 8, 0, -11 }, // 0x3F '?' - { 250, 13, 15, 14, 1, -10 }, // 0x40 '@' - { 275, 10, 12, 10, 0, -11 }, // 0x41 'A' - { 290, 8, 12, 10, 1, -11 }, // 0x42 'B' - { 302, 9, 12, 10, 1, -11 }, // 0x43 'C' - { 316, 9, 12, 11, 1, -11 }, // 0x44 'D' - { 330, 8, 12, 9, 1, -11 }, // 0x45 'E' - { 342, 8, 12, 9, 1, -11 }, // 0x46 'F' - { 354, 9, 12, 11, 1, -11 }, // 0x47 'G' - { 368, 9, 12, 11, 1, -11 }, // 0x48 'H' - { 382, 2, 12, 5, 1, -11 }, // 0x49 'I' - { 385, 8, 12, 9, 0, -11 }, // 0x4A 'J' - { 397, 9, 12, 10, 1, -11 }, // 0x4B 'K' - { 411, 7, 12, 9, 1, -11 }, // 0x4C 'L' - { 422, 12, 12, 14, 1, -11 }, // 0x4D 'M' - { 440, 9, 12, 11, 1, -11 }, // 0x4E 'N' - { 454, 9, 12, 11, 1, -11 }, // 0x4F 'O' - { 468, 9, 12, 10, 1, -11 }, // 0x50 'P' - { 482, 9, 14, 11, 1, -11 }, // 0x51 'Q' - { 498, 9, 12, 11, 1, -11 }, // 0x52 'R' - { 512, 8, 12, 10, 1, -11 }, // 0x53 'S' - { 524, 9, 12, 9, 0, -11 }, // 0x54 'T' - { 538, 9, 12, 11, 1, -11 }, // 0x55 'U' - { 552, 10, 12, 10, 0, -11 }, // 0x56 'V' - { 567, 14, 12, 14, 0, -11 }, // 0x57 'W' - { 588, 9, 12, 10, 1, -11 }, // 0x58 'X' - { 602, 10, 12, 10, 0, -11 }, // 0x59 'Y' - { 617, 8, 12, 10, 1, -11 }, // 0x5A 'Z' - { 629, 3, 15, 4, 1, -12 }, // 0x5B '[' - { 635, 7, 13, 7, 0, -11 }, // 0x5C '\' - { 647, 3, 15, 4, 0, -12 }, // 0x5D ']' - { 653, 6, 6, 7, 0, -11 }, // 0x5E '^' - { 658, 7, 1, 7, 0, 1 }, // 0x5F '_' - { 659, 3, 2, 5, 1, -11 }, // 0x60 '`' - { 660, 7, 9, 9, 1, -8 }, // 0x61 'a' - { 668, 7, 12, 9, 1, -11 }, // 0x62 'b' - { 679, 7, 9, 9, 1, -8 }, // 0x63 'c' - { 687, 7, 12, 9, 1, -11 }, // 0x64 'd' - { 698, 7, 9, 8, 1, -8 }, // 0x65 'e' - { 706, 6, 12, 6, 0, -11 }, // 0x66 'f' - { 715, 7, 13, 9, 1, -8 }, // 0x67 'g' - { 727, 7, 12, 9, 1, -11 }, // 0x68 'h' - { 738, 2, 13, 4, 1, -12 }, // 0x69 'i' - { 742, 4, 17, 4, -1, -12 }, // 0x6A 'j' - { 751, 7, 12, 8, 1, -11 }, // 0x6B 'k' - { 762, 2, 12, 4, 1, -11 }, // 0x6C 'l' - { 765, 12, 9, 14, 1, -8 }, // 0x6D 'm' - { 779, 7, 9, 9, 1, -8 }, // 0x6E 'n' - { 787, 7, 9, 9, 1, -8 }, // 0x6F 'o' - { 795, 7, 13, 9, 1, -8 }, // 0x70 'p' - { 807, 7, 13, 9, 1, -8 }, // 0x71 'q' - { 819, 4, 9, 5, 1, -8 }, // 0x72 'r' - { 824, 7, 9, 8, 1, -8 }, // 0x73 's' - { 832, 5, 11, 6, 0, -10 }, // 0x74 't' - { 839, 7, 9, 9, 1, -8 }, // 0x75 'u' - { 847, 8, 9, 8, 0, -8 }, // 0x76 'v' - { 856, 12, 9, 12, 0, -8 }, // 0x77 'w' - { 870, 8, 9, 8, 0, -8 }, // 0x78 'x' - { 879, 8, 13, 8, 0, -8 }, // 0x79 'y' - { 892, 6, 9, 8, 1, -8 }, // 0x7A 'z' - { 899, 5, 15, 5, 0, -11 }, // 0x7B '{' - { 909, 2, 14, 4, 1, -11 }, // 0x7C '|' - { 913, 5, 15, 5, 0, -11 }, // 0x7D '}' - { 923, 9, 3, 11, 1, -5 } }; // 0x7E '~' + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 2, 12, 4, 1, -11 }, // 0x21 '!' + { 4, 4, 4, 5, 1, -11 }, // 0x22 '"' + { 6, 8, 12, 10, 1, -11 }, // 0x23 '#' + { 18, 7, 15, 9, 1, -13 }, // 0x24 '$' + { 32, 10, 12, 12, 1, -11 }, // 0x25 '%' + { 47, 10, 12, 10, 0, -11 }, // 0x26 '&' + { 62, 1, 4, 3, 1, -11 }, // 0x27 ''' + { 63, 4, 17, 5, 1, -12 }, // 0x28 '(' + { 72, 4, 17, 5, 0, -12 }, // 0x29 ')' + { 81, 7, 7, 7, 0, -11 }, // 0x2A '*' + { 88, 7, 8, 9, 1, -8 }, // 0x2B '+' + { 95, 2, 4, 3, 0, -1 }, // 0x2C ',' + { 96, 4, 1, 4, 0, -4 }, // 0x2D '-' + { 97, 2, 2, 4, 1, -1 }, // 0x2E '.' + { 98, 6, 13, 7, 0, -11 }, // 0x2F '/' + { 108, 7, 12, 9, 1, -11 }, // 0x30 '0' + { 119, 4, 12, 9, 1, -11 }, // 0x31 '1' + { 125, 7, 12, 9, 1, -11 }, // 0x32 '2' + { 136, 7, 12, 9, 1, -11 }, // 0x33 '3' + { 147, 9, 12, 9, 0, -11 }, // 0x34 '4' + { 161, 7, 12, 9, 1, -11 }, // 0x35 '5' + { 172, 7, 12, 9, 1, -11 }, // 0x36 '6' + { 183, 7, 12, 9, 1, -11 }, // 0x37 '7' + { 194, 7, 12, 9, 1, -11 }, // 0x38 '8' + { 205, 7, 12, 9, 1, -11 }, // 0x39 '9' + { 216, 2, 9, 4, 1, -8 }, // 0x3A ':' + { 219, 2, 11, 4, 1, -8 }, // 0x3B ';' + { 222, 6, 7, 8, 1, -7 }, // 0x3C '<' + { 228, 7, 4, 9, 1, -6 }, // 0x3D '=' + { 232, 7, 7, 8, 1, -7 }, // 0x3E '>' + { 239, 7, 12, 8, 0, -11 }, // 0x3F '?' + { 250, 13, 15, 14, 1, -10 }, // 0x40 '@' + { 275, 10, 12, 10, 0, -11 }, // 0x41 'A' + { 290, 8, 12, 10, 1, -11 }, // 0x42 'B' + { 302, 9, 12, 10, 1, -11 }, // 0x43 'C' + { 316, 9, 12, 11, 1, -11 }, // 0x44 'D' + { 330, 8, 12, 9, 1, -11 }, // 0x45 'E' + { 342, 8, 12, 9, 1, -11 }, // 0x46 'F' + { 354, 9, 12, 11, 1, -11 }, // 0x47 'G' + { 368, 9, 12, 11, 1, -11 }, // 0x48 'H' + { 382, 2, 12, 5, 1, -11 }, // 0x49 'I' + { 385, 8, 12, 9, 0, -11 }, // 0x4A 'J' + { 397, 9, 12, 10, 1, -11 }, // 0x4B 'K' + { 411, 7, 12, 9, 1, -11 }, // 0x4C 'L' + { 422, 12, 12, 14, 1, -11 }, // 0x4D 'M' + { 440, 9, 12, 11, 1, -11 }, // 0x4E 'N' + { 454, 9, 12, 11, 1, -11 }, // 0x4F 'O' + { 468, 9, 12, 10, 1, -11 }, // 0x50 'P' + { 482, 9, 14, 11, 1, -11 }, // 0x51 'Q' + { 498, 9, 12, 11, 1, -11 }, // 0x52 'R' + { 512, 8, 12, 10, 1, -11 }, // 0x53 'S' + { 524, 9, 12, 9, 0, -11 }, // 0x54 'T' + { 538, 9, 12, 11, 1, -11 }, // 0x55 'U' + { 552, 10, 12, 10, 0, -11 }, // 0x56 'V' + { 567, 14, 12, 14, 0, -11 }, // 0x57 'W' + { 588, 9, 12, 10, 1, -11 }, // 0x58 'X' + { 602, 10, 12, 10, 0, -11 }, // 0x59 'Y' + { 617, 8, 12, 10, 1, -11 }, // 0x5A 'Z' + { 629, 3, 15, 4, 1, -12 }, // 0x5B '[' + { 635, 7, 13, 7, 0, -11 }, // 0x5C '\' + { 647, 3, 15, 4, 0, -12 }, // 0x5D ']' + { 653, 6, 6, 7, 0, -11 }, // 0x5E '^' + { 658, 7, 1, 7, 0, 1 }, // 0x5F '_' + { 659, 3, 2, 5, 1, -11 }, // 0x60 '`' + { 660, 7, 9, 9, 1, -8 }, // 0x61 'a' + { 668, 7, 12, 9, 1, -11 }, // 0x62 'b' + { 679, 7, 9, 9, 1, -8 }, // 0x63 'c' + { 687, 7, 12, 9, 1, -11 }, // 0x64 'd' + { 698, 7, 9, 8, 1, -8 }, // 0x65 'e' + { 706, 6, 12, 6, 0, -11 }, // 0x66 'f' + { 715, 7, 13, 9, 1, -8 }, // 0x67 'g' + { 727, 7, 12, 9, 1, -11 }, // 0x68 'h' + { 738, 2, 13, 4, 1, -12 }, // 0x69 'i' + { 742, 4, 17, 4, -1, -12 }, // 0x6A 'j' + { 751, 7, 12, 8, 1, -11 }, // 0x6B 'k' + { 762, 2, 12, 4, 1, -11 }, // 0x6C 'l' + { 765, 12, 9, 14, 1, -8 }, // 0x6D 'm' + { 779, 7, 9, 9, 1, -8 }, // 0x6E 'n' + { 787, 7, 9, 9, 1, -8 }, // 0x6F 'o' + { 795, 7, 13, 9, 1, -8 }, // 0x70 'p' + { 807, 7, 13, 9, 1, -8 }, // 0x71 'q' + { 819, 4, 9, 5, 1, -8 }, // 0x72 'r' + { 824, 7, 9, 8, 1, -8 }, // 0x73 's' + { 832, 5, 11, 6, 0, -10 }, // 0x74 't' + { 839, 7, 9, 9, 1, -8 }, // 0x75 'u' + { 847, 8, 9, 8, 0, -8 }, // 0x76 'v' + { 856, 12, 9, 12, 0, -8 }, // 0x77 'w' + { 870, 8, 9, 8, 0, -8 }, // 0x78 'x' + { 879, 8, 13, 8, 0, -8 }, // 0x79 'y' + { 892, 6, 9, 8, 1, -8 }, // 0x7A 'z' + { 899, 5, 15, 5, 0, -11 }, // 0x7B '{' + { 909, 2, 14, 4, 1, -11 }, // 0x7C '|' + { 913, 5, 15, 5, 0, -11 }, // 0x7D '}' + { 923, 9, 3, 11, 1, -5 } }; // 0x7E '~' const GFXfont Roboto_Regular8pt7b PROGMEM = { (uint8_t *)Roboto_Regular8pt7bBitmaps, (GFXglyph *)Roboto_Regular8pt7bGlyphs, - 0x20, 0x7E, 21 }; + 0x20, 0x7E, 21 }; // Approx. 1599 bytes +#endif // ifndef FONTS_ROBOTO_REGULAR8PT7B_H diff --git a/src/src/Static/Fonts/Seven_Segment18pt7b.h b/src/src/Static/Fonts/Seven_Segment18pt7b.h index f70351a4e..4a6d48b5b 100644 --- a/src/src/Static/Fonts/Seven_Segment18pt7b.h +++ b/src/src/Static/Fonts/Seven_Segment18pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_SEVEN_SEGMENT18PT7B_H +#define FONTS_SEVEN_SEGMENT18PT7B_H const uint8_t Seven_Segment18pt7bBitmaps[] PROGMEM = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x40, 0x4B, 0x74, 0x80, 0x00, 0x08, 0x03, 0x30, 0x0E, 0x60, 0x19, 0xC0, 0x33, 0x0F, 0xFF, 0x9F, 0xFF, 0x07, @@ -297,105 +299,106 @@ const uint8_t Seven_Segment18pt7bBitmaps[] PROGMEM = { 0x0C, 0x07, 0xFE }; const GFXglyph Seven_Segment18pt7bGlyphs[] PROGMEM = { - { 0, 0, 0, 11, 0, 1 }, // 0x20 ' ' - { 0, 2, 25, 6, 2, -24 }, // 0x21 '!' - { 7, 6, 3, 10, 2, -23 }, // 0x22 '"' - { 10, 15, 16, 19, 2, -15 }, // 0x23 '#' - { 40, 13, 31, 18, 2, -27 }, // 0x24 '$' - { 91, 20, 25, 25, 2, -24 }, // 0x25 '%' - { 154, 79, 25, 83, 2, -24 }, // 0x26 '&' - { 401, 9, 23, 13, 1, -22 }, // 0x27 ''' - { 427, 9, 25, 13, 2, -24 }, // 0x28 '(' - { 456, 9, 25, 13, 2, -24 }, // 0x29 ')' - { 485, 10, 11, 14, 2, -28 }, // 0x2A '*' - { 499, 19, 18, 23, 2, -19 }, // 0x2B '+' - { 542, 4, 4, 8, 2, -3 }, // 0x2C ',' - { 544, 10, 2, 14, 2, -12 }, // 0x2D '-' - { 547, 2, 3, 6, 2, -2 }, // 0x2E '.' - { 548, 15, 24, 19, 2, -23 }, // 0x2F '/' - { 593, 13, 25, 18, 2, -24 }, // 0x30 '0' - { 634, 2, 25, 6, 2, -24 }, // 0x31 '1' - { 641, 13, 25, 18, 2, -24 }, // 0x32 '2' - { 682, 12, 25, 16, 2, -24 }, // 0x33 '3' - { 720, 13, 25, 18, 2, -24 }, // 0x34 '4' - { 761, 13, 25, 18, 2, -24 }, // 0x35 '5' - { 802, 13, 25, 18, 2, -24 }, // 0x36 '6' - { 843, 12, 25, 16, 2, -24 }, // 0x37 '7' - { 881, 13, 25, 18, 2, -24 }, // 0x38 '8' - { 922, 13, 25, 18, 2, -24 }, // 0x39 '9' - { 963, 2, 10, 6, 2, -9 }, // 0x3A ':' - { 966, 9, 23, 13, 1, -22 }, // 0x3B ';' - { 992, 6, 25, 10, 2, -24 }, // 0x3C '<' - { 1011, 15, 9, 19, 2, -13 }, // 0x3D '=' - { 1028, 6, 25, 10, 2, -24 }, // 0x3E '>' - { 1047, 13, 25, 18, 2, -24 }, // 0x3F '?' - { 1088, 13, 25, 18, 2, -24 }, // 0x40 '@' - { 1129, 13, 25, 18, 2, -24 }, // 0x41 'A' - { 1170, 13, 25, 18, 2, -24 }, // 0x42 'B' - { 1211, 12, 25, 16, 2, -24 }, // 0x43 'C' - { 1249, 13, 25, 18, 2, -24 }, // 0x44 'D' - { 1290, 12, 25, 16, 2, -24 }, // 0x45 'E' - { 1328, 12, 25, 16, 2, -24 }, // 0x46 'F' - { 1366, 13, 25, 18, 2, -24 }, // 0x47 'G' - { 1407, 13, 25, 18, 2, -24 }, // 0x48 'H' - { 1448, 2, 25, 6, 2, -24 }, // 0x49 'I' - { 1455, 13, 25, 18, 2, -24 }, // 0x4A 'J' - { 1496, 13, 25, 18, 2, -24 }, // 0x4B 'K' - { 1537, 12, 25, 16, 2, -24 }, // 0x4C 'L' - { 1575, 20, 25, 24, 2, -24 }, // 0x4D 'M' - { 1638, 13, 25, 18, 2, -24 }, // 0x4E 'N' - { 1679, 13, 25, 18, 2, -24 }, // 0x4F 'O' - { 1720, 13, 25, 18, 2, -24 }, // 0x50 'P' - { 1761, 13, 25, 18, 2, -24 }, // 0x51 'Q' - { 1802, 13, 25, 18, 2, -24 }, // 0x52 'R' - { 1843, 13, 25, 18, 2, -24 }, // 0x53 'S' - { 1884, 16, 25, 20, 2, -24 }, // 0x54 'T' - { 1934, 13, 25, 18, 2, -24 }, // 0x55 'U' - { 1975, 13, 25, 18, 2, -24 }, // 0x56 'V' - { 2016, 20, 25, 24, 2, -24 }, // 0x57 'W' - { 2079, 13, 25, 18, 2, -24 }, // 0x58 'X' - { 2120, 13, 25, 18, 2, -24 }, // 0x59 'Y' - { 2161, 13, 25, 18, 2, -24 }, // 0x5A 'Z' - { 2202, 9, 25, 13, 2, -24 }, // 0x5B '[' - { 2231, 15, 24, 19, 2, -23 }, // 0x5C '\' - { 2276, 9, 25, 13, 2, -24 }, // 0x5D ']' - { 2305, 25, 6, 29, 2, -16 }, // 0x5E '^' - { 2324, 18, 2, 22, 2, -1 }, // 0x5F '_' - { 2329, 9, 23, 13, 1, -22 }, // 0x60 '`' - { 2355, 13, 25, 18, 2, -24 }, // 0x61 'a' - { 2396, 13, 25, 18, 2, -24 }, // 0x62 'b' - { 2437, 12, 25, 16, 2, -24 }, // 0x63 'c' - { 2475, 13, 25, 18, 2, -24 }, // 0x64 'd' - { 2516, 12, 25, 16, 2, -24 }, // 0x65 'e' - { 2554, 12, 25, 16, 2, -24 }, // 0x66 'f' - { 2592, 13, 25, 18, 2, -24 }, // 0x67 'g' - { 2633, 13, 25, 18, 2, -24 }, // 0x68 'h' - { 2674, 2, 25, 6, 2, -24 }, // 0x69 'i' - { 2681, 13, 25, 18, 2, -24 }, // 0x6A 'j' - { 2722, 13, 25, 18, 2, -24 }, // 0x6B 'k' - { 2763, 12, 25, 16, 2, -24 }, // 0x6C 'l' - { 2801, 20, 25, 24, 2, -24 }, // 0x6D 'm' - { 2864, 13, 25, 18, 2, -24 }, // 0x6E 'n' - { 2905, 13, 25, 18, 2, -24 }, // 0x6F 'o' - { 2946, 13, 25, 18, 2, -24 }, // 0x70 'p' - { 2987, 13, 25, 18, 2, -24 }, // 0x71 'q' - { 3028, 13, 25, 18, 2, -24 }, // 0x72 'r' - { 3069, 13, 25, 18, 2, -24 }, // 0x73 's' - { 3110, 16, 25, 20, 2, -24 }, // 0x74 't' - { 3160, 13, 25, 18, 2, -24 }, // 0x75 'u' - { 3201, 13, 25, 18, 2, -24 }, // 0x76 'v' - { 3242, 20, 25, 24, 2, -24 }, // 0x77 'w' - { 3305, 13, 25, 18, 2, -24 }, // 0x78 'x' - { 3346, 13, 25, 18, 2, -24 }, // 0x79 'y' - { 3387, 13, 25, 18, 2, -24 }, // 0x7A 'z' - { 3428, 13, 25, 17, 2, -24 }, // 0x7B '{' - { 3469, 2, 27, 6, 2, -26 }, // 0x7C '|' - { 3476, 13, 25, 17, 2, -24 }, // 0x7D '}' - { 3517, 9, 23, 13, 1, -22 } }; // 0x7E '~' + { 0, 0, 0, 11, 0, 1 }, // 0x20 ' ' + { 0, 2, 25, 6, 2, -24 }, // 0x21 '!' + { 7, 6, 3, 10, 2, -23 }, // 0x22 '"' + { 10, 15, 16, 19, 2, -15 }, // 0x23 '#' + { 40, 13, 31, 18, 2, -27 }, // 0x24 '$' + { 91, 20, 25, 25, 2, -24 }, // 0x25 '%' + { 154, 79, 25, 83, 2, -24 }, // 0x26 '&' + { 401, 9, 23, 13, 1, -22 }, // 0x27 ''' + { 427, 9, 25, 13, 2, -24 }, // 0x28 '(' + { 456, 9, 25, 13, 2, -24 }, // 0x29 ')' + { 485, 10, 11, 14, 2, -28 }, // 0x2A '*' + { 499, 19, 18, 23, 2, -19 }, // 0x2B '+' + { 542, 4, 4, 8, 2, -3 }, // 0x2C ',' + { 544, 10, 2, 14, 2, -12 }, // 0x2D '-' + { 547, 2, 3, 6, 2, -2 }, // 0x2E '.' + { 548, 15, 24, 19, 2, -23 }, // 0x2F '/' + { 593, 13, 25, 18, 2, -24 }, // 0x30 '0' + { 634, 2, 25, 6, 2, -24 }, // 0x31 '1' + { 641, 13, 25, 18, 2, -24 }, // 0x32 '2' + { 682, 12, 25, 16, 2, -24 }, // 0x33 '3' + { 720, 13, 25, 18, 2, -24 }, // 0x34 '4' + { 761, 13, 25, 18, 2, -24 }, // 0x35 '5' + { 802, 13, 25, 18, 2, -24 }, // 0x36 '6' + { 843, 12, 25, 16, 2, -24 }, // 0x37 '7' + { 881, 13, 25, 18, 2, -24 }, // 0x38 '8' + { 922, 13, 25, 18, 2, -24 }, // 0x39 '9' + { 963, 2, 10, 6, 2, -9 }, // 0x3A ':' + { 966, 9, 23, 13, 1, -22 }, // 0x3B ';' + { 992, 6, 25, 10, 2, -24 }, // 0x3C '<' + { 1011, 15, 9, 19, 2, -13 }, // 0x3D '=' + { 1028, 6, 25, 10, 2, -24 }, // 0x3E '>' + { 1047, 13, 25, 18, 2, -24 }, // 0x3F '?' + { 1088, 13, 25, 18, 2, -24 }, // 0x40 '@' + { 1129, 13, 25, 18, 2, -24 }, // 0x41 'A' + { 1170, 13, 25, 18, 2, -24 }, // 0x42 'B' + { 1211, 12, 25, 16, 2, -24 }, // 0x43 'C' + { 1249, 13, 25, 18, 2, -24 }, // 0x44 'D' + { 1290, 12, 25, 16, 2, -24 }, // 0x45 'E' + { 1328, 12, 25, 16, 2, -24 }, // 0x46 'F' + { 1366, 13, 25, 18, 2, -24 }, // 0x47 'G' + { 1407, 13, 25, 18, 2, -24 }, // 0x48 'H' + { 1448, 2, 25, 6, 2, -24 }, // 0x49 'I' + { 1455, 13, 25, 18, 2, -24 }, // 0x4A 'J' + { 1496, 13, 25, 18, 2, -24 }, // 0x4B 'K' + { 1537, 12, 25, 16, 2, -24 }, // 0x4C 'L' + { 1575, 20, 25, 24, 2, -24 }, // 0x4D 'M' + { 1638, 13, 25, 18, 2, -24 }, // 0x4E 'N' + { 1679, 13, 25, 18, 2, -24 }, // 0x4F 'O' + { 1720, 13, 25, 18, 2, -24 }, // 0x50 'P' + { 1761, 13, 25, 18, 2, -24 }, // 0x51 'Q' + { 1802, 13, 25, 18, 2, -24 }, // 0x52 'R' + { 1843, 13, 25, 18, 2, -24 }, // 0x53 'S' + { 1884, 16, 25, 20, 2, -24 }, // 0x54 'T' + { 1934, 13, 25, 18, 2, -24 }, // 0x55 'U' + { 1975, 13, 25, 18, 2, -24 }, // 0x56 'V' + { 2016, 20, 25, 24, 2, -24 }, // 0x57 'W' + { 2079, 13, 25, 18, 2, -24 }, // 0x58 'X' + { 2120, 13, 25, 18, 2, -24 }, // 0x59 'Y' + { 2161, 13, 25, 18, 2, -24 }, // 0x5A 'Z' + { 2202, 9, 25, 13, 2, -24 }, // 0x5B '[' + { 2231, 15, 24, 19, 2, -23 }, // 0x5C '\' + { 2276, 9, 25, 13, 2, -24 }, // 0x5D ']' + { 2305, 25, 6, 29, 2, -16 }, // 0x5E '^' + { 2324, 18, 2, 22, 2, -1 }, // 0x5F '_' + { 2329, 9, 23, 13, 1, -22 }, // 0x60 '`' + { 2355, 13, 25, 18, 2, -24 }, // 0x61 'a' + { 2396, 13, 25, 18, 2, -24 }, // 0x62 'b' + { 2437, 12, 25, 16, 2, -24 }, // 0x63 'c' + { 2475, 13, 25, 18, 2, -24 }, // 0x64 'd' + { 2516, 12, 25, 16, 2, -24 }, // 0x65 'e' + { 2554, 12, 25, 16, 2, -24 }, // 0x66 'f' + { 2592, 13, 25, 18, 2, -24 }, // 0x67 'g' + { 2633, 13, 25, 18, 2, -24 }, // 0x68 'h' + { 2674, 2, 25, 6, 2, -24 }, // 0x69 'i' + { 2681, 13, 25, 18, 2, -24 }, // 0x6A 'j' + { 2722, 13, 25, 18, 2, -24 }, // 0x6B 'k' + { 2763, 12, 25, 16, 2, -24 }, // 0x6C 'l' + { 2801, 20, 25, 24, 2, -24 }, // 0x6D 'm' + { 2864, 13, 25, 18, 2, -24 }, // 0x6E 'n' + { 2905, 13, 25, 18, 2, -24 }, // 0x6F 'o' + { 2946, 13, 25, 18, 2, -24 }, // 0x70 'p' + { 2987, 13, 25, 18, 2, -24 }, // 0x71 'q' + { 3028, 13, 25, 18, 2, -24 }, // 0x72 'r' + { 3069, 13, 25, 18, 2, -24 }, // 0x73 's' + { 3110, 16, 25, 20, 2, -24 }, // 0x74 't' + { 3160, 13, 25, 18, 2, -24 }, // 0x75 'u' + { 3201, 13, 25, 18, 2, -24 }, // 0x76 'v' + { 3242, 20, 25, 24, 2, -24 }, // 0x77 'w' + { 3305, 13, 25, 18, 2, -24 }, // 0x78 'x' + { 3346, 13, 25, 18, 2, -24 }, // 0x79 'y' + { 3387, 13, 25, 18, 2, -24 }, // 0x7A 'z' + { 3428, 13, 25, 17, 2, -24 }, // 0x7B '{' + { 3469, 2, 27, 6, 2, -26 }, // 0x7C '|' + { 3476, 13, 25, 17, 2, -24 }, // 0x7D '}' + { 3517, 9, 23, 13, 1, -22 } }; // 0x7E '~' const GFXfont Seven_Segment18pt7b PROGMEM = { (uint8_t *)Seven_Segment18pt7bBitmaps, (GFXglyph *)Seven_Segment18pt7bGlyphs, - 0x20, 0x7E, 36 }; + 0x20, 0x7E, 36 }; // Approx. 4215 bytes +#endif // ifndef FONTS_SEVEN_SEGMENT18PT7B_H diff --git a/src/src/Static/Fonts/Seven_Segment24pt7b.h b/src/src/Static/Fonts/Seven_Segment24pt7b.h index 0e59a6df6..1046b4dbc 100644 --- a/src/src/Static/Fonts/Seven_Segment24pt7b.h +++ b/src/src/Static/Fonts/Seven_Segment24pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_SEVEN_SEGMENT24PT7B_H +#define FONTS_SEVEN_SEGMENT24PT7B_H const uint8_t Seven_Segment24pt7bBitmaps[] PROGMEM = { 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x01, 0xBF, 0x40, 0x45, 0xDF, 0xBF, 0x34, 0x40, 0x00, 0x61, 0x80, 0x07, 0x3C, 0x00, @@ -532,105 +534,106 @@ const uint8_t Seven_Segment24pt7bBitmaps[] PROGMEM = { 0x03, 0x80, 0x38, 0x03, 0xFF, 0xFF, 0xFF }; const GFXglyph Seven_Segment24pt7bGlyphs[] PROGMEM = { - { 0, 0, 0, 14, 0, 1 }, // 0x20 ' ' - { 0, 3, 33, 9, 3, -32 }, // 0x21 '!' - { 13, 7, 5, 13, 3, -32 }, // 0x22 '"' - { 18, 20, 22, 26, 3, -21 }, // 0x23 '#' - { 73, 18, 41, 24, 3, -36 }, // 0x24 '$' - { 166, 27, 33, 33, 3, -32 }, // 0x25 '%' - { 278, 105, 33, 111, 3, -32 }, // 0x26 '&' - { 712, 12, 32, 17, 2, -31 }, // 0x27 ''' - { 760, 12, 33, 18, 3, -32 }, // 0x28 '(' - { 810, 12, 33, 18, 3, -32 }, // 0x29 ')' - { 860, 14, 15, 19, 3, -38 }, // 0x2A '*' - { 887, 25, 25, 31, 3, -27 }, // 0x2B '+' - { 966, 5, 5, 11, 3, -4 }, // 0x2C ',' - { 970, 13, 3, 19, 3, -17 }, // 0x2D '-' - { 975, 3, 5, 9, 3, -4 }, // 0x2E '.' - { 977, 20, 32, 25, 3, -31 }, // 0x2F '/' - { 1057, 18, 33, 24, 3, -32 }, // 0x30 '0' - { 1132, 3, 33, 9, 3, -32 }, // 0x31 '1' - { 1145, 18, 33, 24, 3, -32 }, // 0x32 '2' - { 1220, 16, 33, 21, 3, -32 }, // 0x33 '3' - { 1286, 18, 33, 24, 3, -32 }, // 0x34 '4' - { 1361, 18, 33, 24, 3, -32 }, // 0x35 '5' - { 1436, 18, 33, 24, 3, -32 }, // 0x36 '6' - { 1511, 16, 33, 21, 3, -32 }, // 0x37 '7' - { 1577, 18, 33, 24, 3, -32 }, // 0x38 '8' - { 1652, 18, 33, 24, 3, -32 }, // 0x39 '9' - { 1727, 3, 14, 9, 3, -13 }, // 0x3A ':' - { 1733, 12, 32, 17, 2, -31 }, // 0x3B ';' - { 1781, 8, 33, 14, 3, -32 }, // 0x3C '<' - { 1814, 20, 11, 26, 3, -17 }, // 0x3D '=' - { 1842, 8, 33, 14, 3, -32 }, // 0x3E '>' - { 1875, 18, 33, 24, 3, -32 }, // 0x3F '?' - { 1950, 18, 33, 24, 3, -32 }, // 0x40 '@' - { 2025, 18, 33, 24, 3, -32 }, // 0x41 'A' - { 2100, 18, 33, 24, 3, -32 }, // 0x42 'B' - { 2175, 16, 33, 21, 3, -32 }, // 0x43 'C' - { 2241, 18, 33, 24, 3, -32 }, // 0x44 'D' - { 2316, 16, 33, 21, 3, -32 }, // 0x45 'E' - { 2382, 16, 33, 21, 3, -32 }, // 0x46 'F' - { 2448, 18, 33, 24, 3, -32 }, // 0x47 'G' - { 2523, 18, 33, 24, 3, -32 }, // 0x48 'H' - { 2598, 3, 33, 9, 3, -32 }, // 0x49 'I' - { 2611, 18, 33, 24, 3, -32 }, // 0x4A 'J' - { 2686, 18, 33, 24, 3, -32 }, // 0x4B 'K' - { 2761, 16, 33, 21, 3, -32 }, // 0x4C 'L' - { 2827, 26, 33, 32, 3, -32 }, // 0x4D 'M' - { 2935, 18, 33, 24, 3, -32 }, // 0x4E 'N' - { 3010, 18, 33, 24, 3, -32 }, // 0x4F 'O' - { 3085, 18, 33, 24, 3, -32 }, // 0x50 'P' - { 3160, 18, 33, 24, 3, -32 }, // 0x51 'Q' - { 3235, 18, 33, 24, 3, -32 }, // 0x52 'R' - { 3310, 18, 33, 24, 3, -32 }, // 0x53 'S' - { 3385, 22, 33, 28, 3, -32 }, // 0x54 'T' - { 3476, 18, 33, 24, 3, -32 }, // 0x55 'U' - { 3551, 18, 33, 24, 3, -32 }, // 0x56 'V' - { 3626, 26, 33, 32, 3, -32 }, // 0x57 'W' - { 3734, 18, 33, 24, 3, -32 }, // 0x58 'X' - { 3809, 18, 33, 24, 3, -32 }, // 0x59 'Y' - { 3884, 18, 33, 24, 3, -32 }, // 0x5A 'Z' - { 3959, 12, 33, 18, 3, -32 }, // 0x5B '[' - { 4009, 20, 32, 25, 3, -31 }, // 0x5C '\' - { 4089, 12, 33, 18, 3, -32 }, // 0x5D ']' - { 4139, 33, 8, 39, 3, -21 }, // 0x5E '^' - { 4172, 23, 3, 29, 3, -2 }, // 0x5F '_' - { 4181, 12, 32, 17, 2, -31 }, // 0x60 '`' - { 4229, 18, 33, 24, 3, -32 }, // 0x61 'a' - { 4304, 18, 33, 24, 3, -32 }, // 0x62 'b' - { 4379, 16, 33, 21, 3, -32 }, // 0x63 'c' - { 4445, 18, 33, 24, 3, -32 }, // 0x64 'd' - { 4520, 16, 33, 21, 3, -32 }, // 0x65 'e' - { 4586, 16, 33, 21, 3, -32 }, // 0x66 'f' - { 4652, 18, 33, 24, 3, -32 }, // 0x67 'g' - { 4727, 18, 33, 24, 3, -32 }, // 0x68 'h' - { 4802, 3, 33, 9, 3, -32 }, // 0x69 'i' - { 4815, 18, 33, 24, 3, -32 }, // 0x6A 'j' - { 4890, 18, 33, 24, 3, -32 }, // 0x6B 'k' - { 4965, 16, 33, 21, 3, -32 }, // 0x6C 'l' - { 5031, 26, 33, 32, 3, -32 }, // 0x6D 'm' - { 5139, 18, 33, 24, 3, -32 }, // 0x6E 'n' - { 5214, 18, 33, 24, 3, -32 }, // 0x6F 'o' - { 5289, 18, 33, 24, 3, -32 }, // 0x70 'p' - { 5364, 18, 33, 24, 3, -32 }, // 0x71 'q' - { 5439, 18, 33, 24, 3, -32 }, // 0x72 'r' - { 5514, 18, 33, 24, 3, -32 }, // 0x73 's' - { 5589, 22, 33, 28, 3, -32 }, // 0x74 't' - { 5680, 18, 33, 24, 3, -32 }, // 0x75 'u' - { 5755, 18, 33, 24, 3, -32 }, // 0x76 'v' - { 5830, 26, 33, 32, 3, -32 }, // 0x77 'w' - { 5938, 18, 33, 24, 3, -32 }, // 0x78 'x' - { 6013, 18, 33, 24, 3, -32 }, // 0x79 'y' - { 6088, 18, 33, 24, 3, -32 }, // 0x7A 'z' - { 6163, 17, 33, 23, 3, -32 }, // 0x7B '{' - { 6234, 3, 36, 9, 3, -35 }, // 0x7C '|' - { 6248, 17, 33, 23, 3, -32 }, // 0x7D '}' - { 6319, 12, 32, 17, 2, -31 } }; // 0x7E '~' + { 0, 0, 0, 14, 0, 1 }, // 0x20 ' ' + { 0, 3, 33, 9, 3, -32 }, // 0x21 '!' + { 13, 7, 5, 13, 3, -32 }, // 0x22 '"' + { 18, 20, 22, 26, 3, -21 }, // 0x23 '#' + { 73, 18, 41, 24, 3, -36 }, // 0x24 '$' + { 166, 27, 33, 33, 3, -32 }, // 0x25 '%' + { 278, 105, 33, 111, 3, -32 }, // 0x26 '&' + { 712, 12, 32, 17, 2, -31 }, // 0x27 ''' + { 760, 12, 33, 18, 3, -32 }, // 0x28 '(' + { 810, 12, 33, 18, 3, -32 }, // 0x29 ')' + { 860, 14, 15, 19, 3, -38 }, // 0x2A '*' + { 887, 25, 25, 31, 3, -27 }, // 0x2B '+' + { 966, 5, 5, 11, 3, -4 }, // 0x2C ',' + { 970, 13, 3, 19, 3, -17 }, // 0x2D '-' + { 975, 3, 5, 9, 3, -4 }, // 0x2E '.' + { 977, 20, 32, 25, 3, -31 }, // 0x2F '/' + { 1057, 18, 33, 24, 3, -32 }, // 0x30 '0' + { 1132, 3, 33, 9, 3, -32 }, // 0x31 '1' + { 1145, 18, 33, 24, 3, -32 }, // 0x32 '2' + { 1220, 16, 33, 21, 3, -32 }, // 0x33 '3' + { 1286, 18, 33, 24, 3, -32 }, // 0x34 '4' + { 1361, 18, 33, 24, 3, -32 }, // 0x35 '5' + { 1436, 18, 33, 24, 3, -32 }, // 0x36 '6' + { 1511, 16, 33, 21, 3, -32 }, // 0x37 '7' + { 1577, 18, 33, 24, 3, -32 }, // 0x38 '8' + { 1652, 18, 33, 24, 3, -32 }, // 0x39 '9' + { 1727, 3, 14, 9, 3, -13 }, // 0x3A ':' + { 1733, 12, 32, 17, 2, -31 }, // 0x3B ';' + { 1781, 8, 33, 14, 3, -32 }, // 0x3C '<' + { 1814, 20, 11, 26, 3, -17 }, // 0x3D '=' + { 1842, 8, 33, 14, 3, -32 }, // 0x3E '>' + { 1875, 18, 33, 24, 3, -32 }, // 0x3F '?' + { 1950, 18, 33, 24, 3, -32 }, // 0x40 '@' + { 2025, 18, 33, 24, 3, -32 }, // 0x41 'A' + { 2100, 18, 33, 24, 3, -32 }, // 0x42 'B' + { 2175, 16, 33, 21, 3, -32 }, // 0x43 'C' + { 2241, 18, 33, 24, 3, -32 }, // 0x44 'D' + { 2316, 16, 33, 21, 3, -32 }, // 0x45 'E' + { 2382, 16, 33, 21, 3, -32 }, // 0x46 'F' + { 2448, 18, 33, 24, 3, -32 }, // 0x47 'G' + { 2523, 18, 33, 24, 3, -32 }, // 0x48 'H' + { 2598, 3, 33, 9, 3, -32 }, // 0x49 'I' + { 2611, 18, 33, 24, 3, -32 }, // 0x4A 'J' + { 2686, 18, 33, 24, 3, -32 }, // 0x4B 'K' + { 2761, 16, 33, 21, 3, -32 }, // 0x4C 'L' + { 2827, 26, 33, 32, 3, -32 }, // 0x4D 'M' + { 2935, 18, 33, 24, 3, -32 }, // 0x4E 'N' + { 3010, 18, 33, 24, 3, -32 }, // 0x4F 'O' + { 3085, 18, 33, 24, 3, -32 }, // 0x50 'P' + { 3160, 18, 33, 24, 3, -32 }, // 0x51 'Q' + { 3235, 18, 33, 24, 3, -32 }, // 0x52 'R' + { 3310, 18, 33, 24, 3, -32 }, // 0x53 'S' + { 3385, 22, 33, 28, 3, -32 }, // 0x54 'T' + { 3476, 18, 33, 24, 3, -32 }, // 0x55 'U' + { 3551, 18, 33, 24, 3, -32 }, // 0x56 'V' + { 3626, 26, 33, 32, 3, -32 }, // 0x57 'W' + { 3734, 18, 33, 24, 3, -32 }, // 0x58 'X' + { 3809, 18, 33, 24, 3, -32 }, // 0x59 'Y' + { 3884, 18, 33, 24, 3, -32 }, // 0x5A 'Z' + { 3959, 12, 33, 18, 3, -32 }, // 0x5B '[' + { 4009, 20, 32, 25, 3, -31 }, // 0x5C '\' + { 4089, 12, 33, 18, 3, -32 }, // 0x5D ']' + { 4139, 33, 8, 39, 3, -21 }, // 0x5E '^' + { 4172, 23, 3, 29, 3, -2 }, // 0x5F '_' + { 4181, 12, 32, 17, 2, -31 }, // 0x60 '`' + { 4229, 18, 33, 24, 3, -32 }, // 0x61 'a' + { 4304, 18, 33, 24, 3, -32 }, // 0x62 'b' + { 4379, 16, 33, 21, 3, -32 }, // 0x63 'c' + { 4445, 18, 33, 24, 3, -32 }, // 0x64 'd' + { 4520, 16, 33, 21, 3, -32 }, // 0x65 'e' + { 4586, 16, 33, 21, 3, -32 }, // 0x66 'f' + { 4652, 18, 33, 24, 3, -32 }, // 0x67 'g' + { 4727, 18, 33, 24, 3, -32 }, // 0x68 'h' + { 4802, 3, 33, 9, 3, -32 }, // 0x69 'i' + { 4815, 18, 33, 24, 3, -32 }, // 0x6A 'j' + { 4890, 18, 33, 24, 3, -32 }, // 0x6B 'k' + { 4965, 16, 33, 21, 3, -32 }, // 0x6C 'l' + { 5031, 26, 33, 32, 3, -32 }, // 0x6D 'm' + { 5139, 18, 33, 24, 3, -32 }, // 0x6E 'n' + { 5214, 18, 33, 24, 3, -32 }, // 0x6F 'o' + { 5289, 18, 33, 24, 3, -32 }, // 0x70 'p' + { 5364, 18, 33, 24, 3, -32 }, // 0x71 'q' + { 5439, 18, 33, 24, 3, -32 }, // 0x72 'r' + { 5514, 18, 33, 24, 3, -32 }, // 0x73 's' + { 5589, 22, 33, 28, 3, -32 }, // 0x74 't' + { 5680, 18, 33, 24, 3, -32 }, // 0x75 'u' + { 5755, 18, 33, 24, 3, -32 }, // 0x76 'v' + { 5830, 26, 33, 32, 3, -32 }, // 0x77 'w' + { 5938, 18, 33, 24, 3, -32 }, // 0x78 'x' + { 6013, 18, 33, 24, 3, -32 }, // 0x79 'y' + { 6088, 18, 33, 24, 3, -32 }, // 0x7A 'z' + { 6163, 17, 33, 23, 3, -32 }, // 0x7B '{' + { 6234, 3, 36, 9, 3, -35 }, // 0x7C '|' + { 6248, 17, 33, 23, 3, -32 }, // 0x7D '}' + { 6319, 12, 32, 17, 2, -31 } }; // 0x7E '~' const GFXfont Seven_Segment24pt7b PROGMEM = { (uint8_t *)Seven_Segment24pt7bBitmaps, (GFXglyph *)Seven_Segment24pt7bGlyphs, - 0x20, 0x7E, 49 }; + 0x20, 0x7E, 49 }; // Approx. 7039 bytes +#endif // ifndef FONTS_SEVEN_SEGMENT24PT7B_H diff --git a/src/src/Static/Fonts/angelina12pt7b.h b/src/src/Static/Fonts/angelina12pt7b.h index 08ca96964..96fd12680 100644 --- a/src/src/Static/Fonts/angelina12pt7b.h +++ b/src/src/Static/Fonts/angelina12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ANGELINA12PT7B_H +#define FONTS_ANGELINA12PT7B_H const uint8_t angelina12pt7bBitmaps[] PROGMEM = { 0x00, 0x5A, 0xAA, 0xA4, 0x10, 0x6F, 0x00, 0x00, 0x08, 0x01, 0x20, 0x04, 0x40, 0x3F, 0xE7, 0xA2, 0x10, 0x88, 0x01, 0x10, 0x07, 0xFF, 0xF8, 0x80, @@ -115,105 +117,106 @@ const uint8_t angelina12pt7bBitmaps[] PROGMEM = { 0xC0 }; const GFXglyph angelina12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' - { 1, 2, 14, 5, 1, -11 }, // 0x21 '!' - { 5, 3, 3, 5, 1, -9 }, // 0x22 '"' - { 7, 15, 14, 16, 0, -13 }, // 0x23 '#' - { 34, 6, 13, 6, 0, -14 }, // 0x24 '$' - { 44, 12, 14, 10, -1, -11 }, // 0x25 '%' - { 65, 10, 13, 12, 1, -10 }, // 0x26 '&' - { 82, 2, 3, 3, 0, -9 }, // 0x27 ''' - { 83, 5, 15, 5, 0, -12 }, // 0x28 '(' - { 93, 5, 15, 5, 0, -12 }, // 0x29 ')' - { 103, 1, 1, 29, 0, 0 }, // 0x2A '*' - { 104, 1, 1, 29, 0, 0 }, // 0x2B '+' - { 105, 3, 3, 5, 1, 0 }, // 0x2C ',' - { 107, 7, 2, 8, 1, -5 }, // 0x2D '-' - { 109, 1, 1, 3, 1, 0 }, // 0x2E '.' - { 110, 12, 14, 10, -1, -11 }, // 0x2F '/' - { 131, 9, 14, 10, 0, -11 }, // 0x30 '0' - { 147, 6, 14, 6, 0, -11 }, // 0x31 '1' - { 158, 10, 13, 10, 0, -10 }, // 0x32 '2' - { 175, 13, 14, 11, -1, -11 }, // 0x33 '3' - { 198, 11, 15, 10, -1, -11 }, // 0x34 '4' - { 219, 10, 14, 10, 0, -11 }, // 0x35 '5' - { 237, 9, 14, 9, 0, -11 }, // 0x36 '6' - { 253, 9, 14, 8, 0, -11 }, // 0x37 '7' - { 269, 11, 14, 10, -1, -11 }, // 0x38 '8' - { 289, 8, 15, 9, 0, -11 }, // 0x39 '9' - { 304, 2, 7, 3, 1, -5 }, // 0x3A ':' - { 306, 4, 8, 5, 0, -5 }, // 0x3B ';' - { 310, 1, 1, 29, 0, 0 }, // 0x3C '<' - { 311, 1, 1, 29, 0, 0 }, // 0x3D '=' - { 312, 1, 1, 29, 0, 0 }, // 0x3E '>' - { 313, 10, 14, 10, 0, -11 }, // 0x3F '?' - { 331, 10, 10, 12, 0, -9 }, // 0x40 '@' - { 344, 13, 16, 13, 0, -12 }, // 0x41 'A' - { 370, 14, 14, 13, -1, -11 }, // 0x42 'B' - { 395, 10, 15, 10, 0, -12 }, // 0x43 'C' - { 414, 14, 14, 14, -1, -11 }, // 0x44 'D' - { 439, 11, 14, 11, 0, -11 }, // 0x45 'E' - { 459, 11, 15, 7, -1, -12 }, // 0x46 'F' - { 480, 12, 16, 12, 0, -12 }, // 0x47 'G' - { 504, 15, 15, 15, -1, -12 }, // 0x48 'H' - { 533, 9, 15, 8, -1, -12 }, // 0x49 'I' - { 550, 13, 20, 8, -4, -13 }, // 0x4A 'J' - { 583, 11, 14, 9, -1, -11 }, // 0x4B 'K' - { 603, 12, 15, 10, -1, -12 }, // 0x4C 'L' - { 626, 20, 15, 19, -1, -12 }, // 0x4D 'M' - { 664, 13, 14, 13, 0, -11 }, // 0x4E 'N' - { 687, 10, 15, 11, 0, -12 }, // 0x4F 'O' - { 706, 14, 16, 13, -1, -13 }, // 0x50 'P' - { 734, 10, 15, 11, 0, -12 }, // 0x51 'Q' - { 753, 14, 16, 13, -1, -13 }, // 0x52 'R' - { 781, 10, 15, 10, -1, -12 }, // 0x53 'S' - { 800, 13, 15, 10, -1, -12 }, // 0x54 'T' - { 825, 12, 15, 12, 0, -12 }, // 0x55 'U' - { 848, 14, 15, 12, -1, -12 }, // 0x56 'V' - { 875, 18, 16, 18, -1, -13 }, // 0x57 'W' - { 911, 12, 16, 12, -1, -13 }, // 0x58 'X' - { 935, 13, 23, 10, -2, -13 }, // 0x59 'Y' - { 973, 14, 15, 11, -1, -12 }, // 0x5A 'Z' - { 1000, 7, 17, 8, 1, -14 }, // 0x5B '[' - { 1015, 1, 1, 29, 0, 0 }, // 0x5C '\' - { 1016, 7, 17, 8, 0, -14 }, // 0x5D ']' - { 1031, 1, 1, 29, 0, 0 }, // 0x5E '^' - { 1032, 1, 1, 29, 0, 0 }, // 0x5F '_' - { 1033, 4, 2, 7, 1, -10 }, // 0x60 '`' - { 1034, 9, 11, 8, 0, -8 }, // 0x61 'a' - { 1047, 10, 15, 10, 0, -12 }, // 0x62 'b' - { 1066, 7, 9, 8, 0, -7 }, // 0x63 'c' - { 1074, 10, 15, 10, 0, -12 }, // 0x64 'd' - { 1093, 7, 9, 7, 0, -7 }, // 0x65 'e' - { 1101, 7, 15, 6, 0, -12 }, // 0x66 'f' - { 1115, 8, 17, 9, 0, -8 }, // 0x67 'g' - { 1132, 8, 15, 8, 0, -12 }, // 0x68 'h' - { 1147, 3, 13, 4, 0, -10 }, // 0x69 'i' - { 1152, 9, 18, 4, -4, -9 }, // 0x6A 'j' - { 1173, 8, 15, 8, 0, -12 }, // 0x6B 'k' - { 1188, 3, 15, 4, 0, -12 }, // 0x6C 'l' - { 1194, 14, 8, 14, -1, -6 }, // 0x6D 'm' - { 1208, 9, 8, 8, 0, -6 }, // 0x6E 'n' - { 1217, 6, 9, 7, 0, -7 }, // 0x6F 'o' - { 1224, 7, 15, 8, 0, -7 }, // 0x70 'p' - { 1238, 9, 15, 8, -1, -7 }, // 0x71 'q' - { 1255, 5, 9, 6, 0, -7 }, // 0x72 'r' - { 1261, 6, 9, 6, 0, -7 }, // 0x73 's' - { 1268, 6, 11, 6, 0, -9 }, // 0x74 't' - { 1277, 8, 9, 8, 0, -7 }, // 0x75 'u' - { 1286, 9, 9, 7, 0, -7 }, // 0x76 'v' - { 1297, 11, 10, 12, 0, -8 }, // 0x77 'w' - { 1311, 9, 12, 9, 0, -9 }, // 0x78 'x' - { 1325, 9, 16, 8, -1, -8 }, // 0x79 'y' - { 1343, 9, 8, 9, 0, -6 }, // 0x7A 'z' - { 1352, 1, 1, 29, 0, 0 }, // 0x7B '{' - { 1353, 1, 1, 29, 0, 0 }, // 0x7C '|' - { 1354, 1, 1, 29, 0, 0 }, // 0x7D '}' - { 1355, 5, 2, 7, 1, -9 } }; // 0x7E '~' + { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' + { 1, 2, 14, 5, 1, -11 }, // 0x21 '!' + { 5, 3, 3, 5, 1, -9 }, // 0x22 '"' + { 7, 15, 14, 16, 0, -13 }, // 0x23 '#' + { 34, 6, 13, 6, 0, -14 }, // 0x24 '$' + { 44, 12, 14, 10, -1, -11 }, // 0x25 '%' + { 65, 10, 13, 12, 1, -10 }, // 0x26 '&' + { 82, 2, 3, 3, 0, -9 }, // 0x27 ''' + { 83, 5, 15, 5, 0, -12 }, // 0x28 '(' + { 93, 5, 15, 5, 0, -12 }, // 0x29 ')' + { 103, 1, 1, 29, 0, 0 }, // 0x2A '*' + { 104, 1, 1, 29, 0, 0 }, // 0x2B '+' + { 105, 3, 3, 5, 1, 0 }, // 0x2C ',' + { 107, 7, 2, 8, 1, -5 }, // 0x2D '-' + { 109, 1, 1, 3, 1, 0 }, // 0x2E '.' + { 110, 12, 14, 10, -1, -11 }, // 0x2F '/' + { 131, 9, 14, 10, 0, -11 }, // 0x30 '0' + { 147, 6, 14, 6, 0, -11 }, // 0x31 '1' + { 158, 10, 13, 10, 0, -10 }, // 0x32 '2' + { 175, 13, 14, 11, -1, -11 }, // 0x33 '3' + { 198, 11, 15, 10, -1, -11 }, // 0x34 '4' + { 219, 10, 14, 10, 0, -11 }, // 0x35 '5' + { 237, 9, 14, 9, 0, -11 }, // 0x36 '6' + { 253, 9, 14, 8, 0, -11 }, // 0x37 '7' + { 269, 11, 14, 10, -1, -11 }, // 0x38 '8' + { 289, 8, 15, 9, 0, -11 }, // 0x39 '9' + { 304, 2, 7, 3, 1, -5 }, // 0x3A ':' + { 306, 4, 8, 5, 0, -5 }, // 0x3B ';' + { 310, 1, 1, 29, 0, 0 }, // 0x3C '<' + { 311, 1, 1, 29, 0, 0 }, // 0x3D '=' + { 312, 1, 1, 29, 0, 0 }, // 0x3E '>' + { 313, 10, 14, 10, 0, -11 }, // 0x3F '?' + { 331, 10, 10, 12, 0, -9 }, // 0x40 '@' + { 344, 13, 16, 13, 0, -12 }, // 0x41 'A' + { 370, 14, 14, 13, -1, -11 }, // 0x42 'B' + { 395, 10, 15, 10, 0, -12 }, // 0x43 'C' + { 414, 14, 14, 14, -1, -11 }, // 0x44 'D' + { 439, 11, 14, 11, 0, -11 }, // 0x45 'E' + { 459, 11, 15, 7, -1, -12 }, // 0x46 'F' + { 480, 12, 16, 12, 0, -12 }, // 0x47 'G' + { 504, 15, 15, 15, -1, -12 }, // 0x48 'H' + { 533, 9, 15, 8, -1, -12 }, // 0x49 'I' + { 550, 13, 20, 8, -4, -13 }, // 0x4A 'J' + { 583, 11, 14, 9, -1, -11 }, // 0x4B 'K' + { 603, 12, 15, 10, -1, -12 }, // 0x4C 'L' + { 626, 20, 15, 19, -1, -12 }, // 0x4D 'M' + { 664, 13, 14, 13, 0, -11 }, // 0x4E 'N' + { 687, 10, 15, 11, 0, -12 }, // 0x4F 'O' + { 706, 14, 16, 13, -1, -13 }, // 0x50 'P' + { 734, 10, 15, 11, 0, -12 }, // 0x51 'Q' + { 753, 14, 16, 13, -1, -13 }, // 0x52 'R' + { 781, 10, 15, 10, -1, -12 }, // 0x53 'S' + { 800, 13, 15, 10, -1, -12 }, // 0x54 'T' + { 825, 12, 15, 12, 0, -12 }, // 0x55 'U' + { 848, 14, 15, 12, -1, -12 }, // 0x56 'V' + { 875, 18, 16, 18, -1, -13 }, // 0x57 'W' + { 911, 12, 16, 12, -1, -13 }, // 0x58 'X' + { 935, 13, 23, 10, -2, -13 }, // 0x59 'Y' + { 973, 14, 15, 11, -1, -12 }, // 0x5A 'Z' + { 1000, 7, 17, 8, 1, -14 }, // 0x5B '[' + { 1015, 1, 1, 29, 0, 0 }, // 0x5C '\' + { 1016, 7, 17, 8, 0, -14 }, // 0x5D ']' + { 1031, 1, 1, 29, 0, 0 }, // 0x5E '^' + { 1032, 1, 1, 29, 0, 0 }, // 0x5F '_' + { 1033, 4, 2, 7, 1, -10 }, // 0x60 '`' + { 1034, 9, 11, 8, 0, -8 }, // 0x61 'a' + { 1047, 10, 15, 10, 0, -12 }, // 0x62 'b' + { 1066, 7, 9, 8, 0, -7 }, // 0x63 'c' + { 1074, 10, 15, 10, 0, -12 }, // 0x64 'd' + { 1093, 7, 9, 7, 0, -7 }, // 0x65 'e' + { 1101, 7, 15, 6, 0, -12 }, // 0x66 'f' + { 1115, 8, 17, 9, 0, -8 }, // 0x67 'g' + { 1132, 8, 15, 8, 0, -12 }, // 0x68 'h' + { 1147, 3, 13, 4, 0, -10 }, // 0x69 'i' + { 1152, 9, 18, 4, -4, -9 }, // 0x6A 'j' + { 1173, 8, 15, 8, 0, -12 }, // 0x6B 'k' + { 1188, 3, 15, 4, 0, -12 }, // 0x6C 'l' + { 1194, 14, 8, 14, -1, -6 }, // 0x6D 'm' + { 1208, 9, 8, 8, 0, -6 }, // 0x6E 'n' + { 1217, 6, 9, 7, 0, -7 }, // 0x6F 'o' + { 1224, 7, 15, 8, 0, -7 }, // 0x70 'p' + { 1238, 9, 15, 8, -1, -7 }, // 0x71 'q' + { 1255, 5, 9, 6, 0, -7 }, // 0x72 'r' + { 1261, 6, 9, 6, 0, -7 }, // 0x73 's' + { 1268, 6, 11, 6, 0, -9 }, // 0x74 't' + { 1277, 8, 9, 8, 0, -7 }, // 0x75 'u' + { 1286, 9, 9, 7, 0, -7 }, // 0x76 'v' + { 1297, 11, 10, 12, 0, -8 }, // 0x77 'w' + { 1311, 9, 12, 9, 0, -9 }, // 0x78 'x' + { 1325, 9, 16, 8, -1, -8 }, // 0x79 'y' + { 1343, 9, 8, 9, 0, -6 }, // 0x7A 'z' + { 1352, 1, 1, 29, 0, 0 }, // 0x7B '{' + { 1353, 1, 1, 29, 0, 0 }, // 0x7C '|' + { 1354, 1, 1, 29, 0, 0 }, // 0x7D '}' + { 1355, 5, 2, 7, 1, -9 } }; // 0x7E '~' const GFXfont angelina12pt7b PROGMEM = { (uint8_t *)angelina12pt7bBitmaps, (GFXglyph *)angelina12pt7bGlyphs, - 0x20, 0x7E, 25 }; + 0x20, 0x7E, 25 }; // Approx. 2029 bytes +#endif // ifndef FONTS_ANGELINA12PT7B_H diff --git a/src/src/Static/Fonts/angelina8pt7b.h b/src/src/Static/Fonts/angelina8pt7b.h index eff391dac..732c59679 100644 --- a/src/src/Static/Fonts/angelina8pt7b.h +++ b/src/src/Static/Fonts/angelina8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_ANGELINA8PT7B_H +#define FONTS_ANGELINA8PT7B_H const uint8_t angelina8pt7bBitmaps[] PROGMEM = { 0x00, 0xAA, 0xA8, 0x80, 0x5C, 0x00, 0x81, 0x40, 0xA0, 0xFF, 0x54, 0x07, 0xFE, 0x40, 0xA0, 0x40, 0x00, 0x00, 0x23, 0x4C, 0xF3, 0xAE, 0x11, 0x1E, @@ -53,105 +55,106 @@ const uint8_t angelina8pt7bBitmaps[] PROGMEM = { 0x27, 0x00, 0x7C, 0x21, 0x08, 0xDF, 0x90, 0x00, 0x00, 0x00, 0xE0 }; const GFXglyph angelina8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' - { 1, 2, 9, 3, 1, -7 }, // 0x21 '!' - { 4, 2, 3, 3, 0, -6 }, // 0x22 '"' - { 5, 10, 10, 10, 0, -9 }, // 0x23 '#' - { 18, 4, 8, 4, 0, -9 }, // 0x24 '$' - { 22, 8, 9, 7, 0, -7 }, // 0x25 '%' - { 31, 7, 8, 8, 0, -6 }, // 0x26 '&' - { 38, 1, 3, 2, 0, -6 }, // 0x27 ''' - { 39, 3, 9, 4, 0, -7 }, // 0x28 '(' - { 43, 3, 9, 4, 0, -7 }, // 0x29 ')' - { 47, 1, 1, 20, 0, 0 }, // 0x2A '*' - { 48, 1, 1, 20, 0, 0 }, // 0x2B '+' - { 49, 2, 2, 3, 0, 0 }, // 0x2C ',' - { 50, 4, 1, 5, 0, -3 }, // 0x2D '-' - { 51, 1, 1, 2, 1, 0 }, // 0x2E '.' - { 52, 8, 9, 7, 0, -7 }, // 0x2F '/' - { 61, 6, 9, 6, 0, -7 }, // 0x30 '0' - { 68, 4, 9, 4, 0, -7 }, // 0x31 '1' - { 73, 7, 9, 7, 0, -7 }, // 0x32 '2' - { 81, 8, 9, 7, -1, -7 }, // 0x33 '3' - { 90, 7, 10, 7, 0, -7 }, // 0x34 '4' - { 99, 7, 9, 7, 0, -7 }, // 0x35 '5' - { 107, 6, 9, 6, 0, -7 }, // 0x36 '6' - { 114, 6, 9, 6, 0, -7 }, // 0x37 '7' - { 121, 7, 9, 6, 0, -7 }, // 0x38 '8' - { 129, 5, 10, 6, 0, -7 }, // 0x39 '9' - { 136, 1, 4, 2, 1, -3 }, // 0x3A ':' - { 137, 3, 5, 3, 0, -3 }, // 0x3B ';' - { 139, 1, 1, 20, 0, 0 }, // 0x3C '<' - { 140, 1, 1, 20, 0, 0 }, // 0x3D '=' - { 141, 1, 1, 20, 0, 0 }, // 0x3E '>' - { 142, 7, 9, 7, 0, -7 }, // 0x3F '?' - { 150, 7, 7, 8, 0, -6 }, // 0x40 '@' - { 157, 9, 10, 9, 0, -7 }, // 0x41 'A' - { 169, 9, 9, 9, 0, -7 }, // 0x42 'B' - { 180, 7, 10, 6, 0, -8 }, // 0x43 'C' - { 189, 9, 9, 9, 0, -7 }, // 0x44 'D' - { 200, 8, 9, 7, 0, -7 }, // 0x45 'E' - { 209, 7, 9, 5, 0, -7 }, // 0x46 'F' - { 217, 8, 11, 8, 0, -8 }, // 0x47 'G' - { 228, 10, 10, 10, -1, -8 }, // 0x48 'H' - { 241, 6, 10, 6, 0, -8 }, // 0x49 'I' - { 249, 9, 13, 5, -2, -8 }, // 0x4A 'J' - { 264, 7, 9, 6, 0, -7 }, // 0x4B 'K' - { 272, 8, 10, 7, 0, -8 }, // 0x4C 'L' - { 282, 14, 10, 13, -1, -8 }, // 0x4D 'M' - { 300, 8, 9, 9, 0, -7 }, // 0x4E 'N' - { 309, 7, 10, 7, 0, -8 }, // 0x4F 'O' - { 318, 9, 11, 9, 0, -9 }, // 0x50 'P' - { 331, 7, 10, 7, 0, -8 }, // 0x51 'Q' - { 340, 9, 10, 8, -1, -8 }, // 0x52 'R' - { 352, 7, 10, 6, 0, -8 }, // 0x53 'S' - { 361, 9, 10, 7, -1, -8 }, // 0x54 'T' - { 373, 8, 9, 8, 0, -7 }, // 0x55 'U' - { 382, 9, 9, 8, -1, -7 }, // 0x56 'V' - { 393, 12, 11, 12, 0, -9 }, // 0x57 'W' - { 410, 8, 10, 8, 0, -8 }, // 0x58 'X' - { 420, 8, 16, 7, 0, -9 }, // 0x59 'Y' - { 436, 9, 10, 7, 0, -8 }, // 0x5A 'Z' - { 448, 4, 11, 6, 1, -9 }, // 0x5B '[' - { 454, 1, 1, 20, 0, 0 }, // 0x5C '\' - { 455, 5, 11, 6, 1, -9 }, // 0x5D ']' - { 462, 1, 1, 20, 0, 0 }, // 0x5E '^' - { 463, 1, 1, 20, 0, 0 }, // 0x5F '_' - { 464, 3, 1, 5, 1, -6 }, // 0x60 '`' - { 465, 6, 7, 6, 0, -5 }, // 0x61 'a' - { 471, 6, 9, 7, 0, -7 }, // 0x62 'b' - { 478, 5, 7, 5, 0, -5 }, // 0x63 'c' - { 483, 6, 10, 7, 0, -8 }, // 0x64 'd' - { 491, 5, 7, 5, 0, -5 }, // 0x65 'e' - { 496, 4, 10, 4, 1, -8 }, // 0x66 'f' - { 501, 6, 11, 6, 0, -5 }, // 0x67 'g' - { 510, 5, 10, 5, 0, -8 }, // 0x68 'h' - { 517, 2, 8, 2, 0, -6 }, // 0x69 'i' - { 519, 6, 12, 3, -3, -6 }, // 0x6A 'j' - { 528, 5, 10, 5, 0, -8 }, // 0x6B 'k' - { 535, 2, 10, 3, 0, -8 }, // 0x6C 'l' - { 538, 9, 6, 9, 0, -4 }, // 0x6D 'm' - { 545, 6, 6, 5, 0, -4 }, // 0x6E 'n' - { 550, 4, 7, 5, 0, -5 }, // 0x6F 'o' - { 554, 5, 11, 5, 0, -5 }, // 0x70 'p' - { 561, 6, 11, 5, 0, -5 }, // 0x71 'q' - { 570, 4, 7, 4, 0, -5 }, // 0x72 'r' - { 574, 4, 7, 4, 0, -5 }, // 0x73 's' - { 578, 4, 8, 4, 0, -6 }, // 0x74 't' - { 582, 6, 6, 5, 0, -4 }, // 0x75 'u' - { 587, 6, 6, 5, 0, -4 }, // 0x76 'v' - { 592, 7, 7, 8, 0, -5 }, // 0x77 'w' - { 599, 6, 7, 6, 0, -5 }, // 0x78 'x' - { 605, 6, 11, 5, -1, -5 }, // 0x79 'y' - { 614, 6, 6, 6, 0, -4 }, // 0x7A 'z' - { 619, 1, 1, 20, 0, 0 }, // 0x7B '{' - { 620, 1, 1, 20, 0, 0 }, // 0x7C '|' - { 621, 1, 1, 20, 0, 0 }, // 0x7D '}' - { 622, 3, 1, 5, 1, -5 } }; // 0x7E '~' + { 0, 1, 1, 4, 0, 0 }, // 0x20 ' ' + { 1, 2, 9, 3, 1, -7 }, // 0x21 '!' + { 4, 2, 3, 3, 0, -6 }, // 0x22 '"' + { 5, 10, 10, 10, 0, -9 }, // 0x23 '#' + { 18, 4, 8, 4, 0, -9 }, // 0x24 '$' + { 22, 8, 9, 7, 0, -7 }, // 0x25 '%' + { 31, 7, 8, 8, 0, -6 }, // 0x26 '&' + { 38, 1, 3, 2, 0, -6 }, // 0x27 ''' + { 39, 3, 9, 4, 0, -7 }, // 0x28 '(' + { 43, 3, 9, 4, 0, -7 }, // 0x29 ')' + { 47, 1, 1, 20, 0, 0 }, // 0x2A '*' + { 48, 1, 1, 20, 0, 0 }, // 0x2B '+' + { 49, 2, 2, 3, 0, 0 }, // 0x2C ',' + { 50, 4, 1, 5, 0, -3 }, // 0x2D '-' + { 51, 1, 1, 2, 1, 0 }, // 0x2E '.' + { 52, 8, 9, 7, 0, -7 }, // 0x2F '/' + { 61, 6, 9, 6, 0, -7 }, // 0x30 '0' + { 68, 4, 9, 4, 0, -7 }, // 0x31 '1' + { 73, 7, 9, 7, 0, -7 }, // 0x32 '2' + { 81, 8, 9, 7, -1, -7 }, // 0x33 '3' + { 90, 7, 10, 7, 0, -7 }, // 0x34 '4' + { 99, 7, 9, 7, 0, -7 }, // 0x35 '5' + { 107, 6, 9, 6, 0, -7 }, // 0x36 '6' + { 114, 6, 9, 6, 0, -7 }, // 0x37 '7' + { 121, 7, 9, 6, 0, -7 }, // 0x38 '8' + { 129, 5, 10, 6, 0, -7 }, // 0x39 '9' + { 136, 1, 4, 2, 1, -3 }, // 0x3A ':' + { 137, 3, 5, 3, 0, -3 }, // 0x3B ';' + { 139, 1, 1, 20, 0, 0 }, // 0x3C '<' + { 140, 1, 1, 20, 0, 0 }, // 0x3D '=' + { 141, 1, 1, 20, 0, 0 }, // 0x3E '>' + { 142, 7, 9, 7, 0, -7 }, // 0x3F '?' + { 150, 7, 7, 8, 0, -6 }, // 0x40 '@' + { 157, 9, 10, 9, 0, -7 }, // 0x41 'A' + { 169, 9, 9, 9, 0, -7 }, // 0x42 'B' + { 180, 7, 10, 6, 0, -8 }, // 0x43 'C' + { 189, 9, 9, 9, 0, -7 }, // 0x44 'D' + { 200, 8, 9, 7, 0, -7 }, // 0x45 'E' + { 209, 7, 9, 5, 0, -7 }, // 0x46 'F' + { 217, 8, 11, 8, 0, -8 }, // 0x47 'G' + { 228, 10, 10, 10, -1, -8 }, // 0x48 'H' + { 241, 6, 10, 6, 0, -8 }, // 0x49 'I' + { 249, 9, 13, 5, -2, -8 }, // 0x4A 'J' + { 264, 7, 9, 6, 0, -7 }, // 0x4B 'K' + { 272, 8, 10, 7, 0, -8 }, // 0x4C 'L' + { 282, 14, 10, 13, -1, -8 }, // 0x4D 'M' + { 300, 8, 9, 9, 0, -7 }, // 0x4E 'N' + { 309, 7, 10, 7, 0, -8 }, // 0x4F 'O' + { 318, 9, 11, 9, 0, -9 }, // 0x50 'P' + { 331, 7, 10, 7, 0, -8 }, // 0x51 'Q' + { 340, 9, 10, 8, -1, -8 }, // 0x52 'R' + { 352, 7, 10, 6, 0, -8 }, // 0x53 'S' + { 361, 9, 10, 7, -1, -8 }, // 0x54 'T' + { 373, 8, 9, 8, 0, -7 }, // 0x55 'U' + { 382, 9, 9, 8, -1, -7 }, // 0x56 'V' + { 393, 12, 11, 12, 0, -9 }, // 0x57 'W' + { 410, 8, 10, 8, 0, -8 }, // 0x58 'X' + { 420, 8, 16, 7, 0, -9 }, // 0x59 'Y' + { 436, 9, 10, 7, 0, -8 }, // 0x5A 'Z' + { 448, 4, 11, 6, 1, -9 }, // 0x5B '[' + { 454, 1, 1, 20, 0, 0 }, // 0x5C '\' + { 455, 5, 11, 6, 1, -9 }, // 0x5D ']' + { 462, 1, 1, 20, 0, 0 }, // 0x5E '^' + { 463, 1, 1, 20, 0, 0 }, // 0x5F '_' + { 464, 3, 1, 5, 1, -6 }, // 0x60 '`' + { 465, 6, 7, 6, 0, -5 }, // 0x61 'a' + { 471, 6, 9, 7, 0, -7 }, // 0x62 'b' + { 478, 5, 7, 5, 0, -5 }, // 0x63 'c' + { 483, 6, 10, 7, 0, -8 }, // 0x64 'd' + { 491, 5, 7, 5, 0, -5 }, // 0x65 'e' + { 496, 4, 10, 4, 1, -8 }, // 0x66 'f' + { 501, 6, 11, 6, 0, -5 }, // 0x67 'g' + { 510, 5, 10, 5, 0, -8 }, // 0x68 'h' + { 517, 2, 8, 2, 0, -6 }, // 0x69 'i' + { 519, 6, 12, 3, -3, -6 }, // 0x6A 'j' + { 528, 5, 10, 5, 0, -8 }, // 0x6B 'k' + { 535, 2, 10, 3, 0, -8 }, // 0x6C 'l' + { 538, 9, 6, 9, 0, -4 }, // 0x6D 'm' + { 545, 6, 6, 5, 0, -4 }, // 0x6E 'n' + { 550, 4, 7, 5, 0, -5 }, // 0x6F 'o' + { 554, 5, 11, 5, 0, -5 }, // 0x70 'p' + { 561, 6, 11, 5, 0, -5 }, // 0x71 'q' + { 570, 4, 7, 4, 0, -5 }, // 0x72 'r' + { 574, 4, 7, 4, 0, -5 }, // 0x73 's' + { 578, 4, 8, 4, 0, -6 }, // 0x74 't' + { 582, 6, 6, 5, 0, -4 }, // 0x75 'u' + { 587, 6, 6, 5, 0, -4 }, // 0x76 'v' + { 592, 7, 7, 8, 0, -5 }, // 0x77 'w' + { 599, 6, 7, 6, 0, -5 }, // 0x78 'x' + { 605, 6, 11, 5, -1, -5 }, // 0x79 'y' + { 614, 6, 6, 6, 0, -4 }, // 0x7A 'z' + { 619, 1, 1, 20, 0, 0 }, // 0x7B '{' + { 620, 1, 1, 20, 0, 0 }, // 0x7C '|' + { 621, 1, 1, 20, 0, 0 }, // 0x7D '}' + { 622, 3, 1, 5, 1, -5 } }; // 0x7E '~' const GFXfont angelina8pt7b PROGMEM = { (uint8_t *)angelina8pt7bBitmaps, (GFXglyph *)angelina8pt7bGlyphs, - 0x20, 0x7E, 16 }; + 0x20, 0x7E, 16 }; // Approx. 1295 bytes +#endif // ifndef FONTS_ANGELINA8PT7B_H diff --git a/src/src/Static/Fonts/unispace12pt7b.h b/src/src/Static/Fonts/unispace12pt7b.h index 738d830d5..f5b4256d7 100644 --- a/src/src/Static/Fonts/unispace12pt7b.h +++ b/src/src/Static/Fonts/unispace12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_UNISPACE12PT7B_H +#define FONTS_UNISPACE12PT7B_H const uint8_t unispace12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0x1C, 0x70, 0x71, 0xC1, @@ -314,105 +316,106 @@ const uint8_t unispace12pt7bBitmaps[] PROGMEM = { 0xEE, 0x1E, 0x00 }; const GFXglyph unispace12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' - { 1, 4, 24, 18, 7, -23 }, // 0x21 '!' - { 13, 8, 7, 18, 5, -24 }, // 0x22 '"' - { 20, 14, 24, 18, 2, -23 }, // 0x23 '#' - { 62, 17, 24, 19, 1, -23 }, // 0x24 '$' - { 113, 16, 24, 18, 1, -23 }, // 0x25 '%' - { 161, 17, 24, 18, 1, -23 }, // 0x26 '&' - { 212, 3, 7, 18, 8, -24 }, // 0x27 ''' - { 215, 9, 35, 18, 4, -27 }, // 0x28 '(' - { 255, 9, 35, 18, 5, -27 }, // 0x29 ')' - { 295, 13, 13, 18, 3, -23 }, // 0x2A '*' - { 317, 15, 12, 18, 2, -18 }, // 0x2B '+' - { 340, 4, 7, 18, 7, -1 }, // 0x2C ',' - { 344, 16, 2, 18, 1, -11 }, // 0x2D '-' - { 348, 4, 3, 18, 7, -2 }, // 0x2E '.' - { 350, 16, 24, 18, 1, -23 }, // 0x2F '/' - { 398, 17, 24, 19, 1, -23 }, // 0x30 '0' - { 449, 16, 24, 18, 1, -23 }, // 0x31 '1' - { 497, 16, 24, 18, 1, -23 }, // 0x32 '2' - { 545, 16, 24, 18, 1, -23 }, // 0x33 '3' - { 593, 17, 24, 19, 1, -23 }, // 0x34 '4' - { 644, 16, 24, 18, 1, -23 }, // 0x35 '5' - { 692, 16, 24, 18, 1, -23 }, // 0x36 '6' - { 740, 16, 24, 18, 1, -23 }, // 0x37 '7' - { 788, 17, 24, 19, 1, -23 }, // 0x38 '8' - { 839, 16, 24, 18, 1, -23 }, // 0x39 '9' - { 887, 4, 14, 18, 7, -13 }, // 0x3A ':' - { 894, 4, 19, 18, 7, -13 }, // 0x3B ';' - { 904, 10, 18, 18, 4, -21 }, // 0x3C '<' - { 927, 12, 8, 18, 3, -16 }, // 0x3D '=' - { 939, 10, 18, 18, 4, -21 }, // 0x3E '>' - { 962, 16, 24, 18, 1, -23 }, // 0x3F '?' - { 1010, 16, 24, 19, 1, -23 }, // 0x40 '@' - { 1058, 16, 24, 18, 1, -23 }, // 0x41 'A' - { 1106, 16, 24, 18, 1, -23 }, // 0x42 'B' - { 1154, 15, 24, 18, 2, -23 }, // 0x43 'C' - { 1199, 16, 24, 18, 1, -23 }, // 0x44 'D' - { 1247, 15, 24, 18, 2, -23 }, // 0x45 'E' - { 1292, 15, 24, 18, 1, -23 }, // 0x46 'F' - { 1337, 16, 24, 18, 1, -23 }, // 0x47 'G' - { 1385, 16, 24, 18, 1, -23 }, // 0x48 'H' - { 1433, 16, 24, 18, 1, -23 }, // 0x49 'I' - { 1481, 15, 24, 19, 2, -23 }, // 0x4A 'J' - { 1526, 16, 24, 18, 1, -23 }, // 0x4B 'K' - { 1574, 16, 24, 18, 1, -23 }, // 0x4C 'L' - { 1622, 16, 24, 18, 1, -23 }, // 0x4D 'M' - { 1670, 16, 24, 18, 1, -23 }, // 0x4E 'N' - { 1718, 16, 24, 18, 1, -23 }, // 0x4F 'O' - { 1766, 16, 24, 18, 1, -23 }, // 0x50 'P' - { 1814, 16, 28, 18, 1, -23 }, // 0x51 'Q' - { 1870, 16, 24, 18, 1, -23 }, // 0x52 'R' - { 1918, 16, 24, 18, 1, -23 }, // 0x53 'S' - { 1966, 15, 24, 18, 1, -23 }, // 0x54 'T' - { 2011, 16, 24, 18, 1, -23 }, // 0x55 'U' - { 2059, 16, 24, 18, 1, -23 }, // 0x56 'V' - { 2107, 18, 24, 18, 0, -23 }, // 0x57 'W' - { 2161, 16, 24, 18, 1, -23 }, // 0x58 'X' - { 2209, 16, 24, 18, 1, -23 }, // 0x59 'Y' - { 2257, 16, 24, 18, 1, -23 }, // 0x5A 'Z' - { 2305, 9, 35, 18, 4, -27 }, // 0x5B '[' - { 2345, 16, 24, 18, 1, -23 }, // 0x5C '\' - { 2393, 9, 35, 18, 5, -27 }, // 0x5D ']' - { 2433, 18, 11, 18, 0, -23 }, // 0x5E '^' - { 2458, 18, 2, 18, 0, 6 }, // 0x5F '_' - { 2463, 7, 3, 18, 6, -22 }, // 0x60 '`' - { 2466, 16, 19, 18, 1, -18 }, // 0x61 'a' - { 2504, 16, 25, 18, 1, -24 }, // 0x62 'b' - { 2554, 15, 19, 18, 1, -18 }, // 0x63 'c' - { 2590, 16, 25, 18, 1, -24 }, // 0x64 'd' - { 2640, 17, 19, 19, 1, -18 }, // 0x65 'e' - { 2681, 16, 25, 18, 1, -24 }, // 0x66 'f' - { 2731, 16, 26, 18, 1, -18 }, // 0x67 'g' - { 2783, 16, 25, 18, 1, -24 }, // 0x68 'h' - { 2833, 16, 25, 18, 1, -24 }, // 0x69 'i' - { 2883, 11, 32, 18, 4, -24 }, // 0x6A 'j' - { 2927, 16, 25, 18, 1, -24 }, // 0x6B 'k' - { 2977, 16, 25, 18, 1, -24 }, // 0x6C 'l' - { 3027, 16, 19, 18, 1, -18 }, // 0x6D 'm' - { 3065, 16, 19, 18, 1, -18 }, // 0x6E 'n' - { 3103, 16, 19, 18, 1, -18 }, // 0x6F 'o' - { 3141, 16, 26, 18, 1, -18 }, // 0x70 'p' - { 3193, 16, 26, 18, 1, -18 }, // 0x71 'q' - { 3245, 15, 19, 18, 2, -18 }, // 0x72 'r' - { 3281, 16, 19, 18, 1, -18 }, // 0x73 's' - { 3319, 16, 24, 18, 1, -23 }, // 0x74 't' - { 3367, 16, 19, 18, 1, -18 }, // 0x75 'u' - { 3405, 17, 19, 18, 1, -18 }, // 0x76 'v' - { 3446, 18, 19, 18, 0, -18 }, // 0x77 'w' - { 3489, 16, 19, 18, 1, -18 }, // 0x78 'x' - { 3527, 18, 26, 18, 0, -18 }, // 0x79 'y' - { 3586, 15, 19, 18, 2, -18 }, // 0x7A 'z' - { 3622, 12, 35, 18, 3, -27 }, // 0x7B '{' - { 3675, 3, 35, 18, 8, -27 }, // 0x7C '|' - { 3689, 11, 35, 18, 3, -27 }, // 0x7D '}' - { 3738, 13, 5, 19, 3, -14 } }; // 0x7E '~' + { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' + { 1, 4, 24, 18, 7, -23 }, // 0x21 '!' + { 13, 8, 7, 18, 5, -24 }, // 0x22 '"' + { 20, 14, 24, 18, 2, -23 }, // 0x23 '#' + { 62, 17, 24, 19, 1, -23 }, // 0x24 '$' + { 113, 16, 24, 18, 1, -23 }, // 0x25 '%' + { 161, 17, 24, 18, 1, -23 }, // 0x26 '&' + { 212, 3, 7, 18, 8, -24 }, // 0x27 ''' + { 215, 9, 35, 18, 4, -27 }, // 0x28 '(' + { 255, 9, 35, 18, 5, -27 }, // 0x29 ')' + { 295, 13, 13, 18, 3, -23 }, // 0x2A '*' + { 317, 15, 12, 18, 2, -18 }, // 0x2B '+' + { 340, 4, 7, 18, 7, -1 }, // 0x2C ',' + { 344, 16, 2, 18, 1, -11 }, // 0x2D '-' + { 348, 4, 3, 18, 7, -2 }, // 0x2E '.' + { 350, 16, 24, 18, 1, -23 }, // 0x2F '/' + { 398, 17, 24, 19, 1, -23 }, // 0x30 '0' + { 449, 16, 24, 18, 1, -23 }, // 0x31 '1' + { 497, 16, 24, 18, 1, -23 }, // 0x32 '2' + { 545, 16, 24, 18, 1, -23 }, // 0x33 '3' + { 593, 17, 24, 19, 1, -23 }, // 0x34 '4' + { 644, 16, 24, 18, 1, -23 }, // 0x35 '5' + { 692, 16, 24, 18, 1, -23 }, // 0x36 '6' + { 740, 16, 24, 18, 1, -23 }, // 0x37 '7' + { 788, 17, 24, 19, 1, -23 }, // 0x38 '8' + { 839, 16, 24, 18, 1, -23 }, // 0x39 '9' + { 887, 4, 14, 18, 7, -13 }, // 0x3A ':' + { 894, 4, 19, 18, 7, -13 }, // 0x3B ';' + { 904, 10, 18, 18, 4, -21 }, // 0x3C '<' + { 927, 12, 8, 18, 3, -16 }, // 0x3D '=' + { 939, 10, 18, 18, 4, -21 }, // 0x3E '>' + { 962, 16, 24, 18, 1, -23 }, // 0x3F '?' + { 1010, 16, 24, 19, 1, -23 }, // 0x40 '@' + { 1058, 16, 24, 18, 1, -23 }, // 0x41 'A' + { 1106, 16, 24, 18, 1, -23 }, // 0x42 'B' + { 1154, 15, 24, 18, 2, -23 }, // 0x43 'C' + { 1199, 16, 24, 18, 1, -23 }, // 0x44 'D' + { 1247, 15, 24, 18, 2, -23 }, // 0x45 'E' + { 1292, 15, 24, 18, 1, -23 }, // 0x46 'F' + { 1337, 16, 24, 18, 1, -23 }, // 0x47 'G' + { 1385, 16, 24, 18, 1, -23 }, // 0x48 'H' + { 1433, 16, 24, 18, 1, -23 }, // 0x49 'I' + { 1481, 15, 24, 19, 2, -23 }, // 0x4A 'J' + { 1526, 16, 24, 18, 1, -23 }, // 0x4B 'K' + { 1574, 16, 24, 18, 1, -23 }, // 0x4C 'L' + { 1622, 16, 24, 18, 1, -23 }, // 0x4D 'M' + { 1670, 16, 24, 18, 1, -23 }, // 0x4E 'N' + { 1718, 16, 24, 18, 1, -23 }, // 0x4F 'O' + { 1766, 16, 24, 18, 1, -23 }, // 0x50 'P' + { 1814, 16, 28, 18, 1, -23 }, // 0x51 'Q' + { 1870, 16, 24, 18, 1, -23 }, // 0x52 'R' + { 1918, 16, 24, 18, 1, -23 }, // 0x53 'S' + { 1966, 15, 24, 18, 1, -23 }, // 0x54 'T' + { 2011, 16, 24, 18, 1, -23 }, // 0x55 'U' + { 2059, 16, 24, 18, 1, -23 }, // 0x56 'V' + { 2107, 18, 24, 18, 0, -23 }, // 0x57 'W' + { 2161, 16, 24, 18, 1, -23 }, // 0x58 'X' + { 2209, 16, 24, 18, 1, -23 }, // 0x59 'Y' + { 2257, 16, 24, 18, 1, -23 }, // 0x5A 'Z' + { 2305, 9, 35, 18, 4, -27 }, // 0x5B '[' + { 2345, 16, 24, 18, 1, -23 }, // 0x5C '\' + { 2393, 9, 35, 18, 5, -27 }, // 0x5D ']' + { 2433, 18, 11, 18, 0, -23 }, // 0x5E '^' + { 2458, 18, 2, 18, 0, 6 }, // 0x5F '_' + { 2463, 7, 3, 18, 6, -22 }, // 0x60 '`' + { 2466, 16, 19, 18, 1, -18 }, // 0x61 'a' + { 2504, 16, 25, 18, 1, -24 }, // 0x62 'b' + { 2554, 15, 19, 18, 1, -18 }, // 0x63 'c' + { 2590, 16, 25, 18, 1, -24 }, // 0x64 'd' + { 2640, 17, 19, 19, 1, -18 }, // 0x65 'e' + { 2681, 16, 25, 18, 1, -24 }, // 0x66 'f' + { 2731, 16, 26, 18, 1, -18 }, // 0x67 'g' + { 2783, 16, 25, 18, 1, -24 }, // 0x68 'h' + { 2833, 16, 25, 18, 1, -24 }, // 0x69 'i' + { 2883, 11, 32, 18, 4, -24 }, // 0x6A 'j' + { 2927, 16, 25, 18, 1, -24 }, // 0x6B 'k' + { 2977, 16, 25, 18, 1, -24 }, // 0x6C 'l' + { 3027, 16, 19, 18, 1, -18 }, // 0x6D 'm' + { 3065, 16, 19, 18, 1, -18 }, // 0x6E 'n' + { 3103, 16, 19, 18, 1, -18 }, // 0x6F 'o' + { 3141, 16, 26, 18, 1, -18 }, // 0x70 'p' + { 3193, 16, 26, 18, 1, -18 }, // 0x71 'q' + { 3245, 15, 19, 18, 2, -18 }, // 0x72 'r' + { 3281, 16, 19, 18, 1, -18 }, // 0x73 's' + { 3319, 16, 24, 18, 1, -23 }, // 0x74 't' + { 3367, 16, 19, 18, 1, -18 }, // 0x75 'u' + { 3405, 17, 19, 18, 1, -18 }, // 0x76 'v' + { 3446, 18, 19, 18, 0, -18 }, // 0x77 'w' + { 3489, 16, 19, 18, 1, -18 }, // 0x78 'x' + { 3527, 18, 26, 18, 0, -18 }, // 0x79 'y' + { 3586, 15, 19, 18, 2, -18 }, // 0x7A 'z' + { 3622, 12, 35, 18, 3, -27 }, // 0x7B '{' + { 3675, 3, 35, 18, 8, -27 }, // 0x7C '|' + { 3689, 11, 35, 18, 3, -27 }, // 0x7D '}' + { 3738, 13, 5, 19, 3, -14 } }; // 0x7E '~' const GFXfont unispace12pt7b PROGMEM = { (uint8_t *)unispace12pt7bBitmaps, (GFXglyph *)unispace12pt7bGlyphs, - 0x20, 0x7E, 36 }; + 0x20, 0x7E, 36 }; // Approx. 4419 bytes +#endif // ifndef FONTS_UNISPACE12PT7B_H diff --git a/src/src/Static/Fonts/unispace8pt7b.h b/src/src/Static/Fonts/unispace8pt7b.h index f7257567d..e12aff7b7 100644 --- a/src/src/Static/Fonts/unispace8pt7b.h +++ b/src/src/Static/Fonts/unispace8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_UNISPACE8PT7B_H +#define FONTS_UNISPACE8PT7B_H const uint8_t unispace8pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x8C, 0x63, 0x18, 0x80, 0x21, 0x10, 0x88, 0x44, 0x22, 0x17, 0xFC, 0x84, 0x42, 0x21, 0x10, 0x88, 0x5F, @@ -143,105 +145,106 @@ const uint8_t unispace8pt7bBitmaps[] PROGMEM = { 0x18, 0x30, 0x60, 0xC1, 0x83, 0x0C, 0x70, 0x71, 0x99, 0x8E }; const GFXglyph unispace8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 12, 0, 0 }, // 0x20 ' ' - { 1, 3, 16, 12, 5, -15 }, // 0x21 '!' - { 7, 5, 5, 12, 3, -16 }, // 0x22 '"' - { 11, 9, 16, 12, 1, -15 }, // 0x23 '#' - { 29, 12, 16, 13, 0, -15 }, // 0x24 '$' - { 53, 10, 16, 12, 1, -15 }, // 0x25 '%' - { 73, 9, 16, 12, 1, -15 }, // 0x26 '&' - { 91, 1, 5, 12, 6, -16 }, // 0x27 ''' - { 92, 6, 24, 12, 3, -18 }, // 0x28 '(' - { 110, 6, 24, 12, 3, -18 }, // 0x29 ')' - { 128, 8, 9, 12, 2, -15 }, // 0x2A '*' - { 137, 9, 8, 12, 2, -12 }, // 0x2B '+' - { 146, 2, 5, 12, 5, 0 }, // 0x2C ',' - { 148, 10, 1, 12, 1, -7 }, // 0x2D '-' - { 150, 3, 1, 12, 5, 0 }, // 0x2E '.' - { 151, 10, 16, 12, 1, -15 }, // 0x2F '/' - { 171, 11, 16, 13, 1, -15 }, // 0x30 '0' - { 193, 11, 16, 12, 1, -15 }, // 0x31 '1' - { 215, 11, 16, 13, 1, -15 }, // 0x32 '2' - { 237, 11, 16, 12, 0, -15 }, // 0x33 '3' - { 259, 12, 16, 12, 0, -15 }, // 0x34 '4' - { 283, 11, 16, 13, 1, -15 }, // 0x35 '5' - { 305, 11, 16, 13, 1, -15 }, // 0x36 '6' - { 327, 11, 16, 12, 1, -15 }, // 0x37 '7' - { 349, 11, 16, 12, 1, -15 }, // 0x38 '8' - { 371, 11, 16, 13, 1, -15 }, // 0x39 '9' - { 393, 3, 9, 12, 5, -8 }, // 0x3A ':' - { 397, 3, 13, 12, 5, -8 }, // 0x3B ';' - { 402, 7, 12, 12, 3, -13 }, // 0x3C '<' - { 413, 8, 5, 12, 2, -10 }, // 0x3D '=' - { 418, 8, 12, 12, 2, -13 }, // 0x3E '>' - { 430, 11, 16, 12, 0, -15 }, // 0x3F '?' - { 452, 10, 16, 12, 1, -15 }, // 0x40 '@' - { 472, 10, 16, 12, 1, -15 }, // 0x41 'A' - { 492, 11, 16, 12, 0, -15 }, // 0x42 'B' - { 514, 10, 16, 12, 1, -15 }, // 0x43 'C' - { 534, 11, 16, 13, 1, -15 }, // 0x44 'D' - { 556, 10, 16, 12, 1, -15 }, // 0x45 'E' - { 576, 11, 16, 12, 1, -15 }, // 0x46 'F' - { 598, 11, 16, 13, 1, -15 }, // 0x47 'G' - { 620, 11, 16, 13, 1, -15 }, // 0x48 'H' - { 642, 11, 16, 12, 1, -15 }, // 0x49 'I' - { 664, 11, 16, 12, 0, -15 }, // 0x4A 'J' - { 686, 11, 16, 12, 1, -15 }, // 0x4B 'K' - { 708, 11, 16, 12, 1, -15 }, // 0x4C 'L' - { 730, 9, 16, 11, 1, -15 }, // 0x4D 'M' - { 748, 10, 16, 12, 1, -15 }, // 0x4E 'N' - { 768, 11, 16, 13, 1, -15 }, // 0x4F 'O' - { 790, 11, 16, 13, 1, -15 }, // 0x50 'P' - { 812, 11, 18, 13, 1, -15 }, // 0x51 'Q' - { 837, 11, 16, 13, 1, -15 }, // 0x52 'R' - { 859, 11, 16, 13, 1, -15 }, // 0x53 'S' - { 881, 11, 16, 12, 1, -15 }, // 0x54 'T' - { 903, 11, 16, 13, 1, -15 }, // 0x55 'U' - { 925, 10, 16, 12, 1, -15 }, // 0x56 'V' - { 945, 12, 16, 12, 0, -15 }, // 0x57 'W' - { 969, 10, 16, 12, 1, -15 }, // 0x58 'X' - { 989, 11, 16, 12, 0, -15 }, // 0x59 'Y' - { 1011, 10, 16, 12, 1, -15 }, // 0x5A 'Z' - { 1031, 6, 24, 12, 3, -18 }, // 0x5B '[' - { 1049, 10, 16, 12, 1, -15 }, // 0x5C '\' - { 1069, 6, 24, 12, 3, -18 }, // 0x5D ']' - { 1087, 12, 7, 12, 0, -15 }, // 0x5E '^' - { 1098, 12, 1, 12, 0, 4 }, // 0x5F '_' - { 1100, 4, 3, 12, 4, -15 }, // 0x60 '`' - { 1102, 11, 13, 13, 1, -12 }, // 0x61 'a' - { 1120, 11, 17, 13, 1, -16 }, // 0x62 'b' - { 1144, 10, 13, 12, 1, -12 }, // 0x63 'c' - { 1161, 11, 17, 13, 1, -16 }, // 0x64 'd' - { 1185, 11, 13, 13, 1, -12 }, // 0x65 'e' - { 1203, 11, 17, 12, 1, -16 }, // 0x66 'f' - { 1227, 11, 18, 13, 1, -12 }, // 0x67 'g' - { 1252, 11, 17, 13, 1, -16 }, // 0x68 'h' - { 1276, 11, 17, 12, 1, -16 }, // 0x69 'i' - { 1300, 8, 22, 12, 2, -16 }, // 0x6A 'j' - { 1322, 11, 17, 12, 1, -16 }, // 0x6B 'k' - { 1346, 11, 17, 12, 0, -16 }, // 0x6C 'l' - { 1370, 12, 13, 13, 0, -12 }, // 0x6D 'm' - { 1390, 11, 13, 13, 1, -12 }, // 0x6E 'n' - { 1408, 11, 13, 13, 1, -12 }, // 0x6F 'o' - { 1426, 11, 18, 13, 1, -12 }, // 0x70 'p' - { 1451, 11, 18, 13, 1, -12 }, // 0x71 'q' - { 1476, 10, 13, 12, 1, -12 }, // 0x72 'r' - { 1493, 11, 13, 12, 1, -12 }, // 0x73 's' - { 1511, 10, 16, 12, 1, -15 }, // 0x74 't' - { 1531, 11, 13, 13, 1, -12 }, // 0x75 'u' - { 1549, 12, 13, 12, 0, -12 }, // 0x76 'v' - { 1569, 12, 13, 12, 0, -12 }, // 0x77 'w' - { 1589, 11, 13, 12, 1, -12 }, // 0x78 'x' - { 1607, 12, 18, 12, 0, -12 }, // 0x79 'y' - { 1634, 10, 13, 12, 1, -12 }, // 0x7A 'z' - { 1651, 8, 24, 12, 2, -18 }, // 0x7B '{' - { 1675, 1, 24, 12, 6, -18 }, // 0x7C '|' - { 1678, 7, 24, 12, 3, -18 }, // 0x7D '}' - { 1699, 8, 3, 12, 2, -9 } }; // 0x7E '~' + { 0, 1, 1, 12, 0, 0 }, // 0x20 ' ' + { 1, 3, 16, 12, 5, -15 }, // 0x21 '!' + { 7, 5, 5, 12, 3, -16 }, // 0x22 '"' + { 11, 9, 16, 12, 1, -15 }, // 0x23 '#' + { 29, 12, 16, 13, 0, -15 }, // 0x24 '$' + { 53, 10, 16, 12, 1, -15 }, // 0x25 '%' + { 73, 9, 16, 12, 1, -15 }, // 0x26 '&' + { 91, 1, 5, 12, 6, -16 }, // 0x27 ''' + { 92, 6, 24, 12, 3, -18 }, // 0x28 '(' + { 110, 6, 24, 12, 3, -18 }, // 0x29 ')' + { 128, 8, 9, 12, 2, -15 }, // 0x2A '*' + { 137, 9, 8, 12, 2, -12 }, // 0x2B '+' + { 146, 2, 5, 12, 5, 0 }, // 0x2C ',' + { 148, 10, 1, 12, 1, -7 }, // 0x2D '-' + { 150, 3, 1, 12, 5, 0 }, // 0x2E '.' + { 151, 10, 16, 12, 1, -15 }, // 0x2F '/' + { 171, 11, 16, 13, 1, -15 }, // 0x30 '0' + { 193, 11, 16, 12, 1, -15 }, // 0x31 '1' + { 215, 11, 16, 13, 1, -15 }, // 0x32 '2' + { 237, 11, 16, 12, 0, -15 }, // 0x33 '3' + { 259, 12, 16, 12, 0, -15 }, // 0x34 '4' + { 283, 11, 16, 13, 1, -15 }, // 0x35 '5' + { 305, 11, 16, 13, 1, -15 }, // 0x36 '6' + { 327, 11, 16, 12, 1, -15 }, // 0x37 '7' + { 349, 11, 16, 12, 1, -15 }, // 0x38 '8' + { 371, 11, 16, 13, 1, -15 }, // 0x39 '9' + { 393, 3, 9, 12, 5, -8 }, // 0x3A ':' + { 397, 3, 13, 12, 5, -8 }, // 0x3B ';' + { 402, 7, 12, 12, 3, -13 }, // 0x3C '<' + { 413, 8, 5, 12, 2, -10 }, // 0x3D '=' + { 418, 8, 12, 12, 2, -13 }, // 0x3E '>' + { 430, 11, 16, 12, 0, -15 }, // 0x3F '?' + { 452, 10, 16, 12, 1, -15 }, // 0x40 '@' + { 472, 10, 16, 12, 1, -15 }, // 0x41 'A' + { 492, 11, 16, 12, 0, -15 }, // 0x42 'B' + { 514, 10, 16, 12, 1, -15 }, // 0x43 'C' + { 534, 11, 16, 13, 1, -15 }, // 0x44 'D' + { 556, 10, 16, 12, 1, -15 }, // 0x45 'E' + { 576, 11, 16, 12, 1, -15 }, // 0x46 'F' + { 598, 11, 16, 13, 1, -15 }, // 0x47 'G' + { 620, 11, 16, 13, 1, -15 }, // 0x48 'H' + { 642, 11, 16, 12, 1, -15 }, // 0x49 'I' + { 664, 11, 16, 12, 0, -15 }, // 0x4A 'J' + { 686, 11, 16, 12, 1, -15 }, // 0x4B 'K' + { 708, 11, 16, 12, 1, -15 }, // 0x4C 'L' + { 730, 9, 16, 11, 1, -15 }, // 0x4D 'M' + { 748, 10, 16, 12, 1, -15 }, // 0x4E 'N' + { 768, 11, 16, 13, 1, -15 }, // 0x4F 'O' + { 790, 11, 16, 13, 1, -15 }, // 0x50 'P' + { 812, 11, 18, 13, 1, -15 }, // 0x51 'Q' + { 837, 11, 16, 13, 1, -15 }, // 0x52 'R' + { 859, 11, 16, 13, 1, -15 }, // 0x53 'S' + { 881, 11, 16, 12, 1, -15 }, // 0x54 'T' + { 903, 11, 16, 13, 1, -15 }, // 0x55 'U' + { 925, 10, 16, 12, 1, -15 }, // 0x56 'V' + { 945, 12, 16, 12, 0, -15 }, // 0x57 'W' + { 969, 10, 16, 12, 1, -15 }, // 0x58 'X' + { 989, 11, 16, 12, 0, -15 }, // 0x59 'Y' + { 1011, 10, 16, 12, 1, -15 }, // 0x5A 'Z' + { 1031, 6, 24, 12, 3, -18 }, // 0x5B '[' + { 1049, 10, 16, 12, 1, -15 }, // 0x5C '\' + { 1069, 6, 24, 12, 3, -18 }, // 0x5D ']' + { 1087, 12, 7, 12, 0, -15 }, // 0x5E '^' + { 1098, 12, 1, 12, 0, 4 }, // 0x5F '_' + { 1100, 4, 3, 12, 4, -15 }, // 0x60 '`' + { 1102, 11, 13, 13, 1, -12 }, // 0x61 'a' + { 1120, 11, 17, 13, 1, -16 }, // 0x62 'b' + { 1144, 10, 13, 12, 1, -12 }, // 0x63 'c' + { 1161, 11, 17, 13, 1, -16 }, // 0x64 'd' + { 1185, 11, 13, 13, 1, -12 }, // 0x65 'e' + { 1203, 11, 17, 12, 1, -16 }, // 0x66 'f' + { 1227, 11, 18, 13, 1, -12 }, // 0x67 'g' + { 1252, 11, 17, 13, 1, -16 }, // 0x68 'h' + { 1276, 11, 17, 12, 1, -16 }, // 0x69 'i' + { 1300, 8, 22, 12, 2, -16 }, // 0x6A 'j' + { 1322, 11, 17, 12, 1, -16 }, // 0x6B 'k' + { 1346, 11, 17, 12, 0, -16 }, // 0x6C 'l' + { 1370, 12, 13, 13, 0, -12 }, // 0x6D 'm' + { 1390, 11, 13, 13, 1, -12 }, // 0x6E 'n' + { 1408, 11, 13, 13, 1, -12 }, // 0x6F 'o' + { 1426, 11, 18, 13, 1, -12 }, // 0x70 'p' + { 1451, 11, 18, 13, 1, -12 }, // 0x71 'q' + { 1476, 10, 13, 12, 1, -12 }, // 0x72 'r' + { 1493, 11, 13, 12, 1, -12 }, // 0x73 's' + { 1511, 10, 16, 12, 1, -15 }, // 0x74 't' + { 1531, 11, 13, 13, 1, -12 }, // 0x75 'u' + { 1549, 12, 13, 12, 0, -12 }, // 0x76 'v' + { 1569, 12, 13, 12, 0, -12 }, // 0x77 'w' + { 1589, 11, 13, 12, 1, -12 }, // 0x78 'x' + { 1607, 12, 18, 12, 0, -12 }, // 0x79 'y' + { 1634, 10, 13, 12, 1, -12 }, // 0x7A 'z' + { 1651, 8, 24, 12, 2, -18 }, // 0x7B '{' + { 1675, 1, 24, 12, 6, -18 }, // 0x7C '|' + { 1678, 7, 24, 12, 3, -18 }, // 0x7D '}' + { 1699, 8, 3, 12, 2, -9 } }; // 0x7E '~' const GFXfont unispace8pt7b PROGMEM = { (uint8_t *)unispace8pt7bBitmaps, (GFXglyph *)unispace8pt7bGlyphs, - 0x20, 0x7E, 24 }; + 0x20, 0x7E, 24 }; // Approx. 2374 bytes +#endif // ifndef FONTS_UNISPACE8PT7B_H diff --git a/src/src/Static/Fonts/unispace_italic12pt7b.h b/src/src/Static/Fonts/unispace_italic12pt7b.h index f46046a5e..62c4f6cdc 100644 --- a/src/src/Static/Fonts/unispace_italic12pt7b.h +++ b/src/src/Static/Fonts/unispace_italic12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_UNISPACE_ITALIC12PT7B_H +#define FONTS_UNISPACE_ITALIC12PT7B_H const uint8_t unispace_italic12pt7bBitmaps[] PROGMEM = { 0x00, 0x07, 0x83, 0xC1, 0xE1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE1, 0xE0, 0xF0, 0x78, 0x3C, 0x20, 0x00, 0x00, 0x00, @@ -381,105 +383,106 @@ const uint8_t unispace_italic12pt7bBitmaps[] PROGMEM = { 0xB0, 0xFC, 0xC1, 0xE0 }; const GFXglyph unispace_italic12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' - { 1, 9, 24, 18, 7, -23 }, // 0x21 '!' - { 28, 10, 7, 18, 9, -24 }, // 0x22 '"' - { 37, 17, 24, 18, 3, -23 }, // 0x23 '#' - { 88, 19, 24, 19, 2, -23 }, // 0x24 '$' - { 145, 15, 24, 18, 4, -23 }, // 0x25 '%' - { 190, 17, 24, 18, 2, -23 }, // 0x26 '&' - { 241, 4, 7, 18, 12, -24 }, // 0x27 ''' - { 245, 17, 35, 18, 3, -27 }, // 0x28 '(' - { 320, 17, 35, 18, 2, -27 }, // 0x29 ')' - { 395, 13, 13, 18, 6, -23 }, // 0x2A '*' - { 417, 15, 12, 18, 5, -18 }, // 0x2B '+' - { 440, 5, 7, 18, 6, -1 }, // 0x2C ',' - { 445, 15, 2, 18, 4, -11 }, // 0x2D '-' - { 449, 5, 3, 18, 7, -2 }, // 0x2E '.' - { 451, 21, 24, 18, 1, -23 }, // 0x2F '/' - { 514, 19, 24, 18, 2, -23 }, // 0x30 '0' - { 571, 16, 24, 18, 1, -23 }, // 0x31 '1' - { 619, 20, 24, 18, 1, -23 }, // 0x32 '2' - { 679, 20, 24, 18, 1, -23 }, // 0x33 '3' - { 739, 18, 24, 18, 2, -23 }, // 0x34 '4' - { 793, 19, 24, 18, 1, -23 }, // 0x35 '5' - { 850, 17, 24, 18, 2, -23 }, // 0x36 '6' - { 901, 19, 24, 18, 3, -23 }, // 0x37 '7' - { 958, 19, 24, 19, 2, -23 }, // 0x38 '8' - { 1015, 18, 24, 18, 3, -23 }, // 0x39 '9' - { 1069, 7, 14, 18, 7, -13 }, // 0x3A ':' - { 1082, 8, 19, 18, 6, -13 }, // 0x3B ';' - { 1101, 10, 18, 18, 7, -21 }, // 0x3C '<' - { 1124, 12, 8, 18, 6, -16 }, // 0x3D '=' - { 1136, 10, 18, 18, 7, -21 }, // 0x3E '>' - { 1159, 17, 24, 18, 4, -23 }, // 0x3F '?' - { 1210, 19, 24, 18, 2, -23 }, // 0x40 '@' - { 1267, 17, 24, 18, 0, -23 }, // 0x41 'A' - { 1318, 20, 24, 18, 1, -23 }, // 0x42 'B' - { 1378, 19, 24, 18, 3, -23 }, // 0x43 'C' - { 1435, 20, 24, 18, 1, -23 }, // 0x44 'D' - { 1495, 20, 24, 18, 2, -23 }, // 0x45 'E' - { 1555, 21, 24, 18, 1, -23 }, // 0x46 'F' - { 1618, 19, 24, 18, 2, -23 }, // 0x47 'G' - { 1675, 21, 24, 18, 1, -23 }, // 0x48 'H' - { 1738, 20, 24, 18, 2, -23 }, // 0x49 'I' - { 1798, 20, 24, 18, 2, -23 }, // 0x4A 'J' - { 1858, 21, 24, 18, 1, -23 }, // 0x4B 'K' - { 1921, 16, 24, 18, 1, -23 }, // 0x4C 'L' - { 1969, 21, 24, 18, 1, -23 }, // 0x4D 'M' - { 2032, 21, 24, 18, 1, -23 }, // 0x4E 'N' - { 2095, 19, 24, 18, 2, -23 }, // 0x4F 'O' - { 2152, 20, 24, 18, 1, -23 }, // 0x50 'P' - { 2212, 19, 28, 18, 2, -23 }, // 0x51 'Q' - { 2279, 19, 24, 17, 1, -23 }, // 0x52 'R' - { 2336, 19, 24, 18, 2, -23 }, // 0x53 'S' - { 2393, 16, 24, 18, 6, -23 }, // 0x54 'T' - { 2441, 20, 24, 18, 2, -23 }, // 0x55 'U' - { 2501, 17, 24, 18, 6, -23 }, // 0x56 'V' - { 2552, 20, 24, 18, 3, -23 }, // 0x57 'W' - { 2612, 21, 24, 18, 1, -23 }, // 0x58 'X' - { 2675, 16, 24, 18, 6, -23 }, // 0x59 'Y' - { 2723, 21, 24, 18, 1, -23 }, // 0x5A 'Z' - { 2786, 17, 35, 18, 3, -27 }, // 0x5B '[' - { 2861, 11, 24, 18, 6, -23 }, // 0x5C '\' - { 2894, 17, 35, 18, 3, -27 }, // 0x5D ']' - { 2969, 18, 11, 18, 3, -23 }, // 0x5E '^' - { 2994, 19, 2, 18, -2, 6 }, // 0x5F '_' - { 2999, 7, 3, 18, 10, -22 }, // 0x60 '`' - { 3002, 18, 19, 18, 2, -18 }, // 0x61 'a' - { 3045, 19, 25, 18, 1, -24 }, // 0x62 'b' - { 3105, 18, 19, 18, 2, -18 }, // 0x63 'c' - { 3148, 20, 25, 18, 2, -24 }, // 0x64 'd' - { 3211, 19, 19, 19, 2, -18 }, // 0x65 'e' - { 3257, 17, 25, 18, 5, -24 }, // 0x66 'f' - { 3311, 19, 26, 18, 2, -18 }, // 0x67 'g' - { 3373, 19, 25, 18, 1, -24 }, // 0x68 'h' - { 3433, 16, 25, 18, 1, -24 }, // 0x69 'i' - { 3483, 18, 32, 18, 2, -24 }, // 0x6A 'j' - { 3555, 20, 25, 18, 1, -24 }, // 0x6B 'k' - { 3618, 16, 25, 18, 1, -24 }, // 0x6C 'l' - { 3668, 19, 19, 18, 1, -18 }, // 0x6D 'm' - { 3714, 19, 19, 18, 1, -18 }, // 0x6E 'n' - { 3760, 18, 19, 18, 2, -18 }, // 0x6F 'o' - { 3803, 21, 26, 18, -1, -18 }, // 0x70 'p' - { 3872, 19, 26, 18, 2, -18 }, // 0x71 'q' - { 3934, 18, 19, 18, 2, -18 }, // 0x72 'r' - { 3977, 20, 19, 18, 1, -18 }, // 0x73 's' - { 4025, 16, 24, 18, 5, -23 }, // 0x74 't' - { 4073, 19, 19, 18, 2, -18 }, // 0x75 'u' - { 4119, 17, 19, 18, 5, -18 }, // 0x76 'v' - { 4160, 19, 19, 18, 3, -18 }, // 0x77 'w' - { 4206, 20, 19, 18, 1, -18 }, // 0x78 'x' - { 4254, 19, 26, 18, 3, -18 }, // 0x79 'y' - { 4316, 19, 19, 18, 2, -18 }, // 0x7A 'z' - { 4362, 15, 35, 18, 6, -27 }, // 0x7B '{' - { 4428, 11, 35, 18, 6, -27 }, // 0x7C '|' - { 4477, 15, 35, 19, 2, -27 }, // 0x7D '}' - { 4543, 14, 5, 18, 5, -14 } }; // 0x7E '~' + { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' + { 1, 9, 24, 18, 7, -23 }, // 0x21 '!' + { 28, 10, 7, 18, 9, -24 }, // 0x22 '"' + { 37, 17, 24, 18, 3, -23 }, // 0x23 '#' + { 88, 19, 24, 19, 2, -23 }, // 0x24 '$' + { 145, 15, 24, 18, 4, -23 }, // 0x25 '%' + { 190, 17, 24, 18, 2, -23 }, // 0x26 '&' + { 241, 4, 7, 18, 12, -24 }, // 0x27 ''' + { 245, 17, 35, 18, 3, -27 }, // 0x28 '(' + { 320, 17, 35, 18, 2, -27 }, // 0x29 ')' + { 395, 13, 13, 18, 6, -23 }, // 0x2A '*' + { 417, 15, 12, 18, 5, -18 }, // 0x2B '+' + { 440, 5, 7, 18, 6, -1 }, // 0x2C ',' + { 445, 15, 2, 18, 4, -11 }, // 0x2D '-' + { 449, 5, 3, 18, 7, -2 }, // 0x2E '.' + { 451, 21, 24, 18, 1, -23 }, // 0x2F '/' + { 514, 19, 24, 18, 2, -23 }, // 0x30 '0' + { 571, 16, 24, 18, 1, -23 }, // 0x31 '1' + { 619, 20, 24, 18, 1, -23 }, // 0x32 '2' + { 679, 20, 24, 18, 1, -23 }, // 0x33 '3' + { 739, 18, 24, 18, 2, -23 }, // 0x34 '4' + { 793, 19, 24, 18, 1, -23 }, // 0x35 '5' + { 850, 17, 24, 18, 2, -23 }, // 0x36 '6' + { 901, 19, 24, 18, 3, -23 }, // 0x37 '7' + { 958, 19, 24, 19, 2, -23 }, // 0x38 '8' + { 1015, 18, 24, 18, 3, -23 }, // 0x39 '9' + { 1069, 7, 14, 18, 7, -13 }, // 0x3A ':' + { 1082, 8, 19, 18, 6, -13 }, // 0x3B ';' + { 1101, 10, 18, 18, 7, -21 }, // 0x3C '<' + { 1124, 12, 8, 18, 6, -16 }, // 0x3D '=' + { 1136, 10, 18, 18, 7, -21 }, // 0x3E '>' + { 1159, 17, 24, 18, 4, -23 }, // 0x3F '?' + { 1210, 19, 24, 18, 2, -23 }, // 0x40 '@' + { 1267, 17, 24, 18, 0, -23 }, // 0x41 'A' + { 1318, 20, 24, 18, 1, -23 }, // 0x42 'B' + { 1378, 19, 24, 18, 3, -23 }, // 0x43 'C' + { 1435, 20, 24, 18, 1, -23 }, // 0x44 'D' + { 1495, 20, 24, 18, 2, -23 }, // 0x45 'E' + { 1555, 21, 24, 18, 1, -23 }, // 0x46 'F' + { 1618, 19, 24, 18, 2, -23 }, // 0x47 'G' + { 1675, 21, 24, 18, 1, -23 }, // 0x48 'H' + { 1738, 20, 24, 18, 2, -23 }, // 0x49 'I' + { 1798, 20, 24, 18, 2, -23 }, // 0x4A 'J' + { 1858, 21, 24, 18, 1, -23 }, // 0x4B 'K' + { 1921, 16, 24, 18, 1, -23 }, // 0x4C 'L' + { 1969, 21, 24, 18, 1, -23 }, // 0x4D 'M' + { 2032, 21, 24, 18, 1, -23 }, // 0x4E 'N' + { 2095, 19, 24, 18, 2, -23 }, // 0x4F 'O' + { 2152, 20, 24, 18, 1, -23 }, // 0x50 'P' + { 2212, 19, 28, 18, 2, -23 }, // 0x51 'Q' + { 2279, 19, 24, 17, 1, -23 }, // 0x52 'R' + { 2336, 19, 24, 18, 2, -23 }, // 0x53 'S' + { 2393, 16, 24, 18, 6, -23 }, // 0x54 'T' + { 2441, 20, 24, 18, 2, -23 }, // 0x55 'U' + { 2501, 17, 24, 18, 6, -23 }, // 0x56 'V' + { 2552, 20, 24, 18, 3, -23 }, // 0x57 'W' + { 2612, 21, 24, 18, 1, -23 }, // 0x58 'X' + { 2675, 16, 24, 18, 6, -23 }, // 0x59 'Y' + { 2723, 21, 24, 18, 1, -23 }, // 0x5A 'Z' + { 2786, 17, 35, 18, 3, -27 }, // 0x5B '[' + { 2861, 11, 24, 18, 6, -23 }, // 0x5C '\' + { 2894, 17, 35, 18, 3, -27 }, // 0x5D ']' + { 2969, 18, 11, 18, 3, -23 }, // 0x5E '^' + { 2994, 19, 2, 18, -2, 6 }, // 0x5F '_' + { 2999, 7, 3, 18, 10, -22 }, // 0x60 '`' + { 3002, 18, 19, 18, 2, -18 }, // 0x61 'a' + { 3045, 19, 25, 18, 1, -24 }, // 0x62 'b' + { 3105, 18, 19, 18, 2, -18 }, // 0x63 'c' + { 3148, 20, 25, 18, 2, -24 }, // 0x64 'd' + { 3211, 19, 19, 19, 2, -18 }, // 0x65 'e' + { 3257, 17, 25, 18, 5, -24 }, // 0x66 'f' + { 3311, 19, 26, 18, 2, -18 }, // 0x67 'g' + { 3373, 19, 25, 18, 1, -24 }, // 0x68 'h' + { 3433, 16, 25, 18, 1, -24 }, // 0x69 'i' + { 3483, 18, 32, 18, 2, -24 }, // 0x6A 'j' + { 3555, 20, 25, 18, 1, -24 }, // 0x6B 'k' + { 3618, 16, 25, 18, 1, -24 }, // 0x6C 'l' + { 3668, 19, 19, 18, 1, -18 }, // 0x6D 'm' + { 3714, 19, 19, 18, 1, -18 }, // 0x6E 'n' + { 3760, 18, 19, 18, 2, -18 }, // 0x6F 'o' + { 3803, 21, 26, 18, -1, -18 }, // 0x70 'p' + { 3872, 19, 26, 18, 2, -18 }, // 0x71 'q' + { 3934, 18, 19, 18, 2, -18 }, // 0x72 'r' + { 3977, 20, 19, 18, 1, -18 }, // 0x73 's' + { 4025, 16, 24, 18, 5, -23 }, // 0x74 't' + { 4073, 19, 19, 18, 2, -18 }, // 0x75 'u' + { 4119, 17, 19, 18, 5, -18 }, // 0x76 'v' + { 4160, 19, 19, 18, 3, -18 }, // 0x77 'w' + { 4206, 20, 19, 18, 1, -18 }, // 0x78 'x' + { 4254, 19, 26, 18, 3, -18 }, // 0x79 'y' + { 4316, 19, 19, 18, 2, -18 }, // 0x7A 'z' + { 4362, 15, 35, 18, 6, -27 }, // 0x7B '{' + { 4428, 11, 35, 18, 6, -27 }, // 0x7C '|' + { 4477, 15, 35, 19, 2, -27 }, // 0x7D '}' + { 4543, 14, 5, 18, 5, -14 } }; // 0x7E '~' const GFXfont unispace_italic12pt7b PROGMEM = { (uint8_t *)unispace_italic12pt7bBitmaps, (GFXglyph *)unispace_italic12pt7bGlyphs, - 0x20, 0x7E, 36 }; + 0x20, 0x7E, 36 }; // Approx. 5224 bytes +#endif // ifndef FONTS_UNISPACE_ITALIC12PT7B_H diff --git a/src/src/Static/Fonts/unispace_italic8pt7b.h b/src/src/Static/Fonts/unispace_italic8pt7b.h index e23bf56ca..cc1fe79aa 100644 --- a/src/src/Static/Fonts/unispace_italic8pt7b.h +++ b/src/src/Static/Fonts/unispace_italic8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_UNISPACE_ITALIC8PT7B_H +#define FONTS_UNISPACE_ITALIC8PT7B_H const uint8_t unispace_italic8pt7bBitmaps[] PROGMEM = { 0x00, 0x1C, 0x61, 0x8E, 0x38, 0xE3, 0x0C, 0x71, 0xC7, 0x18, 0x00, 0x00, 0x38, 0x6D, 0xBC, 0xF3, 0xD8, 0x0C, 0x61, 0x88, 0x31, 0x04, 0x60, 0x8C, @@ -176,105 +178,106 @@ const uint8_t unispace_italic8pt7bBitmaps[] PROGMEM = { 0x78, 0xA6, 0xF1, 0xC0 }; const GFXglyph unispace_italic8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 12, 0, 0 }, // 0x20 ' ' - { 1, 6, 16, 12, 5, -15 }, // 0x21 '!' - { 13, 6, 5, 12, 6, -16 }, // 0x22 '"' - { 17, 11, 16, 12, 2, -15 }, // 0x23 '#' - { 39, 12, 16, 12, 2, -15 }, // 0x24 '$' - { 63, 10, 16, 11, 3, -15 }, // 0x25 '%' - { 83, 13, 16, 12, 1, -15 }, // 0x26 '&' - { 109, 3, 5, 12, 8, -16 }, // 0x27 ''' - { 111, 12, 24, 12, 2, -18 }, // 0x28 '(' - { 147, 12, 24, 12, 1, -18 }, // 0x29 ')' - { 183, 9, 9, 12, 4, -15 }, // 0x2A '*' - { 194, 9, 8, 12, 3, -12 }, // 0x2B '+' - { 203, 3, 5, 12, 4, 0 }, // 0x2C ',' - { 205, 11, 1, 12, 2, -7 }, // 0x2D '-' - { 207, 3, 1, 12, 5, 0 }, // 0x2E '.' - { 208, 14, 16, 12, 1, -15 }, // 0x2F '/' - { 236, 13, 16, 12, 1, -15 }, // 0x30 '0' - { 262, 11, 16, 12, 1, -15 }, // 0x31 '1' - { 284, 14, 16, 12, 0, -15 }, // 0x32 '2' - { 312, 14, 16, 13, 1, -15 }, // 0x33 '3' - { 340, 12, 16, 12, 1, -15 }, // 0x34 '4' - { 364, 14, 16, 12, 0, -15 }, // 0x35 '5' - { 392, 12, 16, 12, 1, -15 }, // 0x36 '6' - { 416, 13, 16, 12, 2, -15 }, // 0x37 '7' - { 442, 14, 16, 13, 1, -15 }, // 0x38 '8' - { 470, 13, 16, 12, 1, -15 }, // 0x39 '9' - { 496, 4, 9, 12, 5, -8 }, // 0x3A ':' - { 501, 5, 13, 12, 4, -8 }, // 0x3B ';' - { 510, 7, 12, 12, 4, -13 }, // 0x3C '<' - { 521, 8, 5, 12, 4, -10 }, // 0x3D '=' - { 526, 7, 12, 12, 4, -13 }, // 0x3E '>' - { 537, 11, 16, 12, 3, -15 }, // 0x3F '?' - { 559, 12, 16, 12, 2, -15 }, // 0x40 '@' - { 583, 11, 16, 13, 1, -15 }, // 0x41 'A' - { 605, 14, 16, 12, 1, -15 }, // 0x42 'B' - { 633, 13, 16, 12, 2, -15 }, // 0x43 'C' - { 659, 13, 16, 12, 1, -15 }, // 0x44 'D' - { 685, 13, 16, 12, 1, -15 }, // 0x45 'E' - { 711, 14, 16, 12, 1, -15 }, // 0x46 'F' - { 739, 13, 16, 12, 1, -15 }, // 0x47 'G' - { 765, 14, 16, 12, 1, -15 }, // 0x48 'H' - { 793, 13, 16, 12, 1, -15 }, // 0x49 'I' - { 819, 13, 16, 12, 1, -15 }, // 0x4A 'J' - { 845, 14, 16, 12, 1, -15 }, // 0x4B 'K' - { 873, 11, 16, 12, 1, -15 }, // 0x4C 'L' - { 895, 14, 16, 12, 1, -15 }, // 0x4D 'M' - { 923, 14, 16, 12, 1, -15 }, // 0x4E 'N' - { 951, 14, 16, 13, 1, -15 }, // 0x4F 'O' - { 979, 13, 16, 12, 1, -15 }, // 0x50 'P' - { 1005, 14, 18, 13, 1, -15 }, // 0x51 'Q' - { 1037, 14, 16, 11, 0, -15 }, // 0x52 'R' - { 1065, 13, 16, 12, 1, -15 }, // 0x53 'S' - { 1091, 10, 16, 12, 4, -15 }, // 0x54 'T' - { 1111, 14, 16, 12, 1, -15 }, // 0x55 'U' - { 1139, 11, 16, 12, 4, -15 }, // 0x56 'V' - { 1161, 13, 16, 12, 2, -15 }, // 0x57 'W' - { 1187, 14, 16, 12, 1, -15 }, // 0x58 'X' - { 1215, 11, 16, 12, 4, -15 }, // 0x59 'Y' - { 1237, 14, 16, 12, 1, -15 }, // 0x5A 'Z' - { 1265, 11, 24, 12, 2, -18 }, // 0x5B '[' - { 1298, 7, 16, 12, 4, -15 }, // 0x5C '\' - { 1312, 11, 24, 12, 2, -18 }, // 0x5D ']' - { 1345, 12, 7, 12, 2, -15 }, // 0x5E '^' - { 1356, 12, 1, 12, -1, 4 }, // 0x5F '_' - { 1358, 5, 3, 12, 7, -15 }, // 0x60 '`' - { 1360, 13, 13, 12, 1, -12 }, // 0x61 'a' - { 1382, 13, 17, 13, 1, -16 }, // 0x62 'b' - { 1410, 13, 13, 12, 1, -12 }, // 0x63 'c' - { 1432, 13, 17, 12, 1, -16 }, // 0x64 'd' - { 1460, 13, 13, 13, 1, -12 }, // 0x65 'e' - { 1482, 12, 17, 12, 3, -16 }, // 0x66 'f' - { 1508, 13, 18, 12, 1, -12 }, // 0x67 'g' - { 1538, 13, 17, 13, 1, -16 }, // 0x68 'h' - { 1566, 10, 17, 12, 1, -16 }, // 0x69 'i' - { 1588, 12, 22, 12, 1, -16 }, // 0x6A 'j' - { 1621, 13, 17, 12, 1, -16 }, // 0x6B 'k' - { 1649, 10, 17, 12, 1, -16 }, // 0x6C 'l' - { 1671, 13, 13, 12, 1, -12 }, // 0x6D 'm' - { 1693, 13, 13, 13, 1, -12 }, // 0x6E 'n' - { 1715, 13, 13, 12, 1, -12 }, // 0x6F 'o' - { 1737, 14, 18, 13, 0, -12 }, // 0x70 'p' - { 1769, 13, 18, 12, 1, -12 }, // 0x71 'q' - { 1799, 13, 13, 12, 1, -12 }, // 0x72 'r' - { 1821, 13, 13, 12, 1, -12 }, // 0x73 's' - { 1843, 11, 16, 12, 4, -15 }, // 0x74 't' - { 1865, 13, 13, 12, 1, -12 }, // 0x75 'u' - { 1887, 11, 13, 12, 3, -12 }, // 0x76 'v' - { 1905, 13, 13, 12, 2, -12 }, // 0x77 'w' - { 1927, 13, 13, 12, 1, -12 }, // 0x78 'x' - { 1949, 13, 18, 12, 2, -12 }, // 0x79 'y' - { 1979, 13, 13, 12, 1, -12 }, // 0x7A 'z' - { 2001, 11, 24, 12, 3, -18 }, // 0x7B '{' - { 2034, 7, 24, 12, 4, -18 }, // 0x7C '|' - { 2055, 11, 24, 13, 1, -18 }, // 0x7D '}' - { 2088, 9, 3, 12, 3, -9 } }; // 0x7E '~' + { 0, 1, 1, 12, 0, 0 }, // 0x20 ' ' + { 1, 6, 16, 12, 5, -15 }, // 0x21 '!' + { 13, 6, 5, 12, 6, -16 }, // 0x22 '"' + { 17, 11, 16, 12, 2, -15 }, // 0x23 '#' + { 39, 12, 16, 12, 2, -15 }, // 0x24 '$' + { 63, 10, 16, 11, 3, -15 }, // 0x25 '%' + { 83, 13, 16, 12, 1, -15 }, // 0x26 '&' + { 109, 3, 5, 12, 8, -16 }, // 0x27 ''' + { 111, 12, 24, 12, 2, -18 }, // 0x28 '(' + { 147, 12, 24, 12, 1, -18 }, // 0x29 ')' + { 183, 9, 9, 12, 4, -15 }, // 0x2A '*' + { 194, 9, 8, 12, 3, -12 }, // 0x2B '+' + { 203, 3, 5, 12, 4, 0 }, // 0x2C ',' + { 205, 11, 1, 12, 2, -7 }, // 0x2D '-' + { 207, 3, 1, 12, 5, 0 }, // 0x2E '.' + { 208, 14, 16, 12, 1, -15 }, // 0x2F '/' + { 236, 13, 16, 12, 1, -15 }, // 0x30 '0' + { 262, 11, 16, 12, 1, -15 }, // 0x31 '1' + { 284, 14, 16, 12, 0, -15 }, // 0x32 '2' + { 312, 14, 16, 13, 1, -15 }, // 0x33 '3' + { 340, 12, 16, 12, 1, -15 }, // 0x34 '4' + { 364, 14, 16, 12, 0, -15 }, // 0x35 '5' + { 392, 12, 16, 12, 1, -15 }, // 0x36 '6' + { 416, 13, 16, 12, 2, -15 }, // 0x37 '7' + { 442, 14, 16, 13, 1, -15 }, // 0x38 '8' + { 470, 13, 16, 12, 1, -15 }, // 0x39 '9' + { 496, 4, 9, 12, 5, -8 }, // 0x3A ':' + { 501, 5, 13, 12, 4, -8 }, // 0x3B ';' + { 510, 7, 12, 12, 4, -13 }, // 0x3C '<' + { 521, 8, 5, 12, 4, -10 }, // 0x3D '=' + { 526, 7, 12, 12, 4, -13 }, // 0x3E '>' + { 537, 11, 16, 12, 3, -15 }, // 0x3F '?' + { 559, 12, 16, 12, 2, -15 }, // 0x40 '@' + { 583, 11, 16, 13, 1, -15 }, // 0x41 'A' + { 605, 14, 16, 12, 1, -15 }, // 0x42 'B' + { 633, 13, 16, 12, 2, -15 }, // 0x43 'C' + { 659, 13, 16, 12, 1, -15 }, // 0x44 'D' + { 685, 13, 16, 12, 1, -15 }, // 0x45 'E' + { 711, 14, 16, 12, 1, -15 }, // 0x46 'F' + { 739, 13, 16, 12, 1, -15 }, // 0x47 'G' + { 765, 14, 16, 12, 1, -15 }, // 0x48 'H' + { 793, 13, 16, 12, 1, -15 }, // 0x49 'I' + { 819, 13, 16, 12, 1, -15 }, // 0x4A 'J' + { 845, 14, 16, 12, 1, -15 }, // 0x4B 'K' + { 873, 11, 16, 12, 1, -15 }, // 0x4C 'L' + { 895, 14, 16, 12, 1, -15 }, // 0x4D 'M' + { 923, 14, 16, 12, 1, -15 }, // 0x4E 'N' + { 951, 14, 16, 13, 1, -15 }, // 0x4F 'O' + { 979, 13, 16, 12, 1, -15 }, // 0x50 'P' + { 1005, 14, 18, 13, 1, -15 }, // 0x51 'Q' + { 1037, 14, 16, 11, 0, -15 }, // 0x52 'R' + { 1065, 13, 16, 12, 1, -15 }, // 0x53 'S' + { 1091, 10, 16, 12, 4, -15 }, // 0x54 'T' + { 1111, 14, 16, 12, 1, -15 }, // 0x55 'U' + { 1139, 11, 16, 12, 4, -15 }, // 0x56 'V' + { 1161, 13, 16, 12, 2, -15 }, // 0x57 'W' + { 1187, 14, 16, 12, 1, -15 }, // 0x58 'X' + { 1215, 11, 16, 12, 4, -15 }, // 0x59 'Y' + { 1237, 14, 16, 12, 1, -15 }, // 0x5A 'Z' + { 1265, 11, 24, 12, 2, -18 }, // 0x5B '[' + { 1298, 7, 16, 12, 4, -15 }, // 0x5C '\' + { 1312, 11, 24, 12, 2, -18 }, // 0x5D ']' + { 1345, 12, 7, 12, 2, -15 }, // 0x5E '^' + { 1356, 12, 1, 12, -1, 4 }, // 0x5F '_' + { 1358, 5, 3, 12, 7, -15 }, // 0x60 '`' + { 1360, 13, 13, 12, 1, -12 }, // 0x61 'a' + { 1382, 13, 17, 13, 1, -16 }, // 0x62 'b' + { 1410, 13, 13, 12, 1, -12 }, // 0x63 'c' + { 1432, 13, 17, 12, 1, -16 }, // 0x64 'd' + { 1460, 13, 13, 13, 1, -12 }, // 0x65 'e' + { 1482, 12, 17, 12, 3, -16 }, // 0x66 'f' + { 1508, 13, 18, 12, 1, -12 }, // 0x67 'g' + { 1538, 13, 17, 13, 1, -16 }, // 0x68 'h' + { 1566, 10, 17, 12, 1, -16 }, // 0x69 'i' + { 1588, 12, 22, 12, 1, -16 }, // 0x6A 'j' + { 1621, 13, 17, 12, 1, -16 }, // 0x6B 'k' + { 1649, 10, 17, 12, 1, -16 }, // 0x6C 'l' + { 1671, 13, 13, 12, 1, -12 }, // 0x6D 'm' + { 1693, 13, 13, 13, 1, -12 }, // 0x6E 'n' + { 1715, 13, 13, 12, 1, -12 }, // 0x6F 'o' + { 1737, 14, 18, 13, 0, -12 }, // 0x70 'p' + { 1769, 13, 18, 12, 1, -12 }, // 0x71 'q' + { 1799, 13, 13, 12, 1, -12 }, // 0x72 'r' + { 1821, 13, 13, 12, 1, -12 }, // 0x73 's' + { 1843, 11, 16, 12, 4, -15 }, // 0x74 't' + { 1865, 13, 13, 12, 1, -12 }, // 0x75 'u' + { 1887, 11, 13, 12, 3, -12 }, // 0x76 'v' + { 1905, 13, 13, 12, 2, -12 }, // 0x77 'w' + { 1927, 13, 13, 12, 1, -12 }, // 0x78 'x' + { 1949, 13, 18, 12, 2, -12 }, // 0x79 'y' + { 1979, 13, 13, 12, 1, -12 }, // 0x7A 'z' + { 2001, 11, 24, 12, 3, -18 }, // 0x7B '{' + { 2034, 7, 24, 12, 4, -18 }, // 0x7C '|' + { 2055, 11, 24, 13, 1, -18 }, // 0x7D '}' + { 2088, 9, 3, 12, 3, -9 } }; // 0x7E '~' const GFXfont unispace_italic8pt7b PROGMEM = { (uint8_t *)unispace_italic8pt7bBitmaps, (GFXglyph *)unispace_italic8pt7bGlyphs, - 0x20, 0x7E, 24 }; + 0x20, 0x7E, 24 }; // Approx. 2764 bytes +#endif // ifndef FONTS_UNISPACE_ITALIC8PT7B_H diff --git a/src/src/Static/Fonts/whitrabt12pt7b.h b/src/src/Static/Fonts/whitrabt12pt7b.h index 3515c6aaf..d9ab4b5fc 100644 --- a/src/src/Static/Fonts/whitrabt12pt7b.h +++ b/src/src/Static/Fonts/whitrabt12pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_WHITRABT12PT7B_H +#define FONTS_WHITRABT12PT7B_H const uint8_t whitrabt12pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xF0, 0xC7, 0x8F, 0x1E, 0x30, 0x33, 0x06, 0x60, 0xCC, 0x19, 0x8F, 0xFF, 0xFF, 0xCC, 0xC1, 0x98, @@ -132,105 +134,106 @@ const uint8_t whitrabt12pt7bBitmaps[] PROGMEM = { 0x3C, 0x63, 0xC6, 0x30, 0x3E, 0x01, 0xC0 }; const GFXglyph whitrabt12pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' - { 1, 4, 15, 13, 3, -14 }, // 0x21 '!' - { 9, 7, 4, 13, 3, -14 }, // 0x22 '"' - { 13, 11, 15, 13, 1, -14 }, // 0x23 '#' - { 34, 12, 15, 14, 1, -14 }, // 0x24 '$' - { 57, 10, 15, 12, 1, -14 }, // 0x25 '%' - { 76, 11, 15, 13, 1, -14 }, // 0x26 '&' - { 97, 2, 4, 14, 6, -14 }, // 0x27 ''' - { 98, 5, 15, 14, 6, -14 }, // 0x28 '(' - { 108, 4, 15, 13, 3, -14 }, // 0x29 ')' - { 116, 11, 11, 13, 1, -14 }, // 0x2A '*' - { 132, 11, 11, 13, 1, -12 }, // 0x2B '+' - { 148, 4, 6, 13, 3, -3 }, // 0x2C ',' - { 151, 11, 2, 13, 1, -8 }, // 0x2D '-' - { 154, 4, 4, 13, 3, -3 }, // 0x2E '.' - { 156, 11, 15, 13, 1, -14 }, // 0x2F '/' - { 177, 11, 15, 13, 1, -14 }, // 0x30 '0' - { 198, 7, 15, 13, 3, -14 }, // 0x31 '1' - { 212, 11, 15, 13, 1, -14 }, // 0x32 '2' - { 233, 11, 15, 13, 1, -14 }, // 0x33 '3' - { 254, 11, 15, 13, 1, -14 }, // 0x34 '4' - { 275, 11, 15, 13, 1, -14 }, // 0x35 '5' - { 296, 11, 15, 13, 1, -14 }, // 0x36 '6' - { 317, 11, 15, 13, 1, -14 }, // 0x37 '7' - { 338, 11, 15, 13, 1, -14 }, // 0x38 '8' - { 359, 11, 15, 13, 1, -14 }, // 0x39 '9' - { 380, 4, 13, 13, 3, -12 }, // 0x3A ':' - { 387, 4, 15, 13, 3, -12 }, // 0x3B ';' - { 395, 9, 15, 13, 1, -14 }, // 0x3C '<' - { 412, 11, 6, 13, 1, -10 }, // 0x3D '=' - { 421, 9, 15, 13, 3, -14 }, // 0x3E '>' - { 438, 12, 15, 14, 1, -14 }, // 0x3F '?' - { 461, 12, 15, 14, 1, -14 }, // 0x40 '@' - { 484, 11, 15, 13, 1, -14 }, // 0x41 'A' - { 505, 11, 15, 13, 1, -14 }, // 0x42 'B' - { 526, 11, 15, 13, 1, -14 }, // 0x43 'C' - { 547, 11, 15, 13, 1, -14 }, // 0x44 'D' - { 568, 11, 15, 13, 1, -14 }, // 0x45 'E' - { 589, 11, 15, 13, 1, -14 }, // 0x46 'F' - { 610, 11, 15, 13, 1, -14 }, // 0x47 'G' - { 631, 11, 15, 13, 1, -14 }, // 0x48 'H' - { 652, 7, 15, 13, 3, -14 }, // 0x49 'I' - { 666, 11, 15, 13, 1, -14 }, // 0x4A 'J' - { 687, 11, 15, 13, 1, -14 }, // 0x4B 'K' - { 708, 11, 15, 13, 1, -14 }, // 0x4C 'L' - { 729, 11, 15, 13, 1, -14 }, // 0x4D 'M' - { 750, 11, 15, 13, 1, -14 }, // 0x4E 'N' - { 771, 11, 15, 13, 1, -14 }, // 0x4F 'O' - { 792, 11, 15, 13, 1, -14 }, // 0x50 'P' - { 813, 11, 15, 13, 1, -14 }, // 0x51 'Q' - { 834, 11, 15, 13, 1, -14 }, // 0x52 'R' - { 855, 11, 15, 13, 1, -14 }, // 0x53 'S' - { 876, 11, 15, 13, 1, -14 }, // 0x54 'T' - { 897, 11, 15, 13, 1, -14 }, // 0x55 'U' - { 918, 11, 15, 13, 1, -14 }, // 0x56 'V' - { 939, 12, 15, 14, 1, -14 }, // 0x57 'W' - { 962, 11, 15, 13, 1, -14 }, // 0x58 'X' - { 983, 12, 15, 14, 1, -14 }, // 0x59 'Y' - { 1006, 11, 15, 13, 1, -14 }, // 0x5A 'Z' - { 1027, 5, 15, 14, 6, -14 }, // 0x5B '[' - { 1037, 11, 15, 13, 1, -14 }, // 0x5C '\' - { 1058, 4, 15, 13, 3, -14 }, // 0x5D ']' - { 1066, 11, 7, 13, 1, -15 }, // 0x5E '^' - { 1076, 11, 2, 13, 1, 1 }, // 0x5F '_' - { 1079, 5, 5, 14, 6, -15 }, // 0x60 '`' - { 1083, 11, 11, 13, 1, -10 }, // 0x61 'a' - { 1099, 11, 15, 13, 1, -14 }, // 0x62 'b' - { 1120, 11, 11, 13, 1, -10 }, // 0x63 'c' - { 1136, 11, 15, 13, 1, -14 }, // 0x64 'd' - { 1157, 11, 11, 13, 1, -10 }, // 0x65 'e' - { 1173, 9, 15, 13, 3, -14 }, // 0x66 'f' - { 1190, 11, 13, 13, 1, -10 }, // 0x67 'g' - { 1208, 11, 15, 13, 1, -14 }, // 0x68 'h' - { 1229, 7, 15, 13, 3, -14 }, // 0x69 'i' - { 1243, 9, 17, 13, 1, -14 }, // 0x6A 'j' - { 1263, 9, 15, 13, 3, -14 }, // 0x6B 'k' - { 1280, 7, 15, 13, 3, -14 }, // 0x6C 'l' - { 1294, 12, 11, 14, 1, -10 }, // 0x6D 'm' - { 1311, 11, 11, 13, 1, -10 }, // 0x6E 'n' - { 1327, 11, 11, 13, 1, -10 }, // 0x6F 'o' - { 1343, 11, 13, 13, 1, -10 }, // 0x70 'p' - { 1361, 11, 13, 13, 1, -10 }, // 0x71 'q' - { 1379, 9, 11, 13, 3, -10 }, // 0x72 'r' - { 1392, 11, 11, 13, 1, -10 }, // 0x73 's' - { 1408, 9, 15, 13, 3, -14 }, // 0x74 't' - { 1425, 11, 11, 13, 1, -10 }, // 0x75 'u' - { 1441, 11, 11, 13, 1, -10 }, // 0x76 'v' - { 1457, 12, 11, 14, 1, -10 }, // 0x77 'w' - { 1474, 11, 11, 13, 1, -10 }, // 0x78 'x' - { 1490, 11, 13, 13, 1, -10 }, // 0x79 'y' - { 1508, 11, 11, 13, 1, -10 }, // 0x7A 'z' - { 1524, 7, 15, 13, 3, -14 }, // 0x7B '{' - { 1538, 2, 15, 14, 6, -14 }, // 0x7C '|' - { 1542, 7, 15, 13, 3, -14 }, // 0x7D '}' - { 1556, 12, 7, 14, 1, -15 } }; // 0x7E '~' + { 0, 1, 1, 13, 0, 0 }, // 0x20 ' ' + { 1, 4, 15, 13, 3, -14 }, // 0x21 '!' + { 9, 7, 4, 13, 3, -14 }, // 0x22 '"' + { 13, 11, 15, 13, 1, -14 }, // 0x23 '#' + { 34, 12, 15, 14, 1, -14 }, // 0x24 '$' + { 57, 10, 15, 12, 1, -14 }, // 0x25 '%' + { 76, 11, 15, 13, 1, -14 }, // 0x26 '&' + { 97, 2, 4, 14, 6, -14 }, // 0x27 ''' + { 98, 5, 15, 14, 6, -14 }, // 0x28 '(' + { 108, 4, 15, 13, 3, -14 }, // 0x29 ')' + { 116, 11, 11, 13, 1, -14 }, // 0x2A '*' + { 132, 11, 11, 13, 1, -12 }, // 0x2B '+' + { 148, 4, 6, 13, 3, -3 }, // 0x2C ',' + { 151, 11, 2, 13, 1, -8 }, // 0x2D '-' + { 154, 4, 4, 13, 3, -3 }, // 0x2E '.' + { 156, 11, 15, 13, 1, -14 }, // 0x2F '/' + { 177, 11, 15, 13, 1, -14 }, // 0x30 '0' + { 198, 7, 15, 13, 3, -14 }, // 0x31 '1' + { 212, 11, 15, 13, 1, -14 }, // 0x32 '2' + { 233, 11, 15, 13, 1, -14 }, // 0x33 '3' + { 254, 11, 15, 13, 1, -14 }, // 0x34 '4' + { 275, 11, 15, 13, 1, -14 }, // 0x35 '5' + { 296, 11, 15, 13, 1, -14 }, // 0x36 '6' + { 317, 11, 15, 13, 1, -14 }, // 0x37 '7' + { 338, 11, 15, 13, 1, -14 }, // 0x38 '8' + { 359, 11, 15, 13, 1, -14 }, // 0x39 '9' + { 380, 4, 13, 13, 3, -12 }, // 0x3A ':' + { 387, 4, 15, 13, 3, -12 }, // 0x3B ';' + { 395, 9, 15, 13, 1, -14 }, // 0x3C '<' + { 412, 11, 6, 13, 1, -10 }, // 0x3D '=' + { 421, 9, 15, 13, 3, -14 }, // 0x3E '>' + { 438, 12, 15, 14, 1, -14 }, // 0x3F '?' + { 461, 12, 15, 14, 1, -14 }, // 0x40 '@' + { 484, 11, 15, 13, 1, -14 }, // 0x41 'A' + { 505, 11, 15, 13, 1, -14 }, // 0x42 'B' + { 526, 11, 15, 13, 1, -14 }, // 0x43 'C' + { 547, 11, 15, 13, 1, -14 }, // 0x44 'D' + { 568, 11, 15, 13, 1, -14 }, // 0x45 'E' + { 589, 11, 15, 13, 1, -14 }, // 0x46 'F' + { 610, 11, 15, 13, 1, -14 }, // 0x47 'G' + { 631, 11, 15, 13, 1, -14 }, // 0x48 'H' + { 652, 7, 15, 13, 3, -14 }, // 0x49 'I' + { 666, 11, 15, 13, 1, -14 }, // 0x4A 'J' + { 687, 11, 15, 13, 1, -14 }, // 0x4B 'K' + { 708, 11, 15, 13, 1, -14 }, // 0x4C 'L' + { 729, 11, 15, 13, 1, -14 }, // 0x4D 'M' + { 750, 11, 15, 13, 1, -14 }, // 0x4E 'N' + { 771, 11, 15, 13, 1, -14 }, // 0x4F 'O' + { 792, 11, 15, 13, 1, -14 }, // 0x50 'P' + { 813, 11, 15, 13, 1, -14 }, // 0x51 'Q' + { 834, 11, 15, 13, 1, -14 }, // 0x52 'R' + { 855, 11, 15, 13, 1, -14 }, // 0x53 'S' + { 876, 11, 15, 13, 1, -14 }, // 0x54 'T' + { 897, 11, 15, 13, 1, -14 }, // 0x55 'U' + { 918, 11, 15, 13, 1, -14 }, // 0x56 'V' + { 939, 12, 15, 14, 1, -14 }, // 0x57 'W' + { 962, 11, 15, 13, 1, -14 }, // 0x58 'X' + { 983, 12, 15, 14, 1, -14 }, // 0x59 'Y' + { 1006, 11, 15, 13, 1, -14 }, // 0x5A 'Z' + { 1027, 5, 15, 14, 6, -14 }, // 0x5B '[' + { 1037, 11, 15, 13, 1, -14 }, // 0x5C '\' + { 1058, 4, 15, 13, 3, -14 }, // 0x5D ']' + { 1066, 11, 7, 13, 1, -15 }, // 0x5E '^' + { 1076, 11, 2, 13, 1, 1 }, // 0x5F '_' + { 1079, 5, 5, 14, 6, -15 }, // 0x60 '`' + { 1083, 11, 11, 13, 1, -10 }, // 0x61 'a' + { 1099, 11, 15, 13, 1, -14 }, // 0x62 'b' + { 1120, 11, 11, 13, 1, -10 }, // 0x63 'c' + { 1136, 11, 15, 13, 1, -14 }, // 0x64 'd' + { 1157, 11, 11, 13, 1, -10 }, // 0x65 'e' + { 1173, 9, 15, 13, 3, -14 }, // 0x66 'f' + { 1190, 11, 13, 13, 1, -10 }, // 0x67 'g' + { 1208, 11, 15, 13, 1, -14 }, // 0x68 'h' + { 1229, 7, 15, 13, 3, -14 }, // 0x69 'i' + { 1243, 9, 17, 13, 1, -14 }, // 0x6A 'j' + { 1263, 9, 15, 13, 3, -14 }, // 0x6B 'k' + { 1280, 7, 15, 13, 3, -14 }, // 0x6C 'l' + { 1294, 12, 11, 14, 1, -10 }, // 0x6D 'm' + { 1311, 11, 11, 13, 1, -10 }, // 0x6E 'n' + { 1327, 11, 11, 13, 1, -10 }, // 0x6F 'o' + { 1343, 11, 13, 13, 1, -10 }, // 0x70 'p' + { 1361, 11, 13, 13, 1, -10 }, // 0x71 'q' + { 1379, 9, 11, 13, 3, -10 }, // 0x72 'r' + { 1392, 11, 11, 13, 1, -10 }, // 0x73 's' + { 1408, 9, 15, 13, 3, -14 }, // 0x74 't' + { 1425, 11, 11, 13, 1, -10 }, // 0x75 'u' + { 1441, 11, 11, 13, 1, -10 }, // 0x76 'v' + { 1457, 12, 11, 14, 1, -10 }, // 0x77 'w' + { 1474, 11, 11, 13, 1, -10 }, // 0x78 'x' + { 1490, 11, 13, 13, 1, -10 }, // 0x79 'y' + { 1508, 11, 11, 13, 1, -10 }, // 0x7A 'z' + { 1524, 7, 15, 13, 3, -14 }, // 0x7B '{' + { 1538, 2, 15, 14, 6, -14 }, // 0x7C '|' + { 1542, 7, 15, 13, 3, -14 }, // 0x7D '}' + { 1556, 12, 7, 14, 1, -15 } }; // 0x7E '~' const GFXfont whitrabt12pt7b PROGMEM = { (uint8_t *)whitrabt12pt7bBitmaps, (GFXglyph *)whitrabt12pt7bGlyphs, - 0x20, 0x7E, 18 }; + 0x20, 0x7E, 18 }; // Approx. 2239 bytes +#endif // ifndef FONTS_WHITRABT12PT7B_H diff --git a/src/src/Static/Fonts/whitrabt16pt7b.h b/src/src/Static/Fonts/whitrabt16pt7b.h index ee11bf99a..ced93d861 100644 --- a/src/src/Static/Fonts/whitrabt16pt7b.h +++ b/src/src/Static/Fonts/whitrabt16pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_WHITRABT16PT7B_H +#define FONTS_WHITRABT16PT7B_H const uint8_t whitrabt16pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1C, @@ -244,105 +246,106 @@ const uint8_t whitrabt16pt7bBitmaps[] PROGMEM = { 0x7E, 0x38, 0xFC, 0x71, 0xC0, 0xFF, 0x80, 0xFE, 0x00, 0x70 }; const GFXglyph whitrabt16pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' - { 1, 6, 21, 17, 4, -20 }, // 0x21 '!' - { 17, 9, 6, 17, 4, -20 }, // 0x22 '"' - { 24, 15, 21, 18, 1, -20 }, // 0x23 '#' - { 64, 15, 21, 18, 1, -20 }, // 0x24 '$' - { 104, 15, 21, 18, 1, -20 }, // 0x25 '%' - { 144, 15, 21, 18, 1, -20 }, // 0x26 '&' - { 184, 3, 6, 17, 7, -20 }, // 0x27 ''' - { 187, 6, 21, 17, 7, -20 }, // 0x28 '(' - { 203, 6, 21, 17, 4, -20 }, // 0x29 ')' - { 219, 15, 15, 18, 1, -20 }, // 0x2A '*' - { 248, 15, 15, 18, 1, -17 }, // 0x2B '+' - { 277, 6, 9, 17, 4, -5 }, // 0x2C ',' - { 284, 15, 3, 18, 1, -11 }, // 0x2D '-' - { 290, 6, 6, 17, 4, -5 }, // 0x2E '.' - { 295, 15, 21, 18, 1, -20 }, // 0x2F '/' - { 335, 15, 21, 18, 1, -20 }, // 0x30 '0' - { 375, 9, 21, 18, 4, -20 }, // 0x31 '1' - { 399, 15, 21, 18, 1, -20 }, // 0x32 '2' - { 439, 15, 21, 18, 1, -20 }, // 0x33 '3' - { 479, 15, 21, 18, 1, -20 }, // 0x34 '4' - { 519, 15, 21, 18, 1, -20 }, // 0x35 '5' - { 559, 15, 21, 18, 1, -20 }, // 0x36 '6' - { 599, 15, 21, 18, 1, -20 }, // 0x37 '7' - { 639, 15, 21, 18, 1, -20 }, // 0x38 '8' - { 679, 15, 21, 18, 1, -20 }, // 0x39 '9' - { 719, 6, 18, 17, 4, -17 }, // 0x3A ':' - { 733, 6, 21, 17, 4, -17 }, // 0x3B ';' - { 749, 12, 21, 17, 1, -20 }, // 0x3C '<' - { 781, 15, 9, 18, 1, -14 }, // 0x3D '=' - { 798, 12, 21, 18, 4, -20 }, // 0x3E '>' - { 830, 15, 21, 18, 1, -20 }, // 0x3F '?' - { 870, 15, 21, 18, 1, -20 }, // 0x40 '@' - { 910, 15, 21, 18, 1, -20 }, // 0x41 'A' - { 950, 15, 21, 18, 1, -20 }, // 0x42 'B' - { 990, 15, 21, 18, 1, -20 }, // 0x43 'C' - { 1030, 15, 21, 18, 1, -20 }, // 0x44 'D' - { 1070, 15, 21, 18, 1, -20 }, // 0x45 'E' - { 1110, 15, 21, 18, 1, -20 }, // 0x46 'F' - { 1150, 15, 21, 18, 1, -20 }, // 0x47 'G' - { 1190, 15, 21, 18, 1, -20 }, // 0x48 'H' - { 1230, 9, 21, 17, 4, -20 }, // 0x49 'I' - { 1254, 15, 21, 18, 1, -20 }, // 0x4A 'J' - { 1294, 15, 21, 18, 1, -20 }, // 0x4B 'K' - { 1334, 15, 21, 18, 1, -20 }, // 0x4C 'L' - { 1374, 15, 21, 18, 1, -20 }, // 0x4D 'M' - { 1414, 15, 21, 18, 1, -20 }, // 0x4E 'N' - { 1454, 15, 21, 18, 1, -20 }, // 0x4F 'O' - { 1494, 15, 21, 18, 1, -20 }, // 0x50 'P' - { 1534, 15, 21, 18, 1, -20 }, // 0x51 'Q' - { 1574, 15, 21, 18, 1, -20 }, // 0x52 'R' - { 1614, 15, 21, 18, 1, -20 }, // 0x53 'S' - { 1654, 15, 21, 18, 1, -20 }, // 0x54 'T' - { 1694, 15, 21, 18, 1, -20 }, // 0x55 'U' - { 1734, 15, 21, 18, 1, -20 }, // 0x56 'V' - { 1774, 15, 21, 18, 1, -20 }, // 0x57 'W' - { 1814, 15, 21, 18, 1, -20 }, // 0x58 'X' - { 1854, 15, 21, 18, 1, -20 }, // 0x59 'Y' - { 1894, 15, 21, 18, 1, -20 }, // 0x5A 'Z' - { 1934, 6, 21, 17, 7, -20 }, // 0x5B '[' - { 1950, 15, 21, 18, 1, -20 }, // 0x5C '\' - { 1990, 6, 21, 17, 4, -20 }, // 0x5D ']' - { 2006, 15, 9, 18, 1, -20 }, // 0x5E '^' - { 2023, 15, 3, 18, 1, 1 }, // 0x5F '_' - { 2029, 6, 6, 17, 7, -20 }, // 0x60 '`' - { 2034, 15, 15, 18, 1, -14 }, // 0x61 'a' - { 2063, 15, 21, 18, 1, -20 }, // 0x62 'b' - { 2103, 15, 15, 18, 1, -14 }, // 0x63 'c' - { 2132, 15, 21, 18, 1, -20 }, // 0x64 'd' - { 2172, 15, 15, 18, 1, -14 }, // 0x65 'e' - { 2201, 12, 21, 18, 4, -20 }, // 0x66 'f' - { 2233, 15, 18, 18, 1, -14 }, // 0x67 'g' - { 2267, 15, 21, 18, 1, -20 }, // 0x68 'h' - { 2307, 9, 21, 17, 4, -20 }, // 0x69 'i' - { 2331, 12, 24, 17, 1, -20 }, // 0x6A 'j' - { 2367, 12, 21, 18, 4, -20 }, // 0x6B 'k' - { 2399, 9, 21, 17, 4, -20 }, // 0x6C 'l' - { 2423, 15, 15, 18, 1, -14 }, // 0x6D 'm' - { 2452, 15, 15, 18, 1, -14 }, // 0x6E 'n' - { 2481, 15, 15, 18, 1, -14 }, // 0x6F 'o' - { 2510, 15, 18, 18, 1, -14 }, // 0x70 'p' - { 2544, 15, 18, 18, 1, -14 }, // 0x71 'q' - { 2578, 12, 15, 18, 4, -14 }, // 0x72 'r' - { 2601, 15, 15, 18, 1, -14 }, // 0x73 's' - { 2630, 12, 21, 18, 4, -20 }, // 0x74 't' - { 2662, 15, 15, 18, 1, -14 }, // 0x75 'u' - { 2691, 15, 15, 18, 1, -14 }, // 0x76 'v' - { 2720, 15, 15, 18, 1, -14 }, // 0x77 'w' - { 2749, 15, 15, 18, 1, -14 }, // 0x78 'x' - { 2778, 15, 18, 18, 1, -14 }, // 0x79 'y' - { 2812, 15, 15, 18, 1, -14 }, // 0x7A 'z' - { 2841, 9, 21, 17, 4, -20 }, // 0x7B '{' - { 2865, 3, 21, 17, 7, -20 }, // 0x7C '|' - { 2873, 9, 21, 17, 4, -20 }, // 0x7D '}' - { 2897, 15, 9, 18, 1, -20 } }; // 0x7E '~' + { 0, 1, 1, 18, 0, 0 }, // 0x20 ' ' + { 1, 6, 21, 17, 4, -20 }, // 0x21 '!' + { 17, 9, 6, 17, 4, -20 }, // 0x22 '"' + { 24, 15, 21, 18, 1, -20 }, // 0x23 '#' + { 64, 15, 21, 18, 1, -20 }, // 0x24 '$' + { 104, 15, 21, 18, 1, -20 }, // 0x25 '%' + { 144, 15, 21, 18, 1, -20 }, // 0x26 '&' + { 184, 3, 6, 17, 7, -20 }, // 0x27 ''' + { 187, 6, 21, 17, 7, -20 }, // 0x28 '(' + { 203, 6, 21, 17, 4, -20 }, // 0x29 ')' + { 219, 15, 15, 18, 1, -20 }, // 0x2A '*' + { 248, 15, 15, 18, 1, -17 }, // 0x2B '+' + { 277, 6, 9, 17, 4, -5 }, // 0x2C ',' + { 284, 15, 3, 18, 1, -11 }, // 0x2D '-' + { 290, 6, 6, 17, 4, -5 }, // 0x2E '.' + { 295, 15, 21, 18, 1, -20 }, // 0x2F '/' + { 335, 15, 21, 18, 1, -20 }, // 0x30 '0' + { 375, 9, 21, 18, 4, -20 }, // 0x31 '1' + { 399, 15, 21, 18, 1, -20 }, // 0x32 '2' + { 439, 15, 21, 18, 1, -20 }, // 0x33 '3' + { 479, 15, 21, 18, 1, -20 }, // 0x34 '4' + { 519, 15, 21, 18, 1, -20 }, // 0x35 '5' + { 559, 15, 21, 18, 1, -20 }, // 0x36 '6' + { 599, 15, 21, 18, 1, -20 }, // 0x37 '7' + { 639, 15, 21, 18, 1, -20 }, // 0x38 '8' + { 679, 15, 21, 18, 1, -20 }, // 0x39 '9' + { 719, 6, 18, 17, 4, -17 }, // 0x3A ':' + { 733, 6, 21, 17, 4, -17 }, // 0x3B ';' + { 749, 12, 21, 17, 1, -20 }, // 0x3C '<' + { 781, 15, 9, 18, 1, -14 }, // 0x3D '=' + { 798, 12, 21, 18, 4, -20 }, // 0x3E '>' + { 830, 15, 21, 18, 1, -20 }, // 0x3F '?' + { 870, 15, 21, 18, 1, -20 }, // 0x40 '@' + { 910, 15, 21, 18, 1, -20 }, // 0x41 'A' + { 950, 15, 21, 18, 1, -20 }, // 0x42 'B' + { 990, 15, 21, 18, 1, -20 }, // 0x43 'C' + { 1030, 15, 21, 18, 1, -20 }, // 0x44 'D' + { 1070, 15, 21, 18, 1, -20 }, // 0x45 'E' + { 1110, 15, 21, 18, 1, -20 }, // 0x46 'F' + { 1150, 15, 21, 18, 1, -20 }, // 0x47 'G' + { 1190, 15, 21, 18, 1, -20 }, // 0x48 'H' + { 1230, 9, 21, 17, 4, -20 }, // 0x49 'I' + { 1254, 15, 21, 18, 1, -20 }, // 0x4A 'J' + { 1294, 15, 21, 18, 1, -20 }, // 0x4B 'K' + { 1334, 15, 21, 18, 1, -20 }, // 0x4C 'L' + { 1374, 15, 21, 18, 1, -20 }, // 0x4D 'M' + { 1414, 15, 21, 18, 1, -20 }, // 0x4E 'N' + { 1454, 15, 21, 18, 1, -20 }, // 0x4F 'O' + { 1494, 15, 21, 18, 1, -20 }, // 0x50 'P' + { 1534, 15, 21, 18, 1, -20 }, // 0x51 'Q' + { 1574, 15, 21, 18, 1, -20 }, // 0x52 'R' + { 1614, 15, 21, 18, 1, -20 }, // 0x53 'S' + { 1654, 15, 21, 18, 1, -20 }, // 0x54 'T' + { 1694, 15, 21, 18, 1, -20 }, // 0x55 'U' + { 1734, 15, 21, 18, 1, -20 }, // 0x56 'V' + { 1774, 15, 21, 18, 1, -20 }, // 0x57 'W' + { 1814, 15, 21, 18, 1, -20 }, // 0x58 'X' + { 1854, 15, 21, 18, 1, -20 }, // 0x59 'Y' + { 1894, 15, 21, 18, 1, -20 }, // 0x5A 'Z' + { 1934, 6, 21, 17, 7, -20 }, // 0x5B '[' + { 1950, 15, 21, 18, 1, -20 }, // 0x5C '\' + { 1990, 6, 21, 17, 4, -20 }, // 0x5D ']' + { 2006, 15, 9, 18, 1, -20 }, // 0x5E '^' + { 2023, 15, 3, 18, 1, 1 }, // 0x5F '_' + { 2029, 6, 6, 17, 7, -20 }, // 0x60 '`' + { 2034, 15, 15, 18, 1, -14 }, // 0x61 'a' + { 2063, 15, 21, 18, 1, -20 }, // 0x62 'b' + { 2103, 15, 15, 18, 1, -14 }, // 0x63 'c' + { 2132, 15, 21, 18, 1, -20 }, // 0x64 'd' + { 2172, 15, 15, 18, 1, -14 }, // 0x65 'e' + { 2201, 12, 21, 18, 4, -20 }, // 0x66 'f' + { 2233, 15, 18, 18, 1, -14 }, // 0x67 'g' + { 2267, 15, 21, 18, 1, -20 }, // 0x68 'h' + { 2307, 9, 21, 17, 4, -20 }, // 0x69 'i' + { 2331, 12, 24, 17, 1, -20 }, // 0x6A 'j' + { 2367, 12, 21, 18, 4, -20 }, // 0x6B 'k' + { 2399, 9, 21, 17, 4, -20 }, // 0x6C 'l' + { 2423, 15, 15, 18, 1, -14 }, // 0x6D 'm' + { 2452, 15, 15, 18, 1, -14 }, // 0x6E 'n' + { 2481, 15, 15, 18, 1, -14 }, // 0x6F 'o' + { 2510, 15, 18, 18, 1, -14 }, // 0x70 'p' + { 2544, 15, 18, 18, 1, -14 }, // 0x71 'q' + { 2578, 12, 15, 18, 4, -14 }, // 0x72 'r' + { 2601, 15, 15, 18, 1, -14 }, // 0x73 's' + { 2630, 12, 21, 18, 4, -20 }, // 0x74 't' + { 2662, 15, 15, 18, 1, -14 }, // 0x75 'u' + { 2691, 15, 15, 18, 1, -14 }, // 0x76 'v' + { 2720, 15, 15, 18, 1, -14 }, // 0x77 'w' + { 2749, 15, 15, 18, 1, -14 }, // 0x78 'x' + { 2778, 15, 18, 18, 1, -14 }, // 0x79 'y' + { 2812, 15, 15, 18, 1, -14 }, // 0x7A 'z' + { 2841, 9, 21, 17, 4, -20 }, // 0x7B '{' + { 2865, 3, 21, 17, 7, -20 }, // 0x7C '|' + { 2873, 9, 21, 17, 4, -20 }, // 0x7D '}' + { 2897, 15, 9, 18, 1, -20 } }; // 0x7E '~' const GFXfont whitrabt16pt7b PROGMEM = { (uint8_t *)whitrabt16pt7bBitmaps, (GFXglyph *)whitrabt16pt7bGlyphs, - 0x20, 0x7E, 24 }; + 0x20, 0x7E, 24 }; // Approx. 3586 bytes +#endif // ifndef FONTS_WHITRABT16PT7B_H diff --git a/src/src/Static/Fonts/whitrabt18pt7b.h b/src/src/Static/Fonts/whitrabt18pt7b.h index e61363dd9..a76d52dc0 100644 --- a/src/src/Static/Fonts/whitrabt18pt7b.h +++ b/src/src/Static/Fonts/whitrabt18pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_WHITRABT18PT7B_H +#define FONTS_WHITRABT18PT7B_H const uint8_t whitrabt18pt7bBitmaps[] PROGMEM = { 0x00, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xC0, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xE1, 0xF8, @@ -311,105 +313,106 @@ const uint8_t whitrabt18pt7bBitmaps[] PROGMEM = { 0x0E, 0x1F, 0x07, 0x9E, 0x01, 0xFE, 0x00, 0x7E, 0x00, 0x1E, 0x00 }; const GFXglyph whitrabt18pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 20, 0, 0 }, // 0x20 ' ' - { 1, 7, 24, 20, 5, -23 }, // 0x21 '!' - { 22, 10, 7, 20, 5, -23 }, // 0x22 '"' - { 31, 17, 24, 21, 2, -23 }, // 0x23 '#' - { 82, 17, 24, 21, 2, -23 }, // 0x24 '$' - { 133, 17, 24, 21, 2, -23 }, // 0x25 '%' - { 184, 17, 24, 21, 2, -23 }, // 0x26 '&' - { 235, 3, 7, 19, 8, -23 }, // 0x27 ''' - { 238, 7, 24, 20, 8, -23 }, // 0x28 '(' - { 259, 7, 24, 20, 5, -23 }, // 0x29 ')' - { 280, 17, 17, 21, 2, -23 }, // 0x2A '*' - { 317, 17, 17, 21, 2, -19 }, // 0x2B '+' - { 354, 7, 10, 20, 5, -6 }, // 0x2C ',' - { 363, 17, 3, 21, 2, -12 }, // 0x2D '-' - { 370, 7, 7, 20, 5, -6 }, // 0x2E '.' - { 377, 17, 24, 21, 2, -23 }, // 0x2F '/' - { 428, 17, 24, 20, 2, -23 }, // 0x30 '0' - { 479, 10, 24, 20, 5, -23 }, // 0x31 '1' - { 509, 17, 24, 20, 2, -23 }, // 0x32 '2' - { 560, 17, 24, 20, 2, -23 }, // 0x33 '3' - { 611, 17, 24, 20, 2, -23 }, // 0x34 '4' - { 662, 17, 24, 20, 2, -23 }, // 0x35 '5' - { 713, 17, 24, 20, 2, -23 }, // 0x36 '6' - { 764, 17, 24, 20, 1, -23 }, // 0x37 '7' - { 815, 17, 24, 20, 2, -23 }, // 0x38 '8' - { 866, 17, 24, 20, 2, -23 }, // 0x39 '9' - { 917, 7, 20, 20, 5, -19 }, // 0x3A ':' - { 935, 7, 24, 20, 5, -20 }, // 0x3B ';' - { 956, 14, 24, 21, 2, -23 }, // 0x3C '<' - { 998, 17, 10, 21, 2, -16 }, // 0x3D '=' - { 1020, 14, 24, 20, 5, -23 }, // 0x3E '>' - { 1062, 17, 24, 21, 2, -23 }, // 0x3F '?' - { 1113, 17, 24, 21, 2, -23 }, // 0x40 '@' - { 1164, 17, 24, 21, 2, -23 }, // 0x41 'A' - { 1215, 17, 24, 21, 2, -23 }, // 0x42 'B' - { 1266, 17, 24, 21, 2, -23 }, // 0x43 'C' - { 1317, 17, 24, 21, 2, -23 }, // 0x44 'D' - { 1368, 17, 24, 21, 2, -23 }, // 0x45 'E' - { 1419, 17, 24, 21, 2, -23 }, // 0x46 'F' - { 1470, 17, 24, 21, 2, -23 }, // 0x47 'G' - { 1521, 17, 24, 21, 2, -23 }, // 0x48 'H' - { 1572, 10, 24, 20, 5, -23 }, // 0x49 'I' - { 1602, 17, 24, 21, 2, -23 }, // 0x4A 'J' - { 1653, 17, 24, 21, 2, -23 }, // 0x4B 'K' - { 1704, 17, 24, 21, 2, -23 }, // 0x4C 'L' - { 1755, 17, 24, 21, 2, -23 }, // 0x4D 'M' - { 1806, 17, 24, 21, 2, -23 }, // 0x4E 'N' - { 1857, 17, 24, 21, 2, -23 }, // 0x4F 'O' - { 1908, 17, 24, 21, 2, -23 }, // 0x50 'P' - { 1959, 17, 24, 21, 2, -23 }, // 0x51 'Q' - { 2010, 17, 24, 21, 2, -23 }, // 0x52 'R' - { 2061, 17, 24, 21, 2, -23 }, // 0x53 'S' - { 2112, 17, 24, 21, 2, -23 }, // 0x54 'T' - { 2163, 17, 24, 21, 2, -23 }, // 0x55 'U' - { 2214, 17, 24, 21, 2, -23 }, // 0x56 'V' - { 2265, 17, 24, 21, 2, -23 }, // 0x57 'W' - { 2316, 17, 24, 21, 2, -23 }, // 0x58 'X' - { 2367, 17, 24, 21, 2, -23 }, // 0x59 'Y' - { 2418, 17, 24, 21, 2, -23 }, // 0x5A 'Z' - { 2469, 7, 24, 20, 8, -23 }, // 0x5B '[' - { 2490, 17, 24, 21, 2, -23 }, // 0x5C '\' - { 2541, 7, 24, 20, 5, -23 }, // 0x5D ']' - { 2562, 17, 10, 21, 2, -23 }, // 0x5E '^' - { 2584, 17, 3, 21, 2, 1 }, // 0x5F '_' - { 2591, 7, 7, 20, 8, -23 }, // 0x60 '`' - { 2598, 17, 17, 21, 2, -16 }, // 0x61 'a' - { 2635, 17, 24, 21, 2, -23 }, // 0x62 'b' - { 2686, 17, 17, 21, 2, -16 }, // 0x63 'c' - { 2723, 17, 24, 21, 2, -23 }, // 0x64 'd' - { 2774, 17, 17, 21, 2, -16 }, // 0x65 'e' - { 2811, 14, 24, 20, 5, -23 }, // 0x66 'f' - { 2853, 17, 20, 21, 2, -16 }, // 0x67 'g' - { 2896, 17, 24, 21, 2, -23 }, // 0x68 'h' - { 2947, 10, 24, 20, 5, -23 }, // 0x69 'i' - { 2977, 13, 27, 20, 2, -23 }, // 0x6A 'j' - { 3021, 14, 24, 20, 5, -23 }, // 0x6B 'k' - { 3063, 10, 24, 20, 5, -23 }, // 0x6C 'l' - { 3093, 17, 17, 21, 2, -16 }, // 0x6D 'm' - { 3130, 17, 17, 21, 2, -16 }, // 0x6E 'n' - { 3167, 17, 17, 21, 2, -16 }, // 0x6F 'o' - { 3204, 17, 20, 21, 2, -16 }, // 0x70 'p' - { 3247, 17, 20, 21, 2, -16 }, // 0x71 'q' - { 3290, 13, 17, 20, 5, -16 }, // 0x72 'r' - { 3318, 17, 17, 21, 2, -16 }, // 0x73 's' - { 3355, 13, 24, 20, 5, -23 }, // 0x74 't' - { 3394, 17, 17, 21, 2, -16 }, // 0x75 'u' - { 3431, 17, 17, 21, 2, -16 }, // 0x76 'v' - { 3468, 17, 17, 21, 2, -16 }, // 0x77 'w' - { 3505, 17, 17, 21, 2, -16 }, // 0x78 'x' - { 3542, 17, 20, 21, 2, -16 }, // 0x79 'y' - { 3585, 17, 17, 21, 2, -16 }, // 0x7A 'z' - { 3622, 11, 24, 21, 5, -23 }, // 0x7B '{' - { 3655, 3, 24, 19, 8, -23 }, // 0x7C '|' - { 3664, 11, 24, 21, 5, -23 }, // 0x7D '}' - { 3697, 17, 10, 21, 2, -23 } }; // 0x7E '~' + { 0, 1, 1, 20, 0, 0 }, // 0x20 ' ' + { 1, 7, 24, 20, 5, -23 }, // 0x21 '!' + { 22, 10, 7, 20, 5, -23 }, // 0x22 '"' + { 31, 17, 24, 21, 2, -23 }, // 0x23 '#' + { 82, 17, 24, 21, 2, -23 }, // 0x24 '$' + { 133, 17, 24, 21, 2, -23 }, // 0x25 '%' + { 184, 17, 24, 21, 2, -23 }, // 0x26 '&' + { 235, 3, 7, 19, 8, -23 }, // 0x27 ''' + { 238, 7, 24, 20, 8, -23 }, // 0x28 '(' + { 259, 7, 24, 20, 5, -23 }, // 0x29 ')' + { 280, 17, 17, 21, 2, -23 }, // 0x2A '*' + { 317, 17, 17, 21, 2, -19 }, // 0x2B '+' + { 354, 7, 10, 20, 5, -6 }, // 0x2C ',' + { 363, 17, 3, 21, 2, -12 }, // 0x2D '-' + { 370, 7, 7, 20, 5, -6 }, // 0x2E '.' + { 377, 17, 24, 21, 2, -23 }, // 0x2F '/' + { 428, 17, 24, 20, 2, -23 }, // 0x30 '0' + { 479, 10, 24, 20, 5, -23 }, // 0x31 '1' + { 509, 17, 24, 20, 2, -23 }, // 0x32 '2' + { 560, 17, 24, 20, 2, -23 }, // 0x33 '3' + { 611, 17, 24, 20, 2, -23 }, // 0x34 '4' + { 662, 17, 24, 20, 2, -23 }, // 0x35 '5' + { 713, 17, 24, 20, 2, -23 }, // 0x36 '6' + { 764, 17, 24, 20, 1, -23 }, // 0x37 '7' + { 815, 17, 24, 20, 2, -23 }, // 0x38 '8' + { 866, 17, 24, 20, 2, -23 }, // 0x39 '9' + { 917, 7, 20, 20, 5, -19 }, // 0x3A ':' + { 935, 7, 24, 20, 5, -20 }, // 0x3B ';' + { 956, 14, 24, 21, 2, -23 }, // 0x3C '<' + { 998, 17, 10, 21, 2, -16 }, // 0x3D '=' + { 1020, 14, 24, 20, 5, -23 }, // 0x3E '>' + { 1062, 17, 24, 21, 2, -23 }, // 0x3F '?' + { 1113, 17, 24, 21, 2, -23 }, // 0x40 '@' + { 1164, 17, 24, 21, 2, -23 }, // 0x41 'A' + { 1215, 17, 24, 21, 2, -23 }, // 0x42 'B' + { 1266, 17, 24, 21, 2, -23 }, // 0x43 'C' + { 1317, 17, 24, 21, 2, -23 }, // 0x44 'D' + { 1368, 17, 24, 21, 2, -23 }, // 0x45 'E' + { 1419, 17, 24, 21, 2, -23 }, // 0x46 'F' + { 1470, 17, 24, 21, 2, -23 }, // 0x47 'G' + { 1521, 17, 24, 21, 2, -23 }, // 0x48 'H' + { 1572, 10, 24, 20, 5, -23 }, // 0x49 'I' + { 1602, 17, 24, 21, 2, -23 }, // 0x4A 'J' + { 1653, 17, 24, 21, 2, -23 }, // 0x4B 'K' + { 1704, 17, 24, 21, 2, -23 }, // 0x4C 'L' + { 1755, 17, 24, 21, 2, -23 }, // 0x4D 'M' + { 1806, 17, 24, 21, 2, -23 }, // 0x4E 'N' + { 1857, 17, 24, 21, 2, -23 }, // 0x4F 'O' + { 1908, 17, 24, 21, 2, -23 }, // 0x50 'P' + { 1959, 17, 24, 21, 2, -23 }, // 0x51 'Q' + { 2010, 17, 24, 21, 2, -23 }, // 0x52 'R' + { 2061, 17, 24, 21, 2, -23 }, // 0x53 'S' + { 2112, 17, 24, 21, 2, -23 }, // 0x54 'T' + { 2163, 17, 24, 21, 2, -23 }, // 0x55 'U' + { 2214, 17, 24, 21, 2, -23 }, // 0x56 'V' + { 2265, 17, 24, 21, 2, -23 }, // 0x57 'W' + { 2316, 17, 24, 21, 2, -23 }, // 0x58 'X' + { 2367, 17, 24, 21, 2, -23 }, // 0x59 'Y' + { 2418, 17, 24, 21, 2, -23 }, // 0x5A 'Z' + { 2469, 7, 24, 20, 8, -23 }, // 0x5B '[' + { 2490, 17, 24, 21, 2, -23 }, // 0x5C '\' + { 2541, 7, 24, 20, 5, -23 }, // 0x5D ']' + { 2562, 17, 10, 21, 2, -23 }, // 0x5E '^' + { 2584, 17, 3, 21, 2, 1 }, // 0x5F '_' + { 2591, 7, 7, 20, 8, -23 }, // 0x60 '`' + { 2598, 17, 17, 21, 2, -16 }, // 0x61 'a' + { 2635, 17, 24, 21, 2, -23 }, // 0x62 'b' + { 2686, 17, 17, 21, 2, -16 }, // 0x63 'c' + { 2723, 17, 24, 21, 2, -23 }, // 0x64 'd' + { 2774, 17, 17, 21, 2, -16 }, // 0x65 'e' + { 2811, 14, 24, 20, 5, -23 }, // 0x66 'f' + { 2853, 17, 20, 21, 2, -16 }, // 0x67 'g' + { 2896, 17, 24, 21, 2, -23 }, // 0x68 'h' + { 2947, 10, 24, 20, 5, -23 }, // 0x69 'i' + { 2977, 13, 27, 20, 2, -23 }, // 0x6A 'j' + { 3021, 14, 24, 20, 5, -23 }, // 0x6B 'k' + { 3063, 10, 24, 20, 5, -23 }, // 0x6C 'l' + { 3093, 17, 17, 21, 2, -16 }, // 0x6D 'm' + { 3130, 17, 17, 21, 2, -16 }, // 0x6E 'n' + { 3167, 17, 17, 21, 2, -16 }, // 0x6F 'o' + { 3204, 17, 20, 21, 2, -16 }, // 0x70 'p' + { 3247, 17, 20, 21, 2, -16 }, // 0x71 'q' + { 3290, 13, 17, 20, 5, -16 }, // 0x72 'r' + { 3318, 17, 17, 21, 2, -16 }, // 0x73 's' + { 3355, 13, 24, 20, 5, -23 }, // 0x74 't' + { 3394, 17, 17, 21, 2, -16 }, // 0x75 'u' + { 3431, 17, 17, 21, 2, -16 }, // 0x76 'v' + { 3468, 17, 17, 21, 2, -16 }, // 0x77 'w' + { 3505, 17, 17, 21, 2, -16 }, // 0x78 'x' + { 3542, 17, 20, 21, 2, -16 }, // 0x79 'y' + { 3585, 17, 17, 21, 2, -16 }, // 0x7A 'z' + { 3622, 11, 24, 21, 5, -23 }, // 0x7B '{' + { 3655, 3, 24, 19, 8, -23 }, // 0x7C '|' + { 3664, 11, 24, 21, 5, -23 }, // 0x7D '}' + { 3697, 17, 10, 21, 2, -23 } }; // 0x7E '~' const GFXfont whitrabt18pt7b PROGMEM = { (uint8_t *)whitrabt18pt7bBitmaps, (GFXglyph *)whitrabt18pt7bGlyphs, - 0x20, 0x7E, 27 }; + 0x20, 0x7E, 27 }; // Approx. 4391 bytes +#endif // ifndef FONTS_WHITRABT18PT7B_H diff --git a/src/src/Static/Fonts/whitrabt20pt7b.h b/src/src/Static/Fonts/whitrabt20pt7b.h index 83f96984c..311b7f8b0 100644 --- a/src/src/Static/Fonts/whitrabt20pt7b.h +++ b/src/src/Static/Fonts/whitrabt20pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_WHITRABT20PT7B_H +#define FONTS_WHITRABT20PT7B_H const uint8_t whitrabt20pt7bBitmaps[] PROGMEM = { 0x00, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xDF, 0xFF, 0xFF, 0xFF, 0xFD, @@ -391,105 +393,106 @@ const uint8_t whitrabt20pt7bBitmaps[] PROGMEM = { 0x7C, 0x07, 0xFF, 0x00, 0xFF, 0x80, 0x1F, 0xC0, 0x03, 0xE0 }; const GFXglyph whitrabt20pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 22, 0, 0 }, // 0x20 ' ' - { 1, 7, 27, 22, 6, -26 }, // 0x21 '!' - { 25, 11, 7, 23, 6, -26 }, // 0x22 '"' - { 35, 19, 27, 23, 2, -26 }, // 0x23 '#' - { 100, 18, 27, 22, 2, -26 }, // 0x24 '$' - { 161, 18, 27, 22, 2, -26 }, // 0x25 '%' - { 222, 19, 27, 22, 2, -26 }, // 0x26 '&' - { 287, 4, 7, 22, 9, -26 }, // 0x27 ''' - { 291, 8, 27, 22, 9, -26 }, // 0x28 '(' - { 318, 8, 27, 22, 5, -26 }, // 0x29 ')' - { 345, 19, 20, 23, 2, -26 }, // 0x2A '*' - { 393, 19, 19, 23, 2, -22 }, // 0x2B '+' - { 439, 7, 11, 22, 6, -6 }, // 0x2C ',' - { 449, 19, 4, 23, 2, -14 }, // 0x2D '-' - { 459, 7, 7, 22, 6, -6 }, // 0x2E '.' - { 466, 19, 27, 23, 2, -26 }, // 0x2F '/' - { 531, 19, 27, 22, 2, -26 }, // 0x30 '0' - { 596, 11, 27, 22, 6, -26 }, // 0x31 '1' - { 634, 19, 27, 22, 2, -26 }, // 0x32 '2' - { 699, 19, 27, 22, 2, -26 }, // 0x33 '3' - { 764, 19, 27, 22, 2, -26 }, // 0x34 '4' - { 829, 19, 27, 22, 2, -26 }, // 0x35 '5' - { 894, 19, 27, 22, 2, -26 }, // 0x36 '6' - { 959, 19, 27, 22, 2, -26 }, // 0x37 '7' - { 1024, 19, 27, 22, 2, -26 }, // 0x38 '8' - { 1089, 19, 27, 22, 2, -26 }, // 0x39 '9' - { 1154, 7, 23, 22, 6, -22 }, // 0x3A ':' - { 1175, 7, 26, 22, 6, -21 }, // 0x3B ';' - { 1198, 15, 27, 23, 2, -26 }, // 0x3C '<' - { 1249, 19, 12, 23, 2, -18 }, // 0x3D '=' - { 1278, 15, 27, 23, 6, -26 }, // 0x3E '>' - { 1329, 18, 27, 22, 2, -26 }, // 0x3F '?' - { 1390, 18, 27, 22, 2, -26 }, // 0x40 '@' - { 1451, 19, 27, 23, 2, -26 }, // 0x41 'A' - { 1516, 19, 27, 23, 2, -26 }, // 0x42 'B' - { 1581, 19, 27, 23, 2, -26 }, // 0x43 'C' - { 1646, 19, 27, 23, 2, -26 }, // 0x44 'D' - { 1711, 19, 27, 22, 2, -26 }, // 0x45 'E' - { 1776, 19, 27, 22, 2, -26 }, // 0x46 'F' - { 1841, 19, 27, 23, 2, -26 }, // 0x47 'G' - { 1906, 19, 27, 23, 2, -26 }, // 0x48 'H' - { 1971, 11, 27, 23, 6, -26 }, // 0x49 'I' - { 2009, 19, 27, 23, 2, -26 }, // 0x4A 'J' - { 2074, 19, 27, 22, 2, -26 }, // 0x4B 'K' - { 2139, 19, 27, 22, 2, -26 }, // 0x4C 'L' - { 2204, 19, 27, 23, 2, -26 }, // 0x4D 'M' - { 2269, 19, 27, 23, 2, -26 }, // 0x4E 'N' - { 2334, 19, 27, 23, 2, -26 }, // 0x4F 'O' - { 2399, 19, 27, 23, 2, -26 }, // 0x50 'P' - { 2464, 19, 27, 23, 2, -26 }, // 0x51 'Q' - { 2529, 19, 27, 23, 2, -26 }, // 0x52 'R' - { 2594, 19, 27, 23, 2, -26 }, // 0x53 'S' - { 2659, 19, 27, 23, 2, -26 }, // 0x54 'T' - { 2724, 19, 27, 23, 2, -26 }, // 0x55 'U' - { 2789, 19, 27, 23, 2, -26 }, // 0x56 'V' - { 2854, 18, 27, 22, 2, -26 }, // 0x57 'W' - { 2915, 19, 27, 23, 2, -26 }, // 0x58 'X' - { 2980, 18, 27, 22, 2, -26 }, // 0x59 'Y' - { 3041, 19, 27, 23, 2, -26 }, // 0x5A 'Z' - { 3106, 8, 27, 22, 9, -26 }, // 0x5B '[' - { 3133, 19, 27, 23, 2, -26 }, // 0x5C '\' - { 3198, 8, 27, 22, 5, -26 }, // 0x5D ']' - { 3225, 19, 12, 23, 2, -26 }, // 0x5E '^' - { 3254, 19, 4, 23, 2, 1 }, // 0x5F '_' - { 3264, 8, 8, 22, 9, -26 }, // 0x60 '`' - { 3272, 19, 19, 23, 2, -18 }, // 0x61 'a' - { 3318, 19, 27, 23, 2, -26 }, // 0x62 'b' - { 3383, 19, 19, 23, 2, -18 }, // 0x63 'c' - { 3429, 19, 27, 23, 2, -26 }, // 0x64 'd' - { 3494, 19, 19, 23, 2, -18 }, // 0x65 'e' - { 3540, 15, 27, 23, 6, -26 }, // 0x66 'f' - { 3591, 19, 23, 23, 2, -18 }, // 0x67 'g' - { 3646, 19, 27, 23, 2, -26 }, // 0x68 'h' - { 3711, 11, 27, 23, 6, -26 }, // 0x69 'i' - { 3749, 15, 31, 23, 2, -26 }, // 0x6A 'j' - { 3808, 15, 27, 23, 6, -26 }, // 0x6B 'k' - { 3859, 11, 27, 23, 6, -26 }, // 0x6C 'l' - { 3897, 18, 19, 22, 2, -18 }, // 0x6D 'm' - { 3940, 19, 19, 23, 2, -18 }, // 0x6E 'n' - { 3986, 19, 19, 23, 2, -18 }, // 0x6F 'o' - { 4032, 19, 23, 23, 2, -18 }, // 0x70 'p' - { 4087, 19, 23, 23, 2, -18 }, // 0x71 'q' - { 4142, 15, 19, 23, 6, -18 }, // 0x72 'r' - { 4178, 19, 19, 23, 2, -18 }, // 0x73 's' - { 4224, 15, 27, 23, 6, -26 }, // 0x74 't' - { 4275, 19, 19, 23, 2, -18 }, // 0x75 'u' - { 4321, 19, 19, 23, 2, -18 }, // 0x76 'v' - { 4367, 18, 19, 22, 2, -18 }, // 0x77 'w' - { 4410, 19, 19, 23, 2, -18 }, // 0x78 'x' - { 4456, 19, 23, 23, 2, -18 }, // 0x79 'y' - { 4511, 19, 19, 23, 2, -18 }, // 0x7A 'z' - { 4557, 12, 27, 22, 5, -26 }, // 0x7B '{' - { 4598, 4, 27, 22, 9, -26 }, // 0x7C '|' - { 4612, 12, 27, 22, 5, -26 }, // 0x7D '}' - { 4653, 18, 11, 22, 2, -25 } }; // 0x7E '~' + { 0, 1, 1, 22, 0, 0 }, // 0x20 ' ' + { 1, 7, 27, 22, 6, -26 }, // 0x21 '!' + { 25, 11, 7, 23, 6, -26 }, // 0x22 '"' + { 35, 19, 27, 23, 2, -26 }, // 0x23 '#' + { 100, 18, 27, 22, 2, -26 }, // 0x24 '$' + { 161, 18, 27, 22, 2, -26 }, // 0x25 '%' + { 222, 19, 27, 22, 2, -26 }, // 0x26 '&' + { 287, 4, 7, 22, 9, -26 }, // 0x27 ''' + { 291, 8, 27, 22, 9, -26 }, // 0x28 '(' + { 318, 8, 27, 22, 5, -26 }, // 0x29 ')' + { 345, 19, 20, 23, 2, -26 }, // 0x2A '*' + { 393, 19, 19, 23, 2, -22 }, // 0x2B '+' + { 439, 7, 11, 22, 6, -6 }, // 0x2C ',' + { 449, 19, 4, 23, 2, -14 }, // 0x2D '-' + { 459, 7, 7, 22, 6, -6 }, // 0x2E '.' + { 466, 19, 27, 23, 2, -26 }, // 0x2F '/' + { 531, 19, 27, 22, 2, -26 }, // 0x30 '0' + { 596, 11, 27, 22, 6, -26 }, // 0x31 '1' + { 634, 19, 27, 22, 2, -26 }, // 0x32 '2' + { 699, 19, 27, 22, 2, -26 }, // 0x33 '3' + { 764, 19, 27, 22, 2, -26 }, // 0x34 '4' + { 829, 19, 27, 22, 2, -26 }, // 0x35 '5' + { 894, 19, 27, 22, 2, -26 }, // 0x36 '6' + { 959, 19, 27, 22, 2, -26 }, // 0x37 '7' + { 1024, 19, 27, 22, 2, -26 }, // 0x38 '8' + { 1089, 19, 27, 22, 2, -26 }, // 0x39 '9' + { 1154, 7, 23, 22, 6, -22 }, // 0x3A ':' + { 1175, 7, 26, 22, 6, -21 }, // 0x3B ';' + { 1198, 15, 27, 23, 2, -26 }, // 0x3C '<' + { 1249, 19, 12, 23, 2, -18 }, // 0x3D '=' + { 1278, 15, 27, 23, 6, -26 }, // 0x3E '>' + { 1329, 18, 27, 22, 2, -26 }, // 0x3F '?' + { 1390, 18, 27, 22, 2, -26 }, // 0x40 '@' + { 1451, 19, 27, 23, 2, -26 }, // 0x41 'A' + { 1516, 19, 27, 23, 2, -26 }, // 0x42 'B' + { 1581, 19, 27, 23, 2, -26 }, // 0x43 'C' + { 1646, 19, 27, 23, 2, -26 }, // 0x44 'D' + { 1711, 19, 27, 22, 2, -26 }, // 0x45 'E' + { 1776, 19, 27, 22, 2, -26 }, // 0x46 'F' + { 1841, 19, 27, 23, 2, -26 }, // 0x47 'G' + { 1906, 19, 27, 23, 2, -26 }, // 0x48 'H' + { 1971, 11, 27, 23, 6, -26 }, // 0x49 'I' + { 2009, 19, 27, 23, 2, -26 }, // 0x4A 'J' + { 2074, 19, 27, 22, 2, -26 }, // 0x4B 'K' + { 2139, 19, 27, 22, 2, -26 }, // 0x4C 'L' + { 2204, 19, 27, 23, 2, -26 }, // 0x4D 'M' + { 2269, 19, 27, 23, 2, -26 }, // 0x4E 'N' + { 2334, 19, 27, 23, 2, -26 }, // 0x4F 'O' + { 2399, 19, 27, 23, 2, -26 }, // 0x50 'P' + { 2464, 19, 27, 23, 2, -26 }, // 0x51 'Q' + { 2529, 19, 27, 23, 2, -26 }, // 0x52 'R' + { 2594, 19, 27, 23, 2, -26 }, // 0x53 'S' + { 2659, 19, 27, 23, 2, -26 }, // 0x54 'T' + { 2724, 19, 27, 23, 2, -26 }, // 0x55 'U' + { 2789, 19, 27, 23, 2, -26 }, // 0x56 'V' + { 2854, 18, 27, 22, 2, -26 }, // 0x57 'W' + { 2915, 19, 27, 23, 2, -26 }, // 0x58 'X' + { 2980, 18, 27, 22, 2, -26 }, // 0x59 'Y' + { 3041, 19, 27, 23, 2, -26 }, // 0x5A 'Z' + { 3106, 8, 27, 22, 9, -26 }, // 0x5B '[' + { 3133, 19, 27, 23, 2, -26 }, // 0x5C '\' + { 3198, 8, 27, 22, 5, -26 }, // 0x5D ']' + { 3225, 19, 12, 23, 2, -26 }, // 0x5E '^' + { 3254, 19, 4, 23, 2, 1 }, // 0x5F '_' + { 3264, 8, 8, 22, 9, -26 }, // 0x60 '`' + { 3272, 19, 19, 23, 2, -18 }, // 0x61 'a' + { 3318, 19, 27, 23, 2, -26 }, // 0x62 'b' + { 3383, 19, 19, 23, 2, -18 }, // 0x63 'c' + { 3429, 19, 27, 23, 2, -26 }, // 0x64 'd' + { 3494, 19, 19, 23, 2, -18 }, // 0x65 'e' + { 3540, 15, 27, 23, 6, -26 }, // 0x66 'f' + { 3591, 19, 23, 23, 2, -18 }, // 0x67 'g' + { 3646, 19, 27, 23, 2, -26 }, // 0x68 'h' + { 3711, 11, 27, 23, 6, -26 }, // 0x69 'i' + { 3749, 15, 31, 23, 2, -26 }, // 0x6A 'j' + { 3808, 15, 27, 23, 6, -26 }, // 0x6B 'k' + { 3859, 11, 27, 23, 6, -26 }, // 0x6C 'l' + { 3897, 18, 19, 22, 2, -18 }, // 0x6D 'm' + { 3940, 19, 19, 23, 2, -18 }, // 0x6E 'n' + { 3986, 19, 19, 23, 2, -18 }, // 0x6F 'o' + { 4032, 19, 23, 23, 2, -18 }, // 0x70 'p' + { 4087, 19, 23, 23, 2, -18 }, // 0x71 'q' + { 4142, 15, 19, 23, 6, -18 }, // 0x72 'r' + { 4178, 19, 19, 23, 2, -18 }, // 0x73 's' + { 4224, 15, 27, 23, 6, -26 }, // 0x74 't' + { 4275, 19, 19, 23, 2, -18 }, // 0x75 'u' + { 4321, 19, 19, 23, 2, -18 }, // 0x76 'v' + { 4367, 18, 19, 22, 2, -18 }, // 0x77 'w' + { 4410, 19, 19, 23, 2, -18 }, // 0x78 'x' + { 4456, 19, 23, 23, 2, -18 }, // 0x79 'y' + { 4511, 19, 19, 23, 2, -18 }, // 0x7A 'z' + { 4557, 12, 27, 22, 5, -26 }, // 0x7B '{' + { 4598, 4, 27, 22, 9, -26 }, // 0x7C '|' + { 4612, 12, 27, 22, 5, -26 }, // 0x7D '}' + { 4653, 18, 11, 22, 2, -25 } }; // 0x7E '~' const GFXfont whitrabt20pt7b PROGMEM = { (uint8_t *)whitrabt20pt7bBitmaps, (GFXglyph *)whitrabt20pt7bGlyphs, - 0x20, 0x7E, 30 }; + 0x20, 0x7E, 30 }; // Approx. 5350 bytes +#endif // ifndef FONTS_WHITRABT20PT7B_H diff --git a/src/src/Static/Fonts/whitrabt8pt7b.h b/src/src/Static/Fonts/whitrabt8pt7b.h index 3cc51e8ac..85748d59f 100644 --- a/src/src/Static/Fonts/whitrabt8pt7b.h +++ b/src/src/Static/Fonts/whitrabt8pt7b.h @@ -1,3 +1,5 @@ +#ifndef FONTS_WHITRABT8PT7B_H +#define FONTS_WHITRABT8PT7B_H const uint8_t whitrabt8pt7bBitmaps[] PROGMEM = { 0x00, 0xFF, 0xFF, 0xC0, 0xFF, 0x80, 0xDE, 0xF6, 0x6C, 0xD9, 0xB7, 0xF6, 0xCD, 0xBF, 0xB6, 0x6C, 0xD9, 0xB0, 0x18, 0x18, 0x7F, 0xD8, 0xD8, 0x7E, @@ -69,105 +71,106 @@ const uint8_t whitrabt8pt7bBitmaps[] PROGMEM = { 0xDB, 0xDB, 0xDB, 0x0E }; const GFXglyph whitrabt8pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 9, 0, 0 }, // 0x20 ' ' - { 1, 3, 11, 9, 2, -10 }, // 0x21 '!' - { 6, 5, 3, 9, 2, -10 }, // 0x22 '"' - { 8, 7, 11, 9, 1, -10 }, // 0x23 '#' - { 18, 8, 11, 10, 1, -10 }, // 0x24 '$' - { 29, 8, 11, 10, 1, -10 }, // 0x25 '%' - { 40, 8, 11, 9, 1, -10 }, // 0x26 '&' - { 51, 2, 3, 10, 4, -10 }, // 0x27 ''' - { 52, 3, 11, 9, 4, -10 }, // 0x28 '(' - { 57, 4, 11, 10, 2, -10 }, // 0x29 ')' - { 63, 7, 7, 9, 1, -10 }, // 0x2A '*' - { 70, 7, 8, 9, 1, -9 }, // 0x2B '+' - { 77, 3, 5, 9, 2, -2 }, // 0x2C ',' - { 79, 7, 1, 9, 1, -5 }, // 0x2D '-' - { 80, 3, 3, 9, 2, -2 }, // 0x2E '.' - { 82, 8, 11, 10, 1, -10 }, // 0x2F '/' - { 93, 8, 11, 9, 1, -10 }, // 0x30 '0' - { 104, 5, 11, 9, 1, -10 }, // 0x31 '1' - { 111, 8, 11, 9, 1, -10 }, // 0x32 '2' - { 122, 8, 11, 9, 1, -10 }, // 0x33 '3' - { 133, 7, 11, 9, 1, -10 }, // 0x34 '4' - { 143, 8, 11, 9, 1, -10 }, // 0x35 '5' - { 154, 8, 11, 9, 1, -10 }, // 0x36 '6' - { 165, 8, 11, 9, 1, -10 }, // 0x37 '7' - { 176, 8, 11, 9, 1, -10 }, // 0x38 '8' - { 187, 8, 11, 9, 1, -10 }, // 0x39 '9' - { 198, 3, 9, 9, 2, -8 }, // 0x3A ':' - { 202, 3, 11, 9, 2, -8 }, // 0x3B ';' - { 207, 6, 11, 9, 1, -10 }, // 0x3C '<' - { 216, 7, 4, 9, 1, -7 }, // 0x3D '=' - { 220, 6, 11, 9, 2, -10 }, // 0x3E '>' - { 229, 8, 11, 10, 1, -10 }, // 0x3F '?' - { 240, 8, 11, 10, 1, -10 }, // 0x40 '@' - { 251, 8, 11, 10, 1, -10 }, // 0x41 'A' - { 262, 8, 11, 10, 1, -10 }, // 0x42 'B' - { 273, 8, 11, 10, 1, -10 }, // 0x43 'C' - { 284, 8, 11, 10, 1, -10 }, // 0x44 'D' - { 295, 8, 11, 10, 1, -10 }, // 0x45 'E' - { 306, 8, 11, 10, 1, -10 }, // 0x46 'F' - { 317, 8, 11, 10, 1, -10 }, // 0x47 'G' - { 328, 8, 11, 10, 1, -10 }, // 0x48 'H' - { 339, 4, 11, 8, 2, -10 }, // 0x49 'I' - { 345, 8, 11, 10, 1, -10 }, // 0x4A 'J' - { 356, 8, 11, 10, 1, -10 }, // 0x4B 'K' - { 367, 8, 11, 10, 1, -10 }, // 0x4C 'L' - { 378, 8, 11, 10, 1, -10 }, // 0x4D 'M' - { 389, 8, 11, 10, 1, -10 }, // 0x4E 'N' - { 400, 8, 11, 10, 1, -10 }, // 0x4F 'O' - { 411, 8, 11, 10, 1, -10 }, // 0x50 'P' - { 422, 8, 11, 10, 1, -10 }, // 0x51 'Q' - { 433, 8, 11, 10, 1, -10 }, // 0x52 'R' - { 444, 8, 11, 10, 1, -10 }, // 0x53 'S' - { 455, 7, 11, 9, 1, -10 }, // 0x54 'T' - { 465, 8, 11, 10, 1, -10 }, // 0x55 'U' - { 476, 8, 11, 10, 1, -10 }, // 0x56 'V' - { 487, 8, 11, 10, 1, -10 }, // 0x57 'W' - { 498, 8, 11, 10, 1, -10 }, // 0x58 'X' - { 509, 8, 11, 10, 1, -10 }, // 0x59 'Y' - { 520, 8, 11, 10, 1, -10 }, // 0x5A 'Z' - { 531, 4, 11, 10, 4, -10 }, // 0x5B '[' - { 537, 8, 11, 10, 1, -10 }, // 0x5C '\' - { 548, 4, 11, 10, 2, -10 }, // 0x5D ']' - { 554, 7, 5, 9, 1, -10 }, // 0x5E '^' - { 559, 7, 1, 9, 1, 1 }, // 0x5F '_' - { 560, 3, 3, 9, 4, -10 }, // 0x60 '`' - { 562, 8, 8, 10, 1, -7 }, // 0x61 'a' - { 570, 8, 11, 10, 1, -10 }, // 0x62 'b' - { 581, 8, 8, 10, 1, -7 }, // 0x63 'c' - { 589, 8, 11, 10, 1, -10 }, // 0x64 'd' - { 600, 8, 8, 10, 1, -7 }, // 0x65 'e' - { 608, 6, 11, 9, 2, -10 }, // 0x66 'f' - { 617, 8, 10, 10, 1, -7 }, // 0x67 'g' - { 627, 8, 11, 10, 1, -10 }, // 0x68 'h' - { 638, 5, 11, 8, 1, -10 }, // 0x69 'i' - { 645, 6, 13, 9, 1, -10 }, // 0x6A 'j' - { 655, 6, 11, 9, 2, -10 }, // 0x6B 'k' - { 664, 5, 11, 8, 1, -10 }, // 0x6C 'l' - { 671, 8, 8, 10, 1, -7 }, // 0x6D 'm' - { 679, 8, 8, 10, 1, -7 }, // 0x6E 'n' - { 687, 8, 8, 10, 1, -7 }, // 0x6F 'o' - { 695, 8, 10, 10, 1, -7 }, // 0x70 'p' - { 705, 8, 10, 10, 1, -7 }, // 0x71 'q' - { 715, 6, 8, 9, 2, -7 }, // 0x72 'r' - { 721, 8, 8, 10, 1, -7 }, // 0x73 's' - { 729, 6, 11, 9, 2, -10 }, // 0x74 't' - { 738, 8, 8, 10, 1, -7 }, // 0x75 'u' - { 746, 8, 8, 10, 1, -7 }, // 0x76 'v' - { 754, 8, 8, 10, 1, -7 }, // 0x77 'w' - { 762, 7, 8, 9, 1, -7 }, // 0x78 'x' - { 769, 8, 10, 10, 1, -7 }, // 0x79 'y' - { 779, 7, 8, 9, 1, -7 }, // 0x7A 'z' - { 786, 5, 11, 9, 2, -10 }, // 0x7B '{' - { 793, 2, 11, 10, 4, -10 }, // 0x7C '|' - { 796, 5, 11, 9, 2, -10 }, // 0x7D '}' - { 803, 8, 5, 10, 1, -11 } }; // 0x7E '~' + { 0, 1, 1, 9, 0, 0 }, // 0x20 ' ' + { 1, 3, 11, 9, 2, -10 }, // 0x21 '!' + { 6, 5, 3, 9, 2, -10 }, // 0x22 '"' + { 8, 7, 11, 9, 1, -10 }, // 0x23 '#' + { 18, 8, 11, 10, 1, -10 }, // 0x24 '$' + { 29, 8, 11, 10, 1, -10 }, // 0x25 '%' + { 40, 8, 11, 9, 1, -10 }, // 0x26 '&' + { 51, 2, 3, 10, 4, -10 }, // 0x27 ''' + { 52, 3, 11, 9, 4, -10 }, // 0x28 '(' + { 57, 4, 11, 10, 2, -10 }, // 0x29 ')' + { 63, 7, 7, 9, 1, -10 }, // 0x2A '*' + { 70, 7, 8, 9, 1, -9 }, // 0x2B '+' + { 77, 3, 5, 9, 2, -2 }, // 0x2C ',' + { 79, 7, 1, 9, 1, -5 }, // 0x2D '-' + { 80, 3, 3, 9, 2, -2 }, // 0x2E '.' + { 82, 8, 11, 10, 1, -10 }, // 0x2F '/' + { 93, 8, 11, 9, 1, -10 }, // 0x30 '0' + { 104, 5, 11, 9, 1, -10 }, // 0x31 '1' + { 111, 8, 11, 9, 1, -10 }, // 0x32 '2' + { 122, 8, 11, 9, 1, -10 }, // 0x33 '3' + { 133, 7, 11, 9, 1, -10 }, // 0x34 '4' + { 143, 8, 11, 9, 1, -10 }, // 0x35 '5' + { 154, 8, 11, 9, 1, -10 }, // 0x36 '6' + { 165, 8, 11, 9, 1, -10 }, // 0x37 '7' + { 176, 8, 11, 9, 1, -10 }, // 0x38 '8' + { 187, 8, 11, 9, 1, -10 }, // 0x39 '9' + { 198, 3, 9, 9, 2, -8 }, // 0x3A ':' + { 202, 3, 11, 9, 2, -8 }, // 0x3B ';' + { 207, 6, 11, 9, 1, -10 }, // 0x3C '<' + { 216, 7, 4, 9, 1, -7 }, // 0x3D '=' + { 220, 6, 11, 9, 2, -10 }, // 0x3E '>' + { 229, 8, 11, 10, 1, -10 }, // 0x3F '?' + { 240, 8, 11, 10, 1, -10 }, // 0x40 '@' + { 251, 8, 11, 10, 1, -10 }, // 0x41 'A' + { 262, 8, 11, 10, 1, -10 }, // 0x42 'B' + { 273, 8, 11, 10, 1, -10 }, // 0x43 'C' + { 284, 8, 11, 10, 1, -10 }, // 0x44 'D' + { 295, 8, 11, 10, 1, -10 }, // 0x45 'E' + { 306, 8, 11, 10, 1, -10 }, // 0x46 'F' + { 317, 8, 11, 10, 1, -10 }, // 0x47 'G' + { 328, 8, 11, 10, 1, -10 }, // 0x48 'H' + { 339, 4, 11, 8, 2, -10 }, // 0x49 'I' + { 345, 8, 11, 10, 1, -10 }, // 0x4A 'J' + { 356, 8, 11, 10, 1, -10 }, // 0x4B 'K' + { 367, 8, 11, 10, 1, -10 }, // 0x4C 'L' + { 378, 8, 11, 10, 1, -10 }, // 0x4D 'M' + { 389, 8, 11, 10, 1, -10 }, // 0x4E 'N' + { 400, 8, 11, 10, 1, -10 }, // 0x4F 'O' + { 411, 8, 11, 10, 1, -10 }, // 0x50 'P' + { 422, 8, 11, 10, 1, -10 }, // 0x51 'Q' + { 433, 8, 11, 10, 1, -10 }, // 0x52 'R' + { 444, 8, 11, 10, 1, -10 }, // 0x53 'S' + { 455, 7, 11, 9, 1, -10 }, // 0x54 'T' + { 465, 8, 11, 10, 1, -10 }, // 0x55 'U' + { 476, 8, 11, 10, 1, -10 }, // 0x56 'V' + { 487, 8, 11, 10, 1, -10 }, // 0x57 'W' + { 498, 8, 11, 10, 1, -10 }, // 0x58 'X' + { 509, 8, 11, 10, 1, -10 }, // 0x59 'Y' + { 520, 8, 11, 10, 1, -10 }, // 0x5A 'Z' + { 531, 4, 11, 10, 4, -10 }, // 0x5B '[' + { 537, 8, 11, 10, 1, -10 }, // 0x5C '\' + { 548, 4, 11, 10, 2, -10 }, // 0x5D ']' + { 554, 7, 5, 9, 1, -10 }, // 0x5E '^' + { 559, 7, 1, 9, 1, 1 }, // 0x5F '_' + { 560, 3, 3, 9, 4, -10 }, // 0x60 '`' + { 562, 8, 8, 10, 1, -7 }, // 0x61 'a' + { 570, 8, 11, 10, 1, -10 }, // 0x62 'b' + { 581, 8, 8, 10, 1, -7 }, // 0x63 'c' + { 589, 8, 11, 10, 1, -10 }, // 0x64 'd' + { 600, 8, 8, 10, 1, -7 }, // 0x65 'e' + { 608, 6, 11, 9, 2, -10 }, // 0x66 'f' + { 617, 8, 10, 10, 1, -7 }, // 0x67 'g' + { 627, 8, 11, 10, 1, -10 }, // 0x68 'h' + { 638, 5, 11, 8, 1, -10 }, // 0x69 'i' + { 645, 6, 13, 9, 1, -10 }, // 0x6A 'j' + { 655, 6, 11, 9, 2, -10 }, // 0x6B 'k' + { 664, 5, 11, 8, 1, -10 }, // 0x6C 'l' + { 671, 8, 8, 10, 1, -7 }, // 0x6D 'm' + { 679, 8, 8, 10, 1, -7 }, // 0x6E 'n' + { 687, 8, 8, 10, 1, -7 }, // 0x6F 'o' + { 695, 8, 10, 10, 1, -7 }, // 0x70 'p' + { 705, 8, 10, 10, 1, -7 }, // 0x71 'q' + { 715, 6, 8, 9, 2, -7 }, // 0x72 'r' + { 721, 8, 8, 10, 1, -7 }, // 0x73 's' + { 729, 6, 11, 9, 2, -10 }, // 0x74 't' + { 738, 8, 8, 10, 1, -7 }, // 0x75 'u' + { 746, 8, 8, 10, 1, -7 }, // 0x76 'v' + { 754, 8, 8, 10, 1, -7 }, // 0x77 'w' + { 762, 7, 8, 9, 1, -7 }, // 0x78 'x' + { 769, 8, 10, 10, 1, -7 }, // 0x79 'y' + { 779, 7, 8, 9, 1, -7 }, // 0x7A 'z' + { 786, 5, 11, 9, 2, -10 }, // 0x7B '{' + { 793, 2, 11, 10, 4, -10 }, // 0x7C '|' + { 796, 5, 11, 9, 2, -10 }, // 0x7D '}' + { 803, 8, 5, 10, 1, -11 } }; // 0x7E '~' const GFXfont whitrabt8pt7b PROGMEM = { (uint8_t *)whitrabt8pt7bBitmaps, (GFXglyph *)whitrabt8pt7bGlyphs, - 0x20, 0x7E, 12 }; + 0x20, 0x7E, 12 }; // Approx. 1480 bytes +#endif // ifndef FONTS_WHITRABT8PT7B_H From 2c618fd6887d898a6c74cd59ce126aed84a78597 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 9 Jun 2022 21:15:38 +0200 Subject: [PATCH 12/32] [AdaGFX] Regression: Background-fill for text should fill entire line height (cherry picked from commit 08a50497b51e2fa21c098f580bd6a10efbc7e551) --- src/src/Helpers/AdafruitGFX_helper.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 72bab020e..6a4fed67a 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -1945,10 +1945,13 @@ void AdafruitGFX_helper::printText(const char *string, } # endif // ifndef BUILD_NO_DEBUG - if (_textPrintMode == AdaGFXTextPrintMode::ClearThenTruncate) { - _display->fillRect(_x + oTop, yText, res_x - (_x - xOffset), hText + oBottom, bkcolor); // Clear text area to right edge of screen + if (bkcolor == color) { bkcolor = _bgcolor; } // To get at least the text readable + + if (_textPrintMode == AdaGFXTextPrintMode::ClearThenTruncate) { // oTop is negative so subtract to add... + _display->fillRect(_x + oTop, yText, res_x - (_x - xOffset), hText + oBottom - oTop, bkcolor); // Clear text area to right edge of + // screen } else { - _display->fillRect(_x + oTop, yText, _w, hText + oBottom, bkcolor); // Clear text area + _display->fillRect(_x + oTop, yText, _w, hText + oBottom - oTop, bkcolor); // Clear text area } delay(0); From 10c019c0f7e5b9d7b060fff22e9bd0f91a649763 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 10 Jun 2022 21:20:58 +0200 Subject: [PATCH 13/32] [AdaGFX] Re-add some previously missed changes --- src/src/Helpers/AdafruitGFX_helper.cpp | 34 +++++++++++++++++++++++--- src/src/Helpers/AdafruitGFX_helper.h | 17 ++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/src/Helpers/AdafruitGFX_helper.cpp b/src/src/Helpers/AdafruitGFX_helper.cpp index 6a4fed67a..b9f519bae 100644 --- a/src/src/Helpers/AdafruitGFX_helper.cpp +++ b/src/src/Helpers/AdafruitGFX_helper.cpp @@ -93,8 +93,10 @@ const __FlashStringHelper* toString(const AdaGFXColorDepth& colorDepth) { # if ADAGFX_SUPPORT_7COLOR case AdaGFXColorDepth::SevenColor: return F("eInk - 7 colors"); # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::EightColor: return F("TFT - 8 colors"); case AdaGFXColorDepth::SixteenColor: return F("TFT - 16 colors"); + # endif // if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::FullColor: return F("Full color - 65535 colors"); } return F("None"); @@ -169,9 +171,17 @@ void AdaGFXFormColorDepth(const __FlashStringHelper *id, uint16_t selectedIndex, bool enabled) { # if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR const int colorDepthCount = 7 + 1; + # else // if ADAGFX_SUPPORT_8and16COLOR + const int colorDepthCount = 5 + 1; + # endif // if ADAGFX_SUPPORT_8and16COLOR # else // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR const int colorDepthCount = 6 + 1; + # else // if ADAGFX_SUPPORT_8and16COLOR + const int colorDepthCount = 4 + 1; + # endif // if ADAGFX_SUPPORT_8and16COLOR # endif // if ADAGFX_SUPPORT_7COLOR const __FlashStringHelper *colorDepths[colorDepthCount] = { // Be sure to use all available modes from enum! toString(static_cast(0)), // include None @@ -181,8 +191,10 @@ void AdaGFXFormColorDepth(const __FlashStringHelper *id, # if ADAGFX_SUPPORT_7COLOR toString(AdaGFXColorDepth::SevenColor), # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR toString(AdaGFXColorDepth::EightColor), toString(AdaGFXColorDepth::SixteenColor), + # endif // if ADAGFX_SUPPORT_8and16COLOR toString(AdaGFXColorDepth::FullColor) }; const int colorDepthOptions[colorDepthCount] = { @@ -193,8 +205,10 @@ void AdaGFXFormColorDepth(const __FlashStringHelper *id, # if ADAGFX_SUPPORT_7COLOR static_cast(AdaGFXColorDepth::SevenColor), # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR static_cast(AdaGFXColorDepth::EightColor), static_cast(AdaGFXColorDepth::SixteenColor), + # endif // if ADAGFX_SUPPORT_8and16COLOR static_cast(AdaGFXColorDepth::FullColor) }; @@ -682,7 +696,9 @@ bool AdafruitGFX_helper::processCommand(const String& string) { getWindowOffsets(_xo, _yo); # endif // if ADAGFX_ENABLE_FRAMED_WINDOW - if (!cmd.equals(_trigger) || subcommand.isEmpty()) { return success; } // Only support own trigger, and at least a non=empty subcommand + if (!(cmd.equals(_trigger) || + isAdaGFXTrigger(cmd)) || + subcommand.isEmpty()) { return success; } // Only support own trigger, and at least a non=empty subcommand String log; std::vector sParams; @@ -749,7 +765,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { if (_columnRowMode) { - _display->setCursor(nParams[0] * _fontwidth, nParams[1] * _fontheight); + _display->setCursor(nParams[0] * _fontwidth + _xo, nParams[1] * _fontheight + _yo); } else { _display->setCursor(nParams[0] + _xo - _p095_compensation, nParams[1] + _yo - _p095_compensation); } @@ -765,7 +781,7 @@ bool AdafruitGFX_helper::processCommand(const String& string) { # endif // if ADAGFX_ARGUMENT_VALIDATION { if (_columnRowMode) { - _display->setCursor(nParams[0] * _fontwidth, nParams[1] * _fontheight); + _display->setCursor(nParams[0] * _fontwidth + _xo, nParams[1] * _fontheight + _yo); } else { _display->setCursor(nParams[0] + _xo, nParams[1] + _yo); } @@ -2080,13 +2096,17 @@ uint16_t AdaGFXparseColor(String & s, } if ((result == -1) || (result == ADAGFX_WHITE)) { // Default & don't convert white + # if ADAGFX_SUPPORT_8and16COLOR + if ( # if ADAGFX_SUPPORT_7COLOR (colorDepth >= AdaGFXColorDepth::SevenColor) && # endif // if ADAGFX_SUPPORT_7COLOR (colorDepth <= AdaGFXColorDepth::SixteenColor)) { result = static_cast(AdaGFXMonoRedGreyscaleColors::ADAGFXEPD_BLACK); // Monochrome fallback, compatible 7-color - } else { + } else + # endif // if ADAGFX_SUPPORT_8and16COLOR + { if (emptyIsBlack) { result = ADAGFX_BLACK; } else { @@ -2106,12 +2126,14 @@ uint16_t AdaGFXparseColor(String & s, result = AdaGFXrgb565ToColor7(result); // Convert break; # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::EightColor: result = color565((result >> 11 & 0x1F) / 4, (result >> 5 & 0x3F) / 4, (result & 0x1F) / 4); // reduce colors factor 4 break; case AdaGFXColorDepth::SixteenColor: result = color565((result >> 11 & 0x1F) / 2, (result >> 5 & 0x3F) / 2, (result & 0x1F) / 2); // reduce colors factor 2 break; + # endif // if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::FullColor: // No color reduction break; @@ -2171,8 +2193,10 @@ void AdaGFXHtmlColorDepthDataList(const __FlashStringHelper *id, break; } # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::EightColor: // TODO: Sort out the actual 8/16 color options case AdaGFXColorDepth::SixteenColor: + # endif // if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::FullColor: { AdaGFXaddHtmlDataListColorOptionValue(ADAGFX_BLACK, colorDepth); @@ -2255,8 +2279,10 @@ const __FlashStringHelper* AdaGFXcolorToString_internal(const uint16_t & break; } # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::EightColor: case AdaGFXColorDepth::SixteenColor: + # endif // if ADAGFX_SUPPORT_8and16COLOR case AdaGFXColorDepth::FullColor: { switch (color) { diff --git a/src/src/Helpers/AdafruitGFX_helper.h b/src/src/Helpers/AdafruitGFX_helper.h index c879da64d..6885cd250 100644 --- a/src/src/Helpers/AdafruitGFX_helper.h +++ b/src/src/Helpers/AdafruitGFX_helper.h @@ -130,6 +130,9 @@ # ifdef ADAGFX_USE_ASCIITABLE # undef ADAGFX_USE_ASCIITABLE # endif // ifdef ADAGFX_USE_ASCIITABLE +# ifdef ADAGFX_SUPPORT_8and16COLOR +# undef ADAGFX_SUPPORT_8and16COLOR +# endif // ifdef ADAGFX_SUPPORT_8and16COLOR // # ifdef ADAGFX_ENABLE_BMP_DISPLAY // # undef ADAGFX_ENABLE_BMP_DISPLAY // # endif // ifdef ADAGFX_ENABLE_BMP_DISPLAY @@ -173,7 +176,7 @@ # define ADAGFX_PARSE_POSTFIX F("~") // Will be removed before the normal template parsing is done # define ADAGFX_PARSE_POSTFIX_LEN 1 -# define ADAGFX_UNIVERSAL_TRIGGER F("adagfx_write") // Universal command trigger +# define ADAGFX_UNIVERSAL_TRIGGER F("adagfx_trigger") // Universal command trigger // Color definitions, borrowed from Adafruit_ILI9341.h @@ -228,11 +231,21 @@ enum class AdaGFXTextPrintMode : uint8_t { }; # if ADAGFX_SUPPORT_7COLOR +# if ADAGFX_SUPPORT_8and16COLOR # define ADAGFX_COLORDEPTH_COUNT 7 # define ADAGFX_MONOCOLORS_COUNT 4 +# else // if ADAGFX_SUPPORT_8and16COLOR +# define ADAGFX_COLORDEPTH_COUNT 5 +# define ADAGFX_MONOCOLORS_COUNT 4 +# endif // if ADAGFX_SUPPORT_8and16COLOR # else // if ADAGFX_SUPPORT_7COLOR +# if ADAGFX_SUPPORT_8and16COLOR # define ADAGFX_COLORDEPTH_COUNT 6 # define ADAGFX_MONOCOLORS_COUNT 3 +# else // if ADAGFX_SUPPORT_8and16COLOR +# define ADAGFX_COLORDEPTH_COUNT 4 +# define ADAGFX_MONOCOLORS_COUNT 3 +# endif // if ADAGFX_SUPPORT_8and16COLOR # endif // if ADAGFX_SUPPORT_7COLOR enum class AdaGFXColorDepth : uint16_t { Monochrome = 2u, // Black & white @@ -241,8 +254,10 @@ enum class AdaGFXColorDepth : uint16_t { # if ADAGFX_SUPPORT_7COLOR SevenColor = 7u, // Black, white, red, yellow, blue, green, orange # endif // if ADAGFX_SUPPORT_7COLOR + # if ADAGFX_SUPPORT_8and16COLOR EightColor = 8u, // 8 regular colors SixteenColor = 16u, // 16 colors + # endif // if ADAGFX_SUPPORT_8and16COLOR FullColor = 65535u // 65535 colors (max. supported by RGB565) }; From a42db28f04f320b3e5a8d2d1459322b896e16fda Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 11 Jun 2022 21:22:15 +0200 Subject: [PATCH 14/32] [P095] Implement getconfig feature, code optimization, update documenation --- docs/source/Plugin/P095.rst | 5 + src/_P095_ILI9341.ino | 104 ++++++++++++--------- src/src/PluginStructs/P095_data_struct.cpp | 28 +++++- src/src/PluginStructs/P095_data_struct.h | 32 ++++--- 4 files changed, 106 insertions(+), 63 deletions(-) diff --git a/docs/source/Plugin/P095.rst b/docs/source/Plugin/P095.rst index a99fe7d31..fe3e90479 100644 --- a/docs/source/Plugin/P095.rst +++ b/docs/source/Plugin/P095.rst @@ -191,6 +191,11 @@ Commands available .. include:: P095_commands.repl .. include:: AdaGFX_commands.repl +Values +------ + +.. include:: AdaGFX_values.repl + Change log diff --git a/src/_P095_ILI9341.ino b/src/_P095_ILI9341.ino index 340c8af40..f5e3cfecf 100644 --- a/src/_P095_ILI9341.ino +++ b/src/_P095_ILI9341.ino @@ -19,6 +19,7 @@ /** * Changelog: + * 2022-06-11 tonhuisman: Implement support for getting config values, see AdafruitGFX_Helper.h changelog for details. Code optimization * 2022-05-17 tonhuisman: Add setting for Splash during plugin startup, default on, when compiled in * 2022-01-09 tonhuisman: Add support for ILI9342 (M5Stack, 240x320), ILI9481, ILI9486 and ILI9488 (320x480) displays * 2021-11-16 tonhuisman: Add support for PLUGIN_GET_DISPLAY_PARAMETERS, removed commented old source @@ -213,12 +214,12 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_095)); } - AdaGFXFormBacklight(F("p095_backlight"), P095_CONFIG_BACKLIGHT_PIN, - F("p095_backpercentage"), P095_CONFIG_BACKLIGHT_PERCENT); + AdaGFXFormBacklight(F("backlight"), P095_CONFIG_BACKLIGHT_PIN, + F("backpercentage"), P095_CONFIG_BACKLIGHT_PERCENT); - AdaGFXFormDisplayButton(F("p095_button"), P095_CONFIG_BUTTON_PIN, - F("p095_buttonInverse"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_INVERT_BUTTON), - F("p095_timer"), P095_CONFIG_DISPLAY_TIMEOUT); + AdaGFXFormDisplayButton(F("button"), P095_CONFIG_BUTTON_PIN, + F("buttonInverse"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_INVERT_BUTTON), + F("timer"), P095_CONFIG_DISPLAY_TIMEOUT); { const __FlashStringHelper *hardwareTypes[] = { @@ -246,7 +247,7 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) static_cast(ILI9xxx_type_e::ILI9488_320x480), }; addFormSelector(F("TFT display model"), - F("p095_type"), + F("dsptype"), static_cast(ILI9xxx_type_e::ILI9xxx_MAX), hardwareTypes, hardwareOptions, @@ -255,17 +256,17 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) addFormSubHeader(F("Layout")); - AdaGFXFormRotation(F("p095_rotate"), P095_CONFIG_ROTATION); + AdaGFXFormRotation(F("rotate"), P095_CONFIG_ROTATION); - AdaGFXFormTextPrintMode(F("p095_mode"), P095_CONFIG_FLAG_GET_MODE); + AdaGFXFormTextPrintMode(F("tpmode"), P095_CONFIG_FLAG_GET_MODE); - AdaGFXFormFontScaling(F("p095_fontscale"), P095_CONFIG_FLAG_GET_FONTSCALE); + AdaGFXFormFontScaling(F("fontscale"), P095_CONFIG_FLAG_GET_FONTSCALE); # ifdef P095_SHOW_SPLASH - addFormCheckBox(F("Show splash on start"), F("p095_splash"), P095_CONFIG_FLAG_GET_SHOW_SPLASH); + addFormCheckBox(F("Show splash on start"), F("splash"), P095_CONFIG_FLAG_GET_SHOW_SPLASH); # endif // ifdef P095_SHOW_SPLASH - addFormCheckBox(F("Clear display on exit"), F("p095_clearOnExit"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_CLEAR_ON_EXIT)); + addFormCheckBox(F("Clear display on exit"), F("clearOnExit"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_CLEAR_ON_EXIT)); { const __FlashStringHelper *commandTriggers[] = { // Be sure to use all options available in the enum (except MAX)! @@ -285,32 +286,36 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) static_cast(P095_CommandTrigger::ili9488) }; addFormSelector(F("Write Command trigger"), - F("p095_commandtrigger"), + F("commandtrigger"), static_cast(P095_CommandTrigger::MAX), commandTriggers, commandTriggerOptions, P095_CONFIG_FLAG_GET_CMD_TRIGGER); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("Select the command that is used to handle commands for this display.")); + # endif // ifndef LIMIT_BUILD_SIZE } // Inverted state! - addFormCheckBox(F("Wake display on receiving text"), F("p095_NoDisplay"), !bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_NO_WAKE)); + addFormCheckBox(F("Wake display on receiving text"), F("NoDisplay"), !bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_NO_WAKE)); + # ifndef LIMIT_BUILD_SIZE addFormNote(F("When checked, the display wakes up at receiving remote updates.")); + # endif // ifndef LIMIT_BUILD_SIZE - AdaGFXFormTextColRowMode(F("p095_colrow"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_USE_COL_ROW) == 1); + AdaGFXFormTextColRowMode(F("colrow"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_USE_COL_ROW) == 1); - AdaGFXFormOnePixelCompatibilityOption(F("p095_compat"), !bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_COMPAT_P095)); // Inverse + AdaGFXFormOnePixelCompatibilityOption(F("compat"), !bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_COMPAT_P095)); // Inverse - AdaGFXFormTextBackgroundFill(F("p095_backfill"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_BACK_FILL) == 0); // Inverse + AdaGFXFormTextBackgroundFill(F("backfill"), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_BACK_FILL) == 0); // Inverse addFormSubHeader(F("Content")); if (P095_CONFIG_COLORS == 0) { // For migrating from older release task settings P095_CONFIG_COLORS = ADAGFX_WHITE | (ADAGFX_BLACK << 16); } - AdaGFXFormForeAndBackColors(F("p095_foregroundcolor"), + AdaGFXFormForeAndBackColors(F("foregroundcolor"), P095_CONFIG_GET_COLOR_FOREGROUND, - F("p095_backgroundcolor"), + F("backgroundcolor"), P095_CONFIG_GET_COLOR_BACKGROUND); String strings[P095_Nlines]; @@ -340,40 +345,38 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) P095_CONFIG_VERSION = 2; // mark config V2 as already saved (next time, will not convert 'invalid' values) // PIN(0)..(2) are already set - P095_CONFIG_ROTATION = getFormItemInt(F("p095_rotate")); - P095_CONFIG_BUTTON_PIN = getFormItemInt(F("p095_button")); - P095_CONFIG_DISPLAY_TIMEOUT = getFormItemInt(F("p095_timer")); - P095_CONFIG_BACKLIGHT_PIN = getFormItemInt(F("p095_backlight")); - P095_CONFIG_BACKLIGHT_PERCENT = getFormItemInt(F("p095_backpercentage")); + P095_CONFIG_ROTATION = getFormItemInt(F("rotate")); + P095_CONFIG_BUTTON_PIN = getFormItemInt(F("button")); + P095_CONFIG_DISPLAY_TIMEOUT = getFormItemInt(F("timer")); + P095_CONFIG_BACKLIGHT_PIN = getFormItemInt(F("backlight")); + P095_CONFIG_BACKLIGHT_PERCENT = getFormItemInt(F("backpercentage")); uint32_t lSettings = 0; - bitWrite(lSettings, P095_CONFIG_FLAG_NO_WAKE, !isFormItemChecked(F("p095_NoDisplay"))); // Bit 0 - // NoDisplayOnReceivingText, - // reverse logic, - // default=checked! - bitWrite(lSettings, P095_CONFIG_FLAG_INVERT_BUTTON, isFormItemChecked(F("p095_buttonInverse"))); // Bit 1 buttonInverse - bitWrite(lSettings, P095_CONFIG_FLAG_CLEAR_ON_EXIT, isFormItemChecked(F("p095_clearOnExit"))); // Bit 2 ClearOnExit - bitWrite(lSettings, P095_CONFIG_FLAG_USE_COL_ROW, isFormItemChecked(F("p095_colrow"))); // Bit 3 Col/Row addressing - bitWrite(lSettings, P095_CONFIG_FLAG_COMPAT_P095, !isFormItemChecked(F("p095_compat"))); // Bit 4 Compat_P095 (inv) - bitWrite(lSettings, P095_CONFIG_FLAG_BACK_FILL, !isFormItemChecked(F("p095_backfill"))); // Bit 5 Back fill text (inv) + bitWrite(lSettings, P095_CONFIG_FLAG_NO_WAKE, !isFormItemChecked(F("NoDisplay"))); // Bit 0 NoDisplayOnReceivingText, reverse + // logic, default=checked! + bitWrite(lSettings, P095_CONFIG_FLAG_INVERT_BUTTON, isFormItemChecked(F("buttonInverse"))); // Bit 1 buttonInverse + bitWrite(lSettings, P095_CONFIG_FLAG_CLEAR_ON_EXIT, isFormItemChecked(F("clearOnExit"))); // Bit 2 ClearOnExit + bitWrite(lSettings, P095_CONFIG_FLAG_USE_COL_ROW, isFormItemChecked(F("colrow"))); // Bit 3 Col/Row addressing + bitWrite(lSettings, P095_CONFIG_FLAG_COMPAT_P095, !isFormItemChecked(F("compat"))); // Bit 4 Compat_P095 (inv) + bitWrite(lSettings, P095_CONFIG_FLAG_BACK_FILL, !isFormItemChecked(F("backfill"))); // Bit 5 Back fill text (inv) # ifdef P095_SHOW_SPLASH - bitWrite(lSettings, P095_CONFIG_FLAG_SHOW_SPLASH, !isFormItemChecked(F("p095_splash"))); // Bit 6 Show splash on startup (inv) + bitWrite(lSettings, P095_CONFIG_FLAG_SHOW_SPLASH, !isFormItemChecked(F("splash"))); // Bit 6 Show splash on startup (inv) # endif // ifdef P095_SHOW_SPLASH - set4BitToUL(lSettings, P095_CONFIG_FLAG_CMD_TRIGGER, getFormItemInt(F("p095_commandtrigger"))); // Bit 8..11 Command trigger - set4BitToUL(lSettings, P095_CONFIG_FLAG_FONTSCALE, getFormItemInt(F("p095_fontscale"))); // Bit 12..15 Font scale - set4BitToUL(lSettings, P095_CONFIG_FLAG_MODE, getFormItemInt(F("p095_mode"))); // Bit 16..19 Text print mode - set4BitToUL(lSettings, P095_CONFIG_FLAG_TYPE, getFormItemInt(F("p095_type"))); // Bit 20..24 Hardwaretype + set4BitToUL(lSettings, P095_CONFIG_FLAG_CMD_TRIGGER, getFormItemInt(F("commandtrigger"))); // Bit 8..11 Command trigger + set4BitToUL(lSettings, P095_CONFIG_FLAG_FONTSCALE, getFormItemInt(F("fontscale"))); // Bit 12..15 Font scale + set4BitToUL(lSettings, P095_CONFIG_FLAG_MODE, getFormItemInt(F("tpmode"))); // Bit 16..19 Text print mode + set4BitToUL(lSettings, P095_CONFIG_FLAG_TYPE, getFormItemInt(F("dsptype"))); // Bit 20..24 Hardwaretype P095_CONFIG_FLAGS = lSettings; - String color = web_server.arg(F("p095_foregroundcolor")); + String color = web_server.arg(F("foregroundcolor")); uint16_t fgcolor = ADAGFX_WHITE; // Default to white when empty if (!color.isEmpty()) { fgcolor = AdaGFXparseColor(color); // Reduce to rgb565 } - color = web_server.arg(F("p095_backgroundcolor")); - uint16_t bgcolor = AdaGFXparseColor(color); + color = web_server.arg(F("backgroundcolor")); + const uint16_t bgcolor = AdaGFXparseColor(color); P095_CONFIG_COLORS = fgcolor | (bgcolor << 16); // Store as a single setting @@ -451,12 +454,10 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) if (P095_CONFIG_BUTTON_PIN != -1) { P095_data_struct *P095_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P095_data) { - return success; + if (nullptr != P095_data) { + P095_data->registerButtonState(digitalRead(P095_CONFIG_BUTTON_PIN), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_INVERT_BUTTON)); + success = true; } - - P095_data->registerButtonState(digitalRead(P095_CONFIG_BUTTON_PIN), bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_INVERT_BUTTON)); - success = true; } break; } @@ -500,6 +501,19 @@ boolean Plugin_095(uint8_t function, struct EventStruct *event, String& string) } break; } + + # if ADAGFX_ENABLE_GET_CONFIG_VALUE + case PLUGIN_GET_CONFIG_VALUE: + { + P095_data_struct *P095_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr != P095_data) { + success = P095_data->plugin_get_config_value(event, string); // GetConfig operation, handle variables, fully delegated to + // AdafruitGFX_helper + } + break; + } + # endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE } return success; diff --git a/src/src/PluginStructs/P095_data_struct.cpp b/src/src/PluginStructs/P095_data_struct.cpp index 4f6223960..b00ac08c1 100644 --- a/src/src/PluginStructs/P095_data_struct.cpp +++ b/src/src/PluginStructs/P095_data_struct.cpp @@ -6,7 +6,7 @@ /**************************************************************************** * ILI9xxx_type_toString: Display-value for the device selected ***************************************************************************/ -const __FlashStringHelper* ILI9xxx_type_toString(ILI9xxx_type_e device) { +const __FlashStringHelper* ILI9xxx_type_toString(const ILI9xxx_type_e& device) { switch (device) { case ILI9xxx_type_e::ILI9341_240x320: return F("ILI9341 240 x 320px"); case ILI9xxx_type_e::ILI9342_240x320: return F("ILI9342 240 x 320px (M5Stack)"); @@ -26,7 +26,9 @@ const __FlashStringHelper* ILI9xxx_type_toString(ILI9xxx_type_e device) { /**************************************************************************** * ILI9xxx_type_toResolution: X and Y resolution for the selected type ***************************************************************************/ -void ILI9xxx_type_toResolution(ILI9xxx_type_e device, uint16_t& x, uint16_t& y) { +void ILI9xxx_type_toResolution(const ILI9xxx_type_e& device, + uint16_t & x, + uint16_t & y) { switch (device) { case ILI9xxx_type_e::ILI9341_240x320: case ILI9xxx_type_e::ILI9342_240x320: @@ -52,7 +54,7 @@ void ILI9xxx_type_toResolution(ILI9xxx_type_e device, uint16_t& x, uint16_t& y) /**************************************************************************** * P095_CommandTrigger_toString: return the command string selected ***************************************************************************/ -const __FlashStringHelper* P095_CommandTrigger_toString(P095_CommandTrigger cmd) { +const __FlashStringHelper* P095_CommandTrigger_toString(const P095_CommandTrigger& cmd) { switch (cmd) { case P095_CommandTrigger::tft: return F("tft"); case P095_CommandTrigger::ili9341: return F("ili9341"); @@ -383,6 +385,23 @@ bool P095_data_struct::plugin_write(struct EventStruct *event, const String& str return success; } +# if ADAGFX_ENABLE_GET_CONFIG_VALUE + +/**************************************************************************** + * plugin_get_config_value: Retrieve values like [#] + ***************************************************************************/ +bool P095_data_struct::plugin_get_config_value(struct EventStruct *event, + String & string) { + bool success = false; + + if (gfxHelper != nullptr) { + success = gfxHelper->pluginGetConfigValue(string); + } + return success; +} + +# endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE + /**************************************************************************** * displayOnOff: Turn display on or off ***************************************************************************/ @@ -407,7 +426,8 @@ void P095_data_struct::displayOnOff(bool state) { /**************************************************************************** * registerButtonState: the button has been pressed, apply some debouncing ***************************************************************************/ -void P095_data_struct::registerButtonState(uint8_t newButtonState, bool bPin3Invers) { +void P095_data_struct::registerButtonState(const uint8_t& newButtonState, + const bool & bPin3Invers) { if ((ButtonLastState == 0xFF) || (bPin3Invers != (!!newButtonState))) { ButtonLastState = newButtonState; DebounceCounter++; diff --git a/src/src/PluginStructs/P095_data_struct.h b/src/src/PluginStructs/P095_data_struct.h index 51961f540..6fb0d85be 100644 --- a/src/src/PluginStructs/P095_data_struct.h +++ b/src/src/PluginStructs/P095_data_struct.h @@ -80,20 +80,20 @@ enum class ILI9xxx_type_e : uint8_t { }; enum class P095_CommandTrigger : uint8_t { - tft = 0u, - ili9341, - ili9342, - ili9481, - ili9486, - ili9488, - MAX // Keep as last item! + tft = 0u, + ili9341 = 1u, + ili9342 = 2u, + ili9481 = 3u, + ili9486 = 4u, + ili9488 = 5u, + MAX = 6u // Keep as last item! }; -const __FlashStringHelper* ILI9xxx_type_toString(ILI9xxx_type_e device); -const __FlashStringHelper* P095_CommandTrigger_toString(P095_CommandTrigger cmd); -void ILI9xxx_type_toResolution(ILI9xxx_type_e device, - uint16_t & x, - uint16_t & y); +const __FlashStringHelper* ILI9xxx_type_toString(const ILI9xxx_type_e& device); +const __FlashStringHelper* P095_CommandTrigger_toString(const P095_CommandTrigger& cmd); +void ILI9xxx_type_toResolution(const ILI9xxx_type_e& device, + uint16_t & x, + uint16_t & y); struct P095_data_struct : public PluginTaskData_base { public: @@ -116,11 +116,15 @@ public: bool plugin_read(struct EventStruct *event); bool plugin_write(struct EventStruct *event, const String & string); + # if ADAGFX_ENABLE_GET_CONFIG_VALUE + bool plugin_get_config_value(struct EventStruct *event, + String & string); + # endif // if ADAGFX_ENABLE_GET_CONFIG_VALUE bool plugin_ten_per_second(struct EventStruct *event); bool plugin_once_a_second(struct EventStruct *event); - void registerButtonState(uint8_t newButtonState, - bool bPin3Invers); + void registerButtonState(const uint8_t& newButtonState, + const bool & bPin3Invers); void markButtonStateProcessed(); bool getButtonState() { return ButtonState; From e897a337753e3b3aecadc0bcfe53e1b10d3080a1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 14 Jun 2022 21:56:16 +0200 Subject: [PATCH 15/32] [P095] Implement splash without delay() --- src/_P095_ILI9341.ino | 1 + src/src/PluginStructs/P095_data_struct.cpp | 35 ++++++++++++++++++---- src/src/PluginStructs/P095_data_struct.h | 6 ++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/_P095_ILI9341.ino b/src/_P095_ILI9341.ino index f5e3cfecf..c8bde42ed 100644 --- a/src/_P095_ILI9341.ino +++ b/src/_P095_ILI9341.ino @@ -19,6 +19,7 @@ /** * Changelog: + * 2022-06-14 tonhuisman: Improved Splash handling, non-blocking delay, default 3 seconds * 2022-06-11 tonhuisman: Implement support for getting config values, see AdafruitGFX_Helper.h changelog for details. Code optimization * 2022-05-17 tonhuisman: Add setting for Splash during plugin startup, default on, when compiled in * 2022-01-09 tonhuisman: Add support for ILI9342 (M5Stack, 240x320), ILI9481, ILI9486 and ILI9488 (320x480) displays diff --git a/src/src/PluginStructs/P095_data_struct.cpp b/src/src/PluginStructs/P095_data_struct.cpp index b00ac08c1..1edc20d8b 100644 --- a/src/src/PluginStructs/P095_data_struct.cpp +++ b/src/src/PluginStructs/P095_data_struct.cpp @@ -173,7 +173,11 @@ bool P095_data_struct::plugin_init(struct EventStruct *event) { gfxHelper->printText(String(F("ESPEasy")).c_str(), 0, yPos, 3, ADAGFX_WHITE, ADAGFX_BLUE); yPos += (3 * _fontheight); gfxHelper->printText(String(F("ILI934x/ILI948x")).c_str(), 0, yPos, 2, ADAGFX_BLUE, ADAGFX_WHITE); - delay(100); // Splash + _splashState = true; // Splash + _splashCounter = P095_SPLASH_DURATION; + # ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_INFO, F("P095 Splash start")); + # endif // ifndef BUILD_NO_DEBUG } # endif // ifdef P095_SHOW_SPLASH updateFontMetrics(); @@ -223,7 +227,7 @@ bool P095_data_struct::plugin_exit(struct EventStruct *event) { * plugin_read: Re-draw the default content ***************************************************************************/ bool P095_data_struct::plugin_read(struct EventStruct *event) { - if (nullptr != tft) { + if ((nullptr != tft) && !_splashState) { String strings[P095_Nlines]; LoadCustomTaskSettings(event->TaskIndex, strings, P095_Nlines, 0); @@ -266,6 +270,27 @@ bool P095_data_struct::plugin_read(struct EventStruct *event) { * plugin_ten_per_second: check button, if any, that wakes up the display ***************************************************************************/ bool P095_data_struct::plugin_ten_per_second(struct EventStruct *event) { + # ifdef P095_SHOW_SPLASH + + if (_splashState) { // Decrement splash counter + _splashCounter--; + _splashState = _splashCounter != 0; + + if (!_splashState) { + # ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_INFO, F("P095 Splash finished.")); + # endif // ifndef BUILD_NO_DEBUG + + if (nullptr != tft) { + tft->fillScreen(_bgcolor); // fill screen with background color + } + + // Schedule the surrogate initial PLUGIN_READ that has been suppressed by the splash + Scheduler.schedule_task_device_timer(event->TaskIndex, millis() + 10); + } + } + # endif // ifdef P095_SHOW_SPLASH + if ((P095_CONFIG_BUTTON_PIN != -1) && (getButtonState()) && (nullptr != tft)) { displayOnOff(true); markButtonStateProcessed(); @@ -277,7 +302,7 @@ bool P095_data_struct::plugin_ten_per_second(struct EventStruct *event) { * plugin_once_a_second: Count down display timer, if any, and turn display off if countdown reached ***************************************************************************/ bool P095_data_struct::plugin_once_a_second(struct EventStruct *event) { - if (_displayTimer > 0) { + if ((_displayTimer > 0) && !_splashState) { _displayTimer--; if ((nullptr != tft) && (_displayTimer == 0)) { @@ -294,7 +319,7 @@ bool P095_data_struct::plugin_write(struct EventStruct *event, const String& str bool success = false; String cmd = parseString(string, 1); - if ((nullptr != tft) && cmd.equals(_commandTriggerCmd)) { + if ((nullptr != tft) && cmd.equals(_commandTriggerCmd) && !_splashState) { String arg1 = parseString(string, 2); success = true; @@ -359,7 +384,7 @@ bool P095_data_struct::plugin_write(struct EventStruct *event, const String& str } } else if (tft && (cmd.equals(_commandTrigger) || - (gfxHelper && gfxHelper->isAdaGFXTrigger(cmd)))) { + (gfxHelper && gfxHelper->isAdaGFXTrigger(cmd))) && !_splashState) { success = true; if (!bitRead(P095_CONFIG_FLAGS, P095_CONFIG_FLAG_NO_WAKE)) { // Wake display? diff --git a/src/src/PluginStructs/P095_data_struct.h b/src/src/PluginStructs/P095_data_struct.h index 6fb0d85be..92305f71d 100644 --- a/src/src/PluginStructs/P095_data_struct.h +++ b/src/src/PluginStructs/P095_data_struct.h @@ -17,6 +17,7 @@ # ifndef LIMIT_BUILD_SIZE # define P095_SHOW_SPLASH // Enable to show initial splash (text) # endif // ifndef LIMIT_BUILD_SIZE +# define P095_SPLASH_DURATION (3000 / 100) // 3 seconds in 100 millisecond chunks # define P095_CONFIG_VERSION PCONFIG(0) // Settings version # define P095_CONFIG_ROTATION PCONFIG(1) // Rotation @@ -169,6 +170,11 @@ private: int8_t _leftMarginCompensation = 0; // Not settable yet int8_t _topMarginCompensation = 0; + + bool _splashState = false; // Have this always available to avoid 'many' #ifdefs in the code + # ifdef P095_SHOW_SPLASH + uint8_t _splashCounter = P095_SPLASH_DURATION; + # endif // ifdef P095_SHOW_SPLASH }; From 3198782a86cb60f756e909cde210a7d634475152 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 18 Aug 2022 22:05:46 +0200 Subject: [PATCH 16/32] [P059] Add documentation, migrated from the Wiki --- docs/source/Plugin/P059.rst | 88 +++++++++++++++++- docs/source/Plugin/P059_520px-Pulse_wheel.jpg | Bin 0 -> 77512 bytes .../Plugin/P059_520px-Pulse_wheel_002.jpg | Bin 0 -> 100058 bytes .../Plugin/P059_520px-Rotary_encoder_001.jpg | Bin 0 -> 56336 bytes .../Plugin/P059_DeviceConfiguration.png | Bin 0 -> 37868 bytes docs/source/Plugin/P059_Rotary_Encoder.rst | 70 -------------- docs/source/Plugin/P059_commands.repl | 9 ++ docs/source/Reference/Command.rst | 6 +- 8 files changed, 96 insertions(+), 77 deletions(-) create mode 100644 docs/source/Plugin/P059_520px-Pulse_wheel.jpg create mode 100644 docs/source/Plugin/P059_520px-Pulse_wheel_002.jpg create mode 100644 docs/source/Plugin/P059_520px-Rotary_encoder_001.jpg create mode 100644 docs/source/Plugin/P059_DeviceConfiguration.png delete mode 100644 docs/source/Plugin/P059_Rotary_Encoder.rst create mode 100644 docs/source/Plugin/P059_commands.repl diff --git a/docs/source/Plugin/P059.rst b/docs/source/Plugin/P059.rst index a4ec25028..4b004447f 100644 --- a/docs/source/Plugin/P059.rst +++ b/docs/source/Plugin/P059.rst @@ -1,4 +1,4 @@ -.. include:: ../Plugin/_plugin_substitutions_p05x.repl +.. include:: ../Plugin/_plugin_substitutions_p05x.repl .. _P059_page: |P059_typename| @@ -21,15 +21,95 @@ Maintainer: |P059_maintainer| Used libraries: |P059_usedlibraries| +Introduction +------------ + +A rotary encoder can be used in many applications that require precise (unlimited) rotation indication. A general use is to have the encoder set the volume of a speaker or position of a stepper motor. + Supported hardware ------------------ +.. image:: P059_520px-Pulse_wheel.jpg + +A pulse wheel used for CNC machines. + +.. image:: P059_520px-Pulse_wheel_002.jpg + +. + +.. image:: P059_520px-Rotary_encoder_001.jpg + +A rotary encoder used for volume and GUI interaction (press the knob for switch input) + |P059_usedby| -.. Commands available -.. ^^^^^^^^^^^^^^^^^^ +Wiring +------ -.. .. include:: P059_commands.repl +.. code:: none + + ESP Encoder + GPIO <--> A or CLK + GPIO <--> B or DT + GPIO* <--> I (optional) + + Power + 3.3V <--> VCC/+ + GND <--> GND/V0 + +\*if any is available, used to "0" the counter after each turn. + +Switch A/B if the encoder is counting backwards! + +A and B is sometimes labeled CLK and DT, other labels might also be used. Test and see what works for your encoder. If the rotary encoder have A- and B- ports it is ideal to use them since the pulses are negative and doesn't strain the ESP unit's power. Using a positive signal is not a problem though. + +Use only GPIO pins that support interrupts, so f.e. GPIO-16 on ESP8266 can't be used. + +Device +------ + +.. image:: P059_DeviceConfiguration.png + +Task settings +~~~~~~~~~~~~~ + +* **Name** The name of the task. This should be unique for all devices that are configured. (Initially empty) + +* **Enabled** For the device to work it has to be enabled. When checked, the device will be started as soon as the ESP starts. If desired, the device can also be enabled from f.e. a rule by using the ``TaskEnable,`` or ``TaskEnable,`` command, or disabled using the corresponding ``TaskDisable,|`` commands. + +Sensor +~~~~~~ + +* **GPIO <- A (CLK)**: Input pin for the **A** or **CLK** wire. + +* **GPIO <- B (DT)**: Input pin for the **B** or **DT** wire. + +* **GPIO <- I (Z)(optional)**: Optional input pin for the reset signal from the rotary knob, to reset the counter when it passes the 0 mark. + +* **Mode**: Sets the "resolution" of the turning on the knob. 1 pulse per cycle is "slowest"/finest and 4 pulses per cycle is the "fastest"/coarsest. + +* **Limit min**: The lowest value that the counter will go to. Observe that if you have the counter on a value below this limit the counter will climb above this value but not below it once it has reached the min limit. + +* **Limit max**: The highest value that the counter will go to. As with the min limit if the counter is above this limit it will descend to the max level but never climb over it once reached below it. + +Data Acquisition +^^^^^^^^^^^^^^^^ + +This group of settings, **Single event with all values**, **Send to Controller** and **Interval** settings are standard available configuration items. Send to Controller is only visible when one or more Controllers are configured. + +**Interval** By default, Interval will be set to 0 sec for this plugin, as this setting is optional. It is the frequency used to read sensor values and send these to any Controllers configured for this device. + +Values +^^^^^^ + +The counted value is available in ``Counter``. + + + +Commands available +^^^^^^^^^^^^^^^^^^ + +.. include:: P059_commands.repl .. Events .. ~~~~~~ diff --git a/docs/source/Plugin/P059_520px-Pulse_wheel.jpg b/docs/source/Plugin/P059_520px-Pulse_wheel.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c6dbdd9a589598ef44fff1c33147fbb61bf174d5 GIT binary patch literal 77512 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

j_byOMYSXU29e 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 z

1gR;V(RcMX>zdLFkKntJ{PH>(XKQCF&$^_bpu9+QD25Df^v!s162mE-T8-Ji1e zV4S)(vr0P_inF5Mdy)&sYAUL^1iU$V%*%4Ir_Sv!N0IunW(TXyMsx0V*ltK%$~cr! zvdAX-Kzgkt#PLED6S%I!S7y*wrTiP9p_y#)nj~)h7UUJ(bj9_$57xXm`ZYaOHdZDqbWtJ|sM9)>WJf zN&Lam*XhxcIMp_s*jp{9hV-$T0l&me$M|GaIqnG}XkJy+CaK>0mKq>jVTT3_S6h!L zcW%*!H1S&mb-F6syUEk*?Apx$B#Fet?D*e9l)hAfxu&v zlTAUYjigDw+~UH)stw7Ry|stv*#{JDiHW8fhEtB!kx<1fqwX<>TE;JDL0u5!q?q1o zfw7Kj9YQLNuOs-@@hZNARRs)nRmp^uRPfG0Snld1Zko@NLq|+o=F2_pq_^exrj)^P z>{g^@{c{CeM*3^Mare=<3HmefA8ndZQK1rE6~|NXAfDJTypRa20x+4N99uoV!pP%% zLyE@?Ppo>`-(Cvfdu7^1EyKDMW8ZBPf^qOV1lU+CMJ^9`IXV^f4B$O~ze>2V?^+j3 ze0f0U&$8uBlT*HbsDZF*K;5xy$Jom1G}*XgT_QfMP?YNX0sF|U3XAU-P4w%M(`j_A z7?E$;hdD5Nz`qcT7M%FO`4S#v67JLP_}faEkJl3nUv5&}B*-B%Hu=~$_Qkr+#r)?p z?BXV4I=BI}9WDODiO628E3!yIK&(`y=OPJ3@9BP~32rer0Rrr()7`j*1{Moqc1mCo zR|9MYYYF~I+&J&|cyKDjW!U$-K*IAUCG;BqfQ4W*RBl&&B}VwyEYw|iW@4FBu3!&1 zz4-x2%x`AuivY(*{~cG2Hfwa09Y3uR%!65dh5jB-S|{ZH4Clr<)PX;dxngNn-CT*inNOC`}s zjiafIZdhRDHg!xIi4xp0g%ChMFWxPwn}oib?GbGo{?4@#TE+y*0AnQyS5iU=-kg$y zQfS(qWnNO5)CcJ{5Srl2!W+Q2#8E_Jkhtdc^BdrJ?nWw9;rLW>#0{Bu%~s$I08mW* z@CFElk;;>oFYFSKy20lwnBA<)VOvaE>QUzf7X_?|Mr&HChq4IjvI>R66lJaCglE8= z8f=v=bi`b_8y;EnKw>{1W|nBX@GI?gRy_Zx`|-9=R&aPbWAw_C7ib$S@01!``fcN| zxtXALnZH!tY7~oO<`PUheg2){N%Qgz@Z~T~(aF=-nl|afDe~W}8LdCDTwuGoRCSXA zAhVj|P{B)n018HV%A`bl>8PoH=*Ds&^7A#!)A_J>29$ZsOcUlS?a3~JRZw;1nk!z9 zBIkc}EP>qrJ_BYG#@vFv-vA5cvbjN%?N3V0|8w2k6plK8A*5djuE%jOOQkXYnRAY@ z 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 Z-+u9&7P1i`LR7@AK`ef%zH TX - GPIO (X) <--> RX - - - Power - 5.0V <--> VCC - GND <--> GND - - -Setup ------ - - - -Rules examples --------------- - -.. code-block:: none - - //Code below... - - -Indicators (recommended settings) ---------------------------------- - -.. csv-table:: - :header: "Indicator", "Value Name", "Interval", "Decimals", "Extra information" - :widths: 8, 5, 5, 5, 40 - - "XXXXXX", "N/A", "", "", "" - -Where to buy ------------- - -.. csv-table:: - :header: "Store", "Link" - :widths: 5, 40 - - "AliExpress","`Link 1 ($) `_" - -|affiliate| - - -More pictures -------------- diff --git a/docs/source/Plugin/P059_commands.repl b/docs/source/Plugin/P059_commands.repl new file mode 100644 index 000000000..3c62f9cad --- /dev/null +++ b/docs/source/Plugin/P059_commands.repl @@ -0,0 +1,9 @@ +.. csv-table:: + :header: "Command Syntax", "Extra information" + :widths: 20, 30 + + " + | ``encwrite,>`` + "," + | Set the **Counter** value, and generate an event for it, as if a pulse was received. + " diff --git a/docs/source/Reference/Command.rst b/docs/source/Reference/Command.rst index 2149ab9ad..370912fd9 100644 --- a/docs/source/Reference/Command.rst +++ b/docs/source/Reference/Command.rst @@ -483,10 +483,10 @@ P053 :ref:`P053_page` .. .. include:: ../Plugin/P058_commands.repl -.. P059 :ref:`P059_page` -.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +P059 :ref:`P059_page` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. .. include:: ../Plugin/P059_commands.repl +.. include:: ../Plugin/P059_commands.repl .. P060 :ref:`P060_page` From 8db3af3a37bcda89c5475e867e197e806a5fab85 Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 19 Aug 2022 13:57:58 +0200 Subject: [PATCH 17/32] [Build] Include ESPEasy_config.h everywhere --- include/ESPEasy_config.h | 109 ++++++++++++++ platformio_core_defs.ini | 12 +- src/ESPEasy_common.cpp | 2 - src/ESPEasy_common.h | 137 ++---------------- src/_N001_Email.cpp | 2 + src/_P021_Level.ino | 2 +- src/_Plugin_Helper.h | 2 +- src/src/CustomBuild/ESPEasyLimits.h | 2 +- src/src/CustomBuild/define_plugin_sets.h | 2 +- src/src/DataTypes/NetworkMedium.h | 2 +- src/src/ESPEasyCore/ESPEasy_setup.cpp | 2 +- src/src/Globals/Services.cpp | 3 - src/src/Globals/Services.h | 1 + src/src/Helpers/ESPEasyStatistics.cpp | 2 +- src/src/Helpers/ESPEasy_FactoryDefault.cpp | 1 + src/src/Helpers/ESPEasy_Storage.h | 2 +- src/src/Helpers/FS_Helper.h | 30 +++- src/src/Helpers/Hardware.cpp | 3 + src/src/Helpers/OTA.cpp | 1 + src/src/Helpers/PeriodicalActions.cpp | 1 + src/src/Helpers/StringGenerator_System.cpp | 3 +- src/src/Helpers/_CPlugin_Helper_webform.cpp | 2 +- src/src/PluginStructs/P037_data_struct.cpp | 2 +- src/src/PluginStructs/P104_data_struct.cpp | 2 +- src/src/WebServer/404.cpp | 2 +- src/src/WebServer/AdvancedConfigPage.cpp | 2 +- src/src/WebServer/CacheControllerPages.cpp | 2 +- src/src/WebServer/ConfigPage.cpp | 2 +- src/src/WebServer/ControlPage.cpp | 2 +- src/src/WebServer/ControllerPage.cpp | 2 +- src/src/WebServer/CustomPage.cpp | 2 +- src/src/WebServer/DevicesPage.cpp | 2 +- src/src/WebServer/DownloadPage.cpp | 2 +- .../{WebServer.cpp => ESPEasy_WebServer.cpp} | 2 +- .../{WebServer.h => ESPEasy_WebServer.h} | 0 src/src/WebServer/FactoryResetPage.cpp | 2 +- src/src/WebServer/Favicon.cpp | 2 +- src/src/WebServer/FileList.cpp | 2 +- src/src/WebServer/HardwarePage.cpp | 2 +- src/src/WebServer/I2C_Scanner.cpp | 2 +- src/src/WebServer/JSON.cpp | 2 +- src/src/WebServer/LoadFromFS.cpp | 2 +- src/src/WebServer/Log.cpp | 2 +- src/src/WebServer/Markup_Forms.cpp | 2 +- src/src/WebServer/Metrics.cpp | 2 +- src/src/WebServer/NotificationPage.cpp | 2 +- src/src/WebServer/PinStates.cpp | 2 +- src/src/WebServer/RootPage.cpp | 2 +- src/src/WebServer/Rules.cpp | 128 ++++++++-------- src/src/WebServer/SettingsArchive.cpp | 2 +- src/src/WebServer/SetupPage.cpp | 2 +- src/src/WebServer/SysInfoPage.cpp | 6 +- src/src/WebServer/SysVarPage.cpp | 2 +- src/src/WebServer/TimingStats.cpp | 2 +- src/src/WebServer/ToolsPage.cpp | 2 +- src/src/WebServer/UploadPage.cpp | 2 +- src/src/WebServer/WiFiScanner.cpp | 2 +- src/src/WebServer/common.h | 16 +- 58 files changed, 291 insertions(+), 246 deletions(-) create mode 100644 include/ESPEasy_config.h rename src/src/WebServer/{WebServer.cpp => ESPEasy_WebServer.cpp} (99%) rename src/src/WebServer/{WebServer.h => ESPEasy_WebServer.h} (100%) diff --git a/include/ESPEasy_config.h b/include/ESPEasy_config.h new file mode 100644 index 000000000..f384cfde9 --- /dev/null +++ b/include/ESPEasy_config.h @@ -0,0 +1,109 @@ +#ifndef INCLUDE_ESPEASY_CONFIG_H +#define INCLUDE_ESPEASY_CONFIG_H + +#ifdef __cplusplus + +//#include + +//#include + +//#include +//#include + + +#ifdef __GCC__ +#pragma GCC system_header +#endif + + +/******************************************************************************\ + * Detect core versions ******************************************************* +\******************************************************************************/ + +#ifndef ESP32 + #if defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) + #ifndef CORE_2_4_X + #define CORE_2_4_X + #endif + #endif + + #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) + #ifndef CORE_PRE_2_4_2 + #define CORE_PRE_2_4_2 + #endif + #endif + + #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(CORE_2_4_X) + #ifndef CORE_PRE_2_5_0 + #define CORE_PRE_2_5_0 + #endif + #else + #ifndef CORE_POST_2_5_0 + #define CORE_POST_2_5_0 + #endif + #endif + + + #ifdef FORCE_PRE_2_5_0 + #ifdef CORE_POST_2_5_0 + #undef CORE_POST_2_5_0 + #endif + #endif + +/* + #ifndef CORE_POST_2_5_0 + #define STR_HELPER(x) #x + #define STR(x) STR_HELPER(x) + #endif +*/ + +#endif + + +#if defined(ESP8266) + #include + + #ifndef CORE_POST_3_0_0 + #ifndef IRAM_ATTR + #define IRAM_ATTR ICACHE_RAM_ATTR + #endif + #endif +#endif + +#if defined(ESP32) + #include + #if ESP_IDF_VERSION_MAJOR < 3 + #ifndef ICACHE_RAM_ATTR + #define ICACHE_RAM_ATTR IRAM_ATTR + #endif + #endif +#endif + +#define ZERO_FILL(S) memset((S), 0, sizeof(S)) +#define ZERO_TERMINATE(S) S[sizeof(S) - 1] = 0 + + + + + +// User configuration +// Include Custom.h before ESPEasyDefaults.h. +#ifdef USE_CUSTOM_H + // make the compiler show a warning to confirm that this file is inlcuded + //#warning "**** Using Settings from Custom.h File ***" + #include "../src/Custom.h" +#endif + +// Check if any deprecated '#define ' (Custom.h) or '-D' (pre_custom_esp82xx.py/pre_custom_esp32.py) are used + +#include "../src/src/CustomBuild/check_defines_custom.h" // Check for replaced #define variables, see https://github.com/letscontrolit/ESPEasy/pull/4153 + +// Include custom first, then build info. (one may want to set BUILD_GIT for example) +#include "../src/src/CustomBuild/ESPEasy_buildinfo.h" +#include "../src/src/CustomBuild/ESPEasyLimits.h" +#include "../src/src/CustomBuild/define_plugin_sets.h" + + +#endif // ifdef __cplusplus + +#endif // ifndef INCLUDE_ESPEASY_CONFIG_H diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 6b03e8e83..48a86c174 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -38,6 +38,9 @@ build_flags = -D NDEBUG -DVTABLES_IN_FLASH -DPUYA_SUPPORT=1 -fno-strict-aliasing + -I$PROJECT_DIR/include + -include "ESPEasy_config.h" + lib_ignore = ESP32_ping ESP32WebServer ESP32HTTPUpdateServer @@ -57,6 +60,8 @@ build_flags = -DNDEBUG -DCORE_POST_2_5_0 -fno-strict-aliasing -DLIBRARIES_NO_LOG=1 + -I$PROJECT_DIR/include + -include "ESPEasy_config.h" lib_ignore = ${esp82xx_defaults.lib_ignore} [esp82xx_2_6_x] @@ -75,7 +80,6 @@ build_flags = ${esp82xx_2_6_x.build_flags} -DCORE_POST_3_0_0 -Wno-deprecated-declarations -Werror=return-type - -DFS_NO_GLOBALS lib_ignore = ${esp82xx_defaults.lib_ignore} @@ -231,6 +235,9 @@ platform_packages = framework-arduinoespressif32 @ https://github.com/ build_flags = -DESP32_STAGE -DMUSTFIX_CLIENT_TIMEOUT_IN_SECONDS -DLIBRARIES_NO_LOG=1 + -I$PROJECT_DIR/include + -include "sdkconfig.h" + -include "ESPEasy_config.h" [core_esp32_stage] platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.4.1/platform-espressif32-2.0.4.1.zip @@ -238,3 +245,6 @@ platform_packages = build_flags = -DESP32_STAGE -DMUSTFIX_CLIENT_TIMEOUT_IN_SECONDS -DLIBRARIES_NO_LOG=1 + -I$PROJECT_DIR/include + -include "sdkconfig.h" + -include "ESPEasy_config.h" diff --git a/src/ESPEasy_common.cpp b/src/ESPEasy_common.cpp index aa7e6a602..e58e339b4 100644 --- a/src/ESPEasy_common.cpp +++ b/src/ESPEasy_common.cpp @@ -1,6 +1,4 @@ #include "ESPEasy_common.h" -String getUnknownString() { return F("Unknown"); } - const String EMPTY_STRING; \ No newline at end of file diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index 6c6b36706..8825b49a1 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -14,30 +14,18 @@ */ -#ifndef CORE_POST_2_5_0 - #define STR_HELPER(x) #x - #define STR(x) STR_HELPER(x) -#endif +#include +// User configuration +#include "../include/ESPEasy_config.h" +#include "./src/CustomBuild/ESPEasyDefaults.h" + #ifdef USE_SECOND_HEAP #include #endif -#ifdef __GCC__ -#pragma GCC system_header -#endif -#include -namespace std -{ - using ::ptrdiff_t; - using ::size_t; -} - -#include -#include -#include #ifdef ESP8266 @@ -50,37 +38,13 @@ namespace std # define SUPPORT_ARP #endif -// User configuration -// Include Custom.h before ESPEasyDefaults.h. -#ifdef USE_CUSTOM_H -// make the compiler show a warning to confirm that this file is inlcuded -//#warning "**** Using Settings from Custom.h File ***" - #include "Custom.h" -#else - // Set as default -// #define PLUGIN_BUILD_NORMAL -#endif - -// Check if any deprecated '#define ' (Custom.h) or '-D' (pre_custom_esp82xx.py/pre_custom_esp32.py) are used -#include "./src/CustomBuild/check_defines_custom.h" // Check for replaced #define variables, see https://github.com/letscontrolit/ESPEasy/pull/4153 - -#include "src/CustomBuild/ESPEasyDefaults.h" #include "src/DataStructs/NodeStruct.h" #include "src/Globals/RamTracker.h" #include "src/ESPEasyCore/ESPEasy_Log.h" #include "src/Helpers/ESPEasy_math.h" -#ifndef FS_NO_GLOBALS - #define FS_NO_GLOBALS -#endif #if defined(ESP8266) - #ifndef CORE_POST_3_0_0 - #define IRAM_ATTR ICACHE_RAM_ATTR - #endif - - - #include #define NODE_TYPE_ID NODE_TYPE_ID_ESP_EASYM_STD #include @@ -111,9 +75,6 @@ namespace std #endif #if defined(ESP32) - // Temp fix for a missing core_version.h within ESP Arduino core. Wait until they actually have different releases - #define ARDUINO_ESP8266_RELEASE "2_4_0" - #ifdef ESP32S2 #define NODE_TYPE_ID NODE_TYPE_ID_ESP_EASY32S2_STD #elif defined(ESP32C3) @@ -121,10 +82,7 @@ namespace std #else #define NODE_TYPE_ID NODE_TYPE_ID_ESP_EASY32_STD #endif - #if ESP_IDF_VERSION_MAJOR < 3 - #define ICACHE_RAM_ATTR IRAM_ATTR - #endif - #include +// #include // #include "esp32_ping.h" #ifdef ESP32S2 @@ -140,99 +98,22 @@ namespace std #include // Needed to call ESP-IDF functions like esp_wifi_.... #endif -#ifdef USE_LITTLEFS - #ifdef ESP32 - #if ESP_IDF_VERSION_MAJOR >= 4 - #include - #define ESPEASY_FS LittleFS - #else - #include - #define ESPEASY_FS LITTLEFS - #endif - #else - #include - #define ESPEASY_FS LittleFS - #endif -#else - #ifdef ESP32 - #include - #endif - #define ESPEASY_FS SPIFFS -#endif #include -#include -#include -#include -#if FEATURE_SD -#include -#else -using namespace fs; -#endif -#include +//#include +//#include +//#include -// Include custom first, then build info. (one may want to set BUILD_GIT for example) -#include "src/CustomBuild/ESPEasy_buildinfo.h" -#include "src/CustomBuild/ESPEasyLimits.h" -#include "src/CustomBuild/define_plugin_sets.h" - #ifdef ESP32 #include #endif - -#define ZERO_FILL(S) memset((S), 0, sizeof(S)) -#define ZERO_TERMINATE(S) S[sizeof(S) - 1] = 0 - - - -String getUnknownString(); - extern const String EMPTY_STRING; - -/******************************************************************************\ - * Detect core versions ******************************************************* -\******************************************************************************/ - -#ifndef ESP32 - #if defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) - #ifndef CORE_2_4_X - #define CORE_2_4_X - #endif - #endif - - #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) - #ifndef CORE_PRE_2_4_2 - #define CORE_PRE_2_4_2 - #endif - #endif - - #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(CORE_2_4_X) - #ifndef CORE_PRE_2_5_0 - #define CORE_PRE_2_5_0 - #endif - #else - #ifndef CORE_POST_2_5_0 - #define CORE_POST_2_5_0 - #endif - #endif - - - #ifdef FORCE_PRE_2_5_0 - #ifdef CORE_POST_2_5_0 - #undef CORE_POST_2_5_0 - #endif - #endif -#endif // ESP32 - - - - // Enable FEATURE_ADC_VCC to measure supply voltage using the analog pin // Please note that the TOUT pin has to be disconnected in this mode // Use the "System Info" device to read the VCC value diff --git a/src/_N001_Email.cpp b/src/_N001_Email.cpp index d26d89932..f400d0510 100644 --- a/src/_N001_Email.cpp +++ b/src/_N001_Email.cpp @@ -24,6 +24,8 @@ #include "src/Helpers/_CPlugin_Helper.h" // safeReadStringUntil #include "src/Helpers/_NPlugin_init.h" +#include + // Forward declaration bool NPlugin_001_send(const NotificationSettingsStruct& notificationsettings, const String& aSub, String& aMesg); bool NPlugin_001_Auth(WiFiClient& client, const String& user, const String& pass); diff --git a/src/_P021_Level.ino b/src/_P021_Level.ino index fcdc5e11b..3d008cb90 100644 --- a/src/_P021_Level.ino +++ b/src/_P021_Level.ino @@ -14,7 +14,7 @@ # include "src/Helpers/ESPEasy_math.h" # include "src/Helpers/Rules_calculate.h" -# include "src/WebServer/WebServer.h" +# include "src/WebServer/ESPEasy_WebServer.h" # define PLUGIN_021 # define PLUGIN_ID_021 21 diff --git a/src/_Plugin_Helper.h b/src/_Plugin_Helper.h index 3edecbf47..1db8369d2 100644 --- a/src/_Plugin_Helper.h +++ b/src/_Plugin_Helper.h @@ -53,7 +53,7 @@ #include "src/WebServer/HTML_wrappers.h" #include "src/WebServer/Markup.h" #include "src/WebServer/Markup_Forms.h" -#include "src/WebServer/WebServer.h" +#include "src/WebServer/ESPEasy_WebServer.h" // Defines to make plugins more readable. diff --git a/src/src/CustomBuild/ESPEasyLimits.h b/src/src/CustomBuild/ESPEasyLimits.h index 386611012..348679f6d 100644 --- a/src/src/CustomBuild/ESPEasyLimits.h +++ b/src/src/CustomBuild/ESPEasyLimits.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_ESPEASY_LIMITS_H #define CUSTOMBUILD_ESPEASY_LIMITS_H -#include "../../ESPEasy_common.h" +#include "ESPEasy_config.h" // *********************************************************************** // * These limits have direct impact on the settings files diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 6509b11a2..ded98d9ba 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_DEFINE_PLUGIN_SETS_H #define CUSTOMBUILD_DEFINE_PLUGIN_SETS_H -#include "../../ESPEasy_common.h" +#include "ESPEasy_config.h" /* ################################################# diff --git a/src/src/DataTypes/NetworkMedium.h b/src/src/DataTypes/NetworkMedium.h index 388a6c37b..4e45ebe1d 100644 --- a/src/src/DataTypes/NetworkMedium.h +++ b/src/src/DataTypes/NetworkMedium.h @@ -4,7 +4,7 @@ #include // Is stored in settings -enum class NetworkMedium_t : uint8_t { +enum class NetworkMedium_t : unsigned char { WIFI = 0, Ethernet = 1 }; diff --git a/src/src/ESPEasyCore/ESPEasy_setup.cpp b/src/src/ESPEasyCore/ESPEasy_setup.cpp index 0d3c93b27..46cbf9050 100644 --- a/src/src/ESPEasyCore/ESPEasy_setup.cpp +++ b/src/src/ESPEasyCore/ESPEasy_setup.cpp @@ -27,7 +27,7 @@ #include "../Helpers/Memory.h" #include "../Helpers/Misc.h" #include "../Helpers/StringGenerator_System.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #ifdef USE_RTOS_MULTITASKING diff --git a/src/src/Globals/Services.cpp b/src/src/Globals/Services.cpp index f3971e2a4..f8a7cd4e8 100644 --- a/src/src/Globals/Services.cpp +++ b/src/src/Globals/Services.cpp @@ -13,8 +13,6 @@ #endif #ifdef ESP32 - #include - #include WebServer web_server(80); #ifndef NO_HTTP_UPDATER ESP32HTTPUpdateServer httpUpdater(true); @@ -23,7 +21,6 @@ #if FEATURE_DNS_SERVER - #include DNSServer dnsServer; bool dnsServerActive = false; #endif // if FEATURE_DNS_SERVER diff --git a/src/src/Globals/Services.h b/src/src/Globals/Services.h index 7d4197e51..6db7783ec 100644 --- a/src/src/Globals/Services.h +++ b/src/src/Globals/Services.h @@ -32,6 +32,7 @@ #ifdef ESP32 #include + #include #include extern WebServer web_server; diff --git a/src/src/Helpers/ESPEasyStatistics.cpp b/src/src/Helpers/ESPEasyStatistics.cpp index a013fd7b4..8f9c897d4 100644 --- a/src/src/Helpers/ESPEasyStatistics.cpp +++ b/src/src/Helpers/ESPEasyStatistics.cpp @@ -4,7 +4,7 @@ #if FEATURE_TIMING_STATS #include "../DataStructs/TimingStats.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../Globals/Protocol.h" #include "../Helpers/Convert.h" diff --git a/src/src/Helpers/ESPEasy_FactoryDefault.cpp b/src/src/Helpers/ESPEasy_FactoryDefault.cpp index 491d35259..c64b4e2bf 100644 --- a/src/src/Helpers/ESPEasy_FactoryDefault.cpp +++ b/src/src/Helpers/ESPEasy_FactoryDefault.cpp @@ -19,6 +19,7 @@ #include "../Helpers/_CPlugin_Helper.h" #include "../Helpers/ESPEasyRTC.h" +#include "../Helpers/FS_Helper.h" #include "../Helpers/Hardware.h" #include "../Helpers/Misc.h" diff --git a/src/src/Helpers/ESPEasy_Storage.h b/src/src/Helpers/ESPEasy_Storage.h index fc3dbd323..9ac92f042 100644 --- a/src/src/Helpers/ESPEasy_Storage.h +++ b/src/src/Helpers/ESPEasy_Storage.h @@ -4,7 +4,7 @@ #include "../../ESPEasy_common.h" -#include +#include "../Helpers/FS_Helper.h" #include "../DataStructs/ProvisioningStruct.h" #include "../DataTypes/ESPEasyFileType.h" diff --git a/src/src/Helpers/FS_Helper.h b/src/src/Helpers/FS_Helper.h index 2a982b4d6..4d491ae63 100644 --- a/src/src/Helpers/FS_Helper.h +++ b/src/src/Helpers/FS_Helper.h @@ -8,9 +8,35 @@ // Macro used to make file system operations a bit more readable. #define SPIFFS_CHECK(result, fname) if (!(result)) { return(FileError(__LINE__, fname)); } -#ifndef FS_NO_GLOBALS - #define FS_NO_GLOBALS +#ifdef USE_LITTLEFS + #ifdef ESP32 + #if ESP_IDF_VERSION_MAJOR >= 4 + #include + #define ESPEASY_FS LittleFS + #else + #include + #define ESPEASY_FS LITTLEFS + #endif + #else + #include + #define ESPEASY_FS LittleFS + #endif +#else + #ifdef ESP32 + #include + #endif + #define ESPEASY_FS SPIFFS #endif + + +#include +#if FEATURE_SD +#include +#else +using namespace fs; +#endif + + #if defined(ESP8266) extern "C" { #include diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index a6bafe1b7..893c56ea7 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -49,6 +49,9 @@ # include #endif // if FEATURE_SD + +#include + /********************************************************************************************\ * Initialize specific hardware settings (only global ones, others are set through devices) \*********************************************************************************************/ diff --git a/src/src/Helpers/OTA.cpp b/src/src/Helpers/OTA.cpp index 624bea983..fba3e3335 100644 --- a/src/src/Helpers/OTA.cpp +++ b/src/src/Helpers/OTA.cpp @@ -5,6 +5,7 @@ #include "../Globals/SecuritySettings.h" #include "../Globals/Services.h" #include "../Globals/Settings.h" +#include "../Helpers/FS_Helper.h" #include "../Helpers/Hardware.h" #include "../Helpers/Misc.h" diff --git a/src/src/Helpers/PeriodicalActions.cpp b/src/src/Helpers/PeriodicalActions.cpp index 31543222b..4557f3e16 100644 --- a/src/src/Helpers/PeriodicalActions.cpp +++ b/src/src/Helpers/PeriodicalActions.cpp @@ -28,6 +28,7 @@ #include "../Globals/Statistics.h" #include "../Globals/WiFi_AP_Candidates.h" #include "../Helpers/ESPEasyRTC.h" +#include "../Helpers/FS_Helper.h" #include "../Helpers/Hardware.h" #include "../Helpers/Memory.h" #include "../Helpers/Misc.h" diff --git a/src/src/Helpers/StringGenerator_System.cpp b/src/src/Helpers/StringGenerator_System.cpp index 98a7ddaf7..523648457 100644 --- a/src/src/Helpers/StringGenerator_System.cpp +++ b/src/src/Helpers/StringGenerator_System.cpp @@ -138,7 +138,7 @@ String getResetReasonString(uint8_t icore) { return reason; } - return getUnknownString(); + return F("Unknown"); } #endif // ifdef ESP32 @@ -231,3 +231,4 @@ String getLWIPversion() { } #endif // ifdef ESP8266 + diff --git a/src/src/Helpers/_CPlugin_Helper_webform.cpp b/src/src/Helpers/_CPlugin_Helper_webform.cpp index c8840c25e..e651860aa 100644 --- a/src/src/Helpers/_CPlugin_Helper_webform.cpp +++ b/src/src/Helpers/_CPlugin_Helper_webform.cpp @@ -9,7 +9,7 @@ #include "../Globals/Settings.h" #include "../Helpers/_CPlugin_Helper.h" #include "../Helpers/Networking.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Forms.h" diff --git a/src/src/PluginStructs/P037_data_struct.cpp b/src/src/PluginStructs/P037_data_struct.cpp index ad5ae5a0c..16899a07e 100644 --- a/src/src/PluginStructs/P037_data_struct.cpp +++ b/src/src/PluginStructs/P037_data_struct.cpp @@ -6,7 +6,7 @@ # include "../Helpers/Numerical.h" # include "../Helpers/RulesMatcher.h" # include "../WebServer/Markup_Forms.h" -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../WebServer/Markup.h" # include "../WebServer/HTML_wrappers.h" # include "../ESPEasyCore/ESPEasyRules.h" diff --git a/src/src/PluginStructs/P104_data_struct.cpp b/src/src/PluginStructs/P104_data_struct.cpp index 3d2f0f75a..32756c824 100644 --- a/src/src/PluginStructs/P104_data_struct.cpp +++ b/src/src/PluginStructs/P104_data_struct.cpp @@ -5,7 +5,7 @@ # include "../Helpers/ESPEasy_Storage.h" # include "../Helpers/Numerical.h" # include "../WebServer/Markup_Forms.h" -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../WebServer/Markup.h" # include "../WebServer/HTML_wrappers.h" # include "../ESPEasyCore/ESPEasyRules.h" diff --git a/src/src/WebServer/404.cpp b/src/src/WebServer/404.cpp index 9fcd3f11b..4ded20b8b 100644 --- a/src/src/WebServer/404.cpp +++ b/src/src/WebServer/404.cpp @@ -1,6 +1,6 @@ #include "../WebServer/404.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/LoadFromFS.h" #include "../WebServer/Rules.h" diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 3f78b64a4..1fd5da53f 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -6,7 +6,7 @@ #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" #include "../WebServer/Markup_Forms.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../ESPEasyCore/ESPEasyWifi.h" diff --git a/src/src/WebServer/CacheControllerPages.cpp b/src/src/WebServer/CacheControllerPages.cpp index 98fbc3276..ac8000711 100644 --- a/src/src/WebServer/CacheControllerPages.cpp +++ b/src/src/WebServer/CacheControllerPages.cpp @@ -2,7 +2,7 @@ #ifdef USES_C016 -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/JSON.h" diff --git a/src/src/WebServer/ConfigPage.cpp b/src/src/WebServer/ConfigPage.cpp index c38154d3d..db35d2a0f 100644 --- a/src/src/WebServer/ConfigPage.cpp +++ b/src/src/WebServer/ConfigPage.cpp @@ -7,7 +7,7 @@ #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" #include "../WebServer/Markup_Forms.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../ESPEasyCore/Controller.h" #include "../ESPEasyCore/ESPEasyNetwork.h" diff --git a/src/src/WebServer/ControlPage.cpp b/src/src/WebServer/ControlPage.cpp index cc3bb8e83..5848d7d48 100644 --- a/src/src/WebServer/ControlPage.cpp +++ b/src/src/WebServer/ControlPage.cpp @@ -5,7 +5,7 @@ # include "../WebServer/HTML_wrappers.h" -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../Helpers/WebServer_commandHelper.h" # include "../../ESPEasy-Globals.h" diff --git a/src/src/WebServer/ControllerPage.cpp b/src/src/WebServer/ControllerPage.cpp index 3a05985fb..ec1ddd439 100644 --- a/src/src/WebServer/ControllerPage.cpp +++ b/src/src/WebServer/ControllerPage.cpp @@ -3,7 +3,7 @@ #ifdef WEBSERVER_CONTROLLERS -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/CustomPage.cpp b/src/src/WebServer/CustomPage.cpp index aa6ca1755..9b7fc215f 100644 --- a/src/src/WebServer/CustomPage.cpp +++ b/src/src/WebServer/CustomPage.cpp @@ -1,6 +1,6 @@ #include "../WebServer/CustomPage.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 00a74aece..485804339 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_DEVICES -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../WebServer/HTML_wrappers.h" # include "../WebServer/Markup.h" # include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/DownloadPage.cpp b/src/src/WebServer/DownloadPage.cpp index 004c29b4f..fac795533 100644 --- a/src/src/WebServer/DownloadPage.cpp +++ b/src/src/WebServer/DownloadPage.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_DOWNLOAD -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../Globals/ESPEasy_time.h" #include "../Globals/Settings.h" #include "../Helpers/ESPEasy_Storage.h" diff --git a/src/src/WebServer/WebServer.cpp b/src/src/WebServer/ESPEasy_WebServer.cpp similarity index 99% rename from src/src/WebServer/WebServer.cpp rename to src/src/WebServer/ESPEasy_WebServer.cpp index f1e1ef8ce..4dedcad27 100644 --- a/src/src/WebServer/WebServer.cpp +++ b/src/src/WebServer/ESPEasy_WebServer.cpp @@ -1,4 +1,4 @@ -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/404.h" #include "../WebServer/AccessControl.h" diff --git a/src/src/WebServer/WebServer.h b/src/src/WebServer/ESPEasy_WebServer.h similarity index 100% rename from src/src/WebServer/WebServer.h rename to src/src/WebServer/ESPEasy_WebServer.h diff --git a/src/src/WebServer/FactoryResetPage.cpp b/src/src/WebServer/FactoryResetPage.cpp index 3ced4bad6..6709e9aad 100644 --- a/src/src/WebServer/FactoryResetPage.cpp +++ b/src/src/WebServer/FactoryResetPage.cpp @@ -3,7 +3,7 @@ #ifdef WEBSERVER_FACTORY_RESET -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/JSON.h" #include "../WebServer/Markup.h" diff --git a/src/src/WebServer/Favicon.cpp b/src/src/WebServer/Favicon.cpp index f163b80cb..a0d670479 100644 --- a/src/src/WebServer/Favicon.cpp +++ b/src/src/WebServer/Favicon.cpp @@ -1,7 +1,7 @@ #include "../WebServer/Favicon.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/404.h" #include "../Globals/RamTracker.h" diff --git a/src/src/WebServer/FileList.cpp b/src/src/WebServer/FileList.cpp index 23e7ac01f..58ab6168e 100644 --- a/src/src/WebServer/FileList.cpp +++ b/src/src/WebServer/FileList.cpp @@ -1,6 +1,6 @@ #include "../WebServer/FileList.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/AccessControl.h" #include "../WebServer/Markup.h" diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 1db17b82f..97b7c36bd 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_HARDWARE -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/I2C_Scanner.cpp b/src/src/WebServer/I2C_Scanner.cpp index d7a1a4530..ce552fe3f 100644 --- a/src/src/WebServer/I2C_Scanner.cpp +++ b/src/src/WebServer/I2C_Scanner.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_I2C_SCANNER -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index a720cbbfb..39f6ebf6d 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -1,6 +1,6 @@ #include "../WebServer/JSON.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/JSON.h" #include "../WebServer/Markup_Forms.h" diff --git a/src/src/WebServer/LoadFromFS.cpp b/src/src/WebServer/LoadFromFS.cpp index a1b1dd9b0..d79398afd 100644 --- a/src/src/WebServer/LoadFromFS.cpp +++ b/src/src/WebServer/LoadFromFS.cpp @@ -7,7 +7,7 @@ #include "../WebServer/CustomPage.h" #include "../WebServer/HTML_wrappers.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #if FEATURE_SD # include diff --git a/src/src/WebServer/Log.cpp b/src/src/WebServer/Log.cpp index de6026522..1315a6ffc 100644 --- a/src/src/WebServer/Log.cpp +++ b/src/src/WebServer/Log.cpp @@ -1,6 +1,6 @@ #include "../WebServer/Log.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/404.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/JSON.h" diff --git a/src/src/WebServer/Markup_Forms.cpp b/src/src/WebServer/Markup_Forms.cpp index 8f2886c88..e5e2b2b1e 100644 --- a/src/src/WebServer/Markup_Forms.cpp +++ b/src/src/WebServer/Markup_Forms.cpp @@ -1,6 +1,6 @@ #include "../WebServer/Markup_Forms.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/Markup.h" #include "../WebServer/HTML_wrappers.h" diff --git a/src/src/WebServer/Metrics.cpp b/src/src/WebServer/Metrics.cpp index 6a3394bc8..64f674c7b 100644 --- a/src/src/WebServer/Metrics.cpp +++ b/src/src/WebServer/Metrics.cpp @@ -1,5 +1,5 @@ # include "../WebServer/Metrics.h" -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../../ESPEasy-Globals.h" # include "../Commands/Diagnostic.h" # include "../ESPEasyCore/ESPEasyNetwork.h" diff --git a/src/src/WebServer/NotificationPage.cpp b/src/src/WebServer/NotificationPage.cpp index bf26c991d..3398cb581 100644 --- a/src/src/WebServer/NotificationPage.cpp +++ b/src/src/WebServer/NotificationPage.cpp @@ -2,7 +2,7 @@ #if FEATURE_NOTIFIER -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/PinStates.cpp b/src/src/WebServer/PinStates.cpp index d62a6f7e3..e27e1b914 100644 --- a/src/src/WebServer/PinStates.cpp +++ b/src/src/WebServer/PinStates.cpp @@ -1,6 +1,6 @@ #include "../WebServer/PinStates.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../DataStructs/PinMode.h" diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 446392053..325a2a301 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -3,7 +3,7 @@ #ifdef WEBSERVER_ROOT -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/LoadFromFS.h" #include "../WebServer/Markup.h" diff --git a/src/src/WebServer/Rules.cpp b/src/src/WebServer/Rules.cpp index fa2663494..6f2b5bc7e 100644 --- a/src/src/WebServer/Rules.cpp +++ b/src/src/WebServer/Rules.cpp @@ -2,7 +2,9 @@ #include "../WebServer/Rules.h" -#include "../WebServer/WebServer.h" +#ifdef WEBSERVER_RULES + +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/LoadFromFS.h" @@ -20,8 +22,6 @@ #include -#ifdef WEBSERVER_RULES - // ******************************************************************************** // Web Interface rules page // ******************************************************************************** @@ -73,9 +73,9 @@ void handle_rules() { addHtml(F("

")); { // Place combo box in its own scope to release these arrays as soon as possible - uint8_t choice = rulesSet; - String options[RULESETS_MAX]; - int optionValues[RULESETS_MAX]; + uint8_t choice = rulesSet; + String options[RULESETS_MAX]; + int optionValues[RULESETS_MAX]; for (uint8_t x = 0; x < RULESETS_MAX; x++) { @@ -85,13 +85,13 @@ void handle_rules() { } addSelector_reloadOnChange( - F("set"), - RULESETS_MAX, - options, - optionValues, - nullptr, - choice, - F("return rules_set_onchange(rulesselect)"), + F("set"), + RULESETS_MAX, + options, + optionValues, + nullptr, + choice, + F("return rules_set_onchange(rulesselect)"), true, F("wide")); addHelpButton(F("Tutorial_Rules")); @@ -172,68 +172,69 @@ void handle_rules_new() { // class StreamingBuffer buffer = TXBuffer; // Build table detail - int count = -1; - HandlerFileInfo renderDetail = [/*&buffer,*/ &count, endIdx](fileInfo fi) - { + int count = -1; + HandlerFileInfo renderDetail = + [/*&buffer,*/ &count, endIdx](fileInfo fi) + { # ifdef WEBSERVER_RULES_DEBUG - Serial.print(F("Start generation of: ")); - Serial.println(fi.Name); + Serial.print(F("Start generation of: ")); + Serial.println(fi.Name); # endif // ifdef WEBSERVER_RULES_DEBUG - if (fi.isDirectory) - { - html_TR_TD(); - } - else - { - count++; - addHtml(F("")); - } + if (fi.isDirectory) + { + html_TR_TD(); + } + else + { + count++; + addHtml(F("")); + } - // Event Name - addHtml(FileNameToEvent(fi.Name)); + // Event Name + addHtml(FileNameToEvent(fi.Name)); - if (fi.isDirectory) - { - addHtml(F("")); - addSaveButton(String(F("/rules/backup?directory=")) + URLEncode(fi.Name) - , F("Backup") - ); - } - else - { - String encodedPath = URLEncode(String(fi.Name + F(".txt"))); + if (fi.isDirectory) + { + addHtml(F("")); + addSaveButton(String(F("/rules/backup?directory=")) + URLEncode(fi.Name) + , F("Backup") + ); + } + else + { + String encodedPath = URLEncode(String(fi.Name + F(".txt"))); - // File Name - addHtml(F("")); - addHtml(String(fi.Name)); - addHtml(F(".txt")); + // File Name + addHtml(F("")); + addHtml(String(fi.Name)); + addHtml(F(".txt")); - // File size - html_TD(); - addHtmlInt(fi.Size); - addHtml(F("")); + // File size + html_TD(); + addHtmlInt(fi.Size); + addHtml(F("")); - // Actions - html_TD(); - addSaveButton(String(F("/rules/backup?fileName=")) + encodedPath - , F("Backup") - ); + // Actions + html_TD(); + addSaveButton(String(F("/rules/backup?fileName=")) + encodedPath + , F("Backup") + ); - addDeleteButton(String(F("/rules/delete?fileName=")) + encodedPath - , F("Delete") - ); - } - addHtml(F("")); + addDeleteButton(String(F("/rules/delete?fileName=")) + encodedPath + , F("Delete") + ); + } + addHtml(F("")); # ifdef WEBSERVER_RULES_DEBUG - Serial.print(F("End generation of: ")); - Serial.println(fi.Name); + Serial.print(F("End generation of: ")); + Serial.println(fi.Name); # endif // ifdef WEBSERVER_RULES_DEBUG - return count < endIdx; - }; + return count < endIdx; + }; bool hasMore = EnumerateFileAndDirectory(rootPath @@ -400,6 +401,7 @@ bool handle_rules_edit(String originalUri, bool isAddNew) { if (isAddNew || (originalUri.startsWith(F("/rules/")) && originalUri.endsWith(F(".txt")))) { if (!isLoggedIn() || !Settings.UseRules) { return false; } + if (Settings.OldRulesEngine()) { Goto_Rules_Root(); diff --git a/src/src/WebServer/SettingsArchive.cpp b/src/src/WebServer/SettingsArchive.cpp index 2ccf2b7d6..d1c08cf50 100644 --- a/src/src/WebServer/SettingsArchive.cpp +++ b/src/src/WebServer/SettingsArchive.cpp @@ -2,7 +2,7 @@ #if FEATURE_SETTINGS_ARCHIVE -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/SetupPage.cpp b/src/src/WebServer/SetupPage.cpp index edcea65a6..e03ee9304 100644 --- a/src/src/WebServer/SetupPage.cpp +++ b/src/src/WebServer/SetupPage.cpp @@ -3,7 +3,7 @@ #ifdef WEBSERVER_SETUP -# include "../WebServer/WebServer.h" +# include "../WebServer/ESPEasy_WebServer.h" # include "../WebServer/AccessControl.h" # include "../WebServer/HTML_wrappers.h" # include "../WebServer/Markup.h" diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index 32122b841..1eb025f4b 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -2,7 +2,7 @@ #if defined(WEBSERVER_SYSINFO) || defined(SHOW_SYSINFO_JSON) -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" @@ -200,7 +200,7 @@ void handle_sysinfo_json() { case FM_DIO: json_prop(F("mode"), F("DIO")); break; case FM_DOUT: json_prop(F("mode"), F("DOUT")); break; default: - json_prop(F("mode"), getUnknownString()); break; + json_prop(F("mode"), F("Unknown")); break; } json_number(F("writes"), String(RTC.flashDayCounter)); @@ -637,7 +637,7 @@ void handle_sysinfo_Storage() { case FM_DIO: addHtml(F("DIO")); break; case FM_DOUT: addHtml(F("DOUT")); break; default: - addHtml(getUnknownString()); break; + addHtml(F("Unknown")); break; } } diff --git a/src/src/WebServer/SysVarPage.cpp b/src/src/WebServer/SysVarPage.cpp index bedbdf369..b18234015 100644 --- a/src/src/WebServer/SysVarPage.cpp +++ b/src/src/WebServer/SysVarPage.cpp @@ -3,7 +3,7 @@ #ifdef WEBSERVER_SYSVARS -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Forms.h" diff --git a/src/src/WebServer/TimingStats.cpp b/src/src/WebServer/TimingStats.cpp index 93cd02ac7..514c5673c 100644 --- a/src/src/WebServer/TimingStats.cpp +++ b/src/src/WebServer/TimingStats.cpp @@ -2,7 +2,7 @@ #if defined(WEBSERVER_TIMINGSTATS) && FEATURE_TIMING_STATS -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Forms.h" diff --git a/src/src/WebServer/ToolsPage.cpp b/src/src/WebServer/ToolsPage.cpp index 3a56f82b4..f205618a6 100644 --- a/src/src/WebServer/ToolsPage.cpp +++ b/src/src/WebServer/ToolsPage.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_TOOLS -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/HTML_wrappers.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" diff --git a/src/src/WebServer/UploadPage.cpp b/src/src/WebServer/UploadPage.cpp index b3364472f..56af54015 100644 --- a/src/src/WebServer/UploadPage.cpp +++ b/src/src/WebServer/UploadPage.cpp @@ -1,6 +1,6 @@ #include "../WebServer/UploadPage.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" diff --git a/src/src/WebServer/WiFiScanner.cpp b/src/src/WebServer/WiFiScanner.cpp index f482eb709..14f1d8b0f 100644 --- a/src/src/WebServer/WiFiScanner.cpp +++ b/src/src/WebServer/WiFiScanner.cpp @@ -1,6 +1,6 @@ #include "../WebServer/WiFiScanner.h" -#include "../WebServer/WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" diff --git a/src/src/WebServer/common.h b/src/src/WebServer/common.h index 2de0551e8..d12569cab 100644 --- a/src/src/WebServer/common.h +++ b/src/src/WebServer/common.h @@ -1,12 +1,24 @@ #ifndef WEBSERVER_WEBSERVER_COMMON_H #define WEBSERVER_WEBSERVER_COMMON_H + +#include +#include + +#ifdef ESP32 + #include + #include +#endif + +#ifdef ESP8266 + #include + #include +#endif + #include "../../ESPEasy_common.h" #include "../ESPEasyCore/ESPEasy_Log.h" #include "../Globals/Services.h" #include "../Globals/TXBuffer.h" #include "../Helpers/StringProvider.h" -#include - #endif \ No newline at end of file From 372d5066d198941544e927afc5c11423e1c8cdc1 Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 19 Aug 2022 14:14:52 +0200 Subject: [PATCH 18/32] [Build] Add missing include of Wire.h in ESPEasy_common.h --- src/ESPEasy_common.h | 10 ++-------- src/src/Helpers/Hardware.cpp | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index 8825b49a1..713d8ff30 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -101,16 +101,10 @@ #include -//#include -//#include -//#include +#include +#include -#ifdef ESP32 -#include - -#endif - extern const String EMPTY_STRING; diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 893c56ea7..30d263caf 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -51,6 +51,7 @@ #include +#include /********************************************************************************************\ * Initialize specific hardware settings (only global ones, others are set through devices) From 57451a627c315cfe222e45f2ebe5623cef49ae5a Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 19 Aug 2022 15:13:13 +0200 Subject: [PATCH 19/32] [Build] Fix ESPEasySerial build with DISABLE_SOFTWARE_SERIAL defined --- .../ESPEasySerial_ESP8266_noSWserial.cpp | 13 +++++++------ lib/ESPEasySerial/library.json | 2 +- lib/ESPEasySerial/library.properties | 2 +- platformio_esp32_envs.ini | 2 +- platformio_esp82xx_base.ini | 2 +- src/src/CustomBuild/define_plugin_sets.h | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/ESPEasySerial/ESPEasySerial_ESP8266_noSWserial.cpp b/lib/ESPEasySerial/ESPEasySerial_ESP8266_noSWserial.cpp index 4dd9e408b..de86a6898 100644 --- a/lib/ESPEasySerial/ESPEasySerial_ESP8266_noSWserial.cpp +++ b/lib/ESPEasySerial/ESPEasySerial_ESP8266_noSWserial.cpp @@ -7,7 +7,13 @@ // No SoftwareSerial // Only support HW serial on Serial 0 .. 1 // **************************************** -ESPeasySerial::ESPeasySerial(ESPEasySerialPort port, int receivePin, int transmitPin, bool inverse_logic, unsigned int buffSize) +ESPeasySerial::ESPeasySerial( + ESPEasySerialPort port, + int receivePin, + int transmitPin, + bool inverse_logic, + unsigned int buffSize, + bool forceSWserial) : _receivePin(receivePin), _transmitPin(transmitPin) { _serialtype = ESPeasySerialType::getSerialType(port, receivePin, transmitPin); @@ -259,11 +265,6 @@ unsigned long ESPeasySerial::detectBaudrate(time_t timeoutMillis) { bool ESPeasySerial::listen() { - if (isValid()) { -# ifndef ARDUINO_ESP8266_RELEASE_2_3_0 - return _swserial->listen(); -# endif // ifndef ARDUINO_ESP8266_RELEASE_2_3_0 - } return false; } diff --git a/lib/ESPEasySerial/library.json b/lib/ESPEasySerial/library.json index b86185ece..fd84feb28 100644 --- a/lib/ESPEasySerial/library.json +++ b/lib/ESPEasySerial/library.json @@ -1,6 +1,6 @@ { "name": "ESPeasySerial", - "version": "2.0.13", + "version": "2.0.14", "keywords": [ "serial", "io", "softwareserial", "hardwareserial" ], diff --git a/lib/ESPEasySerial/library.properties b/lib/ESPEasySerial/library.properties index 83ea80441..f15f92360 100644 --- a/lib/ESPEasySerial/library.properties +++ b/lib/ESPEasySerial/library.properties @@ -1,5 +1,5 @@ name=ESPeasySerial -version=2.0.13 +version=2.0.14 author=Gijs Noorlander maintainer=Gijs Noorlander sentence=Wrapper for SoftwareSerial, SC16IS752 I2C to UART bridge and HardwareSerial for ESP8266 and ESP32/ESP32S2. diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 709cc2643..f4603352f 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -38,7 +38,7 @@ lib_deps = adafruit/Adafruit GFX Library@^1.11.1 ccronexpr rlogiacco/CircularBuffer - td-er/ESPeasySerial @ 2.0.13 + td-er/ESPeasySerial @ 2.0.14 sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.3 ShiftRegister74HC595_NonTemplate VL53L0X @ 1.3.0 diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index 5a7d281ed..d70b8ceb8 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -83,7 +83,7 @@ lib_deps = adafruit/Adafruit GFX Library@^1.11.1 bblanchon/ArduinoJson @ ^6.17.2 rlogiacco/CircularBuffer - td-er/ESPeasySerial @ 2.0.13 + td-er/ESPeasySerial @ 2.0.14 td-er/RABurton ESP8266 Mutex @ ^1.0.2 sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.3 VL53L0X @ 1.3.0 diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index ded98d9ba..f2674cc0a 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_DEFINE_PLUGIN_SETS_H #define CUSTOMBUILD_DEFINE_PLUGIN_SETS_H -#include "ESPEasy_config.h" +#include "../../../include/ESPEasy_config.h" /* ################################################# From 512c6743e8aec6e9dba0f9503de1813ee58c7491 Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 19 Aug 2022 20:14:45 +0200 Subject: [PATCH 20/32] [Build] Explicit ignore SD libraries on "minimal" builds --- platformio_esp82xx_base.ini | 10 ++++++++++ platformio_esp82xx_envs.ini | 7 +++++++ src/_Plugin_Helper.h | 2 +- src/src/CustomBuild/ESPEasyLimits.h | 2 +- src/src/CustomBuild/define_plugin_sets.h | 3 ++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index d70b8ceb8..b6d7cadb5 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -239,10 +239,19 @@ build_flags = ${ir.build_flags} [esp82xx_1M] extends = esp82xx_common build_flags = -DBUILD_NO_DEBUG + -DFEATURE_SD=0 -Os -s ${esp82xx_common.build_flags} extra_scripts = ${esp82xx_common.extra_scripts} +lib_ignore = ${esp82xx_common.lib_ignore} + ESP8266SdFat + SD + SDFS + SD(esp8266) + LittleFS + + [esp8266_1M] extends = esp82xx_1M @@ -259,6 +268,7 @@ extends = esp82xx_1M build_flags = ${esp82xx_1M.build_flags} -DPLUGIN_BUILD_MINIMAL_OTA -DDISABLE_SC16IS752_Serial + [esp8266_1M_OTA] diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index 557b49a7c..ee1089557 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -397,6 +397,13 @@ platform_packages = ${core302_platform.platform_packages} build_flags = ${core302_platform.build_flags} ${esp8266_1M_OTA.build_flags} ${minimal_OTA_domoticz.build_flags} +lib_ignore = ${esp82xx_common.lib_ignore} + ESP8266SdFat + SD + SDFS + SD(esp8266) + LittleFS + [env:minimal_core_274_ESP8266_1M_OTA_FHEM_HA] diff --git a/src/_Plugin_Helper.h b/src/_Plugin_Helper.h index 1db8369d2..0621b8c21 100644 --- a/src/_Plugin_Helper.h +++ b/src/_Plugin_Helper.h @@ -3,7 +3,7 @@ #include -#include "ESPEasy_common.h" +#include "../../include/ESPEasy_config.h" #include "src/CustomBuild/ESPEasyLimits.h" diff --git a/src/src/CustomBuild/ESPEasyLimits.h b/src/src/CustomBuild/ESPEasyLimits.h index 348679f6d..963b14713 100644 --- a/src/src/CustomBuild/ESPEasyLimits.h +++ b/src/src/CustomBuild/ESPEasyLimits.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_ESPEASY_LIMITS_H #define CUSTOMBUILD_ESPEASY_LIMITS_H -#include "ESPEasy_config.h" +#include "../../../include/ESPEasy_config.h" // *********************************************************************** // * These limits have direct impact on the settings files diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index f2674cc0a..790f5805e 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1733,7 +1733,7 @@ To create/register a plugin, you have to : /******************************************************************************\ * Libraries dependencies ***************************************************** \******************************************************************************/ -#if defined(USES_P020) || defined(USES_P049) || defined(USES_P052) || defined(USES_P053) || defined(USES_P056) || defined(USES_P071) || defined(USES_P075) || defined(USES_P078) || defined(USES_P082) || defined(USES_P085) || defined(USES_P087) || defined(USES_P094) || defined(USES_P102) || defined(USES_P108) || defined(USES_C018) +#if defined(USES_P020) || defined(USES_P049) || defined(USES_P052) || defined(USES_P053) || defined(USES_P056) || defined(USES_P071) || defined(USES_P075) || defined(USES_P078) || defined(USES_P082) || defined(USES_P085) || defined(USES_P087) || defined(USES_P093)|| defined(USES_P094) || defined(USES_P102) || defined(USES_P105) || defined(USES_P108) || defined(USES_C018) // At least one plugin uses serial. #ifndef PLUGIN_USES_SERIAL #define PLUGIN_USES_SERIAL @@ -1814,6 +1814,7 @@ To create/register a plugin, you have to : #if FEATURE_SD #undef FEATURE_SD // Unlikely on 1M units #define FEATURE_SD 0 + #define NO_GLOBAL_SD #endif #ifndef LIMIT_BUILD_SIZE #define LIMIT_BUILD_SIZE From d75df831d6428f065b54fbc1337a868c77e056c1 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 20 Aug 2022 02:41:14 +0200 Subject: [PATCH 21/32] [Cleanup] Reduce build size for minimal builds --- lib/ESPEasySerial/ESPEasySC16IS752_Serial.cpp | 4 ++++ lib/ESPEasySerial/ESPEasySC16IS752_Serial.h | 3 +++ lib/ESPEasySerial/ESPEasySerial_ESP32.cpp | 2 ++ lib/ESPEasySerial/library.json | 2 +- lib/ESPEasySerial/library.properties | 2 +- platformio_esp32_envs.ini | 2 +- platformio_esp82xx_base.ini | 19 ++++++++++++++++++- platformio_esp82xx_envs.ini | 18 +++++------------- src/src/CustomBuild/define_plugin_sets.h | 13 +++++++++++++ src/src/Helpers/WiFi_AP_CandidatesList.cpp | 7 +++++++ src/src/Helpers/WiFi_AP_CandidatesList.h | 2 ++ 11 files changed, 57 insertions(+), 17 deletions(-) diff --git a/lib/ESPEasySerial/ESPEasySC16IS752_Serial.cpp b/lib/ESPEasySerial/ESPEasySC16IS752_Serial.cpp index c67d161e2..fb3da3f32 100644 --- a/lib/ESPEasySerial/ESPEasySC16IS752_Serial.cpp +++ b/lib/ESPEasySerial/ESPEasySC16IS752_Serial.cpp @@ -1,5 +1,7 @@ #include +#ifndef DISABLE_SC16IS752_Serial + #include @@ -141,3 +143,5 @@ void ESPEasySC16IS752_Serial::flush(void) _i2cuart->flush(_channel); } } + +#endif \ No newline at end of file diff --git a/lib/ESPEasySerial/ESPEasySC16IS752_Serial.h b/lib/ESPEasySerial/ESPEasySC16IS752_Serial.h index 84559dc4a..18d83a6bf 100644 --- a/lib/ESPEasySerial/ESPEasySC16IS752_Serial.h +++ b/lib/ESPEasySerial/ESPEasySC16IS752_Serial.h @@ -1,6 +1,7 @@ #ifndef ESPeasySC16IS752_Serial_h #define ESPeasySC16IS752_Serial_h +#ifndef DISABLE_SC16IS752_Serial #include #include @@ -41,4 +42,6 @@ private: bool _pingReplied = false; }; +#endif + #endif // ESPeasySC16IS752_Serial_h diff --git a/lib/ESPEasySerial/ESPEasySerial_ESP32.cpp b/lib/ESPEasySerial/ESPEasySerial_ESP32.cpp index 61aad9f5f..d99c1bbb0 100644 --- a/lib/ESPEasySerial/ESPEasySerial_ESP32.cpp +++ b/lib/ESPEasySerial/ESPEasySerial_ESP32.cpp @@ -92,6 +92,7 @@ ESPeasySerial::ESPeasySerial( _serialtype = ESPeasySerialType::getSerialType(port, receivePin, transmitPin); } +#ifndef DISABLE_SC16IS752_Serial switch (_serialtype) { case ESPEasySerialPort::sc16is752: { @@ -103,6 +104,7 @@ ESPeasySerial::ESPeasySerial( default: break; } +#endif } diff --git a/lib/ESPEasySerial/library.json b/lib/ESPEasySerial/library.json index fd84feb28..e5221a4e1 100644 --- a/lib/ESPEasySerial/library.json +++ b/lib/ESPEasySerial/library.json @@ -1,6 +1,6 @@ { "name": "ESPeasySerial", - "version": "2.0.14", + "version": "2.0.15", "keywords": [ "serial", "io", "softwareserial", "hardwareserial" ], diff --git a/lib/ESPEasySerial/library.properties b/lib/ESPEasySerial/library.properties index f15f92360..0ac07918e 100644 --- a/lib/ESPEasySerial/library.properties +++ b/lib/ESPEasySerial/library.properties @@ -1,5 +1,5 @@ name=ESPeasySerial -version=2.0.14 +version=2.0.15 author=Gijs Noorlander maintainer=Gijs Noorlander sentence=Wrapper for SoftwareSerial, SC16IS752 I2C to UART bridge and HardwareSerial for ESP8266 and ESP32/ESP32S2. diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index f4603352f..034612c12 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -38,7 +38,7 @@ lib_deps = adafruit/Adafruit GFX Library@^1.11.1 ccronexpr rlogiacco/CircularBuffer - td-er/ESPeasySerial @ 2.0.14 + td-er/ESPeasySerial @ 2.0.15 sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.3 ShiftRegister74HC595_NonTemplate VL53L0X @ 1.3.0 diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index b6d7cadb5..e32893a6e 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -83,7 +83,7 @@ lib_deps = adafruit/Adafruit GFX Library@^1.11.1 bblanchon/ArduinoJson @ ^6.17.2 rlogiacco/CircularBuffer - td-er/ESPeasySerial @ 2.0.14 + td-er/ESPeasySerial @ 2.0.15 td-er/RABurton ESP8266 Mutex @ ^1.0.2 sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.3 VL53L0X @ 1.3.0 @@ -275,6 +275,23 @@ build_flags = ${esp82xx_1M.build_flags} extends = esp82xx_1M_OTA board = esp8266_1M128k_OTA build_flags = ${esp82xx_1M_OTA.build_flags} +lib_ignore = ${esp82xx_1M.lib_ignore} + NewPing + PZEM-004T-v30 + SerialSensors + HLW8012 + AS_BH1750 + AM2320 + Itho + ccronexpr + ArduinoOTA + ESP8266mDNS + WakeOnLan + Blynk + Servo(esp8266) + SC16IS752 + + ;;; 2MB flash nodes ************************************************** diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index ee1089557..bf424eb9b 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -374,10 +374,12 @@ lib_ignore = ESP32_ping ; ********************************************************************* [minimal_OTA_domoticz] -build_flags = -DFEATURE_DOMOTICZ=1 +build_flags = ${esp8266_1M_OTA.build_flags} + -DFEATURE_DOMOTICZ=1 [minimal_OTA_FHEM_HA] -build_flags = -DFEATURE_FHEM=1 +build_flags = ${esp8266_1M_OTA.build_flags} + -DFEATURE_FHEM=1 -DFEATURE_HOMEASSISTANT_OPENHAB=1 @@ -386,8 +388,8 @@ extends = esp8266_1M_OTA platform = ${regular_platform.platform} platform_packages = ${regular_platform.platform_packages} build_flags = ${regular_platform.build_flags} - ${esp8266_1M_OTA.build_flags} ${minimal_OTA_domoticz.build_flags} + -DDISABLE_SC16IS752_Serial [env:minimal_core_302_ESP8266_1M_OTA_Domoticz] @@ -395,15 +397,7 @@ extends = esp8266_1M_OTA platform = ${core302_platform.platform} platform_packages = ${core302_platform.platform_packages} build_flags = ${core302_platform.build_flags} - ${esp8266_1M_OTA.build_flags} ${minimal_OTA_domoticz.build_flags} -lib_ignore = ${esp82xx_common.lib_ignore} - ESP8266SdFat - SD - SDFS - SD(esp8266) - LittleFS - [env:minimal_core_274_ESP8266_1M_OTA_FHEM_HA] @@ -411,7 +405,6 @@ extends = esp8266_1M_OTA platform = ${regular_platform.platform} platform_packages = ${regular_platform.platform_packages} build_flags = ${regular_platform.build_flags} - ${esp8266_1M_OTA.build_flags} ${minimal_OTA_FHEM_HA.build_flags} @@ -420,7 +413,6 @@ extends = esp8266_1M_OTA platform = ${core302_platform.platform} platform_packages = ${core302_platform.platform_packages} build_flags = ${core302_platform.build_flags} - ${esp8266_1M_OTA.build_flags} ${minimal_OTA_FHEM_HA.build_flags} diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 790f5805e..e5f11aca0 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -333,6 +333,19 @@ To create/register a plugin, you have to : #define FEATURE_ESPEASY_P2P 0 #endif + #ifdef FEATURE_MDNS + #undef FEATURE_MDNS + #endif + #define FEATURE_MDNS 0 + #ifndef DISABLE_SC16IS752_Serial + #define DISABLE_SC16IS752_Serial + #endif + + #ifdef FEATURE_ARDUINO_OTA + #undef FEATURE_ARDUINO_OTA + #endif + #define FEATURE_ARDUINO_OTA 0 + #ifndef PLUGIN_DESCR #define PLUGIN_DESCR "Minimal 1M OTA" #endif diff --git a/src/src/Helpers/WiFi_AP_CandidatesList.cpp b/src/src/Helpers/WiFi_AP_CandidatesList.cpp index a42703e2a..7f2293ee5 100644 --- a/src/src/Helpers/WiFi_AP_CandidatesList.cpp +++ b/src/src/Helpers/WiFi_AP_CandidatesList.cpp @@ -18,6 +18,13 @@ WiFi_AP_CandidatesList::WiFi_AP_CandidatesList() { load_knownCredentials(); } +WiFi_AP_CandidatesList::~WiFi_AP_CandidatesList() { + candidates.clear(); + known.clear(); + scanned.clear(); + scanned_new.clear(); +} + void WiFi_AP_CandidatesList::load_knownCredentials() { if (!_mustLoadCredentials) { return; } _mustLoadCredentials = false; diff --git a/src/src/Helpers/WiFi_AP_CandidatesList.h b/src/src/Helpers/WiFi_AP_CandidatesList.h index b2ea571ef..609b61334 100644 --- a/src/src/Helpers/WiFi_AP_CandidatesList.h +++ b/src/src/Helpers/WiFi_AP_CandidatesList.h @@ -12,6 +12,8 @@ typedef std::list::const_iterator WiFi_AP_Candidate_const_ite struct WiFi_AP_CandidatesList { WiFi_AP_CandidatesList(); + ~WiFi_AP_CandidatesList(); + // Load the known credentials from the settings void load_knownCredentials(); From 42b0d83d4e03209832d702f32d07662b94733f7a Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 20 Aug 2022 02:42:19 +0200 Subject: [PATCH 22/32] [Cleanup] Disable MCP/PCF commands when P009 and P019 not included. --- src/_P001_Switch.ino | 11 ++-- src/src/Commands/GPIO.cpp | 60 ++++++++++++++++++-- src/src/Commands/GPIO.h | 4 ++ src/src/Commands/InternalCommands.cpp | 4 ++ src/src/DataStructs/SettingsStruct.h | 2 - src/src/DataStructs_templ/SettingsStruct.cpp | 19 +++---- src/src/ESPEasyCore/ESPEasyGPIO.cpp | 18 ++++++ src/src/ESPEasyCore/ESPEasyGPIO.h | 4 ++ src/src/Globals/Plugins.cpp | 6 +- src/src/Helpers/Scheduler.cpp | 4 ++ 10 files changed, 106 insertions(+), 26 deletions(-) diff --git a/src/_P001_Switch.ino b/src/_P001_Switch.ino index d397cd32f..c0f48a74d 100644 --- a/src/_P001_Switch.ino +++ b/src/_P001_Switch.ino @@ -229,10 +229,13 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) // used to track if LP has fired PCONFIG(6) = 0; - // store millis for debounce, doubleclick and long press - PCONFIG_LONG(0) = millis(); // debounce timer - PCONFIG_LONG(1) = millis(); // doubleclick timer - PCONFIG_LONG(2) = millis(); // longpress timer + { + // store millis for debounce, doubleclick and long press + const unsigned long cur_millis = millis(); + PCONFIG_LONG(0) = cur_millis; // debounce timer + PCONFIG_LONG(1) = cur_millis; // doubleclick timer + PCONFIG_LONG(2) = cur_millis; // longpress timer + } // set minimum value for doubleclick MIN interval speed if (P001_DC_MAX_INT < SWITCH_DOUBLECLICK_MIN_INTERVAL) { diff --git a/src/src/Commands/GPIO.cpp b/src/src/Commands/GPIO.cpp index 0b6cb44de..9d77db6d7 100644 --- a/src/src/Commands/GPIO.cpp +++ b/src/src/Commands/GPIO.cpp @@ -30,15 +30,27 @@ void logErrorGpioNotOutput(const String& prefix, int port); void logErrorModeOutOfRange(const String& prefix, int port); bool gpio_monitor_helper(int port, struct EventStruct *event, const char* Line); bool gpio_unmonitor_helper(int port, struct EventStruct *event, const char* Line); +#ifdef USES_P009 bool mcpgpio_range_pattern_helper(struct EventStruct *event, const char* Line, bool isWritePattern); +#endif +#ifdef USES_P019 bool pcfgpio_range_pattern_helper(struct EventStruct *event, const char* Line, bool isWritePattern); +#endif bool gpio_mode_range_helper(uint8_t pin, uint8_t pinMode, struct EventStruct *event, const char* Line); +#ifdef USES_P019 uint8_t getPcfAddress(uint8_t pin); +#endif bool setGPIOMode(uint8_t pin, uint8_t mode); +#ifdef USES_P019 bool setPCFMode(uint8_t pin, uint8_t mode); +#endif +#ifdef USES_P009 bool setMCPMode(uint8_t pin, uint8_t mode); bool mcpgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t &result); +#endif +#ifdef USES_P019 bool pcfgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t &result); +#endif /*************************************************************************/ @@ -203,12 +215,16 @@ const __FlashStringHelper * Command_GPIO_Status(struct EventStruct *event, const sendStatusFlag = true; break; case 'm': // mcp +#ifdef USES_P009 pluginID = PLUGIN_MCP; sendStatusFlag = GPIO_MCP_Read(event->Par2) == -1; +#endif break; case 'p': // pcf +#ifdef USES_P019 pluginID = PLUGIN_PCF; sendStatusFlag = GPIO_PCF_Read(event->Par2) == -1; +#endif break; default: success = false; @@ -450,8 +466,10 @@ const __FlashStringHelper * Command_GPIO(struct EventStruct *event, const char * state = GPIO_Read_Switch_State(event->Par1, PIN_MODE_INPUT_PULLUP); break; case PLUGIN_MCP: +#ifdef USES_P009 setMCPInputAndPullupMode(event->Par1, true); GPIO_Read(PLUGIN_MCP, event->Par1, state); +#endif break; case PLUGIN_PCF: // PCF8574 specific: only can read 0/low state, so we must send 1 @@ -731,15 +749,19 @@ range_pattern_helper_data range_pattern_helper_shared(pluginID_t plugin, struct ** mask = 973 = '1111001101' ** write pattern after mask = '1000xx11x1' where x indicates that the pin will not be changed ******************************************************************************/ +#ifdef USES_P009 const __FlashStringHelper * Command_GPIO_McpGPIOPattern(struct EventStruct *event, const char *Line) { return mcpgpio_range_pattern_helper(event, Line, true) ? return_command_success() : return_command_failed(); } +#endif +#ifdef USES_P019 const __FlashStringHelper * Command_GPIO_PcfGPIOPattern(struct EventStruct *event, const char *Line) { return pcfgpio_range_pattern_helper(event, Line, true) ? return_command_success() : return_command_failed(); } +#endif /****************************************************************************** ** Par1=starting pin @@ -760,16 +782,21 @@ const __FlashStringHelper * Command_GPIO_PcfGPIOPattern(struct EventStruct *even ** mask = 973 = '1111001101' ** write pattern after mask = '1111xx11x1' where x indicates that the pin will not be changed ******************************************************************************/ +#ifdef USES_P009 const __FlashStringHelper * Command_GPIO_McpGPIORange(struct EventStruct *event, const char *Line) { return mcpgpio_range_pattern_helper(event, Line, false) ? return_command_success() : return_command_failed(); } +#endif +#ifdef USES_P019 const __FlashStringHelper * Command_GPIO_PcfGPIORange(struct EventStruct *event, const char *Line) { return pcfgpio_range_pattern_helper(event, Line, false) ? return_command_success() : return_command_failed(); } +#endif +#ifdef USES_P009 bool mcpgpio_range_pattern_helper(struct EventStruct *event, const char *Line, bool isWritePattern) { range_pattern_helper_data data = range_pattern_helper_shared(PLUGIN_MCP, event, Line, isWritePattern); @@ -828,7 +855,9 @@ bool mcpgpio_range_pattern_helper(struct EventStruct *event, const char *Line, b } return onLine; } +#endif +#ifdef USES_P019 uint8_t getPcfAddress(uint8_t pin) { uint8_t retValue = static_cast((pin - 1) / 8) + 0x20; @@ -895,6 +924,7 @@ bool pcfgpio_range_pattern_helper(struct EventStruct *event, const char *Line, b } return onLine; } +#endif bool setGPIOMode(uint8_t pin, uint8_t mode) { @@ -916,6 +946,7 @@ bool setGPIOMode(uint8_t pin, uint8_t mode) } } +#ifdef USES_P009 bool setMCPMode(uint8_t pin, uint8_t mode) { if (checkValidPortRange(PLUGIN_MCP, pin)) { @@ -935,7 +966,9 @@ bool setMCPMode(uint8_t pin, uint8_t mode) return false; } } +#endif +#ifdef USES_P019 bool setPCFMode(uint8_t pin, uint8_t mode) { if (checkValidPortRange(PLUGIN_PCF, pin)) { @@ -953,6 +986,7 @@ bool setPCFMode(uint8_t pin, uint8_t mode) return false; } } +#endif /*********************************************** * event->Par1: PIN to be set @@ -1019,11 +1053,14 @@ bool gpio_mode_range_helper(uint8_t pin, uint8_t pinMode, struct EventStruct *ev break; case PLUGIN_PCF: // set pin = 1 when INPUT - +#ifdef USES_P019 /* setSuccess = */ setPCFMode(pin, mode); +#endif break; case PLUGIN_MCP: +#ifdef USES_P009 /* setSuccess = */ setMCPMode(pin, mode); +#endif break; } @@ -1086,17 +1123,19 @@ bool getGPIOPinStateValues(String& str) { break; case 'm': - +#ifdef USES_P009 str = GPIO_MCP_Read(par1); logPrefix = F("MCP"); success = true; +#endif break; case 'p': - +#ifdef USES_P019 str = GPIO_PCF_Read(par1); logPrefix = F("PCF"); success = true; +#endif break; } } @@ -1121,19 +1160,28 @@ bool getGPIOPinStateValues(String& str) { } if (successPar) { - uint16_t tempValue = 0; switch (device[0]) { case 'm': +#ifdef USES_P009 + { + uint16_t tempValue = 0; logPrefix = F("MCP"); success = mcpgpio_plugin_range_helper(par1, par2, tempValue); str = String(tempValue); + } +#endif break; case 'p': +#ifdef USES_P019 + { + uint16_t tempValue = 0; logPrefix = F("PCF"); success = pcfgpio_plugin_range_helper(par1, par2, tempValue); str = String(tempValue); + } +#endif break; } @@ -1161,6 +1209,7 @@ bool getGPIOPinStateValues(String& str) { return success; } +#ifdef USES_P009 bool mcpgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t& result) { const range_pattern_helper_data data = range_helper_shared(PLUGIN_MCP, pin1, pin2); @@ -1195,7 +1244,9 @@ bool mcpgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t& result) return success; } +#endif +#ifdef USES_P019 bool pcfgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t& result) { const range_pattern_helper_data data = range_helper_shared(PLUGIN_PCF, pin1, pin2); @@ -1229,3 +1280,4 @@ bool pcfgpio_plugin_range_helper(uint8_t pin1, uint8_t pin2, uint16_t& result) return success; } +#endif \ No newline at end of file diff --git a/src/src/Commands/GPIO.h b/src/src/Commands/GPIO.h index 69ad3e26e..5dedb7d04 100644 --- a/src/src/Commands/GPIO.h +++ b/src/src/Commands/GPIO.h @@ -21,11 +21,15 @@ const __FlashStringHelper * Command_GPIO_Monitor(struct EventStruct *event, cons const __FlashStringHelper * Command_GPIO_UnMonitor(struct EventStruct *event, const char* Line); const __FlashStringHelper * Command_GPIO_Status(struct EventStruct *event, const char* Line); +#ifdef USES_P009 const __FlashStringHelper * Command_GPIO_McpGPIORange(struct EventStruct *event, const char* Line); const __FlashStringHelper * Command_GPIO_McpGPIOPattern(struct EventStruct *event, const char* Line); +#endif +#ifdef USES_P019 const __FlashStringHelper * Command_GPIO_PcfGPIORange(struct EventStruct *event, const char* Line); const __FlashStringHelper * Command_GPIO_PcfGPIOPattern(struct EventStruct *event, const char* Line); +#endif const __FlashStringHelper * Command_GPIO_Mode(struct EventStruct *event, const char* Line); const __FlashStringHelper * Command_GPIO_ModeRange(struct EventStruct *event, const char* Line); diff --git a/src/src/Commands/InternalCommands.cpp b/src/src/Commands/InternalCommands.cpp index 9b3dae2f8..5b60ffba1 100644 --- a/src/src/Commands/InternalCommands.cpp +++ b/src/src/Commands/InternalCommands.cpp @@ -342,6 +342,7 @@ bool executeInternalCommand(command_case_data & data) break; } case 'm': { +#ifdef USES_P009 if (cmd_lc_length > 3 && data.cmd_lc[3] == 'g') { COMMAND_CASE_A( "mcpgpio", Command_GPIO, 2); // Gpio.h COMMAND_CASE_A( "mcpgpiorange", Command_GPIO_McpGPIORange, -1); // Gpio.h @@ -354,6 +355,7 @@ bool executeInternalCommand(command_case_data & data) COMMAND_CASE_A( "mcpmoderange", Command_GPIO_ModeRange, 3); // Gpio.h COMMAND_CASE_A( "mcppulse", Command_GPIO_Pulse, 3); // GPIO.h } +#endif COMMAND_CASE_A( "monitor", Command_GPIO_Monitor, 2); // GPIO.h COMMAND_CASE_A( "monitorrange", Command_GPIO_MonitorRange, 3); // GPIO.h #ifndef BUILD_NO_DIAGNOSTIC_COMMANDS @@ -374,6 +376,7 @@ bool executeInternalCommand(command_case_data & data) break; } case 'p': { +#ifdef USES_P019 if (cmd_lc_length > 3 && data.cmd_lc[3] == 'g') { COMMAND_CASE_A( "pcfgpio", Command_GPIO, 2); // Gpio.h COMMAND_CASE_A( "pcfgpiorange", Command_GPIO_PcfGPIORange, -1); // Gpio.h @@ -386,6 +389,7 @@ bool executeInternalCommand(command_case_data & data) COMMAND_CASE_A( "pcfmoderange", Command_GPIO_ModeRange, 3); // Gpio.h ************ COMMAND_CASE_A( "pcfpulse", Command_GPIO_Pulse, 3); // GPIO.h } +#endif COMMAND_CASE_R("password", Command_Settings_Password, 1); // Settings.h #if FEATURE_CUSTOM_PROVISIONING COMMAND_CASE_A( "provisionconfig", Command_Provisioning_Config, 0); // Provisioning.h diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 6f0b16af6..9689cfcda 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -185,8 +185,6 @@ class SettingsStruct_tmpl void clearMisc(); - void clearAll(); - void clearTask(taskIndex_t task); // Return hostname + unit when selected to add unit. diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index d1e901c81..5c3f464de 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -12,7 +12,13 @@ template SettingsStruct_tmpl::SettingsStruct_tmpl() : ResetFactoryDefaultPreference(0) { //-V730 - clearAll(); + clearMisc(); + clearTimeSettings(); + clearNotifications(); + clearControllers(); + clearTasks(); + clearLogSettings(); + clearUnitNameSettings(); clearNetworkSettings(); } @@ -498,17 +504,6 @@ void SettingsStruct_tmpl::clearMisc() { DoNotStartAP(DEFAULT_DONT_ALLOW_START_AP); } -template -void SettingsStruct_tmpl::clearAll() { - clearMisc(); - clearTimeSettings(); - clearNetworkSettings(); - clearNotifications(); - clearControllers(); - clearTasks(); - clearLogSettings(); - clearUnitNameSettings(); -} template void SettingsStruct_tmpl::clearTask(taskIndex_t task) { diff --git a/src/src/ESPEasyCore/ESPEasyGPIO.cpp b/src/src/ESPEasyCore/ESPEasyGPIO.cpp index e3bc0aaf1..e754674f3 100644 --- a/src/src/ESPEasyCore/ESPEasyGPIO.cpp +++ b/src/src/ESPEasyCore/ESPEasyGPIO.cpp @@ -86,6 +86,7 @@ bool GPIO_Read_Switch_State(int pin, uint8_t pinMode) { return digitalRead(pin) == HIGH; } +#ifdef USES_P009 //******************************************************************************** // MCP23017 PIN read //******************************************************************************** @@ -287,7 +288,9 @@ bool setMCPOutputMode(uint8_t Par1) } return success; } +#endif +#ifdef USES_P019 //******************************************************************************** // PCF8574 read pin //******************************************************************************** @@ -406,6 +409,9 @@ bool setPCFInputMode(uint8_t pin) } else return false; } +#endif + + //********************************************************* // GPIO_Monitor10xSec: // What it does: @@ -433,12 +439,16 @@ void GPIO_Monitor10xSec() eventString = F("GPIO"); break; case PLUGIN_MCP: +#ifdef USES_P009 currentState = GPIO_MCP_Read(gpioPort); eventString = F("MCP"); +#endif break; case PLUGIN_PCF: +#ifdef USES_P019 currentState = GPIO_PCF_Read(gpioPort); eventString = F("PCF"); +#endif break; default: caseFound=false; @@ -519,10 +529,14 @@ bool GPIO_Write(pluginID_t pluginID, int port, uint8_t value, uint8_t pinMode) success=false; break; case PLUGIN_MCP: +#ifdef USES_P009 GPIO_MCP_Write(port, value); +#endif break; case PLUGIN_PCF: +#ifdef USES_P019 GPIO_PCF_Write(port, value); +#endif break; default: success=false; @@ -539,10 +553,14 @@ bool GPIO_Read(pluginID_t pluginID, int port, int8_t &value) value = GPIO_Internal_Read(port); break; case PLUGIN_MCP: +#ifdef USES_P009 value = GPIO_MCP_Read(port); +#endif break; case PLUGIN_PCF: +#ifdef USES_P019 value = GPIO_PCF_Read(port); +#endif break; default: success=false; diff --git a/src/src/ESPEasyCore/ESPEasyGPIO.h b/src/src/ESPEasyCore/ESPEasyGPIO.h index 47119777d..10f41033c 100644 --- a/src/src/ESPEasyCore/ESPEasyGPIO.h +++ b/src/src/ESPEasyCore/ESPEasyGPIO.h @@ -26,6 +26,7 @@ bool GPIO_Internal_Read(int pin); bool GPIO_Read_Switch_State(struct EventStruct *event); bool GPIO_Read_Switch_State(int pinNumber, uint8_t pinMode); +#ifdef USES_P009 //******************************************************************************** // MCP23017 read //******************************************************************************** @@ -41,7 +42,9 @@ void GPIO_MCP_WriteRegister(uint8_t mcpAddr, uint8_t regAddr, uint8_t regValue); //******************************************************************************** // MCP23017 pullUP //******************************************************************************** +#endif +#ifdef USES_P019 //******************************************************************************** // PCF8574 read //******************************************************************************** @@ -54,6 +57,7 @@ bool GPIO_PCF_ReadAllPins(uint8_t address, uint8_t *retValue); //******************************************************************************** bool GPIO_PCF_Write(int Par1, uint8_t Par2); void GPIO_PCF_WriteAllPins(uint8_t Par1, uint8_t Par2); +#endif //********************************************************* // GPIO_Monitor10xSec: diff --git a/src/src/Globals/Plugins.cpp b/src/src/Globals/Plugins.cpp index 93f2f2161..3110ca521 100644 --- a/src/src/Globals/Plugins.cpp +++ b/src/src/Globals/Plugins.cpp @@ -428,7 +428,7 @@ bool PluginCall(uint8_t Function, struct EventStruct *event, String& str) int dotPos = command.indexOf('.'); // Find first period if (Function == PLUGIN_WRITE // Only applicable on PLUGIN_WRITE function && dotPos > -1) { // First precondition is just a quick check for a period (fail-fast strategy) - String arg0 = parseString(command, 1); // Get first argument + const String arg0 = parseString(command, 1); // Get first argument dotPos = arg0.indexOf('.'); if (dotPos > -1) { String thisTaskName = parseString(arg0, 1, '.'); // Extract taskname prefix @@ -518,9 +518,7 @@ bool PluginCall(uint8_t Function, struct EventStruct *event, String& str) { for (taskIndex_t taskIndex = 0; taskIndex < TASKS_MAX; taskIndex++) { - bool retval = PluginCallForTask(taskIndex, Function, &TempEvent, str); - - if (retval) { + if (PluginCallForTask(taskIndex, Function, &TempEvent, str)) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("PluginCallUDP"), taskIndex); #endif diff --git a/src/src/Helpers/Scheduler.cpp b/src/src/Helpers/Scheduler.cpp index 730749d06..4185d1a0c 100644 --- a/src/src/Helpers/Scheduler.cpp +++ b/src/src/Helpers/Scheduler.cpp @@ -926,12 +926,16 @@ void ESPEasy_Scheduler::process_gpio_timer(unsigned long id) { pluginID = PLUGIN_GPIO; break; case GPIO_TYPE_MCP: +#ifdef USES_P009 GPIO_MCP_Write(pinNumber, pinStateValue); pluginID = PLUGIN_MCP; +#endif break; case GPIO_TYPE_PCF: +#ifdef USES_P019 GPIO_PCF_Write(pinNumber, pinStateValue); pluginID = PLUGIN_PCF; +#endif break; default: success = false; From 91abe4bb65bd16d3b2c81e7ddef63e63354d750d Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 20 Aug 2022 13:25:16 +0200 Subject: [PATCH 23/32] [Cleanup] Remove MCP/PCF related code when plugins not included --- platformio_esp82xx_base.ini | 15 +--- src/_P026_Sysinfo.ino | 67 ++++-------------- src/src/Commands/GPIO.cpp | 80 +++++++++++++--------- src/src/CustomBuild/define_plugin_sets.h | 1 - src/src/ESPEasyCore/Controller.cpp | 28 ++++---- src/src/ESPEasyCore/Controller.h | 1 + src/src/Helpers/Convert.cpp | 2 + src/src/Helpers/StringProvider.cpp | 10 +-- src/src/PluginStructs/P012_data_struct.cpp | 3 +- src/src/PluginStructs/P057_data_struct.cpp | 2 +- src/src/PluginStructs/P058_data_struct.cpp | 3 +- src/src/PluginStructs/P064_data_struct.cpp | 4 +- src/src/PluginStructs/P083_data_struct.cpp | 4 +- 13 files changed, 96 insertions(+), 124 deletions(-) diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index e32893a6e..815a40871 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -276,20 +276,11 @@ extends = esp82xx_1M_OTA board = esp8266_1M128k_OTA build_flags = ${esp82xx_1M_OTA.build_flags} lib_ignore = ${esp82xx_1M.lib_ignore} - NewPing - PZEM-004T-v30 - SerialSensors - HLW8012 - AS_BH1750 - AM2320 - Itho - ccronexpr ArduinoOTA ESP8266mDNS - WakeOnLan - Blynk - Servo(esp8266) - SC16IS752 +; Adding the libs below to the lib_ignore will even increase build size +; Adafruit TCS34725 +; RN2xx3 Arduino Library diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index 06bb39476..d9ad2d160 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -212,73 +212,34 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string) float P026_get_value(int type) { - float value = 0; - switch (type) { - case 0: - { - value = getUptimeMinutes(); - break; - } - case 1: - { - value = FreeMem(); - break; - } - case 2: - { - value = WiFi.RSSI(); - break; - } + case 0: return getUptimeMinutes(); + case 1: return FreeMem(); + case 2: return WiFi.RSSI(); case 3: - { # if FEATURE_ADC_VCC - value = vcc; + return vcc; # else // if FEATURE_ADC_VCC - value = -1.0f; + return -1.0f; # endif // if FEATURE_ADC_VCC - break; - } - case 4: - { - value = getCPUload(); - break; - } + case 4: return getCPUload(); case 5: case 6: case 7: case 8: - { - value = NetworkLocalIP()[type - 5]; - break; - } - case 9: - { - value = timePassedSince(lastWeb) / 1000.0f; // respond in seconds - break; - } - case 10: - { - value = getCurrentFreeStack(); - break; - } - case 12: - { - value = WiFiEventData.wifi_TX_pwr; - break; - } + return NetworkLocalIP()[type - 5]; + case 9: return timePassedSince(lastWeb) / 1000.0f; // respond in seconds + case 10: return getCurrentFreeStack(); + case 12: return WiFiEventData.wifi_TX_pwr; case 13: - { #ifdef USE_SECOND_HEAP - value = FreeMem2ndHeap(); - #endif + return FreeMem2ndHeap(); + #else break; - } - - + #endif } - return value; + return 0.0f; } #endif // USES_P026 diff --git a/src/src/Commands/GPIO.cpp b/src/src/Commands/GPIO.cpp index 9d77db6d7..9780569f4 100644 --- a/src/src/Commands/GPIO.cpp +++ b/src/src/Commands/GPIO.cpp @@ -204,7 +204,6 @@ const __FlashStringHelper * Command_GPIO_LongPulse_Ms(struct EventStruct *event, const __FlashStringHelper * Command_GPIO_Status(struct EventStruct *event, const char *Line) { - bool success = true; bool sendStatusFlag; uint8_t pluginID = 0; @@ -214,31 +213,31 @@ const __FlashStringHelper * Command_GPIO_Status(struct EventStruct *event, const pluginID = PLUGIN_GPIO; sendStatusFlag = true; break; - case 'm': // mcp #ifdef USES_P009 + case 'm': // mcp pluginID = PLUGIN_MCP; sendStatusFlag = GPIO_MCP_Read(event->Par2) == -1; -#endif break; - case 'p': // pcf +#endif #ifdef USES_P019 + case 'p': // pcf pluginID = PLUGIN_PCF; sendStatusFlag = GPIO_PCF_Read(event->Par2) == -1; -#endif break; +#endif default: - success = false; + addLog(LOG_LEVEL_ERROR, F("Plugin not included in build")); + return return_command_failed(); } - if (success && checkValidPortRange(pluginID, event->Par2)) + if (!checkValidPortRange(pluginID, event->Par2)) { - const uint32_t key = createKey(pluginID, event->Par2); // WARNING: 'status' uses Par2 instead of Par1 - String dummy; - SendStatusOnlyIfNeeded(event, sendStatusFlag, key, dummy, 0); - return return_command_success(); - } else { return return_command_failed(); } + const uint32_t key = createKey(pluginID, event->Par2); // WARNING: 'status' uses Par2 instead of Par1 + String dummy; + SendStatusOnlyIfNeeded(event, sendStatusFlag, key, dummy, 0); + return return_command_success(); } const __FlashStringHelper * Command_GPIO_PWM(struct EventStruct *event, const char *Line) @@ -465,16 +464,21 @@ const __FlashStringHelper * Command_GPIO(struct EventStruct *event, const char * setInternalGPIOPullupMode(event->Par1); state = GPIO_Read_Switch_State(event->Par1, PIN_MODE_INPUT_PULLUP); break; - case PLUGIN_MCP: #ifdef USES_P009 + case PLUGIN_MCP: setMCPInputAndPullupMode(event->Par1, true); GPIO_Read(PLUGIN_MCP, event->Par1, state); -#endif break; +#endif +#ifdef USES_P019 case PLUGIN_PCF: // PCF8574 specific: only can read 0/low state, so we must send 1 state = 1; break; +#endif + default: + addLog(LOG_LEVEL_ERROR, F("Plugin not included in build")); + return return_command_failed(); } } else { // OUTPUT mode = PIN_MODE_OUTPUT; @@ -584,8 +588,6 @@ void createAndSetPortStatus_Mode_State(uint32_t key, uint8_t newMode, int8_t new bool getPluginIDAndPrefix(char selection, pluginID_t& pluginID, String& logPrefix) { - bool success = true; - switch (tolower(selection)) { case 'g': // gpio @@ -593,19 +595,23 @@ bool getPluginIDAndPrefix(char selection, pluginID_t& pluginID, String& logPrefi pluginID = PLUGIN_GPIO; logPrefix = F("GPIO"); break; +#ifdef USES_P009 case 'm': // mcp & mcplongpulse pluginID = PLUGIN_MCP; logPrefix = F("MCP"); break; +#endif +#ifdef USES_P019 case 'p': // pcf & pcflongpulse pluginID = PLUGIN_PCF; logPrefix = F("PCF"); break; +#endif default: - logPrefix = F("PluginID out of range. Error"); - success = false; + logPrefix = F("Plugin not included in build"); + return false; } - return success; + return true; } struct range_pattern_helper_data { @@ -1051,17 +1057,20 @@ bool gpio_mode_range_helper(uint8_t pin, uint8_t pinMode, struct EventStruct *ev case PLUGIN_GPIO: /* setSuccess = */ setGPIOMode(pin, mode); break; +#ifdef USES_P019 case PLUGIN_PCF: // set pin = 1 when INPUT -#ifdef USES_P019 /* setSuccess = */ setPCFMode(pin, mode); -#endif break; - case PLUGIN_MCP: +#endif #ifdef USES_P009 + case PLUGIN_MCP: /* setSuccess = */ setMCPMode(pin, mode); -#endif break; +#endif + default: + addLog(LOG_LEVEL_ERROR, F("Plugin not included in build")); + return false; } const uint32_t key = createKey(pluginID, pin); @@ -1122,21 +1131,24 @@ bool getGPIOPinStateValues(String& str) { success = true; break; - case 'm': #ifdef USES_P009 + case 'm': str = GPIO_MCP_Read(par1); logPrefix = F("MCP"); success = true; -#endif break; +#endif - case 'p': #ifdef USES_P019 + case 'p': str = GPIO_PCF_Read(par1); logPrefix = F("PCF"); success = true; -#endif break; +#endif + default: + addLog(LOG_LEVEL_ERROR, F("Plugin not included in build")); + return false; } } @@ -1162,27 +1174,31 @@ bool getGPIOPinStateValues(String& str) { if (successPar) { switch (device[0]) { - case 'm': #ifdef USES_P009 + case 'm': { uint16_t tempValue = 0; logPrefix = F("MCP"); success = mcpgpio_plugin_range_helper(par1, par2, tempValue); str = String(tempValue); + break; } #endif - break; - case 'p': #ifdef USES_P019 + case 'p': { uint16_t tempValue = 0; logPrefix = F("PCF"); success = pcfgpio_plugin_range_helper(par1, par2, tempValue); str = String(tempValue); - } -#endif break; + } + #endif + default: + addLog(LOG_LEVEL_ERROR, F("PLUGIN PINSTATE. Plugin not included in build")); + return false; + } if (success) { diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index e5f11aca0..5e8cc970b 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1768,7 +1768,6 @@ To create/register a plugin, you have to : #endif */ - #if defined(USES_C018) #define FEATURE_PACKED_RAW_DATA 1 #endif diff --git a/src/src/ESPEasyCore/Controller.cpp b/src/src/ESPEasyCore/Controller.cpp index b99d73d65..3f27c7ce7 100644 --- a/src/src/ESPEasyCore/Controller.cpp +++ b/src/src/ESPEasyCore/Controller.cpp @@ -212,14 +212,14 @@ bool MQTTConnect(controllerIndex_t controller_idx) MQTTclient.setCallback(incoming_mqtt_callback); // MQTT needs a unique clientname to subscribe to broker - String clientid = getMQTTclientID(ControllerSettings); + const String clientid = getMQTTclientID(ControllerSettings); - String LWTTopic = getLWT_topic(ControllerSettings); - String LWTMessageDisconnect = getLWT_messageDisconnect(ControllerSettings); - bool MQTTresult = false; - uint8_t willQos = 0; - bool willRetain = ControllerSettings.mqtt_willRetain() && ControllerSettings.mqtt_sendLWT(); - bool cleanSession = ControllerSettings.mqtt_cleanSession(); // As suggested here: + const String LWTTopic = getLWT_topic(ControllerSettings); + const String LWTMessageDisconnect = getLWT_messageDisconnect(ControllerSettings); + bool MQTTresult = false; + const uint8_t willQos = 0; + const bool willRetain = ControllerSettings.mqtt_willRetain() && ControllerSettings.mqtt_sendLWT(); + const bool cleanSession = ControllerSettings.mqtt_cleanSession(); // As suggested here: if (MQTTclient_should_reconnect) { addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect")); @@ -247,10 +247,7 @@ bool MQTTConnect(controllerIndex_t controller_idx) } delay(0); - - uint8_t controller_number = Settings.Protocol[controller_idx]; - - count_connection_results(MQTTresult, F("MQTT : Broker "), controller_number); + count_connection_results(MQTTresult, F("MQTT : Broker "), Settings.Protocol[controller_idx]); if (!MQTTresult) { MQTTclient.disconnect(); @@ -259,8 +256,8 @@ bool MQTTConnect(controllerIndex_t controller_idx) return false; } if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("MQTT : Connected to broker with client ID: "); - + String log; + log += F("MQTT : Connected to broker with client ID: "); log += clientid; addLogMove(LOG_LEVEL_INFO, log); } @@ -460,6 +457,11 @@ bool SourceNeedsStatusUpdate(EventValueSource::Enum eventSource) return false; } +void SendStatus(struct EventStruct *event, const __FlashStringHelper * status) +{ + SendStatus(event, String(status)); +} + void SendStatus(struct EventStruct *event, const String& status) { if (status.isEmpty()) { return; } diff --git a/src/src/ESPEasyCore/Controller.h b/src/src/ESPEasyCore/Controller.h index e451c4091..3222db340 100644 --- a/src/src/ESPEasyCore/Controller.h +++ b/src/src/ESPEasyCore/Controller.h @@ -54,6 +54,7 @@ void SendStatusOnlyIfNeeded(struct EventStruct *event, bool param1, uint32_t key bool SourceNeedsStatusUpdate(EventValueSource::Enum eventSource); +void SendStatus(struct EventStruct *event, const __FlashStringHelper * status); void SendStatus(struct EventStruct *event, const String& status); #if FEATURE_MQTT diff --git a/src/src/Helpers/Convert.cpp b/src/src/Helpers/Convert.cpp index c0c4c023f..a2393465c 100644 --- a/src/src/Helpers/Convert.cpp +++ b/src/src/Helpers/Convert.cpp @@ -1,5 +1,7 @@ #include "../Helpers/Convert.h" + + /*********************************************************************************************\ Convert bearing in degree to bearing string \*********************************************************************************************/ diff --git a/src/src/Helpers/StringProvider.cpp b/src/src/Helpers/StringProvider.cpp index 8f3a63371..33cf1724e 100644 --- a/src/src/Helpers/StringProvider.cpp +++ b/src/src/Helpers/StringProvider.cpp @@ -308,20 +308,20 @@ String getValue(LabelType::Enum label) { case LabelType::WIFI_CONNECTION: break; case LabelType::WIFI_RSSI: return String(WiFi.RSSI()); - case LabelType::IP_CONFIG: return useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel( - LabelType::IP_CONFIG_DYNAMIC); + case LabelType::IP_CONFIG: return String(useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel( + LabelType::IP_CONFIG_DYNAMIC)); case LabelType::IP_CONFIG_STATIC: break; case LabelType::IP_CONFIG_DYNAMIC: break; case LabelType::IP_ADDRESS: return NetworkLocalIP().toString(); case LabelType::IP_SUBNET: return NetworkSubnetMask().toString(); - case LabelType::IP_ADDRESS_SUBNET: return String(getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET)); + case LabelType::IP_ADDRESS_SUBNET: return getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET); case LabelType::GATEWAY: return NetworkGatewayIP().toString(); case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); #if FEATURE_MDNS - case LabelType::M_DNS: return String(NetworkGetHostname()) + F(".local"); + case LabelType::M_DNS: return NetworkGetHostname() + F(".local"); #endif // if FEATURE_MDNS - case LabelType::DNS: return String(getValue(LabelType::DNS_1) + F(" / ") + getValue(LabelType::DNS_2)); + case LabelType::DNS: return getValue(LabelType::DNS_1) + F(" / ") + getValue(LabelType::DNS_2); case LabelType::DNS_1: return NetworkDnsIP(0).toString(); case LabelType::DNS_2: return NetworkDnsIP(1).toString(); case LabelType::ALLOWED_IP_RANGE: return describeAllowedIPrange(); diff --git a/src/src/PluginStructs/P012_data_struct.cpp b/src/src/PluginStructs/P012_data_struct.cpp index 22eae2065..c5955bc06 100644 --- a/src/src/PluginStructs/P012_data_struct.cpp +++ b/src/src/PluginStructs/P012_data_struct.cpp @@ -1,10 +1,11 @@ #include "../PluginStructs/P012_data_struct.h" +#ifdef USES_P012 + // Needed also here for PlatformIO's library finder as the .h file // is in a directory which is excluded in the src_filter #include -#ifdef USES_P012 P012_data_struct::P012_data_struct(uint8_t addr, uint8_t lcd_size, diff --git a/src/src/PluginStructs/P057_data_struct.cpp b/src/src/PluginStructs/P057_data_struct.cpp index 9737765e3..19a8d2b4f 100644 --- a/src/src/PluginStructs/P057_data_struct.cpp +++ b/src/src/PluginStructs/P057_data_struct.cpp @@ -1,11 +1,11 @@ #include "../PluginStructs/P057_data_struct.h" +#ifdef USES_P057 // Needed also here for PlatformIO's library finder as the .h file // is in a directory which is excluded in the src_filter # include -#ifdef USES_P057 P057_data_struct::P057_data_struct(uint8_t i2c_addr) : i2cAddress(i2c_addr) { ledMatrix.Init(i2cAddress); diff --git a/src/src/PluginStructs/P058_data_struct.cpp b/src/src/PluginStructs/P058_data_struct.cpp index 4dd3ed53b..4c0a8f0eb 100644 --- a/src/src/PluginStructs/P058_data_struct.cpp +++ b/src/src/PluginStructs/P058_data_struct.cpp @@ -1,11 +1,12 @@ #include "../PluginStructs/P058_data_struct.h" +#ifdef USES_P058 + // Needed also here for PlatformIO's library finder as the .h file // is in a directory which is excluded in the src_filter # include -#ifdef USES_P058 P058_data_struct::P058_data_struct(uint8_t i2c_addr) { keyPad.Init(i2c_addr); diff --git a/src/src/PluginStructs/P064_data_struct.cpp b/src/src/PluginStructs/P064_data_struct.cpp index 304048797..6c97f5b58 100644 --- a/src/src/PluginStructs/P064_data_struct.cpp +++ b/src/src/PluginStructs/P064_data_struct.cpp @@ -1,11 +1,11 @@ #include "../PluginStructs/P064_data_struct.h" +#ifdef USES_P064 + // Needed also here for PlatformIO's library finder as the .h file // is in a directory which is excluded in the src_filter #include // Lib is modified to work with ESP -#ifdef USES_P064 - P064_data_struct::P064_data_struct() {} diff --git a/src/src/PluginStructs/P083_data_struct.cpp b/src/src/PluginStructs/P083_data_struct.cpp index 7bea9beb7..ad43c8e00 100644 --- a/src/src/PluginStructs/P083_data_struct.cpp +++ b/src/src/PluginStructs/P083_data_struct.cpp @@ -1,13 +1,11 @@ #include "../PluginStructs/P083_data_struct.h" +#ifdef USES_P083 // Needed also here for PlatformIO's library finder as the .h file // is in a directory which is excluded in the src_filter #include - -#ifdef USES_P083 - P083_data_struct::P083_data_struct() { initialized = sgp.begin(); init_time = millis(); From b35b4955d82e0923f8da0d487cc4a01ba86c7c74 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 20 Aug 2022 14:14:03 +0200 Subject: [PATCH 24/32] [Build] Reduce build size reducing ArduinoJSON instances --- src/_P016_IR.ino | 2 +- src/src/Helpers/StringParser.cpp | 4 ++-- src/src/PluginStructs/P037_data_struct.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/_P016_IR.ino b/src/_P016_IR.ino index 609f93da3..1793892c2 100644 --- a/src/_P016_IR.ino +++ b/src/_P016_IR.ino @@ -745,7 +745,7 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) (typeToString(results.decode_type).length() > 1)) // be sent { IRAcUtils::decodeToState(&results, &state); - StaticJsonDocument<300> doc; + DynamicJsonDocument doc(300); // Checks if a particular state is something else than the default and only then it adds it to the JSON document doc[F("protocol")] = typeToString(state.protocol); diff --git a/src/src/Helpers/StringParser.cpp b/src/src/Helpers/StringParser.cpp index e133d9839..0ef9fe3fd 100644 --- a/src/src/Helpers/StringParser.cpp +++ b/src/src/Helpers/StringParser.cpp @@ -391,10 +391,10 @@ void transformValue( break; } case 'F': // FLOOR (round down) - value = static_cast(floorf(valFloat)); + value = static_cast(floor(valFloat)); break; case 'E': // CEILING (round up) - value = static_cast(ceilf(valFloat)); + value = static_cast(ceil(valFloat)); break; default: value = F("ERR"); diff --git a/src/src/PluginStructs/P037_data_struct.cpp b/src/src/PluginStructs/P037_data_struct.cpp index 16899a07e..aeaf7f38d 100644 --- a/src/src/PluginStructs/P037_data_struct.cpp +++ b/src/src/PluginStructs/P037_data_struct.cpp @@ -989,7 +989,7 @@ bool P037_data_struct::parseJSONMessage(const String& message) { } if (nullptr != root) { - deserializeJson(*root, message.c_str()); + deserializeJson(*root, message); if (!root->isNull()) { result = true; From a17741f961d9d4942e2822010773e8e201a8edca Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 21 Aug 2022 10:29:27 +0200 Subject: [PATCH 25/32] [Build] Fix compile time defines strings with spaces For example the ESP Board Name was incorrect. ``` ESP Board Name: Espressif Generic 1 4M Flash ESPEasy 1810k Code/OTA 316k FS ``` `ESP32` was replaced with a `1` in the string. --- src/src/CustomBuild/CompiletimeDefines.cpp | 15 ++++++++++----- tools/pio/generate-compiletime-defines.py | 10 +++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/src/CustomBuild/CompiletimeDefines.cpp b/src/src/CustomBuild/CompiletimeDefines.cpp index 82525ca53..d02a46889 100644 --- a/src/src/CustomBuild/CompiletimeDefines.cpp +++ b/src/src/CustomBuild/CompiletimeDefines.cpp @@ -12,15 +12,20 @@ // End of defines being patched by the Python build script. +// Uncrustify must not be used on macros, so turn it off. +// *INDENT-OFF* + // Need to add quotes around defines as the PIO build tools make it hard to include the string quotes. #define STRINGIFY(s) STRINGIFY1(s) -#define STRINGIFY1(s) # s +#define STRINGIFY1(s) #s +// Uncrustify must not be used on macros, but we're now done, so turn Uncrustify on again. +// *INDENT-ON* const __FlashStringHelper* get_binary_filename() { #ifndef SET_BUILD_BINARY_FILENAME return F("firmware.bin"); #else // ifndef SET_BUILD_BINARY_FILENAME - return F(STRINGIFY(SET_BUILD_BINARY_FILENAME)); + return F(SET_BUILD_BINARY_FILENAME); #endif // ifndef SET_BUILD_BINARY_FILENAME } @@ -46,7 +51,7 @@ const __FlashStringHelper* get_build_platform() { #ifndef SET_BUILD_PLATFORM return F(""); #else // ifndef SET_BUILD_PLATFORM - return F(STRINGIFY(SET_BUILD_PLATFORM)); + return F(SET_BUILD_PLATFORM); #endif // ifndef SET_BUILD_PLATFORM } @@ -54,13 +59,13 @@ const __FlashStringHelper* get_git_head() { #ifndef SET_BUILD_GIT_HEAD return F(""); #else // ifndef SET_BUILD_GIT_HEAD - return F(STRINGIFY(SET_BUILD_GIT_HEAD)); + return F(SET_BUILD_GIT_HEAD); #endif // ifndef SET_BUILD_GIT_HEAD } const __FlashStringHelper * get_board_name() { #ifdef SET_BOARD_NAME - return F(STRINGIFY(SET_BOARD_NAME)); + return F(SET_BOARD_NAME); #elif defined(ARDUINO_BOARD) return F(ARDUINO_BOARD); #else diff --git a/tools/pio/generate-compiletime-defines.py b/tools/pio/generate-compiletime-defines.py index 03b7ee931..1ddd2df82 100644 --- a/tools/pio/generate-compiletime-defines.py +++ b/tools/pio/generate-compiletime-defines.py @@ -22,7 +22,7 @@ def get_git_description(): from pygit2 import Repository try: repo = Repository('.') - return "'{0}_{1}'".format(repo.head.shorthand, repo.revparse_single('HEAD').short_id) + return "{0}_{1}".format(repo.head.shorthand, repo.revparse_single('HEAD').short_id) except: return 'No_.git_dir' except ImportError: @@ -56,10 +56,10 @@ def gen_compiletime_defines(node): return env.Object( node, CPPDEFINES=env["CPPDEFINES"] - + [("SET_BUILD_BINARY_FILENAME", create_binary_filename())] - + [("SET_BOARD_NAME", get_board_name())] - + [("SET_BUILD_PLATFORM", platform.platform())] - + [("SET_BUILD_GIT_HEAD", get_git_description())], + + [("SET_BUILD_BINARY_FILENAME", '\\"%s\\"' % create_binary_filename())] + + [("SET_BOARD_NAME", '\\"%s\\"' % get_board_name())] + + [("SET_BUILD_PLATFORM", '\\"%s\\"' % platform.platform())] + + [("SET_BUILD_GIT_HEAD", '\\"%s\\"' % get_git_description())], CCFLAGS=env["CCFLAGS"] ) From 58737d4a5dc307e01d9a1b715085b96cefc7b8bc Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 21 Aug 2022 12:46:04 +0200 Subject: [PATCH 26/32] [Build Version] Generate build version based on date --- platformio_esp82xx_base.ini | 16 ++- src/_N001_Email.cpp | 3 +- src/src/Commands/Settings.cpp | 5 +- src/src/CustomBuild/CompiletimeDefines.cpp | 12 +++ src/src/CustomBuild/CompiletimeDefines.h | 4 +- src/src/CustomBuild/ESPEasy_buildinfo.h | 4 + src/src/ESPEasyCore/ESPEasy_setup.cpp | 3 +- src/src/Helpers/ESPEasy_FactoryDefault.cpp | 3 +- src/src/Helpers/ESPEasy_Storage.cpp | 3 +- src/src/Helpers/ESPEasy_time.cpp | 104 ++----------------- src/src/Helpers/ESPEasy_time.h | 15 --- src/src/Helpers/ESPEasy_time_calc.cpp | 114 +++++++++++++++++++++ src/src/Helpers/ESPEasy_time_calc.h | 20 ++++ src/src/Helpers/ESPEasy_time_zone.cpp | 8 +- src/src/Helpers/Networking.cpp | 2 +- src/src/Helpers/StringGenerator_System.cpp | 20 +++- src/src/Helpers/StringGenerator_System.h | 2 + src/src/Helpers/StringProvider.cpp | 2 +- src/src/WebServer/DownloadPage.cpp | 5 +- src/src/WebServer/ESPEasy_WebServer.h | 6 +- src/src/WebServer/JSON.cpp | 7 +- src/src/WebServer/RootPage.cpp | 4 +- src/src/WebServer/SysInfoPage.cpp | 2 +- tools/pio/generate-compiletime-defines.py | 11 +- 24 files changed, 236 insertions(+), 139 deletions(-) diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index 815a40871..368bc2909 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -37,10 +37,15 @@ lib_ignore = ${core_stage.lib_ignore} [no_ir] -lib_ignore = IRremoteESP8266, HeatpumpIR +lib_ignore = IRremoteESP8266 + HeatpumpIR [no_sd] -lib_ignore = SD(esp8266), SD, SDFS +lib_ignore = ESP8266SdFat + SD(esp8266) + SD + SDFS + LittleFS(esp8266) [no_littlefs] lib_ignore = LittleFS(esp8266) @@ -110,6 +115,7 @@ platform = ${regular_platform.platform} platform_packages = ${regular_platform.platform_packages} build_flags = ${regular_platform.build_flags} lib_ignore = ${regular_platform.lib_ignore} + ESP8266SdFat SD(esp8266) SD SDFS @@ -120,6 +126,7 @@ platform = ${regular_platform_alt_wifi.platform} platform_packages = ${regular_platform_alt_wifi.platform_packages} build_flags = ${regular_platform_alt_wifi.build_flags} lib_ignore = ${regular_platform_alt_wifi.lib_ignore} + ESP8266SdFat SD(esp8266) SD SDFS @@ -131,6 +138,7 @@ platform = ${beta_platform.platform} platform_packages = ${beta_platform.platform_packages} build_flags = ${beta_platform.build_flags} lib_ignore = ${beta_platform.lib_ignore} + ESP8266SdFat SD(esp8266) SD SDFS @@ -164,6 +172,7 @@ build_flags = ${regular_platform_alt_wifi.build_flags} -DLIMIT_BUILD_SIZE -DDISABLE_SC16IS752_Serial lib_ignore = ${regular_platform_alt_wifi.lib_ignore} + ESP8266SdFat SD(esp8266) SD SDFS @@ -177,6 +186,8 @@ build_flags = ${beta_platform.build_flags} -DLIMIT_BUILD_SIZE -DDISABLE_SC16IS752_Serial lib_ignore = ${beta_platform.lib_ignore} + ESP8266SdFat + SD(esp8266) SD SDFS LittleFS(esp8266) @@ -194,6 +205,7 @@ lib_ignore = ESP32_ping ESP32WebServer ServoESP32 ESP32HTTPUpdateServer + ESP8266SdFat SD(esp8266) SD SDFS diff --git a/src/_N001_Email.cpp b/src/_N001_Email.cpp index f400d0510..1276acf0f 100644 --- a/src/_N001_Email.cpp +++ b/src/_N001_Email.cpp @@ -20,6 +20,7 @@ #include "src/Helpers/ESPEasy_Storage.h" #include "src/Helpers/ESPEasy_time_calc.h" #include "src/Helpers/Networking.h" +#include "src/Helpers/StringGenerator_System.h" #include "src/Helpers/StringParser.h" #include "src/Helpers/_CPlugin_Helper.h" // safeReadStringUntil #include "src/Helpers/_NPlugin_init.h" @@ -142,7 +143,7 @@ bool NPlugin_001_send(const NotificationSettingsStruct& notificationsettings, co mailheader.replace(F("$emailfrom"), notificationsettings.Sender); mailheader.replace(F("$ato"), notificationsettings.Receiver); mailheader.replace(F("$subject"), aSub); - mailheader.replace(F("$espeasyversion"), String(BUILD)); + mailheader.replace(F("$espeasyversion"), getSystemBuildString()); aMesg.replace(F("\r"), F("
")); // re-write line breaks for Content-type: text/html // Wait for Client to Start Sending diff --git a/src/src/Commands/Settings.cpp b/src/src/Commands/Settings.cpp index 0e16e99b8..17ef70b6d 100644 --- a/src/src/Commands/Settings.cpp +++ b/src/src/Commands/Settings.cpp @@ -4,6 +4,8 @@ #include "../Commands/Common.h" +#include "../CustomBuild/CompiletimeDefines.h" + #include "../ESPEasyCore/ESPEasyNetwork.h" #include "../ESPEasyCore/Serial.h" @@ -15,6 +17,7 @@ #include "../Helpers/Memory.h" #include "../Helpers/Misc.h" #include "../Helpers/StringConverter.h" +#include "../Helpers/StringGenerator_System.h" String Command_Settings_Build(struct EventStruct *event, const char* Line) @@ -94,7 +97,7 @@ const __FlashStringHelper * Command_Settings_Print(struct EventStruct *event, co serialPrintln(F("System Info")); serialPrint(F(" IP Address : ")); serialPrintln(NetworkLocalIP().toString()); - serialPrint(F(" Build : ")); serialPrintln(String(static_cast(BUILD))); + serialPrint(F(" Build : ")); serialPrintln(String(get_build_nr()) + '/' + getSystemBuildString()); serialPrint(F(" Name : ")); serialPrintln(Settings.Name); serialPrint(F(" Unit : ")); serialPrintln(String(static_cast(Settings.Unit))); serialPrint(F(" WifiSSID : ")); serialPrintln(SecuritySettings.WifiSSID); diff --git a/src/src/CustomBuild/CompiletimeDefines.cpp b/src/src/CustomBuild/CompiletimeDefines.cpp index d02a46889..139ae00a7 100644 --- a/src/src/CustomBuild/CompiletimeDefines.cpp +++ b/src/src/CustomBuild/CompiletimeDefines.cpp @@ -1,5 +1,7 @@ #include "../CustomBuild/CompiletimeDefines.h" +#include "../CustomBuild/ESPEasy_buildinfo.h" + // This file will be "patched" at compiletime by // tools/pio/generate-compiletime-defines.py // Therefore this one may not include ESPEasy_common.h @@ -21,6 +23,16 @@ // Uncrustify must not be used on macros, but we're now done, so turn Uncrustify on again. // *INDENT-ON* + +uint16_t get_build_nr() { + #ifdef SET_BUILD_VERSION + return SET_BUILD_VERSION; + #else + #pragma message ( "Build is not based on current date" ) + return BUILD; + #endif +} + const __FlashStringHelper* get_binary_filename() { #ifndef SET_BUILD_BINARY_FILENAME return F("firmware.bin"); diff --git a/src/src/CustomBuild/CompiletimeDefines.h b/src/src/CustomBuild/CompiletimeDefines.h index 4ffa1ef19..392a83d25 100644 --- a/src/src/CustomBuild/CompiletimeDefines.h +++ b/src/src/CustomBuild/CompiletimeDefines.h @@ -3,8 +3,10 @@ #include -//#include "../../ESPEasy_common.h" +// Build NR is used as a "revision" nr for settings +// As of 2022-08-18, it is the nr of days since 2022-08-18 + 20200 +uint16_t get_build_nr(); const __FlashStringHelper * get_binary_filename(); const __FlashStringHelper * get_build_time(); const __FlashStringHelper * get_build_date(); diff --git a/src/src/CustomBuild/ESPEasy_buildinfo.h b/src/src/CustomBuild/ESPEasy_buildinfo.h index 9fcc3c922..ca89c15e5 100644 --- a/src/src/CustomBuild/ESPEasy_buildinfo.h +++ b/src/src/CustomBuild/ESPEasy_buildinfo.h @@ -20,7 +20,11 @@ #endif // if defined(ESP32) +// Deprecated define. +// Use get_build_nr() from CustomBuild/CompiletimeDefines.h #define BUILD 20116 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) + + #ifndef BUILD_NOTES #if defined(ESP8266) # define BUILD_NOTES " - Mega" diff --git a/src/src/ESPEasyCore/ESPEasy_setup.cpp b/src/src/ESPEasyCore/ESPEasy_setup.cpp index 46cbf9050..435e37d90 100644 --- a/src/src/ESPEasyCore/ESPEasy_setup.cpp +++ b/src/src/ESPEasyCore/ESPEasy_setup.cpp @@ -4,6 +4,7 @@ #include "../../ESPEasy-Globals.h" #include "../../_Plugin_Helper.h" +#include "../CustomBuild/CompiletimeDefines.h" #include "../ESPEasyCore/ESPEasyNetwork.h" #include "../ESPEasyCore/ESPEasyRules.h" #include "../ESPEasyCore/ESPEasyWifi.h" @@ -359,7 +360,7 @@ void ESPEasy_setup() #endif - if (Settings.Build != BUILD) { + if (Settings.Build != get_build_nr()) { BuildFixes(); } diff --git a/src/src/Helpers/ESPEasy_FactoryDefault.cpp b/src/src/Helpers/ESPEasy_FactoryDefault.cpp index c64b4e2bf..2695c43cb 100644 --- a/src/src/Helpers/ESPEasy_FactoryDefault.cpp +++ b/src/src/Helpers/ESPEasy_FactoryDefault.cpp @@ -3,6 +3,7 @@ #include "../../ESPEasy_common.h" #include "../../_Plugin_Helper.h" +#include "../CustomBuild/CompiletimeDefines.h" #include "../CustomBuild/StorageLayout.h" #include "../DataStructs/ControllerSettingsStruct.h" @@ -184,7 +185,7 @@ void ResetFactory() Settings.PID = ESP_PROJECT_PID; Settings.Version = VERSION; - Settings.Build = BUILD; + Settings.Build = get_build_nr(); // Settings.IP_Octet = DEFAULT_IP_OCTET; Settings.Delay = DEFAULT_DELAY; diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 611c8f794..6e58bfc29 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -2,6 +2,7 @@ #include "../../ESPEasy_common.h" +#include "../CustomBuild/CompiletimeDefines.h" #include "../CustomBuild/StorageLayout.h" #include "../DataStructs/TimingStats.h" @@ -320,7 +321,7 @@ String BuildFixes() #endif - Settings.Build = BUILD; + Settings.Build = get_build_nr(); return SaveSettings(); } diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index 181f8108e..b2ebf6525 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -51,40 +51,6 @@ struct tm ESPEasy_time::addSeconds(const struct tm& ts, int seconds, bool toLoca return result; } -void ESPEasy_time::breakTime(unsigned long timeInput, struct tm& tm) { - uint32_t time = (uint32_t)timeInput; - tm.tm_sec = time % 60; - time /= 60; // now it is minutes - tm.tm_min = time % 60; - time /= 60; // now it is hours - tm.tm_hour = time % 24; - time /= 24; // now it is days - tm.tm_wday = ((time + 4) % 7) + 1; // Sunday is day 1 - - int year = 1970; - unsigned long days = 0; - while ((unsigned)(days += (isLeapYear(year) ? 366 : 365)) <= time) { - year++; - } - tm.tm_year = year - 1900; // tm_year starts at 1900 - - days -= isLeapYear(year) ? 366 : 365; - time -= days; // now it is days in this year, starting at 0 - - uint8_t month = 0; - for (month = 0; month < 12; month++) { - const uint8_t monthLength = getMonthDays(year, month); - if (time >= monthLength) { - time -= monthLength; - } else { - break; - } - } - tm.tm_mon = month; // Jan is month 0 - tm.tm_mday = time + 1; // day of month start at 1 -} - - void ESPEasy_time::restoreFromRTC() { static bool firstCall = true; @@ -482,82 +448,30 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d) \*********************************************************************************************/ String ESPEasy_time::getDateString(char delimiter) const { - return getDateString(tm, delimiter); + return formatDateString(tm, delimiter); } -String ESPEasy_time::getDateString(const struct tm& ts, char delimiter) { - // time format example with ':' delimiter: 23:59:59 (HH:MM:SS) - char DateString[20]; // 19 digits plus the null char - const int year = 1900 + ts.tm_year; - - sprintf_P(DateString, PSTR("%4d%c%02d%c%02d"), year, delimiter, ts.tm_mon + 1, delimiter, ts.tm_mday); - return DateString; -} String ESPEasy_time::getTimeString(char delimiter, bool show_seconds /*=true*/, char hour_prefix /*='\0'*/) const { - return getTimeString(tm, delimiter, false, show_seconds, hour_prefix); + return formatTimeString(tm, delimiter, false, show_seconds, hour_prefix); } String ESPEasy_time::getTimeString_ampm(char delimiter, bool show_seconds /*=true*/, char hour_prefix /*='\0'*/) const { - return getTimeString(tm, delimiter, true, show_seconds, hour_prefix); + return formatTimeString(tm, delimiter, true, show_seconds, hour_prefix); } -// returns the current Time separated by the given delimiter -// time format example with ':' delimiter: 23:59:59 (HH:MM:SS) -String ESPEasy_time::getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix /*='\0'*/) -{ - char TimeString[20]; // 19 digits plus the null char - char hour_prefix_s[2] = { 0 }; - if (am_pm) { - uint8_t hour(ts.tm_hour % 12); - - if (hour == 0) { hour = 12; } - const char a_or_p = ts.tm_hour < 12 ? 'A' : 'P'; - if (hour < 10) { hour_prefix_s[0] = hour_prefix; } - - if (show_seconds) { - sprintf_P(TimeString, PSTR("%s%d%c%02d%c%02d %cM"), - hour_prefix_s, hour, delimiter, ts.tm_min, delimiter, ts.tm_sec, a_or_p); - } else { - sprintf_P(TimeString, PSTR("%s%d%c%02d %cM"), - hour_prefix_s, hour, delimiter, ts.tm_min, a_or_p); - } - } else { - if (show_seconds) { - sprintf_P(TimeString, PSTR("%02d%c%02d%c%02d"), - ts.tm_hour, delimiter, ts.tm_min, delimiter, ts.tm_sec); - } else { - if (ts.tm_hour < 10) { hour_prefix_s[0] = hour_prefix; } - sprintf_P(TimeString, PSTR("%s%d%c%02d"), - hour_prefix_s, ts.tm_hour, delimiter, ts.tm_min); - } - } - return TimeString; -} String ESPEasy_time::getDateTimeString(char dateDelimiter, char timeDelimiter, char dateTimeDelimiter) const { - return getDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, false); + return formatDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, false); } String ESPEasy_time::getDateTimeString_ampm(char dateDelimiter, char timeDelimiter, char dateTimeDelimiter) const { - return getDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, true); + return formatDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, true); } -String ESPEasy_time::getDateTimeString(const struct tm& ts, char dateDelimiter, char timeDelimiter, char dateTimeDelimiter, bool am_pm) -{ - // if called like this: getDateTimeString('\0', '\0', '\0'); - // it will give back this: 20161231235959 (YYYYMMDDHHMMSS) - String ret = getDateString(ts, dateDelimiter); - - if (dateTimeDelimiter != '\0') { - ret += dateTimeDelimiter; - } - ret += getTimeString(ts, timeDelimiter, am_pm, true); - return ret; -} /********************************************************************************************\ Get current time/date @@ -624,25 +538,25 @@ int ESPEasy_time::getSecOffset(const String& format) { } String ESPEasy_time::getSunriseTimeString(char delimiter) const { - return getTimeString(sunRise, delimiter, false, false); + return formatTimeString(sunRise, delimiter, false, false); } String ESPEasy_time::getSunsetTimeString(char delimiter) const { - return getTimeString(sunSet, delimiter, false, false); + return formatTimeString(sunSet, delimiter, false, false); } String ESPEasy_time::getSunriseTimeString(char delimiter, int secOffset) const { if (secOffset == 0) { return getSunriseTimeString(delimiter); } - return getTimeString(getSunRise(secOffset), delimiter, false, false); + return formatTimeString(getSunRise(secOffset), delimiter, false, false); } String ESPEasy_time::getSunsetTimeString(char delimiter, int secOffset) const { if (secOffset == 0) { return getSunsetTimeString(delimiter); } - return getTimeString(getSunSet(secOffset), delimiter, false, false); + return formatTimeString(getSunSet(secOffset), delimiter, false, false); } float ESPEasy_time::sunDeclination(int doy) { diff --git a/src/src/Helpers/ESPEasy_time.h b/src/src/Helpers/ESPEasy_time.h index 73f5b4ae9..7c98fb2b9 100644 --- a/src/src/Helpers/ESPEasy_time.h +++ b/src/src/Helpers/ESPEasy_time.h @@ -18,8 +18,6 @@ public: struct tm addSeconds(const struct tm& ts, int seconds, bool toLocalTime) const; - static void breakTime(unsigned long timeInput, - struct tm & tm); // Restore the last known system time // This may be useful to get some idea of what time it is. @@ -63,30 +61,17 @@ public: // Default date format example: 20161231 (YYYYMMDD) String getDateString(char delimiter = '\0') const; -// Format given Date separated by the given delimiter -// date format example with '-' delimiter: 2016-12-31 (YYYY-MM-DD) -static String getDateString(const struct tm& ts, char delimiter); - // Formats the current Time // Default time format example: 235959 (HHMMSS) String getTimeString(char delimiter = '\0', bool show_seconds = true, char hour_prefix = '\0') const; String getTimeString_ampm(char delimiter = '\0', bool show_seconds = true, char hour_prefix = '\0') const; -// returns the current Time separated by the given delimiter -// time format example with ':' delimiter: 23:59:59 (HH:MM:SS) -static String getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix = '\0'); - - String getDateTimeString(char dateDelimiter = '-', char timeDelimiter = ':', char dateTimeDelimiter = ' ') const; String getDateTimeString_ampm(char dateDelimiter = '-', char timeDelimiter = ':', char dateTimeDelimiter = ' ') const; -// returns the current Date and Time separated by the given delimiter -// if called like this: getDateTimeString('\0', '\0', '\0'); -// it will give back this: 20161231235959 (YYYYMMDDHHMMSS) -static String getDateTimeString(const struct tm& ts, char dateDelimiter = '-', char timeDelimiter = ':', char dateTimeDelimiter = ' ', bool am_pm = false); /********************************************************************************************\ diff --git a/src/src/Helpers/ESPEasy_time_calc.cpp b/src/src/Helpers/ESPEasy_time_calc.cpp index c22fa24b2..fdccbba13 100644 --- a/src/src/Helpers/ESPEasy_time_calc.cpp +++ b/src/src/Helpers/ESPEasy_time_calc.cpp @@ -65,6 +65,120 @@ uint32_t makeTime(const struct tm& tm) { return seconds; } +void breakTime(unsigned long timeInput, struct tm& tm) { + uint32_t time = (uint32_t)timeInput; + tm.tm_sec = time % 60; + time /= 60; // now it is minutes + tm.tm_min = time % 60; + time /= 60; // now it is hours + tm.tm_hour = time % 24; + time /= 24; // now it is days + tm.tm_wday = ((time + 4) % 7) + 1; // Sunday is day 1 + + int year = 1970; + unsigned long days = 0; + while ((unsigned)(days += (isLeapYear(year) ? 366 : 365)) <= time) { + year++; + } + tm.tm_year = year - 1900; // tm_year starts at 1900 + + days -= isLeapYear(year) ? 366 : 365; + time -= days; // now it is days in this year, starting at 0 + + uint8_t month = 0; + for (month = 0; month < 12; month++) { + const uint8_t monthLength = getMonthDays(year, month); + if (time >= monthLength) { + time -= monthLength; + } else { + break; + } + } + tm.tm_mon = month; // Jan is month 0 + tm.tm_mday = time + 1; // day of month start at 1 +} + + +String formatDateString(const struct tm& ts, char delimiter) { + // time format example with ':' delimiter: 23:59:59 (HH:MM:SS) + char DateString[20]; // 19 digits plus the null char + const int year = 1900 + ts.tm_year; + if (delimiter == '\0') { + sprintf_P(DateString, PSTR("%4d%02d%02d"), year, ts.tm_mon + 1, ts.tm_mday); + } else { + sprintf_P(DateString, PSTR("%4d%c%02d%c%02d"), year, delimiter, ts.tm_mon + 1, delimiter, ts.tm_mday); + } + return DateString; +} + + +// returns the current Time separated by the given delimiter +// time format example with ':' delimiter: 23:59:59 (HH:MM:SS) +String formatTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix /*='\0'*/) +{ + char TimeString[20]; // 19 digits plus the null char + char hour_prefix_s[2] = { 0 }; + + if (am_pm) { + uint8_t hour(ts.tm_hour % 12); + + if (hour == 0) { hour = 12; } + const char a_or_p = ts.tm_hour < 12 ? 'A' : 'P'; + if (hour < 10) { hour_prefix_s[0] = hour_prefix; } + + if (show_seconds) { + if (delimiter == '\0') { + sprintf_P(TimeString, PSTR("%s%d%02d%02d %cM"), + hour_prefix_s, hour, ts.tm_min, ts.tm_sec, a_or_p); + } else { + sprintf_P(TimeString, PSTR("%s%d%c%02d%c%02d %cM"), + hour_prefix_s, hour, delimiter, ts.tm_min, delimiter, ts.tm_sec, a_or_p); + } + } else { + if (delimiter == '\0') { + sprintf_P(TimeString, PSTR("%s%d%02d %cM"), + hour_prefix_s, hour, ts.tm_min, a_or_p); + } else { + sprintf_P(TimeString, PSTR("%s%d%c%02d %cM"), + hour_prefix_s, hour, delimiter, ts.tm_min, a_or_p); + } + } + } else { + if (show_seconds) { + if (delimiter == '\0') { + sprintf_P(TimeString, PSTR("%02d%02d%02d"), + ts.tm_hour, ts.tm_min, ts.tm_sec); + } else { + sprintf_P(TimeString, PSTR("%02d%c%02d%c%02d"), + ts.tm_hour, delimiter, ts.tm_min, delimiter, ts.tm_sec); + } + } else { + if (ts.tm_hour < 10) { hour_prefix_s[0] = hour_prefix; } + if (delimiter == '\0') { + sprintf_P(TimeString, PSTR("%s%d%02d"), + hour_prefix_s, ts.tm_hour, ts.tm_min); + } else { + sprintf_P(TimeString, PSTR("%s%d%c%02d"), + hour_prefix_s, ts.tm_hour, delimiter, ts.tm_min); + } + } + } + return TimeString; +} + + +String formatDateTimeString(const struct tm& ts, char dateDelimiter, char timeDelimiter, char dateTimeDelimiter, bool am_pm) +{ + // if called like this: getDateTimeString('\0', '\0', '\0'); + // it will give back this: 20161231235959 (YYYYMMDDHHMMSS) + String ret = formatDateString(ts, dateDelimiter); + + if (dateTimeDelimiter != '\0') { + ret += dateTimeDelimiter; + } + ret += formatTimeString(ts, timeDelimiter, am_pm, true); + return ret; +} /********************************************************************************************\ Time computations for rules. diff --git a/src/src/Helpers/ESPEasy_time_calc.h b/src/src/Helpers/ESPEasy_time_calc.h index 1b2eb714e..d71fbfc46 100644 --- a/src/src/Helpers/ESPEasy_time_calc.h +++ b/src/src/Helpers/ESPEasy_time_calc.h @@ -69,6 +69,26 @@ uint8_t getMonthDays(int year, uint8_t month); uint32_t makeTime(const struct tm& tm); +void breakTime(unsigned long timeInput, struct tm& tm); + +/********************************************************************************************\ + Unix Time formatting + \*********************************************************************************************/ + +// Format given Date separated by the given delimiter +// date format example with '-' delimiter: 2016-12-31 (YYYY-MM-DD) +String formatDateString(const struct tm& ts, char delimiter); + +// returns the current Time separated by the given delimiter +// time format example with ':' delimiter: 23:59:59 (HH:MM:SS) +String formatTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix = '\0'); + +// returns the current Date and Time separated by the given delimiter +// if called like this: getDateTimeString('\0', '\0', '\0'); +// it will give back this: 20161231235959 (YYYYMMDDHHMMSS) +String formatDateTimeString(const struct tm& ts, char dateDelimiter = '-', char timeDelimiter = ':', char dateTimeDelimiter = ' ', bool am_pm = false); + + /********************************************************************************************\ Time computations for rules. \*********************************************************************************************/ diff --git a/src/src/Helpers/ESPEasy_time_zone.cpp b/src/src/Helpers/ESPEasy_time_zone.cpp index e6202e3e9..bb56c1ceb 100644 --- a/src/src/Helpers/ESPEasy_time_zone.cpp +++ b/src/src/Helpers/ESPEasy_time_zone.cpp @@ -62,8 +62,8 @@ void ESPEasy_time_zone::logTimeZoneInfo() { if (m_dstLoc != 0) { struct tm tmp; - ESPEasy_time::breakTime(m_dstLoc, tmp); - log += ESPEasy_time::getDateTimeString(tmp, '-', ':', ' ', false); + breakTime(m_dstLoc, tmp); + log += formatDateTimeString(tmp, '-', ':', ' ', false); } log += F(" offset: "); log += m_dst.offset; @@ -75,8 +75,8 @@ void ESPEasy_time_zone::logTimeZoneInfo() { if (m_stdLoc != 0) { struct tm tmp; - ESPEasy_time::breakTime(m_stdLoc, tmp); - log += ESPEasy_time::getDateTimeString(tmp, '-', ':', ' ', false); + breakTime(m_stdLoc, tmp); + log += formatDateTimeString(tmp, '-', ':', ' ', false); } log += F(" offset: "); log += m_std.offset; diff --git a/src/src/Helpers/Networking.cpp b/src/src/Helpers/Networking.cpp index c43d8e459..bb15ddc2e 100644 --- a/src/src/Helpers/Networking.cpp +++ b/src/src/Helpers/Networking.cpp @@ -1223,7 +1223,7 @@ String get_user_agent_string() { userAgent.reserve(agent_size); userAgent += F("ESP Easy/"); - userAgent += BUILD; + userAgent += get_build_nr(); userAgent += '/'; userAgent += get_build_date(); userAgent += ' '; diff --git a/src/src/Helpers/StringGenerator_System.cpp b/src/src/Helpers/StringGenerator_System.cpp index 523648457..4b97a3667 100644 --- a/src/src/Helpers/StringGenerator_System.cpp +++ b/src/src/Helpers/StringGenerator_System.cpp @@ -5,6 +5,7 @@ ESPEasy specific strings \*********************************************************************************************/ +#include "../CustomBuild/CompiletimeDefines.h" #if FEATURE_MQTT @@ -158,12 +159,21 @@ String getResetReasonString() { } String getSystemBuildString() { - String result; + return formatSystemBuildNr(get_build_nr()); +} - result += BUILD; - result += ' '; - result += F(BUILD_NOTES); - return result; +String formatSystemBuildNr(uint16_t buildNr) { + if (buildNr < 20200) return String(buildNr); + + // Build NR is used as a "revision" nr for settings + // As of 2022-08-18, it is the nr of days since 2022-08-18 + 20200 + const uint32_t seconds_since_start = (buildNr - 20200) * 86400; + const uint32_t unix_time_start = 1660780800; // Thu Aug 18 2022 00:00:00 GMT+0000 + struct tm build_time; + breakTime(unix_time_start + seconds_since_start, build_time); + + String res = formatDateString(build_time, '\0'); + return res; } String getPluginDescriptionString() { diff --git a/src/src/Helpers/StringGenerator_System.h b/src/src/Helpers/StringGenerator_System.h index b16c744ac..aa3ff622f 100644 --- a/src/src/Helpers/StringGenerator_System.h +++ b/src/src/Helpers/StringGenerator_System.h @@ -29,6 +29,8 @@ String getResetReasonString(); String getSystemBuildString(); +String formatSystemBuildNr(uint16_t buildNr); + String getPluginDescriptionString(); String getSystemLibraryString(); diff --git a/src/src/Helpers/StringProvider.cpp b/src/src/Helpers/StringProvider.cpp index 33cf1724e..b0fa5648c 100644 --- a/src/src/Helpers/StringProvider.cpp +++ b/src/src/Helpers/StringProvider.cpp @@ -361,7 +361,7 @@ String getValue(LabelType::Enum label) { case LabelType::PERIODICAL_GRAT_ARP: return jsonBool(Settings.gratuitousARP()); case LabelType::CONNECTION_FAIL_THRESH: return String(Settings.ConnectionFailuresThreshold); - case LabelType::BUILD_DESC: return String(BUILD); + case LabelType::BUILD_DESC: return getSystemBuildString(); case LabelType::GIT_BUILD: { const String res(F(BUILD_GIT)); diff --git a/src/src/WebServer/DownloadPage.cpp b/src/src/WebServer/DownloadPage.cpp index fac795533..914a4d8ae 100644 --- a/src/src/WebServer/DownloadPage.cpp +++ b/src/src/WebServer/DownloadPage.cpp @@ -2,10 +2,11 @@ #ifdef WEBSERVER_DOWNLOAD -#include "../WebServer/ESPEasy_WebServer.h" +//#include "../WebServer/ESPEasy_WebServer.h" #include "../Globals/ESPEasy_time.h" #include "../Globals/Settings.h" #include "../Helpers/ESPEasy_Storage.h" +#include "../Helpers/StringGenerator_System.h" // ******************************************************************************** @@ -35,7 +36,7 @@ void handle_download() str += F("_U"); str += Settings.Unit; str += F("_Build"); - str += BUILD; + str += getSystemBuildString(); str += '_'; if (node_time.systemTimePresent()) diff --git a/src/src/WebServer/ESPEasy_WebServer.h b/src/src/WebServer/ESPEasy_WebServer.h index 68b598a2c..6bf46aac1 100644 --- a/src/src/WebServer/ESPEasy_WebServer.h +++ b/src/src/WebServer/ESPEasy_WebServer.h @@ -1,5 +1,5 @@ -#ifndef WEBSERVER_WEBSERVER_H -#define WEBSERVER_WEBSERVER_H +#ifndef WEBSERVER_ESPEASY_WEBSERVER_H +#define WEBSERVER_ESPEASY_WEBSERVER_H #include "../WebServer/common.h" @@ -211,4 +211,4 @@ String webArg(const String& arg); String webArg(int i); #endif -#endif // ifndef WEBSERVER_WEBSERVER_H \ No newline at end of file +#endif // ifndef WEBSERVER_ESPEASY_WEBSERVER_H \ No newline at end of file diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index 39f6ebf6d..7381371e0 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -4,6 +4,8 @@ #include "../WebServer/JSON.h" #include "../WebServer/Markup_Forms.h" +#include "../CustomBuild/CompiletimeDefines.h" + #include "../Globals/Cache.h" #include "../Globals/Nodes.h" #include "../Globals/Device.h" @@ -16,6 +18,7 @@ #include "../Helpers/Numerical.h" #include "../Helpers/StringConverter.h" #include "../Helpers/StringProvider.h" +#include "../Helpers/StringGenerator_System.h" #include "../../_Plugin_Helper.h" #include "../../ESPEasy-Globals.h" @@ -312,7 +315,7 @@ void handle_json() (it->first != Settings.Unit) ? it->second.nodeName : Settings.Name); if (it->second.build) { - stream_next_json_object_value(F("build"), it->second.build); + stream_next_json_object_value(F("build"), formatSystemBuildNr(it->second.build)); } if (it->second.nodeType) { @@ -521,7 +524,7 @@ void handle_nodes_list_json() { json_number(F("first"), String(it->first)); json_prop(F("name"), isThisUnit ? Settings.Name : it->second.nodeName); - if (it->second.build) { json_prop(F("build"), String(it->second.build)); } + if (it->second.build) { json_prop(F("build"), formatSystemBuildNr(it->second.build)); } json_prop(F("type"), getNodeTypeDisplayString(it->second.nodeType)); json_prop(F("ip"), it->second.ip.toString()); json_number(F("age"), String(it->second.age)); diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 325a2a301..ae2a98fea 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -8,6 +8,7 @@ #include "../WebServer/LoadFromFS.h" #include "../WebServer/Markup.h" #include "../WebServer/Markup_Buttons.h" +#include "../WebServer/Markup_Forms.h" #include "../Commands/InternalCommands.h" #include "../ESPEasyCore/ESPEasyNetwork.h" @@ -21,6 +22,7 @@ #include "../Helpers/ESPEasy_Storage.h" #include "../Helpers/Memory.h" #include "../Helpers/Misc.h" +#include "../Helpers/StringGenerator_System.h" #include "../Helpers/WebServer_commandHelper.h" @@ -298,7 +300,7 @@ void handle_root() { if (MAIN_PAGE_SHOW_NODE_LIST_BUILD) { if (it->second.build) { - addHtmlInt(it->second.build); + addHtml(formatSystemBuildNr(it->second.build)); } html_TD(); } diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index 1eb025f4b..6f06319a7 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -148,7 +148,7 @@ void handle_sysinfo_json() { # endif // if FEATURE_ETHERNET json_open(false, F("firmware")); - json_prop(F("build"), String(BUILD)); + json_prop(F("build"), getSystemBuildString()); json_prop(F("notes"), F(BUILD_NOTES)); json_prop(F("libraries"), getSystemLibraryString()); json_prop(F("git_version"), getValue(LabelType::GIT_BUILD)); diff --git a/tools/pio/generate-compiletime-defines.py b/tools/pio/generate-compiletime-defines.py index 1ddd2df82..2af365798 100644 --- a/tools/pio/generate-compiletime-defines.py +++ b/tools/pio/generate-compiletime-defines.py @@ -7,6 +7,13 @@ from datetime import date import json +def compute_version_date(): + d0 = date(2022, 8, 18) + today = date.today() + delta = today - d0 + return 20200 + delta.days + + def create_binary_filename(): today = date.today() d1 = today.strftime("%Y%m%d") @@ -59,7 +66,8 @@ def gen_compiletime_defines(node): + [("SET_BUILD_BINARY_FILENAME", '\\"%s\\"' % create_binary_filename())] + [("SET_BOARD_NAME", '\\"%s\\"' % get_board_name())] + [("SET_BUILD_PLATFORM", '\\"%s\\"' % platform.platform())] - + [("SET_BUILD_GIT_HEAD", '\\"%s\\"' % get_git_description())], + + [("SET_BUILD_GIT_HEAD", '\\"%s\\"' % get_git_description())] + + [("SET_BUILD_VERSION", compute_version_date())], CCFLAGS=env["CCFLAGS"] ) @@ -72,6 +80,7 @@ print("\u001b[33m PROGNAME: \u001b[0m {}".format(env['PROGNAME'])) print("\u001b[33m BOARD_NAME: \u001b[0m {}".format(get_board_name())) print("\u001b[33m BUILD_PLATFORM: \u001b[0m {}".format(platform.platform())) print("\u001b[33m GIT_HEAD: \u001b[0m {}".format(get_git_description())) +print("\u001b[33m BUILD_VERSION: \u001b[0m {}".format(compute_version_date())) print("\u001b[32m ------------------------------- \u001b[0m") print("\u001b[32m Flash configuration \u001b[0m") From a4e34afa7376a2844a27db6a50226dbf3cc4fdad Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 21 Aug 2022 13:08:17 +0200 Subject: [PATCH 27/32] [Build] Fix build error due to missed function renames --- src/_P081_Cron.ino | 2 +- src/_P082_GPS.ino | 2 +- src/src/CustomBuild/CompiletimeDefines.cpp | 4 +++- src/src/CustomBuild/ESPEasy_buildinfo.h | 2 +- src/src/Helpers/ESPEasy_Storage.cpp | 4 ++++ src/src/PluginStructs/P081_data_struct.cpp | 2 +- src/src/WebServer/TimingStats.cpp | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/_P081_Cron.ino b/src/_P081_Cron.ino index 44cb2ec7f..81d770288 100644 --- a/src/_P081_Cron.ino +++ b/src/_P081_Cron.ino @@ -163,7 +163,7 @@ boolean Plugin_081(uint8_t function, struct EventStruct *event, String& string) P081_setCronExecTimes(event, last_exec_time, next_exec_time); # ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG, String(F("Next execution:")) + ESPEasy_time::getDateTimeString(*gmtime(&next_exec_time))); + addLog(LOG_LEVEL_DEBUG, String(F("Next execution:")) + formatDateTimeString(*gmtime(&next_exec_time))); # endif // ifndef BUILD_NO_DEBUG if (function != PLUGIN_TIME_CHANGE) { diff --git a/src/_P082_GPS.ino b/src/_P082_GPS.ino index 362fa4dba..2068493ae 100644 --- a/src/_P082_GPS.ino +++ b/src/_P082_GPS.ino @@ -721,7 +721,7 @@ void P082_html_show_stats(struct EventStruct *event) { if (P082_data->getDateTime(dateTime, age, pps_sync)) { dateTime = node_time.addSeconds(dateTime, (age / 1000), false); - addHtml(ESPEasy_time::getDateTimeString(dateTime)); + addHtml(formatDateTimeString(dateTime)); } else { addHtml('-'); } diff --git a/src/src/CustomBuild/CompiletimeDefines.cpp b/src/src/CustomBuild/CompiletimeDefines.cpp index 139ae00a7..4554e6ccf 100644 --- a/src/src/CustomBuild/CompiletimeDefines.cpp +++ b/src/src/CustomBuild/CompiletimeDefines.cpp @@ -29,7 +29,9 @@ uint16_t get_build_nr() { return SET_BUILD_VERSION; #else #pragma message ( "Build is not based on current date" ) - return BUILD; + // Last used version for BUILD was 20116, + // so make sure we can recognize a build not made using the compile time defines. + return 20117; #endif } diff --git a/src/src/CustomBuild/ESPEasy_buildinfo.h b/src/src/CustomBuild/ESPEasy_buildinfo.h index ca89c15e5..73047418d 100644 --- a/src/src/CustomBuild/ESPEasy_buildinfo.h +++ b/src/src/CustomBuild/ESPEasy_buildinfo.h @@ -22,7 +22,7 @@ // Deprecated define. // Use get_build_nr() from CustomBuild/CompiletimeDefines.h -#define BUILD 20116 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) +//#define BUILD 20116 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) #ifndef BUILD_NOTES diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 6e58bfc29..3b546e209 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -320,6 +320,10 @@ String BuildFixes() } #endif + // Starting 2022/08/18 + // Use get_build_nr() value for settings transitions. + // This value will also be shown when building using PlatformIO, when showing the Compile time defines + Settings.Build = get_build_nr(); return SaveSettings(); diff --git a/src/src/PluginStructs/P081_data_struct.cpp b/src/src/PluginStructs/P081_data_struct.cpp index 468badec3..5cb54b7a4 100644 --- a/src/src/PluginStructs/P081_data_struct.cpp +++ b/src/src/PluginStructs/P081_data_struct.cpp @@ -175,7 +175,7 @@ String P081_formatExecTime(taskIndex_t taskIndex, uint8_t varNr) { time_t exec_time = P081_getCronExecTime(taskIndex, varNr); if (exec_time != CRON_INVALID_INSTANT) { - return ESPEasy_time::getDateTimeString(*gmtime(&exec_time)); + return formatDateTimeString(*gmtime(&exec_time)); } return F("-"); } diff --git a/src/src/WebServer/TimingStats.cpp b/src/src/WebServer/TimingStats.cpp index 514c5673c..3b0122fab 100644 --- a/src/src/WebServer/TimingStats.cpp +++ b/src/src/WebServer/TimingStats.cpp @@ -44,7 +44,7 @@ void handle_timingstats() { addFormHeader(F("Statistics")); addRowLabel(F("Start Period")); struct tm startPeriod = node_time.addSeconds(node_time.tm, -1.0f * timespan, false); - addHtml(ESPEasy_time::getDateTimeString(startPeriod, '-', ':', ' ', false)); + addHtml(formatDateTimeString(startPeriod, '-', ':', ' ', false)); addRowLabelValue(LabelType::LOCAL_TIME); addRowLabel(F("Time span")); addHtmlFloat(timespan); From a59b75c53f6d584386d6dbc34b34a51370cb3bfb Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 21 Aug 2022 14:14:07 +0200 Subject: [PATCH 28/32] [Build] Fix warning when P009 or P019 is not included in build --- src/src/Helpers/Scheduler.cpp | 38 ++++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/src/Helpers/Scheduler.cpp b/src/src/Helpers/Scheduler.cpp index 4185d1a0c..f0d95df1e 100644 --- a/src/src/Helpers/Scheduler.cpp +++ b/src/src/Helpers/Scheduler.cpp @@ -915,9 +915,7 @@ void ESPEasy_Scheduler::process_gpio_timer(unsigned long id) { uint8_t pinNumber = static_cast((id >> 8) & 0xFF); uint8_t pinStateValue = static_cast((id >> 16) & 0xFF); - bool success = true; - - uint8_t pluginID; + uint8_t pluginID = PLUGIN_GPIO; switch (GPIOType) { @@ -925,39 +923,37 @@ void ESPEasy_Scheduler::process_gpio_timer(unsigned long id) { GPIO_Internal_Write(pinNumber, pinStateValue); pluginID = PLUGIN_GPIO; break; - case GPIO_TYPE_MCP: #ifdef USES_P009 + case GPIO_TYPE_MCP: GPIO_MCP_Write(pinNumber, pinStateValue); pluginID = PLUGIN_MCP; -#endif break; - case GPIO_TYPE_PCF: +#endif #ifdef USES_P019 + case GPIO_TYPE_PCF: GPIO_PCF_Write(pinNumber, pinStateValue); pluginID = PLUGIN_PCF; -#endif break; +#endif default: - success = false; + return; } - if (success) { - const uint32_t key = createKey(pluginID, pinNumber); + const uint32_t key = createKey(pluginID, pinNumber); - // WARNING: operator [] creates an entry in the map if key does not exist - portStatusStruct tempStatus = globalMapPortStatus[key]; + // WARNING: operator [] creates an entry in the map if key does not exist + portStatusStruct tempStatus = globalMapPortStatus[key]; - tempStatus.mode = PIN_MODE_OUTPUT; - tempStatus.command = 1; // set to 1 in order to display the status in the PinStatus page + tempStatus.mode = PIN_MODE_OUTPUT; + tempStatus.command = 1; // set to 1 in order to display the status in the PinStatus page - if (tempStatus.state != pinStateValue) { - tempStatus.state = pinStateValue; - tempStatus.output = pinStateValue; - tempStatus.forceEvent = 1; - tempStatus.forceMonitor = 1; - } - savePortStatus(key, tempStatus); + if (tempStatus.state != pinStateValue) { + tempStatus.state = pinStateValue; + tempStatus.output = pinStateValue; + tempStatus.forceEvent = 1; + tempStatus.forceMonitor = 1; } + savePortStatus(key, tempStatus); } /*********************************************************************************************\ From 50967584e840527592eae02924c57bb59ad26df4 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 21 Aug 2022 14:17:26 +0200 Subject: [PATCH 29/32] [Custom build] Remove #include from Custom_sample.h Caused the confusion in #4212 --- src/Custom-sample.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Custom-sample.h b/src/Custom-sample.h index 9601723da..2b3a559f6 100644 --- a/src/Custom-sample.h +++ b/src/Custom-sample.h @@ -1,8 +1,6 @@ #ifndef ESPEASY_CUSTOM_H #define ESPEASY_CUSTOM_H -#include - /* To modify the stock configuration without changing the EspEasy.ino file : 1) rename this file to "Custom.h" (It is ignored by Git) From f7d8142afebe7a811c1572c5dd904130206c15d2 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 22 Aug 2022 14:47:27 +0200 Subject: [PATCH 30/32] [Build] Move include/ESPEasy_config.h to src/include (#4216) Fixes: #4216 --- platformio_core_defs.ini | 8 ++++---- src/ESPEasy_common.h | 2 +- src/_Plugin_Helper.h | 2 +- {include => src/include}/ESPEasy_config.h | 10 +++++----- src/src/CustomBuild/ESPEasyLimits.h | 2 +- src/src/CustomBuild/define_plugin_sets.h | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) rename {include => src/include}/ESPEasy_config.h (87%) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 48a86c174..9c08b8221 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -38,7 +38,7 @@ build_flags = -D NDEBUG -DVTABLES_IN_FLASH -DPUYA_SUPPORT=1 -fno-strict-aliasing - -I$PROJECT_DIR/include + -I$PROJECT_DIR/src/include -include "ESPEasy_config.h" lib_ignore = ESP32_ping @@ -60,7 +60,7 @@ build_flags = -DNDEBUG -DCORE_POST_2_5_0 -fno-strict-aliasing -DLIBRARIES_NO_LOG=1 - -I$PROJECT_DIR/include + -I$PROJECT_DIR/src/include -include "ESPEasy_config.h" lib_ignore = ${esp82xx_defaults.lib_ignore} @@ -235,7 +235,7 @@ platform_packages = framework-arduinoespressif32 @ https://github.com/ build_flags = -DESP32_STAGE -DMUSTFIX_CLIENT_TIMEOUT_IN_SECONDS -DLIBRARIES_NO_LOG=1 - -I$PROJECT_DIR/include + -I$PROJECT_DIR/src/include -include "sdkconfig.h" -include "ESPEasy_config.h" @@ -245,6 +245,6 @@ platform_packages = build_flags = -DESP32_STAGE -DMUSTFIX_CLIENT_TIMEOUT_IN_SECONDS -DLIBRARIES_NO_LOG=1 - -I$PROJECT_DIR/include + -I$PROJECT_DIR/src/include -include "sdkconfig.h" -include "ESPEasy_config.h" diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index 713d8ff30..ec7836ff4 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -16,7 +16,7 @@ #include // User configuration -#include "../include/ESPEasy_config.h" +#include "include/ESPEasy_config.h" #include "./src/CustomBuild/ESPEasyDefaults.h" diff --git a/src/_Plugin_Helper.h b/src/_Plugin_Helper.h index 0621b8c21..da3c127f1 100644 --- a/src/_Plugin_Helper.h +++ b/src/_Plugin_Helper.h @@ -3,7 +3,7 @@ #include -#include "../../include/ESPEasy_config.h" +#include "include/ESPEasy_config.h" #include "src/CustomBuild/ESPEasyLimits.h" diff --git a/include/ESPEasy_config.h b/src/include/ESPEasy_config.h similarity index 87% rename from include/ESPEasy_config.h rename to src/include/ESPEasy_config.h index f384cfde9..d2c0f7666 100644 --- a/include/ESPEasy_config.h +++ b/src/include/ESPEasy_config.h @@ -91,17 +91,17 @@ #ifdef USE_CUSTOM_H // make the compiler show a warning to confirm that this file is inlcuded //#warning "**** Using Settings from Custom.h File ***" - #include "../src/Custom.h" + #include "../Custom.h" #endif // Check if any deprecated '#define ' (Custom.h) or '-D' (pre_custom_esp82xx.py/pre_custom_esp32.py) are used -#include "../src/src/CustomBuild/check_defines_custom.h" // Check for replaced #define variables, see https://github.com/letscontrolit/ESPEasy/pull/4153 +#include "../src/CustomBuild/check_defines_custom.h" // Check for replaced #define variables, see https://github.com/letscontrolit/ESPEasy/pull/4153 // Include custom first, then build info. (one may want to set BUILD_GIT for example) -#include "../src/src/CustomBuild/ESPEasy_buildinfo.h" -#include "../src/src/CustomBuild/ESPEasyLimits.h" -#include "../src/src/CustomBuild/define_plugin_sets.h" +#include "../src/CustomBuild/ESPEasy_buildinfo.h" +#include "../src/CustomBuild/ESPEasyLimits.h" +#include "../src/CustomBuild/define_plugin_sets.h" #endif // ifdef __cplusplus diff --git a/src/src/CustomBuild/ESPEasyLimits.h b/src/src/CustomBuild/ESPEasyLimits.h index 963b14713..64bf0fdeb 100644 --- a/src/src/CustomBuild/ESPEasyLimits.h +++ b/src/src/CustomBuild/ESPEasyLimits.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_ESPEASY_LIMITS_H #define CUSTOMBUILD_ESPEASY_LIMITS_H -#include "../../../include/ESPEasy_config.h" +#include "../../include/ESPEasy_config.h" // *********************************************************************** // * These limits have direct impact on the settings files diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 5e8cc970b..919a0ed40 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1,7 +1,7 @@ #ifndef CUSTOMBUILD_DEFINE_PLUGIN_SETS_H #define CUSTOMBUILD_DEFINE_PLUGIN_SETS_H -#include "../../../include/ESPEasy_config.h" +#include "../../include/ESPEasy_config.h" /* ################################################# From 20f09d5fdba11fffa6d2a2aea9ba0333efe7a3a9 Mon Sep 17 00:00:00 2001 From: stefan Date: Mon, 22 Aug 2022 19:24:11 +0200 Subject: [PATCH 31/32] [ArduinoIDE] Make it compile again Some small changes to make it compile again on Arduino IDE for esp8266 as well as esp32. --- lib/ccronexpr/library.properties | 2 ++ src/_P001_Switch.ino | 35 +++++++++++----------- src/src/DataStructs/WiFi_AP_Candidate.cpp | 8 +++-- src/src/Helpers/Hardware.cpp | 7 +++++ src/src/Helpers/StringGenerator_System.cpp | 1 + src/src/Helpers/SystemVariables.cpp | 8 +++++ src/src/Helpers/WiFi_AP_CandidatesList.cpp | 7 +++++ src/src/WebServer/DownloadPage.cpp | 2 +- src/src/WebServer/HTML_wrappers.cpp | 1 + 9 files changed, 50 insertions(+), 21 deletions(-) diff --git a/lib/ccronexpr/library.properties b/lib/ccronexpr/library.properties index 413205dc2..ac3a250a4 100644 --- a/lib/ccronexpr/library.properties +++ b/lib/ccronexpr/library.properties @@ -4,3 +4,5 @@ sentence=Cron expression parsing in ANSI C paragraph= url=https://github.com/staticlibs/ccronexpr architectures=esp8266,esp32,esp32s2 +author= +maintainer= diff --git a/src/_P001_Switch.ino b/src/_P001_Switch.ino index c0f48a74d..e47dc5b52 100644 --- a/src/_P001_Switch.ino +++ b/src/_P001_Switch.ino @@ -60,6 +60,23 @@ # define P001_LP_MIN_INT PCONFIG_FLOAT(2) # define P001_SAFE_BTN PCONFIG_FLOAT(3) +// TD-er: Needed to fix a mistake in earlier fixes. +uint8_t P001_getSwitchType(struct EventStruct *event) { + uint8_t choice = PCONFIG(0); + + switch (choice) { + case 2: // Old implementation for Dimmer + case PLUGIN_001_TYPE_DIMMER: + choice = PLUGIN_001_TYPE_DIMMER; + break; + case 1: // Old implementation for switch + case PLUGIN_001_TYPE_SWITCH: + default: + choice = PLUGIN_001_TYPE_SWITCH; + break; + } + return choice; +} boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) { @@ -715,22 +732,4 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) return success; } -// TD-er: Needed to fix a mistake in earlier fixes. -uint8_t P001_getSwitchType(struct EventStruct *event) { - uint8_t choice = PCONFIG(0); - - switch (choice) { - case 2: // Old implementation for Dimmer - case PLUGIN_001_TYPE_DIMMER: - choice = PLUGIN_001_TYPE_DIMMER; - break; - case 1: // Old implementation for switch - case PLUGIN_001_TYPE_SWITCH: - default: - choice = PLUGIN_001_TYPE_SWITCH; - break; - } - return choice; -} - #endif // USES_P001 diff --git a/src/src/DataStructs/WiFi_AP_Candidate.cpp b/src/src/DataStructs/WiFi_AP_Candidate.cpp index 30caedb09..c46408bcb 100644 --- a/src/src/DataStructs/WiFi_AP_Candidate.cpp +++ b/src/src/DataStructs/WiFi_AP_Candidate.cpp @@ -9,8 +9,12 @@ #include "../Helpers/StringGenerator_WiFi.h" #include "../../ESPEasy_common.h" - - +#if defined(ESP8266) + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include +#endif // if defined(ESP32) #define WIFI_AP_CANDIDATE_MAX_AGE 300000 // 5 minutes in msec diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 30d263caf..c4fa6f72c 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -19,6 +19,13 @@ #include "../Helpers/StringConverter.h" +#if defined(ESP8266) + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include +#endif // if defined(ESP32) + // #include "../../ESPEasy-Globals.h" #ifdef ESP32 diff --git a/src/src/Helpers/StringGenerator_System.cpp b/src/src/Helpers/StringGenerator_System.cpp index 4b97a3667..cea5fb7cb 100644 --- a/src/src/Helpers/StringGenerator_System.cpp +++ b/src/src/Helpers/StringGenerator_System.cpp @@ -1,4 +1,5 @@ #include "../Helpers/StringGenerator_System.h" +#include "../Helpers/ESPEasy_time_calc.h" /*********************************************************************************************\ diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 73293653d..083db4228 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -31,6 +31,14 @@ #include "../Helpers/StringProvider.h" +#if defined(ESP8266) + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include +#endif // if defined(ESP32) + + String getReplacementString(const String& format, String& s) { int startpos = s.indexOf(format); int endpos = s.indexOf('%', startpos + 1); diff --git a/src/src/Helpers/WiFi_AP_CandidatesList.cpp b/src/src/Helpers/WiFi_AP_CandidatesList.cpp index 7f2293ee5..c5642383a 100644 --- a/src/src/Helpers/WiFi_AP_CandidatesList.cpp +++ b/src/src/Helpers/WiFi_AP_CandidatesList.cpp @@ -7,6 +7,13 @@ #include "../Helpers/Misc.h" +#if defined(ESP8266) + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include +#endif // if defined(ESP32) + #define WIFI_CUSTOM_DEPLOYMENT_KEY_INDEX 3 #define WIFI_CUSTOM_SUPPORT_KEY_INDEX 4 #define WIFI_CREDENTIALS_FALLBACK_SSID_INDEX 5 diff --git a/src/src/WebServer/DownloadPage.cpp b/src/src/WebServer/DownloadPage.cpp index 914a4d8ae..509d16448 100644 --- a/src/src/WebServer/DownloadPage.cpp +++ b/src/src/WebServer/DownloadPage.cpp @@ -2,7 +2,7 @@ #ifdef WEBSERVER_DOWNLOAD -//#include "../WebServer/ESPEasy_WebServer.h" +#include "../WebServer/ESPEasy_WebServer.h" #include "../Globals/ESPEasy_time.h" #include "../Globals/Settings.h" #include "../Helpers/ESPEasy_Storage.h" diff --git a/src/src/WebServer/HTML_wrappers.cpp b/src/src/WebServer/HTML_wrappers.cpp index 6db6b7d3a..499f8540b 100644 --- a/src/src/WebServer/HTML_wrappers.cpp +++ b/src/src/WebServer/HTML_wrappers.cpp @@ -6,6 +6,7 @@ #include "../Helpers/StringConverter.h" +#include "..//Globals/Settings.h" // ******************************************************************************** // HTML string re-use to keep the executable smaller From 3516ae4aef9681cfe49aec52e57bc00b2267f8be Mon Sep 17 00:00:00 2001 From: stefan Date: Mon, 22 Aug 2022 20:31:00 +0200 Subject: [PATCH 32/32] [ArduinoIDE] make it build agian - Fix typo --- src/src/WebServer/HTML_wrappers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/WebServer/HTML_wrappers.cpp b/src/src/WebServer/HTML_wrappers.cpp index 499f8540b..f72281e60 100644 --- a/src/src/WebServer/HTML_wrappers.cpp +++ b/src/src/WebServer/HTML_wrappers.cpp @@ -6,7 +6,7 @@ #include "../Helpers/StringConverter.h" -#include "..//Globals/Settings.h" +#include "../Globals/Settings.h" // ******************************************************************************** // HTML string re-use to keep the executable smaller

w*3YTlAE zb>Zg8thxSzcUPPfM0&EMDVYiAr!>-GrA}L7xhG~<&R*+gRF;v&`rg==>zGnWlYV0x zLk+6js#3YDW5S-#i}-I|t$b#@awbjnbkQwtuwirkAa^>#Db4@SGYfJ1#OQS9YPvK> zI)6sCx6MGT@yAc=Z3LDS-pFr77Y{v6CmWmc*rOR@BC4*d4AUbw}VecE`V8=Yz_x+=ll6_UYiu#0<$X zkcfixXAJa)m)ql4X=0-{GpiwpbY#v0d!UhKVj;Ga%HQKR zrj#z+yjK#(S+>8V1lg_W=rVsxq-0axIZaA2wk}anyR=tk&+W|ftgTrzM`y$}h>*(` zIR=hzxKN^9IyK5XTLxGxG2Yum+)_Lt2=ThD>3KsF*620J7kfWzk}ALVP|P!ev@Tjg zr>W|-{OJxyxXe1-0!41Wdy~@FOE?2~^1<^`6p%WSw=iUcDG;f}C!o+yH@%2&!n?BF znHB6gcKLr~t72K-e`ra60f!YWa?z$#6+F24y0(iCBGT~qSXzgcIwzb8aEmS^BEmXY zO@k5b1W4ApzKd{B)5VCi1tJ8wS!XfiQ~U2W1Qu($u2RqG=#I{b&1AXL(#K1fnog;W ze+<`*m550K=GqB9EjnW&Igkr%WS%nVZxy057iT-=D+1d6Oq^Dlu#3&UsZJ6WQcnv) z6cH4(S_B0n@auqanrLK~y!OEsWYt*gusPFM^seoTb^D&PRmA9L0$`cBQ(}SJMf0E^ zhz|pjNr2b9DY%4A{K_RL&Dk?xR`&H{6?Np*OFB|iMQ36~RQ(k-umE|k4v280L!9bX zulhhRotelEmDm$E)>Jr?Mk^I{a1kL9cOus2^H5n$y*K{3SA0m8lrz6wfY~Go=zczi zti6Cx0S+PkCLmjG?goxu=ryiQGnscfe3m@$gLCz9rFL|)*4A>dNkS9JvVF$3LqPoR z9)Pn~A#!_lc0h57)_+}HG^y#ER)|y*gLhIhU-)A`qfZ>}u|r4wyG^P|hu_ArBR-xb;lhN9$S4T<=Wl&5D-63Rn-fNSQ}mjyUM3`!D0#a-Q{ z>LkIqF-SEjP^$tKPy!T%I#c?~!E8p| z0V;8#tXa+buBNaV{4!A5BG#NCLaQyzKxMAvh0vdM?xM1t?%=lTy7JG?OKZ$=6zEE5 zWP?bofi=+xq1dJxK@ARS1{_j?$z>}m|5Bo-BvxhrQh;AKM0TAJ(tyl8UuVK&y#ZYi zz-x2Ki5b|?Dz0k{^gGCdnOnLZghJKH2S)cI{zF@?&B9Lo30aaibQ3huOK<=)S}v{$ z*Zg|LZjm+r)v@ikn5&1Jm?ow#6l-TJOT&u!c30^wBH|T zYw%DA#VEHbZGa_O^n4ngp-D@hV9EBptogLm@KMBW4}Z96YAy?JPi$r`53-O;YUf+3 zxnLD~ug|i;VFyVY3~l9)KG|>!DRKBdXkhywc(_!LvXB^h-cp9JmwEq31WVE+QAwOr8PrlJfNjovp7kNCJQAMR7$iXzeryv`<|dNG*nt^ z(i!(L3@VE~Y)}A+k2D>Yox~TAW-qIx%)Y#PqxQz4BkyB9>bb+gy4i_9-ITkBcOk+c zOi#)Ja>lr=km}t0EiqZpn#w6{X6~znz<}q_xbN#v=le<5Psx2a?$dAZ^ZQe%}&z{m zUbpW`cdP|7wLRmfy2IXnUdNwvB4cgh^qMyi0~4;PlQm7cCl9xCO-UT^@CtF3`QG)> zcP$4%+6+$VwSUT3NxDhUE&-%RoVVpRVD`SzDt{*SZq3YI$HLXibx2lW$CUQ6RiVF)8$JYC@&_D~eNR*8|!s*1jKO4lAJYDS{k#aQ^T!buo7w;6!D0-)x zoF7zmn6jpW@PuU#cGD~PeYELF;BoRJhNu)CV=>&4ic*v5;bOzdZLO zJlkalOE3rm4K7WA*iPqm?mY3kNd7+P1rX4bmXK!Mf{!=QvuHszuAkJ+1cf$?U}xD$ zO`Fc8vw`l;bWsDtRwR!ZcQ}Jdb5c&@V_^gA47RB56N}*`3yMI^9e|})2+KOo&5r4k z#%!hL&19KAaZ<6fe4n~IejdmxJ3){ElDh^CgH}6tZwF757teUoX0%2o+^KME!G}vd z0gE#9C~G8>yT{rG3V*M(km8~J>U#C2&|fOka^hBrwzpV`OQsdn9IOEpC}I*NB;U`c zh510I$DduUrT;oK2b^(&f`_-YGPumPMj~S-uwp(<2>rlFgDVv=FULGB09F@@1h6A0 zWs4QL40$NKYCbbI`Nos0KH)_03YY7cSUCAjKqOi759Io8$l%aCiUYF3BPBtO?qcT) zcR6cf9JSN6Pl_>ZXn-=WJp#m2aYxCbovbE06(z68hMDsPP zwt0SUqxrksU-&AR&NmyXIr#W$*CMK4y$bo=ta-lr)uDipsKzWUVriWkMS+xr6PfyXt_p*Yn)9!n(u?pR5gi>}KT^NbJ|HMk6DlQ21u zaz)4(#Mfo;r#h;)Itoaw-S7G4P9upzZl+_TsY+7?Q93gj0euCF{N~f&v-L&J&;D8< zc|`}+U(7?nkziZbn7MM;A#f01t{t_&IjA1qe(mpqh6m5!)t@U!<&V`pLt;FT|KDc{ zn0Nj|iz}oPDkOHe*UyB_zgMdoTo_1c9i5%xk|V-EA9NExMCJ-Zy_LZa8pwws5NVI7 zZyCfsZlh+YyKZCCj~UA_Gp}Q~Y!)NRLN3|qq?blP^z{E0My|h7Lf!*4f$s1CM~c5` zZwsxBFqjf;_AXBuprw2Srf}o=@c8Zfwv6`tnNW%VbV{2=n<;!i8vxKCte@@!2@fhP8kCHQme)kPWV z9t5DPVR108(|pKI1Bj3W(t36Sts`6$Qkqf8+E!^@7jV6L9YyUnz?`SaTy+*Ic)66f z1%!P&I2CfWt5S|CZM1S0g-Sy5UvcAHFyoK^(`Uui#W=Yb_PwpE27jDcRoIzH>;<0Q z)LKy|Ws=GBX}tr#K{V%vVXkXo;z>eIbgnSbo7(~5b}qprX;Y?V}qJHReM zEI6~9ewWL{!iowXAD)R0RQCH}ZtR%rjA~idzjcrj__@B{^qJ0(Seaq((S1hve%lUm zfn*g$k!cQ40}7P~MSwyq3MF{{kFai#D+Om|aL)mW7dUV#c^7Td95hYUc?U4??D@w zxvL@FVUh!v4!s02wEvDue6?p8_+y8yBYWo4DjCDsGgYBfd-cLs`BRHqWgoNeYl|;8 z`n6uGO*zemo`9nML!;^9piik`&BuFe81SQAjoV!2V&)!rw3hg)A!i;T++=F= zb42T%hljv*ko7Cd;tulB39{VpMp+l1|4w$k{~T#g$%$1;U^TkDaBafDy{tE{@c1iW zLC>$m4le3xPkGPj=q&-B<__IGPQf?lWdaq=dU;@XNN8QL`33c6MQ zQmT^;1$pL_?$SP7ZtjNb#5U5nNk6W<%g(wj&Ma^+LrIX|G*nmQMmu!Rd03;cddtW+ z9-+>sS+I5=;LtOGtNhtJfKW=2+1f0_nSoahw{ks&Q#u_H`k2?l`7{cCg~Efl0)cI< z6>yA!rR9!*qg&$Nadg`M;>h1>Zk4wsFt}j&p`m(#)^J4`A=L6%^CWq)jnDhUH1ore zABh7sn>(0K<4|8X5^gix5F{IBQN>}W$>I-hXDu1$l^RZs%(&CUfXj6MFheQU&tJG6 z{;rSF3RgEVN^8y4mda=R(t9GA0m^x20a1|04}n<>pK3DS9@3XTUR{a_&Ze|;Yqh|wBg{G$@+Fn zeDUvFzbkwf%Zw3qma-{M3R^y-Q3SOP^)UH>!>moSzsY-?7R1oc2t zAdcrz1Q3;75fHJENg>{5&0u783bVCS;5nOk?v@bfW+lb(t_abHv?@oveEcP42Macv zWs641`8YVvxy>0jW<>!o_;;ex-_wnn_D)?%?=*k@zefW#P(%UX&)5R`xhG=Zd86e( zD##4J$#DVYLUTfMfog+DrX&&J4;|V<_Fel#!Xb~KA_N*-uk5Vo0X@+4F_J~43{DZX z`yX0l_Mb4STfyj8%vz1mPgl{-f?Ll>hE6 z#YJlnQ+^WRU|6ilS&#{CKNoM zuKcUi}eK~RH4?1|_vNMbVA&5+cpBTgp0{bx6kMmw}b}!_iB$EWUx{q4{ zxpQ3g0zuOtl@4SLd|N-^4+u|4EvHDICX3juh(=-j@HZ7&LFiX$uG5s&!zb+JA{6T^ zPnQ`)DMcU7osylU_qbTjghW4F=2>_!s0(C5s=*2Y!{lTzJ?vuwF83dyhRherR-4}| zq=K8*klHgty~JO>b@A;y*f7^HJSg^I7PAMWulLf07|$vyn&pU#e~OnOK^g@>q|FIl z`UZdO?#)9N$mo|X-2QWPR#4ir`Fjr1!+y+rJ=jt3Dr`)y@Gzy0v7sRKz4jNY zR|6r~+*%B+f}0z`m*-bq27_@ByKvEpxE1ci7Qd!WH9!-L;+3c5>i#JLo-5GL5 zDzti4UP@G$K@O>d#OC?#bEWZoTt)ad^B$cLZSEnp>fV${=96^cq#s( z{DhEmW8ECRZ=5*j4m4i(=R35Ia`Z%xODKomxJjr#Pez#uE4QxtsNVd@hdc+f%l;z) zg!6A)!Lv8`^HXB77|&-gtxME0H(W&Z1*8N$$(9Nd-|eA)#dGu%K@RVZ-c+ko0~y+C z-Q4UnEG%MAB*l9`{R>-!7IV$eN7d;VVFkpdhaY@0Q&oo=SQi3njIe_@1rBF|2wh*?<8(X`+ORVA zw0)>5U~`36od{hyQQ;IT61fDa{&{M45odEg`|VBVm~R}%;?AjizM1$kP_P{PWr|@Z zhEy;zSFHxiNac#Y+q3XCtTvjJ3tdKEbxM&Vu-x|1fA-AYUBa#YP)1}HC3_!TSklre z6z&vBqXII$uFZ4UVl~PnF$v_PudhSuab-JeLe#rh1+>>*q(*y2{58;e#U&`Na1_o} zT4ThnXyhD}t%KtQOiia1p5c8+QBNi<7iwT$8-~s9 znHzm$N%P_LUb4s%{o=OWE%k%2^Y)fsOSdazuV8CUmBDiQjZ^`&(0FF?Ov>7JLizJH z2NO|&@}YTH`2gk`ihn09-Y}_KY~-fAnahyIPmdX&KRHvo$}2ry5TWl}>YEbF2#+2! zmXwtD+|&fs_>Cm*z_(Xzv5Qt)F1ql~#g4iDo$07Vu6LeMeiXlRN`!w*a(zQo=^ujk zan0Y5sZQr=0MQQv^grZI)SwuX0dkEr^S#K_m~U@I#A5$n>{38>xWapnSD1OcQ?(K*xZQ7wLyEpV^$_-##kvWbDiIVTmHg?M% z^Dh{PFcy~&bFyz`iW#_E=ypA73?B zy3)(1$gBbAVm!>yDvYqah*2yl4D&KR?zm`1;Or{Po3YA<*{WQmA*6|5}o^kxvv-1ARXrce4NYXuv)$ zvhRJVdc7U7h1T2+(@d0-e2_*36sjdyq@1?Se#$LU>PV!KAHf?GAhp%$_~?xmO7lq} zLKme6)7&jfvUXsbw`pqQ>6{F8W-bs1?-}I!rXY0T!AWlxy2z^UhFQlkUK^1n``SGP zYC8zb$9;$Nt}a8(8bcgwQ~auphqzK1E3QI`8|eL5kZQ(`PY zUcE8k7r`XH2FCMJ;2i?2wUsr+nl(R-hCBD7Osf6&ZgMdgX%dMN5M>mITGGtCqrMJD1hW9YzPT`Av|Pvph=CcxxrMS<;MB! z*EECTw>Wa9wsh*Th!M=noko|(m^y`d@J@K}^9Ep0?6m0$8LlOk1jRhPSP-T>r}7PV zO3DgLF}3C>`+OBzygV90)umUBl0&vaz!b-V)yu|!wv+dU!={BLd#Wv`*s_SuW2LUN zhj!|L954?J=kLtKi3XE&ES#}M=(e{kur?P!2$-!gXgY>{-n?3uiI$d~fYX}BQ<>0iH3mAciHcdwtUfA+VaVY-ZBo2icdyee9f()tDNcSVXm z42Te=rJ)qz*UQWG=PZH6onN`$(4vJjGN9f6KFmdC?|O#;CB#hfwZ*d`2UnJ*R)`v9 z7IeynS>=-S)AGT3b7DI~xKiIJ)yzsr6Wzs`CR`8^0t21q>})^xb@>lX0RUQ-q@CzB zUNKTsNCE$;I7u{->_8Y!%jNM8T%;(F{yY!i>*rf*1Ui4>9!3=X5=b5vlOnXfO`=|M zG$UXl_k7ah-H(bD{JuXnfUz!v`&Zxb3?Q$F2;-eMee9qg#(XUVdL{R{0SnA2JUL%& zrQ{~pjEb6WWuW|UGJvs(%on-2-I(i zkCk4o$rjCJ2`HzXLLA2`8}~0CmkcC&@|G^|KCG=P>8lii*|S(BRWO*OuImgR0VuKK zc32OveFzsry+Z=IA2h~n@xq$1T51$A^y1Zvg>l16Nf#DP^TYD%!wXj=FHmEK z7LxQj)X*5fmWQM{AG7};h?+V~f1NYn?awzfDgj|zQS5F3L?hyr4i9>+f+D@%i=A{9 zC_=>ewjrEis5e@qzRlTS*U1lY#NlT5VCwLd0PNvqnxfGRgDuoqWi6OH&Kg&v=YhGI z`fw{%?qbGev;cj@2buqGj0ppSka9b{Yx5=`A{mCGj(5i(f@Vp%itX{1S(R;vmiGPp zmaIYbVZpF73qF)1eEUy6=h-QW48q~c8!?(qVp#Q=4L31%b?pN{iDag4J82enObd?I z(MGuI%RnEyo7a0OfuHqFh&^BY!JnWY$%6NZ2cG)~( z^T5ReNr0ai7xq5Hm2lz%fBdv?){9^vT?&G8-evbf^4@P*mHk^Xs|PQwQ&dx zQ>nuaWQ98&Q@6$eg#4T$pbN1cQO`2@{_Q{%Uq$St?qlV9+8a~!wVwA#6F3$`ISlO3 zi;Xgd5&UuX`4|I961ml!+i!8ZBx_TSLbsG4h07>VgCo|G9j`xBHi}+haDsWjj0xgkz;%b{F zyFT%~Elq>z+>A|b*?1%7irui8N1+k2fsnorC_%UhBJZ(0&;VXGV1aQS2r9OiDrHXd zO%(DGc(?1U#a+z(K0z+Pe3Z;;&KPJxX znbiNuOc)+jG0H=y@_3v0<_EdyUi+`kT&1y=z%M(XSb7GeI$&T$M(lRRSuF%gSDQGJ z8+{E;SKxe?4_;HOs|nd@TL$9~m2x4_qk8wBZRzc1mq=9$S9-%Q8(tNuw-2R)Ha(z+SPBXndw^ z*qUaKWlv;C9nD!_a~ipYojo-xtjb%>N00u3i5KVX!Sk+ zK%o}HnxXWh$ef)v8On7>;Qa}^;$AhzbpAS+griL9w*M$o_y;{zI!Vv17??`je87!t zVZpTDT!Oh!Dq%Tg=sWYW9P4hp`~LL!8;_@mzR8r~-X?;fAXQtKX7qOr1yCkw?w3v_ za_PadD_fS|*wO?cR%ReznPeS8?VJ2WrvRadOAJ{5GU?F1zrK7S>iOiUuB5%bR|-+JKVC^wwmRE=o1U8Op)?r3x5l3>8rYcPIS0P! zk%D77&}wbTn-B6CPM{4UE>OqcBdHTM<2Zy?M+3>{x?JH`LputUtm&mDQ%~suUcvTM z5A{DUQXo>ePaz>dQmANXFby)~flYmZ!HD2~Of7smq-!{Rx3!<(6>Fw_i2W}){C`TL zb7()6#E#6kvv^t>*=Jaux&?TOW9HT%d&xKsGXr)Em@!`$n| z$^X#S;AE-jl6p&3V@3!Z&jz3C>rLj%N(E=O6_CzH6Rh@)G~2HEn)go( z&krH&R;8R66N9nt^yYL;nVVO>NLS{We}A%nE8NX+244FLou4EvGn>oO1~)TuDqFnK zjR8ij=|c^KJqapLH1(3S#y{xu^ih^ShD@A3hIGF8sQdbro{o^t zAT{UcEKukSMT4&X`jjfyecJc_|I18isXmSG{YzYoqb(H$G5e(>yUtRkA`BXS56u)s zE+xiwsd05qxgQH5k|ukLzgDH}Xk+Mf_v~S;Ew7iay&3Y22?>hB8&RG+C(5%uD_O_J zOM2N+$LM{aOyjvGX_)}STJq;$UJ3mJ4f@prS?z~)q8-(a0bxS}es zJeW#wk;Ab}IiEG$O3A6IyrXUHPh#bAeqr`e_wnp(VAQY{+jJ*{^91ufK4_9;bK5;ch+mh#=rD8%l5kIszzM0*?S->6iTIFoCyl&H z#H0;w=8wE6-}sRlv2zlTuubWB-}uf@Nt+CsqGP6AT!rq^H4Q0}Vz2M2(3PUt51fN`uD3v9YG$INA3Nmx!0S?;qa;}x z2*luc^&nHfcr1n9iI^xUzi$PuY}*Vyl2(=U{IdxLv$JWc`F@duh=Dodk}!#c$7n?A z-)A8;w#dSPrAwed61Xae^r{@xIdJ6hQu4BMHt-I#gU+B!msF{{mWfVw{h-_|xPd5g(*)IKZpg&@i$eV!n+W5 z4dR2ilfQLT%2~>NGMtYEFUp_^kCM9^4aSeTvmYO%$~^daB94_QrB5Q@7BMKB9Y&qO zHQe9qVkTi!9EGyMz0*DUu&w-nA1Fik`}DDPhUk}9d8t`8Cnhp{DFgl&(I3^lm)Ih! zD6R+zH9W*d?xwUSIknRg7ZI#RUpQwyB3kzX1IRmCwW?e`D2br$rG?*2n@Z! z?+u{cxeozPcPk8SHvnMNDPBC+{!2QkX{7~=4$p0@ABSS}-6vyR7BC%%MVM>ioI{~g zoT@dVrakm%{vTIQmOzqTkvL(f1w z<@cjWYWd9QS?V2>A>`(SO%tgIPxu44=hh0);em*&AqGZg z5rhgQ(N}!kdy>0C9Iu$3;VppW%D+%CL4Gx9!kBkJhuG9Su=iHP8#w?p?DVI3KI?WqZ4*x{au7 z{&XI0x!!vIQa&$+0Y1ufVti6Q<+<2Eu$(^4nZG-qrlj)vxve}U*{HR9L4HN4 zjMuHQf+tX(+Qt}nsP&RRP3M{|lqHPzZ1k8GcKWs{#iVSun-cq?E0M{*+TC8?Mraj` z8u>ONd?vrUptl2917WlS`7%#zmAhy$*WJ}nd_*k^3bd1?bjqEpSjCSv_H9I(piCp5 zv!x7{y^A^~Lx~c)Meq==Ph+ux-U+!{9;VnREd##VME$k?@sNnC_W3W*GkHtqdB!>t z4)AE>e{iOJOKq}$t)cXntGpes{#ZF}il`hQ!S0Bm%eNHHud>-&@dV>AI;#`q`1iv` zU8+J2CJvEuu)B9ttZ|ndSg&4FVL~x)p}D_gD3SEedS^Sci&bZtBh^zNDH ztMZQ4dc!y(3t&LGt=wCH~JmcnntXotr#nWo_f zYCrb??mp0JIEBQ{G?%2!G1{=ws7o`-Yq=F?kIgXO9FHtjZ3TiJe?2i94guTy5$%nU zz{9E5wgqNao(wCGh&^SL!(8=S;~O0ulroPV#uN3Vd1L{f@C`dYQWQ z>e?3aXP9BjrzRz(tASdO3KmHL>t@*>1*n2er#UGq7@!Y`)E7UK62_cQed;(8O-;FN zKtC~=brN}-=_kKK3s3eOc~|BGu}#xgDOxGl2o4r|(vx7!%hvy5?3HEwIas~9OQj<8 z83P)|dSbxBaxjA~W@p7m+B6kZ&`Emug~bB1#c2YzE!7{(GTJ;3)$7{rJ_~fL{9Hs!kz9P!Qz3RTilcCyu+m<`N4==@Umt3TiuT>;Pl zryynBRIdkd5DxZaEdd~MJTdTr+3&bUT@NjOX8Q|iE12G&%=27$qLX&o>cWOC z)?QC|AXwghF0sb=F+(<_L&J6X=Qx^pBDd(x6Mi5%>^90K(P8OsJdAnfO0uv506Q(4 z&+vunLwCEo-c4+KNkzvqZ#x zWBFG}4ZK0w0{#_|)|rD;YXI3rKf7ZsFWHJX6@K>H` z0NVjWH{Iuh?@iH+R~md$FdVKk>r=xVVrND{$o&mw-z#Q`T_!XraICi&9-MJm(4$%F z)4Jm0Agv!!V5Uc;=qcBF1uu zKGb!vZK*0w7TKgS0l4O>>dL0UZI!ZRA%7BaQ%qrGNVZ^bF;#C&bL$qipd2AG9yde3rN@Ny3lw{HjFJXSHDX)>N?Yoz2$O%PGOlYsnxG7xOXr*DdinRBb-bNl9>SZX-Z9dyM{-tq8eQ zN%u0XE?QD+v9IAR9y=ckSlF@ve3d7T=ac;FR(lvc#Ed3+$QY(uM;uQaDL2ZhIo;R_ zo*};M;%~aXwVdYVHzMH_qL9YZpfVCvjynpYcc(`ktkT68%VYvawQ7}+qY)-^kUgtA zQ)`&CnFyHVxyp{ds>xCHXFe<-@J|Ec0Zco`) zasL2jy1$2Z?w%EjR~a)q$VvBOS{j9?ngncv1pKwNY0KL^Oleb#qK^mH{uF6b%t1!@{{Vp6J?Ebx)7LBr`@O5`ZBN6-Rv<#WgIuqOJS@@M%P_Rg0mvQe2YHun zN3r?Ws(#6S9G6z{7O0j}Bgu3WY?X%GC-|P7E5kl6e$BUb*7I0cT-`@%jtu247;ZbV zJL4U5U#8IfHAyUQu3FR4zC3E zx?=+rySO;O9{uahE+Eux{6lr8J(PsOg=IfXjOX&N7HYLOsqEAC6;_AHo)7pJsrcXG zzl>}yb-Sj6O}d0chGrn{1pMB;IQmqcD)nJqN$Nb-p+7{gw8RW`^G@ES_HM=L0p@JZ)-oO8pn)aYqG0blYpI z{LhPgRpG5`!R~_o^cdvFmnO^)&!6z9Vz==-#~Zz?GDz7+Mb3Nr*VKMD_&EllrrP;d zjh2`ze4VqJ!SP4KcG6*j7&O+}0Lqo+KAybSR5K5E-bWnr=Xc7_5Q9*b)*ZL7$sC-5 zvZ)6jr}-5h_Pn#)Z&?A_*!A zEwkjyBQSWw9-TdZ3ha&|5=RuU^NE_8tgRx5Q5A^+zECs%PAf_cW=o4=&kM4kI1SS| z#(4g|m6KuOZwlysCb5&onkk!1`%*RPM>E9D9!69ZJY;eHb6=>R1Ha&zKk!aZ+E2r_ zx~GFaA^4|7ySR-X>}{=Ex?^a{t2{00I{vk%wt=6rk@=OWK@@D8)JiyJ+D-{&&fl*j z9CzoXV%=ZPjV_##`8baDS`y+q<00#4Z&hp-?T6}2ngm5xtS?+Au9C|Q- zagNpFf3*+%5_|Rx{hE9md*V+X{?L9Yy1ZLwHnx_}W&6fZNK#BBb@U&VUq3d$=}m5a zX=tgcYEv?$)P^3CamF#uJx(jG(;~C6geA0lc7VKhKEIwTA{|r0@U*|!x_t6M8~*L2 zl>Ev#Ex^Y({c82q+)&&^mfCnea*}-68!N!$x8p*bP`M;@7INS#jFlskf$h?vyS$xW zauQdNMmkqNW8+KfZy2tJKA#VlCAf436Or6Ee&2<3T5hFxa`W4%5&2VX!o{?ZKqLI| z`c*oq4lr_MMbz~LZ<5{FK;VV-{{Z!xyJ2}Wvmu^zLd1=%K|cHs!ku-bol8tEWtZ<{ zki-%)2fz8nbvhrzyIWPXnn<5MU@O7rJdEe+Ybj!4k+d+=lQ``!Tea3aWqIJ+6LR;K z&Y@Xx|uAM3DO>Ne8b!W0v-NVlAO5_mOhLhv27nfqc}SWg)dYB~p) zS7|vTEB!NHQhYt|6`~pJ?JXIId=O*L48N6g*Tu><SJ`OX#H%566!>@wh5oFQD z?asceScW035N$r)&3gBPejNNqmg>^p&stUpLEhHN0^=Too}DYy`~&c=Ta7X}ZX?2> z!HP5^Joh#1UJv+7X>S}dwXOgo>frKP3I`%htUZQcy|Q;Hg#5sn2+8!oDGj$}ckfa0dbrlU+8Sqibn)tS*7d@I0Y` zT@H<;#Fl_GN8jbD9xw%TUfm9Nd2Db$5462r)5N;ImbWA1xhy|+Ixx;_ zxq`!4Scq%FammDEtyHqHi%j^RGKAWfR>PH5n$WpB@3IPy`DQ=DwCtio0LnK5xT{0SiP8L{=y2O#5%hovR-3r4F2p?_Oe57tj`ff#F%gZ^&kCey2}ZP z(NO%Ojy)=+H_dwrFkH5|n6~=JkzPC83}E6h{uIqiPu4FiE^M0fB3PMujCU2W6CglB zao>uQ3XjU3N2O=&T6-7l(^|8V@GI+AIwFa0PU!wpp$8b^ww?`L9a!C+*v57Wr{R+h zpRQl&KoR@)br|RypXO_F>Ti%Tp(Pj|m8EIFX}082iuQWFiVF_1vXC#2%yK?KRWJ%B^M>qDe}ylGXT_^o$PVb3p~%NWiqe_YHc7PlaZXZdZCE0cg4D^k zi(6gM{{Uz)+r|WI{uPPiOHFdtdo5sI5#`V2vw35MZ^P6I>cp|F)^@NAJBp{`duX*i z3hKo{+)$YK{vpWyYUxzvsl7DGF9YNt2{3xb)YgCU>&|sfo1whZY ztrSk`R%lUar0!XXe7My%jo9ZkB!_#fCjjRp4{GM$z_(?AkHpvOgPeem-cq=@4PIq95}{VM`5 z3;2-?tiCI{$3d3|KbZHZG<_4sgHDp|d`~FzWp)E%oPcmTk3mgSg`4JIh@DB@Cl~k~ zjA}MKq;O9e?^3{#t*COmn&lry@zi!|f8iu0itw!po_{K|H2(k{AVf`Z7z}W2g-^1N z^Do4uQe9&I01xvzE0sbL1yVA@isZaZBGi5&X!=M(!V>d11F#q$tyqyfez%F8PThj! zoZI8E_pWEdw;ngtJ|pTkLG4;gOLdG$(U1mCae!-lJu7odnP{K+7*?yzX!5;U{{S=7 zp@m*&8#q?b{vCcVG8U1N2^^Y7!2IkZ48*wGRW);ln z$)~FO&V^Phqx+7X)*}Ns8Q|7txoE#;iULk#WkdLpRAkotTCplgq}%g>^2~q2s%jo1 z@iXgocJHAfUHkB}9&icgimG&Gp6l-v>cZPUxa$_m5W|j?&$A<45!fwd9~A5H^8Opn z7x-uY0P9pR_`_8aO44|0Oo9LlC_m?|LZw%K)feq4{{TswZ)+abV8`2<#_@BlpMWbMV;9-n@6{P9Zbsn8e zp(=jOYIsMC{tKN(=@sHr$;m02@!uK#%^psxaBQqlwBVOwgRVcr`B&G=<39=Ow<2{u zP*B7MiLytpN~fsV_%8c=uXv&M6aJ~c!nvwo-A&{88dI;x?xcQH{5t)bHQx^F{yNoF z8BN!SpUW#3J3@if)E+PJhPR>VPHt_3#~WumJwN?_rGAF^SK)7h=F>H6oX4AuQfUY% zdC4Bt!hB2ppL{8)X_H9|%Z4KeV<#fGvAJbORq`XZ37ExFw3+c8z;=$wWe5)R>N)N2 zT3VNdE%lwZk8Fg5;1%T8v3yJT3!+-f4Dd>;vBPHsV;_ZZ8uhN7;hBsw>ybnPo*j+= zuO_A!6HV(DdUUZ^dW%UO9-j$V{7%9-rL*pQdGS}^exZ4zOC&a&rVM3N0UYl1KM>n|F~75Wc)VSve9oW)c7Wp``j2|4 z;!gqi6U9ClgTjCCn^+~1+%pK0{dVp-JX; z!ji?JgqqK4fwY~NJ$db0W5K$e{{V<>CTk@&ss;gE1IOk0SF}gqKZnCcnNNx|_GMPY zDRhLf^aCgSircsFzk=6Kx44H_vz4NiKt#Aq@;V=<_}72dX8IW{8t!;K-@~h$&x^Ww zI%rcqmnPLypSsN;caAI`h|58#fWcc$9QX{0Lr(d4@4k6hQ$9vb*T;aH$zx`m?_91}W`j&u9;(@ zM|uI&VH?wdym8HXe^UM28(lwB&v>^gle6pkBZcsi{{RUx zS|STz3Xo1~rqZpnD5Q}WQG=Wx^@Gy3Etg13bDc)t)DJLLs*{eEF?AfeoZ5J4;MHvB zFbuM?lldCx^xYBTxng1*jEq$JrN)aCcDE4Uz)W)u$|W7at&43#MtPN!QGjK7d4v3F z+LtQOBBI;7D`~o9iX>Sg0}azPd+cl>LXoaj!8xhzwH+7FWNl909=>R)4y~a1ETd9` zAo2Ur{xvQ#zQ(cSQL;Io65BPOjdYDfMgF-SBcA;Yb~g5{#!z(iu3zE?r=`7)ov1;m zLd|b_ncE=F4+p(;cHSV-+8EkBP7j#}K47h?#%`1yyRXE`n~JL?e$VhGwhoH%q+sK< zK4T=2BN)dFD!h8;jUCg5)L|Lt{b1&wCbgp*c0byX@IU9E?OgVq_BXt3xgFBU7Oe!# zgARpG4{(3_^`Wu+!?i{YWNSM1jL^Yz7OM_YU=QyH0E~Lo{66_ znEI)GJI4@Qp#WW5;QN(7;A^44aM%NpT+fYl%@GBTsTQRRHNDUWY=iEw!L4|FRpI7= zW*WQ%FdT^mYgQE0*5BH&0(%(; zJ?a?zUE#%y2G(HQI{x#a6`QA1v1)McHXky}#B;(iws5imk6sV*ts9n@#KAzw^saxz z9xL$mz3rx?n#4HVV{_(qJdf0VwW7W-@XO(bu?7g|_ky*ZDvc>v&NG5-T(u;VNfKNr z8B@wKygmlwPRD zoax5#Z)2ub87H18v5--i4z2mp31mpg^2R%y(9Bi=5lkFo@vciVeVGQMFWEGiW<~jm z5(l}f7WVO4>G0XFBq&xm@7}3vmnKOqbm0#ZP6GpugXTZVuQc1|jXa~rI2BLfLSGRr z!YfM}DIA)xii;;N&~*l?nV0Rn#&U_%(?9;Im2M-$F+OH8c(bAlU)%` zG$i}9zf&1CD)C*Df1%Q12tS9cq_Z9q@r zf2}opKR}aLNYF5&F(pPw^r+yqgrm8Pa_6Y03E>FG%p7$&qS4UWD+U~bbM>gzBD8Et zpp7kxswgCN#dF^gZR4ITJ5C5OHT+6Odj<#kS4VKjQDbKuupNEto$*}8kRPZ6Jd}xs%HW_ib8$@ymWSlj9jmcxvGT^-O2$RZYpw zdXrH_MX}mOj|6%xv`rWrU_p<-R2tuf>@`A`v%(6qA8OXM43I?@e(HgP?L@1aq{DVR zQ*|ZG-NTYRsTiZdT2fppM`*Z6us&Xboc^w>XH#OO8q7*NUmEY68zskT2dVv~lZLxk^iOPiF>AA&d&w=&t_$23oX0l|q(FOvjQ1GjF;-GK% zCJupRA{6lTp$i~l4WQ#6g?;;Rx9q18jEsLeb43wQWQcX=0=ZrelU;uEby}tOKQ*-v z_$H2rKkXT3tzCF>2_pXhgl$I{j$mA!GC`6*+7;0o3kSG;*2%~p!YgXnI%z{!w|_G#b?RPTzoI@ExBmcw zd3-mwwlR+bS{_abv`_G@n_t*J;kBKbd0qvy3<`o))d%#ivl~pYFtYubIL z3|pz-VwE~EfafX8c6^%u0I{EewCz_*p3}m%(WG)Xc*G0HBk5gUm-{SuI@eP({{X@< z046cVls)U{9a~Ga7gkd&N;cdKaqMd2*xQSwD-h)lO?0U^#Tas4Oz`_p+3P@wm_wmN zqqZUydrkNYp~I(bi%5lbj?jwsab*yYx0VN?sNl0-C6fa=VbZNunp=s`i+Y|T@dM!w zmuIGFm+NAR(P~iSg&oc@UA>>eog7IEiwOBc{2xl#_?rR`0n2bu69dO5i+;k7}0{QC2ouLIg3w*nlv|Un-m#Pe(0-d;4L8)m+Ue0JQS{p zffIr;%F~GC=kcz0UZ-=RQK#7CwQmJ!Lq`+GVv14J?%DyyMOtqN=@F!NUto_1ughCE zspe@j$G13*urcYHZM?pAnGA$=3UO5HRB_*^y^TBUXCDaZBIEZqsfJ(fQ{eD!kgVX? z$NvC)R zF;(;_Bx?Z_nB5sFexTy3+Ej4dpJxtjh#SLtT3jowvU0flwI}=|nqgvo%(*@G)ysnF zfz)(hDZ!X9;8Z%5ExBqC>~p>>@O_2nhOX`6wq4>P>4omRkL63@eH%;EbUS;mAr4S~ z2(E$9GO`iF4s%@p0Dxp@tuAzyKQ*Px#s{DTcTnF**RXjdhuI~2@M&>7;{+O6J|?!bmqow zrfB&+f#dYWTB$cl>#+_HRW{snczaBa=Wp2)58r6!qaGa6m6{W1m;{mX`qrJ+;EN*T zDtS4k%*?VRgB*-zlAODg;U32^XC#8F+Cd`w{rNaU}E=bhuBUR}g2WPz5)PQT<)G^%EfG65%_%lwMZ8a>>zstsP? zDyb!l_oQ7O{N1q{#N;5rB#e@J_O32i+jFV8K7+$O=ZaP!1}&}2A7aM?^aiwT-*wB7 zMiT?^>;4sop=tVqO?!R)qb^>3fv^rjkEf|MdJ8>KZJuGOINV7CV)5J3s!45qiHm#K z(6?e;)ZV1oW!hTk;hY1E#TGG)H7caO5|k+Q}|OaBG$gnu*G~gJ18VY>UpW< zP3~7Sw#Hw@E0b;Dm$Hd)*D@qu_t60V06OUGEQO7Yrko=fiZo1Tt^lqp;tYDV?}{`X z1+G>>CHI=i<$;Akl27Sfc>djcgaUYu&`JH*;p6O2E#;(Ldf@f^>zT#ubSHAu zZ5z!il;CkybR>#fdFKQDWy75PK40ljwdSh@oRax5oT(*_denL?&Zsn~kJ)1Z&^IhW z=b!6U%G4OSmom`RmN>7pJX9Z4_gC zfkt=wRBNhCs?636_qh408(mIgYnIcb3`scLJ!=ISSlgO6E^JJ8?^!-FwvF_d;2+0x z5}(DzTmI6OS3lYEecp0M_||WWb$9c0`*US4?=O?4I~@A^Rnm<8q9&xH$j#M_6etHd z>P0Zb4e&gWBlV`os2A8xl&g`P5I@G4H8dCQt!Xa^IRJY7Ydc84cEtAafpaSobAgPS z&)1@wJu2X3P|V%l8p!TCq0)~NWGS5Npx@1z#eFYYAdsPyaBsxg;3 z`4cA|MpXDn5O@m4K*a8em=fNsO>VWfn1?RkG=Ptqus$4KTUz)ZP6ioHEYqTK$gP*w zZQgypOrR?P{;c(@tfcG7rPY&5m)OVA79`Wq%@HJ>q@GPt)O1s*T!m*~6~hjC)yLJX zP0VpJ$;dqUW~3UGt2qH*f!z*kD@@kWW@d|PBznE*F2o5Jzh9QLpoQ8ax!W0RjQiC+ zCi2m>Tk@guWl!Kg-TGC?uk95I{M@lT#(4cIrlo(o@+J*i?+M`vY;z&%JJBo*z$&@x z%`CUJq7qwnIQ|1qHC@!>2(GR>X$|9pBOEB` zYnbsZ-Lm{u&}UuSMYY1V5cdNdV!E}|EXC8J?#Mt-$bIXgvX>+@>H4#tlU(!l{SdEc zn*ng}!3)j-D4NlK%W<&n~e4p^BlK#c)S+}uVHbFz%@UCQ;yRlzchDUw zu5Y-Up(k*2)1WlSBYn@8{w|c(zqLmBobo@oX|d{7rfC&f_#-1>^!ijKCRUd*J|bGR z&%@15HDi%%QOmtGvyZ1By#-c`qzdB{H1oAB3K zvzy`7gsknDpjCg6oE12(q@?iPlKj!m`Bi_HkM=Ny6osW&%4A?fQ?ZuL7f ziaAR;1;-l?dXV4Rl0NrNn+~esEpK7p|_A7Ga zvt+10>d&Q8(RC|AZfw4PmgUAgv)t#>ttoQ7I}xWcHCb4~pE>K-G~m4fb5$2owfh)Z z1D-hf4NP@AGNYH{xkFLQBJQp@#9C(x%d&M%#M8e=Oeyh_x zf6i*2oL(JH?%27&aKIDTfPbE8ZZ&&UXyw@_4~`=}>a@DWt-iXF6mlkq97c1HfBN;L zV<#4^(9TkiGW9iF7lnr7oN++fV^$I#InL^?n!TRwxN)CY%`zQI-C;2@$V#8?8jeX= zzG&RJB9Pe)`ByWgteSVk3;Q;6vgRb6IX!W-{-U>kwXFj&1R!CXxs~uM4$!^N71VuI7N?(CX7x%xrJn3o4?&Z z$W`cdt7)zGeVT4K{{UCqRzHe$yGuLWJ5~EM;3VEtpD(k2^}wwuMs7|$%;zZbsT+pb zo;Hn~`+U_K!d}iYlk^zfxko#pp@)FmWE@065^9 zNiBEXM-s?>@i`~biYhM3TAZ`O_rDophs+>Z=`SLZ$E!Bl>yjo*i8jjE017CsitVKz z@S_R~;(mXk7TyV1JBiK%bUwnJ63UUYnMuxQqPg4D=u1MLzvkQcdR9q##BeYw^mgwJ zqCm2Isue)T;YAeN_ZP4E0$%eSEKTM_h4KS#tah@Y2^dQ&1<7R__F zAvvOo#e62O^c1XxMmFaosI0FMp_9ZKJ-Y=X?GF5pL~1Cir@zVmMAZ0x@66fxi*y_c zjwQ|8jiaE+qKeII%Y6dUJT#|j{{XB#ewCNwjnVioQ)N-boS(?iMQIP?N7V{z_iU5F zR>BVl>Cl8;ETbRz=&Pl1Fgr#}-_nXGsNc4is}(f8lzkB_oL)vYjFoC~5$2zecIJvI z9>tXOcVF#YKnTbB_5T3S1zvzBmyLt(ALm6Ca`?XQ$WZt~;Z)m|C^!`CjDl2AMP|x5 zFBUpS@khg-FW!phkN61x02=ERRjwJr0hAo~qKfLR{5pT({aMdT_>=Yh5U7y{W!O5@ zQAZcqSweC1aYYr%jrx>zh~s|^Ji9>Jf&Ty^4P20?mmB$Gh6f*o6jj~w{K@J{+erkk zQB6cuyJN6&gEUc4x|GPLi5d%p*f2rQJ#s6U_&(_V0$4<25lu9CJ@D;C71d8%G`(Z` zobvwwc#os~4x(bMXdlZQZ8-dDVybqXgPJI=W^^JKNX62F7|B!5(yD366k5&fYY+sL za(=|vTB_+Oz9b?f>Tpip6W$}a?pRN5f{kaVJomQooyBDz18KKJvkPg;2N{{V|R zb;NL~`(B*!u>SycvOk>^S56mMKS%i-_?;rXSLTks5{~VNfbUV;nDHcDP{O&Qiota@ z7UOAzlNjTkwNqFt6xMf37|54t=dmCCVMP^i_?OI?Y|CENQ6an=wldf ze`+YH3$jwFu%U=^T<^r_VP6aVy`crIE@G8Fp@9BIiYn-7T0W%K{tUehn+I87hCvV; zkbf7oK1Ef!3*|4)nI}HF)IJ)D6)(k|;_eiOLW{dQ6o=qY+=>>L;1=AixVyVk+}(o&hd;mfUF+U2 z_rtw+vd*kzWzL-aoRfL>-p`)AExv66KFLT(O8{VC005Zx7vSv`An;v9TvSa_g`eEQ zlo{w?W^CA|e0R-ru33Afx{G;lD}# z_tX#Yu(0sRhzN-PGvxnM_tpi#{P=|*bJ4pEdG4CDe|2CKp zuyF7Qi0@{gybq}V^lm;Z?7PwM?-sw0_Idvv0EY?x`3t)!0+zB7B84M1hksnoM@q5k zZXA{AODaxdrvM~mTs(XNLTVaXI(h~!?yo$&eEi>kh)YOHNz16JscUFzY3rDnnweWz zS^=GZxwyKydw2#01&90z4GRawCnP2%r=+Ik=H(X@78RG2*3{P3H#9aixAgS(^$!dV z4Uf#s&do3UTU=V++TPjS+dnuwI)+?b-`qm)?jIii!vzC?{a;w`{r@8_%y(QL{(A<9 z|KWo9;P!sNV#2|HVMq8Zs*Gslh(*ES{}Ed(E~mO1iIP+0635tS8X1?0Yl|B4AGH5L z_Wur8!2d5~{}-_T8`m-b6&B|G;lW}8L;x>w;b*3ECP$HX72>JR8Q}weXTKit#SunY^VcR;eZtNrO!#Nh9ARSaeBKN`OM6 zZDAH*t{5iwVy>gS*rA=Ln`Ed;ojca1S9CpYvYA61`}F`y)>a{Cuc`7O3Wj2H7FYfH z_qaIJE75?4>~5SxK)0$60gF{p23u3fHd(MsL0q#l%NQ3iLp2ER+so~dT0N2Vz$X8r zOD?@LT>hLquinRhB5TW@{fnXBLuU^IM z*CN6&S=&Tv@@Wl`+xkrJ%4?c#WHaq=Ed^JWTc=K}I013-b7`4^caPg$Nz%^Vetcv( z-goYgvGCNAd__wGSr%k;N9q^n0A%Uge&LB7wl9;w!h#{jvUpi!TPDDfTnL=86;%_w z)Fe=f1}551MPz5Vc7 zfm5|q*cWPrCVs+VLDfAp15Z}G;+;jk;1Ld zP_Du)Szp#)>!Nj^I)ka|Ne27A>0wHc~r zwBJyG4bA+>Y;2}sJ%xnfnoscOG~H8Q|5Ns!>`rvsTy>D314DxXqJdSKeQgDo)<*f!@dr zZohE-P+u=q8A%YigvoODWxZmi2)*5T0QfhaGr+I&2bP>&|80nHy5yd+{&!r&ApvMn zenb~H&TN3>Od-!cQT-orIA+2Fz?(`xsTsrJUG5<_(+SUK^J*X!N@)#5QNe*E8Q%qG0%T8DPH zc)lDe&)MV&NGN`vnoDwJk5KET43`&wy%36$x1zhkj-O!2C>RQ>*{4VwqoZm*l7`Q* ziQQGZ9x6a*pNY_zkSwG((94_IRW#kWp1mn$TdZ08OfBLKt?(cM3t0=}kpYjMeU5rm z=2WCIZK+=007uH>_H;(q=#m9`8gM_6!!6+70GmP#YMHl0QvN@)h%sk!<~Ez2L`GxU z_|rPtTu55f2-9OIiTpxUBRAN%nx$-Vnywta@d`Ps@GC}QA6=+uv0)N}ZyDnnBbDie zf69s_h&g!ZIC7et6DDyq4;N)NcirTS>ibi&NV8}_!uuQtfYYFFh(n&&{hxp8HSjyC zmazctN^PyOK|V6^<21VzoE!Cm3a(BcpBcQOezPFz9dPBS6~Wds9^%rkt)4X)OUn82 z+h!h1If8HPj!d37>0z&m&rH4#DL<&nJB3edvV?ff;vPu@z`pesqk30)5S-8bgc&vl zb&RN1SsS;dte#lPE=(Sjm)ms)_=^@mun7vHQrfCi;p@eNNd%jt)efY zO{tafn`SKh;#VKxB&)+1DU?MifD21L31=qV%xHywSq3QasKDS@%9Z;21e;76dH+Ke z?B8p~abGsL%$dC|a|{pvoRIE`3szI#orWt_Ya+i^D{Pq4mxAX!wXAFCl=aC+SG+5( zY1rBSXM7*$xLih6J?tA!bROWSJdE}@c$F>a=UJxJ?E`JFXT&$u0WyrQDk#dMWgqjW zMQbZNIp3D<+5a9)a=gVsJ@H=kpsgw{Q6?G3j$^NTRC9A8kBL{GGoXF0w(ltea;(D* zf>yI+fIP-dHSG~CvUwhnANSgU`=STogVTZ#7!xAz2`}|ouE2PrUpEE3Ufqc26eHLi zsE>1_f1O)z%ZCnPM_?p~{ankL7KsCAX9|^V3aDuEN8943n04yJuRf8Thxg61;>&zP zEM$~G37}B&Yk^lQ>G*+}=47@M5OlTxf`iwkY*$MHejyfPZ^iybGk(*K4n4 zpKVu-!mRu@2vJF|C|3|B*ll{@H z-@QpG)AEE^9T=F3sBa}$@U-OJ+Ps~(?2;bvmQ9J>yxTT=C)9B?Ns(T!^3}zSA@r2 zM%O*lx$Z6>*y`l28V4(kmq-R}C z4j_IxXRa_(7k6kgoYL16eKn6MO_A=op8Xmy&>L1~j=hKrSDNyGVsh zu@tNjkVJvztBO&psS;=(Ymu3XnnQ9=wbmm3NbTl6AK7X16~}(m#^;!D4y%O-6JC^{ zgmVxFm2UHAoC;1Xx|NojnN}zs$HCK$s+v6Xhcs4+5xO2lJLD!Ou*vY2G6OZ=sTB4-0tM*6@E$3^eaR9_@JVWlhgjktHmlP{O6d=7BJAnY(Q}KK~+O_KM;H?4COtN9?q5~&}qmR zr%23r*^p_pHa)S)8zXaYEdBwBcl)%T zL3N8gGnHz4E-B!rQ^lnz8iLnYVMX;Doq;GsWlcbhULawnT3ch+KlnZWKvQS&?OTlU zA3D>a8}^S;@F>2e|FqmG_)}HIdsLMBm&H+(%ibqQBVr}Pu*V-YkwoF{`Pk?|9Mcr& zE{~^Ea{J%h3aqaJskLKrd^bfAA)7dY(0;AZqSOG+agjS42SiVzD?-KQFhB2Mzpn0O z0rmP$A_Pf6M->A}j1{%N#6<;KpZbQAlyCY~K~|pNFJ*xQw9wyEd9)TBnika87Aj$60B3IDKQelXNcSSCexM)Kk1jph9HJZ zSH`jRy#a8n9NcM~^&*QqfFHYn;n+&Um6rZoTQFUyl zFIfa2{dj4%yw3qg4ftqplxD?@7zx^VuQW5p681x8kBKAWO7;uDCTQ`WMV z8Ek^PSHL3t63gMBg3(eYaemTBerO3?SRjbsQ^WLYT7b+39i_;684Ah%y3(r)3&S4G z6NW_;s}=(BZ%1+SwTj~n*gYQlIb|I$fwI*sD+_Bv#$sJkshtz$H-J@d)9;|@gsjEO zU@Do1+wmW1bR6`Y+@=WvfzGTxrKkW!Lz(dN$B$Dbc8-fPB=jN&t@A>%at=tk@l(*! zNE0tTYWjj|3#q2yJP(4FM$dX^3UWrh^55yb=y90lV-8<~dP*y2C*LWIIaN^9jS(JK zQc$N=fNZe1&~aCqP!}FfIzlpU(xHZEyfH2VUfMB|>T1QHOU2ILs^1ivwj6GN3HUF?_4^)k7iQ14I}~q5txP zL=XyfbqzwyDJd7{mfToVpE)DAU{Zf#(s@i$PcHyk}xT%~}P#*Hkv}Q7O;$ z2K(IC3hWEH;kPw1)unfYq0+A&0J!MFP|;PV4BL|I!;cS&ik{I|ViMADkv{eOqWr?vEm*SK?c8EYtm_Fg?^)LqCbrd-4Xj)ahJYk)Ra8=4!wn zW}js0@?{ez7s)g~rlpCeRxeCC_&44AG~HdYj<6GcPjmN*GW^7-J27m%otO;EU^Hv5 zXF|Y71CJvia?e_Hy2Z$6D{+P?)%yncx%x>|c-Leh-8P^~KFbr>aOF`Jc?C{%T1ULX zw#dEi_XfOQ+yG=+mtrLL<^*wdl zJP+9;;5IS)9sn=uK;$r4AXiy&XONc#lgxaw4Dw7v)4xX~DP@)%dm;j1td;Dbygbix zBVlU~@nAH|i+I55;MCRZlZq0ngZeO9fM_hgEFrCpo^|?CLtJ~l#wM4!bv7##h!9V; z4s+c&`PB~VpLZpAMAcGeBrV(PfSHkfB&oZ^>U-is@Twu$(PAHo`7Xq)mE4-0 z#|BlGbL0N@?H4Q-5fsXPTHA;_k>+AU2OzGO96O!4$0()*Y6^l8R_BEbHtsA3`Ltoi z)ojP;ZM5o>e`%Ax>wsi?%+d4k3F4}DJCSoU0|OjFk_EI)Q>DGLT$M|D#(7dpUbErV z_}DPAaxP@Fa;BJ?&lCI_`uR?SuE*?sA$7lvn}riqb>h)N&S8dN+l90&h<$)~82bk# z;_sY3R6-YinX3@#{-8it?DFj)43d=+&X8aixteAcMsqbt$rUR{lCqs-N$G7jNqY0Q zm#}0x-}G_8Q>)#MmzQr`rL#%Hp3z>_UsH#@&Od9Sgt=7Kw~00oT(4YzOXF4_QF>gA zmko=bD?LTc_=Dd(7mTxV7e%EyjbeG&pHJ-EFGr<22r1d?LyLzg6_|CX#x=i8zIfzQHsRzn4|U@|GaNv$Sf`&PM!`Hpd}U+YXI+kYMP7U2@SW)JjkDekg5cJo@7c0`cS#uNtpiyY6GLg; z>Lt4A2L!S-jz!GFKg{C5uD3mHOP+nXl-vZTvy?!{2GbN0$u61qwi!G4dMcd;7m=U+ zUh@1l8$0Xq22yEfI*5nyf`2s=#E;AjJmq$t$@G%HtFL$`hAcq-i$2!Su8L6h5;Eyy_Fa0DJvAXl~QhpX5 zFKHUHF8&H6Nn$N#56C-ub*}?yN;Q;du}40o9U6$#0VxF9t>zRuTl9BvZ@XX@7v{jE zv+~)2Bh=COUwJ9Be1XkB{pmSFV!EyH5(3DncIfmag`QqBOCgs&QDZYw%mJmbZ2uf@ z2fPT6DsFVOnDg9iHTO)e0qE$?hgMZKkUkj+Y|h``lwgc*bg+$8N1sk@pZ zjJJHPW+N{VY07#pXNK)2Gor{vhxCg??j~u&j|=~%t<$8QCU)a%MeJ5p@|KqkEgTLy zbJq@hp=Ahq?gDSeD~oI6dk*&As}Qho4PJ$RLQEy#C2bz;)XDbdDc035pLP#3c6Y2! zvW@H%eZ^@k88#xewlH!X=7^ffO2Nz$;}a=RZ8uN-Bzyyp$Y>`Mfj`?kb61%P8jMv(~RDI;Z*99px2y>B-2Ow>j|jv+Nm9Uu+eV zi!Hlxyyf5rT|eg9b7w;V>C*MqVJg?58VXx!oUaEPjFEF$E6FprN5OmPag<_!rP0mMRfQ%gGoEM_WZB_9r zieI<7FU+$A7{&hM^N;B&+T`=aNf#(%u9rW~z*?VQjl3_>NXysaafjqj5-`h$N28 zEZuy97+U#`8(tdf+H!xH78Z2pf0Bre0s(!=Oq|VEO_*&N?IPWTb>k1~3g|`G`WCo7 z5>p>n@`k;eDJX|-D=_NT;f8}=tPd`hMxoF5Um!(N@`^njf-|>TGS4$s@wgzI+qAXc zX=MG57Y6SF!O0_QD3i(?Kw>VZDQw_-Klx8TOa*mHo?lk-UJcD!8~PC;4@7~pI7aqG zXiWoyVBQjFag!kW@9+$ON6xS-3wyFNrDjL6jpElqM}Ur!UD#_Zu6j^N}Fx9 zM&ccD@=7$!?ro{0Dx>S6!Z*)3T`g(EQG-lJwS(C+@fGt=oPjbdBw{kI)A1Gin@u7z z()JQ+@hdZh(IablWaLn;rBm`R(gs00aC1dOi4{Sz^^8r%WxzWts03{_;%ynG)g{gs z(dT27m#=)xrt)LL-~H1Z_x2ITM`*JAh_h(ee8zP+b9T5>3$0`Tj-2S*Rl?vdQ#r}^ zm_FufKty6a4vX=rpH6}-0g1S>KF7DE>-)(9nFdZwe;yn22$s$CTB59 z<*Gq0I|O`8t(M^6nT-G{I1bo_O5K%p_+t_N61pX>p~!-<`H0Br5CXe)hHt9H0MT{U}Md5mC zkw-%$T^Bd-6~!kgMM9iYzSiHi*F&#*TxD;Mx`gj@#p5n0FFa&N>6`1>$#VG%XobwV zLTmxIMj?B^UAT_LAP=ZPjR(XA@b!P)zNIvf1ja7unto_!U~H8V%$0DA(UJK_)+S!C z##Ad!v%ZNu#UrI@sZ&yL1fe4Gx6=aGn^kDml1*eZ>(za9raR`aPPp6MF2Jf%94Qk5 zr6N!Xd8!ruqxYvLIFnwq8a@{<*6$@2mv!0Bo;H)@7>*y^G*2zn#tJa!B{);HOfx~@ zc4S?rx@0)Rk(;=3L0Or-m;Z4kp#^Y^Ka%#0)#|fjsrpQ%B+HorU}(s&sgJPa7NS)P zI9^tfQ`H?JAtNUK@_0?-brWnm+Elw25ud#(`APMn4<#74MyVmB&D#hI+{~i;X`1F4 zqhI{ksz*&TK+=4)>lxX5Jhst>b`PH=XS3=qo^f=csV|jiuTiXFhP|XD?gdwM`h*h7 zY=^j3PK0tdl)-NR^A5M^U(ELE58M%1NlKkx_>5ltDy(&^aFf`F?U~SsqmnQSQ922_ zY5kv%&%^J~%yGH35)sCWJ)rO%iRD%U0t9?~cJc-HJYutypLOXpka@h9Z0>flh5Huj zIQe04qS699lOMvfjAm+8RqLx=gU7&jtBGnN>_;1or1M2NdWywkWmu);R5&Y52gG2+ z0(-n^#Fih+@)P-^ZZ2;71E3N_Uvn>Ie?j8a$djQzta4L;PuHu>x67< z_CDzr-(U{b`;^ft|3U%J(st?dh&y^fIJe3E{1Rb}!&$E-948_jpjv%+1N@%Nhv27MvN{ILyoZ|lXgbyLwq>}c0qnu#vm8`Mb64-=z*wZ$Cw%&sEjPH^KUrxiXHghb`Rr73} zN=5W`8}n7(y`Z2*o@}C%{V5xLKb^YPR#VL5J%Dc)qHD#O1d`SN>6sJ5g4zWB{31no zed%`*Zt^-y_Q5WesB`H+Sw(Wf=2^OyOld0PwViPQG!_DP9i1|XQ2yPP0J&UPg)`$; zxUTZ)5BqTi1PiLXFuJO^WsiSYD`2)Oo5Cu=JBdp9!eEm7I!a2%9)-6fK9KZ{FQSi- zE6#6c+9RN?nX9}G@3mkVZ(-2iMy-b39U=$k3{S7wwifh*(xTHnmcLB>| zThhqd#KYdp<{yviiKD%}-5IE2=mD~KfWP_G1AmemJrzQ>lhs>d_(Kuz7;|N%T6310 z3lI0$2UV4k^+?@q5rcicB1zp+N6bKegHF%%MdWdVvn10XWvtg$Uug%F)ivl|#-1`2u+JA32bhgp=@ z1W3e{#MEwl@Pr{EmhyxUiO56&u0~f?i zxEYl=_33QP7xTOX@no%8_=m^%2N(YaAJZnN@jk6p8)}|K!@&7b%K31fU52DP$B$b4 zQ9ZfPZW2$(|EGF43YC4Iu-F^+CGT`c7lS}Iy&9jhYs46gxjKwOGJ@!)0(k?}8>%1a zEM!$K4*KQmzlRLjmU~gXjIgVi3!RB8ToBq|ZcCR9#A7#H%?9T%VmX2X86K)eMo=KTTJV^W%_8h;<|=3ls-yJ;5KTQYv5r#SlZ-2yD2OPXg^ zlTPc1jc#BsvvmF>W%tmtqk+{WBeeWp@#)7s2eVr@n7Xc6H`GmHO0O)xshb+#=hTgu z1B?&b?`fXUB_90KDG!biO9AnRj&qAyLG0DXW3M@lnwn}APxb?DL5ui!IdK$56M}I{ z6(f3DzS87)4*kI6MEBw$0U*kKf-I5EgebPeKdeqs$b@%w^qed`ef$KP@B$b8NVxVF zm8itC_gx;6*ln@mpLtS(Fy}C33A2Uh&pyXZ5>Nk1c_e7D?dpn*mc+@PK_y)(#r->w z%t1Gy@qN82#owT?QlpvuUMd2u&yU}!COS8j%H6Mh863Ck1C&smgECc1t#8gpSW%i0 zDFXj!H8KNioItSRL2`I}B*418X2RH(xlg@oeG9XOYK&{qZt{%}*}CVY`#X;TnI zO#&|;e(rCO3AG;s9STKzYs2mCB{mzTa2LEE9#WZt?9pxRc6+XY2+1(6;K~GRmwd2S^2jK zPk;mmV|Rz3w|V_b>MNg)yJR1$^SJX%I0U~qv=LU85 zEdA00jmO4TjeiTvI-`*46Q#(PNb@b17rjSLXu|sBN$^%UjF)i5efHYux=DF3eg~R4Kre7t^n=E zBs#ef6XS`nL-AoxI`5f^PP2CW!VKUq$p#FA*KynCD{k~Dy!^0ajcl}M@GN)n(3?~M z$&)6*M5qN)FxHzS90K~BGT}?ct0je`z_${Hi61~QK zu6Gj-emd({EMz|Y*_u)hu?){8li!cJtBi;CT0L_fGwat=O}X)z^#Z#51GILEAEWtI zXmSw1_lZ0_>mP-$GBo8aTyiJ#L(f-nsp>fXZ1TJT3_GiE410xPg{jhZ`Z(8Cjy#!D zn2W6&4{RKx9UGs-GF7s6kyq4h4PTLO9x7{eU^pe{UZpeRP=c+l=(6z}P)403=O2ML0aMf*}h|-I-i& z+!l!_r@Gt->hr~)T0-?Rno(GyQOIgfdA;`ABp6SOc2K&_U-Pw6sm1| zx=SI;M;7}dg2KNpCWj9PsQW-WOFpxwC8i@yDP|IiVEf!~Fd#)F0dq9L9v>^8n6H1; z&^1O>c**zTS0Msa{Afa|<$}0qoP6M*93$$l82RxYRYA8(2EQ`QHvi`a#SLXv@4x5U zl0FpztuF(fja%#Ys2efZ@|{;f$uce)i5`&P3g@(|F7Q= z{Uvb6KG>#ysC=8X_{0}GnzvrSu?dTMAVUl35A9tnRwQgK-(<0YH_^Q`WJR)V;T7@z zP7WfROx$WfmpGQxhnlja#WaOA1T%-a+u%4+s+=}8J}{}eUqQK36~R;<-}46eT<7J7 zci6)ghFd&%rg1d**xa?=M1l?K$j$G(=i6ir|C_0~i4mT%p2++jEx2MDusZMYtYwj% zJ`XwMAnC+NxVq+Y45h7EWae+mfPwX#PYYh>5 zkc|36ITc+e(3ho}F(=4aWtA55O!-)l(U1%@waRWGV*mTO7mT66z7bw#=EEMAqpi-? zYlJxE)R}x;r8X+U+;E@v#~Bo@8@_;7Xh!A=#&_@wF~63V}g;#RO5QCxZ9=hg+79tP2+uQ`(tAHyr0 zi^?x6Cc)~BXf+ZJoLOTU73X238Mq%!I6_`Y-OpkU9@MRwzY2zG;n=RdCmO`zV*GD_ zrCw;_ediO4dqJD%JVAovu|JeZl_#(~a}s@dkjadiPmS3%Zvb+ z*;aMz!p}{@V)w_(%!QI34$MEdVd;~P^^cnwRCOmwIg{_cv+67QpjkmvRh_1TP0?x$ zG;j7Mel(Av;dVkb2|Q9{laO59oH|?dOvT!GAdHA~SQKKEVeEn+lzJ8v{B4Pr2z4q@ z3X{FCW^9A=iC zR*c%UP20f(<@Ji~zHgzw&NRPAUV3`Y>puMs9dzS8Qs8MytD(12T2Ce2?EklSqS3Hn zS{?ersbQ-*+$b(2HC)00*uA+cqSs$l4o=#)?Mu%8*|!SCG5?xImxwCgvpMJAIELVJ z>^-#}D62oBx;l<+8oDAPQ)J}qNWCL9bgy0^Tk=6dUcB&w5$9Kqvoxy$yc`zhVW7a7 z0)L*bI?md)L{KnaS$+wCY#=Wkts6G}NTtFl^Q;-ZeJ7>cCYs)?<703N7+zOg^_lXj z_#BrVbEIldtiESP)|q1Y>5Q<{BG>e$!urJyjaEKcrP+pxJ=w++W;uJBIVb5#TMqa& zDldHazNkXG+tz+7!keIq3O+pYO#DlILUtjg<=Dtc_3iu@6D{xAYKx)oAA*x81#mwp3ZtoDp8;fnSFc%E$*LgA=5pzYdIH)3)JK@?hBifWkxU_M! zHaf0ivOr`}k!klFbvKBWg;ag6b* z&HMAD1w#9Bxa>ja?XeGyA+2Dk{7X{SXvq`I6O*^g^skGhB8B_JDl3SzZBbnVVSS{p z9ujh`|J8Et+%r^0vB!-#FuZqP5a^^lc_7Gc>T&P&#d# z-v-pC?7RVzcwiCtHaS1!BkYpZB){LLE&i9}4rXs5S?TQXC$ZMn+9z4~kMX*-ImikK zZn%g!&)sLD`+&OPevQyQ9``+z3(04(8@8sE0hgSR^N>o{li%$gU^AV)CH_zNU z6~z2`wx0!w^{GmSgTfof50OvNML5Rf*_*_1{VW=aoZp2f3B4DE+eH*TJy!%`5`Kc0 z-T)#8I5cCCrlya6Su&2WMBjd50K%Ej8aO`AtD^K;;0wVEnE;#|{d-mZimj-D`N<3{ zt(lHzmvTIOQ#>Ax4|PcoMMEz_l5Q++f)K&A~v_FmIbmHM8$etu1Qa z5;RN{?Uc{>K?FALVkR?8r^bh^x5Pj?&(6~R&Lb&yh^^5P9zN1GD|NonT)5Stmz?;= zvf01L8|U0^&j=_%hBd#%l6qk*N`Of$?l3!-uhvL3Mheo<)}&9-@f4cC04Y*N4zm2l zp9|bA^#LhI;#_*=W;pCsO=80N*|R!DYy&19Qil4Lc_tFm*~$gY>Nz`XNOO(=b%>G! zO7`NW=?*V-r4{~CqDlMw4cXV;Glz9uQG248vr$*KC>^t44Zg%cbS;Oi$?;hCqNB&+ zXpMBWSsOE|?<8#+f4PusQKdeJWwQ?*%aTf)O#MV&9^*VYB03SKoOi*fS^d)(zHbSq zJQNk#7>~>qneW&fjUi-ZbH-wKjwSy$s8(uAUF~jH)skA^&}AK6n4nF%s{Vq1hDg97 zNqf4Ns+N$8TmTpd3M)lEij2mB#o!|_hZsRo6w|y=cOC0k665utXIz)M&T&9 zqViNi5eA%iJ|Pl-DcbJye4ePgbF%R6gRGYm1{FE`VKn_>ZL%iSF|NTcFIFN7k1nmCtZcLT|)BAk_-Zzka(sFm*7%)WhmLy$cR7#Aitg}i%5+3J@!&N4S+u_qV zz~^2I7+_Lkr8YM+h{!*!XYhXC77$Rk=pM3bDbhgu8@-A+w%qYP;#&Z3QDk%!b0-pw z19k#?EQiBtnOFax9>w6SI*DMiaADZ{QALPCrZbZ=b#U9hw9V)zb>z=AKMr`wgGXUA zZbgy|DChqfE|||#)`qW9iBPelGDMmbm0U#MvIcvbY+t|vBP!i#`}vb%JWEHC)AVnW zu8Jw)5XC+Y-Bn2|$oeR_DV)e-R0_Im31LY<2u^Q2jh+0$U z3MUn8PdhKBKW<_%jA6)0(NAPpKBA)IF-L;(7VmJZ#UXg1Z3NrAZHAkp7c~aDB}54b z+F1B>hwi_OVny-EuaER4+D&qw<)_T<<1aVlzcw~7cJ>LA1czCBgDw8hG9!tEV+GEA z_P~&=9;9;A(=I5lt~y`wR=^`_e!Z*sw60h2$hr1_RZIseSyT{3E%-yenRtg59F2e@&+&!i6Cq6ZGQ>A>=lnD`8uKY`VWGhT_|Av z)xMR~@p`D2S2TY0xowV5OI9`T-u{wk+i!rCRCIGPKp3lI;g&x74Nzk>?L7tXaI*`A zIbS5!Jdr$=zf6Z-&9vbZdt`dViC-`2nMZ1Q zbT|EAUnjFJrL&fxgT1~a(;>~<7oT{a#8(n!qcpZO_md>aA2c90u(5ft@L}Ao+Z)Rm z8uyw{{P%&-%=-!p^R)hjXRCg zDpiYi!sjR_T<_e@`s5xx*{iX9!*N{UMeN#e;zX*>N;5TvM@2`K0Y+a%ex7+rZ1dVC z!(4UG+S!P-`E{l!S<`6GAg@i{vK+j)$rj)mN%uvAI+mPois(lmn}XP5=#o&@AdQI#Ij69hPlQtk!Kx|R5Fu9jR8z?39}Q9{s;s11$x zaOh4*&w#X$5SblReFsg67q=%?F|El)TrcNI!Cw#(cxOH-{1Ms|cG7n5|(+*vM`IJ@fPh~MOaCW@honHOG83P0reh{kM)_TNHYT{uUemEhAH zNVlv6@v_7#ampdqfpa0;)R7UR&9_bkW`G8z)kO(}#KQWS;(@5fH=ukK7%TCICVQre z0xV5Se%n^sDdFUY zJfj&w%v+WeCzWzSGjw_E+*mI`D3S6Z1KnA5n8}^jXk5~s%1%2lfHS(Du296;Ka#Ml zSWl+*Vs}fFZGb)AE3(;$Lk5=<&!O^IPgGjY#Y$DNGg4W#gI4W>%0N;2Gvg`gK<16J>4s zK=KhK5UZQ3A#Rd4NxX3kxGpCXm#Aq&w*qqVcz&-J2GqQ+YQ6y)GzWR6xkw}w@5P>( z8CNW0_Y&=PN5bq<+*Z{}Aw4@eG#&5xV!+S)vaPJM#wTo^(|X8PS;h*BF1s?4kUT*A zMBN)8*`tT7EiZxhBFjX3Ap*2-L1n%oO{Vhf_>v`z`MRvJj5qK;$K%b{4*F?i11q-$ z9-w^Rk6rvVr+A6AR5y&&kpBY?LGivmW>fI@?I-&Pc*o*SgR1yv#5!~~TD&^++NGoh zM*>!qlJUl}muN_CLI>Ib`{$tgGeZ5IH1B{m&Hn%jX5oB0YWEDoMYp?m(fAHtfCi0zsnJ|AnE3P-IuVSv&6vgLSV z=i|yFBO$(8`P^1pfydTToLgz#H02&Dh zvDNhTw$>W?2m&BR@LM_D$O4i#5!AB~n;m5d&hn^)NU>zwANv{yt}=*A|VR6XB+Ba1%aW1hb&fy1!|M3+ve2$i~Xd&CVU~&Kj4%Wll)V7^#1@6{7Tnb#F}oG z3WmCJZ`SG0QMFbQ(U&|AFbr}9er5QN;tsRp?-fPj&1XQclG@TQBTv$pKajBQBn&G8 z2nVPjlgY^>(>!nSugBlC{{Y3QzA0*Ygz)Ir7SZV53)0n?M`x$P1Zb#)@K_Da>dw^t zWiB64VRs6nM0~bLqFB}Tk~4rY`1kK!wBXh6+~$>{t=P(n-e~|b0GR};D8Nyi-~*HY z0P3kyB~U(GanO)6R%Esys+HVFs37Oor1Fcuog=Psjz>}JTcu+*$fJp4K+HkM-Q%r2 zOJ^#)CA4*Rz%3~C<@_qd&SqkGsW9;oaPJy>=^1(Z>dC$|2)Ker-h#6C!#O9_h ztAh&jj&ePz0C^*lP(Ub|>x0cPbS!B)oz;wsaTJV>x!v-H1#{4Y!S@7WlTe!8?q+CU z5uxCy91o^?b5F9hg7;2Y?B+jdhB9?4IaDiKo#j$NlZTDeDGoRcSq>RUsDUx<<*;%x z4?)~e4(XI;`$A8%Y57;>!Sz4kR--ZBXp5w3%C{DcyEd0-B#)E9+CdrX&O1^xC(Ou; zr=ZW_#XdOIdBD#(2c~EjGb-HOX?_*bTHq&hW9GF*!k_ULuF@(j7CT9h z<9oZRfI0WC0{CO`YvNzQopn58@W;lNT1Dt4H#W0l%}xnP5d5x(p;iPQ;-XSJ_IS0L%SX|CS@4%ix9|<7QaGM%K7B$-ZR5e(@-@BOa)nZIkvj~5 zn*2ogMgIT=G4Kz?9U3nN{?+~rk_(iW74b%cZIp1%41#D^4Ib_ZF_OP7(HPEa)%;iR zX5-?&!!0sDf`1opb^ibiY5KzIIusgLh!{STdaJc1wJJ+NCoFITWaMu`RY>QnN80=^ znak7-V9}!TiDa0sjC6c>S#Y6!?zQ z;ScR6kT?(fi#Z}XtNY#Qzx4m$(AuX;w2lmf@LnnRY|WG6Hb*0UarTdhvu!VGw4y_ zjZ@&P_FfV2CxTGh>X%I}uO_i>Wiuw-kl6Gul}*4AkDY-y1n0+p;IQ8eA@NV_W37J8 z{{RcV8l~@uyj^o^W#GRKTEQAgE!=Xg?3lp{yDhD5WMiCR4?K$V-`Y3+3p;nGc;-8M zpA%^Q3zJN|RwGo?qI>qW`IMw~#I&YXZZ?NPNL{}nk<-wBWozGwpBuGlzu=<3wC9KJ z{41qdcv@=@hQ1xwrUrXUIeu&1Uf^v}8_cO3F^mu02@Wven87v7+*9RSHmtrv#KFaT z&0Y5WPv;inOok+uF?7P}2iYyWk?lDIh8=Qok52TDj< zHK(par(9f%YinrYMacy|P5s_ogMSu0W&1q*QPRFB_#*hjcc)%OIbETYvO2o%2ZM%CdC241zMcKA{vv!i z_@$zFfA+`t4dO?(y4UqDw_jSvcumiT_4_@KD2<8TkCkO#RUx=yahE5xlaH6;K6M4m zebN5_1seE6;_rz60JO)$y*kzIqS7yQ2yMLho2o@On%x?Q8oY_@Cpa$EZFfc>6-X zj?Os}<}n;zbS{y$RN)Q}IX^Oy$=ih?N5tp23}swIYEpxgTUWN}`ThsHmQ|xhvz11d zW8}+!09{;o7r}qCK(dl;TgI1hHT1HqrfX|#gEWJ5r{xQ|cVTm$M_TMJsFxTlDgw)r1H+Oul5&}!Cl10Bo>DiPcf zoYlXx-FbPy>FZuy@N464i>Uaj@8H$^(M5Zr#G=hafcduDS8x0cHvq%Yk-v()T_#qK z0N2*JHx$lTIK5F$<_n`A1CV;tB3rO<$)7`4T0qEG+M|v@2q4l@b}6E}eWRzAYc9pE zt?n8xEr!=4rEfOUG7oCbxx`wLA+Q_+R|#m>wjM_{1lJQJfb4EY4PHkj zI#NsbdvVQ0%CS~Er#SgrpK6O#mEO^S4UjhuJu2|WTz99*8a#L?IpFa}GEU&rXvov` zJgx}zJu3eI+SIOcG4EBZ;)XdI6B^}Mj+J?0jk=)e=}uO@gvC1*qP;~WNgNzeQoXbu zX5$d%idq$BQ`GePJ-_Pz04Axd^jm9dVHY6do_o|QFWRrxJaD|8y(>Yb=ZI(cWCW8{wHw8PGn3kc<#1{#YG-MhMDKGX=H%gc99EFiX9NB|PXmfHt*K~? zRD%BiG063+CO}Toc&9nZ$e2PZCVj@6b~qOUk7{fhZTv_8oqFWvuFpP5PUMex=?+2_KVm`!uWR`M|amV+I8mPA?%5&FAXpc7V=AUD$T+5`-r~K`M1k4U% zInM*QAb<6%W5FIj_|Nbc;suArui59tDWv$5LXnEVa@f`{(IK7lE;6iH20CLQU)MPza-%BdHjDm>2QqWV~sZ#q4!_xtN#E6 zTK$+lJL+jRzv8P;hJG`f3F40hc*b%xolVIBp4#R9Sjpt#O}OA>)c*kRQJ?rHMveP* z>Rt-?lkh{tx?GnQHxgUk6LTHR3u@&HY>^x1+Ee9He~A4n^DoE$01W&y;`g6X@g1~G zp<3)+rpkRxZYJtFqne8{{VR#x6`$G^1-N2o-W5^aSCze zl0Rv@CI0{fq5XkA0BDKg-`b1BF``03uCe1E5kX;U()LKz-9aBI0C0HXzGnXbg0*H+(IF>tjl~NT&01R+4anl_Bb-m&( z2U(X?zSZt6X3I}0ce#`IncPbgxa6OkBzyg8q?Yo@7%0pcTjV%6Cy&aD_q)ECZg1x= za8XdZo=5{|&#wRq>a~u3WoL6XNLVk+7}^-%o(KN`UWA1(8O}EG$^QTvyFIkx5M+_r z1gywO<8j99f8)QUHd|YWZakUeXvqM8;HdzPI`%w%begdxORE{It{xfVD9g!K1RN2; z$GGN^5#(aQMlsO-2Cb#0T~(armvIWGj;Hx#{VA;q2MmSIdISD>rC@KN61K(0NF8un zjQalo_34cqk030?fX`}~;_}Am`jSrE@IS((fIHhDX9bjCliw#l)}5{^qNLI7P*pGp zzy$U7t2#A>!e2uX8f4;lBw?rC>nmwAsxgUE<#r)(ayBq*^;~A7y0kYRF46L^B}b=W zT2@*cFNff~f>5p@irRA~(H+8|D+;q71h`F)8mSv4tb;ky->KZ}UG&!~Z012!KZnJrsjgFgqw>HS*Bg~3K zX3BiW2*=D%nNHxl+O>ZXOW5N!v9F;b!;w>*&)Tg_e z%1J{;l3QHKIgaryW{gO&8ROd`e66vdwoIcs}% z7~jY79N>Cjni|sVg{!gWf3#PLT1^5^0qBy3wzNOL!)MNyfXCYy+CGHx2*-ik>9@9l zT3dMlWh8Elj-7grabIfw%s;RXj=yXlje3W|T^qzw>A%^Uba!4d@g2K)(da27DUKEj zK$_x35`hvh+Ej-s1MU41(0^eM_$6QLPw?$LNAX|6v-pDQ;n^e9e0zDmS-=Wi#NJp) zSdws%#?u_}$0N_Lil(e*#9Rp@k1EPO_T^uZ zzCVA#3$JZ79~gMU_ComWZ{y$iM1gz12VCi|2C!p|oo+m_!p_kV86YZ>vZ(;&cXLt4 zVJptjmZsCg)Qh`Coip~%_#xwnmqh)etb9Lv9nld(I)0_^;vXe;526@dREW(=Kf{L3akC$tuL869hL=ERc#J6wVhqB!pjrxNe3r}2m05e&2_4|$fIdlAEY1fPd^F&0Kq%|0A?>3 zYd;fzXfF=Ggtbi{6If{)-i3RtU);tzv{yk{6|<0bK@5YaasdO;{{Y~#{{Zk&?*)8l z_Q9!<9(Ut=!{Mzl zZ7i)*?N{sedpmSHe5g)P0giz3J(XLgMR$J<{1s*34-G?VB@^CF8EcmZqZ1*RR zpj90~uQB++;A_tf+UXu5@r3JfeX3cl#lDMaF=9iU2XGX5NslcRGEd4muS)oRqiT9L zg6%CeS@+zOFDzhuv1g(v?5a2%_N}75>zvb$&9eRW12YvQm**!m`|TUbvs?7lEiNL$ zWn!22fr{=RqX1411c8kAH0hu&5UUI~-2mgCfAiX*mIqL-PT~+Q2|NsN0s3S4Q+kq} zhAP`MV;^~2C!VX*^uhf7s=NHzl1y?AK5qT7{OZ%hzG+EZg)9NU=rh+99I&K=I6Fz> z6j-x4E!sIqWd&G#*#fgXEve}~6!8`Jg8XH3bTkhV>^9eNu-m3zplywY;4AJio`CNJ zoF#6^gf>KsJA>HP4~_gWZQ_jzT^eOg%y%Tkv$254KF2(MIH_vdp{~r%_&@toe$pSa zPsEG=02O}A-xjqk1`|6&2}yaDC1Zgi;DgIC!RT1ysjsyD1^)oSTK@pxq8C<@YVZ3! z=>9TGaJN_Yei6RA(`J;DmXb)V=4cq5rz|bUB;@m6gZ}^oy6~s$sqx3)-JikViJuKT z6aN4S9-niyZnZcM+BJCQX&sv?!JbIUxHtp^F%ojz{gprb6NBIng6*c%J_lmL z09&)OYn!V-CR^EW0xK;M2~b03hz*jw%^-2v$#+{o&Sxnb&k!G0C(X{uM`8f>Gtny_;)(HF7KH z9R?UwT8yyGX(EHp+>gVWBXuE4&LY^E9uOG&8kwVfW7mqKq-rqB7z+OYg#XSGx*iZd70E5q-18B zs)+oNIR5~aZJ)xH)>zp=R|I`(o4ipeS+UbdcJ2W1dr?yjt<=#;G&ZhQ(xFnXaOyJc z$33drq8#CCHYu;|;8=t#aJc)mB3|99{Lr@ppO%Lf*)ftz#hLahoPqgM;Duv^anE|n zZAR{Em4rk<-I6wTt1YTbrv?+r^rqn?fle)#jA?&mW9?dtOwr^-xcq9N32scM2d8swEzwg7zSN=>1OEW8RSvNlkGOw2YwK|=V3p+d z%|eWseDLmA5i3o}`=i#J@eFmU7TVk|xyqcDy{{U&%@OQ&4C-!ad#-huA;`vOPy2jr!SVnmScMjk$&>H-lywojiP}vzu zL>TP~0Sa<@g=ULxoy!}+=pc!-r7F3$6Q}r=vEGv8gxx?Ut&n> z^DcV!=Zx2B1*MIMd#g*SA(59T!N@<(vfo5|_G{?alD~0XPbd6;#-*;qJumik(BiQ0 zZlmK{#Cb0-16W$fs4|GD=1$n?2p(Gh0J`ViwV>Z?wlz^9lOfY{VMzy`KOVo20~M{| zn;kd8-Wag(_NAw+;@d$BEGu!dWz^^;-gfn9-Qxua&rkFI=%Aho%mO+&& zIU|hVeScqDrrzR}kxpm=l4Fc1AnqibFv!R9sM0lahd3a5b>r(+@8J=uk2!86WkyHZ zb`{&m+}I$3HuOA$gVQFpro*IPy_L4HYkaY+ZT71sV-s$TUuZ6%H<4bf5=MV^H;jTg9>b^CkyX{2;uw@WjA^ki^I&Pg7p z-;+(0LnAvt?5~4@%0~e7JboDWq|hO#CXlnU50v_Hdw)uqVpKztuakqfJ^ujD`4wXK zNWamq1-7jN!!ty$wXwNX)H39D%ADZf;Ez#Jh}E*W>~Oiy^XW}1A|2Z+NfBv6V}a8H zlTsuK=gb*X?0-JoRDl;}SHB|}!T$g}RN*(bk^tl7ETi8Yy3izwlEe!iF>*3;2;c`Cyc;oY? zHFV7xTf_5MNfonR>D!QOi%(b`6b_3VcM(k-EA0}eO2N2}&+T^?c2KgJrSoQaoV=4r za5pjIoCO#FC;$Zj04mEVkxW|-&zOUrKm>L7su%wN6f8apYFZzT{7Ixfp{85w5vBF2 zkD5qINN_nB!2sZp3C2%C6q-urit~0hw0$1eO0|>4o**7orK$-8O~Xv*lvN(*zIp{8i&m5+4?LeOp@B^;_7q&k0yW>J8STAy5?;aUmd5T%K`=w*>_4`g1_=U+l;G zSokFBUkH4Ard*ig4=$e#q>;&KAu7PjANuH<0zf1?m5xH-Z#B;R2k@_pzhh6@r@`MC z?`|Nu(X<LTONWVrASnAYJGK8p5okIBSV(y;Bh#$e;U}vsZzPJD{t`Zwsrx})*=pVs zWbiV_;ycYA^5)-C({yv@TpO2&#+I1?j2RsSgnX#MRfue;;V%CG;Gtdv{f~caxV0}7 zT-a(~1%5o)!+&q$3wyZaTODa3x3rXpjf`Y6EPiV4IQdvN?%W@GwDCvm+dqhw@4+9m zj+YnwB-Syi*;(5p+N|ua#k6I~j5u{845imEjAwB9{AE9F7ar%cLOiWCx#hnCZ~hl} zTj5rv;$IPKej?JfzaGmh)>=lBrQNfpmR# zy>+YUms*yKHkGT#HM-t~n&#%_OKF6G_6ut?rin_HpUcH)UHy(=HlMtrXxAFDJBQcxpB1RkK^^e zk*MCy_H91GYl%FzkjD&6%oRZ_a614AC!iJm75>&*@4}z>C@01_KV+WNA1)SG4>Bx3#y?;P`{% zOJ6I)o)C&#hR;ijrzEN#Fl3YDjaQNs6O1-wU&BJSZbW{_ln#YRyVAT*3Z z@XK9F=*~?`Lu=r##}9#iF!<4_c+>W-(DfUX)ukU|y3ylObb_i(Y$IY7<5E{BHs^0p z4lC-dZ}w)={Ab}q@iX8ji>y3P;kA!@Y8o+j`x=p*w@@;PZJQjEwUapmg(kl@bvf+r zwL6=gKH1^7l6Pn#l1=Rz79~`+IUrzXy?TG_pRRm<)4X@~kAVLG5+~4gOGsL1nY9Ln zDLCaDs{F%@Fxq+(OPxVogQv`Uj;)|;x;4@M)6<$IJV!7fqn?~F;Pcnh9MoEr^V~Xl zq9G(!=zyRDAOHY3ILH7GUODEwj|=|VJ^}H4;`}%Lu)Z3vf_z6L&Gd z?UjNRJG17+k`LWnU=6Px{>^%}kKyRNdEi_7Eq}u|CH~Fg4Fc=!R&Rny3`g%Rn`s2c zCCGIbHXMv&<{11BLOttG z?AO{^md%mV&WuMOT!8WJ3_0jVRCAngDTt1!P`PDO@~cJ;2cYAMyCM>IGTzCUY+wS6 zwpd_#{yvpjTNvSR(?*Pq!zdXfbH!_`DrI?PVakqzt4b0{L~j@X@=Sk;>C?BhNW)3^ zeWLjLO4Ys<-Ch9tjicOXH>#|UZ+{T;BHNr09Iupr-_P)aUR9-hVEwK1I|lI2hQDd= z96@9dp|rH|Rq95gpO#%7kID6mt(}=5Ikpns@zIX zoh|LelSssWdEAnC0=+-L5M1dN%cSYoCek>-#3%p+V;uM7cRVO#^9lE@qZ6%0A;L#~m||t$P>z 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