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**_
This commit is contained in:
@@ -259,6 +259,7 @@ STR_SECTION_PREFIX: "Раздзел"
|
||||
STR_UPLOAD: "Адправіць"
|
||||
STR_BOOK_S_STYLE: "Стыль кнігі"
|
||||
STR_EMBEDDED_STYLE: "Убудаваны стыль"
|
||||
STR_FOCUS_READING: "Фокуснае чытанне"
|
||||
STR_OPDS_SERVER_URL: "URL OPDS сервера"
|
||||
STR_SCREENSHOT_BUTTON: "Зрабіць здымак экрана"
|
||||
STR_IMAGES: "Выявы"
|
||||
|
||||
@@ -287,6 +287,7 @@ STR_SECTION_PREFIX: "Secció "
|
||||
STR_UPLOAD: "Puja"
|
||||
STR_BOOK_S_STYLE: "Estil del llibre"
|
||||
STR_EMBEDDED_STYLE: "Estil incrustat"
|
||||
STR_FOCUS_READING: "Lectura enfocada"
|
||||
STR_OPDS_SERVER_URL: "URL del servidor OPDS"
|
||||
STR_FOOTNOTES: "Notes al peu"
|
||||
STR_NO_FOOTNOTES: "No hi ha notes al peu en aquesta pàgina"
|
||||
|
||||
@@ -264,6 +264,7 @@ STR_SECTION_PREFIX: "Sekce"
|
||||
STR_UPLOAD: "Nahrát"
|
||||
STR_BOOK_S_STYLE: "Styl knihy"
|
||||
STR_EMBEDDED_STYLE: "Vložený styl"
|
||||
STR_FOCUS_READING: "Soustředěné čtení"
|
||||
STR_OPDS_SERVER_URL: "URL serveru OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Udělat snímek obrazovky"
|
||||
STR_TILT_PAGE_TURN: "Otáčení stránek nakloněním"
|
||||
|
||||
@@ -287,6 +287,7 @@ STR_SECTION_PREFIX: "Afsnit "
|
||||
STR_UPLOAD: "Upload"
|
||||
STR_BOOK_S_STYLE: "Bogens stil"
|
||||
STR_EMBEDDED_STYLE: "Indlejret stil"
|
||||
STR_FOCUS_READING: "Fokuslæsning"
|
||||
STR_OPDS_SERVER_URL: "OPDS Server URL"
|
||||
STR_FOOTNOTES: "Fodnoter"
|
||||
STR_NO_FOOTNOTES: "Ingen fodnoter på denne side"
|
||||
|
||||
@@ -287,6 +287,7 @@ STR_SECTION_PREFIX: "Sectie "
|
||||
STR_UPLOAD: "Uploaden"
|
||||
STR_BOOK_S_STYLE: "Stijl van boek"
|
||||
STR_EMBEDDED_STYLE: "Ingebedde stijl"
|
||||
STR_FOCUS_READING: "Gefocust lezen"
|
||||
STR_OPDS_SERVER_URL: "OPDS-server URL"
|
||||
STR_FOOTNOTES: "Voetnoten"
|
||||
STR_NO_FOOTNOTES: "Geen voetnoten op deze pagina"
|
||||
|
||||
@@ -296,6 +296,7 @@ STR_SECTION_PREFIX: "Section "
|
||||
STR_UPLOAD: "Upload"
|
||||
STR_BOOK_S_STYLE: "Book's Style"
|
||||
STR_EMBEDDED_STYLE: "Embedded Style"
|
||||
STR_FOCUS_READING: "Focus Reading"
|
||||
STR_OPDS_SERVER_URL: "OPDS Server URL"
|
||||
STR_SET_SLEEP_COVER: "Set Cover"
|
||||
STR_FOOTNOTES: "Footnotes"
|
||||
|
||||
@@ -262,6 +262,7 @@ STR_SECTION_PREFIX: "Osio "
|
||||
STR_UPLOAD: "Lähetä"
|
||||
STR_BOOK_S_STYLE: "Kirjan tyyli"
|
||||
STR_EMBEDDED_STYLE: "Upotettu tyyli"
|
||||
STR_FOCUS_READING: "Keskittynyt lukeminen"
|
||||
STR_OPDS_SERVER_URL: "OPDS-palvelimen osoite"
|
||||
STR_SCREENSHOT_BUTTON: "Ota kuvakaappaus"
|
||||
STR_TILT_PAGE_TURN: "Sivunkääntö kallistamalla"
|
||||
|
||||
@@ -288,6 +288,7 @@ STR_SECTION_PREFIX: "Section "
|
||||
STR_UPLOAD: "Envoyer"
|
||||
STR_BOOK_S_STYLE: "Style du livre"
|
||||
STR_EMBEDDED_STYLE: "Style intégré"
|
||||
STR_FOCUS_READING: "Lecture focalisée"
|
||||
STR_OPDS_SERVER_URL: "URL serveur OPDS"
|
||||
STR_FOOTNOTES: "Notes de bas de page"
|
||||
STR_NO_FOOTNOTES: "Aucune note sur cette page"
|
||||
|
||||
@@ -289,6 +289,7 @@ STR_SECTION_PREFIX: "Abschnitt"
|
||||
STR_UPLOAD: "Hochladen"
|
||||
STR_BOOK_S_STYLE: "Buch-Stil"
|
||||
STR_EMBEDDED_STYLE: "Eingebetteter Stil"
|
||||
STR_FOCUS_READING: "Fokus-Lesen"
|
||||
STR_OPDS_SERVER_URL: "OPDS-Server-URL"
|
||||
STR_SCREENSHOT_BUTTON: "Screenshot aufnehmen"
|
||||
STR_FOOTNOTES: "Fußnoten"
|
||||
|
||||
@@ -284,6 +284,7 @@ STR_SECTION_PREFIX: "Szakasz "
|
||||
STR_UPLOAD: "Feltöltés"
|
||||
STR_BOOK_S_STYLE: "Könyv stílusa"
|
||||
STR_EMBEDDED_STYLE: "Beágyazott stílus"
|
||||
STR_FOCUS_READING: "Fókuszált olvasás"
|
||||
STR_OPDS_SERVER_URL: "OPDS szerver URL"
|
||||
STR_FOOTNOTES: "Lábjegyzetek"
|
||||
STR_NO_FOOTNOTES: "Nincsenek lábjegyzetek ezen az oldalon"
|
||||
|
||||
@@ -288,6 +288,7 @@ STR_SECTION_PREFIX: "Sezione "
|
||||
STR_UPLOAD: "Carica"
|
||||
STR_BOOK_S_STYLE: "Stile libro"
|
||||
STR_EMBEDDED_STYLE: "Stile integrato dell'epub"
|
||||
STR_FOCUS_READING: "Lettura focalizzata"
|
||||
STR_OPDS_SERVER_URL: "Server OPDS"
|
||||
STR_FOOTNOTES: "Note a piè pagina"
|
||||
STR_NO_FOOTNOTES: "Nessuna nota in questa pagina"
|
||||
|
||||
@@ -258,6 +258,7 @@ STR_SECTION_PREFIX: "Бөлім "
|
||||
STR_UPLOAD: "Жүктеп салу"
|
||||
STR_BOOK_S_STYLE: "Кітап стилі"
|
||||
STR_EMBEDDED_STYLE: "Кірістірілген стиль"
|
||||
STR_FOCUS_READING: "Зейінді оқу"
|
||||
STR_OPDS_SERVER_URL: "OPDS сервері URL"
|
||||
STR_NO_FILES_FOUND: "Файлдар табылмады"
|
||||
STR_IMAGES: "Суреттер"
|
||||
|
||||
@@ -284,6 +284,7 @@ STR_SECTION_PREFIX: "Dalis "
|
||||
STR_UPLOAD: "Įkelti"
|
||||
STR_BOOK_S_STYLE: "Knygos stilius"
|
||||
STR_EMBEDDED_STYLE: "Integruotas stilius"
|
||||
STR_FOCUS_READING: "Sufokusuotas skaitymas"
|
||||
STR_OPDS_SERVER_URL: "OPDS URL"
|
||||
STR_FOOTNOTES: "Išnašos"
|
||||
STR_NO_FOOTNOTES: "Šiame psl. išnašų nėra"
|
||||
|
||||
@@ -296,6 +296,7 @@ STR_SECTION_PREFIX: "Sekcja "
|
||||
STR_UPLOAD: "Wyślij"
|
||||
STR_BOOK_S_STYLE: "Styl książki"
|
||||
STR_EMBEDDED_STYLE: "Style wbudowane w EPUB"
|
||||
STR_FOCUS_READING: "Czytanie skupione"
|
||||
STR_OPDS_SERVER_URL: "URL serwera OPDS"
|
||||
STR_SET_SLEEP_COVER: "Ustaw okładkę"
|
||||
STR_FOOTNOTES: "Przypisy"
|
||||
|
||||
@@ -264,6 +264,7 @@ STR_SECTION_PREFIX: "Seção"
|
||||
STR_UPLOAD: "Enviar"
|
||||
STR_BOOK_S_STYLE: "Estilo do livro"
|
||||
STR_EMBEDDED_STYLE: "Estilo embutido"
|
||||
STR_FOCUS_READING: "Leitura focada"
|
||||
STR_OPDS_SERVER_URL: "URL do servidor OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Capturar tela"
|
||||
STR_TILT_PAGE_TURN: "Virar página por inclinação"
|
||||
|
||||
@@ -287,6 +287,7 @@ STR_SECTION_PREFIX: "Secţiune "
|
||||
STR_UPLOAD: "Încărcare"
|
||||
STR_BOOK_S_STYLE: "Stilul cărţii"
|
||||
STR_EMBEDDED_STYLE: "Stil încorporat"
|
||||
STR_FOCUS_READING: "Lectură concentrată"
|
||||
STR_OPDS_SERVER_URL: "URL server OPDS"
|
||||
STR_FOOTNOTES: "Note de subsol"
|
||||
STR_NO_FOOTNOTES: "Nicio notă de subsol"
|
||||
|
||||
@@ -291,6 +291,7 @@ STR_SECTION_PREFIX: "Раздел "
|
||||
STR_UPLOAD: "Отправить"
|
||||
STR_BOOK_S_STYLE: "Стиль книги"
|
||||
STR_EMBEDDED_STYLE: "Встроенный стиль"
|
||||
STR_FOCUS_READING: "Фокусное чтение"
|
||||
STR_OPDS_SERVER_URL: "URL OPDS сервера"
|
||||
STR_SCREENSHOT_BUTTON: "Сделать снимок экрана"
|
||||
STR_AUTO_TURN_ENABLED: "Автоперелистывание: "
|
||||
|
||||
@@ -284,6 +284,7 @@ STR_SECTION_PREFIX: "Razdelek "
|
||||
STR_UPLOAD: "Naloži"
|
||||
STR_BOOK_S_STYLE: "Slog knjige"
|
||||
STR_EMBEDDED_STYLE: "Vgrajen slog"
|
||||
STR_FOCUS_READING: "Fokusirano branje"
|
||||
STR_OPDS_SERVER_URL: "URL OPDS strežnika"
|
||||
STR_FOOTNOTES: "Opombe"
|
||||
STR_NO_FOOTNOTES: "Na tej strani ni opomb"
|
||||
|
||||
@@ -288,6 +288,7 @@ STR_SECTION_PREFIX: "Secc.:"
|
||||
STR_UPLOAD: "Subir"
|
||||
STR_BOOK_S_STYLE: "Estilo del libro"
|
||||
STR_EMBEDDED_STYLE: "Estilo integrado"
|
||||
STR_FOCUS_READING: "Lectura enfocada"
|
||||
STR_OPDS_SERVER_URL: "URL del servidor OPDS"
|
||||
STR_FOOTNOTES: "Pie de página"
|
||||
STR_NO_FOOTNOTES: "No hay notas al pie de esta página"
|
||||
|
||||
@@ -296,6 +296,7 @@ STR_SECTION_PREFIX: "Sektion"
|
||||
STR_UPLOAD: "Uppladdning"
|
||||
STR_BOOK_S_STYLE: "Bokstil"
|
||||
STR_EMBEDDED_STYLE: "Inbäddad stil"
|
||||
STR_FOCUS_READING: "Fokusläsning"
|
||||
STR_OPDS_SERVER_URL: "OPDS-serveradress"
|
||||
STR_SET_SLEEP_COVER: "Ställ in omslag"
|
||||
STR_FOOTNOTES: "Fotnoter"
|
||||
|
||||
@@ -262,6 +262,7 @@ STR_SECTION_PREFIX: "Bölüm "
|
||||
STR_UPLOAD: "Yükle"
|
||||
STR_BOOK_S_STYLE: "Kitabın Stili"
|
||||
STR_EMBEDDED_STYLE: "Gömülü Stil"
|
||||
STR_FOCUS_READING: "Odaklanmış Okuma"
|
||||
STR_OPDS_SERVER_URL: "OPDS Sunucu Adresi"
|
||||
STR_AUTO_TURN_ENABLED: "Otomatik Çevirme Etkin: "
|
||||
STR_AUTO_TURN_PAGES_PER_MIN: "Otomatik Çevirme (Dakikada Sayfa)"
|
||||
|
||||
@@ -292,6 +292,7 @@ STR_SECTION_PREFIX: "Розділ "
|
||||
STR_UPLOAD: "Завантажити"
|
||||
STR_BOOK_S_STYLE: "Стиль книги"
|
||||
STR_EMBEDDED_STYLE: "Вбудований стиль"
|
||||
STR_FOCUS_READING: "Фокусне читання"
|
||||
STR_OPDS_SERVER_URL: "URL сервера OPDS"
|
||||
STR_FOOTNOTES: "Примітки"
|
||||
STR_NO_FOOTNOTES: "На цій сторінці немає приміток"
|
||||
|
||||
Reference in New Issue
Block a user