Commit Graph

648 Commits

Author SHA1 Message Date
Jonas Jenwald
82a0bcecfa Skip transfers, in LoopbackPort.postMessage, for PDF.js legacy-builds (issue 16255)
Apparently the `structuredClone` polyfill doesn't handle transfers correctly, and `DOMException`s may thus be thrown. This is particularly problematical in Node.js environments, where that exception (obviously) isn't available.

To work-around these issues we'll simply ignore any transfers in `legacy`-builds, since those *may* use the `structuredClone` polyfill. This will obviously lead to slightly higher memory usage in those builds, however this really only affects Node.js environments. (Browsers are only affected if workers are disabled, however that's never been an officially recommended/supported configuration.)
2023-04-12 14:18:29 +02:00
Jonas Jenwald
b35c03ac3a [api-minor] Remove the canvasFactory option from PDFPageProxy.render (PR 16100 follow-up) 2023-04-01 16:00:31 +02:00
Jonas Jenwald
8b7e44682c
Merge pull request #16159 from nmtigor/b-Object_in_api
Write some {Object} in api.js more precise
2023-04-01 15:57:46 +02:00
Jonas Jenwald
5063a6f2a9 [api-minor] Remove the disableCombineTextItems option
*Please note:* This parameter has never been used within the PDF.js library/viewer itself, and it was only ever added for backwards compatibility reasons.

This parameter was added in PR 7475, over six years ago, to try and optionally maintain the previous *default* text-extraction behaviour.
However as part of the general text-extraction improvements in PR 13257, almost two years ago, the `disableCombineTextItems` functionality was accidentally "broken" in various ways. Note how the only (very basic) unit-test was updated in a way that doesn't really make sense, since generally speaking you'd expect that using the option should result in *more* (or at least the same number of) text-items. Furthermore there's also the recent issue 16209, where the option causes almost all textContent to be concatenated together.

Hence this patch proposes that we simply remove the `disableCombineTextItems` option since it's essentially unused/untested functionality, as evident from the fact that it took almost two years for someone to notice that it's broken.
2023-03-30 14:23:38 +02:00
nmtigor
167b363eb3 Write some {Object} in api.js more precise 2023-03-25 22:00:06 +01:00
Jonas Jenwald
378caa7203 Slightly reduce the size of the FontInspector-integration in the API
Given that this functionality only applies in the viewer, when `PDFBug` is being enabled and used, it can't hurt to slightly reduce the size of this code.
2023-03-23 14:07:10 +01:00
calixteman
8bfebf1c24
Merge pull request #16188 from calixteman/bug1823296
Use the position of the previous xref stream if any when saving a pdf (bug 1823296)
2023-03-21 21:21:49 +01:00
Calixte Denizet
2d0f30a67c Use the position of the previous xref stream if any when saving a pdf (bug 1823296) 2023-03-21 19:27:24 +01:00
Jonas Jenwald
b1e0253f29
Merge pull request #16175 from Snuffleupagus/LoopbackPort-transfer
Fix the `transfer` parameter, for `structuredClone`, in the `LoopbackPort`
2023-03-20 14:22:09 +01:00
Jonas Jenwald
cc9f6650a8 Stop passing in pageColors to the CanvasGraphics-constructor (PR 16075 follow-up)
The `pageColors`-option was removed from the `CanvasGraphics`-constructor in PR 16075, hence the code in the API no longer needs to pass in that option; this is something that I missed during review.
2023-03-20 11:41:57 +01:00
Jonas Jenwald
c4a725fe98 Fix the transfer parameter, for structuredClone, in the LoopbackPort
The way that we handle the `transfer` parameter is unfortunately wrong, ever since PR 14392 which introduced the code, given that the MDN article originally contained incorrect information; please see https://github.com/mdn/content/pull/23164

