Draw on PDF pages
Stage four. Strokes are kept per page in that page's own coordinate space — PDF points at scale 1 — not in the fixed 1200x1600 space a note's drawing uses. A PDF cannot use one space: every page has its own size, and a stroke belongs to the page it was drawn on. That is what keeps a mark on the word it was drawn over at any zoom and on any screen, and it is the only form that can be stamped back into the file in stage seven, where page points are the only coordinates that mean anything. Measured rather than assumed: zooming moves a stroke by 0.001 of the page. Pen sizes are scaled by the page width. The sizes are calibrated for the 1200-unit note page, so on a 595-point A4 page the same number would have drawn twice as thick. Reading and drawing are separate modes. While reading the ink layer takes no pointer events, so scrolling and selecting text reach the page beneath it; while drawing, a finger still scrolls and only a pen or mouse marks, because a touch-drag on a phone means scroll far more often than it means draw. The drawing can be hidden without being erased, for reading the original clean. The server accepted only the single-page shape; it now takes either and counts strokes across pages for its limit. Carried over from notes: the save token guard, so the six-second poller adopting a response issued before the local save cannot undo what was just drawn. The suite waits nine seconds and checks the ink is still there — that bug has cost strokes twice before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2986bcb620
commit
1be3a9b9ba
7 files changed
+589
-14
No files matched your search
@@ -330,7 +330,7 @@ docker compose -f docker-compose.dev.yml up -d --build # must be running
|
||||
| `search-attachments` | 12 | body-only matches, ranking, umlauts; images as blob URLs, not inline bytes |
|
||||
| `history` | 10 | a large deletion is snapshotted, restoring works, restoring is itself undoable |
|
||||
| `drawing` | 7 | strokes survive the poller, and match across four viewport widths |
|
||||
| `pdf` | 10 | import, page proportions, lazy loading, and reading with the network off |
|
||||
| `pdf` | 19 | import, page proportions, lazy loading, and reading with the network off |
|
||||
| `conflict` | 10 | a late write wins but the state it buries survives as a version |
|
||||
| `export` | 21 | the downloaded bytes are real Markdown, ZIP and PNG, unpacked and read back |
|
||||
|
||||
@@ -442,6 +442,32 @@ storage is content-addressed, a cached copy can never go stale.
|
||||
|
||||
---
|
||||
|
||||
## Drawing on a PDF
|
||||
|
||||
Strokes are stored **per page, in that page's own coordinate space** — PDF
|
||||
points at scale 1, exactly what pdf.js reports — rather than in the fixed
|
||||
1200×1600 space a note's drawing uses. A PDF cannot use one space: every page
|
||||
has its own size, and a stroke belongs to the page it was drawn on.
|
||||
|
||||
That choice is what keeps a mark on the word it was drawn over at any zoom, on
|
||||
any screen, and it is the only form that can be stamped back into the file later,
|
||||
where page points are the only coordinates that mean anything. The suite measures
|
||||
it: zooming in moves a stroke by 0.001 of the page.
|
||||
|
||||
```jsonc
|
||||
{ "v": 2, "pages": { "1": { "w": 595, "h": 842, "strokes": [...] } } }
|
||||
```
|
||||
|
||||
Only pages that carry ink get an entry. Pen sizes are scaled from the note page
|
||||
width, or the same number would draw twice as thick on an A4 page half as wide.
|
||||
|
||||
Reading and drawing are separate modes. While reading, the ink layer takes no
|
||||
pointer events at all, so scrolling and selecting text reach the page beneath;
|
||||
while drawing, a finger still scrolls and only a pen or mouse leaves a mark. The
|
||||
drawing can be hidden without being erased, for reading the original clean.
|
||||
|
||||
---
|
||||
|
||||
## PDF storage
|
||||
|
||||
An imported PDF is stored as an attachment: encrypted, named by the hash of its
|
||||
|
||||
Reference in new issue
Block a user