7908 Commits

Author SHA1 Message Date
Jonas Jenwald
55c8516944 Use the convertRGBToRGBA helper with RGB images in putBinaryImageData
This removes a little bit of code duplication, which only exist since the `src/display/canvas.js` code pre-dates the helper function by many years.

Note: Given that `OffscreenCanvas` is enabled by default there's currently not a lot of test coverage for this code-path, hence the added browser-test.
2026-06-13 13:14:50 +02:00
Tim van der Meij
e75a7cfd62
Merge pull request #21441 from Snuffleupagus/JpegImage-isSourcePDF-conditional
Re-factor the `isSourcePDF` handling in the `JpegImage` class
2026-06-13 12:48:00 +02:00
Tim van der Meij
5f8f6b1e40
Merge pull request #21439 from Snuffleupagus/more-getOrInsertComputed
Use `Map.prototype.getOrInsertComputed()` more in the code-base
2026-06-13 12:44:51 +02:00
Jonas Jenwald
ec1e94423b Re-factor the isSourcePDF handling in the JpegImage class
This functionality was added specifically for the standalone image-decoders, and by utilizing the pre-processor we can reduce the amount of "unnecessary" code in the regular builds.

Also, shorten a few loop variables a little bit since less code is always good.
2026-06-13 10:59:02 +02:00
Jonas Jenwald
5873e1cbc0
Merge pull request #21431 from Snuffleupagus/more-isDict
Use the `isDict` helper function in a few more places
2026-06-12 23:32:22 +02:00
Jonas Jenwald
ffa7ac7a91 Use Map.prototype.getOrInsertComputed() more in the code-base 2026-06-12 23:21:16 +02:00
Tim van der Meij
ca34359e1f
Merge pull request #21426 from Snuffleupagus/rm-convertToViewportRectangle
[api-minor] Remove the unused `convertToViewportRectangle` method in the `PageViewport` class
2026-06-12 22:06:19 +02:00
calixteman
35d275d3b1
Merge pull request #18907 from calixteman/bug1802506
Use the checkboxes and radio button appearances as defined in the pdf to render them in the annotation layer (bug 1802506)
2026-06-12 22:04:29 +02:00
Calixte Denizet
069b757998 Use the checkboxes and radio button appearances as defined in the pdf to render them in the annotation layer (bug 1802506)
The idea is to generate two operator lists for the Yes/Off states and render them on a separate canvas.
These canvases are then attached the annotation and we modify their display depending on the input state.

It fixes #18021.
2026-06-12 20:10:56 +02:00
Jonas Jenwald
131d6b7d38 Handle corrupt PDFs that lack /Kids array and just inline the /Page dictionary (issue 21436)
This basically extends PR 9549 to the fallback `getAllPageDicts` method, which didn't exist at the time, in order to support more cases of corrupt PDF documents.
2026-06-12 12:04:58 +02:00
Jonas Jenwald
3b628d59fb Use the isDict helper function in a few more places 2026-06-11 17:24:03 +02:00
Jonas Jenwald
587abf0ef4 Re-use the getPassword helper function more in the src/core/worker.js file
Currently the same code, for requesting the password from the main-thread, is now duplicated three times.
Let's avoid that by moving the new `getPassword` helper function, added in the previous commit, and re-use that everywhere instead.
2026-06-11 10:07:39 +02:00
Jonas Jenwald
f3f5acc418 Fix the unit-tests for on-demand password handling of encrypted attachments (issue 21425)
These unit-tests used a PDF that prompted for password on document load, which meant that the on-demand password handling wasn't actually being tested as intended.

Updating the unit-tests also caused the "re-prompts for encrypted attachments after incorrect passwords" test to fail, since the `INCORRECT_PASSWORD` password reason was being accidentally "swallowed" in the worker-thread.
2026-06-10 23:08:34 +02:00
Jonas Jenwald
d1926fb179 Use the convertBlackAndWhiteToRGBA helper with grayscale images in putBinaryImageData
This removes a little bit of code duplication, which only exist since the `src/display/canvas.js` code pre-dates the helper function by many years.

