2cc497cdcabf25c84a8c9089cdd22b9c3cf24704
447
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2cc497cdca |
fix: use double FAST_REFRESH to prevent washout on large grey images (#957)
## Summary Fixes https://github.com/crosspoint-reader/crosspoint-reader/issues/1011 Use double FAST_REFRESH for image pages to prevent grayscale washout, HALF_REFRESH sets e-ink particles too firmly for the grayscale LUT to adjust, causing washed-out images (especially large, light-gray ones). Replace HALF_REFRESH with @pablohc's double FAST_REFRESH technique: blank only the image bounding box area, then re-render with images. This clears ghosting while keeping particles loosely set for grayscale. ## Additional Context --- ### 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 >**_ |
||
|
|
8db3542e90 |
fix: re-implementing Cover Outlines for the new Lyra Themes (#1017)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Improve legibility of Cover Icons on the home page and elsewhere. Fixes #898 Re implements the changes made in #907 that were overwritten by the new lyra themes * **What changes are included?** Cover outline is now shown even when cover is found to prevent issues with low contrast covers blending into the background. Photo is attached below: <img width="1137" height="758" alt="Untitled (4)" src="https://github.com/user-attachments/assets/21ae6c94-4b43-4a0c-bec7-a6e4c642ffad" /> ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). Re implements the changes made in #907 that were overwritten by the new lyra themes --- ### 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**_ |
||
|
|
87d9d1dc2a |
perf: Improve font drawing performance (#978)
## Summary * ``renderChar`` checked ``is2Bit`` on every pixel inside the inner loop, even though the value is constant for the lifetime of a single glyph * Moved the branch above both loops so each path (2-bit antialiased / 1-bit monochrome) runs without a per-pixel conditional * Eliminates redundant work in the two inner loops that render font glyphs to the frame buffer, targeting ``renderChar`` and ``drawTextRotated90CW`` in ``GfxRenderer.cpp`` ## Additional Context * Measured on device using a dedicated framebuffer benchmark (no display refresh). 100 repetitions of "The quick brown fox jumps". | Test | Before | After | Change | |-----------------|-----------------|-----------------|---------| | drawText UI12 | 1,337 µs/call | 1,024 µs/call | −23%| | drawText Bookerly14 | 2.174 µs / call | 1,847 µs/call | −15% | --- ### 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**_ Claude did the analysis and wrote the benchmarks |
||
|
|
588984ec30 |
fix: Fix dangling pointer (#1010)
## Summary * **What is the goal of this PR?** Small fix for bug I found. ## Additional Context 1. `RecentBooksActivity::loop()` calls `onSelectBook(recentBooks[selectorIndex].path)` - passing a **reference** to the path 2. `onSelectBook` is `onGoToReader` which first calls `exitActivity()` 3. `exitActivity()` triggers `RecentBooksActivity::onExit()` which call `recentBooks.clear()` 4. The string reference `initialEpubPath` is now a **dangling reference** - the underlying string has been destroyed 5. When the reference is then used in `new ReaderActivity(...)`, it reads garbage memory 6. The same issue occurs in `HomeActivity` at line 200 with the same pattern The fix is to make a copy of the string in `onGoToReader` before calling `exitActivity()`, so the path data persists even after the activity clears its data structures. --- ### AI Usage Did you use AI tools to help write this code? _**< YES >**_ Claude found the bug, after I shared with it a serial log. |
||
|
|
b8e743ef80 |
fix: Increase PNGdec buffer size to support wide images (#995)
## Summary * Increased `PNG_MAX_BUFFERED_PIXELS` from 6402 to 16416 in `platformio.ini` to support up to 2048px wide RGBA images * adds a check to abort decoding and log an error if the required PNG scanline buffer exceeds the configured `PNG_MAX_BUFFERED_PIXELS`, preventing possible buffer overruns. * fixes https://github.com/crosspoint-reader/crosspoint-reader/issues/993 --- ### 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 >**_ |
||
|
|
3e2c518b8e |
fix: Crash (Load access fault) when indexing chapters containing characters unsupported by bold/italic font variants (#997)
## Summary * **What is the goal of this PR?** I flashed the last revision before commit |
||
|
|
402e887f73 | chore: Bump version to 1.1.0 | ||
|
|
103fac2ee1 |
feat: Basic table support (#980)
I've been reading "Children of Time" over the last days and that book, annyoingly, has some tabular content. This content is relevant for the story so I needed some really basic way to at least be able to read those tables. This commit simply renders the contents of table cells as separate paragraphs with a small header describing its position in the table. For me, it's better than nothing. ## Summary * **What is the goal of this PR?** Implements really basic table support * **What changes are included?** * Minimal changes to ChapterHtmlSlimParser * A demo book in test/epubs ## Additional Context Here's some screenshots of the demo-book I provide with this PR.   --- ### 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**_ _Little bit of guidance on what to touch, parts of the impl, rest manually._ |
||
|
|
6527f43cb1 |
feat: Scale cover images up if they're smaller than the device resolution (#964)
## Summary **What is the goal of this PR?** * Implement feature request [#954](https://github.com/crosspoint-reader/crosspoint-reader/issues/954) * Ensure cover images are scaled up to match the dimensions of the screen, as well as scaled down **What changes are included?** * Naïve implementation for scaling up the source image ## Additional Context If you find the extra comments to be excessive I can pare them back. Edit: Fixed title --- ### 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 >**_ |
||
|
|
eb241ab3fc |
feat: increase keyboard font size for classic theme (#897)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Adresses Feature Request #896 * **What changes are included?** Changed key dimensions, initial positions and margins. ## Additional Context The keyboard now looks like this:  --- ### 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**_ |
||
|
|
840e8c38f1 |
feat: add script for listing objects in flash (#880)
## Summary Adding a simple script to list objects and its size. I know `pio` already had the "analyze" function but it never works in my case. Ref discussion: https://github.com/crosspoint-reader/crosspoint-reader/discussions/862 To use it: ```sh scripts/script_profile_mem.sh ``` Example: ``` ============================================ Top 10 largest symbols in section: .dram0.bss Total section size: 85976 bytes (83.96 KB) ============================================ 0000bb98 ( 46.90 KB) display 00000ed8 ( 3.71 KB) g_cnxMgr 00000ad8 ( 2.71 KB) ftm_initiator 00000830 ( 2.05 KB) xIsrStack 000005b4 ( 1.43 KB) packet.8427 000004e0 ( 1.22 KB) _ZN12_GLOBAL__N_17ctype_wE 000004a0 ( 1.16 KB) dns_table 0000049c ( 1.15 KB) s_wifi_nvs 00000464 ( 1.10 KB) s_coredump_stack 0000034c ( 0.82 KB) gWpaSm ============================================ Top 10 largest symbols in section: .dram0.data Total section size: 13037 bytes (12.73 KB) ============================================ 000003c0 ( 0.94 KB) TxRxCxt 00000328 ( 0.79 KB) phy_param 000001d0 ( 0.45 KB) g_wifi_osi_funcs 0000011b ( 0.28 KB) _ZN18CrossPointSettings8instanceE 000000e6 ( 0.22 KB) country_info_24ghz 000000dc ( 0.21 KB) g_eb_list_desc 000000c0 ( 0.19 KB) s_fd_table 000000b8 ( 0.18 KB) g_timer_info 000000a8 ( 0.16 KB) rc11NSchedTbl 000000a0 ( 0.16 KB) g_rmt_objects ============================================ Top 200 largest symbols in section: .flash.rodata Total section size: 4564375 bytes (4457.40 KB) ============================================ 000325b7 ( 201.43 KB) _ZL12de_trie_data 0001cbd8 ( 114.96 KB) _ZL29notosans_18_bolditalicBitmaps 0001ca38 ( 114.55 KB) _ZL29bookerly_18_bolditalicBitmaps 0001bd3f ( 111.31 KB) _ZL23bookerly_18_boldBitmaps 0001af54 ( 107.83 KB) _ZL23notosans_18_boldBitmaps 0001abcc ( 106.95 KB) _ZL25bookerly_18_italicBitmaps 0001a341 ( 104.81 KB) _ZL25notosans_18_italicBitmaps 0001a0a5 ( 104.16 KB) _ZL26bookerly_18_regularBitmaps 0001890c ( 98.26 KB) _ZL26notosans_18_regularBitmaps 000188cc ( 98.20 KB) _ZL33opendyslexic_14_bolditalicBitmaps 000170ca ( 92.20 KB) _ZL29notosans_16_bolditalicBitmaps 00015e7f ( 87.62 KB) _ZL29bookerly_16_bolditalicBitmaps 00015acb ( 86.70 KB) _ZL23notosans_16_boldBitmaps 00015140 ( 84.31 KB) _ZL23bookerly_16_boldBitmaps 00014f0c ( 83.76 KB) _ZL25notosans_16_italicBitmaps 00014d54 ( 83.33 KB) _ZL29opendyslexic_14_italicBitmaps 00014766 ( 81.85 KB) _ZL27opendyslexic_14_boldBitmaps 0001467f ( 81.62 KB) _ZL25bookerly_16_italicBitmaps 00013c46 ( 79.07 KB) _ZL26bookerly_16_regularBitmaps 00013934 ( 78.30 KB) _ZL26notosans_16_regularBitmaps 00012572 ( 73.36 KB) _ZL33opendyslexic_12_bolditalicBitmaps 00011cee ( 71.23 KB) _ZL29notosans_14_bolditalicBitmaps 00011547 ( 69.32 KB) _ZL30opendyslexic_14_regularBitmaps 0001153c ( 69.31 KB) _ZL29bookerly_14_bolditalicBitmaps 00010c2e ( 67.04 KB) _ZL23notosans_14_boldBitmaps 0001096e ( 66.36 KB) _ZL23bookerly_14_boldBitmaps 000103d2 ( 64.96 KB) _ZL25notosans_14_italicBitmaps 000100d5 ( 64.21 KB) _ZL25bookerly_14_italicBitmaps 0000f83e ( 62.06 KB) _ZL26bookerly_14_regularBitmaps 0000f7fc ( 62.00 KB) _ZL29opendyslexic_12_italicBitmaps 0000f42b ( 61.04 KB) _ZL26notosans_14_regularBitmaps 0000f229 ( 60.54 KB) _ZL27opendyslexic_12_boldBitmaps 0000d301 ( 52.75 KB) _ZL29notosans_12_bolditalicBitmaps 0000d22f ( 52.55 KB) _ZL30opendyslexic_12_regularBitmaps 0000cff4 ( 51.99 KB) _ZL29bookerly_12_bolditalicBitmaps 0000cd12 ( 51.27 KB) _ZL33opendyslexic_10_bolditalicBitmaps 0000cad2 ( 50.71 KB) _ZL23bookerly_12_boldBitmaps 0000c60a ( 49.51 KB) _ZL23notosans_12_boldBitmaps 0000c147 ( 48.32 KB) _ZL25bookerly_12_italicBitmaps 0000c120 ( 48.28 KB) _ZL25notosans_12_italicBitmaps 0000ba7e ( 46.62 KB) _ZL26bookerly_12_regularBitmaps 0000b454 ( 45.08 KB) _ZL26notosans_12_regularBitmaps 0000b1e0 ( 44.47 KB) _ZL29opendyslexic_10_italicBitmaps 0000a939 ( 42.31 KB) _ZL27opendyslexic_10_boldBitmaps 0000a0dd ( 40.22 KB) _ZL13FilesPageHtml 0000949d ( 37.15 KB) _ZL30opendyslexic_10_regularBitmaps 00008415 ( 33.02 KB) _ZL32opendyslexic_8_bolditalicBitmaps 00008240 ( 32.56 KB) _ZL15ru_ru_trie_data 00007587 ( 29.38 KB) _ZL28opendyslexic_8_italicBitmaps 00006f4d ( 27.83 KB) _ZL26opendyslexic_8_boldBitmaps 00006943 ( 26.32 KB) _ZL15en_us_trie_data 00006196 ( 24.40 KB) _ZL29opendyslexic_8_regularBitmaps 00004990 ( 18.39 KB) _ZL21ubuntu_12_boldBitmaps 000042ce ( 16.70 KB) _ZL24ubuntu_12_regularBitmaps 000036d0 ( 13.70 KB) _ZL25notosans_18_regularGlyphs 000036d0 ( 13.70 KB) _ZL25notosans_16_regularGlyphs 000036d0 ( 13.70 KB) _ZL25notosans_14_regularGlyphs 000036d0 ( 13.70 KB) _ZL25notosans_12_regularGlyphs 000036d0 ( 13.70 KB) _ZL24notosans_8_regularGlyphs 000036d0 ( 13.70 KB) _ZL22notosans_18_boldGlyphs 000036d0 ( 13.70 KB) _ZL22notosans_16_boldGlyphs 000036d0 ( 13.70 KB) _ZL22notosans_14_boldGlyphs 000036d0 ( 13.70 KB) _ZL22notosans_12_boldGlyphs 000036c0 ( 13.69 KB) _ZL28notosans_18_bolditalicGlyphs 000036c0 ( 13.69 KB) _ZL28notosans_16_bolditalicGlyphs 000036c0 ( 13.69 KB) _ZL28notosans_14_bolditalicGlyphs 000036c0 ( 13.69 KB) _ZL28notosans_12_bolditalicGlyphs 000036c0 ( 13.69 KB) _ZL24notosans_18_italicGlyphs 000036c0 ( 13.69 KB) _ZL24notosans_16_italicGlyphs 000036c0 ( 13.69 KB) _ZL24notosans_14_italicGlyphs 000036c0 ( 13.69 KB) _ZL24notosans_12_italicGlyphs 00003627 ( 13.54 KB) _ZL21ubuntu_10_boldBitmaps 00003551 ( 13.33 KB) _ZL12es_trie_data 000030c4 ( 12.19 KB) _ZL24ubuntu_10_regularBitmaps 00002eb0 ( 11.67 KB) _ZL28bookerly_18_bolditalicGlyphs 00002eb0 ( 11.67 KB) _ZL28bookerly_16_bolditalicGlyphs 00002eb0 ( 11.67 KB) _ZL28bookerly_14_bolditalicGlyphs 00002eb0 ( 11.67 KB) _ZL28bookerly_12_bolditalicGlyphs 00002eb0 ( 11.67 KB) _ZL25bookerly_18_regularGlyphs 00002eb0 ( 11.67 KB) _ZL25bookerly_16_regularGlyphs 00002eb0 ( 11.67 KB) _ZL25bookerly_14_regularGlyphs 00002eb0 ( 11.67 KB) _ZL25bookerly_12_regularGlyphs 00002eb0 ( 11.67 KB) _ZL24bookerly_18_italicGlyphs 00002eb0 ( 11.67 KB) _ZL24bookerly_16_italicGlyphs 00002eb0 ( 11.67 KB) _ZL24bookerly_14_italicGlyphs 00002eb0 ( 11.67 KB) _ZL24bookerly_12_italicGlyphs 00002eb0 ( 11.67 KB) _ZL22bookerly_18_boldGlyphs 00002eb0 ( 11.67 KB) _ZL22bookerly_16_boldGlyphs 00002eb0 ( 11.67 KB) _ZL22bookerly_14_boldGlyphs 00002eb0 ( 11.67 KB) _ZL22bookerly_12_boldGlyphs 00002d50 ( 11.33 KB) _ZL32opendyslexic_14_bolditalicGlyphs 00002d50 ( 11.33 KB) _ZL32opendyslexic_12_bolditalicGlyphs 00002d50 ( 11.33 KB) _ZL32opendyslexic_10_bolditalicGlyphs 00002d50 ( 11.33 KB) _ZL31opendyslexic_8_bolditalicGlyphs 00002d50 ( 11.33 KB) _ZL29opendyslexic_14_regularGlyphs 00002d50 ( 11.33 KB) _ZL29opendyslexic_12_regularGlyphs 00002d50 ( 11.33 KB) _ZL29opendyslexic_10_regularGlyphs 00002d50 ( 11.33 KB) _ZL28opendyslexic_8_regularGlyphs 00002d50 ( 11.33 KB) _ZL28opendyslexic_14_italicGlyphs 00002d50 ( 11.33 KB) _ZL28opendyslexic_12_italicGlyphs 00002d50 ( 11.33 KB) _ZL28opendyslexic_10_italicGlyphs 00002d50 ( 11.33 KB) _ZL27opendyslexic_8_italicGlyphs 00002d50 ( 11.33 KB) _ZL26opendyslexic_14_boldGlyphs 00002d50 ( 11.33 KB) _ZL26opendyslexic_12_boldGlyphs 00002d50 ( 11.33 KB) _ZL26opendyslexic_10_boldGlyphs 00002d50 ( 11.33 KB) _ZL25opendyslexic_8_boldGlyphs 00002bca ( 10.95 KB) _ZL25notosans_8_regularBitmaps 0000294c ( 10.32 KB) _ZL16SettingsPageHtml 000024f0 ( 9.23 KB) _ZL23ubuntu_12_regularGlyphs 000024f0 ( 9.23 KB) _ZL23ubuntu_10_regularGlyphs 000024f0 ( 9.23 KB) _ZL20ubuntu_12_boldGlyphs 000024f0 ( 9.23 KB) _ZL20ubuntu_10_boldGlyphs 00001b4c ( 6.82 KB) _ZL12fr_trie_data 000012e8 ( 4.73 KB) ciphersuite_definitions 00000c8d ( 3.14 KB) _ZL12HomePageHtml 00000708 ( 1.76 KB) _ZL7Logo120 00000708 ( 1.76 KB) _ZL7Logo120 00000688 ( 1.63 KB) esp_err_msg_table 00000613 ( 1.52 KB) _ZL12it_trie_data 00000500 ( 1.25 KB) namingBitmap 00000450 ( 1.08 KB) _ZN4mime9mimeTableE 00000404 ( 1.00 KB) _ZNSt8__detail12__prime_listE 00000340 ( 0.81 KB) ciphersuite_preference 00000300 ( 0.75 KB) _ZL31bookerly_18_bolditalicIntervals 00000300 ( 0.75 KB) _ZL31bookerly_16_bolditalicIntervals 00000300 ( 0.75 KB) _ZL31bookerly_14_bolditalicIntervals 00000300 ( 0.75 KB) _ZL31bookerly_12_bolditalicIntervals 00000300 ( 0.75 KB) _ZL28bookerly_18_regularIntervals 00000300 ( 0.75 KB) _ZL28bookerly_16_regularIntervals 00000300 ( 0.75 KB) _ZL28bookerly_14_regularIntervals 00000300 ( 0.75 KB) _ZL28bookerly_12_regularIntervals 00000300 ( 0.75 KB) _ZL27bookerly_18_italicIntervals 00000300 ( 0.75 KB) _ZL27bookerly_16_italicIntervals 00000300 ( 0.75 KB) _ZL27bookerly_14_italicIntervals 00000300 ( 0.75 KB) _ZL27bookerly_12_italicIntervals 00000300 ( 0.75 KB) _ZL25bookerly_18_boldIntervals 00000300 ( 0.75 KB) _ZL25bookerly_16_boldIntervals 00000300 ( 0.75 KB) _ZL25bookerly_14_boldIntervals 00000300 ( 0.75 KB) _ZL25bookerly_12_boldIntervals 000002a0 ( 0.66 KB) small_prime 000002a0 ( 0.66 KB) _ZL35opendyslexic_14_bolditalicIntervals 000002a0 ( 0.66 KB) _ZL35opendyslexic_12_bolditalicIntervals 000002a0 ( 0.66 KB) _ZL35opendyslexic_10_bolditalicIntervals 000002a0 ( 0.66 KB) _ZL34opendyslexic_8_bolditalicIntervals 000002a0 ( 0.66 KB) _ZL32opendyslexic_14_regularIntervals 000002a0 ( 0.66 KB) _ZL32opendyslexic_12_regularIntervals 000002a0 ( 0.66 KB) _ZL32opendyslexic_10_regularIntervals 000002a0 ( 0.66 KB) _ZL31opendyslexic_8_regularIntervals 000002a0 ( 0.66 KB) _ZL31opendyslexic_14_italicIntervals 000002a0 ( 0.66 KB) _ZL31opendyslexic_12_italicIntervals 000002a0 ( 0.66 KB) _ZL31opendyslexic_10_italicIntervals 000002a0 ( 0.66 KB) _ZL30opendyslexic_8_italicIntervals 000002a0 ( 0.66 KB) _ZL29opendyslexic_14_boldIntervals 000002a0 ( 0.66 KB) _ZL29opendyslexic_12_boldIntervals 000002a0 ( 0.66 KB) _ZL29opendyslexic_10_boldIntervals 000002a0 ( 0.66 KB) _ZL28opendyslexic_8_boldIntervals 00000280 ( 0.62 KB) K 000001c8 ( 0.45 KB) _ZL26ubuntu_12_regularIntervals 000001c8 ( 0.45 KB) _ZL26ubuntu_10_regularIntervals 000001c8 ( 0.45 KB) _ZL23ubuntu_12_boldIntervals 000001c8 ( 0.45 KB) _ZL23ubuntu_10_boldIntervals 0000016c ( 0.36 KB) utf8_encoding_ns 0000016c ( 0.36 KB) utf8_encoding 0000016c ( 0.36 KB) little2_encoding_ns 0000016c ( 0.36 KB) little2_encoding 0000016c ( 0.36 KB) latin1_encoding_ns 0000016c ( 0.36 KB) latin1_encoding 0000016c ( 0.36 KB) internal_utf8_encoding_ns 0000016c ( 0.36 KB) internal_utf8_encoding 0000016c ( 0.36 KB) big2_encoding_ns 0000016c ( 0.36 KB) big2_encoding 0000016c ( 0.36 KB) ascii_encoding_ns 0000016c ( 0.36 KB) ascii_encoding 0000016c ( 0.36 KB) __default_global_locale 00000150 ( 0.33 KB) oid_sig_alg 00000150 ( 0.33 KB) mbedtls_cipher_definitions 00000140 ( 0.31 KB) adc_error_coef_atten 00000140 ( 0.31 KB) NUM_ERROR_CORRECTION_CODEWORDS 0000012c ( 0.29 KB) _ZL11lookupTable 00000101 ( 0.25 KB) _ctype_ 00000100 ( 0.25 KB) unhex 00000100 ( 0.25 KB) tokens 00000100 ( 0.25 KB) nmstrtPages 00000100 ( 0.25 KB) namePages 00000100 ( 0.25 KB) __chclass 00000100 ( 0.25 KB) FSb4 00000100 ( 0.25 KB) FSb3 00000100 ( 0.25 KB) FSb2 00000100 ( 0.25 KB) FSb 000000fc ( 0.25 KB) _C_time_locale 000000f0 ( 0.23 KB) oid_ecp_grp 000000d4 ( 0.21 KB) _ZL8mapTable 000000c8 ( 0.20 KB) __mprec_tens 000000c0 ( 0.19 KB) dh_group5_prime 000000c0 ( 0.19 KB) dh_group5_order 000000b4 ( 0.18 KB) _ZL31notosans_18_bolditalicIntervals 000000b4 ( 0.18 KB) _ZL31notosans_16_bolditalicIntervals 000000b4 ( 0.18 KB) _ZL31notosans_14_bolditalicIntervals 000000b4 ( 0.18 KB) _ZL31notosans_12_bolditalicIntervals 000000b4 ( 0.18 KB) _ZL28notosans_18_regularIntervals ============================================ Top 40 largest symbols in section: .flash.text Total section size: 1431082 bytes (1397.54 KB) ============================================ 000025b8 ( 9.43 KB) http_parser_execute 000023aa ( 8.92 KB) _vfprintf_r 000022ce ( 8.70 KB) _svfprintf_r 0000225a ( 8.59 KB) _svfwprintf_r 00001fdc ( 7.96 KB) __ssvfscanf_r 00001cb0 ( 7.17 KB) _Z15getSettingsListv 00001bbc ( 6.93 KB) mbedtls_ssl_handshake_server_step 00001ac2 ( 6.69 KB) __ssvfiscanf_r 000018fe ( 6.25 KB) mbedtls_ssl_handshake_client_step 000015fe ( 5.50 KB) mdns_parse_packet 00001554 ( 5.33 KB) _vfiprintf_r 0000146e ( 5.11 KB) _svfiprintf_r 0000123a ( 4.56 KB) doProlog 0000101e ( 4.03 KB) tcp_input 0000100e ( 4.01 KB) unsignedCharToPrintable 00000f4e ( 3.83 KB) pjpeg_decode_mcu 00000ef6 ( 3.74 KB) nd6_input 00000d4a ( 3.32 KB) _dtoa_r 00000d44 ( 3.32 KB) little2_contentTok 00000d44 ( 3.32 KB) big2_contentTok 00000d36 ( 3.30 KB) _strtod_l 00000d30 ( 3.30 KB) mbedtls_high_level_strerr 00000cec ( 3.23 KB) ieee80211_sta_new_state 00000ca6 ( 3.16 KB) tcp_receive 00000c82 ( 3.13 KB) mbedtls_internal_sha512_process 00000c14 ( 3.02 KB) _ZN9WebServer10_parseFormER10WiFiClient6Stringm 00000bc0 ( 2.94 KB) qrcode_initBytes 00000b62 ( 2.85 KB) __multf3 00000b1c ( 2.78 KB) normal_contentTok 00000a98 ( 2.65 KB) _ZN16ContentOpfParser12startElementEPvPKcPS2_ 00000a96 ( 2.65 KB) _ZN18JpegToBmpConverter27jpegFileToBmpStreamInternalER6FsFileR5Printiibb 00000a82 ( 2.63 KB) _mdns_service_task 00000a64 ( 2.60 KB) __strftime 00000a64 ( 2.60 KB) _ZNK9BaseTheme19drawRecentBookCoverER11GfxRenderer4RectRKSt6vectorI10RecentBookSaIS4_EEiRbS9_S9_St8functionIFbvEE 00000a60 ( 2.59 KB) __strftime 000009cc ( 2.45 KB) _Z16start_ssl_clientP17sslclient_contextRK9IPAddressmPKciS5_bS5_S5_S5_S5_bPS5_ 000009c4 ( 2.44 KB) doContent 0000099a ( 2.40 KB) wpa_sm_rx_eapol 00000984 ( 2.38 KB) __divtf3 00000974 ( 2.36 KB) _ZNSt6locale5_ImplC2Ej ============================================ Top 10 largest symbols in section: .iram0.text Total section size: 57640 bytes (56.29 KB) ============================================ 00000668 ( 1.60 KB) rmt_driver_isr_default 00000504 ( 1.25 KB) tlsf_realloc 00000458 ( 1.09 KB) tlsf_free 000003e8 ( 0.98 KB) tlsf_malloc 000003d0 ( 0.95 KB) esp_sleep_start 00000340 ( 0.81 KB) rtc_sleep_init 00000218 ( 0.52 KB) spi_flash_mmap_pages 000001fc ( 0.50 KB) esp_flash_erase_region 000001fc ( 0.50 KB) call_start_cpu0 000001de ( 0.47 KB) wdt_hal_init ``` --- ### 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** |
||
|
|
c4e3c244ea |
feat: Add 4bit bmp support (#944)
## Summary * What is the goal of this PR? - Allow users to create custom sleep screen images with standard tools (ImageMagick, GIMP, etc.) that render cleanly on the e-ink display without dithering artifacts. Previously, avoiding dithering required non-standard 2-bit BMPs that no standard image editor can produce. ( see issue #931 ) * What changes are included? - Add 4-bit BMP format support to Bitmap.cpp (standard format, widely supported by image tools) - Auto-detect "native palette" images: if a BMP has ≤4 palette entries and all luminances map within ±21 of the display's native gray levels (0, 85, 170, 255), skip dithering entirely and direct-map pixels - Clarify pixel processing strategy with three distinct paths: error-diffusion dithering, simple quantization, or direct mapping - Add scripts/generate_test_bmps.py for generating test images across all supported BMP formats ## Additional Context * The e-ink display has 4 native gray levels. When a BMP already uses exactly those levels, dithering adds noise to what should be clean output. The native palette detection uses a ±21 tolerance (~10%) to handle slight rounding from color space conversions in image tools. Users can now create a 4-color grayscale BMP with (imagemagic example): ``` convert input.png -colorspace Gray -colors 4 -depth ``` --- ### 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**_ |
||
|
|
3c1bd77813 |
fix: prevent UITheme memory leak on theme reload (#975)
## Summary - `UITheme::currentTheme` was a raw owning pointer with no destructor, causing a heap leak every time `setTheme()` was called (e.g. on theme change via settings reload) ## Additional Context - Replaced `const BaseTheme*` with `std::unique_ptr<BaseTheme>` so the previous theme object is automatically deleted on reassignment - Added `<memory>` include to `UITheme.h`; allocations updated to `std::make_unique<>` in `UITheme.cpp` --- ### 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**_ (identified by claude though) --------- Co-authored-by: Dave Allie <dave@daveallie.com> |
||
|
|
10b7769865 |
fix: go to prev page on the first one, get teleported to the end of book (#970)
## Summary 1. Go to the first page in a .epub file. 2. Hit `Up` button 3. Get teleported to the last page :) `TxtRenderActivity` seems to have this if check, but EPUB one does not. --- ### 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**_ |
||
|
|
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**_ |
||
|
|
e1074a84c0 |
fix: Skip large CSS files to prevent crashes (#952)
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) * Fixes: https://github.com/crosspoint-reader/crosspoint-reader/issues/947 **What changes are included?** * Check to see if there's free heap memory before processing CSS (should we be doing this type of check or is it better to just crash if we exhaust the memory?) * Skip CSS files larger than 128kb ## Additional Context * I found that a copy of `Release it` contained a 250kb+ CSS file, from the homepage of the publisher. It has nothing to do with the epub, so we should just skip it * Major question: Are there better ways to detect CSS that doesn't belong in a book, or is this size-based approach valid? * Another question: Are there any epubs we know of that legitimately include >128kb CSS files? Code changes themselves created with an agent, all investigation and write-up done by human. If you (the maintainers) would prefer a different fix for this issue, let me know. --- ### 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 >**_ |
||
|
|
e70066e7c2 |
fix: add bresenham for arbitrary lines (#923)
## Summary * GfxRender did handle horizontal and vertical lines but had a TODO for arbitrary lines. * Added integer based Bresenham line drawing ## Additional Context --- ### 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**_ |
||
|
|
00e25b1a90 |
fix: Fix kosync repositioning issue (#783)
## Summary * Original implementation had inconsistent positioning logic: - When XPath parsing succeeded: incorrectly set pageNumber = 0 (always beginning of chapter) - When XPath parsing failed: used percentage for positioning (worked correctly) - Result: Positions restored to wrong locations depending on XPath parsing success - Mentioned in Issue #581 * Solution - Unified ProgressMapper::toCrossPoint() to use percentage-based positioning exclusively for both spine identification and intra-chapter page calculation, eliminating unreliable XPath parsing entirely. ## Additional Context * ProgressMapper.cpp: Simplified toCrossPoint() to always use percentage for positioning, removed parseDocFragmentIndex() function * ProgressMapper.h: Updated comments and removed unused function declaration * Tests confirmed appropriate positioning * __Notabene: the syncing to another device will (most probably) end up at the current chapter of crosspoints reading position. There is not much we can do about it, as KOReader needs to have the correct XPath information - we can only provide an apporximate position (plus percentage) - the percentage information is not used in KOReaders current 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? YES |
||
|
|
fdcd71e94d |
feat: Lyra Icons (#725)
/!\ This PR depends on https://github.com/crosspoint-reader/crosspoint-reader/pull/732 being merged first Also requires the https://github.com/open-x4-epaper/community-sdk/pull/18 PR ## Summary Lyra theme icons on the home menu, in the file browser and on empty book covers     ## Additional Context - Added a function to the open-x4-sdk renderer to draw transparent images - Added a scripts/convert_icon.py script to convert svg/png icons into a C array that can be directly imported into the project. Usage: ```bash python ./scripts/convert_icon.py 'path/to/icon.png' cover 32 32 ``` This will create a components/icons/cover.h file with a C array called CoverIcon, of size 32x32px. Lyra uses icons from https://lucide.dev/icons with a stroke width of 2px, that can be downloaded with any desired size on the site. > The file browser is noticeably slower with the addition of icons, and using an image buffer like on the home page doesn't help very much. Any suggestions to optimize this are welcome. --- ### 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**_ The icon conversion python script was generated by Copilot as I am not a python dev. --------- Co-authored-by: Dave Allie <dave@daveallie.com> |
||
|
|
e7ee6ff05e |
feat: Lyra screens (#732)
## Summary Implements Lyra theme for some more Crosspoint screens:       ## Additional Context - A bit of refactoring for list scrolling logic --- ### 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**_ --------- Co-authored-by: Dave Allie <dave@daveallie.com> |
||
|
|
c6ddc5d6a0 | Update Ukrainian hyphenation | ||
|
|
feff739963 |
feat: Added Ukrainian language hyphenation support (#646)
## Summary * **What is the goal of this PR?** Add proper hyphenation support for the Ukrainian language. * **What changes are included?** - Added Ukrainian hyphenation rules/dictionary ## Additional Context --- ### AI Usage 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**_ |
||
|
|
6be4413c97 |
fix: Don't extract unsupported formats (#977)
## Summary * During chapter parsing, every <img> tag triggered ZIP decompression and an SD card write regardless of whether the image format was supported. The mandatory delay(50) after each SD write compounded the cost. A chapter with 6 GIF images (a common decorative element in older EPUBs) wasted ~750 ms before any text rendering began. * **What changes are included?** Added an ``ImageDecoderFactory::isFormatSupported()`` check before any file I/O in the img-handler. Only JPEG and PNG proceed to extraction; all other formats (GIF, SVG, WebP, etc.) fall through immediately to alt-text rendering with no SD card access. ## Additional Context Measured impact on a representative chapter with 6 GIF decorations: | | Before | After| |-- | -- | --| |Total parse time | ~882 ms | ~207 ms| |Image handling | ~750 ms | ~76 ms| --- ### 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**_ |
||
|
|
47aa0dda76 |
perf: Reduce overall flash usage by 30.7% by compressing built-in fonts (#831)
## Summary **What is the goal of this PR?** Compress reader font bitmaps to reduce flash usage by 30.7%. **What changes are included?** - New `EpdFontGroup` struct and extended `EpdFontData` with `groups`/`groupCount` fields - `--compress` flag in `fontconvert.py`: groups glyphs (ASCII base group + groups of 8) and compresses each with raw DEFLATE - `FontDecompressor` class with 4-slot LRU cache for on-demand decompression during rendering - `GfxRenderer` transparently routes bitmap access through `getGlyphBitmap()` (compressed or direct flash) - Uses `uzlib` for decompression with minimal heap overhead. - 48 reader fonts (Bookerly, NotoSans 12-18pt, OpenDyslexic) regenerated with compression; 5 UI fonts unchanged - Round-trip verification script (`verify_compression.py`) runs as part of font generation ## Additional Context ## Flash & RAM | | baseline | font-compression | Difference | |--|--------|-----------------|------------| | Flash (ELF) | 6,302,476 B (96.2%) | 4,365,022 B (66.6%) | -1,937,454 B (-30.7%) | | firmware.bin | 6,468,192 B | 4,531,008 B | -1,937,184 B (-29.9%) | | RAM | 101,700 B (31.0%) | 103,076 B (31.5%) | +1,376 B (+0.5%) | ## Script-Based Grouping (Cold Cache) Comparison of uncompressed baseline vs script-based group compression (4-slot LRU cache, cleared each page). Glyphs are grouped by Unicode block (ASCII, Latin-1, Latin Extended-A, Combining Marks, Cyrillic, General Punctuation, etc.) instead of sequential groups of 8. ### Render Time | | Baseline | Compressed (cold cache) | Difference | |---|---|---|---| | **Median** | 414.9 ms | 431.6 ms | +16.7 ms (+4.0%) | | **Pages** | 37 | 37 | | ### Memory Usage | | Baseline | Compressed (cold cache) | Difference | |---|---|---|---| | **Heap free (median)** | 187.0 KB | 176.3 KB | -10.7 KB | | **Heap free (min)** | 186.0 KB | 166.5 KB | -19.5 KB | | **Largest block (median)** | 148.0 KB | 128.0 KB | -20.0 KB | | **Largest block (min)** | 148.0 KB | 120.0 KB | -28.0 KB | ### Cache Effectiveness | | Misses/page | Hit rate | |---|---|---| | **Compressed (cold cache)** | 2.1 | 99.85% | ------ ### 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**_ Implementation was done by Claude Code (Opus 4.6) based on a plan developed collaboratively. All generated font headers were verified with an automated round-trip decompression test. The firmware was compiled successfully but has not yet been tested on-device. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
f16c0e52fd |
feat: Tweak Lyra popup UI (#768)
## Summary I want to preface this PR by stating that the proposed changes are subjective to people's opinions. The following is just my suggestion, but I'm of course open to changes. The popups in the currently implemented version of the Lyra theme feel a bit out of place. This PR suggests an updated version which looks a bit more polished and in line with the rest of the theme. I've also taken the liberty to remove the ellipsis behind the text of the popups, as they made the popup feel a bit off balance (example below). With the applied changes, popups will look like this.  The vertical position is (more or less) aligned to be in line with the sleep button. I'm aware the popup is used for other purposes aside from the sleep message, but this still felt like a good place. It's also a place where your eyes naturally 'rest'. The popup has a small 2px white outline, neatly separating it from whatever is behind it. ### Alternatives considered and rationale behind proposal Initially I started out worked off the Figma design for the Lyra theme, which [moves the popups](https://www.figma.com/design/UhxoV4DgUnfrDQgMPPTXog/Lyra-Theme?node-id=2011-19296&t=Ppj6B2MrFRfUo9YX-1) to the bottom of the screen. To me, this results in popups that are much too easy to miss:  After this, I tried moving the popup back up (to the position of the sleep button), but to me it still kinda disappeared into the text of the book:  Inverting the colors of the popup made things stand out the perfect amount in my opinion. The white outline separates the popup from what is behind it.  This looked much better to me. The only thing that felt a bit off to me, was the balance due to the ellipsis at the end of the popup text. Also, "Entering Sleep..." felt a bit.. engineer-y. I felt something a bit more 'conversational' makes at all feel a bit more human-centric. But I'm no copywriter, and English is not even my native language. So feel free to chip in! After tweaking that, I ended up with the final result: _(Same picture as the first one shown in this PR)_  ## Additional Context * Figma design: https://www.figma.com/design/UhxoV4DgUnfrDQgMPPTXog/Lyra-Theme?node-id=2011-19296&t=Ppj6B2MrFRfUo9YX-1 --- ### 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**_ |
||
|
|
6ec5fc5603 |
feat: lower CPU freq on idle, add HalPowerManager (#852)
## Summary Continue my experiment from https://github.com/crosspoint-reader/crosspoint-reader/pull/801 This PR add the ability to lower the CPU frequency on extended idle period (currently set to 3 seconds). By default, the esp32c3 CPU is set to 160MHz, and now on idle, we can reduce it to just 10MHz. Note that while this functionality is already provided by [esp power management](https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32c3/api-reference/system/power_management.html), the current Arduino build lacks of this, and enabling it is just too complicated (not worth the effort compared to this PR) Update: more info in https://github.com/crosspoint-reader/crosspoint-reader/pull/852#issuecomment-3904562827 ## Testing Pre-condition for each test case: the battery is charged to 100%, and is left plugged in after fully charged for an extra 1 hour. The table below shows how much battery is **used** for a given duration: | case / duration | 6 hrs | 12 hrs | | --- | --- | --- | | `delay(10)` | 26% | 48% | | `delay(50)`, PR https://github.com/crosspoint-reader/crosspoint-reader/pull/801 | 20% | Not tested | | `delay(50)` + low CPU freq (This PR) | Not tested | 25% | | `delay(10)` + low CPU freq (1) | Not tested | Not tested | (1) I decided not to test this case because it may not make sense. The problem is that CPU frequency vs power consumption do not follow a linear relationship, see [this](https://www.arrow.com/en/research-and-events/articles/esp32-power-consumption-can-be-reduced-with-sleep-modes) as an example. So, tight loop (10ms) + lower CPU freq significantly impact battery life, because the active CPU time is now much higher compared to the wall time. **So in conclusion, this PR improves ~150% to ~200% battery use time per charge.** The projected battery life is now: ~36-48 hrs of reading time (normal reading, no wifi) --- ### 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**_ |
||
|
|
dc6562a51c |
fix: Fix a dangling pointer (#939)
## Summary * **What is the goal of this PR?** Fix a dangling pointer issue caused by using `.c_str()` on a temporary `std::string`. `basepath.substr()` creates a temporary `std::string`, and calling `.c_str()` on it returns a pointer to its internal buffer (not a copy). Since the temporary string is destroyed at the end of the full expression, `folderName` ends up holding a dangling pointer, leading to undefined behavior. To solve this, we stores the result in a persistent `std::string` object, ensuring the underlying buffer remains valid for the duration of its use. A similar pattern caused the behavior reported in https://github.com/crosspoint-reader/crosspoint-reader/pull/728#issuecomment-3902529697 --- ### 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 >**_ |
||
|
|
530d43997b |
fix: Update Translators list (#927)
## Summary * **What is the goal of this PR?** Update translators.md to include all the contributors from #728 --- ### 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**_ |
||
|
|
2a32d8a182 |
chore: improve Russian language support (#926)
## Summary This PR includes vocabulary and grammar fixes for Russian translation, originally made as review comments [here](https://github.com/crosspoint-reader/crosspoint-reader/pull/728). --- ### 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**_ |
||
|
|
d6f38d4441 |
fix: align battery icon based on context (UI / Reader) (#796)
Issues solved: #729 and #739 ## Summary * **What is the goal of this PR?** Currently, the battery icon and charge percentage were aligned to the left even for the UI, where they were positioned on the right side of the screen. This meant that when changing values of different numbers of digits, the battery would shift, creating a block of icons and text that was illegible. * **What changes are included?** - Add drawBatteryUi() method for right-aligned battery display in UI headers - Keep drawBattery() for left-aligned display in reader mode - Extract drawBatteryIcon() helper to reduce code duplication - Battery icon now stays fixed at right edge regardless of percentage digits - Text adjusts to left of icon in UI mode, to right of icon in reader mode ## Additional Context * Add any other information that might be helpful for the reviewer * This fix applies to both themes (Base and Lyra). --- ### 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 >**_ |
||
|
|
513d111634 |
docs: add translators doc (#792)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Add a translators document for us to track which individuals have volunteered to contribute in which languages. * **What changes are included?** Add a new document that includes who the translators are and what languages they have volunteered for. ## Additional Context This is primarily to keep a handle on the volunteers coming into the repo. This will serve as a master list of all volunteer translators. --- ### 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** --------- Signed-off-by: Andrew Brandt <brandt.andrew89@gmail.com> |
||
|
|
ad9137cfdf |
fix: added cover image outlines to improve legibility (#907)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Improve legibility of Cover Icons on the home page and elsewhere. Fixes #898 * **What changes are included?** Cover outline is now shown even when cover is found to prevent issues with low contrast covers blending into the background. Photo is attached below: <img width="404" height="510" alt="Group 1 (4)" src="https://github.com/user-attachments/assets/9d794b51-554b-486d-8520-6ef920548b9a" /> ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). Not much else to say here. I did simplify the logic in lyratheme.cpp based on there no longer being a requirement for any non-cover specific rendering differences. --- ### 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**_ |
||
|
|
5c80cface7 |
docs: Updating webserver.md documentation to align with 1.0.0 features (#906)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Updating webserver.md documentation to align with 1.0.0 features * **What changes are included?** Added documentation for the following new features (including replacing screenshots) - file renaming - file moving - support for uploading any file type - batch uploads ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). Nothing comes to mind --- ### 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**_ |
||
|
|
86d3774a8f |
fix: Removed white boxes extending passed the bounds of the empty button icon when hint text is blank/null (#884)
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Empty Button Icons (I.E. Back button in the home menu) were still rendering the full sized white rectangles going passed the boarders of the little button nub. This was not visible on the home screen due to the white background, but it does cause issues if we ever want to have bmp files displayed while buttons are visible or implement a dark mode. * **What changes are included?** Made it so that when a button hint text is empty string or null the displayed mini button nub does not have a white rectangle extending passed the bounds of the mini button nub ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). Having that extended rectangle was likely never noticed due to the only space where that feature is used being the main menu where the background is completely white. I am working on some new features that would have an image displayed while there are button hints and noticed this issue while implementing that. One other note is that this only affects the Lyra Theme --- ### 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**_ |
||
|
|
7ba5978848 |
feat: User-Interface I18n System (#728)
## Summary **What is the goal of this PR?** This PR introduces Internationalization (i18n) support, enabling users to switch the UI language dynamically. **What changes are included?** - Core Logic: Added I18n class (`lib/I18n/I18n.h/cpp`) to manage language state and string retrieval. - Data Structures: - `lib/I18n/I18nStrings.h/cpp`: Static string arrays for each supported language. - `lib/I18n/I18nKeys.h`: Enum definitions for type-safe string access. - `lib/I18n/translations.csv`: single source of truth. - Documentation: Added `docs/i18n.md` detailing the workflow for developers and translators. - New Settings activity: `src/activities/settings/LanguageSelectActivity.h/cpp` ## Additional Context This implementation (building on concepts from #505) prioritizes performance and memory efficiency. The core approach is to store all localized strings for each language in dedicated arrays and access them via enums. This provides O(1) access with zero runtime overhead, and avoids the heap allocations, hashing, and collision handling required by `std::map` or `std::unordered_map`. The main trade-off is that enums and string arrays must remain perfectly synchronized—any mismatch would result in incorrect strings being displayed in the UI. To eliminate this risk, I added a Python script that automatically generates `I18nStrings.h/.cpp` and `I18nKeys.h` from a CSV file, which will serve as the single source of truth for all translations. The full design and workflow are documented in `docs/i18n.md`. ### Next Steps - [x] Python script `generate_i18n.py` to auto-generate C++ files from CSV - [x] Populate translations.csv with initial translations. Currently available translations: English, Español, Français, Deutsch, Čeština, Português (Brasil), Русский, Svenska. Thanks, community! **Status:** EDIT: ready to be merged. As a proof of concept, the SPANISH strings currently mirror the English ones, but are fully uppercased. --- ### AI Usage Did you use AI tools to help write this code? _**< PARTIALLY >**_ I used AI for the black work of replacing strings with I18n references across the project, and for generating the documentation. EDIT: also some help with merging changes from master. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: yeyeto2788 <juanernestobiondi@gmail.com> |
||
|
|
3d47c081f2 |
fix: use RAII render lock everywhere (#916)
## Summary Follow-up to https://github.com/crosspoint-reader/crosspoint-reader/pull/774 --- ### 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** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Modernized internal synchronization mechanisms across multiple components to improve code reliability and maintainability. All functionality remains unchanged. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
6702060960 |
fix: Implement guide-based cover image fallback (#830)
This partially fixes #769 but is dependent upon PR #827 being merged along side this @daveallie. I removed my PNG conversion code after finding out that PR was already created. Without this PR though that book in #769 will still fail to load because of how it's stored in the file --------- Co-authored-by: Dave Allie <dave@daveallie.com> |
||
|
|
0bc6747483 |
feat: Add PNG cover image support for EPUB books (#827)
## Summary - EPUB books with PNG cover images now display covers on the home screen instead of blank rectangles - Adds `PngToBmpConverter` library mirroring the existing `JpegToBmpConverter` pattern - Uses miniz (already in the project) for streaming zlib decompression of PNG IDAT data - Supports all PNG color types (Grayscale, RGB, RGBA, Palette, Gray+Alpha) - Optimized for ESP32-C3: batch grayscale conversion, 2KB read buffer, same area-averaging scaling and Atkinson dithering as the JPEG path ## Changes - **New:** `lib/PngToBmpConverter/PngToBmpConverter.h` — Public API matching JpegToBmpConverter's interface - **New:** `lib/PngToBmpConverter/PngToBmpConverter.cpp` — Streaming PNG decoder + BMP converter - **Modified:** `lib/Epub/Epub.cpp` — Added `.png` handling in `generateCoverBmp()` and `generateThumbBmp()` ## Test plan - [x] Tested with EPUB files using PNG covers — covers appear correctly on home screen - [ ] Verify with various PNG color types (most stock EPUBs use 8-bit RGB) - [ ] Confirm no regressions with JPEG cover EPUBs <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit **New Features** - Added PNG format support for EPUB cover and thumbnail images. PNG files are automatically processed and cached alongside existing supported formats. This enhancement enables users to leverage PNG cover artwork when generating EPUB files, improving workflow flexibility and compatibility with common image sources. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Nik Outchcunis <outchy@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Dave Allie <dave@daveallie.com> |
||
|
|
00666377de |
fix: Add miniz directive to get rid of compilation warning (#858)
## Summary * I am getting miniz warning during compilation: "Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files." * Disable the io module from miniz as it is not used and get rid of the warning ## Additional Context * the ZipFile.cpp implementation only uses tinfl_decompressor, tinfl_init(), and tinfl_decompress() (low-level API) and does all ZIP file parsing manually using SD card file I/O * it never uses miniz's high-level file functions like mz_zip_reader_init_file() * so we can disable Miniz io-stack be setting MINIZ_NO_STDIO to 1 ### 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, let claude inspect the codebase |
||
|
|
22b77edddf |
fix: Correct multiple author display (#856)
## Summary * If an EPUB has: ``` <dc:creator>J.R.R. Tolkien</dc:creator> <dc:creator>Christopher Tolkien</dc:creator> ``` the current result for epub.author would provide : "J.R.R. TolkienChristopher Tolkien" (no separator!) * The fix will seperate multiple authors: "J.R.R. Tolkien, Christopher Tolkien" ## Additional Context * Simple fix in ContentOpfParser - I am not seeing any dependence on the wrong concatenated 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 |
||
|
|
2e673c753d |
docs: Include dictionary as in-scope (#917)
## Summary * Include dictionary as in-scope ## Additional Context * Discussion in https://github.com/crosspoint-reader/crosspoint-reader/discussions/878 --- ### 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 |
||
|
|
1a30826981 |
fix: add distro agnostic shebang and clang-format check to clang-format-fix (#840)
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Minor development tooling fix for nonstandard environments (NixOS, FreeBSD, Guix, etc.) **What changes are included?** - environment relative shebang in `clang-format-fix` - clang-format check in `clang-format-fix` --- ### 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**_ |
||
|
|
50e6ef9bd8 |
fix: Auto calculate the settings size on serialization (#832)
## Summary * The constant SETTINGS_CONST was hardcoded and needed to be updated whenever an additional setting was added * This is no longer necessary as the settings size will be determined automatically on settings persistence ## Additional Context * New settings need to be added (as previously) in saveToFile - that's it --- ### 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 --------- Co-authored-by: Xuan Son Nguyen <son@huggingface.co> |
||
|
|
a616f42cb4 |
refactor: move render() to Activity super class, use freeRTOS notification (#774)
## Summary Currently, each activity has to manage their own `displayTaskLoop` which adds redundant boilerplate code. The loop is a wait loop which is also not the best practice, as the `updateRequested` boolean is not protected by a mutex. In this PR: - Move `displayTaskLoop` to the super `Activity` class - Replace `updateRequested` with freeRTOS's [direct to task notification](https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/03-Direct-to-task-notifications/01-Task-notifications) - For `ActivityWithSubactivity`, whenever a sub-activity is present, the parent's `render()` automatically goes inactive With this change, activities now only need to expose `render()` function, and anywhere in the code base can call `requestUpdate()` to request a new rendering pass. ## Additional Context In theory, this change may also make the battery life a bit better, since one wait loop is removed. Although the equipment in my home lab wasn't been able to verify it (the electric current is too noisy and small). Would appreciate if anyone has any insights on this subject. Update: I managed to hack [a small piece of code](https://github.com/ngxson/crosspoint-reader/tree/xsn/measure_cpu_usage) that allow tracking CPU idle time. The CPU load does decrease a bit (1.47% down to 1.39%), which make sense, because the display task is now sleeping most of the time unless notified. This should translate to a slightly increase in battery life in the long run. ``` PR: [40012] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes [40012] [IDLE] Idle time: 98.61% (CPU load: 1.39%) [50017] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes [50017] [IDLE] Idle time: 98.61% (CPU load: 1.39%) [60022] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes [60022] [IDLE] Idle time: 98.61% (CPU load: 1.39%) master: [20012] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes [20012] [IDLE] Idle time: 98.53% (CPU load: 1.47%) [30017] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes [30017] [IDLE] Idle time: 98.53% (CPU load: 1.47%) [40022] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes [40022] [IDLE] Idle time: 98.53% (CPU load: 1.47%) ``` --- ### 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** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Streamlined rendering architecture by consolidating update mechanisms across all activities, improving efficiency and consistency. * Modernized synchronization patterns for display updates to ensure reliable, conflict-free rendering. * **Bug Fixes** * Enhanced rendering stability through improved locking mechanisms and explicit update requests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: znelson <znelson@users.noreply.github.com> |
||
|
|
0508bfc1f7 |
perf: apply (micro) optimization on SerializedHyphenationPatterns (#689)
## Summary This PR applies a micro optimization on `SerializedHyphenationPatterns`, which allow reading `rootOffset` directly without having to parse then cache it. It should not affect storage space since no new bytes are added. This also gets rid of the linear cache search whenever `liangBreakIndexes` is called. In theory, the performance should be improved a bit, although it may be too small to be noticeable in practice. ## Testing master branch: ``` english: 99.1023% french: 100% german: 97.7289% russian: 97.2167% spanish: 99.0236% ``` This PR: ``` english: 99.1023% french: 100% german: 97.7289% russian: 97.2167% spanish: 99.0236% ``` --- ### 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 - mostly IDE tab-autocompletions |
||
|
|
6c3a615fac |
feat: add png jpeg support (#556)
## Summary
- Add embedded image support to EPUB rendering with JPEG and PNG
decoders
- Implement pixel caching system to cache decoded/dithered images to SD
card for faster re-rendering
- Add 4-level grayscale support for display
## Changes
### New Image Rendering System
- Add `ImageBlock` class to represent an image with its cached path and
display dimensions
- Add `PageImage` class as a new `PageElement` type for images on pages
- Add `ImageToFramebufferDecoder` interface for format-specific image
decoders
- Add `JpegToFramebufferConverter` - JPEG decoder with Bayer dithering
and scaling
- Add `PngToFramebufferConverter` - PNG decoder with Bayer dithering and
scaling
- Add `ImageDecoderFactory` to select appropriate decoder based on file
extension
- Add `getRenderMode()` to GfxRenderer for grayscale render mode queries
### Dithering and Grayscale
- Implement 4x4 Bayer ordered dithering for 4-level grayscale output
- Stateless algorithm works correctly with MCU block decoding
- Handles scaling without artifacts
- Add grayscale render mode support (BW, GRAYSCALE_LSB, GRAYSCALE_MSB)
- Image decoders and cache renderer respect current render mode
- Enables proper 4-level e-ink grayscale when anti-aliasing is enabled
### Pixel Caching
- Cache decoded/dithered images to `.pxc` files on SD card
- Cache format: 2-bit packed pixels (4 pixels per byte) with
width/height header
- On subsequent renders, load directly from cache instead of re-decoding
- Cache renderer supports grayscale render modes for multi-pass
rendering
- Significantly improves page navigation speed for image-heavy EPUBs
### HTML Parser Integration
- Update `ChapterHtmlSlimParser` to process `<img>` tags and extract
images from EPUB
- Resolve relative image paths within EPUB ZIP structure
- Extract images to cache directory before decoding
- Create `PageImage` elements with proper scaling to fit viewport
- Fall back to alt text display if image processing fails
### Build Configuration
- Add `PNG_MAX_BUFFERED_PIXELS=6402` to support up to 800px wide images
### Test Script
- Generate test EPUBs with annotated JPEG and PNG images
- Test cases cover: grayscale (4 levels), centering, scaling, cache
performance
## Test plan
- [x] Open EPUB with JPEG images - verify images display with proper
grayscale
- [x] Open EPUB with PNG images - verify images display correctly and no
crash
- [x] Navigate away from image page and back - verify faster load from
cache
- [x] Verify grayscale tones render correctly (not just black/white
dithering)
- [x] Verify large images are scaled down to fit screen
- [x] Verify images are centered horizontally
- [x] Verify page serialization/deserialization works with images
- [x] Verify images rendered in landscape mode
## Test Results
[png](https://photos.app.goo.gl/5zFUb8xA8db3dPd19)
[jpeg](https://photos.app.goo.gl/SwtwaL2DSQwKybhw7)








---
### AI Usage
Did you use AI tools to help write this code? _**< YES >**_
---------
Co-authored-by: Matthías Páll Gissurarson <mpg@mpg.is>
Co-authored-by: Dave Allie <dave@daveallie.com>
|