7379 Commits

Author SHA1 Message Date
Jonas Jenwald
ecb09d62fc Add the current loading percentage to the onPassword callback
The percentage calculation is currently "spread out" across various viewer functionality, which we can avoid by having the API handle that instead.

Also, remove the `this.#lastProgress` special-case[1] and just register a "normal" `fullReader.onProgress` callback unconditionally. Once `headersReady` is resolved the callback can simply be removed when not needed, since the "worst" thing that could theoretically happen is that the loadingBar (in the viewer) updates sooner this way. In practice though, since `fullReader.read` cannot return data until `headersReady` is resolved, this change is not actually observable in the API.

---

[1] This was added in PR 8617, close to a decade ago, but it's not obvious to me that it was ever necessary to implement it that way.
2026-01-31 16:33:58 +01:00
Jonas Jenwald
4ca205bac3 Add an abstract BasePDFStreamRangeReader class, that all the old IPDFStreamRangeReader implementations inherit from
Given that there's no less than *five* different, but very similar, implementations this helps reduce code duplication and simplifies maintenance.
2026-01-30 14:15:39 +01:00
Jonas Jenwald
54d8c5e7b4 Add an abstract BasePDFStreamReader class, that all the old IPDFStreamReader implementations inherit from
Given that there's no less than *five* different, but very similar, implementations this helps reduce code duplication and simplifies maintenance.

Also, remove the `rangeChunkSize` not defined checks in all the relevant stream-constructor implementations.
Note how the API, since some time, always validates *and* provides that parameter when creating a `BasePDFStreamReader`-instance.
2026-01-30 14:15:39 +01:00
Jonas Jenwald
4a8fb4dde1 Add an abstract BasePDFStream class, that all the old IPDFStream implementations inherit from
Given that there's no less than *five* different, but very similar, implementations this helps reduce code duplication and simplifies maintenance.

Also, spotted during rebasing, pass the `enableHWA` option "correctly" (i.e. as part of the existing `transportParams`) to the `WorkerTransport`-class to keep the constructor simpler.
2026-01-30 14:15:39 +01:00
Jonas Jenwald
a80f10ff1a Remove the onProgress callback from the IPDFStreamRangeReader interface
Note how there's *nowhere* in the code-base where the `IPDFStreamRangeReader.prototype.onProgress` callback is actually being set and used, however the loadingBar (in the viewer) still works just fine since loading progress is already reported via:
 - The `ChunkedStreamManager` instance respectively the `getPdfManager` function, through the use of a "DocProgress" message, on the worker-thread.
 - A `IPDFStreamReader.prototype.onProgress` callback, on the main-thread.

Furthermore, it would definitely *not* be a good idea to add any `IPDFStreamRangeReader.prototype.onProgress` callbacks since they only include the `loaded`-property which would trigger the "indeterminate" loadingBar (in the viewer).

Looking briefly at the history of this code it's not clear, at least to me, when this became unused however it's probably close to a decade ago.
2026-01-30 14:15:39 +01:00
Jonas Jenwald
05b78ce03c Stop registering an onProgress callback on the PDFWorkerStreamRangeReader-instance, in the ChunkedStreamManager class
Given that nothing in the `PDFWorkerStreamRangeReader` class attempts to invoke the `onProgress` callback, this is effectively dead code now.
Looking briefly at the history of this code it's not clear, at least to me, when this became unused however it's probably close to a decade ago.

Finally, note also how progress is already being reported through the `ChunkedStreamManager.prototype.onReceiveData` method.
2026-01-30 14:15:38 +01:00
Jonas Jenwald
987265720e Remove the unused IPDFStreamRangeReader.prototype.isStreamingSupported getter
This getter was only invoked from `src/display/network.js` and `src/core/chunked_stream.js`, however in both cases it's hardcoded to `false` and thus isn't actually needed.
This originated in PR 6879, close to a decade ago, for a potential TODO which was never implemented and it ought to be OK to just simplify this now.
2026-01-30 14:15:38 +01:00
Jonas Jenwald
62d5408cf0 Stop tracking progressiveDataLength in the ChunkedStreamManager class
Currently this property is essentially "duplicated", so let's instead use the identical one that's availble on the `ChunkedStream` instance.
2026-01-30 14:15:38 +01:00
Tim van der Meij
471adfd023
Merge pull request #20596 from Snuffleupagus/FileSpec-fixes
Simplify the `FileSpec` class, and remove no longer needed polyfills
2026-01-29 22:03:38 +01:00
Tim van der Meij
7cdd03ad9b
Merge pull request #20595 from Snuffleupagus/NetworkManager-simplify
Simplify the `NetworkManager` class, and inline it in the  `PDFNetworkStream` class
2026-01-29 21:56:58 +01:00
Tim van der Meij
c0572c1c8f
Merge pull request #20594 from Snuffleupagus/Node-ReadableStream
[Node.js] Don't abort the full request for local PDF files smaller than two range requests, and use standard `ReadableStream`s
2026-01-29 21:48:43 +01:00
Jonas Jenwald
5b368dd58a Remove the Uint8Array.prototype.toHex(), Uint8Array.prototype.toBase64(), and Uint8Array.fromBase64() polyfills
(During rebasing of the previous patches I happened to look at the polyfills and noticed that this one could be removed now.)

See:
 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toHex#browser_compatibility
 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64#browser_compatibility
 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64#browser_compatibility

Note that technically this functionality can still be disabled via a preference in Firefox, however that's slated for removal in [bug 1985120](https://bugzilla.mozilla.org/show_bug.cgi?id=1985120).
Looking at the Firefox source-code, see https://searchfox.org/firefox-main/search?q=array.tobase64%28%29&path=&case=false&regexp=false, you can see that it's already being used *unconditionally* elsewhere in the browser hence removing the polyfills ought to be fine (since toggling the preference would break other parts of the browser).
2026-01-29 17:27:43 +01:00
Jonas Jenwald
247ee02299 Remove the Promise.try() polyfill
(During rebasing of the previous patches I happened to look at the polyfills and noticed that this one could be removed now.)

Note:
 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try#browser_compatibility
 - https://bugzilla.mozilla.org/show_bug.cgi?id=1928493
2026-01-29 17:25:46 +01:00
Jonas Jenwald
b3f35b6007 Return the rawFilename as-is even if it's empty, from FileSpec.prototype.serializable
It's more correct to return the `rawFilename` as-is, and limit the fallback for empty filenames to only the `filename` property.
2026-01-29 17:25:44 +01:00
Calixte Denizet
dd6a0c6cf4
Add a manage button in the thumbnail view in order to save an edited pdf (bug 2010830) 2026-01-26 18:09:07 +01:00
Calixte Denizet
806133379e
Refactor a bit page mapping stuff in order to be able to support delete/copy pages 2026-01-26 16:53:52 +01:00
calixteman
48df8a5ea2
Merge pull request #20586 from marco-c/commentundo
Bug 1999154 - Add the ability to undo comment deletion
2026-01-26 15:52:15 +01:00
calixteman
9f660be8a2
Use DecompressionStream in async code
Usually, content stream or fonts are compressed using FlateDecode.
So use the DecompressionStream API to decompress those streams
in the async code path.
2026-01-25 14:22:19 +01:00
Jonas Jenwald
640a3106d5 Remove caching/shadowing from the FileSpec getters, and simplify the code
Given that only the `FileSpec.prototype.serializable` getter is ever invoked from "outside" of the class, and only once per `FileSpec`-instance, the caching/shadowing isn't actually necessary.

