7662 Commits

Author SHA1 Message Date
Jonas Jenwald
7b1b1a9153 Reduce allocations in CFFCompiler.prototype.compileIndex (PR 21053 follow-up)
It's possible to compute the final index-data size upfront, thus avoiding a bunch of intermediate allocations during index compilation.
This also means that a TypedArray can be used, rather than a plain Array, making it more efficient to insert the `objects` data.

This helps PDFs with large and complex CFF fonts the most, for example the PDFs in https://bugs.ghostscript.com/show_bug.cgi?id=706451 render ~40 percent faster (based on quick measurements in the viewer with `#pdfBug=Stats`).
2026-04-07 18:38:10 +02:00
calixteman
f61e00f2fa
Merge pull request #21054 from calixteman/fix_writing_numbers
Fix the way to write numbers when saving a pdf
2026-04-07 16:55:36 +02:00
Jonas Jenwald
6f0431456c Reduce allocations when compiling CFF fonts
Currently the `CFFCompiler.prototype.compile` implementation seem a bit inefficient, since the data is stored in a plain Array that needs to grow (a lot) during compilation. Additionally, adding a lot of entries isn't very efficient either and requires special handling of the "too many elements" case.
Some of the "helper" methods that use TypedArrays internally currently need to convert their return data to plain Arrays, via the `compileTypedArray` method, which adds even more intermediate allocations.
Note also that the `OpenTypeFileBuilder` has a special-case for writing plain Array data, which is only needed because of how the CFF compilation is implemented.

To improve this situation the `CFFCompiler.prototype.compile` method is re-factored to store its data in a TypedArray, whose initial size is estimated from the "raw" file size.
This removes the need for most intermediate allocations, and it also handles adding of "many elements" more efficiently.
2026-04-07 14:27:55 +02:00
Calixte Denizet
3d95aab8d7
Fix the way to write numbers when saving a pdf
It'll avoid to have numbers like 1e-23.
2026-04-07 10:52:06 +02:00
Jonas Jenwald
f8d7c20a1a
Merge pull request #21051 from Snuffleupagus/writePDF-stringToBytes
Use the `stringToBytes` helper in the `PDFEditor.prototype.writePDF` method
2026-04-06 15:55:49 +02:00
Jonas Jenwald
ea12a28e2f Use the stringToBytes helper in the PDFEditor.prototype.writePDF method
This avoids effectively re-implementing an existing helper function, and the code is also simplified a tiny bit by building the final TypedArray header directly.
2026-04-06 14:58:21 +02:00
calixteman
a9f142c796
Unconditionally create a gpu device
One drawback of the current implementation is that the GPU device can be
unavailable at the time of the first pattern fill, which causes the
GPU-accelerated canvas to be move on the main thread because of putImageData.

Most of the shading patterns stuff will be moved to the GPU and in order
to avoid creating some useless data we've to know if the GPU is available or not.

So in this patch we create the GPU device during the worker initialization
and pass a flag to the evaluator to know if the GPU is available or not.
2026-04-06 13:23:29 +02:00
Jonas Jenwald
9f9be2c619 Use this more in static methods in the src/core/postscript/ folder
Inside of static methods it's possible to reference static fields with `this`, rather than having to spell out the full class name.
2026-04-05 14:22:08 +02:00
Jonas Jenwald
ccab310a39 Add an optional parameter in buildPostScriptJsFunction to force use of the PSStackBasedInterpreter code
This way the test-only function `buildPostScriptProgramFunction` can be removed.
2026-04-05 13:52:09 +02:00
Jonas Jenwald
d155506005 Remove unnecessary "flooring" of the components when setting the Annotation borderColor
This looks like a leftover from much older code, since all colors are now parsed with the [`getRgbColor` helper](ca85d73335/src/core/annotation.js (L558-L583)) which returns `Uint8ClampedArray` data when the color is valid.

Also, use spread syntax when calling `Util.makeHexColor` in a few more spots.
2026-04-05 11:23:32 +02:00
calixteman
b5dd450041
Merge pull request #21040 from Snuffleupagus/constructSampled-flat-arrays
Use the original array-data when parsing Type 0 (Sampled) Functions
2026-04-04 19:56:54 +02:00
Tim van der Meij
68da778329
Introduce a function type enumeration
This improves readability by removing "magic" numbers, and matches what
we already have for e.g. annotation and shading types.