*Note:* Given that `OffscreenCanvas` is enabled by default there's currently not a lot of test coverage for this code-path, hence the added browser-test.
2026-06-10 18:31:07 +02:00
Jonas Jenwald
a543d0a2e0 [api-minor] Remove the unused convertToViewportRectangle method in the PageViewport class
This method has been completely unused for many years, possibly as far back as PR 8030, hence we can avoid shipping a little bit of dead code.

*Note:* If there's any third-party code depending on it, updating it ought to be as simple as changing
```javascript
const r = viewport.convertToViewportRectangle(rect);
```
into
```javascript
const r = [
  ...viewport.convertToViewportPoint(rect[0], rect[1]),
  ...viewport.convertToViewportPoint(rect[2], rect[3])
];
```
2026-06-10 14:19:20 +02:00
calixteman
ce08a803c4
Merge pull request #21416 from calixteman/drop-css-unsafe-inline
Drop 'unsafe-inline' from the CSP style-src directives
2026-06-09 23:16:38 +02:00
calixteman
a13f2aa793
Merge pull request #21413 from calixteman/improve_comb
Improve rendering of comb text fields
2026-06-09 23:10:49 +02:00
Calixte Denizet
fe5eb0f779
Improve rendering of comb text fields
Center each glyph within its comb cell instead of left-aligning it,
both in the HTML annotation layer and in the printed/saved appearance,
to match Acrobat. Cell width is now the single source of truth via the
--comb-width CSS variable, and field text-alignment (center/right) is
applied as a whole-cell --comb-offset that stays in sync on input,
blur, resetform and updatefromsandbox. The field no longer grows on
focus; trailing letter-spacing is clipped and cell dividers are drawn
on focus.
2026-06-09 22:15:40 +02:00
Calixte Denizet
5ca6026d80
Drop 'unsafe-inline' from the CSP style-src directives
The print service injected the per-PDF `@page { size }` rule as an inline
<style> element, which required 'unsafe-inline' on style-src-elem.

Inject it through a constructable CSSStyleSheet attached to
document.adoptedStyleSheets instead. Constructable stylesheets aren't
subject to style-src's inline restrictions in browsers.
2026-06-09 22:08:08 +02:00
Tim van der Meij
c541d24ac3
Merge pull request #21407 from calixteman/fix_hidden_updated_field
Fix form fields with their own canvas updated on non-rendered pages
2026-06-09 20:03:20 +02:00
Tim van der Meij
8a80f1b8b7
Merge pull request #21418 from Snuffleupagus/getAttachments-Map
[api-minor] Convert `getAttachments` to return data in a `Map`
2026-06-09 19:42:23 +02:00
Jonas Jenwald
ea139e7df1 [api-minor] Convert getAttachments to return data in a Map
Compared to regular `Object`s there's a number of advantages to using `Map`s:
 - They support "proper" iteration.
 - They have a simple way to check for the existence of data.
 - They have a simple/efficient way to check the number of elements.

If this functionality was added today, I cannot imagine that we'd choose an `Object` for this sort of data.
Furthermore, in PR 21351 the data returned by `getAttachments` changed slightly and third-party users will need to update their code anyway (hence why `[api-minor]` should be fine here).
2026-06-09 10:17:23 +02:00
Calixte Denizet
473b53fe3c Handle TR2 with /Default entry
It fixes #21406.
2026-06-08 19:09:45 +02:00
Calixte Denizet
ecd43bc8e1 Fix form fields with their own canvas updated on non-rendered pages
When a read-only field (which has its own canvas) is updated by the
sandbox while its page isn't rendered, showElementAndHideCanvas
isn't called, so once the page is finally rendered the field still
shows its outdated canvas instead of the new value.

