Commit Graph
587 Commits
Author SHA1 Message Date
jpirnay 72a0d2a611 chore: remove unused STR_CALIBRE from German translations 2026-03-16 15:44:38 +01:00
jpirnay 960cb91b23 Optimize output 2026-03-16 15:10:41 +01:00
jpirnay e4b0abec03 Fix english hyphenation 2026-03-16 11:51:28 +01:00
jpirnay 125ef361d2 fix: jpeg resource cleanup (#1320)
## Summary

* **What is the goal of this PR?** Fix leak on decode error path in JPEG
converter
* **What changes are included?**
Unif resource cleanup

## 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**_
Identification of the issue by AI
2026-03-13 17:45:42 -05:00
jpirnay 9b70ddc93b Merge branch 'master' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-13 21:24:04 +01:00
fsocietyipaandOkzhetpes dabdfcd683 feat: Add Kazakh (kk) language support (#1377)
## Summary

* **What is the goal of this PR?** Implements Kazakh language
* **What changes are included?**

## 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

---------

Co-authored-by: Okzhetpes <okhzetpes.20@gmail.com>
2026-03-11 18:40:14 -05:00
jpirnay 906dd202b9 fix: Add special handling for apostrophe hyphenation (#1318)
## Summary

* **What is the goal of this PR?** Fixing / extending the hyphenation
logic to deal with words containing an apostophe as raised in #1186
* **What changes are included?**

## 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**_ (as the
user provided a thorough analysis that I followed)
2026-03-11 18:35:23 -05:00
Adrian Wilkins-Caruana 1409259721 perf: font-compression improvements (#1056)
## Purpose

This PR includes some preparatory changes that are needed for an
upcoming performant CJK font feature. The changes have no impact on
render time and heap allocation for latin text. **Despite this, I think
these changes stand on their own as a better font
compression/decompression implementation.**

## Summary

- Font decompressor rewrite: Replaced the 4-slot LRU group cache with a
two-tier system — a page buffer (glyphs prewarmed before rendering
begins) and a hot-group fallback (last decompressed group retained for
non-prewarmed
  glyphs). 
- Byte-aligned compressed bitmap format: Glyph bitmaps within compressed
groups are now stored row-padded rather than tightly packed before
DEFLATE compression, improving compression ratios by making identical
pixel rows produce
identical byte patterns. Glyphs are compacted back to packed format on
demand at render time. Reduces flash size by 155 KB.
- Page prewarm system: Added `Page::collectText` and
`Page::getDominantStyle` to extract per-style glyph requirements before
rendering, and `GfxRenderer::prewarmFontCache` to pre-decompress only
the groups needed for the dominant style
   — eliminating mid-render decompression for the common case.
- UTF-8 robustness fixes: `utf8NextCodepoint` now validates continuation
bytes and returns a replacement glyph on malformed input;
`ChapterHtmlSlimParser` correctly preserves incomplete multi-byte
sequences across word-buffer flush
  boundaries rather than splitting them.

---

### 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**_ Architecture and
design was done by me, refined a bit by Claude. Code mostly by Claude,
but not entirely.
2026-03-11 21:05:46 +01:00
Dani Poveda 80871b97d1 fix: Improve and add Spanish translations (#1338)
## Summary

* **What is the goal of this PR?** 
    - Improve and add the latest missing Spanish translations

* **What changes are included?**
    - Replaced `Der.` with `Dcha.`, as it's a more common abbreviation
- Replaced `Selec.` with `Selecc.` (same reason as in the previous case)
- Added missing strings `STR_IMAGES`, `STR_IMAGES_DISPLAY`,
`STR_IMAGES_PLACEHOLDER` and `STR_IMAGES_SUPPRESS`
    - Rewording certain translations to make them clearer

---

### 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**_
2026-03-11 23:02:22 +03:00
Zach Nelson f9d32b11d9 fix: Fix inter-word spacing rounding error in text layout (#1311)
## Summary

**What is the goal of this PR?**

### Problem

Inter-word gap widths were computed as two separately-snapped integers:

```cpp
gap = getSpaceWidth(fontId, style);                        // fp4::toPixel(spaceAdvance)
gap += getSpaceKernAdjust(fontId, leftCp, rightCp, style); // fp4::toPixel(kern1 + kern2)
```

Because `fp4::toPixel(a) + fp4::toPixel(b)` can differ from
`fp4::toPixel(a + b)` by +/-1 pixel when the fractional parts straddle a
rounding boundary, each inter-word space could be one pixel wider or
narrower than the correct value. This affected line-break width
decisions and word-position accumulation across the whole paragraph
layout pipeline.

### Fix

Replaces `getSpaceKernAdjust()` with `getSpaceAdvance(fontId, leftCp,
rightCp, style)`, which combines the space glyph advance and both
flanking kern values (`kern(leftCp, ' ')` + `kern(' ', rightCp)`) into a
single fixed-point sum before the snap:

```cpp
return fp4::toPixel(spaceAdvanceFP + kern(leftCp, ' ') + kern(' ', rightCp));
```

This is the same single-snap pattern already used by `getTextAdvanceX`
for word widths.

### Changes

- **`GfxRenderer`**: Replaces `getSpaceKernAdjust()` with
`getSpaceAdvance()`. `getSpaceWidth()` is retained for the
single-space-word case in `measureWordWidth` where no adjacent-word kern
context is available.
- **`ParsedText`**: All four call sites (`computeLineBreaks`,
`computeHyphenatedLineBreaks`, and both loops in `extractLine`) updated
to use `getSpaceAdvance()`. The now-redundant `spaceWidth`
pre-computation and parameter are removed from all three internal layout
functions.

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES to analyze for
correctness**_
2026-03-10 22:55:23 -05:00
Uri Tauber cbdbbc096a fix: load access fault crash (#1370)
## Summary

Fixes a crash (load access fault) when opening EPUB chapters whose first
text block exceeds 750 words.

## Changes

* **Crash fix (`addLineToPage`)**: Added a null guard for `currentPage`.
If `makePages()` hasn't run yet (which can happen when the first block
triggers the "text block too long" split path), the page is now created
on demand.
* **Layout fix (`characterData`)**: The early-split path previously used
`viewportWidth`, ignoring CSS margins and padding. It now computes
`effectiveWidth` using `totalHorizontalInset()`, consistent with
`makePages()`.

## Additional Context

* Crash signature: `MCAUSE=0x5` (load access fault), `A0=0x0` (`Page*`
null), `MTVAL=0x4 / 0x8` (offsets into `Page::elements`).
* Confirmed in two user reports reported in #1328
* Tested on PR #1357 (not on `master`).

---

### 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 >**_
2026-03-09 16:57:40 -05:00
jpirnay 03e62a8812 fix: Fix bootloop logging crash (#1357)
## Summary

* **What is the goal of this PR?** On a cold boot (or after a crash that
corrupts RTC RAM), logHead contains garbage. Then addToLogRingBuffer
does: ``strncpy(logMessages[logHead], message, MAX_ENTRY_LEN - 1); ``
With garbage logHead, this computes a completely invalid address. The %
MAX_LOG_LINES guard on line 16 only runs after the bad store, which is
too late. The fix is to clamp logHead before use.

## 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**_ (did use claude
for the magic hash value)
2026-03-09 21:53:38 +01:00
jpirnay cde401d22b chore: micro-optimisation: early exit on fillUncompressedSizes (#1322)
## Summary

* **What is the goal of this PR?** Avoid repeated full central-directory
scans by using early stop when all requested targets are already
matched.
* **What changes are included?**

## 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? _** PARTIALLY **_
Identified by AI
2026-03-08 14:15:51 -05:00
jpirnay 8070d251f1 Merge branch 'feat-bookinfo' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 17:58:33 +01:00
jpirnay e52d0d3fb3 Merge branch 'fix-logging' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 16:34:28 +01:00
jpirnay 996ae89d62 And nitpick, too 2026-03-08 16:33:01 +01:00
jpirnay ed1a21fb7b Add magic value 2026-03-08 16:26:52 +01:00
jpirnay a3a50c8c40 Clear log if invalid 2026-03-08 16:05:08 +01:00
jpirnay c464bdede8 Add and expose sanitizing logic 2026-03-08 15:51:05 +01:00
jpirnay eaee1e3a83 Merge branch 'fix-logging' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 15:41:53 +01:00
jpirnay 98fb3d65c9 And even more... 2026-03-08 12:45:14 +01:00
jpirnay 9182a05670 And more... 2026-03-08 12:14:18 +01:00
jpirnay 42a01446ef More review changes 2026-03-08 11:27:52 +01:00
jpirnay b9b60d31ba Further guards according to review 2026-03-08 11:19:56 +01:00
jpirnay 2010b33e5d Review amendments 2026-03-08 11:03:50 +01:00
jpirnay 35897d33ae Fix bootloop logging crash 2026-03-08 10:57:49 +01:00
jpirnay 69f893840a Add getmODIFYdATEtIME 2026-03-08 10:08:38 +01:00
jpirnay b9eefc5e70 Fix fast path 2026-03-08 10:06:08 +01:00
jpirnay d76581e7ff Merge branch 'perf-uifonts2' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 10:01:38 +01:00
jpirnay ec79f7b2ef Merge branch 'perf-fillrect' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 10:01:17 +01:00
jpirnay ed0302571e Merge branch 'feat-koysnc-xpath' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:58:54 +01:00
jpirnay c63659311e Merge branch 'feat-overlay' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:58:14 +01:00
jpirnay 8688139a71 Merge branch 'feat-hiddenfiles' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:56:47 +01:00
jpirnay f82cc27d09 Merge branch 'feat-cache-koreader-hash' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:55:42 +01:00
jpirnay ea36d2c787 Merge branch 'fix-jpegcleanup' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:55:24 +01:00
jpirnay 786fbfa7c1 Merge branch 'feat-page-overlay' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:55:09 +01:00
jpirnay bfc86eabf9 Merge branch 'fix-hyphen_apostrophe' of https://github.com/jpirnay/crosspoint-reader into mybuild 2026-03-08 09:54:39 +01:00
jpirnay 2abcf9bc68 Review fixes 2026-03-07 19:33:02 +01:00
jpirnay a6f61fb0d0 Proper series detection 2026-03-07 19:06:53 +01:00
jpirnay 95f1d14f3f Revert version bump 2026-03-07 18:53:39 +01:00
jpirnay 10e0680f6e Add bookinfo 2026-03-07 18:07:49 +01:00
jpirnay 87e5cc4fe1 Extend metadata 2026-03-07 18:01:18 +01:00
jpirnay c083079898 deduping by byteOffset alone for clarity. 2026-03-07 10:59:48 +01:00
jpirnay 579d140ee9 Some fixes according to review 2026-03-07 10:52:31 +01:00
jpirnay 34a96d717d Merge branch 'master' of https://github.com/crosspoint-reader/crosspoint-reader into feat-page-overlay 2026-03-07 10:22:18 +01:00
jpirnay 520ae07ad5 Pick up assert recommendation 2026-03-07 10:20:11 +01:00
jpirnay ae19e975fa Implement znelson recommendation 2026-03-07 10:11:54 +01:00
Jonasz Potoniec 65e6caea57 chore: Polish localization for STR_DELETE (#1323) 2026-03-06 21:22:52 -05:00
Xuan-Son Nguyenandcoderabbitai[bot] a59af01583 fix: dump crash log without usb plugged, bump release log to INFO (#1332)
## Summary

Follow-up
https://github.com/crosspoint-reader/crosspoint-reader/pull/1145

- Fix log not being record without USB connected
- Bump release log to INFO for more logging details

---

### 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: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-06 22:05:23 +01:00
Uri Tauber 8fbb37b359 feat: footnote anchor navigation (#1245)
## Summary: Enable footnote anchor navigation in EPUB reader

This PR extracts the core anchor-to-page mapping mechanism from PR #1143
(TOC fragment navigation) to provide immediate footnote navigation
support. By merging this focused subset first, users get a complete
footnote experience now while simplifying the eventual review and merge
of the full #1143 PR.

  ---

## What this extracts from PR #1143

PR #1143 implements comprehensive TOC fragment navigation for EPUBs with
multi-chapter spine files. This PR takes only the anchor resolution
infrastructure:

- Anchor-to-page mapping in section cache: During page layout,
ChapterHtmlSlimParser records which page each HTML id attribute lands
on, serializing the map into the .bin cache file.
- Anchor resolution in `EpubReaderActivity`: When navigating to a
footnote link with a fragment (e.g., `chapter2.xhtml#note1`), the reader
resolves the anchor to a page number and jumps directly to it.
- Section file format change: Bumped to version 15, adds anchor map
offset in header.

  ---

## Simplified scope vs. PR #1143

To minimize conflicts and complexity, this PR differs from #1143 in key
ways:

* **Anchors tracked**
  * **Origin:** Only TOC anchors (passed via `std::set`)
  * **This branch:** All `id` attributes

* **Page breaks**
  * **Origin**: Forces new page at TOC chapter boundaries
  * **This branch:** None — natural flow

* **TOC integration**
  * **Origin**: `tocBoundaries`, `getTocIndexForPage()`, chapter skip
  * **This branch:** None — just footnote links

* **Bug fix**
  * **This branch:** Fixed anchor page off-by-1/2 bug


The anchor recording bug (recording page number before `makePages()`
flushes previous block) was identified and fixed during this extraction.
The fix uses a deferred `pendingAnchorId` pattern that records the
anchor after page completion.

  ---

## Positioning for future merge

Changes are structured to minimize conflicts when #1143 eventually
merges:

- `ChapterHtmlSlimParser.cpp` `startElement()`: Both branches rewrite
the same if `(!idAttr.empty())` block. The merged version will combine
both approaches (TOC anchors get page breaks + immediate recording;
footnote anchors get deferred recording).
- `EpubReaderActivity.cpp` `render()`: The `pendingAnchor` resolution
block is positioned at the exact same insertion point where #1143 places
its `pendingTocIndex` block (line 596, right after `nextPageNumber`
assignment). During merge, both blocks will sit side-by-side.
   
  ---

## Why merge separately?

1. Immediate user value: Footnote navigation works now without waiting
for the full TOC overhaul
   2. Easier review: ~100 lines vs. 500+ lines in #1143 
3. Bug fix included: The page recording bug is fixed here and will carry
into #1143
4. Minimal conflicts: Structured for clean merge — both PRs touch the
same files but in complementary ways
---

### AI Usage

Did you use AI tools to help write this code? _**< YES >**_ Done by
Claude Opus 4.6
2026-03-06 21:10:45 +03:00