-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Font lost when rendered in an iframe #8271
Comments
can I work on this bug ? |
Yes, please feel free to work on this. |
@amitsin6h Let me know if you need anything else |
This is likely caused by the fact that Try serializing the canvas, e.g. via To fix this at its core, we should not rely on a global |
I'm gonna test, thanks |
Any update on it? |
Hi all! Anyone tried to get some luck on making the PDF fonts rendered correctly in an iframe? |
Hi, if somebody visits this issue again, here is a workarround. I followed the steps @Rob--W provided above and can confirm it works on all browsers (Safari, Chrome, Firefox and Edge). Here is the code snippet (Renders all pages at once): import {PDFPageViewport} from 'pdfjs-dist';
import pdfjsLib from 'pdfjs-dist/webpack';
import {range} from 'lodash';
const renderPage = async (page: any, container: HTMLElement) => {
// This gives us the page's dimensions at full scale
const viewport: PDFPageViewport = page.getViewport({ scale: 1 });
// We'll create a canvas for each page to draw it on
const canvas = document.createElement('canvas');
canvas.style.display = 'block';
container.appendChild(canvas);
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Draw it on the canvas
await page.render({ canvasContext: context, viewport }).promise;
// eslint-disable-next-line max-len
return new Promise<{ blob: Blob, height: number, width: number }>(((resolve) => canvas.toBlob((result) => resolve({ blob: result!, height: viewport.height, width: viewport.width }))));
};
// Render a hidden container element to add all canvases (canvas per page in the pdf)
const container = document.createElement('div') as HTMLDivElement;
container.style.visibility = 'hidden';
document.body.appendChild(container);
// Create the iframe
const iframe = document.createElement('iframe') as HTMLIFrameElement;
iframe.style.visibility = 'hidden';
iframe.src = 'about:blank';
document.body.appendChild(iframe);
iframe.contentWindow!.onbeforeunload = () => document.body.removeChild(iframe);
iframe.contentWindow!.onafterprint = () => document.body.removeChild(iframe);
const pdf = await pdfjsLib.getDocument(source).promise;
const numPages = pdf.numPages;
const pageNumbers = range(1, numPages + 1);
// Create the canvas for each page and retrieve the image blob data
const imageBlobData = await Promise.all(pageNumbers.map(async number => {
return renderPage(await pdf.getPage(number), container);
}));
// Due to a bug we need to copy the canvas image to the iframe instead of writing the canvas directly
// in the iframe. (https://github.com/mozilla/pdf.js/issues/8271)
imageBlobData.forEach((blobData) => {
const image = document.createElement('img');
image.style.height = `${blobData.height}`;
image.style.width = `${blobData.width}`;
image.src = URL.createObjectURL(blobData.blob);
iframe.contentWindow!.document.body.appendChild(image);
});
// Remove the intermediary container element
document.body.removeChild(container);
// Wait for the content to be fully rendered and print
await setTimeout(() => {
iframe.contentWindow!.focus();
iframe.contentWindow!.print();
}, 500); |
Nice workaround but it would still be great to be fixed in core PDF.js. |
I'm trying to use an iframe to print a PDF easily, everything is ok but the fonts.
Configuration:
Steps to reproduce the problem:
Here is my print function which takes the pdfDoc as parameter (from
PDFJS.getDocument(url)
)On the left, the main page canvas, on the right, the iframe canvas.
The rendering in the iframe seems to not embed the fonts.
The text was updated successfully, but these errors were encountered: