Reduces heap fragmentation by ~12x fewer allocations per TextBlock. This fixes crashes when repeatedly navigating dictionary pages. - Replace std::list with std::vector in TextBlock members - Replace splice() with move+erase in ParsedText::extractLine() - Use index-based access in hyphenateWordAtIndex()
64 lines
2.3 KiB
C++
64 lines
2.3 KiB
C++
#pragma once
|
|
#include <EpdFontFamily.h>
|
|
#include <SdFat.h>
|
|
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "Block.h"
|
|
#include "BlockStyle.h"
|
|
|
|
// Represents a line of text on a page
|
|
class TextBlock final : public Block {
|
|
public:
|
|
enum Style : uint8_t {
|
|
JUSTIFIED = 0,
|
|
LEFT_ALIGN = 1,
|
|
CENTER_ALIGN = 2,
|
|
RIGHT_ALIGN = 3,
|
|
};
|
|
|
|
private:
|
|
std::vector<std::string> words;
|
|
std::vector<uint16_t> wordXpos;
|
|
std::vector<EpdFontFamily::Style> wordStyles;
|
|
std::vector<bool> wordUnderlines; // Track underline per word
|
|
Style style;
|
|
BlockStyle blockStyle;
|
|
|
|
public:
|
|
explicit TextBlock(std::vector<std::string> words, std::vector<uint16_t> word_xpos,
|
|
std::vector<EpdFontFamily::Style> word_styles, const Style style,
|
|
const BlockStyle& blockStyle = BlockStyle(), std::vector<bool> word_underlines = std::vector<bool>())
|
|
: words(std::move(words)),
|
|
wordXpos(std::move(word_xpos)),
|
|
wordStyles(std::move(word_styles)),
|
|
wordUnderlines(std::move(word_underlines)),
|
|
style(style),
|
|
blockStyle(blockStyle) {
|
|
// Ensure underlines list matches words list size
|
|
while (this->wordUnderlines.size() < this->words.size()) {
|
|
this->wordUnderlines.push_back(false);
|
|
}
|
|
}
|
|
~TextBlock() override = default;
|
|
void setStyle(const Style style) { this->style = style; }
|
|
void setBlockStyle(const BlockStyle& blockStyle) { this->blockStyle = blockStyle; }
|
|
Style getStyle() const { return style; }
|
|
const BlockStyle& getBlockStyle() const { return blockStyle; }
|
|
bool isEmpty() override { return words.empty(); }
|
|
|
|
// Getters for word selection support
|
|
const std::vector<std::string>& getWords() const { return words; }
|
|
const std::vector<uint16_t>& getWordXPositions() const { return wordXpos; }
|
|
const std::vector<EpdFontFamily::Style>& getWordStyles() const { return wordStyles; }
|
|
size_t getWordCount() const { return words.size(); }
|
|
void layout(GfxRenderer& renderer) override {};
|
|
// 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; }
|
|
bool serialize(FsFile& file) const;
|
|
static std::unique_ptr<TextBlock> deserialize(FsFile& file);
|
|
};
|