Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch: Activities (migrated to new ActivityManager pattern): - Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity - Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity, DictionaryWordSelectActivity, LookedUpWordsActivity - Bookmark: EpubReaderBookmarkSelectionActivity - Book management: BookManageMenuActivity, EndOfBookMenuActivity - OPDS: OpdsServerListActivity, OpdsSettingsActivity - Utility: DirectoryPickerActivity, NumericStepperActivity Utilities (unchanged): - BookManager, BookSettings, BookmarkStore, BootNtpSync - Dictionary, LookupHistory, TimeSync, OpdsServerStore Libraries: PlaceholderCover, TableData, ChapterXPathIndexer Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover Docs: KOReader sync XPath mapping Migration changes: - ActivityWithSubactivity -> Activity base class - Callback constructors -> finish()/setResult() pattern - enterNewActivity() -> startActivityForResult() - Activity::RenderLock&& -> RenderLock&& These files won't compile yet - they reference mod settings and I18n strings that will be added in subsequent phases. Made-with: Cursor
60 lines
4.0 KiB
Markdown
60 lines
4.0 KiB
Markdown
# Sleep Screen Tweaks Implementation
|
|
|
|
## Task Description
|
|
Implemented the two "Sleep Screen tweaks" from the plan:
|
|
1. **Gradient fill for letterboxed areas** - When a sleep screen image doesn't match the display's aspect ratio, the void (letterbox) areas are now filled with a dithered gradient sampled from the nearest ~20 pixels of the image's edge, fading toward white.
|
|
2. **Fix "Fit" mode for small images** - Images smaller than the 480x800 display are now scaled up (nearest-neighbor) to fit while preserving aspect ratio, instead of being displayed at native size with wasted screen space.
|
|
|
|
## Changes Made
|
|
|
|
### `lib/GfxRenderer/GfxRenderer.cpp`
|
|
- Modified `drawBitmap()` scaling logic: when both `maxWidth` and `maxHeight` are provided, always computes an aspect-ratio-preserving scale factor (supports both upscaling and downscaling)
|
|
- Modified `drawBitmap()` rendering loop: uses block-fill approach where each source pixel maps to a screen rectangle (handles both upscaling blocks and 1:1/downscaling single pixels via a unified loop)
|
|
- Applied same changes to `drawBitmap1Bit()` for 1-bit bitmap consistency
|
|
- Added `drawPixelGray()` method: draws a pixel using its 2-bit grayscale value, dispatching correctly based on the current render mode (BW, GRAYSCALE_LSB, GRAYSCALE_MSB)
|
|
|
|
### `lib/GfxRenderer/GfxRenderer.h`
|
|
- Added `drawPixelGray(int x, int y, uint8_t val2bit)` declaration
|
|
|
|
### `lib/GfxRenderer/BitmapHelpers.cpp`
|
|
- Added `quantizeNoiseDither()`: hash-based noise dithering that always uses noise (unlike `quantize()` which is controlled by a compile-time flag), used for smooth gradient rendering on the 4-level display
|
|
|
|
### `lib/GfxRenderer/BitmapHelpers.h`
|
|
- Added `quantizeNoiseDither()` declaration
|
|
|
|
### `src/activities/boot_sleep/SleepActivity.cpp`
|
|
- Removed the `if (bitmap.getWidth() > pageWidth || bitmap.getHeight() > pageHeight)` gate in `renderBitmapSleepScreen()` — position/scale is now always computed regardless of whether the image is larger or smaller than the screen
|
|
- Added anonymous namespace with:
|
|
- `LetterboxGradientData` struct for edge sample storage
|
|
- `sampleBitmapEdges()`: reads bitmap row-by-row to sample per-column (or per-row) average gray values from the first/last 20 pixels of the image edges
|
|
- `drawLetterboxGradients()`: draws dithered gradients in letterbox areas using sampled edge colors, interpolating toward white
|
|
- Integrated gradient rendering into the sleep screen flow: edge sampling (first pass), then gradient + bitmap rendering in BW pass, and again in each grayscale pass (LSB, MSB)
|
|
|
|
## Follow-up: Letterbox Fill Settings
|
|
|
|
Added three letterbox fill options and two new persisted settings:
|
|
|
|
### `src/CrossPointSettings.h`
|
|
- Added `SLEEP_SCREEN_LETTERBOX_FILL` enum: `LETTERBOX_NONE` (plain white), `LETTERBOX_GRADIENT` (default), `LETTERBOX_SOLID`
|
|
- Added `SLEEP_SCREEN_GRADIENT_DIR` enum: `GRADIENT_TO_WHITE` (default), `GRADIENT_TO_BLACK`
|
|
- Added `sleepScreenLetterboxFill` and `sleepScreenGradientDir` member fields
|
|
|
|
### `src/CrossPointSettings.cpp`
|
|
- Incremented `SETTINGS_COUNT` to 32
|
|
- Added serialization (read/write) for the two new fields at the end for backward compatibility
|
|
|
|
### `src/SettingsList.h`
|
|
- Added "Letterbox Fill" menu entry (None / Gradient / Solid) in Display category
|
|
- Added "Gradient Direction" menu entry (To White / To Black) in Display category
|
|
|
|
### `src/activities/boot_sleep/SleepActivity.cpp`
|
|
- Renamed `drawLetterboxGradients` → `drawLetterboxFill` with added `solidFill` and `targetColor` parameters
|
|
- Solid mode: uses edge color directly (no distance-based interpolation), quantized with noise dithering
|
|
- Gradient direction: interpolates from edge color toward `targetColor` (255 for white, 0 for black)
|
|
- `renderBitmapSleepScreen` reads the settings and skips edge sampling entirely when fill mode is "None"
|
|
|
|
## Follow-up Items
|
|
- Test with various cover image sizes and aspect ratios on actual hardware
|
|
- Test custom images from `/sleep/` directory (1-bit and multi-bit)
|
|
- Monitor RAM usage via serial during gradient rendering
|