Files
Vincent Politzer 4e5e2fe40a feat: focus reading (#1670)
## Summary

This PR introduces **Focus Reading**, a generic implementation of
artificial fixation points (similar to Bionic Reading) designed to
improve reading speed and focus by bolding the initial characters of
words. This is achieved by dynamically bolding characters during
indexing.

<img width="500" alt="Focus Reading on X3"
src="https://github.com/user-attachments/assets/94a632a5-82da-47be-957c-538b35bf84d9"
/>

### Implementation Details
#### Core Text Engine (`ParsedText`)
- Modified `ParsedText::addWord` to implement a custom bolding
algorithm. It uses a 45% ratio for bolding, with a minimum of 1
character and a maximum of 9.
- UTF-8 Safety: Integrated `utf8NextCodepoint` to ensure character
counting and string slicing occur at safe byte boundaries, preventing
corruption of multi-byte characters (e.g., accented letters or smart
quotes).
- Intelligent Tokenization: This correctly identifies and separates
"word" characters (letters, apostrophes, hyphens) from "non-word"
characters (numbers, brackets, smart quotes).
- Formatting Preservation: The logic ensures that punctuation is not
"stolen" for the bolding count and that existing styles (like italics or
underlines) are preserved across the bold/regular split.
- Processing at indexing stage reduces CPU load at render-time and
ensures layout/fit is unaffected.
- Split details are tracked with `wordIsFocusSuffix`. After splitting
and layout, suffixes are merged back into their preceding word entries
to prevent a doubling of RAM usage.

#### Settings and UI
- Version Management: Bumped `SECTION_FILE_VERSION` to `21`
- Global Settings: Added `focusReadingEnabled` to `CrossPointSettings`.
- User Interface: Added a new toggle in the "Reader" section of the
settings menu, positioned after the "Embedded Style" option.
- Localization: Added the `STR_FOCUS_READING` string

#### Plumbing
- Plumbed the `focusReadingEnabled` boolean through
`EpubReaderActivity`, `Section`, and `ChapterHtmlSlimParser` to ensure
the user's setting reaches the `ParsedText` constructor during chapter
indexing.

## Additional Context

### Files Changed
- `lib/Epub/Epub/ParsedText.h / .cpp`: Core fixation logic and UTF-8
tokenization.
- `lib/Epub/Epub/Section.h / .cpp`: Cache header updates and
invalidation logic.
- `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h / .cpp`: Plumbing the
setting to text blocks.
- `src/CrossPointSettings.h`: Data persistence for the new setting.
- `src/SettingsList.h`: UI toggle implementation.
- `src/activities/reader/EpubReaderActivity.cpp`: Handling settings
changes during reading sessions.
- `lib/I18n/translations/*.yaml`: UI strings.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES**_
2026-05-10 20:02:14 +02:00
..
2025-12-14 13:46:15 +11:00
2026-05-10 20:02:14 +02:00
2025-12-20 01:15:20 +11:00