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

4.0 KiB

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 drawLetterboxGradientsdrawLetterboxFill 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