Convert paragraph indent and spacing from boolean toggles to configurable ranges

This commit is contained in:
warren 2026-01-17 20:31:34 +08:00
parent 21277e03eb
commit 854b63fa8a
10 changed files with 85 additions and 49 deletions

View File

@ -42,10 +42,12 @@ std::vector<uint16_t> ParsedText::calculateWordWidths(const GfxRenderer& rendere
std::vector<uint16_t> wordWidths; std::vector<uint16_t> wordWidths;
wordWidths.reserve(totalWordCount); wordWidths.reserve(totalWordCount);
// add em-space at the beginning of first word in paragraph to indent // add em-space at the beginning of first word in paragraph to indent (independent of paragraph spacing)
if ((style == TextBlock::JUSTIFIED || style == TextBlock::LEFT_ALIGN) && !extraParagraphSpacing) { if ((style == TextBlock::JUSTIFIED || style == TextBlock::LEFT_ALIGN) && indentParagraph > 0) {
std::string& first_word = words.front(); std::string& first_word = words.front();
first_word.insert(0, "\xe2\x80\x83"); for (uint8_t i = 0; i < indentParagraph; ++i) {
first_word.insert(0, "\xe2\x80\x83"); // em-space
}
} }
auto wordsIt = words.begin(); auto wordsIt = words.begin();

View File

@ -16,7 +16,8 @@ class ParsedText {
std::list<std::string> words; std::list<std::string> words;
std::list<EpdFontFamily::Style> wordStyles; std::list<EpdFontFamily::Style> wordStyles;
TextBlock::Style style; TextBlock::Style style;
bool extraParagraphSpacing; uint8_t extraParagraphSpacing;
uint8_t indentParagraph;
std::vector<size_t> computeLineBreaks(int pageWidth, int spaceWidth, const std::vector<uint16_t>& wordWidths) const; 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,
@ -25,8 +26,9 @@ class ParsedText {
std::vector<uint16_t> calculateWordWidths(const GfxRenderer& renderer, int fontId); std::vector<uint16_t> calculateWordWidths(const GfxRenderer& renderer, int fontId);
public: public:
explicit ParsedText(const TextBlock::Style style, const bool extraParagraphSpacing) explicit ParsedText(const TextBlock::Style style, const uint8_t extraParagraphSpacing,
: style(style), extraParagraphSpacing(extraParagraphSpacing) {} const uint8_t indentParagraph = 1)
: style(style), extraParagraphSpacing(extraParagraphSpacing), indentParagraph(indentParagraph) {}
~ParsedText() = default; ~ParsedText() = default;
void addWord(std::string word, EpdFontFamily::Style fontStyle); void addWord(std::string word, EpdFontFamily::Style fontStyle);

View File

@ -8,8 +8,9 @@
namespace { namespace {
constexpr uint8_t SECTION_FILE_VERSION = 9; constexpr uint8_t SECTION_FILE_VERSION = 9;
constexpr uint32_t HEADER_SIZE = sizeof(uint8_t) + sizeof(int) + sizeof(float) + sizeof(bool) + sizeof(uint8_t) + constexpr uint32_t HEADER_SIZE = sizeof(uint8_t) + sizeof(int) + sizeof(float) + sizeof(bool) + sizeof(bool) +
sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t); sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) +
sizeof(uint32_t);
} // namespace } // namespace
uint32_t Section::onPageComplete(std::unique_ptr<Page> page) { uint32_t Section::onPageComplete(std::unique_ptr<Page> page) {
@ -29,21 +30,23 @@ uint32_t Section::onPageComplete(std::unique_ptr<Page> page) {
return position; return position;
} }
void Section::writeSectionFileHeader(const int fontId, const float lineCompression, const bool extraParagraphSpacing, void Section::writeSectionFileHeader(const int fontId, const float lineCompression, const uint8_t extraParagraphSpacing,
const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint8_t indentParagraph, const uint8_t paragraphAlignment,
const uint16_t viewportHeight) { const uint16_t viewportWidth, const uint16_t viewportHeight) {
if (!file) { if (!file) {
Serial.printf("[%lu] [SCT] File not open for writing header\n", millis()); Serial.printf("[%lu] [SCT] File not open for writing header\n", millis());
return; return;
} }
static_assert(HEADER_SIZE == sizeof(SECTION_FILE_VERSION) + sizeof(fontId) + sizeof(lineCompression) + static_assert(HEADER_SIZE == sizeof(SECTION_FILE_VERSION) + sizeof(fontId) + sizeof(lineCompression) +
sizeof(extraParagraphSpacing) + sizeof(paragraphAlignment) + sizeof(viewportWidth) + sizeof(extraParagraphSpacing) + sizeof(indentParagraph) +
sizeof(viewportHeight) + sizeof(pageCount) + sizeof(uint32_t), sizeof(paragraphAlignment) + sizeof(viewportWidth) + sizeof(viewportHeight) +
sizeof(pageCount) + sizeof(uint32_t),
"Header size mismatch"); "Header size mismatch");
serialization::writePod(file, SECTION_FILE_VERSION); serialization::writePod(file, SECTION_FILE_VERSION);
serialization::writePod(file, fontId); serialization::writePod(file, fontId);
serialization::writePod(file, lineCompression); serialization::writePod(file, lineCompression);
serialization::writePod(file, extraParagraphSpacing); serialization::writePod(file, extraParagraphSpacing);
serialization::writePod(file, indentParagraph);
serialization::writePod(file, paragraphAlignment); serialization::writePod(file, paragraphAlignment);
serialization::writePod(file, viewportWidth); serialization::writePod(file, viewportWidth);
serialization::writePod(file, viewportHeight); serialization::writePod(file, viewportHeight);
@ -51,9 +54,9 @@ void Section::writeSectionFileHeader(const int fontId, const float lineCompressi
serialization::writePod(file, static_cast<uint32_t>(0)); // Placeholder for LUT offset serialization::writePod(file, static_cast<uint32_t>(0)); // Placeholder for LUT offset
} }
bool Section::loadSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, bool Section::loadSectionFile(const int fontId, const float lineCompression, const uint8_t extraParagraphSpacing,
const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint8_t indentParagraph, const uint8_t paragraphAlignment,
const uint16_t viewportHeight) { const uint16_t viewportWidth, const uint16_t viewportHeight) {
if (!SdMan.openFileForRead("SCT", filePath, file)) { if (!SdMan.openFileForRead("SCT", filePath, file)) {
return false; return false;
} }
@ -72,18 +75,21 @@ bool Section::loadSectionFile(const int fontId, const float lineCompression, con
int fileFontId; int fileFontId;
uint16_t fileViewportWidth, fileViewportHeight; uint16_t fileViewportWidth, fileViewportHeight;
float fileLineCompression; float fileLineCompression;
bool fileExtraParagraphSpacing; uint8_t fileExtraParagraphSpacing;
uint8_t fileIndentParagraph;
uint8_t fileParagraphAlignment; uint8_t fileParagraphAlignment;
serialization::readPod(file, fileFontId); serialization::readPod(file, fileFontId);
serialization::readPod(file, fileLineCompression); serialization::readPod(file, fileLineCompression);
serialization::readPod(file, fileExtraParagraphSpacing); serialization::readPod(file, fileExtraParagraphSpacing);
serialization::readPod(file, fileIndentParagraph);
serialization::readPod(file, fileParagraphAlignment); serialization::readPod(file, fileParagraphAlignment);
serialization::readPod(file, fileViewportWidth); serialization::readPod(file, fileViewportWidth);
serialization::readPod(file, fileViewportHeight); serialization::readPod(file, fileViewportHeight);
if (fontId != fileFontId || lineCompression != fileLineCompression || if (fontId != fileFontId || lineCompression != fileLineCompression ||
extraParagraphSpacing != fileExtraParagraphSpacing || paragraphAlignment != fileParagraphAlignment || extraParagraphSpacing != fileExtraParagraphSpacing || indentParagraph != fileIndentParagraph ||
viewportWidth != fileViewportWidth || viewportHeight != fileViewportHeight) { paragraphAlignment != fileParagraphAlignment || viewportWidth != fileViewportWidth ||
viewportHeight != fileViewportHeight) {
file.close(); file.close();
Serial.printf("[%lu] [SCT] Deserialization failed: Parameters do not match\n", millis()); Serial.printf("[%lu] [SCT] Deserialization failed: Parameters do not match\n", millis());
clearCache(); clearCache();
@ -113,9 +119,10 @@ bool Section::clearCache() const {
return true; return true;
} }
bool Section::createSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, bool Section::createSectionFile(const int fontId, const float lineCompression, const uint8_t extraParagraphSpacing,
const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint8_t indentParagraph, const uint8_t paragraphAlignment,
const uint16_t viewportHeight, const std::function<void()>& progressSetupFn, const uint16_t viewportWidth, const uint16_t viewportHeight,
const std::function<void()>& progressSetupFn,
const std::function<void(int)>& progressFn) { const std::function<void(int)>& progressFn) {
constexpr uint32_t MIN_SIZE_FOR_PROGRESS = 50 * 1024; // 50KB constexpr uint32_t MIN_SIZE_FOR_PROGRESS = 50 * 1024; // 50KB
const auto localPath = epub->getSpineItem(spineIndex).href; const auto localPath = epub->getSpineItem(spineIndex).href;
@ -171,13 +178,13 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c
if (!SdMan.openFileForWrite("SCT", filePath, file)) { if (!SdMan.openFileForWrite("SCT", filePath, file)) {
return false; return false;
} }
writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, paragraphAlignment, viewportWidth, writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, indentParagraph, paragraphAlignment,
viewportHeight); viewportWidth, viewportHeight);
std::vector<uint32_t> lut = {}; std::vector<uint32_t> lut = {};
ChapterHtmlSlimParser visitor( ChapterHtmlSlimParser visitor(
tmpHtmlPath, renderer, fontId, lineCompression, extraParagraphSpacing, paragraphAlignment, viewportWidth, tmpHtmlPath, renderer, fontId, lineCompression, extraParagraphSpacing, indentParagraph, paragraphAlignment,
viewportHeight, viewportWidth, viewportHeight,
[this, &lut](std::unique_ptr<Page> page) { lut.emplace_back(this->onPageComplete(std::move(page))); }, [this, &lut](std::unique_ptr<Page> page) { lut.emplace_back(this->onPageComplete(std::move(page))); },
progressFn); progressFn);
success = visitor.parseAndBuildPages(); success = visitor.parseAndBuildPages();

View File

@ -14,8 +14,8 @@ class Section {
std::string filePath; std::string filePath;
FsFile file; FsFile file;
void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, void writeSectionFileHeader(int fontId, float lineCompression, uint8_t extraParagraphSpacing, uint8_t indentParagraph,
uint16_t viewportWidth, uint16_t viewportHeight); uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight);
uint32_t onPageComplete(std::unique_ptr<Page> page); uint32_t onPageComplete(std::unique_ptr<Page> page);
public: public:
@ -28,11 +28,11 @@ class Section {
renderer(renderer), renderer(renderer),
filePath(epub->getCachePath() + "/sections/" + std::to_string(spineIndex) + ".bin") {} filePath(epub->getCachePath() + "/sections/" + std::to_string(spineIndex) + ".bin") {}
~Section() = default; ~Section() = default;
bool loadSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, bool loadSectionFile(int fontId, float lineCompression, uint8_t extraParagraphSpacing, uint8_t indentParagraph,
uint16_t viewportWidth, uint16_t viewportHeight); uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight);
bool clearCache() const; bool clearCache() const;
bool createSectionFile(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, bool createSectionFile(int fontId, float lineCompression, uint8_t extraParagraphSpacing, uint8_t indentParagraph,
uint16_t viewportWidth, uint16_t viewportHeight, uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight,
const std::function<void()>& progressSetupFn = nullptr, const std::function<void()>& progressSetupFn = nullptr,
const std::function<void(int)>& progressFn = nullptr); const std::function<void(int)>& progressFn = nullptr);
std::unique_ptr<Page> loadPageFromSectionFile(); std::unique_ptr<Page> loadPageFromSectionFile();

View File

@ -51,7 +51,7 @@ void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::Style style) {
makePages(); makePages();
} }
currentTextBlock.reset(new ParsedText(style, extraParagraphSpacing)); currentTextBlock.reset(new ParsedText(style, extraParagraphSpacing, indentParagraph));
} }
void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) { void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) {
@ -387,8 +387,11 @@ void ChapterHtmlSlimParser::makePages() {
currentTextBlock->layoutAndExtractLines( currentTextBlock->layoutAndExtractLines(
renderer, fontId, viewportWidth, renderer, fontId, viewportWidth,
[this](const std::shared_ptr<TextBlock>& textBlock) { addLineToPage(textBlock); }); [this](const std::shared_ptr<TextBlock>& textBlock) { addLineToPage(textBlock); });
// Extra paragraph spacing if enabled // Apply paragraph spacing: 0->0%, 1->30%, 2->50%, 3->80%, 4->100%, 5->120%, 6->140%
if (extraParagraphSpacing) { if (extraParagraphSpacing > 0) {
currentPageNextY += lineHeight / 2; const float spacingMultipliers[] = {0.0f, 0.3f, 0.5f, 0.8f, 1.0f, 1.2f, 1.4f};
const float spacingMultiplier = spacingMultipliers[extraParagraphSpacing];
const int spacingAmount = static_cast<int>(lineHeight * spacingMultiplier);
currentPageNextY += spacingAmount;
} }
} }

View File

@ -32,7 +32,8 @@ class ChapterHtmlSlimParser {
int16_t currentPageNextY = 0; int16_t currentPageNextY = 0;
int fontId; int fontId;
float lineCompression; float lineCompression;
bool extraParagraphSpacing; uint8_t extraParagraphSpacing;
uint8_t indentParagraph;
uint8_t paragraphAlignment; uint8_t paragraphAlignment;
uint16_t viewportWidth; uint16_t viewportWidth;
uint16_t viewportHeight; uint16_t viewportHeight;
@ -46,9 +47,9 @@ class ChapterHtmlSlimParser {
public: public:
explicit ChapterHtmlSlimParser(const std::string& filepath, GfxRenderer& renderer, const int fontId, explicit ChapterHtmlSlimParser(const std::string& filepath, GfxRenderer& renderer, const int fontId,
const float lineCompression, const bool extraParagraphSpacing, const float lineCompression, const uint8_t extraParagraphSpacing,
const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint8_t indentParagraph, const uint8_t paragraphAlignment,
const uint16_t viewportHeight, const uint16_t viewportWidth, const uint16_t viewportHeight,
const std::function<void(std::unique_ptr<Page>)>& completePageFn, const std::function<void(std::unique_ptr<Page>)>& completePageFn,
const std::function<void(int)>& progressFn = nullptr) const std::function<void(int)>& progressFn = nullptr)
: filepath(filepath), : filepath(filepath),
@ -56,6 +57,7 @@ class ChapterHtmlSlimParser {
fontId(fontId), fontId(fontId),
lineCompression(lineCompression), lineCompression(lineCompression),
extraParagraphSpacing(extraParagraphSpacing), extraParagraphSpacing(extraParagraphSpacing),
indentParagraph(indentParagraph),
paragraphAlignment(paragraphAlignment), paragraphAlignment(paragraphAlignment),
viewportWidth(viewportWidth), viewportWidth(viewportWidth),
viewportHeight(viewportHeight), viewportHeight(viewportHeight),

View File

@ -14,7 +14,7 @@ CrossPointSettings CrossPointSettings::instance;
namespace { namespace {
constexpr uint8_t SETTINGS_FILE_VERSION = 1; constexpr uint8_t SETTINGS_FILE_VERSION = 1;
// Increment this when adding new persisted settings fields // Increment this when adding new persisted settings fields
constexpr uint8_t SETTINGS_COUNT = 18; constexpr uint8_t SETTINGS_COUNT = 19;
constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
} // namespace } // namespace
@ -48,6 +48,7 @@ bool CrossPointSettings::saveToFile() const {
serialization::writePod(outputFile, textAntiAliasing); serialization::writePod(outputFile, textAntiAliasing);
serialization::writePod(outputFile, hideBatteryPercentage); serialization::writePod(outputFile, hideBatteryPercentage);
serialization::writePod(outputFile, longPressChapterSkip); serialization::writePod(outputFile, longPressChapterSkip);
serialization::writePod(outputFile, indentParagraph);
outputFile.close(); outputFile.close();
Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis());
@ -116,6 +117,8 @@ bool CrossPointSettings::loadFromFile() {
if (++settingsRead >= fileSettingsCount) break; if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, longPressChapterSkip); serialization::readPod(inputFile, longPressChapterSkip);
if (++settingsRead >= fileSettingsCount) break; if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, indentParagraph);
if (++settingsRead >= fileSettingsCount) break;
} while (false); } while (false);
inputFile.close(); inputFile.close();

View File

@ -58,14 +58,27 @@ class CrossPointSettings {
// Hide battery percentage // Hide battery percentage
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2 }; enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2 };
// Paragraph spacing options
enum PARAGRAPH_SPACING {
SPACING_NONE = 0,
SPACING_0_3X = 1,
SPACING_0_5X = 2,
SPACING_0_8X = 3,
SPACING_1_0X = 4,
SPACING_1_2X = 5,
SPACING_1_4X = 6
};
// Sleep screen settings // Sleep screen settings
uint8_t sleepScreen = DARK; uint8_t sleepScreen = DARK;
// Sleep screen cover mode settings // Sleep screen cover mode settings
uint8_t sleepScreenCoverMode = FIT; uint8_t sleepScreenCoverMode = FIT;
// Status bar settings // Status bar settings
uint8_t statusBar = FULL; uint8_t statusBar = FULL;
// Text rendering settings // Text rendering settings 0-3: number of em-spaces to indent paragraph
uint8_t extraParagraphSpacing = 1; uint8_t indentParagraph = 1;
// 0-6: spacing (0, 0.3x, 0.5x, 0.8x, 1x, 1.2x, 1.4x)
uint8_t extraParagraphSpacing = SPACING_1_0X;
uint8_t textAntiAliasing = 1; uint8_t textAntiAliasing = 1;
// Short power button click behaviour // Short power button click behaviour
uint8_t shortPwrBtn = IGNORE; uint8_t shortPwrBtn = IGNORE;

View File

@ -267,8 +267,8 @@ void EpubReaderActivity::renderScreen() {
const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom;
if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, SETTINGS.extraParagraphSpacing, SETTINGS.indentParagraph, SETTINGS.paragraphAlignment,
viewportHeight)) { viewportWidth, viewportHeight)) {
Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis()); Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis());
// Progress bar dimensions // Progress bar dimensions
@ -312,8 +312,9 @@ void EpubReaderActivity::renderScreen() {
}; };
if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, SETTINGS.extraParagraphSpacing, SETTINGS.indentParagraph,
viewportHeight, progressSetup, progressCallback)) { SETTINGS.paragraphAlignment, viewportWidth, viewportHeight, progressSetup,
progressCallback)) {
Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis()); Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis());
section.reset(); section.reset();
return; return;

