113 Commits

Author SHA1 Message Date
Calixte Denizet
bb2a1126e6 Use a binary format for the glyph paths
We used a SVG string which can be pass to the Path2D ctor but it's a bit slower than
building the path step by step.
Having numerical data instead of a string will help the font data serialization.
2025-10-16 15:52:51 +02:00
Ujjwal Sharma
4bed7370f4 [WIP] Serialize font data into an ArrayBuffer
This PR serializes font data into an ArrayBuffer
that is then transfered from the worker to the
main thread. It's more efficient than the current
solution which clones the "export data" object
which includes the font data as a Uint8Array.

It prepares us to switch to a SharedArrayBuffer
in the future, which would allow us to share
the font data with multiple agents, which would be
crucial for the upcoming "renderer" worker.
2025-09-19 12:02:40 +05:30
Jonas Jenwald
da17c7b82f
Merge pull request #19548 from Snuffleupagus/Font-exportData-disableFontFace-fontExtraProperties
Send `disableFontFace` and `fontExtraProperties` as part of the exported font-data
2025-02-26 11:25:29 +01:00
Jonas Jenwald
2966171a2b Fix the assert in FontLoader.prototype.loadSystemFont
Currently this `assert` isn't actually doing what it's supposed to, since the `FontLoader`-class doesn't have a `disableFontFace`-field.
The `FontFaceObject`-class on the other hand has such a field, hence we update the method-signature to be able to check the intended thing.
2025-02-24 16:09:07 +01:00
Jonas Jenwald
839e23f5c2 Send disableFontFace and fontExtraProperties as part of the exported font-data
These options are needed in the `FontFaceObject` class, and indirectly in `FontLoader` as well, which means that we currently need to pass them around manually in the API.
Given that the options are (obviously) available on the worker-thread, it's very easy to just provide them when creating `Font`-instances and then send them as part of the exported font-data. This way we're able to simplify the code (primarily on the main-thread), and note that `Font`-instances even had a `disableFontFace`-field already (but it wasn't properly initialized).
2025-02-24 09:34:48 +01:00
Jonas Jenwald
33f3506842 Use the FeatureTest helper in the src/display/font_loader.js file 2025-02-06 20:45:18 +01:00
Jonas Jenwald
6153b15231 Remove the raw path-strings after creating the actual Path2D glyph-objects
The `Path2D` glyph-objects are cached on the `FontFaceObject`-instance, so we can save a little bit of memory by removing the raw path-strings once they're no longer needed.
2024-12-09 15:09:18 +01:00
Calixte Denizet
2b05924504 Improve perfs of the font renderer
Some SVG paths are generated from the font and used in the main thread
to render the glyphs.
2024-12-08 17:12:10 +01:00
Calixte Denizet
79e1f155ac Apply gradient when stroking text
It fixes #19022.

I noticed that the glyph contours weren't correct (for T and x) and
because we forgot to close the contour.
2024-11-11 15:53:07 +01:00
Jonas Jenwald
8f47d06d07 Add helper functions to allow using new Uint8Array methods
This allows using the new methods in browsers that support them, e.g. Firefox 133+, while still providing fallbacks where necessary; see https://github.com/tc39/proposal-arraybuffer-base64

*Please note:* These are not actual polyfills, but only implements what we need in the PDF.js code-base. Eventually this patch should be reverted, once support is generally available.
2024-10-29 10:22:35 +01:00
Jonas Jenwald
bfc645bab1 Introduce some Uint8Array.fromBase64 and Uint8Array.prototype.toBase64 usage in the main code-base
See https://github.com/tc39/proposal-arraybuffer-base64
2024-10-29 10:22:35 +01:00
Jonas Jenwald
5f6f1686b5 Remove the ignoreErrors option from the FontFaceObject class
- The `stopAtErrors` API option, which is the inverse of the "internal" `ignoreErrors` option, is explicitly documented as applying to *parsing* (i.e. the worker-thread) while the `FontFaceObject` class is used during rendering (i.e. the main-thread); see b6765403a1/src/display/api.js (L164-L167)

 - A glyph that fails in the `FontRendererFactory`, on the worker-thread, will already cause (overall) parsing to stop when `ignoreErrors === false` hence checking the option on the main-thread as well seems redundant; see b6765403a1/src/core/evaluator.js (L4527-L4533)

 - Removing this option simplifies the code, and slightly reduces the number of options that we need to handle in the main-thread code.
2024-05-11 10:18:23 +02:00
Calixte Denizet
551e63901c Simplify the way to pass the glyph drawing instructions from the worker to the main thread
and remove the use of eval in the font loader.
2024-04-27 21:28:31 +02:00
Jonas Jenwald
c1fef7d2f2 Guard navigator-object accesses in src/-files (issue 15728)
There are environments that include *incomplete* polyfills for the `navigator`-object, which may thus cause the PDF.js library to break.
Despite that clearly not being our fault, it may still result in bug reports filed against the PDF.js project; see e.g. 15728.

Currently this even seem to affect *the latest* version of Node.js; see e.g. [here].

*Please note:* Thanks to the pre-processor none of these changes affect the Firefox PDF Viewer, however it does add "overhead" when working with and reviewing the affected code (which is why I'm not crazy about this).
2023-10-28 14:41:46 +02:00
Calixte Denizet
7851c0da8d [Debugger] Add some info about substitution font
When pdfBug is true, the substitution font is used in the text layer in order
to be able to know what is the font really used thanks to the devtools.
And to be sure that fonts are loaded, the font cache isn't cleaned up when
the debugger is active.
2023-10-09 12:06:33 +02:00
Jonas Jenwald
3a886e7264 Move the isNodeJS-helper into the src/shared/util.js file
With the changes in the previous patch the `isNodeJS`-helper no longer needs to live in its own file, which helps get rid of a closure in the *built* files.
2023-07-17 16:42:25 +02:00
Calixte Denizet
385f275ad9 Warn when pdf.js can't load an OS font 2023-05-16 14:58:38 +02:00
Calixte Denizet
d4b70ec306 For missing font, use a local font if it exists even if there's no standard substitution
If the font foo is missing we just try lo load local(foo) and maybe
we'll be lucky.
2023-05-13 21:54:27 +02:00
Calixte Denizet
cfb908c999 Add a cache to avoid to load several times a local font
On my computer, it takes few tenths of a second to load a local font.
Since a font can be used several times in a document, the cache will
improve performances.
2023-05-10 20:01:21 +02:00
Calixte Denizet
53134c0c0b [api-minor] Use a local font or fallback on an embedded one (if it exists) for non-embedded fonts (bug 1766039)
- Replace FoxitSans with LiberationSans: LiberationSans is already there (for XFA) and we can use
it as a good replacement of FoxitSans.
- For now we just try to substitue standard fonts, the strategy is the following:
  * we try to find a font locally from a hardcoded list;
  * if it fails then we use Liberation as fallback (only for Helvetica for the moment);
  * else we just fallback on the system serif/sansserif/monospace font.
2023-05-10 14:10:23 +02:00
Jonas Jenwald
804aa896a7 Stop using the PRODUCTION build-target in the JavaScript code
This *special* build-target is very old, and was introduced with the first pre-processor that only uses comments to enable/disable code.
When the new pre-processor was added `PRODUCTION` effectively became redundant, at least in JavaScript code, since `typeof PDFJSDev === "undefined"` checks now do the same thing.

This patch proposes that we remove `PRODUCTION` from the JavaScript code, since that simplifies the conditions and thus improves readability in many cases.
*Please note:* There's not, nor has there ever been, any gulp-task that set `PRODUCTION = false` during building.
2023-04-17 12:04:34 +02: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
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
1a69d537c1 [api-minor] Limit the PDFDocumentLoadingTask.onUnsupportedFeature functionality to GENERIC builds (PR 15758 follow-up)
This was deprecated in PR 15758 but it's unfortunately quite difficult to tell if third-party users are depending on this, e.g. to implement custom error reporting, and if so to what extent.
However, thanks to the pre-processor we can limit *most* of this code to GENERIC builds which still seem like a worthwhile change.

These changes reduce the bundle size of the Firefox PDF Viewer by 3.8 kB in total.
2023-01-01 17:53:12 +01:00
Jonas Jenwald
85f03c0ea4 Slightly modernize the FontLoader.isSyncFontLoadingSupported getter
This is very old code, which is unused (by default) in browsers nowadays since the Font Loading API will always be preferred.
For Node.js environments we use the same constant as elsewhere throughout the code-base, and we can also simplify the Firefox-specific check given that the lowest supported version is `102` (as of this writing).

Finally the old TODO is removed, since the general availability of the Font Loading API has made it redundant.
2022-11-27 12:19:11 +01:00
Jonas Jenwald
8e4ef6d89d [api-minor] Stop setting an id on the styleElement used with CSS font-loading
This is yet another small piece of clean-up of the `FontLoader`-code, since we've not used this `id`-property for anything ever since PR 6571 (which landed almost seven years ago). Furthermore, by default we're also not even using that code-path now since the Font Loading API will always be used when available.

*Please note:* This is tagged `[api-minor]` since it's technically observable from the outside, however no user ought to be directly interacting with these CSS font rules.
2022-10-02 12:01:33 +02:00
Jonas Jenwald
9ce2427e79 [Firefox viewer] Skip some unnecessary code in the FontLoader.bind method
Given that Firefox supports *synchronous* font loading, when the Font Loading API isn't being used, there's really no point including code which if called would just throw in the MOZCENTRAL build. (This is safe, since the `FontLoader.isSyncFontLoadingSupported`-getter always return `true` there.)
2022-09-26 15:18:22 +02:00
Jonas Jenwald
2161f334a0 Remove the ability to pass in more than one font to the _prepareFontLoadEvent method (PR 10539 follow-up)
After the changes in PR 10539 (which landed over three years ago) the `FontLoader.bind` method can only be called with *a single* font at a time, hence the `_prepareFontLoadEvent` method obviously don't need to support multiple fonts any more.
2022-09-26 13:33:52 +02:00
Jonas Jenwald
ca05b650aa Remove the unused rules parameter from the _prepareFontLoadEvent method (PR 3477 follow-up)
This is yet another small piece of functionality that became unused in PR 3477 (which landed nine years ago).
2022-09-26 13:26:14 +02:00
Jonas Jenwald
ad83fbe2a1 Replace the BaseFontLoader classes with one FontLoader class
By having just *one* class, and using pre-processor blocks directly in the relevant methods, we reduce the size of this code in the *built* `pdf.js` file.
Originally, when the `BaseFontLoader` abstraction was added in PR 9982, the idea was probably that additional build-targets would get their own implementations. Given that this hasn't happened in the four years since that landed, it doesn't seem meaningful to keep it around.
2022-09-25 12:31:58 +02:00
Jonas Jenwald
9a03d36af4 Remove some unused code from the _queueLoadingCallback method (PR 3477 follow-up)
The existing `loadingContext` class-property can be simplified slightly, since we've not been using the `id`-property on the requests ever since PR 3477 (which landed nine years ago).
Furthermore, by default we're also not even using that code-path now since the Font Loading API will always be used when available.
2022-09-25 10:41:06 +02:00
Jonas Jenwald
38ee28b1d3 Use more optional chaining in the code-base
This patch updates a bunch of older code, that makes conditional function calls, to use optional chaining rather than `if`-blocks.

These mostly mechanical changes reduce the size of the `gulp mozcentral` build by a little over 1 kB.
2022-09-05 15:41:53 +02:00
Jonas Jenwald
f6db7975c5 Enable the ESLint prefer-spread rule
Note that in a couple of spots the argument could be `undefined` and there we simply disable the rule instead.

Please refer to https://eslint.org/docs/latest/rules/prefer-spread
2022-08-06 10:17:00 +02:00
Jonas Jenwald
8129815538 Enable the unicorn/prefer-dom-node-append ESLint plugin rule
This rule will help enforce slightly shorter code, especially since you can insert multiple elements at once, and according to MDN `Element.append()` is available in all browsers that we currently support.

Please find additional information here:
 - https://developer.mozilla.org/en-US/docs/Web/API/Element/append
 - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-append.md
2022-06-12 13:07:03 +02:00
Jonas Jenwald
1dc4713a0b Re-factor the isLittleEndian/isEvalSupported caching
This functionality is very old, hence we should be able to improve the caching a little bit with modern JavaScript features.
2022-04-05 16:01:01 +02:00
Jonas Jenwald
4ef1a129fa Replace the remaining Node.removeChild() instances with Element.remove()
Using `Element.remove()` is a slightly more compact way of removing an element, since you no longer need to explicitly find/use its parent element.
Furthermore, the patch also replaces a couple of loops that're used to delete all elements under a node with simply overwriting the contents directly (a pattern already used throughout the viewer).

See also:
 - https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
 - https://developer.mozilla.org/en-US/docs/Web/API/Element/remove
2021-11-16 17:52:50 +01:00
Calixte Denizet
63caa101f8 XFA - Add support for reftests 2021-06-08 10:37:26 +02:00
Jonas Jenwald
9ad7746118 Replace a couple of standard for-loops with for...of in src/display/font_loader.js 2021-05-25 14:11:57 +02:00
Jonas Jenwald
dcbb23d7fa Re-factor FontFaceObject.getPathGenerator to use Arrays instead of strings
This is similar to a lot of other code, where we use "Array + join" rather than repeated string concatenation.
2021-05-25 14:11:54 +02:00
Jonas Jenwald
90b5fcb8e0 Remove unnecessary TypedArray re-initialization in FontFaceObject.createFontFaceRule
The `this.data` property is, when defined, sent from the worker-thread as a `Uint8Array` and there's thus no reason to re-initialize the TypedArray here.
Note also the `FontFaceObject.createNativeFontFace` method just above, where we simply use `this.data` as-is.

The explanation for this code looking like it does is, as is often the case, for historical reasons. Originally we only supported `@font-face`, before the Font Loading API existed, and back then we also polyfilled TypedArrays (using regular Arrays) which should explain this particular line of code.
2021-05-01 19:20:36 +02:00
Jonas Jenwald
da22146b95 Replace a bunch of Array.prototype.forEach() cases with for...of loops instead
Using `for...of` is a modern and generally much nicer pattern, since it gets rid of unnecessary callback-functions. (In a couple of spots, a "regular" `for` loop had to be used.)
2021-04-24 13:00:19 +02:00
Calixte Denizet
7e9579045f XFA -- Load fonts permanently from the pdf
- Different fonts can be used in xfa and some of them are embedded in the pdf.
  - Load all the fonts in window.document.

Update src/core/document.js

Co-authored-by: Jonas Jenwald <jonas.jenwald@gmail.com>

Update src/core/worker.js

Co-authored-by: Jonas Jenwald <jonas.jenwald@gmail.com>
2021-04-15 17:57:42 +02:00
Jonas Jenwald
fec8c4c43f Access this._onUnsupportedFeature directly in FontFaceObject.getPathGenerator
Given that `FontFaceObject` is not exposed in the public API, but only accessed internally, there's no need to assume that a `FontFaceObject`-instance is ever initialized without `onUnsupportedFeature` being provided. This is also consistent with the `BaseFontLoader` implementation.
2021-01-29 16:48:55 +01:00
Jonas Jenwald
1dad255784 Convert files in the src/display/-folder to use optional chaining where possible
By using optional chaining, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining, it's possible to reduce unnecessary code-repetition in many cases.
Note that these changes also reduce the size of the *built* `pdf.js` file, when `SKIP_BABEL == true` is set, and for the `MOZCENTRAL` build-target that result in a `0.1%` filesize reduction from a simple and mostly mechanical code change.
2020-11-07 13:22:06 +01:00
Jonathan Grimes
ac723a1760 Allow loading pdf fonts into another document. 2020-08-08 02:52:32 +00:00
Jonas Jenwald
05baa4c89f
Revert "[api-minor] Allow loading pdf fonts into another document." 2020-08-01 12:52:39 +02:00
Jonathan Grimes
9b16b8ef71
Allow loading pdf fonts into another document. 2020-07-31 11:41:48 -05:00
Brendan Dahl
b1be33c96f Add more categories of unsupported features.
Fixes #11815
2020-05-04 11:02:16 -07:00
Jonas Jenwald
426945b480 Update Prettier to version 2.0
Please note that these changes were done automatically, using `gulp lint --fix`.

Given that the major version number was increased, there's a fair number of (primarily whitespace) changes; please see https://prettier.io/blog/2020/03/21/2.0.0.html
In order to reduce the size of these changes somewhat, this patch maintains the old "arrowParens" style for now (once mozilla-central updates Prettier we can simply choose the same formatting, assuming it will differ here).
2020-04-14 12:28:14 +02:00
Jonas Jenwald
e4758beaaa Move IsLittleEndianCached and IsEvalSupportedCached to src/shared/util.js
Rather than duplicating the lookup and caching in multiple files, it seems easier to simply move all of this functionality into `src/shared/util.js` instead.
This will also help avoid a bunch of ESLint errors once the `no-shadow` rule is eventually enabled.
2020-03-12 11:36:26 +01:00