2813 Commits

Author SHA1 Message Date
Jonas Jenwald
2e7a2215e3 [api-major] Remove support for calling getDocument without a parameter object
This is a left-over from very old code[1], before there were a lot of `getDocument` options and when most of the library configuration was done via the (since removed) `PDFJS` global.
Given all the functionality added through the years, which require configuration[2], in practice it's now unlikely that calling `getDocument` without additional options will work except for the most trivial PDFs.

---

[1] If the `getDocument` function was added today, there's no chance that it'd support anything other than a parameter object.

[2] Note things such as CMaps, standard fonts, wasm-based image decoders, and ICC-based colour spaces.
2026-05-09 13:00:27 +02:00
calixteman
b8232710c8
Fall back to pixel-buffer SMask filtering when ctx.filter is unavailable
For now OffscreenCanvas in worker threads doesn't support ctx.filter,
so we need to fall back to a more expensive pixel-buffer SMask filtering in that case.
As a side effect, this also allows to support correctly smask in Safari.
2026-05-07 22:27:04 +02:00
Tim van der Meij
a328294713
Merge pull request #21235 from calixteman/bug2033095
Improve soft mask composition performance (bug 2033095)
2026-05-07 21:35:09 +02:00
Calixte Denizet
1658a792ce Improve soft mask composition performance (bug 2033095)
Prepare reusable soft-mask canvases for filtered and backdrop-dependent masks,
and use a faster destination-in composition path where possible.
Handle Alpha SMask /BC correctly, preserve OOB alpha behavior, and mirror canvas path
operations needed while rendering inside soft-mask mode (mirrored clip was buggy).

Add reftest PDFs covering Alpha masks, transfer functions, backdrop/OOB
alpha, and the optimized composition paths.
2026-05-07 19:06:49 +02:00
Calixte Denizet
4c62a49483
Place new annotations on the correct page when extracting pages (bug 2027682) 2026-05-06 18:44:02 +02:00
Jonas Jenwald
8fc56772e8 A couple of small tweaks of the getPdfFilenameFromUrl helper
- Shorten the `getURL` function slightly, by re-factoring the try-catch blocks.
 - Change how the `decode` function looks for a decoded ".pdf" name, to skip the regular expression matching when it's not needed and to allow re-using the already defined `pdfRegex`.
2026-05-05 12:16:57 +02:00
Jonas Jenwald
8142937ac4
Merge pull request #20961 from calixteman/use_image_decoder_chrome
[api-minor] Use the ImageDecoder by default on Chrome
2026-05-01 13:09:43 +02:00
Jonas Jenwald
270b68feb9 [api-major] Update the minimum supported browsers, and remove no longer needed polyfills
By removing support for older browsers it's possible to simplify both the code and the build-scripts, in addition to removing manually implemented polyfills.
Using the PDF.js library/viewer will now require native support for the following features:
 - The `AbortSignal.any()` static method, see https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static#browser_compatibility
 - The `:dir()` CSS pseudo-class, see https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:dir#browser_compatibility
 - The `light-dark()` CSS function, see https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/light-dark#browser_compatibility
 - The CSS `&` nesting selector, see https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/Nesting_selector#browser_compatibility

This patch updates the minimum supported browsers as follows:
 - Google Chrome 125, which was released on 2024-05-15; see https://chromereleases.googleblog.com/2024/05/stable-channel-update-for-desktop_15.html
 - Safari 18, which was released on 2024-09-16; see https://developer.apple.com/documentation/safari-release-notes/safari-18-release-notes
   *Note:* This version is the first with experimental support for the `CanvasRenderingContext2D.filter` property, which is a long-standing missing feature in Safari, however it must be *manually enabled*; see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter#browser_compatibility

Note that nowadays we usually try, where feasible and possible, to support browsers that are about two years old. By limiting support to only "recent" browsers we reduce the risk of holding back improvements of the *built-in* Firefox PDF Viewer, and also (significantly) reduce the maintenance/support burden for the PDF.js contributors.