Furthermore the `_contentRef`-caching wasn't actually correct, since it ended up storing a `BaseStream`-instance and those should *generally* never be cached.
(Since calling `BaseStream.prototype.getBytes()` more than once, without resetting the stream in between, will return an empty TypedArray after the first time.)
2026-01-25 13:16:29 +01:00
Jonas Jenwald
84b5866853 Reduce duplication in the pickPlatformItem helper function
Also, tweak code/comment used when handling "GoToR" destinations.
2026-01-25 13:16:06 +01:00
Jonas Jenwald
eaf605d720 Move the NetworkManager functionality into the PDFNetworkStream class
The `NetworkManager` is very old code at this point, and it predates the introduction of the streaming functionality by many years.
To simplify things, especially with upcoming re-factoring patches, let's move this functionality into private (and semi-private) methods in the `PDFNetworkStream` class to avoid having to deal with too many different scopes.
2026-01-25 12:41:33 +01:00
Jonas Jenwald
4d9301fceb Simplify the NetworkManager class
Store pending requests in a `WeakMap`, which allows working directly with the `XMLHttpRequest`-data and removes the need for a couple of methods.

Simplify the `PDFNetworkStreamRangeRequestReader.prototype._onDone` method, since after removing `moz-chunked-arraybuffer` support (see PR 10678) it's never called without an argument.

Stop sending the `begin`-property to the `onDone`-callbacks since it's unused. Originally this code was shared with the Firefox PDF Viewer, many years ago, and then that property mattered.

Re-factor the `status` validation, to avoid checking for a "bad" range-request response unconditionally.
2026-01-25 12:41:20 +01:00
Jonas Jenwald
663d4cd6e7 Use standard ReadableStreams in the src/display/node_stream.js code
Thanks to newer Node.js functionality, see https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options, we can use standard `ReadableStream`s which help to significantly shorten and simplify the code.

For older Node.js versions we use the `node-readable-to-web-readable-stream` package, see https://www.npmjs.com/package/node-readable-to-web-readable-stream, to get the same functionality.
2026-01-25 12:34:47 +01:00
Jonas Jenwald
45294d31cb In Node.js, don't abort the full request for local PDF files smaller than two range requests
This follows the behaviour used with both the Fetch API and `XMLHttpRequest`, compare with the `validateRangeRequestCapabilities` helper function.
2026-01-25 12:34:35 +01:00
Marco Castelluccio
bdc9323b15
Hide comment popup after redo action 2026-01-22 13:12:13 +01:00
Marco Castelluccio
84d15dc453
Restore date too 2026-01-21 17:06:13 +01:00
Marco Castelluccio
d9f67bd8ee
Bug 1999154 - Add the ability to undo comment deletion 2026-01-21 15:15:40 +01:00
calixteman
ce296d8d42
Add the possibility to order the pages in an extracted pdf (bug 1997379)
or in a merged one.
2026-01-19 18:58:23 +01:00
calixteman
8abfd9a797
Avoid exception after having moved an annotation
It fixes #20571.
2026-01-18 21:01:40 +01:00
Calixte Denizet
b5ed988267
Don't use contents stream which have an image format
The original bug has been filled in mupdf bug tracker:
https://bugs.ghostscript.com/show_bug.cgi?id=709033