By updating the `structuredClone` call such that it works correctly, we can enable more unit-tests in Node.js environments; please refer to https://developer.mozilla.org/en-US/docs/Web/API/structuredClone#parameters
2023-03-19 22:04:01 +01:00
Calixte Denizet
da080cc26e [api-minor] Use a SVG filter when rendering pages in HCM
The idea is to apply an overall filter on each page: the main advantage
is to have some filtered images which could help to make them visible for
some users.
2023-03-18 12:45:10 +01:00
Jonas Jenwald
5e4b3d13eb
Merge pull request #16151 from Snuffleupagus/DefaultFilterFactory
[api-minor] Extend general transfer function support to browsers without `OffscreenCanvas`
2023-03-14 14:03:26 +01:00
Jonas Jenwald
50c844c5b8 Stop including isOffscreenCanvasSupported in the "StartRenderPage" message
With the previous commit this is now completely unused in API, hence it can be removed. This is done in a separate commit to make it easier to re-instate it, would the need ever arise.
2023-03-14 13:09:20 +01:00
Jonas Jenwald
fc055dbd80 [api-minor] Extend general transfer function support to browsers without OffscreenCanvas
This patch extends PR 16115 to work in all browsers, regardless of their `OffscreenCanvas` support, such that transfer functions will be applied to general rendering (and not just image data).
In order to do this we introduce the `BaseFilterFactory` that is then extended in browsers/Node.js environments, similar to all the other factories used in the API, such that we always have the necessary factory available in `src/display/canvas.js`.

These changes help simplify the existing `putBinaryImageData` function, and the new method can easily be stubbed-out in the Firefox PDF Viewer.

*Please note:* This patch removes the old *partial* transfer function support, which only applied to image data, from Node.js environments since the `node-canvas` package currently doesn't support filters. However, this should hopefully be fine given that:
 - Transfer functions are not very commonly used in PDF documents.
 - Browsers in general, and Firefox in particular, are the *primary* development target for the PDF.js library.
 - The FAQ only lists Node.js as *mostly* supported, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2023-03-14 13:09:08 +01:00
Jonas Jenwald
103fda1d91 Update the canvasContext parameter, in RenderParameters (issue 16133)
Hopefully this works correctly (since I don't know anything about TypeScript), given that `CanvasRenderingContext2D` is a standard name; please see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
2023-03-13 16:56:36 +01:00
Tim van der Meij
9819f1cc6b
Merge pull request #16108 from Snuffleupagus/delay-cleanup
Slightly delay cleanup, after rendering, in documents with large images
2023-03-11 15:52:12 +01:00
Jonas Jenwald
92296fa6a1 Include the document-id in the SVG-filter names (PR 16062 follow-up)
In the general PDF.js library multiple PDF documents may be opened on the same web-page, which is why we many years ago started using document-specific identifiers to prevent issues with global data such e.g. with fonts.
Hence we need to treat the identifiers generated by the `FilterFactory` in the same way, since the SVG-filters for two separate PDF documents may otherwise get identical ids.
2023-03-09 15:35:29 +01:00
Jonas Jenwald
c0671ac133 Slightly increase the maximum image sizes that we'll cache
The current value originated in PR 2317, and in the decade that have passed the amount of RAM available in (most) devices should have increased a fair bit.
Nowadays we also do a much better job of detecting repeated images at both the page- and document-level, which helps reduce overall memory-usage in many documents.

Finally the constant is also moved into the `src/shared/util.js` file, since it was implicitly used on both the main- and worker-thread previously.
2023-03-08 17:06:10 +01:00
Jonas Jenwald
15d9faba57 Slightly delay cleanup, after rendering, in documents with large images
Currently in PDF documents with large images we immediately cleanup once rendering has finished, in order to reduce memory-usage.
Normally that shouldn't be a big problem, however when e.g. repeated zooming happens in the viewer that could easily lead to a lot of wasted resources (and waiting).

Hence this patch, which introduces a new `PDFPageProxy` method that will slightly delay cleanup after rendering.
2023-03-08 17:06:09 +01:00
Jonas Jenwald
e7a7f02f4c Convert a couple of fields/methods into properly private ones in PDFPageProxy
These were always intended to be *private*, so let's use modern JS features to actually enforce that.
2023-03-08 17:06:09 +01:00
Jonas Jenwald
6839f15a32
Merge pull request #16128 from Snuffleupagus/issue-16127
Support (rare) Type3 fonts with Pattern resources (issue 16127)
2023-03-08 12:21:53 +01:00
Jonas Jenwald
e5427ab11b
Merge pull request #16122 from Snuffleupagus/rm-onUnsupportedFeature
[api-minor] Remove the deprecated `onUnsupportedFeature` functionality (PR 15758 follow-up)
2023-03-08 12:16:27 +01:00
Calixte Denizet
e9474f1c84 [api-minor] Add an option to set the max canvas area 2023-03-08 10:37:06 +01:00
Jonas Jenwald
471aef5fc6 Support (rare) Type3 fonts with Pattern resources (issue 16127)
This simply extends the approach in PR 10727 to also cover Patterns, which shouldn't be a common occurrence in Type3 fonts (since this is the first issue we've seen).
2023-03-08 09:20:52 +01:00
Jonas Jenwald
2f3dcc2327 [api-minor] Remove the deprecated onUnsupportedFeature functionality (PR 15758 follow-up)
This was deprecated in PR 15758, which has now been included in three official PDF.js releases.
While PR 15880 did limit the bundle-size impact of this functionality on e.g. the Firefox PDF Viewer, it still leads to some unnecessary "bloat" that these changes remove.
Furthermore, with this being deprecated there'd also be no effort put into e.g. extending the `UNSUPPORTED_FEATURES` list when handling future error cases.
2023-03-07 10:18:43 +01:00
Jonas Jenwald
ceec93c832
[api-minor] Remove calling getDocument directly with a PDFDataRangeTransport-instance (PR 15943 follow-up)
This was deprecated in PR 15943, which has now been included in two official PDF.js releases.
Given that `PDFDataRangeTransport` is somewhat unlikely to be used outside of the *built-in* Firefox PDF Viewer, it doesn't seem necessary to wait longer before removing this.