Replace the imperative canvas/element toggling with a `sandboxModified`
class, set from the annotation storage both at render time and on
sandbox updates, and let the CSS show the element and hide the canvas.
2026-06-08 17:22:11 +02:00
Jonas Jenwald
5f83408099 Remove the Map.prototype.getOrInsertComputed polyfill from the scripting implementation (PR 21399 follow-up)
All unit- and integration-tests pass with this patch, and according to the QuickJS changelog this is supported now; note 3d5e064e9d/Changelog (L10) and https://github.com/tc39/proposal-upsert.
2026-06-08 11:48:42 +02:00
calixteman
7a7e4fd382 Update quickjs to rev 3d5e064e9dd67c70f7962836505a7fa067bf0a4e 2026-06-08 09:26:36 +02:00
Tim van der Meij
9c437e6ab4
Merge pull request #21388 from calixteman/strip_jbig2_header
Strip the JBIG2 file header from JBIG2Decode streams
2026-06-05 20:06:02 +02:00
Tim van der Meij
4ed78beb38
Merge pull request #21387 from Snuffleupagus/ChunkedStream-abort-reject
Reject the stream-capability when aborting the `ChunkedStreamManager`
2026-06-05 20:02:02 +02:00
Tim van der Meij
e34e11cf78
Merge pull request #21386 from KonstantinRight/print-params-flag-fix
fix typo in bit flag value for suppressCropClip
2026-06-05 19:58:58 +02:00
calixteman
173e083c71
Merge pull request #21350 from calixteman/kb_shortcuts_l10n
Match editor keyboard shortcuts by event.code as a fallback
2026-06-05 17:19:17 +02:00
Calixte Denizet
88c52a1523 Strip the JBIG2 file header from JBIG2Decode streams
It's rendering correctly in Acrobat and PdfBox.
2026-06-05 16:31:44 +02:00
Jonas Jenwald
959ce38f5b Reject the stream-capability when aborting the ChunkedStreamManager
Given that any incoming data is already being ignored after loading has been aborted, it seems reasonable to reject the stream-capability to avoid it remaining in a pending state indefinitely.

*Note:* This is something that I noticed while looking at the coverage data, since the `ChunkedStreamManager.prototype.onError` method is not used and from a brief look at the history of the code it never appears to have been used either.
2026-06-05 12:25:53 +02:00
Konstantin
a66782615e fix typo in bit flag value for suppressCropClip 2026-06-05 11:30:20 +03:00
Tim van der Meij
23ea0810d9
Merge pull request #21379 from calixteman/dedup_stream_merging
Deduplicate shared font/image streams when merging PDFs
2026-06-04 20:58:22 +02:00
Jonas Jenwald
d36d3ab893 Shorten the getBytes method in the Stream/ChunkedStream classes
This is very old code and there's currently a bit of unneeded duplication in these methods, especially in the `ChunkedStream` class.
2026-06-04 13:10:24 +02:00
Titus Wormer
4db9e45b8c
Add support for /AuthEvent, on-demand decryption
Normally entire PDFs are encrypted (or not).
But it is also possible to only encrypt attachments.
It is then also possible to *only* prompt for a password when the user opens
them.

In the existing flow, prompting for passwords happens because things are decrypted.
A specific error is thrown, caught, and the user is prompted.
To keep this flow working, this PR changes to decrypting attachments on demand,
instead of eagerly.
This sounds logical: to not read attachments on startup.

I’ve extensively tested this, not only with regular attachments, but also with outline items
and attachments in annotations.

This PR builds on GH-21234.
It’s an alternative to the naïve GH-20732.

Closes GH-20049.
2026-06-03 16:44:57 +02:00
Calixte Denizet
836a08084e Match editor keyboard shortcuts by event.code as a fallback
So that Ctrl+A, Ctrl+Z, etc. still fire on non-US keyboard layouts where
the physical "A" key produces a non-Latin character (Cyrillic, Greek,
some AZERTY combinations, ...). KeyboardManager now tries event.key first
and falls back to a US-layout translation of event.code (KeyA => a,
Digit1 => 1, Numpad1 => 1) when no shortcut is bound on event.key.

