From 8d023b3af719dc3a9393d7609ea86630c2153c69 Mon Sep 17 00:00:00 2001 From: OSAKANA TARO Date: Wed, 30 Sep 2026 18:23:08 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20CodeRabbit=20=E3=81=AE=E6=8C=87?= =?UTF-8?q?=E6=91=989=E4=BB=B6=EF=BC=88fork=20PR=20#4=E3=80=811.6.5=20?= =?UTF-8?q?=E8=B5=B7=E7=82=B9=E3=81=AE=E6=AE=8B=E3=82=8A=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E3=81=AE=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 実害のあるもの: - 縦書きのページは列の位置で埋まり縦の位置を進めないため、
と表の行の区切りが ページ上端を横切る横線になっていた。
は空いた列1列(ページ頭では何もしない)、 表の行の線は縦書きでは出さない。章の版 55→56。 - Text Settings で Font Copy in Flash が Off のまま書体・大きさを変えると、読み込んだ 直後に強制的に読み直し、SD から表を2回読んでいた。Off かつ SD から読んでいるときは省く。 - 保存済みの文字列の読み込み(3つの版)で、長さや本体が途中で切れていても成功扱い だった。読めたバイト数を確かめて失敗を返す。 条件が重なれば起きうるもの: - 本体の書き換えは書体の複製と同じ領域を消す。失敗して UI に戻ると複製を読み続けて いたため、書き換えの開始前(SD から・ネットから)に次の再起動まで複製を無効にする。 - 字ごとの改行位置を文字数の 1/3 で見込んで確保していたため、英字と漢字が交互の並びで 再確保になりえた。先に数えてちょうどの量を確保する。 潜在的なもの: 時計の RTC 失敗時の未初期化値、字の走査の診断値の 0 戻しの順序、 ZIP の取り出しで 512B 未満の塊の要求、番号を共有する環境の限定(ost_version.py)。 実機確認: 2026093006-diag(X3・X4 Pro)。vertical-rule-table-test.epub の3章、 Font Copy in Flash の On/Off での書体・大きさの変更、時計モード。 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GSMiDKH4CDUUtu78uJCe4F --- lib/EpdFont/SdCardFontCache.cpp | 9 ++- lib/EpdFont/SdCardFontCache.h | 5 ++ lib/Epub/Epub/ParsedText.cpp | 62 +++++++++---------- lib/Epub/Epub/Section.cpp | 2 +- .../Epub/parsers/ChapterHtmlSlimParser.cpp | 14 +++++ lib/GfxRenderer/FontCacheManager.cpp | 5 +- lib/Serialization/BufferedFile.h | 13 ++-- lib/Serialization/Serialization.h | 23 +++++-- lib/ZipFile/ZipFile.cpp | 5 +- scripts/ost_version.py | 3 +- .../settings/TextSettingsActivity.cpp | 3 + src/activities/util/ClockActivity.cpp | 2 +- src/network/FirmwareFlasher.cpp | 4 ++ src/network/OtaUpdater.cpp | 4 ++ 14 files changed, 105 insertions(+), 49 deletions(-) diff --git a/lib/EpdFont/SdCardFontCache.cpp b/lib/EpdFont/SdCardFontCache.cpp index 0cdcdd1bb71..ce10eaa84a0 100644 --- a/lib/EpdFont/SdCardFontCache.cpp +++ b/lib/EpdFont/SdCardFontCache.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include "SdCardFontCacheFormat.h" @@ -14,6 +15,9 @@ namespace SdCardFontCache { namespace { +// Set by invalidateUntilReboot() from the task running a firmware update, read by the render task. +std::atomic slotBeingUpdated{false}; + using sd_card_font_cache_format::Header; constexpr size_t CHUNK_SIZE = 4096; @@ -132,6 +136,7 @@ bool sourceFits(const char* sourcePath, size_t* payloadBytes) { bool isValidFor(const char* sourcePath, size_t* payloadBytes) { if (payloadBytes) *payloadBytes = 0; + if (slotBeingUpdated.load()) return false; const HalOtaSlot slot = HalOtaSlot::inactive(); Header header{}; @@ -145,7 +150,7 @@ bool isValidFor(const char* sourcePath, size_t* payloadBytes) { bool readAt(size_t offset, void* data, size_t length, size_t payloadBytes) { static const HalOtaSlot slot = HalOtaSlot::inactive(); - if (payloadBytes > payloadCapacity(slot) || + if (slotBeingUpdated.load() || payloadBytes > payloadCapacity(slot) || !sd_card_font_cache_format::containsPayloadRange(payloadBytes, offset, length)) { return false; } @@ -252,4 +257,6 @@ const char* resultName(Result result) { return "unknown"; } +void invalidateUntilReboot() { slotBeingUpdated.store(true); } + } // namespace SdCardFontCache diff --git a/lib/EpdFont/SdCardFontCache.h b/lib/EpdFont/SdCardFontCache.h index d716599bc2c..6cf01315b7b 100644 --- a/lib/EpdFont/SdCardFontCache.h +++ b/lib/EpdFont/SdCardFontCache.h @@ -43,5 +43,10 @@ bool readAt(size_t offset, void* data, size_t length, size_t payloadBytes); // (copy, then read-back verification). Result preload(const char* sourcePath, ProgressCallback progress = nullptr, void* context = nullptr); const char* resultName(Result result); +// A firmware update is about to erase and write the slot the copy lives in. From here until the +// next boot isValidFor() and readAt() report no copy, so a loaded font falls back to the card +// instead of reading erased or new-image bytes (an update that fails returns to the UI without +// rebooting). A successful update reboots, and the header check then rebuilds the copy. +void invalidateUntilReboot(); } // namespace SdCardFontCache diff --git a/lib/Epub/Epub/ParsedText.cpp b/lib/Epub/Epub/ParsedText.cpp index eaa2ae50a83..5e903c5556d 100644 --- a/lib/Epub/Epub/ParsedText.cpp +++ b/lib/Epub/Epub/ParsedText.cpp @@ -123,38 +123,38 @@ std::vector cjkCharacterBreakByteOffsets(const std::string& text) { // which for a Japanese paragraph -- one unspaced "word" -- cost 8x the paragraph's // bytes in one block: 20 KB for a 2.5 KB paragraph, requested mid-build where the // largest free block was 5 KB. With -fno-exceptions the failed reserve was a - // terminate() (crash 2026-09-17, horizontal-regression-test ch.14). The result vector - // is bounded by one entry per codepoint; pure CJK is 3 bytes each, so reserve a third - // and let a mixed run grow. - std::vector allowedOffsets; - const auto* ptr = reinterpret_cast(text.c_str()); - const auto* const start = ptr; - uint32_t prevCp = utf8NextCodepoint(&ptr); - if (prevCp == 0) return {}; - size_t prevEnd = static_cast(ptr - start); - bool hasCjkBreakable = utf8IsCjkBreakable(prevCp); - bool reserved = false; - while (*ptr) { - const uint32_t cp = utf8NextCodepoint(&ptr); - if (cp == 0) break; - if (utf8IsCjkBreakable(cp)) hasCjkBreakable = true; - if (hasCjkBreakOpportunityBetween(prevCp, cp)) { - if (!reserved) { - // First opportunity found: size the result once. Skip the whole per-character - // split when even that block cannot be placed -- the word then stays one token, - // and the line pre-check reports the page instead of the allocator aborting. - const size_t want = text.size() / 3 + 1; - constexpr size_t RESERVE_HEADROOM = 4 * 1024; - if (ESP.getMaxAllocHeap() < want * sizeof(size_t) + RESERVE_HEADROOM) return {}; - allowedOffsets.reserve(want); - reserved = true; - } - allowedOffsets.push_back(prevEnd); + // terminate() (crash 2026-09-17, horizontal-regression-test ch.14). The result is sized + // exactly: a first pass counts the opportunities without allocating (a guess by byte + // length is short for mixed runs such as "a漢a漢", where every boundary breaks, and + // over-reserves pure CJK), then the vector is reserved once and never regrows. + const auto* const start = reinterpret_cast(text.c_str()); + const auto forEachBreak = [start](auto&& onBreak) { + const auto* ptr = start; + uint32_t prevCp = utf8NextCodepoint(&ptr); + if (prevCp == 0) return false; + size_t prevEnd = static_cast(ptr - start); + bool hasCjkBreakable = utf8IsCjkBreakable(prevCp); + while (*ptr) { + const uint32_t cp = utf8NextCodepoint(&ptr); + if (cp == 0) break; + if (utf8IsCjkBreakable(cp)) hasCjkBreakable = true; + if (hasCjkBreakOpportunityBetween(prevCp, cp)) onBreak(prevEnd); + prevCp = cp; + prevEnd = static_cast(ptr - start); } - prevCp = cp; - prevEnd = static_cast(ptr - start); - } - if (!hasCjkBreakable) return {}; + return hasCjkBreakable; + }; + + size_t count = 0; + if (!forEachBreak([&count](size_t) { count++; }) || count == 0) return {}; + // Skip the whole per-character split when even that block cannot be placed -- the word + // then stays one token, and the line pre-check reports the page instead of the allocator + // aborting. + constexpr size_t RESERVE_HEADROOM = 4 * 1024; + if (ESP.getMaxAllocHeap() < count * sizeof(size_t) + RESERVE_HEADROOM) return {}; + std::vector allowedOffsets; + allowedOffsets.reserve(count); + forEachBreak([&allowedOffsets](size_t offset) { allowedOffsets.push_back(offset); }); return allowedOffsets; } diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index a3d678cfd72..3854422924b 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -67,7 +67,7 @@ namespace { // v53: Vertical columns carry link rectangles, so the footnote selector can reach them. // v54: Images honour max-width/max-height; vertical books set images in the column flow. // v55: A vertical page holding a single image centres it horizontally. -constexpr uint8_t SECTION_FILE_VERSION = 55; +constexpr uint8_t SECTION_FILE_VERSION = 56; // Written into the version field while a build is in progress; patched to // SECTION_FILE_VERSION only when the build is finalized. An abandoned / // crash-interrupted .bin therefore carries version 0, which loadSectionFile rejects diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index c0aa66dd4de..a4c2097c99d 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -1045,6 +1045,17 @@ void ChapterHtmlSlimParser::emitHorizontalRule(const BlockStyle& blockStyle) { startNewTextBlock(parentBlockStyle); } + if (isVertical) { + // Vertical pages fill by column (currentPageNextX) and never advance currentPageNextY, so a + // horizontal rule would be drawn across the column heads. The break is kept as one blank + // column, the usual form of a scene break in vertical text. At the start of a page it adds + // nothing, and a cursor already past the left edge makes the next column start a new page. + if (currentPage && !currentPage->elements.empty() && verticalCursorPageIndex == completedPageCount) { + currentPageNextX = static_cast(currentPageNextX - verticalColumnWidth() - verticalColumnSpacing()); + } + return; + } + if (!currentPage) { currentPage.reset(new (std::nothrow) Page()); if (!currentPage) { @@ -1156,6 +1167,9 @@ void ChapterHtmlSlimParser::closeTableCell() { } void ChapterHtmlSlimParser::addTableRowSeparator() { + // Vertical pages never advance currentPageNextY: every separator would land as a full-width + // line across the column heads. The stacked rows read as separate paragraphs without it. + if (isVertical) return; if (!currentPage || currentPage->elements.empty() || viewportWidth == 0 || currentPageNextY + TABLE_ROW_SEPARATOR_GAP > viewportHeight) { return; diff --git a/lib/GfxRenderer/FontCacheManager.cpp b/lib/GfxRenderer/FontCacheManager.cpp index b409347a703..600f95944af 100644 --- a/lib/GfxRenderer/FontCacheManager.cpp +++ b/lib/GfxRenderer/FontCacheManager.cpp @@ -207,12 +207,13 @@ FontCacheManager::PrewarmScope::PrewarmScope(FontCacheManager& manager) : manage void FontCacheManager::PrewarmScope::endScanAndPrewarm() { const bool wasScanning = manager_->scanMode_ == ScanMode::Scanning; manager_->scanMode_ = ScanMode::None; - if (manager_->scanCodepointCount_ == 0) return; - + // Before the empty-scan return: a page scope whose hook never fired has to report zero, not the + // previous page's figures. if (wasScanning) { manager_->lastScanBytes_ = 0; manager_->lastScanFonts_ = 0; } + if (manager_->scanCodepointCount_ == 0) return; std::sort(manager_->scanCodepoints_, manager_->scanCodepoints_ + manager_->scanCodepointCount_); diff --git a/lib/Serialization/BufferedFile.h b/lib/Serialization/BufferedFile.h index a2f5dc864e2..2fbabf73a35 100644 --- a/lib/Serialization/BufferedFile.h +++ b/lib/Serialization/BufferedFile.h @@ -156,8 +156,11 @@ inline void writeString(BufferedFileWriter& out, const std::string& s) { // rejected length leaves the stream desynced, so the caller must abort the // whole record rather than continue parsing. [[nodiscard]] inline bool readString(BufferedFileReader& in, std::string& s) { - uint32_t len; - readPod(in, len); + uint32_t len = 0; + if (in.read(&len, sizeof(len)) != sizeof(len)) { + s.clear(); + return false; + } // See Serialization.h's MAX_SERIALIZED_STRING_LEN for why this is capped. if (len > MAX_SERIALIZED_STRING_LEN) { LOG_ERR("SER", "readString: length %u exceeds max, treating as corrupt", len); @@ -165,8 +168,10 @@ inline void writeString(BufferedFileWriter& out, const std::string& s) { return false; } s.resize(len); - if (len > 0) { - in.read(&s[0], len); + // A file cut short inside the string is as corrupt as an oversized length. + if (len > 0 && in.read(&s[0], len) != len) { + s.clear(); + return false; } return true; } diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index 00b98aee27f..6e18c23fcc2 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -58,28 +58,39 @@ constexpr uint32_t MAX_SERIALIZED_STRING_LEN = 65535; // already returns nullptr on its own corruption checks) rather than pressing // on. [[nodiscard]] inline bool readString(std::istream& is, std::string& s) { - uint32_t len; + uint32_t len = 0; readPod(is, len); - if (len > MAX_SERIALIZED_STRING_LEN) { + if (!is || len > MAX_SERIALIZED_STRING_LEN) { LOG_ERR("SER", "readString: length %u exceeds max, treating as corrupt", len); s.clear(); return false; } s.resize(len); - is.read(&s[0], len); + // A stream cut short inside the string is as corrupt as an oversized length. + if (len > 0 && !is.read(&s[0], len)) { + s.clear(); + return false; + } return true; } [[nodiscard]] inline bool readString(HalFile& file, std::string& s) { - uint32_t len; - readPod(file, len); + uint32_t len = 0; + if (file.read(reinterpret_cast(&len), sizeof(len)) != static_cast(sizeof(len))) { + s.clear(); + return false; + } if (len > MAX_SERIALIZED_STRING_LEN) { LOG_ERR("SER", "readString: length %u exceeds max, treating as corrupt", len); s.clear(); return false; } s.resize(len); - file.read(&s[0], len); + // A file cut short inside the string is as corrupt as an oversized length. + if (len > 0 && file.read(&s[0], len) != static_cast(len)) { + s.clear(); + return false; + } return true; } } // namespace serialization diff --git a/lib/ZipFile/ZipFile.cpp b/lib/ZipFile/ZipFile.cpp index 043cae2cd94..cb107896528 100644 --- a/lib/ZipFile/ZipFile.cpp +++ b/lib/ZipFile/ZipFile.cpp @@ -457,8 +457,9 @@ namespace { // more room (2026-09-17, p050.jpg of a commercial volume). Smaller chunks cost // more trips to the card and nothing else, so a slow picture beats no picture. uint8_t* allocChunkDownTo(const size_t want, size_t* got) { - constexpr size_t CHUNK_FLOOR = 512; - for (size_t size = want; size >= CHUNK_FLOOR; size /= 2) { + // A request already below 512 is its own floor. + const size_t floor = std::min(want, 512); + for (size_t size = want; size >= floor && size > 0; size /= 2) { if (auto* p = static_cast(malloc(size))) { *got = size; if (size != want) { diff --git a/scripts/ost_version.py b/scripts/ost_version.py index 4b60a4b3d49..5c6ae201e00 100644 --- a/scripts/ost_version.py +++ b/scripts/ost_version.py @@ -181,7 +181,8 @@ def main(env): project_dir = env.subst('$PROJECT_DIR') pioenv = env.subst('$PIOENV') board = BOARD_TAGS.get(pioenv, '') - version = next_version(project_dir, advance=(pioenv == 'default')) + # Only a board with its own tag may share the day's number: its image name still differs. + version = next_version(project_dir, advance=(pioenv not in BOARD_TAGS)) diag_at_pre = has_input_diag(env) write_build_id_header(project_dir, f'{version}{board}{"-diag" if diag_at_pre else ""}') diff --git a/src/activities/settings/TextSettingsActivity.cpp b/src/activities/settings/TextSettingsActivity.cpp index 90fe5a64e22..3070a3d8165 100644 --- a/src/activities/settings/TextSettingsActivity.cpp +++ b/src/activities/settings/TextSettingsActivity.cpp @@ -394,6 +394,9 @@ void TextSettingsActivity::applySize(int listIndex) { void TextSettingsActivity::applyFlashCacheSetting() { if (SETTINGS.sdFontFamilyName[0] == '\0') return; // built-in family: nothing to copy, nothing to reload const bool wantFlash = SETTINGS.sdFontFlashCache != 0; + // Copy off and the font already read from the card: the family/size change has just loaded + // it that way, and a forced reload would read its tables from the SD a second time. + if (!wantFlash && !sdFontSystem.readerFontFromFlash()) return; if (wantFlash && !runFlashCopy()) { // runFlashCopy switched the setting off; the reload below returns the font to the card. } diff --git a/src/activities/util/ClockActivity.cpp b/src/activities/util/ClockActivity.cpp index 4fcaea318e3..94a1679deaa 100644 --- a/src/activities/util/ClockActivity.cpp +++ b/src/activities/util/ClockActivity.cpp @@ -153,7 +153,7 @@ void ClockActivity::render(RenderLock&&) { } #endif - Rtc::DateTime now; + Rtc::DateTime now{}; const bool haveTime = halClock.getLocalDateTime(now); if (haveTime) { renderedMinute = now.minute; diff --git a/src/network/FirmwareFlasher.cpp b/src/network/FirmwareFlasher.cpp index de52491eb4c..9ccd01e9baa 100644 --- a/src/network/FirmwareFlasher.cpp +++ b/src/network/FirmwareFlasher.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -311,6 +312,9 @@ Result flashFromSdPath(const char* sdPath, ProgressCb onProgress, void* ctx, boo return Result::OOM; } + // The destination is the slot the flash font copy lives in: stop reading it before the erase. + SdCardFontCache::invalidateUntilReboot(); + // Interleave erase + write so the progress bar advances 0→100% smoothly // rather than stalling for several seconds during a single up-front erase. size_t streamPos = 0; diff --git a/src/network/OtaUpdater.cpp b/src/network/OtaUpdater.cpp index d1fa10b3ef4..b202a101377 100644 --- a/src/network/OtaUpdater.cpp +++ b/src/network/OtaUpdater.cpp @@ -6,6 +6,7 @@ // the local header last and break the build. #include "HttpDownloader.h" #include +#include #include #include #include @@ -146,6 +147,9 @@ OtaUpdater::OtaUpdaterError OtaUpdater::installUpdate(ProgressCallback onProgres return INTERNAL_UPDATE_ERROR; } + // The update slot holds the flash font copy: stop reading it before esp_ota_begin erases it. + SdCardFontCache::invalidateUntilReboot(); + esp_ota_handle_t otaHandle = 0; esp_err_t esp_err = esp_ota_begin(updatePartition, OTA_SIZE_UNKNOWN, &otaHandle); if (esp_err != ESP_OK) { From c08f5e39609bec24012888b5c51c4844fae5ada8 Mon Sep 17 00:00:00 2001 From: OSAKANA TARO Date: Wed, 30 Sep 2026 18:23:22 +0900 Subject: [PATCH 2/3] =?UTF-8?q?README:=20CodeRabbit=20=E3=81=AE=E6=8C=87?= =?UTF-8?q?=E6=91=989=E4=BB=B6=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GSMiDKH4CDUUtu78uJCe4F --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b1bc8cdb2e8..189b7a2205e 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ CJK版だけは freeink-sdk 自体も自前でforkしていて、SSD1677パネ - 抹茶版・Yomuka版から: 空きが少ないときにツールバーを開いても落ちない、本の終わりの位置で目次・進み具合を引いても落ちない - 自動ページ送りの間は自動スリープさせない - 当版の変更を本家 1.6.5 からの段階ごとに区切って fork 内の PR にし、CodeRabbit のレビューを受け始めた(土台の枝 `vertical-1.6.5review`、1本目は診断記録とビルド番号)。指摘2件(診断版の番号の見分け、待ち時間の組み立て失敗の記録)を修正 + - 残り全部(段階2〜9 と X4 Pro 対応)を1本にまとめてレビューを受け、指摘9件を修正(2026093006-diag、X3・X4 Pro で実機確認済み)。縦書きの本で区切り線(hr)と表の行の線がページ上端を横切る横線になっていた件(区切り線は空いた列1列に、表の行の線は出さない。章の版 56)、Font Copy in Flash が Off のとき書体・大きさの変更で書体ファイルを2回読んでいた件、保存済みの文字列が途中で切れていても読めた扱いだった件、本体の書き換えに失敗したとき書体の複製を読み続けるおそれ、など - 段階0(素の 1.6.5 のビルド)、段階1(診断)、段階2(時計と監視)、段階3(字形の計測と素の実測)まで完了。詳細は下の「1.6.5ベースへの作り直し」節 - 段階9(実測②と補い)を実施中。漢字の多いページの 1 字ずつの読み直し(最大 16.5 秒)を字形の置き場の 4KB 分割で解消し、本文ページ内の JPEG 挿絵が出ない件を組み立て中の先回り展開で直した。組み立て中の空きの底を 2KB→17KB に引き上げ(章で使う CSS の規則だけ読む・設定一覧を常駐させない)、組み立て中にメニューを開くと落ちる件も直した - 段階8bまで完了。Library(書棚)の並び・見出し・検索を、本の読み(file-as)に基づく五十音順にした(本家に出している PR #3651 を先に取り込み) From 142654adc02f4760552361f051b846dc30233a22 Mon Sep 17 00:00:00 2001 From: OSAKANA TARO Date: Wed, 30 Sep 2026 18:25:15 +0900 Subject: [PATCH 3/3] =?UTF-8?q?review=20only:=20README=E3=83=BB=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=94=9F=E6=88=90=E3=81=AE=20ClockDigits.h=E3=83=BB?= =?UTF-8?q?=E6=96=87=E6=9B=B8=E3=81=A8=E3=83=86=E3=82=B9=E3=83=88=E3=81=AE?= =?UTF-8?q?=E7=B5=84=E3=81=BF=E7=AB=8B=E3=81=A6=E8=A8=AD=E5=AE=9A=E3=81=AA?= =?UTF-8?q?=E3=81=A9=E3=82=92=E5=9C=9F=E5=8F=B0=E3=81=A8=E5=90=8C=E3=81=98?= =?UTF-8?q?=E7=8A=B6=E6=85=8B=E3=81=AB=E6=88=BB=E3=81=99=EF=BC=88=E4=BD=B5?= =?UTF-8?q?=E5=90=88=E3=81=97=E3=81=AA=E3=81=84=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1625 ++--------------- docs/file-formats.md | 35 +- src/images/ClockDigits.h | 1312 ------------- test/CMakeLists.txt | 1 - test/cjk_line_break/CMakeLists.txt | 15 - test/library_format/LibraryFormatTest.cpp | 2 +- .../LibraryIndexFileTest.cpp | 6 +- 7 files changed, 200 insertions(+), 2796 deletions(-) delete mode 100644 src/images/ClockDigits.h delete mode 100644 test/cjk_line_break/CMakeLists.txt diff --git a/README.md b/README.md index 189b7a2205e..f6f68770dfc 100644 --- a/README.md +++ b/README.md @@ -1,1532 +1,297 @@ -# CrossPoint Reader OST 改造版 - -XTEINK X3上で日本語EPUBファイルを読むために、CrossPoint Reader を改造しています。 -命名は面倒くさくなったのでOSakanaTaro版ってことでOST版です。 - -### 2026/09/29時点の開発方針 -- XTEINK X3とXTEINK X4 Pro向けに開発 - - Xteink X3はaliexpressで買ったUSB接続ができないバージョンを使用 - - Xteink X4 Proは [Xteink公式](https://go.sjv.io/aNGBAW)で購入したバージョンを使用 -- Claude Codeで開発する - - コンパイルなどはUbuntu 24.04仮想マシン上で実施 -- 本家をベースにする - - X3の最近のバージョンは液晶パネルが違う件への対応などが本家には入っているため - - 2026/08/09から1.5.0ベースで開発開始。本家にXteink x4 pro対応が入ったあたりで乖離が始まった - - 2026/08/20から1.6.0rcをベースにして再構成開始 - - 2026/09/06から1.6.0リリース版をベースに再構成 - - 2026/09/28から1.6.5リリース版をベースに再構成(ブランチ `vertical-1.6.5`) -- 日本語訳は付けない -- フォントはSDカード上に配置する - - 容量食うのでSDカード上に置く -- ページめくりボタンは左が進むで、右が戻る - - 縦書きフォーマット(RTL)のEPUBを開いた時だけその動作をする -- 青空文庫ダウンロードなどの機能は付けない -- 時計表示機能を追加 - - 磁石で貼り付けることができるので作業時の時計表示に使えるな、と実装 - - [Settings]-[System]-[Clock]の[Timezone]を「Tokyo / Seoul」とすることで日本時間表示に(1.6.5 から。1.6.0 ベースの版では[Settings]-[Reader]-[Customize Status Bar]の[Clock UTC Offset]を「UTC+9:00」) -- テスト用EPUBファイルにて動作を確認 - - 一部、特殊なフォントを必要とする文字以外について表示できることが期待される -- ルビ表示について対応 - - 横書きであればルビに対応してるなら縦書きでも対応しておくかな、って -- 電書連 EPUB 3 制作ガイド ver.1.1.4に準拠したEPUB表示についての対策 - - ~~CSSが巨大すぎてメモリクラッシュを起こす件についての対応をやる必要があるのかという問題~~ - - ~~[Setings]-[Reader]-[Text Settings]にある[Style]にて「Embedded Style」を「OFF」にするとCSSを使わないため回避できる~~ - - こんな小さな端末で著者がやりたいという複雑な表現をやって期待通りの表示になるのか?と思いつつ対応 -- 本家との付き合い方 - - UIの大きな変更は個別に追随しない。本家のタグが更新された時点でforkしなおし再実装する - - 基本的に縦書き・挿絵・フォントに関わる本家修正だけ取り込む -- フォントの明朝/ゴシック混植は実施しない - - 1冊のなかでフォント指定を途中から変える機能について - - 商業EPUBの91%が指定を持つが1冊あたり中央値40箇所で、2書体常駐のメモリ代償に見合わない -- 組版やレイアウトについての出典として下記を採用している - - EPUB 3.3 仕様書 https://www.w3.org/TR/epub/ - - EPUB 3.4 テスト仕様 https://w3c.github.io/epub-tests/index.html - - 日本語組版処理の要件(JLREQ) https://www.w3.org/TR/jlreq/ - - 特に JLREQ 3.3.2 ルビの付け方 - - Unicode Vertical Text Layout(UAX #50) https://www.unicode.org/reports/tr50/ - - Unicode Line Breaking Algorithm https://www.unicode.org/reports/tr14/ - - 電書協 EPUB 3 制作ガイド https://dpfj.or.jp/counsel/guide - - KADOKAWA-EPUB 制作仕様 および KADOKAWA-EPUB 再現指標 https://kadokawa-epub.bookwalker.co.jp/%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89 -- 開発に際して下記URLをClaude codeに読み込ませている(実装内容まとめで使う略語) - - 本家 https://github.com/crosspoint-reader/crosspoint-reader - - JP版 https://github.com/zrn-ns/crosspoint-jp - - CJK版 https://github.com/CrossPoint-CJK/crosspoint-reader-cjk (旧URL https://github.com/aBER0724/crosspoint-reader-cjk ) - - Yomuka版 https://github.com/ponto1216-ai/crosspoint-jp - - 抹茶版 https://github.com/eszter007/matcha-reader - - freeink-sdk https://github.com/Free-Ink/freeink-sdk - - 以下は日本語縦書きには直接関係しない実装で、UIなどの機能面の参考として読む(2026/09/09 追加。同日、3つとも縦書き・ルビ・禁則・text-orientation などの実装が無いことをソースと履歴で確認済み) - - Papyrix版 https://github.com/bigbag/papyrix-reader - - Inx版 https://github.com/obijuankenobiii/inx - - witchhunt版 https://github.com/jpirnay/witchhunt-reader - - crossmux版 https://github.com/0x1abin/crossmux - -各フォークが本家のどのリリースまで取り込んでいるか(2026/09/22時点、GitHubの履歴を照合)。 - -| 版 | 取り込み済みの最新 | 本家との世代差 | 使用しているfreeink-sdk | -|---|---|---|---| -| 本家 | 1.6.5rc(2026/09/14 先行版。developの先端はさらに31件先、うち #2332 画像まわりの断片化対策、#3600 一覧の行を必要な分だけ作る、#3618 組み込むUI言語を選べる、#3528 語間・字間の設定、#3608 転送後に Library の索引を作り直す) | ― | ffcbb1c | -| **OST版 新ツリー** `feat/vertical-1.6.0based` | 1.6.0(2026/09/05) | 1.6.5rc が未取り込み(1.6.0から31件、develop先端までさらに31件)。#2925(段階表示JPEGの分離走査)と #3581(合字表の宙づり参照)は 09/17 に個別に取り込み済み。残りで当版に効きそうなのは断片化対処の連作 #3518/#3521/#3527(章レイアウト前のフォントキャッシュ解放)・#3398(フォント目録を1領域に)・#2332(画像まわり)と、#3439(X3のアンチエイリアス安定化)。いずれも 1.6.5 起点の作り直しで本家のまま採る | fde240f | -| 抹茶版 | 1.6.0(2026/09/20、安定版。本家 develop 09/20 時点 `8c84ef32` を含む) | 1.5.0 以来の安定版。X4 Pro・X4C・Sticky 対応、辞書引き(長押し・ボタン選択・縦書き対応・ページ跨ぎの語)、漫画の吹き出しの語の引き当て(変換のやり直しが必要)。独自分は辞書引き(漫画の吹き出しの語の引き当て、触れる操作)が中心。#282 は日本語の添え書体の区間表を Regular/Bold で共有して読み込みの山を半分にし、読み込み前に字形の保存を捨てる(20pt NotoSansJP で 26.6KB×2 が入らなかった件。当版の書体は区間が密で1書体3KBのため無縁) | 4b17a7bb | -| CJK版 | **本家タグを1つも含まない**(0.4.2、2026/09/05) | 本家と共通の祖先を持たない再構成履歴。以後の同期なし | 自前fork 62976c5 | -| JP版 | 1.2.0(2026/04/03) | 1.3.0 以降すべて未取り込み。独自開発は活発(v0.3.2=2026/09/19: #149 眠り画面の動的壁紙、#150 ホームの読書進捗率と Vega テーマ。09/08以降: **禁則処理の行分割 #144**、字形の鮮明さ設定 #145、UI書体のディセンダ #146、整形済みブロックの行間 #147、フォルダを開くたびの全走査をやめる #148/#136、横向きUI #138) | e38baecc | -| Yomuka版 | 1.2.0(2026/04/03) | JP版からの派生のため同じ。独自開発は活発(yomuka-v0.7.6.0=2026/09/17: SD書体の作業領域をページ間で使い回す(本家の「収まれば保持」方式の移植で当版は既に同等)、ルビ・上付きなどの小さい字に 10pt 専用の書体データを使う、縦中横の桁数を2/3桁で選べる、曲線引用符 ‘’“” を縦の升に正立で置く(`3f631371`/BIZUD向け補正 `9dcfc3dc`)、全冊の事前生成中のSD書き込み失敗を安全に止める) | 30011399 | -| crossmux版 | 1.6.0(2026/09/05) | 本家 1.6.0 起点(1.6.5rc は未取り込み)で独自 618 件。中国語(簡体字)対応の community fork。Apps(ゲーム・道具)、微信読書、AirPage、読書統計、Bluetooth ページめくり、33 言語を1 firmware に、C3 の読書メモリの上限管理。SD 書体は本家と同じ cpfont v4。**縦書き・禁則なし**(2026/09/22 に確認対象へ追加) | 自前fork 094976e | - -各版の最新リリース(先行版を含む。安定版だけを見るとJP版・Yomuka版の日付つき開発版や、 -Inx版・witchhunt版・抹茶版の先行版を取り落とす): - -| 版 | 最新 | 日付 | -|---|---|---| -| 本家 | 1.6.5rc(先行版) | 2026/09/14 | -| Yomuka版 | yomuka-v0.7.6.0 | 2026/09/17 | -| JP版 | v0.3.2 | 2026/09/19 | -| 抹茶版 | 1.6.0 | 2026/09/20 | -| Papyrix版 | v1.31.0 | 2026/09/18 | -| Inx版 | 1.0.20-BETA(先行版) | 2026/09/11 | -| witchhunt版 | 2.31(2.31.0-rc.1 も同日) | 2026/09/20 | -| **OST版** | 20260929(先行版、1.6.5 ベース) | 2026/09/29 | -| crossmux版 | 1.6.0(stable/nightly タグは動く先行版) | 2026/09/20 | -| CJK版 | 0.4.2 | 2026/09/05 | - -CJK版だけは freeink-sdk 自体も自前でforkしていて、SSD1677パネル向けの修正を独自に入れている。 -他は本家のfreeink-sdkをそのまま参照している。 - -# 最近の更新内容について(2026/09/30) - -- 本家 1.6.5(2026/09/27 リリース)を起点に作り直しを開始(2026/09/28〜、ブランチ `vertical-1.6.5`)。新しい系統の最初の pre-release として OST版 2026093001-diag(タグ 20260929、診断版、X3 と X4 Pro の2本)を公開 - - Xteink X4 Pro 向けの版も作るようにした(2026/09/29〜)。X4 Pro は PSRAM があり読書中の空きが 130KB 以上、18pt の縦書きは 1 ページ 8 列(X3 は 9 列) - - X4 Pro には Back ボタンが無いため、時計画面をホームキーで終了できるようにした(タップ・長押しとも。ダブルタップの前面ライト切り替えは時計画面のまま使える) - - 挿絵が白いページになる件を本家に PR #3802 として提出(章の組み立て中に挿絵の大きさを読む処理へ画面用の記憶を貸す)。本家 1.6.5 で表紙・章の扉が枠もなく白くなることを実機で再現し、修正版で表示されることを確認。本文中の細い挿絵の件は本家 PR #3675 に実測をコメント - - その PR のレビューで見つかった件を当版にも反映: 待ち時間の組み立てで画面用の記憶を貸したらページを描き直し、描き直すまではツールバーを今の画面に直接重ねない(重ね表示中は待ち時間の組み立てを止める) - - 本家・他フォークから小さな修正を取り込み(2026093004-diag、X3・X4 Pro で実機確認済み) - - 本家から: ボタン操作ごとの記憶の確保をやめる(#3698)、脚注の一覧で電源ボタンでも飛べる(#3766)、タッチ機で見出しの戻るボタンがキーボード画面でも効く、読み込み用ファイルの確保失敗で落ちない(#3419)、保存済みの文字列の長さを上限で打ち切る(#3452) - - 抹茶版・Yomuka版から: 空きが少ないときにツールバーを開いても落ちない、本の終わりの位置で目次・進み具合を引いても落ちない - - 自動ページ送りの間は自動スリープさせない - - 当版の変更を本家 1.6.5 からの段階ごとに区切って fork 内の PR にし、CodeRabbit のレビューを受け始めた(土台の枝 `vertical-1.6.5review`、1本目は診断記録とビルド番号)。指摘2件(診断版の番号の見分け、待ち時間の組み立て失敗の記録)を修正 - - 残り全部(段階2〜9 と X4 Pro 対応)を1本にまとめてレビューを受け、指摘9件を修正(2026093006-diag、X3・X4 Pro で実機確認済み)。縦書きの本で区切り線(hr)と表の行の線がページ上端を横切る横線になっていた件(区切り線は空いた列1列に、表の行の線は出さない。章の版 56)、Font Copy in Flash が Off のとき書体・大きさの変更で書体ファイルを2回読んでいた件、保存済みの文字列が途中で切れていても読めた扱いだった件、本体の書き換えに失敗したとき書体の複製を読み続けるおそれ、など - - 段階0(素の 1.6.5 のビルド)、段階1(診断)、段階2(時計と監視)、段階3(字形の計測と素の実測)まで完了。詳細は下の「1.6.5ベースへの作り直し」節 - - 段階9(実測②と補い)を実施中。漢字の多いページの 1 字ずつの読み直し(最大 16.5 秒)を字形の置き場の 4KB 分割で解消し、本文ページ内の JPEG 挿絵が出ない件を組み立て中の先回り展開で直した。組み立て中の空きの底を 2KB→17KB に引き上げ(章で使う CSS の規則だけ読む・設定一覧を常駐させない)、組み立て中にメニューを開くと落ちる件も直した - - 段階8bまで完了。Library(書棚)の並び・見出し・検索を、本の読み(file-as)に基づく五十音順にした(本家に出している PR #3651 を先に取り込み) - - 段階8aまで完了。書体を内蔵 flash に複製して読めるようにした(Text Settings → Style「Font Copy in Flash」、18pt は 16pt を 9/8 倍)。商業書籍で挿絵と表紙が白いページになる件も直した - - 段階8まで完了。表紙が SVG の包みになっている本でも、本棚と眠り画面に表紙が出るようにした - - 段階7まで完了。縦書きの本の挿絵と外字を表示できるようにした(挿絵は列を割り当てて置き、1字大の外字は本文の列に入れる) - - 段階6まで完了。本家の Character spacing(字間)が縦書きでも効くようにした - - 段階5(縦書きの中核)まで完了。縦書き検証テスト集の26試験を実機で確認。縦書きでも脚注の選択(Footnotes)が使えるようにした - - 段階4(横書きの組版)まで完了。禁則を JLREQ の各類に広げ(本家 PR #3609 の形)、長い段落の途中に字下げや空きが入る件、章内の飛び先が1ページ手前を指す件を直した - - 段階9から前倒しで、字の幅だけを読む経路を持ち込んだ。離れた章への移動(185ページの章)で組み立て 20.7 秒 → 12.6 秒、体感 21 秒 → 14 秒(`2026092815-diag`) - - この時点のブランチには日本語フォントの扱い・縦書き・挿絵などはまだ入っていない(以下の各項目は 1.6.0 ベースの `feat/vertical-1.6.0based` の内容) -- 章の境目の待ちを減らすため、読書中の待機時間に次の章を先に組み立てる(2026/09/09〜) - - 商業書籍で章をまたぐたびに7秒前後待つのを、ページを表示して1.5秒以上操作が無い間に少しずつ済ませる - - ボタンの読み取りを止めないよう1回の作業を25ms以内に区切り、字形の一時記憶を汚さないよう配置計算の前後で空にする -- 縦書きの本文中の1文字大の画像(外字)は字として列に流す(2026/09/10〜) - - 幅が列の間隔以内・高さが列の半分以内の画像は前後の字と同じ列の同じ位置に入り、ルビも付く。それより大きいものは従来どおり独立した列 -- 描画中のボタン操作は別の系で読み取って保持し、階調の描き分けは押されたら打ち切る(2026/09/10〜) - - 効かない時間を「反応が遅れる時間」に変える。待ち表示(Indexing)は 1〜3 秒の章の組み立てでも出す -- 章内リンクの飛び先は、その要素の行が実際に載ったページを指す(2026/09/10〜) - - 段落の1行目が次ページへ送られる場合に1つ手前を指していた。章の保存の版を50に上げたので初回オープンで全書籍が作り直しになる -- 語数の上限で分割された長い段落の続きに、一字下げを再び入れない(2026/09/10〜) -- 配置に使うメモリが足りないときは落とさず、その章の組み立てを失敗させて作り直しに回す(2026/09/10〜) -- 字形のその場読みの置き場を8→48枠に広げる(2026/09/10〜) - - 階調は短冊ごとに同じページを描き直すため、8枠では二十数字が毎回押し出し合い、描き直すたびにSDから読み直していた。遅いページの表示が15.3秒→4.9秒 -- 字形の先読みの取り分を、一時記憶を保持する床と同じ値にする(2026/09/10〜) - - 別々の数字だったため、空きを使い切って作った一時記憶をその場で捨てていた。字の大きいフォントに変えると露呈し、1ページ7.8秒+中断(abort)になっていた -- 1行・1列を作る前に、必要な大きさの領域を試しに取って確かめる(2026/09/10〜) - - 取れなければそのページを諦めて報告する。従来は確保に失敗すると firmware ごと停止していた -- 縦書きの列送りを、フォント内部の行送りではなく全角の幅×1.5から求める(2026/09/10〜、章の版51) - - 書体を変えると同じ設定でも1ページの文字数が変わっていた(BIZ 11列/Noto 7列)。全角を実測して揃えた -- 挿絵のログは短冊の判定より後に出す/小さい外字もRAMに載せる(2026/09/11〜) - - 前者は1ページ12行のログで診断の記録を潰していた。後者は297バイトの外字が24KBの門番に断られていた -- 本家 develop を併合(2026/09/11〜、章の版53) - - SDK の `ed39106`(X3の余計な電源投入を止める)でページ送りが 3,773ms → 1,601ms。#3439 でX3の階調を安定化 -- 縦書きの一番右の列のルビが画面端で切れないようにする(2026/09/11〜) - - ルビは列の右隣に描かれるため右端の列だけ領域外に出ていた。画面余白で足りない分だけ確保する -- 挿絵の初回展開の内訳を測り、SdFat の SPI をまとめ転送にする(2026/09/11〜) - - 17.7秒のうち復号自体は16%で、残りは保管層。SdFat が ESP32 で1バイトずつ転送していた。**保管層が2〜3倍**になり挿絵1枚16秒→8.1秒 -- 本家から2件を取り込み(2026/09/17〜、`2026091703-diag`、実機確認済み) - - #2925 輝度と色を別々の走査に分けた段階表示JPEGが真っ白になる修正(JPEGDEC への3つ目の補正)。`image-format-test.epub` の A3/A4 で退行なし - - #3581 合字表を解放したあとも `stubData`/`miniData` が解放済みの表を指したままになる修正。当版は一覧画面に入るたび解放するので本家より踏みやすかった。日本語フォントは合字ゼロで無縁、欧文の本文フォント(Literata・Alegreya 等)で該当。Literata+`horizontal-regression-test.epub` で章一覧⇄読書を繰り返し、落ちないことを確認 -- 一覧画面に入るときの字形の解放を本家へ出すことを検討し、実測のうえ見送り(2026/09/17) -- 横書きの日本語で長い段落を開くと落ちる件(2026/09/17〜、`2026091705-diag`、実機確認済み) - - 横書きは空白の無い段落を1語として受け、字境を探す前処理が全文字ぶんの8バイトの記録を一塊で確保していた(本家 #2288 由来)。2,559 バイトの段落で 20.5KB の連続領域を章の組み立て中に要求し、最大連続 5KB で abort。1回の走査に直して 3.4KB にし、それも置けなければ分割を諦めて落ちない経路へ回す。縦書きは別経路で影響なし。配置の結果は同じなので章の版は据え置き - - 併せて、本棚に入るときも一覧画面と同じく字形の保持を無条件に手放す。18pt の日本語書体では1ページぶんの保持が約35KB あり、読書から戻った本棚が 空き20KB/最大連続7KB になっていた(→ 57KB/45KB) - - 本家 develop `3555ff55` の素のビルドに探針を入れて X3 で測ると、本を読んでいる最中でも章一覧に入る時点で最大連続 47KB が残り、章一覧の初回描画は解放の有無にかかわらず 641ms、戻った直後のページも 1.37 秒で差なし。当版で観測した 78 秒は 1.6.0 起点のツリーだけの症状で、本家は #3521/#3527 で既に解消済み。1.6.5 起点の作り直しではこの解放も最初は載せない -- **配布**: 本節までの内容を **pre-release 20260917(`2026091707`、非DIAG、`3a692cd9`)** として公開した(2026/09/17)。添付は `crosspoint-OST-2026091707.bin` のみ。フォントは変更が無いので 20260909 の `fonts-202609080.zip` をそのまま使う。ページ配置の保存形式 48→54・本の情報の保存形式 11→12 のため、初回オープンで全書籍の作り直しが走る -- 商業書籍の挿絵が枠だけになる/本棚の縮小表紙が出ない(2026/09/18〜、`2026091714-diag`、実機確認済み) - - 3段とも「大きい一塊をヒープに求めていた」のが原因だった。**挿絵**: 取り出しが 8KB の連続領域を2つ要り、最大連続 5,364 の章の組み立てで失敗(→ 512B まで半分ずつ下げて確保)。**表紙の取り出し**: deflate の窓 32,768 を一塊で要り、読書後の本棚は最大連続 20,468 で頭打ち(→ 画面用の記憶 48,000 を借りる)。**表紙の復号**: MCU 用の 23,040 を、直前に確保した復号器本体が割った穴から取ろうとして失敗(→ 同じく借りる) - - 併せて、表紙作りの失敗を `recent.json` に恒久記録するのをやめた(本当に表紙が無い本だけ記録する)。従来は一度失敗すると再起動しても二度と試さなかった - - 失敗点ごとの記録を足し、SDの `image-diag.txt` だけで場所が分かるようにした(`jpg OOM mcu 23040` の1行で原因が確定した) -- **配布**: 本節までの内容を **pre-release 20260918(`2026091801`、非DIAG、`4ed08c40`)** として公開した(2026/09/18)。前日の 20260917 の差し替えで、挿絵と縮小表紙の3件だけが差分。添付は `crosspoint-OST-2026091801.bin` のみ、フォントは 20260909 の `fonts-202609080.zip` をそのまま使う -- 配布版 2026091801 で15分読んだ末に章の境目で abort(2026/09/18〜、`2026091803`〜`1807-diag`、実機確認済み) - - 番地を引くと `addVerticalToken` の `std::deque::push_back`。「配置の前に領域を試す関門」は配置時にしか無く、押し込み時に無かった。`hasHeapForToken`(空き4KB/最大連続2KB)を入口に置き、割ったら組み立てを失敗扱いに - - 章の組み立てが極端に苦しい原因も1つ潰した。送り幅の表(768語)が満杯になると、表に無い字の**幅を測るためだけに字形本体を予備リング(48枠≈17KB)へ読んでいた**。`readAdvanceOnly`(常駐→予備リング→SDの12バイト)で幅だけ返し、`MeasureOnlyScope` で組み立て中に限る(描画中に使うと二度読みになり page_draw が 76→384ms に増えたので)。同じ本・同じ章で 組み立て中の最大連続 2,164→13,300、余裕の最低 7,432→20,436 - - 保存済みの章を開くと30KB台しか空かず1ページ分の字形が入らない(`prewarm_entry_fails`、その場読み888回、6秒/ページ)のは18ptの限界で以前からの挙動。別件 -- 横書きの禁則を JLREQ 3.1.7/3.1.8 の各類に広げる(2026/09/18〜、`2026091807-diag`、実機確認済み・章の版55) - - 横書きは本家 #2288(韓国語対応)由来の集合のままで括弧と句読点しか知らなかった。JLREQ 原文で確認: 3.1.7 の本則が cl-02〜cl-11・cl-13 を挙げ、**小書きの仮名(cl-11)も本則に含まれる**(Note の「行頭禁則としない方法」は採らない)。文字は付属書 A のとおりで、〒 は cl-12 に無いので入れない。……――は同じ字が続く間は切らない - - 横書きは「切ってよい組か」で判定して禁じられた組を1語に貼り合わせる方式なので、JP版 #144 のような追い出しの繰り返しは要らない(推移的に『「漢」』。は割れない)。縦書きの列末の戻しだけ1回→上限4回に(『「 の入れ子で「が列末に残っていた) - - 出典は JIS X 4051 ではなく JLREQ(W3C、日英併記で公開)に統一。**本家に PR #3609 として提出**(2026/09/18、ブランチ `fix/cjk-line-break-prohibitions`、`CjkLineBreak.h` に切り出し+gtest 9件、本家 develop `dc9c3eab` 版でも実機確認済み。審査待ち) - - 隣り合う組がすべて禁則になる人工的な試験文字列は1語が1行より長くなり「長い語を割る」予備の経路に落ちるので、現実的な語に差し替えた。`` の境目で語が貼り合わされ「見ているも」が広がるのは本家由来の別件 -- **配布**: 本節までの内容を **pre-release 20260918-2(`2026091808`、非DIAG、`15bdbaab`)** として公開した(2026/09/18)。同日の 2026091801 の差し替え。添付は `crosspoint-OST-2026091808.bin` のみ -- **配布(テクニカルプレビュー)**: 下の flash 複製の仕組みを **pre-release 20260923-tp(`2026092204-diag`、診断版のまま、`0aaf2ca7`)** として公開した(2026/09/23)。これまでの pre-release とは別系統で、普段使いは 20260918-2 のまま。説明文に「microSD のルートに動作記録(input-diag.txt など 5 種)が書き出される」旨と、複製の所要 2 分・firmware 書き換えで消える・電池 20% 未満は複製しない・戻し用の旧 firmware が失われる、を明記 -- **SD 書体を内蔵 flash に複製して読む(crossmux版 A の実装)**(2026/09/22〜23、`2026092204-diag`、実機確認済み: 初回起動の自動複製 6,549,504B が約 2 分で完了し、以降 `font=NotoSansJP_16.cpfont … src=flash flash_kb=6396 scale=18/16`。Home の空きヒープ 56.6KB/最大連続 51KB、本を開く各段階のヒープは複製 On/Off で同じ(sect 45KB、page1 33〜34KB)で、読み経路の常駐メモリは増えていない。確認中に商業本の第 44 章の作り直しでヒープが尽きて落ちた 1 件は Off でも同じ段階で同じ値になる既知の型で、本件とは無関係と判断) - - 仕組み: 使っていない側の firmware 領域(app0/app1 の空いている方、先頭 4KB のヘッダを除いて 6,549,504B)に選択中の書体ファイルの**先頭部分**を複製し、字形の読みを SD ではなく内蔵 flash から行う(`SdCardFontCache`、`HalOtaSlot`、`SdCardFont` 内の読み取り窓口 `FontFile`)。ファイル全体が入るなら全体、入らなければ入る分だけを複製し、**Regular(style 0)の実体が丸ごと入ること**を条件にする。当版の cpfont は Regular+Bold の 2 style で Regular が前半にあるので、複製の範囲外=Bold の字形だけが SD 読みになる。範囲外の読みは窓口が自動で SD に切り替える(SD のファイルは必要になるまで開かない) - - 18pt: NotoSansJP_18 は Regular だけで 7,621,409B あり入らないので、**16pt の実体を複製し 9/8 倍に拡大して 18pt を出す**(前項の検証機構を本番化。倍率は「選んだ大きさ/実体の大きさ」で上限 9/8、配布の大きさでは 18→16 の組だけが該当)。BIZUDGothic_18/BIZUDMincho_18 は Regular が 4.0〜4.2MB で本物が入る。配布 zip(fonts-202609080)の実測: NotoSansJP_16 の Regular 終端 6,160,269B(入る)、NotoSansJP_14 5,035,418B、BIZUDGothic_16 は全体 6,527,441B が入る - - 操作: Text Settings → Style に「Font Copy in Flash」を追加。On にすると複製を作る(進捗画面。SD→flash の複製と、flash からの読み戻し照合の 2 段で 6MB なら 1 分前後)。On のまま書体や大きさを変えると、変えた直後に複製を作り直す。失敗(入らない・書けない・照合不一致)は設定を Off に戻して理由を表示し SD 読みのまま。**firmware を書き換えると複製は消える**(書き換え先が同じ領域)ので、次の起動で設定が On なら自動で作り直してから Home に行く - - 電池: 複製は SD の読みと flash の書き込みを 1 分ほど続けるので、**電池 20% 未満(USB 給電中は除く)では複製を始めず設定を Off に戻す**(起動時の自動作り直しは Home に行く、設定画面では理由を表示)。途中で電池が切れてもヘッダが書けていないので複製なし扱いになるが、次の起動でまた同じ複製を始めてしまうのを避けるため(2026/09/22 ユーザー指摘) - - 診断: `font=` 行に `src=flash|sd flash_kb=… scale=n/d` を追加。`font_copy=` 行に起動時の判定(候補・倍率・容量・有効か・現在の読み元)と複製の結果(結果・大きさ・時間)を 3 件まで残し、複製の直後は強制で書き出す。18pt を選んで複製 On なら `font=NotoSansJP_16.cpfont … src=flash flash_kb=6396 scale=18/16`、Off なら `font=NotoSansJP_18.cpfont … src=sd scale=1/1` - - 安全側: 先頭 sector の消去→本体の複製(CRC-32 を取りながら)→flash からの読み戻し照合→ヘッダ(`OSTSDFC1`、経路・大きさ・ヘッダと TOC の FNV-1a・CRC)の書き込みの順。途中で電源が落ちてもヘッダ不正=複製なしとして SD から読む。読み込み時は経路・ファイル長・ヘッダと TOC の hash を照合するだけで本体の CRC は取り直さない(crossmux版と同じ)。書き換え直後で確定していない firmware では書かない(当版は Arduino の初期化が起動時に確定させるので実際は常に可)。firmware の書き換え先が空き側なので、書き換え前の firmware への戻しは失われる(当版の復旧手順は update.bin 前提で支障なし) - - 出典: crossmux版 PR #57(`perf: cache SD fonts in inactive OTA slot`)。当版は「先頭部分だけの複製」と「16pt の拡大」の組み合わせが違うので magic を別にした。前項の検証機構(`OST_SCALE_TEST`、内部値 118)は削除し、拡大の仕組みだけを残した -- 章ごとの CSS の読み直しが空の一覧で走り、章から CSS が全部抜ける件(2026/09/25、`2026092503-diag`、実機確認済み・章の版 56) - - KADOKAWA テンプレートのような大きな CSS は保存が「一部だけ」になり、章を組むたびにその章で使う規則だけを読み直す。本を開いた経路によっては CSS ファイルの一覧が空のままで、読み直しは何も読まずに規則ゼロで章を組んでいた。リアデイルの大地にて 8 巻で、1em 指定の外字画像(迸)が元の 128px のまま 1 列を占めた - - 一覧が空なら ZIP から CSS を探して補う。CSS なしで組まれた章を作り直すため章の版 55→56 -- 16pt→18pt の拡大で、字形の箱と画素の引き伸ばしを正確に 9/8 倍に(2026/09/25、`2026092501-diag`、実機確認済み) - - 寸法の切り上げと原点の四捨五入を別々に行い箱いっぱいに引き伸ばしていたため、実際の倍率が 1.13〜1.17 倍にばらつき、縦書きの 「」 が本物の 18pt より列の中心寄りに約 1px ずれ、墨も 3〜23% 多かった(線がやや太い)。元の墨の端を 9/8 倍して外側へ丸めた箱に、画素中心を正確な比で戻して補間する。墨の位置は理想から 0.1px 前後、墨の量は本物の 18pt とほぼ同じ -- 読書の後の Home で表紙の縮小画像が作れない件(2026/09/25、`2026092505-diag`、実機確認済み) - - Home のヒープを全部書き出して起動直後と比べると、読書は大きな物を何も残していない。本を開くたびに作り直される「最近の本」の文字列や、最初に使われた瞬間に作られる排他部品などの小物が、起動時の 60KB 前後の一続きの空きに散り、最大の塊が 17〜35KB に細っていた - - 縮小画像づくりは画面用の記憶を借りて作業用の行だけをそこから取っていたが、JPEG の解読器(17,884B の一塊)は一般の空きから確保していて先に失敗していた。借りた領域の先頭に解読器を置き、残りを作業用の行に回す(1440 幅で計 40.9KB、借りられる約 48KB に収まる) -- 診断の追加(2026/09/24〜25、診断版のみ): 空きメモリの最小値が下がった区間の記録(`heap_min_log=`、ページ描画の検査点 pg:load〜pg:msb)、Home に入った時点のヒープの全塊と作業単位の一覧(`heap-map-boot.txt`=起動後最初、`heap-map.txt`=以後)。最小値の底はページ描画中(白黒の描画中や階調の 1 面目)で 3KB 前後まで下がることが分かった(対策は上の 2026/09/26 の項) -- ページ描画中の空きメモリの底を上げる(2026/09/26、`2026092604-diag`、実機確認済み) - - 底は字形の予備置き場(その場読みの環)が空きを見ずに 48 枠まで育つところだった。空きが 16KB を割ったら 12 枠以上は増やさず古い枠を上書きして使い回す。描画中の最小の空きが 2.7KB 前後 → 6〜6.8KB - - 挿絵の事前変換も、最大連続だけでなく空きの総量が足りないときに画面用の記憶を借りる -- Home の空きが読書のあとで細切れになる件の根本対策(2026/09/26、`2026092605-diag`、実機確認済み) - - 前項の診断でヒープの全塊に確保元の印を付けて調べると、読書中に初めて作られてそのまま残る小物が起動時の一続きの空きに散っていた。小数の書式化の作業領域(作業単位ごと)、共有ポインタ用の排他部品、時刻取得の鍵、C++ 例外の管理情報、縦書きの全角幅の記憶、「最近の本」の一覧の伸長など - - これらを起動時と描画の作業単位の開始時に先に作らせる、固定の大きさにする、同じ内容なら書き換えない、のいずれかで読書中に新しく作らないようにした。読書のあとの Home の最大連続が 17〜35KB → 65.5KB(起動直後 69.6KB) - - 診断版には確保元の印(1 塊 12 バイト増)と、排他部品・newlib の鍵の作成元の記録を追加(通常版には入らない) -- 縦書きで入れ物(div)の上下の余白を、中の段落すべての列に効かせる(2026/09/26、`2026092607-diag`、実機確認済み・章の版 58) - - 縦書きでは上の余白が列の頭、下の余白が列の足の空きになる。入れ物の上の余白を最初の段落にだけ渡していたため、商業書籍の場面の区切り(五文字下げた入れ物の中に「・」だけの段落が三つ)で、二つ目と三つ目の「・」が列の頭に上がっていた(うちうち『逃げる魔法使い』で発見) - - 縦書きのときは段落が入れ物の上下の余白・詰め物(padding)を受け継ぐようにした。最初の段落に預けていた分とは大きい方を取り、二重に下げない(詰め物の入れ物で最初の段落だけ 4 文字下がる形で一度踏んだ) - - `vertical-test-suite.epub` のテスト25(場面の区切り、長い段落、入れ子、段落自身の余白、列の足側、詰め物、入れ物の外)で 7 項目とも合格 -- Home 画面の本体を、前の画面を消した後で作る(2026/09/26、`2026092608-diag`、実機確認済み) - - 前項の対策後も、読書のあとの Home で最大連続が 45〜51KB に割れることがあった。確保元を引くと Home 画面の本体(約 200 バイト)で、画面の切り替えは次の画面を作ってから前の画面を消すため、読書画面の物が小さな穴を埋めているうちに大きな空きの途中へ置かれていた - - Home へ戻るときは作成要求だけを預かり、読書画面を消してから作る。読書のあとの Home のヒープが起動直後と一致するようになった(空き 72.9KB/最大連続 65.5KB) -- 挿絵の事前変換の取り出しで、読み書きの区画も画面用の記憶を借りた残りに置く(2026/09/26、`2026092609-diag`、実機確認済み) - - 伸長の状態と窓(約41KB)は画面用の記憶から借りていたが、読み込み用・書き出し用の 8KB 区画2つはヒープから取っており、章の組み立て中の空きを 22.7KB → 4.8KB まで下げていた - - 借りた残り(約6.8KB)に区画を約3KB ずつ置くようにし、取り出しの前後の空きの減りが約18KB → 0.3KB、取り出し時間も 2.2〜2.3 秒 → 1.7 秒 -- 設定項目の一覧を常駐させず、使うときだけ作る(2026/09/26、`2026092613-diag`) - - 本家は一覧を一度だけ作って起動中ずっと持っていたため、約13.9KB のヒープが読書中も埋まっていた(空き 5〜6KB で描画している場面がある) - - 一覧が要るのは設定の読み書き・設定画面・Web の設定ページだけなので、そのたびに作り直す(数 ms) -- 診断の追加(2026/09/26、診断版のみ): 空きが 16KB を割ったとき確保元ごとの持ち分を `heap-low.txt`(章の組み立て中は `heap-low-build.txt`)に書き出す。確保元の印からは operator new・malloc の共通部分を除き、呼び出し元が見えるようにした -- 試験用 EPUB の整理(2026/09/26): `test/epubs-ja` の画像の試験4冊(表紙SVG・縦書きの中の画像・画素数・形式と書き方)を `image-test.epub` の1冊に統合し、`vertical-test-suite.epub` をテスト25まで入った版に差し替えた -- 空きの塊が細った読書中に、挿絵が枠だけになる件(2026/09/23、`2026092302-diag`、実機確認済み) - - JPEG の解読器(JPEGDEC)は X3 で 17,884B の一塊が要る。読書を続けて最大連続が 17,396B まで細ると、章の組み立て中の挿絵の事前変換が確保の段階で全部失敗し、表示時の再試行も書体の解放で塊が育たず代わりの枠のままだった(2 回とも 17,396B で失敗、19,444B 以上は成功) - - 事前変換は画面を描かないので、塊が足りないときだけ画面用の記憶を借りて解読器を置く(PNG の逐次展開・ZIP の展開と同じ仕組み)。実機で最大連続 15,348B のまま 2 枚とも約 3 秒で変換でき、`image-diag.txt` に `jpeg decoder in lent framebuffer` が出る。表示時のその場の変換は画面を描いている最中なので従来どおり -- 診断ファイル `input-diag.txt` の書き出しを分割(2026/09/23、`2026092301-diag`、実機確認済み) - - 2,304B の枠 1 つに全体を組んでいたため、`font_copy=` の追加後は末尾の説明が毎回切れ、描画の記録が 12 件たまると枠を超えて**書き出し自体を省いていた**(長く読んだ後ほど古い記録が残る)。前半・後半を同じ枠で順に書き、説明文は flash 上の定数から直接書く。`font_copy=` の行も途中で切れていたので枠を広げた(常駐 +144B) -- **拡縮の検証機構**(2026/09/22、`2026092201-diag`、実機確認済み。`-DOST_SCALE_TEST=1` のときだけ組み込まれ、通常版には入らない) - - 目的: crossmux版由来の「SD 書体を空き側の firmware 領域(実効 6.5MB)に複製して flash から読む」案(A)に向け、18pt の実体(NotoSansJP_18 は 15.6MB で入らない)の代わりに **16pt の実体を 9/8 倍に拡大して 18pt を出す**画質を実機で確かめる - - 作り: Text Settings → Size に「18 pt (16 x9/8)」(内部値 118)。`SdCardFont::load` に倍率を持たせ、TOC の行送り・上端・下端を 9/8 倍、字形が置き場(mini 領域・予備の環)に入る瞬間に字形記録(幅・高さは切り上げ、寄せ・送り幅は四捨五入)と 2 階調 bitmap(双一次で拡大して 4 段階に丸め直す、整数演算)を拡大。送り幅表もその場読みも倍率適用。書体の識別子と章の保存は 118 として本物の 16/18 と別扱い - - 実機: `font=NotoSansJP_16.cpfont advY=54`(本物の 18pt と同じ行送り)で起動、縦書き 146 升 174ms、先読み 225ms、その場読み 18 字、組版・禁則・約物・ルビに異常なし。画質は写真では本物と区別がつかず、最終判断はユーザーの目視待ち - - 前段の検討: 10pt→18pt(1.81 倍)や 12pt→18pt(1.52 倍)は 2 階調化で画の太さが不揃いになり本文には不可、16pt→18pt(1.12 倍)だけが許容範囲(`e-ink/pr-photos/font-scale-compare.png`)。FreeType(本家 PR #3646 の方式)は cmap+loca を丸ごと RAM に置くため X3 では不可(BIZUDGothic 258KB、NotoSansJP 203KB) -- 確認対象のフォークに **crossmux版**(0x1abin/crossmux、中国語対応の community fork)を追加(2026/09/22、ユーザー指示)。本家 1.6.0 起点、SDK も自前 fork、縦書き・禁則の実装なし。UI・機能面の参考(Apps、読書統計、C3 の読書メモリの上限管理)として見る -- 本家とフォークの更新確認(2026/09/22): 本家 develop は 09/20〜21 に #3630(一覧の NFC 合成の復元)・#3528(語間・字間の設定、章の版 47)・#3608(転送後に Library の索引を作り直す)。#3528 で PR #3609 が衝突したため develop の上に積み直し(章の版 48、CI 通過)。抹茶版が 1.6.0 安定版(辞書引きと漫画が中心、当版に無縁)。witchhunt版 2.31 で当版に関係する知見が3つ: (1) **章ごとの style の記憶(inline style と tag|class の解決結果)を 64 件で打ち切り**——PDF 由来の EPUB は語ごとに固有の inline style を持ち、記憶が 129KB まで育っていた(当版の CSS の省略と同じ問題の別の入口。1.6.5 起点の作り直し時に本家の `ChapterHtmlSlimParser` を見て要否判断)。(2) SD 書体を最も近い顔から拡大して 20〜26pt を出す(当版は 18pt が上限で、拡大は画質を落とすので採らない)。(3) SD の読み出しをセクタ単位で束ねる(当版は `USE_SPI_ARRAY_TRANSFER` で把握済み)。本家 PR #3646(TTF)は未マージ、#3469(X3 階調の縦縞)も未マージ -- **本家の Library 表示を日本語で使えるようにする読み対応を本家に PR #3651 として提出**(2026/09/21、枝 `feat/library-file-as-reading`、本家 develop `ce2b4fcd` 起点、当版のコードは含まない) - - 本家 Library(#3366)を実機で試した結果「日本語では利点が薄い」(漢字の題名が符号順、見出しが1字ごと)。EPUB の読み(`file-as`、蔵書 2,256 冊中 1,943 冊が題名に持つ)を並び・見出し・著者の組にだけ使い、表示は本の題名・著者名のまま - - 読み取り: `refines` の前後どちらの書き方も、EPUB 2 の `opf:file-as` 属性も読む。書誌の保存に読みを2欄追加(v11) - - 折りたたみ: カタカナ→ひらがな、全角英数→半角、ー・々・ゝゞ は語の一部、見出しは五十音の行頭(が→か、ぱ→は) - - 並びの鍵: 12 バイトの鍵にかなを1字1バイトで詰め(従来4字→12字)、それでも同じ題名は読みの全文で並べ直す(叢書の巻順のため)。著者順は読みが「姓 名」なので姓の推測をやめる。索引形式 3/折りたたみ版 4 - - 実機: Title で あ・か の見出し、ら でリアデイル 4→8 巻順、Author で読み シーズ の Ceez が さ〜た の間。読みの無い自作 EPUB は従来どおり漢字1字の見出し。host テスト 105 件通過 - - 別件として判明: 本家は著者欄「Ceez, てんまそ」(著者と絵師)を「姓, 名」と見なして「てんまそ Ceez」に反転する(著者2人の本すべて)。この PR には含めない - - PR の写真は fork の孤立した枝 `pr-assets` に置いた(claudeworks は非公開のため) -- 本家とフォークの更新確認(2026/09/20): 本家 develop は 09/18 以降 5件(#3613 網の画面を抜けるときに無線を切る、#3618 組み込むUI言語の選択、CI 2件、独語訳)で、当版に効くものなし。#3618 は `custom_i18n_builtin_langs = en` で 34 言語分の文字列をフラッシュから外せるので 1.6.5 起点の作り直しで使う。本家 SDK は当版の `fde240f` から 61件先(TTF 描画、一覧の行の要求方式 #105、X3 の絶対階調 #94 は当版に含まれ、本家側の PR #3469(X3 の階調画像の縦縞、BMP 表示と眠り画面が対象)は未マージのまま)。Yomuka版 v0.7.6.0 の候補は 2件: 曲線引用符 ‘’“” を縦の升に正立で置く(当版は横倒しのまま。要実機写真)、ルビ・上付きに 10pt 専用の書体データ(当版は本文書体の SUP 縮小。細い画の途切れが出ているか要写真)。抹茶版 #282(区間表の共有)・JP版 v0.3.2(動的壁紙・進捗率・テーマ)・witchhunt版 2.30(触れる操作・機種追加)は当版に無縁。当版の本家 PR は #3539・#3609 とも人のレビュー待ち -- 本家 1.6.5rc の蔵書表示が 4096 冊で止まる報告(討議 #3544)について当版を確認(2026/09/17) - - 上限は蔵書目録 `lib/LibraryIndex/`(#3366)の `CLIX_MAX_RECORDS = 4096` で、当版にはその機能自体が無い。当版で冊数に効くのは Browse Files の1フォルダあたりの件数(本家 1.6.0 と同じ作りで、見積もり数百件が頭打ち)と、`/.crosspoint/` 直下に1冊1フォルダで平らに増える作業用フォルダ(本家由来)。作り直しで蔵書表示を採ると 4096 の上限もそのまま入る -- 内蔵字形のページ枠は同じ書体で二重に取らない/挿絵の保存が無いページの四角の下書きは描かない(2026/09/10〜、抹茶版から) - - 前者は読まれない枠が4枠の1つを潰していた分の解消、後者は書き換え1回(約0.5秒)の削減 - - 挿絵ページが白黒→階調の2段階で出るのはX3の階調表示の仕組み上の挙動で、実用上の不都合が無いためこのままとする - - -## 1.6.5ベースへの作り直し(2026/09/28〜) by claude code - -本家 1.6.5(タグ `1.6.5`=`93e98bb7`、2026/09/27)から `vertical-1.6.5` を作り、当版の機能を段階ごとに載せ直す。 -前回(1.6.0)は机上で取捨を決めたが、今回は本家が断片化・入力の取りこぼしに正面から取り組んだ後なので、 -**本家の対処をまず素のまま採り、実測で足りない箇所だけ当版の実装を戻す**。freeink-sdk は 1.6.5 が指す -`111fdcc7` を使う(当版が使っていた `fde240f` とパネル待ちの修正 ed39106 を含むので、SDK で持ち込むものは無い)。 - -| 段階 | 中身 | 状態 | -|---|---|---| -| 0 | 素の 1.6.5 のビルド | 完了(RAM 57,912B/flash 5,621,527B) | -| 1 | 診断(INPUT_DIAG、ビルド番号) | 完了(`2026092803-diag`、実機確認済み) | -| 2 | 時計と監視(#3562 の地域・夏時間の設定に載せ替え) | 完了(`2026092806-diag`、実機確認済み) | -| 3 | 日本語フォント(生成フォントと描画の追加分。メモリ処理は入れない)+素の実測① | 完了(`2026092807-diag`、実測済み) | -| 4 | 横書きの組版(禁則、長い段落) | 完了(`2026092818-diag`、実機確認済み) | -| 5 | 縦書きの中核 | 完了(`2026092901-diag`、実機確認済み) | -| 6 | 縦書きの字間(本家 #3528 の字間を縦書きの字送りにも効かせる、新規) | 完了(`2026092903-diag`、実機確認済み) | -| 7 | 挿絵(本家 #2332 の上に載せる) | 完了(`2026092908-diag`、実機確認済み) | -| 8 | 表紙(SVG の包み、縮小表紙) | 完了(`2026092910-diag`、実機確認済み) | -| 8a | flash から書体を読む仕組み、16pt を 9/8 倍して 18pt に使う仕組み | 完了(`2026092913-diag`、実機確認済み) | -| 8b | 書棚の読み順(本家 PR #3651) | 完了(`2026092914-diag`、実機確認済み) | -| 9 | 実測②と不足分の補い(断片化対策・描画中の入力・本棚での解放など) | 実施中(`2026092918-diag` まで実機確認済み) | -| 10 | 配布(非診断版、README の整理) | | - -### 段階1: 診断(2026-09-28、`2026092803-diag`、実機確認済み) -- `src/util/InputDiag.*` と `scripts/ost_version.py` は旧ツリーの最終形のまま持ち込み、呼び出しは本家 1.6.5 にある処理にだけ入れ直した - - 主ループの読み取り間隔と書き出し(書き出しは、描画中に主ループが途中で戻る本家 #3652 の分岐より手前に置いた)、画面の描画時間、Home に入った時点のヒープの一覧、読書画面の開く各段階・閉じたときのヒープ・章の組み立ての計時・ページ描画の検査点、章の保存のページごとの書き出し時間、クラッシュ報告の先頭のビルド番号 - - 字形の読み込み回数と字形置き場の解放記録は段階3、縦書き・挿絵・先読みの計測点は各段階で入れる。一覧画面の表示範囲の記録は、本家が一覧の作りを変えたため入れる場所が無く見送り -- 非診断版もビルドが通る(RAM は素の 1.6.5 と同じ、flash +236B) -- 実機での最初の観察(素の 1.6.5 に診断だけ、日本語 SD 書体・商業書籍の横書き、文字のアンチエイリアス ON) - - ページ送り 1.1〜1.3 秒、章の組み立て最長 3.5 秒(5回に分けて)、本を開く各段階の空き 95→70KB(最大連続 41KB のまま)、閉じると 96KB に戻る - - 空きの底は 11.4KB(最大連続 4.6KB)で、アンチエイリアスの帯描画の 8KB 作業領域を取った直後。その時点の持ち主の上位は、画面用の記憶 53,248B(SDK が起動時にヒープに取る。旧ツリーでも同じ)、設定項目の一覧 9,216B(本家は起動中ずっと保持。旧ツリーでは `8cc5f333` で使うときだけ作る形にした)、読書中の CSS 6,912B+4,352B、SD 書体の一覧 5,376B と書体ファイル名の文字列 35 個 3,272B、章の組み立て中の XML 読み取り用 4,352B - - Home の初回描画 7.1 秒は表紙の縮小画像の作成(823KB の JPEG の展開 3 秒+変換 2.5 秒)。初回だけ - -### 段階2: 時計と監視(2026-09-28、`2026092806-diag`、実機確認済み) -- 時計モードの画面・数字の画像・12時間表示は旧ツリーのまま。Home のメニューの末尾(Settings の次)に「Start clock mode」 -- 時刻は本家 #3562 の地域・夏時間の設定に従う。本家の時刻の読み出しは 10 秒ごとにしか RTC を読まず秒が古くなるため、時計の画面向けに RTC を毎回読んで地域の規則で変換する `HalClock::getLocalDateTime()` を足した。旧版の UTC の時差を自前で足す計算は廃止 - - 1.6.0 の「UTC+9」の設定は本家の移行処理で一覧の「UTC+9」として引き継がれ、表示は変わらなかった。「Tokyo / Seoul」に切り替えても同じ -- 時計の描画と時計表示中のメイン処理を 30 秒の監視に登録(すべてのビルド)。CPU の速度切り替えの直列化、電池電圧の記録、「自動スリープさせない」と「速度を保つ」の区別(時計表示中は 10MHz)も旧ツリーのまま -- 実機確認: わざと固まらせる検証ボタン(CLOCK_HANG_TRIGGERS)で、メイン処理(Confirm)・描画(側面ボタン)とも 30 秒以内に再起動し、`crash_report.txt` にそれぞれ `loopTask`/`ActivityManager` の名前が残った。時計表示中は `cpu_mhz_min=10`、ボタンの読み取り間隔 76ms 以内、空き 78〜80KB で一定 - -### 段階3: 字形の計測と素の実測①(2026-09-28、`2026092807-diag`) -- 旧ツリーのフォント層の変更を仕分けた。SD に置く日本語書体はそのまま 1.6.5 で使え、生成フォントの定義はフォント用ブランチにあるので firmware で移すものは無い。メモリ処理(4KB 分割の置き場、予備枠 8→48、解放の経路など)は段階9、縦書き用は段階5、flash から読む仕組みは段階8a、挿絵・階調は段階7 -- 入れたもの: 字形を1つずつ読んだ回数・置き場の作り直し(回数と時間)・置き場の解放記録・描画前の走査の結果・幅の表の作業量・本文の書体を診断に出す計測(書体のメモリの扱いは変えない)。異体字選択子(VS1〜VS16、IVS)の読み飛ばし(章の版 48→49) -- 素の実測①(商業書籍の横書き、NotoSansJP 18pt、アンチエイリアス ON) - - **離れた章への移動が 39.2 秒**(組み立て 34.6 秒)。本家は字の幅を 768 字分まで表に覚え、日本語の章はそれを超えるため、以降の幅の測定のたびに字形の画像まで SD から1字ずつ読む(1回の描画で 2,817 字)。旧ツリーの `15bdbaab` が塞いでいた穴なので、段階9から前倒しして持ち込む - - 同じ本を開き直した直後に空き 2.7KB(最大連続 1.2KB)。持ち主は本の CSS 36KB、設定項目の一覧 9KB、画面用の記憶 53KB など - - 読んだ後の Home で空き 62.5KB に対し最大連続 17.4KB(起動直後 102KB/98KB)。旧ツリーの `7239d0bb`/`f3293ca7` が直した形と同じ - - ボタンの取りこぼしは無し(押下 230 回すべて受け付け) - - 2点目・3点目は縦書きと挿絵を載せた後の実測②(段階9)で判断する - -### 段階3の続き: 幅だけを読む経路の前倒し(2026-09-28、`2026092815-diag`、実機確認済み) -- 測り方: 商業書籍の横書き、キャッシュを消して電源を入れ直し、目次の8番目から1つ前のページへ戻る(前の章 177KB・約 180 ページを最初から組み立てる) -- **段階3の 39.2 秒の大半は診断版の記録の重さだった**(訂正)。メモリの持ち主の記録(1 塊ごとの印と呼び出し元の遡り)を外すと、同じ操作の組み立てが 31.4 秒 → 20.9 秒。持ち主の記録は `INPUT_DIAG_ALLOC_TAGS` を付けたときだけ有効にした。非診断版でも体感 21 秒で、残りは本物の遅さ -- 入れたもの(旧ツリーの `15bdbaab` を元に作り直し) - - 幅の表(768 字)が満杯になった後は、字形の画像を読まずに幅だけを返す `readAdvanceOnly`(常駐の置き場 → 予備の環 → SD の 12 バイトの字の記録)。章の組み立ての間(`MeasureOnlyScope`)だけ使う - - 組み立ての間は書体ファイルを開いたままにする(1 回の読みが 3.9ms → 1.15ms) - - SD から読んだ幅を 512 字分の表(約 3KB)に覚える。組み立ての1回分(8 ページ)ごとにファイルと一緒に捨てるので、読書中・Home には残らない - - 診断に `build_adv_only=`(呼ばれた回数・SD を読んだ回数・時間)を追加 -- 結果(同じ章): 組み立て 20.7 秒 → **12.6 秒**、体感 → **14 秒**。幅だけの読みは 2,734 回すべて SD・10.7 秒 → 2,580 回のうち SD は 1,269 回・2.3 秒。残りは配置の計算そのもの(約 6.6 秒)、ページの書き出し 2.3 秒、表の範囲の幅の読み 1.4 秒 -- 試して戻したもの: 組み立て中だけ幅の表を 2,048 字に広げる案は、時間が変わらず(21.3 秒)空きが減ったので取り消した -- 本を開く途中の空き(`open_heap` の sect)が 93KB の回と 40〜55KB の回があるのは、今回の変更ではなく、起動直後に開いた章の組み立てが1回で終わるかどうかの差。終わらない間は XML の読み取り器を次の回まで持ち続ける(本家の作り)。その状態でのページ描画で空きの底 3.9KB(最大連続 2.2KB)があり、段階9で扱う - -### 段階4: 横書きの組版(2026-09-28、`2026092818-diag`、実機確認済み・章の版 51) -- 禁則: 本家に提出中の PR #3609(`CjkLineBreak.h`+試験 9 件)をそのまま持ち込んだ。行頭に ー・々〜%」。、と小書き仮名、行末に始め括弧が来ない。……―― は同じ字が続く間は切らない。字の集合は旧ツリーと同じ。1.6.5 で本家がハングルの行分けを別の関数に分けていたので、ハングルも同じ規則を通す -- 長い段落: 字境の表を1回の走査で作る(段落のバイト数の8倍を一塊で求めない。旧ツリー `b18977ad`) -- 長い段落は語数の上限(CSS のある本は 320 語)で分けて組む。その続きの回を段落の1行目と見なして字下げしていた(旧ツリー `82eed024` と同じ直し)。全角の空白で始まる段落には端末の字下げを重ねない -- **新規**: 段落の上の余白(CSS の margin-top)を最後の回でまとめて足していたため、分けて組んだ長い段落では途中に 0.5em の空きが入り、段落の頭には入っていなかった。最初に行を出す回の前に1回だけ足す。旧ツリーも同じ作りだった -- 章内の飛び先は、目印の段落の1行目が実際に載ったページを指す(1.6.5 も旧ツリーの修正前と同じく、次ページへ送られると1ページ手前を指していた。旧ツリー `82eed024`) -- 実機(`horizontal-regression-test.epub` 第1・9・13章): 禁則の違反なし、異体字選択子の後に四角が出ない、第13章の 2,559 バイトの段落で落ちない、途中に字下げ・空きなし、「目印へ飛ぶ」が正しいページに着く。空きの最低は 37.6KB -- 1行に入りきらない禁則の塊(例: 18pt の「名・ー・・・々・〜・%・……――」)を途中で割ると、英単語と同じく行末に「-」が付く(本家の作り)。割ったことが見て分かるので、このままとする(2026/09/28 判断) - -### 段階5: 縦書きの中核(2026-09-29、`2026092901-diag`、実機確認済み・章の版 53) -- 旧ツリーの縦書きを 1.6.5 の作りに合わせて載せ直した。文字の分類(UAX #50・約物・小書き仮名・禁則)、CSS の圏点・文字の向き・縦中横・二段の子孫指定子、横倒しの描画、列の描画(ルビ・傍線・二分アキ)、列組み、字ごとの分解、列のページ配置、入れ物の余白、右開きのページ送り -- 1.6.5 に合わせて変えた点: 語の持ち方(WordStore)に合わせて列組みを書き直し、縦書きの字にも本文の位置を持たせた(読みかけの位置が字の位置で保存される。旧ツリーは段落の終わりの位置だった)。字形の置き方(Frame)に横倒しを1種類足した -- 本家の「空き 48KB 未満で CSS を無視する」関門は外した。読書中の空きは 44〜62KB を行き来するので、縦書き・ルビ・圏点の指定が段落によって効いたり効かなかったりする -- 長い段落の区切りを語を足す途中でも行う(段階9から前倒し)。縦書きは1字が1語なので、区切らないと 4KB 読むたびに 1,300 語ほどたまる -- **新規**: 縦書きの列にもリンクの範囲を持たせ、Footnotes で番号を選んで飛べるようにした(旧ツリーでは一覧は出ても選べなかった)。1 ページの脚注は本家の上限どおり 16 件まで -- まだ入れていないもの: 縦書きの本の挿絵と1字大の外字(段階7)、縦書きの字間(段階6) -- 実機(`vertical-test-suite.epub` の 26 試験、Extra Paragraph Spacing OFF): すべて期待どおり。漢字の多いページの階調描画は 1 ページ 4〜6 秒(字形の予備の置き場 8 枠の読み直し。段階9)。ルビ中の 2 桁の数字は斜めにずれて並ぶ(重なりではない、記録のみ)。列の末尾の中点は旧ツリー同様の既知の未対応 - -### 段階6: 縦書きの字間(2026-09-29、`2026092903-diag`、実機確認済み) -- 本家 #3528 の Character spacing(-2〜+2px)を、縦書きでは字と字の縦の間隔に効かせる。1マスごとに足し、二分に詰めた約物・縦中横のマスも同じ。横倒しの欧文の並びは1マスとして1回だけ足す(横倒しの描画は字間を持たないため、1字ごとに足すと字との位置がずれる) -- 旧ツリーの縦書き専用の字間(設定が無く常に0だった)は取り除いた。字間は本家の時点で章の保存の照合項目なので、設定を変えれば章は組み直される -- 実機(テスト17): +2px→-2px で1列目が3字多く入り、章が3ページ→2ページ。-2px でも字は重ならず、ルビも本文の横の正しい位置 - -### 段階7: 挿絵(2026-09-29、`2026092908-diag`、実機確認済み) -- 縦書きの本では画像を列の流れに置く。列の幅と画面の半分の高さに収まる画像は1字として本文の列に入れる(外字)。それ以外は右から左へ列を割り当てて上下中央に置き、入らなければ次のページへ送る。中身が画像1枚だけのページは左右も中央に置く -- CSS の max-width / max-height を画像の大きさに効かせる(電書協テンプレートの `max-width:100%; max-height:100%` や四割指定が効く) -- 章の組み立て中に、画面用の記憶を借りて画像を本から取り出し、PNG は少しずつ読む展開器で画素の保存まで作っておく。ページを描くときは保存を読むだけなので、字形で記憶が埋まったページでも外字が枠だけにならない(修正前は取り出しに要る 32KB の連続領域が 2KB しか残っていなかった) -- 実機(`image-test.epub` 第2〜13章): 外字(1em・em単位の各大きさ・ルビ付き・Kobo形式)、低ビット深度 PNG、svg で包んだ挿絵、横組み指定の挿絵ページ、挿絵12枚の章まですべて表示。挿絵12枚の章を初めて開くのは 8.5 秒(組み立て 4.9 秒、うち挿絵1枚あたり約 0.3 秒の保存作り) -- 残り: 挿絵のあるページは本家の既定で残像消しの書き換えになり 1 回 2.8 秒かかる。高さだけ1字分の横長の外字は独立した列になる(文の途中で列が切れる) - -### 段階8: 表紙(2026-09-29、`2026092910-diag`、実機確認済み) -- 本の情報が表紙として SVG ファイルを指す本(旧ツリーの蔵書調査で 2,256 冊中 56 冊)は、SVG の中の JPEG/PNG をたどって表紙に使う。1.6.5 のままでは本棚にも眠り画面にも表紙が出なかった -- 表紙の取り出しに失敗したときは空のファイルを画像として扱わずに止め、本棚は一時的な失敗を「表紙なし」と記録しない(再起動しても二度と試さなくなっていた) -- 旧ツリーで入れた「本棚の縮小表紙を画面用の記憶を借りて作る」等のメモリ対策は入れていない。1.6.5 の上では読書後の本棚でも最大連続が 61〜73KB 残り、縮小表紙がそのまま作れている -- 実機(`cover-svg-test.epub`): 本棚に表紙が出る。記録で `opf cover=item/image/cover.jpg` → `thumb jpg decode ok` を確認 - -### 段階9: 実測②と不足分の補い(2026-09-29〜、実施中) -- 字形の置き場を 4KB の塊に分けて確保するようにした(旧ツリーの 4KB 分割を移植)。章を移った直後の 1 ページが 16.5 秒かかっていた件(1 字ずつの読み直し 1,175 字)が 11 字に減った -- 塊が足りないときは置き場をまるごと諦めず、置けた字数に縮めて作り直す(本家 1.6.5 #3126 と同じ考え方)。のんびり農家のページ送りが 1.0〜7.9 秒 → 0.84〜1.31 秒 -- 本からの取り出しの塊を空きに合わせて 512B まで半分ずつ縮める(旧ツリー c042f63c)。組み立て中の外字の取り出し失敗が解消 -- JPEG の挿絵も、PNG と同じく章の組み立て中に表示用の形(.pxc)まで展開しておく。本文ページ内の細長い挿絵が描画時の空き不足で出なかった件を解消(11 枚すべて展開成功を確認) -- 実測: リアデイル 1 巻 17 章の組み立て 11.6 秒(旧ツリー 21.1 秒)、vertical-test-suite テスト14本文(異なる漢字 1,336 字)のページ送り 1.1〜1.9 秒(段階5 では 4〜6 秒)、Font Copy in Flash は On の方が速く、ヒープの差はほぼ無い -- 組み立て中にメニューを開くと落ちる件を修正。組み立てが空き不足で止まったまま XML 読み取りと CSS の表を持ち続け、メニューの確保に失敗していた。メニューを開く前に組み立てを一時停止(組み立て済みのページは保存し、本文に戻ると続きから再開) -- 章の組み立てでは、その章で当たりうる CSS の規則だけを読み込む(旧ツリーの CssSelectorUsage、元は JP版 #106)。出版社のひな形 CSS の全規則を読むと書式の表が 32KB の 1 塊になっていた。書式の表 32KB→2KB -- 設定項目の一覧を常駐させず、設定の読み書き・設定画面を開くときだけ作る(旧ツリー 8cc5f333)。約 11KB が空きに戻る -- 実測(のんびり農家、Delete Book Cache 後に挿絵の多い章を組み立て): 組み立て中の空きの底 2.0KB→17KB、空き全体の底 2.0KB→13.4KB、読書中の空き 47KB→54〜63KB、起動後の本棚 97KB→108KB -- 残り: 挿絵ページの残像消し 2.8 秒、漢字の多いページで字形の置き場の作り直しが 1 ページ 5〜10 回 - -### 段階8b: Library の読み順(2026-09-29、`2026092914-diag`、実機確認済み) -- 本家に出している PR #3651(未マージ)の 4 コミットを取り込んだ。Library の並び・見出し・検索の元に、EPUB の本の情報にある読み(file-as)を使う。表示する題名・著者名は変えない -- 読みのカタカナはひらがなに、全角英数は半角にそろえ、見出しは五十音の行(が→か、ぁ→あ)でまとめる。読みの無い本は題名そのものから同じ規則で並べる -- 本の情報の保存(BOOK_CACHE_VERSION)を 13 に上げた(本家 PR 側の番号 11 は当版の縦書き・SVG 表紙で使用済みのため) -- 実機: 「異世界のんびり農家」01〜05 が「あ」に巻順、「リアデイルの大地にて」1〜8 が「ら」に巻順 -- 既知: 著者が 2 人の本で名前の並びが入れ替わって見えるのは本家の名前整形の元からの不具合 - -### 段階8a: flash から書体を読む、16pt を 9/8 倍して 18pt に(2026-09-29、`2026092913-diag`、実機確認済み) -- Text Settings → Style「Font Copy in Flash」を On にすると、選んでいる書体を内蔵 flash の使っていない側(約 6.4MB)に複製し、字形を SD カードではなく flash から読む。firmware を書き換えると複製は消えるので、次の起動で自動で作り直してから本棚に入る(電池 20% 未満で USB 未接続なら Off に戻す) -- NotoSansJP の 18pt は大きすぎて入らないので、16pt を複製して字形の箱と画素を正確に 9/8 倍し、18pt として使う -- 旧ツリーの最終形を 1.6.5 に合わせた。1.6.5 は字形の画素を一塊の領域に置くので、拡大後の大きさで確保する -- 実機: 複製 6,549,504 バイトが約 2 分、`src=flash scale=18/16`。ページ送りの体感は問題なし -- 併せて直した不具合: 商業書籍で表紙・扉・挿絵がすべて白いページになっていた。章の組み立て中は最大連続が 19KB まで下がり、画像の大きさを読むための展開(32KB の窓が要る)が失敗して、画像がページから外れていた。大きさを読む展開にも画面用の記憶を貸すようにして、9 枚すべて表示を確認 -- 残り(段階9): JPEG の挿絵は初めて開くページで展開するため 1 ページ 8〜10 秒かかる。書き出しの瞬間に空きが 2KB まで下がることがある - -## 1.6.0ベースへの作り直し(2026/09/06〜) by claude code - -本家1.6.0が2026/09/05に正式リリースされたため、方針どおり**1.6.0(`54337e6d`)から新ブランチ -`feat/vertical-1.6.0based` を切り、旧ツリー `feat/vertical-1.6` の成果を段階ごとに移し直している**。 -移す元は旧ツリーの完成形(`68a4b4ca`、1.6.0rcから124コミット)で、コミット単位の機械的な移し替えではない。 -6段階の移植と実機確認を終え、**新ツリー初の配布版を pre-release 20260906(`2026090611`、非DIAG)として公開**した -(2026-09-06)。旧ツリーの配布版(pre-release 20260905=`2026090504`)はそのまま残す。同日、GitHubのデフォルトブランチを -`feat/vertical-1.6` から `feat/vertical-1.6.0based` に切り替えた。 - -### 本家 1.6.0 との差分一覧(2026-09-08時点、`c28f1cb5`) - -本家 v1.6.0(`54337e6d`)に対して、コミット21件、73ファイル、+9,601/−567行。領域ごとの内訳は次のとおり -(行数は追加/削除。本家側は 1.6.0 以降 #3397 のビルド環境更新1件だけで、当版と重なるのは体裁変更の3ファイル)。 - -**1. 縦書き組版(本体の中心)** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `lib/GfxRenderer/VerticalTextUtils.h` | +371/0 | 新規。UAX#50準拠の文字の向き分類、縦書き約物の位置表、小書き仮名の寄せ、禁則表(行頭・行末、〝〟や中点まで拡充済み) | -| `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp/.h` | +1,043/−43 | 縦書きの字ごとの分解、縦中横の自動判定、ルビ・圏点の付け方、外字画像、変異選択子の読み飛ばし、文字の向き指定(`VERTICAL_FLIP`)、子孫指定子用の先祖要素の記録、列のページ配置 | -| `lib/Epub/Epub/ParsedText.cpp/.h` | +293/−24 | 右から左への列組み、列境界の禁則押し戻し、縦書きの字下げ(正負)、横書きの圏点 | -| `lib/Epub/Epub/blocks/TextBlock.cpp/.h` | +603/−5 | 縦書き列の描画(正立・横倒し・縦中横、ルビ、傍線・打ち消し線)、保存形式の縦書き拡張 | -| `lib/GfxRenderer/GfxRenderer.cpp/.h` | +206/−7 | 横倒し描画 `drawTextSideways`、縦書き字間設定、縦書き用の計測 | -| `lib/EpdFont/EpdFontFamily.h` | +5/0 | 書式ビット `VERTICAL_FLIP` | -| `src/activities/reader/EpubReaderActivity.cpp/.h`、`ReaderUtils.h` | +325/−40 | 縦書き本の自動判別、右開きのページ送り(左が進む)、縦書き時の余白と状態表示 | -| `lib/Epub/Epub/ReaderRenderSpec.h`、`Section.cpp` の一部 | — | 縦書きフラグと字間を配置の仕様に持たせる | - -**2. 書式(CSS)解析の拡張** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `lib/Epub/Epub/css/CssParser.cpp/.h`、`CssStyle.h` | +331/−46 | text-emphasis(圏点)、max-width/max-height、text-orientation/text-combine-upright(接頭辞付き含む)、二段の子孫指定子(`.vrtl .x`)、保存形式 v13 | -| `lib/Epub/Epub/css/CssSelectorUsage.cpp/.h` | +288/0 | 新規。章が実際に使う要素名・クラス名を集めて、読み込む規則を絞る | -| `lib/Epub/Epub.cpp/.h`、`Section.cpp` | +161/−9 | 章ごとの絞り込み解析、保存が打ち切られた場合の読み直し、空きメモリ24KBでの再解析 | - -**3. 挿絵** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `lib/Epub/Epub/converters/PngStreamDecoder.cpp/.h` | +382/0 | 新規。逐次読みのPNG展開 | -| `converters/ImageToFramebufferDecoder`、`Jpeg…`、`PngToFramebufferConverter` | +39/−6 | 寸法指定(幅・高さ・上限)と構築時の画像キャッシュ | -| `lib/Epub/Epub/blocks/ImageBlock.cpp/.h` | +107/−1 | 縦書きでの挿絵の置き方(列の流れに入れる、幅広は列を割り当てて上下中央) | -| `lib/Epub/Epub/parsers/ContentOpfParser.cpp/.h` | +8/0 | 画像の探索用 | - -**4. SDフォントのメモリ管理** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `lib/EpdFont/SdCardFont.cpp/.h` | +196/−65 | 字形領域を4KB刻みで確保(連続領域が取れない状況の回避)、縦書き字形の存在確認 | -| `lib/GfxRenderer/FontCacheManager.cpp/.h` | +21/0 | 一覧画面での字形キャッシュ解放 | -| `src/activities/UiListActivity.cpp` | +16/−1 | 同上の呼び出し | - -**5. 時計モードと固まり検知** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `src/activities/util/ClockActivity.cpp/.h`、`src/util/ClockFace.cpp/.h` | +484/0 | 新規。時計画面 | -| `src/images/ClockDigits.h`、`scripts/build_clock_digits.py` | +1,522/0 | 新規。時計の数字画像とその生成台本 | -| `lib/hal/HalClock.cpp/.h`、`HalPowerManager.cpp/.h`、`HalSystem.cpp`、`HalGPIO.cpp/.h` | +151/−12 | UTC補正、時計中の省電力、30秒の監視タイマーと再起動理由の記録 | -| `src/activities/ActivityManager.cpp/.h`、`HomeActivity.cpp/.h`、`Activity.h`、`main.cpp` | +140/−12 | Homeメニューの「Start clock mode」、監視の掛け外し、クラッシュ報告へのビルド番号 | -| `lib/I18n/translations/english.yaml` | +1/0 | メニュー文言 | - -**6. 診断基盤** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `src/util/InputDiag.cpp/.h` | +741/0 | 新規。ボタン応答・画像処理・空きメモリをSDのファイルに書き出す(`-DINPUT_DIAG=1` のときだけ組み込む) | - -**7. ビルド・配布・資料** - -| ファイル | 追加/削除 | 内容 | -|---|---|---| -| `scripts/ost_version.py`、`platformio.ini` | +171/0 | `crosspoint-OST-YYYYMMDDNN[-diag].bin` の命名とビルド番号 | -| `README.md` | — | 当版の記録 | -| `test/epubs-ja/`(EPUB 7冊+README) | +549/0 と 858KB | 縦書きテスト書、挿絵テスト書、寸法テスト書、横書き・縦書きの基本テスト | -| `src/util/DictHtmlPages.cpp` | +1/−1 | 配置仕様の引数追加に伴う1行 | - -**2026-09-09 の追加分**(上の表に未反映): `EpubReaderActivity.cpp/.h`(次の章の先組み +170)、`Section.cpp/.h`(組み立て1回の時間上限 +10)、 -`SdCardFont.cpp/.h`(寸法だけの字形集合への絵付き合成の抑止、字形集合を捨てた記録 +40)、`HalGPIO`・`MappedInputManager`(押下中の判定 +20)、 -`InputDiag.cpp/.h`(先組みと字形集合の診断行 +60)、`test/epubs-ja/vertical-test-suite.epub` にテスト22(42→46章)。 - -**本家と意図的に違えている点**(機能ではなく判断): UI文字の太さは本家どおり Regular(#3096 は採用しない)、 -「Extra Paragraph Spacing」ONでも縦書きの明示の字下げは効かせる(横書きの本家挙動とは異なる)、表は縦書きでは -格子ではなく積み上げ、列より幅の広い外字画像は独立した列(1文字大のものは 2026-09-10 から字として列に流す)。 - ----- - -### 配布フォントの出典と同梱文書(2026-09-08) - -SDカード用フォント `fonts-YYYYMMDD.zip` の3書体は、`feat/japanese-sd-fonts` ブランチの `lib/EpdFont/scripts/sd-fonts.yaml` -に書いた取得元から元フォントを取り、JIS X 0213 などの符号位置リストで収録範囲を絞って点画像形式(.cpfont)に変換したもの。 -太字は元フォントの太字から作り、字形は変えていない。元フォントはすべて SIL Open Font License 1.1。 - -| zip内の書体 | 元フォント(取得元) | 2026-08-12 取得時の版 | 著作権表示 | -|---|---|---|---| -| BIZUDGothic | BIZ UDGothic Regular/Bold — github.com/googlefonts/morisawa-biz-ud-gothic(main) | 1.051 | 2022 The BIZ UDGothic Project Authors(モリサワ) | -| BIZUDMincho | BIZ UDMincho Regular/Bold — github.com/googlefonts/morisawa-biz-ud-mincho(main) | 1.06 | 2022 The BIZ UDMincho Project Authors | -| NotoSansJP | Noto Sans CJK JP Regular/Bold(OTF)— github.com/notofonts/noto-cjk(main) | 2.004 | 2014–2021 Adobe | -| 後詰め(共通) | Noto Sans Math — github.com/notofonts/notofonts.github.io(main)、Noto Sans — 本家同梱 `builtinFonts/source/NotoSans` | 3.000/— | Google LLC/The Noto Project Authors | - -後詰めは元フォントに無い字(∼ ≈ などの記号)だけを補う。取得元は版を固定していないので、作り直すと元フォントの版が -上がっている可能性がある(NOTICE.txt に取得時の版を記録する)。 - -**2026-09-08 から、配布 zip に `fonts/NOTICE.txt`(上の表に当たる出典・版・著作権表示・後詰め・変換内容)と -`fonts/OFL-1.1.txt`(ライセンス本文)を同梱する**(ユーザー指示)。OFL は変換物を配る際もライセンス本文と著作権表示を -添えることを求めているため。生成は同ブランチの `lib/EpdFont/scripts/make-fonts-zip.py` で、元フォントの名前表から -版・著作権・Reserved Font Name の有無を読んで書き出す(4つの元フォントのいずれも Reserved Font Name は宣言していない)。 -最初の同梱版は `fonts-202609080.zip`(フォント本体は `fonts-202608240.zip` と1バイトも変わらない)。**pre-release 20260909 に添付済み**(2026-09-09。フォント本体は同一なので、`fonts-202608240.zip` を入れた microSD はそのままで足りる)。 - -### 本家 #3412 から挿絵の失敗記録の扱いを取り込み(2026-09-08、`2026090801-diag`、実機確認済み) - -本家 develop の `b7bceb56` #3412(KOSync のメモリ検査の修正)のうち、当版に効く部分だけを手で移した。展開に失敗した挿絵の記録を -「本を閉じるまで」から「そのページの描画の間だけ」に縮め、次にそのページを開いたときに読み解きをやり直す(`ImageBlock` の -改名と、`renderContents` の先頭で記録を消す1行)。X3 では一時的なメモリ不足で挿絵1枚が白い枠になることがあり、従来はその本を -閉じるまで戻らなかった。KOSync・PSRAM・表示用領域の貸し出しに関わる残りの部分は当版に無縁なので取り込まない。 - -`vertical-image-test.epub` は v12 として第13章「挿絵が多い章(展開の失敗と再挑戦)」を追加。480×360 の番号付き挿絵12枚を続けて置き、 -白い枠が出たら1ページ戻って再度進めば絵が戻る、という見かたを解説に書いた。実機(2026-09-08): 12枚すべてが番号順に出て、 -間の文も欠けなし。白い枠は一度も出なかったため再挑戦の経路そのものは未通過だが、退行なし。 - -### 次の章の先組みと、章の境目の描画の遅さの修正(2026-09-09、`2026090908-diag`、実機確認済み) - -**配布**: 本節までの内容を **pre-release 20260909(`2026090909`、非DIAG、`e83d2122`)** として公開した(2026-09-09)。 -添付は `crosspoint-OST-2026090909.bin` と `fonts-202609080.zip`(NOTICE.txt/OFL-1.1.txt 同梱、フォント本体は 202608240 と同一)。 -非DIAG版は `strings` で `input-diag` が 0 件、時計の監視が入っていることを確認してから添付した。 - -参考3ツリー(Papyrix版・Inx版・witchhunt版)の表示高速化を見比べた結果、当版の実測(`2026090609-diag`)では通常のページ送り -約460msのうち描画は約30msで残りは電子ペーパーの書き換えそのものであり、witchhunt版の「次ページの先描き」を移しても -40ms程度しか縮まない。Papyrix版の全体 `-O2` はフラッシュが 84.4→96.2% になるため不採用。本当に長いのは章の境目 -(章の組み立て 4.6〜8.8秒を含めて 7〜17秒)、挿絵ページ(3.2秒)、章の最初のページの淡い階調(2.2秒)で、まず章の境目を -「次の章の先組み」で潰すことにした(ユーザー承認 2026-09-09)。 - -**先組みの仕組み**(`EpubReaderActivity::tickLookaheadBuild`): いま読んでいる章の組み立てが終わっていて、ページ表示から -1.5秒以上ボタン操作が無いとき、次の章の配置を少しずつ組み立ててSDの保存(`sections/N.bin`)に書く。章を進めると保存を -読むだけになる。空きメモリ 40KB 未満か最大の連続領域 20KB 未満なら手を付けず、途中で別の章へ跳んだら部分保存として残す。 -章の元データの展開が要るときは章をまたぐときと同じ方法で表示用領域を一時的に借り、終わったら今のページを描き戻す -(画面は変わらない)。診断ファイルに `lookahead=starts N done N ticks N pages N total_ms N chunk_max_ms N (spine N at N MHz) -font_releases N` の行を追加。 - -**実機で直した3件**(すべて診断ファイルの数字で発見): - -1. `2026090902-diag`: 先組みの1ページ分が 17.6 秒。本体は操作が3秒途切れると CPU を 160MHz→10MHz に落とす(X3 は外部 - メモリ無しの設定)ため、その後の先組みが16分の1の速さで動いていた。0903 で、先組みの1回分に描画と同じ全速の保持を掛け、 - 進行中は主ループの待ちも省くようにした(終われば元どおり3秒で省電力へ)。 -2. `2026090903-diag`: 11秒待ってからのページ送りが無視された。X3 のボタンは抵抗の分圧を主ループが読み、5ms以上離れた2回の - 読み取りで同じ状態が続いて初めて確定する。先組みの1回分(1ページ=最長0.5秒)の間は読み取りが止まるので、その間に - 押して離した操作は消える。0906 で、1回分を「元データ1KBぶんの処理」単位で 25ms 上限に区切り(`Section::buildSomeMore` - の時間上限)、ボタンが押されている・確定待ち・押した直後・離した直後のいずれかなら1回休むようにした。実測の最長は 190ms - (1単位が重いページ)。待機中の次ページの字形先読み(既存、最長0.7秒)にも同じ条件を付けた。 -3. `2026090906-diag`/`2026090907-diag`: 目次から章を開いたときや、キャッシュ削除後の最初の開きで、1ページ目が出たあと - 19〜21秒ボタンが効かない(描画 23〜25秒)。白黒の描画は 47ms で正常なのに、淡い階調の描き分け2回が字形を 812〜945 個 - SD から1個ずつ読んでいた(8個しか入らない予備の置き場の使い回し)。原因は字形の一時記憶(ページ分の部分集合)の合成規則: - 章の組み立て(配置計算)は字形の**寸法だけ**を集めるが、その直後のページ描画はその集合に**絵付き**でページの字形を合成する - ため、章ぶん(最大512字)の絵を読み込む大きな塊になり、直後の空き不足で塊ごと捨てられて階調の描き分けが裸で走っていた。 - 先組みでも同じ膨張が起き(本を閉じたあとの空きが 54→34KB)、後のページの字形予算が削られていた。0907 で先組みの配置計算の - 前後に一時記憶を空にし、0908 で寸法だけの集合には絵付きの合成をしない(ページ分だけ作り直す)ようにした。あわせて - 一時記憶を捨てた時刻・呼び出し元・空き・字数を `mini_free=` 行に最新4件残す(番地は `dist/*.elf` で `addr2line`)。 - キャッシュ削除後の最初の開きは 5.9 秒(組み立て 1.2 秒+描画 4.1 秒。階調の1回目 2.2 秒は全面書き換えの完了待ち)で、 - 字形の個別読み込みは 0。 - -**残る章の境目のコスト**: 全面書き換え 1.05 秒+その完了待ち 2.2 秒+字形の先読み 0.4 秒。組み立ては先組みで隠れる。 -次はこの完了待ち(`gray_lsb` に含まれる `waitRefreshComplete`)を見る。 - -**テストEPUB**: `vertical-test-suite.epub` にテスト22「章の切り替えと次の章の先組み」を追加(第43〜46章、42→46章)。 -本文A(待つ場所、約950字)・本文B(先組みの対象、番号付き60段落・約13,000字)・本文C(Bと同じ長さの比較用、目次から -直接開く)。解説に見かた(1)効果(2)比較(3)取りこぼし(4)表示の正しさ(5)待機中の画面と、再試験時のキャッシュ削除を記載。 -実機(2026-09-09、`0906`〜`0908`): 先組み 40〜48 ページを約1秒で完了、1回押しで確実に切り替わり、体感の違和感なし。 - -**共有時の記録**: `2026090902`→`0903`→`0906`→`0907`→`0908` の各 diag を claudeworks で入れ替えながら確認。診断ファイルは -`/input-diag.txt`・`/input-diag-log.txt`・`/open-heap.txt`。 - -### 縦書きの外字画像を字として列に流す(2026-09-10、`2026091002-diag`、商業書籍で実機確認済み) - -前節の「№2」の続き。1文字大に直っても、当版は縦書きの本文中の画像を独立した列の上下中央に置いていたため、文の途中の -「№2」が別の列の真ん中に浮いていた(既知の制限「外字画像は独立した列」)。JP版 #129 と同じ考え方で、**幅が列の間隔 -(`getLineHeight`)以内で高さが列の半分以内の画像は、文字と同じ扱いの1語として列に流す**ようにした。 - -- 語の文字列に画像の寸法と保存先を埋め込む(先頭に私用領域の U+F8F0、続けて `幅,高さ,展開先元の場所`。 - `lib/Epub/Epub/InlineImageToken.h`)。章の保存形式は変えず、描画時に語の文字列から読み解く(縦中横・横倒しの判定と同じ方式)。 - `VerticalBehavior::InlineImage` を追加し、配置では高さの分だけ進む(字間の設定も同じく加える) -- 描画は `TextBlock::renderVertical` で、列の幅に対して中央に寄せ、`ImageBlock::render` で挿絵と同じ経路(組み立て時に作る - 縮小済みの保存 `.pxc`、無ければその場で展開)を使う。字形の一時記憶の走査中は描かない -- ルビの親文字の範囲は語の数で数えているので、`` の形はそのまま画像の横に読みが出る。ルビの範囲の長さと - 列の末端の計算は画像の高さを使う -- 解析器は画像の縮小済み保存を作ったあと、条件を満たせば段落を分けずに語として追加する(`IMG_DIAG("inline WxH pitch=N")`)。 - 幅が列より広い画像(幅1.5em・2em など)と高さが列の半分を超えるものは従来どおり独立した列。横書きは変えていない - -実機(2026-09-10、`2026091002-diag`): 『リアデイルの大地にて5』の「スキルマスター№2! 九条様管理下!」が同じ列に -1文字大で並び、直後のルビも崩れない。`vertical-image-test.epub` の第5・8・10・12章の合格条件(「前後の文字と同じ列に並ぶ」)は -元からこの動きを求める書き方なので変更なし。**第5章は5ページ全部合格**(同日、写真で照合): 【外字1em】と【連続外字】が -前後の字と同じ列に同じ大きさで入り、【大画像を縮小】は枠・左上の丸・右下の三角がすべて見える1文字大、【文の連続】は画像の前後で -文が切れず、**【ルビ付き外字】に読み「るび」が画像の横に出る**(これまで「未対応として記録」だった項目。ルビの範囲を語の数で -数える仕組みがそのまま効いた)。**第8章も合格**(同日): 【外字・正方】と【外字・縦長】(幅1em・高さ自動)が前後の字と -同じ列に入り、【外字・横長】(高さ1em・幅自動=列より広い)は設計どおり独立した列で本文と重ならない。挿絵の【前】【後】・全面・ -横長・【指定なし】(原寸)は従来どおり。**第10章も合格**(同日): 【基準】の1em角だけが字として流れ、【幅1.5em】【幅2em】 -【幅2em・横長】【高さ3em】(元が縦長で幅1.5em)【高さ4em】(正方形で幅4em)【幅6em】は幅が列の間隔(54px)を超えるので -設計どおり独立した列の上下中央。解説は「列を一本割り当てて置く実装は合格」としており本文とも重ならない。列の間隔+両側の -空き(38px の字幅に対して片側 8px)まで許せば幅1.5em(66px)も流せるが、ルビの置き場と当たるので今は間隔以内に留める。 -**第12章も合格**(同日): Kobo形式の区切り要素に包まれた【文中外字】が同じ列に1文字大、**【ルビ付き外字】に読み「るび」が出る** -(市販の本の912箇所の形)、【一字ずつの読み】と【区切りの境目】は従来どおり。これで第5・8・10・12章の外字に関わる項目は全部合格。 -テスト書の解説にある「読みが出ていなければ未対応として記録」の文言は次にテスト書を触るときに改める。 - -### 描画中のボタンを別の系で読み取る/階調の描き分けの打ち切り/Indexing を早く出す(2026-09-10、`2026091005-diag`、実機確認済み) - -「ボタンが効かない瞬間に待ち表示を出せないか」という問いへの答え。待ち表示は画面の書き換え(最短 0.3 秒)を処理の前に -先回りして出すしかなく、最も頻度の高い通常のページ送り(1.2〜4.5 秒)に付けると毎ページ遅くなってちらつく。そこで -表示ではなく、**押されたことを取りこぼさない**方向で実装した(ユーザー承認 2026-09-10)。 - -1. **描画中のボタン読み取り**(`HalGPIO::startBackgroundSampling`): 描画は専用の系(`ActivityManagerRender`、優先度1)で - 走り、主ループはその間 `RenderLock` で止まるので分圧の読み取りも止まっていた。描画の間だけ優先度2の小さな系 - (`btnsample`、5ms 周期、2回の ADC 読み)が `InputManager::update()` を代わりに呼び、押した・離したの立ち上がりを - 保持する。主ループの次の `HalGPIO::update()` が保持分を「いま起きた」として渡す(`wasPressed`/`wasReleased` に OR)。 - `update()` と読み取り系の排他は FreeRTOS の相互排他(ADC の読み取りは割り込み禁止の区間に入れない)。描画が終わると - 読み取り系は通知待ちで眠り、待機中は従来どおり主ループが読むので省電力の動きは変わらない -2. **階調の描き分けの打ち切り**: 短冊ごと(50〜100ms)に保持分を見て、押されていれば残りの描き分けと階調の書き換えを - 省き、白黒のページのまま `cleanupGrayscaleWithFrameBuffer()` で制御器の基準を戻して次へ進む。診断の `aa_aborts=` -3. **Indexing の条件緩和**: 目標 20→10 ページ、章 96KB かつ展開あり→32KB(展開の有無を問わず)、途中で出す待ち時間 - 1→0.5 秒、組み立ての単位 8→4 ページ(判定を細かくするため) -4. 章の組み立て中(Indexing)の押下も保持されるので組み立て後に効く。組み立て自体の打ち切りは未実装 - -実機(`2026091005-diag`、2分15秒): `aa_aborts=4`(ページを出した直後の押下で描き分けを打ち切って進んだ回数)、 -押した回数と確定した数は読み取り系の分が確定側に加わる形(84 episodes/130 edges)で、取りこぼしなし。 -主ループの読み取りの最長の空きは 20 秒→2 秒(描画中は読み取り系が受け持つので、この空きは取りこぼしにならない)。 -誤動作(押していないのに進む、二重に進む)の有無はユーザーの体感で確認。 - -同じ診断から: 挿絵ページ(512×694)の階調の描き分けは短冊ごとに縮小済み保存を SD から読み直しており(1回の描き分けで -7回・1.7 秒、2回で 3.5 秒)、ページ全体で 5.0 秒。RAM の置き場(`img_slot`)はこの大きさでは使われない。次の高速化候補。 - -### 本家の更新確認と #3463 の取り込み(2026-09-10、`2026091006-diag`) - -本家 develop は 1.6.0 に 09-09 の2件が加わった状態(リリースは 1.6.0 のまま)。 - -- **#3463**(`9ba16086`、`cherry-pick -x` で取り込み → `5a3d3bfe`): 操作が3秒途切れたあと主ループは 50ms 眠って読むため、 - 65ms 未満の押下が1回しか読まれず消えていた。眠りを 10ms 刻みにし、分圧が待機の電位(約4095)から離れた瞬間に起こす - (`HalGPIO::rawInputActive()`、`main.cpp` の待機の眠り)。当版の「描画中は別の系で読む」(同日)は描画中、こちらは待機中を - 受け持つ補完関係。本家の実測では押下の中央値 145ms・最短 31ms で、65ms 以下が 100% 消えていた -- **#3439**(`1f3d7458`、X3 の文字の階調がかすれる・斑点が出る #3400 の修正): **見送り**。新しいパネル(UC8279)の X3 での - 症状で、手元の X3(UC8253)ではテスト14 本文を 8 回送っても黒が保たれ斑点も出ない(写真で確認)。SDK の更新 - (cb9167d→7f6bd0f)を伴い、当版の階調の打ち切りと書き換えの順序が絡むため、次の本家のタグで fork し直す時点で一緒に入れる - -### 他フォークの確認と、抹茶版から2件の取り込み(2026-09-10、`2026091007-diag`、実機確認済み) - -9つのフォーク(本家・JP版・CJK版・Yomuka版・抹茶版・freeink-sdk・Papyrix版・Inx版・witchhunt版)の先端を取り直し、 -当版に無い修正を洗った。当版のコードで該当を確認し、効く条件は商業EPUB 955冊+Kobo形式 2,256冊で数えてから選んだ。 - -**取り込んだ2件**(どちらも抹茶版。配置の結果は変わらないので章の保存の版は据え置き): - -- **内蔵字形のページ枠を同じ書体で二重に取らない**(抹茶版 #218 相当、`FontDecompressor::prewarmCache`)。 - `getBitmap()` は `fontData` が一致した最初の枠で探索を打ち切るため、同じ書体の2枚目の枠は**永久に読まれない**まま - 4枠のうち1つを占め、別の書体が「全部埋まっている」で温められなくなる。1つの書体が見出し・本文・代替として - 複数の font id から届くので実際に起きる。既に枠がある書体は温めずに戻す(8行)。当版は本文がSDフォントなので主にUI側に効く -- **挿絵の保存が無いページで四角の下書きを描かない**(抹茶版 #220 相当、`EpubReaderActivity::renderContents`)。 - 四角を描いて1回書き換え、すぐ本番の描画で上書きしていた。電子ペーパーは前のページを保持するので、その1回 - (約0.5秒)は丸ごと省ける。**当版は章の組み立て中に `.pxc` を先に作るので、この経路は先作りが失敗したページしか通らない** - (`image-diag.txt` に `pregen ... FAIL` が出るページ)。本家の API である `renderWithImagePlaceholders()` と - `hasImagesNeedingDecode()` は定義を残してある - -**実機確認**(`2026091007-diag`、挿絵20ページの縦書きテスト書): 退行なし。`ui_prewarm_fail=0`、`prewarm_entry_fails=0`、 -`glyph_ondemand_last=0 max=7`、`page_draw_ms=156`(最大229)。挿絵は8枚とも `pregen stream ok` だったので、 -下書きの経路は今回1度も通っておらず、こちらの効果の実測は取れていない。 - -**挿絵ページが白黒→階調の2段階で出るのは仕組み上の挙動**(今回の変更とは無関係)。同じ診断の -`Page render (tiled): display=1053ms gray_lsb=2158ms gray_msb=35ms gray_display=226ms total=3848ms` がそのままで、 -白黒の土台を出す→2.2秒かけて4階調の面を組む(この間ずっと白黒版が見えている)→階調を重ねる、という順序。 -X3 のドライバは階調を当てる前に較正された白黒の土台を要求する(`Uc8253X3Driver::displayGrayscaleBase` のコメント)。 -**本家 #3439 を入れても変わらない**——あれは本文のアンチエイリアス経路だけで、PR 本文にも -「retain existing image-page handling」とある。**実用上の不都合は無いのでこのままとする**(2026-09-10、ユーザー判断)。 -縮めるなら (1) 土台を `displayBuffer(HALF/FAST)` から差分方式の `displayGrayscaleBase()` に替える -(当版の今のSDKに X3 向けの実装がある)、(2) SDK の `ed39106`(下記)の2案があり、どちらも計測から。 - -**見送り・不要と判断したもの**(調べた根拠つき): - -| 出どころ | 内容 | 判断 | -|---|---|---| -| freeink-sdk `ed39106` | X3(UC8253) の全面同期で電源が入っていても電源投入を送り、BUSY が下がらず約1秒空回りする | **有力候補として保留**。当版の SDK(cb9167d)にも同じコードがある。SDK main は本家の参照先より20件先で階調の大改造を含むため、丸ごと上げずに3行だけ当てるには SDK の fork が要る。診断で全面書き換えの時間を測ってから | -| witchhunt版 `5698985b` | 章内の飛び先が1ページ手前を指す(段落の1行目が次ページに送られた場合) | **該当あり・保留**。当版も `flushPendingAnchor()` で `completedPageCount` をその場で記録している。章内リンクを持つ本は 1,349/3,211(42%)。章の保存の内容が変わるので版上げが要る | -| Inx版 #115 | 長い段落の途中で一字下げが再発する | **該当あり・保留**。語数 320(本の書式使用時)/750 で分割したあと、`isFirstColumn`/`breakIndex==0` が再び真になる。320字超の段落を持つ本は 383/3,211(12%)。同じく版上げが要るので上と同時に | -| witchhunt版 `d4547ae6` | 章の飛び先表をSDへ逃がしてRAMを空ける | **不要**。当版は `span` の id を記録しないので、記録対象は1章あたり最大82個(3,211冊、中央値2、p99 27)。上限1024には遠く2KB程度 | -| Yomuka版 `fddb339` | 縦書きで小書きの仮名を上へ10%寄せる | **不採用**。JLREQ は縦組みで「字面を天地中央で右寄り」。当版は右へ1/8だけ寄せ上下は中央=仕様どおり | -| witchhunt版 `e0c99be6` ほか | 書式の #id 解決を省いて再解決を減らす | **該当なし**。当版の `resolveStyle` は tag/.class/tag.class しか引かない(`CssSelectorUsage`) | -| JP版 #123 | ルビが段落の最終行(縦書きは最終列)で消える | **該当なし**。当版は横書き側が存在する分だけ複写、縦書き側は `addVerticalToken` が常に長さを揃える | -| JP版 #129/Yomuka版 `99d0754` | 縦書きの本文中画像を語として流す | **実装済み**(2026-09-10、`2026091002-diag`) | -| Yomuka版 `2138120` | 書式の画像上限(max-width/max-height) | **実装済み**(保存形式 v13) | -| Yomuka版 `1e65fe8` | 圏点のゴマ点 U+FE45/FE46 を日本語フォントに入れる | **実装済み**。`cjk-symbols` の FE30–FE46 に含まれており(08-23 追加)、配布中の `fonts-202609080.zip` の3書体×Regular/Bold 全部に実体を確認 | -| Yomuka版 `dd8b64d` | SVGで包まれた画像の寸法を親の svg から取る | **保留**。当版も `` は読み、電書協型は内在寸法+画面合わせで正しく出る。該当ページを持つ本が多い(通常EPUB 552/955、Kobo形式 1,712/2,256)ので、不具合の報告が出るまで触らない | -| Yomuka版 `f8a9d0f` | PNG展開の作業領域をスタックからヒープへ | **不要**。当版の展開器は本体(約11KB+32KB)がヒープにあり、スタックに残るのは約3KB | -| CJK版 `1d6776b6` | zip の展開緩衝を 8KB→512B と段階的に縮める | **不要**。当版は 1KB で読んでいる | -| CJK版 `e9c66ee6` | 字形の予備リングに参照順の更新を入れる | **条件付き保留**。当版も順送りのみだが、返した `EpdGlyph*` の番地で予備かどうかを判定しているため、入れ替えると描画中の参照が壊れる。添字で持つ作りに直してから | -| JP版 #124 | zip の EOCD 解析の非整列読み | **不要**。X3(C3)で現に動作しており不具合ではない | -| 抹茶版 #214/#216 | 章の組み立て中の周波数の上げ下げ | **ほぼ対策済み**。当版は本組みが `render()` の中=電源保持の内側、先読みも 09-09 に保持を入れた | -| 抹茶版 `7523403a` | フォント配信画面が低メモリで異常終了する | **該当あり・低優先**。当版も `onEnter()` が無条件に `WiFi.mode(WIFI_STA)`(:73)。本を開いたまま入ると落ちうる | -| 本家 #2560 | HTTP配信のキャッシュ制御 | **無縁** | -| UI系全般 | JP版 #134–#138(横向き表示)、抹茶版 #230–#240(タッチ・辞書・図書館)、Papyrix版の時計とX3波形、CJK版のOTA、Inx版 | **非対象**(方針どおり) | - -### 字形の読み直しで遅くなるページの調査と修正(2026-09-10、`2026091021-diag`、実機確認済み) - -診断の `mini_free`(字形の一時記憶を捨てた記録)と `glyph_rebuild … total_ms`(積み直しに使った時間)が -セッション合計で12〜17秒に達しており、ページによっては表示に5〜15秒かかっていた。原因を追って複数箇所を -直したが、**効いたのは最後の1点だけ**だったので、経過も含めて残す。 - -**決め手: その場読みの置き場(overflow ring)が8枠しかなかった** - -一時記憶に載らなかった字は「その場読み」でSDから1字ずつ読み、予備の枠に置く。この枠が8個しかなかった。 -階調の描き分けは**短冊ごとに同じページを10回前後描き直す**ので、載らなかった字が二十数種類あると毎回 -押し出し合い、描き直すたびに全部読み直していた(1字約10ms)。枠を48に広げた(`OVERFLOW_CAPACITY`、 -16pt CJKで約4KB。枠は描画のたびに `clearCache()` で空になるので抱えっぱなしにはならない)。 - -同じ章(テスト24 本文)での実測: - -| 診断 | 前 | 後 | -|---|---|---| -| `aa_worst_lsb_ms … glyphs=` | 8,812ms / 699字 | **2,255ms / 0字** | -| `aa_worst_msb_ms … glyphs=` | 4,432ms / 378字 | **98ms / 0字** | -| `page_draw_ms` の最大 | 4,497ms | **464ms** | -| `render_max_ms` | 15,344ms | **4,917ms** | -| `glyph_ondemand` の最大 | 1,128 | **41** | -| `heap_min_free` | 5,364 | 5,604(悪化なし) | - -CJK版が同じ症状で 80→120 に広げていた(`e9c66ee6`)。当版は8のままだった。 - -**同時に入れた変更(効果は測れていないが筋は通る)** - -- 一時記憶の保持の床を 40KB→24KB(`MINI_RETAIN_MIN_FREE_HEAP`)。読書中の空きは36〜45KBで - この床をまたぐため、ページを描くたびに(`PrewarmScope` の生成→`clearCache()`)捨てていた。 - メモリを本当に要求する経路(章の組み立て・先読み・メニュー・フォント配信)は明示的に解放している -- 絵つきの一時記憶がある間は、metaOnly の要求(代替フォントに振り替わった文字列の測定)で - 作り直さない。作り直すとページの絵が捨てられる -- ページ自身の prewarm にも空きに応じた字数の上限を掛ける。従来は複数文字列の一括要求にしか - 掛かっておらず、積む途中で失敗して**全部捨てて**いた(空き5KBで76字ぶんを破棄した記録がある) -- 余裕の見込み(`PREWARM_HEAP_HEADROOM`)を16KB→8KB。16KBだと空きが少ないとき上限が0になり、 - 一時記憶を一切積まなくなっていた -- 走査の font 枠を 4→6(`MAX_SCAN_FONTS`)。上限を超えた font は黙って走査から落ちるため。 - 実測では `font_slots_lost=0` で該当しなかったが、保険として残す - -**回り道の記録(同日、いずれも撤回・修正済み)** - -- 階調の短冊用領域(7.9KB)を描画の先頭で確保するようにしたら、まさに一時記憶を積む時点で - 競合して**悪化した**。元の位置(階調に入る直前)に戻した -- 配置の門番(メモリ不足なら章の組み立てを失敗させる)が **abort を誘発した**。配置を諦めると - 語が消費されないので解析器が字を足し続け、`addVerticalToken` の push で落ちる。失敗と決まったら - 文字を受け取らないようにした。見積もりも過大で(380語に8.4KB要求)、縦は4B/語・床2KBに直した - -**診断に足した道具** - -- `glyph_miss=` … その場読みした符号位置の直近24件。**どの字が漏れているかで原因が割れる** - (本文の字=ページの積み込み失敗、数字やASCII=UI側、特定の書体だけ=走査の枠不足) -- `font_slots_lost=` … 走査の font 枠が足りずに落ちた回数 -- 遅い描画の記録(`input-diag-log.txt`)の先頭にも `glyph_miss=` を出す。定期報告は採取時 - (たいてい別の画面)の内容になってしまい、遅かったページの中身が分からなかった - -**残っている費用**(今回は手を付けていない) - -- 階調の描き分けそのものが1ページ約2.3秒。字形とは無関係で、書き換えの仕組み側の話 -- UI画面(一覧・メニュー)には一括プリウォームが無く、行ごとに1文字列ずつ積み直している。 - 旧ツリーの `UiGlyphPrewarm` 相当の移植が保留のまま - -### フォントを変えたあとの中断と極端な遅さ(2026-09-10、`2026091023-diag`、実機確認済み) - -前節の変更を入れた `2026091021-diag` で、**フォントを BIZ UDGothic に変えたところ中断(abort)した**。 -番地から引くと縦組みの列を作る `ParsedText.cpp` の `colRuby.assign()`、つまり **ふりがなの配列の確保**だった。 - -**原因1: 確保の失敗が報告にならない経路が残っていた** - -例外を使わない設定なので `std::vector` の確保は失敗すると報告ではなく firmware ごと停止する。前節で -段落規模の配列(字の高さ)と列の入れ物は「失敗しても止まらない」形にしたが、**1列ぶんの配列5本** -(本文・ふりがな・字体・座標2本)は素通しのままだった。1行・1列を作る前に**同じ大きさの領域を試しに -取って返す**関門を入れ、取れなければそのページを諦めて報告する(横組みの1行も同じ。失敗した行の語は -消費せずに残し、呼び出し側も止まるようにした)。 - -**原因2: 先読みの取り分と、保持の床が別々の数字だった** - -前節で `PREWARM_HEAP_HEADROOM` を16KB→8KB、`MINI_RETAIN_MIN_FREE_HEAP` を40KB→24KBにした。この2つが -食い違うと次のことが毎ページ起きる。 - -| 手順 | 結果 | -|---|---| -| 先読みが空き8KBまで使って一時記憶を作る | SDから何百字も読む | -| ページを描き終える | 空き9KB < 保持の床24KB → **作ったばかりの一時記憶を全部捨てる** | -| 次のページ | また最初から読み直す | - -診断の `Low heap opening menu (9184 free, 6388 max block)` が8KBの取り分とほぼ一致し、`glyph_miss=476`、 -1ページ7.8秒。**払った費用が毎ページ捨てられていた**。取り分を保持の床から導くようにして、二度と -ずれないようにした(`PREWARM_HEAP_HEADROOM = MINI_RETAIN_MIN_FREE_HEAP`)。作った一時記憶は必ず保持 -されるか、そもそも作らない。 +# CrossPoint Reader -**実測(BIZ UDGothic 12、同じ書籍・第13章)** +[![Fund contributors](https://img.shields.io/badge/%F0%9F%91%91_Fund_contributors-royalty.dev-BB953A?style=for-the-badge&labelColor=1a1a1a)](https://app.royalty.dev/crosspoint-reader/crosspoint-reader) -| 診断 | `2026091021-diag` | `2026091023-diag` | -|---|---|---| -| 中断 | **abort(`colRuby.assign`)** | **なし**(176秒・挿絵ページと20分割の章組み立てを含む) | -| ページ送り | 4,565ms(打ち切りあり) | **1,704〜2,455ms** | -| `aa_worst_lsb_ms … glyphs=` | 2,144ms / 0字(押下で打ち切り) | 2,259ms / 0字 | -| `glyph_ondemand` の直近 | — | 49(最大513は章の組み立てを含む初回) | -| `heap_min_free` | — | 716(最も細ったところ。関門が受け止めて中断せず) | +CrossPoint is open-source e-reader firmware - community-built, fully hackable, free forever. It's maintained by a growing community of developers and readers who believe your device should do what you want - not what a manufacturer decided for you. -**分かったこと: このフォントは1ページ分の字形が物理的に入らない** +### Now running on: +- **ESP32C3-based** Xteink X4 and X3. +- **ESP32S3-based** Xteink X4Pro and X4Classic, Seeed reTerminal Sticky, M5PaperMono -新しい診断行が出したのはこの2行。 +Check [our Devices page](https://crosspointreader.com/devices) for the full list. -``` -font=BIZUDGothic_12.cpfont styles=2 advY=25 glyphs=24519 resident=6144 -prewarm_budget_min=66 wanted_then=67 free_then=47588 clips=9 -``` +![CrossPoint Reader running on Xteink device](./docs/images/cover.jpg) -空き47,588バイトから保持の床24KBを引いた23KBで**66字**しか置けない。つまり**1字あたり約350バイト** -(advY=25の2階調字形の実測平均)。1ページの異なり字数は約130なので、必要なのは約45KB——**空きとほぼ -同じ**で、描画に使う分を残すと入りきらない。入らなかった字はその場読みに回る(1ページ49字)。 -`clips=9` は先読みの上限に達したページ数。フォントを変える前に速かったのは、字形が小さく1ページ分が -収まっていたからで、**これはフォントの大きさが決める限界**であって直せる不具合ではない。 +> If you're planning to buy an Xteink device, consider purchasing an **X3/X4 Developer Edition** through https://crosspointreader.com. CrossPoint receives a small share of each sale, helping fund development costs. -**診断に足した道具** +## What can CrossPoint do? -- `font=` … 使用中の .cpfont の名前・字体数・字の高さ・収録字数・常駐量。「フォントを変えたら遅く - なった」という報告が、これまで診断だけでは読めなかった -- `prewarm_budget_min=` … 先読みが許された字数、必要だった字数、そのときの空き、上限に達した回数。 - **字形が大きくなったのか、組版が複雑になったのかを分ける**数字 +- **Reader engine**: EPUB 2/3 rendering with embedded-style option, image handling, hyphenation, kerning, adaptive table layouts, native CJK ruby annotations, chapter navigation, footnotes, bookmarks, dictionary lookups ([StarDict](docs/dictionary.md)), go-to-percent, auto page turn, orientation control, focus reading, KOReader progress sync and more. -**残っている費用**(今回は手を付けていない) +- **Various formats**: native handling for `.epub`, `.xtc/.xtch`, `.txt`, and `.bmp`. -- 33×33の外字画像が**1ページの描画で10回以上再描画**されている(階調の短冊ごと)。1回約20msで約200ms -- 大きな章の初回オープンが20.8秒(うち章の組み立て12.5秒/20分割) +- **Touch reading**: follow EPUB links and look up words in the dictionary on touch-enabled devices. -### 書体を変えると1ページの文字数が変わる(2026-09-10、`2026091025-diag`、実機確認済み・章の版51) +- **Screenshots.** -フォント指定以外の設定をすべて同じにしても、1ページに入る文字数が書体で大きく違うという指摘。 -同じ書籍の同じ章で NotoSansJP が32ページ、BIZUDGothic と ExGothic が20ページだった。 +- **Custom fonts**: install your favorite fonts on the SD card. -**原因: 縦書きの列の幅に、フォント内部の行送りをそのまま使っていた** +- **Tilt page turn (X3 and Sticky)**. -配布中の .cpfont を直接読んだ値。 +- **USB Drive mode (X4Pro)**: access the SD card as USB mass storage. -| ファイル | `advY`(焼き込まれた行送り) | 上へ | 下へ | -|---|---|---|---| -| BIZUDGothic_12 | **25** | 22 | −3 | -| BIZUDMincho_12 | **25** | 22 | −3 | -| NotoSansJP_12 | **36** | 29 | −8 | +- **Library workflow**: indexed title/author search, recently-added and alphabetical views, multilingual grouping, folder browser, recent books, and SD-cache management. -同じ「12」でも1.44倍違う。三段階の仕様が重なってこうなる。 - -1. 大きさの設定は `<書体>_.cpfont` を選ぶだけで、実寸は変換時に焼き込み済み。変換は - `face.set_char_size(size, 150dpi)` で **全角25画素**(どの書体も同じ) -2. しかし `advanceY = norm_ceil(face.size.height)` を焼き込む。`face.size.height` は全角ではなく - **その書体自身が指定する推奨行送り**(`hhea` の上端・下端の合計)で、Noto Sans CJK は全角の - 約1.44倍、BIZ UD 系はほぼ全角ちょうど -3. 縦書きでは `columnWidth = getLineHeight()`(=`advanceY`)、列間はその1/4。つまり - **列送りが BIZ で全角の1.25倍、Noto で1.8倍**になっていた +- **Wireless workflows**: + + - File transfer web UI + - EPUB Optimizer + - Web settings UI/API (edit many device settings from browser) + - WebSocket fast uploads + - WebDAV handler + - AP mode (hotspot) and STA mode (join existing Wi-Fi), both with QR helpers + - Calibre wireless connect flow + - OPDS browser with saved servers (up to 8), search, pagination, and direct download + - OTA update checks and installs from GitHub releases -全角幅は同じなので **1列あたりの字数は変わらず(どちらも19字)、列数だけが減る**。写真でもそのとおりだった。 +- **Customization**: night mode, multiple themes (Classic, Lyra, Lyra Extended, RoundedRaff), sleep screen modes including transparent overlays, front/side button remapping, status bar controls, power-button behavior, refresh cadence, and more. -**直した内容: 列送りを全角基準にする** +- **Localization**: 34 UI languages and counting, including CJK font fallback and RTL support. -JLREQ 2.3 は行送りを字の大きさに対する倍率(本文で1.5〜1.75倍)で定める。フォント内部の行送りを -使う仕様ではない。 +### Coming soon: -- `GfxRenderer::getCjkCellWidth()` を新設し、**全角の幅をフォントから実測**する - (U+3000 →「あ」→「ア」→「国」の順。書体ごとに1回だけ測って覚える。字形がまだ読めない状態なら - 覚えずに次回やり直す) -- 列送り=**全角 × 1.5 × 行間設定**(`VERTICAL_COLUMN_PITCH_EM`)。行間設定の四段階(0.95/1.0/1.1/1.2) - と合わせて1.43〜1.8倍となり、JLREQ の範囲を覆う -- 文字の列・挿絵の列(1文字大か独立した列かの判定を含む)・**描画側の升の幅**を、すべて同じ値から求める -- 縦中横の判定にあった `行送り × 2/3` という全角幅の代用も本物に置き換え +- More themes. -**実測(同じ書籍・プロローグ、章の保存を作り直した後)** +- Web plugins. -| 書体 | 前 | 後 | -|---|---|---| -| NotoSansJP | 32ページ(7列) | **28ページ(9列)** | -| BIZUDGothic | 20ページ(11列) | **28ページ(9列)** | -| ExGothic | 20ページ(11列) | **28ページ(9列)** | +- Bluetooth pageturner. -列の切れ目・行頭行末・ふりがなの位置まで3書体で一致。12ptなら列送りは全書体38画素になる。 -BIZ で読んでいた密度からは約19%ゆるくなる(1.25倍→1.5倍)ので、詰めたい場合は行間設定の「狭い」で -1.43倍まで戻せる。 +- Much more! stay tuned. -**横書きは変更していない。** 欧文には全角という単位が無く、行送りをフォントの上下端から取るのは -横書きでは正しいため。縦書きは日本語専用なので全角基準にできる。 +--- -**調べたが直す必要が無かった点**: 場面の区切り(`
`)が足す余白はフォントの行送り基準のままだが、 -縦書きでは `verticalIndent = max(textIndent, -topInset)` と負の値との比較にしか使われないため、 -列の頭下げには影響しない(負の字下げを列の外へはみ出させない歯止めとしてのみ働く)。 +## USB-locked devices (Xteink Unlocker) -### 挿絵のログが診断を潰す/小さい外字がRAMに載らない(2026-09-11、`2026091101-diag`、実機確認済み) +Some Xteink units purchased from third-party stores (e.g. AliExpress) ship with USB flashing locked from the factory. +If your device is locked, you will need to use the **Xteink Unlocker** tool available at +https://crosspointreader.com/#unlock-tool before you can flash CrossPoint. -「挿絵が1ページで10回以上再描画されている」として調べたが、**再描画はしていなかった**。診断が費用を -直接測っていて、`aa_worst_lsb … img_slot=0/0 stream=1 sd=8ms` — 1面1回・8ms。ログの間隔15〜23msは -その短冊全体を描く時間だった。短冊に掛からない挿絵は `glyphIntersectsStrip()` が既に飛ばしている。 -かわりに2点見つかった。 +**You do not need this tool if you bought your device directly from xteink.com.** Those units are not locked. -**① 「Rendering image at …」を短冊の判定より前に出していた** +**Not sure if your device is locked?** Power it on, connect the USB-C cable, and try flashing via the web flasher first (see +[Install firmware](#install-firmware) below). If the browser's serial device picker does not show your device, try a different +USB port or browser before assuming the device is locked. Only reach for the unlocker if the device still doesn't appear. -階調は短冊ごとに全画像を一巡するので、判定より前だと1ページで12行出る。ログ環は16行しかないので、 -**採取の目的だった内容がすべて押し出されていた**(2026-09-10 の遅い描画の記録は16行中12行がこの1行 -だった)。判定の後ろへ移した。 +> ### ⚠️ WARNING: READ THIS BEFORE USING THE UNLOCKER ⚠️ +> +> **The only officially supported firmwares in the unlock tool are CrossPoint and CrossInk.** +> +> Flashing any other firmware on a USB-locked device may **permanently brick the device** or leave it **permanently +> stuck on that firmware with no recovery path**. Once USB flashing is re-locked, your only way back is via OTA, and if +> the firmware you flashed doesn't support OTA, **there is no way out**. -| | 前 | 後 | -|---|---|---| -| 1ページの画像のログ | 12行(描画は1回) | **4行(描画4回)=1行につき必ず描画が伴う** | -| 記録に残った内訳 | なし | `AA split` / `Page render (tiled)` / `Rendered page in` / `Progress saved` | +## Install firmware -**② RAM置き場の門番が、要求量に関係なく空き24KB・最大確保8KBを求めていた** +### Web installer (recommended) -置き場(`pxcSlot`)は画面いっぱいの挿絵(約93KB)を想定した数字で門番を作ってあった。ところが -33×33の外字は2階調で **297バイト**しか要らない。空きの少ないページほど断られる——SDに戻る費用が -一番高い場面で断られていた。4KB以下の要求には4KBの余裕で足りるようにした(大きい画像の条件は不変)。 +1. Connect your device to your computer via USB-C and wake/unlock the device +2. Go to https://crosspointreader.com/#flash-tools, select your device (X3, X4, Xteink X4Pro, Seeed reTerminal Sticky, or M5PaperMono), and choose an official CrossPoint release. -``` -前: img_slot=0/0 stream=1 一度も載らない -後: img_slot=1/0 stream=4 白黒の回で載り、階調の回は当たる -``` +### Web installer (specific version) -**残っている費用**: 置き場は1枚しか持てないので、外字が複数あるページは2枚目以降がSDへ戻る -(実測1面32ms、1ページ65ms=ページ全体4,156msの約1.6%)。数枚持てるようにすれば消せる(外字1枚 -300バイト)。効果が小さいので保留。 +1. Connect your device to your computer via USB-C and wake/unlock the device +2. Download the firmware file for your device from [Releases](https://github.com/crosspoint-reader/crosspoint-reader/releases), or compile yourself. +3. Go to https://crosspointreader.com/#flash-tools, select your device, click "Custom .bin" and upload the firmware file. -**この節の教訓**: ログの間隔を費用と読み違えた。診断に数字がある場合はそちらを先に見る。 +### Revert to Official Firmware -### 章の組み立てとページ送りの費用を測る(2026-09-11、`2026091105-diag`、実機測定のみ・機能変更なし) +To revert to the official firmware, you can also flash the latest official firmware using https://crosspointreader.com/#flash-tools. -「大きな章の初回オープンが20.8秒(章の組み立て12.5秒/20分割)」を追った。**推測で手を付ける前に -内訳を出す**方針で、診断に3行足して測った結果、**組み立てには狙うべき一点が無く、ページ送りのほうの -最大の費用は計測の区切り方の誤りだった**。 +### Command line -**組み立て: 挿絵の展開が全部だった** +1. Install [`esptool`](https://github.com/espressif/esptool): -| 同じ章(20ページ)| 挿絵の画素保存なし | 保存あり | -|---|---|---| -| `build_total_max_ms` | 3,784ms | **1,028ms** | -| `build_page_write` | 100ms | 58ms | -| `build_font`(文字幅表のSD読み) | 203ms | 54ms | -| 残り(構文解析・書式照合・配置) | ~3,480ms | **~916ms** | +```bash +pip install esptool +``` -差の2,756msは 480×360 の挿絵1枚あたり約470ms×8枚。設計どおり(描画時は空きが足りず失敗するので -組み立て時に作る)。本文側は**1ページ約46ms**で、書き出しも文字幅表も誤差。 +2. Download the firmware file for your device from the [releases page](https://github.com/crosspoint-reader/crosspoint-reader/releases). +3. Connect your device via USB-C. +4. Find the device port. On Linux, run `dmesg` after connecting. On macOS: -事前に立てた仮説「文字幅表が768字で打ち止めになり、以後は測るたびに1字ずつ読む」は**外れ**だった。 -実測は `table 13/768 full_skips 0`。打ち止めには全く届いていない。 +```bash +log stream --predicate 'subsystem == "com.apple.iokit"' --info +``` -商業書籍の127ページの章の12.5秒もこの単価の積み上げで、しかも章ごとに1回きり・次の章は待機中に -先組みしている。20.8秒になったのは章の版を50→51に上げて全部作り直させたため。**ここで打ち切る。** +5. Flash an X3 or X4: -**ページ送り: `gray_lsb` の中に書き換え待ちが入っていた** +```bash +esptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 921600 write_flash 0x10000 /path/to/firmware.bin +``` -1回目の階調が2,293ms、2回目が140ms。同じ処理なのに60倍という差が長く残っていて、コード中の注記も -「1回目が何かを暖め、2回目はそれを見つける」と書いていた。繰り返しを「短冊をRAMで組む」と -「パネルへ送る」に分けて測ると—— + Flash an Xteink X4Pro, Seeed reTerminal Sticky, or M5PaperMono: -``` -AA split: lsb=2293ms | msb=140ms -AA phases: lsb draw=97ms push=36ms | msb draw=99ms push=41ms +```bash +esptool.py --chip esp32s3 --port /dev/ttyACM0 --baud 921600 write_flash 0x10000 /path/to/firmware.bin ``` -2回目は 99+41=140 でぴったり。1回目は 97+36=133 しかなく、**2,160msが繰り返しの外**にあった。 -その正体は階調に入る直前の `renderer.waitRefreshComplete()`——**白黒の書き換えの完了待ち**で、 -これが `gray_lsb` の計測区間に含まれていた。1回目と2回目の処理量は同じで、差は最初から無かった。 +### Manual -読み直したページ送りの内訳: +See [Development quick start](#development-quick-start) below. -| 項目 | ms | 種別 | -|---|---|---| -| prewarm | 619 | CPU | -| bw_render | 132 | CPU | -| display | 1,080 | **パネル** | -| 書き換え待ち | 2,160 | **パネル** | -| 階調1回目 | 133 | CPU | -| 階調2回目 | 140 | CPU | -| gray_display | 228 | **パネル** | -| cleanup | 78 | CPU | -| 合計 | 4,570 | パネル 3,468(**76%**) | +--- -**階調の描画そのものは273ms**。以前この節に書いた「階調の描き分けそのものが1ページ約2.3秒」は -誤りで、その2.3秒は書き換え待ちだった。 +## Custom SD-card fonts -計測の区切りを直し、`AA split` と `Page render (tiled)` に `wait=` を分けて出す。診断にも -`aa_refresh_wait= (max )` を追加。 +On devices with external RAM enabled in CrossPoint, copy `.ttf`, `.otf`, or `.ttc` files to the SD card and select them as reader fonts. Put one file in `/fonts/` or `/.fonts/`, or put one family's files in a subfolder. See the [SD card font guide](./docs/sd-card-fonts.md) for the folder layout and styles. -**次の行き先**: CPU側でページ送りから削れるものはもう多くない(prewarm 619ms が最大)。パネル側の -3.5秒が本体で、後回しにしているSDKの `ed39106`(X3 UC8253 の余計な電源投入、全面書き換え1回あたり -約1秒)がそこに直接効く。なお全面書き換えを待たずに階調を組んでおく経路は既にあるが -(`lsbPlaneBuf`)、1面47.5KB+余裕60KBで**空き107KBを要求する**ため、読書中に40〜70KBしかない -X3では一度も走らない。 +On other devices, convert the font to `.cpfont` first. `.cpfont` files also work on devices with external RAM enabled and have better performance. No firmware reflash is needed to add fonts. -**この節の教訓**: 計測の区切りが誤っていると、同じ誤りを何度でも追う。区間の中に待ちが入って -いないかを最初に疑う。 +To make `.cpfont` files: -### 本家 develop の併合と、右端のルビ(2026-09-11、`2026091115-diag`、実機確認済み・章の版53) +1. Go to https://crosspointreader.com/fonts and open the "SD-card font builder" form. +2. Upload up to four styles (regular, bold, italic, bold-italic), set the family name, point sizes, and Unicode range. +3. Download the generated `.cpfont` files. +4. Copy them to your SD card under `/fonts/YourFont/` (or `/.fonts/YourFont/` to hide the folder). +5. Select the font on the device from the font settings. -ページ送りの費用がパネル側に偏っていることが前節で分かり、そこに効く SDK 修正 `ed39106` -(X3 UC8253 の余計な電源投入)を取りに行った。調べると**本家は 2026-09-10 に取り込み済み**で、 -Yomuka版・抹茶版は未取り込みだった(SDKの固定先が全て 08-23 以前)。当版が独自に判断する必要は -なく、本家に追随すればよい話だった。 +Conversion runs the firmware repo's `lib/EpdFont/scripts/fontconvert_sdcard.py` script unmodified, so output matches a local host build. -**再fork は不要だった** +--- -方針は「本家のタグが更新された時点で fork し直す」だが、今回は**素直な併合で足りた**。 +## Documentation -| | ファイル | 行 | -|---|---|---| -| 当版が加えた分(1.6.0 から) | 80 | +10,586/−589 | -| 本家が進めた分 | 106 | +2,236/−585 | -| **両方が触ったファイル** | **15** | — | +- [User Guide](./USER_GUIDE.md) +- [Web server usage](./docs/webserver.md) +- [Web server endpoints](./docs/webserver-endpoints.md) +- [Project scope](./SCOPE.md) +- [Contributing docs](./docs/contributing/README.md) +- [Touch and UI development](./docs/contributing/touch-and-ui.md) - how to build new screens on the FreeInkUI activity bases (UiListActivity and friends), plus build envs for the non-Xteink touch devices -試験併合の結果は **104ファイルが自動併合、衝突は5ファイル8箇所・142行**。**縦書きの中核 -(`VerticalTextUtils` `TextBlock` `ParsedText` `Section` `CssParser` `PngStreamDecoder`)は本家が -一切触っておらず衝突ゼロ**で、当版の1万行の大半は本家の変更と物理的に重ならない。 +--- -衝突の解決: `Epub.h`/`ReaderUtils.h` は当版の縦書き用の宣言と本家の引数変更を両立、 -`ImageBlock.cpp` は当版の `hasValidCache()` 分離とログ位置を維持、`ChapterHtmlSlimParser.cpp` は -当版の診断と本家の `hidden` 属性対応を両方、`EpubReaderActivity.cpp` は本家の -`chapterPosition()` の整理を採って当版のメニューの低メモリ保護と nothrow 生成を載せ直した。 +## Development quick start -**文字として併合できても意味は保証されない**: ビルドが `HalGPIO::rawInputActive()` の二重定義を -検出した。#3463 を当版が先に取り込んでいたため、本家側の同じ実装が別位置に入っていた。 +### Prerequisites -**入ったもの** +- [pioarduino PlatformIO Core](https://github.com/pioarduino/platformio-core) or [VS Code + pioarduino IDE](https://github.com/pioarduino/pioarduino-vscode-ide) +- Python 3.8+ +- `clang-format` 21 +- USB-C cable supporting data transfer -- **SDK `cb9167d` → `fde240fa`(29コミット)**。本命は `ed39106`「電源が入っているときは - POWER_ON を繰り返さない」。余計な PON は BUSY が下がらないため待機が 1000ms の上限まで回る -- **#3439** X3の階調の安定化。X3 は `asyncBase=false` となり、階調の組み立てを白黒の書き換えに - 重ねる経路が無効になる(**X3では安全でない**と本家が判定した。前節で「要求メモリを見直せば - 使える」と書いたのは誤りで、使ってはいけない経路だった)。当版の短冊方式は `stripUploads=true` - でそのまま残る -- **#3478** 階調機能の判定を `GrayscaleCapabilities` に集約 +### Setup -**実測(本文ページ)** +```bash +git clone --recursive https://github.com/crosspoint-reader/crosspoint-reader +cd crosspoint-reader -| 項目 | 併合前 | 併合後 | -|---|---|---| -| 書き換え待ち(`aa_refresh_wait`) | 2,120ms | **1ms** | -| 白黒の表示 | 1,053ms | **579ms** | -| 階調 1回目+2回目 | 2,192ms | **220ms** | -| **ページ全体** | **3,773ms** | **1,601ms** | +# if cloned without --recursive: +git submodule update --init --recursive +``` -**見送った本家の更新**: #3390(`hidden` 属性)は手持ちの商業書籍513冊を走査して**0冊・0箇所**、 -効果がない。#3036(macOS由来のNFDファイル名)は中身がラテン系と結合ハングルのみで、**日本語の -濁点(U+3099/U+309A)は対象外**。同じ問題は日本語にもあるので、ファイル一覧で「か゛」を -見かけたら同じ関数を広げるのが対処になる。#3437 はUI(方針により見送り)。 +### Nix/NixOS -**右端のルビが画面端で切れていた** +Nix/NixOS users can enter the development shell with either `nix develop` (flakes) or `nix-shell`: -併合とは無関係の、縦書き移植(段階5)以来の不具合。ルビは列の右隣に描かれるが -(`TextBlock.cpp` の `rubyX = cellX + cellWidth`)、ページの一番右の列は本文領域の右端に -密着していたため、そのルビが領域外に出ていた。 +```bash +nix develop -f nix +# or +nix-shell nix +``` -最初はルビ幅(升の半分)をそのまま本文領域から引いたが、診断で**1ページから列を1つ丸ごと -奪っている**ことが分かった。 +To flash a connected ESP32-C3 device, enable PlatformIO's udev rules in your NixOS configuration: -``` -vert_layout=cell 38 pitch 57 ruby_reserve 19 viewport 512x756 -> 8 cols - 確保なし (512-38)/57+1 = 9列 - 確保19 (512-19-38)/57+1 = 8列 ← 境目は18。1画素超えて11%の文字数を失っていた +```nix +services.udev.packages = with pkgs; [ platformio-core.udev ]; ``` -ルビは**利用者が設定した画面余白の上に出て構わない**(そこは実際にパネル上にある。枠の下に -隠れる bezel の分は使えない)。確保量を「ルビ幅 − 画面余白」にして、既定なら 19−5=14。 -**9列を保ったままルビが完全に出る**。実機で確認済み(ページ数 206→153)。 +After rebuilding the system configuration, reconnect the device or reload udev rules. -**この節の失敗**: 確保量を直したとき、配置が変わるのに章の保存の版を据え置いた。「まだ配布して -いないから」と判断したが一つ前の版は配布済みで、実機はその配置で保存を作っていた。修正が一度も -実行されず、診断の `vert_layout=cell 0 … -> 0 cols`(組み立てが走っていない)で発覚した。 -**配置に触ったら版を上げる**。 +### Build / flash / monitor -**診断に足した道具** +```bash +pio run --target upload +``` -- `vert_layout=cell <升> pitch <列送り> ruby_reserve <右端の確保> viewport <幅x高さ> -> <列数>` - 縦書きのページがどの寸法で組まれたか。フォントの大きさ・余白・行間の設定と列数を突き合わせられる -- `font=` 行が「最後に読み込んだフォント」を出していたのを本文用に直した。UI用の代替サイズが - 後から読み込まれるため、本文が18ptなのに `font=ExGothic_12` と出ていた -- `layout_giveup=<回数> last=kind …` 配置を諦める6か所のどれが断ったか -- 失敗時の記録が、書き出し待ちの「遅い描画」の記録に塞がれていたのを、追い出せるようにした - (`flushNow()` で即座に書き出す) +### Contributor pre-PR checks -### 挿絵の初回展開が1枚8〜17秒(2026-09-11、`2026091121-diag`、実機測定・上限は保管層と判明) +```bash +./bin/clang-format-fix +pio check -e default +pio run -e default +``` -商業書籍の 1440×2048 の挿絵を初めて開くと1枚8〜17秒かかる。1画素あたり約3,700サイクルに見えたので -JPEGの扱い方を疑ったが、**復号そのものは妥当で、時間はファイルの読み書きに消えていた**。 +### Debugging -**内訳を測る** +After flashing the new features, it’s recommended to capture detailed logs from the serial port. -`pregen` の ms が展開(zipからの取り出しとSDへの書き出し)と復号を1つの数字にしていたので分け、 -復号の中も分けた。 +First, make sure all required Python packages are installed: -``` -pregen extract ok ms=8563 -jpeg split total=8283 io=4270/846 draw=343 flush=901 prog=0 scale=1/2 +```python +python3 -m pip install pyserial colorama matplotlib ``` -| 項目 | ms | 割合 | -|---|---|---| -| 展開(zipから取り出してSDへ) | 8,563 | **50%** | -| JPEGDEC の読み込み(846回) | 4,270 | **25%** | -| JPEGDEC 自身の復号 | 2,769 | 16% | -| 画素保存の書き戻し | 901 | 5% | -| 拡縮+網点 | 343 | 2% | +After that run the script: -累進形式ではなく(`prog=0`)縮尺 1/2 も妥当。**JPEGの扱い方に問題は無かった**。復号2,769msは -1画素あたり約600サイクルで、この機械としては妥当な値。 +```sh +# For Linux +# This was tested on Debian and should work on most Linux systems. +python3 scripts/debugging_monitor.py -**往復を減らしても変わらなかった** +# For macOS +python3 scripts/debugging_monitor.py /dev/cu.usbmodem2101 +``` -JPEGDEC は1KB前後ずつ要求してくるので、8KBの緩衝を1枚挟んだ。 +Minor adjustments may be required for Windows. -| | 前 | 後 | -|---|---|---| -| 読み込み | 4,270ms/846回 | 3,825ms/**163回** | -| 展開 | 8,563ms | 7,914ms | +--- -**回数は1/5になったのに時間は7%しか減らない**。163回×8KB=1.3MBを3,825msで読んで**340KB/s**。 -展開は1.4MBで7,914ms=**180KB/s**。緩衝の補充が毎回呼んでいた `seek` も外したが変わらなかった。 +## Internals -別の経路でも同じだった。表紙のサムネイル生成は SD への書き出しが無いのに—— +CrossPoint Reader is pretty aggressive about caching data down to the SD card to minimise RAM usage. The ESP32-C3 only has ~380KB of usable RAM, so we have to be careful. A lot of the decisions made in the design of the firmware were based on this constraint. -``` -[ZIP] Decompressed 633921 bytes into 633770 bytes ← 3,886ms = 163KB/s +### Data caching + +The first time chapters of a book are loaded, they are cached to the SD card. Subsequent loads are served from the +cache. This cache directory exists at `.crosspoint` on the SD card. The structure is as follows: + +```text +.crosspoint/ +├── epub_/ # one directory per book, named by content hash +│ ├── progress.bin # reading position (chapter, page, etc.) +│ ├── cover.bmp # generated cover image +│ ├── book.bin # metadata: title, author, spine, TOC +│ ├── css_rules.cache # parsed CSS rule cache +│ ├── img_* # rendered image cache files +│ └── sections/ # per-chapter layout cache +│ ├── 0.bin +│ ├── 1.bin +│ └── ... +├── settings.json # device settings +├── state.json # resume/runtime state +└── recent.json # recent books list ``` -151バイトしか縮まない(=実質そのまま通すだけの)データで163KB/s。**保管層そのものが -160〜340KB/s**で、SDのSPIは既定の40MHz(5MB/s相当)なので**数%しか出ていない**。挿絵の経路を -どう調整してもここが頭打ちで、同じ割合が字形の読み込み・画素保存・章の保存・サムネイルにも効く。 +Removing `/.crosspoint` clears all cached metadata and forces a full regeneration on next open. Book deletes, overwrites, and moves done through the firmware or web UI clear or re-key matching caches; manual SD-card edits may leave stale cache directories behind. -**この節の失敗**: 展開の塊を 4096→16384 に広げたら、deflate 済みの項目は塊を**2つ** malloc する -ため32KB連続を要求し、最大32KBの状況で**外字の取り出しが失敗した**(`pregen extract FAIL`)。 -実測で塊の大きさがほぼ効かないと分かっていたので 8192(`extractItemToFile` と同じ実績値)へ戻した。 +For more details on the internal file structures, see the [file formats document](./docs/file-formats.md). -**あわせて直したもの**: `readerRenderSpec()` の呼び出し3か所のうち `rightMargin` を設定していたのは -1か所だけで、待機中の先組みが組んだ章だけルビの確保が19(前景は14)になり、**章によって1ページの -列数が変わっていた**。設定由来の値なので `readerRenderSpec()` 自身に入れた。 +--- -**残っている費用**: 表紙のサムネイル生成が Home 画面を8.4秒止める(展開3.9秒+復号3.0秒)。 -挿絵と同じ原因。保管層の速度は別途の調査対象。 +## Contributing -### 保管層が遅い原因は SdFat の1バイト転送だった(2026-09-11、`2026091124-diag`、実機確認済み) +Contributions are welcome. If you're new to the codebase, start with the [contributing docs](./docs/contributing/README.md). For things to work on, check the [ideas discussion board](https://github.com/crosspoint-reader/crosspoint-reader/discussions/categories/ideas) — leave a comment before starting so we don't duplicate effort. -前節で挿絵の時間の75%がファイルの読み書きに消えており、経路を問わず**160〜340KB/s**しか出ていない -ことが分かった。40MHz のバスは MB/s 級を運べるはずで、桁が合わない。 +Everyone here is a volunteer, so please be respectful and patient. For governance and community expectations, see [GOVERNANCE.md](./GOVERNANCE.md). -**外したほうの仮説**: X3 の SD は画面と同じ SPI バス(GPIO 8/10/7)を使い、C3 の SPI2 が直結で使える -のは 2/6/7/10 なので SCLK 8 は GPIO マトリクス経由。ESP-IDF はこの経路を読み出し26.6MHzと定めており、 -SDK は既定で40MHzを要求している——タイミング余裕が無く再試行しているのでは、と考えて20MHzを試した。 +--- -| クロック | 634KBの展開 | -|---|---| -| 40MHz | 3,886ms | -| 20MHz | 4,342ms | +## Community forks -**半分にしても10%しか遅くならない**。純粋にクロック律速なら半分になるので、転送時間は全体の約1割で -残り9割は1回ごとの手間、と分かった。既定に戻し、`sd_clock_hz=` を診断に残した(どのクロックで出た -数字かが分からないと比較できない)。 +One of the best things about open source is that anyone can take the code in a different direction. If you need something outside CrossPoint's [scope](./SCOPE.md), check out the community forks: -**当たったほう**: `SdFatConfig.h` は ESP32 では `USE_SPI_ARRAY_TRANSFER` を **0** にする -(RP2040 と UNO R4 のみが例外)。0 のとき `SdSpiArduinoDriver::receive` は—— +- [CrossInk](https://github.com/uxjulia/CrossInk) — UX focused with minimal reading stats and broader customizations for the reading experience. -```cpp -for (size_t i = 0; i < count; i++) buf[i] = m_spi->transfer(0XFF); -``` +- [papyrix-reader](https://github.com/bigbag/papyrix-reader) — Adds FB2 and MD format support. Actively maintained with Arabic script support. Custom themes. + +- [inx](https://github.com/obijuankenobiii/inx) — Completely reimagines the user interface with tabbed navigation. + +- [Witch(hunt) Reader](https://github.com/jpirnay/witchhunt-reader) — More faithful CSS styling and background work for slightly snappier interaction. Weather information panel. Markdown support. + +**Note:** Many of these features will make their way into CrossPoint over time. Each project chooses its own priorities and tradeoffs. + +Want to build your own device? Be sure to check out the [de-link](https://github.com/iandchasse/de-link) project or [OnePage Reader](https://github.com/MoveCall/onepage-reader). + +--- -**1バイトずつ**転送する。Arduino-ESP32 の `transfer(uint8_t)` は毎回データレジスタを書いて起動し -完了を待つので1バイト約2.8µs、8KBで23ms——実測の**23.5ms/8KB とぴたり一致**する。40MHzのバス自体は -8KBを0.2msで運べるので、**99%が1バイトごとの手間**だった。クロックを半分にしても10%しか変わらなかった -のも、転送が元々ごく一部だったからで辻褄が合う。 - -`platformio.ini` に `-DUSE_SPI_ARRAY_TRANSFER=1` の1行(送信側で512バイトのスタック領域を使う)。 - -**実測(同じ1440×2048の挿絵)** - -| 項目 | 前 | 後 | -|---|---|---| -| 展開(zip→SD) | 7,914ms | **3,089ms** | -| JPEGDEC の読み込み | 3,825ms/163回 | **1,335ms**/163回 | -| 復号全体 | 7,882ms | **4,979ms** | -| **挿絵1枚の合計** | **約16,000ms** | **約8,139ms** | -| 外字(128×128)の展開+変換 | 169ms | **90ms** | -| 8KBあたりの読み | 23.5ms(340KB/s) | **8.2ms(1MB/s)** | - -副次: `page_prewarm_ms` 363〜590 → **154**、`glyph_rebuild total_ms` 400〜1,600 → **175**。 -**保管層を通る全部**(字形・挿絵・章の保存・zip の取り出し・表紙のサムネイル)に効く。 - -あわせて、表紙のサムネイルの取り出しだけ塊が 1024 だったのを 8192 に揃えた(634KB に対し620回の -往復になっていた。Home 画面を8.4〜9.2秒止めている経路)。 - -**これは X3 固有ではなく ESP32 全般の話**で、本家・他フォーク・SDK も同じ既定で動いているはず。 - -**この節の失敗**: 展開の塊を 4096→16384 に広げたら、deflate 済みの項目は塊を**2つ** malloc するため -32KB連続を要求し、最大32KBの状況で外字の取り出しが失敗した(`pregen extract FAIL`)。塊の大きさが -ほぼ効かないことは実測で分かっていたので 8192 へ戻した。**塊を増やす前に、その塊がいくつ確保されるかを -見る**。 - -### 章内の飛び先のページと、長い段落の途中の字下げ(2026-09-10、`2026091011-diag`、実機確認済み・章の版50) - -他フォークの確認で見つけた2件を直した。どちらも章の保存の中身が変わるので `SECTION_FILE_VERSION` を -49→50 に上げてある(更新後の初回オープンで全書籍の章が作り直しになる)。 - -**1. 章内の飛び先が1ページ手前を指す**(witchhunt版 `5698985b` と同じ不具合) - -`flushPendingAnchor()` は飛び先(id)を「その要素が現れた時点の `completedPageCount`」で記録していた。 -段落の1行目がページに入りきらず次へ送られる場合、記録は1つ手前のページのままになる。注のリンクから -飛ぶと目当ての段落が画面に無く、ページを1つ送って初めて現れる、という形で出る。目次の飛び先だけは -記録の前にページを切るので無事だった。 - -飛び先を待ち行列(上限16)に積み、`addLineToPage`/`addColumnToPage`/挿絵の配置2箇所/罫線の配置で -「その行が実際に載ったページ」として確定するようにした。1行も生まないまま章が終わった場合は最後の -ページに割り当てる。上限1024の数え方も待ち行列のぶんを足す。縦書きの表は当版では各セルの行が -`addLineToPage` を通るので追加の対応は不要だった。 - -**2. 長い段落の途中で一字下げが再発する**(Inx版 #115 と同じ不具合) - -語数が上限(本の書式を使うとき320語、使わないとき750語)を超えた段落は何回かに分けて配置されるが、 -続きの回も「段落の一行目」と見なされて字下げが入っていた。`ParsedText` に「この段落は既に行(縦書きは列) -を出したか」を持たせ、横書きの `resolveFirstLineIndent` と縦書きの `verticalIndent` の両方で見る。 -行分割の計算(`computeLineBreaks`/`computeHyphenatedLineBreaks`)も同じ判定を通るので、測る幅と描く幅が -ずれない。 - -**テスト資産**: `vertical-test-suite.epub` にテスト23(長い段落の途中の字下げ)とテスト24(章内リンクの -飛び先ページ)を追加した(生成は `test-assets/corpus-survey/patch_suite6.py`、epubcheck 5.3.0 で追加分に -エラーなし)。テスト23は書式指定 `text-indent:3em` の1,464字の段落と、自動の一字下げに任せる1,438字の段落の -2本立てで、読書設定の段落間の空きに左右されずに確かめられる。テスト24は最初のページに01〜24のリンク、 -その下に長さを25〜104字で変えた24個の目印段落を置き、どれかの段落の頭がページの境目に当たるようにしてある。 - -**実機確認**(`2026091011-diag`): -- テスト23: 1/24 で〔見本〕と〔1〕の2箇所だけが3文字ぶん下がる(16字=19字−3)。2/24 は先頭列が19字=満杯で、 - ページと区切りをまたいでも下がらない -- テスト24: **07 は 5/14、14 は 9/14** に着地。どちらも【NN】が着地ページの右端の列の先頭=以前ずれていた形。 - 列の途中から始まる06は元から正しく4/14 -- 注意: 最初の試行では07・14とも1つ手前に着いた。作り直し後は正しくなったので、前の状態の章の保存 - (部分保存か、別ビルドで組んだ配置)が残っていたものと見られる。再発したら `e-ink/dump_section_anchors.py` - で章の保存の飛び先表を直接読み、記録側か読み出し側かを切り分けられる - -### 配置がメモリ不足で落ちるのを止める(2026-09-10、`2026091011-diag`) - -`2026091008` の実機でページ送り中に異常終了した。ELFで逆引きすると発生源は -`ParsedText::layoutVerticalColumns` の `wordHeights.reserve`(`ParsedText.cpp`、2026-09-06 の縦書き移植から -あるコード)で、`-fno-exceptions` では `operator new` が失敗時に nullptr を返さず `std::terminate` を呼ぶ。 -直前のログに「1024バイトの確保に失敗」が出ており、原因は空きメモリの枯渇。26秒前には -`Low heap opening menu (5340 free, 2164 max block)` も出ていた。 - -- **配置に入る前に見積もりと空きを比べる**。縦書き6バイト/語・横書き12バイト/語(行分割の dp と ans が - 4バイトずつ要るため横が高い)+6KBの床。足りなければその章の組み立てを失敗として返し、`abandonBuild()` で - 保存を書かずに終わる。**落ちる代わりに「次に開いたときに作り直し」**になる -- `wordHeights` を nothrow の配列に、列の `TextBlock` も nothrow 生成+`valid()` 確認に -- **区切り(soft flush)の取りこぼしを直した**。判定を語を足す途中でも行う。従来は文字の塊を読み終えてから - しか見ないため、上限320語に対して648語まで溜まり、配置が確保する山が倍になっていた。 - 最初の修正では語の切れ目(`partWordBufferIndex == 0`)に置いたが、空白の無い日本語は200バイトの - 溜め込みが埋まったときにしか字を渡さず、しかも3バイトの字が境目をまたぐと溜め込みが空にならないため - ほぼ発火していなかった(`words_max=471` で判明)。溜め込みが埋まった直後にも判定するようにした -- 診断版に `build_headroom_min=` を追加(配置に入る直前の空き・最大連続・語数の最小値と、扱った語数の最大値) - -**実機確認**: `2026091010-diag`(10分の読書)で `build_headroom_min=13920 max_alloc_then=10228 words_then=447`。 -447語なら見積もりは8.8KBなので約5KBの余裕を残して通っており、門番が誤って章を拒否してはいない。落ちた章 -(テスト23本文)が今度は最後まで組み上がった。続く `2026091011-diag` でテスト23本文を組み直させたところ -`build_headroom_min=24360 max_alloc_then=18420 words_then=380` で **`words_max=471`→`380`**。上限320に対する -超過が151語から60語(溜め込み1杯=約66字)に収まり、区切りの修正が効いていることを確認した。 -`heap_min_free` は 3,756/8,188/2,920 バイトまで落ちており、**落ちなくなっただけで狭さ自体は残っている** -(`OOM: grayscale strip scratch (7920 bytes); skipping AA this page` や -`132 glyphs loaded on demand in the BW pass; skipping AA this page` が出る)。 - -同じ診断から次の候補: 字形の一時記憶の作り直しにセッション合計18.6秒(`glyph_rebuild ... total_ms=18656`、 -`mini_free=120`)、および「BW描画で128字を1字ずつSDから読み階調を諦めた」6秒のページ(`aa_aborts=2`)。 - -### 章の配置の保存の版を上げる(2026-09-09、未配布・次のリリースに含める) - -商業書籍の本文中の外字画像「№2」(`img.gaiji`、`width:1em;height:1em`)が X3 で元画像の 128px のまま出る報告。診断で追うと、 -キャッシュ消去後の組み立てでは 44×44(1文字大)に置かれ(`image-diag.txt`: `placed 44x44 … vert=1`)、章ごとの絞り込み再解析も -8ファイル全部を読んで 9 規則で完了していた(`css done rules=9 result=0 filtered=1`)。つまり現行の解析は正しく、報告の表示は -**09-06 夜の書式対応(tag.class・二段の指定子・縦書き字下げ)より前に組み立てた章の保存**を読んでいたもの。章の保存 -(`sections/N.bin`)には配置結果がそのまま入るので、書式の解釈が変わっても版を上げなければ古い配置が残る。09-06 は -`SECTION_FILE_VERSION` を 48 に上げたのが昼(部分保存の再解析の修正)で、夜の書式対応では上げていなかった。pre-release -20260906/20260909 の「初回オープン時に配置の作り直しが走る」はスタイルの保存(`CSS_CACHE_VERSION` 13)の話で、章の配置は対象外 -だった。`SECTION_FILE_VERSION` を 49 に上げ(部分保存の目印も連動)、次のリリースで全章が作り直されるようにする。 -**以後、配置の結果が変わる修正では必ずこの版を上げる。** - -同じ診断から: 保存の無い章の途中(第13章の126ページ目)を読書位置から開くと、そこまでの組み立てに 38.4 秒(16 回、最長 10.8 秒)、 -描画まで 46.4 秒。続く描画で階調用の作業領域(7.9KB)が取れず、そのページだけ白黒で出た(`OOM: grayscale strip scratch`)。 -先組みは章の途中を開く場合には効かない。外字画像そのものは「独立した列の上下中央」に置かれる既知の制限が残る(文の途中の -「№2」が別の列の真ん中に浮く)。1文字大の画像を字として列に流す実装(JP版 #129 と同じ考え方)が次の候補。 - -### 段階と進み具合(ユーザー指定の順序): - -| 段階 | 内容 | 状態 | -|---|---|---| -| 1 | 1.6.0から `feat/vertical-1.6.0based` を作成、SDK `cb9167d` | 完了(2026-09-06) | -| 2 | 診断基盤(INPUT_DIAG、ビルド番号、クラッシュ報告の先頭行) | 完了・実機確認済み(2026-09-06、`2026090601-diag`) | -| 3 | 時計機能の移植と、固まった時の再起動の実機検証 | 完了・実機確認済み(2026-09-06、`2026090602-diag`) | -| 4 | フォント(SDフォントの字形領域の分割・キャッシュ解放・ヒープ門番) | 完了・実機確認済み(2026-09-06、`2026090604-diag`) | -| 5 | 縦書き(縦組版コア・電書協CSSのメモリ管理・ルビ/圏点/約物/UAX#50・傍線) | 完了・実機確認済み(2026-09-06、`2026090606-diag`、テスト書16章すべて旧ツリーと一致) | -| 6 | 挿絵(章内画像、寸法指定、ページ送りの速度) | 完了・実機確認済み(2026-09-06、`2026090609-diag`〜`0610-diag`)。コードは段階5に同梱。商業書籍1冊の寸法指定が旧ツリーと同値、`image-size-test.epub` 13サイズ全部合格、`vertical-image-test.epub` 全章が旧ツリーと一致 | - -### 旧ツリーとの照合(2026-09-06、6段階完了後) -旧ツリー `feat/vertical-1.6` が本家 `1.6.0rc` から**加えた行**(生成フォントの表・README・テスト書を除く87ファイル、 -5,443行)を、新ツリーの同じファイルに1行ずつ探した。見つからなかったのは384行で、内訳は全部が説明できる: - -| 見つからなかった行 | 何か | 判断 | -|---|---|---| -| UIフォント関係のスクリプト3本(286行)、`convert-builtin-fonts.sh`、`main.cpp` の Medium フォント宣言、`build-font-ids.sh` | 本家 #3096「UI文字を Ubuntu Medium にする」と、その手直し #3186・光学補正済み Noto UI 面。旧ツリーは採用していた | **本家が 1.6.0 で #3096 を取り消した**(#3314)。新ツリーは本家に従い Regular。旧ツリーの見た目に戻すなら移植が必要(下記) | -| `CssParser.cpp/.h`(32行)、`Epub.cpp/.h`(18行) | 解析中の空き32KB門番、`validateCache`、`cssComplete` で保存を止める旧方式 | 本家 #3005 の「上限付き保存+部分キャッシュ」の上に作り直したので形が違う。機能は「部分なら章ごとに選別解析」で置き換え済み(段階6の項) | -| `fontconvert.py` の `--mono`/`--autohint-font`(18行) | #3096 系の1bit描画オプション | 上と同じ理由で不要。SDフォント側(`fontconvert_sdcard.py`・`sd-fonts.yaml`)は全行一致 | -| `ChapterHtmlSlimParser.cpp`(7行) | 圏点を先頭トークンにまとめて付ける旧形(本節で直した側) | 新ツリーのほうが正しい | -| `ReaderUtils.h`(1行) | 長押し設定OFF時に押下で送る判定 | 本家 1.6.0 が「長押し/離した」判定に変えたのを取り込み、`usePress` 分岐は残してある | -| `HalGPIO.cpp`・`Section.cpp` の各1〜2行 | 条件式の書き方、版番号(旧49/新48) | 同等。版番号は違えば作り直すので混在しても問題ない | - -**本家 1.6.0 の変更で、旧ツリーが取り込んでいた11件**(#3107 #3009 #3122 #3134 #3102 #3191 #3244 #3119 #3222 -#3144 #3186)は、#3096 の取り消しを除き**すべて 1.6.0 本体に入っている**。新ツリー側で改めて当てる必要はない。 - -**新ツリーにだけあるもの**: 本家 1.6.0 の79コミット(言語別フォント #3146、表の列描画 #2654、リンクのタッチ操作 -#3296、SD電源断と単押し起動 #3341、冷間起動の電源ボタン誤判定 #3248、X4 Classic 対応 #3279、リーダーのツールバー -メニュー #3182、辞書まわり、KOSync・OPDS 修正ほか)と、この作り直しで加えた**部分キャッシュ時の章ごと選別解析** -(`95a7600c`)、**圏点の文字ごと付与**(`f1dd384f`)、縦書き本での表の縦積みへの退避、`wordLinkIds` との歩調合わせ。 - -**UI文字の太さは本家どおり Regular にする**(2026-09-06 決定)。旧ツリー(公開中の 2026090504)は Ubuntu Medium -だったが、本家が #3096 を採用しなかった(#3314 で取り消し)以上、新版でも採用しない。1bit描画で Regular は縦線が -2px、Medium は3pxになる差があり、本家は表示崩れ(#3186 で直した文字の重なり)を理由に戻している。 - -### 1.6.0で変わったビルドのしかた -1.6.0は `firmware_tuned` という設定でArduino基盤そのものを再構築し、ヒープを32〜37KB回収する -(タスクの持ち分の縮小、WiFiの処理をIRAMから外す、使わない部品の除外)。初回ビルドで基盤を作り直すため -7分半かかり、ESP-IDF用のPython部品(`idf-component-manager` ほか)が環境に無いと設定段階で止まる。 -以降のビルドは1分半〜3分半。素の1.6.0のX3向けビルドは RAM 17.1%・Flash 83.5%。 - -### 段階2: 診断基盤(2026-09-06、実機確認済み) -`InputDiag` 本体と `scripts/ost_version.py` は旧ツリーからそのまま複製し、差し込み口だけを1.6.0側の -コードに合わせて置き直した: 主ループの入力採取と書き出し、画面描画ごとの所要時間と5秒超の記録採取、 -一覧画面の行配置、読書画面の本を開く6段階のヒープ・章構築の所要・ページ描画の内訳、`crash_report.txt` -先頭のビルド番号。字形の読み込み回数などSDフォント側の計測値はフォント段階まで0のまま。 - -実機で採れた最初の数字が、そのまま後の段階の動機になっている。**素の1.6.0に日本語SDフォントを載せると、 -読書中の空きが最低2.3KB・最大連続4.8KBまで落ち、テスト書の第2章は「出力バッファのメモリ確保に失敗」で -3回再試行の末に章の構築に失敗した**(診断が `section-build-failed` として直前ログ付きで捕捉)。 -一覧画面の描画も空き7〜9KBで1.9〜4.8秒かかっている。旧ツリーではフォント段階(キャッシュ解放・領域分割)と -縦書き段階(CSSのメモリ管理)で解消していたものが、1.6.0素の状態では丸ごと残っていることの確認になった。 -本を開く6段階は enter 93KB → page1 62KB(最大連続 71KB → 33KB)。 - -### 段階3: 時計機能と、固まった時の再起動(2026-09-06、実機検証済み) -旧ツリーの完成形をそのまま移した: 時計画面(`ClockActivity`/`ClockFace`/数字の図案)、RTCの日時取得 -(`HalClock::getLocalDateTime`)、電池電圧の読み取り、CPU速度切り替えの直列化(`HalPowerManager`)、 -待機中の降速を「入力の有無」で判定する主ループ、時計画面限定の30秒監視(主処理・描画処理、全ビルド)、 -止まったタスク名をクラッシュ報告に残す処理、故意ハングの引き金(`CLOCK_HANG_TRIGGERS`/ -`DEBUG_RENDER_WATCHDOG` の試験ビルドのみ)、Homeメニューの「Start clock mode」。 -1.6.0側に #3009(起床時の残像取り)が既に入っていたため、旧ツリーで自前に持っていた `goHome` の引数は -そのまま使えた。1.6.0が足したクラッシュ報告の「Reset reason」行とも共存する。 - -実機検証(`2026090602-diag`=配布版と同じ監視経路、`DEBUG_RENDER_WATCHDOG` なし): -- 側面ボタン → `forced hang: render task` → 主処理は `minute turn` を記録し続け → 30秒で再起動、 - 理由欄 `ActivityManager (CPU 0)`、`Reset reason: TASK_WDT` -- 前面ボタン → `forced hang: main task` → 30秒で再起動、理由欄 `loopTask (CPU 0)` -- 時計は11分の連続表示で分更新445ms・残像取り3.19秒、**空き76KB・最大連続71KBで一定**。旧ツリーの - 44KBより30KB以上多い(1.6.0の基盤再構築による回収分と、SDフォントの常駐がまだ無いことの両方) - -**前面ボタンの試験で1回引き金が引かれなかった**。直前ログの周波数の上げ下げから押下は約1.2秒で、 -X3の前面「決定」キーは電源ボタンと線を共有しており、SDKの入力処理が**0.4秒以上の押下を電源ボタン -の操作として扱う**(`CONFIRM_POWER_HOLD_MS`)。電源短押しは既定で無視なので何も起きなかったように見えた。 -短く叩いて再試験し合格。旧SDKも同じ判定なので、試験手順としては「前面は短く叩く」が正しい。 - -旧ツリーの配布版 `2026090504`(同じ監視・同じ時計)では給電なし11時間11分の連続表示で誤発火なし、 -残量100%→96%、−14mV/h(2026-09-05〜06)。1.6.0側での長時間放置は次の段階のビルドと並行して行う。 - -### 段階4: フォント=SDフォントのメモリ管理(2026-09-06、実機確認済み) -旧ツリーのコミットを差分として1.6.0に当て直した(3方向マージ): 字形領域を4KB片で組み立てる方式、 -符号位置の受け皿を必要量まで伸ばす方式、SDフォントのキャッシュ解放(一覧画面を開くとき・飢えたヒープで -本を開くとき・章の展開が断片化ヒープに当たったとき・低ヒープで読書メニューを開くとき)、読書画面の -ページ表示と章構築のヒープ門番、診断への字形読み込み回数・領域作り直し回数・走査結果の接続。 - -**本家1.6.0の #3126(字形領域が取れないとき半分ずつ縮めて再試行)は外した**。同じ問題への別解で、 -当版の分割方式が入れば再試行は決して走らない死んだ経路になるため、定数・欄・再試行ループを撤去した。 -内蔵UIフォントは1.6.0のまま(本家が Ubuntu Medium を取り消した判断に合わせる)。SDフォントのファイル形式は -変わらず、`fonts-202608240.zip` がそのまま使える。 - -実機(`2026090604-diag`): 段階2で構築に失敗したテスト書の第2章が開く。本を開く6段階の最大連続ブロックが -sect 33KB→55KB、page1 33KB→47KB に改善。字形の計測欄が生きた(`page_scan_last=88b/3f`)。 -**残る問題(旧ツリーから引き継ぎ、移植による後退ではない)**: 読書後にファイル一覧を開くと1画面の描画で -字形領域の作り直しが16〜21回走り、3.0〜4.5秒かかる(旧ツリーでも 3.9〜4.6秒・12〜14回の記録がある)。 -一覧の行ごとに逐次で字形を読むためで、読書ページ式の一括事前読み込みを一覧画面にも適用する必要がある。 -起動直後の一覧は0.5〜0.9秒なので、読書が残したヒープの状態に依存する。 - -### 段階5: 縦書き(2026-09-06、実機確認済み) -**やり方を変えた。** 旧ツリーの縦書き関連コミット(約25件)を順に当てると、本家1.6.0が同じファイルに入れた -変更(タッチでのリンク #3296、表の段組み #2654、CSS保存方式の書き換え #3005、RTL継承 #3198、 -段落間隔 #3221、脚注の上付き #3355)と衝突を繰り返す。そこで**旧ツリーの完成形をファイル単位で -1.6.0に3方向マージ**した(本家が触っていないファイルは丸ごと複製、両方が触ったファイルは -`git diff rc..old -- F | git apply -3`)。衝突は10ファイル29箇所。解析器と章構築(`ChapterHtmlSlimParser`・ -`Section`・`ImageBlock`)は縦書きと挿絵で共有しているため、**段階6の挿絵のコードも同じ変更に入った**。 -検証だけを段階の順に分けている。 - -手を入れた箇所: -- **CSS解析器は本家1.6.0の新実装を土台に作り直した。** 本家は規則の保存を可変長の連想配列から上限付きの - 固定領域(選択子プール+スタイルの重複排除、`-fno-exceptions`で落ちない)へ書き換えており、当版の - 「メモリ不足で落ちない」目的と同じ。その上に当版の機能を載せ直した: 圏点(`text-emphasis`、`-epub-`/`-webkit-` - 接頭辞込み)と `max-width`/`max-height` の解釈と保存形式(記録に1バイト+2長さ、定義ビット18〜20)、 - 章ごとの選別読み込み(登録時とキャッシュ読み込み時の両方でフィルタ)、描画時のヒープ門番の撤去。 - 本家が足した「部分キャッシュを残して後で再試行」「メモリ不足なら章構築を延期」はそのまま生きる。 - CSSキャッシュの版は12(本家11と記録長が違う) -- **章の版は46**: 本家の40〜45と旧ツリーの40〜49のどちらの番号とも重ならない値。全書籍が初回オープンで - 配置を作り直す -- 語の並列配列: 本家の `wordLinkIds` と当版の `wordVerticalBehaviors` を両方保持し、縦書きの追加・削除経路 - でも歩調を合わせた -- 語の追加: 本家のリンク識別(語ごとのlink id)と当版の縦書き分岐を同じ関数で両立。**縦書き本では本家の - 表の段組みを使わず平坦化に固定**(段組みは横書き座標で置かれるため) -- ページ送りボタン: 本家の長押しスキップと、当版の右開き(RTL)での左右反転・側面ボタンの上書きを合成 -- 読書画面は本家の道具箱型メニューなど新UIをそのまま残し、縦書き判定・RTLページ送り・AA見送り・ - 挿絵ページの残像取りだけを当てた - -実機(`2026090606-diag`、`vertical-test-suite.epub` 全16章を写真で照合): **テスト1〜16すべて旧ツリーと同じ -表示**。約物・記号の向き(UAX#50)、補助面漢字、互換漢字の代替、圏点5種と入れ子解除、実体参照2経路、 -欧文語間空白、小書き仮名の右寄せ、40行の長大段落と1300字の漢字連続、太字/下線/取り消し線のタグ版と -クラス版。20分・177描画・368回のボタン操作で異常終了なし。診断: ページ描画1.2〜1.5秒(字形領域の -作り直しが毎ページ1〜4回、計39秒)、空き最低3.3KB(旧ツリーの同種の読書でも4.3〜16KBまで落ちていた)、 -CSSは20規則を完全読み込み、`resolveStyle` の結果が診断に出る。 - -旧ツリーから引き継いだ既知の差(後退ではない): 縦書きの段落配置(中央/末尾寄せ)は未実装(`text-indent` は -2026-09-06 に対応、下の「縦書きの書式対応の拡充」)、Extra Paragraph Spacing ONでは自動字下げが無効、 -中黒「・」(U+30FB/半角U+FF65)の行頭禁則(同日に表へ追加)、読書後の一覧画面が遅い。 - -### 段階6: 挿絵(2026-09-06、完了・商業書籍1冊とテスト書2冊で実機確認) -KADOKAWA テンプレートの縦書きライトノベル(旧ツリーが 2026-08-31 に検証したのと同じ本)で、 -`2026090606`〜`0608` は**挿絵の寸法が開くたびに変わった**(容器いっぱい/小さく/その中間)。診断で原因が -3つ重なっていると分かり、順に直した: - -1. **部分キャッシュを完全扱いしていた**。本家1.6.0の保存方式は規則索引・選択子・書式を連続領域で倍々に - 伸ばすため、最大連続ブロック18〜22KBの断片化ヒープでは32KBへの成長に失敗し、テンプレート - 3,172規則のうち296件で打ち切る。本家はそれを「部分キャッシュ」として保存し、章構築はそれを - 読み込み成功として使っていた。画像用クラスは切り落とされた側にあるので `fit ... rules=0` になる。 - → 部分キャッシュを読んだ章構築は、旧ツリーと同じく**章ごとの選別解析をやり直す** - (`CssParser::lastCacheLoadPartial`)。章の版を47に上げ、規則なしで組んだ章を作り直させた -2. **選別解析にも全体解析用の門番(空き64KB)が掛かっていた**。章構築時の空きは47〜66KBなので、 - 6ファイル全部を読み飛ばす回と読める回が混在し、同じ挿絵が別の大きさになった。 - → 選別解析は24KBで走らせる(登録は数十規則、初期領域は索引1KB・選択子4KB・書式16件、 - ファイルは512バイトずつ流し読み)。全体解析の64KBはそのまま -3. **診断が章構築を遅くしていた**。Kobo由来の `koboSpan` が全文に付く本で、クラス付きspanごとの - 診断1行がSDカードへの書き直し1回になり、1章39回で数秒を食い、CSSと画像の行を記録の輪から押し出した。 - → 太字・斜体・線・圏点のどれかに解決したspanだけ書く - -`2026090609-diag` の結果は旧ツリーの 08-31 の記録と**同値**: 3,172規則中7件だけ登録(`result=0 filtered=1`)、 -166x180→70x76(max-height 10%)、195x244→60x76、199x1345→89x605(80%)、570x1600→269x756(`fit` のみ)。 -章題ページの羊とロゴが1文字大なのは著者指定(高さ10%)で、0606で大きく見えていたほうが誤りだった。 -章の初回表示は17秒(構築9.2秒+選別解析+挿絵5枚の前生成)で、その間は入力を受け付けない。 -旧ツリーの「画像の多い章で11秒」より長く、選別解析の分が乗っている。改善候補。 - -テスト書2冊の結果(同じ `2026090609-diag`): - -- `image-size-test.epub`(横書き、実書籍954冊の実測寸法13種、各ページ画像1枚のみ): **13ページ全部合格**。 - 外枠の欠け・円の歪み・四隅の向きの異常なし。縦長9種(720×1024〜1748×2480)は全面に収まり、 - 横長4種(2048×1589・2868×2048・3049×1300 など)は横幅いっぱいで上寄せ、下は余白。 - 最大の5.87Mpx(2868×2048)と最長辺3049×1300も止まらず表示。1px縞は縮小率によって - グレーに潰れるか、間引き位置しだいで真っ黒/薄いグレーの一様な塗りになる(2048×1589で観察)。 - 縮小器が近い画素を拾うだけで平均を取らないためで、線画のテスト図形でしか目立たず、対処しない。 - 3049×1300(約6分の1)では中央の小さな文字が読めなくなる。これは判定外の「実用下限」の観察項目。 -- `vertical-image-test.epub`(縦書き): 全章が旧ツリーの既知の挙動と一致 - (外字画像は1マス幅の独立した列を占める、全面・40%・横長は正しく縮小、1bit/4bit PNG と svg包みは表示)。 - 第3章(同じ縞画像を4経路で参照)は4枚とも表示。画像は列の流れに入り、ページの右端に画像、その左に - 次の見出しが続く並びで、読み順(見出し→画像→次の見出し)どおり。1ページに画像1枚ずつ、2〜5ページ目。 -- 縦書き本のページ送り(左が進む、側面ボタン)は想定どおり。章境界の描画は7.4秒 - (章の組版5.2秒+字形再構築3回)、灰色階調の描画は約2.2秒で、いずれも旧ツリーと同じ傾向。 - -横書きの回帰確認で1件直した(`2026090610-diag`、章の版48)。横書きの圏点は、対象の文字列を1回で -まとめて処理し**先頭の1文字にまとめて全部の点をルビとして付けていた**ため、13文字の強調で先頭の -「は」に13個分のルビが乗り、ルビ幅に合わせて「は 一 文」と行が引き伸ばされた。横書きの本文は -CJK文字を1文字1トークンに分けて積むので、トークンごとにその文字数分の点を付ける形に直した。 -旧ツリーでも同じ挙動だった(移植で持ち込んだ既存の不具合)。 - -### 商業EPUB蔵書の取得し直しに伴うテストEPUB3冊の更新(2026-09-06、調査とテスト資産のみ・FW変更なし) - -蔵書の取得し直しが完了し(旧 `protect-epub` は廃止、`new-protect-epub` に一本化)、2,256ファイル・識別子で重複を除いて -**1,941冊(リフロー型878・固定レイアウト1,063、縦書き1,814)**を対象に、これまで3回に分けて行った調査 -(挿絵の書き方955冊、画像寸法954冊、使用文字とフォント収録範囲955冊)を一つの集計器で取り直した。本文は保存も引用も -していない(タグの形・クラス名・CSSの値・画像の見出し部・文字の出現数だけ)。集計器と数値だけの結果は -`e-ink/test-assets/corpus-survey/`(リポジトリ外)に置いた。 - -**蔵書の性質で新しく分かったこと**: リフロー型はほぼ全冊がKobo書店の形式(KEPUB)で(ルビを持つ852冊の全部で確認)、本文のすべての文字列が読書位置記録用の -`` で包まれている。ルビの親文字・読み・外字画像も一つずつ包まれ、 -ルビ160万箇所のうち約39万箇所(528冊)が親文字一字ごとに読みを分けた形(`ruby` の中に `rt` が複数)、 -`rp` の括弧も span で包まれる(21冊・23,001箇所、XHTMLの規則上は不正だが実在する)。これまでのテスト書は -どれもこの形を含んでいなかった。 - -**数値の主な変化と新しい発見**(リフロー型878冊、詳細は `test/epubs-ja/README`): - -| 項目 | 前回 | 今回 | -|---|---|---| -| 挿絵の寸法指定が max-* クラス | ほぼ全て | 757冊(固定幅8・width属性2・style属性2) | -| svgで包んだ挿絵 | 527/955冊・約7万箇所 | 408/878冊・8,071箇所(コミックは全ページ) | -| 無圧縮格納の画像 | 0/10万枚超 | 0/209,851枚 | -| 文庫(リフロー)画像の中央値/上位10% | 844×1200/1120×1600 | **1135×1600/1440×2048**(加わった出版社の口絵が大きい) | -| 画素数最大 | 2868×2048(コミック) | 2868×2048(**文庫の見開き口絵**に移った) | -| 外字画像の大きさ指定 | 1em角のみ想定 | 幅2em 833・幅1.5em 74・幅6em 62・高さ3em 82・高さ4em 87箇所 | -| 挿絵だけのページ | 未調査 | vrtlファイル9,841・**hltr(横組み指定)ファイル6,355ページ**、hltrの画像ページを持つ本352冊 | -| ルビ付き外字画像 | 1例を想定 | 1,329箇所・120冊 | -| upright/sideways クラス | 未調査 | 147冊・3,605箇所/226冊・451箇所。CSSは接頭辞付き(-webkit-/-epub-)だけで書かれる | -| 段落の text-indent/text-align クラス | 未調査 | 421冊/705冊。負の値(ぶら下げ、`text-indent:-Nem; padding-top:Nem`)1万箇所超 | -| span の font-size クラス | 未調査 | 641冊(90% 3,864・110% 2,087・0.7em 1,002箇所) | -| フォント未収録の文字 | ℃・溺蓮煉・𠮟 など | 3書体共通で未収録はなし(1冊限りのタイ文字・ヘブライ文字・合字を除く)。BIZ UD系のみ **Ⓒ(56冊)**・逬(4冊)・溺(11冊)・煉(3冊)が元フォント未収録。**IVS異体字選択子 U+E0100 が1冊**にあり、現状は読み飛ばさない | -| 頻出記号 | — | ─(U+2500)637冊・31万回(ダッシュ「──」)、〝〟で始まる段落6,223(禁則表に未登録)、⁉634回・‼ | - -**テストEPUBへの反映**(3冊とも epubcheck は従来からの意図的な不整合以外エラーなし。**テスト17は実機で5項目すべて合格**(2026-09-06、`2026090611`): 文の分割・ルビ・一字ずつの読み・rp の括弧・装飾クラスの内側の区切り要素のどれも「なし」と同じ見え方で、Kobo形式の本は現状の解析器でそのまま読める。**テスト18も実機確認済み**: 予想どおり upright/sideways の指定は無視され、指定あり・比較の両段落が同じ見え方(矢印は既定どおり下向き、全角の!?ーは正立のまま)。周りの字への影響は無い。**テスト19・20も実機確認済み**: 19は text-indent(正負)・padding-top・margin-top の全部が無視され、全段落が天から始まる(予想どおり)。ただし **text-align:center の段落の最初の列で、末尾の1字の前に空きが入る**現象を新しく確認した(同じ形の文で right では出ない。要調査)。20は span の font-size が全部無視され、同じ大きさで出る(予想どおり。ルビと列は乱れない)。**テスト21も実機確認済み**(NotoSansJP): ─―‐は縦の線(合格)、⁉‼♡♥※●◆①は正立(合格)だが Ⅱ(U+2161)は写真では横倒しに見えたが、**2026-09-08 に拡大写真で正立を確認**(セリフの無い2本の縦線が低解像度の写真で「=」に見えていただけ。変換済みフォントの字形も縦長で保存されていることを確かめた。規格どおりで問題なし)、Ⓒ・逬は表示(合格)、**葛の直後に四角が出る=IVS未対応を確認(同日 `2026090612-diag` で修正・実機合格)**、数字の桁数別の形は合格、〝〟の禁則は列の変わり目に来ず判定できず(文の長さを調節する)。**`image-size-test.epub` は14ページ全部合格**(2026-09-06、`2026090611`): 新しく入った 3360×1187・2868×2048(5.87Mpx)・2700×1410・1832×2600 を含め、どれも幅いっぱい・外枠四辺あり・正円で、横長は上寄せ。**`vertical-image-test.epub` v11 の第10〜12章も実機確認済み**: 第10章は幅1.5em・2em・2em横長・高さ3em・4em・幅6emの全部が指定どおりの大きさで本文と重ならない(列をまたぐ幅の絵は列を割り当てて上下中央に置かれる)。第11章は hltr+img/hltr+svg/vrtl+img の挿絵ページが全部表示され、送り順 A→B→C→D→第12章 も正しい。D の文字ページは既知の制限どおり縦で出る。第12章は区切り要素に包まれた外字・一字ずつの読み・分割された文が合格、ルビ付き外字の読みは既知の制限どおり付かない。**3冊とも実機確認完了**): - -- `image-size-test.epub` を新しい実測値で作り直した(13→14ページ)。文庫の中央値・上位10%・最長辺 3360×1187・ - 最大画素 2868×2048、コミック現行の最長辺 2700×1410・最大画素 1748×2480、旧世代の最頻 710×1024、大判の最大 1832×2600。 - まとめページに前回との比較表と測りかた(固定レイアウトは各本12枚前後の見出し部を読み、残りはsvgのimage属性。 - 読んだ46,166枚のうち属性と食い違い68枚)を載せた。生成器 `test-assets/build_image_size_test.py` を更新 -- `vertical-image-test.epub` を v11 に(9→18ページ)。第7・9章の数値を更新し、第10章「1em以外のem単位の外字・小画像」、 - 第11章「別ファイルの挿絵ページ(hltr+img/hltr+svg/vrtl+img/hltr文字ページの4ファイル、送り順の確認)」、 - 第12章「Kobo形式の区切り要素と外字・ルビ」を追加 -- `vertical-test-suite.epub` にテスト17〜21を追加(32→42章)。17: Kobo形式の区切り要素(同じ文の「あり/なし」を対にして - 比較。文の分割・ルビ・一字ずつのルビ・rp・縦中横・傍点・太字)、18: upright/sideways の明示指定 - (**当版は未対応と分かっている**ので記録用)、19: 電書協テンプレートの字下げ・ぶら下げ・天アキ(同じく未対応の記録用)、 - 20: 文中の font-size 指定、21: 頻度順の記号(─―‐の向き、〝〟の禁則、⁉‼♡♥※●◆①Ⅱの正立、Ⓒ・逬の収録、 - IVS の読み飛ばし、数字の桁数別の形)。テスト8・9の解説に再調査の冊数を1文ずつ追記 - -**実装への含意(今回はFWを変えていない)**: 優先度順に、(1) IVS(U+E0100〜E01EF)をVS15/16と同じく読み飛ばす(**2026-09-06 実施**: 読み飛ばしを VS1〜VS16 の U+FE00〜FE0F 全部と IVS の U+E0100〜E01EF に広げた。`2026090612-diag` でテスト21の「葛󠄀」の四角が消えたのを実機確認)、 -(2) 〝(U+301D)を行末禁則・〟(U+301F)を行頭禁則に加える、(3) 接頭辞付きの text-orientation を読んで upright/sideways -を効かせる、(4) 縦書きの text-indent(正負)と margin-top の天アキ、(5) span の font-size、(6) text-align:center の列で末尾の1字の前に空きが入る件の原因調査。(3)〜(5) は市販の本での -使用冊数が多く、既知の制限として残していたものに実際の頻度が付いた形になる。 - -### 縦書きの書式対応の拡充(2026-09-06、前節の実装候補(2)〜(6)を優先度順に実施・`2026090613-diag`・実機確認済み) - -前節の「実装への含意」(2)〜(6)を順に片付けた。(5)だけは見送り(理由は下)。 - -**(2) 禁則表の拡充**(`VerticalTextUtils.h`): 〝(U+301D)を行末禁則、〟(U+301F)を行頭禁則に加えた。同じ性質の -“‘(行末)と ”’(行頭)も一緒に登録。あわせて JLREQ の行頭禁則のうち表に無かった類——ハイフン類「‐–〜゠~」 -(cl-03)、中点類「・・」(cl-05。段階5の節で候補にしていた中黒の件はこれで解消)、分離禁止「‥…〳〴〵」(cl-08)、 -繰返し記号「々〻ゝゞヽヾ」(cl-09)——を行頭禁則に加えた。 - -**(6) text-align:center の列で末尾の1字の前に空きが見える件は、原因が分かり不具合ではなかった。** 18pt NotoSansJP で -1マスは38px。写真の【中央】の第1列は 【中央】この段落は+半角17字+。+縦 で 715px、【右】の第1列は 686px、 -【基準】の第1列は 684px(次の1字を足すと722pxで入らない)。つまり列の容量は715〜721pxで、【中央】の列だけが -容量ぎりぎりまで詰まっていた。「。」の後の空きを写真の画素で測ると【中央】も【右】も同じ47px——縦書きの句点は -縦書き用の字形「︒」で1マスを使い、点がマスの上端に付くので残りが空きに見える、いつもの形。最後の1字が -状態表示の直上まで下がったので目についただけで、中央揃え特有の現象ではない。中央揃え・右揃えは縦書きでは列の -位置を変えないという現状の扱いはそのまま。 - -**(3) 文字の向きの明示指定**(`CssParser`・`ChapterHtmlSlimParser`・`TextBlock`・`EpdFontFamily.h`): -`text-orientation`(upright/sideways/sideways-right/mixed)を、市販の本が使う `-webkit-`/`-epub-` 接頭辞付きも -含めて読む。縦中横の `text-combine-upright: all`(電書協の `tcy` クラスが使う `-webkit-text-combine: horizontal` -の形も)も同じ欄で持つ。仕組み: ページの保存形式に字ごとの向きの配列を足す代わりに、語の書式ビットの空きの1ビット -(`VERTICAL_FLIP`)を「文字の種類から決まる向きを反転する」印にした。描画側は従来どおり文字の種類から向きを決め、 -印が付いていれば逆にする。これで章の保存形式(`SECTION_FILE_VERSION`)は変えずに済む。 -- 正立指定: 半角の英数字・記号・矢印は1字ずつ1マスを占め、マスの中央に置く。もともと正立する字(漢字・かな・全角記号) - はそのまま -- 横倒し指定: もともと倒れる字(欧文・数字・括弧・長音)は従来どおりひとつながりの語に、正立する字(全角の!?、かな) - は1字ずつ倒す。1〜2桁の数字と「!?」は自動で縦中横になる字なので、横倒し指定の中では印を付けて倒す -- 縦中横指定: 自動でならない並び(3桁の数字、「EU」「3.5」)を1マスに正立で入れる。幅が1.5マスを超える並びは - 横倒しのまま。マスの幅を超える分は左右に均等にはみ出す - -**(4) 縦書きの text-indent と天アキ**(`ParsedText.cpp`・`CssParser`・`CssSelectorUsage`): 縦書きの列組みで -明示の `text-indent` を正負とも効かせる。負の値(ぶら下げ)は電書協テンプレートが `padding-top` と対で書くので、 -列の天のずらし(前からあった)が空けた分だけ第1列を上に戻す形になる。対が無い場合は天のずらしの範囲で止める。 -「Extra Paragraph Spacing」ONでも明示の指定は効かせる(横書きの本家実装はONのとき正の明示指定も捨てるが、縦書きの -市販本ではこのクラスが特定の段落だけに付いていて著者の意図があるため。自動の字下げは従来どおりONで無効)。 -天アキ(`margin-top`/`padding-top`)は列の天のずらしとして前から入っていたのに効かなかった原因は、**電書協テンプレートが -これらのクラスを `.vrtl .h-indent-1em`、`.hltr .start-1em` のように html 要素の書字方向クラスを親に付けた二段の指定子で -書いていて、当版の書式解析器が空白を含む指定子を全部捨てていた**こと。テスト19の指定は全部この形で、実物の -テンプレート(1,905規則)では956規則がこの形だった。そこで二段の子孫指定子(`a b`、a・bは要素名/.クラス/要素名.クラス) -を読むようにした。保存は「a b」の1個の空白区切り、照合はパーサが開いている先祖要素の要素名とクラスを積んでおいて -(`ancestorStack`)、要素の書式を引くときに先祖ごとに「先祖 .クラス」「先祖 要素名」「先祖 要素名.クラス」を引く。 -CSSの優先度どおり単段の規則より後に重ねる。章ごとの絞り込み(`CssSelectorUsage`)は二段とも章に現れるときだけ残す。 -書式の保存形式は `CSS_CACHE_VERSION` 12→13(1バイト追加+空白付きの鍵)で、初回オープン時に書式の保存だけ作り直しが走る。 -- 副作用として横書きの本でも `.hltr .h-indent-1em{text-indent:-1em; padding-left:1em}` などが効くようになる(横書きの - ぶら下げは本家の組版がもともと負の text-indent と padding-left を扱える) -- メモリの面: 電書協テンプレートは単段625規則の時点で固有の書式本体が583種と上限256を超えていて、すでに - 「保存は打ち切り、章ごとに絞り込んで読み直す」経路に乗っている。二段の規則が増えても同じ経路のままで、 - 章ごとの絞り込み後の規則数は変わらず少ない - -**(5) span の font-size は見送り。** 当版のフォントは大きさごとに別ファイルの点画像で、同時に読み込むのは1つの -大きさだけ(メモリ)。ルビ・上付きの50%縮小だけが描画にあり、70/90/110/150%の拡縮を足すと点画像の拡縮で字が崩れる。 -もう一つの大きさを読み込む案は空きメモリ(読書中48〜80KB)に対して大きすぎる。既知の制限として残す。 - -**実機での見かた**(`vertical-test-suite.epub` は解説を新しい合格条件に書き換え、テスト18に【縦中横】、テスト21に -【引用・連続】の段落を足した。epubcheck は従来の意図的な不整合のみ): -1. テスト18: 見かた(1)〜(5)。正立の A x 3 & + と →、横倒しの!?ー、縦中横の 100・EU・3.5(1234 は横倒しのままが正) - → **実機で5項目とも合格**(2026-09-06、`2026090613-diag`、NotoSansJP 18pt)。A x 3 & + が1字1マスで正立、→が右向き、!?が横倒し(【比較】側は正立のまま)、100・EU・3.5 が1マスに横並び、1234 は横倒し -2. テスト19: 見かた(1)〜(4)。字下げ1em、ぶら下げ1em/2em(一行目は天から、二行目以降が下がる)、天アキ1em/3em - → **実機で(2)〜(4)合格、(1)は判定保留**(2026-09-06、`2026090613-diag`)。ぶら下げは二行目以降(ページをまたぐ続きの列も)、天アキは全行が指定の文字数分下がり、中央・右揃えは列の位置が変わらない。二段の指定子 `.vrtl .xxx` が読めていることの確認を兼ねる。(1)は【字下げ1em】が一字分下がっているものの、端末の「Extra Paragraph Spacing」がOFFで【基準】にも当版の自動の字下げ(1マス)が入り、差が見えなかった(写真の見直しで判明。仕様どおりで不具合ではない)。テスト書に【字下げ2em】の段落を足し、再確認で **(1)も合格**: 【基準】(自動の1マス)≈【字下げ1em】<【字下げ2em】の順に下がる。なお em の換算は横書きと同じく字面の高さ(18pt NotoSansJP で44px)なので、1em は1マス(38px)より一割ほど深い。実用上の差は小さく、既知の癖として残す -3. テスト21: 見かた(2)。【引用】【引用・連続】で〝が列末・〟が列頭に残っていないこと - → 実機(18pt)では9か所の列の変わり目のどこにも引用符が来ておらず、字形の送り幅からの計算でも引用符が変わり目に掛かる位置に無かったため、**禁則が働いたかは判定できず**。三字ごとに引用符が来る【引用・密】(〝一〟〝二〟…)を足したが、実機では列が18マスで3マスの組が6組ずつ割り切れ、これも変わり目が全部組の境目に落ちて判定できず。そこで組の間に0〜2字のかなを挟み、列の長さが14〜26字のどれでも禁則なしなら必ず二か所以上で違反が出る並びを計算で作って差し替え、**再確認で合格**: 「…〝三〟い」の列と「…ちつ〝丑〟てと」の列がそれぞれ1マス空けて終わり、次の列が〝四〟・〝寅〟で始まる(列末に来るはずの〝が引き取られた形)。全部の列で三字の組が崩れず、列末の〝・列頭の〟は無い。ほかの段落(線・正立記号・収録・異体字・数字)は前回と同じ結果で退行なし -4. 退行確認: テスト17(Kobo形式)が前回と同じこと、商業書籍1冊で会話文のぶら下げ・扉の天アキが崩れていないこと - → **商業書籍1冊(電書協形式、KEPUB)で確認済み**(2026-09-06): 会話文の「」の行は天から、地の文は一字下げ、章扉の挿絵ページと章の最初のページも従来どおりで、二段の指定子が効くようになった副作用は見えない。テスト20(font-size、見送り)は前回と同じ見え方で退行なし +CrossPoint Reader is **not affiliated with Xteink or any device manufacturer**. diff --git a/docs/file-formats.md b/docs/file-formats.md index f3d44bf2607..8e0c4d2529c 100644 --- a/docs/file-formats.md +++ b/docs/file-formats.md @@ -90,13 +90,6 @@ if (parsedSize != fileSize) { ## `section.bin` -### Version 49 - -Version 49 keeps the version 48 serialized layout unchanged. It was bumped -because variation selectors (U+FE00..U+FE0F and U+E0100..U+E01EF) are now -dropped while parsing instead of being laid out as replacement glyphs, so -cached line breaks and word positions from version 48 no longer match. - ### Version 48 Version 48 keeps the version 47 serialized layout unchanged. It was bumped @@ -207,7 +200,7 @@ import std.mem; import std.string; import std.core; -#define EXPECTED_VERSION 49 +#define EXPECTED_VERSION 48 #define MAX_STRING_LENGTH 65535 #define FOOTNOTE_NUMBER_LEN 32 #define FOOTNOTE_HREF_LEN 256 @@ -422,7 +415,7 @@ Written by `lib/LibraryIndex/LibraryBuilder.cpp`, read by `LibraryIndexFile`. On file describing every book on the card, so the shelf can sort and search thousands of titles without opening any of them. -Format version 3. An index written by another version fails validation on open +Format version 2. An index written by another version fails validation on open and is rebuilt; that is the entire migration mechanism. ### Layout @@ -433,7 +426,7 @@ and is rebuilt; that is the entire migration mechanism. | Folders | `folderStart` | length-prefixed paths, one per folder | | Records | `recordStart` | `bookCount` × 128-byte `ClixRecord` | | Permutations | `permStart` | `bookCount` u16 author order, then `bookCount` u16 arrival order | -| Name blob | `nameStart` | per record: path hash, name, canonical author, title, source author, author reading (see below) | +| Name blob | `nameStart` | per record: path hash, name, canonical author, title, source author (see below) | The arrival permutation runs oldest first, keyed by the record's FAT modification time (when the file landed on the card); `firstSeen` — the @@ -441,7 +434,6 @@ build-assigned discovery counter — breaks ties and carries books whose filesystem reports no time. Fold version 3 introduced the timestamp key; a fold bump rebuilds ranks while preserving `firstSeen`. Fold version 4 preserves leading articles in title sort and search keys. -Fold version 5 folds a book's `file-as` reading where it carries one (see below). Sections are 512-byte aligned so each starts on an SD block boundary. @@ -456,22 +448,6 @@ the author's words folded and sorted so that "Victor Hugo" and "Hugo Victor" gro one person. `authorKey` is a GROUPING key, not an ordering one: the shelf orders by surname, derived separately from the display name. -A book that carries sort forms in its package metadata (EPUB 3 `file-as`, or -EPUB 2 `opf:file-as`) is folded from those instead of its display strings. For -Japanese that is the kana reading, the only way to order a 漢字 title; the fold -maps katakana to hiragana and fullwidth ASCII to ASCII so either spelling gives -one key, and the group initial of a kana fold is the head of its gojūon row -(が → か). An author reading keys the group in the publisher's own order, -family name first, and orders the shelf in place of the surname guess. - -`authorKey` and the phase-local sort keys hold the fold in `packSortKey()` byte -form: ASCII and every non-Japanese script keep their UTF-8 bytes, hiragana packs -to one byte each at `0x80 + (cp - 0x3040)`, so twelve bytes hold twelve kana -instead of four and kana sort after Latin. Titles whose packed prefixes tie are -ordered by their full folds, read back from the stage for those runs only -(one checked 6,336-byte allocation; a run longer than 64 keeps walk order), so -the volumes of a series come out in order. - The byte before the folded title records metadata extraction status: not attempted, extracted, or failed. The final four bytes contain the packed FAT modification date and time returned by SdFat. A zero timestamp is not trusted. @@ -492,13 +468,8 @@ Per record, at `nameStart + nameOff`: [u8][author] display author, one spelling chosen per authorKey across the library [u8][title] the book's own title, or length 0 if it never gave one [u8][source] cleaned author spelling before the library-wide spelling vote -[u8][reading] folded file-as reading of the author, or length 0 if it gave none ``` -The reading is stored so an unchanged rebuild can reproduce the author order -without opening the book again; it is folded already because only its fold is -ever compared. - The filename must stay the first textual field and stay the filename: `readPath` rebuilds a book's path from it, so writing the display title there makes the book impossible to open. That was a real defect, and it is why title has its own field. diff --git a/src/images/ClockDigits.h b/src/images/ClockDigits.h deleted file mode 100644 index 7225941b745..00000000000 --- a/src/images/ClockDigits.h +++ /dev/null @@ -1,1312 +0,0 @@ -#pragma once -#include - -// Generated by scripts/build_clock_digits.py -- do not edit. -// font=DejaVuSans-Bold.ttf large=150 small=56 rotate=0 -// -// Clock mode's glyphs, drawn with GfxRenderer::drawImage rather than a font: the -// timer-wake path never mounts the SD card, and the built-in fonts stop at 18 pt. -// The rotation is baked in because drawImage rotates the origin but not the bits. - -// Order matches ClockGlyph in ClockFace.h. - -#define CLOCKLARGE_WIDTH 91 -#define CLOCKLARGE_HEIGHT 125 -// Unrotated cell, for laying the face out in logical coordinates. -#define CLOCKLARGE_CELL_W 91 -#define CLOCKLARGE_CELL_H 125 - -// ClockLargeDigit0: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit0[] = { - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, - 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, - 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, - 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x7f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x80, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, - 0x00, 0x7f, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, - 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, - 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, - 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x0f, 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, 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, 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, -}; - -// ClockLargeDigit1: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit1[] = { - 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, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 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, 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, 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, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockLargeDigit2: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit2[] = { - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xfc, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, - 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x03, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 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, 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, 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, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockLargeDigit3: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit3[] = { - 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0x80, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf1, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 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, 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, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockLargeDigit4: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit4[] = { - 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, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x1f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, - 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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, 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, 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, -}; - -// ClockLargeDigit5: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit5[] = { - 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, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 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, 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, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockLargeDigit6: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit6[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xbf, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, - 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, - 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x03, 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, 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, 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, -}; - -// ClockLargeDigit7: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit7[] = { - 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 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, 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, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockLargeDigit8: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit8[] = { - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, - 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, - 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, - 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, - 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0f, - 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xf0, - 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0x01, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, - 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xe0, - 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, - 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, - 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x01, 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, 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, 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, -}; - -// ClockLargeDigit9: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeDigit9[] = { - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, - 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xe0, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, - 0x01, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, - 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, - 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, - 0x7f, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xe0, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x87, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x03, 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, 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, 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, -}; - -// ClockLargeColon: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeColon[] = { - 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, 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, 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, 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, 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, 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, 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, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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, 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, 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, -}; - -// ClockLargeSlash: 91x125, 1bpp MSB-first, 0 = black -static const uint8_t ClockLargeSlash[] = { - 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, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// Indexed by ClockGlyph. Every cell is 91x125, so the face advances a fixed pitch. -static const uint8_t* const ClockLargeGlyphs[] = { - ClockLargeDigit0, ClockLargeDigit1, ClockLargeDigit2, ClockLargeDigit3, ClockLargeDigit4, ClockLargeDigit5, - ClockLargeDigit6, ClockLargeDigit7, ClockLargeDigit8, ClockLargeDigit9, ClockLargeColon, ClockLargeSlash, -}; - -#define CLOCKSMALL_WIDTH 34 -#define CLOCKSMALL_HEIGHT 47 -// Unrotated cell, for laying the face out in logical coordinates. -#define CLOCKSMALL_CELL_W 34 -#define CLOCKSMALL_CELL_H 47 - -// ClockSmallDigit0: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit0[] = { - 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x0f, - 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x01, 0xe0, - 0x01, 0xff, 0xe0, 0x07, 0xf8, 0x01, 0xff, 0xc0, 0x07, 0xf8, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0x80, 0x0f, - 0xfc, 0x00, 0x7f, 0x80, 0x0f, 0xfc, 0x00, 0x7f, 0x80, 0x0f, 0xfc, 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x00, - 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, - 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, - 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x00, 0x1f, 0xfe, - 0x00, 0x3f, 0x00, 0x1f, 0xfe, 0x00, 0x3f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x0f, 0xfc, 0x00, 0x7f, 0x80, 0x0f, - 0xfc, 0x00, 0x7f, 0x80, 0x0f, 0xfc, 0x00, 0x7f, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0xc0, 0x07, 0xf8, 0x00, 0xff, 0xe0, - 0x07, 0xf8, 0x01, 0xff, 0xe0, 0x01, 0xe0, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x07, 0xff, - 0xf8, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0xff, - 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit1: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit1[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, - 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x03, - 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x30, 0x03, 0xff, 0xff, 0xc7, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, - 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, - 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, - 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, - 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xe0, - 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, - 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, - 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, -}; - -// ClockSmallDigit2: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit2[] = { - 0xff, 0x80, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x0f, - 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x3f, 0x80, - 0x01, 0xff, 0xc1, 0xff, 0xe0, 0x01, 0xff, 0xc7, 0xff, 0xf0, 0x00, 0xff, 0xdf, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, - 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, - 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x1f, - 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x03, - 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x00, - 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xc0, 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, 0xff, -}; - -// ClockSmallDigit3: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit3[] = { - 0xfe, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x0f, - 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0xff, 0x00, - 0x01, 0xff, 0xef, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, - 0xf0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, - 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x07, - 0xff, 0xff, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xf0, - 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xbf, 0xff, 0xf0, 0x00, 0xff, 0x8f, - 0xff, 0xe0, 0x01, 0xff, 0x80, 0xff, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, - 0x80, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0xff, - 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit4: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit4[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x00, 0x0f, - 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, - 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0x80, - 0x40, 0x0f, 0xff, 0xff, 0x80, 0xc0, 0x0f, 0xff, 0xff, 0x00, 0xc0, 0x0f, 0xff, 0xfe, 0x01, 0xc0, 0x0f, 0xff, 0xfe, - 0x03, 0xc0, 0x0f, 0xff, 0xfc, 0x03, 0xc0, 0x0f, 0xff, 0xf8, 0x07, 0xc0, 0x0f, 0xff, 0xf8, 0x0f, 0xc0, 0x0f, 0xff, - 0xf0, 0x0f, 0xc0, 0x0f, 0xff, 0xe0, 0x1f, 0xc0, 0x0f, 0xff, 0xe0, 0x3f, 0xc0, 0x0f, 0xff, 0xc0, 0x3f, 0xc0, 0x0f, - 0xff, 0xc0, 0x7f, 0xc0, 0x0f, 0xff, 0x80, 0xff, 0xc0, 0x0f, 0xff, 0x00, 0xff, 0xc0, 0x0f, 0xff, 0x01, 0xff, 0xc0, - 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, - 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, - 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, -}; - -// ClockSmallDigit5: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit5[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, - 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, - 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x1f, - 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xe0, - 0x10, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, - 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0xff, 0x00, 0x01, - 0xff, 0xe7, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xf8, - 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xbf, 0xff, 0xf0, 0x00, 0xff, 0x8f, 0xff, 0xe0, 0x01, 0xff, 0x83, - 0xff, 0xc0, 0x01, 0xff, 0x80, 0x7f, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, - 0x80, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit6: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit6[] = { - 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x03, - 0xff, 0xfe, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x3f, - 0x83, 0xff, 0xf0, 0x01, 0xff, 0xfb, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x07, - 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0x1f, 0x00, 0xff, 0xff, 0x80, 0x18, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, - 0x80, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0x80, 0x01, 0xf0, 0x00, - 0xff, 0x80, 0x03, 0xf8, 0x00, 0xff, 0x80, 0x07, 0xfc, 0x00, 0x7f, 0x80, 0x07, 0xfc, 0x00, 0x7f, 0x80, 0x0f, 0xfe, - 0x00, 0x7f, 0x80, 0x0f, 0xfe, 0x00, 0x7f, 0x80, 0x0f, 0xfe, 0x00, 0x7f, 0xc0, 0x0f, 0xfe, 0x00, 0x7f, 0xc0, 0x0f, - 0xfe, 0x00, 0x7f, 0xc0, 0x0f, 0xfe, 0x00, 0x7f, 0xe0, 0x07, 0xfc, 0x00, 0x7f, 0xe0, 0x07, 0xfc, 0x00, 0xff, 0xe0, - 0x03, 0xf8, 0x00, 0xff, 0xf0, 0x01, 0xf0, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, - 0xfc, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x7f, - 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit7: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit7[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, - 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, - 0x00, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, - 0xf0, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, - 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x7f, - 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x01, - 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xe0, - 0x07, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, - 0x80, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, - 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xfc, 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, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit8: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit8[] = { - 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x07, - 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x03, 0xf0, - 0x00, 0xff, 0xc0, 0x07, 0xf8, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0xc0, 0x0f, - 0xfc, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0xe0, 0x07, 0xf8, 0x01, 0xff, 0xf0, - 0x03, 0xf0, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0x80, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x03, - 0xff, 0xe0, 0x03, 0xf0, 0x01, 0xff, 0xc0, 0x07, 0xf8, 0x00, 0xff, 0xc0, 0x0f, 0xfc, 0x00, 0xff, 0x80, 0x1f, 0xfe, - 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x1f, - 0xfe, 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x1f, 0xfe, 0x00, 0x7f, 0x80, 0x0f, 0xfc, 0x00, 0x7f, 0xc0, - 0x07, 0xf8, 0x00, 0xff, 0xc0, 0x03, 0xf0, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, - 0xf0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallDigit9: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallDigit9[] = { - 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x1f, - 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x03, 0xe0, - 0x03, 0xff, 0xc0, 0x07, 0xf0, 0x01, 0xff, 0xc0, 0x0f, 0xf8, 0x01, 0xff, 0x80, 0x1f, 0xf8, 0x01, 0xff, 0x80, 0x1f, - 0xfc, 0x00, 0xff, 0x80, 0x1f, 0xfc, 0x00, 0xff, 0x80, 0x1f, 0xfc, 0x00, 0xff, 0x80, 0x1f, 0xfc, 0x00, 0xff, 0x80, - 0x1f, 0xfc, 0x00, 0x7f, 0x80, 0x1f, 0xfc, 0x00, 0x7f, 0x80, 0x0f, 0xf8, 0x00, 0x7f, 0x80, 0x0f, 0xf8, 0x00, 0x7f, - 0xc0, 0x07, 0xf0, 0x00, 0x7f, 0xc0, 0x03, 0xe0, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, - 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x06, - 0x00, 0x7f, 0xff, 0xc0, 0x3e, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, - 0xfc, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xf7, - 0xff, 0xe0, 0x03, 0xff, 0xf0, 0x7f, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, - 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, - 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockSmallColon: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallColon[] = { - 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, - 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, - 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 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, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, - 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, - 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x03, 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, -}; - -// ClockSmallSlash: 34x47, 1bpp MSB-first, 0 = black -static const uint8_t ClockSmallSlash[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x3f, - 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xe0, - 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, - 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, - 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0xff, - 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x1f, - 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xf0, - 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, - 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, - 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, - 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, -}; - -// Indexed by ClockGlyph. Every cell is 34x47, so the face advances a fixed pitch. -static const uint8_t* const ClockSmallGlyphs[] = { - ClockSmallDigit0, ClockSmallDigit1, ClockSmallDigit2, ClockSmallDigit3, ClockSmallDigit4, ClockSmallDigit5, - ClockSmallDigit6, ClockSmallDigit7, ClockSmallDigit8, ClockSmallDigit9, ClockSmallColon, ClockSmallSlash, -}; - -// --- 12-hour AM/PM markers --- -// Same generator, appended later (freetype's mono hinting differs across -// versions, so regenerating the digit sets above would have subtly changed -// the already-verified 24-hour face; only this set was taken from the rerun). -// font=DejaVuSans-Bold.ttf size=56 rotate=0, glyph order: A, P, M. - -// Rows below the baseline in each set's cell (the generator now emits these; -// added here by hand because the digit sets above are kept byte-identical). -// '/' descends 14px at 150px and 5px at 56px; A/P/M sit on the baseline. -#define CLOCKLARGE_DESCENT 14 -#define CLOCKSMALL_DESCENT 5 -#define CLOCKAMPM_DESCENT 0 - -#define CLOCKAMPM_WIDTH 45 -#define CLOCKAMPM_HEIGHT 41 -// Unrotated cell, for laying the face out in logical coordinates. -#define CLOCKAMPM_CELL_W 45 -#define CLOCKAMPM_CELL_H 41 - -// ClockAmPmLetterA: 45x41, 1bpp MSB-first, 0 = black -static const uint8_t ClockAmPmLetterA[] = { - 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xf0, 0x02, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x02, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x02, 0x00, - 0x7f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x07, 0x80, 0x1f, - 0xff, 0xff, 0xc0, 0x0f, 0x80, 0x1f, 0xff, 0xff, 0xc0, 0x0f, 0x80, 0x1f, 0xff, 0xff, 0x80, 0x1f, 0xc0, 0x0f, 0xff, - 0xff, 0x80, 0x1f, 0xc0, 0x0f, 0xff, 0xff, 0x80, 0x1f, 0xc0, 0x0f, 0xff, 0xff, 0x00, 0x3f, 0xe0, 0x07, 0xff, 0xff, - 0x00, 0x3f, 0xe0, 0x07, 0xff, 0xfe, 0x00, 0x3f, 0xe0, 0x03, 0xff, 0xfe, 0x00, 0x7f, 0xf0, 0x03, 0xff, 0xfe, 0x00, - 0x7f, 0xf0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x03, 0xff, 0xfe, 0x00, - 0x3f, 0xe0, 0x03, 0xff, 0xfe, 0x00, 0x3f, 0xe0, 0x07, 0xff, 0xff, 0x00, 0x3f, 0xc0, 0x07, 0xff, 0xff, 0x00, 0x1f, - 0xc0, 0x07, 0xff, 0xff, 0x00, 0x1f, 0xc0, 0x0f, 0xff, 0xff, 0x80, 0x1f, 0x80, 0x0f, 0xff, 0xff, 0x80, 0x0f, -}; - -// ClockAmPmLetterP: 45x41, 1bpp MSB-first, 0 = black -static const uint8_t ClockAmPmLetterP[] = { - 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0xff, 0x80, 0x03, 0xff, 0xf8, 0x00, 0xff, - 0xc0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xe0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xf0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xf0, - 0x01, 0xff, 0xf8, 0x00, 0xff, 0xf0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xf0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xf0, 0x01, - 0xff, 0xf8, 0x00, 0xff, 0xe0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0xc0, 0x01, 0xff, 0xf8, 0x00, 0xff, 0x80, 0x03, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, -}; - -// ClockAmPmLetterM: 45x41, 1bpp MSB-first, 0 = black -static const uint8_t ClockAmPmLetterM[] = { - 0x00, 0x03, 0xff, 0xfe, 0x00, 0x07, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x07, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x07, 0x00, - 0x01, 0xff, 0xfc, 0x00, 0x07, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x07, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x07, 0x00, 0x00, - 0xff, 0xf8, 0x00, 0x07, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x07, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x07, 0x00, 0x00, 0x7f, - 0xf0, 0x00, 0x07, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x07, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x07, 0x00, 0x20, 0x1f, 0xc0, - 0x20, 0x07, 0x00, 0x20, 0x1f, 0xc0, 0x20, 0x07, 0x00, 0x20, 0x1f, 0xc0, 0x20, 0x07, 0x00, 0x30, 0x0f, 0x80, 0x60, - 0x07, 0x00, 0x30, 0x0f, 0x80, 0x60, 0x07, 0x00, 0x38, 0x07, 0x00, 0xe0, 0x07, 0x00, 0x38, 0x07, 0x00, 0xe0, 0x07, - 0x00, 0x3c, 0x06, 0x01, 0xe0, 0x07, 0x00, 0x3c, 0x02, 0x01, 0xe0, 0x07, 0x00, 0x3c, 0x02, 0x01, 0xe0, 0x07, 0x00, - 0x3e, 0x00, 0x03, 0xe0, 0x07, 0x00, 0x3e, 0x00, 0x03, 0xe0, 0x07, 0x00, 0x3f, 0x00, 0x07, 0xe0, 0x07, 0x00, 0x3f, - 0x00, 0x07, 0xe0, 0x07, 0x00, 0x3f, 0x80, 0x07, 0xe0, 0x07, 0x00, 0x3f, 0x80, 0x0f, 0xe0, 0x07, 0x00, 0x3f, 0x80, - 0x0f, 0xe0, 0x07, 0x00, 0x3f, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x3f, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x3f, 0xe0, 0x3f, - 0xe0, 0x07, 0x00, 0x3f, 0xe0, 0x3f, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, - 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, - 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, -}; - -// Indexed by ClockGlyph. Every cell is 45x41, so the face advances a fixed pitch. -static const uint8_t* const ClockAmPmGlyphs[] = { - ClockAmPmLetterA, - ClockAmPmLetterP, - ClockAmPmLetterM, -}; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bab07c15908..184721f52db 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,7 +54,6 @@ add_subdirectory(combining_marks) add_subdirectory(credential_integrity) add_subdirectory(xml_parser_utils) add_subdirectory(token_boundary) -add_subdirectory(cjk_line_break) add_subdirectory(koreader_xpath_resolver) add_subdirectory(progress_comparison) add_subdirectory(font_cache_manager) diff --git a/test/cjk_line_break/CMakeLists.txt b/test/cjk_line_break/CMakeLists.txt deleted file mode 100644 index 93c0b82fb50..00000000000 --- a/test/cjk_line_break/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_executable(CjkLineBreakTest - CjkLineBreakTest.cpp -) - -target_include_directories(CjkLineBreakTest PRIVATE - ${REPO_ROOT}/lib/Utf8 - ${REPO_ROOT}/lib/Epub/Epub -) - -target_link_libraries(CjkLineBreakTest PRIVATE - crosspoint_test_common - GTest::gtest_main -) - -gtest_discover_tests(CjkLineBreakTest) diff --git a/test/library_format/LibraryFormatTest.cpp b/test/library_format/LibraryFormatTest.cpp index 2a67dbf0444..e233eda65c0 100644 --- a/test/library_format/LibraryFormatTest.cpp +++ b/test/library_format/LibraryFormatTest.cpp @@ -30,7 +30,7 @@ TEST(LibraryFormat, StructSizesAreFrozen) { EXPECT_EQ(sizeof(ClixHeader), 64u); EXPECT_EQ(sizeof(ClixRecord), 128u); EXPECT_EQ(sizeof(ClixFolderHeader), 1u); - EXPECT_EQ(CLIX_FORMAT_VERSION, 3u); + EXPECT_EQ(CLIX_FORMAT_VERSION, 2u); } TEST(LibraryFormat, RecordsTileSectorsExactly) { diff --git a/test/library_index_file/LibraryIndexFileTest.cpp b/test/library_index_file/LibraryIndexFileTest.cpp index 035ca63ec4e..abf7b19383f 100644 --- a/test/library_index_file/LibraryIndexFileTest.cpp +++ b/test/library_index_file/LibraryIndexFileTest.cpp @@ -139,8 +139,7 @@ TEST(LibraryIndexFile, ReadsPathHashAndEveryPublicBlobField) { header.bookCount = 1; const uint8_t folder[] = {6, '/', 'b', 'o', 'o', 'k', 's'}; constexpr uint64_t PATH_HASH = 0x0123456789ABCDEFULL; - const auto blob = - makeBlob(PATH_HASH, {'x', 1, 'a', 1, 't', 8, 'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l', 4, 'y', 'a', 'm', 'a'}); + const auto blob = makeBlob(PATH_HASH, {'x', 1, 'a', 1, 't', 8, 'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l'}); header.folderCount = 1; library::layoutSections(header, sizeof(folder), blob.size()); std::vector bytes(header.selfSize, 0); @@ -167,9 +166,6 @@ TEST(LibraryIndexFile, ReadsPathHashAndEveryPublicBlobField) { EXPECT_EQ(title, "t"); ASSERT_TRUE(index.readSourceAuthor(record, author)); EXPECT_EQ(author, "Original"); - std::string reading; - ASSERT_TRUE(index.readAuthorReading(record, reading)); - EXPECT_EQ(reading, "yama"); std::string path; ASSERT_TRUE(index.readPath(record, path)); EXPECT_EQ(path, "/books/x");