Skip to content

Use @napi-rs/canvas in native engine to match pdfjs-dist#56

Open
ywang-clarify wants to merge 1 commit into
marcdacz:masterfrom
ywang-clarify:napi-rs-canvas-engine
Open

Use @napi-rs/canvas in native engine to match pdfjs-dist#56
ywang-clarify wants to merge 1 commit into
marcdacz:masterfrom
ywang-clarify:napi-rs-canvas-engine

Conversation

@ywang-clarify
Copy link
Copy Markdown

Fixes #55.

pdfjs-dist@4.x uses @napi-rs/canvas in Node for its internal polyfills (DOMMatrix, ImageData, Path2D) and intermediate canvases (pdf.mjs:11411-11443, pdf.mjs:11451-11456). When the native engine hands pdfjs a Cairo-backed canvas v3 rendering context, the intermediate image objects pdfjs constructs fail canvas's strict instanceOf type check inside Context2d::DrawImage, throwing TypeError: Image or Canvas expected. The error is then swallowed by comparePdfByImage's outer try/catch and surfaces only as a generic status: failed, message: "An error occurred.".

Switching the native engine to @napi-rs/canvas so both sides of the boundary speak the same module fixes it. Same fix recommended by the pdf.js maintainers in mozilla/pdf.js#19566 and #19794.

Changes

functions/engines/NodeCanvasFactory.js

  • require("canvas")require("@napi-rs/canvas")

functions/engines/native.js

  • require("canvas")require("@napi-rs/canvas")
  • canvas.toBuffer()canvas.toBuffer("image/png") (×3) — @napi-rs/canvas requires an explicit mime type.

package.json

  • Adds @napi-rs/canvas as a direct dependency. Today it's installed indirectly via pdfjs-dist's optionalDependencies; declaring it directly makes the dependency explicit and guaranteed.

graphicsMagick engine unchanged. Public API and types unchanged.

Verification

Self-compare of a PDF with embedded raster images:

  • before: { status: "failed", message: "An error occurred.\nTypeError: Image or Canvas expected" }
  • after: { status: "passed" }

Local npm test against the modified branch passes all the native-engine specs that pass on master (the same 2 native specs and ~22 graphicsMagick specs fail on master too — appears to be environmental, e.g. GraphicsMagick/Ghostscript not installed on a Windows machine).

Follow-up (optional)

canvas (Cairo v3) becomes unused after this change. Left in dependencies in this PR to keep the diff minimal — happy to drop it in a follow-up if you'd prefer.

pdfjs-dist 4.x ships its own @napi-rs/canvas-based NodeCanvasFactory
and polyfills (DOMMatrix, ImageData, Path2D) when running on Node. If
the native engine hands pdfjs a Cairo-backed canvas v3 context, the
intermediate image objects pdfjs constructs fail canvas v3's strict
instanceOf type check in Context2d::DrawImage and throw "Image or
Canvas expected" -- which the outer try/catch in comparePdfByImage
swallows into a generic "An error occurred". Reproduces on any PDF
that contains an embedded raster image; text-only PDFs pass.

Swap the native engine to @napi-rs/canvas so both sides of the
boundary use the same module. Same fix the pdf.js maintainers
recommend in mozilla/pdf.js#19566 and #19794.

@napi-rs/canvas's toBuffer() requires an explicit mime type, so the
three call sites are updated to pass "image/png".

Adds @napi-rs/canvas as a direct dependency. Today it's installed
indirectly via pdfjs-dist's optionalDependencies; declaring it
directly makes the dependency explicit and guaranteed.

graphicsMagick engine unchanged; public API and types unchanged.
The `canvas` dep becomes unused for the native engine but is left
in dependencies in this PR to keep the diff minimal -- happy to drop
it in a follow-up if you'd prefer.

Fixes marcdacz#55.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: Image or Canvas expected from native engine on PDFs with embedded images

1 participant