Add cover image display in *Continue Reading* card with framebuffer caching#200
Conversation
Display book cover image as background in the Continue Reading card on the home screen, improving visual identification of the current book. Key changes: - Add thumbnail generation (thumb.bmp) for EPUB and XTC/XTCH files - Uses same dithering/scaling algorithms as sleep screen covers - Target size: 240x400 (half screen) for optimal Continue Reading card fit - Add JpegToBmpConverter::jpegFileToBmpStreamWithSize() for custom target sizes - Add GfxRenderer::copyStoredBwBuffer() and freeStoredBwBuffer() for framebuffer caching to maintain fast navigation performance - Add UTF-8 safe string truncation for Korean/CJK text in title/author display - Draw white boxes behind title/author text for readability over cover image - Increase HomeActivityTask stack size to 4096 for cover image rendering - Add bounds checking in XTC thumbnail generation to prevent buffer overflow
1179640 to
6fbdd06
Compare
|
This PR hopefully closes #179 |
|
In order to keep the home screen rendering quick, I think we should be generating a 1-bit bmp to avoid having to do gray passes on the home screen. There's some existing implementation in this PR: #108 As it currently stands, this PR prepares a 2-bit bmp but renders all grays as black, so images are overly dark. Additionally, there seems to be an initialization issue as when I first land on the home screen, there's a bookmark icon on the cover, but after navigating down and up, it switched back to the expected border. |
- Add 1-bit BMP generation with Atkinson dithering for better quality thumbnails - Replace noise dithering with error diffusion for smoother gradients - Add fillPolygon() to GfxRenderer for proper bookmark ribbon shape - Change bookmark from rect+triangle carve to pentagon polygon - Fix bookmark inversion when Continue Reading card is selected - Show selection state on first render (not just after navigation) - Fix 1-bit BMP palette lookup in Bitmap::readRow() - Add drawBitmap1Bit() optimized path for 1-bit BMPs The 1-bit format eliminates gray passes on home screen for faster rendering while Atkinson dithering maintains good image quality through error diffusion.
I've addressed all the issues:
Changed from 2-bit to true 1-bit BMP format for thumbnails
Replaced the rect + triangle "carve out" approach with a proper polygon (pentagon shape)
Selection state (border + inverted bookmark) is now shown on first render, not just after navigation
Fixed 1-bit BMP palette lookup in The home screen now renders without gray passes while maintaining good image quality through Atkinson error diffusion dithering. |
src/activities/home/HomeActivity.cpp
Outdated
| // Draw bookmark ribbon (white normally, will be inverted if selected) | ||
| renderer.fillPolygon(xPoints, yPoints, 5, false); | ||
|
|
||
| // Store the buffer with cover image AND bookmark for fast navigation | ||
| coverBufferStored = renderer.storeBwBuffer(); | ||
| coverRendered = true; | ||
|
|
||
| // First render: if selected, draw selection indicators now | ||
| if (bookSelected) { | ||
| renderer.drawRect(bookX + 1, bookY + 1, bookWidth - 2, bookHeight - 2); | ||
| renderer.drawRect(bookX + 2, bookY + 2, bookWidth - 4, bookHeight - 4); | ||
| // Invert bookmark to black | ||
| renderer.fillPolygon(xPoints, yPoints, 5, true); | ||
| } |
There was a problem hiding this comment.
Sorry maybe the feedback was bad, but we want to be doing the opposite here, if we've shown a cover, we can omit the bookmark icon as it's not adding anything and just covering the art. If there's no cover, then we should show the bookmark as an additional visual flair.
Currently we show the bookmark icon when there is a cover, and show nothing when there's no cover.
There was a problem hiding this comment.
Done! I've inverted the logic as requested. Now the bookmark ribbon is only shown when there's no cover image (as visual decoration), and hidden when a cover is displayed so it doesn't obscure the artwork. The bookmark also properly inverts when selected in the no-cover case.
src/activities/home/HomeActivity.cpp
Outdated
| renderer.fillPolygon(xPoints, yPoints, 5, false); | ||
|
|
||
| // Store the buffer with cover image AND bookmark for fast navigation | ||
| coverBufferStored = renderer.storeBwBuffer(); |
There was a problem hiding this comment.
I think this is a bit of a bastardisation of the storeBwBuffer function. That function was designed to temporarily hold the BW buffer for gray renders, we're using it to store a full screen frame atm.
If we'd like to store a full screen frame, then we should make it HomeActivity's responsibility to store that frame. When constructing HomeActivity we should be building our own buffer and cloning the frame buffer into it, something like:
// During initialization / entering activity:
auto baseFrame = static_cast<uint8_t *>(malloc(renderer.getBufferSize()));
// Instead of the this storeBwBuffer call
memcpy(baseFrame, renderer.getFrameBuffer(), renderer.getBufferSize());
// When restoring it
memcpy(renderer.getFrameBuffer(), baseFrame, renderer.getBufferSize());
// When exiting
free(baseFrame);Alternatively, we could just copy a subregion of the frame buffer where the cover is (which is only 1/4 of the screen) and then display that back onto the screen when we need it.
There was a problem hiding this comment.
I've refactored this to use HomeActivity's own buffer management. Added three private methods: storeCoverBuffer(), restoreCoverBuffer(), and freeCoverBuffer() that handle a dedicated uint8_t* coverBuffer member. This keeps the buffer responsibility within HomeActivity and leaves storeBwBuffer/restoreBwBuffer for their intended grayscale rendering purpose.
lib/GfxRenderer/GfxRenderer.cpp
Outdated
| /** | ||
| * Copy stored BW buffer to framebuffer without freeing the stored chunks. | ||
| * Use this when you want to restore the buffer but keep it for later reuse. | ||
| * Returns true if buffer was copied successfully. | ||
| */ | ||
| bool GfxRenderer::copyStoredBwBuffer() { | ||
| // Check if all chunks are allocated | ||
| for (const auto& bwBufferChunk : bwBufferChunks) { | ||
| if (!bwBufferChunk) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| uint8_t* frameBuffer = einkDisplay.getFrameBuffer(); | ||
| if (!frameBuffer) { | ||
| return false; | ||
| } | ||
|
|
||
| for (size_t i = 0; i < BW_BUFFER_NUM_CHUNKS; i++) { | ||
| const size_t offset = i * BW_BUFFER_CHUNK_SIZE; | ||
| memcpy(frameBuffer + offset, bwBufferChunks[i], BW_BUFFER_CHUNK_SIZE); | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Free the stored BW buffer chunks manually. | ||
| * Use this when you no longer need the stored buffer. | ||
| */ | ||
| void GfxRenderer::freeStoredBwBuffer() { freeBwBufferChunks(); } | ||
|
|
There was a problem hiding this comment.
Given some of the feedback in the other files, I think we should remove this functionality as it opens up a little too much room for abuse for my liking.
There was a problem hiding this comment.
Agreed. I've removed both copyStoredBwBuffer() and freeStoredBwBuffer() from GfxRenderer. The original storeBwBuffer() and restoreBwBuffer() are kept since they're still used by EpubReaderActivity for grayscale rendering as intended.
| free(rowBytes); | ||
| } | ||
|
|
||
| void GfxRenderer::fillPolygon(const int* xPoints, const int* yPoints, int numPoints, bool state) const { |
| // UTF-8 safe string truncation - removes one character from the end | ||
| // Returns the new size after removing one UTF-8 character | ||
| size_t utf8RemoveLastChar(std::string& str) { | ||
| if (str.empty()) return 0; | ||
| size_t pos = str.size() - 1; | ||
| // Walk back to find the start of the last UTF-8 character | ||
| // UTF-8 continuation bytes start with 10xxxxxx (0x80-0xBF) | ||
| while (pos > 0 && (static_cast<unsigned char>(str[pos]) & 0xC0) == 0x80) { | ||
| --pos; | ||
| } | ||
| str.resize(pos); | ||
| return pos; | ||
| } | ||
|
|
||
| // Truncate string by removing N UTF-8 characters from the end | ||
| void utf8TruncateChars(std::string& str, size_t numChars) { | ||
| for (size_t i = 0; i < numChars && !str.empty(); ++i) { | ||
| utf8RemoveLastChar(str); | ||
| } | ||
| } |
There was a problem hiding this comment.
For now these can stay here, but will relocate them once StringUtils get merged in from the Calibre Syncing PR
- Invert bookmark icon logic: show bookmark only when no cover image (as visual decoration), hide when cover is displayed to show more art - Replace GfxRenderer::storeBwBuffer usage with HomeActivity's own buffer management (storeCoverBuffer/restoreCoverBuffer/freeCoverBuffer) - Remove copyStoredBwBuffer() and freeStoredBwBuffer() from GfxRenderer as they enabled misuse of the grayscale buffer storage mechanism
Resolve conflicts: - GfxRenderer: Add cropX/cropY params to drawBitmap, keep 1-bit BMP support - GfxRenderer: Update drawBitmap1Bit to use readNextRow (API change) - JpegToBmpConverter: Use upstream scaling logic (larger dimension) - HomeActivity: Use StringUtils::checkFileExtension, add hasOpdsUrl - HomeActivity: Keep cover image functionality with own buffer management
|
Apologies, I've created more merge conflicts with the merge of #302, if you could resolve them, then I can get this in. |
Resolved merge conflicts: - lib/Epub/Epub.h: Kept both upstream's cropped parameter and HEAD's thumb functions - lib/JpegToBmpConverter/JpegToBmpConverter.cpp: Used upstream's version (dithering code moved to BitmapHelpers) - src/activities/home/HomeActivity.cpp: Kept HEAD's comment about stack size Added missing 1-bit dithering support to BitmapHelpers: - Added Atkinson1BitDitherer class to BitmapHelpers.h - Added quantize1bit() function to BitmapHelpers.cpp
|
Fwiw I'd recommend that if the cover image is available that we hide the book name and author since that's usually on the book cover as well |
Respectfully disagree. This info can be small or hard to read in the thumbnail depending on the book. I do think we could use a smaller font in the overlay. And the overlay should invert colors (white text on black background) when selected, consistent with the other buttons on the home screen. |
Well, what does Kindle or others do? I've never seen a reader UI that has both the cover and the book title stacked on top of each other haha. To me, it looks like a bug or a modal with information i need to dismiss. I'm fine with it being there in addition to the cover but why have the cover if you're gonna cover it with a box? defeats the purpose of having a nice beautiful book cover at all |
I second this. You're already supposed to know what book you're reading; you recognize the art, and there wouldn't be an issue with slightly less legible text in the art. Adding the current book's title label ruins the experience. If book covers were shown in a grid instead of a list of titles, displaying the name below the cover would make sense, especially when you haven’t opened the book yet and the text is hard to read. @eunchurn Is it possible to modify this? I've also been thinking that if the cover image is going to be scaled to fit the width of the container, vertical alignment might not be necessary. It could be aligned to the bottom, which would avoid the white boxes that currently appear above and below the covers. |
…aching (crosspoint-reader#200) ## Summary * **What is the goal of this PR?** (e.g., Fixes a bug in the user authentication module, Display the book cover image in the **"Continue Reading"** card on the home screen, with fast navigation using framebuffer caching. * **What changes are included?** - Display book cover image in the "Continue Reading" card on home screen - Load cover from cached BMP (same as sleep screen cover) - Add framebuffer store/restore functions (`copyStoredBwBuffer`, `freeStoredBwBuffer`) for fast navigation after initial render - Fix `drawBitmap` scaling bug: apply scale to offset only, not to base coordinates - Add white text boxes behind title/author/continue reading label for readability on cover - Support both EPUB and XTC file cover images - Increase HomeActivity task stack size from 2048 to 4096 for cover image rendering ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). - Performance: First render loads cover from SD card (~800ms), subsequent navigation uses cached framebuffer (~instant) - Memory: Framebuffer cache uses ~48KB (6 chunks × 8KB) while on home screen, freed on exit - Fallback: If cover image is not available, falls back to standard text-only display - The `drawBitmap` fix corrects a bug where screenY = (y + offset) scale was incorrectly scaling the base coordinates. Now correctly uses screenY = y + (offset scale)
commit 21277e0 Author: Luke Stein <[email protected]> Date: Thu Jan 15 07:27:17 2026 -0500 docs: Update User Guide to reflect release 0.14.0 (crosspoint-reader#376) commit 4eef2b5 Author: Luke Stein <[email protected]> Date: Thu Jan 15 07:26:39 2026 -0500 feat: Add MAC address display to WiFi Networks screen (crosspoint-reader#381) ## Summary * Implements crosspoint-reader#380, allowing the user to see the device's MAC address in order to register on wifi networks ## Additional Context * Although @markatlnk suggested showing on the settings screen, I implemented display at the bottom of the WiFi Networks selection screen (accessed via "File Transfer" > "Join a Network") since I think it makes more sense there. * Tested on my own device  --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**YES**_ --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> commit 5a55fa1 Author: Nathan James <[email protected]> Date: Thu Jan 15 12:25:18 2026 +0000 fix: also apply longPressChapterSkip setting to xtc reader (crosspoint-reader#378) ## Summary * This builds upon the helpful PR crosspoint-reader#341, and adds support for the setting to also apply to the XTC reader, which I believed has just been missed and was not intentionally left out. * XTC does not have chapter support yet, but it does skip 10 pages when long-pressed, and so I think this is useful. --- ### AI Usage Did you use AI tools to help write this code? No commit c98ba14 Author: Maeve Andrews <[email protected]> Date: Thu Jan 15 06:23:36 2026 -0600 fix: draw button hints correctly if orientation is not portrait (crosspoint-reader#363) ~~Quick~~ fix for crosspoint-reader#362 (this just applies to the chapter selection menu:) ~~If the orientation is portrait, hints as we know them make sense to draw. If the orientation is inverted, we'd have to change the order of the labels (along with everything's position), and if it's one of the landscape choices, we'd have to render the text and buttons vertically. All those other cases will be more complicated.~~ ~~Punt on this for now by only rendering if portrait.~~ Update: this now draws the hints at the physical button position no matter what the orientation is, by temporarily changing orientation to portrait. --------- Co-authored-by: Maeve Andrews <[email protected]> commit c1c94c0 Author: Jonas Diemer <[email protected]> Date: Thu Jan 15 13:21:46 2026 +0100 Feature: Show img alt text (crosspoint-reader#168) Let's start small by showing the ALT text of IMG. This is rudimentary, but avoids those otherwise completely blank chapters. I feel we will need this even when we can render images if that rendering takes >1s - I would then prefer rendering optional and showing the ALT text first. commit eb84bce Author: Dave Allie <[email protected]> Date: Thu Jan 15 02:22:38 2026 +1100 chore: Pin links2004/WebSockets version commit d45f355 Author: efenner <[email protected]> Date: Thu Jan 15 05:14:59 2026 -0700 feat: Add EPUB table omitted placeholder (crosspoint-reader#372) ## Summary * **What is the goal of this PR?**: Fix the bug I reported in crosspoint-reader#292 * **What changes are included?**: Instead of silently dropping table content in EPUBs., replace with an italicized '[Table omitted]' message where tables appear. ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**PARTIALLY **_ --------- Co-authored-by: Evan Fenner <[email protected]> Co-authored-by: Warp <[email protected]> commit 56ec3df Author: Dave Allie <[email protected]> Date: Thu Jan 15 01:01:47 2026 +1100 chore: Cut release 0.14.0 commit e517945 Author: Maeve Andrews <[email protected]> Date: Wed Jan 14 06:23:03 2026 -0600 Add a bullet to the beginning of any <li> (crosspoint-reader#368) Currently there is no visual indication whatsoever if something is in a list. An `<li>` is essentially just another paragraph. As a partial remedy for this, add a bullet character to the beginning of `<li>` text blocks so that the user can see that they're list items. This is incomplete in that an `<ol>` should also have a counter so that its list items can get numbers instead of bullets (right now I don't think we track if we're in a `<ul>` or an `<ol>` at all), but it's strictly better than the current situation. Co-authored-by: Maeve Andrews <[email protected]> commit 4892208 Author: Maeve Andrews <[email protected]> Date: Wed Jan 14 06:21:48 2026 -0600 Only indent paragraphs for justify/left-align (crosspoint-reader#367) Currently, when Extra Paragraph Spacing is off, an em-space is added to the beginning of each ParsedText even for blocks like headers that are centered. This whitespace makes the centering slightly off. Change the calculation here to only add the em-space for left/justified text. Co-authored-by: Maeve Andrews <[email protected]> commit 3ee10b3 Author: Dave Allie <[email protected]> Date: Wed Jan 14 23:14:00 2026 +1100 Update OTA updater URL commit a946c83 Author: swwilshub <[email protected]> Date: Wed Jan 14 12:11:28 2026 +0000 Turbocharge WiFi uploads with WebSocket + watchdog stability (crosspoint-reader#364) ## Summary * **What is the goal of this PR?** Fix WiFi file transfer stability issues (especially crashes during uploads) and improve upload speed via WebSocket binary protocol. File transfers now don't really crash as much, if they do it recovers and speed has gone form 50KB/s to 300+KB/s. * **What changes are included?** - **WebSocket upload support** - Adds WebSocket binary protocol for file uploads, achieving faster speeds 335 KB/s vs HTTP multipart) - **Watchdog stability fixes** - Adds `esp_task_wdt_reset()` calls throughout upload path to prevent watchdog timeouts during: - File creation (FAT allocation can be slow) - SD card write operations - HTTP header parsing - WebSocket chunk processing - **4KB write buffering** - Batches SD card writes to reduce I/O overhead - **WiFi health monitoring** - Detects WiFi disconnection in STA mode and exits gracefully - **Improved handleClient loop** - 500 iterations with periodic watchdog resets and button checks for responsiveness - **Progress bar improvements** - Fixed jumping/inaccurate progress by capping local progress at 95% until server confirms completion - **Exit button responsiveness** - Button now checked inside the handleClient loop every 64 iterations - **Reduced exit delays** - Decreased shutdown delays from ~850ms to ~140ms **Files changed:** - `platformio.ini` - Added WebSockets library dependency - `CrossPointWebServer.cpp/h` - WebSocket server, upload buffering, watchdog resets - `CrossPointWebServerActivity.cpp` - WiFi monitoring, improved loop, button handling - `FilesPage.html` - WebSocket upload JavaScript with HTTP fallback ## Additional Context - WebSocket uses 4KB chunks with backpressure management to prevent ESP32 buffer overflow - Falls back to HTTP automatically if WebSocket connection fails - The main bottleneck now is SD card write speed (~44% of transfer time), not WiFi - STA mode was more prone to crashes than AP mode due to external network factors; WiFi health monitoring helps detect and handle disconnections gracefully --- ### AI Usage Did you use AI tools to help write this code? _**YES**_ Claude did it ALL, I have no idea what I am doing, but my books transfer fast now. --------- Co-authored-by: Claude <[email protected]> commit 847786e Author: Justin Mitchell <[email protected]> Date: Wed Jan 14 06:54:14 2026 -0500 Fixes issue with Calibre web expecting SSL (crosspoint-reader#347) http urls now work with Calibre web --------- Co-authored-by: Dave Allie <[email protected]> commit c2fb8ce Author: Luke Stein <[email protected]> Date: Wed Jan 14 06:48:43 2026 -0500 Update User Guide to reflect release 0.13.1 (crosspoint-reader#337) Please note I have not tested the Calibre features and am not yet in a position to offer detailed documentation of how they work. commit ed05554 Author: Armando Cerna <[email protected]> Date: Wed Jan 14 06:47:24 2026 -0500 feat: Add setting to toggle long-press chapter skip (crosspoint-reader#341) ## Summary Adds a new "Long-press Chapter Skip" toggle in Settings to control whether holding the side buttons skips chapters. I kept accidentally triggering chapter skips while reading, which caused me to lose my place in the middle of long chapters. ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**PARTIALLY **_ commit 9a9dc04 Author: Jonas Diemer <[email protected]> Date: Wed Jan 14 12:40:40 2026 +0100 ifdef around optional fonts to reduce flash size/time. (crosspoint-reader#339) ## Summary Adds define to omit optional fonts from the build. This reduces time to flash from >31s to <13s. Useful for development that doesn't require fonts. Addresses crosspoint-reader#193 Invoke it like this during development: `PLATFORMIO_BUILD_FLAGS="-D OMIT_FONTS" pio run --target upload && pio device monitor` Changing the define causes `pio` to do a full rebuild (but it will be quick if you keep the define). --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? NO commit 1c027ce Author: Jonas Diemer <[email protected]> Date: Wed Jan 14 12:38:30 2026 +0100 Skip BOM character (sometimes used in front of em-dashes) (crosspoint-reader#340) ## Summary Skip BOM character (sometimes used in front of em-dashes) - they are not part of the glyph set and would render `?` otherwise. --- ### AI Usage Did you use AI tools to help write this code? _**YES**_ commit 49f97b6 Author: Eunchurn Park <[email protected]> Date: Wed Jan 14 19:36:40 2026 +0900 Add TXT file reader support (crosspoint-reader#240) ## Summary * **What is the goal of this PR?** Add support for reading plain text (.txt) files, enabling users to browse, read, and track progress in TXT documents alongside existing EPUB and XTC formats. * **What changes are included?** - New Txt library for loading and parsing plain text files - New TxtReaderActivity with streaming page rendering using 8KB chunks to handle large files without memory issues on ESP32-C3 - Page index caching system (index.bin) for instant re-open after sleep or app restart - Progress bar UI during initial file indexing (matching EPUB style) - Word wrapping with proper UTF-8 support - Cover image support for TXT files: - Primary: image with same filename as TXT (e.g., book.jpg for book.txt) - Fallback: cover.bmp/jpg/jpeg in the same folder - JPG to BMP conversion using existing converter - Sleep screen cover mode now works with TXT files - File browser now shows .txt files ## Additional Context * Add any other information that might be helpful for the reviewer * Memory constraints: The streaming approach was necessary because ESP32-C3 only has 320KB RAM. A 700KB TXT file cannot be loaded entirely into memory, so we read 8KB chunks and build a page offset index instead. * Cache invalidation: The page index cache automatically invalidates when file size, viewport width, or lines per page changes (e.g., font size or orientation change). * Performance: First open requires indexing (with progress bar), subsequent opens load from cache instantly. * Cover image format: PNG is detected but not supported for conversion (no PNG decoder available). Only BMP and JPG/JPEG work. commit 14643d0 Author: Dave Allie <[email protected]> Date: Wed Jan 14 21:19:12 2026 +1100 Move string helpers out of HomeActivity into StringUtils commit fecd184 Author: Eunchurn Park <[email protected]> Date: Wed Jan 14 19:24:02 2026 +0900 Add cover image display in *Continue Reading* card with framebuffer caching (crosspoint-reader#200) ## Summary * **What is the goal of this PR?** (e.g., Fixes a bug in the user authentication module, Display the book cover image in the **"Continue Reading"** card on the home screen, with fast navigation using framebuffer caching. * **What changes are included?** - Display book cover image in the "Continue Reading" card on home screen - Load cover from cached BMP (same as sleep screen cover) - Add framebuffer store/restore functions (`copyStoredBwBuffer`, `freeStoredBwBuffer`) for fast navigation after initial render - Fix `drawBitmap` scaling bug: apply scale to offset only, not to base coordinates - Add white text boxes behind title/author/continue reading label for readability on cover - Support both EPUB and XTC file cover images - Increase HomeActivity task stack size from 2048 to 4096 for cover image rendering ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). - Performance: First render loads cover from SD card (~800ms), subsequent navigation uses cached framebuffer (~instant) - Memory: Framebuffer cache uses ~48KB (6 chunks × 8KB) while on home screen, freed on exit - Fallback: If cover image is not available, falls back to standard text-only display - The `drawBitmap` fix corrects a bug where screenY = (y + offset) scale was incorrectly scaling the base coordinates. Now correctly uses screenY = y + (offset scale) commit 2040e08 Author: Will Morrow <[email protected]> Date: Wed Jan 14 05:05:08 2026 -0500 Ensure new custom sleep image every time (crosspoint-reader#300) When picking a random sleep image from a set of custom images, compare the randomly chosen index against a cached value in settings. If the value matches, use the next image (rolling over if it's the last image). Cache the chosen image index to settings in either case. ## Summary Implements a tweak on the custom sleep image feature that ensures that the user gets a new image every time the device goes to sleep. This change adds a new setting (perhaps there's a better place to cache this?) that stores the most recently used file index. During picking the random image index, we compare this against the random index and choose the next one (modulo the number of image files) if it matches, ensuring we get a new image. ## Additional Context As mentioned, I used settings to cache this value since it is a persisted store, perhaps that's overkill. Open to suggestions on if there's a better way. commit 65d2391 Author: Andrew Brandt <[email protected]> Date: Wed Jan 14 04:04:02 2026 -0600 ci: add PR format check workflow (crosspoint-reader#328) **Description**: Add a new workflow to check the PR formatting to ensure consistency on PR titles. We can also use this for semantic release versioning later, if we so desire. **Related Issue(s)**: Implements first portion of crosspoint-reader#327 --------- Signed-off-by: Andrew Brandt <[email protected]> commit 52995fa Author: Dave Allie <[email protected]> Date: Tue Jan 13 02:09:39 2026 +1100 chore: Cut release 0.13.1 commit d4f8eda Author: Dave Allie <[email protected]> Date: Tue Jan 13 01:09:06 2026 +1000 fix: Increase home activity stack size (crosspoint-reader#333) ## Summary * fix: Increase home activity stack size ## Additional Context * Home activity can crash occasionally depending on book --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? No commit 33b8fa0 Author: Dave Allie <[email protected]> Date: Tue Jan 13 00:56:21 2026 +1100 chore: Cut release 0.13.0 commit 16c760b Author: Dave Allie <[email protected]> Date: Tue Jan 13 00:58:43 2026 +1100 copy: Tweak pull request template wording commit 8f3df7e Author: Dave Allie <[email protected]> Date: Mon Jan 12 23:57:34 2026 +1000 fix: Handle EPUB 3 TOC to spine mapping when nav file in subdirectory (crosspoint-reader#332) ## Summary - Nav file in EPUB 3 file is a HTML file with relative hrefs - If this file exists anywhere but in the same location as the content.opf file, navigating in the book will fail - Bump the book cache version to rebuild potentially broken books ## Additional Context - Fixes crosspoint-reader#264 --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? - [ ] Yes - [ ] Partially - [x] No commit 0165fab Author: Jonas Diemer <[email protected]> Date: Mon Jan 12 12:36:19 2026 +0100 Fix BMP rendering gamma/brightness (crosspoint-reader#302) 1. Refactor Bitmap.cpp/h to expose the options for FloydSteinberg and brightness/gamma correction at runtime 2. Fine-tune the thresholds for Floyd Steiberg and simple quantization to better match the display's colors Turns out that 2 is enough to make the images render properly, so the brightness boost and gamma adjustment doesn't seem necessary currently (at least for my test image). commit 66b100c Author: danoob <[email protected]> Date: Mon Jan 12 17:49:42 2026 +0700 fix: Wi-Fi Selection on Calibre Library launch (crosspoint-reader#313) ## Summary * **What is the goal of this PR?** Fixes the Wi-Fi connection issue when launching the Calibre Library (OPDS browser). The previous implementation always attempted to connect using the first saved WiFi credential, which caused connection failures when users were in locations where only other saved networks (not the first one) were available. Now, the activity launches a WiFi selection screen allowing users to choose from available networks. * **What changes are included?** ## Additional Context **Bug Fixed**: Previously, the code used `credentials[0]` (always the first saved WiFi), so users in areas with only their secondary/tertiary saved networks available could never connect. --------- Co-authored-by: danoooob <[email protected]> commit 41bda43 Author: Andrew Brandt <[email protected]> Date: Mon Jan 12 04:37:23 2026 -0600 chore: update formatting in github workflows (crosspoint-reader#320) **Description**: The purpose of this change is to modify the spacing in the `.github/workflow` files to ensure consistency. **Related Issue(s)**: Implements crosspoint-reader#319 Signed-off-by: Andrew Brandt <[email protected]> commit 82f21f3 Author: Dave Allie <[email protected]> Date: Mon Jan 12 21:35:18 2026 +1100 Add AI usage question to the PR template commit a9242fe Author: Jonas Diemer <[email protected]> Date: Mon Jan 12 10:55:47 2026 +0100 Generate different .bmp for cropped covers so settings have effect. (crosspoint-reader#330) Addresses crosspoint-reader#225 (comment) commit 88d0d90 Author: Jonas Diemer <[email protected]> Date: Mon Jan 12 10:53:58 2026 +0100 Add option to hide battery percentage. (crosspoint-reader#297) with option to always hide or hide in reader only. Co-authored-by: Dave Allie <[email protected]> commit 97c4871 Author: David Fischer <[email protected]> Date: Mon Jan 12 10:07:26 2026 +0100 Add page turn on power button press (crosspoint-reader#286) ## Summary * **What is the goal of this PR?** * This PR adds a setting to (additionally) map the forward page turn onto the powerbutton when in `EPUBReaderActivity` and powerbutton short press is not mapped to sleep mode. I find the powerbutton to be exactly where my thumb is while reading so it is very convenient to map the forwardpage turn to that. Maybe Im not alone with this ^^ * **What changes are included?** ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). commit 66811bf Author: Seth <[email protected]> Date: Mon Jan 12 00:59:02 2026 -0800 Add navigation hints to ChapterSelectionActivities (crosspoint-reader#294) ## Summary Add navigation hints to Chapter Select - crosspoint-reader#190 ### Before  ### After  commit 8728701 Author: Samuel Carpentier <[email protected]> Date: Mon Jan 12 17:58:08 2026 +0900 Updated user guide (sleep screens list) (crosspoint-reader#293) ## Summary Updated sleep screens list by adding the newly available "Blank" option
|
I am hesitant to completely remove the title when the book cover is being shown, perhaps we can show it below the cover to avoid occluding it, but I have a few books where the "cover" is just the Penguin Books logo or something equally silly. Perhaps that's just a library management issue though |
…aching (crosspoint-reader#200) ## Summary * **What is the goal of this PR?** (e.g., Fixes a bug in the user authentication module, Display the book cover image in the **"Continue Reading"** card on the home screen, with fast navigation using framebuffer caching. * **What changes are included?** - Display book cover image in the "Continue Reading" card on home screen - Load cover from cached BMP (same as sleep screen cover) - Add framebuffer store/restore functions (`copyStoredBwBuffer`, `freeStoredBwBuffer`) for fast navigation after initial render - Fix `drawBitmap` scaling bug: apply scale to offset only, not to base coordinates - Add white text boxes behind title/author/continue reading label for readability on cover - Support both EPUB and XTC file cover images - Increase HomeActivity task stack size from 2048 to 4096 for cover image rendering ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). - Performance: First render loads cover from SD card (~800ms), subsequent navigation uses cached framebuffer (~instant) - Memory: Framebuffer cache uses ~48KB (6 chunks × 8KB) while on home screen, freed on exit - Fallback: If cover image is not available, falls back to standard text-only display - The `drawBitmap` fix corrects a bug where screenY = (y + offset) scale was incorrectly scaling the base coordinates. Now correctly uses screenY = y + (offset scale)
…aching (crosspoint-reader#200) ## Summary * **What is the goal of this PR?** (e.g., Fixes a bug in the user authentication module, Display the book cover image in the **"Continue Reading"** card on the home screen, with fast navigation using framebuffer caching. * **What changes are included?** - Display book cover image in the "Continue Reading" card on home screen - Load cover from cached BMP (same as sleep screen cover) - Add framebuffer store/restore functions (`copyStoredBwBuffer`, `freeStoredBwBuffer`) for fast navigation after initial render - Fix `drawBitmap` scaling bug: apply scale to offset only, not to base coordinates - Add white text boxes behind title/author/continue reading label for readability on cover - Support both EPUB and XTC file cover images - Increase HomeActivity task stack size from 2048 to 4096 for cover image rendering ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). - Performance: First render loads cover from SD card (~800ms), subsequent navigation uses cached framebuffer (~instant) - Memory: Framebuffer cache uses ~48KB (6 chunks × 8KB) while on home screen, freed on exit - Fallback: If cover image is not available, falls back to standard text-only display - The `drawBitmap` fix corrects a bug where screenY = (y + offset) scale was incorrectly scaling the base coordinates. Now correctly uses screenY = y + (offset scale)
Summary
Display the book cover image in the "Continue Reading" card on the home screen, with fast navigation using framebuffer caching.
copyStoredBwBuffer,freeStoredBwBuffer) for fast navigation after initial renderdrawBitmapscaling bug: apply scale to offset only, not to base coordinatesAdditional Context
drawBitmapfix corrects a bug where screenY = (y + offset) scale was incorrectly scaling the base coordinates. Now correctly uses screenY = y + (offset scale)