Merged
Conversation
## 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 >**_
## 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 #728 (comment) --- ### 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 >**_
## 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**_
## Summary Continue my experiment from #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 #852 (comment) ## 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 #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**
## 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**_
## 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**_
…ts (#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 <[email protected]>
## 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**_
## 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**_
## 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**_
## 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 <[email protected]>
/!\ This PR depends on #732 being merged first Also requires the open-x4-epaper/community-sdk#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 <[email protected]>
## 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
## 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**_
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) * Fixes: #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 >**_
## 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**_
…ook (#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**_
## 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 <[email protected]>
## 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**_
## 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: #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**
## 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**_
…tion (#964) ## Summary **What is the goal of this PR?** * Implement feature request [#954](#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 >**_
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._
…acters unsupported by bold/italic font variants (#997) ## Summary * **What is the goal of this PR?** I flashed the last revision before commit f1740db, and chapter indexing worked without any crashes. After applying f1740db, the same chapter consistently triggered a device reboot during indexing. The affected chapter contains inline equation images surrounded by styled (bold/italic) text that includes special math/symbol characters. ## Additional Context Prior to f1740db, both `getTextAdvanceX()` and `getSpaceWidth()` always measured text using `EpdFontFamily::REGULAR`, regardless of the actual style. Commit f1740db improved correctness by passing the active style so spacing is calculated using the actual bold/italic font variant. However, bold and italic variants have narrower Unicode coverage than the regular font. When a character exists in the regular font but not in the selected styled variant, `pdFont::getGlyph()` returns `nullptr`. The updated measurement functions did not check for this and immediately dereferenced the pointer: `width += font.getGlyph(cp, style)->advanceX; // nullptr->advanceX` Because `advanceX` is located at byte offset 2 within `EpdGlyph`, dereferencing a null pointer caused the CPU to attempt a load from address `0x00000002`, resulting in a RISC-V: Load access fault MCAUSE = 5 MTVAL = 2 ## Fix Added null-safety checks to both `getTextAdvanceX()` and `getSpaceWidth()`, following the same pattern used in the rendering path: If the glyph is missing in the selected style → fall back to the replacement glyph. If the replacement glyph is also unavailable → treat the character as zero-width. This preserves the improved style-correct spacing while preventing crashes. No behavioral changes occur for characters that are supported by the selected font variant. --- ### AI Usage Did you use AI tools to help write this code? _**< YES >**_ I encounter this bug while testing 1.1.0 RC. I pasted the serial log to Claude, which identify the bug and fixed it. I can confirm now the chapter in question is indexed and loaded correctly.
## 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 #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 >**_
## Summary The introduction of `HalGPIO` moved the `BatteryMonitor battery` object into the member function `HalGPIO::getBatteryPercentage()`. Then, with the introduction of `HalPowerManager`, this function was moved to `HalPowerManager::getBatteryPercentage()`. However, the original `BatteryMonitor battery` object is still utilized by themes for displaying the battery percentage. This PR replaces these deprecated uses of `BatteryMonitor battery` with the new `HalPowerManager::getBatteryPercentage()` function. --- ### 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 **_
## 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.
## 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
## 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**_
…957) ## Summary Fixes #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 >**_
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Epub image support was added in #556. The goal of this PR is to document that in the readme. * **What changes are included?** Only the checkmark in the readme. ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### 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 >**_
## Summary * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) When no width is set for an image, the image currently automatically sets to the width of the page. However, with this fix, the parser will use the height and aspect ratio of the image to properly set a height for it. See below example: Before:  After:  * **What changes are included?✱ Changes to the CSS parser ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- ### 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, Cursor
## Summary
* In a sample book I loaded, it had 900+ CSS rules, and took up 180kB of
memory loading the cache in
* Looking at the rules, a lot of them were completely useless as we only
ever apply look for 3 kinds of CSS rules:
* `tag`
* `tag.class1`
* `.class1`
* Stripping out CSS rules with descendant, nested, attribute matching,
sibling matching, pseudo element selection (as we never actually read
these from the cache) reduced the rule count down to 200
## Additional Context
* I've left in `.class1.class2` rules for now, even though we
technically can never match on them as they're likely to be addressed
soonest out of the all the CSS expansion
* Because we don't ever delete the CSS cache, users will need to delete
the book cache through the menu in order to get this new logic
* A new PR should be done up to address this - tracked here
#1015
---
### 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
## Summary * **What is the goal of this PR?** * **What changes are included?** - Adapt card width to cover image aspect ratio in Classic theme - Increase homeTopPadding from 20px to 40px to avoid overlap with battery icon - Card width now calculated from BMP dimensions instead of fixed 240px - Maximum card width limited to 90% of screen width - Falls back to original behavior (half screen width) when no cover available ## Additional Context * Solve conflicts in PR #683 Before: <img width="1052" height="1014" alt="image" src="https://github.com/user-attachments/assets/6c857913-d697-4e9e-9695-443c0a4c0804" /> 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? _**< YES >**_
## Summary * Destroy CSS Cache file when invalid ## Additional Context * Fixes issue where it would attempt to rebuild every book open --- ### 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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.