Also refactors KeyboardManager to store modifiers as a bitmask instead
of a serialized string, and treats a shortcut array without any
"mac+"-prefixed entry as applying on all platforms, letting us drop the
redundant "mac+X" duplicates of bare "X" entries across the editor code.
2026-06-03 10:13:41 +02:00
Calixte Denizet
1a7821ab13 Deduplicate shared font/image streams when merging PDFs
Identical embedded fonts and images across the merged documents are now
written once and shared, instead of being copied per source file.
And avoid to compress already compressed stream with Brotli.
2026-06-02 22:08:21 +02:00
Jonas Jenwald
19046a6949
Merge pull request #21349 from Snuffleupagus/OptionalContentConfig-serializable
Implement proper serialization of `OptionalContentConfig`
2026-06-02 21:57:16 +02:00
Tim van der Meij
744c1e6d7a
Merge pull request #21372 from calixteman/issue7998
Render gray transparency groups in grayscale
2026-06-02 20:10:18 +02:00
calixteman
69e8d6900f Render gray transparency groups in grayscale
It fixes #7998.
2026-05-31 21:16:29 +02:00
Jonas Jenwald
a6321e7201 Improve the BaseStream.prototype.clone implementations
- The `dict` field is optional, hence avoid an Error if trying to clone a non-existent dictionary.

 - Use the `length` getter in the `Stream` class, to avoid duplication.

 - Fix the `DecodeStream` implementation, since it has a couple of bugs:
    - The `clone` method currently uses `start`/`end` fields, despite these only existing on `Stream` instances.
    - Given the previous point, we ended up creating the cloned `Stream` instance using the *entire* underlying `buffer`. This is problematic since the length of a `DecodeStream` cannot be accurately estimated before decoding, and the `buffer`-length is simply a multiple of two.
       Unless the size of the decoded-data just happens to also be a multiple of two, this causes the cloned `Stream` instance to be "padded" with zeros at the end.
2026-05-31 20:24:39 +02:00
Tim van der Meij
5fbab91f71
Merge pull request #21368 from Snuffleupagus/more-internal-events
Mark a couple of viewer, and editor, EventBus listeners as "internal"
2026-05-31 14:35:18 +02:00
Jonas Jenwald
94fdea15f4
Merge pull request #21366 from Snuffleupagus/StringStream-dict
Update the `StringStream` constructor to accept an optional dictionary argument
2026-05-31 13:01:43 +02:00
Jonas Jenwald
04237100a5 Mark a couple of viewer, and editor, EventBus listeners as "internal"
There's currently a few EventBus listeners that aren't marked as "internal", however I'm assuming that they probably should be (e.g. to reduce the risk of intermittent failures in the integration-tests).
2026-05-31 12:12:41 +02:00
Jonas Jenwald
345089de1f
Merge pull request #21367 from Snuffleupagus/canvas-MathClamp
Use the `MathClamp` helper function in the `src/display/canvas.js` file
2026-05-31 11:55:48 +02:00
Jonas Jenwald
06439a95c3 Update the StringStream constructor to accept an optional dictionary argument
There's currently some amount of `StringStream` usage where the `dict`-parameter is manually assigned, and by updating the signature of the constructor this can be avoided.
2026-05-31 11:36:32 +02:00
Jonas Jenwald
0e1660700a Use the MathClamp helper function in the src/display/canvas.js file 2026-05-31 11:13:42 +02:00
calixteman
5d28cf5e88 Skip the format 4 cmap sub-table when it doesn't fit its 16-bits fields
It's a follow-up of bug 199861 (see https://bugzilla.mozilla.org/show_bug.cgi?id=1998618#c2).
2026-05-30 21:53:29 +02:00
Jonas Jenwald
74db085794 Re-factor how "internal" EventBus listeners are handled in the viewer
Currently the viewer uses semi-private `EventBus.prototype.{_on, _off}` methods, to try and ensure that all internal viewer state is updated *before* any "external" listeners are invoked.
For all use-cases outside of the viewer, e.g in the integration-tests, the `EventBus.prototype.{on, off}` methods are supposed to be used instead.

Unfortunately this isn't currently enforced in any way, except (hopefully) during review, and generally speaking it's not really possible to prevent the semi-private methods being used (e.g. by third-party users).
Hence this patch adds a new `INTERNAL_EVT` property which is *not* exposed anywhere (neither in the API nor globally), and whose value is generated at build-time, that the viewer uses to mark its `EventBus` listeners are internal.
This allows us to remove the semi-private `EventBus` methods, which helps to simplify that class a little bit.
2026-05-29 22:11:58 +02:00