You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 00aacf9
Browse filesBrowse the repository at this point in the historyBrowse files
Draw complex pages in a background thread (experimental)
pdf.js parses in its worker but paints on the main thread, so complex
plans blocked scrolling for up to half a second per piece. Documents whose
pages are slow to draw (over 120 ms) now get a second pdf.js instance in a
worker that paints into an OffscreenCanvas; the picture comes back as an
ImageBitmap and is shown through a bitmaprenderer canvas.
- Page view, sharp zoom pieces and thumbnails share one drawing helper
(render/draw.ts); worker renders have their own queue, pages before
thumbnails, thumbnails never taking every place.
- Pages that need SVG filters (luminosity soft masks, transfer functions)
are reported back and drawn on the main thread, as before.
- Edits and undo keep the document in the worker; closing a document
closes it there.
- The editing worker hands documents it holds to other threads over a
MessageChannel (copied and transferred there), so neither the drawing
worker nor pdf.js's reload after an edit copies a big file on the main
thread.
- Preferences: "Draw complex pages in the background (experimental)".
On the architectural sample at 400%, panning goes from about 36 to 60
frames per second with no long tasks; on the 286 MB plan, going to a
sheet and zooming to 400% block the main thread for 0.4-0.6 s instead of
about 3 s, and undo after an edit for 0.1 s instead of 0.5 s or more.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H1UeohehDf7pyxWyDSZgJg
Copy file name to clipboardExpand all lines: README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -84,6 +84,7 @@ instead. These files are left out of the offline cache.
84
84
| Layer | Where | What |
85
85
| --- | --- | --- |
86
86
| Rendering |`src/lib/pdfjs.ts`, `src/components/PageView.tsx`|[pdf.js](https://mozilla.github.io/pdf.js/) renders pages to canvas plus a selectable text layer. Pages are rendered lazily as they scroll into view. |
87
+
| Background drawing |`src/lib/render/`| Documents whose pages are slow to draw (plans, maps) get a second pdf.js instance in a worker that paints into an `OffscreenCanvas`; pictures come back as `ImageBitmap`s. Pages that need SVG filters (luminosity soft masks, transfer functions) are drawn on the main thread. Experimental, can be turned off in Preferences. |
87
88
| Editing |`src/lib/pdfOps.ts`|[@cantoo/pdf-lib](https://github.com/cantoo-scribe/pdf-lib) (a maintained pdf-lib fork with encryption and incremental saving) implements every document change as `bytes → bytes`: page operations, watermarks, headers/footers, metadata, forms and annotation export. DOM-free and unit-tested. |
88
89
| Annotations I/O |`src/lib/appearance.ts`, `src/lib/annotIO.ts`| Every annotation gets an appearance stream. Saving writes native PDF annotations (`/Highlight`, `/Ink`, `/FreeText`, …); flattening paints the same appearance into the page. On open, supported annotations from any producer are imported for editing. |
89
90
| Fonts |`src/lib/fonts.ts`, `src/lib/subset.ts`| Added text uses a Noto fallback stack (Noto Sans and Symbols 2 bundled; CJK fetched on demand), subset with HarfBuzz `hb-subset` (WebAssembly). |
@@ -112,6 +113,7 @@ PDF-XChange Editor, and what comes next is in [ROADMAP.md](ROADMAP.md).
- Complex pages (plans, maps) are drawn in a background thread, so scrolling and zooming stay smooth while they draw (experimental; File → Preferences; uses more memory)
115
117
- Zoom in/out, presets, fit width, fit page, Ctrl+wheel zoom
116
118
- Hand (pan), Select Text and Edit Comments tools, text selection & copy
117
119
- Snapshot tool: drag a box to copy that part of the page (with comments) to the clipboard as an image; copy/save a whole page as an image
<labelclassName="row"><inputtype="checkbox"style={NOFLEX}checked={session}onChange={(e)=>voidsetSessionEnabled(e.target.checked)}/>{t('Restore open documents at the next start')}</label>
48
+
<labelclassName="row"title={t('Complex pages (plans, maps) are drawn in a background thread, so scrolling and zooming stay smooth. Uses more memory.')}>
49
+
<inputtype="checkbox"style={NOFLEX}checked={background!=='off'}onChange={(e)=>setPrefs({backgroundDrawing: e.target.checked ? 'auto' : 'off'})}/>{t('Draw complex pages in the background (experimental)')}
50
+
</label>
47
51
<h3className="prefs-heading">{t('Window')}</h3>
48
52
<divclassName="row">
49
53
<spanclassName="muted small"style={{flex: 1}}>{t('Pane widths, open panes and the ribbon tab are remembered.')}</span>
0 commit comments