View File

@ -13,14 +13,17 @@
// Define the static settings list // Define the static settings list
namespace { namespace {
constexpr int settingsCount = 20; constexpr int settingsCount = 21;
const SettingInfo settingsList[settingsCount] = { const SettingInfo settingsList[settingsCount] = {
// Should match with SLEEP_SCREEN_MODE // Should match with SLEEP_SCREEN_MODE
SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}),
SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}),
SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}),
SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}),
SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), SettingInfo::Value("Paragraph Indent", &CrossPointSettings::indentParagraph, {0, 3, 1}),
SettingInfo::Enum("Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing,
{"None", "0.3 LineHeight", "0.5 LineHeight", "0.8 LineHeight", "1.0 LineHeight", "1.2 LineHeight",
"1.4 LineHeight"}),
SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing), SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing),
SettingInfo::Enum("Short Power Button Click", &CrossPointSettings::shortPwrBtn, {"Ignore", "Sleep", "Page Turn"}), SettingInfo::Enum("Short Power Button Click", &CrossPointSettings::shortPwrBtn, {"Ignore", "Sleep", "Page Turn"}),
SettingInfo::Enum("Reading Orientation", &CrossPointSettings::orientation, SettingInfo::Enum("Reading Orientation", &CrossPointSettings::orientation,