# Revert Letterbox Fill to Dithered / Solid / None (with edge cache) **Date:** 2026-02-13 ## Task Reverted letterbox fill modes from None/Solid/Extend Edges back to Dithered (default)/Solid/None per user request. Restored Bayer ordered dithering for "Dithered" mode and re-introduced edge average caching to avoid recomputing on every sleep. ## Changes Made ### `src/CrossPointSettings.h` - Reordered enum: `LETTERBOX_DITHERED=0`, `LETTERBOX_SOLID=1`, `LETTERBOX_NONE=2` - Changed default from `LETTERBOX_NONE` to `LETTERBOX_DITHERED` ### `src/SettingsList.h` - Updated UI labels from `{"None", "Solid", "Extend Edges"}` to `{"Dithered", "Solid", "None"}` ### `src/activities/boot_sleep/SleepActivity.h` - Added `#include ` - Restored `edgeCachePath` parameter to `renderBitmapSleepScreen()` ### `src/activities/boot_sleep/SleepActivity.cpp` - **Removed**: `getPackedPixel()`, `setPackedPixel()`, all EXTENDED-mode logic, `freeEdgeData()`, per-pixel edge arrays - **Simplified** `LetterboxFillData` to just `avgA`, `avgB`, `letterboxA`, `letterboxB`, `horizontal`, `valid` - **Restored** `BAYER_4X4[4][4]` matrix and `quantizeBayerDither()` function - **Renamed** `computeEdgeData()` → `computeEdgeAverages()` (averages-only, no edge pixel capture) - **Added** edge average cache: `loadEdgeCache()` / `saveEdgeCache()` (~12 byte binary file per cover) - **Updated** `drawLetterboxFill()`: DITHERED uses Bayer dithering, SOLID uses snap-to-level - **Updated** `renderBitmapSleepScreen()`: accepts `edgeCachePath`, tries cache before computing - **Updated** `renderCoverSleepScreen()`: derives `edgeCachePath` from cover BMP path (`_edges.bin`) ## Build Compilation succeeds (ESP32-C3 target, PlatformIO). ## Follow-up - The specific "The World in a Grain" cover still has rendering issues with dithered mode — to be investigated separately - Custom sleep BMPs (`/sleep/` directory, `/sleep.bmp`) intentionally skip caching since the selected BMP can change each sleep