Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch: Activities (migrated to new ActivityManager pattern): - Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity - Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity, DictionaryWordSelectActivity, LookedUpWordsActivity - Bookmark: EpubReaderBookmarkSelectionActivity - Book management: BookManageMenuActivity, EndOfBookMenuActivity - OPDS: OpdsServerListActivity, OpdsSettingsActivity - Utility: DirectoryPickerActivity, NumericStepperActivity Utilities (unchanged): - BookManager, BookSettings, BookmarkStore, BootNtpSync - Dictionary, LookupHistory, TimeSync, OpdsServerStore Libraries: PlaceholderCover, TableData, ChapterXPathIndexer Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover Docs: KOReader sync XPath mapping Migration changes: - ActivityWithSubactivity -> Activity base class - Callback constructors -> finish()/setResult() pattern - enterNewActivity() -> startActivityForResult() - Activity::RenderLock&& -> RenderLock&& These files won't compile yet - they reference mod settings and I18n strings that will be added in subsequent phases. Made-with: Cursor
2.8 KiB
Dictionary Feature Bug Fixes
Date: 2026-02-12
Branch: mod/add-dictionary
Task
Fix three bugs reported after initial implementation of PR #857 dictionary word lookup feature.
Changes Made
1. Fix: Lookup fails after first successful lookup (Dictionary.cpp)
Root cause: cleanWord() lowercases the search term, but the dictionary index is sorted case-sensitively (uppercase entries sort before lowercase). The binary search lands in the wrong segment on the second pass because the index is already loaded and the sparse offset table was built for a case-sensitive sort order.
Fix: Extracted the binary-search + linear-scan logic into a new searchIndex() private helper. The lookup() method now performs a two-pass search: first with the lowercased word, then with the first-letter-capitalized variant. This handles dictionaries that store headwords as "Hello" instead of "hello". Also removed stripHtml from the header since HTML is now rendered, not stripped.
Files: src/util/Dictionary.h, src/util/Dictionary.cpp
2. Fix: Raw HTML displayed in definitions (DictionaryDefinitionActivity)
Root cause: Dictionary uses sametypesequence=h (HTML format). The original activity rendered definitions as plain text.
Fix: Complete rewrite of the definition activity to render HTML with styled text:
- New
parseHtml()method tokenizes HTML intoTextAtomstructs (word + style + newline directives) - Supports bold (
<b>,<strong>, headings), italic (<i>,<em>), and mixed bold-italic viaEpdFontFamily::Style - Handles
<ol>(numbered with digit/alpha support),<ul>(bullet points), nested lists with indentation - Decodes HTML entities (named + numeric/hex → UTF-8)
- Skips
<svg>content, treats</html>as section separators wrapText()flows styled atoms into positioned line segments (Segmentstruct with x-offset and style)renderScreen()draws each segment with correct position and style viarenderer.drawText(fontId, x, y, text, true, style)
Files: src/activities/reader/DictionaryDefinitionActivity.h, src/activities/reader/DictionaryDefinitionActivity.cpp
3. Fix: No button hints on word selection screen (DictionaryWordSelectActivity)
Fix: Added GUI.drawButtonHints() call at the end of renderScreen() with labels: "« Back", "✓ Lookup", "↕ Row", "↔ Word".
Files: src/activities/reader/DictionaryWordSelectActivity.cpp
Follow-up Items
- If the reader font doesn't include bold/italic variants, styled text gracefully falls back to regular style
- Nested list indentation uses 15px per level after the first
- Alpha list numbering (
list-style-type: lower-alpha) is supported; other custom list styles fall back to numeric - Button hint labels may need tuning once tested on device (especially in landscape orientation)