Process lines into pages as they are built

This commit is contained in:
Dave Allie 2025-12-13 20:10:16 +11:00
parent c7a32fe41f
commit 5bae283838
No known key found for this signature in database
GPG Key ID: F2FDDB3AD8D0276F
4 changed files with 27 additions and 28 deletions

View File

@ -4,6 +4,7 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <functional>
#include <limits> #include <limits>
#include <vector> #include <vector>
@ -17,10 +18,10 @@ void ParsedText::addWord(std::string word, const EpdFontStyle fontStyle) {
} }
// Consumes data to minimize memory usage // Consumes data to minimize memory usage
std::list<std::shared_ptr<TextBlock>> ParsedText::layoutAndExtractLines(const GfxRenderer& renderer, const int fontId, void ParsedText::layoutAndExtractLines(const GfxRenderer& renderer, const int fontId, const int horizontalMargin,
const int horizontalMargin) { const std::function<void(std::shared_ptr<TextBlock>)>& processLine) {
if (words.empty()) { if (words.empty()) {
return {}; return;
} }
const size_t totalWordCount = words.size(); const size_t totalWordCount = words.size();
@ -99,8 +100,6 @@ std::list<std::shared_ptr<TextBlock>> ParsedText::layoutAndExtractLines(const Gf
currentWordIndex = nextBreakIndex; currentWordIndex = nextBreakIndex;
} }
std::list<std::shared_ptr<TextBlock>> lines;
// Initialize iterators for consumption // Initialize iterators for consumption
auto wordStartIt = words.begin(); auto wordStartIt = words.begin();
auto wordStyleStartIt = wordStyles.begin(); auto wordStyleStartIt = wordStyles.begin();
@ -153,7 +152,7 @@ std::list<std::shared_ptr<TextBlock>> ParsedText::layoutAndExtractLines(const Gf
std::list<EpdFontStyle> lineWordStyles; std::list<EpdFontStyle> lineWordStyles;
lineWordStyles.splice(lineWordStyles.begin(), wordStyles, wordStyleStartIt, wordStyleEndIt); lineWordStyles.splice(lineWordStyles.begin(), wordStyles, wordStyleStartIt, wordStyleEndIt);
lines.push_back( processLine(
std::make_shared<TextBlock>(std::move(lineWords), std::move(lineXPos), std::move(lineWordStyles), style)); std::make_shared<TextBlock>(std::move(lineWords), std::move(lineXPos), std::move(lineWordStyles), style));
// Update pointers/indices for the next line // Update pointers/indices for the next line
@ -162,6 +161,4 @@ std::list<std::shared_ptr<TextBlock>> ParsedText::layoutAndExtractLines(const Gf
wordWidthIndex += lineWordCount; wordWidthIndex += lineWordCount;
lastBreakAt = lineBreak; lastBreakAt = lineBreak;
} }
return lines;
} }

View File

@ -3,6 +3,7 @@
#include <EpdFontFamily.h> #include <EpdFontFamily.h>
#include <cstdint> #include <cstdint>
#include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
#include <string> #include <string>
@ -24,6 +25,6 @@ class ParsedText {
void setStyle(const TextBlock::BLOCK_STYLE style) { this->style = style; } void setStyle(const TextBlock::BLOCK_STYLE style) { this->style = style; }
TextBlock::BLOCK_STYLE getStyle() const { return style; } TextBlock::BLOCK_STYLE getStyle() const { return style; }
bool isEmpty() const { return words.empty(); } bool isEmpty() const { return words.empty(); }
std::list<std::shared_ptr<TextBlock>> layoutAndExtractLines(const GfxRenderer& renderer, int fontId, void layoutAndExtractLines(const GfxRenderer& renderer, int fontId, int horizontalMargin,
int horizontalMargin); const std::function<void(std::shared_ptr<TextBlock>)>& processLine);
}; };

View File

@ -245,6 +245,20 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
return true; return true;
} }
void ChapterHtmlSlimParser::addLineToPage(std::shared_ptr<TextBlock> line) {
const int lineHeight = renderer.getLineHeight(fontId) * lineCompression;
const int pageHeight = GfxRenderer::getScreenHeight() - marginTop - marginBottom;
if (currentPageNextY + lineHeight > pageHeight) {
completePageFn(std::move(currentPage));
currentPage.reset(new Page());
currentPageNextY = marginTop;
}
currentPage->elements.push_back(std::make_shared<PageLine>(line, marginLeft, currentPageNextY));
currentPageNextY += lineHeight;
}
void ChapterHtmlSlimParser::makePages() { void ChapterHtmlSlimParser::makePages() {
if (!currentTextBlock) { if (!currentTextBlock) {
Serial.printf("[%lu] [EHP] !! No text block to make pages for !!\n", millis()); Serial.printf("[%lu] [EHP] !! No text block to make pages for !!\n", millis());
@ -257,23 +271,9 @@ void ChapterHtmlSlimParser::makePages() {
} }
const int lineHeight = renderer.getLineHeight(fontId) * lineCompression; const int lineHeight = renderer.getLineHeight(fontId) * lineCompression;
const int pageHeight = GfxRenderer::getScreenHeight() - marginTop - marginBottom; currentTextBlock->layoutAndExtractLines(
renderer, fontId, marginLeft + marginRight,
// Long running task, make sure to let other things happen [this](const std::shared_ptr<TextBlock>& textBlock) { addLineToPage(textBlock); });
vTaskDelay(1); // Extra paragrpah spacing
const auto lines = currentTextBlock->layoutAndExtractLines(renderer, fontId, marginLeft + marginRight);
for (auto&& line : lines) {
if (currentPageNextY + lineHeight > pageHeight) {
completePageFn(std::move(currentPage));
currentPage.reset(new Page());
currentPageNextY = marginTop;
}
currentPage->elements.push_back(std::make_shared<PageLine>(line, marginLeft, currentPageNextY));
currentPageNextY += lineHeight;
}
// add some extra line between blocks
currentPageNextY += lineHeight / 2; currentPageNextY += lineHeight / 2;
} }

View File

@ -59,4 +59,5 @@ class ChapterHtmlSlimParser {
completePageFn(completePageFn) {} completePageFn(completePageFn) {}
~ChapterHtmlSlimParser() = default; ~ChapterHtmlSlimParser() = default;
bool parseAndBuildPages(); bool parseAndBuildPages();
void addLineToPage(std::shared_ptr<TextBlock> line);
}; };