7825 Commits

Author SHA1 Message Date
Calixte Denizet
0f90987927 Fix 'Select all' after #20981 2026-05-21 16:39:34 +02:00
Titus Wormer
957e004e38
Make text selection more visible (bug 1879559)
References <https://bugzilla.mozilla.org/show_bug.cgi?id=1879559>
(“In HCM, the text selection is barely visible”).

Continues work from @calixteman who had a partial patch.

This PR improves viewer text-selection highlighting by rendering
selection shapes in the draw layer.

* add selection overlay rendering in the draw layer
  * significant code relates to selections spanning multiple text
    layers/pages, and edges/end-of-content boundaries
* clear selection on rotate/scale/scroll/spread changes

My main question is: how should it appear?
I don’t have access to the Figma file linked on bugzilla.

In the CSS (`draw_layer-builder.css`) there are 3 blocks:

* default
* `@supports` for browsers supporting `backdrop-filter`
* `forced-colors` mode

So it’s possible to design for those (or more).
Personally, the `backdrop-filter: invert(1)` is the most contrast,
so perhaps it’s better to use something else as the default,
and to use `invert(1)` if high contrast mode is used (maybe with a
`prefers-contrast` media query instead)?
2026-05-19 21:10:12 +02:00
Jonas Jenwald
d1da73931a Move the Util.scaleMinMax helper into src/display/canvas_dependency_tracker.js
This method is completely unused in the worker-thread, and it only has a single call-site in the main-thread.
By moving this helper into the `src/display/canvas_dependency_tracker.js` file, the size of the `gulp mozcentral` bundle is reduced by `1220` bytes.
2026-05-18 11:41:37 +02:00
calixteman
deb532334f
Merge pull request #21290 from calixteman/issue20633
Recover CFF private dict defaults zeroed by Ghostscript
2026-05-17 21:57:16 +02:00
calixteman
cd8a78c4e2
Recover CFF private dict defaults zeroed by Ghostscript
It fixes the issue #20633.
2026-05-17 20:51:35 +02:00
Jonas Jenwald
036436a0be Remove the unused Outline._normalizePagePoint method
This method was added in PR 19093, back in 2024, however it never actually appears to have been used.
2026-05-16 23:17:10 +02:00
Jonas Jenwald
7c5087cc16 Move the SVG_NS definition into src/shared/util.js
This constant is already defined in both the `src/core/` and `src/display/` folders, and in a few spots the same string was also inlined.
2026-05-16 15:17:04 +02:00
Jonas Jenwald
e8f07d7ca3 [api-minor] Move the getXfaPageViewport helper into the XfaLayer class
This small helper function only exists to support printing of XFA documents, in the viewer, hence it seems like a good idea to (ever so slightly) reduce the official API surface a little bit.
2026-05-16 12:31:53 +02:00
Jonas Jenwald
eda97fe8fc Move the PageViewport class into its own file
This is necessary to prevent import cycles with the next patch.

