add time left in chapter feature
This commit is contained in:
@@ -31,6 +31,17 @@ void Page::render(GfxRenderer& renderer, const int fontId, const int xOffset, co
|
||||
}
|
||||
}
|
||||
|
||||
size_t Page::wordCount() const {
|
||||
size_t count = 0;
|
||||
for (const auto& element : elements) {
|
||||
const auto* line = dynamic_cast<PageLine*>(element.get());
|
||||
if (line) {
|
||||
count += line->wordCount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Page::serialize(FsFile& file) const {
|
||||
const uint16_t count = elements.size();
|
||||
serialization::writePod(file, count);
|
||||
|
||||
@@ -29,6 +29,7 @@ class PageLine final : public PageElement {
|
||||
PageLine(std::shared_ptr<TextBlock> block, const int16_t xPos, const int16_t yPos)
|
||||
: PageElement(xPos, yPos), block(std::move(block)) {}
|
||||
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override;
|
||||
size_t wordCount() const { return block ? block->wordCount() : 0; }
|
||||
bool serialize(FsFile& file) override;
|
||||
static std::unique_ptr<PageLine> deserialize(FsFile& file);
|
||||
};
|
||||
@@ -38,6 +39,7 @@ class Page {
|
||||
// the list of block index and line numbers on this page
|
||||
std::vector<std::shared_ptr<PageElement>> elements;
|
||||
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const;
|
||||
size_t wordCount() const;
|
||||
bool serialize(FsFile& file) const;
|
||||
static std::unique_ptr<Page> deserialize(FsFile& file);
|
||||
};
|
||||
|
||||
@@ -233,3 +233,64 @@ std::unique_ptr<Page> Section::loadPageFromSectionFile() {
|
||||
file.close();
|
||||
return page;
|
||||
}
|
||||
|
||||
std::unique_ptr<Page> Section::loadPageAt(const uint16_t pageIndex) const {
|
||||
FsFile localFile;
|
||||
if (!SdMan.openFileForRead("SCT", filePath, localFile)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
localFile.seek(HEADER_SIZE - sizeof(uint32_t));
|
||||
uint32_t lutOffset;
|
||||
serialization::readPod(localFile, lutOffset);
|
||||
if (pageIndex >= pageCount) {
|
||||
localFile.close();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
localFile.seek(lutOffset + sizeof(uint32_t) * pageIndex);
|
||||
uint32_t pagePos;
|
||||
serialization::readPod(localFile, pagePos);
|
||||
localFile.seek(pagePos);
|
||||
|
||||
auto page = Page::deserialize(localFile);
|
||||
localFile.close();
|
||||
return page;
|
||||
}
|
||||
|
||||
bool Section::ensureWordCountsLoaded() const {
|
||||
if (wordCountsLoaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pageWordCounts.clear();
|
||||
pageWordCounts.reserve(pageCount);
|
||||
|
||||
for (uint16_t i = 0; i < pageCount; i++) {
|
||||
auto page = loadPageAt(i);
|
||||
if (!page) {
|
||||
pageWordCounts.clear();
|
||||
return false;
|
||||
}
|
||||
pageWordCounts.push_back(static_cast<uint32_t>(page->wordCount()));
|
||||
}
|
||||
|
||||
wordCountsLoaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t Section::getWordsLeftFrom(const uint16_t pageIndex) const {
|
||||
if (pageIndex >= pageCount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ensureWordCountsLoaded()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t total = 0;
|
||||
for (size_t i = pageIndex; i < pageWordCounts.size(); i++) {
|
||||
total += pageWordCounts[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Epub.h"
|
||||
|
||||
@@ -13,6 +14,8 @@ class Section {
|
||||
GfxRenderer& renderer;
|
||||
std::string filePath;
|
||||
FsFile file;
|
||||
mutable std::vector<uint32_t> pageWordCounts;
|
||||
mutable bool wordCountsLoaded = false;
|
||||
|
||||
void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment,
|
||||
uint16_t viewportWidth, uint16_t viewportHeight);
|
||||
@@ -36,4 +39,7 @@ class Section {
|
||||
const std::function<void()>& progressSetupFn = nullptr,
|
||||
const std::function<void(int)>& progressFn = nullptr);
|
||||
std::unique_ptr<Page> loadPageFromSectionFile();
|
||||
std::unique_ptr<Page> loadPageAt(uint16_t pageIndex) const;
|
||||
bool ensureWordCountsLoaded() const;
|
||||
uint32_t getWordsLeftFrom(uint16_t pageIndex) const;
|
||||
};
|
||||
|
||||
@@ -36,6 +36,7 @@ class TextBlock final : public Block {
|
||||
// given a renderer works out where to break the words into lines
|
||||
void render(const GfxRenderer& renderer, int fontId, int x, int y) const;
|
||||
BlockType getType() override { return TEXT_BLOCK; }
|
||||
size_t wordCount() const { return words.size(); }
|
||||
bool serialize(FsFile& file) const;
|
||||
static std::unique_ptr<TextBlock> deserialize(FsFile& file);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user