*Please note:* As always, the minimum supported browser version assumes that a `legacy`-build of the PDF.js library is being used; see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2026-04-30 20:32:08 +02:00
Calixte Denizet
e7ec356be0
Fix free highlight on pages without images (bug 2035530) 2026-04-29 19:24:35 +02:00
calixteman
30ea3216c9
Merge pull request #21175 from calixteman/bug1942304
Send 'Terminate' to the worker when destroy races the load-time handshake (bug 1942304)
2026-04-28 15:22:20 +02:00
Calixte Denizet
dc3c07b3e3 Allow free-highlighting on top of image placeholders (bug 2034980)
The `textLayerImagePlaceholder` canvas added in #20626 covers scanned
pages and was not recognized as a valid pointerdown target by
`#textLayerPointerDown`, so free highlights couldn't start.
2026-04-27 20:13:39 +02:00
Calixte Denizet
cffb19e266 Send 'Terminate' to the worker when destroy races the load-time handshake (bug 1942304)
If `PDFDocumentLoadingTask.destroy` ran while `workerIdPromise` was
pending, the inner `.then` in `getDocument` threw "Loading aborted"
before `WorkerTransport` was constructed, so `_transport` was never set
and the "Terminate" message was never posted.
2026-04-27 17:14:45 +02:00
Nicolò Ribaudo
81678f20ca
Fix array type in CanvasBBoxTracker comment
Remove the "Float32Array" mention in the comment, given that the
implementation usesa  Float64Array.

Actually using a Float32Array passes all the tests we currently have and
reduces memory usage (by 16 bytes per op), however to be sure that it
does not introduce rounding bugs we'd need to `Math.fround` all
operations we do on the clipBox and pendingBBox. It reduces the
readibilty of the code, but we can revisit if this memory usage becomes
a problem.
2026-04-27 15:52:12 +02:00
Calixte Denizet
64b25a8f47
Fix merging a PDF after a page deletion (bug 2034804)
When pages carry explicit pageIndices (e.g. after a delete),
resolve insertAfter against that layout instead of the empty
base sequence. Also reject partial pageIndices combined with
insertAfter, which would race against the extraction's auto-fill.
2026-04-26 22:37:22 +02:00
Jonas Jenwald
72011c5088 Get the zIndex correctly in PopupElement.prototype.renderCommentButton
In practice this probably hasn't caused any bugs, however given that `DOMElement.style.zIndex` returns a string the existing code is subtly wrong.
This is also consistent with pre-existing `zIndex` code in the `PopupElement` class, see the `#show` and `#hide` methods.
2026-04-26 14:46:39 +02:00
Jonas Jenwald
5c11bf15b0
Merge pull request #21160 from Snuffleupagus/more-hexNumbers
Move the `hexNumbers` Array into `Util`, to enable using it in the viewer
2026-04-26 13:08:42 +02:00
Tim van der Meij
0d7439e856
Merge pull request #21158 from Snuffleupagus/modifiedIds-proper-hash
Compute a "proper" hash in the `AnnotationStorage.prototype.modifiedIds` getter
2026-04-26 12:10:24 +02:00
Jonas Jenwald
9b238b9719 Move the hexNumbers Array into Util, to enable using it in the viewer
This reduces some code duplication, and the new `Util.hexNums` property is now computed lazily.
2026-04-26 12:05:12 +02:00
Jonas Jenwald
b72a229ee8 Compute a "proper" hash in the AnnotationStorage.prototype.modifiedIds getter
Currently the hash-property is just a stringified Array, which means that the hash-property can become arbitrarily long. That's not a good idea since it's used to compute a cache-key, in the API, which is then sent to the worker-thread. Hence the hash-property should be reasonably short, and its length should *not* depend on the number of modified editors, which can be achieved by using `MurmurHash3_64` here as well.
2026-04-25 12:52:29 +02:00
Jonas Jenwald
e6dba6ee34 Enable the radix ESLint rule
Many `parseInt` call-sites already provide the `radix` argument, and this rule helps improve consistency in the code-base; see https://eslint.org/docs/latest/rules/radix

