mozilla / pdf.js

PDF Reader in JavaScript
https://mozilla.github.io/pdf.js/
Apache License 2.0
48.33k stars 9.97k forks source link

Certain embedded fonts not rendering properly in web viewer in Firefox and Chrome (but works in IE) #6343

Closed YellowYak closed 8 years ago

YellowYak commented 9 years ago

I have a PDF document (see https://www.dropbox.com/s/ugcx6u2mqp57uix/BadPDFJS.pdf) that contains Helvetica Neu as an embedded font.

When I go to the pdf.js web viewer online at https://mozilla.github.io/pdf.js/web/viewer.html and open this PDF using IE 11, it views fine. However, when I go to the same URL and open the same document using either the latest version of Chrome (v44) or Firefox (v39) the font does not appear to render and there are a number of small boxes interspersed through the text. (The PDF loads and displays as expected when using a stand-alone PDF view, such as Adobe Acrobat Reader.)

The problem text in particular is in the lower left corner of the single page document, the white text on a blue background that reads: "Odiant. Cipsusae. Itatem quide id maionsequi officae sitaqui ut que dolessequis explitior rendis."

Here is a screenshot of that text when viewing the PDF in IE 11:

Output in IE 11

And here is a screenshot of that text when viewing the PDF in Chrome (it looks the same in Firefox):

Output in Chrome

Thanks

timvandermeij commented 9 years ago

I see a lot of font sanitizer errors in the console, which probably has something to do with this.

YellowYak commented 9 years ago

Hi Tim, thanks for looking into this.

You'll have to excuse my ignorance w/r/t PDFs and fonts, but what do the font sanitizer errors hint at? Is the font invalid? What's odd is that it displays without issue in Acrobat Reader as well as displaying in pdf.js when viewed through IE (but not through Chrome or FF). Why would the browser impact the rendering of the font?

Thanks

yurydelendik commented 9 years ago

PDFs often contain embedded fonts. These fonts can be invalid, and PDF generators often reduce size of them by removing unused glyphs without carrying about their completeness. PDF.js reconstruct fonts so they can be usage by web browsers. On other side, fonts can be malicious causing security issues, so web browsers validate any external font (in case on Firefox and Chrome, it's the Sanitiser for OpenType). In your case it's probably PDF.js was unable to reconstruct font to satisfy the sanitizer, but that was enough for IE.

YellowYak commented 9 years ago

In my research I did find this issue posted for the Sanitiser for OpenType project, https://github.com/khaledhosny/ots/issues/34, in which an Adobe employee identified a number of OTF fonts that were improperly being flagged as malicious by OTS (including HelveticaNeue, which is the font I'm using).

However, the bug was reported last August (almost a year ago) and marked as resolved shortly thereafter. But maybe Chrome and Firefox have older versions of OTS?

HelveticaNeue is a (relatively) popular font, no? Is this is a known issue with pdf.js, rendering HelveticaNeue?

Thanks

timvandermeij commented 9 years ago

I have not seen issues mentioning HelveticaNeue before. Either the font in this file is just corrupted or Sanitiser for OpenType is wrong. If the latter case is happening here, then an issue should be opened at the OTS repository.

khaledhosny commented 9 years ago

I think the fonts PDF.js is generating are broken, OTS reports cmap: Range glyph reference too high (253 > 252), which is not terribly informative, but it means that a format 4 cmap subtable maps to glyph id that is bigger than number of glyphs in the font. FontTools fails to decode the font as well, and both issues seems to be due to wrong (less by one) number of glyphs in the maxp table.

Snuffleupagus commented 9 years ago

The problematic fonts (in the PDF file) are of the CIDFontType0 type, with a CIDFontType0C subtype. This means that the font data is embedded as a CFF (Compact Font Format) file.

We attempt to parse and convert the CFF file into an OpenType font, which is then passed to the browser. As the OTS errors, and https://github.com/mozilla/pdf.js/issues/6343#issuecomment-130498467, shows we unfortunately don't succeed in creating a valid font. Since we're generally able to parse/convert CFF data into valid OpenType fonts, I'm thinking that this may point to something being wrong with the CFF file. Unfortunately our font code might not be as resilient to errors/weirdness in CFF files as one would like.

A very quick look into this PDF file suggests that issue #5132 may become relevant here. (Also, it's interesting to note that prior to PR #4259 those fonts didn't render even remotely correct.)


Since the problematic fonts in the PDF file are CFF, and not TrueType/OpenType, I don't think that https://github.com/khaledhosny/ots/issues/34 is even remotely relevant here. Also note that in createCmapTable, see fonts.js#L2833, we're not building a (0, 1) cmap either.

ChazyTheBest commented 8 years ago

I'm also having this issue but in my case it's in the printed document. PDF.js is rendering the fonts in the viewer but not while generating the printing version. It replaces the glyphs (like arrows) with the rectangular box symbol and it prints a strange symbol over the letters (like a pyramid but made of three circles: one in the top center, other in the bottom left and another in the bottom right, for each affected letter). It also removes the bold and the letters from those words gets too close together.

However, it didn't happened while printing only one of the affected pages...

screenshot from 2015-12-02 03-11-09

img_20151202_021034_hdr

Snuffleupagus commented 8 years ago

Closing as fixed by #6715.

lloyddugmore commented 7 years ago

[‎29/‎11/‎2016 3:38 PM] Giovanni Roos: This worked for me: 

Here's how I solved this problem (with Acrobat 9.0 Pro on Windows XP) on my system: 

  1. Navigate to <C:\Program Files\Adobe\Acrobat 9.0\Acrobat\Browser> 
  2. Copy the file "nppdf32.dll" 
  3. Navigate to <C:\Documents and Settings\ username>\Local Settings\Application Data\Google\Chrome\Application\Plugins  *note: I did not have a Plugins folder yet, so I created one** 
  4. Paste the nppdf32.dll file 
  5. Restart Chrome. 

Worked like a charm!