diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index 45cd8f9..74c91f3 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -148,6 +148,18 @@ bool Epub::load() { return false; } + // determine size of spine items + size_t spineItemsCount = getSpineItemsCount(); + size_t spineItemsSize = 0; + for (size_t i = 0; i < spineItemsCount; i++) { + std::string spineItem = getSpineItem(i); + size_t s = 0; + getItemSize(spineItem, &s); + spineItemsSize += s; + cumulativeSpineItemSize.emplace_back(spineItemsSize); + } + Serial.printf("[%lu] [EBP] Book size: %u\n", millis(), spineItemsSize); + Serial.printf("[%lu] [EBP] Loaded ePub: %s\n", millis(), filepath.c_str()); return true; @@ -255,6 +267,8 @@ bool Epub::getItemSize(const std::string& itemHref, size_t* size) const { int Epub::getSpineItemsCount() const { return spine.size(); } +size_t Epub::getCumulativeSpineItemSize(const int spineIndex) const { return cumulativeSpineItemSize.at(spineIndex); } + std::string& Epub::getSpineItem(const int spineIndex) { if (spineIndex < 0 || spineIndex >= spine.size()) { Serial.printf("[%lu] [EBP] getSpineItem index:%d is out of range\n", millis(), spineIndex); @@ -302,3 +316,14 @@ int Epub::getTocIndexForSpineIndex(const int spineIndex) const { Serial.printf("[%lu] [EBP] TOC item not found\n", millis()); return -1; } + +size_t Epub::getBookSize() const { return getCumulativeSpineItemSize(getSpineItemsCount() - 1); } + +// Calculate progress in book +uint8_t Epub::calculateProgress(const int currentSpineIndex, const float currentSpineRead) { + size_t prevChapterSize = getCumulativeSpineItemSize(currentSpineIndex - 1); + size_t curChapterSize = getCumulativeSpineItemSize(currentSpineIndex) - prevChapterSize; + size_t bookSize = getBookSize(); + size_t sectionProgSize = currentSpineRead * curChapterSize; + return round(static_cast(prevChapterSize + sectionProgSize) / bookSize * 100.0); +} diff --git a/lib/Epub/Epub.h b/lib/Epub/Epub.h index 765eacc..1f2dfa9 100644 --- a/lib/Epub/Epub.h +++ b/lib/Epub/Epub.h @@ -20,6 +20,8 @@ class Epub { std::string filepath; // the spine of the EPUB file std::vector> spine; + // the file size of the spine items (proxy to book progress) + std::vector cumulativeSpineItemSize; // the toc of the EPUB file std::vector toc; // the base path for items in the EPUB file @@ -51,8 +53,12 @@ class Epub { bool getItemSize(const std::string& itemHref, size_t* size) const; std::string& getSpineItem(int spineIndex); int getSpineItemsCount() const; - EpubTocEntry& getTocItem(int tocTndex); + size_t getCumulativeSpineItemSize(const int spineIndex) const; + EpubTocEntry& getTocItem(int tocIndex); int getTocItemsCount() const; int getSpineIndexForTocIndex(int tocIndex) const; int getTocIndexForSpineIndex(int spineIndex) const; + + size_t getBookSize() const; + uint8_t calculateProgress(const int currentSpineIndex, const float currentSpineRead); }; diff --git a/src/screens/EpubReaderScreen.cpp b/src/screens/EpubReaderScreen.cpp index 84f9c26..e4c0969 100644 --- a/src/screens/EpubReaderScreen.cpp +++ b/src/screens/EpubReaderScreen.cpp @@ -324,8 +324,14 @@ void EpubReaderScreen::renderContents(std::unique_ptr page) { void EpubReaderScreen::renderStatusBar() const { constexpr auto textY = 776; + + // Calculate progress in book + float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; + uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); + // Right aligned text for progress counter - const std::string progress = std::to_string(section->currentPage + 1) + " / " + std::to_string(section->pageCount); + const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + + " " + std::to_string(bookProgress) + "%"; const auto progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); renderer.drawText(SMALL_FONT_ID, GfxRenderer::getScreenWidth() - marginRight - progressTextWidth, textY, progress.c_str());