It also shouldn't hurt to reduce the size of `src/display/display_utils.js` a little bit, since utility-files have a tendency to increase in size over time.
2026-05-16 12:31:40 +02:00
Tim van der Meij
26474b09cb
Merge pull request #21277 from calixteman/issue21276
Clear the full SMask scratch canvas in compose()
2026-05-15 20:04:11 +02:00
Jonas Jenwald
367f994d94 Remove the Util.domMatrixToTransform method
This method is unused in the worker-thread and has only *a single* call-site in the main-thread, which can be trivially replaced with the `getCurrentTransform` helper function.
2026-05-15 15:07:44 +02:00
Jonas Jenwald
e5330f06fa Move the stringToPDFString helper function into the src/core/string_utils.js file
Given that this function is only ever used during *parsing* of the PDF document, which happens in the worker-thread, this has always added (a little bit of) dead code in the built `pdf.mjs` file.
2026-05-15 12:10:30 +02:00
Jonas Jenwald
7a7e7049c1 Shorten the isAscii helper function a tiny bit 2026-05-15 11:56:33 +02:00
Jonas Jenwald
153cef615e Move a couple of src/core/ string helper functions into their own file
Given that the various utility-files naturally increase in size over time, it shouldn't hurt to shorten `src/core/core_utils.js` a little bit by moving a few of its string helper functions to their own file.
2026-05-15 11:49:54 +02:00
calixteman
5e18cfd8f0
Clear the full SMask scratch canvas in compose()
PR #21101 narrowed `compose()`'s `clearRect` from full canvas to the
caller-supplied dirty box. That leaves pixels outside the current
dirty box on the SMask scratch canvas between `compose()` calls;
subsequent draws into scratch are then source-over-blended on top of
those leftovers, so the output depends on the cumulative draw history
rather than just the current draw.
2026-05-14 23:02:14 +02:00
Roland Arnold
16d82e094f fix: inline styles for hidden helper elements
Set layout-neutral styles at the creation sites for the hidden TextLayer
canvas and PDFViewer copy element rather than relying on the shared
web/pdf_viewer.css rule.

This keeps the helper elements invisible and out of layout when viewer CSS
selectors are scoped or omitted, and removes the obsolete hiddenCanvasElement
class and shared CSS rule.
2026-05-14 14:28:41 +01:00
Tim van der Meij
056837dace
Merge pull request #21173 from timvandermeij/github-actions-integration-tests-coverage
Collect coverage information for the integration tests
2026-05-14 13:40:05 +02:00
Tim van der Meij
26dc195a65
Collect coverage information for the integration tests
Note that for the integration tests the coverage information ends up
being processed in the Node.js context where `window` is not available,
so we use `globalThis` instead for the function that merges individual
test's coverage information into the global object because that is
available in all contexts we support. For clarity we also rename said
function since we're not exclusively dealing with `window` nor worker
data anymore.
2026-05-14 12:34:12 +02:00
Jonas Jenwald
204f9203bd Avoid bundling DOM-related code in the built pdf.worker.mjs file
Currently the `isCanvasFilterSupported`/`isAlphaColorInputSupported` getters, on the `FeatureTest` class, contains code that cannot run in the worker-thread since it relies on the DOM being available.
To avoid that a new DEFINE is added, in `gulpfile.mjs`, to allow skipping this sort of dead code in the built `pdf.worker.mjs` file.
2026-05-14 12:21:36 +02:00
calixteman
7f151c777b
Merge pull request #21262 from calixteman/issue18032
Fix nested non-isolated groups in knockout rendering
2026-05-12 22:37:31 +02:00
calixteman
0e0f7b7696
Merge pull request #21263 from Snuffleupagus/editor-_l10nAlert
[Editor] Avoid "generating" the l10n-ids used for the `a11yAlert`
2026-05-12 22:07:54 +02:00
Calixte Denizet
0e335d53ee Fix nested non-isolated groups in knockout rendering
It fixes #18032.

Only use the special inner-backdrop compositing path for nested non-isolated groups that actually need isolation.
This preserves the parent/page backdrop for simple nested groups inside knockout groups, preventing later group
compositing from erasing existing backdrop content.
2026-05-12 22:00:44 +02:00
Calixte Denizet
1dac67ff54 Use FeatureTest.isCanvasFilterSupported in _bakeSMaskCanvas 2026-05-12 20:02:06 +02:00
Jonas Jenwald
4072d3f835 [Editor] Avoid "generating" the l10n-ids used for the a11yAlert
In the `DrawingEditor.prototype.#createDrawOutlines` method the l10n-id was being "generated", which is bad for maintainability since searching for l10n-id becomes more difficult and the `gulp check_l10n` script actually warns about this.