Also, removes the specific error-message for GENERIC builds to not unnecessarily "advertise" using non-objects when calling the `getDocument`-function.

*Please note:* This patch is written using the GitHub UI, since I'm currently without a dev machine, so hopefully it works correctly.
2023-03-02 15:12:01 +01:00
Calixte Denizet
fd03cd5493 [api-minor] Generate images in the worker instead of the main thread.
We introduced the use of OffscreenCanvas in #14754 and this patch aims
to use them for all kind of images.
It'll slightly improve performances (and maybe slightly decrease memory use).
Since an image can be rendered in using some transfer maps but because of
OffscreenCanvas we don't have the underlying pixels array the transfer maps
stuff is re-implemented in using the SVG filter feComponentTransfer.
2023-03-01 17:40:12 +01:00
Jonas Jenwald
f42a2e8451
[api-minor] Move the canvasFactory option into getDocument
Rather than repeatedly initializing a `canvasFactory`-instance for every page, move it to the document-level instead.

*Please note:* This patch is written using the GitHub UI, since I'm currently without a dev machine, so hopefully it works correctly.
2023-03-01 09:07:16 +01:00
Calixte Denizet
3a21423386 [Acroform] Use the full path to find the node in the XFA datasets where to store the value
I noticed several 'Path not found' errors because of a field called #subform[2].
From the XFA specs, the hash is used for a class of elements in the template tree.
When we're looking for a node in the datasets tree, it doesn't make sense to search
for a class. Hence the path element starting with a hash are just skipped.
2023-02-23 12:09:39 +01:00
Jonas Jenwald
1b076b7a35
Move the ImageBitmap clean-up into the PDFObjects class
With upcoming changes we'll potentially start to cache `ImageBitmap` data at the document-level, in addition to just at the page-level.
Hence we need to ensure that such data is actually released on clean-up, and rather than duplicating the existing *manual* handling this code is instead moved into the `PDFObjects.clear` method. (In my opinion, this is an overall improvement even without globally cached `ImageBitmap` data.)

*Please note:* This patch is written using the GitHub UI, since I'm currently without a dev machine, so hopefully it's correct and makes sense.
2023-02-21 12:00:45 +01:00
Jonas Jenwald
b6ba8cc84a [api-minor] Deprecate providing binary data as Buffer in Node.js environments
The `Buffer`-object is Node.js specific functionality[1], thus (obviously) not found in browsers. Please note that the PDF.js library has never officially supported/documented that binary data can be passed as a `Buffer`, and that *internally* in the `src/core`-code we only work with standard `Uint8Array`s.
This means that if, in Node.js environments, a `Buffer` is passed to the API we need to wrap it into a `Uint8Array`, which essentially means creating a copy of the data and thus increasing memory usage.

---
[1] Refer to https://nodejs.org/api/buffer.html#buffer
2023-02-14 11:30:40 +01:00
Jonas Jenwald
df3b359280 Remove "else after return" from the getUrlProp/getDataProp helper functions
This helps readability of this code a little bit, in my opinion, and it's actually ever so slightly less code in the *built* `pdf.js` file.
2023-02-14 10:50:22 +01:00
Jonas Jenwald
9d29abdfa0 Change the LoopbackPort class to use a Set internally
This is a tiny bit more compact, thanks to the `Set.prototype.delete` method.
2023-02-09 12:34:41 +01:00
Jonas Jenwald
0a0f3fc733 Move the main-thread CMap/StandardFontData factory initialization to getDocument
By default we're using worker-thread fetching (in browsers) of this data nowadays, however in Node.js environments or if the user provides custom factories we still fallback to main-thread fetching.
Hence it makes sense, as far as I'm concerned, to move this initialization into the `getDocument` function to ensure that the factories can actually be initialized *before* attempting to load the document.

