From f36d89cd18bb8c458826513b6331106ca05036ba Mon Sep 17 00:00:00 2001 From: Justin Mitchell Date: Tue, 13 Jan 2026 03:53:45 -0500 Subject: [PATCH] dont round % and default to start of chapter not end --- lib/Epub/Epub.cpp | 11 ++--- lib/Epub/Epub.h | 2 +- lib/KOReaderSync/ProgressMapper.cpp | 41 ++++++++----------- src/activities/reader/EpubReaderActivity.cpp | 8 ++-- .../reader/KOReaderSyncActivity.cpp | 4 +- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index 234344d7..7c6e0658 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -539,14 +539,15 @@ int Epub::getSpineIndexForTextReference() const { return 0; } -// Calculate progress in book -uint8_t Epub::calculateProgress(const int currentSpineIndex, const float currentSpineRead) const { +// Calculate progress in book (returns 0.0-1.0) +float Epub::calculateProgress(const int currentSpineIndex, const float currentSpineRead) const { const size_t bookSize = getBookSize(); if (bookSize == 0) { - return 0; + return 0.0f; } const size_t prevChapterSize = (currentSpineIndex >= 1) ? getCumulativeSpineItemSize(currentSpineIndex - 1) : 0; const size_t curChapterSize = getCumulativeSpineItemSize(currentSpineIndex) - prevChapterSize; - const size_t sectionProgSize = currentSpineRead * curChapterSize; - return round(static_cast(prevChapterSize + sectionProgSize) / bookSize * 100.0); + const float sectionProgSize = currentSpineRead * static_cast(curChapterSize); + const float totalProgress = static_cast(prevChapterSize) + sectionProgSize; + return totalProgress / static_cast(bookSize); } diff --git a/lib/Epub/Epub.h b/lib/Epub/Epub.h index a6555e7e..e18acfd5 100644 --- a/lib/Epub/Epub.h +++ b/lib/Epub/Epub.h @@ -60,5 +60,5 @@ class Epub { int getSpineIndexForTextReference() const; size_t getBookSize() const; - uint8_t calculateProgress(int currentSpineIndex, float currentSpineRead) const; + float calculateProgress(int currentSpineIndex, float currentSpineRead) const; }; diff --git a/lib/KOReaderSync/ProgressMapper.cpp b/lib/KOReaderSync/ProgressMapper.cpp index a1e2b4f7..3f946961 100644 --- a/lib/KOReaderSync/ProgressMapper.cpp +++ b/lib/KOReaderSync/ProgressMapper.cpp @@ -14,9 +14,8 @@ KOReaderPosition ProgressMapper::toKOReader(const std::shared_ptr& epub, c intraSpineProgress = static_cast(pos.pageNumber) / static_cast(pos.totalPages); } - // Calculate overall book progress (0-100 from Epub, convert to 0.0-1.0) - const uint8_t progressPercent = epub->calculateProgress(pos.spineIndex, intraSpineProgress); - result.percentage = static_cast(progressPercent) / 100.0f; + // Calculate overall book progress (0.0-1.0) + result.percentage = epub->calculateProgress(pos.spineIndex, intraSpineProgress); // Generate XPath with estimated paragraph position based on page result.xpath = generateXPath(pos.spineIndex, pos.pageNumber, pos.totalPages); @@ -48,9 +47,11 @@ CrossPointPosition ProgressMapper::toCrossPoint(const std::shared_ptr& epu int xpathSpineIndex = parseDocFragmentIndex(koPos.xpath); if (xpathSpineIndex >= 0 && xpathSpineIndex < epub->getSpineItemsCount()) { result.spineIndex = xpathSpineIndex; - Serial.printf("[%lu] [ProgressMapper] Got spine index from XPath: %d\n", millis(), result.spineIndex); + // When we have XPath, go to page 0 of the spine - byte-based page calculation is unreliable + result.pageNumber = 0; + Serial.printf("[%lu] [ProgressMapper] Got spine index from XPath: %d (page=0)\n", millis(), result.spineIndex); } else { - // Fall back to percentage-based lookup + // Fall back to percentage-based lookup for both spine and page const size_t targetBytes = static_cast(bookSize * koPos.percentage); // Find the spine item that contains this byte position @@ -63,26 +64,20 @@ CrossPointPosition ProgressMapper::toCrossPoint(const std::shared_ptr& epu } Serial.printf("[%lu] [ProgressMapper] Got spine index from percentage (%.2f%%): %d\n", millis(), koPos.percentage * 100, result.spineIndex); - } - // Estimate page number within the spine item using percentage - if (totalPagesInSpine > 0 && result.spineIndex < epub->getSpineItemsCount()) { - // Calculate what percentage through the spine item we should be - const size_t prevCumSize = (result.spineIndex > 0) ? epub->getCumulativeSpineItemSize(result.spineIndex - 1) : 0; - const size_t currentCumSize = epub->getCumulativeSpineItemSize(result.spineIndex); - const size_t spineSize = currentCumSize - prevCumSize; + // Estimate page number within the spine item using percentage (only when no XPath) + if (totalPagesInSpine > 0 && result.spineIndex < epub->getSpineItemsCount()) { + const size_t prevCumSize = (result.spineIndex > 0) ? epub->getCumulativeSpineItemSize(result.spineIndex - 1) : 0; + const size_t currentCumSize = epub->getCumulativeSpineItemSize(result.spineIndex); + const size_t spineSize = currentCumSize - prevCumSize; - if (spineSize > 0) { - const size_t targetBytes = static_cast(bookSize * koPos.percentage); - const size_t bytesIntoSpine = (targetBytes > prevCumSize) ? (targetBytes - prevCumSize) : 0; - const float intraSpineProgress = static_cast(bytesIntoSpine) / static_cast(spineSize); - - // Clamp to valid range - const float clampedProgress = std::max(0.0f, std::min(1.0f, intraSpineProgress)); - result.pageNumber = static_cast(clampedProgress * totalPagesInSpine); - - // Ensure page number is valid - result.pageNumber = std::max(0, std::min(result.pageNumber, totalPagesInSpine - 1)); + if (spineSize > 0) { + const size_t bytesIntoSpine = (targetBytes > prevCumSize) ? (targetBytes - prevCumSize) : 0; + const float intraSpineProgress = static_cast(bytesIntoSpine) / static_cast(spineSize); + const float clampedProgress = std::max(0.0f, std::min(1.0f, intraSpineProgress)); + result.pageNumber = static_cast(clampedProgress * totalPagesInSpine); + result.pageNumber = std::max(0, std::min(result.pageNumber, totalPagesInSpine - 1)); + } } } diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 2c9998e9..18a3d0a9 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -438,11 +438,13 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in if (showProgress) { // Calculate progress in book const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; - const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); + const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100; // Right aligned text for progress counter - const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + - " " + std::to_string(bookProgress) + "%"; + char progressStr[32]; + snprintf(progressStr, sizeof(progressStr), "%d/%d %.1f%%", section->currentPage + 1, section->pageCount, + bookProgress); + const std::string progress = progressStr; progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - orientedMarginRight - progressTextWidth, textY, progress.c_str()); diff --git a/src/activities/reader/KOReaderSyncActivity.cpp b/src/activities/reader/KOReaderSyncActivity.cpp index 59ae4eed..4a85f23d 100644 --- a/src/activities/reader/KOReaderSyncActivity.cpp +++ b/src/activities/reader/KOReaderSyncActivity.cpp @@ -296,7 +296,7 @@ void KOReaderSyncActivity::render() { snprintf(remoteChapterStr, sizeof(remoteChapterStr), " %s", remoteChapter.c_str()); renderer.drawText(UI_10_FONT_ID, 20, 185, remoteChapterStr); char remotePageStr[64]; - snprintf(remotePageStr, sizeof(remotePageStr), " Page %d, %.0f%% overall", remotePosition.pageNumber + 1, + snprintf(remotePageStr, sizeof(remotePageStr), " Page %d, %.2f%% overall", remotePosition.pageNumber + 1, remoteProgress.percentage * 100); renderer.drawText(UI_10_FONT_ID, 20, 210, remotePageStr); @@ -312,7 +312,7 @@ void KOReaderSyncActivity::render() { snprintf(localChapterStr, sizeof(localChapterStr), " %s", localChapter.c_str()); renderer.drawText(UI_10_FONT_ID, 20, 295, localChapterStr); char localPageStr[64]; - snprintf(localPageStr, sizeof(localPageStr), " Page %d/%d, %.0f%% overall", currentPage + 1, totalPagesInSpine, + snprintf(localPageStr, sizeof(localPageStr), " Page %d/%d, %.2f%% overall", currentPage + 1, totalPagesInSpine, localProgress.percentage * 100); renderer.drawText(UI_10_FONT_ID, 20, 320, localPageStr);