Hence, similar to e.g. the resizer localization, let's define the `a11yAlert` l10n-ids *once* and provide shorthands for accessing them.
2026-05-12 16:41:53 +02:00
calixteman
0c66063cd4
Merge pull request #21242 from calixteman/knockout
Render knockout transparency groups
2026-05-12 12:02:10 +02:00
Jonas Jenwald
5bc5791a86
Merge pull request #21257 from Snuffleupagus/deepCompare-Refs
Update the `deepCompare` helper function to handle `Ref`s and `Name`s correctly
2026-05-12 11:53:02 +02:00
calixteman
d1e9194e1f
Render knockout transparency groups
In a knockout (KO) group each painting operator ("element") composites against
the group's initial backdrop instead of accumulating onto prior elements
of the same group. The backend renders each element to a per-group pooled
temp canvas (keyed off `#groupStackMeta`), builds a binary alpha mask via
a new `feFuncA` filter (`addKnockoutFilter`), `destination-out`s the
group canvas through that mask, restores the initial backdrop into the
cleared footprint for non-isolated groups (cropped to the same mask so
sparse groups don't bleed the whole rectangle), and finally paints the
element on top with the parent's blend mode. Path / clip / transform ops
are mirrored back to the group canvas via `mirrorContextOperations` so
graphics state stays in sync between elements; only the raster pixels
land on the temp canvas.

The temp canvas is forced to source-over for the element raster (`multiply`
on a transparent backdrop would zero the color) and the original GCO is
restored before `copyCtxState` writes back, so the parent's blend mode
survives for the final composite.

Also handled:
  - Nested KO groups (the level is incremented for KO, reset to 0 for
    non-KO subgroups so an ancestor KO doesn't leak in).
  - Non-isolated non-KO subgroups inside a KO parent (`hasInnerBackdrop`
    path: blend the elements against the subgroup's running backdrop for
    color, mask with the elements-only canvas).
  - Soft masks installed inside a KO element (`applySMaskInPlace` in
    `compose`, which runs the SMask destination-in directly on the temp
    canvas; the existing blit-to-suspended step is gated by `if (!ctx)`).
  - Type-3 text, shading fills, image-mask groups, inline images and the
    solid-color mask path: each is wrapped in `#begin/#endKnockoutElement`.
  - `endDrawing` cleanup so cancelled rendering doesn't leak pooled
    canvases or stale knockout state.
2026-05-11 23:08:06 +02:00
Jonas Jenwald
aecb571ea6 Move the getModificationDate helper function into src/core/core_utils.js
Given that this function is only ever used in `src/core/` code, let's avoid a little bit of dead code in the *built* `pdf.mjs` file.

Also, place the `AnnotationPrefix` and `AnnotationEditorPrefix` constants together in `src/shared/util.js` since that should aid readability.
2026-05-11 14:13:23 +02:00
Jonas Jenwald
326df1f711 Update the deepCompare helper function to handle Refs and Names correctly
Note that `Ref`s and `Name`s are cached globally[1], since that helps reduce object creation (a lot) during parsing.
That cache will be cleared after a period of inactivity in the viewer[2], which is why those primitives cannot *safely* be compared with just `===`/`!==` and also (partially) why abstractions such as `RefSet`/`RefSetCache` are necessary.

Currently `deepCompare` doesn't handle `Ref`s and `Name`s correctly, which may lead to future *intermittent* bugs in any code using the `deepCompare` helper function.

---

[1] This applies to `Cmd` as well, however that doesn't matter in the context of this patch.

[2] Currently, and for more than a decade, set to 30 seconds.
2026-05-11 13:18:54 +02:00
Tim van der Meij
702d60aa18
Merge pull request #21230 from calixteman/avoid_cycles
Avoid cycles when getting operator list in patterns
2026-05-10 18:15:01 +02:00
Tim van der Meij
3b58a339c8
Merge pull request #21213 from saripovdenis/perf-name-tree-getall-queue-index
perf: Avoid multi-second getDestinations stalls for PDFs with many named destinations
2026-05-10 18:13:12 +02:00
Tim van der Meij
02c9051b64
Merge pull request #21245 from Snuffleupagus/getDocument-only-DocumentInitParameters
[api-major] Remove support for calling `getDocument` without  a parameter object, and remove the `PDFDocumentProxy.prototype.destroy` method
2026-05-10 14:30:15 +02:00
Tim van der Meij
559e2f2006
Merge pull request #21236 from calixteman/pixel_fallback_smask
Fall back to pixel-buffer SMask filtering when ctx.filter is unavailable
2026-05-10 14:27:52 +02:00
Jonas Jenwald
43ce1bb491 [api-major] Remove the PDFDocumentProxy.prototype.destroy method
This is a left-over from very old code, which pre-dates the introduction of the `PDFDocumentLoadingTask` and it's nothing more than an alias for its `destroy` method.
Given that `PDFDocumentProxy` already provides a way to access the underlying `PDFDocumentLoadingTask` instance, it shouldn't be necessary to have an alias for one of its methods.

*Please note:* For any existing code relying on the removed method, updating it should be as simple as replacing `pdfDocument.destroy()` with `pdfDocument.loadingTask.destroy()`.

---

[1] If the `PDFDocumentProxy` class was added today, there's no chance that it'd include a `destroy` method.
2026-05-09 13:20:39 +02:00
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
Calixte Denizet
29fcf0aa76
Avoid cycles when getting operator list in patterns 2026-05-07 22:30:51 +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
Calixte Denizet
b39440b6e0
Simplify '#getFilteredPageIndices' and '#resolveInsertAfterIndices' 2026-05-07 21:41:37 +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
Tim van der Meij
e81507c167
Merge pull request #21228 from calixteman/bug2027682
Place new annotations on the correct page when extracting pages (bug 2027682)
2026-05-07 21:12:15 +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
3f6a2feef6 Tweak the WasmImage implementation a little bit (PR 21225 follow-up)
This fixes two things that I overlooked in PR 21225, more specifically:

 - Use proper, rather than semi, private class fields in `WasmImage`.

 - Make tracking of `WasmImage` instances optional, to avoid keeping data alive permanently in the `IMAGE_DECODERS` build.
2026-05-06 17:52:35 +02:00
saripovdenis
473f9b4592 Avoid quadratic traversal in NameOrNumberTree.getAll
Using Array.prototype.shift() to drain the traversal queue makes each
visited node move the remaining queued entries. For large name/number
trees this can make getAll() spend quadratic time in queue management.

Iterate over the queue with for...of instead. Children pushed while
iterating are still visited, and the queue no longer needs repeated
front removals.
2026-05-06 09:51:57 +08:00
Tim van der Meij
ac51bdf745
Merge pull request #21222 from Snuffleupagus/getPdfFilenameFromUrl-tweaks
A couple of small tweaks of the `getPdfFilenameFromUrl` helper
2026-05-05 20:27:55 +02:00
Jonas Jenwald
6ff0f8690f Add an abstract WasmImage class, that JBig2CCITTFaxImage and JpxImage inherit from
Given that these classes are, with the exception of their `decode` methods, virtually identical this helps reduce code duplication and simplifies maintenance.

These changes reduce the size of the `gulp mozcentral` build-target by `1292` bytes, which obviously isn't a lot but still cannot hurt.
2026-05-05 17:25:18 +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
ac6a9230d1 Replace TrueTypeTableBuilder and CompilerOutput with a single class
Given that both of these classes are so similar, let's replace them with a single `DataBuilder` class instead to reduce unnecessary code-duplication.
2026-05-04 15:01:53 +02:00
Jonas Jenwald
53fd89682c Remove the unused raw field from the CFFCharset class
This was necessary before charset compilation was implemented, however that's been supported for many years and this is just dead code now.
 - PR 9340, back in 2018, stopped using the `raw` field.
 - PR 10591, back in 2019, implemented proper charset compilation.
2026-05-03 18:51:24 +02:00
Jonas Jenwald
027671e6dc Replace a loop with TypedArray.prototype.set() in the compileFDSelect method
Given that the `fdSelect.fdSelect` data is a regular Array, this code can simplified a tiny bit.
2026-05-03 16:32:48 +02:00