Also, this further reduces the amount of `getDocument` parameters that we need to pass into into the `WorkerTransport` class.
2023-02-05 11:52:35 +01:00
Jonas Jenwald
ce8ac6d96a Only pass the necessary parameters to _fetchDocument and WorkerTransport
Currently we're passing all available parameters to this function respectively class, despite that not actually being necessary.
By splitting the parameters we not only improve the structure, and basically "document" the code a little bit, but we can also simplify the `_fetchDocument` function considerably.
2023-02-05 11:52:33 +01:00
Jonas Jenwald
512aa50fdd Re-factor the parameter parsing/validation in getDocument
This is very old code, where we loop through the user-provided options and build an internal parameter object. To prevent errors we also need to ensure that the parameters are correct/valid, which is especially important for the ones that are sent to the worker-thread such that structured cloning won't fail.[1]

Over the years this has led to more and more code being added in `getDocument` to validate the user-provided options, and at this point *most* of them have at least basic validation. However the way that this is implemented feels slightly backwards, since we first build the internal parameter object and only *afterwards* validate those parameters.[2]

Hence this patch changes the `getDocument` function to instead check/validate the supported options upfront, and then *explicitly* build the internal parameter object with only the needed properties.

---
[1] Note the supported types at https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types

[2] The internal parameter object may also, because of the loop, end up with lots of unnecessary properties since anything that the user provides is being copied.
2023-02-05 11:52:25 +01:00
Tim van der Meij
e698664927
Merge pull request #16004 from Snuffleupagus/WorkerTransport-cacheSimpleMethod
Improve how we cache Promises in `WorkerTransport`
2023-02-04 15:13:12 +01:00
Tim van der Meij
b75dafba87
Merge pull request #15987 from Snuffleupagus/onOpenWithTransport-params
Remove unused parameters from the `onOpenWithTransport` method in `PDFViewerApplication.initPassiveLoading`
2023-02-04 15:07:42 +01:00
Tim van der Meij
e848a0e61c
Merge pull request #15981 from Snuffleupagus/cMapPacked-true
[api-minor] Let the `cMapPacked` parameter, in `getDocument`, default to `true`
2023-02-04 15:00:26 +01:00
Jonas Jenwald
2de03a7d91 Improve how we cache Promises in WorkerTransport
A number of methods have their Promises cached, to avoid repeated worker round-trips, since they're expected to be called more than once from the default viewer. The way that the caching is currently implemented means that we need to remember to manually clear these Promises on document cleanup/destruction, and it'd be nice to avoid that.

With this patch the relevant Promises are now instead placed in just one `Map`, which is easy to clear, and a new helper method is also introduced to reduce duplication for *simple* `WorkerTransport` methods.
2023-02-04 11:57:37 +01:00
Jonas Jenwald
cf8ee47589 Remove unused parameters from the onOpenWithTransport method in PDFViewerApplication.initPassiveLoading
The only parameter that we actually need here is the `PDFDataRangeTransport`-instance, since the others are not necessary.
 - The `url` parameter, as passed to the `getDocument` function in the API, is simply being ignored; see 2d87a2eb1c/src/display/api.js (L447-L458)
 - The `length` parameter, as passed to the `getDocument` function in the API, is always being overwritten; see 2d87a2eb1c/src/display/api.js (L519-L525)
2023-02-01 09:33:22 +01:00
Jonas Jenwald
5e88228767 Allow, optionally, using worker-modules during local development
Until PR 12563 is deemed safe to land, I'd still like to be able to use worker-modules in the viewer during local development.
Hence this patch which *temporarily* adds a new `workerModules` hash-parameter, only available in non-PRODUCTION mode, that allows using worker-modules in the development viewer.

To enable this functionality, simply use http://localhost:8888/web/viewer.html#workerModules=true
2023-01-31 12:09:44 +01:00
Jonas Jenwald
c5d6391898 [api-minor] Let the cMapPacked parameter, in getDocument, default to true
The initial CMap support was added in PR 4259 using the "raw" Adobe files, however they were quickly deemed to be unnecessarily large. As a result PR 4470 introduced the more compact "binary" CMap format, with both of those PRs being included in the very same release (version `0.8.1334`) .

