wojtekmaj / react-pdf

Display PDFs in your React app as easily as if they were images.
https://projects.wojtekmaj.pl/react-pdf
MIT License
9.42k stars 885 forks source link

Checkbox not checked #961

Closed stefandutoit closed 2 years ago

stefandutoit commented 2 years ago

Before you start - checklist

Description

If the PDF below is opened and viewed using 'react-pdf' (v5.7.1), the checkbox 4.10 (Retail Trade) on page 1 is not checked. Viewing the PDF with another viewer (Adobe or Mozilla PDF.js) shows the same checkbox correctly checked.

Certificate 110608.pdf

Steps to reproduce

  1. Open the PDF in a viewer using the 'react-pdf' (latest - v5.7.1) library.
  2. On Page 1, checkbox 4.10 (Retail Trade) should be checked. It is not checked.

Expected behavior

On Page 1, checkbox 4.10 (Retail Trade) should be checked. The screenshot below is using the Adobe PDF / Mozilla PDF.js Viewer.

image

Actual behavior

On Page 1, checkbox 4.10 (Retail Trade) should be checked. It is not checked. The screenshot below is using 'react-pdf' library.

image

The only hint is that the following is shown in Browser Console when the PDF is opened.

Warning: loadFont - translateFont failed: "TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from undefinedFoxitDingbats.pfb". pdf.js:479 Warning: Error during font loading: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from undefinedFoxitDingbats.pfb

Additional information

import React from 'react';
import { pdfjs } from 'react-pdf/dist/esm/entry.webpack';
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack';

const DocumentViewer = (url: string): JSX.Element => {
  const [numberPages, setNumberPages] = React.useState<number>(null);
  const [pageNumber, setPageNumber] = React.useState(1);

  const onDocumentLoad = (pdf: pdfjs.PDFDocumentProxy) => {
    setNumberPages(pdf.numPages);
  }

  return (
    // <div id={'sbsDocumentViewer'} className="sbsDocumentViewer">
    //   <Document
    //     file={url}
    //     onLoadSuccess={onDocumentLoad}
    //   >
    //     <Page pageNumber={pageNumber} />
    //   </Document>
    // </div>
  );
}

export default DocumentViewer;

Environment

Browsers: Chrome - Version 99.0.4844.51 (Official Build) (64-bit) Edge - Version 99.0.1150.36 (Official build) (64-bit)

React-PDF: 5.7.1 React: 16.13.1

78raoul78 commented 2 years ago

hello @stefandutoit , did you manage to find a solution to your issue, i'm having the same one ?

I think I found a solution : just replace

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`

with

import pdfjsWorker from 'react-pdf/node_modules/pdfjs-dist/build/pdf.worker.entry'
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker

I guess there are issues with the library provided from the cdn 🤔

wojtekmaj commented 2 years ago

Yeah @78raoul78, it's definitely the case here! Could reproduce it.

With remote workerSrc, I got this in the console:

Test.jsx:179 Loaded a document PDFDocumentProxy
pdf.js:697 Deprecated API usage: render no longer accepts the `renderInteractiveForms`-option, please use the `annotationMode`-option instead.
pdf.worker.min.js:22 Warning: loadFont - translateFont failed: "TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from undefinedFoxitDingbats.pfb".
pdf.js:1828 Warning: Error during font loading: Failed to execute 'fetch' on 'WorkerGlobalScope': Failed to parse URL from undefinedFoxitDingbats.pfb
Test.jsx:188 Rendered a page PDFPageProxy

while with local worker, I got:

Test.jsx:178 Loaded a document PDFDocumentProxy
pdf.js:697 Deprecated API usage: render no longer accepts the `renderInteractiveForms`-option, please use the `annotationMode`-option instead.
51103eacf3bef7f35f0812db4ea611f7.js:1918 Warning: fetchStandardFontData: failed to fetch file "undefinedFoxitDingbats.pfb" with "Not Found".
Test.jsx:187 Rendered a page PDFPageProxy {_pageIndex: 0, _pageInfo: {…}, _ownerDocument: document, _transport: WorkerTransport, _stats: null, …}

So it looks like this checkmark is rendered using some custom fonts that cannot be fetched using remote worker... 🤔

wojtekmaj commented 2 years ago

Yep - there are "standard fonts" involved here., used in PDF standard before version 1.5.

From p. 255: http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf

Beginning with PDF 1.5, the special treatment given to the standard 14 fonts is deprecated. Conforming writers should represent all fonts using a complete font descriptor. For backwards capability, conforming readers shall still provide the special treatment identified for the standard 14 fonts.

The solution is simple: add standardFontDataUrl to options, similarly to how cMapsUrl is set:

  standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts/`,
NinjaAniket commented 2 years ago

import pdfjsWorker from 'react-pdf/node_modules/pdfjs-dist/build/pdf.worker.entry' pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker

thanks it worked but FYI react pdf version 5.7.2+ import pdfjfworker file directory has changed

import pdfjsWorker from "react-pdf/dist/esm/pdf.worker.entry"; pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;