From 4a5b45409f0e1e6ef68d34cd3bb91ee7d3d3b17a Mon Sep 17 00:00:00 2001 From: Justin Mitchell Date: Mon, 15 Jun 2026 23:37:49 -0400 Subject: [PATCH] Add icon rendering and list scroll gesture support Implement orientation-aware icon rendering using freeink::Icon format that applies rotation transforms per-pixel. Add wasListScroll helper for touch-based list navigation with swipe gestures. Switch vertical centering from x-height to cap-height for better visual alignment with capital-led UI labels. --- lib/GfxRenderer/GfxRenderer.cpp | 32 +++- lib/GfxRenderer/GfxRenderer.h | 6 + platformio.ini | 1 + src/MappedInputManager.cpp | 16 ++ src/MappedInputManager.h | 5 + src/activities/home/FileBrowserActivity.cpp | 8 + src/activities/home/RecentBooksActivity.cpp | 8 + .../network/WifiSelectionActivity.cpp | 8 + .../reader/EpubReaderBookmarksActivity.cpp | 6 + .../EpubReaderChapterSelectionActivity.cpp | 6 + .../reader/EpubReaderMenuActivity.cpp | 7 + .../settings/FontDownloadActivity.cpp | 5 + .../settings/FontSelectionActivity.cpp | 11 +- .../settings/LanguageSelectActivity.cpp | 9 +- .../settings/OpdsServerListActivity.cpp | 7 + src/activities/settings/SettingsActivity.cpp | 11 ++ src/components/UITheme.cpp | 8 +- src/components/icons/generated_icons.h | 126 +++++++++++++++ src/components/themes/lyra/LyraTheme.cpp | 143 +++++++++--------- src/main.cpp | 12 +- 20 files changed, 339 insertions(+), 96 deletions(-) create mode 100644 src/components/icons/generated_icons.h diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index ec8a2529..1467e5d2 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -905,6 +906,22 @@ void GfxRenderer::drawIcon(const uint8_t bitmap[], const int x, const int y, con display.drawImageTransparent(bitmap, y, getScreenWidth() - width - x, height, width); } +void GfxRenderer::drawIcon(const freeink::Icon& icon, const int x, const int y, const bool black) const { + // Orientation-correct blit: the bits are stored un-rotated, so each black pixel + // goes through drawPixel (which applies the current orientation transform). The + // legacy uint8_t* overload above pre-rotates and is locked to one orientation; + // freeink::Icon assets are correct in every orientation. + const int rowBytes = (icon.w + 7) / 8; + for (int row = 0; row < icon.h; ++row) { + const uint8_t* r = icon.bits + static_cast(row) * rowBytes; + for (int col = 0; col < icon.w; ++col) { + if (((r[col >> 3] >> (7 - (col & 7))) & 1) == 0) { // 0 = drawn + drawPixel(x + col, y + row, black); + } + } + } +} + void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, const int maxWidth, const int maxHeight, const float cropX, const float cropY) const { if (fontCacheManager_ && fontCacheManager_->isScanning()) return; @@ -1572,14 +1589,15 @@ int GfxRenderer::getFontXHeight(const int fontId) const { return glyphTop(fontId int GfxRenderer::getTextVisualCenterOffset(const int fontId) const { // Distance from drawText's y (text top) down to the text's optical middle. The - // baseline is at y + ascender; the lowercase mass is centered at half the - // x-height above it, so the optical center is ascender - xHeight/2 below the top. - // x-height-based (UI text is lowercase-heavy); falls back to ascender*0.7 if the - // 'x' glyph is missing. Scales with the font, so no per-size tweaking. + // baseline is at y + ascender; the capitals reach capHeight above it, so the cap + // middle is ascender - capHeight/2 below the top. Cap-height (not x-height): UI + // labels are capital-led, so the eye centers on the caps — x-height sits a few px + // low. Falls back to ascender*0.65 if the 'H' glyph is missing. Scales with the + // font, so no per-size tweaking. const int ascender = getFontAscenderSize(fontId); - const int xHeight = getFontXHeight(fontId); - if (xHeight <= 0) return (ascender * 7) / 10; - return ascender - xHeight / 2; + const int capHeight = getFontCapHeight(fontId); + if (capHeight <= 0) return (ascender * 65) / 100; + return ascender - capHeight / 2; } void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, const int y, const char* text, const bool black, diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index a504ec89..469d75c1 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -13,6 +13,9 @@ enum class BidiBaseDir : signed char { AUTO = -1, LTR = 0, RTL = 1 }; class FontCacheManager; class SdCardFont; +namespace freeink { +struct Icon; +} #include #include @@ -102,6 +105,9 @@ class GfxRenderer { // Setup void begin(); // must be called right after display.begin() void insertFont(int fontId, EpdFontFamily font); + // Orientation-correct icon blit for the freeink::Icon format (un-rotated bits + + // optical-center metadata). Prefer this over the legacy raw-bitmap drawIcon. + void drawIcon(const freeink::Icon& icon, int x, int y, bool black = true) const; // UI chrome font scaling: firmware supplies a small remap table (from the board // uiScale) that substitutes a larger font for each scaled UI font id at lookup // time, so layout and drawing stay consistent with no call-site changes. Reader diff --git a/platformio.ini b/platformio.ini index 21a63032..dc38b9ab 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,6 +66,7 @@ lib_deps = SDCardManager=symlink://freeink-sdk/libs/hardware/SDCardManager BoardConfig=symlink://freeink-sdk/libs/hardware/BoardConfig PowerManager=symlink://freeink-sdk/libs/hardware/PowerManager + Icons=symlink://freeink-sdk/libs/assets/Icons bblanchon/ArduinoJson @ 7.4.2 ricmoo/QRCode @ 0.0.1 bitbank2/PNGdec @ 1.1.6 diff --git a/src/MappedInputManager.cpp b/src/MappedInputManager.cpp index 5e45e7df..ce0e524f 100644 --- a/src/MappedInputManager.cpp +++ b/src/MappedInputManager.cpp @@ -2,6 +2,7 @@ #include +#include #include #include "CrossPointSettings.h" @@ -118,6 +119,21 @@ bool MappedInputManager::wasCoverTapped(int& id) const { return TouchRegistry::getInstance().hitTest(lx, ly, TouchRegistry::Cover, id); } +bool MappedInputManager::wasListScroll(int& index, int count, int pageItems) const { + if (count <= 0) return false; + if (pageItems < 1) pageItems = 1; + const SwipeDir swipe = wasSwipe(); + if (swipe == SwipeDir::Up) { + index = std::min(index + pageItems, count - 1); + return true; + } + if (swipe == SwipeDir::Down) { + index = std::max(index - pageItems, 0); + return true; + } + return false; +} + MappedInputManager::SwipeDir MappedInputManager::wasSwipe() const { float nxs = 0.0f, nys = 0.0f, nxe = 0.0f, nye = 0.0f; if (!gpio.wasSwipe(nxs, nys, nxe, nye)) return SwipeDir::None; diff --git a/src/MappedInputManager.h b/src/MappedInputManager.h index cbf2281e..03cbb5b7 100644 --- a/src/MappedInputManager.h +++ b/src/MappedInputManager.h @@ -41,6 +41,11 @@ class MappedInputManager { // Swipe direction in the current logical (oriented) frame, or None. A swipe also // raises the tap helpers above, so check this first and consume it. SwipeDir wasSwipe() const; + // Page-scroll a list selection by a vertical swipe (touch nav without buttons): + // swipe up advances down the list, swipe down moves up, by pageItems, clamped to + // [0, count-1]. Updates index and returns true when a vertical swipe occurred, so + // callers can requestUpdate() and return before the tap handlers run. + bool wasListScroll(int& index, int count, int pageItems) const; bool wasAnyPressed() const; bool wasAnyReleased() const; unsigned long getHeldTime() const; diff --git a/src/activities/home/FileBrowserActivity.cpp b/src/activities/home/FileBrowserActivity.cpp index 9c6d0896..b8fef609 100644 --- a/src/activities/home/FileBrowserActivity.cpp +++ b/src/activities/home/FileBrowserActivity.cpp @@ -206,6 +206,14 @@ void FileBrowserActivity::loop() { const int pathReserved = renderer.getLineHeight(SMALL_FONT_ID) + UITheme::getInstance().getMetrics().verticalSpacing; const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false, pathReserved); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + int scrollIdx = static_cast(selectorIndex); + if (mappedInput.wasListScroll(scrollIdx, static_cast(files.size()), pageItems)) { + selectorIndex = scrollIdx; + requestUpdate(); + return; + } + // Touch-down moves the selector to the pressed entry (shows selected state); release // opens it below. int downId = -1; diff --git a/src/activities/home/RecentBooksActivity.cpp b/src/activities/home/RecentBooksActivity.cpp index 59d3a9fc..830dc89e 100644 --- a/src/activities/home/RecentBooksActivity.cpp +++ b/src/activities/home/RecentBooksActivity.cpp @@ -44,6 +44,14 @@ void RecentBooksActivity::onExit() { void RecentBooksActivity::loop() { const int pageItems = UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, true); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + int scrollIdx = static_cast(selectorIndex); + if (mappedInput.wasListScroll(scrollIdx, static_cast(recentBooks.size()), pageItems)) { + selectorIndex = scrollIdx; + requestUpdate(); + return; + } + // After a long-press has fired, swallow input until Confirm is physically released // (so the release doesn't also open the book; re-arm only once the button is up). if (longPressFired) { diff --git a/src/activities/network/WifiSelectionActivity.cpp b/src/activities/network/WifiSelectionActivity.cpp index 2393da4b..ae446f81 100644 --- a/src/activities/network/WifiSelectionActivity.cpp +++ b/src/activities/network/WifiSelectionActivity.cpp @@ -409,6 +409,14 @@ void WifiSelectionActivity::loop() { // Handle network list state if (state == WifiSelectionState::NETWORK_LIST) { + // Vertical swipe page-scrolls the network list (touch nav without the side buttons). + int scrollIdx = static_cast(selectedNetworkIndex); + if (mappedInput.wasListScroll(scrollIdx, static_cast(networks.size()), + UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, false))) { + selectedNetworkIndex = scrollIdx; + requestUpdate(); + return; + } // Touch: down-select highlights the pressed network, tap selects it (like Confirm). int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0 && downId < static_cast(networks.size())) { diff --git a/src/activities/reader/EpubReaderBookmarksActivity.cpp b/src/activities/reader/EpubReaderBookmarksActivity.cpp index 0a25c243..0ac165ac 100644 --- a/src/activities/reader/EpubReaderBookmarksActivity.cpp +++ b/src/activities/reader/EpubReaderBookmarksActivity.cpp @@ -104,6 +104,12 @@ void EpubReaderBookmarksActivity::loop() { } if (confirmingDelete < DELETE_MODE_DISPLAY) { + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + const int pageItems = GUI.getListPageItems(getListHeight(renderer), true); + if (mappedInput.wasListScroll(selectorIndex, static_cast(bookmarks.size()), pageItems)) { + requestUpdate(); + return; + } int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0 && downId < static_cast(bookmarks.size())) { selectorIndex = downId; diff --git a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp index 853b47d8..22d92224 100644 --- a/src/activities/reader/EpubReaderChapterSelectionActivity.cpp +++ b/src/activities/reader/EpubReaderChapterSelectionActivity.cpp @@ -31,6 +31,12 @@ void EpubReaderChapterSelectionActivity::loop() { const int pageItems = UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, false); const int totalItems = getTotalItems(); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectorIndex, totalItems, pageItems)) { + requestUpdate(); + return; + } + int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0 && downId < totalItems) { selectorIndex = downId; diff --git a/src/activities/reader/EpubReaderMenuActivity.cpp b/src/activities/reader/EpubReaderMenuActivity.cpp index 08c7d18c..dbe12247 100644 --- a/src/activities/reader/EpubReaderMenuActivity.cpp +++ b/src/activities/reader/EpubReaderMenuActivity.cpp @@ -57,6 +57,13 @@ void EpubReaderMenuActivity::loop() { requestUpdate(); }); + // Vertical swipe page-scrolls the menu (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectedIndex, static_cast(menuItems.size()), + UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, false))) { + requestUpdate(); + return; + } + // Touch-down moves the selection to the pressed item (shows selected state), like // moving with Up/Down; release activates it below. int downId = -1; diff --git a/src/activities/settings/FontDownloadActivity.cpp b/src/activities/settings/FontDownloadActivity.cpp index 0ccae794..cc381b4b 100644 --- a/src/activities/settings/FontDownloadActivity.cpp +++ b/src/activities/settings/FontDownloadActivity.cpp @@ -431,6 +431,11 @@ void FontDownloadActivity::loop() { const int listSize = listItemCount(); const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectedIndex_, listSize, pageItems)) { + requestUpdate(); + return; + } buttonNavigator_.onNextRelease([this, listSize] { selectedIndex_ = ButtonNavigator::nextIndex(selectedIndex_, listSize); diff --git a/src/activities/settings/FontSelectionActivity.cpp b/src/activities/settings/FontSelectionActivity.cpp index f5b0b0c7..dbdcb52e 100644 --- a/src/activities/settings/FontSelectionActivity.cpp +++ b/src/activities/settings/FontSelectionActivity.cpp @@ -54,6 +54,14 @@ void FontSelectionActivity::loop() { return; } + const int listSize = static_cast(fonts_.size()); + const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectedIndex_, listSize, pageItems)) { + requestUpdate(); + return; + } + int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0) { selectedIndex_ = downId; @@ -72,9 +80,6 @@ void FontSelectionActivity::loop() { return; } - const int listSize = static_cast(fonts_.size()); - const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false); - buttonNavigator_.onNextRelease([this, listSize] { selectedIndex_ = ButtonNavigator::nextIndex(selectedIndex_, listSize); requestUpdate(); diff --git a/src/activities/settings/LanguageSelectActivity.cpp b/src/activities/settings/LanguageSelectActivity.cpp index ff0be608..d60a3a20 100644 --- a/src/activities/settings/LanguageSelectActivity.cpp +++ b/src/activities/settings/LanguageSelectActivity.cpp @@ -32,6 +32,13 @@ void LanguageSelectActivity::loop() { return; } + const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false); + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectedIndex, totalItems, pageItems)) { + requestUpdate(); + return; + } + int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0) { selectedIndex = downId; @@ -50,8 +57,6 @@ void LanguageSelectActivity::loop() { return; } - const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false); - // Handle navigation buttonNavigator.onNextRelease([this] { selectedIndex = ButtonNavigator::nextIndex(static_cast(selectedIndex), totalItems); diff --git a/src/activities/settings/OpdsServerListActivity.cpp b/src/activities/settings/OpdsServerListActivity.cpp index 4a0c367f..f0667afd 100644 --- a/src/activities/settings/OpdsServerListActivity.cpp +++ b/src/activities/settings/OpdsServerListActivity.cpp @@ -41,6 +41,13 @@ void OpdsServerListActivity::loop() { return; } + // Vertical swipe page-scrolls the list (touch nav without the side buttons). + if (mappedInput.wasListScroll(selectedIndex, getItemCount(), + UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, false))) { + requestUpdate(); + return; + } + int downId = -1; if (mappedInput.wasItemTouchedDown(downId) && downId >= 0) { selectedIndex = downId; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index fde3fc83..8374ce4b 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -130,6 +130,17 @@ void SettingsActivity::loop() { selectedSettingIndex = 0; hasChangedCategory = true; requestUpdate(); + } else if (swipe == MappedInputManager::SwipeDir::Up || swipe == MappedInputManager::SwipeDir::Down) { + // Vertical swipe scrolls the settings list a page at a time (touch navigation + // without the side buttons). Swipe up moves down the list, and vice versa. + const int page = std::max( + 1, UITheme::getNumberOfItemsPerPage(renderer, true, true, BaseTheme::showButtonHints(), false)); + if (swipe == MappedInputManager::SwipeDir::Up) { + selectedSettingIndex = std::min(selectedSettingIndex + page, settingsCount); + } else { + selectedSettingIndex = std::max(selectedSettingIndex - page, 0); + } + requestUpdate(); } // Tap a settings row to select + activate it. Row 0 is the tab bar, so the list diff --git a/src/components/UITheme.cpp b/src/components/UITheme.cpp index 1494361a..ff510912 100644 --- a/src/components/UITheme.cpp +++ b/src/components/UITheme.cpp @@ -50,10 +50,10 @@ ThemeMetrics scaleThemeMetrics(const ThemeMetrics& b, float s) { m.homeMenuTopOffset = sp(b.homeMenuTopOffset, s); m.buttonHintsHeight = sp(b.buttonHintsHeight, s); m.sideButtonHintsWidth = sp(b.sideButtonHintsWidth, s); - m.progressBarHeight = sp(b.progressBarHeight, s); - m.progressBarMarginTop = sp(b.progressBarMarginTop, s); - m.statusBarHorizontalMargin = sp(b.statusBarHorizontalMargin, s); - m.statusBarVerticalMargin = sp(b.statusBarVerticalMargin, s); + // Status-bar metrics are intentionally NOT scaled: it's compact reader chrome + // (with the un-remapped SMALL font), and scaling it would eat reading area and + // bloat the customise-status-bar preview. progressBarHeight / progressBarMarginTop + // / statusBar*Margin keep their base values. m.keyboardKeyWidth = sp(b.keyboardKeyWidth, s); m.keyboardKeyHeight = sp(b.keyboardKeyHeight, s); m.keyboardKeySpacing = sp(b.keyboardKeySpacing, s); diff --git a/src/components/icons/generated_icons.h b/src/components/icons/generated_icons.h new file mode 100644 index 00000000..5ebeadc2 --- /dev/null +++ b/src/components/icons/generated_icons.h @@ -0,0 +1,126 @@ +#pragma once + +#include "Icon.h" + +// Generated by libs/assets/Icons/tools/gen_icons.py from Lucide SVGs. Do not edit. +// Sizes: 24, 32, 40, 48px. Icons: 12. + +// folder (lucide: folder) +static const uint8_t icon_folder_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0x3F, 0xFF, 0x9F, 0x9F, 0xFF, 0x9F, 0xC0, 0x07, 0x9F, 0xE0, 0x03, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0xC0, 0x00, 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_folder_24 = {24, 24, 12, icon_folder_24_bits}; +static const uint8_t icon_folder_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xC7, 0xE1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF8, 0x00, 0x07, 0x8F, 0xFC, 0x00, 0x03, 0x8F, 0xFF, 0xFF, 0xE3, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0xCF, 0xFF, 0xFF, 0xF3, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_folder_32 = {32, 32, 16, icon_folder_32_bits}; +static const uint8_t icon_folder_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xC7, 0xFE, 0x1F, 0xFF, 0xFF, 0xC7, 0xFE, 0x00, 0x00, 0x3F, 0xC7, 0xFF, 0x00, 0x00, 0x0F, 0xC7, 0xFF, 0x80, 0x00, 0x07, 0xC7, 0xFF, 0xE0, 0x00, 0x03, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC3, 0xFF, 0xFF, 0xFF, 0xC3, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_folder_40 = {40, 40, 19, icon_folder_40_bits}; +static const uint8_t icon_folder_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xC3, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xC3, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xC3, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_folder_48 = {48, 48, 24, icon_folder_48_bits}; + +// text (lucide: file-text) +static const uint8_t icon_text_24_bits[] = {0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xF0, 0x00, 0x7F, 0xE7, 0xF8, 0x3F, 0xE7, 0xF9, 0x1F, 0xE7, 0xF9, 0x8F, 0xE7, 0xF9, 0xC7, 0xE7, 0xF8, 0x07, 0xE6, 0x1C, 0x07, 0xE6, 0x1F, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE6, 0x00, 0x67, 0xE6, 0x00, 0x67, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE6, 0x00, 0x67, 0xE6, 0x00, 0x67, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xF0, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_text_24 = {24, 24, 12, icon_text_24_bits}; +static const uint8_t icon_text_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xF1, 0xFF, 0x80, 0xFF, 0xF1, 0xFF, 0x88, 0x7F, 0xF1, 0xFF, 0x8C, 0x3F, 0xF1, 0xFF, 0x8E, 0x1F, 0xF1, 0xFF, 0x8F, 0x1F, 0xF1, 0xFF, 0x80, 0x0F, 0xF1, 0xFF, 0xC0, 0x0F, 0xF1, 0xC3, 0xE0, 0x0F, 0xF1, 0xC3, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xC0, 0x03, 0x8F, 0xF1, 0x80, 0x01, 0x8F, 0xF1, 0xC0, 0x03, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xC0, 0x03, 0x8F, 0xF1, 0x80, 0x01, 0x8F, 0xF1, 0xC0, 0x03, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF8, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_text_32 = {32, 32, 16, icon_text_32_bits}; +static const uint8_t icon_text_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x7F, 0xFC, 0x07, 0xFF, 0xF8, 0xFF, 0xFC, 0x43, 0xFF, 0xF8, 0xFF, 0xFC, 0x61, 0xFF, 0xF8, 0xFF, 0xFC, 0x70, 0xFF, 0xF8, 0xFF, 0xFC, 0x78, 0x7F, 0xF8, 0xFF, 0xFC, 0x7C, 0x3F, 0xF8, 0xFF, 0xFC, 0x7E, 0x1F, 0xF8, 0xFF, 0xFC, 0x00, 0x1F, 0xF8, 0xF8, 0x7C, 0x00, 0x1F, 0xF8, 0xF0, 0x3E, 0x00, 0x1F, 0xF8, 0xF0, 0x3F, 0xFF, 0x1F, 0xF8, 0xF8, 0x7F, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xF0, 0x00, 0x0F, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x7F, 0xFF, 0xFE, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_text_40 = {40, 40, 20, icon_text_40_bits}; +static const uint8_t icon_text_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xC2, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0x07, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0x83, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC1, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xE0, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xF0, 0x7F, 0xFC, 0x3F, 0xFF, 0xC3, 0xF8, 0x7F, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFC, 0x3E, 0x07, 0xE0, 0x00, 0x3F, 0xFC, 0x3C, 0x03, 0xF0, 0x00, 0x3F, 0xFC, 0x3C, 0x03, 0xFF, 0xFC, 0x3F, 0xFC, 0x3E, 0x07, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3E, 0x00, 0x00, 0x7C, 0x3F, 0xFC, 0x3C, 0x00, 0x00, 0x3C, 0x3F, 0xFC, 0x3C, 0x00, 0x00, 0x3C, 0x3F, 0xFC, 0x3E, 0x00, 0x00, 0x7C, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3E, 0x00, 0x00, 0x7C, 0x3F, 0xFC, 0x3C, 0x00, 0x00, 0x3C, 0x3F, 0xFC, 0x3C, 0x00, 0x00, 0x3C, 0x3F, 0xFC, 0x3E, 0x00, 0x00, 0x7C, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_text_48 = {48, 48, 24, icon_text_48_bits}; + +// image (lucide: image) +static const uint8_t icon_image_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xCF, 0xFF, 0xF3, 0xCF, 0xFF, 0xF3, 0xCF, 0x3F, 0xF3, 0xCE, 0x1F, 0xF3, 0xCC, 0xCF, 0xF3, 0xCC, 0xCF, 0xF3, 0xCE, 0x1F, 0x73, 0xCF, 0x3C, 0x13, 0xCF, 0xF8, 0x83, 0xCF, 0xF1, 0xC3, 0xCF, 0xE3, 0xE3, 0xCF, 0xC7, 0xF3, 0xCF, 0x8F, 0xF3, 0xCF, 0x1F, 0xF3, 0xCE, 0x3F, 0xF3, 0xCC, 0x7F, 0xF3, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_image_24 = {24, 24, 12, icon_image_24_bits}; +static const uint8_t icon_image_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x07, 0xE3, 0xFF, 0xFF, 0xC7, 0xE7, 0xFF, 0xFF, 0xE7, 0xE7, 0xFF, 0xFF, 0xE7, 0xE7, 0xC3, 0xFF, 0xE7, 0xE7, 0x81, 0xFF, 0xE7, 0xE7, 0x00, 0xFF, 0xE7, 0xE7, 0x18, 0xFF, 0xE7, 0xE7, 0x18, 0xFF, 0xE7, 0xE7, 0x00, 0xFF, 0xE7, 0xE7, 0x81, 0xF0, 0xE7, 0xE7, 0xC3, 0xE0, 0x67, 0xE7, 0xFF, 0xC0, 0x07, 0xE7, 0xFF, 0x8F, 0x07, 0xE7, 0xFF, 0x1F, 0x87, 0xE7, 0xFE, 0x3F, 0xC7, 0xE7, 0xFC, 0x7F, 0xC7, 0xE7, 0xF8, 0xFF, 0xE7, 0xE7, 0xF1, 0xFF, 0xE7, 0xE7, 0xE3, 0xFF, 0xE7, 0xE7, 0xC7, 0xFF, 0xE7, 0xE7, 0x8F, 0xFF, 0xE7, 0xE2, 0x0F, 0xFF, 0xC7, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_image_32 = {32, 32, 16, icon_image_32_bits}; +static const uint8_t icon_image_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xE1, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xF8, 0x7F, 0xFF, 0x87, 0xE1, 0xF0, 0x3F, 0xFF, 0x87, 0xE1, 0xE0, 0x1F, 0xFF, 0x87, 0xE1, 0xC3, 0x0F, 0xFF, 0x87, 0xE1, 0xC7, 0x8F, 0xFF, 0x87, 0xE1, 0xC7, 0x8F, 0xFF, 0x87, 0xE1, 0xC3, 0x0F, 0xFF, 0x87, 0xE1, 0xE0, 0x1F, 0xC7, 0x87, 0xE1, 0xF0, 0x3F, 0x01, 0x87, 0xE1, 0xF8, 0x7E, 0x00, 0x87, 0xE1, 0xFF, 0xFC, 0x00, 0x07, 0xE1, 0xFF, 0xF8, 0x38, 0x07, 0xE1, 0xFF, 0xF0, 0x7C, 0x07, 0xE1, 0xFF, 0xE0, 0xFE, 0x07, 0xE1, 0xFF, 0xC1, 0xFF, 0x07, 0xE1, 0xFF, 0x83, 0xFF, 0x87, 0xE1, 0xFF, 0x07, 0xFF, 0x87, 0xE1, 0xFE, 0x0F, 0xFF, 0x87, 0xE1, 0xFC, 0x1F, 0xFF, 0x87, 0xE1, 0xF8, 0x3F, 0xFF, 0x87, 0xE1, 0xF0, 0x7F, 0xFF, 0x87, 0xE1, 0xE0, 0xFF, 0xFF, 0x87, 0xF1, 0xC1, 0xFF, 0xFF, 0x8F, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_image_40 = {40, 40, 20, icon_image_40_bits}; +static const uint8_t icon_image_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xFF, 0xFF, 0x0F, 0xF0, 0xFC, 0x03, 0xFF, 0xFF, 0x0F, 0xF0, 0xF8, 0x01, 0xFF, 0xFF, 0x0F, 0xF0, 0xF8, 0x01, 0xFF, 0xFF, 0x0F, 0xF0, 0xF0, 0x60, 0xFF, 0xFF, 0x0F, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0xF0, 0x60, 0xFF, 0xFF, 0x0F, 0xF0, 0xF8, 0x01, 0xFF, 0xFF, 0x0F, 0xF0, 0xF8, 0x01, 0xFC, 0x0F, 0x0F, 0xF0, 0xFC, 0x03, 0xF8, 0x07, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x03, 0x0F, 0xF0, 0xFF, 0xFF, 0xE0, 0x01, 0x0F, 0xF0, 0xFF, 0xFF, 0xC1, 0xE0, 0x0F, 0xF0, 0xFF, 0xFF, 0x83, 0xF0, 0x0F, 0xF0, 0xFF, 0xFF, 0x07, 0xF8, 0x0F, 0xF0, 0xFF, 0xFE, 0x0F, 0xFC, 0x0F, 0xF0, 0xFF, 0xFC, 0x1F, 0xFE, 0x0F, 0xF0, 0xFF, 0xF8, 0x3F, 0xFF, 0x0F, 0xF0, 0xFF, 0xF0, 0x7F, 0xFF, 0x0F, 0xF0, 0xFF, 0xE0, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC1, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0x83, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0x07, 0xFF, 0xFF, 0x0F, 0xF0, 0xFE, 0x0F, 0xFF, 0xFF, 0x0F, 0xF0, 0xFC, 0x1F, 0xFF, 0xFF, 0x0F, 0xF0, 0xF8, 0x3F, 0xFF, 0xFF, 0x0F, 0xF0, 0x70, 0x7F, 0xFF, 0xFE, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_image_48 = {48, 48, 24, icon_image_48_bits}; + +// book (lucide: book-open) +static const uint8_t icon_book_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3C, 0x03, 0x80, 0x18, 0x01, 0x9F, 0xC3, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x80, 0x00, 0x01, 0xC0, 0x00, 0x03, 0xFF, 0xC3, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_book_24 = {24, 24, 11, icon_book_24_bits}; +static const uint8_t icon_book_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x01, 0x80, 0x03, 0x8F, 0xF0, 0x0F, 0xF1, 0x8F, 0xFC, 0x3F, 0xF1, 0x8F, 0xFC, 0x3F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0x8F, 0xFE, 0x7F, 0xF1, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_book_32 = {32, 32, 14, icon_book_32_bits}; +static const uint8_t icon_book_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xC0, 0x1F, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xC0, 0x00, 0x18, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xC7, 0xFF, 0x00, 0xFF, 0xE3, 0xC7, 0xFF, 0x81, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC0, 0x00, 0xC3, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_book_40 = {40, 40, 18, icon_book_40_bits}; +static const uint8_t icon_book_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x03, 0xC0, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xC3, 0xFF, 0xC0, 0x07, 0xFF, 0xC3, 0xC3, 0xFF, 0xF0, 0x0F, 0xFF, 0xC3, 0xC3, 0xFF, 0xF8, 0x1F, 0xFF, 0xC3, 0xC3, 0xFF, 0xF8, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC0, 0x00, 0x0C, 0x30, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_book_48 = {48, 48, 21, icon_book_48_bits}; + +// file (lucide: file) +static const uint8_t icon_file_24_bits[] = {0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xF0, 0x00, 0x7F, 0xE7, 0xF8, 0x3F, 0xE7, 0xF9, 0x1F, 0xE7, 0xF9, 0x8F, 0xE7, 0xF9, 0xC7, 0xE7, 0xF8, 0x07, 0xE7, 0xFC, 0x07, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xE7, 0xFF, 0xE7, 0xF0, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_file_24 = {24, 24, 11, icon_file_24_bits}; +static const uint8_t icon_file_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xF1, 0xFF, 0x80, 0xFF, 0xF1, 0xFF, 0x88, 0x7F, 0xF1, 0xFF, 0x8C, 0x3F, 0xF1, 0xFF, 0x8E, 0x1F, 0xF1, 0xFF, 0x8F, 0x1F, 0xF1, 0xFF, 0x80, 0x0F, 0xF1, 0xFF, 0xC0, 0x0F, 0xF1, 0xFF, 0xE0, 0x0F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x8F, 0xF8, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_file_32 = {32, 32, 15, icon_file_32_bits}; +static const uint8_t icon_file_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x7F, 0xFC, 0x07, 0xFF, 0xF8, 0xFF, 0xFC, 0x43, 0xFF, 0xF8, 0xFF, 0xFC, 0x61, 0xFF, 0xF8, 0xFF, 0xFC, 0x70, 0xFF, 0xF8, 0xFF, 0xFC, 0x78, 0x7F, 0xF8, 0xFF, 0xFC, 0x7C, 0x3F, 0xF8, 0xFF, 0xFC, 0x7E, 0x1F, 0xF8, 0xFF, 0xFC, 0x00, 0x1F, 0xF8, 0xFF, 0xFC, 0x00, 0x1F, 0xF8, 0xFF, 0xFE, 0x00, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x7F, 0xFF, 0xFE, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_file_40 = {40, 40, 19, icon_file_40_bits}; +static const uint8_t icon_file_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xC2, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0x07, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0x83, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC1, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xE0, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xF0, 0x7F, 0xFC, 0x3F, 0xFF, 0xC3, 0xF8, 0x7F, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x3F, 0xFC, 0x3F, 0xFF, 0xF0, 0x00, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_file_48 = {48, 48, 23, icon_file_48_bits}; + +// recent (lucide: clock) +static const uint8_t icon_recent_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFE, 0x00, 0x7F, 0xF8, 0x7E, 0x1F, 0xF1, 0xFF, 0x8F, 0xE3, 0xE7, 0xC7, 0xE7, 0xE7, 0xE7, 0xCF, 0xE7, 0xF3, 0xCF, 0xE7, 0xF3, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE7, 0xF9, 0x9F, 0xE1, 0xF9, 0x9F, 0xF8, 0x79, 0x9F, 0xFE, 0x79, 0xCF, 0xFF, 0xF3, 0xCF, 0xFF, 0xF3, 0xE7, 0xFF, 0xE7, 0xE3, 0xFF, 0xC7, 0xF1, 0xFF, 0x8F, 0xF8, 0x7E, 0x1F, 0xFE, 0x00, 0x7F, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_recent_24 = {24, 24, 11, icon_recent_24_bits}; +static const uint8_t icon_recent_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFE, 0x07, 0xE0, 0x7F, 0xFC, 0x3F, 0xFC, 0x3F, 0xF8, 0x7F, 0xFE, 0x1F, 0xF1, 0xFE, 0x7F, 0x8F, 0xF1, 0xFE, 0x7F, 0x8F, 0xE3, 0xFE, 0x7F, 0xC7, 0xC7, 0xFE, 0x7F, 0xE7, 0xC7, 0xFE, 0x7F, 0xE3, 0xCF, 0xFE, 0x7F, 0xE3, 0xCF, 0xFE, 0x7F, 0xF3, 0xCF, 0xFE, 0x7F, 0xF3, 0x8F, 0xFE, 0x3F, 0xF1, 0x8F, 0xFE, 0x0F, 0xF1, 0xCF, 0xFF, 0x03, 0xF3, 0xCF, 0xFF, 0xC1, 0xF3, 0xC7, 0xFF, 0xF3, 0xE3, 0xC7, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xE7, 0xE3, 0xFF, 0xFF, 0xC7, 0xF1, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0x0F, 0xF8, 0x7F, 0xFE, 0x1F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFE, 0x07, 0xE0, 0x7F, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_recent_32 = {32, 32, 15, icon_recent_32_bits}; +static const uint8_t icon_recent_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0xFF, 0x01, 0xFF, 0xFF, 0x07, 0xFF, 0xE0, 0xFF, 0xFE, 0x0F, 0xFF, 0xF0, 0x7F, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0xF8, 0x7F, 0xE7, 0xFE, 0x1F, 0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xE1, 0xFF, 0xC3, 0xFF, 0x87, 0xE3, 0xFF, 0xC3, 0xFF, 0xC7, 0xE3, 0xFF, 0xC3, 0xFF, 0xC7, 0xC3, 0xFF, 0xC3, 0xFF, 0xC3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC3, 0xFF, 0xE3, 0xC7, 0xFF, 0xC1, 0xFF, 0xE3, 0xC7, 0xFF, 0xE0, 0x7F, 0xE3, 0xC7, 0xFF, 0xE0, 0x1F, 0xE3, 0xC7, 0xFF, 0xF8, 0x0F, 0xE3, 0xC7, 0xFF, 0xFE, 0x0F, 0xE3, 0xC3, 0xFF, 0xFF, 0x8F, 0xC3, 0xE3, 0xFF, 0xFF, 0xFF, 0xC7, 0xE3, 0xFF, 0xFF, 0xFF, 0xC7, 0xE1, 0xFF, 0xFF, 0xFF, 0x87, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0x0F, 0xF8, 0x7F, 0xFF, 0xFE, 0x1F, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0xFE, 0x0F, 0xFF, 0xF0, 0x7F, 0xFF, 0x07, 0xFF, 0xE0, 0xFF, 0xFF, 0x80, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_recent_40 = {40, 40, 19, icon_recent_40_bits}; +static const uint8_t icon_recent_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xF0, 0x07, 0xFF, 0xFF, 0xC0, 0x7F, 0xFE, 0x03, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFE, 0x0F, 0xFE, 0x7F, 0xF0, 0x7F, 0xFC, 0x1F, 0xFC, 0x3F, 0xF8, 0x3F, 0xF8, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0x7F, 0xFC, 0x3F, 0xFE, 0x1F, 0xF0, 0x7F, 0xFC, 0x3F, 0xFE, 0x0F, 0xF0, 0xFF, 0xFC, 0x3F, 0xFF, 0x0F, 0xE0, 0xFF, 0xFC, 0x3F, 0xFF, 0x07, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x3F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x1F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x07, 0xFF, 0xC3, 0xC3, 0xFF, 0xFE, 0x01, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0x80, 0x7F, 0xC3, 0xC3, 0xFF, 0xFF, 0xE0, 0x3F, 0xC3, 0xE1, 0xFF, 0xFF, 0xF8, 0x3F, 0x87, 0xE1, 0xFF, 0xFF, 0xFE, 0x7F, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0xFE, 0x1F, 0xF8, 0x3F, 0xFF, 0xFF, 0xFC, 0x1F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xC0, 0x7F, 0xFE, 0x03, 0xFF, 0xFF, 0xE0, 0x0F, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_recent_48 = {48, 48, 23, icon_recent_48_bits}; + +// settings (lucide: settings) +static const uint8_t icon_settings_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0x99, 0xFF, 0xF0, 0x3C, 0x0F, 0xE0, 0x7E, 0x07, 0xCF, 0xFF, 0xF3, 0xCF, 0xC3, 0xF3, 0xC7, 0x81, 0xE3, 0xE3, 0x18, 0xC7, 0xF3, 0x3C, 0xCF, 0xF3, 0x3C, 0xCF, 0xE3, 0x18, 0xC7, 0xC7, 0x81, 0xE3, 0xCF, 0xC3, 0xF3, 0xCF, 0xFF, 0xF3, 0xE0, 0x7E, 0x07, 0xF0, 0x3C, 0x0F, 0xFF, 0x99, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_settings_24 = {24, 24, 11, icon_settings_24_bits}; +static const uint8_t icon_settings_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xF0, 0x03, 0xC0, 0x0F, 0xF0, 0x07, 0xE0, 0x0F, 0xE3, 0x9F, 0xF9, 0xC7, 0xE7, 0xFF, 0xFF, 0xE7, 0xE7, 0xF8, 0x1F, 0xE7, 0xE3, 0xF0, 0x0F, 0xC7, 0xF1, 0xE1, 0x87, 0x8F, 0xF8, 0xE3, 0xC7, 0x1F, 0xF8, 0xE7, 0xE7, 0x1F, 0xF8, 0xE7, 0xE7, 0x1F, 0xF8, 0xE3, 0xC7, 0x1F, 0xF1, 0xE1, 0x87, 0x8F, 0xE3, 0xF0, 0x0F, 0xC7, 0xE7, 0xF8, 0x1F, 0xE7, 0xE7, 0xFF, 0xFF, 0xE7, 0xE3, 0x9F, 0xF9, 0xC7, 0xF0, 0x07, 0xE0, 0x0F, 0xF0, 0x03, 0xC0, 0x1F, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xF3, 0xCF, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_settings_32 = {32, 32, 15, icon_settings_32_bits}; +static const uint8_t icon_settings_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x18, 0x7F, 0xFF, 0xFF, 0xFE, 0x3C, 0x7F, 0xFF, 0xFF, 0xFC, 0x3C, 0x3F, 0xFF, 0xFE, 0x18, 0x7E, 0x18, 0x7F, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xF0, 0xC1, 0xFF, 0x83, 0x0F, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xF1, 0xFF, 0xE7, 0xFF, 0x8F, 0xF1, 0xFF, 0x00, 0xFF, 0x8F, 0xF0, 0xFE, 0x00, 0x7F, 0x0F, 0xF0, 0x7C, 0x00, 0x3E, 0x0F, 0xF8, 0x7C, 0x3C, 0x3E, 0x1F, 0xFC, 0x3C, 0x7E, 0x3C, 0x3F, 0xFE, 0x38, 0x7E, 0x1C, 0x7F, 0xFE, 0x38, 0x7E, 0x1C, 0x7F, 0xFC, 0x3C, 0x7E, 0x3C, 0x3F, 0xF8, 0x7C, 0x3C, 0x3E, 0x1F, 0xF0, 0x7C, 0x00, 0x3E, 0x0F, 0xF0, 0xFE, 0x00, 0x7F, 0x0F, 0xF1, 0xFF, 0x00, 0xFF, 0x8F, 0xF1, 0xFF, 0xE7, 0xFF, 0x8F, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0xC1, 0xFF, 0x83, 0x0F, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xFE, 0x18, 0x7E, 0x18, 0x7F, 0xFF, 0xFC, 0x3C, 0x3F, 0xFF, 0xFF, 0xFE, 0x3C, 0x7F, 0xFF, 0xFF, 0xFE, 0x18, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_settings_40 = {40, 40, 20, icon_settings_40_bits}; +static const uint8_t icon_settings_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x02, 0x07, 0xE0, 0x40, 0xFF, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x1F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xFC, 0x3F, 0xFF, 0x0F, 0xF0, 0xFF, 0xE0, 0x07, 0xFF, 0x0F, 0xF8, 0x7F, 0xC0, 0x03, 0xFE, 0x1F, 0xF8, 0x3F, 0x80, 0x01, 0xFC, 0x1F, 0xFC, 0x1F, 0x83, 0xC1, 0xF8, 0x3F, 0xFE, 0x1F, 0x87, 0xE1, 0xF8, 0x7F, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0xFE, 0x1F, 0x87, 0xE1, 0xF8, 0x7F, 0xFC, 0x1F, 0x83, 0xC1, 0xF8, 0x3F, 0xF8, 0x3F, 0x80, 0x01, 0xFC, 0x1F, 0xF8, 0x7F, 0xC0, 0x03, 0xFE, 0x1F, 0xF0, 0xFF, 0xE0, 0x07, 0xFF, 0x0F, 0xF0, 0xFF, 0xFC, 0x3F, 0xFF, 0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x3F, 0xFF, 0x02, 0x07, 0xE0, 0x40, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_settings_48 = {48, 48, 24, icon_settings_48_bits}; + +// transfer (lucide: arrow-down-up) +static const uint8_t icon_transfer_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x3F, 0xFC, 0xFE, 0x1F, 0xFC, 0xFC, 0x0F, 0xFC, 0xF8, 0x07, 0xFC, 0xF1, 0x23, 0xFC, 0xF3, 0x33, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xCC, 0xCF, 0x3F, 0xC4, 0x8F, 0x3F, 0xE0, 0x1F, 0x3F, 0xF0, 0x3F, 0x3F, 0xF8, 0x7F, 0x3F, 0xFC, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_transfer_24 = {24, 24, 12, icon_transfer_24_bits}; +static const uint8_t icon_transfer_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0x7F, 0xFF, 0x1F, 0xF0, 0x3F, 0xFF, 0x1F, 0xE0, 0x1F, 0xFF, 0x1F, 0xC0, 0x0F, 0xFF, 0x1F, 0x88, 0x87, 0xFF, 0x1F, 0x18, 0xC7, 0xFF, 0x1F, 0x38, 0xE7, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xE7, 0x1C, 0xF8, 0xFF, 0xE3, 0x18, 0xF8, 0xFF, 0xE1, 0x11, 0xF8, 0xFF, 0xF0, 0x03, 0xF8, 0xFF, 0xF8, 0x07, 0xF8, 0xFF, 0xFC, 0x0F, 0xF8, 0xFF, 0xFE, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_transfer_32 = {32, 32, 16, icon_transfer_32_bits}; +static const uint8_t icon_transfer_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xC3, 0xFF, 0xFF, 0xC7, 0xFF, 0x81, 0xFF, 0xFF, 0xC7, 0xFF, 0x00, 0xFF, 0xFF, 0xC7, 0xFE, 0x00, 0x7F, 0xFF, 0xC7, 0xFC, 0x00, 0x3F, 0xFF, 0xC7, 0xF8, 0x22, 0x1F, 0xFF, 0xC7, 0xF0, 0x63, 0x0F, 0xFF, 0xC7, 0xF0, 0xE3, 0x87, 0xFF, 0xC7, 0xF9, 0xE3, 0xCF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xF3, 0xC7, 0x9F, 0xE3, 0xFF, 0xE1, 0xC7, 0x0F, 0xE3, 0xFF, 0xF0, 0xC6, 0x0F, 0xE3, 0xFF, 0xF8, 0x44, 0x1F, 0xE3, 0xFF, 0xFC, 0x00, 0x3F, 0xE3, 0xFF, 0xFE, 0x00, 0x7F, 0xE3, 0xFF, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0x81, 0xFF, 0xE3, 0xFF, 0xFF, 0xC3, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_transfer_40 = {40, 40, 20, icon_transfer_40_bits}; +static const uint8_t icon_transfer_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xF0, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xF0, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xF0, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xF0, 0xFF, 0xC1, 0x08, 0x3F, 0xFF, 0xF0, 0xFF, 0x83, 0x0C, 0x1F, 0xFF, 0xF0, 0xFF, 0x07, 0x0E, 0x0F, 0xFF, 0xF0, 0xFF, 0x0F, 0x0F, 0x0F, 0xFF, 0xF0, 0xFF, 0x9F, 0x0F, 0x9F, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF9, 0xF0, 0xF9, 0xFF, 0x0F, 0xFF, 0xF0, 0xF0, 0xF0, 0xFF, 0x0F, 0xFF, 0xF0, 0x70, 0xE0, 0xFF, 0x0F, 0xFF, 0xF8, 0x30, 0xC1, 0xFF, 0x0F, 0xFF, 0xFC, 0x10, 0x83, 0xFF, 0x0F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_transfer_48 = {48, 48, 24, icon_transfer_48_bits}; + +// library (lucide: library-big) +static const uint8_t icon_library_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x19, 0xFF, 0xC0, 0x00, 0xFF, 0xCC, 0xC4, 0xFF, 0xCC, 0xCE, 0x7F, 0xCC, 0xC6, 0x7F, 0xCC, 0xC6, 0x7F, 0xCC, 0xC7, 0x3F, 0xCC, 0xC3, 0x3F, 0xCC, 0xC3, 0x3F, 0xCC, 0xC3, 0x9F, 0xCC, 0xC9, 0x9F, 0xCC, 0xC9, 0x9F, 0xCC, 0xCD, 0xCF, 0xCC, 0xCC, 0xCF, 0xCC, 0xCC, 0xE7, 0xCC, 0xCE, 0x67, 0xCC, 0xCE, 0x67, 0xCC, 0xCE, 0x67, 0xC0, 0x0F, 0x07, 0xE0, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_library_24 = {24, 24, 12, icon_library_24_bits}; +static const uint8_t icon_library_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0x0F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xE7, 0x18, 0x07, 0xFF, 0xE7, 0x18, 0xE3, 0xFF, 0xE7, 0x18, 0xE3, 0xFF, 0xE7, 0x18, 0x71, 0xFF, 0xE7, 0x18, 0x71, 0xFF, 0xE7, 0x18, 0x79, 0xFF, 0xE7, 0x18, 0x38, 0xFF, 0xE7, 0x18, 0x38, 0xFF, 0xE7, 0x18, 0x1C, 0xFF, 0xE7, 0x18, 0x1C, 0x7F, 0xE7, 0x18, 0x9C, 0x7F, 0xE7, 0x18, 0x8E, 0x7F, 0xE7, 0x18, 0x8E, 0x3F, 0xE7, 0x18, 0xCE, 0x3F, 0xE7, 0x18, 0xC7, 0x3F, 0xE7, 0x18, 0xC7, 0x1F, 0xE7, 0x18, 0xE7, 0x9F, 0xE7, 0x18, 0xE3, 0x8F, 0xE7, 0x18, 0xE3, 0x8F, 0xE7, 0x18, 0xF1, 0xCF, 0xE7, 0x18, 0xF1, 0xCF, 0xE7, 0x18, 0xF8, 0x0F, 0xE0, 0x00, 0xF8, 0x0F, 0xF0, 0x01, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_library_32 = {32, 32, 16, icon_library_32_bits}; +static const uint8_t icon_library_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x10, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xE1, 0xC7, 0x87, 0x1F, 0xFF, 0xE1, 0xC7, 0x8F, 0x1F, 0xFF, 0xE1, 0xC7, 0x87, 0x0F, 0xFF, 0xE1, 0xC7, 0x87, 0x8F, 0xFF, 0xE1, 0xC7, 0x87, 0x8F, 0xFF, 0xE1, 0xC7, 0x83, 0x87, 0xFF, 0xE1, 0xC7, 0x83, 0xC7, 0xFF, 0xE1, 0xC7, 0x83, 0xC3, 0xFF, 0xE1, 0xC7, 0x81, 0xE3, 0xFF, 0xE1, 0xC7, 0x81, 0xE3, 0xFF, 0xE1, 0xC7, 0x81, 0xE1, 0xFF, 0xE1, 0xC7, 0x80, 0xF1, 0xFF, 0xE1, 0xC7, 0x88, 0xF1, 0xFF, 0xE1, 0xC7, 0x88, 0x70, 0xFF, 0xE1, 0xC7, 0x8C, 0x78, 0xFF, 0xE1, 0xC7, 0x8C, 0x78, 0xFF, 0xE1, 0xC7, 0x8C, 0x38, 0x7F, 0xE1, 0xC7, 0x8E, 0x3C, 0x7F, 0xE1, 0xC7, 0x8E, 0x3C, 0x3F, 0xE1, 0xC7, 0x8E, 0x1C, 0x3F, 0xE1, 0xC7, 0x8F, 0x1E, 0x3F, 0xE1, 0xC7, 0x8F, 0x1E, 0x1F, 0xE1, 0xC7, 0x8F, 0x0F, 0x1F, 0xE1, 0xC7, 0x8F, 0x8F, 0x1F, 0xE1, 0xC7, 0x8F, 0x87, 0x0F, 0xE1, 0xC7, 0x8F, 0x87, 0x0F, 0xE0, 0x00, 0x0F, 0xC0, 0x1F, 0xF0, 0x00, 0x0F, 0xC0, 0x1F, 0xF0, 0x00, 0x1F, 0xE0, 0x7F, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_library_40 = {40, 40, 20, icon_library_40_bits}; +static const uint8_t icon_library_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xC7, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x10, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF8, 0x7F, 0xFF, 0xF0, 0xF0, 0xF0, 0xF8, 0x7F, 0xFF, 0xF0, 0xF0, 0xF0, 0x78, 0x7F, 0xFF, 0xF0, 0xF0, 0xF0, 0x7C, 0x3F, 0xFF, 0xF0, 0xF0, 0xF0, 0x7C, 0x3F, 0xFF, 0xF0, 0xF0, 0xF0, 0x3C, 0x3F, 0xFF, 0xF0, 0xF0, 0xF0, 0x3E, 0x1F, 0xFF, 0xF0, 0xF0, 0xF0, 0x1E, 0x1F, 0xFF, 0xF0, 0xF0, 0xF0, 0x1E, 0x0F, 0xFF, 0xF0, 0xF0, 0xF0, 0x1F, 0x0F, 0xFF, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0xFF, 0xF0, 0xF0, 0xF0, 0x0F, 0x07, 0xFF, 0xF0, 0xF0, 0xF0, 0x0F, 0x87, 0xFF, 0xF0, 0xF0, 0xF0, 0x87, 0x87, 0xFF, 0xF0, 0xF0, 0xF0, 0x87, 0xC3, 0xFF, 0xF0, 0xF0, 0xF0, 0x87, 0xC3, 0xFF, 0xF0, 0xF0, 0xF0, 0xC3, 0xC3, 0xFF, 0xF0, 0xF0, 0xF0, 0xC3, 0xE1, 0xFF, 0xF0, 0xF0, 0xF0, 0xC1, 0xE1, 0xFF, 0xF0, 0xF0, 0xF0, 0xE1, 0xE1, 0xFF, 0xF0, 0xF0, 0xF0, 0xE1, 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xE0, 0xF0, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x7F, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0x7F, 0xF0, 0xF0, 0xF0, 0xF8, 0x78, 0x7F, 0xF0, 0xF0, 0xF0, 0xF8, 0x7C, 0x3F, 0xF0, 0xF0, 0xF0, 0xF8, 0x7C, 0x3F, 0xF0, 0xF0, 0xF0, 0xFC, 0x3C, 0x3F, 0xF0, 0xF0, 0xF0, 0xFC, 0x3E, 0x1F, 0xF0, 0xF0, 0xF0, 0xFC, 0x3E, 0x1F, 0xF0, 0xF0, 0xF0, 0xFE, 0x10, 0x1F, 0xF0, 0x00, 0x00, 0xFE, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0xF8, 0x00, 0x01, 0xFF, 0x01, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_library_48 = {48, 48, 24, icon_library_48_bits}; + +// wifi (lucide: wifi) +static const uint8_t icon_wifi_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFC, 0x00, 0x1F, 0xF0, 0xFF, 0x0F, 0xC3, 0xFF, 0xC3, 0x8F, 0xFF, 0xF1, 0x9F, 0x81, 0xF9, 0xFE, 0x00, 0x7F, 0xF8, 0x7E, 0x1F, 0xF1, 0xFF, 0x8F, 0xF3, 0xFF, 0xCF, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_wifi_24 = {24, 24, 10, icon_wifi_24_bits}; +static const uint8_t icon_wifi_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xF8, 0x1F, 0xF8, 0x1F, 0xE0, 0x7F, 0xFE, 0x07, 0xC1, 0xFF, 0xFF, 0x83, 0x87, 0xFF, 0xFF, 0xE1, 0xCF, 0xF8, 0x1F, 0xF3, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFE, 0x1F, 0xF8, 0x7F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xC7, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_wifi_32 = {32, 32, 13, icon_wifi_32_bits}; +static const uint8_t icon_wifi_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF8, 0x0F, 0xFF, 0xF0, 0x1F, 0xE0, 0x7F, 0xFF, 0xFE, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xC3, 0xFF, 0xFF, 0xFF, 0xC3, 0xC7, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x7E, 0x01, 0xFF, 0xFF, 0x03, 0xFF, 0xC0, 0xFF, 0xFE, 0x0F, 0xFF, 0xF0, 0x7F, 0xFE, 0x1F, 0xFF, 0xF8, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x7E, 0x1F, 0xFF, 0xFF, 0xF9, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_wifi_40 = {40, 40, 16, icon_wifi_40_bits}; +static const uint8_t icon_wifi_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x3F, 0xFC, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xF8, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xF0, 0x3F, 0xFF, 0xFF, 0xFC, 0x0F, 0xC0, 0x7F, 0xFF, 0xFF, 0xFE, 0x03, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xC3, 0xFF, 0xF0, 0x0F, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xF0, 0x07, 0xFF, 0xFF, 0xC0, 0x7F, 0xFE, 0x03, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xE0, 0x7F, 0xFF, 0xFF, 0xFE, 0x1F, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_wifi_48 = {48, 48, 20, icon_wifi_48_bits}; + +// hotspot (lucide: router) +static const uint8_t icon_hotspot_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0x8F, 0xC7, 0xFF, 0x1F, 0xE3, 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x3F, 0xFF, 0xE7, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x03, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0x99, 0x9F, 0xF9, 0x99, 0x9F, 0xF9, 0x9F, 0xFF, 0xF9, 0x9F, 0xFF, 0xF9, 0xC0, 0x00, 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_hotspot_24 = {24, 24, 13, icon_hotspot_24_bits}; +static const uint8_t icon_hotspot_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xF0, 0x7E, 0x0F, 0xFF, 0xE1, 0xFF, 0x87, 0xFF, 0xE3, 0xFF, 0xC7, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFE, 0x18, 0x7F, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x03, 0xCF, 0xFF, 0xFF, 0xF3, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8E, 0x73, 0xFF, 0xF1, 0x8E, 0x73, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0x8F, 0xFF, 0xFF, 0xF1, 0xCF, 0xFF, 0xFF, 0xF3, 0xC0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_hotspot_32 = {32, 32, 18, icon_hotspot_32_bits}; +static const uint8_t icon_hotspot_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x03, 0xF0, 0x1F, 0xFF, 0xFC, 0x1F, 0xFE, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0x0F, 0xFF, 0xFE, 0x7F, 0x3F, 0xDF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xE3, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0x7F, 0xFF, 0xE3, 0xC7, 0x9E, 0x3F, 0xFF, 0xE3, 0xC7, 0x9E, 0x3F, 0xFF, 0xE3, 0xC7, 0xFF, 0x7F, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xE3, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_hotspot_40 = {40, 40, 22, icon_hotspot_40_bits}; +static const uint8_t icon_hotspot_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x3F, 0xC0, 0x3F, 0xFF, 0xFF, 0x80, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x87, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xDF, 0xE0, 0x7F, 0xBF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0x83, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xE7, 0xE7, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xE7, 0xE7, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_hotspot_48 = {48, 48, 28, icon_hotspot_48_bits}; + +// bookmark (lucide: bookmark) +static const uint8_t icon_bookmark_24_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xFF, 0xCF, 0xF3, 0xE7, 0xCF, 0xF3, 0x81, 0xCF, 0xF2, 0x18, 0x4F, 0xF0, 0x7E, 0x0F, 0xF9, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_bookmark_24 = {24, 24, 12, icon_bookmark_24_bits}; +static const uint8_t icon_bookmark_32_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0x3F, 0xFC, 0x7F, 0xFE, 0x3F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFF, 0xFF, 0x1F, 0xF8, 0xFC, 0x3F, 0x1F, 0xF8, 0xF0, 0x0F, 0x1F, 0xF8, 0xC1, 0x83, 0x1F, 0xF8, 0x03, 0xC0, 0x1F, 0xFC, 0x0F, 0xF0, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_bookmark_32 = {32, 32, 16, icon_bookmark_32_bits}; +static const uint8_t icon_bookmark_40_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0xFF, 0xFC, 0x7F, 0xFE, 0x3F, 0x81, 0xFC, 0x7F, 0xFE, 0x3E, 0x00, 0x7C, 0x7F, 0xFE, 0x38, 0x00, 0x1C, 0x7F, 0xFE, 0x30, 0x3C, 0x0C, 0x7F, 0xFE, 0x00, 0xFF, 0x00, 0x7F, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xFF, 0x07, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_bookmark_40 = {40, 40, 19, icon_bookmark_40_bits}; +static const uint8_t icon_bookmark_48_bits[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFC, 0x3F, 0xF0, 0xFF, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0xFF, 0x0F, 0xC0, 0x03, 0xF0, 0xFF, 0xFF, 0x0F, 0x80, 0x00, 0xF0, 0xFF, 0xFF, 0x0E, 0x01, 0x80, 0x70, 0xFF, 0xFF, 0x08, 0x07, 0xE0, 0x10, 0xFF, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFE, 0x00, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const freeink::Icon icon_bookmark_48 = {48, 48, 24, icon_bookmark_48_bits}; diff --git a/src/components/themes/lyra/LyraTheme.cpp b/src/components/themes/lyra/LyraTheme.cpp index f9661b2b..dfd6eff1 100644 --- a/src/components/themes/lyra/LyraTheme.cpp +++ b/src/components/themes/lyra/LyraTheme.cpp @@ -14,21 +14,8 @@ #include "RecentBooksStore.h" #include "components/TouchRegistry.h" #include "components/UITheme.h" -#include "components/icons/book.h" -#include "components/icons/book24.h" -#include "components/icons/bookmark.h" #include "components/icons/cover.h" -#include "components/icons/file24.h" -#include "components/icons/folder.h" -#include "components/icons/folder24.h" -#include "components/icons/hotspot.h" -#include "components/icons/image24.h" -#include "components/icons/library.h" -#include "components/icons/recent.h" -#include "components/icons/settings2.h" -#include "components/icons/text24.h" -#include "components/icons/transfer.h" -#include "components/icons/wifi.h" +#include "components/icons/generated_icons.h" // Lucide icons (freeink::Icon) generated via the SDK Icons lib #include "fontIds.h" // Internal constants @@ -47,55 +34,60 @@ constexpr int listIconSize = 24; constexpr int mainMenuColumns = 2; int coverWidth = 0; -const uint8_t* iconForName(UIIcon icon, int size) { - if (size == 24) { - switch (icon) { - case UIIcon::Folder: - return Folder24Icon; - case UIIcon::Text: - return Text24Icon; - case UIIcon::Image: - return Image24Icon; - case UIIcon::Book: - return Book24Icon; - case UIIcon::File: - return File24Icon; - default: - return nullptr; - } - } else if (size == 32) { - switch (icon) { - case UIIcon::Folder: - return FolderIcon; - case UIIcon::Book: - return BookIcon; - case UIIcon::Recent: - return RecentIcon; - case UIIcon::Settings: - return Settings2Icon; - case UIIcon::Transfer: - return TransferIcon; - case UIIcon::Library: - return LibraryIcon; - case UIIcon::Wifi: - return WifiIcon; - case UIIcon::Hotspot: - return HotspotIcon; - case UIIcon::Bookmark: - return BookmarkIcon; - default: - return nullptr; +// Pick the generated Lucide icon variant nearest to targetPx for a UIIcon. The +// generator emits 24/32/40/48px with each icon's optical center baked in, so a +// scaled UI gets a crisp larger asset (not an upscaled one) and exact alignment. +const freeink::Icon* pickIcon(UIIcon icon, int targetPx) { + const freeink::Icon* const* v = nullptr; +#define VARIANTS(n) \ + { \ + static const freeink::Icon* a[] = {&icon_##n##_24, &icon_##n##_32, &icon_##n##_40, \ + &icon_##n##_48}; \ + v = a; \ + } + switch (icon) { + case UIIcon::Folder: VARIANTS(folder) break; + case UIIcon::Text: VARIANTS(text) break; + case UIIcon::Image: VARIANTS(image) break; + case UIIcon::Book: VARIANTS(book) break; + case UIIcon::File: VARIANTS(file) break; + case UIIcon::Recent: VARIANTS(recent) break; + case UIIcon::Settings: VARIANTS(settings) break; + case UIIcon::Transfer: VARIANTS(transfer) break; + case UIIcon::Library: VARIANTS(library) break; + case UIIcon::Wifi: VARIANTS(wifi) break; + case UIIcon::Hotspot: VARIANTS(hotspot) break; + case UIIcon::Bookmark: VARIANTS(bookmark) break; + default: return nullptr; + } +#undef VARIANTS + static constexpr int kSizes[] = {24, 32, 40, 48}; + int best = 0, bestDist = 1 << 30; + for (int i = 0; i < 4; ++i) { + const int d = kSizes[i] > targetPx ? kSizes[i] - targetPx : targetPx - kSizes[i]; + if (d < bestDist) { + bestDist = d; + best = i; } } - return nullptr; + return v[best]; } -// Top-left Y to box-center an icon on a line of text whose top is at textTop. The -// UI icons are already centered in their boxes, so this just box-centers the icon -// on the text's optical middle, which the renderer derives from the real font -// metrics (x-height) — no per-size fraction to tweak. -int iconYForText(const GfxRenderer& renderer, int fontId, int textTop, int boxSize) { - return textTop + renderer.getTextVisualCenterOffset(fontId) - boxSize / 2; +// Scale a base icon size by the board uiScale. +int scaledIcon(int base) { return static_cast(base * UITheme::uiScale() + 0.5f); } + +// Nearest generated icon size (24/32/40/48) to targetPx. +int nearestIconSize(int targetPx) { + static constexpr int kSizes[] = {24, 32, 40, 48}; + int best = kSizes[0], bestDist = 1 << 30; + for (int s : kSizes) { + const int d = s > targetPx ? s - targetPx : targetPx - s; + if (d < bestDist) { + bestDist = d; + best = s; + } + } + return best; } } // namespace @@ -281,11 +273,12 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, int textX = rect.x + M().contentSidePadding + hPaddingInSelection; int textWidth = contentWidth - M().contentSidePadding * 2 - hPaddingInSelection * 2; - int iconSize = 0; + int drawnIconPx = 0; // chosen generated icon size (scaled by uiScale) if (rowIcon != nullptr) { - iconSize = (rowSubtitle != nullptr) ? mainMenuIconSize : listIconSize; - textX += iconSize + hPaddingInSelection; - textWidth -= iconSize + hPaddingInSelection; + const int base = (rowSubtitle != nullptr) ? mainMenuIconSize : listIconSize; + drawnIconPx = nearestIconSize(scaledIcon(base)); + textX += drawnIconPx + hPaddingInSelection; + textWidth -= drawnIconPx + hPaddingInSelection; } // Title baseline-top offset within the row. Single-line rows center the title @@ -327,12 +320,12 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, } if (rowIcon != nullptr) { - UIIcon icon = rowIcon(i); - const uint8_t* iconBitmap = iconForName(icon, iconSize); - if (iconBitmap != nullptr) { - const int iconDrawY = iconYForText(renderer, UI_10_FONT_ID, titleTop, iconSize); - renderer.drawIcon(iconBitmap, rect.x + M().contentSidePadding + hPaddingInSelection, iconDrawY, iconSize, - iconSize); + const freeink::Icon* ic = pickIcon(rowIcon(i), drawnIconPx); + if (ic != nullptr) { + // Place the icon's baked-in optical center on the title's optical center. + const int textCenter = titleTop + renderer.getTextVisualCenterOffset(UI_10_FONT_ID); + renderer.drawIcon(*ic, rect.x + M().contentSidePadding + hPaddingInSelection, + textCenter - ic->opticalCenterY); } } @@ -591,12 +584,12 @@ void LyraTheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount const int textY = tileRect.y + (rowHeight - lineHeight) / 2; if (rowIcon != nullptr) { - UIIcon icon = rowIcon(i); - const uint8_t* iconBitmap = iconForName(icon, mainMenuIconSize); - if (iconBitmap != nullptr) { - const int iconY = iconYForText(renderer, UI_12_FONT_ID, textY, mainMenuIconSize); - renderer.drawIcon(iconBitmap, textX, iconY, mainMenuIconSize, mainMenuIconSize); - textX += mainMenuIconSize + hPaddingInSelection + 2; + const freeink::Icon* ic = pickIcon(rowIcon(i), scaledIcon(mainMenuIconSize)); + if (ic != nullptr) { + // Place the icon's baked-in optical center on the label's optical center. + const int textCenter = textY + renderer.getTextVisualCenterOffset(UI_12_FONT_ID); + renderer.drawIcon(*ic, textX, textCenter - ic->opticalCenterY); + textX += ic->w + hPaddingInSelection + 2; } } diff --git a/src/main.cpp b/src/main.cpp index f5403d7f..7a2b3723 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,8 +300,10 @@ void setupDisplayAndFonts(bool seamless = false) { renderer.insertFont(SMALL_FONT_ID, smallFontFamily); // UI chrome font scaling on high-density / touch boards: Ubuntu UI is only built - // at 10/12pt, so remap the small UI fonts up the Noto Sans ladder to grow chrome - // text with uiScale. Reader body fonts aren't remapped, so book text is unchanged. + // at 10/12pt, so remap the UI fonts up the Noto Sans ladder to grow chrome text + // with uiScale. SMALL is deliberately NOT remapped — it's secondary/compact text + // (reader status bar, subtitles, battery %) that should stay small so reader + // chrome doesn't balloon. Reader body fonts aren't remapped either. if (const float s = UITheme::uiScale(); s > 1.05f) { auto nearestNotoSans = [](float pt) -> int { const struct { @@ -322,9 +324,9 @@ void setupDisplayAndFonts(bool seamless = false) { } return best; }; - const int from[3] = {SMALL_FONT_ID, UI_10_FONT_ID, UI_12_FONT_ID}; - const int to[3] = {nearestNotoSans(8 * s), nearestNotoSans(10 * s), nearestNotoSans(12 * s)}; - renderer.setUiFontRemap(from, to, 3); + const int from[2] = {UI_10_FONT_ID, UI_12_FONT_ID}; + const int to[2] = {nearestNotoSans(10 * s), nearestNotoSans(12 * s)}; + renderer.setUiFontRemap(from, to, 2); } // Discover and load SD card fonts