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
4.3 KiB
4.3 KiB
feat: Sleep screen letterbox fill and image upscaling
Branch: mod/sleep-screen-tweaks
Summary
-
What is the goal of this PR? Improve the sleep screen experience for cover images that don't match the display's aspect ratio, and fix Fit mode for images smaller than the screen.
-
What changes are included?
- Configurable letterbox fill for sleep screen cover images. Four fill modes:
- Solid — computes the dominant (average) shade from the image edge and fills the entire letterbox area with that single dithered color.
- Blended — fills using per-pixel sampled edge colors with noise dithering (no distance-based interpolation), producing a smooth edge-matching fill that varies along the image border.
- Gradient — interpolates per-pixel edge colors toward a configurable target color (white or black) over distance, creating a fade effect.
- None — plain white letterbox (original behavior).
- Image upscaling in Fit mode: images smaller than the display are now scaled up to fit while preserving aspect ratio. Previously, small images were simply centered without scaling.
- Edge data caching: the edge-sampling pass (which reads the full bitmap) is performed once per cover and cached as a compact binary file (~1KB) alongside the cover BMP in
.crosspoint/. Subsequent sleeps load from cache, skipping the bitmap scan entirely. Cache is validated against screen dimensions and auto-regenerated when stale. - Two new user-facing settings:
- Letterbox Fill — None / Solid / Blended / Gradient
- Gradient Direction — To White / To Black
- Configurable letterbox fill for sleep screen cover images. Four fill modes:
Files Changed
| File | Change |
|---|---|
lib/GfxRenderer/GfxRenderer.cpp |
Unified block-fill scaling in drawBitmap/drawBitmap1Bit supporting both upscaling and downscaling; added drawPixelGray helper |
lib/GfxRenderer/GfxRenderer.h |
drawPixelGray declaration |
lib/GfxRenderer/BitmapHelpers.cpp |
Added quantizeNoiseDither — hash-based noise dithering for gradient/solid fills |
lib/GfxRenderer/BitmapHelpers.h |
quantizeNoiseDither declaration |
src/activities/boot_sleep/SleepActivity.cpp |
Edge sampling (sampleBitmapEdges), letterbox fill rendering (drawLetterboxFill), edge data cache (loadEdgeCache/saveEdgeCache), integration in renderBitmapSleepScreen/renderCoverSleepScreen; unconditional aspect-ratio scaling for Fit mode |
src/activities/boot_sleep/SleepActivity.h |
Updated renderBitmapSleepScreen signature with optional edgeCachePath parameter |
src/CrossPointSettings.h |
New enums SLEEP_SCREEN_LETTERBOX_FILL (4 values) and SLEEP_SCREEN_GRADIENT_DIR; new fields sleepScreenLetterboxFill, sleepScreenGradientDir |
src/CrossPointSettings.cpp |
Serialization of new settings fields (incremented SETTINGS_COUNT) |
src/SettingsList.h |
New "Letterbox Fill" and "Gradient Direction" setting entries in Display category |
Additional Context
- Performance: The edge sampling pass reads the full bitmap row-by-row (~48KB for a full-screen 2-bit image). This is done once per cover image and cached. Subsequent sleeps for the same cover skip this pass entirely, loading ~1KB from the cache file instead.
- Memory: Edge sampling uses temporary
uint32_taccumulator arrays (~10KB peak) which are freed immediately after processing. Final edge data arrays (~1.6KB max) persist only for the duration of rendering. The cache file is ~970 bytes for a 480-wide image. - Upscaling approach: Nearest-neighbor via block-fill — each source pixel maps to a rectangle of destination pixels. No interpolation, which is appropriate for the 4-level grayscale e-ink display.
- Cache invalidation: Validated by cache version byte and screen dimensions (width × height). Orientation changes trigger regeneration. Each cover mode (Fit vs Crop) produces a different BMP and thus a different cache path. Cache files live in the book-specific
.crosspoint/epub_<hash>/directory and are naturally scoped per-book. - Potential risks: The
drawBitmap/drawBitmap1Bitscaling refactor affects all bitmap rendering, not just sleep screens. The logic is functionally equivalent for downscaling (≤1.0) and 1:1 cases; upscaling (>1.0) is new behavior only triggered when bothmaxWidthandmaxHeightare provided.
AI Usage
Did you use AI tools to help write this code? YES