From 40c3ecbada054278b376228e52a7ca20236d60c6 Mon Sep 17 00:00:00 2001 From: spfenwick Date: Sat, 2 May 2026 16:05:30 +1200 Subject: [PATCH] When a large paragraph is split across blocks, don't treat the continuation as a new paragraph --- lib/Epub/Epub/ParsedText.cpp | 10 +++++++--- lib/Epub/Epub/ParsedText.h | 2 ++ lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp | 16 ++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/Epub/Epub/ParsedText.cpp b/lib/Epub/Epub/ParsedText.cpp index bc869102..0987aa16 100644 --- a/lib/Epub/Epub/ParsedText.cpp +++ b/lib/Epub/Epub/ParsedText.cpp @@ -215,9 +215,13 @@ void ParsedText::layoutAndExtractLines( } // Apply fixed transforms before any per-line layout work. - applyParagraphIndent(); - if (bionicReadingEnabled) { - applyBionicReadingTransform(); + // Skip on continuation flushes: the words are mid-paragraph and have + // already been transformed by the initial layoutAndExtractLines call. + if (!isContinuation_) { + applyParagraphIndent(); + if (bionicReadingEnabled) { + applyBionicReadingTransform(); + } } // Ensure SD card font glyph metrics are loaded before measuring word widths. diff --git a/lib/Epub/Epub/ParsedText.h b/lib/Epub/Epub/ParsedText.h index 2d94ed09..7b19db4c 100644 --- a/lib/Epub/Epub/ParsedText.h +++ b/lib/Epub/Epub/ParsedText.h @@ -27,6 +27,7 @@ class ParsedText { bool extraParagraphSpacing; bool hyphenationEnabled; bool bionicReadingEnabled; + bool isContinuation_ = false; ///< true after an intermediate flush; suppresses re-applying indent/transforms void applyParagraphIndent(); void applyBionicReadingTransform(); @@ -74,6 +75,7 @@ class ParsedText { BlockStyle& getBlockStyle() { return blockStyle; } size_t size() const { return words.size(); } bool isEmpty() const { return words.empty(); } + bool isContinuation() const { return isContinuation_; } void layoutAndExtractLines( const GfxRenderer& renderer, int fontId, uint16_t viewportWidth, const std::function, bool, bool)>& processLine, diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index dfe7d664..231f30fa 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -1592,13 +1592,17 @@ void ChapterHtmlSlimParser::makePages() { const int lineHeight = renderer.getLineHeight(fontId) * lineCompression; - // Apply top spacing before the paragraph (stored in pixels) + // Apply top spacing before the paragraph — skip for continuation fragments + // (words left over after an intermediate flush): the top margin was already + // applied before the first set of lines from this logical paragraph. const BlockStyle& blockStyle = currentTextBlock->getBlockStyle(); - if (blockStyle.marginTop > 0) { - currentPageNextY += blockStyle.marginTop; - } - if (blockStyle.paddingTop > 0) { - currentPageNextY += blockStyle.paddingTop; + if (!currentTextBlock->isContinuation()) { + if (blockStyle.marginTop > 0) { + currentPageNextY += blockStyle.marginTop; + } + if (blockStyle.paddingTop > 0) { + currentPageNextY += blockStyle.paddingTop; + } } // Calculate effective width accounting for horizontal margins/padding