Note that function type 1 does not exist in the specification, but that
also applies to everything higher than 4, so we can also remove the
specific handling of function type 1 and instead just let it fall
through to throwing an exception for unknown function types, in which we
now also log the provided function type to aid debugging.
2026-04-04 14:57:59 +02:00
Jonas Jenwald
fa344c1852 Use the original array-data when parsing Type 0 (Sampled) Functions
It seems just as easy to lookup the needed data in the original arrays, rather than having to first create (and allocate) nested arrays for that purpose.
2026-04-04 14:07:21 +02:00
Tim van der Meij
0b9f8fa950
Merge pull request #21036 from calixteman/fix_comment
Fix comments for (is/has)Singlefile in pdf_editor
2026-04-04 11:30:12 +02:00
Jonas Jenwald
fe35a87c85
Merge pull request #21005 from Snuffleupagus/rm-PostScriptCompiler
[api-minor] Remove `PostScriptCompiler` and `PostScriptEvaluator`, since it's now dead code (PR 21023 follow-up)
2026-04-04 11:02:34 +02:00
Jonas Jenwald
4cf0bf410b Remove the unused compilePostScriptToIR function (PR 21023 follow-up)
This function was added in PR 21010, and it became unused in PR 21023.
2026-04-03 22:47:12 +02:00
calixteman
b3e4932cca
Fix comments for (is/has)Singlefile in pdf_editor 2026-04-03 22:15:34 +02:00
Jonas Jenwald
f6bac014ea [api-minor] Remove PostScriptCompiler and PostScriptEvaluator, since it's now dead code (PR 21023 follow-up)
These classes, and various related code, became unused after PR 21023 with only unit-tests actually running that code now.

Also removes the `isEvalSupported` API option, since the `PostScriptCompiler` was the only remaining code where `eval` was used.
2026-04-03 22:14:14 +02:00
calixteman
5347c22703
Merge pull request #21020 from calixteman/issue7821
Fix the annotation base transform before drawing it
2026-04-03 21:26:48 +02:00
Calixte Denizet
1e3d688a32
Add an eslint plugin for using MathClamp when it's possible 2026-04-03 21:12:52 +02:00
Calixte Denizet
9ed5eef6d7
Fix the annotation base transform before drawing it
It fixes #7821.

We do something similar for before drawing XObjects.
2026-04-03 20:59:37 +02:00
Calixte Denizet
a1b64c52a1
Get the right transform for a pattern before filling some text
It fixes #16091.
2026-04-03 20:54:22 +02:00
Tim van der Meij
d1a711bca3
Merge pull request #21023 from calixteman/wasm_stack_js
Add a js fallback for interpreting ps code
2026-04-03 20:09:29 +02:00
Tim van der Meij
a96fb4dbb8
Merge pull request #21014 from calixteman/issue257
Fix radial gradient when the two circles have an intersection
2026-04-03 20:00:37 +02:00
Tim van der Meij
255c3e7c14
Merge pull request #21028 from Snuffleupagus/PDFDataRangeTransport-listener
[api-minor] Change `PDFDataRangeTransport` to use a single (internal)  listener
2026-04-03 19:53:39 +02:00
Tim van der Meij
bb1033053c
Merge pull request #21029 from Snuffleupagus/Object-hasOwn
Replace all `Object.prototype.hasOwnProperty` usage with `Object.hasOwn`
2026-04-03 19:51:09 +02:00
Jonas Jenwald
477f756a76
Merge pull request #21027 from Snuffleupagus/move-MathClamp
Move the `MathClamp` helper function to its own file
2026-04-03 19:08:12 +02:00
Tim van der Meij
38981ce638
Merge pull request #21034 from Snuffleupagus/collectAnnotationsByType-fixes
A couple of small `collectAnnotationsByType` improvements
2026-04-03 18:02:32 +02:00
Jonas Jenwald
5b6640eab3 A couple of small collectAnnotationsByType improvements
- Use the same `PartialEvaluator` instance for all annotations on the page, to reduce unnecessary object creation.

 - Use `Object.hasOwn` to check if the annotations were already parsed, to avoid having to keep a separate boolean variable in-sync with the actual code.
2026-04-03 13:20:06 +02:00
Calixte Denizet
535c8d13c2 Fix wrong values when sanitizing fonts
NPUSHW: push signed 16-bits integer: https://learn.microsoft.com/en-us/typography/opentype/spec/tt_instructions#push-n-words
indexToLocFormat: field in the 'head' table: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6head.html#:~:text=indexToLocFormat,-0
2026-04-02 18:13:17 +02:00
Jonas Jenwald
cbfe2abc53 Replace all Object.prototype.hasOwnProperty usage with Object.hasOwn
The newer `Object.hasOwn` method is intended as a replacement for `Object.prototype.hasOwnProperty`, since that one may be problematical; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#problematic_cases_for_hasownproperty

To ensure that `Object.hasOwn` is used in the future, the ESLint "no-restricted-syntax" rule is extended to catch the old method.
2026-04-02 13:40:10 +02:00
Jonas Jenwald
f3a2ca08d0 [api-minor] Change PDFDataRangeTransport to use a single (internal) listener
The `PDFDataTransportStream` constructor has always registered exactly one listener for each type of data that an `PDFDataRangeTransport` instance can receive.
Given that an end-user of the `PDFDataRangeTransport` class will supply data through its `onData...` methods, it's also somewhat difficult to understand why additional end-user registered listeners would be needed (since the data is already, by definition, available to the user).
Furthermore, since TypedArray data is being transferred nowadays it's not even clear that multiple listeners (of the same kind) would generally work.

