Files
crosspoint-reader-mod/chat-summaries/2026-02-09_04-43-summary.md
cottongin dfbc931c14 mod: Phase 1 - bring forward mod-exclusive files with ActivityManager migration
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
2026-03-07 15:10:00 -05:00

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