Simplify
This commit is contained in:
@@ -51,22 +51,37 @@ void logReaderMemSnapshot(const char* stage) {
|
||||
inline void logReaderMemSnapshot(const char*) {}
|
||||
#endif
|
||||
|
||||
// Computes the [0..100] EPUB progress percent. Returns 0 when pageCount is unknown (sync/bookmark
|
||||
// pre-render writes), in which case the next saveProgress() will overwrite progress.bin with the
|
||||
// real value before the user can leave the reader.
|
||||
uint8_t epubProgressPercentByte(const Epub& epub, const int spineIndex, const int currentPage, const int pageCount) {
|
||||
if (pageCount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const float chapterProgress = static_cast<float>(currentPage) / static_cast<float>(pageCount);
|
||||
return ReaderUtils::fractionProgressPercentByte(epub.calculateProgress(spineIndex, chapterProgress));
|
||||
}
|
||||
|
||||
// Writes the canonical EPUB progress.bin layout: spine(2) + page(2) + pageCount(2) + percent(1).
|
||||
// Used by the per-page saveProgress() and by transient writers (sync restore, bookmark jump) so
|
||||
// the on-disk format stays consistent regardless of caller.
|
||||
bool writeReaderProgressCache(const std::string& cachePath, const int spineIndex, const int currentPage,
|
||||
const int pageCount) {
|
||||
const int pageCount, const uint8_t percent) {
|
||||
FsFile f;
|
||||
if (!Storage.openFileForWrite("ERS", cachePath + "/progress.bin", f)) {
|
||||
LOG_ERR("ERS", "Failed to open progress cache for sync restore: %s", cachePath.c_str());
|
||||
LOG_ERR("ERS", "Failed to open progress cache: %s", cachePath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t data[6];
|
||||
uint8_t data[7];
|
||||
data[0] = spineIndex & 0xFF;
|
||||
data[1] = (spineIndex >> 8) & 0xFF;
|
||||
data[2] = currentPage & 0xFF;
|
||||
data[3] = (currentPage >> 8) & 0xFF;
|
||||
data[4] = pageCount & 0xFF;
|
||||
data[5] = (pageCount >> 8) & 0xFF;
|
||||
f.write(data, 6);
|
||||
data[6] = percent;
|
||||
f.write(data, 7);
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
@@ -900,7 +915,9 @@ void EpubReaderActivity::applyPendingSyncSession() {
|
||||
// Store 0 to disable rescaling; the paragraph lookup handles precise positioning.
|
||||
const int restorePageCount = (restoreSpineIndex == sync.spineIndex) ? sync.totalPagesInSpine : 0;
|
||||
|
||||
if (writeReaderProgressCache(epub->getCachePath(), restoreSpineIndex, restorePage, restorePageCount)) {
|
||||
// Transient write — the next render's saveProgress() supplies the real percent before the user
|
||||
// can return to the home screen, so a placeholder 0 here is harmless.
|
||||
if (writeReaderProgressCache(epub->getCachePath(), restoreSpineIndex, restorePage, restorePageCount, 0)) {
|
||||
cachedSpineIndex = restoreSpineIndex;
|
||||
cachedChapterTotalPageCount = restorePageCount;
|
||||
LOG_DBG("ERS", "Prepared progress.bin for sync restore: spine=%d page=%d/%d", restoreSpineIndex, restorePage,
|
||||
@@ -924,7 +941,8 @@ void EpubReaderActivity::applyPendingBookmarkJump() {
|
||||
return;
|
||||
}
|
||||
LOG_DBG("ERS", "Applying pending bookmark jump: spine=%u page=%u", jump.spineIndex, jump.pageNumber);
|
||||
if (writeReaderProgressCache(epub->getCachePath(), jump.spineIndex, jump.pageNumber, 0)) {
|
||||
// Transient write before initializeReader; saveProgress() overwrites with the real percent.
|
||||
if (writeReaderProgressCache(epub->getCachePath(), jump.spineIndex, jump.pageNumber, 0, 0)) {
|
||||
cachedSpineIndex = jump.spineIndex;
|
||||
cachedChapterTotalPageCount = 0;
|
||||
} else {
|
||||
@@ -1383,28 +1401,12 @@ void EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportW
|
||||
}
|
||||
|
||||
void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) {
|
||||
FsFile f;
|
||||
if (Storage.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) {
|
||||
uint8_t overallPercent = 0;
|
||||
if (epub->getBookSize() > 0 && pageCount > 0) {
|
||||
const float chapterProgress = static_cast<float>(currentPage) / static_cast<float>(pageCount);
|
||||
overallPercent = static_cast<uint8_t>(
|
||||
clampPercent(static_cast<int>(epub->calculateProgress(spineIndex, chapterProgress) * 100.0f + 0.5f)));
|
||||
}
|
||||
uint8_t data[7];
|
||||
data[0] = spineIndex & 0xFF;
|
||||
data[1] = (spineIndex >> 8) & 0xFF;
|
||||
data[2] = currentPage & 0xFF;
|
||||
data[3] = (currentPage >> 8) & 0xFF;
|
||||
data[4] = pageCount & 0xFF;
|
||||
data[5] = (pageCount >> 8) & 0xFF;
|
||||
data[6] = overallPercent;
|
||||
f.write(data, 7);
|
||||
f.close();
|
||||
LOG_DBG("ERS", "Progress saved: Chapter %d, Page %d (%d%%)", spineIndex, currentPage, overallPercent);
|
||||
} else {
|
||||
const uint8_t percent = epubProgressPercentByte(*epub, spineIndex, currentPage, pageCount);
|
||||
if (!writeReaderProgressCache(epub->getCachePath(), spineIndex, currentPage, pageCount, percent)) {
|
||||
LOG_ERR("ERS", "Could not save progress!");
|
||||
return;
|
||||
}
|
||||
LOG_DBG("ERS", "Progress saved: Chapter %d, Page %d (%d%%)", spineIndex, currentPage, percent);
|
||||
}
|
||||
void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int orientedMarginTop,
|
||||
const int orientedMarginRight, const int orientedMarginBottom,
|
||||
|
||||
@@ -750,7 +750,6 @@ void MdReaderActivity::saveProgress() const {
|
||||
// 7-byte format matching TxtReaderActivity: page(2 bytes LE) + file offset(4 bytes LE) + overallPercent(1 byte)
|
||||
const size_t offset =
|
||||
(currentPage >= 0 && currentPage < static_cast<int>(pageOffsets.size())) ? pageOffsets[currentPage] : 0;
|
||||
const uint8_t overallPercent = (totalPages > 0) ? static_cast<uint8_t>((currentPage + 1) * 100 / totalPages) : 0;
|
||||
uint8_t data[7];
|
||||
data[0] = currentPage & 0xFF;
|
||||
data[1] = (currentPage >> 8) & 0xFF;
|
||||
@@ -758,7 +757,7 @@ void MdReaderActivity::saveProgress() const {
|
||||
data[3] = (offset >> 8) & 0xFF;
|
||||
data[4] = (offset >> 16) & 0xFF;
|
||||
data[5] = (offset >> 24) & 0xFF;
|
||||
data[6] = overallPercent;
|
||||
data[6] = ReaderUtils::pageProgressPercentByte(currentPage, totalPages);
|
||||
f.write(data, 7);
|
||||
}
|
||||
}
|
||||
@@ -770,10 +769,8 @@ void MdReaderActivity::loadProgress() {
|
||||
const int dataSize = f.read(data, 7);
|
||||
f.close();
|
||||
if (dataSize >= 4) {
|
||||
// Old 4-byte format: uint32 page — detect by checking if bytes 2-3 are non-zero
|
||||
// (new format stores page in bytes 0-1 only, bytes 2-3 are offset low bytes).
|
||||
// Since page counts are small (< 65536), bytes 2-3 of the old uint32 page are always 0.
|
||||
// We can safely read bytes 0-1 as the page number in both formats.
|
||||
// Page sits in bytes 0-1 in both the old 4-byte uint32 format and the new 7-byte format
|
||||
// (page counts stay well under 65536, so the upper bytes were always zero).
|
||||
int loadedPage = data[0] + (data[1] << 8);
|
||||
if (totalPages == 0) {
|
||||
currentPage = 0;
|
||||
|
||||
@@ -4,12 +4,37 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <Logging.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "MappedInputManager.h"
|
||||
|
||||
namespace ReaderUtils {
|
||||
|
||||
constexpr unsigned long GO_HOME_MS = 1000;
|
||||
|
||||
// Round-half-up integer division clamped to [0, 100], used as the percent byte appended to
|
||||
// progress.bin so the home screen can render a per-book badge without re-loading the document.
|
||||
// All reader types must funnel through this so the displayed value matches across formats.
|
||||
inline uint8_t pageProgressPercentByte(int currentPage, int totalPages) {
|
||||
if (totalPages <= 0 || currentPage < 0) {
|
||||
return 0;
|
||||
}
|
||||
const long numerator = static_cast<long>(currentPage + 1) * 200L + totalPages;
|
||||
const long percent = numerator / (2L * totalPages);
|
||||
if (percent < 0) return 0;
|
||||
if (percent > 100) return 100;
|
||||
return static_cast<uint8_t>(percent);
|
||||
}
|
||||
|
||||
// Round-half-up clamp for a pre-computed [0,1] progress fraction (used by EPUB, where progress
|
||||
// is byte-weighted across spine items rather than a simple page ratio).
|
||||
inline uint8_t fractionProgressPercentByte(float fraction) {
|
||||
const int percent = static_cast<int>(fraction * 100.0f + 0.5f);
|
||||
if (percent < 0) return 0;
|
||||
if (percent > 100) return 100;
|
||||
return static_cast<uint8_t>(percent);
|
||||
}
|
||||
|
||||
inline void applyOrientation(GfxRenderer& renderer, const uint8_t orientation) {
|
||||
switch (orientation) {
|
||||
case CrossPointSettings::ORIENTATION::PORTRAIT:
|
||||
|
||||
@@ -411,7 +411,6 @@ void TxtReaderActivity::saveProgress() const {
|
||||
// 7-byte format: page(2 bytes LE) + file offset(4 bytes LE) + overallPercent(1 byte)
|
||||
// The offset lets drawCurrentPageToBuffer render without requiring index.bin.
|
||||
const size_t offset = (currentPage < static_cast<int>(pageOffsets.size())) ? pageOffsets[currentPage] : 0;
|
||||
const uint8_t overallPercent = (totalPages > 0) ? static_cast<uint8_t>((currentPage + 1) * 100 / totalPages) : 0;
|
||||
uint8_t data[7];
|
||||
data[0] = currentPage & 0xFF;
|
||||
data[1] = (currentPage >> 8) & 0xFF;
|
||||
@@ -419,7 +418,7 @@ void TxtReaderActivity::saveProgress() const {
|
||||
data[3] = (offset >> 8) & 0xFF;
|
||||
data[4] = (offset >> 16) & 0xFF;
|
||||
data[5] = (offset >> 24) & 0xFF;
|
||||
data[6] = overallPercent;
|
||||
data[6] = ReaderUtils::pageProgressPercentByte(currentPage, totalPages);
|
||||
f.write(data, 7);
|
||||
f.close();
|
||||
}
|
||||
|
||||
@@ -334,14 +334,13 @@ void XtcReaderActivity::renderPage() {
|
||||
void XtcReaderActivity::saveProgress() const {
|
||||
FsFile f;
|
||||
if (Storage.openFileForWrite("XTR", xtc->getCachePath() + "/progress.bin", f)) {
|
||||
const uint32_t pageCount = xtc->getPageCount();
|
||||
const uint8_t overallPercent = (pageCount > 0) ? static_cast<uint8_t>((currentPage + 1) * 100 / pageCount) : 0;
|
||||
uint8_t data[5];
|
||||
data[0] = currentPage & 0xFF;
|
||||
data[1] = (currentPage >> 8) & 0xFF;
|
||||
data[2] = (currentPage >> 16) & 0xFF;
|
||||
data[3] = (currentPage >> 24) & 0xFF;
|
||||
data[4] = overallPercent;
|
||||
data[4] =
|
||||
ReaderUtils::pageProgressPercentByte(static_cast<int>(currentPage), static_cast<int>(xtc->getPageCount()));
|
||||
f.write(data, 5);
|
||||
f.close();
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ int LyraTheme::getRecentBookProgressPercent(const RecentBook& book) {
|
||||
}
|
||||
|
||||
std::string cachePath;
|
||||
int percentByteOffset; // byte index of the percent field in progress.bin
|
||||
int percentByteOffset = 0; // byte index of the percent field in progress.bin
|
||||
|
||||
if (FsHelpers::hasEpubExtension(book.path)) {
|
||||
cachePath = Epub(book.path, "/.crosspoint").getCachePath();
|
||||
@@ -160,8 +160,8 @@ int LyraTheme::getRecentBookProgressPercent(const RecentBook& book) {
|
||||
const int dataSize = progressFile.read(data, 7);
|
||||
progressFile.close();
|
||||
|
||||
if (dataSize <= percentByteOffset) {
|
||||
return -1; // old format without percent byte — not yet read by new firmware
|
||||
if (dataSize < percentByteOffset + 1) {
|
||||
return -1; // old format (or pre-render placeholder) without the percent byte
|
||||
}
|
||||
|
||||
return clampProgressPercent(static_cast<int>(data[percentByteOffset]));
|
||||
|
||||
Reference in New Issue
Block a user