Please note that we've thus never shipped anything *except* the "binary" CMap files with the PDF library, and furthermore note that we've not even once updated the CMap files since they were originally added almost nine years ago.

Requiring users to remember that `cMapPacked = true` is necessary, in addition to setting the `cMapUrl` parameter, in order for CMap loading to work feels like a less than ideal API.
Hence this patch, which suggests that we simply let `cMapPacked` default to `true` now.
2023-01-30 15:35:02 +01:00
Tim van der Meij
e539d2da1e
Merge pull request #15964 from Snuffleupagus/getDocument-non-object
Only accept non-objects passed to `getDocument` in GENERIC builds
2023-01-28 18:42:09 +01:00
Jonas Jenwald
4758e6649c Only accept non-objects passed to getDocument in GENERIC builds
In general it's always recommended to pass a *parameter object* when calling the `getDocument`-function in the API, since that's the only way to provide additional options, and the fact that it also accepts a URL or TypedArray directly is now mostly for backwards compatibility reasons.
Unfortunately we cannot really remove this, since that code has existed since "forever", however we can limit it to only the GENERIC build to avoid completely unnecessary checks in e.g. the Firefox PDF Viewer.

Finally, note that the default-viewer always provides a *parameter object* when calling the `getDocument`-function and it's thus completely unaffected by these changes.
2023-01-26 10:48:58 +01:00
Jonas Jenwald
755319130e Tweak the internal handling of the url-parameter in getDocument (PR 13166 follow-up)
- Use a `URL`-instance directly, since it's by definition an absolute URL.
 - Actually limit the "raw" url-string handling to Node.js environments, as intended.
 - Skip the warning, since we're already throwing an Error if the `url`-parameter is invalid.
2023-01-24 11:18:41 +01:00
Jonas Jenwald
7976fc7851 [api-minor] Deprecate calling getDocument directly with a PDFDataRangeTransport-instance
In general it's recommended to pass a *parameter object* when calling the `getDocument`-function in the API, since that's the only way to provide additional options, and the fact that it also accepts a URL or TypedArray directly is now mostly for backwards compatibility reasons.
However, the `getDocument`-function also accepts a direct `PDFDataRangeTransport`-instance which just seems unnecessary.

*Please note:* The `PDFDataRangeTransport`-implementation was added specifically for the *built-in* Firefox PDF Viewer, however it's most likely not commonly used by any third-party (given that it requires manual PDF-data loading).
Furthermore, the default-viewer always provides a *parameter object* when calling the `getDocument`-function and it's thus completely unaffected by these changes.
2023-01-19 14:25:55 +01:00
Jonas Jenwald
397f943ca3 [api-minor] Enable transferring of TypedArray PDF data by default (PR 15908 follow-up)
This patch removes the recently introduced `transferPdfData` API-option, and simply enables transferring of TypedArray data *by default* instead of copying it. This will help reduce main-thread memory usage, however it will take ownership of the TypedArrays. Currently this only applies to the following cases:
 - TypedArrays passed to the `getDocument`-function in the API, in order to open PDF documents from binary data.
 - TypedArrays passed to a `PDFDataRangeTransport`-instance, used to support custom PDF document fetching/loading (see e.g. the Firefox PDF Viewer).

*PLEASE NOTE:* To avoid being affected by this, please simply *copy* any TypedArray data before passing it to either of the functions/methods mentioned above.

Now that we transfer TypedArray data that we previously only copied, we need to be more careful with input validation. Given how the `{IPDFStreamReader, IPDFStreamRangeReader}.read` methods will always return ArrayBuffer data, which is then transferred to the worker-thread[1], the actual TypedArray data passed to the API thus need to have the same exact size as its underlying ArrayBuffer to prevent issues.
Hence we'll check for this and only allow transferring of *safe* TypedArray data, and fallback to simply copying the data just as before. This obviously shouldn't be an issue in the Firefox PDF Viewer, but for the general PDF.js library we need to be more careful here.

---
[1] See e09ad99973/src/display/api.js (L2492-L2506) respectively e09ad99973/src/display/api.js (L2578-L2590)
2023-01-14 10:39:36 +01:00
Jonas Jenwald
99cfab18c1 Combine the array-like and ArrayBuffer branches, when handling binary data, in getDocument 2023-01-13 13:28:44 +01:00