diff --git a/.skills/SKILL.md b/.skills/SKILL.md index 30cd9de3..23e7772a 100644 --- a/.skills/SKILL.md +++ b/.skills/SKILL.md @@ -664,7 +664,7 @@ Tested in all 4 orientations with 5MB+ files. - `lib/I18n/I18nKeys.h`, `lib/I18n/I18nStrings.h`, `lib/I18n/I18nStrings.cpp` - **Source**: YAML translation files in `lib/I18n/translations/` (one per language) - **To modify**: Edit source YAML files, then run `python scripts/gen_i18n.py lib/I18n/translations lib/I18n/` - - **Commit**: Source YAML files + `I18nKeys.h` and `I18nStrings.h` (needed for IDE symbol resolution), but NOT `I18nStrings.cpp` + - **Commit**: Source YAML files only. All three generated files (`I18nKeys.h`, `I18nStrings.h`, `I18nStrings.cpp`) are in `.gitignore` and regenerated at build time. 3. **Build Artifacts** (in `.gitignore`): - `.pio/` - PlatformIO build output @@ -686,7 +686,7 @@ Tested in all 4 orientations with 5MB+ files. - English (`english.yaml`) is the reference; missing keys in other languages fall back to English 2. Run generator: `python scripts/gen_i18n.py lib/I18n/translations lib/I18n/` 3. Generated files update: `I18nKeys.h`, `I18nStrings.h`, `I18nStrings.cpp` -4. **Commit** source YAML files + `I18nKeys.h` and `I18nStrings.h` (IDE needs these for symbol resolution), but NOT `I18nStrings.cpp` +4. **Commit** source YAML files only. All three generated files are in `.gitignore` and regenerated at build time. **To use translated strings in code**: ```cpp diff --git a/include/README b/include/README deleted file mode 100644 index 49819c0d..00000000 --- a/include/README +++ /dev/null @@ -1,37 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the convention is to give header files names that end with `.h'. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 8d450aa5..d4382e02 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -534,14 +534,14 @@ void EpubReaderActivity::render(RenderLock&& lock) { orientedMarginBottom += std::max(SETTINGS.screenMargin, statusBarHeight); } + const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; + const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; + if (!section) { const auto filepath = epub->getSpineItem(currentSpineIndex).href; LOG_DBG("ERS", "Loading file: %s, index: %d", filepath.c_str(), currentSpineIndex); section = std::unique_ptr
(new Section(epub, currentSpineIndex, renderer)); - const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; - const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; - if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, @@ -639,6 +639,7 @@ void EpubReaderActivity::render(RenderLock&& lock) { renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft); LOG_DBG("ERS", "Rendered page in %dms", millis() - start); } + silentIndexNextChapterIfNeeded(viewportWidth, viewportHeight); saveProgress(currentSpineIndex, section->currentPage, section->pageCount); if (pendingScreenshot) { @@ -647,6 +648,38 @@ void EpubReaderActivity::render(RenderLock&& lock) { } } +void EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportWidth, const uint16_t viewportHeight) { + if (!epub || !section || section->pageCount < 2) { + return; + } + + // Build the next chapter cache while the penultimate page is on screen. + if (section->currentPage != section->pageCount - 2) { + return; + } + + const int nextSpineIndex = currentSpineIndex + 1; + if (nextSpineIndex < 0 || nextSpineIndex >= epub->getSpineItemsCount()) { + return; + } + + Section nextSection(epub, nextSpineIndex, renderer); + if (nextSection.loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), + SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, + viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, + SETTINGS.imageRendering)) { + return; + } + + LOG_DBG("ERS", "Silently indexing next chapter: %d", nextSpineIndex); + if (!nextSection.createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(), + SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth, + viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle, + SETTINGS.imageRendering)) { + LOG_ERR("ERS", "Failed silent indexing for chapter: %d", nextSpineIndex); + } +} + void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) { FsFile f; if (Storage.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) { diff --git a/src/activities/reader/EpubReaderActivity.h b/src/activities/reader/EpubReaderActivity.h index ad150e9a..ae46e7ee 100644 --- a/src/activities/reader/EpubReaderActivity.h +++ b/src/activities/reader/EpubReaderActivity.h @@ -41,6 +41,7 @@ class EpubReaderActivity final : public Activity { void renderContents(std::unique_ptr page, int orientedMarginTop, int orientedMarginRight, int orientedMarginBottom, int orientedMarginLeft); void renderStatusBar() const; + void silentIndexNextChapterIfNeeded(uint16_t viewportWidth, uint16_t viewportHeight); void saveProgress(int spineIndex, int currentPage, int pageCount); // Jump to a percentage of the book (0-100), mapping it to spine and page. void jumpToPercent(int percent);