You've already forked crosspoint-reader
mirror of
https://github.com/crosspoint-reader/crosspoint-reader.git
synced 2026-04-29 10:26:52 -07:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ebcd813ff6 | |||
| 712c566664 | |||
| 5894ae5afe | |||
| 8c1c80787a | |||
| 140fcb9db5 | |||
| e0b6b9b28a | |||
| 83315b6179 | |||
| 8e0d2bece2 | |||
| 4848a77e1b | |||
| 49190cca6d | |||
| e9c2fe1c87 | |||
| dd1741bf0b | |||
| 51c5c3c0aa | |||
| 5e24895f6d | |||
| e2ca0e94ca | |||
| a4b9a43ca1 | |||
| c73fca26f5 | |||
| dfd7b615dc | |||
| aca6dceaa8 | |||
| 6ca75c4653 | |||
| 1b9c8ab545 | |||
| bf6cf83577 | |||
| 3a761b18af | |||
| 13f0ebed96 | |||
| 0bc0baa966 | |||
| 5d369df6be | |||
| b8ebcf5867 | |||
| e858ebbe88 | |||
| 9224bc3f8c | |||
| 67a679ab41 | |||
| 7a53342f9d | |||
| 3ce11f14ce | |||
| 47ef92e8fd | |||
| e3d6e32609 | |||
| d399afb53d | |||
| 838993259d | |||
| cc74039cab | |||
| 87d6c032a5 | |||
| c9b5462370 | |||
| e548bfc0e1 | |||
| 73c30748d8 | |||
| 6d68466891 | |||
| 8824c87490 | |||
| 5fef99c641 | |||
| 7a792a5384 | |||
| f69cddf2cc | |||
| 7185e5d287 | |||
| 12940cc546 | |||
| 21277e03eb | |||
| 4eef2b5793 | |||
| 5a55fa1c6e | |||
| c98ba142e8 | |||
| c1c94c0112 | |||
| eb84bcee7c | |||
| d45f355e87 |
@@ -4,3 +4,8 @@
|
||||
.vscode
|
||||
lib/EpdFont/fontsrc
|
||||
*.generated.h
|
||||
.vs
|
||||
build
|
||||
**/__pycache__/
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
|
||||
@@ -41,7 +41,9 @@ This project is **not affiliated with Xteink**; it's built as a community projec
|
||||
- [ ] Full UTF support
|
||||
- [x] Screen rotation
|
||||
|
||||
See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint.
|
||||
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.
|
||||
|
||||
## Installing
|
||||
|
||||
|
||||
+55
-1
@@ -2,6 +2,27 @@
|
||||
|
||||
Welcome to the **CrossPoint** firmware. This guide outlines the hardware controls, navigation, and reading features of the device.
|
||||
|
||||
- [CrossPoint User Guide](#crosspoint-user-guide)
|
||||
- [1. Hardware Overview](#1-hardware-overview)
|
||||
- [Button Layout](#button-layout)
|
||||
- [2. Power \& Startup](#2-power--startup)
|
||||
- [Power On / Off](#power-on--off)
|
||||
- [First Launch](#first-launch)
|
||||
- [3. Screens](#3-screens)
|
||||
- [3.1 Home Screen](#31-home-screen)
|
||||
- [3.2 Book Selection](#32-book-selection)
|
||||
- [3.3 Reading Mode](#33-reading-mode)
|
||||
- [3.4 File Upload Screen](#34-file-upload-screen)
|
||||
- [3.5 Settings](#35-settings)
|
||||
- [3.6 Sleep Screen](#36-sleep-screen)
|
||||
- [4. Reading Mode](#4-reading-mode)
|
||||
- [Page Turning](#page-turning)
|
||||
- [Chapter Navigation](#chapter-navigation)
|
||||
- [System Navigation](#system-navigation)
|
||||
- [5. Chapter Selection Screen](#5-chapter-selection-screen)
|
||||
- [6. Current Limitations \& Roadmap](#6-current-limitations--roadmap)
|
||||
|
||||
|
||||
## 1. Hardware Overview
|
||||
|
||||
The device utilises the standard buttons on the Xtink X4 (in the same layout as the manufacturer firmware, by default):
|
||||
@@ -60,6 +81,18 @@ See the [webserver docs](./docs/webserver.md) for more information on how to con
|
||||
> [!TIP]
|
||||
> 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
|
||||
|
||||
The Settings screen allows you to configure the device's behavior. There are a few settings you can adjust:
|
||||
@@ -72,6 +105,10 @@ 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:
|
||||
- "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)
|
||||
- **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:
|
||||
- "None" - No status bar
|
||||
- "No Progress" - Show status bar without reading progress
|
||||
@@ -95,7 +132,12 @@ The Settings screen allows you to configure the device's behavior. There are a f
|
||||
- Back, Confirm, Left, Right (default)
|
||||
- Left, Right, Back, Confirm
|
||||
- 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.
|
||||
- **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
|
||||
- "Page Scroll" - Long-pressing scrolls a page up/down
|
||||
- Swap the order of the up and down volume buttons from Previous/Next to Next/Previous. This change is only in effect when reading.
|
||||
- **Reader Font Family**: Choose the font used for reading:
|
||||
- "Bookerly" (default) - Amazon's reading font
|
||||
- "Noto Sans" - Google's sans-serif font
|
||||
@@ -106,7 +148,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".
|
||||
- **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.
|
||||
- **Calibre Settings**: Set up integration for accessing a Calibre web library or connecting to Calibre as a wireless device.
|
||||
- **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.
|
||||
- **Check for updates**: Check for firmware updates over WiFi.
|
||||
|
||||
### 3.6 Sleep Screen
|
||||
@@ -144,11 +186,23 @@ If the **Short Power Button Click** setting is set to "Page Turn", you can also
|
||||
* **Next Chapter:** Press and **hold** the **Right** (or **Volume Down**) button briefly, then release.
|
||||
* **Previous Chapter:** Press and **hold** the **Left** (or **Volume Up**) button briefly, then release.
|
||||
|
||||
This feature can be disabled in **[Settings](#35-settings)** to help avoid changing chapters by mistake.
|
||||
|
||||
|
||||
### System Navigation
|
||||
* **Return to Book Selection:** Press **Back** to close the book and return to the **[Book Selection](#32-book-selection)** 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)**.
|
||||
|
||||
### 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
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Hypher Binary Tries
|
||||
|
||||
CrossPoint embeds the exact binary automata produced by
|
||||
[Typst's `hypher`](https://github.com/typst/hypher).
|
||||
|
||||
## File layout
|
||||
|
||||
Each `.bin` blob is a single self-contained automaton:
|
||||
|
||||
```
|
||||
uint32_t root_addr_be; // big-endian offset of the root node
|
||||
uint8_t levels[]; // shared "levels" tape (dist/score pairs)
|
||||
uint8_t nodes[]; // node records packed back-to-back
|
||||
```
|
||||
|
||||
The size of the `levels` tape is implicit. Individual nodes reference slices
|
||||
inside that tape via 12-bit offsets, so no additional pointers are required.
|
||||
|
||||
### Node encoding
|
||||
|
||||
Every node starts with a single control byte:
|
||||
|
||||
- Bit 7 – set when the node stores scores (`levels`).
|
||||
- Bits 5-6 – stride of the target deltas (1, 2, or 3 bytes, big-endian).
|
||||
- Bits 0-4 – transition count (values ≥ 31 spill into an extra byte).
|
||||
|
||||
If the `levels` flag is set, two more bytes follow. Together they encode a
|
||||
12-bit offset into the global `levels` tape and a 4-bit length. Each byte in the
|
||||
levels tape packs a distance/score pair as `dist * 10 + score`, where `dist`
|
||||
counts how many UTF-8 bytes we advanced since the previous digit.
|
||||
|
||||
After the optional levels header come the transition labels (one byte per edge)
|
||||
followed by the signed target deltas. Targets are stored as relative offsets
|
||||
from the current node address. Deltas up to ±128 fit in a single byte, larger
|
||||
distances grow to 2 or 3 bytes. The runtime walks the transitions with a simple
|
||||
linear scan and materializes the absolute address by adding the decoded delta
|
||||
to the current node’s base.
|
||||
|
||||
## Embedding blobs into the firmware
|
||||
|
||||
The helper script `scripts/generate_hyphenation_trie.py` acts as a thin
|
||||
wrapper: it reads the hypher-generated `.bin` files, formats them as `constexpr`
|
||||
byte arrays, and emits headers under
|
||||
`lib/Epub/Epub/hyphenation/generated/`. Each header defines the raw data plus a
|
||||
`SerializedHyphenationPatterns` descriptor so the reader can keep the automaton
|
||||
in flash.
|
||||
|
||||
To refresh the firmware assets after updating the `.bin` files, run:
|
||||
|
||||
```
|
||||
./scripts/generate_hyphenation_trie.py \
|
||||
--input lib/Epub/Epub/hyphenation/tries/en.bin \
|
||||
--output lib/Epub/Epub/hyphenation/generated/hyph-en.trie.h
|
||||
|
||||
./scripts/generate_hyphenation_trie.py \
|
||||
--input lib/Epub/Epub/hyphenation/tries/fr.bin \
|
||||
--output lib/Epub/Epub/hyphenation/generated/hyph-fr.trie.h
|
||||
|
||||
./scripts/generate_hyphenation_trie.py \
|
||||
--input lib/Epub/Epub/hyphenation/tries/de.bin \
|
||||
--output lib/Epub/Epub/hyphenation/generated/hyph-de.trie.h
|
||||
|
||||
./scripts/generate_hyphenation_trie.py \
|
||||
--input lib/Epub/Epub/hyphenation/tries/ru.bin \
|
||||
--output lib/Epub/Epub/hyphenation/generated/hyph-ru.trie.h
|
||||
```
|
||||
@@ -0,0 +1,57 @@
|
||||
# Troubleshooting
|
||||
|
||||
This document show most common issues and possible solutions while using the device features.
|
||||
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Cannot See the Device on the Network](#cannot-see-the-device-on-the-network)
|
||||
- [Connection Drops or Times Out](#connection-drops-or-times-out)
|
||||
- [Upload Fails](#upload-fails)
|
||||
- [Saved Password Not Working](#saved-password-not-working)
|
||||
|
||||
### Cannot See the Device on the Network
|
||||
|
||||
**Problem:** Browser shows "Cannot connect" or "Site can't be reached"
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Verify both devices are on the **same WiFi network**
|
||||
- Check your computer/phone WiFi settings
|
||||
- Confirm the CrossPoint Reader shows "Connected" status
|
||||
2. Double-check the IP address
|
||||
- Make sure you typed it correctly
|
||||
- Include `http://` at the beginning
|
||||
3. Try disabling VPN if you're using one
|
||||
4. Some networks have "client isolation" enabled - check with your network administrator
|
||||
|
||||
### Connection Drops or Times Out
|
||||
|
||||
**Problem:** WiFi connection is unstable
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Move closer to the WiFi router
|
||||
2. Check signal strength on the device (should be at least `||` or better)
|
||||
3. Avoid interference from other devices
|
||||
4. Try a different WiFi network if available
|
||||
|
||||
### Upload Fails
|
||||
|
||||
**Problem:** File upload doesn't complete or shows an error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Ensure the file is a valid `.epub` file
|
||||
2. Check that the SD card has enough free space
|
||||
3. Try uploading a smaller file first to test
|
||||
4. Refresh the browser page and try again
|
||||
|
||||
### Saved Password Not Working
|
||||
|
||||
**Problem:** Device fails to connect with saved credentials
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. When connection fails, you'll be prompted to "Forget Network"
|
||||
2. Select **Yes** to remove the saved password
|
||||
3. Reconnect and enter the password again
|
||||
4. Choose to save the new password
|
||||
@@ -0,0 +1,331 @@
|
||||
# Webserver Endpoints
|
||||
|
||||
This document describes all HTTP and WebSocket endpoints available on the CrossPoint Reader webserver.
|
||||
|
||||
- [Webserver Endpoints](#webserver-endpoints)
|
||||
- [Overview](#overview)
|
||||
- [HTTP Endpoints](#http-endpoints)
|
||||
- [GET `/` - Home Page](#get----home-page)
|
||||
- [GET `/files` - File Browser Page](#get-files---file-browser-page)
|
||||
- [GET `/api/status` - Device Status](#get-apistatus---device-status)
|
||||
- [GET `/api/files` - List Files](#get-apifiles---list-files)
|
||||
- [POST `/upload` - Upload File](#post-upload---upload-file)
|
||||
- [POST `/mkdir` - Create Folder](#post-mkdir---create-folder)
|
||||
- [POST `/delete` - Delete File or Folder](#post-delete---delete-file-or-folder)
|
||||
- [WebSocket Endpoint](#websocket-endpoint)
|
||||
- [Port 81 - Fast Binary Upload](#port-81---fast-binary-upload)
|
||||
- [Network Modes](#network-modes)
|
||||
- [Station Mode (STA)](#station-mode-sta)
|
||||
- [Access Point Mode (AP)](#access-point-mode-ap)
|
||||
- [Notes](#notes)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
The CrossPoint Reader exposes a webserver for file management and device monitoring:
|
||||
|
||||
- **HTTP Server**: Port 80
|
||||
- **WebSocket Server**: Port 81 (for fast binary uploads)
|
||||
|
||||
---
|
||||
|
||||
## HTTP Endpoints
|
||||
|
||||
### GET `/` - Home Page
|
||||
|
||||
Serves the home page HTML interface.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
curl http://crosspoint.local/
|
||||
```
|
||||
|
||||
**Response:** HTML page (200 OK)
|
||||
|
||||
---
|
||||
|
||||
### GET `/files` - File Browser Page
|
||||
|
||||
Serves the file browser HTML interface.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
curl http://crosspoint.local/files
|
||||
```
|
||||
|
||||
**Response:** HTML page (200 OK)
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/status` - Device Status
|
||||
|
||||
Returns JSON with device status information.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
curl http://crosspoint.local/api/status
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"ip": "192.168.1.100",
|
||||
"mode": "STA",
|
||||
"rssi": -45,
|
||||
"freeHeap": 123456,
|
||||
"uptime": 3600
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
| ---------- | ------ | --------------------------------------------------------- |
|
||||
| `version` | string | CrossPoint firmware version |
|
||||
| `ip` | string | Device IP address |
|
||||
| `mode` | string | `"STA"` (connected to WiFi) or `"AP"` (access point mode) |
|
||||
| `rssi` | number | WiFi signal strength in dBm (0 in AP mode) |
|
||||
| `freeHeap` | number | Free heap memory in bytes |
|
||||
| `uptime` | number | Seconds since device boot |
|
||||
|
||||
---
|
||||
|
||||
### GET `/api/files` - List Files
|
||||
|
||||
Returns a JSON array of files and folders in the specified directory.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
# List root directory
|
||||
curl http://crosspoint.local/api/files
|
||||
|
||||
# List specific directory
|
||||
curl "http://crosspoint.local/api/files?path=/Books"
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
| Parameter | Required | Default | Description |
|
||||
| --------- | -------- | ------- | ---------------------- |
|
||||
| `path` | No | `/` | Directory path to list |
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
[
|
||||
{"name": "MyBook.epub", "size": 1234567, "isDirectory": false, "isEpub": true},
|
||||
{"name": "Notes", "size": 0, "isDirectory": true, "isEpub": false},
|
||||
{"name": "document.pdf", "size": 54321, "isDirectory": false, "isEpub": false}
|
||||
]
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
| ------------- | ------- | ---------------------------------------- |
|
||||
| `name` | string | File or folder name |
|
||||
| `size` | number | Size in bytes (0 for directories) |
|
||||
| `isDirectory` | boolean | `true` if the item is a folder |
|
||||
| `isEpub` | boolean | `true` if the file has `.epub` extension |
|
||||
|
||||
**Notes:**
|
||||
- Hidden files (starting with `.`) are automatically filtered out
|
||||
- System folders (`System Volume Information`, `XTCache`) are hidden
|
||||
|
||||
---
|
||||
|
||||
### POST `/upload` - Upload File
|
||||
|
||||
Uploads a file to the SD card via multipart form data.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
# Upload to root directory
|
||||
curl -X POST -F "file=@mybook.epub" http://crosspoint.local/upload
|
||||
|
||||
# Upload to specific directory
|
||||
curl -X POST -F "file=@mybook.epub" "http://crosspoint.local/upload?path=/Books"
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
| Parameter | Required | Default | Description |
|
||||
| --------- | -------- | ------- | ------------------------------- |
|
||||
| `path` | No | `/` | Target directory for the upload |
|
||||
|
||||
**Response (200 OK):**
|
||||
```
|
||||
File uploaded successfully: mybook.epub
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
| Status | Body | Cause |
|
||||
| ------ | ----------------------------------------------- | --------------------------- |
|
||||
| 400 | `Failed to create file on SD card` | Cannot create file |
|
||||
| 400 | `Failed to write to SD card - disk may be full` | Write error during upload |
|
||||
| 400 | `Failed to write final data to SD card` | Error flushing final buffer |
|
||||
| 400 | `Upload aborted` | Client aborted the upload |
|
||||
| 400 | `Unknown error during upload` | Unspecified error |
|
||||
|
||||
**Notes:**
|
||||
- Existing files with the same name will be overwritten
|
||||
- Uses a 4KB buffer for efficient SD card writes
|
||||
|
||||
---
|
||||
|
||||
### POST `/mkdir` - Create Folder
|
||||
|
||||
Creates a new folder on the SD card.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
curl -X POST -d "name=NewFolder&path=/" http://crosspoint.local/mkdir
|
||||
```
|
||||
|
||||
**Form Parameters:**
|
||||
|
||||
| Parameter | Required | Default | Description |
|
||||
| --------- | -------- | ------- | ---------------------------- |
|
||||
| `name` | Yes | - | Name of the folder to create |
|
||||
| `path` | No | `/` | Parent directory path |
|
||||
|
||||
**Response (200 OK):**
|
||||
```
|
||||
Folder created: NewFolder
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
| Status | Body | Cause |
|
||||
| ------ | ----------------------------- | ----------------------------- |
|
||||
| 400 | `Missing folder name` | `name` parameter not provided |
|
||||
| 400 | `Folder name cannot be empty` | Empty folder name |
|
||||
| 400 | `Folder already exists` | Folder with same name exists |
|
||||
| 500 | `Failed to create folder` | SD card error |
|
||||
|
||||
---
|
||||
|
||||
### POST `/delete` - Delete File or Folder
|
||||
|
||||
Deletes a file or folder from the SD card.
|
||||
|
||||
**Request:**
|
||||
```bash
|
||||
# Delete a file
|
||||
curl -X POST -d "path=/Books/mybook.epub&type=file" http://crosspoint.local/delete
|
||||
|
||||
# Delete an empty folder
|
||||
curl -X POST -d "path=/OldFolder&type=folder" http://crosspoint.local/delete
|
||||
```
|
||||
|
||||
**Form Parameters:**
|
||||
|
||||
| Parameter | Required | Default | Description |
|
||||
| --------- | -------- | ------- | -------------------------------- |
|
||||
| `path` | Yes | - | Path to the item to delete |
|
||||
| `type` | No | `file` | Type of item: `file` or `folder` |
|
||||
|
||||
**Response (200 OK):**
|
||||
```
|
||||
Deleted successfully
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
| Status | Body | Cause |
|
||||
| ------ | --------------------------------------------- | ----------------------------- |
|
||||
| 400 | `Missing path` | `path` parameter not provided |
|
||||
| 400 | `Cannot delete root directory` | Attempted to delete `/` |
|
||||
| 400 | `Folder is not empty. Delete contents first.` | Non-empty folder |
|
||||
| 403 | `Cannot delete system files` | Hidden file (starts with `.`) |
|
||||
| 403 | `Cannot delete protected items` | Protected system folder |
|
||||
| 404 | `Item not found` | Path does not exist |
|
||||
| 500 | `Failed to delete item` | SD card error |
|
||||
|
||||
**Protected Items:**
|
||||
- Files/folders starting with `.`
|
||||
- `System Volume Information`
|
||||
- `XTCache`
|
||||
|
||||
---
|
||||
|
||||
## WebSocket Endpoint
|
||||
|
||||
### Port 81 - Fast Binary Upload
|
||||
|
||||
A WebSocket endpoint for high-speed binary file uploads. More efficient than HTTP multipart for large files.
|
||||
|
||||
**Connection:**
|
||||
```
|
||||
ws://crosspoint.local:81/
|
||||
```
|
||||
|
||||
**Protocol:**
|
||||
|
||||
1. **Client** sends TEXT message: `START:<filename>:<size>:<path>`
|
||||
2. **Server** responds with TEXT: `READY`
|
||||
3. **Client** sends BINARY messages with file data chunks
|
||||
4. **Server** sends TEXT progress updates: `PROGRESS:<received>:<total>`
|
||||
5. **Server** sends TEXT when complete: `DONE` or `ERROR:<message>`
|
||||
|
||||
**Example Session:**
|
||||
|
||||
```
|
||||
Client -> "START:mybook.epub:1234567:/Books"
|
||||
Server -> "READY"
|
||||
Client -> [binary chunk 1]
|
||||
Client -> [binary chunk 2]
|
||||
Server -> "PROGRESS:65536:1234567"
|
||||
Client -> [binary chunk 3]
|
||||
...
|
||||
Server -> "PROGRESS:1234567:1234567"
|
||||
Server -> "DONE"
|
||||
```
|
||||
|
||||
**Error Messages:**
|
||||
|
||||
| Message | Cause |
|
||||
| --------------------------------- | ---------------------------------- |
|
||||
| `ERROR:Failed to create file` | Cannot create file on SD card |
|
||||
| `ERROR:Invalid START format` | Malformed START message |
|
||||
| `ERROR:No upload in progress` | Binary data received without START |
|
||||
| `ERROR:Write failed - disk full?` | SD card write error |
|
||||
|
||||
**Example with `websocat`:**
|
||||
```bash
|
||||
# Interactive session
|
||||
websocat ws://crosspoint.local:81
|
||||
|
||||
# Then type:
|
||||
START:mybook.epub:1234567:/Books
|
||||
# Wait for READY, then send binary data
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- Progress updates are sent every 64KB or at completion
|
||||
- Disconnection during upload will delete the incomplete file
|
||||
- Existing files with the same name will be overwritten
|
||||
|
||||
---
|
||||
|
||||
## Network Modes
|
||||
|
||||
The device can operate in two network modes:
|
||||
|
||||
### Station Mode (STA)
|
||||
- Device connects to an existing WiFi network
|
||||
- IP address assigned by router/DHCP
|
||||
- `mode` field in `/api/status` returns `"STA"`
|
||||
- `rssi` field shows signal strength
|
||||
|
||||
### Access Point Mode (AP)
|
||||
- Device creates its own WiFi hotspot
|
||||
- Default IP is typically `192.168.4.1`
|
||||
- `mode` field in `/api/status` returns `"AP"`
|
||||
- `rssi` field returns `0`
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- These examples use `crosspoint.local`. If your network does not support mDNS or the address does not resolve, replace it with the specific **IP Address** displayed on your device screen (e.g., `http://192.168.1.102/`).
|
||||
- All paths on the SD card start with `/`
|
||||
- Trailing slashes are automatically stripped (except for root `/`)
|
||||
- The webserver uses chunked transfer encoding for file listings
|
||||
+2
-83
@@ -172,89 +172,7 @@ This is useful for organizing your ebooks by genre, author, or series.
|
||||
|
||||
## Command Line File Management
|
||||
|
||||
For power users, you can manage files directly from your terminal using `curl` while the device is in File Upload mode.
|
||||
|
||||
### Uploading a File
|
||||
To upload a file to the root directory, use the following command:
|
||||
```bash
|
||||
curl -F "file=@book.epub" "http://crosspoint.local/upload?path=/"
|
||||
```
|
||||
|
||||
* **`-F "file=@filename"`**: Points to the local file on your computer.
|
||||
* **`path=/`**: The destination folder on the device SD card.
|
||||
|
||||
### Deleting a File
|
||||
|
||||
To delete a specific file, provide the full path on the SD card:
|
||||
|
||||
```bash
|
||||
curl -F "path=/folder/file.epub" "http://crosspoint.local/delete"
|
||||
```
|
||||
|
||||
### Advanced Flags
|
||||
|
||||
For more reliable transfers of large EPUB files, consider adding these flags:
|
||||
|
||||
* `-#`: Shows a simple progress bar.
|
||||
* `--connect-timeout 30`: Limits how long curl waits to establish a connection (in seconds).
|
||||
* `--max-time 300`: Sets a maximum duration for the entire transfer (5 minutes).
|
||||
|
||||
> [!NOTE]
|
||||
> These examples use `crosspoint.local`. If your network does not support mDNS or the address does not resolve, replace it with the specific **IP Address** displayed on your device screen (e.g., `http://192.168.1.102/`).
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Cannot See the Device on the Network
|
||||
|
||||
**Problem:** Browser shows "Cannot connect" or "Site can't be reached"
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Verify both devices are on the **same WiFi network**
|
||||
- Check your computer/phone WiFi settings
|
||||
- Confirm the CrossPoint Reader shows "Connected" status
|
||||
2. Double-check the IP address
|
||||
- Make sure you typed it correctly
|
||||
- Include `http://` at the beginning
|
||||
3. Try disabling VPN if you're using one
|
||||
4. Some networks have "client isolation" enabled - check with your network administrator
|
||||
|
||||
### Connection Drops or Times Out
|
||||
|
||||
**Problem:** WiFi connection is unstable
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Move closer to the WiFi router
|
||||
2. Check signal strength on the device (should be at least `||` or better)
|
||||
3. Avoid interference from other devices
|
||||
4. Try a different WiFi network if available
|
||||
|
||||
### Upload Fails
|
||||
|
||||
**Problem:** File upload doesn't complete or shows an error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. Ensure the file is a valid `.epub` file
|
||||
2. Check that the SD card has enough free space
|
||||
3. Try uploading a smaller file first to test
|
||||
4. Refresh the browser page and try again
|
||||
|
||||
### Saved Password Not Working
|
||||
|
||||
**Problem:** Device fails to connect with saved credentials
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. When connection fails, you'll be prompted to "Forget Network"
|
||||
2. Select **Yes** to remove the saved password
|
||||
3. Reconnect and enter the password again
|
||||
4. Choose to save the new password
|
||||
|
||||
---
|
||||
For power users, you can manage files directly from your terminal using `curl` while the device is in File Upload mode a detailed documentation can be found [here](./webserver-endpoints.md).
|
||||
|
||||
## Security Notes
|
||||
|
||||
@@ -303,4 +221,5 @@ Your uploaded files will be immediately available in the file browser!
|
||||
## Related Documentation
|
||||
|
||||
- [User Guide](../USER_GUIDE.md) - General device operation
|
||||
- [Troubleshooting](./troubleshooting.md) - Troubleshooting
|
||||
- [README](../README.md) - Project overview and features
|
||||
|
||||
@@ -22,8 +22,7 @@ void EpdFont::getTextBounds(const char* string, const int startX, const int star
|
||||
const EpdGlyph* glyph = getGlyph(cp);
|
||||
|
||||
if (!glyph) {
|
||||
// TODO: Replace with fallback glyph property?
|
||||
glyph = getGlyph('?');
|
||||
glyph = getGlyph(REPLACEMENT_GLYPH);
|
||||
}
|
||||
|
||||
if (!glyph) {
|
||||
|
||||
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,11 +3,12 @@
|
||||
* name: bookerly_14_italic
|
||||
* size: 14
|
||||
* mode: 2-bit
|
||||
* Command used: fontconvert.py bookerly_14_italic 14 ../builtinFonts/source/Bookerly/Bookerly-Italic.ttf --2bit
|
||||
*/
|
||||
#pragma once
|
||||
#include "EpdFontData.h"
|
||||
|
||||
static const uint8_t bookerly_14_italicBitmaps[64856] = {
|
||||
static const uint8_t bookerly_14_italicBitmaps[65749] = {
|
||||
0x00, 0x05, 0x00, 0x0F, 0x80, 0x0B, 0xD0, 0x03, 0xF0, 0x00, 0xF8, 0x00, 0x7D, 0x00, 0x2F, 0x00,
|
||||
0x0F, 0x80, 0x03, 0xD0, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x1E, 0x00, 0x0B, 0x40, 0x02, 0xC0, 0x00,
|
||||
0xF0, 0x00, 0x3C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x3F, 0x40, 0x0F,
|
||||
@@ -3681,7 +3682,51 @@ static const uint8_t bookerly_14_italicBitmaps[64856] = {
|
||||
0x00, 0x00, 0x00, 0x0E, 0x00, 0xD0, 0x2C, 0x03, 0x80, 0x7E, 0x0B, 0xC0, 0xFC, 0x1F, 0x42, 0xF4,
|
||||
0x3F, 0x07, 0xE0, 0xFD, 0x0F, 0xC2, 0xF8, 0x3F, 0x03, 0xF0, 0xBD, 0x0F, 0xC1, 0xF8, 0x2F, 0x43,
|
||||
0xE0, 0x7D, 0x0B, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x3D, 0x0B, 0xC0, 0xF4, 0x0F, 0x01, 0xE0, 0x3D,
|
||||
0x00, 0x40, 0x10, 0x02, 0x00, 0x10, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0, 0x07, 0xFF, 0xFF, 0xFD,
|
||||
0x00, 0x40, 0x10, 0x02, 0x00, 0x10, 0x00, 0x00, 0x2F, 0x80, 0x0B, 0xFF, 0xC0, 0xBD, 0x2F, 0x43,
|
||||
0xD0, 0x3E, 0x2E, 0x00, 0xB8, 0xF4, 0x03, 0xE7, 0xC0, 0x0F, 0x6E, 0x00, 0x3C, 0xB8, 0x01, 0xF2,
|
||||
0xE0, 0x0F, 0x4B, 0xC0, 0xBC, 0x1F, 0x9B, 0xC0, 0x2F, 0xFC, 0x00, 0x19, 0x40, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xB8, 0x00, 0x3C, 0xB4, 0x00, 0xF0, 0xF0,
|
||||
0x03, 0xD0, 0xF0, 0x0F, 0x41, 0xF0, 0x3F, 0xAB, 0xF9, 0x3F, 0xFF, 0xFD, 0x00, 0x03, 0xC0, 0x00,
|
||||
0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA4, 0x03, 0xFF, 0xE0, 0x1F, 0xAA,
|
||||
0x00, 0xB4, 0x00, 0x03, 0xD0, 0x00, 0x1F, 0xF8, 0x00, 0x06, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x03,
|
||||
0xC0, 0x00, 0x1F, 0x00, 0x01, 0xF4, 0x05, 0xBF, 0x80, 0xBF, 0xF4, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||
0x01, 0xB8, 0x00, 0x1F, 0xF9, 0x00, 0xFE, 0x00, 0x03, 0xF0, 0x00, 0x0B, 0xC0, 0x00, 0x0F, 0xFE,
|
||||
0x00, 0x2F, 0xAF, 0xD0, 0x3D, 0x02, 0xF0, 0x3C, 0x01, 0xF0, 0x3C, 0x01, 0xF0, 0x3D, 0x03, 0xD0,
|
||||
0x2F, 0x5F, 0xC0, 0x0B, 0xFE, 0x00, 0x01, 0x50, 0x00, 0x2A, 0xAA, 0x47, 0xFF, 0xFD, 0xB9, 0x5B,
|
||||
0xCF, 0x00, 0xF0, 0x50, 0x3D, 0x00, 0x0B, 0x80, 0x01, 0xF0, 0x00, 0x3D, 0x00, 0x0B, 0x80, 0x01,
|
||||
0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0x78, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2F, 0x80, 0x07,
|
||||
0xEF, 0xC0, 0x7C, 0x0F, 0x42, 0xD0, 0x3D, 0x0B, 0x81, 0xF0, 0x0F, 0xAF, 0x00, 0x2F, 0xF0, 0x03,
|
||||
0xD7, 0xE0, 0x3D, 0x07, 0xC1, 0xF0, 0x0F, 0x47, 0xC0, 0x3C, 0x0F, 0x87, 0xE0, 0x2F, 0xFE, 0x00,
|
||||
0x05, 0x40, 0x00, 0x00, 0x1F, 0x90, 0x00, 0xFF, 0xF8, 0x03, 0xE0, 0x7C, 0x07, 0xC0, 0x3D, 0x07,
|
||||
0x80, 0x2D, 0x0B, 0xC0, 0x3D, 0x07, 0xD0, 0x7C, 0x02, 0xFF, 0xFC, 0x00, 0x19, 0xF4, 0x00, 0x03,
|
||||
0xE0, 0x00, 0x1F, 0xC0, 0x01, 0xFE, 0x00, 0x3F, 0xF4, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0xFD, 0x2F, 0x81, 0xF7, 0xFE, 0x03, 0xE8, 0x78, 0x0F, 0xC2, 0xD0, 0x7C, 0x0F, 0x02, 0xE0, 0x3C,
|
||||
0x0F, 0x41, 0xE0, 0x3C, 0x0B, 0xB4, 0xF0, 0x3F, 0x81, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0xFF, 0x40, 0x3F, 0xBF, 0x03, 0xE0, 0x3D, 0x1F, 0x00, 0xF8, 0xF4, 0x02, 0xE3, 0xC0, 0x0F, 0x9F,
|
||||
0x00, 0x3D, 0xB8, 0x01, 0xF2, 0xE0, 0x0B, 0xCB, 0x80, 0x3D, 0x1F, 0x03, 0xE0, 0x3F, 0xFE, 0x00,
|
||||
0x7F, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x0F, 0xFD, 0x05, 0xBC, 0x00, 0x7C,
|
||||
0x00, 0xB8, 0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF0, 0x01, 0xF0, 0x02, 0xE0, 0x03, 0xD0, 0x2F, 0xFC,
|
||||
0x7F, 0xF8, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x40, 0x7F, 0xBF, 0x03, 0xE0, 0x3D, 0x0E, 0x00, 0xF4,
|
||||
0x00, 0x07, 0xC0, 0x00, 0x3D, 0x00, 0x07, 0xD0, 0x00, 0x7D, 0x00, 0x0B, 0xC0, 0x00, 0xF8, 0x00,
|
||||
0x0F, 0x80, 0x00, 0xFF, 0xFF, 0xD1, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x07, 0xEB,
|
||||
0xE0, 0xB0, 0x2E, 0x00, 0x02, 0xE0, 0x00, 0x7C, 0x00, 0x7F, 0x00, 0x3F, 0xF4, 0x01, 0x0B, 0xC0,
|
||||
0x00, 0x7C, 0x00, 0x0B, 0xC0, 0x02, 0xF4, 0x6B, 0xFD, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x02, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x1E, 0xB8, 0x00, 0x78,
|
||||
0xF4, 0x01, 0xF0, 0xF0, 0x07, 0xC0, 0xF0, 0x1F, 0x01, 0xE0, 0x3F, 0xFF, 0xFD, 0x2F, 0xFF, 0xFC,
|
||||
0x00, 0x03, 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x07, 0x40, 0x00, 0xFF, 0xF8, 0x03, 0xFF, 0xD0, 0x2E,
|
||||
0x00, 0x00, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x0B, 0xFD, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xF0, 0x00,
|
||||
0x03, 0xC0, 0x00, 0x2F, 0x00, 0x02, 0xF0, 0x1B, 0xFF, 0x00, 0x7F, 0xD0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x07, 0xFD, 0x00, 0x3F, 0x90, 0x01, 0xF8, 0x00, 0x03, 0xD0, 0x00, 0x0F,
|
||||
0x94, 0x00, 0x1F, 0xFF, 0x80, 0x2E, 0x57, 0xE0, 0x3C, 0x01, 0xF0, 0x3C, 0x01, 0xF0, 0x3C, 0x02,
|
||||
0xE0, 0x3E, 0x03, 0xD0, 0x1F, 0xFF, 0x80, 0x07, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xD7,
|
||||
0xFF, 0xFD, 0xB0, 0x0B, 0x8E, 0x01, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x40, 0x02, 0xE0, 0x00, 0x7C,
|
||||
0x00, 0x0F, 0x40, 0x02, 0xF0, 0x00, 0x3D, 0x00, 0x07, 0xC0, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0xFF, 0x40, 0x3E, 0x6F, 0x02, 0xE0, 0x3D, 0x0B, 0x40, 0xF0, 0x1F, 0x0B,
|
||||
0x80, 0x2F, 0xF4, 0x00, 0xFF, 0xC0, 0x1F, 0x0F, 0xC0, 0xF0, 0x0F, 0x47, 0x80, 0x3D, 0x1F, 0x01,
|
||||
0xF0, 0x3F, 0xAF, 0x40, 0x2F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7F, 0xF0,
|
||||
0x01, 0xFA, 0xFC, 0x03, 0xD0, 0x3C, 0x07, 0xC0, 0x3D, 0x0B, 0x80, 0x3D, 0x07, 0xC0, 0x3D, 0x03,
|
||||
0xF9, 0xBC, 0x00, 0xFF, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x07, 0xD0, 0x00, 0x2F, 0x40, 0x1B, 0xFD,
|
||||
0x00, 0x2F, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0, 0x07, 0xFF, 0xFF, 0xFD,
|
||||
0x00, 0x07, 0xE5, 0x57, 0xD0, 0x00, 0x7D, 0x00, 0x3C, 0x00, 0x0B, 0xC0, 0x03, 0xC0, 0x00, 0xFC,
|
||||
0x00, 0x10, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x95, 0x64, 0x00,
|
||||
0x02, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xAA, 0xA0, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x7D, 0x00,
|
||||
@@ -4061,7 +4106,19 @@ static const uint8_t bookerly_14_italicBitmaps[64856] = {
|
||||
0xFC, 0x00, 0x06, 0xAA, 0xBF, 0xAA, 0xA6, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0x80,
|
||||
0x0A, 0x43, 0xFC, 0x3F, 0xC2, 0xF8, 0x00, 0x00, 0x0A, 0x00, 0x01, 0xA0, 0x00, 0x29, 0x0F, 0xF0,
|
||||
0x01, 0xFD, 0x00, 0x2F, 0xC3, 0xFC, 0x00, 0xBF, 0x80, 0x0F, 0xF0, 0xFD, 0x00, 0x0F, 0xC0, 0x01,
|
||||
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
|
||||
0xE0, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x5B, 0xE0, 0x00, 0x00, 0x00, 0x02, 0xC0, 0x02, 0xE0, 0x00,
|
||||
0x00, 0x00, 0x2E, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x02, 0xFC, 0x69, 0x02, 0xE0, 0x00, 0x00, 0x2F,
|
||||
0xFF, 0xFF, 0x03, 0xE0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x0F, 0xE0, 0x00, 0x2F, 0xFF, 0xFF, 0xFC,
|
||||
0x2F, 0xE0, 0x02, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0x42, 0xFF, 0xE2,
|
||||
0xFF, 0xFF, 0xFE, 0x40, 0x0F, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x03, 0xFF, 0xFF,
|
||||
0x00, 0x2F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x0B, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xF0, 0xBF, 0xFF,
|
||||
0xF0, 0x00, 0x03, 0xFF, 0xD1, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x03, 0xFF, 0xEF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xF0,
|
||||
0x3F, 0x00, 0x00, 0x00, 0x00, 0x03, 0xD2, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const EpdGlyph bookerly_14_italicGlyphs[] = {
|
||||
@@ -4716,83 +4773,102 @@ static const EpdGlyph bookerly_14_italicGlyphs[] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 58775 }, //
|
||||
{ 0, 0, 0, 0, 0, 0, 58775 }, //
|
||||
{ 0, 0, 0, 0, 0, 0, 58775 }, //
|
||||
{ 18, 20, 18, 0, 20, 90, 58775 }, // ₣
|
||||
{ 19, 22, 18, -1, 21, 105, 58865 }, // ₤
|
||||
{ 35, 22, 36, 0, 21, 193, 58970 }, // ₧
|
||||
{ 20, 22, 18, -1, 21, 110, 59163 }, // €
|
||||
{ 17, 12, 29, 6, 16, 51, 59273 }, // ←
|
||||
{ 13, 20, 29, 8, 20, 65, 59324 }, // ↑
|
||||
{ 17, 12, 29, 6, 16, 51, 59389 }, // →
|
||||
{ 13, 20, 29, 8, 20, 65, 59440 }, // ↓
|
||||
{ 18, 12, 29, 5, 16, 54, 59505 }, // ↔
|
||||
{ 13, 20, 29, 8, 20, 65, 59559 }, // ↕
|
||||
{ 13, 20, 29, 8, 20, 65, 59624 }, // ↨
|
||||
{ 13, 20, 29, 8, 20, 65, 59689 }, // ↲
|
||||
{ 13, 20, 29, 8, 20, 65, 59754 }, // ↳
|
||||
{ 17, 14, 29, 6, 17, 60, 59819 }, // ↵
|
||||
{ 17, 14, 29, 6, 17, 60, 59879 }, // ⇐
|
||||
{ 13, 18, 29, 8, 19, 59, 59939 }, // ⇑
|
||||
{ 17, 14, 29, 6, 17, 60, 59998 }, // ⇒
|
||||
{ 13, 18, 29, 8, 19, 59, 60058 }, // ⇓
|
||||
{ 19, 14, 29, 5, 17, 67, 60117 }, // ⇔
|
||||
{ 19, 22, 29, 5, 21, 105, 60184 }, // ∀
|
||||
{ 14, 24, 18, 2, 23, 84, 60289 }, // ∂
|
||||
{ 13, 21, 29, 8, 21, 69, 60373 }, // ∃
|
||||
{ 23, 24, 29, 3, 22, 138, 60442 }, // ∅
|
||||
{ 19, 21, 19, 0, 21, 100, 60580 }, // ∆
|
||||
{ 19, 22, 29, 5, 21, 105, 60680 }, // ∇
|
||||
{ 19, 21, 29, 5, 21, 100, 60785 }, // ∈
|
||||
{ 19, 26, 29, 5, 23, 124, 60885 }, // ∉
|
||||
{ 19, 16, 29, 5, 18, 76, 61009 }, // ∊
|
||||
{ 19, 21, 29, 5, 21, 100, 61085 }, // ∋
|
||||
{ 19, 26, 29, 5, 23, 124, 61185 }, // ∌
|
||||
{ 19, 16, 29, 5, 18, 76, 61309 }, // ∍
|
||||
{ 22, 26, 23, 1, 21, 143, 61385 }, // ∏
|
||||
{ 18, 26, 18, 0, 21, 117, 61528 }, // ∑
|
||||
{ 13, 3, 18, 3, 11, 10, 61645 }, // −
|
||||
{ 17, 23, 14, -1, 21, 98, 61655 }, // ∕
|
||||
{ 11, 23, 14, 2, 21, 64, 61753 }, // ∖
|
||||
{ 14, 14, 18, 2, 17, 49, 61817 }, // ∗
|
||||
{ 10, 10, 18, 4, 15, 25, 61866 }, // ∘
|
||||
{ 6, 4, 18, 6, 10, 6, 61891 }, // ∙
|
||||
{ 18, 28, 18, 0, 24, 126, 61897 }, // √
|
||||
{ 14, 11, 18, 2, 15, 39, 62023 }, // ∝
|
||||
{ 18, 10, 18, 0, 14, 45, 62062 }, // ∞
|
||||
{ 19, 21, 29, 5, 21, 100, 62107 }, // ∟
|
||||
{ 21, 21, 29, 3, 21, 111, 62207 }, // ∠
|
||||
{ 4, 30, 15, 5, 23, 30, 62318 }, // ∣
|
||||
{ 9, 30, 15, 3, 23, 68, 62348 }, // ∥
|
||||
{ 19, 21, 29, 5, 21, 100, 62416 }, // ∧
|
||||
{ 19, 21, 29, 5, 21, 100, 62516 }, // ∨
|
||||
{ 17, 21, 29, 6, 21, 90, 62616 }, // ∩
|
||||
{ 17, 22, 29, 6, 21, 94, 62706 }, // ∪
|
||||
{ 16, 30, 18, 1, 23, 120, 62800 }, // ∫
|
||||
{ 19, 17, 29, 5, 16, 81, 62920 }, // ∴
|
||||
{ 19, 17, 29, 5, 16, 81, 63001 }, // ∵
|
||||
{ 6, 16, 9, 1, 18, 24, 63082 }, // ∶
|
||||
{ 19, 17, 29, 5, 16, 81, 63106 }, // ∷
|
||||
{ 17, 5, 29, 6, 11, 22, 63187 }, // ∼
|
||||
{ 17, 15, 29, 6, 17, 64, 63209 }, // ≅
|
||||
{ 14, 10, 18, 2, 15, 35, 63273 }, // ≈
|
||||
{ 17, 10, 29, 6, 13, 43, 63308 }, // ≍
|
||||
{ 13, 13, 18, 3, 16, 43, 63351 }, // ≠
|
||||
{ 17, 13, 29, 6, 15, 56, 63394 }, // ≡
|
||||
{ 14, 18, 18, 2, 18, 63, 63450 }, // ≤
|
||||
{ 14, 18, 18, 2, 18, 63, 63513 }, // ≥
|
||||
{ 23, 14, 29, 3, 17, 81, 63576 }, // ≪
|
||||
{ 23, 14, 29, 3, 17, 81, 63657 }, // ≫
|
||||
{ 19, 16, 29, 5, 18, 76, 63738 }, // ⊃
|
||||
{ 19, 26, 29, 5, 23, 124, 63814 }, // ⊄
|
||||
{ 19, 26, 29, 5, 23, 124, 63938 }, // ⊅
|
||||
{ 19, 21, 29, 5, 21, 100, 64062 }, // ⊆
|
||||
{ 19, 21, 29, 5, 21, 100, 64162 }, // ⊇
|
||||
{ 21, 22, 29, 4, 21, 116, 64262 }, // ⊕
|
||||
{ 21, 22, 29, 4, 21, 116, 64378 }, // ⊖
|
||||
{ 21, 22, 29, 4, 21, 116, 64494 }, // ⊗
|
||||
{ 21, 22, 29, 4, 21, 116, 64610 }, // ⊘
|
||||
{ 17, 21, 29, 6, 21, 90, 64726 }, // ⊥
|
||||
{ 6, 5, 18, 6, 10, 8, 64816 }, // ⋅
|
||||
{ 25, 5, 29, 2, 10, 32, 64824 }, // ⋯
|
||||
{ 11, 14, 13, 1, 24, 39, 58775 }, // ⁰
|
||||
{ 12, 14, 13, 0, 24, 42, 58814 }, // ⁴
|
||||
{ 11, 14, 13, 1, 24, 39, 58856 }, // ⁵
|
||||
{ 12, 14, 13, 1, 24, 42, 58895 }, // ⁶
|
||||
{ 10, 14, 13, 3, 24, 35, 58937 }, // ⁷
|
||||
{ 11, 14, 13, 1, 24, 39, 58972 }, // ⁸
|
||||
{ 12, 14, 13, 0, 24, 42, 59011 }, // ⁹
|
||||
{ 11, 11, 16, 3, 21, 31, 59053 }, // ⁿ
|
||||
{ 11, 15, 13, 1, 10, 42, 59084 }, // ₀
|
||||
{ 8, 14, 13, 2, 10, 28, 59126 }, // ₁
|
||||
{ 11, 14, 13, 1, 10, 39, 59154 }, // ₂
|
||||
{ 10, 15, 13, 1, 10, 38, 59193 }, // ₃
|
||||
{ 12, 14, 13, 0, 10, 42, 59231 }, // ₄
|
||||
{ 11, 14, 13, 1, 9, 39, 59273 }, // ₅
|
||||
{ 12, 15, 13, 1, 10, 45, 59312 }, // ₆
|
||||
{ 10, 14, 13, 3, 9, 35, 59357 }, // ₇
|
||||
{ 11, 15, 13, 1, 10, 42, 59392 }, // ₈
|
||||
{ 12, 15, 13, 0, 10, 45, 59434 }, // ₉
|
||||
{ 18, 20, 18, 0, 20, 90, 59479 }, // ₣
|
||||
{ 19, 22, 18, -1, 21, 105, 59569 }, // ₤
|
||||
{ 35, 22, 36, 0, 21, 193, 59674 }, // ₧
|
||||
{ 20, 22, 18, -1, 21, 110, 59867 }, // €
|
||||
{ 17, 12, 29, 6, 16, 51, 59977 }, // ←
|
||||
{ 13, 20, 29, 8, 20, 65, 60028 }, // ↑
|
||||
{ 17, 12, 29, 6, 16, 51, 60093 }, // →
|
||||
{ 13, 20, 29, 8, 20, 65, 60144 }, // ↓
|
||||
{ 18, 12, 29, 5, 16, 54, 60209 }, // ↔
|
||||
{ 13, 20, 29, 8, 20, 65, 60263 }, // ↕
|
||||
{ 13, 20, 29, 8, 20, 65, 60328 }, // ↨
|
||||
{ 13, 20, 29, 8, 20, 65, 60393 }, // ↲
|
||||
{ 13, 20, 29, 8, 20, 65, 60458 }, // ↳
|
||||
{ 17, 14, 29, 6, 17, 60, 60523 }, // ↵
|
||||
{ 17, 14, 29, 6, 17, 60, 60583 }, // ⇐
|
||||
{ 13, 18, 29, 8, 19, 59, 60643 }, // ⇑
|
||||
{ 17, 14, 29, 6, 17, 60, 60702 }, // ⇒
|
||||
{ 13, 18, 29, 8, 19, 59, 60762 }, // ⇓
|
||||
{ 19, 14, 29, 5, 17, 67, 60821 }, // ⇔
|
||||
{ 19, 22, 29, 5, 21, 105, 60888 }, // ∀
|
||||
{ 14, 24, 18, 2, 23, 84, 60993 }, // ∂
|
||||
{ 13, 21, 29, 8, 21, 69, 61077 }, // ∃
|
||||
{ 23, 24, 29, 3, 22, 138, 61146 }, // ∅
|
||||
{ 19, 21, 19, 0, 21, 100, 61284 }, // ∆
|
||||
{ 19, 22, 29, 5, 21, 105, 61384 }, // ∇
|
||||
{ 19, 21, 29, 5, 21, 100, 61489 }, // ∈
|
||||
{ 19, 26, 29, 5, 23, 124, 61589 }, // ∉
|
||||
{ 19, 16, 29, 5, 18, 76, 61713 }, // ∊
|
||||
{ 19, 21, 29, 5, 21, 100, 61789 }, // ∋
|
||||
{ 19, 26, 29, 5, 23, 124, 61889 }, // ∌
|
||||
{ 19, 16, 29, 5, 18, 76, 62013 }, // ∍
|
||||
{ 22, 26, 23, 1, 21, 143, 62089 }, // ∏
|
||||
{ 18, 26, 18, 0, 21, 117, 62232 }, // ∑
|
||||
{ 13, 3, 18, 3, 11, 10, 62349 }, // −
|
||||
{ 17, 23, 14, -1, 21, 98, 62359 }, // ∕
|
||||
{ 11, 23, 14, 2, 21, 64, 62457 }, // ∖
|
||||
{ 14, 14, 18, 2, 17, 49, 62521 }, // ∗
|
||||
{ 10, 10, 18, 4, 15, 25, 62570 }, // ∘
|
||||
{ 6, 4, 18, 6, 10, 6, 62595 }, // ∙
|
||||
{ 18, 28, 18, 0, 24, 126, 62601 }, // √
|
||||
{ 14, 11, 18, 2, 15, 39, 62727 }, // ∝
|
||||
{ 18, 10, 18, 0, 14, 45, 62766 }, // ∞
|
||||
{ 19, 21, 29, 5, 21, 100, 62811 }, // ∟
|
||||
{ 21, 21, 29, 3, 21, 111, 62911 }, // ∠
|
||||
{ 4, 30, 15, 5, 23, 30, 63022 }, // ∣
|
||||
{ 9, 30, 15, 3, 23, 68, 63052 }, // ∥
|
||||
{ 19, 21, 29, 5, 21, 100, 63120 }, // ∧
|
||||
{ 19, 21, 29, 5, 21, 100, 63220 }, // ∨
|
||||
{ 17, 21, 29, 6, 21, 90, 63320 }, // ∩
|
||||
{ 17, 22, 29, 6, 21, 94, 63410 }, // ∪
|
||||
{ 16, 30, 18, 1, 23, 120, 63504 }, // ∫
|
||||
{ 19, 17, 29, 5, 16, 81, 63624 }, // ∴
|
||||
{ 19, 17, 29, 5, 16, 81, 63705 }, // ∵
|
||||
{ 6, 16, 9, 1, 18, 24, 63786 }, // ∶
|
||||
{ 19, 17, 29, 5, 16, 81, 63810 }, // ∷
|
||||
{ 17, 5, 29, 6, 11, 22, 63891 }, // ∼
|
||||
{ 17, 15, 29, 6, 17, 64, 63913 }, // ≅
|
||||
{ 14, 10, 18, 2, 15, 35, 63977 }, // ≈
|
||||
{ 17, 10, 29, 6, 13, 43, 64012 }, // ≍
|
||||
{ 13, 13, 18, 3, 16, 43, 64055 }, // ≠
|
||||
{ 17, 13, 29, 6, 15, 56, 64098 }, // ≡
|
||||
{ 14, 18, 18, 2, 18, 63, 64154 }, // ≤
|
||||
{ 14, 18, 18, 2, 18, 63, 64217 }, // ≥
|
||||
{ 23, 14, 29, 3, 17, 81, 64280 }, // ≪
|
||||
{ 23, 14, 29, 3, 17, 81, 64361 }, // ≫
|
||||
{ 19, 16, 29, 5, 18, 76, 64442 }, // ⊃
|
||||
{ 19, 26, 29, 5, 23, 124, 64518 }, // ⊄
|
||||
{ 19, 26, 29, 5, 23, 124, 64642 }, // ⊅
|
||||
{ 19, 21, 29, 5, 21, 100, 64766 }, // ⊆
|
||||
{ 19, 21, 29, 5, 21, 100, 64866 }, // ⊇
|
||||
{ 21, 22, 29, 4, 21, 116, 64966 }, // ⊕
|
||||
{ 21, 22, 29, 4, 21, 116, 65082 }, // ⊖
|
||||
{ 21, 22, 29, 4, 21, 116, 65198 }, // ⊗
|
||||
{ 21, 22, 29, 4, 21, 116, 65314 }, // ⊘
|
||||
{ 17, 21, 29, 6, 21, 90, 65430 }, // ⊥
|
||||
{ 6, 5, 18, 6, 10, 8, 65520 }, // ⋅
|
||||
{ 25, 5, 29, 2, 10, 32, 65528 }, // ⋯
|
||||
{ 27, 28, 29, 1, 24, 189, 65560 }, // �
|
||||
};
|
||||
|
||||
static const EpdUnicodeInterval bookerly_14_italicIntervals[] = {
|
||||
@@ -4825,44 +4901,48 @@ static const EpdUnicodeInterval bookerly_14_italicIntervals[] = {
|
||||
{ 0x2053, 0x2053, 0x283 },
|
||||
{ 0x2057, 0x2057, 0x284 },
|
||||
{ 0x205F, 0x2064, 0x285 },
|
||||
{ 0x20A3, 0x20A4, 0x28B },
|
||||
{ 0x20A7, 0x20A7, 0x28D },
|
||||
{ 0x20AC, 0x20AC, 0x28E },
|
||||
{ 0x2190, 0x2195, 0x28F },
|
||||
{ 0x21A8, 0x21A8, 0x295 },
|
||||
{ 0x21B2, 0x21B3, 0x296 },
|
||||
{ 0x21B5, 0x21B5, 0x298 },
|
||||
{ 0x21D0, 0x21D4, 0x299 },
|
||||
{ 0x2200, 0x2200, 0x29E },
|
||||
{ 0x2202, 0x2203, 0x29F },
|
||||
{ 0x2205, 0x220D, 0x2A1 },
|
||||
{ 0x220F, 0x220F, 0x2AA },
|
||||
{ 0x2211, 0x2212, 0x2AB },
|
||||
{ 0x2215, 0x221A, 0x2AD },
|
||||
{ 0x221D, 0x2220, 0x2B3 },
|
||||
{ 0x2223, 0x2223, 0x2B7 },
|
||||
{ 0x2225, 0x2225, 0x2B8 },
|
||||
{ 0x2227, 0x222B, 0x2B9 },
|
||||
{ 0x2234, 0x2237, 0x2BE },
|
||||
{ 0x223C, 0x223C, 0x2C2 },
|
||||
{ 0x2245, 0x2245, 0x2C3 },
|
||||
{ 0x2248, 0x2248, 0x2C4 },
|
||||
{ 0x224D, 0x224D, 0x2C5 },
|
||||
{ 0x2260, 0x2261, 0x2C6 },
|
||||
{ 0x2264, 0x2265, 0x2C8 },
|
||||
{ 0x226A, 0x226B, 0x2CA },
|
||||
{ 0x2283, 0x2287, 0x2CC },
|
||||
{ 0x2295, 0x2298, 0x2D1 },
|
||||
{ 0x22A5, 0x22A5, 0x2D5 },
|
||||
{ 0x22C5, 0x22C5, 0x2D6 },
|
||||
{ 0x22EF, 0x22EF, 0x2D7 },
|
||||
{ 0x2070, 0x2070, 0x28B },
|
||||
{ 0x2074, 0x2079, 0x28C },
|
||||
{ 0x207F, 0x2089, 0x292 },
|
||||
{ 0x20A3, 0x20A4, 0x29D },
|
||||
{ 0x20A7, 0x20A7, 0x29F },
|
||||
{ 0x20AC, 0x20AC, 0x2A0 },
|
||||
{ 0x2190, 0x2195, 0x2A1 },
|
||||
{ 0x21A8, 0x21A8, 0x2A7 },
|
||||
{ 0x21B2, 0x21B3, 0x2A8 },
|
||||
{ 0x21B5, 0x21B5, 0x2AA },
|
||||
{ 0x21D0, 0x21D4, 0x2AB },
|
||||
{ 0x2200, 0x2200, 0x2B0 },
|
||||
{ 0x2202, 0x2203, 0x2B1 },
|
||||
{ 0x2205, 0x220D, 0x2B3 },
|
||||
{ 0x220F, 0x220F, 0x2BC },
|
||||
{ 0x2211, 0x2212, 0x2BD },
|
||||
{ 0x2215, 0x221A, 0x2BF },
|
||||
{ 0x221D, 0x2220, 0x2C5 },
|
||||
{ 0x2223, 0x2223, 0x2C9 },
|
||||
{ 0x2225, 0x2225, 0x2CA },
|
||||
{ 0x2227, 0x222B, 0x2CB },
|
||||
{ 0x2234, 0x2237, 0x2D0 },
|
||||
{ 0x223C, 0x223C, 0x2D4 },
|
||||
{ 0x2245, 0x2245, 0x2D5 },
|
||||
{ 0x2248, 0x2248, 0x2D6 },
|
||||
{ 0x224D, 0x224D, 0x2D7 },
|
||||
{ 0x2260, 0x2261, 0x2D8 },
|
||||
{ 0x2264, 0x2265, 0x2DA },
|
||||
{ 0x226A, 0x226B, 0x2DC },
|
||||
{ 0x2283, 0x2287, 0x2DE },
|
||||
{ 0x2295, 0x2298, 0x2E3 },
|
||||
{ 0x22A5, 0x22A5, 0x2E7 },
|
||||
{ 0x22C5, 0x22C5, 0x2E8 },
|
||||
{ 0x22EF, 0x22EF, 0x2E9 },
|
||||
{ 0xFFFD, 0xFFFD, 0x2EA },
|
||||
};
|
||||
|
||||
static const EpdFontData bookerly_14_italic = {
|
||||
bookerly_14_italicBitmaps,
|
||||
bookerly_14_italicGlyphs,
|
||||
bookerly_14_italicIntervals,
|
||||
60,
|
||||
64,
|
||||
38,
|
||||
31,
|
||||
-8,
|
||||
|
||||
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user