diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index ecec1f62..d8c06e85 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -12,7 +12,7 @@ CrossPointSettings CrossPointSettings::instance; namespace { constexpr uint8_t SETTINGS_FILE_VERSION = 1; // Increment this when adding new persisted settings fields -constexpr uint8_t SETTINGS_COUNT = 9; +constexpr uint8_t SETTINGS_COUNT = 10; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -36,6 +36,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, sideButtonLayout); serialization::writePod(outputFile, fontFamily); serialization::writePod(outputFile, fontSize); + serialization::writePod(outputFile, lineSpacing); outputFile.close(); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); @@ -80,6 +81,8 @@ bool CrossPointSettings::loadFromFile() { if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, fontSize); if (++settingsRead >= fileSettingsCount) break; + serialization::readPod(inputFile, lineSpacing); + if (++settingsRead >= fileSettingsCount) break; } while (false); inputFile.close(); @@ -87,6 +90,42 @@ bool CrossPointSettings::loadFromFile() { return true; } +float CrossPointSettings::getReaderLineCompression() const { + switch (fontFamily) { + case ALEO: + default: + switch (lineSpacing) { + case TIGHT: + return 0.95f; + case NORMAL: + default: + return 1.0f; + case WIDE: + return 1.1f; + } + case NOTOSANS: + switch (lineSpacing) { + case TIGHT: + return 0.90f; + case NORMAL: + default: + return 0.95f; + case WIDE: + return 1.0f; + } + case OPENDYSLEXIC: + switch (lineSpacing) { + case TIGHT: + return 0.90f; + case NORMAL: + default: + return 0.95f; + case WIDE: + return 1.0f; + } + } +} + int CrossPointSettings::getReaderFontId() const { switch (fontFamily) { case ALEO: diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index d9021136..99f2275e 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -42,6 +42,7 @@ class CrossPointSettings { enum FONT_FAMILY { ALEO = 0, NOTOSANS = 1, OPENDYSLEXIC = 2 }; // Font size options enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3 }; + enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 }; // Sleep screen settings uint8_t sleepScreen = DARK; @@ -54,14 +55,13 @@ class CrossPointSettings { // EPUB reading orientation settings // 0 = portrait (default), 1 = landscape clockwise, 2 = inverted, 3 = landscape counter-clockwise uint8_t orientation = PORTRAIT; - // Front button layout + // Button layouts uint8_t frontButtonLayout = BACK_CONFIRM_LEFT_RIGHT; - // Side button layout uint8_t sideButtonLayout = PREV_NEXT; - // Font family + // Reader font settings uint8_t fontFamily = ALEO; - // Font size uint8_t fontSize = MEDIUM; + uint8_t lineSpacing = NORMAL; ~CrossPointSettings() = default; @@ -73,6 +73,8 @@ class CrossPointSettings { bool saveToFile() const; bool loadFromFile(); + + float getReaderLineCompression() const; }; // Helper macro to access settings diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 149bd578..118decb3 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -16,7 +16,6 @@ namespace { constexpr int pagesPerRefresh = 15; constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; -constexpr float lineCompression = 0.95f; constexpr int topPadding = 5; constexpr int horizontalPadding = 5; constexpr int statusBarMargin = 19; @@ -257,8 +256,8 @@ void EpubReaderActivity::renderScreen() { const auto viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; const auto viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; - if (!section->loadSectionFile(SETTINGS.getReaderFontId(), lineCompression, SETTINGS.extraParagraphSpacing, - viewportWidth, viewportHeight)) { + if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), + SETTINGS.extraParagraphSpacing, viewportWidth, viewportHeight)) { Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis()); // Progress bar dimensions @@ -301,8 +300,9 @@ void EpubReaderActivity::renderScreen() { renderer.displayBuffer(EInkDisplay::FAST_REFRESH); }; - if (!section->createSectionFile(SETTINGS.getReaderFontId(), lineCompression, SETTINGS.extraParagraphSpacing, - viewportWidth, viewportHeight, progressSetup, progressCallback)) { + if (!section->createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), + SETTINGS.extraParagraphSpacing, viewportWidth, viewportHeight, progressSetup, + progressCallback)) { Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis()); section.reset(); return; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 020b5080..cec9a145 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -9,7 +9,7 @@ // Define the static settings list namespace { -constexpr int settingsCount = 10; +constexpr int settingsCount = 11; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE {"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}}, @@ -30,6 +30,7 @@ const SettingInfo settingsList[settingsCount] = { {"Prev, Next", "Next, Prev"}}, {"Reader Font Family", SettingType::ENUM, &CrossPointSettings::fontFamily, {"Aleo", "Noto Sans", "Open Dyslexic"}}, {"Reader Font Size", SettingType::ENUM, &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}}, + {"Reader Line Spacing", SettingType::ENUM, &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}}, {"Check for updates", SettingType::ACTION, nullptr, {}}, }; } // namespace