Compare commits
No commits in common. "crosspoint-ef" and "0.15.0" have entirely different histories.
crosspoint
...
0.15.0
@ -1,41 +0,0 @@
|
|||||||
name: CI
|
|
||||||
'on':
|
|
||||||
push:
|
|
||||||
branches: [master, crosspoint-ef]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
run: |
|
|
||||||
# Use system Python on self-hosted runner
|
|
||||||
python3 --version
|
|
||||||
python3 -m pip install --upgrade pip
|
|
||||||
|
|
||||||
- name: Install PlatformIO Core
|
|
||||||
run: python3 -m pip install --upgrade platformio
|
|
||||||
|
|
||||||
- name: Run cppcheck
|
|
||||||
run: pio check --fail-on-defect low --fail-on-defect medium --fail-on-defect high
|
|
||||||
|
|
||||||
- name: Run clang-format
|
|
||||||
run: |
|
|
||||||
# Use system clang-format if available, skip if not
|
|
||||||
if command -v clang-format &> /dev/null; then
|
|
||||||
./bin/clang-format-fix && git diff --exit-code || (echo "Please run 'bin/clang-format-fix' to fix formatting issues" && exit 1)
|
|
||||||
else
|
|
||||||
echo "clang-format not found, skipping format check"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Generate Dictionary Index
|
|
||||||
run: |
|
|
||||||
python3 scripts/generate_dict_index.py --zip dict-en-en.zip --output lib/StarDict/DictPrefixIndex.generated.h
|
|
||||||
|
|
||||||
- name: Build CrossPoint
|
|
||||||
run: pio run
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
name: "PR Formatting"
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- reopened
|
|
||||||
- edited
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
title-check:
|
|
||||||
name: Title Check
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check PR Title Format
|
|
||||||
run: |
|
|
||||||
PR_TITLE="${{ github.event.pull_request.title }}"
|
|
||||||
echo "Checking PR title: $PR_TITLE"
|
|
||||||
|
|
||||||
# Conventional commit pattern: type(scope): description or type: description
|
|
||||||
# Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
|
||||||
PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-zA-Z0-9_-]+\))?: .+"
|
|
||||||
|
|
||||||
if echo "$PR_TITLE" | grep -qE "$PATTERN"; then
|
|
||||||
echo "✓ PR title follows conventional commit format"
|
|
||||||
else
|
|
||||||
echo "✗ PR title does not follow conventional commit format"
|
|
||||||
echo ""
|
|
||||||
echo "Expected format: type(scope): description"
|
|
||||||
echo " or: type: description"
|
|
||||||
echo ""
|
|
||||||
echo "Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
|
|
||||||
echo ""
|
|
||||||
echo "Examples:"
|
|
||||||
echo " feat(reader): add bookmark sync feature"
|
|
||||||
echo " fix: resolve memory leak in epub parser"
|
|
||||||
echo " docs: update README with new instructions"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
name: Compile Release
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
run: |
|
|
||||||
# Use system Python on self-hosted runner
|
|
||||||
python3 --version
|
|
||||||
python3 -m pip install --upgrade pip
|
|
||||||
|
|
||||||
- name: Install PlatformIO Core
|
|
||||||
run: python3 -m pip install --upgrade platformio
|
|
||||||
|
|
||||||
- name: Generate Dictionary Index
|
|
||||||
run: |
|
|
||||||
python3 scripts/generate_dict_index.py --zip dict-en-en.zip --output lib/StarDict/DictPrefixIndex.generated.h
|
|
||||||
|
|
||||||
- name: Build CrossPoint
|
|
||||||
run: pio run -e gh_release
|
|
||||||
|
|
||||||
- name: Upload Artifacts
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: CrossPoint-${{ github.ref_name }}
|
|
||||||
path: |
|
|
||||||
.pio/build/gh_release/bootloader.bin
|
|
||||||
.pio/build/gh_release/firmware.bin
|
|
||||||
.pio/build/gh_release/firmware.elf
|
|
||||||
.pio/build/gh_release/firmware.map
|
|
||||||
.pio/build/gh_release/partitions.bin
|
|
||||||
13
.gitignore
vendored
13
.gitignore
vendored
@ -2,20 +2,7 @@
|
|||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode
|
.vscode
|
||||||
.cursor/
|
|
||||||
chat-summaries/
|
|
||||||
lib/EpdFont/fontsrc
|
lib/EpdFont/fontsrc
|
||||||
*.generated.h
|
*.generated.h
|
||||||
.vs
|
|
||||||
build
|
build
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
test/epubs/
|
|
||||||
CrossPoint-ef.md
|
|
||||||
Serial_print.code-search
|
|
||||||
|
|
||||||
# Gitea Release note drafts
|
|
||||||
release-notes-*.md
|
|
||||||
|
|
||||||
# Gitea Actions runner config (contains credentials)
|
|
||||||
.runner
|
|
||||||
.runner.*
|
|
||||||
|
|||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,5 +1,3 @@
|
|||||||
[submodule "open-x4-sdk"]
|
[submodule "open-x4-sdk"]
|
||||||
path = open-x4-sdk
|
path = open-x4-sdk
|
||||||
url = https://code.cottongin.xyz/cottongin/community-sdk.git
|
url = https://github.com/open-x4-epaper/community-sdk.git
|
||||||
branch = crosspoint-ef
|
|
||||||
ignore = dirty
|
|
||||||
|
|||||||
15
README.md
15
README.md
@ -1,15 +1,4 @@
|
|||||||
# CrossPoint Reader (ef fork)
|
# CrossPoint Reader
|
||||||
|
|
||||||
> **Note:** This is **crosspoint-ef**, a heavily customized fork of [CrossPoint Reader](https://github.com/crosspoint-reader/crosspoint-reader) with additional features, UI improvements, and bug fixes. It also uses a [forked community-sdk](https://code.cottongin.xyz/cottongin/community-sdk) with additional hardware support.
|
|
||||||
>
|
|
||||||
> **Documentation:**
|
|
||||||
> - [Feature Overview](./docs/crosspoint-ef-features.md) - What's new in this fork
|
|
||||||
> - [User Guide](./docs/crosspoint-ef-user-guide.md) - How to use the new features
|
|
||||||
> - [Technical Comparison](./docs/branch-comparison-summary.md) - Detailed diff from upstream
|
|
||||||
>
|
|
||||||
> **Disclaimer:** Much of the code in this fork was developed with assistance from [Claude](https://claude.ai), an AI assistant by Anthropic.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Firmware for the **Xteink X4** e-paper display reader (unaffiliated with Xteink).
|
Firmware for the **Xteink X4** e-paper display reader (unaffiliated with Xteink).
|
||||||
Built using **PlatformIO** and targeting the **ESP32-C3** microcontroller.
|
Built using **PlatformIO** and targeting the **ESP32-C3** microcontroller.
|
||||||
@ -52,8 +41,6 @@ This project is **not affiliated with Xteink**; it's built as a community projec
|
|||||||
- [ ] Full UTF support
|
- [ ] Full UTF support
|
||||||
- [x] Screen rotation
|
- [x] Screen rotation
|
||||||
|
|
||||||
Multi-language support: Read EPUBs in various languages, including English, Spanish, French, German, Italian, Portuguese, Russian, Ukrainian, Polish, Swedish, Norwegian, [and more](./USER_GUIDE.md#supported-languages).
|
|
||||||
|
|
||||||
See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint.
|
See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint.
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|||||||
@ -81,18 +81,6 @@ See the [webserver docs](./docs/webserver.md) for more information on how to con
|
|||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Advanced users can also manage files programmatically or via the command line using `curl`. See the [webserver docs](./docs/webserver.md) for details.
|
> Advanced users can also manage files programmatically or via the command line using `curl`. See the [webserver docs](./docs/webserver.md) for details.
|
||||||
|
|
||||||
### 3.4.1 Calibre Wireless Transfers
|
|
||||||
|
|
||||||
CrossPoint supports sending books from Calibre using the CrossPoint Reader device plugin.
|
|
||||||
|
|
||||||
1. Install the plugin in Calibre:
|
|
||||||
- Head to https://github.com/crosspoint-reader/calibre-plugins/releases to download the latest version of the crosspoint_reader plugin.
|
|
||||||
- Download the zip file.
|
|
||||||
- Open Calibre → Preferences → Plugins → Load plugin from file → Select the zip file.
|
|
||||||
2. On the device: File Transfer → Connect to Calibre → Join a network.
|
|
||||||
3. Make sure your computer is on the same WiFi network.
|
|
||||||
4. In Calibre, click "Send to device" to transfer books.
|
|
||||||
|
|
||||||
### 3.5 Settings
|
### 3.5 Settings
|
||||||
|
|
||||||
The Settings screen allows you to configure the device's behavior. There are a few settings you can adjust:
|
The Settings screen allows you to configure the device's behavior. There are a few settings you can adjust:
|
||||||
@ -105,10 +93,6 @@ The Settings screen allows you to configure the device's behavior. There are a f
|
|||||||
- **Sleep Screen Cover Mode**: How to display the book cover when "Cover" sleep screen is selected:
|
- **Sleep Screen Cover Mode**: How to display the book cover when "Cover" sleep screen is selected:
|
||||||
- "Fit" (default) - Scale the image down to fit centered on the screen, padding with white borders as necessary
|
- "Fit" (default) - Scale the image down to fit centered on the screen, padding with white borders as necessary
|
||||||
- "Crop" - Scale the image down and crop as necessary to try to to fill the screen (Note: this is experimental and may not work as expected)
|
- "Crop" - Scale the image down and crop as necessary to try to to fill the screen (Note: this is experimental and may not work as expected)
|
||||||
- **Sleep Screen Cover Filter**: What filter will be applied to the book cover when "Cover" sleep screen is selected
|
|
||||||
- "None" (default) - The cover image will be converted to a grayscale image and displayed as it is
|
|
||||||
- "Contrast" - The image will be displayed as a black & white image without grayscale conversion
|
|
||||||
- "Inverted" - The image will be inverted as in white&black and will be displayed without grayscale conversion
|
|
||||||
- **Status Bar**: Configure the status bar displayed while reading:
|
- **Status Bar**: Configure the status bar displayed while reading:
|
||||||
- "None" - No status bar
|
- "None" - No status bar
|
||||||
- "No Progress" - Show status bar without reading progress
|
- "No Progress" - Show status bar without reading progress
|
||||||
@ -132,7 +116,6 @@ The Settings screen allows you to configure the device's behavior. There are a f
|
|||||||
- Back, Confirm, Left, Right (default)
|
- Back, Confirm, Left, Right (default)
|
||||||
- Left, Right, Back, Confirm
|
- Left, Right, Back, Confirm
|
||||||
- Left, Back, Confirm, Right
|
- Left, Back, Confirm, Right
|
||||||
- Back, Confirm, Right, Left
|
|
||||||
- **Side Button Layout (reader)**: Swap the order of the up and down volume buttons from Previous/Next to Next/Previous. This change is only in effect when reading.
|
- **Side Button Layout (reader)**: Swap the order of the up and down volume buttons from Previous/Next to Next/Previous. This change is only in effect when reading.
|
||||||
- **Long-press Chapter Skip**: Set whether long-pressing page turn buttons skip to the next/previous chapter.
|
- **Long-press Chapter Skip**: Set whether long-pressing page turn buttons skip to the next/previous chapter.
|
||||||
- "Chapter Skip" (default) - Long-pressing skips to next/previous chapter
|
- "Chapter Skip" (default) - Long-pressing skips to next/previous chapter
|
||||||
@ -148,7 +131,7 @@ The Settings screen allows you to configure the device's behavior. There are a f
|
|||||||
- **Reader Paragraph Alignment**: Set the alignment of paragraphs; options are "Justified" (default), "Left", "Center", or "Right".
|
- **Reader Paragraph Alignment**: Set the alignment of paragraphs; options are "Justified" (default), "Left", "Center", or "Right".
|
||||||
- **Time to Sleep**: Set the duration of inactivity before the device automatically goes to sleep.
|
- **Time to Sleep**: Set the duration of inactivity before the device automatically goes to sleep.
|
||||||
- **Refresh Frequency**: Set how often the screen does a full refresh while reading to reduce ghosting.
|
- **Refresh Frequency**: Set how often the screen does a full refresh while reading to reduce ghosting.
|
||||||
- **OPDS Browser**: Configure OPDS server settings for browsing and downloading books. Set the server URL (for Calibre Content Server, add `/opds` to the end), and optionally configure username and password for servers requiring authentication. Note: Only HTTP Basic authentication is supported. If using Calibre Content Server with authentication enabled, you must set it to use Basic authentication instead of the default Digest authentication.
|
- **Calibre Settings**: Set up integration for accessing a Calibre web library or connecting to Calibre as a wireless device.
|
||||||
- **Check for updates**: Check for firmware updates over WiFi.
|
- **Check for updates**: Check for firmware updates over WiFi.
|
||||||
|
|
||||||
### 3.6 Sleep Screen
|
### 3.6 Sleep Screen
|
||||||
@ -194,15 +177,6 @@ This feature can be disabled in **[Settings](#35-settings)** to help avoid chang
|
|||||||
* **Return to Home:** Press and **hold** the **Back** button to close the book and return to the **[Home](#31-home-screen)** screen.
|
* **Return to Home:** Press and **hold** the **Back** button to close the book and return to the **[Home](#31-home-screen)** screen.
|
||||||
* **Chapter Menu:** Press **Confirm** to open the **[Table of Contents/Chapter Selection](#5-chapter-selection-screen)**.
|
* **Chapter Menu:** Press **Confirm** to open the **[Table of Contents/Chapter Selection](#5-chapter-selection-screen)**.
|
||||||
|
|
||||||
### Supported Languages
|
|
||||||
|
|
||||||
CrossPoint renders text using the following Unicode character blocks, enabling support for a wide range of languages:
|
|
||||||
|
|
||||||
* **Latin Script (Basic, Supplement, Extended-A):** Covers English, German, French, Spanish, Portuguese, Italian, Dutch, Swedish, Norwegian, Danish, Finnish, Polish, Czech, Hungarian, Romanian, Slovak, Slovenian, Turkish, and others.
|
|
||||||
* **Cyrillic Script (Standard and Extended):** Covers Russian, Ukrainian, Belarusian, Bulgarian, Serbian, Macedonian, Kazakh, Kyrgyz, Mongolian, and others.
|
|
||||||
|
|
||||||
What is not supported: Chinese, Japanese, Korean, Vietnamese, Hebrew, Arabic and Farsi.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Chapter Selection Screen
|
## 5. Chapter Selection Screen
|
||||||
|
|||||||
@ -1,137 +0,0 @@
|
|||||||
# Ghosting Issue Bisect Debug Summary
|
|
||||||
|
|
||||||
**Date:** 2026-01-27
|
|
||||||
**Branch:** `catch-up-PR-merges`
|
|
||||||
**Issue:** Text ghosting on page turns when anti-aliasing enabled
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Problem Description
|
|
||||||
|
|
||||||
After merging 15 upstream PRs, ghosting artifacts appeared when turning pages in the EPUB reader. The ghosting manifested as residual edges/outlines of previous page text, visible only when text anti-aliasing was enabled.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## The 15 Merged PRs (in merge order)
|
|
||||||
|
|
||||||
| Order | Commit | PR | Description |
|
|
||||||
|-------|--------|-----|-------------|
|
|
||||||
| 1 | `703d955` | #466 | fix: Add .vs folder to .gitignore |
|
|
||||||
| 2 | `7a4af97` | #530 | docs: Update README with supported languages for EPUB |
|
|
||||||
| 3 | `aa87b3f` | #547 | docs: add font generation commands to builtin font headers |
|
|
||||||
| 4 | `25b75b7` | #425 | fix: Allow line break after ellipsis and underscore |
|
|
||||||
| 5 | `31199f9` | #507 | fix: remove decimal places from progress % |
|
|
||||||
| 6 | `d8b8c5b` | #526 | fix: add txt books to recent tab |
|
|
||||||
| 7 | `991b6b5` | #498 | feat: treat .md files as .txt |
|
|
||||||
| 8 | `8920c62` | #525 | fix: line break - flush word before br tag |
|
|
||||||
| 9 | `3cee01b` | #460 | feat: add new configuration for front buttons |
|
|
||||||
| 10 | `f01f397` | #557 | fix: rotate origin in drawImage |
|
|
||||||
| 11 | `03a18fb` | #484 | UX improvement to Forget Network page |
|
|
||||||
| 12 | `ff0392b` | #492 | fix: Validate settings on read |
|
|
||||||
| 13 | `6ffd19a` | #482 | fix: short-press power button to wakeup |
|
|
||||||
| 14 | `c90304f` | #465 | fix: cover artifacts - merge crop parameter |
|
|
||||||
| 15 | `bc4edee` | #404 | Refactor: Replace CalibreWirelessActivity with CalibreConnectActivity |
|
|
||||||
|
|
||||||
**Base commit:** `1a38fd9` (before any PR merges)
|
|
||||||
**Checkpoint commit:** `397abe1` (after all PR merges)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bisect Process
|
|
||||||
|
|
||||||
### Initial State
|
|
||||||
- **GOOD:** `1a38fd9` - no ghosting
|
|
||||||
- **BAD:** `397abe1` (HEAD) - ghosting present
|
|
||||||
|
|
||||||
### Bisect Steps
|
|
||||||
|
|
||||||
| Step | Commit | PR | Result | Remaining |
|
|
||||||
|------|--------|-----|--------|-----------|
|
|
||||||
| 1 | `991b6b5` | #498 (midpoint) | NO ghosting | Bug in commits 8-15 |
|
|
||||||
| 2 | `ff0392b` | #492 (midpoint of 8-15) | NO ghosting | Bug in commits 13-15 |
|
|
||||||
| 3 | `c90304f` | #465 | NO ghosting | Bug in commits 15 or checkpoint |
|
|
||||||
| 4 | `bc4edee` | #404 | NO ghosting | Bug in checkpoint only |
|
|
||||||
|
|
||||||
### Compilation Issue During Bisect
|
|
||||||
|
|
||||||
A conflict from PR #526 merge left `RECENT_BOOKS.addBook()` with 1 argument instead of 3. This caused compilation failures at intermediate commits. Temporary fix applied at each step:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// Changed from:
|
|
||||||
RECENT_BOOKS.addBook(txt->getPath());
|
|
||||||
// To:
|
|
||||||
RECENT_BOOKS.addBook(txt->getPath(), txt->getTitle(), "");
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Root Cause Finding
|
|
||||||
|
|
||||||
**The ghosting was NOT caused by any upstream PR.**
|
|
||||||
|
|
||||||
After testing all commits, the bisect pointed to the checkpoint commit `397abe1`. However, the diff between `bc4edee` and `397abe1` only contained:
|
|
||||||
- The `addBook` fix (unrelated to display)
|
|
||||||
- Removing duplicate `handleDownload` (unrelated to display)
|
|
||||||
|
|
||||||
### Actual Cause: Uncommitted Local Changes
|
|
||||||
|
|
||||||
The ghosting was caused by **uncommitted local changes in the IDE working directory**. These changes were being preserved across `git checkout` operations because they existed in IDE buffers.
|
|
||||||
|
|
||||||
When `git checkout -f catch-up-PR-merges` was executed (force checkout), all local changes were discarded and the ghosting disappeared.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Local Changes That Were Present
|
|
||||||
|
|
||||||
The following modifications existed in the working directory but were NOT in the checkpoint commit:
|
|
||||||
|
|
||||||
- `CrossPointSettings.h/cpp` - enum `_COUNT` suffixes, `readAndValidate`, OPDS auth fields
|
|
||||||
- `ChapterHtmlSlimParser.h/cpp` - `flushPartWordBuffer()` function
|
|
||||||
- `SleepActivity.cpp` - `drawImage` coordinate changes
|
|
||||||
- `JpegToBmpConverter.h/cpp` - `crop` parameter
|
|
||||||
- `HomeActivity.cpp` - "OPDS Browser" label
|
|
||||||
- `SettingsActivity.cpp` - front button layout options
|
|
||||||
- `CrossPointWebServer.h/cpp` - UDP discovery, `WsUploadStatus`
|
|
||||||
|
|
||||||
**Important:** These changes were actually already committed in the PR merge commits. The confusion arose because:
|
|
||||||
1. Checking out older commits removed these changes
|
|
||||||
2. IDE buffers or manual re-application restored them as "local changes"
|
|
||||||
3. This created a mismatch between committed code and working directory
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resolution
|
|
||||||
|
|
||||||
1. Force checkout to HEAD: `git checkout -f catch-up-PR-merges`
|
|
||||||
2. Verified all PR changes are properly committed
|
|
||||||
3. Built and tested - no ghosting
|
|
||||||
4. Working directory is now clean (matches committed state)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Key Lessons
|
|
||||||
|
|
||||||
1. **Always check `git status` before bisecting** - local changes can persist across checkouts
|
|
||||||
2. **Use `git checkout -f` or `git checkout <commit> -- .`** to ensure clean state
|
|
||||||
3. **IDE buffers can reintroduce changes** - close/reload files after checkout if needed
|
|
||||||
4. **Bisecting with compilation errors** requires temporary fixes that don't affect the bug being investigated
|
|
||||||
5. **The "bug" may not be in commits at all** - it could be in uncommitted working directory changes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Commands Reference
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Force checkout to discard local changes
|
|
||||||
git checkout -f <branch>
|
|
||||||
|
|
||||||
# Checkout specific commit with clean state
|
|
||||||
git checkout <commit> -- . && git checkout <commit>
|
|
||||||
|
|
||||||
# Check for uncommitted changes
|
|
||||||
git status
|
|
||||||
git diff --stat
|
|
||||||
|
|
||||||
# View what's in a specific commit
|
|
||||||
git show <commit>:path/to/file
|
|
||||||
```
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
# Serial.printf Calls Without `if (Serial)` Guards
|
|
||||||
|
|
||||||
**Date:** 2026-01-28
|
|
||||||
**Status:** Informational (not blocking issues)
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
The codebase contains **408 Serial print calls** across 27 files in `src/`. Of these, only **16 calls** (in 2 files) have explicit `if (Serial)` guards.
|
|
||||||
|
|
||||||
**This is not a problem** because `Serial.setTxTimeoutMs(0)` is called in `setup()` before any activity code runs, making all Serial output non-blocking globally.
|
|
||||||
|
|
||||||
## Protection Mechanism
|
|
||||||
|
|
||||||
In `src/main.cpp` (lines 467-468):
|
|
||||||
```cpp
|
|
||||||
Serial.begin(115200);
|
|
||||||
Serial.setTxTimeoutMs(0); // Non-blocking TX - critical for USB disconnect handling
|
|
||||||
```
|
|
||||||
|
|
||||||
This ensures that even without `if (Serial)` guards, Serial.printf calls will return immediately when USB is disconnected instead of blocking indefinitely.
|
|
||||||
|
|
||||||
## Files with `if (Serial)` Guards (16 calls)
|
|
||||||
|
|
||||||
| File | Protected Calls |
|
|
||||||
|------|-----------------|
|
|
||||||
| `src/activities/reader/EpubReaderActivity.cpp` | 15 |
|
|
||||||
| `src/main.cpp` | 1 |
|
|
||||||
|
|
||||||
## Files Without Guards (392 calls)
|
|
||||||
|
|
||||||
These calls are protected by `Serial.setTxTimeoutMs(0)` but don't have explicit guards:
|
|
||||||
|
|
||||||
| File | Unguarded Calls |
|
|
||||||
|------|-----------------|
|
|
||||||
| `src/network/CrossPointWebServer.cpp` | 106 |
|
|
||||||
| `src/activities/network/CrossPointWebServerActivity.cpp` | 49 |
|
|
||||||
| `src/activities/boot_sleep/SleepActivity.cpp` | 33 |
|
|
||||||
| `src/BookManager.cpp` | 25 |
|
|
||||||
| `src/activities/reader/TxtReaderActivity.cpp` | 20 |
|
|
||||||
| `src/activities/home/HomeActivity.cpp` | 16 |
|
|
||||||
| `src/network/OtaUpdater.cpp` | 16 |
|
|
||||||
| `src/util/Md5Utils.cpp` | 15 |
|
|
||||||
| `src/main.cpp` | 13 (plus 1 guarded) |
|
|
||||||
| `src/WifiCredentialStore.cpp` | 12 |
|
|
||||||
| `src/network/HttpDownloader.cpp` | 12 |
|
|
||||||
| `src/BookListStore.cpp` | 11 |
|
|
||||||
| `src/activities/network/WifiSelectionActivity.cpp` | 11 |
|
|
||||||
| `src/activities/settings/OtaUpdateActivity.cpp` | 9 |
|
|
||||||
| `src/activities/browser/OpdsBookBrowserActivity.cpp` | 9 |
|
|
||||||
| `src/activities/settings/ClearCacheActivity.cpp` | 7 |
|
|
||||||
| `src/BookmarkStore.cpp` | 6 |
|
|
||||||
| `src/RecentBooksStore.cpp` | 5 |
|
|
||||||
| `src/activities/reader/ReaderActivity.cpp` | 4 |
|
|
||||||
| `src/activities/Activity.h` | 3 |
|
|
||||||
| `src/CrossPointSettings.cpp` | 3 |
|
|
||||||
| `src/activities/network/CalibreConnectActivity.cpp` | 2 |
|
|
||||||
| `src/activities/home/ListViewActivity.cpp` | 2 |
|
|
||||||
| `src/activities/home/MyLibraryActivity.cpp` | 1 |
|
|
||||||
| `src/activities/dictionary/DictionarySearchActivity.cpp` | 1 |
|
|
||||||
| `src/CrossPointState.cpp` | 1 |
|
|
||||||
|
|
||||||
## Recommendation
|
|
||||||
|
|
||||||
No immediate action required. The global `Serial.setTxTimeoutMs(0)` protection is sufficient.
|
|
||||||
|
|
||||||
If desired, `if (Serial)` guards could be added to high-frequency logging paths for minor performance optimization (skipping format string processing), but this is low priority.
|
|
||||||
|
|
||||||
## Note on open-x4-sdk
|
|
||||||
|
|
||||||
The `open-x4-sdk` submodule also contains Serial calls (in `EInkDisplay.cpp`, `SDCardManager.cpp`). These are also protected by the global timeout setting since `Serial.begin()` and `setTxTimeoutMs()` are called before any SDK code executes.
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
# Serial Blocking Debug Session Summary
|
|
||||||
|
|
||||||
**Date:** 2026-01-28
|
|
||||||
**Issue:** Device freezes when booted without USB connected
|
|
||||||
**Resolution:** `Serial.setTxTimeoutMs(0)` - make Serial TX non-blocking
|
|
||||||
|
|
||||||
## Problem Description
|
|
||||||
|
|
||||||
During release preparation for ef-0.15.9, the device was discovered to freeze completely when:
|
|
||||||
1. Unplugged from USB
|
|
||||||
2. Powered on via power button
|
|
||||||
3. Book page displays, then device becomes unresponsive
|
|
||||||
4. No button presses register
|
|
||||||
|
|
||||||
The device worked perfectly when USB was connected.
|
|
||||||
|
|
||||||
## Investigation Process
|
|
||||||
|
|
||||||
### Initial Hypotheses Tested
|
|
||||||
|
|
||||||
Multiple hypotheses were systematically investigated:
|
|
||||||
|
|
||||||
1. **Hypothesis A-D:** Display/rendering mutex issues
|
|
||||||
- Added mutex logging to SD card
|
|
||||||
- Mutex operations completed successfully
|
|
||||||
- Ruled out as root cause
|
|
||||||
|
|
||||||
2. **Hypothesis E:** FreeRTOS task creation issues
|
|
||||||
- Task created and ran successfully
|
|
||||||
- First render completed normally
|
|
||||||
- Ruled out
|
|
||||||
|
|
||||||
3. **Hypothesis F-G:** Main loop execution
|
|
||||||
- Added loop counter logging to SD card
|
|
||||||
- **Key finding:** Main loop never started logging
|
|
||||||
- Setup() completed but loop() never executed meaningful work
|
|
||||||
|
|
||||||
4. **Hypothesis H-J:** Various timing and initialization issues
|
|
||||||
- Tested different delays and initialization orders
|
|
||||||
- No improvement
|
|
||||||
|
|
||||||
### Root Cause Discovery
|
|
||||||
|
|
||||||
The breakthrough came from analyzing the boot sequence:
|
|
||||||
|
|
||||||
1. `setup()` completes successfully
|
|
||||||
2. `EpubReaderActivity::onEnter()` runs and calls `Serial.printf()` to log progress
|
|
||||||
3. **Device hangs at Serial.printf() call**
|
|
||||||
|
|
||||||
On ESP32-C3 with USB CDC (USB serial), `Serial.printf()` blocks indefinitely waiting for the TX buffer to drain when USB is not connected. The default behavior expects a host to read the data.
|
|
||||||
|
|
||||||
### Evidence
|
|
||||||
|
|
||||||
- When USB connected: `Serial.printf()` returns immediately (data sent to host)
|
|
||||||
- When USB disconnected: `Serial.printf()` blocks forever waiting for TX buffer space
|
|
||||||
- The hang occurred specifically in `EpubReaderActivity.cpp` during progress logging
|
|
||||||
|
|
||||||
## Solution
|
|
||||||
|
|
||||||
### Primary Fix
|
|
||||||
|
|
||||||
Configure Serial to be non-blocking in `src/main.cpp`:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// Always initialize Serial but make it non-blocking
|
|
||||||
Serial.begin(115200);
|
|
||||||
Serial.setTxTimeoutMs(0); // Non-blocking TX - critical for USB disconnect handling
|
|
||||||
```
|
|
||||||
|
|
||||||
`Serial.setTxTimeoutMs(0)` tells the ESP32 Arduino core to return immediately from Serial write operations if the buffer is full, rather than blocking.
|
|
||||||
|
|
||||||
### Secondary Protection (Belt and Suspenders)
|
|
||||||
|
|
||||||
Added `if (Serial)` guards to high-traffic Serial calls in `EpubReaderActivity.cpp`:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
if (Serial) Serial.printf("[%lu] [ERS] Loaded progress...\n", millis());
|
|
||||||
```
|
|
||||||
|
|
||||||
This provides an additional check before attempting to print, though it's not strictly necessary with the timeout set to 0.
|
|
||||||
|
|
||||||
## Files Changed
|
|
||||||
|
|
||||||
| File | Change |
|
|
||||||
|------|--------|
|
|
||||||
| `src/main.cpp` | Added `Serial.setTxTimeoutMs(0)` after `Serial.begin()` |
|
|
||||||
| `src/main.cpp` | Added `if (Serial)` guard to auto-sleep log |
|
|
||||||
| `src/main.cpp` | Added `if (Serial)` guard to max loop duration log |
|
|
||||||
| `src/activities/reader/EpubReaderActivity.cpp` | Added 16 `if (Serial)` guards |
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
After applying the fix:
|
|
||||||
1. Device boots successfully when unplugged from USB
|
|
||||||
2. Book pages render correctly
|
|
||||||
3. Button presses register normally
|
|
||||||
4. Sleep/wake cycle works
|
|
||||||
5. No functionality lost when USB is connected
|
|
||||||
|
|
||||||
## Lessons Learned
|
|
||||||
|
|
||||||
1. **ESP32-C3 USB CDC behavior:** Serial output can block indefinitely without a connected host
|
|
||||||
2. **Always set non-blocking:** `Serial.setTxTimeoutMs(0)` should be standard for battery-powered devices
|
|
||||||
3. **Debug logging location matters:** When debugging hangs, SD card logging proved essential since Serial was the problem
|
|
||||||
4. **Systematic hypothesis testing:** Ruled out many red herrings (mutex, task, rendering) before finding the true cause
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Why This Affects ESP32-C3 Specifically
|
|
||||||
|
|
||||||
The ESP32-C3 uses native USB CDC for serial communication (no external USB-UART chip). The Arduino core's default behavior is to wait for TX buffer space, which requires an active USB host connection.
|
|
||||||
|
|
||||||
### Alternative Approaches Considered
|
|
||||||
|
|
||||||
1. **Only initialize Serial when USB connected:** Partially implemented, but insufficient because USB can be disconnected after boot
|
|
||||||
2. **Add `if (Serial)` guards everywhere:** Too invasive (400+ calls)
|
|
||||||
3. **Disable Serial entirely:** Would lose debug output when USB connected
|
|
||||||
|
|
||||||
The chosen solution (`setTxTimeoutMs(0)`) provides the best balance: debug output works when USB is connected, device operates normally when disconnected.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- ESP32 Arduino Core Serial documentation
|
|
||||||
- ESP-IDF USB CDC documentation
|
|
||||||
- FreeRTOS queue behavior (initial red herring investigation)
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
# USB Serial Blocking Issue - Root Cause and Fix
|
|
||||||
|
|
||||||
**Date:** 2026-01-28
|
|
||||||
**Issue:** Device blocking/hanging when USB is not connected at boot
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Problem Description
|
|
||||||
|
|
||||||
The device would hang or behave unpredictably when booted without USB connected. This was traced to improper Serial handling on ESP32-C3 with USB CDC.
|
|
||||||
|
|
||||||
## Root Cause Analysis
|
|
||||||
|
|
||||||
### Factor A: `checkForFlashCommand()` Called Without Serial Initialization
|
|
||||||
|
|
||||||
The most critical issue was in `checkForFlashCommand()`, which is called at the start of every `loop()` iteration:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
void loop() {
|
|
||||||
checkForFlashCommand(); // Called EVERY loop iteration
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkForFlashCommand() {
|
|
||||||
while (Serial.available()) { // Called even when Serial.begin() was never called!
|
|
||||||
char c = Serial.read();
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When USB is not connected at boot, `Serial.begin()` is never called. Then in `loop()`, `checkForFlashCommand()` calls `Serial.available()` and `Serial.read()` on an uninitialized Serial object. On ESP32-C3 with USB CDC, this causes undefined behavior or blocking.
|
|
||||||
|
|
||||||
### Factor B: Removed `while (!Serial)` Wait Loop
|
|
||||||
|
|
||||||
The upstream 0.16.0 code included a 3-second wait loop after `Serial.begin()`:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
if (isUsbConnected()) {
|
|
||||||
Serial.begin(115200);
|
|
||||||
unsigned long start = millis();
|
|
||||||
while (!Serial && (millis() - start) < 3000) {
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This wait loop was removed in an earlier attempt to fix boot delays, but it may be necessary for proper USB CDC initialization.
|
|
||||||
|
|
||||||
### Factor C: `Serial.setTxTimeoutMs(0)` Added Too Early
|
|
||||||
|
|
||||||
`Serial.setTxTimeoutMs(0)` was added immediately after `Serial.begin()` to make TX non-blocking. However, calling this before the Serial connection is fully established may interfere with USB CDC initialization.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## The Fix
|
|
||||||
|
|
||||||
### 1. Guard `checkForFlashCommand()` with Serial Check
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
void checkForFlashCommand() {
|
|
||||||
if (!Serial) return; // Early exit if Serial not initialized
|
|
||||||
while (Serial.available()) {
|
|
||||||
// ... rest unchanged
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Restore Upstream Serial Initialization Pattern
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
void setup() {
|
|
||||||
t1 = millis();
|
|
||||||
|
|
||||||
// Only start serial if USB connected
|
|
||||||
pinMode(UART0_RXD, INPUT);
|
|
||||||
if (isUsbConnected()) {
|
|
||||||
Serial.begin(115200);
|
|
||||||
// Wait up to 3 seconds for Serial to be ready to catch early logs
|
|
||||||
unsigned long start = millis();
|
|
||||||
while (!Serial && (millis() - start) < 3000) {
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ... rest of setup
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Remove `Serial.setTxTimeoutMs(0)`
|
|
||||||
|
|
||||||
This call was removed entirely as it's not present in upstream and may cause issues.
|
|
||||||
|
|
||||||
### 4. Remove Unnecessary `if (Serial)` Guards
|
|
||||||
|
|
||||||
The 15 `if (Serial)` guards added to `EpubReaderActivity.cpp` were removed. `Serial.printf()` is safe to call when Serial isn't initialized (it simply returns 0), so guards around output calls are unnecessary.
|
|
||||||
|
|
||||||
**Key distinction:**
|
|
||||||
- `Serial.printf()` / `Serial.println()` - Safe without guards (no-op when not initialized)
|
|
||||||
- `Serial.available()` / `Serial.read()` - **MUST** be guarded (undefined behavior when not initialized)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Files Changed
|
|
||||||
|
|
||||||
| File | Change |
|
|
||||||
|------|--------|
|
|
||||||
| `src/main.cpp` | Removed `Serial.setTxTimeoutMs(0)`, restored `while (!Serial)` wait, added guard to `checkForFlashCommand()` |
|
|
||||||
| `src/activities/reader/EpubReaderActivity.cpp` | Removed all 15 `if (Serial)` guards |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing Checklist
|
|
||||||
|
|
||||||
After applying fixes, verify:
|
|
||||||
|
|
||||||
1. ✅ Boot with USB connected, serial monitor open - should work
|
|
||||||
2. ✅ Boot with USB connected, NO serial monitor - should work (3s delay then continue)
|
|
||||||
3. ✅ Boot without USB - should work immediately (no blocking)
|
|
||||||
4. ✅ Sleep without USB, plug in USB during sleep, wake - should work
|
|
||||||
5. ✅ Sleep with USB, unplug during sleep, wake - should work
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Lessons Learned
|
|
||||||
|
|
||||||
1. **Always guard Serial input operations**: `Serial.available()` and `Serial.read()` must be guarded with `if (Serial)` or `if (!Serial) return` when Serial initialization is conditional.
|
|
||||||
|
|
||||||
2. **Serial output is safe without guards**: `Serial.printf()` and similar output functions are safe to call even when Serial is not initialized - they simply return 0.
|
|
||||||
|
|
||||||
3. **Don't remove initialization waits without understanding why they exist**: The `while (!Serial)` wait loop exists for proper USB CDC initialization and shouldn't be removed without careful testing.
|
|
||||||
|
|
||||||
4. **Upstream patterns exist for a reason**: When diverging from upstream behavior, especially around low-level hardware initialization, be extra cautious and test thoroughly.
|
|
||||||
BIN
dict-en-en.zip
BIN
dict-en-en.zip
Binary file not shown.
@ -1,422 +0,0 @@
|
|||||||
# Branch Comparison Summary: crosspoint-ef vs 0.16.0
|
|
||||||
|
|
||||||
This document provides a comprehensive comparison between the `crosspoint-ef` branch and the upstream `0.16.0` release for merge planning and implementation decisions.
|
|
||||||
|
|
||||||
## Branch History
|
|
||||||
|
|
||||||
| Branch | Base | Commits Since Base | Status |
|
|
||||||
|--------|------|-------------------|--------|
|
|
||||||
| `crosspoint-ef` | 0.15.0 | 90+ | Active development |
|
|
||||||
| `0.16.0` | 0.15.0 | 30 | Released |
|
|
||||||
|
|
||||||
Both branches diverged from `0.15.0` at commit `3ce11f14`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Feature Comparison Matrix
|
|
||||||
|
|
||||||
### Major Features
|
|
||||||
|
|
||||||
| Feature | crosspoint-ef | 0.16.0 | Notes |
|
|
||||||
|---------|:-------------:|:------:|-------|
|
|
||||||
| Dictionary Support | Yes | No | StarDict format with word selection |
|
|
||||||
| Bookmark System | Yes | No | Per-book bookmarks with visual indicator |
|
|
||||||
| Quick Menu | Yes | No | Power button quick access |
|
|
||||||
| Library Search | Yes | No | Character picker with weighted search |
|
|
||||||
| CSS Parsing | Yes | No | Element, class, inline styles |
|
|
||||||
| Inline Images (PNG/JPEG) | Yes | No | With caching and dithering |
|
|
||||||
| Custom Fonts | Yes | No | Atkinson Hyperlegible, Fern Micro |
|
|
||||||
| Enhanced Web Server | Yes | Partial | File ops, MD5 API, mDNS |
|
|
||||||
| Companion App API | Yes | No | Deep links, WebSocket uploads |
|
|
||||||
| Reading Lists | Yes | No | With pinning support |
|
|
||||||
| Tab Bar Enhancements | Yes | No | Scrolling, overflow indicators |
|
|
||||||
| High Contrast Mode | Yes | No | System-wide |
|
|
||||||
| Bezel Compensation | Yes | No | Edge defect compensation |
|
|
||||||
| Sleep Screen Edge Detection | Yes | No | Dominant color fill |
|
|
||||||
| Recents Improvements | Yes | No | Badges, removal, clearing |
|
|
||||||
| Progress Bar Status Bar | Yes | Yes | Same feature |
|
|
||||||
| Spanish Hyphenation | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| XTC/XTCH Author Extraction | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| OTA Rework | No | Yes | Different implementation |
|
|
||||||
| KOReader MD5 Binary Matching | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| Relative Position on Settings Change | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| Multi-line Keyboard Entry | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| Italics on Image Alt | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| Page Turn on Button Press (UX) | No | Yes | When chapter skip disabled |
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
| Fix | crosspoint-ef | 0.16.0 | Notes |
|
|
||||||
|-----|:-------------:|:------:|-------|
|
|
||||||
| Large EPUB indexing O(n²)→O(n) | Yes | Yes | Same fix |
|
|
||||||
| Settings validation on read | Yes | Yes | Same fix |
|
|
||||||
| Line break fixes | Yes | Yes | Similar fixes |
|
|
||||||
| Rotate origin in drawImage | Yes | Yes | Same fix |
|
|
||||||
| Short-press power wakeup | Yes | Yes | Same fix |
|
|
||||||
| TXT books in recent tab | Yes | Yes | Same fix |
|
|
||||||
| B&W filters for covers | Yes | Yes | Same fix |
|
|
||||||
| Cover fit artifacts | Yes | Yes | Same fix |
|
|
||||||
| Grayscale state corruption | Yes | No | Unique to crosspoint-ef |
|
|
||||||
| Memory graceful degradation | Yes | No | Unique to crosspoint-ef |
|
|
||||||
| Chapter Selection UI (KOReader) | No | Yes | Missing in crosspoint-ef |
|
|
||||||
| Front layout in mapLabels() | No | Yes | Missing in crosspoint-ef |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Files Changed Summary
|
|
||||||
|
|
||||||
### crosspoint-ef Unique Files (New)
|
|
||||||
|
|
||||||
| Category | Files |
|
|
||||||
|----------|-------|
|
|
||||||
| Dictionary | `src/activities/dictionary/` (8 files), `lib/StarDict/` (4 files) |
|
|
||||||
| Bookmarks | `src/BookmarkStore.cpp/.h`, `src/activities/home/BookmarkListActivity.cpp/.h` |
|
|
||||||
| Quick Menu | `src/activities/util/QuickMenuActivity.cpp/.h` |
|
|
||||||
| CSS | `lib/Epub/Epub/css/` (3 files) |
|
|
||||||
| Images | `lib/Epub/Epub/blocks/ImageBlock.cpp/.h`, `lib/Epub/Epub/converters/` (6 files) |
|
|
||||||
| Custom Fonts | `src/customFonts.cpp`, `src/fontIds.h`, `lib/EpdFont/builtinFonts/custom/` (50+ files) |
|
|
||||||
| Utils | `src/util/Md5Utils.cpp/.h`, `src/util/StringUtils.cpp/.h` |
|
|
||||||
| Lists | `src/BookListStore.cpp/.h` |
|
|
||||||
| Docs | `docs/webserver-api-reference.md`, `docs/companion-app-deep-link-API.md`, `docs/troubleshooting.md` |
|
|
||||||
|
|
||||||
### crosspoint-ef Modified Files (Significant Changes)
|
|
||||||
|
|
||||||
| File | Changes |
|
|
||||||
|------|---------|
|
|
||||||
| `src/network/CrossPointWebServer.cpp` | +1083 lines (file ops, API, WebSocket) |
|
|
||||||
| `src/activities/home/MyLibraryActivity.cpp` | +700 lines (tabs, search, badges) |
|
|
||||||
| `src/main.cpp` | +255 lines (feature integration) |
|
|
||||||
| `lib/GfxRenderer/GfxRenderer.cpp` | +439 lines (contrast, bezel) |
|
|
||||||
| `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp` | +596 lines (CSS integration) |
|
|
||||||
| `src/CrossPointSettings.cpp/.h` | New settings fields |
|
|
||||||
| `src/activities/boot_sleep/SleepActivity.cpp` | Edge detection, caching |
|
|
||||||
| `src/RecentBooksStore.cpp` | Badges, removal, metadata |
|
|
||||||
| `src/ScreenComponents.cpp` | Tab bar enhancements |
|
|
||||||
|
|
||||||
### 0.16.0 Unique Files/Changes
|
|
||||||
|
|
||||||
| File | Description |
|
|
||||||
|------|-------------|
|
|
||||||
| `lib/Epub/Epub/hyphenation/generated/hyph-es.trie.h` | Spanish hyphenation (removed in ef) |
|
|
||||||
| `lib/KOReaderSync/` | KOReader credential handling (removed in ef) |
|
|
||||||
| `src/network/OtaUpdater.cpp` | OTA rework |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Merge Strategy Recommendations
|
|
||||||
|
|
||||||
### Phase 1: Cherry-pick 0.16.0 Fixes into crosspoint-ef
|
|
||||||
|
|
||||||
**Low Risk - Recommended First:**
|
|
||||||
|
|
||||||
1. **Spanish hyphenation support** (#558)
|
|
||||||
- Add `hyph-es.trie.h` back
|
|
||||||
- Update `LanguageRegistry.cpp`
|
|
||||||
|
|
||||||
2. **Render keyboard entry over multiple lines** (#567)
|
|
||||||
- Update `KeyboardEntryActivity.cpp`
|
|
||||||
|
|
||||||
3. **Correctly render italics on image alt** (#569)
|
|
||||||
- Minimal change to text rendering
|
|
||||||
|
|
||||||
4. **Page turning on button pressed** (#451)
|
|
||||||
- UX improvement when chapter skip disabled
|
|
||||||
|
|
||||||
5. **Missing front layout in mapLabels()** (#564)
|
|
||||||
- Bug fix for button mapping
|
|
||||||
|
|
||||||
**Medium Risk:**
|
|
||||||
|
|
||||||
6. **KOReader document MD5 binary matching** (#529)
|
|
||||||
- May conflict with MD5Utils changes
|
|
||||||
|
|
||||||
7. **Chapter Selection UI bugs** (#501)
|
|
||||||
- Review for conflicts with tab bar changes
|
|
||||||
|
|
||||||
8. **Relative position on settings change** (#486)
|
|
||||||
- Reader state management change
|
|
||||||
|
|
||||||
**Higher Risk:**
|
|
||||||
|
|
||||||
9. **OTA feature rework** (#509)
|
|
||||||
- Compare implementations, may need reconciliation
|
|
||||||
- crosspoint-ef has different OTA changes
|
|
||||||
|
|
||||||
10. **Extract author from XTC/XTCH** (#563)
|
|
||||||
- XTC format was removed in crosspoint-ef
|
|
||||||
- Evaluate if needed
|
|
||||||
|
|
||||||
### Phase 2: Potential Upstream Contributions from crosspoint-ef
|
|
||||||
|
|
||||||
**High Value, Moderate Complexity:**
|
|
||||||
|
|
||||||
1. **Dictionary Support**
|
|
||||||
- Self-contained feature
|
|
||||||
- New files, minimal integration points
|
|
||||||
- Requires shipping dictionary data
|
|
||||||
|
|
||||||
2. **Bookmark System**
|
|
||||||
- Clean implementation
|
|
||||||
- New files with reader integration
|
|
||||||
|
|
||||||
3. **Quick Menu**
|
|
||||||
- Simple overlay feature
|
|
||||||
- Depends on bookmark and dictionary
|
|
||||||
|
|
||||||
4. **CSS Parsing**
|
|
||||||
- Significant EPUB improvement
|
|
||||||
- Well-isolated in `lib/Epub/Epub/css/`
|
|
||||||
|
|
||||||
**High Value, Higher Complexity:**
|
|
||||||
|
|
||||||
5. **Inline Image Support**
|
|
||||||
- Major EPUB enhancement
|
|
||||||
- Multiple new converters
|
|
||||||
- Memory management considerations
|
|
||||||
|
|
||||||
6. **Library Search**
|
|
||||||
- Integrated into MyLibraryActivity
|
|
||||||
- Tab bar changes included
|
|
||||||
|
|
||||||
7. **Enhanced Web Server**
|
|
||||||
- Large changes to CrossPointWebServer
|
|
||||||
- New API endpoints
|
|
||||||
- WebSocket uploads
|
|
||||||
|
|
||||||
**Medium Value:**
|
|
||||||
|
|
||||||
8. **Custom Fonts**
|
|
||||||
- Large binary additions (font headers)
|
|
||||||
- Clean integration
|
|
||||||
|
|
||||||
9. **Display Enhancements**
|
|
||||||
- High contrast, bezel compensation
|
|
||||||
- Settings additions
|
|
||||||
|
|
||||||
10. **Reading Lists**
|
|
||||||
- New feature with web API
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Potential Conflicts
|
|
||||||
|
|
||||||
### High Conflict Risk
|
|
||||||
|
|
||||||
| Area | crosspoint-ef | 0.16.0 | Resolution |
|
|
||||||
|------|---------------|--------|------------|
|
|
||||||
| `MyLibraryActivity.cpp` | Major restructure | Minor fixes | Manual merge required |
|
|
||||||
| `CrossPointWebServer.cpp` | Extensive additions | Minimal changes | crosspoint-ef likely compatible |
|
|
||||||
| `CrossPointSettings.h` | Many new fields | Few changes | Additive, low conflict |
|
|
||||||
| `main.cpp` | Feature integration | Minor changes | Review integration points |
|
|
||||||
| `OtaUpdater.cpp` | Modified | Reworked (#509) | Compare implementations |
|
|
||||||
|
|
||||||
### Low Conflict Risk
|
|
||||||
|
|
||||||
| Area | Notes |
|
|
||||||
|------|-------|
|
|
||||||
| Dictionary files | All new, no conflicts |
|
|
||||||
| Bookmark files | All new, no conflicts |
|
|
||||||
| CSS parser files | All new, no conflicts |
|
|
||||||
| Image converter files | All new, no conflicts |
|
|
||||||
| Custom font files | All new, no conflicts |
|
|
||||||
| StarDict library | All new, no conflicts |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing Considerations
|
|
||||||
|
|
||||||
### Regression Testing Required
|
|
||||||
|
|
||||||
After any merge:
|
|
||||||
|
|
||||||
1. **EPUB Reading**
|
|
||||||
- Page navigation
|
|
||||||
- Chapter selection
|
|
||||||
- CSS styling
|
|
||||||
- Image rendering
|
|
||||||
- Bookmark indicators
|
|
||||||
|
|
||||||
2. **Library Functions**
|
|
||||||
- Tab navigation
|
|
||||||
- Search functionality
|
|
||||||
- Recent books display
|
|
||||||
- List management
|
|
||||||
|
|
||||||
3. **Dictionary**
|
|
||||||
- Word selection
|
|
||||||
- Lookup accuracy
|
|
||||||
- Definition display
|
|
||||||
|
|
||||||
4. **Web Server**
|
|
||||||
- File upload/download
|
|
||||||
- API endpoints
|
|
||||||
- WebSocket uploads
|
|
||||||
- mDNS discovery
|
|
||||||
|
|
||||||
5. **Settings**
|
|
||||||
- All new settings persist correctly
|
|
||||||
- Settings migration from older versions
|
|
||||||
|
|
||||||
6. **Display**
|
|
||||||
- High contrast mode
|
|
||||||
- Bezel compensation (all orientations)
|
|
||||||
- Sleep screen variations
|
|
||||||
|
|
||||||
### Memory Testing
|
|
||||||
|
|
||||||
crosspoint-ef includes memory optimization fixes. After merge:
|
|
||||||
|
|
||||||
1. Test with large EPUBs (2000+ chapters)
|
|
||||||
2. Test opening multiple books in sequence
|
|
||||||
3. Test anti-aliasing under memory pressure
|
|
||||||
4. Monitor for ghosting/artifacts
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Priority Recommendations
|
|
||||||
|
|
||||||
### Immediate (For crosspoint-ef Stability)
|
|
||||||
|
|
||||||
1. Cherry-pick Spanish hyphenation (#558)
|
|
||||||
2. Cherry-pick multi-line keyboard entry (#567)
|
|
||||||
3. Cherry-pick italics on image alt (#569)
|
|
||||||
4. Cherry-pick front layout fix (#564)
|
|
||||||
|
|
||||||
### Short-term (Feature Completeness)
|
|
||||||
|
|
||||||
5. Evaluate OTA rework (#509) - compare implementations
|
|
||||||
6. Cherry-pick page turn UX (#451)
|
|
||||||
7. Cherry-pick relative position fix (#486)
|
|
||||||
|
|
||||||
### Long-term (Upstream Contribution)
|
|
||||||
|
|
||||||
8. Prepare dictionary feature as PR
|
|
||||||
9. Prepare bookmark system as PR
|
|
||||||
10. Prepare CSS parsing as PR
|
|
||||||
11. Evaluate inline image support for upstream
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## File Inventory for Merge
|
|
||||||
|
|
||||||
### Files to Add to 0.16.0 Base (for upstream contribution)
|
|
||||||
|
|
||||||
```
|
|
||||||
src/activities/dictionary/
|
|
||||||
DictionaryMargins.h
|
|
||||||
DictionaryMenuActivity.cpp
|
|
||||||
DictionaryMenuActivity.h
|
|
||||||
DictionaryResultActivity.cpp
|
|
||||||
DictionaryResultActivity.h
|
|
||||||
DictionarySearchActivity.cpp
|
|
||||||
DictionarySearchActivity.h
|
|
||||||
EpubWordSelectionActivity.cpp
|
|
||||||
EpubWordSelectionActivity.h
|
|
||||||
|
|
||||||
src/activities/util/
|
|
||||||
QuickMenuActivity.cpp
|
|
||||||
QuickMenuActivity.h
|
|
||||||
|
|
||||||
src/activities/home/
|
|
||||||
BookmarkListActivity.cpp
|
|
||||||
BookmarkListActivity.h
|
|
||||||
|
|
||||||
src/
|
|
||||||
BookmarkStore.cpp
|
|
||||||
BookmarkStore.h
|
|
||||||
BookListStore.cpp
|
|
||||||
BookListStore.h
|
|
||||||
customFonts.cpp
|
|
||||||
fontIds.h
|
|
||||||
BadgeConfig.h
|
|
||||||
|
|
||||||
src/util/
|
|
||||||
Md5Utils.cpp
|
|
||||||
Md5Utils.h
|
|
||||||
StringUtils.cpp
|
|
||||||
StringUtils.h
|
|
||||||
|
|
||||||
src/images/
|
|
||||||
LockIcon.h
|
|
||||||
|
|
||||||
lib/StarDict/
|
|
||||||
StarDict.cpp
|
|
||||||
StarDict.h
|
|
||||||
DictHtmlParser.cpp
|
|
||||||
DictHtmlParser.h
|
|
||||||
DictPrefixIndex.generated.h
|
|
||||||
|
|
||||||
lib/Epub/Epub/css/
|
|
||||||
CssParser.cpp
|
|
||||||
CssParser.h
|
|
||||||
CssStyle.h
|
|
||||||
|
|
||||||
lib/Epub/Epub/blocks/
|
|
||||||
ImageBlock.cpp
|
|
||||||
ImageBlock.h
|
|
||||||
BlockStyle.h
|
|
||||||
|
|
||||||
lib/Epub/Epub/converters/
|
|
||||||
FramebufferWriter.cpp
|
|
||||||
FramebufferWriter.h
|
|
||||||
ImageDecoderFactory.cpp
|
|
||||||
ImageDecoderFactory.h
|
|
||||||
ImageToFramebufferDecoder.cpp
|
|
||||||
ImageToFramebufferDecoder.h
|
|
||||||
JpegToFramebufferConverter.cpp
|
|
||||||
JpegToFramebufferConverter.h
|
|
||||||
PngToFramebufferConverter.cpp
|
|
||||||
PngToFramebufferConverter.h
|
|
||||||
|
|
||||||
lib/EpdFont/builtinFonts/custom/
|
|
||||||
[All font header files]
|
|
||||||
|
|
||||||
docs/
|
|
||||||
webserver-api-reference.md
|
|
||||||
companion-app-deep-link-API.md
|
|
||||||
troubleshooting.md
|
|
||||||
crosspoint-ef-features.md
|
|
||||||
crosspoint-ef-user-guide.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Files to Merge Carefully
|
|
||||||
|
|
||||||
```
|
|
||||||
src/main.cpp
|
|
||||||
src/CrossPointSettings.cpp
|
|
||||||
src/CrossPointSettings.h
|
|
||||||
src/network/CrossPointWebServer.cpp
|
|
||||||
src/network/CrossPointWebServer.h
|
|
||||||
src/network/OtaUpdater.cpp
|
|
||||||
src/network/OtaUpdater.h
|
|
||||||
src/activities/home/MyLibraryActivity.cpp
|
|
||||||
src/activities/home/MyLibraryActivity.h
|
|
||||||
src/activities/reader/EpubReaderActivity.cpp
|
|
||||||
src/activities/settings/SettingsActivity.cpp
|
|
||||||
src/activities/settings/CategorySettingsActivity.cpp
|
|
||||||
src/ScreenComponents.cpp
|
|
||||||
src/ScreenComponents.h
|
|
||||||
src/RecentBooksStore.cpp
|
|
||||||
src/RecentBooksStore.h
|
|
||||||
lib/GfxRenderer/GfxRenderer.cpp
|
|
||||||
lib/GfxRenderer/GfxRenderer.h
|
|
||||||
lib/GfxRenderer/BitmapHelpers.cpp
|
|
||||||
lib/GfxRenderer/BitmapHelpers.h
|
|
||||||
lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp
|
|
||||||
lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h
|
|
||||||
lib/Epub/Epub/Section.cpp
|
|
||||||
lib/Epub/Epub/Section.h
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The `crosspoint-ef` branch represents a significant enhancement over the `0.15.0` baseline with 14+ major features. Most features are cleanly isolated in new files, making selective upstream contribution feasible.
|
|
||||||
|
|
||||||
**Recommended approach:**
|
|
||||||
1. First, bring crosspoint-ef up to date with 0.16.0 bug fixes
|
|
||||||
2. Then, evaluate individual features for upstream PR submission
|
|
||||||
3. Prioritize dictionary, bookmarks, and CSS parsing as highest-value contributions
|
|
||||||
|
|
||||||
The grayscale state corruption fix in crosspoint-ef should also be submitted upstream as a critical bug fix, as it prevents display artifacts under memory pressure.
|
|
||||||
@ -1,309 +0,0 @@
|
|||||||
# CrossPoint Companion Deep Link API
|
|
||||||
|
|
||||||
This document describes the deep link functionality that allows the CrossPoint Companion Android app to be launched from QR codes displayed on CrossPoint e-reader devices.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The CrossPoint firmware can generate QR codes containing deep link URLs. When scanned with a mobile device, these URLs launch the companion app directly to a specific tab and optionally auto-connect to the device.
|
|
||||||
|
|
||||||
## URL Scheme
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://<path>?<query_parameters>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Components
|
|
||||||
|
|
||||||
| Component | Description |
|
|
||||||
|-----------|-------------|
|
|
||||||
| `crosspoint://` | Custom URL scheme registered by the app |
|
|
||||||
| `<path>` | Target tab in the app (see [Path Mapping](#path-mapping)) |
|
|
||||||
| `<query_parameters>` | Optional device connection parameters |
|
|
||||||
|
|
||||||
## Path Mapping
|
|
||||||
|
|
||||||
The URL path determines which tab the app navigates to:
|
|
||||||
|
|
||||||
| Path | App Tab | Description |
|
|
||||||
|------|---------|-------------|
|
|
||||||
| `files` | Device | File browser for device storage |
|
|
||||||
| `library` | Library | Local book library |
|
|
||||||
| `lists` | Lists | Reading lists management |
|
|
||||||
| `settings` | Settings | App settings |
|
|
||||||
|
|
||||||
**Note:** Unknown paths default to the Library tab.
|
|
||||||
|
|
||||||
## Query Parameters
|
|
||||||
|
|
||||||
Query parameters provide device connection information for automatic connection:
|
|
||||||
|
|
||||||
| Parameter | Type | Default | Description |
|
|
||||||
|-----------|------|---------|-------------|
|
|
||||||
| `host` | string | *(required for auto-connect)* | IP address or hostname of the device |
|
|
||||||
| `port` | integer | `80` | HTTP API port |
|
|
||||||
| `wsPort` | integer | `81` | WebSocket port for file uploads |
|
|
||||||
|
|
||||||
## URL Examples
|
|
||||||
|
|
||||||
### Basic Navigation (No Auto-Connect)
|
|
||||||
|
|
||||||
Navigate to a specific tab without connecting to a device:
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://files
|
|
||||||
crosspoint://library
|
|
||||||
crosspoint://lists
|
|
||||||
crosspoint://settings
|
|
||||||
```
|
|
||||||
|
|
||||||
### Auto-Connect to Device
|
|
||||||
|
|
||||||
Navigate to Device tab and auto-connect:
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://files?host=192.168.1.100
|
|
||||||
crosspoint://files?host=192.168.1.100&port=80&wsPort=81
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Ports
|
|
||||||
|
|
||||||
Connect to a device with non-default ports:
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://files?host=192.168.1.100&port=8080&wsPort=8081
|
|
||||||
```
|
|
||||||
|
|
||||||
### Hostname Instead of IP
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://files?host=crosspoint.local&port=80&wsPort=81
|
|
||||||
```
|
|
||||||
|
|
||||||
## Firmware Implementation
|
|
||||||
|
|
||||||
### QR Code Generation
|
|
||||||
|
|
||||||
The CrossPoint firmware should generate QR codes containing the deep link URL. Example format:
|
|
||||||
|
|
||||||
```
|
|
||||||
crosspoint://files?host=<device_ip>&port=<http_port>&wsPort=<ws_port>
|
|
||||||
```
|
|
||||||
|
|
||||||
Where:
|
|
||||||
- `<device_ip>` is the device's current IP address (e.g., from WiFi connection)
|
|
||||||
- `<http_port>` is the HTTP API port (default: 80)
|
|
||||||
- `<ws_port>` is the WebSocket port (default: 81)
|
|
||||||
|
|
||||||
### Example Firmware Code (C++)
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
String generateDeepLinkUrl(const char* path = "files") {
|
|
||||||
String url = "crosspoint://";
|
|
||||||
url += path;
|
|
||||||
url += "?host=";
|
|
||||||
url += WiFi.localIP().toString();
|
|
||||||
url += "&port=";
|
|
||||||
url += String(HTTP_PORT); // e.g., 80
|
|
||||||
url += "&wsPort=";
|
|
||||||
url += String(WS_PORT); // e.g., 81
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate QR code with:
|
|
||||||
// String url = generateDeepLinkUrl("files");
|
|
||||||
// displayQRCode(url);
|
|
||||||
```
|
|
||||||
|
|
||||||
## App Behavior
|
|
||||||
|
|
||||||
### Launch Scenarios
|
|
||||||
|
|
||||||
#### 1. App Not Running
|
|
||||||
|
|
||||||
When the app is launched via deep link:
|
|
||||||
1. App starts and parses the deep link URL
|
|
||||||
2. Navigates to the target tab
|
|
||||||
3. If device connection info is present and target is "files":
|
|
||||||
- Checks for existing device with matching IP
|
|
||||||
- If found: uses existing device (preserving user's custom name)
|
|
||||||
- If not found: creates temporary connection
|
|
||||||
- Attempts to connect automatically
|
|
||||||
|
|
||||||
#### 2. App Already Running
|
|
||||||
|
|
||||||
When a deep link is received while the app is open:
|
|
||||||
1. `onNewIntent` receives the new URL
|
|
||||||
2. Navigates to the target tab
|
|
||||||
3. Handles device connection (same as above)
|
|
||||||
|
|
||||||
### Device Matching Logic
|
|
||||||
|
|
||||||
When connecting via deep link:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Look up device by IP address in database
|
|
||||||
2. If device exists:
|
|
||||||
a. Check if ports match
|
|
||||||
b. If ports differ, update the stored device with new ports
|
|
||||||
c. Connect using the existing device (preserves custom name)
|
|
||||||
3. If device doesn't exist:
|
|
||||||
a. Create temporary Device object (not saved to database)
|
|
||||||
b. Connect using temporary device
|
|
||||||
c. Display as "CrossPoint (<ip>)"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
| Scenario | Behavior |
|
|
||||||
|----------|----------|
|
|
||||||
| Malformed URL | App opens to Library tab (default) |
|
|
||||||
| Unknown path | App opens to Library tab with warning logged |
|
|
||||||
| Invalid host format | Navigation succeeds, no auto-connect |
|
|
||||||
| Invalid port values | Default ports used (80, 81) |
|
|
||||||
| Connection failure | Error message displayed, user can retry |
|
|
||||||
| Device unreachable | Error message with device IP shown |
|
|
||||||
|
|
||||||
## Android Implementation Details
|
|
||||||
|
|
||||||
### Intent Filter (AndroidManifest.xml)
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
<data android:scheme="crosspoint" />
|
|
||||||
</intent-filter>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Classes
|
|
||||||
|
|
||||||
| Class | Purpose |
|
|
||||||
|-------|---------|
|
|
||||||
| `DeepLinkParser` | Parses URI into `DeepLinkData` |
|
|
||||||
| `DeepLinkData` | Data class holding parsed deep link info |
|
|
||||||
| `DeviceConnectionInfo` | Data class for host/port/wsPort |
|
|
||||||
| `MainActivity` | Handles incoming intents |
|
|
||||||
| `CrossPointApp` | Routes navigation based on deep link |
|
|
||||||
| `DeviceBrowserViewModel` | Handles `connectFromDeepLink()` |
|
|
||||||
|
|
||||||
### Data Flow
|
|
||||||
|
|
||||||
```
|
|
||||||
QR Code Scan
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
Android Intent (ACTION_VIEW)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
MainActivity.onCreate() / onNewIntent()
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
DeepLinkParser.parse(uri)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
DeepLinkData { targetTab, deviceConnection? }
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
CrossPointApp (LaunchedEffect)
|
|
||||||
│
|
|
||||||
├─► Navigate to targetTab
|
|
||||||
│
|
|
||||||
└─► If targetTab == Device && deviceConnection != null
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
DeviceBrowserScreen
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
DeviceBrowserViewModel.connectFromDeepLink()
|
|
||||||
│
|
|
||||||
├─► Check existing device by IP
|
|
||||||
├─► Update ports if needed
|
|
||||||
└─► Connect and load files
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validation Rules
|
|
||||||
|
|
||||||
### Host Validation
|
|
||||||
|
|
||||||
Valid hosts:
|
|
||||||
- IPv4 addresses: `192.168.1.100`, `10.0.0.1`
|
|
||||||
- Hostnames: `crosspoint.local`, `my-device`
|
|
||||||
|
|
||||||
Invalid hosts (rejected):
|
|
||||||
- Empty strings
|
|
||||||
- Malformed IPs: `192.168.1.256`, `192.168.1`
|
|
||||||
- IPs with invalid octets
|
|
||||||
|
|
||||||
### Port Validation
|
|
||||||
|
|
||||||
- Valid range: 1-65535
|
|
||||||
- Out-of-range values default to 80 (HTTP) or 81 (WebSocket)
|
|
||||||
- Non-numeric values default to standard ports
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
### Manual Testing with ADB
|
|
||||||
|
|
||||||
Test deep links without a QR code using ADB:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Basic navigation
|
|
||||||
adb shell am start -a android.intent.action.VIEW -d "crosspoint://files"
|
|
||||||
adb shell am start -a android.intent.action.VIEW -d "crosspoint://library"
|
|
||||||
|
|
||||||
# With device connection
|
|
||||||
adb shell am start -a android.intent.action.VIEW -d "crosspoint://files?host=192.168.1.100"
|
|
||||||
adb shell am start -a android.intent.action.VIEW -d "crosspoint://files?host=192.168.1.100&port=80&wsPort=81"
|
|
||||||
|
|
||||||
# Test while app is running (onNewIntent)
|
|
||||||
adb shell am start -a android.intent.action.VIEW -d "crosspoint://settings"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test Cases
|
|
||||||
|
|
||||||
1. **Valid deep link with connection info**
|
|
||||||
- URL: `crosspoint://files?host=192.168.1.100&port=80&wsPort=81`
|
|
||||||
- Expected: Opens Device tab, auto-connects to device
|
|
||||||
|
|
||||||
2. **Valid deep link without connection info**
|
|
||||||
- URL: `crosspoint://files`
|
|
||||||
- Expected: Opens Device tab, shows device selection
|
|
||||||
|
|
||||||
3. **Unknown path**
|
|
||||||
- URL: `crosspoint://unknown`
|
|
||||||
- Expected: Opens Library tab (default)
|
|
||||||
|
|
||||||
4. **Missing host parameter**
|
|
||||||
- URL: `crosspoint://files?port=80`
|
|
||||||
- Expected: Opens Device tab, no auto-connect
|
|
||||||
|
|
||||||
5. **Invalid host format**
|
|
||||||
- URL: `crosspoint://files?host=invalid..host`
|
|
||||||
- Expected: Opens Device tab, no auto-connect
|
|
||||||
|
|
||||||
6. **Device already exists in database**
|
|
||||||
- Precondition: Device with IP 192.168.1.100 saved as "My Reader"
|
|
||||||
- URL: `crosspoint://files?host=192.168.1.100`
|
|
||||||
- Expected: Connects using "My Reader" name
|
|
||||||
|
|
||||||
7. **Existing device with different ports**
|
|
||||||
- Precondition: Device saved with port=80, wsPort=81
|
|
||||||
- URL: `crosspoint://files?host=192.168.1.100&port=8080&wsPort=8081`
|
|
||||||
- Expected: Updates device ports, then connects
|
|
||||||
|
|
||||||
## Security Considerations
|
|
||||||
|
|
||||||
1. **Local Network Only**: Deep links should only contain local network addresses. The app does not validate this, but firmware should only generate URLs with local IPs.
|
|
||||||
|
|
||||||
2. **No Authentication**: The deep link does not include authentication. Device security relies on network-level access control.
|
|
||||||
|
|
||||||
3. **Temporary Devices**: Devices created from deep links (when no matching device exists) are not persisted, preventing automatic accumulation of device entries.
|
|
||||||
|
|
||||||
4. **No Sensitive Data**: Deep link URLs should not contain sensitive information as QR codes can be photographed.
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
| Version | Changes |
|
|
||||||
|---------|---------|
|
|
||||||
| 1.0.0 | Initial deep link support with `crosspoint://` scheme |
|
|
||||||
@ -1,603 +0,0 @@
|
|||||||
# CrossPoint-EF Branch Features
|
|
||||||
|
|
||||||
This document describes the features and enhancements unique to the `crosspoint-ef` branch, which diverged from CrossPoint Reader at version `0.15.0`.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The `crosspoint-ef` branch introduces significant new functionality including:
|
|
||||||
|
|
||||||
- **Dictionary Support** - Offline StarDict dictionary with word selection from reader
|
|
||||||
- **Bookmark System** - Per-book bookmarks with visual indicators and management
|
|
||||||
- **Quick Menu** - Fast access to common actions via power button
|
|
||||||
- **Library Search** - Search across all books by title, author, or filename
|
|
||||||
- **CSS Support** - Parse and apply CSS styles from EPUB files
|
|
||||||
- **Inline Images** - PNG and Baseline JPEG image rendering within EPUBs
|
|
||||||
- **Custom Fonts** - Atkinson Hyperlegible Next and Fern Micro accessibility fonts
|
|
||||||
- **Enhanced Web Server** - File management, companion app API, mDNS discovery
|
|
||||||
- **Reading Lists** - Create, manage, and pin custom book lists
|
|
||||||
- **Display Enhancements** - High contrast mode, bezel compensation, sleep screen improvements
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Major Features
|
|
||||||
|
|
||||||
### 1. Dictionary Support
|
|
||||||
|
|
||||||
Full offline dictionary lookup using the StarDict format with fast prefix-indexed search.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Word selection directly from EPUB pages
|
|
||||||
- Manual word entry via on-screen keyboard
|
|
||||||
- Rich HTML formatting in definitions (bold, italic, lists)
|
|
||||||
- Multi-page definitions with pagination
|
|
||||||
- Synonym support
|
|
||||||
- Case-insensitive search with prefix optimization
|
|
||||||
|
|
||||||
**Access Methods:**
|
|
||||||
- **Quick Menu** → Dictionary
|
|
||||||
- **Power Button** (when configured to `Dictionary` action)
|
|
||||||
|
|
||||||
**Dictionary Format:**
|
|
||||||
- StarDict format with dictzip compression
|
|
||||||
- Files located at `/dictionaries/dict-data` on SD card:
|
|
||||||
- `dict-data.ifo` - Metadata
|
|
||||||
- `dict-data.idx` - Word index
|
|
||||||
- `dict-data.dict.dz` - Compressed definitions
|
|
||||||
- `dict-data.syn` - Synonyms (optional)
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/activities/dictionary/`, `lib/StarDict/`
|
|
||||||
- Prefix jump table for near-instant lookups
|
|
||||||
- On-demand chunk decompression using miniz
|
|
||||||
- HTML definition parsing with entity decoding
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Bookmark System
|
|
||||||
|
|
||||||
Per-book bookmark storage with visual indicators and dedicated management interface.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Add/remove bookmarks from current page
|
|
||||||
- Visual folded-corner indicator on bookmarked pages
|
|
||||||
- Bookmarks tab in library showing all books with bookmarks
|
|
||||||
- Long-press to delete bookmarks
|
|
||||||
- Auto-generated bookmark names ("Chapter Title - Page X")
|
|
||||||
- Maximum 100 bookmarks per book
|
|
||||||
|
|
||||||
**Storage:**
|
|
||||||
- Binary file per book: `/.crosspoint/{epub_|txt_}<hash>/bookmarks.bin`
|
|
||||||
- Stores: name, spine index, content offset, page number, timestamp
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/BookmarkStore.cpp/.h`, `src/activities/home/BookmarkListActivity.cpp/.h`
|
|
||||||
- Bookmark identification by `spineIndex + contentOffset` (stable across re-renders)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. Quick Menu
|
|
||||||
|
|
||||||
In-reader quick access menu for common actions, triggered by short power button press.
|
|
||||||
|
|
||||||
**Menu Options:**
|
|
||||||
1. **Dictionary** - Look up a word
|
|
||||||
2. **Bookmark** - Add/Remove bookmark (state-aware text)
|
|
||||||
3. **Clear Cache** - Free up storage space
|
|
||||||
4. **Settings** - Open settings menu
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → Controls → Short Power Button Click → `Quick Menu`
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- File: `src/activities/util/QuickMenuActivity.cpp/.h`
|
|
||||||
- Renders overlay with navigation and selection
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Library Search with Character Picker
|
|
||||||
|
|
||||||
Search across all books using a dynamic character picker interface.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Character picker with dynamically generated character set from library content
|
|
||||||
- Weighted search scoring:
|
|
||||||
- Title match: 100 points (+50 if at start)
|
|
||||||
- Author match: 80 points (+40 if at start)
|
|
||||||
- Path match: 30 points
|
|
||||||
- Results sorted by relevance score
|
|
||||||
- Special controls: SPC (space), ← (backspace), CLR (clear)
|
|
||||||
|
|
||||||
**Navigation:**
|
|
||||||
- Left/Right: Select character
|
|
||||||
- Confirm: Add character to query
|
|
||||||
- Up/Down: Switch between picker and results
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Integrated in `src/activities/home/MyLibraryActivity.cpp`
|
|
||||||
- Search tab accessible from library tab bar
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. CSS Support for EPUBs
|
|
||||||
|
|
||||||
Parse and apply CSS styles from EPUB stylesheets.
|
|
||||||
|
|
||||||
**Supported Selectors:**
|
|
||||||
- Element selectors: `p`, `div`, `h1`, etc.
|
|
||||||
- Class selectors: `.classname`
|
|
||||||
- Combined selectors: `element.classname`
|
|
||||||
- Grouped selectors: `h1, h2, h3`
|
|
||||||
- Inline styles: `style="..."`
|
|
||||||
|
|
||||||
**Supported Properties:**
|
|
||||||
- `text-align` (left, center, right, justify)
|
|
||||||
- `font-style` (normal, italic)
|
|
||||||
- `font-weight` (normal, bold)
|
|
||||||
- `text-decoration` (underline)
|
|
||||||
- `text-indent`
|
|
||||||
- `margin-top`, `margin-bottom`
|
|
||||||
- `padding-top`, `padding-bottom`
|
|
||||||
|
|
||||||
**Cascade Order:**
|
|
||||||
1. Element styles
|
|
||||||
2. Class styles
|
|
||||||
3. Element.class styles
|
|
||||||
4. Inline styles
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `lib/Epub/Epub/css/CssParser.cpp/.h`, `CssStyle.h`
|
|
||||||
- CSS files parsed during EPUB loading
|
|
||||||
- Styles applied during HTML parsing via `ChapterHtmlSlimParser`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6. Inline Image Support (PNG/Baseline JPEG)
|
|
||||||
|
|
||||||
Render embedded images within EPUB content.
|
|
||||||
|
|
||||||
**Supported Formats:**
|
|
||||||
- Baseline JPEG (.jpg, .jpeg)
|
|
||||||
- PNG (.png)
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Images decoded to 2-bit grayscale with dithering
|
|
||||||
- Image caching as `.pxc` files (2 bits per pixel, packed format)
|
|
||||||
- Row-by-row rendering to minimize memory usage
|
|
||||||
- Automatic scaling to fit page width
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `lib/Epub/Epub/blocks/ImageBlock.cpp/.h`
|
|
||||||
- Converters: `JpegToFramebufferConverter`, `PngToFramebufferConverter`
|
|
||||||
- Factory: `ImageDecoderFactory` routes to appropriate decoder
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 7. Custom Fonts
|
|
||||||
|
|
||||||
Additional accessibility-focused fonts beyond the standard Bookerly and Noto Sans.
|
|
||||||
|
|
||||||
**Available Fonts:**
|
|
||||||
1. **Atkinson Hyperlegible Next** - Designed for low-vision readers
|
|
||||||
2. **Fern Micro** - Optimized for small screens
|
|
||||||
|
|
||||||
**Font Sizes:**
|
|
||||||
- 12pt, 14pt, 16pt, 18pt for each font
|
|
||||||
- Full style support: Regular, Italic, Bold, Bold Italic
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → Reader → Font Family → Custom
|
|
||||||
- Settings → Reader → Custom Font → [Select font]
|
|
||||||
- Settings → Reader → Fallback Font → [Bookerly/Noto Sans]
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/customFonts.cpp`, `src/fontIds.h`
|
|
||||||
- Font headers: `lib/EpdFont/builtinFonts/custom/`
|
|
||||||
- Conversion scripts: `lib/EpdFont/scripts/convert-builtin-fonts.sh`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 8. Enhanced Web Server
|
|
||||||
|
|
||||||
Extended web server with file management operations and companion app support.
|
|
||||||
|
|
||||||
**File Operations:**
|
|
||||||
| Endpoint | Method | Description |
|
|
||||||
|----------|--------|-------------|
|
|
||||||
| `/api/files` | GET | List files with MD5 hashes for EPUBs |
|
|
||||||
| `/api/status` | GET | Device status (version, IP, heap, uptime) |
|
|
||||||
| `/api/archived` | GET | List archived books |
|
|
||||||
| `/api/hash` | GET | Compute/retrieve MD5 hash for sync |
|
|
||||||
| `/download` | GET | Download files |
|
|
||||||
| `/upload` | POST | Upload files (multipart) |
|
|
||||||
| `/delete` | POST | Delete files/folders |
|
|
||||||
| `/archive` | POST | Archive a book |
|
|
||||||
| `/unarchive` | POST | Restore archived book |
|
|
||||||
| `/rename` | POST | Rename files/folders |
|
|
||||||
| `/copy` | POST | Copy files/folders |
|
|
||||||
| `/move` | POST | Move files/folders |
|
|
||||||
| `/mkdir` | POST | Create folders |
|
|
||||||
| `/list` | GET/POST | Manage reading lists |
|
|
||||||
|
|
||||||
**WebSocket Upload (Port 81):**
|
|
||||||
- Fast binary uploads for large files
|
|
||||||
- Protocol: `START:<filename>:<size>:<path>` → `READY` → binary chunks → `DONE`
|
|
||||||
- Progress updates: `PROGRESS:<received>:<total>`
|
|
||||||
|
|
||||||
**mDNS Discovery:**
|
|
||||||
- Hostname: `crosspoint.local`
|
|
||||||
- Service: `_http._tcp` on port 80
|
|
||||||
- UDP discovery on port 8134
|
|
||||||
|
|
||||||
**Deep Link Support:**
|
|
||||||
- URL scheme: `crosspoint://<path>?host=<ip>&port=<port>&wsPort=<wsPort>`
|
|
||||||
- Paths: `files`, `library`, `lists`, `settings`
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/network/CrossPointWebServer.cpp/.h`
|
|
||||||
- MD5 Utils: `src/util/Md5Utils.cpp/.h`
|
|
||||||
- Docs: `docs/webserver-api-reference.md`, `docs/companion-app-deep-link-API.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 9. Reading Lists with Pinning
|
|
||||||
|
|
||||||
Create and manage custom book lists with pinning support.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Create, load, delete lists
|
|
||||||
- Pin a list to show on home screen
|
|
||||||
- List contents displayed with book metadata
|
|
||||||
- Web API for list upload/download (CSV format)
|
|
||||||
|
|
||||||
**Storage:**
|
|
||||||
- Lists stored in `/.lists/` as `.bin` files
|
|
||||||
- CSV format for API: `order,title,author,path`
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Library → Lists tab → Long-press → Pin/Unpin
|
|
||||||
- Pinned list name shown on home screen Lists button
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/BookListStore.cpp/.h`
|
|
||||||
- Pinned list stored in `SETTINGS.pinnedListName`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 10. Display Enhancements
|
|
||||||
|
|
||||||
#### High Contrast Mode
|
|
||||||
|
|
||||||
System-wide display contrast adjustment for improved readability.
|
|
||||||
|
|
||||||
- **Normal mode:** Standard grayscale thresholds
|
|
||||||
- **High contrast mode:** Pushes mid-grays toward black/white
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → Display → High Contrast → On/Off
|
|
||||||
|
|
||||||
#### Bezel Compensation
|
|
||||||
|
|
||||||
Compensate for physical screen edge defects with configurable margin.
|
|
||||||
|
|
||||||
- **Range:** 0-10 pixels
|
|
||||||
- **Edges:** Bottom, Top, Left, Right
|
|
||||||
- **Behavior:** Margin rotates with screen orientation
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → Display → Bezel Compensation → [0-10]
|
|
||||||
- Settings → Display → Bezel Edge → [Bottom/Top/Left/Right]
|
|
||||||
|
|
||||||
#### Sleep Screen Improvements
|
|
||||||
|
|
||||||
Enhanced sleep screen with edge-aware color filling.
|
|
||||||
|
|
||||||
- **Edge luminance detection:** Samples edge pixels for dominant color
|
|
||||||
- **Letterbox fill:** Fills letterbox regions with edge colors for seamless appearance
|
|
||||||
- **Two-level caching:**
|
|
||||||
- Per-BMP cache: `.bmp.perim` files store edge luminance
|
|
||||||
- Book-level cache: `edge.bin` stores cover data
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 11. Recents View Improvements
|
|
||||||
|
|
||||||
Enhanced recent books display with metadata and management.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- **Badges:** Extension and suffix tags (e.g., "epub", "X4")
|
|
||||||
- **Metadata display:** Title and author from EPUB
|
|
||||||
- **Remove from recents:** Long-press → Remove from Recents
|
|
||||||
- **Clear all:** Long-press → Clear All Recents
|
|
||||||
|
|
||||||
**Badge Configuration:**
|
|
||||||
- Extension badges: `.epub` → "epub", `.txt` → "txt"
|
|
||||||
- Suffix badges: `-x4` → "X4", `-x4p` → "X4P"
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/RecentBooksStore.cpp/.h`
|
|
||||||
- Badge config: `src/BadgeConfig.h`
|
|
||||||
- String utils: `src/util/StringUtils.cpp/.h`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 12. Enhanced Tab Bar
|
|
||||||
|
|
||||||
Unified tab bar with scrolling and overflow indicators.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Horizontal scrolling when tabs exceed available width
|
|
||||||
- Overflow indicators (< >) when content extends beyond view
|
|
||||||
- Selected tab highlighting with underline
|
|
||||||
- Bullet cursors for focus mode
|
|
||||||
|
|
||||||
**Tabs:**
|
|
||||||
- Recent, Lists, Bookmarks, Search, Files
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/ScreenComponents.cpp/.h`
|
|
||||||
- Used in `MyLibraryActivity` for library navigation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 13. Progress Bar Status Bar
|
|
||||||
|
|
||||||
Additional status bar option showing visual progress bar.
|
|
||||||
|
|
||||||
**Options:**
|
|
||||||
- `Full w/ Progress Bar` - Full status bar with progress bar
|
|
||||||
- `Progress Bar` - Only progress bar, no other status info
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → Display → Status Bar
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 14. Additional Settings
|
|
||||||
|
|
||||||
New configuration options unique to crosspoint-ef:
|
|
||||||
|
|
||||||
| Setting | Options | Description |
|
|
||||||
|---------|---------|-------------|
|
|
||||||
| Short Power Button Click | Ignore, Sleep, Page Turn, Dictionary, Quick Menu | Map power button to action |
|
|
||||||
| Bezel Compensation | 0-10 pixels | Edge defect compensation |
|
|
||||||
| Bezel Edge | Bottom, Top, Left, Right | Which edge to compensate |
|
|
||||||
| High Contrast | Off, On | System-wide contrast boost |
|
|
||||||
| Custom Font | [Font list] | Select custom font |
|
|
||||||
| Fallback Font | Bookerly, Noto Sans | Fallback for custom fonts |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 15. OPDS Browser Enhancements
|
|
||||||
|
|
||||||
Improved OPDS catalog browsing experience.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- **Navigation history stack** - Back button navigates through visited feeds
|
|
||||||
- **Page skipping** - Hold Up/Down for 700ms to skip 23 items at once
|
|
||||||
- **Error retry mechanism** - Retry button on error screens with WiFi status check
|
|
||||||
- **HTTP Basic Authentication** - Username/password support for protected OPDS servers
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- Settings → System → Calibre Settings → OPDS Server URL
|
|
||||||
- Settings → System → Calibre Settings → Username/Password
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/activities/browser/OpdsBookBrowserActivity.cpp`
|
|
||||||
- Authentication: `src/network/HttpDownloader.cpp`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 16. Development Tools
|
|
||||||
|
|
||||||
Scripts and utilities for firmware development.
|
|
||||||
|
|
||||||
**Scripts:**
|
|
||||||
| Script | Purpose |
|
|
||||||
|--------|---------|
|
|
||||||
| `pre_flash.py` | Displays "Flashing firmware..." screen during upload |
|
|
||||||
| `debugging_monitor.py` | Enhanced serial monitor with memory graphs and color output |
|
|
||||||
| `pio_helper.py` | Interactive PlatformIO workflow helper with presets |
|
|
||||||
| `version_hash.py` | Embeds git commit hash in dev builds |
|
|
||||||
| `build_html.py` | Minifies HTML files for web server |
|
|
||||||
|
|
||||||
**Firmware Flashing Screen:**
|
|
||||||
- Full-screen display during firmware upload
|
|
||||||
- Shows "Flashing firmware..." with version info
|
|
||||||
- Lock icon indicates USB port location
|
|
||||||
- Prevents accidental disconnection
|
|
||||||
|
|
||||||
**Debug/Memory Monitoring:**
|
|
||||||
- `DEBUG_MEMORY` build mode for heap tracking at activity transitions
|
|
||||||
- Periodic memory logging every 10 seconds (when Serial connected)
|
|
||||||
- Loop duration warnings when exceeding 50ms
|
|
||||||
- Detailed heap fragmentation info
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Scripts: `scripts/pre_flash.py`, `scripts/debugging_monitor.py`, `scripts/pio_helper.py`
|
|
||||||
- Flash screen: `src/main.cpp` (lines 138-247)
|
|
||||||
- Memory monitoring: `src/main.cpp` (lines 549-562)
|
|
||||||
- Build config: `platformio.ini` (`debug_memory` environment)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 17. Power Management Enhancements
|
|
||||||
|
|
||||||
Optimizations for battery life and responsiveness.
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- **Auto-sleep prevention** - Background tasks (web server, OTA, downloads) prevent auto-sleep
|
|
||||||
- **USB connection detection** - Serial only starts when USB is connected (saves power)
|
|
||||||
- **Skip loop delay** - Activities can request faster loop execution for responsive HTTP handling
|
|
||||||
- **Power button release wait** - Prevents immediate wake if button is still held
|
|
||||||
|
|
||||||
**Technical Implementation:**
|
|
||||||
- Files: `src/main.cpp`, `src/activities/Activity.h`
|
|
||||||
- Methods: `preventAutoSleep()`, `skipLoopDelay()`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bug Fixes
|
|
||||||
|
|
||||||
### Unique to crosspoint-ef
|
|
||||||
|
|
||||||
1. **Grayscale state corruption fix** - Prevents ghosting and gray filter artifacts when anti-aliasing is enabled under memory pressure
|
|
||||||
2. **Memory optimization** - Graceful degradation when memory is low (skip anti-aliasing instead of corrupting display)
|
|
||||||
|
|
||||||
### Shared with 0.16.0
|
|
||||||
|
|
||||||
- Large EPUB indexing optimization (O(n²) → O(n))
|
|
||||||
- Settings validation on read
|
|
||||||
- Line break fixes (flush word before `<br/>`)
|
|
||||||
- Rotate origin in `drawImage()`
|
|
||||||
- Short-press power button to wakeup
|
|
||||||
- Add txt books to recent tab
|
|
||||||
- B&W filters for cover images
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Missing or Removed Features from 0.16.0
|
|
||||||
|
|
||||||
The following features are present in the upstream `0.16.0` release but are missing or were removed in `crosspoint-ef`:
|
|
||||||
|
|
||||||
### Removed Features
|
|
||||||
|
|
||||||
#### 1. KOReader Sync Support (Removed)
|
|
||||||
|
|
||||||
The entire KOReader sync functionality has been removed.
|
|
||||||
|
|
||||||
**What was removed:**
|
|
||||||
- `lib/KOReaderSync/` library (8 files deleted)
|
|
||||||
- Progress sync with KOReader sync server (`sync.koreader.rocks`)
|
|
||||||
- Document MD5 binary matching for progress synchronization
|
|
||||||
- KOReader credential storage
|
|
||||||
|
|
||||||
**Impact:**
|
|
||||||
- Cannot sync reading progress with KOReader app
|
|
||||||
- Chapter Selection UI fixes for KOReader sync (#501) not applicable
|
|
||||||
|
|
||||||
**Files deleted:**
|
|
||||||
- `KOReaderSyncClient.cpp/.h`
|
|
||||||
- `KOReaderCredentialStore.cpp/.h`
|
|
||||||
- `KOReaderDocumentId.cpp/.h`
|
|
||||||
- `ProgressMapper.cpp/.h`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 2. Non-English Hyphenation Patterns (Removed)
|
|
||||||
|
|
||||||
Hyphenation pattern files for non-English languages have been removed.
|
|
||||||
|
|
||||||
**What was removed:**
|
|
||||||
- `hyph-es.trie.h` - Spanish hyphenation
|
|
||||||
- `hyph-de.trie.h` - German hyphenation
|
|
||||||
- `hyph-fr.trie.h` - French hyphenation
|
|
||||||
- `hyph-ru.trie.h` - Russian hyphenation
|
|
||||||
|
|
||||||
**Impact:**
|
|
||||||
- Only English hyphenation patterns remain
|
|
||||||
- Non-English books will not hyphenate correctly
|
|
||||||
- Spanish hyphenation support (#558) not available
|
|
||||||
|
|
||||||
**Note:** These can be restored by copying the trie files from 0.16.0.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 3. XTC/XTCH File Support (Removed)
|
|
||||||
|
|
||||||
Support for the XTC/XTCH proprietary format has been removed.
|
|
||||||
|
|
||||||
**What was removed:**
|
|
||||||
- Author extraction from XTC/XTCH files (#563)
|
|
||||||
- XTC format handling in file browsers
|
|
||||||
|
|
||||||
**Impact:**
|
|
||||||
- XTC/XTCH files cannot be read
|
|
||||||
- Author metadata not extracted from these formats
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Missing Bug Fixes
|
|
||||||
|
|
||||||
The following bug fixes from 0.16.0 have not been applied to crosspoint-ef:
|
|
||||||
|
|
||||||
| PR | Description | Impact |
|
|
||||||
|----|-------------|--------|
|
|
||||||
| #567 | Multi-line keyboard entry | Long text input truncated with "..." instead of wrapping |
|
|
||||||
| #569 | Italics on image alt text | Image alt placeholders don't render in italics |
|
|
||||||
| #564 | Front layout in mapLabels() | Button mapping may be incorrect in some layouts |
|
|
||||||
| #486 | Relative position on settings change | Reader may jump to different location when settings change |
|
|
||||||
| #501 | Chapter Selection UI (KOReader) | N/A - KOReader sync removed |
|
|
||||||
| #529 | KOReader MD5 binary matching | N/A - KOReader sync removed |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Missing UX Enhancements
|
|
||||||
|
|
||||||
| PR | Description | Impact |
|
|
||||||
|----|-------------|--------|
|
|
||||||
| #451 | Page turn on button press | When long-press chapter skip is disabled, 0.16.0 allows page turn on button press; crosspoint-ef does not |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Different Implementation: OTA Updates
|
|
||||||
|
|
||||||
The OTA update mechanism uses a different implementation:
|
|
||||||
|
|
||||||
| Aspect | crosspoint-ef | 0.16.0 |
|
|
||||||
|--------|---------------|--------|
|
|
||||||
| HTTP Client | Arduino `HTTPClient` | ESP-IDF `esp_http_client` |
|
|
||||||
| OTA Library | Arduino `Update` | ESP-IDF `esp_https_ota` |
|
|
||||||
| Memory Management | Standard | Improved with custom buffer handling |
|
|
||||||
|
|
||||||
**Impact:**
|
|
||||||
- Both implementations work, but 0.16.0's ESP-IDF approach may be more memory-efficient
|
|
||||||
- Consider evaluating 0.16.0's OTA rework (#509) for potential adoption
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Recommendation for Missing Features
|
|
||||||
|
|
||||||
**High Priority to Cherry-pick:**
|
|
||||||
1. Multi-line keyboard entry (#567) - Improves UX for long inputs
|
|
||||||
2. Front layout fix (#564) - Bug fix for button mapping
|
|
||||||
3. Relative position on settings change (#486) - Improves reader UX
|
|
||||||
|
|
||||||
**Medium Priority:**
|
|
||||||
4. Restore hyphenation patterns for non-English languages
|
|
||||||
5. Italics on image alt (#569) - Minor visual improvement
|
|
||||||
6. Page turn on button press (#451) - UX enhancement
|
|
||||||
|
|
||||||
**Evaluate:**
|
|
||||||
7. OTA rework (#509) - Compare implementations for memory benefits
|
|
||||||
8. KOReader sync - Restore if sync functionality is desired
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## File Summary
|
|
||||||
|
|
||||||
| Feature | Primary Files |
|
|
||||||
|---------|---------------|
|
|
||||||
| Dictionary | `src/activities/dictionary/`, `lib/StarDict/` |
|
|
||||||
| Bookmarks | `src/BookmarkStore.*`, `src/activities/home/BookmarkListActivity.*` |
|
|
||||||
| Quick Menu | `src/activities/util/QuickMenuActivity.*` |
|
|
||||||
| Search | `src/activities/home/MyLibraryActivity.cpp` |
|
|
||||||
| CSS | `lib/Epub/Epub/css/` |
|
|
||||||
| Images | `lib/Epub/Epub/blocks/ImageBlock.*`, `lib/Epub/Epub/converters/` |
|
|
||||||
| Custom Fonts | `src/customFonts.cpp`, `lib/EpdFont/builtinFonts/custom/` |
|
|
||||||
| Web Server | `src/network/CrossPointWebServer.*`, `src/util/Md5Utils.*` |
|
|
||||||
| Lists | `src/BookListStore.*` |
|
|
||||||
| Settings | `src/CrossPointSettings.*` |
|
|
||||||
| Tab Bar | `src/ScreenComponents.*` |
|
|
||||||
| Recents | `src/RecentBooksStore.*`, `src/BadgeConfig.h` |
|
|
||||||
| OPDS Browser | `src/activities/browser/OpdsBookBrowserActivity.*` |
|
|
||||||
| Dev Tools | `scripts/pre_flash.py`, `scripts/debugging_monitor.py`, `scripts/pio_helper.py` |
|
|
||||||
| Power Management | `src/main.cpp`, `src/activities/Activity.h` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Version Information
|
|
||||||
|
|
||||||
- **Base version:** 0.15.0
|
|
||||||
- **Branch:** crosspoint-ef
|
|
||||||
- **Commits since divergence:** 90+
|
|
||||||
- **Files changed:** 250+
|
|
||||||
@ -1,555 +0,0 @@
|
|||||||
# CrossPoint-EF User Guide Supplement
|
|
||||||
|
|
||||||
This guide covers the additional features available in the `crosspoint-ef` branch. For basic operation, refer to the main [User Guide](../USER_GUIDE.md).
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
- [Dictionary](#dictionary)
|
|
||||||
- [Bookmarks](#bookmarks)
|
|
||||||
- [Quick Menu](#quick-menu)
|
|
||||||
- [Library Search](#library-search)
|
|
||||||
- [Reading Lists](#reading-lists)
|
|
||||||
- [Display Settings](#display-settings)
|
|
||||||
- [Web Server Features](#web-server-features)
|
|
||||||
- [Custom Fonts](#custom-fonts)
|
|
||||||
- [Additional Settings](#additional-settings)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dictionary
|
|
||||||
|
|
||||||
The dictionary feature provides offline word lookup while reading.
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
1. Download a StarDict dictionary (English-English dictionary provided as `dict-en-en.zip`)
|
|
||||||
2. Extract the dictionary files to `/dictionaries/dict-data/` on your SD card
|
|
||||||
3. You should have these files:
|
|
||||||
- `dict-data.ifo`
|
|
||||||
- `dict-data.idx`
|
|
||||||
- `dict-data.dict.dz`
|
|
||||||
- `dict-data.syn` (optional, for synonyms)
|
|
||||||
|
|
||||||
### Using the Dictionary
|
|
||||||
|
|
||||||
#### Method 1: Quick Menu
|
|
||||||
|
|
||||||
1. While reading, press the **Power** button briefly (requires Quick Menu to be configured)
|
|
||||||
2. Select **Dictionary** from the menu
|
|
||||||
3. Choose **Select from Screen** or **Enter a Word**
|
|
||||||
|
|
||||||
#### Method 2: Direct Power Button Access
|
|
||||||
|
|
||||||
1. Go to **Settings → Controls → Short Power Button Click**
|
|
||||||
2. Set to **Dictionary**
|
|
||||||
3. While reading, press the **Power** button briefly to open the dictionary
|
|
||||||
|
|
||||||
### Selecting a Word from the Page
|
|
||||||
|
|
||||||
1. Choose **Select from Screen** from the dictionary menu
|
|
||||||
2. The current page will display with word selection enabled
|
|
||||||
3. Use **Left/Right** to move between words
|
|
||||||
4. Use **Up/Down** to jump between lines
|
|
||||||
5. Press **Confirm** to look up the selected word
|
|
||||||
6. Press **Back** to cancel
|
|
||||||
|
|
||||||
### Viewing Definitions
|
|
||||||
|
|
||||||
- Definitions display with rich formatting (bold, italic, lists)
|
|
||||||
- Use **Left/Right** or **Volume Up/Down** to navigate between pages if the definition is long
|
|
||||||
- Press **Confirm** to search for another word
|
|
||||||
- Press **Back** to return to your book
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bookmarks
|
|
||||||
|
|
||||||
Create and manage bookmarks within your books.
|
|
||||||
|
|
||||||
### Adding a Bookmark
|
|
||||||
|
|
||||||
#### Method 1: Quick Menu
|
|
||||||
|
|
||||||
1. Press the **Power** button briefly (requires Quick Menu to be configured)
|
|
||||||
2. Select **Add Bookmark** (or **Remove Bookmark** if already bookmarked)
|
|
||||||
|
|
||||||
#### Method 2: Settings Configuration
|
|
||||||
|
|
||||||
1. Go to **Settings → Controls → Short Power Button Click**
|
|
||||||
2. Set to **Quick Menu**
|
|
||||||
3. Use Quick Menu to toggle bookmarks
|
|
||||||
|
|
||||||
### Bookmark Indicator
|
|
||||||
|
|
||||||
When a page is bookmarked, a small folded corner triangle appears in the top-right corner of the page.
|
|
||||||
|
|
||||||
### Viewing Bookmarks
|
|
||||||
|
|
||||||
1. Go to **Home → Library**
|
|
||||||
2. Select the **Bookmarks** tab
|
|
||||||
3. You'll see a list of books that have bookmarks
|
|
||||||
4. Select a book to view its bookmarks
|
|
||||||
5. Select a bookmark to jump to that location
|
|
||||||
|
|
||||||
### Deleting Bookmarks
|
|
||||||
|
|
||||||
1. Open a book's bookmark list (from Bookmarks tab)
|
|
||||||
2. Navigate to the bookmark you want to delete
|
|
||||||
3. **Long-press Confirm** (hold for about 1 second)
|
|
||||||
4. Confirm deletion when prompted
|
|
||||||
|
|
||||||
### Bookmark Naming
|
|
||||||
|
|
||||||
Bookmarks are automatically named based on:
|
|
||||||
- Chapter title and page number (e.g., "Chapter 3 - Page 42")
|
|
||||||
- Just page number if no chapter title (e.g., "Page 15")
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Quick Menu
|
|
||||||
|
|
||||||
Fast access to common actions while reading.
|
|
||||||
|
|
||||||
### Enabling Quick Menu
|
|
||||||
|
|
||||||
1. Go to **Settings → Controls → Short Power Button Click**
|
|
||||||
2. Select **Quick Menu**
|
|
||||||
|
|
||||||
### Using Quick Menu
|
|
||||||
|
|
||||||
1. While reading, press the **Power** button briefly
|
|
||||||
2. Navigate with **Up/Down** or **Left/Right**
|
|
||||||
3. Press **Confirm** to select an option
|
|
||||||
4. Press **Back** to close the menu
|
|
||||||
|
|
||||||
### Quick Menu Options
|
|
||||||
|
|
||||||
| Option | Description |
|
|
||||||
|--------|-------------|
|
|
||||||
| **Dictionary** | Look up a word |
|
|
||||||
| **Add/Remove Bookmark** | Toggle bookmark on current page |
|
|
||||||
| **Clear Cache** | Free up storage space |
|
|
||||||
| **Settings** | Open settings menu |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Library Search
|
|
||||||
|
|
||||||
Search your library by title, author, or filename.
|
|
||||||
|
|
||||||
### Accessing Search
|
|
||||||
|
|
||||||
1. Go to **Home → Library**
|
|
||||||
2. Select the **Search** tab
|
|
||||||
3. Or from any tab, scroll to the bottom and select **Search...**
|
|
||||||
|
|
||||||
### Using the Character Picker
|
|
||||||
|
|
||||||
The search uses a character picker interface:
|
|
||||||
|
|
||||||
1. **Left/Right** - Move between characters
|
|
||||||
2. **Confirm** - Add character to search query
|
|
||||||
3. **SPC** - Add a space
|
|
||||||
4. **←** - Delete last character (backspace)
|
|
||||||
5. **CLR** - Clear entire query
|
|
||||||
|
|
||||||
### Navigating Results
|
|
||||||
|
|
||||||
1. After entering characters, results appear below
|
|
||||||
2. Press **Down** to move from character picker to results
|
|
||||||
3. **Left/Right** to navigate results
|
|
||||||
4. **Confirm** to open a book
|
|
||||||
5. **Up** to return to character picker
|
|
||||||
|
|
||||||
### Search Scoring
|
|
||||||
|
|
||||||
Results are ranked by relevance:
|
|
||||||
- Title matches rank highest
|
|
||||||
- Author matches rank second
|
|
||||||
- Filename matches rank lowest
|
|
||||||
- Matches at the start of a field rank higher
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Reading Lists
|
|
||||||
|
|
||||||
Create custom book lists for organizing your library.
|
|
||||||
|
|
||||||
### Viewing Lists
|
|
||||||
|
|
||||||
1. Go to **Home → Library**
|
|
||||||
2. Select the **Lists** tab
|
|
||||||
3. Available lists are displayed
|
|
||||||
|
|
||||||
### Opening a List
|
|
||||||
|
|
||||||
1. Navigate to a list name
|
|
||||||
2. Press **Confirm** to view the list contents
|
|
||||||
3. Select a book to start reading
|
|
||||||
|
|
||||||
### Pinning a List
|
|
||||||
|
|
||||||
Pin a list to quickly access it from the home screen:
|
|
||||||
|
|
||||||
1. In the Lists tab, navigate to a list
|
|
||||||
2. **Long-press Confirm** to open the action menu
|
|
||||||
3. Select **Pin List**
|
|
||||||
|
|
||||||
The pinned list name will appear on the Lists button on the home screen.
|
|
||||||
|
|
||||||
### Unpinning a List
|
|
||||||
|
|
||||||
1. Navigate to the pinned list
|
|
||||||
2. **Long-press Confirm**
|
|
||||||
3. Select **Unpin List**
|
|
||||||
|
|
||||||
### Deleting a List
|
|
||||||
|
|
||||||
1. Navigate to a list
|
|
||||||
2. **Long-press Confirm**
|
|
||||||
3. Select **Delete List**
|
|
||||||
4. Confirm deletion
|
|
||||||
|
|
||||||
### Creating Lists via Web Server
|
|
||||||
|
|
||||||
Lists can be created and uploaded via the web server API. See [Web Server Features](#web-server-features).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Display Settings
|
|
||||||
|
|
||||||
### High Contrast Mode
|
|
||||||
|
|
||||||
Increases contrast across the entire UI for better readability.
|
|
||||||
|
|
||||||
1. Go to **Settings → Display → High Contrast**
|
|
||||||
2. Set to **On** or **Off**
|
|
||||||
|
|
||||||
When enabled, mid-gray tones are pushed toward black or white.
|
|
||||||
|
|
||||||
### Bezel Compensation
|
|
||||||
|
|
||||||
Compensate for physical screen edge defects (common on some devices).
|
|
||||||
|
|
||||||
1. Go to **Settings → Display → Bezel Compensation**
|
|
||||||
2. Set value from **0** (disabled) to **10** pixels
|
|
||||||
3. If compensation is enabled, select **Bezel Edge**:
|
|
||||||
- **Bottom** - Default, compensates bottom edge
|
|
||||||
- **Top** - Compensates top edge
|
|
||||||
- **Left** - Compensates left edge
|
|
||||||
- **Right** - Compensates right edge
|
|
||||||
|
|
||||||
The compensation margin automatically rotates with screen orientation.
|
|
||||||
|
|
||||||
### Status Bar Options
|
|
||||||
|
|
||||||
Additional status bar display options:
|
|
||||||
|
|
||||||
| Option | Description |
|
|
||||||
|--------|-------------|
|
|
||||||
| None | No status bar |
|
|
||||||
| No Progress | Status bar without reading progress |
|
|
||||||
| Full w/ Percentage | Status bar with percentage progress |
|
|
||||||
| Full w/ Progress Bar | Status bar with visual progress bar |
|
|
||||||
| Progress Bar | Only progress bar, no other info |
|
|
||||||
|
|
||||||
Configure at **Settings → Display → Status Bar**.
|
|
||||||
|
|
||||||
### Sleep Screen Cover Filter
|
|
||||||
|
|
||||||
When using book cover as sleep screen:
|
|
||||||
|
|
||||||
| Filter | Effect |
|
|
||||||
|--------|--------|
|
|
||||||
| None | Grayscale image as-is |
|
|
||||||
| Contrast | Black and white only (no grays) |
|
|
||||||
| Inverted | Inverted black and white |
|
|
||||||
|
|
||||||
Configure at **Settings → Display → Sleep Screen Cover Filter**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Web Server Features
|
|
||||||
|
|
||||||
The web server provides extended file management and companion app support.
|
|
||||||
|
|
||||||
### Starting the Web Server
|
|
||||||
|
|
||||||
1. Go to **Home → File Transfer**
|
|
||||||
2. Select a WiFi network or create a hotspot
|
|
||||||
3. The web server URL will be displayed
|
|
||||||
|
|
||||||
### File Management
|
|
||||||
|
|
||||||
Access the file manager at `http://<device-ip>/files`
|
|
||||||
|
|
||||||
**Available Operations:**
|
|
||||||
- **Upload** - Upload files via drag-and-drop or file picker
|
|
||||||
- **Download** - Download files to your computer
|
|
||||||
- **Delete** - Remove files and folders
|
|
||||||
- **Rename** - Rename files and folders
|
|
||||||
- **Create Folder** - Create new directories
|
|
||||||
- **Archive/Unarchive** - Archive books (preserves reading progress)
|
|
||||||
- **Copy/Move** - Copy or move files and folders
|
|
||||||
|
|
||||||
### API Access
|
|
||||||
|
|
||||||
The web server provides a JSON API for programmatic access:
|
|
||||||
|
|
||||||
| Endpoint | Description |
|
|
||||||
|----------|-------------|
|
|
||||||
| `GET /api/status` | Device status |
|
|
||||||
| `GET /api/files?path=/` | List files |
|
|
||||||
| `GET /api/archived` | List archived books |
|
|
||||||
| `GET /api/hash?path=/book.epub` | Get MD5 hash |
|
|
||||||
|
|
||||||
### mDNS Discovery
|
|
||||||
|
|
||||||
The device advertises itself as `crosspoint.local` on your network.
|
|
||||||
|
|
||||||
### Companion App Support
|
|
||||||
|
|
||||||
The web server supports the CrossPoint Companion Android app:
|
|
||||||
|
|
||||||
1. **QR Code** - Scan the QR code displayed on the web server screen
|
|
||||||
2. **Deep Links** - URLs like `crosspoint://files?host=192.168.1.100` open the app directly
|
|
||||||
|
|
||||||
### Managing Reading Lists via API
|
|
||||||
|
|
||||||
**Get all lists:**
|
|
||||||
```
|
|
||||||
GET /list
|
|
||||||
```
|
|
||||||
|
|
||||||
**Get specific list:**
|
|
||||||
```
|
|
||||||
GET /list?name=MyList
|
|
||||||
```
|
|
||||||
|
|
||||||
**Upload a list:**
|
|
||||||
```
|
|
||||||
POST /list?action=upload&name=MyList
|
|
||||||
Content-Type: text/plain
|
|
||||||
|
|
||||||
1,Book Title,Author Name,/path/to/book.epub
|
|
||||||
2,Another Book,Another Author,/path/to/another.epub
|
|
||||||
```
|
|
||||||
|
|
||||||
**Delete a list:**
|
|
||||||
```
|
|
||||||
POST /list?action=delete&name=MyList
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Custom Fonts
|
|
||||||
|
|
||||||
Two additional accessibility-focused fonts are available.
|
|
||||||
|
|
||||||
### Available Custom Fonts
|
|
||||||
|
|
||||||
1. **Atkinson Hyperlegible Next** - Designed for low-vision readers with high character differentiation
|
|
||||||
2. **Fern Micro** - Optimized for small screens
|
|
||||||
|
|
||||||
### Enabling Custom Fonts
|
|
||||||
|
|
||||||
1. Go to **Settings → Reader → Font Family**
|
|
||||||
2. Select **Custom**
|
|
||||||
3. Go to **Settings → Reader → Custom Font**
|
|
||||||
4. Select your preferred font
|
|
||||||
|
|
||||||
### Fallback Font
|
|
||||||
|
|
||||||
When using custom fonts, set a fallback for missing glyphs:
|
|
||||||
|
|
||||||
1. Go to **Settings → Reader → Fallback Font**
|
|
||||||
2. Choose **Bookerly** or **Noto Sans**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Additional Settings
|
|
||||||
|
|
||||||
### Short Power Button Actions
|
|
||||||
|
|
||||||
Configure what happens when you briefly press the Power button:
|
|
||||||
|
|
||||||
| Option | Action |
|
|
||||||
|--------|--------|
|
|
||||||
| Ignore | No action (default) |
|
|
||||||
| Sleep | Put device to sleep |
|
|
||||||
| Page Turn | Turn to next page |
|
|
||||||
| Dictionary | Open dictionary |
|
|
||||||
| Quick Menu | Open quick menu |
|
|
||||||
|
|
||||||
Configure at **Settings → Controls → Short Power Button Click**.
|
|
||||||
|
|
||||||
### Long-press Chapter Skip
|
|
||||||
|
|
||||||
Control side button long-press behavior:
|
|
||||||
|
|
||||||
- **On** (default) - Long-press Volume buttons to skip chapters
|
|
||||||
- **Off** - Long-press scrolls a page instead
|
|
||||||
|
|
||||||
Configure at **Settings → Controls → Long-press Chapter Skip**.
|
|
||||||
|
|
||||||
### Hyphenation
|
|
||||||
|
|
||||||
Enable word hyphenation for justified text:
|
|
||||||
|
|
||||||
1. Go to **Settings → Reader → Hyphenation**
|
|
||||||
2. Set to **On**
|
|
||||||
|
|
||||||
Hyphenation patterns are available for multiple languages (English, German, French, Spanish, Russian, etc.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Recents View Enhancements
|
|
||||||
|
|
||||||
### Badges
|
|
||||||
|
|
||||||
Books in the Recent tab display badges showing:
|
|
||||||
- **File extension** (epub, txt, md)
|
|
||||||
- **Suffix tags** (X4, X4P for files with `-x4` or `-x4p` suffixes)
|
|
||||||
|
|
||||||
### Removing from Recents
|
|
||||||
|
|
||||||
1. Navigate to a book in the Recent tab
|
|
||||||
2. **Long-press Confirm**
|
|
||||||
3. Select **Remove from Recents**
|
|
||||||
|
|
||||||
### Clearing All Recents
|
|
||||||
|
|
||||||
1. Navigate to any book in the Recent tab
|
|
||||||
2. **Long-press Confirm**
|
|
||||||
3. Select **Clear All Recents**
|
|
||||||
4. Confirm the action
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tab Navigation
|
|
||||||
|
|
||||||
The library uses a unified tab bar for navigation.
|
|
||||||
|
|
||||||
### Tabs Available
|
|
||||||
|
|
||||||
| Tab | Contents |
|
|
||||||
|-----|----------|
|
|
||||||
| Recent | Recently opened books |
|
|
||||||
| Lists | Custom reading lists |
|
|
||||||
| Bookmarks | Books with bookmarks |
|
|
||||||
| Search | Search all books |
|
|
||||||
| Files | File browser |
|
|
||||||
|
|
||||||
### Navigating Tabs
|
|
||||||
|
|
||||||
When the tab bar is focused:
|
|
||||||
- **Left/Right** - Switch between tabs
|
|
||||||
- **Down** - Enter the selected tab's content
|
|
||||||
- **Confirm** - Same as Down
|
|
||||||
|
|
||||||
### Tab Overflow
|
|
||||||
|
|
||||||
When tabs don't fit on screen:
|
|
||||||
- **<** indicator appears on left when more tabs exist to the left
|
|
||||||
- **>** indicator appears on right when more tabs exist to the right
|
|
||||||
- Scroll continues automatically when navigating past visible tabs
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Inline Images
|
|
||||||
|
|
||||||
EPUBs with embedded images now display them inline with text.
|
|
||||||
|
|
||||||
### Supported Formats
|
|
||||||
|
|
||||||
- JPEG (.jpg, .jpeg)
|
|
||||||
- PNG (.png)
|
|
||||||
|
|
||||||
### Image Display
|
|
||||||
|
|
||||||
- Images are automatically scaled to fit the page width
|
|
||||||
- Images are converted to 4-level grayscale with dithering
|
|
||||||
- First load may be slower as images are processed
|
|
||||||
- Subsequent loads use cached versions
|
|
||||||
|
|
||||||
### Image Cache
|
|
||||||
|
|
||||||
Processed images are cached as `.pxc` files in the book's cache directory for faster loading.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Dictionary Not Working
|
|
||||||
|
|
||||||
1. Verify dictionary files are in `/dictionaries/dict-data/`
|
|
||||||
2. Check that all required files exist (.ifo, .idx, .dict.dz)
|
|
||||||
3. File names must match exactly (case-sensitive)
|
|
||||||
|
|
||||||
### Bookmarks Not Saving
|
|
||||||
|
|
||||||
1. Ensure SD card is not write-protected
|
|
||||||
2. Check available storage space
|
|
||||||
3. Bookmarks are saved per-book in `/.crosspoint/`
|
|
||||||
|
|
||||||
### Search Not Finding Books
|
|
||||||
|
|
||||||
1. Search only indexes books in the library
|
|
||||||
2. Ensure books have proper EPUB metadata
|
|
||||||
3. Try searching by filename if metadata is missing
|
|
||||||
|
|
||||||
### Images Not Displaying
|
|
||||||
|
|
||||||
1. Only PNG and JPEG formats are supported
|
|
||||||
2. Very large images may fail to load due to memory constraints
|
|
||||||
3. Check for sufficient free memory (multiple large books open may exhaust memory)
|
|
||||||
|
|
||||||
### Web Server Connection Issues
|
|
||||||
|
|
||||||
1. Ensure device and computer are on the same network
|
|
||||||
2. Try accessing via IP address instead of `crosspoint.local`
|
|
||||||
3. Check that firewall isn't blocking port 80
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Keyboard Shortcuts Summary
|
|
||||||
|
|
||||||
### In Reader
|
|
||||||
|
|
||||||
| Button | Action |
|
|
||||||
|--------|--------|
|
|
||||||
| Left/Volume Up | Previous page |
|
|
||||||
| Right/Volume Down | Next page |
|
|
||||||
| Left (hold) | Previous chapter |
|
|
||||||
| Right (hold) | Next chapter |
|
|
||||||
| Back | Return to library |
|
|
||||||
| Back (hold) | Return to home |
|
|
||||||
| Confirm | Open chapter selection |
|
|
||||||
| Power (brief) | Configured action (Quick Menu/Dictionary/Sleep/Page Turn) |
|
|
||||||
|
|
||||||
### In Quick Menu
|
|
||||||
|
|
||||||
| Button | Action |
|
|
||||||
|--------|--------|
|
|
||||||
| Up/Down/Left/Right | Navigate options |
|
|
||||||
| Confirm | Select option |
|
|
||||||
| Back | Close menu |
|
|
||||||
|
|
||||||
### In Word Selection
|
|
||||||
|
|
||||||
| Button | Action |
|
|
||||||
|--------|--------|
|
|
||||||
| Left/Right | Move between words |
|
|
||||||
| Up/Down | Move between lines |
|
|
||||||
| Confirm | Look up word |
|
|
||||||
| Back | Cancel |
|
|
||||||
|
|
||||||
### In Library Tabs
|
|
||||||
|
|
||||||
| Button | Action |
|
|
||||||
|--------|--------|
|
|
||||||
| Left/Right | Switch tabs (when tab bar focused) |
|
|
||||||
| Up/Down | Navigate within tab |
|
|
||||||
| Confirm | Select item / Enter tab |
|
|
||||||
| Confirm (hold) | Action menu |
|
|
||||||
| Back | Go back / Exit to home |
|
|
||||||
@ -3,40 +3,11 @@
|
|||||||
This document show most common issues and possible solutions while using the device features.
|
This document show most common issues and possible solutions while using the device features.
|
||||||
|
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
- [Images Not Displaying in EPUBs](#images-not-displaying-in-epubs)
|
|
||||||
- [Cannot See the Device on the Network](#cannot-see-the-device-on-the-network)
|
- [Cannot See the Device on the Network](#cannot-see-the-device-on-the-network)
|
||||||
- [Connection Drops or Times Out](#connection-drops-or-times-out)
|
- [Connection Drops or Times Out](#connection-drops-or-times-out)
|
||||||
- [Upload Fails](#upload-fails)
|
- [Upload Fails](#upload-fails)
|
||||||
- [Saved Password Not Working](#saved-password-not-working)
|
- [Saved Password Not Working](#saved-password-not-working)
|
||||||
|
|
||||||
### Images Not Displaying in EPUBs
|
|
||||||
|
|
||||||
**Problem:** Some images in EPUB books show as placeholders like "[Image: filename.jpg]" instead of the actual image
|
|
||||||
|
|
||||||
**Possible Causes:**
|
|
||||||
|
|
||||||
1. **Progressive JPEGs are not supported**
|
|
||||||
- The device uses a minimal JPEG decoder optimized for embedded systems
|
|
||||||
- Progressive/multi-scan JPEGs cannot be decoded due to memory constraints
|
|
||||||
- This affects some professionally published EPUBs, especially maps and high-quality photos
|
|
||||||
- **Workaround:** Use Calibre or another EPUB editor to convert progressive JPEGs to baseline JPEGs
|
|
||||||
|
|
||||||
2. **Unsupported image format**
|
|
||||||
- Only JPEG and PNG images are supported
|
|
||||||
- Other formats (GIF, WebP, SVG graphics) will show placeholders
|
|
||||||
|
|
||||||
3. **Image extraction failed**
|
|
||||||
- The image file may be corrupted or the EPUB structure malformed
|
|
||||||
- Try re-downloading the EPUB or converting it with Calibre
|
|
||||||
|
|
||||||
**How to check if an image is progressive JPEG:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
from PIL import Image
|
|
||||||
print(Image.open("image.jpg").info.get('progressive', 0))
|
|
||||||
# Output: 1 = progressive (not supported), 0 = baseline (supported)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cannot See the Device on the Network
|
### Cannot See the Device on the Network
|
||||||
|
|
||||||
**Problem:** Browser shows "Cannot connect" or "Site can't be reached"
|
**Problem:** Browser shows "Cannot connect" or "Site can't be reached"
|
||||||
|
|||||||
@ -1,334 +0,0 @@
|
|||||||
# CrossPointWebServer API Reference
|
|
||||||
|
|
||||||
Source: `src/network/CrossPointWebServer.cpp` and `CrossPointWebServer.h`
|
|
||||||
|
|
||||||
## Server Configuration
|
|
||||||
|
|
||||||
- HTTP port: 80 (default)
|
|
||||||
- WebSocket port: 81 (default)
|
|
||||||
- WiFi sleep disabled for responsiveness
|
|
||||||
- Supports both STA (station) and AP (access point) modes
|
|
||||||
|
|
||||||
## HTTP Endpoints
|
|
||||||
|
|
||||||
### GET /
|
|
||||||
**Handler:** `handleRoot()`
|
|
||||||
**Response:** HTML homepage from `HomePageHtml` (generated from `html/HomePage.html`)
|
|
||||||
**Content-Type:** text/html
|
|
||||||
|
|
||||||
### GET /files
|
|
||||||
**Handler:** `handleFileList()`
|
|
||||||
**Response:** HTML file browser page from `FilesPageHtml` (generated from `html/FilesPage.html`)
|
|
||||||
**Content-Type:** text/html
|
|
||||||
|
|
||||||
### GET /api/status
|
|
||||||
**Handler:** `handleStatus()`
|
|
||||||
**Response:** JSON device status
|
|
||||||
**Content-Type:** application/json
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"version": "CROSSPOINT_VERSION",
|
|
||||||
"ip": "192.168.x.x",
|
|
||||||
"mode": "AP" | "STA",
|
|
||||||
"rssi": -50, // 0 in AP mode
|
|
||||||
"freeHeap": 123456,
|
|
||||||
"uptime": 3600 // seconds
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /api/files
|
|
||||||
**Handler:** `handleFileListData()`
|
|
||||||
**Query params:**
|
|
||||||
- `path` (optional): Directory path, defaults to "/"
|
|
||||||
- `showHidden` (optional): "true" to show dot-files (except .crosspoint)
|
|
||||||
**Response:** JSON array of files
|
|
||||||
**Content-Type:** application/json
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{"name": "book.epub", "size": 123456, "isDirectory": false, "isEpub": true},
|
|
||||||
{"name": "folder", "size": 0, "isDirectory": true, "isEpub": false}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
**Notes:**
|
|
||||||
- Hidden by default: files starting with ".", "System Volume Information", "XTCache"
|
|
||||||
- Always hidden: ".crosspoint" (internal cache folder)
|
|
||||||
- Streamed response (chunked encoding) to reduce memory usage
|
|
||||||
|
|
||||||
### GET /api/archived
|
|
||||||
**Handler:** `handleArchivedList()`
|
|
||||||
**Response:** JSON array of archived books
|
|
||||||
**Content-Type:** application/json
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{"filename": "archived_file.epub", "originalPath": "/Books/archived_file.epub"}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
**Notes:** Uses `BookManager::listArchivedBooks()` and `BookManager::getArchivedBookOriginalPath()`
|
|
||||||
|
|
||||||
### GET /download
|
|
||||||
**Handler:** `handleDownload()`
|
|
||||||
**Query params:**
|
|
||||||
- `path` (required): File path to download
|
|
||||||
**Response:** File binary with Content-Disposition attachment header
|
|
||||||
**Content-Type:** application/octet-stream
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing path, path is directory
|
|
||||||
- 403: Hidden/system file, protected item
|
|
||||||
- 404: File not found
|
|
||||||
**Notes:**
|
|
||||||
- Streams in 4KB chunks
|
|
||||||
- Updates `totalBytesDownloaded` and `totalFilesDownloaded` stats
|
|
||||||
- Security: rejects paths with "..", files starting with ".", protected items
|
|
||||||
|
|
||||||
### POST /upload
|
|
||||||
**Handler:** `handleUpload()` (multipart handler), `handleUploadPost()` (response handler)
|
|
||||||
**Query params:**
|
|
||||||
- `path` (optional): Upload directory, defaults to "/"
|
|
||||||
**Form data:** multipart/form-data with file
|
|
||||||
**Response:** "File uploaded successfully: filename" or error message
|
|
||||||
**Notes:**
|
|
||||||
- Uses 4KB write buffer for SD card efficiency
|
|
||||||
- Overwrites existing files
|
|
||||||
- Clears epub cache after upload via `clearEpubCacheIfNeeded()`
|
|
||||||
- Updates `totalBytesUploaded` and `totalFilesUploaded` stats
|
|
||||||
- Logs progress every 100KB
|
|
||||||
|
|
||||||
### POST /mkdir
|
|
||||||
**Handler:** `handleCreateFolder()`
|
|
||||||
**Form params:**
|
|
||||||
- `name` (required): Folder name
|
|
||||||
- `path` (optional): Parent directory, defaults to "/"
|
|
||||||
**Response:** "Folder created: foldername" or error
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing name, empty name, folder exists
|
|
||||||
|
|
||||||
### POST /delete
|
|
||||||
**Handler:** `handleDelete()`
|
|
||||||
**Form params:**
|
|
||||||
- `path` (required): Item path to delete
|
|
||||||
- `type` (optional): "file" (default) or "folder"
|
|
||||||
- `archived` (optional): "true" for archived books
|
|
||||||
**Response:** "Deleted successfully" or error
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing path, root directory, folder not empty
|
|
||||||
- 403: Hidden/system file, protected item
|
|
||||||
- 404: Item not found
|
|
||||||
- 500: Delete failed
|
|
||||||
**Notes:**
|
|
||||||
- For files: uses `BookManager::deleteBook()` which handles cache and recent books cleanup
|
|
||||||
- For folders: must be empty first
|
|
||||||
- For archived: passes filename to `BookManager::deleteBook(filename, true)`
|
|
||||||
|
|
||||||
### POST /archive
|
|
||||||
**Handler:** `handleArchive()`
|
|
||||||
**Form params:**
|
|
||||||
- `path` (required): Book path to archive
|
|
||||||
**Response:** "Book archived successfully" or error
|
|
||||||
**Notes:** Uses `BookManager::archiveBook()`
|
|
||||||
|
|
||||||
### POST /unarchive
|
|
||||||
**Handler:** `handleUnarchive()`
|
|
||||||
**Form params:**
|
|
||||||
- `filename` (required): Archived book filename
|
|
||||||
**Response:** JSON with original path
|
|
||||||
**Content-Type:** application/json
|
|
||||||
```json
|
|
||||||
{"success": true, "originalPath": "/Books/book.epub"}
|
|
||||||
```
|
|
||||||
**Notes:** Uses `BookManager::unarchiveBook()` and `BookManager::getArchivedBookOriginalPath()`
|
|
||||||
|
|
||||||
### POST /rename
|
|
||||||
**Handler:** `handleRename()`
|
|
||||||
**Form params:**
|
|
||||||
- `path` (required): Current item path
|
|
||||||
- `newName` (required): New name (filename only, no path separators)
|
|
||||||
**Response:** "Renamed successfully" or error
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing params, empty name, name contains "/" or "\\", root directory, destination exists
|
|
||||||
- 403: System file, protected item
|
|
||||||
- 404: Source not found
|
|
||||||
- 500: Rename failed
|
|
||||||
**Notes:**
|
|
||||||
- Renames in place (same directory, new name)
|
|
||||||
- Uses `SdMan.rename()`
|
|
||||||
- Clears epub cache after rename via `clearEpubCacheIfNeeded()`
|
|
||||||
|
|
||||||
### POST /copy
|
|
||||||
**Handler:** `handleCopy()`
|
|
||||||
**Form params:**
|
|
||||||
- `srcPath` (required): Source path
|
|
||||||
- `destPath` (required): Full destination path (including new name)
|
|
||||||
**Response:** "Copied successfully" or error
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing params, root directory, destination exists, copy into self
|
|
||||||
- 403: System file, protected item
|
|
||||||
- 404: Source not found
|
|
||||||
- 500: Copy failed
|
|
||||||
**Notes:**
|
|
||||||
- Uses `copyFile()` for files (4KB buffer chunks)
|
|
||||||
- Uses `copyFolder()` for recursive directory copy
|
|
||||||
- Skips hidden files in folder copy
|
|
||||||
|
|
||||||
### POST /move
|
|
||||||
**Handler:** `handleMove()`
|
|
||||||
**Form params:**
|
|
||||||
- `srcPath` (required): Source path
|
|
||||||
- `destPath` (required): Full destination path (including new name)
|
|
||||||
**Response:** "Moved successfully" or error
|
|
||||||
**Errors:** Same as copy
|
|
||||||
**Notes:**
|
|
||||||
- First attempts atomic `SdMan.rename()` (fast)
|
|
||||||
- Falls back to copy+delete if rename fails
|
|
||||||
- Uses `deleteFolderRecursive()` for folder cleanup
|
|
||||||
|
|
||||||
### GET /list
|
|
||||||
**Handler:** `handleListGet()`
|
|
||||||
**Query params:**
|
|
||||||
- `name` (optional): Specific list name to retrieve
|
|
||||||
**Response:** JSON array of lists (if no name) or single list details (if name specified)
|
|
||||||
**Content-Type:** application/json
|
|
||||||
|
|
||||||
**Response (all lists - no name param):**
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{"name": "MyReadingList", "path": "/.lists/MyReadingList.bin", "bookCount": 5},
|
|
||||||
{"name": "Favorites", "path": "/.lists/Favorites.bin", "bookCount": 12}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (specific list - with name param):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "MyReadingList",
|
|
||||||
"path": "/.lists/MyReadingList.bin",
|
|
||||||
"books": [
|
|
||||||
{"order": 1, "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "path": "/Books/gatsby.epub"},
|
|
||||||
{"order": 2, "title": "1984", "author": "George Orwell", "path": "/Books/1984.epub"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Errors:**
|
|
||||||
- 404: List not found (when `name` specified but doesn't exist)
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- Lists are stored in `/.lists/` directory as `.bin` files
|
|
||||||
- Uses `BookListStore::listAllLists()` and `BookListStore::loadList()`
|
|
||||||
|
|
||||||
### POST /list
|
|
||||||
**Handler:** `handleListPost()`
|
|
||||||
**Query params:**
|
|
||||||
- `action` (required): "upload" or "delete"
|
|
||||||
- `name` (required): List name (without .bin extension)
|
|
||||||
**Request body (for upload):** CSV text with one book per line
|
|
||||||
**Content-Type:** text/plain (for upload body)
|
|
||||||
|
|
||||||
**Input format (POST body for upload action):**
|
|
||||||
```
|
|
||||||
1,The Great Gatsby,F. Scott Fitzgerald,/Books/gatsby.epub
|
|
||||||
2,1984,George Orwell,/Books/1984.epub
|
|
||||||
3,Pride and Prejudice,Jane Austen,/Books/pride.epub
|
|
||||||
```
|
|
||||||
Format: `order,title,author,path` (one per line)
|
|
||||||
|
|
||||||
**Response (upload success):**
|
|
||||||
```json
|
|
||||||
{"success": true, "path": "/.lists/MyReadingList.bin"}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (delete success):**
|
|
||||||
```json
|
|
||||||
{"success": true}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Errors:**
|
|
||||||
- 400: Missing action or name parameter, empty name, failed to parse list data
|
|
||||||
- 404: List not found (for delete action)
|
|
||||||
- 500: Failed to save/delete list
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- Lists are stored as binary files in `/.lists/` directory
|
|
||||||
- Uses `BookListStore::parseFromText()`, `BookListStore::saveList()`, `BookListStore::deleteList()`
|
|
||||||
- Order field determines display order (books are sorted by order when loaded)
|
|
||||||
- Overwrites existing list with same name on upload
|
|
||||||
|
|
||||||
## WebSocket Protocol (port 81)
|
|
||||||
|
|
||||||
**Handler:** `onWebSocketEvent()` via `wsEventCallback()` trampoline
|
|
||||||
|
|
||||||
### Upload Protocol
|
|
||||||
|
|
||||||
1. Client connects
|
|
||||||
2. Server: (implicit connection acknowledgment)
|
|
||||||
3. Client TEXT: `START:<filename>:<size>:<path>`
|
|
||||||
4. Server TEXT: `READY` or `ERROR:<message>`
|
|
||||||
5. Client BIN: file data chunks (any size, recommend 64KB)
|
|
||||||
6. Server TEXT: `PROGRESS:<received>:<total>` (every 64KB or at end)
|
|
||||||
7. Server TEXT: `DONE` or `ERROR:<message>`
|
|
||||||
|
|
||||||
### Events
|
|
||||||
- `WStype_CONNECTED`: Client connected, logs connection
|
|
||||||
- `WStype_DISCONNECTED`: Cleanup incomplete upload, delete partial file
|
|
||||||
- `WStype_TEXT`: Parse control messages (START)
|
|
||||||
- `WStype_BIN`: Write file data, send progress, complete upload
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
- Faster than HTTP multipart for large files
|
|
||||||
- Direct binary writes to SD card
|
|
||||||
- Clears epub cache after upload
|
|
||||||
- Updates traffic statistics
|
|
||||||
|
|
||||||
## Security
|
|
||||||
|
|
||||||
### Protected Items (HIDDEN_ITEMS[])
|
|
||||||
- "System Volume Information"
|
|
||||||
- "XTCache"
|
|
||||||
|
|
||||||
### Always Hidden
|
|
||||||
- ".crosspoint" (internal cache)
|
|
||||||
|
|
||||||
### Security Checks Applied To
|
|
||||||
- `/delete`: Rejects dot-files (unless archived), protected items
|
|
||||||
- `/download`: Rejects dot-files, protected items, path traversal (..)
|
|
||||||
- `/rename`: Rejects dot-files, protected items
|
|
||||||
- `/copy`: Rejects dot-files, protected items
|
|
||||||
- `/move`: Rejects dot-files, protected items
|
|
||||||
|
|
||||||
## Helper Functions
|
|
||||||
|
|
||||||
### clearEpubCacheIfNeeded(filePath)
|
|
||||||
- Location: anonymous namespace at top of file
|
|
||||||
- Clears epub cache if file ends with ".epub"
|
|
||||||
- Uses `Epub(filePath, "/.crosspoint").clearCache()`
|
|
||||||
- Called by: upload, WebSocket upload, rename
|
|
||||||
|
|
||||||
### scanFiles(path, callback, showHidden)
|
|
||||||
- Iterates directory, calls callback for each FileInfo
|
|
||||||
- Yields and resets watchdog during iteration
|
|
||||||
- Filters hidden items based on showHidden flag
|
|
||||||
|
|
||||||
### copyFile(srcPath, destPath) / copyFolder(srcPath, destPath)
|
|
||||||
- 4KB buffer for file copy
|
|
||||||
- Recursive for folders
|
|
||||||
- Returns bool success
|
|
||||||
|
|
||||||
### deleteFolderRecursive(path)
|
|
||||||
- Static helper for move fallback
|
|
||||||
- Recursively deletes contents then directory
|
|
||||||
|
|
||||||
## Traffic Statistics (mutable, updated from const handlers)
|
|
||||||
- `totalBytesUploaded`
|
|
||||||
- `totalBytesDownloaded`
|
|
||||||
- `totalFilesUploaded`
|
|
||||||
- `totalFilesDownloaded`
|
|
||||||
- `serverStartTime` (for uptime calculation)
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
- `<WebServer.h>` - ESP32 HTTP server
|
|
||||||
- `<WebSocketsServer.h>` - WebSocket support
|
|
||||||
- `<ArduinoJson.h>` - JSON serialization
|
|
||||||
- `<SDCardManager.h>` - SD card operations (SdMan singleton)
|
|
||||||
- `<Epub.h>` - Epub cache management
|
|
||||||
- `BookListStore.h` - Book list management (lists feature)
|
|
||||||
- `BookManager.h` - Book deletion, archiving, recent books
|
|
||||||
- `StringUtils.h` - File extension checking
|
|
||||||
195
ef-CHANGELOG.md
195
ef-CHANGELOG.md
@ -1,195 +0,0 @@
|
|||||||
# crosspoint-ef Changelog
|
|
||||||
|
|
||||||
All notable changes to the crosspoint-ef fork are documented here.
|
|
||||||
|
|
||||||
Base: CrossPoint Reader 0.15.0
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.5
|
|
||||||
|
|
||||||
**Stability & Memory Improvements**
|
|
||||||
|
|
||||||
### Bug Fixes - Webserver
|
|
||||||
|
|
||||||
- **File Transfer Stability**: Removed blocking MD5 hash computation from file listings that caused EAGAIN errors and connection stalls
|
|
||||||
- **JSON Batching**: Implemented 2KB batch streaming for file listings with pacing to prevent TCP buffer overflow
|
|
||||||
- **Simplified Flow Control**: Removed unnecessary yield/delay logic from content streaming
|
|
||||||
|
|
||||||
### Bug Fixes - Memory
|
|
||||||
|
|
||||||
- **QR Code Caching**: Generate QR codes once on server start instead of regenerating on each screen render
|
|
||||||
- **WiFi Scan Optimization**: Replaced memory-heavy `std::map` deduplication with in-place vector search, limited results to 20 networks, earlier `WiFi.scanDelete()` for faster memory recovery
|
|
||||||
- **Cover Buffer Leak**: Fixed 48KB memory leak when navigating from Home to File Transfer (cover buffer now explicitly freed)
|
|
||||||
|
|
||||||
### Bug Fixes - EPUB Reader
|
|
||||||
|
|
||||||
- **Errant Underlining**: Fixed words before styled inline elements (like `<a>` tags with CSS underline) incorrectly receiving the element's style by flushing the text buffer before style changes
|
|
||||||
|
|
||||||
### Bug Fixes - Flashing Screen
|
|
||||||
|
|
||||||
- **Version String Overflow**: Fixed flash notification parsing failing on longer version strings (buffer limit increased from 30 to 50 characters)
|
|
||||||
- **Display Quality**: Changed flashing screen to half refresh for cleaner appearance
|
|
||||||
- **Timing**: Adjusted pre-flash script timing for half refresh completion
|
|
||||||
|
|
||||||
### Upstream Merges
|
|
||||||
|
|
||||||
- **PR #522 - HAL Abstraction Layer**: Merged hardware abstraction layer refactor introducing `HalDisplay` and `HalGPIO` classes, decoupling application code from direct hardware access
|
|
||||||
- **PR #603 - Sunlight Fading Fix**: Added user-toggleable setting to turn off display between refreshes, mitigating the sunlight fading issue on e-ink displays
|
|
||||||
- New "Sunlight Fading Fix" toggle in Display settings (OFF/ON)
|
|
||||||
- Passes `turnOffScreen` parameter through display stack when enabled
|
|
||||||
|
|
||||||
### Files Changed
|
|
||||||
|
|
||||||
- `src/main.cpp` - flash screen fixes, cover buffer free on File Transfer entry, fading fix integration
|
|
||||||
- `scripts/pre_flash.py` - timing adjustments for full refresh
|
|
||||||
- `src/network/CrossPointWebServer.cpp` - JSON batching, removed MD5 from listings
|
|
||||||
- `src/network/CrossPointWebServer.h` - removed md5 from FileInfo, simplified sendContentSafe
|
|
||||||
- `src/activities/network/CrossPointWebServerActivity.cpp` - QR code caching
|
|
||||||
- `src/activities/network/CrossPointWebServerActivity.h` - QR code cache members
|
|
||||||
- `src/activities/network/WifiSelectionActivity.cpp` - WiFi scan memory optimization
|
|
||||||
- `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp` - flush buffer before style changes
|
|
||||||
- `lib/hal/HalDisplay.h` - new HAL abstraction for display (PR #522), turnOffScreen parameter (PR #603)
|
|
||||||
- `lib/hal/HalDisplay.cpp` - HAL display implementation with fading fix passthrough
|
|
||||||
- `lib/hal/HalGPIO.h` - new HAL abstraction for GPIO (PR #522)
|
|
||||||
- `lib/hal/HalGPIO.cpp` - HAL GPIO implementation
|
|
||||||
- `lib/GfxRenderer/GfxRenderer.h` - updated for HAL layer, added fadingFix member
|
|
||||||
- `lib/GfxRenderer/GfxRenderer.cpp` - updated for HAL layer, passes fadingFix to display
|
|
||||||
- `src/CrossPointSettings.h` - added fadingFix setting
|
|
||||||
- `src/CrossPointSettings.cpp` - fadingFix persistence
|
|
||||||
- `src/activities/settings/SettingsActivity.cpp` - added Sunlight Fading Fix toggle
|
|
||||||
- `open-x4-sdk` - updated submodule with turnOffScreen support in EInkDisplay
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.4
|
|
||||||
|
|
||||||
**EPUB Rendering & Stability**
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
- **End-of-Book "Start Over"**: Press next at end of book to wrap to first page
|
|
||||||
|
|
||||||
### EPUB Rendering Improvements
|
|
||||||
|
|
||||||
- CSS `margin-left`/`padding-left` parsing for block indentation
|
|
||||||
- Vertical bar and italic styling for blockquotes
|
|
||||||
- Left margin indentation for list items (`<ol>`/`<ul>`)
|
|
||||||
- Fixed ordered lists showing bullets instead of numbers
|
|
||||||
- Fixed nested `<p>` inside `<li>` causing marker on separate line
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
- **Webserver**: Fixed file listing disconnection issues with flow control
|
|
||||||
- **Webserver**: Memory optimization for File Transfer mode (frees heap before starting)
|
|
||||||
- **Dictionary**: Fixed zip dictionary allocation order for better memory allocation success
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.3
|
|
||||||
|
|
||||||
**Maintenance Release**
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
- Fixed cppcheck CI failure: removed unused `screenWidth` variable in word selection activity
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.2
|
|
||||||
|
|
||||||
**Quick Menu Enhancements**
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
- **Screen Rotation Toggle**: Quick toggle between Portrait and Landscape CCW directly from the quick menu
|
|
||||||
- Automatically reindexes content for new screen dimensions
|
|
||||||
- Preserves reading position via content offset restoration
|
|
||||||
- **Customizable Menu Order**: Reorder quick menu items to your preference
|
|
||||||
- New "Edit List Order" option at bottom of menu
|
|
||||||
- Pick-and-place reordering: select item, navigate to destination, place
|
|
||||||
- Order persists across sessions
|
|
||||||
|
|
||||||
### UI Improvements
|
|
||||||
|
|
||||||
- Added navigation button hints to quick menu (prev/next on front buttons, up/down on side buttons)
|
|
||||||
- Fixed orientation-aware margins for button hint areas in landscape modes
|
|
||||||
- New default menu order: Bookmark, Dictionary, Rotate Screen, Settings, Clear Cache
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.1
|
|
||||||
|
|
||||||
**Dictionary Stability & UX Improvements**
|
|
||||||
|
|
||||||
### Bug Fixes - Stability
|
|
||||||
|
|
||||||
- Fixed dictionary crashes caused by heap fragmentation from repeated page navigation
|
|
||||||
- Refactored TextBlock/ParsedText from `std::list` to `std::vector`, reducing heap allocations by ~12x per TextBlock
|
|
||||||
- Affects EPUB reader page rendering, dictionary definition display, and word selection
|
|
||||||
- Contiguous memory improves cache locality during text layout and reduces heap fragmentation on the memory-constrained ESP32
|
|
||||||
- Added uncompressed dictionary (`.dict`) support to avoid decompression memory issues with large dictzip chunks (58KB chunks -> direct read)
|
|
||||||
- Implemented chunked on-demand HTML parsing for large definitions, parsing pages as user navigates rather than all at once
|
|
||||||
- Limited cached pages to 4 with re-parse capability for backward navigation beyond cache window
|
|
||||||
- Fixed double-button press bug when loading new dictionary chunks
|
|
||||||
|
|
||||||
### Bug Fixes - UI/Layout
|
|
||||||
|
|
||||||
- Restored proper orientation-aware button hint spacing (front: 45px, side: 50px)
|
|
||||||
- Added side button hints to definition screen with "<" / ">" labels for page navigation
|
|
||||||
- Added side button hints to word selection screen ("UP"/"DOWN" labels, borderless, small font)
|
|
||||||
- Added side button hints to dictionary menu ("< Prev", "Next >")
|
|
||||||
- Moved page indicator up to avoid bezel cutoff in landscape orientations
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ef-1.0.0
|
|
||||||
|
|
||||||
**First Official Release** (previously ef-0.15.99)
|
|
||||||
|
|
||||||
First milestone release of the crosspoint-ef fork, building on CrossPoint Reader 0.15.0 with 14+ major new features and enhancements.
|
|
||||||
|
|
||||||
### New Features
|
|
||||||
|
|
||||||
- **Dictionary Support**: Offline StarDict dictionary with word selection from reader, fast prefix-indexed search, rich HTML formatting, and multi-page pagination
|
|
||||||
- **Bookmark System**: Per-book bookmarks with visual folded-corner indicators, dedicated management interface, and auto-generated bookmark names
|
|
||||||
- **Quick Menu**: In-reader quick access menu for common actions (Dictionary, Bookmark, Clear Cache, Settings) via short power button press
|
|
||||||
- **Library Search**: Search across all books by title, author, or filename with dynamic character picker and weighted relevance scoring
|
|
||||||
- **CSS Support**: Parse and apply CSS styles from EPUB stylesheets (text-align, font-style, font-weight, text-decoration, margins, padding)
|
|
||||||
- **Inline Image Support**: PNG and Baseline JPEG rendering within EPUB content with 2-bit grayscale dithering and caching
|
|
||||||
- **Custom Fonts**: Atkinson Hyperlegible Next (low-vision readers) and Fern Micro (small screens)
|
|
||||||
- **Enhanced Web Server**: File management (upload, download, delete, rename, copy, move, mkdir), companion app API, WebSocket uploads, mDNS discovery at `crosspoint.local`
|
|
||||||
- **Reading Lists**: Create, manage, and pin custom book lists with web API support (CSV format)
|
|
||||||
- **Enhanced Tab Bar**: Unified tab bar with horizontal scrolling and overflow indicators (Recent, Lists, Bookmarks, Search, Files)
|
|
||||||
- **Progress Bar Status**: Additional status bar option showing visual reading progress
|
|
||||||
- **OPDS Browser Enhancements**: Navigation history, page skipping (hold Up/Down), error retry, HTTP Basic Auth support
|
|
||||||
|
|
||||||
### Display Enhancements
|
|
||||||
|
|
||||||
- **High Contrast Mode**: System-wide contrast adjustment
|
|
||||||
- **Bezel Compensation**: Configurable margin (0-10px) for physical screen edge defects
|
|
||||||
- **Sleep Screen Improvements**: Edge-aware color filling for seamless letterbox appearance
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
- Fixed device hanging when booted without USB connected (Serial.available()/Serial.read() called without Serial.begin())
|
|
||||||
- Fixed grayscale state corruption causing ghosting artifacts when anti-aliasing enabled under memory pressure
|
|
||||||
- Memory optimization with graceful degradation when memory is low
|
|
||||||
|
|
||||||
### Development Tools
|
|
||||||
|
|
||||||
- `pre_flash.py`: Displays "Flashing firmware..." screen during upload
|
|
||||||
- `debugging_monitor.py`: Enhanced serial monitor with memory graphs
|
|
||||||
- `pio_helper.py`: Interactive PlatformIO workflow helper
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Differences from Upstream 0.16.0
|
|
||||||
|
|
||||||
This fork is based on upstream 0.15.0. The following 0.16.0 features are not included:
|
|
||||||
|
|
||||||
- KOReader sync support
|
|
||||||
- Non-English hyphenation patterns (Spanish, German, French, Russian)
|
|
||||||
- XTC/XTCH file format support
|
|
||||||
|
|
||||||
See [crosspoint-ef-features.md](docs/crosspoint-ef-features.md) for complete feature documentation.
|
|
||||||
@ -33,10 +33,23 @@
|
|||||||
#include <builtinFonts/notosans_18_bolditalic.h>
|
#include <builtinFonts/notosans_18_bolditalic.h>
|
||||||
#include <builtinFonts/notosans_18_italic.h>
|
#include <builtinFonts/notosans_18_italic.h>
|
||||||
#include <builtinFonts/notosans_18_regular.h>
|
#include <builtinFonts/notosans_18_regular.h>
|
||||||
|
#include <builtinFonts/opendyslexic_10_bold.h>
|
||||||
|
#include <builtinFonts/opendyslexic_10_bolditalic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_10_italic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_10_regular.h>
|
||||||
|
#include <builtinFonts/opendyslexic_12_bold.h>
|
||||||
|
#include <builtinFonts/opendyslexic_12_bolditalic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_12_italic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_12_regular.h>
|
||||||
|
#include <builtinFonts/opendyslexic_14_bold.h>
|
||||||
|
#include <builtinFonts/opendyslexic_14_bolditalic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_14_italic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_14_regular.h>
|
||||||
|
#include <builtinFonts/opendyslexic_8_bold.h>
|
||||||
|
#include <builtinFonts/opendyslexic_8_bolditalic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_8_italic.h>
|
||||||
|
#include <builtinFonts/opendyslexic_8_regular.h>
|
||||||
#include <builtinFonts/ubuntu_10_bold.h>
|
#include <builtinFonts/ubuntu_10_bold.h>
|
||||||
#include <builtinFonts/ubuntu_10_regular.h>
|
#include <builtinFonts/ubuntu_10_regular.h>
|
||||||
#include <builtinFonts/ubuntu_12_bold.h>
|
#include <builtinFonts/ubuntu_12_bold.h>
|
||||||
#include <builtinFonts/ubuntu_12_regular.h>
|
#include <builtinFonts/ubuntu_12_regular.h>
|
||||||
|
|
||||||
// Custom fonts registry (generated by convert-builtin-fonts.sh)
|
|
||||||
#include <builtinFonts/custom/customFonts.h>
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_12_bold
|
* name: bookerly_12_bold
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_12_bold 12 ../builtinFonts/source/Bookerly/Bookerly-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_12_bolditalic
|
* name: bookerly_12_bolditalic
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_12_bolditalic 12 ../builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_12_italic
|
* name: bookerly_12_italic
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_12_italic 12 ../builtinFonts/source/Bookerly/Bookerly-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_12_regular
|
* name: bookerly_12_regular
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_12_regular 12 ../builtinFonts/source/Bookerly/Bookerly-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_14_bold
|
* name: bookerly_14_bold
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_14_bold 14 ../builtinFonts/source/Bookerly/Bookerly-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_14_bolditalic
|
* name: bookerly_14_bolditalic
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_14_bolditalic 14 ../builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_14_italic
|
* name: bookerly_14_italic
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_14_italic 14 ../builtinFonts/source/Bookerly/Bookerly-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_14_regular
|
* name: bookerly_14_regular
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_14_regular 14 ../builtinFonts/source/Bookerly/Bookerly-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_16_bold
|
* name: bookerly_16_bold
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_16_bold 16 ../builtinFonts/source/Bookerly/Bookerly-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_16_bolditalic
|
* name: bookerly_16_bolditalic
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_16_bolditalic 16 ../builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_16_italic
|
* name: bookerly_16_italic
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_16_italic 16 ../builtinFonts/source/Bookerly/Bookerly-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_16_regular
|
* name: bookerly_16_regular
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_16_regular 16 ../builtinFonts/source/Bookerly/Bookerly-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_18_bold
|
* name: bookerly_18_bold
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_18_bold 18 ../builtinFonts/source/Bookerly/Bookerly-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_18_bolditalic
|
* name: bookerly_18_bolditalic
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_18_bolditalic 18 ../builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_18_italic
|
* name: bookerly_18_italic
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_18_italic 18 ../builtinFonts/source/Bookerly/Bookerly-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: bookerly_18_regular
|
* name: bookerly_18_regular
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py bookerly_18_regular 18 ../builtinFonts/source/Bookerly/Bookerly-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,99 +0,0 @@
|
|||||||
/**
|
|
||||||
* Generated by convert-builtin-fonts.sh
|
|
||||||
* Registry of available custom fonts
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <EpdFont.h>
|
|
||||||
#include <EpdFontFamily.h>
|
|
||||||
|
|
||||||
class GfxRenderer;
|
|
||||||
|
|
||||||
#define CUSTOM_FONT_COUNT 2
|
|
||||||
|
|
||||||
static const char* CUSTOM_FONT_NAMES[] = {
|
|
||||||
"AtkinsonHyperlegibleNext",
|
|
||||||
"FernMicro"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Include all custom font headers
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_12_regular.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_12_italic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_12_bold.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_12_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_14_regular.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_14_italic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_14_bold.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_14_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_16_regular.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_16_italic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_16_bold.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_16_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_18_regular.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_18_italic.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_18_bold.h>
|
|
||||||
#include <builtinFonts/custom/atkinsonhyperlegiblenext_18_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_12_regular.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_12_italic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_12_bold.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_12_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_14_regular.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_14_italic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_14_bold.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_14_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_16_regular.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_16_italic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_16_bold.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_16_bolditalic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_18_regular.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_18_italic.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_18_bold.h>
|
|
||||||
#include <builtinFonts/custom/fernmicro_18_bolditalic.h>
|
|
||||||
|
|
||||||
// Extern EpdFont declarations for custom fonts
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext12RegularFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext12ItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext12BoldFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext12BoldItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext14RegularFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext14ItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext14BoldFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext14BoldItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext16RegularFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext16ItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext16BoldFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext16BoldItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext18RegularFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext18ItalicFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext18BoldFont;
|
|
||||||
extern EpdFont atkinsonhyperlegiblenext18BoldItalicFont;
|
|
||||||
extern EpdFont fernmicro12RegularFont;
|
|
||||||
extern EpdFont fernmicro12ItalicFont;
|
|
||||||
extern EpdFont fernmicro12BoldFont;
|
|
||||||
extern EpdFont fernmicro12BoldItalicFont;
|
|
||||||
extern EpdFont fernmicro14RegularFont;
|
|
||||||
extern EpdFont fernmicro14ItalicFont;
|
|
||||||
extern EpdFont fernmicro14BoldFont;
|
|
||||||
extern EpdFont fernmicro14BoldItalicFont;
|
|
||||||
extern EpdFont fernmicro16RegularFont;
|
|
||||||
extern EpdFont fernmicro16ItalicFont;
|
|
||||||
extern EpdFont fernmicro16BoldFont;
|
|
||||||
extern EpdFont fernmicro16BoldItalicFont;
|
|
||||||
extern EpdFont fernmicro18RegularFont;
|
|
||||||
extern EpdFont fernmicro18ItalicFont;
|
|
||||||
extern EpdFont fernmicro18BoldFont;
|
|
||||||
extern EpdFont fernmicro18BoldItalicFont;
|
|
||||||
|
|
||||||
// Extern EpdFontFamily declarations for custom fonts
|
|
||||||
extern EpdFontFamily atkinsonhyperlegiblenext12FontFamily;
|
|
||||||
extern EpdFontFamily atkinsonhyperlegiblenext14FontFamily;
|
|
||||||
extern EpdFontFamily atkinsonhyperlegiblenext16FontFamily;
|
|
||||||
extern EpdFontFamily atkinsonhyperlegiblenext18FontFamily;
|
|
||||||
extern EpdFontFamily fernmicro12FontFamily;
|
|
||||||
extern EpdFontFamily fernmicro14FontFamily;
|
|
||||||
extern EpdFontFamily fernmicro16FontFamily;
|
|
||||||
extern EpdFontFamily fernmicro18FontFamily;
|
|
||||||
|
|
||||||
// Function to register all custom fonts with the renderer
|
|
||||||
void registerCustomFonts(GfxRenderer& renderer);
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_12_bold
|
* name: notosans_12_bold
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_12_bold 12 ../builtinFonts/source/NotoSans/NotoSans-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_12_bolditalic
|
* name: notosans_12_bolditalic
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_12_bolditalic 12 ../builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_12_italic
|
* name: notosans_12_italic
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_12_italic 12 ../builtinFonts/source/NotoSans/NotoSans-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_12_regular
|
* name: notosans_12_regular
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_12_regular 12 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_14_bold
|
* name: notosans_14_bold
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_14_bold 14 ../builtinFonts/source/NotoSans/NotoSans-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_14_bolditalic
|
* name: notosans_14_bolditalic
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_14_bolditalic 14 ../builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_14_italic
|
* name: notosans_14_italic
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_14_italic 14 ../builtinFonts/source/NotoSans/NotoSans-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_14_regular
|
* name: notosans_14_regular
|
||||||
* size: 14
|
* size: 14
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_14_regular 14 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_16_bold
|
* name: notosans_16_bold
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_16_bold 16 ../builtinFonts/source/NotoSans/NotoSans-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_16_bolditalic
|
* name: notosans_16_bolditalic
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_16_bolditalic 16 ../builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_16_italic
|
* name: notosans_16_italic
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_16_italic 16 ../builtinFonts/source/NotoSans/NotoSans-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_16_regular
|
* name: notosans_16_regular
|
||||||
* size: 16
|
* size: 16
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_16_regular 16 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_18_bold
|
* name: notosans_18_bold
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_18_bold 18 ../builtinFonts/source/NotoSans/NotoSans-Bold.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_18_bolditalic
|
* name: notosans_18_bolditalic
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_18_bolditalic 18 ../builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_18_italic
|
* name: notosans_18_italic
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_18_italic 18 ../builtinFonts/source/NotoSans/NotoSans-Italic.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_18_regular
|
* name: notosans_18_regular
|
||||||
* size: 18
|
* size: 18
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py notosans_18_regular 18 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: notosans_8_regular
|
* name: notosans_8_regular
|
||||||
* size: 8
|
* size: 8
|
||||||
* mode: 1-bit
|
* mode: 1-bit
|
||||||
* Command used: fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_10_bold
|
* name: opendyslexic_10_bold
|
||||||
* size: 10
|
* size: 10
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_10_bold 10 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-Bold.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_10_bolditalic
|
* name: opendyslexic_10_bolditalic
|
||||||
* size: 10
|
* size: 10
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_10_bolditalic 10 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-BoldItalic.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_10_italic
|
* name: opendyslexic_10_italic
|
||||||
* size: 10
|
* size: 10
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_10_italic 10 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-Italic.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_10_regular
|
* name: opendyslexic_10_regular
|
||||||
* size: 10
|
* size: 10
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_10_regular 10 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-Regular.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_12_bold
|
* name: opendyslexic_12_bold
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_12_bold 12 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-Bold.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
* name: opendyslexic_12_bolditalic
|
* name: opendyslexic_12_bolditalic
|
||||||
* size: 12
|
* size: 12
|
||||||
* mode: 2-bit
|
* mode: 2-bit
|
||||||
* Command used: fontconvert.py opendyslexic_12_bolditalic 12 ../builtinFonts/source/OpenDyslexic/OpenDyslexic-BoldItalic.otf --2bit
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "EpdFontData.h"
|
#include "EpdFontData.h"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user