932a472835b67327fa4907d3c20d6a23f8079236
81
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f2e3d117dc | fix: Hanging indent causes overlapping words (#2324) | ||
|
|
9202522a39 |
refactor: Drop redundant self-class prefix on applyDirectionToEntry (#2325)
## Summary Non-functional cleanup: `ChapterHtmlSlimParser::` prefix is redundant when calling `applyDirectionToEntry` within `ChapterHtmlSlimParser` methods. --- ### AI Usage Did you use AI tools to help write this code? _**NO**_ |
||
|
|
3a1e9f3023 |
refactor: Dedupe wifi scan in-place without std::map (#2262)
## Summary `std::map` heap-allocates each node. Avoid using it for wifi SSID dedupe, and instead just dedupe in-place with the existing `networks` vector. Removed dead `ipAddress` member in `WifiNetworkInfo` struct. --- ### AI Usage Did you use AI tools to help write this code? _**PARTIALLY**_ |
||
|
|
b5b1f650e2 |
perf: Minimize string allocations in CSS parsing (#2263)
## Summary Use `std::string_view` and case-insensitive comparisons to avoid string allocations during CSS parsing. **Hot path:** `resolveStyle` (called per HTML start tag during chapter rendering) now does zero heap allocations. Previously it allocated a normalized tag string, a vector of class strings, and a composite key per class. For a chapter with ~2000 tags × 2 classes each, that's ~12 000 small short-lived allocations eliminated per page render — primarily a heap-fragmentation win on the ESP32-C3's ~380KB RAM. **Cold path:** CSS load no longer allocates per-rule selector vectors or per-token strings; `splitOnChar`/`splitWhitespace` are gone, replaced with callback-based tokenization (`forEachDelimitedToken`). **Behavioral notes:** - The selector `unordered_map` now uses an ASCII-case-insensitive hash/equal. Selectors are stored with their original case rather than pre-lowercased; the observable lookup result is unchanged. - `stripTrailingImportant` is now case-insensitive (per CSS spec; previously matched only lowercase `!important`). **Cache compatibility:** `CSS_CACHE_VERSION` unchanged. Old caches (lowercase selectors) load correctly under the new lookup; new caches will contain verbatim-case selectors — both forms work. --- ### AI Usage Did you use AI tools to help write this code? _**PARTIALLY**_ |
||
|
|
34e923d722 | chore: Pin PNGdec lib_dep to 1.1.6 (#2154) | ||
|
|
94d4b0c7bb | ci: Cache PlatformIO packages between runs (#2142) | ||
|
|
6dbfc29c7e | test: Migrate unit tests to gtest, integrate with CI (#2144) | ||
|
|
e9120888fa | refactor: Drop FsFile alias, use HalFile in downstream code (#2141) | ||
|
|
b53ac3d52c |
chore: Minor cleanup flagged by newer gcc (#2140)
## Summary Minor cleanup flagged by newer gcc: - Removed unused variables - Removed unimplemented function declaration - `static` -> `inline` to avoid per-TU duplication --- ### AI Usage Did you use AI tools to help write this code? _**NO**_ |
||
|
|
938ca3fac1 |
chore: Update version to 1.3.0 (#1827)
## Summary This release adds SD card fonts — the most-requested feature since launch — brings the X3 to first-class status, redesigns the on-screen keyboard, overhauls OPDS, and ships SD-card firmware updates. 144 changes from 53 contributors, 32 of whom are new to the project. **🔠 SD Card Fonts** Custom fonts are here. A complete font subsystem lets you install and use fonts beyond the three built-in families. A new `.cpfont` binary format packs multiple styles (regular, bold, italic, bold-italic) into a single file per size, with on-demand glyph loading from the SD card. A two-pass prewarm renderer bulk-reads glyphs per page, achieving near-flash performance for Latin text and viable CJK rendering. Fonts can be downloaded over WiFi directly from the device, uploaded via the web interface, or copied manually to the SD card. The build pipeline ships a 17-family font library (serif, sans, mono, accessibility) with CI distribution via a dedicated crosspoint-fonts repository. As a bonus, CJK characters no longer get spurious hyphens at line breaks, and an advance-table cache eliminates 30+ second stalls during CJK section indexing. **📱 X3 Comes of Age** The X3 graduates from initial bring-up to a proper target. Grayscale antialiasing is sharper, EPUB images render correctly, OTA updates work, and sleep screen dimensions are dialed in. The headline addition: gyroscope-based tilt page turning via the QMI8658 IMU — tilt the device to turn pages hands-free. SD-card firmware update support and X3 bootloader compatibility mean users can update without a USB connection. **⌨️ Redesigned On-Screen Keyboard** The keyboard has been completely redesigned with improved layout, better key feedback, and a fix for the space key barely moving the cursor. Text entry across WiFi setup, OPDS search, and KOSync login is noticeably smoother. **👁️ Focus Reading** A new reading mode bolds the initial characters of each word (similar to Bionic Reading) to create artificial fixation points, helping improve reading speed and focus. The bolding ratio is 45%, with a minimum of 1 character and a maximum of 9, applied dynamically during indexing. **📚 OPDS Overhaul** OPDS gains in-catalog search with next/prev page navigation, support for multiple servers, correct handling of relative paths and query parameters (fixing CopyParty compatibility), and KOReader-compatible download filenames. **🔤 Text Rendering Refinements** Combining marks (diacritics) now use font metrics for positioning instead of heuristics, proportional numeral spacing is supported, and differential rounding eliminates uneven inter-glyph gaps. Hyphenation now recognizes ISO 639-2 language codes, nested block-level CSS styles are tracked correctly, and horizontal CSS insets are capped at 2em to prevent runaway margins. Bookerly has been replaced with Noto Serif for licensing reasons. **🎨 New Theme: RoundedRaff** A new rounded theme joins the theme picker, with fixes for sleep cover crop grid artifacts. **🔋 Battery & Power** Battery percentage smoothing on the X4 eliminates jittery readings. A short press on the power button can be set to trigger a manual screen refresh — handy for clearing ghosting. **📶 WiFi & Networking** WiFi connections now self-heal from transient drops without manual intervention, and a dBm signal strength indicator appears during web server sessions. WiFi networks can be edited directly from the web UI. **🔄 KOSync** Reading position sync is significantly more accurate. The old character-offset approach frequently landed on the wrong paragraph after syncing between devices — the new xpath-based mapping syncs at the paragraph level, matching KOReader's own behavior. A separate fix switches the HTTP layer to `esp_http_client`, and the reader now releases ~65KB of EPUB heap before the TLS handshake — together these eliminate the out-of-memory crashes that plagued KOSync on large books. **🛡️ Stability** Two memory leaks patched, a wild pointer crash in JPEGDEC MCU_SKIP handling fixed, boot loops with large XTC files eliminated, legacy XTC headers supported, the OTA updater now streams GitHub release JSON instead of buffering it in RAM, and a JPEG downscaler y-axis scale factor bug is corrected. **🌐 Languages** Slovenian is new. Russian, Ukrainian, Swedish, Italian, and Spanish translations received significant updates. --- Also in this release: **SD-card firmware updates without USB**, **file extensions in the file browser**, **full path bar navigation**, **end-of-book navigation improvements**, **XTC status bar**, **smarter "Cover + Custom" sleep screens**, **set sleep cover from the BMP viewer**, **orientation-aware popups**, **page turn buttons that follow orientation**, **long-press delete for directories**, **context-aware screenshot filenames with book title**, **crash reason displayed on boot**, **empty line rendering in the TXT reader**, **wallpaper recency buffer to prevent clustering**, **font family deletion from the device**, **next/prev labels in the BMP viewer**, **non-breaking space justification fix**, **README guidance for USB-locked third-party Xteink units**, and a long tail of web UI polish, i18n memory optimizations, and code quality improvements. ## What's Changed ### Features * feat: add SD card font support with on-device download and web management by @adriancaruana, @znelson, @itsthisjustin, @jpirnay, and @mcrosson * feat: Initial support for the x3 by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/875 * feat: X3 grayscale antialiasing improvements by @juicecultus in https://github.com/crosspoint-reader/crosspoint-reader/pull/1607 * feat: X3 gyroscope-based tilt page turning via QMI8658 IMU by @juicecultus in https://github.com/crosspoint-reader/crosspoint-reader/pull/1636 * feat(update): SD-card firmware update + X3 bootloader compatibility by @eunchurn in https://github.com/crosspoint-reader/crosspoint-reader/pull/1786 * feat: self-heal from transient WiFi loss, add dBm indicator during WebServerActivity by @jeremydk in https://github.com/crosspoint-reader/crosspoint-reader/pull/1780 * feat: edit wifi networks in webui by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1743 * feat: add OPDS search support & next/prev page navigation by @rxmmah in https://github.com/crosspoint-reader/crosspoint-reader/pull/1462 * feat: Support for multiple OPDS servers by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1209 * feat: Adjust Navigation at End of Book by @nscheung in https://github.com/crosspoint-reader/crosspoint-reader/pull/1425 * feat: Display file extensions in File Browser by @CaptainFrito in https://github.com/crosspoint-reader/crosspoint-reader/pull/1019 * feat: show full path bar in file browser by @zgredex in https://github.com/crosspoint-reader/crosspoint-reader/pull/1411 * feat: enable manual screen refresh on power button short press by @bdeshi in https://github.com/crosspoint-reader/crosspoint-reader/pull/1626 * feat: Rework "Cover + Custom" sleep screens to show covers only when currently reading by @iandchasse in https://github.com/crosspoint-reader/crosspoint-reader/pull/1256 * feat: Set sleep cover from BMP viewer by @el in https://github.com/crosspoint-reader/crosspoint-reader/pull/1104 * feat: show crash reason on boot by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1453 * feat: Support for proportional numeral spacing by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1414 * feat: add orientation-aware popups for reader activities by @mrtnvgr in https://github.com/crosspoint-reader/crosspoint-reader/pull/1428 * feat: smooth battery percentage for x4 by @jonvex in https://github.com/crosspoint-reader/crosspoint-reader/pull/1635 * feat: context-aware screenshot filenames with book title by @jonstieglitz in https://github.com/crosspoint-reader/crosspoint-reader/pull/1589 * feat(theme): add roundedraff theme and fix sleep cover crop grid artifacts by @bunsoootchi in https://github.com/crosspoint-reader/crosspoint-reader/pull/918 * feat: Page turn button orientation change by @mchuck in https://github.com/crosspoint-reader/crosspoint-reader/pull/1069 * feat: Status bar for XTC files by @leecming82 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1849 * feat: enhance long press action to delete both files and directories by @WuTofu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1803 * feat: Added Slovenian translation by @thehijacker in https://github.com/crosspoint-reader/crosspoint-reader/pull/1551 * feat: focus reading by @vjapolitzer in https://github.com/crosspoint-reader/crosspoint-reader/pull/1670 * feat: add next / prev labels to bmp viewer by @Telemaniaka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1852 * feat: add font family deletion functionality by @WuTofu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1919 * feat: separate into "Download All" and "Update All" in font manager by @WuTofu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1955 * feat: verify CRC32 checksum for font files by @WuTofu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1904 * feat: increase default weight of Bitter font for improved rendering by @uxjulia in https://github.com/crosspoint-reader/crosspoint-reader/pull/1922 * feat: allow unnamed intervals by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1903 ### Fixes * fix: epub images not rendering correctly on x3 by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1572 * fix: OTA update on x3 and progress bar on x4 and x3 by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1805 * fix: boot looping when opening large XTC files by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1648 * fix: Wild pointer crash in JPEGDEC MCU_SKIP handling by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1627 * fix: two small memory leaks by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1628 * fix: use esp_http_client for KOSync to prevent TLS OOM on ESP32-C3 by @trilwu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1381 * fix: Read GH release JSON as stream in OTA updater by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1810 * fix: support legacy XTC file headers where pageTableOffset=48 by @uxjulia in https://github.com/crosspoint-reader/crosspoint-reader/pull/1816 * fix: Use font metrics for combining mark positioning by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1310 * fix: Use differential rounding for consistent inter-glyph spacing by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1413 * fix: Support hyphenation for EPUBs using ISO 639-2 language codes by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1461 * fix: Track block style stack for nested styles by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1582 * fix: cap per-side horizontal CSS inset at 2em by @rhoopr in https://github.com/crosspoint-reader/crosspoint-reader/pull/1694 * fix: increase loadable epub size by @CSCMe in https://github.com/crosspoint-reader/crosspoint-reader/pull/1638 * fix: Switch to xpath map for paragraph level syncing in KOSync by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1686 * fix: free Epub RAM and simplify KOSync navigation via ActivityManager by @wylanswets in https://github.com/crosspoint-reader/crosspoint-reader/pull/1860 * fix: improve KOSync bidirectional position matching accuracy by @wylanswets in https://github.com/crosspoint-reader/crosspoint-reader/pull/1897 * fix: Fix failing very first wifi connection attempt by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1521 * fix: avoid skipping chapter after screenshot by @Mraulio in https://github.com/crosspoint-reader/crosspoint-reader/pull/1625 * fix: back navigation from BMPViewer by @Telemaniaka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1597 * fix: Fix ghosting on exit of BMPViewer by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1432 * fix: make footnotes consider orientation for gutters by @Telemaniaka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1665 * fix: footnote link text by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1666 * fix: Erroneous navigation with long filenames in footnote links by @CSCMe in https://github.com/crosspoint-reader/crosspoint-reader/pull/1723 * fix: prevent wallpaper clustering with 16-entry recency buffer by @zgredex in https://github.com/crosspoint-reader/crosspoint-reader/pull/1606 * fix: webserver /delete API backward compatibility by @DianaNites in https://github.com/crosspoint-reader/crosspoint-reader/pull/1475 * fix: relative opds paths and query param with copyparty by @philips in https://github.com/crosspoint-reader/crosspoint-reader/pull/1535 * fix: use same file name as KOReader for OPDS downloads by @spfenwick in https://github.com/crosspoint-reader/crosspoint-reader/pull/1286 * fix: pressing space barely moves input cursor (#1729) by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1733 * fix: keyboard feedback #1644 by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1697 * fix: pluralize folder/file counts correctly in file list summary by @fain182 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1701 * fix: rendering bug of scrollbar in RoundedRaff theme by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1814 * fix: two roundedraff bugs by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1851 * fix: overlap in download font list layout by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1900 * fix: remove duplicate 'Download Fonts' menu entry and improve navigation by @zgredex in https://github.com/crosspoint-reader/crosspoint-reader/pull/1893 * fix: Add common ligatures to SD font conversion ranges by @znelson * fix: capture instantiateVariableFont return value by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1911 * fix: Roundraff theme home menu offset with no recent books by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1845 * fix: Missing navigation button labels in Roundedraff theme by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1905 * fix: gracefully resolve fonts missing variants by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1921 * fix: distribute justifyExtra to non-breaking space tokens by @prawnwhoyawns in https://github.com/crosspoint-reader/crosspoint-reader/pull/1783 * fix: remove percent rendering from activities by @mcrosson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1901 * fix: Restore performance in fontconvert_sdcard.py by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1924 * fix: Prepare SD card font caches from txt reader by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1973 * fix: make script help paths lightweight by @sabraman in https://github.com/crosspoint-reader/crosspoint-reader/pull/1937 * fix: Replaced Bookerly with Noto Serif for licensing reasons by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1736 * fix: incorrect y-axis scale factor in jpeg nearest-neighbor downscaler by @WuTofu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1807 * fix: display empty lines in txt reader by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1841 * fix: short-press power action triggered after screenshot combo release by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1853 * fix: correct Russian auto-turn translations by @a-ignatev in https://github.com/crosspoint-reader/crosspoint-reader/pull/1566 * fix: Update Ukrainian translations for footnotes (issue 1409) by @mirus-ua in https://github.com/crosspoint-reader/crosspoint-reader/pull/1585 * fix: missing swedish translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1667 * fix: Add swedish keyboard translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1726 * fix: swedish translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1762 * fix: swedish translation by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1829 * fix: swedish translation by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1888 * fix: Polish translation by @th0m4sek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1909 * fix: Ukrainian-translation by @KymAndriy in https://github.com/crosspoint-reader/crosspoint-reader/pull/1946 * fix: Ukrainian translation by @KymAndriy in https://github.com/crosspoint-reader/crosspoint-reader/pull/1939 * fix: python requirements files by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1768 * fix: missing requirement by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1896 * fix: Use LOG_ macros in loc functions by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1794 ### Internal * refactor: redesign on-screen keyboard by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1644 * refactor: replace picojpeg with JPEGDEC for cover art conversion by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1517 * refactor: Refactor drawArc / fillArc for faster execution by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1540 * perf: replace i18n pointer tables with offset tables, strip unused strings by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1408 * refactor: Store only unique localization strings in offset buffers by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1802 * refactor: Move language setting into JSON settings by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1796 * refactor: Use C++20 'requires' in ActivityResult constructor by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1420 * refactor: Use default member initializers for JpegContext and PngContext by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1435 * refactor: logPrintf and predefined log level strings by @CSCMe in https://github.com/crosspoint-reader/crosspoint-reader/pull/1546 * refactor: RAII scoped open/close for ZipFile by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1433 * refactor: Deduplicated BMP header writing in Xtc by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1439 * refactor: Added shared XML parser teardown helper by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1438 * refactor: Removed redundant FsFile close() calls by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1434 * refactor: Deduplicate battery drawing code and fix Lyra charging indicator by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1437 * refactor: Deduplicate Roundraff battery drawing by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1847 * refactor: Simplify sort in GfxRenderer::fillPolygon by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1817 * refactor: Avoid vector for page turn rates list by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1818 * refactor: Use std::size instead of sizeof/sizeof by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1819 * refactor: Use fixed-size integers for BookMetadataCache data by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1844 * refactor: Simplify isReaderActivity bookkeeping by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1838 * refactor: Simplify XtcReaderActivity with detectPageTurn by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1837 * refactor: change ukrainian translation to adaptation and add missing lines by @KymAndriy in https://github.com/crosspoint-reader/crosspoint-reader/pull/1828 * chore: drop JPEGDEC patch in favour of upstream fix by @martinbrook in https://github.com/crosspoint-reader/crosspoint-reader/pull/1465 * chore: clang-format.fix.ps1 script: Add .venv to list of path exclusions by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1515 * chore: Updating sleep screen dimensions for X3 by @jensechu in https://github.com/crosspoint-reader/crosspoint-reader/pull/1688 * chore: Clarify X3 RTC in SCOPE.md by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1687 * chore: Improved Italian translations by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1685 * chore: change ukrainian translation to adaptation by @KymAndriy in https://github.com/crosspoint-reader/crosspoint-reader/pull/1684 * chore: Update spanish.yaml by @mvidelatraduc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1717 * chore: One Italian translation tweak by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1718 * chore: git pre-commit hook for format fix by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1730 * chore: Update SDK to fork in CrossPoint org by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1836 * chore: Added RAM to firmware_size_history.py script by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1830 * chore: Updated docs to reflect DESTRUCTOR_CLOSES_FILE=1 by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1878 * feat: cap compressed group size at 64 KB by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1913 * fix: build-script bug fixes for fontconvert{,_sdcard}.py by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1910 * feat: include short SHA in CROSSPOINT_VERSION by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1728 * feat: show long branch names by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1727 * feat: enable pio build cache by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1769 * style: put page name first in browser titles by @fain182 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1703 * style: unify page headers across web UI by @fain182 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1702 * style: move file type badges into Type column by @fain182 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1793 * style: align action buttons vertically with page title by @fain182 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1795 * docs: Update README with firmware flashing instructions by @ryneches in https://github.com/crosspoint-reader/crosspoint-reader/pull/1654 * docs: fix typos by @kianmeng in https://github.com/crosspoint-reader/crosspoint-reader/pull/1705 * docs: update README.md to reflect the current state of crosspoint by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1812 * docs: Add documentation for USB-locked Xteink devices by @itsthisjustin in https://github.com/crosspoint-reader/crosspoint-reader/pull/1990 * docs: expand first use of OPDS acronym and provide a wikipedia link by @sizezero in https://github.com/crosspoint-reader/crosspoint-reader/pull/1824 * docs: fix KOReader sync guide link by @sabraman in https://github.com/crosspoint-reader/crosspoint-reader/pull/1930 * docs: fix hyphenation updater script name by @sabraman in https://github.com/crosspoint-reader/crosspoint-reader/pull/1931 * fix: sd font download urls in docs by @mcrosson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1945 * fix: sd font folder paths in documentation by @mcrosson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1944 * chore: Add verbose mode to build-sd-fonts.py by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1923 ## New Contributors * @a-ignatev made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1566 * @CSCMe made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1546 * @thehijacker made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1551 * @Telemaniaka made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1597 * @Mraulio made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1625 * @rxmmah made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1462 * @bdeshi made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1626 * @DianaNites made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1475 * @ryneches made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1654 * @zgredex made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1411 * @jonvex made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1635 * @KymAndriy made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1684 * @jensechu made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1688 * @kianmeng made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1705 * @philips made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1535 * @fain182 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1701 * @mvidelatraduc made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1717 * @bunsoootchi made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/918 * @rhoopr made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1694 * @spfenwick made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1286 * @trilwu made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1381 * @jonstieglitz made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1589 * @uxjulia made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1816 * @mchuck made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1069 * @sizezero made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1824 * @leecming82 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1849 * @jeremydk made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1780 * @WuTofu made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1803 * @wylanswets made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1860 * @sabraman made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1930 * @prawnwhoyawns made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1783 * @mcrosson made their first contribution as co-author on SD card font support **Full Changelog**: https://github.com/crosspoint-reader/crosspoint-reader/compare/1.2.0...release/1.3.0 --------- Co-authored-by: Justin Mitchell <justin@jmitch.com> Co-authored-by: Chun Ming Lee <95391408+leecming82@users.noreply.github.com> Co-authored-by: Uri Tauber <uritaube@gmail.com> |
||
|
|
b186529120 |
fix: Prepare SD card font caches from txt reader (#1973)
## Summary SD card font fixes: - `TxtReaderActivity` needs to call `renderer.ensureSdCardFontReady` to build the advance lookup table to support rendering with SD card fonts. This revealed that `TxtReaderActivity` was inconsistently performing layout with `getTextWidth`, when the renderer actually uses `getTextAdvanceX`, which can lead to minor inconsistencies in alignment. - Avoid allocating one big `allText` string in `ParsedText::layoutAndExtractLines`. Instead, pass the vector of word strings directly to `SdCardFont::buildAdvanceTable`, where the algorithm just needs to iterate codepoints anyway. --- ### 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? _**PARTIALLY**_ --------- Co-authored-by: Justin Mitchell <justin@jmitch.com> |
||
|
|
aa43bd3569 |
chore: Removed unused icon header files (#1975)
## Summary Deleted two unused header files containing binary icon data. --- ### 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? _**NO**_ |
||
|
|
8377ac9e31 |
refactor: Added utils for non-throwing memory allocation and scoped cleanup (#1832)
## Summary
Pared down version of #1418.
Following up on
|
||
|
|
30b14f2ecf |
refactor: Removed SdCardFontGlobals.h (#1962)
## Summary First of several changes to decouple and clean up SD card fonts integration. This change eliminates SdCardFontGlobals.h: - Simply declare the `extern SdCardFontSystem sdFontSystem` in SdCardFontSystem.h. - `ActivityManager::goToReader` should not care about loading SD card fonts. Instead do the same work in `ReaderActivity::onEnter`, after the previous activity has exited and after ReaderActivity has validated the file path. --- ### 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? _**NO**_ |
||
|
|
6f7f4c592a |
refactor: Eliminated relative path includes (#1961)
## Summary Relative includes can hide inappropriate dependency relationships. In this case, I found that lib/KOReaderSync/KOReaderCredentialStore.cpp was dependent on src/JsonSettingsIO.h -- a lib -> app dependency, the opposite direction dependencies should flow in this project. This change replaces all relative includes with root-relative includes, and corrects the KOReaderCredentialStore dependency by moving its JSON settings serialization local to the KOReaderSync library. --- ### 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? _**PARTIALLY**_ |
||
|
|
63d5094f2e |
Revert "feat: closest-pt size selection instead of ordinal slot" (#1949)
Reverts crosspoint-reader/crosspoint-reader#1912 This was meant to be more robust with partial SD card fonts, but causes trouble for folks using custom font sizes. We need a better approach to decouple numeric font sizes from S/M/L/XL settings. |
||
|
|
2ff63884d6 |
fix: Restore performance in fontconvert_sdcard.py (#1924)
## Summary #1910 caused a massive performance degradation in the way rasterized glyph buffers were handled during pixel iteration. This change restores the original performance characteristics so the font generation job finishes in a reasonable amount of time. --- ### 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**_ |
||
|
|
74b8cac928 |
chore: Add verbose mode to build-sd-fonts.py (#1923)
## Summary One of the recent font conversion script changes obliterated performance. Add a verbose mode to build-sd-fonts.py to help diagnose problems. Changed the CI process to use verbose mode. --- ### 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**_ |
||
|
|
628794f8b8 | fix: Add common ligatures to SD font conversion ranges | ||
|
|
a48ad3cd61 |
chore: Updated docs to reflect DESTRUCTOR_CLOSES_FILE=1 (#1878)
## Summary
Follow-up to
|
||
|
|
e841c84194 |
refactor: Deduplicate Roundraff battery drawing (#1847)
## Summary Deduplicated battery drawing code for Roundraff theme with other themes. Now `BaseTheme` provides non-virtual `drawBatteryLeft` and `drawBatteryRight` methods, which use a shared static `drawBatteryOutline` implementation, and defer to a virtual `fillBatteryIcon` implementation. In Classic and Roundraff `fillBatteryIcon` uses a solid fill, while Lyra and Lyra Extended use a segmented fill. The charging indicator inside the battery was missing for Roundraff, but is now consistent with other themes because of the shared drawing implementation. --- ### 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? _**PARTIALLY**_ |
||
|
|
83f0cee565 |
fix: Roundraff theme home menu offset with no recent books (#1845)
## Summary
With the Roundraff theme selected and no recent books, the home screen
menu shows a "Continue Reading" option and menu handling is offset by
one ("Continue Reading" actually does "Browse Files", "File Transfer"
actually does "Settings", etc.) Simple fix here is to omit the "Continue
Reading" menu item when there are no recent books.
---
### 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? _**NO**_
|
||
|
|
11bc36ebb5 | refactor: Use fixed-size integers for BookMetadataCache data (#1844) | ||
|
|
395e68ea2b |
refactor: Simplify isReaderActivity bookkeeping (#1838)
## Summary Before, any sub-activity of a reader activity needed to override `isReaderActivity` to maintain correct bookkeeping through `ActivityManager::isReaderActivity`. We could easily miss this in any new sub-activities. Instead, simplify so each reader activity correctly reports and then `ActivityManager` checks for any reader activity in its stack. --- ### 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? _**NO**_ |
||
|
|
cfe3a948a0 |
refactor: Simplify XtcReaderActivity with detectPageTurn (#1837)
## Summary Simplify duplicated code in `XtcReaderActivity` to use `ReaderUtils::detectPageTurn`. This implementation is now shared with `EpubReaderActivity` and `TxtReaderActivity`. Also deduplicated the chapter skip time constant. --- ### 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? _**PARTIALLY**_ |
||
|
|
4ea938b709 |
chore: Update SDK to fork in CrossPoint org (#1836)
## Summary Update the Open X4 SDK to point to the CrossPoint organization fork. This allows us to take SDK changes without being blocked on the upstream repository. --- ### 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? _**NO**_ |
||
|
|
78625afe76 |
chore: Added RAM to firmware_size_history.py script (#1830)
## Summary Added RAM delta output to firmware_size_history.py output, e.g.: ``` % scripts/firmware_size_history.py --commits |
||
|
|
333286acfc |
refactor: Use std::size instead of sizeof/sizeof (#1819)
## Summary Simplify code calculating compile-time array sizes with `sizeof(array)/sizeof(element)` to use `std::size`. --- ### 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? _**PARTIALLY**_ |
||
|
|
6c4ae7c41a |
refactor: Avoid vector for page turn rates list (#1818)
## Summary Small cleanup to avoid a dynamically allocated static structure for auto page-turn rate values. --- ### 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? _**NO**_ |
||
|
|
a5fac320ab |
refactor: Simplify sort in GfxRenderer::fillPolygon (#1817)
## Summary Small simplification to node sorting algorithm in GfxRenderer::fillPolygon. --- ### 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? _**NO**_ |
||
|
|
aa7a31b3db |
fix: Read GH release JSON as stream in OTA updater (#1810)
## Summary The GitHub recent release API returns lots of data, including the full release notes. For 1.2.0, that data is 30,530 bytes. The existing OtaUpdater HTTP handler and single-buffer JSON parsing can't reliably handle that much data in the constrained ESP32 environment. This change does a few things: 1. Adds a very simple lib/JsonParser/StreamingJsonParser.cpp with SAX-style callbacks to read JSON data incrementally. 2. Adds a very simple lib/JsonParser/ReleaseJsonParser.cpp building on StreamingJsonParser, which specifically parses the GitHub release JSON for the release version, URL, and size. 3. Updates OtaUpdater.cpp to use an instance of ReleaseJsonParser to incrementally parse the large response it may receive from GitHub. Building from this commit while overriding my local version to 1.1.9, I was able to run the OTA update process ~5 times in a row successfully. Fixes #1561 (second part, after #1805). --- ### 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**_ |
||
|
|
64ecfe2ef3 |
refactor: Store only unique localization strings in offset buffers (#1802)
## Summary Omit any duplicate strings in non-English localization lookup tables. For non-English lookup offsets, tag bit 15 to indicate the offset applies to the English localization table. Saves 18,766 bytes of flash. --- ### 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? _**PARTIALLY**_ |
||
|
|
b25389b43e |
refactor: Move language setting into JSON settings (#1796)
## Summary
Another follow up to #1408. That PR revised the language.bin settings
file to version 2. After merging, it occurred to me that it would make
more sense to have the language inside the overall settings.json file,
easy for users to see and change directly.
This change adds migration from language.bin to settings.json. It only
migrates from the pre-#1408 v1 language.bin format, because v2 has only
been in for a couple of commits and I don't think we need long-term
maintenance code to handle it.
#1408 had a potential long-term maintenance issue for migration. It
assumed that the enum order of languages never changes, only grows. So,
e.g. "Portuguese (Portugal)" could never be added next to "Portuguese
(Brazil)", only appended. This change includes a hardcoded frozen
ordering of the language indices as they existed at
|
||
|
|
ae865f6d08 |
fix: Use LOG_ macros in loc functions (#1794)
## Summary
Quick follow up to #1408. We overlooked the fact that the change wasn't
using the LOG_ macros. Also, removed redundant file.close() calls, as in
|
||
|
|
15e0d39d2c |
Revert "feat: Add royalty.dev funding integration" (#1745)
Reverts crosspoint-reader/crosspoint-reader#1741 I don't entirely understand Royalty.dev and want to vet this further. |
||
|
|
c5f82709c0 |
fix: Replaced Bookerly with Noto Serif for licensing reasons (#1736)
## Summary Fixes #258. Bookerly is not licensed for use in CrossPoint. Switched to Google's open Noto Serif font. --- ### 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? _**NO**_ |
||
|
|
5e26baef63 |
chore: One Italian translation tweak (#1718)
## Summary Following up on #1685. One tweaked string confirmed by @alan0ford. --- ### 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? _**NO**_ |
||
|
|
64f5ef018a |
feat: Support for proportional numeral spacing (#1414)
## Summary **What is the goal of this PR?** Reading a book with frequent numbers, I noticed that the spacing between numeral glyphs was strangely large. This was because Bookerly and Noto Sans default to tabular figures, where every digit gets an identical advance width. This is designed for column alignment in spreadsheets, but in rendering prose it produces visually wide gaps between digits. This change adds a `--pnum` flag to fontconvert.py that applies the font's OpenType `pnum` (proportional numerals) feature during conversion. When active, the converter: - Parses the GSUB table for pnum SingleSubst lookups - Resolves substitute glyph indices via fonttools' glyph order - Loads the proportional alternate glyphs instead of the tabular defaults - Includes substitute glyph names in kern pair extraction, so kerning data that references proportional alternates is captured Bookerly's proportional alternates also carry digit-digit and digit-punctuation kerning that the tabular glyphs lack (e.g., at 16pt 7->4 at -1.69px, 7->. at -2.31px, 7->1 at +1.00px). Noto Sans gains proportional advances but no new kerning (its proportional glyphs have no kern class data in the font). OpenDyslexic is unaffected. Its `cmap` already points to proportional glyphs, so `--pnum` is a no-op. `--pnum` is intentionally omitted from OpenDyslexic in the build script for deliberately uniform digit spacing as an accessibility choice. UI fonts (Ubuntu, notosans_8) also omit `--pnum` to preserve tabular alignment for page numbers, battery percentages, etc. | Before | After | | -- | -- | | <img src="https://github.com/user-attachments/files/26042238/screenshot-31673.bmp" width="300" /> | <img src="https://github.com/user-attachments/files/26042241/screenshot-124075.bmp" width="300" /> | --- ### 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**_ |
||
|
|
3cdfc6c781 |
chore: Improved Italian translations (#1685)
## Summary Improved Italian translations provided by @alan0ford, closes #1578. --- ### 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? _**NO**_ |
||
|
|
a888978f95 |
chore: Clarify X3 RTC in SCOPE.md (#1687)
## Summary Clarify that X3 device has a reliable RTC chip, so clock feature can be in-scope depending on device. --- ### 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? _**NO**_ |
||
|
|
ce1756e36f |
refactor: Added shared XML parser teardown helper (#1438)
## Summary **What is the goal of this PR?** Added `destroyXmlParser()` helper to replace the repeated 4-line parser cleanup block (stop, clear callbacks, free, null) that was copyied across 6 XML parser files. --- ### 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? _**PARTIALLY**_ |
||
|
|
1bd7a1de67 |
refactor: Deduplicate battery drawing code and fix Lyra charging indicator (#1437)
## Summary **What is the goal of this PR?** Following up on #1427: - Extracted shared battery drawing logic, including lightning bolt, to reduce duplication. - In Lyra with segmented battery the lightning bolt was hard to see, so when charging Lyra now uses a solid battery fill. --- ### 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? _**PARTIALLY**_ |
||
|
|
23aad213fc |
refactor: Removed redundant FsFile close() calls (#1434)
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) `DESTRUCTOR_CLOSES_FILE=1` is set in platformio.ini, which makes SdFat's FsBaseFile destructor call close() automatically when a file goes out of scope. Three categories of file close calls remain untouched: 1. Close before Storage.remove() on the same path: ScreenshotUtil.cpp closes the file before deleting it on write error. The remove might fail if the file is still open. 2. Close before reopening the same variable: Epub.cpp writes a temp NCX/nav file, closes it, then reopens it for reading. The RecentBooksStore.cpp close before saveToFile() is the same pattern, it rewrites the same file. 3. Close on member variables: BookMetadataCache.cpp (bookFile, spineFile, tocFile), Section.cpp (file), XtcParser.cpp (m_file), ZipFile.cpp (file). These persist beyond any single function scope, so the destructor timing doesn't match the intended close point. --- ### 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? _**PARTIALLY**_ |
||
|
|
075ad7d021 |
fix: Use font metrics for combining mark positioning (#1310)
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Combining diacritical marks (U+0300–U+036F) were positioned using a heuristic that centered them at the midpoint of the base glyph's **advance width**. This worked acceptably for Bookerly but produced visibly off-center marks for Noto Sans due to a fundamental difference in how the two fonts design their combining mark metrics. Builds on the work of #1037. ## The problem The two built-in body fonts encode combining mark `left` offsets with very different conventions: | Mark | Bookerly `left` | Noto Sans `left` | |---|---|---| | U+0301 (acute) | -2 | -10 | | U+0300 (grave) | -5 | -15 | | U+0302 (circumflex) | -5 | -5 | | U+0323 (dot below) | -2 | -11 | Noto Sans uses large negative `left` values because its marks are designed for placement at the post-advance cursor position, with `left` pulling the bitmap back over the base glyph. Bookerly uses small offsets because its marks sit closer to the glyph origin. The old `advance/2` centering split the difference poorly — it happened to land close to correct for Bookerly but placed Noto Sans marks roughly 6px left of center on a typical lowercase letter. There was also a bug in the vertical gap heuristic. It unconditionally computed a `raiseBy` value to prevent above-baseline marks from colliding with tall base glyphs, but it applied the same logic to **below-baseline** marks like cedilla (U+0327), dot below (U+0323), and ogonek (U+0328). For those marks, the math produced a large positive raise (e.g., 24px for dot-below on 'a'), launching them above the x-height instead of keeping them below the baseline. ## The fix **Horizontal positioning**: Instead of centering at `advance/2`, align the mark bitmap's visual midpoint directly over the base glyph bitmap's visual midpoint. This uses the base glyph's actual `left` and `width` rather than its advance width, producing correct results regardless of how the font encodes its mark offsets. **Vertical positioning**: The raise heuristic now checks `markTop - markHeight > 0` and skips below-baseline marks entirely, leaving them at their font-designed position. **Consolidation**: The shared math is extracted into two `constexpr` helpers (`combiningMark::centerOver` and `combiningMark::raiseAboveBase`) in `EpdFontData.h`, eliminating the previously triplicated inline calculations across `drawText`, `drawTextRotated90CW`, and `getTextBounds`. The `MIN_COMBINING_GAP_PX` constant is also centralized as `combiningMark::MIN_GAP_PX`. | Before | After | | -- | -- | | <img src="https://github.com/user-attachments/files/25752257/before-noto.bmp" width="250" /> | <img src="https://github.com/user-attachments/files/25752258/after-noto.bmp" width="250" /> | | <img src="https://github.com/user-attachments/files/25752259/before-bookerly.bmp" width="250" /> | <img src="https://github.com/user-attachments/files/25752260/after-bookerly.bmp" width="250" /> | --- ### 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 to analyze differences between Noto Sans and Bookerly font metrics**_ --------- Co-authored-by: Uri Tauber <142022451+Uri-Tauber@users.noreply.github.com> |
||
|
|
5ba85290ab |
refactor: Deduplicated BMP header writing in Xtc (#1439)
## Summary **What is the goal of this PR?** Replaced manual 1-bit BMP header logic in `Xtc::generateCoverBmp()` and `Xtc::generateThumbBmp()` with calls to the existing `createBmpHeader()` utility. Added a `BmpRowOrder` enum and param to support the top-down row order of XTC cover images. --- ### 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? _**PARTIALLY**_ |
||
|
|
b3b43bb373 |
refactor: RAII scoped open/close for ZipFile (#1433)
## Summary **What is the goal of this PR?** Added `ScopedOpenClose` RAII guard to eliminate repetitive `wasOpen`/`close()` boilerplate across all ZipFile methods. --- ### 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? _**PARTIALLY**_ |
||
|
|
1398aeb1ed |
fix: Use differential rounding for consistent inter-glyph spacing (#1413)
## Summary **What is the goal of this PR?** A tweak to the fixed-point x-advance and kerning calculations to ensure that the spacing between any two glyphs is always calculated consistently. I noticed that sometimes I'd see common character pairs like "oo" more than once on a page, and the distance between the two snapped to different pixels depending on the running accumulated error for the line of text. This change uses a differential rounding approach where each glyph's x-advance plus the kerning relative to the next glyph are combined in fixed-point precision, then snapped to a pixel to draw the next glyph. This results in a consistent inter-glyph spacing any time the same two glyphs show up adjacent to each other, regardless of the accumulated error across the line. --- ### 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? _**PARTIALLY**_ |
||
|
|
f429f9035c |
refactor: Use default member initializers for JpegContext and PngContext (#1435)
## Summary **What is the goal of this PR?** Replace verbose constructor initializer lists with in-class default member initializers in JpegContext and PngContext --- ### 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? _**NO**_ |
||
|
|
11984f8fef |
refactor: Use C++20 'requires' in ActivityResult constructor (#1420)
## Summary **What is the goal of this PR?** Replace SFINAE std::enable_if_t with a C++20 `requires` clause for clearer constraint expression and better compiler diagnostics on mismatch. --- ### 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? _**NO**_ |
||
|
|
1c13331189 |
fix: Support hyphenation for EPUBs using ISO 639-2 language codes (#1461)
## Summary EPUBs that use ISO 639-2 three-letter language codes in their `dc:language` metadata (e.g. `<dc:language>eng</dc:language>`) got no hyphenation. The hyphenator registry only matched ISO 639-1 two-letter codes (`"en"`, `"fr"`, etc.), so `"eng"` produced a null hyphenator and every word in the book was treated as unhyphenatable. Added a normalization step in `hyphenatorForLanguage` that maps ISO 639-2 codes (both bibliographic and terminological variants) to their two-letter equivalents before the registry lookup. Discovered via *Project Hail Mary* (Random House), which uses `<dc:language>eng</dc:language>`. --- ### 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? _**PARTIALLY**_ |
||
|
+7 |
e6c6e72a24 |
chore(release): 1.2.0 Release Candidate (#1483)
Compile Release / build-release (push) Canceled after 0s
## Summary It's been a little while since the last release, but the community has been incredibly busy. With 155 changes from 48 contributors (30 of which were new!), there was a lot to cover. Here are some of the highlights: **🔤 Kerning, Ligatures, and Font Improvements** Text rendering gets a significant upgrade with proper kerning and ligature support, fixed-point fractional x-advance for more accurate character placement, and font compression improvements that reduce flash usage. **📝 Footnotes** Footnote anchor navigation lets you select a footnote reference and jump to the footnote text, then jump back. Slim footnotes support is also available for books that use inline footnotes. **📖 EPUB Optimizer** A new integrated EPUB optimizer can clean up and reprocess books for better compatibility with the reader, directly from the device. **🔋 Battery Charging Indicator** You can now see when your device is actively charging, with a visual indicator on the battery icon. **💾 Crash Diagnostics** When something goes wrong, the firmware now dumps a crash report to the SD card — even without USB plugged in. This makes it much easier to report and diagnose issues. **🌐 New Languages** The community continues to expand language support. New in this release: Turkish, Danish, Finnish, Polish, Dutch, Belarusian, Italian, Ukrainian, Romanian, Catalan, Vietnamese, and Kazakh — along with significant improvements to existing translations. **📂 File Management** Multi-select file deletion, BMP image viewer in the file browser, hidden directory browsing, and long-click file deletion from the file browser. **⚡ Performance** Under the hood, text layout switched from `std::list` to `std::vector`, HTML entity lookups are now O(log(n)), font rendering is faster, image decode is 5-20% faster with per-pixel overhead eliminated, and multiple string allocation hot paths were eliminated. Pre-indexing of the next chapter also reduces page-turn latency at chapter boundaries. --- Along with all of the above, there are many other additions including **WebDAV support**, **auto page turn**, **QR code for current page**, **split status bar settings**, **screenshot capture**, **JSON-based settings migration**, **light/dark theme groundwork**, and a long list of stability fixes and translation improvements. ## What's Changed ### Features * feat: Support for kerning and ligatures by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/873 * feat: footnote anchor navigation by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1245 * feat: slim footnotes support by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1031 * feat: integrated epub optimizer by @zgredex and @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1224 * feat: battery charging indicator (mirroring PR #537) by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1427 * feat: dump crash report to sdcard by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1145 * feat: Implement silent pre-indexing for the next chapter in EpubReaderActivity by @LSTAR1900 in https://github.com/crosspoint-reader/crosspoint-reader/pull/979 * feat: upgrade platform and support webdav by @dexif in https://github.com/crosspoint-reader/crosspoint-reader/pull/1047 * feat: Auto Page Turn for Epub Reader by @GenesiaW in https://github.com/crosspoint-reader/crosspoint-reader/pull/1219 * feat: enhance file deletion functionality with multi-select by @Jessica765 in https://github.com/crosspoint-reader/crosspoint-reader/pull/682 * feat: Long Click for File Deletion through File Browser by @Levrk in https://github.com/crosspoint-reader/crosspoint-reader/pull/909 * feat: Take screenshots by @el in https://github.com/crosspoint-reader/crosspoint-reader/pull/759 * feat: Current page as QR by @el in https://github.com/crosspoint-reader/crosspoint-reader/pull/1099 * feat: Download links for web server by @el in https://github.com/crosspoint-reader/crosspoint-reader/pull/1039 * feat: Added BmpViewer activity for viewing .bmp images in file browser by @Levrk in https://github.com/crosspoint-reader/crosspoint-reader/pull/887 * feat: User setting for image display by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1291 * feat: Show hidden directories in browser by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1288 * feat: Prefer ".sleep" over "sleep" for custom image directory by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/948 * feat: Allow a local configuration file for custom compiles by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/879 * feat: Migrate binary settings to json by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/920 * feat: split status bar setting by @whyte-j in https://github.com/crosspoint-reader/crosspoint-reader/pull/733 * feat: wrapped text in GfxRender, implemented in themes so far by @iandchasse in https://github.com/crosspoint-reader/crosspoint-reader/pull/1141 * feat: Themed language screen by @CaptainFrito in https://github.com/crosspoint-reader/crosspoint-reader/pull/1020 * feat: set WiFi hostname to CrossPoint-Reader-XXXXXXXXXXXX by @dexif in https://github.com/crosspoint-reader/crosspoint-reader/pull/1107 * feat: Add maxAlloc to memory information by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1152 * feat: replace picojpeg with JPEGDEC for JPEG image decoding by @martinbrook in https://github.com/crosspoint-reader/crosspoint-reader/pull/1136 * feat: Add git branch to version information on settings screen by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1225 * feat: sort languages in selection menu by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1071 * feat: Latin Extended-B European glyphs by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1157 * feat: Latin Extended-B European glyphs by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1167 * feat: Vietnamese glyphs support by @danoooob in https://github.com/crosspoint-reader/crosspoint-reader/pull/1147 * feat: add Turkish translation by @barbarhan in https://github.com/crosspoint-reader/crosspoint-reader/pull/1192 * feat: add full Danish translation by @hajisan in https://github.com/crosspoint-reader/crosspoint-reader/pull/1146 * feat: Add Finnish translations by @plahteenlahti in https://github.com/crosspoint-reader/crosspoint-reader/pull/1133 * feat: Add Polish Language by @th0m4sek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1155 * feat: add Dutch translation by @basvdploeg in https://github.com/crosspoint-reader/crosspoint-reader/pull/1204 * feat: add Belarusian translation by @dexif in https://github.com/crosspoint-reader/crosspoint-reader/pull/1120 * feat: Add full Italian translations by @andreaturchet in https://github.com/crosspoint-reader/crosspoint-reader/pull/1144 * feat: add Ukrainian translation by @mirus-ua in https://github.com/crosspoint-reader/crosspoint-reader/pull/1065 * feat: Add Kazakh (kk) language support by @fsocietyipa in https://github.com/crosspoint-reader/crosspoint-reader/pull/1377 * feat: added Romanian strings by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/987 * feat: add Catalan strings by @angeldenom in https://github.com/crosspoint-reader/crosspoint-reader/pull/1049 * feat: Make directories stand out more in local file browser: "[dir]" instead of "dir" by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1339 * feat: Add Polish strings for commits #1219,#1169,#1031 +tweaks by @th0m4sek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1227 * feat: Polish translation tweaks by @th0m4sek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1193 ### Fixes * fix: Fix img layout issue / support CSS display:none for elements and images by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1443 * fix: Overlapping battery percentage on image pages with anti-aliasing by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1452 * fix: Fix prewarm perf when a page contains many styles by @adriancaruana in https://github.com/crosspoint-reader/crosspoint-reader/pull/1451 * fix: use sleep routine from the original firmware by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1298 * fix: Prevent line breaks on common English contractions by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1405 * fix: Build with -fno-exceptions by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1412 * fix: Reduce flash usage by cleaning up I18n translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1401 * fix: jpeg resource cleanup by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1320 * fix: back button in settings returns to tab bar first by @Cache8063 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1354 * fix: Init lastSleepImage (edge case) by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1360 * fix: Add special handling for apostrophe hyphenation by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1318 * fix: Fix inter-word spacing rounding error in text layout by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1311 * fix: load access fault crash by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1370 * fix: Fix bootloop logging crash by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1357 * fix: dump crash log without usb plugged, bump release log to INFO by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1332 * fix: avoid zip filename overflow by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1321 * fix: Hanging indent (negative text-indent) and em-unit sizing by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1229 * fix: Use fixed-point fractional x-advance and kerning for better text layout by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1168 * fix: use HTTPClient::writeToStream for downloading files from OPDS by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1207 * fix: make file system operations thread-safe (HalFile) by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1212 * fix: properly implement requestUpdateAndWait() by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1218 * fix: prevent infinite render loop in Calibre Wireless after file transfer by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1070 * fix: WiFi lifecycle and hyphenation heap defragmentation for KOReader sync by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1151 * fix: Fix coverRendered flag by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1154 * fix: Handle non-ASCII characters in sanitizeFilename by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1132 * fix: Update activity was missing "Back" button label by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1128 * fix: force auto-hinting for Bookerly to fix inconsistent stem widths by @adriancaruana in https://github.com/crosspoint-reader/crosspoint-reader/pull/1098 * fix: image centering bleed by @martinbrook in https://github.com/crosspoint-reader/crosspoint-reader/pull/1096 * fix: double free WebDAVHandler by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1093 * fix: Consider extra quotation styles when hyphenating quoted words by @cbix in https://github.com/crosspoint-reader/crosspoint-reader/pull/1077 * fix: acquire power lock before sleeping by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1125 * fix: Unify inconsistent Wi-Fi/WiFi in Czech translation by @pepastach in https://github.com/crosspoint-reader/crosspoint-reader/pull/1138 * fix: sdfat warning about redefinition of macro by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1135 * fix: Close leaked file descriptors in SleepActivity and web server by @brbla in https://github.com/crosspoint-reader/crosspoint-reader/pull/869 * fix: Enable DESTRUCTOR_CLOSES_FILE flag by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1075 * fix: Change "UI Font Size" to "Reader Font Size" by @divinitycove in https://github.com/crosspoint-reader/crosspoint-reader/pull/1171 * fix: Hide unusable button hints when viewing empty directory by @Levrk in https://github.com/crosspoint-reader/crosspoint-reader/pull/1253 * fix: broken translations in status bar settings by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1188 * fix: clarity issue with ambiguous string `SET` by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1169 * fix: Crash (Load access fault) when indexing chapters containing characters unsupported by bold/italic font variants by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/997 * fix: Increase PNGdec buffer size to support wide images by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/995 * fix: Use HalPowerManager for battery percentage by @vjapolitzer in https://github.com/crosspoint-reader/crosspoint-reader/pull/1005 * fix: Fix dangling pointer by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1010 * fix: re-implementing Cover Outlines for the new Lyra Themes by @Levrk in https://github.com/crosspoint-reader/crosspoint-reader/pull/1017 * fix: use double FAST_REFRESH to prevent washout on large grey images by @martinbrook in https://github.com/crosspoint-reader/crosspoint-reader/pull/957 * fix: Fixed Image Sizing When No Width is Set by @DestinySpeaker in https://github.com/crosspoint-reader/crosspoint-reader/pull/1002 * fix: Strip unused CSS rules by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1014 * fix: continue reading card classic theme by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/990 * fix: Destroy CSS Cache file when invalid by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1018 * fix: Shorten "Forget Wifi" button labels to fit on button by @lukestein in https://github.com/crosspoint-reader/crosspoint-reader/pull/1045 * fix: improve Spanish translations by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1054 * fix: Fixed book title in home screen by @DestinySpeaker in https://github.com/crosspoint-reader/crosspoint-reader/pull/1013 * fix: Fix hyphenation and rendering of decomposed characters by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1037 * fix: Improve and add Spanish translations by @DaniPhii in https://github.com/crosspoint-reader/crosspoint-reader/pull/1338 * fix: improve and add Spanish translations by @DaniPhii in https://github.com/crosspoint-reader/crosspoint-reader/pull/1254 * fix: improve and add Swedish translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1317 * fix: Extend missing / amend existing German translations by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1226 * fix: update french.yaml file to have a better French translation of the CFW by @Spigaw in https://github.com/crosspoint-reader/crosspoint-reader/pull/1130 * fix: added romanian translation to new strings by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1105 * fix: add missing romanian strings by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1187 * fix: add new Ukrainian translation line for STR_SCREENSHOT_BUTTON by @mirus-ua in https://github.com/crosspoint-reader/crosspoint-reader/pull/1149 * fix: Dutch translation prefix correction by @basvdploeg in https://github.com/crosspoint-reader/crosspoint-reader/pull/1223 * fix: Small typo in i18n.md regarding C++ identifiers by @victordomingos in https://github.com/crosspoint-reader/crosspoint-reader/pull/1210 * fix: typo in USER_GUIDE.md by @arnaugamez in https://github.com/crosspoint-reader/crosspoint-reader/pull/1036 * fix: add missing keyboard metrics to Lyra3CoversTheme by @dexif in https://github.com/crosspoint-reader/crosspoint-reader/pull/1101 ### Internal * perf: font-compression improvements by @adriancaruana in https://github.com/crosspoint-reader/crosspoint-reader/pull/1056 * perf: Improve font drawing performance by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/978 * perf: Replace std::list with std::vector in text layout by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1038 * perf: Optimize HTML entities lookup to O(log(n)) by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1194 * perf: UITheme::getMetrics const and const-ref usage by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1094 * perf: Avoid creating strings for file extension checks by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1303 * perf: Eliminate per-pixel overheads in image rendering by @martinbrook in https://github.com/crosspoint-reader/crosspoint-reader/pull/1293 * perf: Update github actions for optimal performance with pioarduino by @Jason2866 in https://github.com/crosspoint-reader/crosspoint-reader/pull/1080 * style: Phase 1 - Simple light dark themes by @cdmoro in https://github.com/crosspoint-reader/crosspoint-reader/pull/1006 * refactor: implement ActivityManager by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1016 * refactor: Simplify REPLACEMENT_GLYPH fallback by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1119 * refactor: Simplify new setting introduction by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1086 * refactor: Use std binary search algorithms for font lookups by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1202 * refactor: rename MyLibrary to FileBrowser by @osteotek in https://github.com/crosspoint-reader/crosspoint-reader/pull/1260 * refactor: Avoid rebuilding cache path strings by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1300 * refactor: reader utils by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1329 * chore: Remove miniz and modularise inflation logic by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1073 * chore: Resolve several build warnings by @daveallie in https://github.com/crosspoint-reader/crosspoint-reader/pull/1076 * chore: Removed generated language headers by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1156 * chore: Added generated lang headers to .gitignore by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1158 * chore: remove redundant xTaskCreate by @ngxson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1264 * chore: Removed unused PlatformIO include directory placeholder by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1417 * chore: micro-optimisation: early exit on fillUncompressedSizes by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1322 * chore: change label while on settings tab actions by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1325 * chore: add firmware size history script by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1235 * chore: Add powershell script for clang-formatting by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/1472 * chore: Removed unused ConfirmationActivity member by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1234 * chore: Update russian.yaml by @madebyKir in https://github.com/crosspoint-reader/crosspoint-reader/pull/1198 * chore: new Ukrainian translation lines by @mirus-ua in https://github.com/crosspoint-reader/crosspoint-reader/pull/1199 * chore: new Ukrainian localization strings by @mirus-ua in https://github.com/crosspoint-reader/crosspoint-reader/pull/1270 * chore: Polish localization for STR_DELETE by @JonaszPotoniec in https://github.com/crosspoint-reader/crosspoint-reader/pull/1323 * chore: Image settings Polish localization by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1299 * chore: add missing Catalan strings by @angeldenom in https://github.com/crosspoint-reader/crosspoint-reader/pull/1302 * chore: add missing translations for Romanian by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1265 * chore: Add Portuguese (Portugal) translator to the list by @victordomingos in https://github.com/crosspoint-reader/crosspoint-reader/pull/1211 * chore: Reduce flash usage by cleaning up I18n translations by @steka in https://github.com/crosspoint-reader/crosspoint-reader/pull/1401 * docs: Add lightweight contributor onboarding documentation by @bilalix in https://github.com/crosspoint-reader/crosspoint-reader/pull/894 * docs: ActivityManager migration guide by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1222 * docs: USER_GUIDE.md update for 1.1.0 by @divinitycove in https://github.com/crosspoint-reader/crosspoint-reader/pull/1108 * docs: add quick KOReader sync setup guide by @wjhrdy in https://github.com/crosspoint-reader/crosspoint-reader/pull/1181 * docs: image support marked as completed by @ariel-lindemann in https://github.com/crosspoint-reader/crosspoint-reader/pull/1008 * feat: aiagent context definition by @jpirnay in https://github.com/crosspoint-reader/crosspoint-reader/pull/922 * chore: Update SKILL.md to reflect generated i18n files are gitignored by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1423 * fix: ActivityManager tweaks by @znelson in https://github.com/crosspoint-reader/crosspoint-reader/pull/1220 * fix: Correct relative file paths in SKILL.md documentation by @pablohc in https://github.com/crosspoint-reader/crosspoint-reader/pull/1304 * fix: add Technically Unsupported section to SCOPE.md by @Uri-Tauber in https://github.com/crosspoint-reader/crosspoint-reader/pull/1295 ## New Contributors * @DestinySpeaker made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1002 * @arnaugamez made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1036 * @angeldenom made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1049 * @cdmoro made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1006 * @bilalix made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/894 * @Jessica765 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/682 * @brbla made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/869 * @dexif made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1047 * @mirus-ua made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1065 * @cbix made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1077 * @divinitycove made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1108 * @pepastach made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1138 * @Jason2866 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1080 * @andreaturchet made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1144 * @Spigaw made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1130 * @iandchasse made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1141 * @th0m4sek made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1155 * @plahteenlahti made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1133 * @hajisan made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1146 * @madebyKir made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1198 * @victordomingos made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1210 * @basvdploeg made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1204 * @wjhrdy made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1181 * @DaniPhii made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1254 * @steka made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1317 * @barbarhan made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1192 * @JonaszPotoniec made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1323 * @Cache8063 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1354 * @fsocietyipa made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1377 * @LSTAR1900 made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/979 * @zgredex made their first contribution in https://github.com/crosspoint-reader/crosspoint-reader/pull/1224 **Full Changelog**: https://github.com/crosspoint-reader/crosspoint-reader/compare/1.1.1...release/1.2.0 --------- Co-authored-by: jpirnay <jens@pirnay.com> Co-authored-by: Dani Poveda <daniphii@outlook.com> Co-authored-by: Baris Albayrak <80099286+barbarhan@users.noreply.github.com> Co-authored-by: Barış Albayrak <barisa@pop-os.lan> Co-authored-by: Stefan Blixten Karlsson <sbkarlsson@gmail.com> Co-authored-by: Àngel <153315454+angeldenom@users.noreply.github.com> Co-authored-by: Jonasz Potoniec <jonasz@potoniec.eu> Co-authored-by: Егор Мартынов <martynovegorOF@yandex.ru> Co-authored-by: Mirus <mirusim@gmail.com> Co-authored-by: Spigaw <73850535+Spigaw@users.noreply.github.com> Co-authored-by: ariel-lindemann <41641978+ariel-lindemann@users.noreply.github.com> Co-authored-by: Nima Salami <54304457+hajisan@users.noreply.github.com> Co-authored-by: Arthur Tazhitdinov <lisnake@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Bas van der Ploeg <bas@basvanderploeg.nl> Co-authored-by: martin brook <martin.brook100@googlemail.com> |
||
|
|
0cbfaa007d |
fix: Overlapping battery percentage on image pages with anti-aliasing (#1452)
## Summary **What is the goal of this PR?** When viewing a page with images and anti-aliasing enabled, the `imagePageWithAA` path renders the page twice with fast refreshes (blank image area, then restore). Both passes called `renderStatusBar()`, which reads the battery percentage live. If the value changed between the two renders (e.g. 88% -> 87%), the digits would overlap on screen. Fix: Removed the redundant `renderStatusBar()` from the second BW render. The status bar is already drawn and displayed in the first pass, and only the image area needs restoration. --- ### 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? _**NO**_ |
||
|
|
53beeeed2b |
chore: Removed unused PlatformIO include directory placeholder (#1417)
## Summary **What is the goal of this PR?** This change deletes include/README, which is a PlatformIO boilerplate placeholder file explaining what header files are. The include/ directory isn't used by this project (headers live in lib/ and src/), so this is just cleanup. ### 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? _**NO**_ |
||
|
|
9665dd7473 |
chore: Update SKILL.md to reflect generated i18n files are gitignored (#1423)
## Summary
**What is the goal of this PR?**
Update SKILL.md to stop instructing contributors to commit `I18nKeys.h`
and `I18nStrings.h`. All three generated i18n files have been gitignored
since
|
||
|
|
d6951f81b7 |
fix: Build with -fno-exceptions (#1412)
## Summary **What is the goal of this PR?** Until today, I sincerely thought we were building without exception support. The codebase is not set up with any exception handling infrastructure. The SKILL.md file specifies no exceptions. I just learned that we actually were building with exceptions enabled, with `-fexceptions` coming from ~/.platformio/packages/framework-arduinoespressif32-libs/esp32c3/pioarduino-build.py. This change removes the `-fexceptions` flag and adds `-fno-exceptions`. The result is **53,670 bytes in flash savings**. --- ### 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? _**NO**_ |
||
|
|
dc39480349 | fix: Prevent line breaks on common English contractions (#1405) | ||
|
|
32a5c1c358 |
fix: Fix inter-word spacing rounding error in text layout (#1311)
## Summary
**What is the goal of this PR?**
### Problem
Inter-word gap widths were computed as two separately-snapped integers:
```cpp
gap = getSpaceWidth(fontId, style); // fp4::toPixel(spaceAdvance)
gap += getSpaceKernAdjust(fontId, leftCp, rightCp, style); // fp4::toPixel(kern1 + kern2)
```
Because `fp4::toPixel(a) + fp4::toPixel(b)` can differ from
`fp4::toPixel(a + b)` by +/-1 pixel when the fractional parts straddle a
rounding boundary, each inter-word space could be one pixel wider or
narrower than the correct value. This affected line-break width
decisions and word-position accumulation across the whole paragraph
layout pipeline.
### Fix
Replaces `getSpaceKernAdjust()` with `getSpaceAdvance(fontId, leftCp,
rightCp, style)`, which combines the space glyph advance and both
flanking kern values (`kern(leftCp, ' ')` + `kern(' ', rightCp)`) into a
single fixed-point sum before the snap:
```cpp
return fp4::toPixel(spaceAdvanceFP + kern(leftCp, ' ') + kern(' ', rightCp));
```
This is the same single-snap pattern already used by `getTextAdvanceX`
for word widths.
### Changes
- **`GfxRenderer`**: Replaces `getSpaceKernAdjust()` with
`getSpaceAdvance()`. `getSpaceWidth()` is retained for the
single-space-word case in `measureWordWidth` where no adjacent-word kern
context is available.
- **`ParsedText`**: All four call sites (`computeLineBreaks`,
`computeHyphenatedLineBreaks`, and both loops in `extractLine`) updated
to use `getSpaceAdvance()`. The now-redundant `spaceWidth`
pre-computation and parameter are removed from all three internal layout
functions.
---
### 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 to analyze for
correctness**_
|
||
|
|
c3f1dbfa09 |
perf: Avoid creating strings for file extension checks (#1303)
## Summary **What is the goal of this PR?** This change avoids the pattern of creating a `std::string` using `.substr` in order to compare against a file extension literal. ```c++ std::string path; if (path.length() >= 4 && path.substr(path.length() - 4) == ".ext") ``` The `checkFileExtension` utility has moved from StringUtils to FsHelpers, to be available to code in lib/. The signature now accepts a `std::string_view` instead of `std::string`, which makes the single implementation reusable for Arduino `String`. Added utility functions for commonly repeated extensions. These changes **save about 2 KB of flash (5,999,427 to 5,997,343)**. --- ### 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? _**NO**_ |
||
|
|
ea88797c8e |
chore: Image settings Polish localization (#1299)
## Summary **What is the goal of this PR?** Quick follow up to #1291, adding Polish translations suggested by @th0m4sek --- ### 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? _**NO**_ |
||
|
|
a826569a0f |
refactor: Avoid rebuilding cache path strings (#1300)
## Summary **What is the goal of this PR?** Avoid building cache path strings twice, once to check existence of the file and a second time to delete the file. --- ### 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? _**NO**_ |
||
|
|
7dc518624c |
fix: Use fixed-point fractional x-advance and kerning for better text layout (#1168)
## Summary **What is the goal of this PR?** Hopefully fixes #1182. _Note: I think letterforms got a "heavier" appearance after #1098, which makes this more noticeable. The current version of this PR reverts the change to add `--force-autohint` for Bookerly, which to me seems to bring the font back to a more aesthetic and consistent weight._ #### Problem Character spacing was uneven in certain words. The word "drew" in Bookerly was the clearest example: a visible gap between `d` and `r`, while `e` and `w` appeared tightly condensed. The root cause was twofold: 1. **Integer-only glyph advances.** `advanceX` was stored as a `uint8_t` of whole pixels, sourced from FreeType's hinted `advance.x` (which grid-fits to integers). A glyph whose true advance is 15.56px was stored as 16px -- an error of +0.44px per character that compounds across a line. 2. **Floor-rounded kerning.** Kern adjustments were converted with `math.floor()`, which systematically over-tightened negative kerns. A kern of -0.3px became -1px -- a 0.7px over-correction that visibly closed gaps. Combined, these produced the classic symptom: some pairs too wide, others too tight, with the imbalance varying per word. #### Solution: fixed-point accumulation with 1/16-pixel resolution, for sub-pixel precision during text layout All font metrics now use a "fixed-point 4" format -- 4 fractional bits giving 1/16-pixel (0.0625px) resolution. This is implemented with plain integer arithmetic (shifts and adds), requiring no floating-point on the ESP32. **How it works:** A value like 15.56px is stored as the integer `249`: ``` 249 = 15 * 16 + 9 (where 9/16 = 0.5625, closest to 0.56) ``` Two storage widths share the same 4 fractional bits: | Field | Type | Format | Range | Use | |-------|------|--------|-------|-----| | `advanceX` | `uint16_t` | 12.4 | 0 -- 4095.9375 px | Glyph advance width | | `kernMatrix` | `int8_t` | 4.4 | -8.0 -- +7.9375 px | Kerning adjustment | Because both have 4 fractional bits, they add directly into a single `int32_t` accumulator during layout. The accumulator is only snapped to the nearest whole pixel at the moment each glyph is rendered: ```cpp int32_t xFP = fp4::fromPixel(startX); // pixel to 12.4: startX << 4 for each character: xFP += kernFP; // add 4.4 kern (sign-extends into int32_t) int xPx = fp4::toPixel(xFP); // snap to nearest pixel: (xFP + 8) >> 4 render glyph at xPx; xFP += glyph->advanceX; // add 12.4 advance ``` Fractional remainders carry forward indefinitely. Rounding errors stay below +/- 0.5px and never compound. #### Concrete example: "drew" in Bookerly **Before** (integer advances, floor-rounded kerning): | Char | Advance | Kern | Cursor | Snap | Gap from prev | |------|---------|------|--------|------|---------------| | d | 16 px | -- | 33 | 33 | -- | | r | 12 px | 0 | 49 | 49 | ~2px | | e | 13 px | -1 | 60 | 60 | ~0px | | w | 22 px | -1 | 72 | 72 | ~0px | The d-to-r gap was visibly wider than the tightly packed `rew`. **After** (12.4 advances, 4.4 kerning, fractional accumulation): | Char | Advance (FP) | Kern (FP) | Accumulator | Snap | Ink start | Gap from prev | |------|-------------|-----------|-------------|------|-----------|---------------| | d | 249 (15.56px) | -- | 528 | 33 | 34 | -- | | r | 184 (11.50px) | 0 | 777 | 49 | 49 | 0px | | e | 208 (13.00px) | -8 (-0.50px) | 953 | 60 | 61 | 1px | | w | 356 (22.25px) | -4 (-0.25px) | 1157 | 72 | 72 | 0px | Spacing is now `0, 1, 0` pixels -- nearly uniform. Verified on-device: all 5 copies of "drew" in the test EPUB produce identical spacing, confirming zero accumulator drift. #### Changes **Font conversion (`fontconvert.py`)** - Use `linearHoriAdvance` (FreeType 16.16, unhinted) instead of `advance.x` (26.6, grid-fitted to integers) for glyph advances - Encode kern values as 4.4 fixed-point with `round()` instead of `floor()` - Add `fp4_from_ft16_16()` and `fp4_from_design_units()` helper functions - Add module-level documentation of fixed-point conventions **Font data structures (`EpdFontData.h`)** - `EpdGlyph::advanceX`: `uint8_t` to `uint16_t` (no memory cost due to existing struct padding) - Add `fp4` namespace with `constexpr` helpers: `fromPixel()`, `toPixel()`, `toFloat()` - Document fixed-point conventions **Font API (`EpdFont.h/cpp`, `EpdFontFamily.h/cpp`)** - `getKerning()` return type: `int8_t` to `int` (to avoid truncation of the 4.4 value) **Rendering (`GfxRenderer.cpp`)** - `drawText()`: replace integer cursor with `int32_t` fixed-point accumulator - `drawTextRotated90CW()`: same accumulator treatment for vertical layout - `getTextAdvanceX()`, `getSpaceWidth()`, `getSpaceKernAdjust()`, `getKerning()`: convert from fixed-point to pixel at API boundary **Regenerated all built-in font headers** with new 12.4 advances and 4.4 kern values. #### Memory impact Zero additional RAM. The `advanceX` field grew from `uint8_t` to `uint16_t`, but the `EpdGlyph` struct already had 1 byte of padding at that position, so the struct size is unchanged. The fixed-point accumulator is a single `int32_t` on the stack. #### Test plan - [ ] Verify "drew" spacing in Bookerly at small, medium, and large sizes - [ ] Verify uppercase kerning pairs: AVERY, WAVE, VALUE - [ ] Verify ligature words: coffee, waffle, office - [ ] Verify all built-in fonts render correctly at each size - [ ] Verify rotated text (progress bar percentage) renders correctly - [ ] Verify combining marks (accented characters) still position correctly - [ ] Spot-check a full-length book for any layout regressions --- ### 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, Claude Opus 4.6 helped figure out a non-floating point approach for sub-pixel error accumulation**_ |
||
|
|
620835a6a1 |
chore: add firmware size history script (#1235)
## Summary **What is the goal of this PR?** - Adds `scripts/firmware_size_history.py`, a developer tool that builds firmware at selected git commits and reports flash usage with deltas between them. - Supports two input modes: `--range START END` to walk every commit in a range, or `--commits REF [REF ...]` to compare specific refs (which can span branches). - Defaults to a human-readable aligned table; pass `--csv` for machine-readable output to stdout or `--csv FILE` to write to a file. --- ### 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, fully written by AI**_ |
||
|
|
3cc8e272ca |
refactor: Use std binary search algorithms for font lookups (#1202)
## Summary **What is the goal of this PR?** Rewrite of font routines to use std binary search algorithms instead of custom repeated implementations: `lookupKernClass`, `EpdFont::getLigature`, and `EpdFont::getGlyph`. --- ### 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? _**NO**_ |
||
|
|
80d1856330 |
perf: Removed unused ConfirmationActivity member (#1234)
## Summary **What is the goal of this PR?** Small follow up to #909, removing an unused member variable and some temporary debug logging. --- ### 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? _**NO**_ |
||
|
|
42b122b8fd |
docs: ActivityManager migration guide (#1222)
## Summary **What is the goal of this PR?** Added overview and migration guide for ActivityManager changes in #1016. Thanks for the suggestion, @drbourbon! --- ### 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, fully written by Claude 4.6**_ |
||
|
|
050a3bd1b6 |
fix: ActivityManager tweaks (#1220)
## Summary **What is the goal of this PR?** Small tweaks to #1016: - Only Activity and ActivityManager can access activityResultHandler and activityResult - `[[maybe_unused]]` in RenderLock constructor - Only ActivityManager and RenderLock can access renderingMutex - Missing renderUpdate after failed wifi selection - Standardize on activities calling finish instead of activityManager.popActivity - Hold RenderLock while mutating state in EpubReaderActivity result handlers --- ### 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? _**NO**_ |
||
|
|
cb72916397 |
feat: Latin Extended-B European glyphs (#1167)
## Summary **What is the goal of this PR?** Correction to #1157, which (embarrassingly) failed to actually include the updated font header files. (Maybe we should generate these at build time?) Add Latin Extended-B glyphs for Croatian, Romanian, Pinyin, and European diacritical variants. Fixes #921. --- ### 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? _**PARTIALLY, confirmed codepoint ranges with Claude**_ |
||
|
|
31396da064 |
fix: Update activity was missing "Back" button label (#1128)
## Summary **What is the goal of this PR?** When update activity finds no update or fails, the "Back" button label was missing. Fixes #1089. --- ### 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? _**NO**_ |
||
|
|
8ab2f22730 |
fix: Handle non-ASCII characters in sanitizeFilename (#1132)
## Summary **What is the goal of this PR?** Probable fix for #1118. `sanitizeFilename` was only passing through ASCII characters from filenames. It now maintains valid UTF-8 codepoints, including non-ASCII multibyte sequences. Truncation happens at a maximum number of bytes, rather than characters, to prevent filenames with many multibyte sequences from unexpectedly exceeding FAT32 limits. --- ### 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, I described #1118 to Claude and it suggested sanitizeFilename as the likely cause**_ |
||
|
|
c0cd7c13a3 |
feat: Latin Extended-B European glyphs (#1157)
## Summary **What is the goal of this PR?** Add Latin Extended-B glyphs for Croatian, Romanian, Pinyin, and European diacritical variants. Fixes #921. --- ### 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? _**PARTIALLY, confirmed codepoint ranges with Claude**_ |
||
|
|
ff577540a3 |
chore: Added generated lang headers to .gitignore (#1158)
## Summary **What is the goal of this PR?** Following up on #1156: generated language header files should be ignored. --- ### 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? _**NO**_ |
||
|
|
43efd80e14 |
chore: Removed generated language headers (#1156)
## Summary **What is the goal of this PR?** I18nKeys.h and I18nStrings.h are generated by gen_i18n.py prior to each build, so we do not need to maintain a checked-in copy of these files. --- ### 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? _**NO**_ |
||
|
|
0eb8a9346b |
feat: Support for kerning and ligatures (#873)
## Summary **What is the goal of this PR?** Improved typesetting, including [kerning](https://en.wikipedia.org/wiki/Kerning) and [ligatures](https://en.wikipedia.org/wiki/Ligature_(writing)#Latin_alphabet). **What changes are included?** - The script to convert built-in fonts now adds kerning and ligature information to the generated font headers. - Epub page layout calculates proper kerning spaces and makes ligature substitutions according to the selected font.    ## Additional Context - I am not a typography expert. - The implementation has been reworked from the earlier version, so it is no longer necessary to omit Open Dyslexic, and kerning data now covers all fonts, styles, and codepoints for which we include bitmap data. - Claude Opus 4.6 helped with a lot of this. - There's an included test epub document with lots of kerning and ligature examples, shown in the photos. **_After some time to mature, I think this change is in decent shape to merge and get people testing._** After opening this PR I came across #660, which overlaps in adding ligature support. --- ### 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, Claude Opus 4.6**_ --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
13fc8b94b0 |
refactor: Simplify REPLACEMENT_GLYPH fallback (#1119)
## Summary **What is the goal of this PR?** Consolidated repeated logic to fall back to REPLACEMENT_GLYPH. --- ### 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? _**NO**_ |
||
|
|
410c70ab89 |
perf: UITheme::getMetrics const and const-ref usage (#1094)
## Summary **What is the goal of this PR?** Small cleanup to make getTheme and getMetrics methods on UITheme const. They return const refs, so updated call sites to use `const auto&`. Realistically this won't make much performance difference, but it better conveys the nature of theme metrics being shared const state. --- ### 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? _**NO**_ |
||
|
|
3696794591 |
perf: Replace std::list with std::vector in text layout (#1038)
## Summary _Revision to @blindbat's #802. Description comes from the original PR._ - Replace `std::list` with `std::vector` for word storage in `TextBlock` and `ParsedText` - Use index-based access (`words[i]`) instead of iterator advancement (`std::advance(it, n)`) - Remove the separate `continuesVec` copy that was built from `wordContinues` for O(1) access — now unnecessary since `std::vector<bool>` already provides O(1) indexing ## Why `std::list` allocates each node individually on the heap with 16 bytes of prev/next pointer overhead per node. For text layout with many small words, this means: - Scattered heap allocations instead of contiguous memory - Poor cache locality during iteration (each node can be anywhere in memory) - Per-node malloc/free overhead during construction and destruction `std::vector` stores elements contiguously, giving better cache performance during the tight rendering and layout loops. The `extractLine` function also benefits: list splice was O(1) but required maintaining three parallel iterators, while vector range construction with move iterators is simpler and still efficient for the small line-sized chunks involved. ## Files changed - `lib/Epub/Epub/blocks/TextBlock.h` / `.cpp` - `lib/Epub/Epub/ParsedText.h` / `.cpp` ## AI Usage YES ## Test plan - [ ] Open an EPUB with mixed formatting (bold, italic, underline) — verify text renders correctly - [ ] Open a book with justified text — verify word spacing is correct - [ ] Open a book with hyphenation enabled — verify words break correctly at hyphens - [ ] Navigate through pages rapidly — verify no rendering glitches or crashes - [ ] Open a book with long paragraphs — verify text layout matches pre-change behavior --------- Co-authored-by: Kuanysh Bekkulov <kbekkulov@gmail.com> |
||
|
|
448a77f02b |
perf: Remove hasPrintableChars pass (#971)
## Summary **What is the goal of this PR?** `hasPrintableChars` does a pass over text before rendering. It looks up glyphs in the font and measures dimensions, returning early if the text results in zero size. This additional pass doesn't offer any benefit over moving straight to rendering the text, because the rendering loop already gracefully handles missing glyphs. This change saves an extra pass over all rendered text. Note that both `hasPrintableChars` and `renderChar` replace missing glyphs with `glyph = getGlyph(REPLACEMENT_GLYPH)`, so there's no difference for characters which are not present in the font. --- ### 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? _**NO**_ |
||
|
|
f1740dbe1e |
fix: Correct word width and space calculations (#963)
## Summary **What is the goal of this PR?** This change fixes an issue I noticed while reading where occasionally, especially in italics, some words would have too much space between them. The problem was that word width calculations were including any negative X overhang, and combined with a space before the word, that can lead to an inconsistently large space. ## Additional Context Screenshots of some problematic text: | In CrossPoint 1.0 | With this change | | -- | -- | | <img src="https://github.com/user-attachments/assets/87bf0e4b-341f-4ba9-b3ea-38c13bd26363" width="400" /> | <img src="https://github.com/user-attachments/assets/bf11ba20-c297-4ce1-aa07-43477ef86fc2" width="400" /> | --- ### 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? _**NO**_ |
||
|
|
d02e21a48f |
fix: Added missing up/down button labels (#935)
## Summary **What is the goal of this PR?** In some places, button labels are omitted intentionally because the button has no purpose in the activity. I noticed a few obvious cases, like Home > File Transfer and Settings > System > Language, where the up and down button labels were missing. This change fixes those and all similar instances I could find. --- ### 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? _**NO**_ |
||
|
|
9125a7ce68 |
perf: Avoid redundant font map lookups (#933)
## Summary **What is the goal of this PR?** Several methods in GfxRenderer were doing a `count()` followed by `at()` on the fonts map, effectively doing the same map lookup unnecessarily. This can be avoided by doing a single `find()` and reusing the iterator. --- ### 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? _**NO**_ |
||
|
|
97c33141bd |
perf: Skip constructing unnecessary std::string (#932)
## Summary **What is the goal of this PR?** Skip constructing a `std::string` just to get the underlying `c_str()` buffer, when a string literal gives the same end result. --- ### 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? _**NO**_ |