The attached pdf can be open in Chrome but not in Acrobat.
2026-01-13 18:39:17 +01:00
Calixte Denizet
0ef085e23b
Aria-hide artifacts in the text layer (bug 2004951) 2026-01-05 16:57:01 +01:00
calixteman
eab33828a9
Fix wasm url issue for the jbig2 decoder
and add a test for jbig2 decoding with the js decoder.
2026-01-04 00:08:59 +01:00
calixteman
98c1955bd4
Use the PDFium JBig2 decoder compiled into wasm
The decoder is ~4x faster than the JS decoder on large images.
2026-01-03 22:05:14 +01:00
calixteman
424c7989aa
Get glyph contours when stroking using a pattern
Fix issue #20513 (second part).
2025-12-28 22:55:59 +01:00
calixteman
5518c8a544
Use CIDToGIDMap when the font is a type 2 with an OpenType font
It fixes #18062.
2025-12-28 14:51:06 +01:00
Tim van der Meij
1990fa7cd0
Merge pull request #20538 from calixteman/issue13425
Fix the loca table length when there is enough space for it
2025-12-28 13:52:32 +01:00
calixteman
22932f7b68
Fix the loca table length when there is enough space for it
It fixes #13425.
2025-12-28 11:21:40 +01:00
calixteman
1dffcf7f25
Remove undefStack stuff in the cff parser
I think it should have been removed with #2527 so it should be useless now.
Because of that stuff, some commands with a wrong number of arguments
weren't stripped out (see the pdf in #13850).
2025-12-27 16:59:29 +01:00
Tim van der Meij
dd6459c3d2
Merge pull request #20525 from calixteman/simplify_gradient
Avoid pattern creation with some basic gradients
2025-12-23 15:44:54 +01:00
calixteman
91033c2199
Fix the encoding for some missing chinese fonts
It fixes #20489.
2025-12-23 14:05:27 +01:00
calixteman
4ff582acbe
Avoid pattern creation with some basic gradients
Some gradients are represented as patterns in PDF.js, because they
mustn't be affected by the current transform. But in most of the cases,
the gradient is attached to the origin and the current transform is very
basic (dilatation + orthogonal + translation). In those cases, we can
avoid creating the pattern because the gradient is transformed into
another gradient when the inverse transform is applied.
2025-12-23 10:36:05 +01:00
calixteman
fc4985819f
Avoid exception when trying to render some glyphs contours
It fixes #20513.
2025-12-22 23:45:34 +01:00
calixteman
ff4529d127
Merge pull request #20492 from nicolo-ribaudo/simplify-markedcontent-text-layer
Simplify positioning of elements inside `markedContent`
2025-12-12 17:29:33 +01:00
calixteman
f824f38e30
Merge pull request #20499 from AtiX/master
Improves text rendering performance by skipping unnecessary pattern calculations
2025-12-12 17:28:22 +01:00
Nicolò Ribaudo
7e0c9395fb
Simplify positioning of elements inside markedContent
By setting `display: contents` on `.markedContent` containers, they stop
affecting the layout of their children. This means that we can always
position text layer `<span>` elements using percentages relative to the
page dimensions, rather than having two separate code paths.

For some reason this breaks the workaround for text selection flickering
in Chrome/Safari, which can be fixed by setting `user-select: text` on
the `.endOfContent` div (only in Chrome/Safari, as it would break
selection in Firefox).
2025-12-12 11:37:45 +01:00
Arthur Silber
9bc4175bde Improves text rendering performance by skipping unnecessary pattern calculations 2025-12-12 07:07:31 +01:00
Tim van der Meij
4af193bbfc
Merge pull request #20491 from nicolo-ribaudo/move-text-scaling-logic-to-css
Move text layer scaling logic to CSS
2025-12-11 20:53:14 +01:00
Tim van der Meij
d946f05841
Merge pull request #20440 from Gaurang-5/master
Fix infinite loop in JBIG2 decoder with >4 referred-to segments
2025-12-09 20:42:51 +01:00
Nicolò Ribaudo
eb2b7c2c86
Move text layer scaling logic to CSS
This commit moves all the logic to scale up&down `<span>`s in the text
layer, introduced in #18283, to CSS.

The motivation for this change is that #18283 is still not enough for
all cases. That PR fixed the problem in Chrome&Firefox desktop, which
allow users to set an actual minimum font size in the browser settings.
However, other browsers (e.g. the Chrome-based WebView on Android) have
more complex logic and they scale up small text rather than simply
applying a minimum.

A workaround for that behavior is probably out of scope for PDF.js
itself as it only affects not officially supported platforms. However,
having access to the actual expected font height (through
`--font-height`) allows embedders of PDF.js to implement a workaround by
themselves.
2025-12-09 13:12:20 +01:00
calixteman
f75812b0af
Merge pull request #20346 from ryzokuken/binary-fontpath
Encode FontPath data into an ArrayBuffer
2025-12-08 13:59:23 +01:00