Files
crosspoint-reader-mod/chat-summaries/2026-02-12_17-08-summary.md
cottongin dfbc931c14 mod: Phase 1 - bring forward mod-exclusive files with ActivityManager migration
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
2026-03-07 15:10:00 -05:00

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 into TextAtom structs (word + style + newline directives)
  • Supports bold (<b>, <strong>, headings), italic (<i>, <em>), and mixed bold-italic via EpdFontFamily::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 (Segment struct with x-offset and style)
  • renderScreen() draws each segment with correct position and style via renderer.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)