#pragma once #include #include #include #include #include #include "blocks/BlockStyle.h" #include "blocks/TextBlock.h" class GfxRenderer; class ParsedText { public: enum class LineProcessResult { Accepted, RetryWithoutHyphenation, }; private: std::vector words; std::vector wordStyles; std::vector wordContinues; // true = word attaches to previous (no space before it) BlockStyle blockStyle; bool extraParagraphSpacing; bool hyphenationEnabled; void applyParagraphIndent(); std::vector computeLineBreaks(const GfxRenderer& renderer, int fontId, int pageWidth, std::vector& wordWidths, std::vector& continuesVec); std::vector computeHyphenatedLineBreaks(const GfxRenderer& renderer, int fontId, int pageWidth, std::vector& wordWidths, std::vector& continuesVec, std::vector& lineEndsWithHyphenatedWord, std::vector& splitPrefixWordIndexes, std::vector& splitInsertedHyphen); // Recompute hyphenated breaks for a suffix that starts at startIndex. // Used after a single-line retry so later lines keep normal hyphenation. std::vector computeHyphenatedLineBreaksFromIndex(const GfxRenderer& renderer, int fontId, int pageWidth, std::vector& wordWidths, std::vector& continuesVec, size_t startIndex, std::vector& lineEndsWithHyphenatedWord, std::vector& splitPrefixWordIndexes, std::vector& splitInsertedHyphen); // Compute exactly one line break without hyphenating words. // Used only for the page-boundary retry line. size_t computeSingleLineBreakNoHyphen(const GfxRenderer& renderer, int fontId, int pageWidth, const std::vector& wordWidths, const std::vector& continuesVec, size_t lineStartIndex) const; bool hyphenateWordAtIndex(size_t wordIndex, int availableWidth, const GfxRenderer& renderer, int fontId, std::vector& wordWidths, bool allowFallbackBreaks, bool* outInsertedHyphen = nullptr); LineProcessResult extractLine( size_t breakIndex, int pageWidth, const std::vector& wordWidths, const std::vector& continuesVec, const std::vector& lineBreakIndices, const std::function, bool, bool)>& processLine, const GfxRenderer& renderer, int fontId, bool lineEndsWithHyphenatedWord, bool suppressHyphenationRetry); std::vector calculateWordWidths(const GfxRenderer& renderer, int fontId); public: explicit ParsedText(const bool extraParagraphSpacing, const bool hyphenationEnabled = false, const BlockStyle& blockStyle = BlockStyle()) : blockStyle(blockStyle), extraParagraphSpacing(extraParagraphSpacing), hyphenationEnabled(hyphenationEnabled) {} ~ParsedText() = default; void addWord(std::string word, EpdFontFamily::Style fontStyle, bool underline = false, bool attachToPrevious = false); void setBlockStyle(const BlockStyle& blockStyle) { this->blockStyle = blockStyle; } BlockStyle& getBlockStyle() { return blockStyle; } size_t size() const { return words.size(); } bool isEmpty() const { return words.empty(); } void layoutAndExtractLines( const GfxRenderer& renderer, int fontId, uint16_t viewportWidth, const std::function, bool, bool)>& processLine, bool includeLastLine = true); };