All in all, let's simplify this old code a little bit by using *a single* (internal) listener in the `PDFDataRangeTransport` class.
2026-04-02 12:38:58 +02:00
Jonas Jenwald
68366e31e4 Move the MathClamp helper function to its own file
This allows using it in the `src/scripting_api/` folder, without increasing the size of the scripting-bundle by also importing a bunch of unused code.
2026-04-02 11:22:28 +02:00
Jonas Jenwald
1bd4c4fbde
Merge pull request #21026 from Snuffleupagus/more-MathClamp
Use the `MathClamp` helper function more
2026-04-02 11:21:46 +02:00
Jonas Jenwald
c012ff6e10 Use the MathClamp helper function more
The idea with this helper function is that once https://github.com/tc39/proposal-math-clamp/ becomes stable, all its call-sites should then be replaced by the native functionality.
2026-04-02 10:10:39 +02:00
calixteman
8c7a5f3500
Add a js fallback for interpreting ps code
It's a basic stack based interpreter.
A wasm version will come soon.
2026-04-01 21:40:45 +02:00
Calixte Denizet
f373923170 Encrypt pdf data when merging the same pdf (bug 2028369) 2026-04-01 19:01:11 +02:00
Calixte Denizet
b42dd39aae
Fix radial gradient when the two circles have an intersection
Fix #257.
2026-04-01 09:43:08 +02:00
calixteman
399fce6471
Merge pull request #21010 from calixteman/ps_js
Add an interpreter for optimized ps code
2026-03-31 22:21:00 +02:00
Calixte Denizet
9f3de1edf6
Add an interpreter for optimized ps code
It'll be used as a fallback when wasm is disabled.
And add in the debugger a view for the generated js code and one for the ps code.
2026-03-31 21:00:22 +02:00
Calixte Denizet
3727b7095a Add support for function-based shadings (bug 1254066)
It fixes #5046.
We just generate a mesh for the pattern rectangle where the color of each vertex is computed from the function.
Since the mesh is generated in the worker we don't really take into account the current transform when it's drawn.
That being said, there are maybe some possible improvements in using directly the gpu for the shading creation
which could then take into account the current transform, but it could only work with ps function we can convert
ino wgsl language and simple enough color spaces (gray and rgb).
2026-03-31 20:46:01 +02:00
Tim van der Meij
58b807d8e8
Merge pull request #21008 from calixteman/ast_cse
Avoid expressions duplication in the ps AST and use a local instead when compiling to WASM
2026-03-31 20:21:59 +02:00
Tim van der Meij
b0c0680bea
Merge pull request #18815 from calixteman/dont_always_use_pattern
Don't use an intermediate canvas when rendering a tiling pattern bigger than the rectangle to fill
2026-03-31 20:18:08 +02:00
Tim van der Meij
48228e2756
Merge pull request #21013 from calixteman/bug2026956
Add attachments when merging/reorganizing a pdf (bug 2026956)
2026-03-31 20:17:54 +02:00
Calixte Denizet
5b8c04f383 Add attachments when merging/reorganizing a pdf (bug 2026956) 2026-03-31 14:48:06 +02:00
Calixte Denizet
4c019e7712
Don't use an intermediate canvas when rendering a tiling pattern bigger than the rectangle to fill 2026-03-30 18:38:56 +02:00
Calixte Denizet
63cf35b47f Avoid expressions duplication in the ps AST and use a local instead when compiling to WASM 2026-03-30 16:30:33 +02:00
Jonas Jenwald
bfffb6c0f0 Import fs/promises directly in a few spots in the unit-tests
Also, use the existing PDF.js helper function to fetch text-data when running the "bidi" tests in browsers.
2026-03-30 14:34:53 +02:00
Jonas Jenwald
90fe6c70ff [Node.js] Remove the node-readable-to-web-readable-stream polyfill
While `Readable.toWeb` wasn't marked as stable until more recently, the functionality itself has existed since Node.js version `17.0.0`; note https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options

Hence the polyfill shouldn't actually be necessary, which is confirmed by the unit-tests passing in Node.js version `20` in GitHub Actions.
2026-03-30 13:45:13 +02:00
calixteman
952952c905
[api-minor] Rewrite the ps lexer & parser and add a small Wasm compiler
The main goal is to remove the eval-based interpreter.
In order to have some good performances, the new parser performs some optimizations
on the AST (similar to the ones in the previous implementation),
and the Wasm compiler generates code for the optimized AST.
For now, in case of errors or unsupported features, the Wasm compiler returns null
and the old interpreter is used as a fallback.
Few things are still missing:
 - a wasm-based interpreter using a stack (in case the ps code isn't stack-free);
 - a better js implementation in case of disabled wasm.

 but they will be added in follow-up patches.
2026-03-30 09:22:33 +02:00