*Please note:* The rule is disabled in `src/scripting_api/util.js` for now, since it's not obvious at a glance (at least to me) what the correct `radix` argument should be there.
2026-04-25 12:13:12 +02:00
Calixte Denizet
f266c4d8b8
[Ink] Replace the opacity slider with an alpha-enabled color input
The alpha feature is available in Firefox nightly (with the pref `dom.forms.html_color_picker.enabled` set to `true`).
It's available in Safari but not in Chrome.
2026-04-23 21:37:37 +02:00
Jonas Jenwald
b01eeaf8e1 Improve the "CopyLocalImage" unit-tests
Rather than relying on the time it takes to parse/render the pages, which leads to intermittent failures, add a test-only property and use it to check if the "CopyLocalImage" code-path was exercised.
2026-04-21 11:43:08 +02:00
Jonas Jenwald
445cb9abf9
Merge pull request #21103 from Snuffleupagus/TrueTypeTableBuilder-2
Use TypedArrays in the `createCmapTable` function
2026-04-16 11:44:14 +02:00
Mario
9dd30474c2 Fix saveDocument JSDoc return type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:51:39 +02:00
Jonas Jenwald
b2cc9ae6d5 Move the string32 helper to the src/display/font_loader.js file
After the previous patches the `string32` helper function is now only used in the `FontLoader.prototype._prepareFontLoadEvent` method, which is stubbed out in the Firefox PDF Viewer, hence move it there instead to avoid bundling dead code.
2026-04-14 20:36:34 +02:00
Calixte Denizet
22a4bd79af
Improve SMask compositing by pre-baking backdrop and filter
remove as much as possible some intermediate canvases and avoid to use SVG filter
at each composition.
Rendering all the pages of issue17784.pdf takes 2x less time now.
2026-04-14 20:18:03 +02:00
Nicolò Ribaudo
2ad6b88850
Fix dependency tracking in pattern fill
1. Record `fill` dependencies even if we early return due to `isPatternFill``
2. Isolate the `drawPattern` inner `executeOperationList` in a
   `CanvasNestedDependencyTracker` so that it does not consume pending
   dependencies from the outer list.
2026-04-14 14:16:26 +01:00
calixteman
419c2652c3
Merge pull request #21094 from calixteman/issue17784
Correctly sync the transform on the scratch canvas
2026-04-13 23:58:20 +02:00
calixteman
1025af059f
Merge pull request #21099 from calixteman/no_gpu
Use the gpu for drawing meshes only when it has more than 16 triangles (bug 2030745)
2026-04-13 23:55:52 +02:00
calixteman
865b48893a
Correctly sync the transform on the scratch canvas
It fixes #17784.
2026-04-13 23:54:53 +02:00
Calixte Denizet
a2c57ee69e
Use the gpu for drawing meshes only when it has more than 16 triangles (bug 2030745)
And in order to slightly improve performances, move the figure creation in the worker.
2026-04-13 22:23:03 +02:00
calixteman
22bcaf5a8a Fix blending issues while compositing
It fixes #13520.
And remove dead code.
2026-04-13 22:12:04 +02:00
Calixte Denizet
ec35057b46
Remove the workaround for bug 1820511 2026-04-13 16:49:07 +02:00
Tim van der Meij
89b195d35c
Merge pull request #21092 from Snuffleupagus/AnnotationEditorLayer-stopEvent
Use the `stopEvent` helper function in the `AnnotationEditorLayer` class
2026-04-12 18:31:31 +02:00
Jonas Jenwald
041f58f1e6 Use the stopEvent helper function in the AnnotationEditorLayer class 2026-04-12 14:23:52 +02:00
calixteman
6d3034d4f9
Remove pattern fill when setting fill color before drawing a tile
It fixes #21089.
2026-04-12 13:08:45 +02:00
Jonas Jenwald
654985c621 Add constants for defining the initial BBox and Float32 BBox
Nowadays there's a lot of places in the code-base where we need to initialize or reset bounding boxes. Rather than spelling this out repeatedly, this patch adds new `Array`/`Float32Array` constants that can be copied or used as-is where appropriate.
2026-04-08 20:30:20 +02:00
Calixte Denizet
00ea8db6bf
Avoid as much as possible to have intermediate canvases
We try to detect in the worker if some patterns or groups need to be drawn or not in isolation.
When they don't, we just draw them on the main canvas instead of drawing on a new canvas.
A pattern or a group is considered as being in isolation if it has some compositing rules or some transparency.

It improves the rendering performance of the pdf in bug 1731514.
2026-04-07 21:03:43 +02:00
calixteman
a9f142c796
Unconditionally create a gpu device
One drawback of the current implementation is that the GPU device can be
unavailable at the time of the first pattern fill, which causes the
GPU-accelerated canvas to be move on the main thread because of putImageData.

Most of the shading patterns stuff will be moved to the GPU and in order
to avoid creating some useless data we've to know if the GPU is available or not.

So in this patch we create the GPU device during the worker initialization
and pass a flag to the evaluator to know if the GPU is available or not.
2026-04-06 13:23:29 +02:00
Jonas Jenwald
d155506005 Remove unnecessary "flooring" of the components when setting the Annotation borderColor
This looks like a leftover from much older code, since all colors are now parsed with the [`getRgbColor` helper](ca85d73335/src/core/annotation.js (L558-L583)) which returns `Uint8ClampedArray` data when the color is valid.

Also, use spread syntax when calling `Util.makeHexColor` in a few more spots.
2026-04-05 11:23:32 +02:00
Jonas Jenwald
f6bac014ea [api-minor] Remove PostScriptCompiler and PostScriptEvaluator, since it's now dead code (PR 21023 follow-up)
These classes, and various related code, became unused after PR 21023 with only unit-tests actually running that code now.

Also removes the `isEvalSupported` API option, since the `PostScriptCompiler` was the only remaining code where `eval` was used.
2026-04-03 22:14:14 +02:00
Calixte Denizet
9ed5eef6d7
Fix the annotation base transform before drawing it
It fixes #7821.

We do something similar for before drawing XObjects.
2026-04-03 20:59:37 +02:00
Calixte Denizet
a1b64c52a1
Get the right transform for a pattern before filling some text
It fixes #16091.
2026-04-03 20:54:22 +02:00
Tim van der Meij
a96fb4dbb8
Merge pull request #21014 from calixteman/issue257
Fix radial gradient when the two circles have an intersection
2026-04-03 20:00:37 +02:00
Tim van der Meij
255c3e7c14
Merge pull request #21028 from Snuffleupagus/PDFDataRangeTransport-listener
[api-minor] Change `PDFDataRangeTransport` to use a single (internal)  listener
2026-04-03 19:53:39 +02:00
Tim van der Meij
bb1033053c
Merge pull request #21029 from Snuffleupagus/Object-hasOwn
Replace all `Object.prototype.hasOwnProperty` usage with `Object.hasOwn`
2026-04-03 19:51:09 +02:00
Jonas Jenwald
cbfe2abc53 Replace all Object.prototype.hasOwnProperty usage with Object.hasOwn
The newer `Object.hasOwn` method is intended as a replacement for `Object.prototype.hasOwnProperty`, since that one may be problematical; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#problematic_cases_for_hasownproperty

To ensure that `Object.hasOwn` is used in the future, the ESLint "no-restricted-syntax" rule is extended to catch the old method.
2026-04-02 13:40:10 +02:00
Jonas Jenwald
f3a2ca08d0 [api-minor] Change PDFDataRangeTransport to use a single (internal) listener
The `PDFDataTransportStream` constructor has always registered exactly one listener for each type of data that an `PDFDataRangeTransport` instance can receive.
Given that an end-user of the `PDFDataRangeTransport` class will supply data through its `onData...` methods, it's also somewhat difficult to understand why additional end-user registered listeners would be needed (since the data is already, by definition, available to the user).
Furthermore, since TypedArray data is being transferred nowadays it's not even clear that multiple listeners (of the same kind) would generally work.

All in all, let's simplify this old code a little bit by using *a single* (internal) listener in the `PDFDataRangeTransport` class.
2026-04-02 12:38:58 +02:00
Jonas Jenwald
68366e31e4 Move the MathClamp helper function to its own file
This allows using it in the `src/scripting_api/` folder, without increasing the size of the scripting-bundle by also importing a bunch of unused code.
2026-04-02 11:22:28 +02:00
Jonas Jenwald
c012ff6e10 Use the MathClamp helper function more
The idea with this helper function is that once https://github.com/tc39/proposal-math-clamp/ becomes stable, all its call-sites should then be replaced by the native functionality.
2026-04-02 10:10:39 +02:00