mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 23:27:38 +03:00
refactor
This commit is contained in:
parent
54669a8fd4
commit
81ad6fa6c4
@ -30,7 +30,6 @@ void ParsedText::layoutAndExtractLines(const GfxRenderer& renderer, const int fo
|
|||||||
|
|
||||||
// Apply fixed transforms before any per-line layout work.
|
// Apply fixed transforms before any per-line layout work.
|
||||||
applyParagraphIndent();
|
applyParagraphIndent();
|
||||||
ensureHyphenationFitsViewport(renderer, fontId, viewportWidth);
|
|
||||||
|
|
||||||
const int pageWidth = viewportWidth;
|
const int pageWidth = viewportWidth;
|
||||||
const int spaceWidth = renderer.getSpaceWidth(fontId);
|
const int spaceWidth = renderer.getSpaceWidth(fontId);
|
||||||
@ -155,100 +154,6 @@ void ParsedText::applyParagraphIndent() {
|
|||||||
words.front().insert(0, "\xe2\x80\x83");
|
words.front().insert(0, "\xe2\x80\x83");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParsedText::ensureHyphenationFitsViewport(const GfxRenderer& renderer, const int fontId, const int viewportWidth) {
|
|
||||||
if (!hyphenationEnabled || viewportWidth <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto wordIt = words.begin();
|
|
||||||
auto styleIt = wordStyles.begin();
|
|
||||||
|
|
||||||
while (wordIt != words.end() && styleIt != wordStyles.end()) {
|
|
||||||
const int wordWidth = renderer.getTextWidth(fontId, wordIt->c_str(), *styleIt);
|
|
||||||
if (wordWidth <= viewportWidth) {
|
|
||||||
++wordIt;
|
|
||||||
++styleIt;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto chunks = hyphenateWordToFit(*wordIt, renderer, fontId, *styleIt, viewportWidth);
|
|
||||||
if (chunks.empty()) {
|
|
||||||
++wordIt;
|
|
||||||
++styleIt;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*wordIt = chunks.front();
|
|
||||||
|
|
||||||
auto wordInsertPos = std::next(wordIt);
|
|
||||||
auto styleInsertPos = std::next(styleIt);
|
|
||||||
for (size_t idx = 1; idx < chunks.size(); ++idx) {
|
|
||||||
wordInsertPos = words.insert(wordInsertPos, chunks[idx]);
|
|
||||||
styleInsertPos = wordStyles.insert(styleInsertPos, *styleIt);
|
|
||||||
++wordInsertPos;
|
|
||||||
++styleInsertPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
++wordIt;
|
|
||||||
++styleIt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> ParsedText::hyphenateWordToFit(const std::string& word, const GfxRenderer& renderer,
|
|
||||||
const int fontId, const EpdFontFamily::Style style,
|
|
||||||
const int viewportWidth) const {
|
|
||||||
std::vector<std::string> chunks;
|
|
||||||
if (word.empty() || viewportWidth <= 0) {
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int hyphenWidth = renderer.getTextWidth(fontId, "-", style);
|
|
||||||
std::string remaining = word;
|
|
||||||
|
|
||||||
while (!remaining.empty()) {
|
|
||||||
const int remainingWidth = renderer.getTextWidth(fontId, remaining.c_str(), style);
|
|
||||||
if (remainingWidth <= viewportWidth) {
|
|
||||||
chunks.push_back(remaining);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto breakOffsets = Hyphenator::breakOffsets(remaining, true);
|
|
||||||
if (breakOffsets.empty()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t chosenOffset = 0;
|
|
||||||
int chosenWidth = -1;
|
|
||||||
for (const size_t offset : breakOffsets) {
|
|
||||||
if (offset == 0 || offset >= remaining.size()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string candidate = remaining.substr(0, offset);
|
|
||||||
const int candidateWidth = renderer.getTextWidth(fontId, candidate.c_str(), style) + hyphenWidth;
|
|
||||||
if (candidateWidth > viewportWidth) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (candidateWidth > chosenWidth) {
|
|
||||||
chosenWidth = candidateWidth;
|
|
||||||
chosenOffset = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chosenWidth < 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string chunk = remaining.substr(0, chosenOffset);
|
|
||||||
chunk.push_back('-');
|
|
||||||
chunks.push_back(std::move(chunk));
|
|
||||||
remaining.erase(0, chosenOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds break indices while opportunistically splitting the word that would overflow the current line.
|
// Builds break indices while opportunistically splitting the word that would overflow the current line.
|
||||||
std::vector<size_t> ParsedText::computeHyphenatedLineBreaks(const GfxRenderer& renderer, const int fontId,
|
std::vector<size_t> ParsedText::computeHyphenatedLineBreaks(const GfxRenderer& renderer, const int fontId,
|
||||||
const int pageWidth, const int spaceWidth,
|
const int pageWidth, const int spaceWidth,
|
||||||
|
|||||||
@ -20,14 +20,11 @@ class ParsedText {
|
|||||||
bool hyphenationEnabled;
|
bool hyphenationEnabled;
|
||||||
|
|
||||||
void applyParagraphIndent();
|
void applyParagraphIndent();
|
||||||
void ensureHyphenationFitsViewport(const GfxRenderer& renderer, int fontId, int viewportWidth);
|
std::vector<size_t> computeLineBreaks(int pageWidth, int spaceWidth, const std::vector<uint16_t>& wordWidths) const;
|
||||||
std::vector<std::string> hyphenateWordToFit(const std::string& word, const GfxRenderer& renderer, int fontId,
|
|
||||||
EpdFontFamily::Style style, int viewportWidth) const;
|
|
||||||
std::vector<size_t> computeHyphenatedLineBreaks(const GfxRenderer& renderer, int fontId, int pageWidth,
|
std::vector<size_t> computeHyphenatedLineBreaks(const GfxRenderer& renderer, int fontId, int pageWidth,
|
||||||
int spaceWidth, std::vector<uint16_t>& wordWidths);
|
int spaceWidth, std::vector<uint16_t>& wordWidths);
|
||||||
bool hyphenateWordAtIndex(size_t wordIndex, int availableWidth, const GfxRenderer& renderer, int fontId,
|
bool hyphenateWordAtIndex(size_t wordIndex, int availableWidth, const GfxRenderer& renderer, int fontId,
|
||||||
std::vector<uint16_t>& wordWidths);
|
std::vector<uint16_t>& wordWidths);
|
||||||
std::vector<size_t> computeLineBreaks(int pageWidth, int spaceWidth, const std::vector<uint16_t>& wordWidths) const;
|
|
||||||
void extractLine(size_t breakIndex, int pageWidth, int spaceWidth, const std::vector<uint16_t>& wordWidths,
|
void extractLine(size_t breakIndex, int pageWidth, int spaceWidth, const std::vector<uint16_t>& wordWidths,
|
||||||
const std::vector<size_t>& lineBreakIndices,
|
const std::vector<size_t>& lineBreakIndices,
|
||||||
const std::function<void(std::shared_ptr<TextBlock>)>& processLine);
|
const std::function<void(std::shared_ptr<TextBlock>)>& processLine);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user