Hide .notdef glyphs in non-embedded Type1 fonts and don't ignore Widths
Fixes #11403 The PDF uses the non-embedded Type1 font Helvetica. Character codes 194 and 160 (`Â` and `NBSP`) are encoded as `.notdef`. We shouldn't show those glyphs because it seems that Acrobat Reader doesn't draw glyphs that are named `.notdef` in fonts like this. In addition to testing `glyphName === ".notdef"`, we must test also `glyphName === ""` because the name `""` is used in `core/encodings.js` for undefined glyphs in encodings like `WinAnsiEncoding`. The solution above hides the `Â` characters but now the replacement character (space) appears to be too wide. I found out that PDF.js ignores font's `Widths` array if the font has no `FontDescriptor` entry. That happens in #11403, so the default widths of Helvetica were used as specified in `core/metrics.js` and `.nodef` got a width of 333. The correct width is 0 as specified by the `Widths` array in the PDF. Thus we must never ignore `Widths`.
This commit is contained in:
parent
40f531ee87
commit
809b96b40c
@ -2945,6 +2945,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var type = preEvaluatedFont.type;
|
var type = preEvaluatedFont.type;
|
||||||
var maxCharIndex = composite ? 0xffff : 0xff;
|
var maxCharIndex = composite ? 0xffff : 0xff;
|
||||||
var properties;
|
var properties;
|
||||||
|
const firstChar = dict.get("FirstChar") || 0;
|
||||||
|
const lastChar = dict.get("LastChar") || maxCharIndex;
|
||||||
|
|
||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
if (type === "Type3") {
|
if (type === "Type3") {
|
||||||
@ -2981,15 +2983,25 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
widths: metrics.widths,
|
widths: metrics.widths,
|
||||||
defaultWidth: metrics.defaultWidth,
|
defaultWidth: metrics.defaultWidth,
|
||||||
flags,
|
flags,
|
||||||
firstChar: 0,
|
firstChar,
|
||||||
lastChar: maxCharIndex,
|
lastChar,
|
||||||
};
|
};
|
||||||
|
const widths = dict.get("Widths");
|
||||||
return this.extractDataStructures(dict, dict, properties).then(
|
return this.extractDataStructures(dict, dict, properties).then(
|
||||||
properties => {
|
properties => {
|
||||||
|
if (widths) {
|
||||||
|
const glyphWidths = [];
|
||||||
|
let j = firstChar;
|
||||||
|
for (let i = 0, ii = widths.length; i < ii; i++) {
|
||||||
|
glyphWidths[j++] = this.xref.fetchIfRef(widths[i]);
|
||||||
|
}
|
||||||
|
properties.widths = glyphWidths;
|
||||||
|
} else {
|
||||||
properties.widths = this.buildCharCodeToWidth(
|
properties.widths = this.buildCharCodeToWidth(
|
||||||
metrics.widths,
|
metrics.widths,
|
||||||
properties
|
properties
|
||||||
);
|
);
|
||||||
|
}
|
||||||
return new Font(baseFontName, null, properties);
|
return new Font(baseFontName, null, properties);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -3001,8 +3013,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// to ignore this rule when a variant of a standard font is used.
|
// to ignore this rule when a variant of a standard font is used.
|
||||||
// TODO Fill the width array depending on which of the base font this is
|
// TODO Fill the width array depending on which of the base font this is
|
||||||
// a variant.
|
// a variant.
|
||||||
var firstChar = dict.get("FirstChar") || 0;
|
|
||||||
var lastChar = dict.get("LastChar") || maxCharIndex;
|
|
||||||
|
|
||||||
var fontName = descriptor.get("FontName");
|
var fontName = descriptor.get("FontName");
|
||||||
var baseFont = dict.get("BaseFont");
|
var baseFont = dict.get("BaseFont");
|
||||||
|
@ -3392,6 +3392,16 @@ var Font = (function FontClosure() {
|
|||||||
// back to the char code.
|
// back to the char code.
|
||||||
fontCharCode = this.toFontChar[charcode] || charcode;
|
fontCharCode = this.toFontChar[charcode] || charcode;
|
||||||
if (this.missingFile) {
|
if (this.missingFile) {
|
||||||
|
const glyphName =
|
||||||
|
this.differences[charcode] || this.defaultEncoding[charcode];
|
||||||
|
if (
|
||||||
|
(glyphName === ".notdef" || glyphName === "") &&
|
||||||
|
this.type === "Type1"
|
||||||
|
) {
|
||||||
|
// .notdef glyphs should be invisible in non-embedded Type1 fonts, so
|
||||||
|
// replace them with spaces.
|
||||||
|
fontCharCode = 0x20;
|
||||||
|
}
|
||||||
fontCharCode = mapSpecialUnicodeValues(fontCharCode);
|
fontCharCode = mapSpecialUnicodeValues(fontCharCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -167,6 +167,7 @@
|
|||||||
!issue3405r.pdf
|
!issue3405r.pdf
|
||||||
!issue7339_reduced.pdf
|
!issue7339_reduced.pdf
|
||||||
!issue3438.pdf
|
!issue3438.pdf
|
||||||
|
!issue11403_reduced.pdf
|
||||||
!issue2074.pdf
|
!issue2074.pdf
|
||||||
!scan-bad.pdf
|
!scan-bad.pdf
|
||||||
!bug847420.pdf
|
!bug847420.pdf
|
||||||
|
90
test/pdfs/issue11403_reduced.pdf
Normal file
90
test/pdfs/issue11403_reduced.pdf
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
%PDF-1.5
|
||||||
|
%âãÏÓ
|
||||||
|
1 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 2 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Pages
|
||||||
|
/Count 1
|
||||||
|
/Kids [3 0 R]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 2 0 R
|
||||||
|
/Contents 6 0 R
|
||||||
|
/MediaBox [0 0 200 50]
|
||||||
|
/Resources 4 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<<
|
||||||
|
/Font << /F2 5 0 R >>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Font
|
||||||
|
/Subtype /Type1
|
||||||
|
/BaseFont /Helvetica
|
||||||
|
/Encoding <<
|
||||||
|
/Type /Encoding
|
||||||
|
/Differences [32 /space 35 /numbersign 37 /percent 40 /parenleft /parenright
|
||||||
|
44 /comma /hyphen /period /slash /zero /one /two /three /four /five /six
|
||||||
|
/seven /eight /nine /colon /semicolon /less 65 /A /B /C /D /E /F /G /H /I
|
||||||
|
/J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y 91 /bracketleft 93 /bracketright
|
||||||
|
97 /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p 114 /r /s /t /u /v /w /x
|
||||||
|
/y /z 128 /.notdef 147 /.notdef 160 /.notdef 194 /.notdef 226 /.notdef]
|
||||||
|
>>
|
||||||
|
/FirstChar 32
|
||||||
|
/LastChar 226
|
||||||
|
/Widths [278 0 0 556 0 889 0 0 333 333 0 0 278 333 278 278 556 556 556 556 556
|
||||||
|
556 556 556 556 556 278 278 584 0 0 0 0 667 667 722 722 667 611 778 722 278
|
||||||
|
500 667 556 833 722 778 667 778 722 667 611 722 667 944 667 667 0 278 0 278
|
||||||
|
0 0 0 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 0 333
|
||||||
|
500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<< /Length 71 >>
|
||||||
|
stream
|
||||||
|
BT
|
||||||
|
14 17 Td
|
||||||
|
/F2 18 Tf
|
||||||
|
(\302\240 2. Eat a healthy diet.) Tj
|
||||||
|
ET
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 7
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000017 00000 n
|
||||||
|
0000000074 00000 n
|
||||||
|
0000000140 00000 n
|
||||||
|
0000000254 00000 n
|
||||||
|
0000000306 00000 n
|
||||||
|
0000001548 00000 n
|
||||||
|
|
||||||
|
trailer
|
||||||
|
<<
|
||||||
|
/Size 7
|
||||||
|
/Root 1 0 R
|
||||||
|
/ID [<7b642074abed518fedb35b69fbbf85c0> <7b642074abed518fedb35b69fbbf85c0>]
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
1677
|
||||||
|
%%EOF
|
@ -1419,6 +1419,12 @@
|
|||||||
"lastPage": 1,
|
"lastPage": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue11403",
|
||||||
|
"file": "pdfs/issue11403_reduced.pdf",
|
||||||
|
"md5": "08287b64f442cb7c329b97c4774aa1cd",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue11139",
|
{ "id": "issue11139",
|
||||||
"file": "pdfs/issue11139.pdf",
|
"file": "pdfs/issue11139.pdf",
|
||||||
"md5": "006dd4f4bb1878bc14a12072d81a4524",
|
"md5": "006dd4f4bb1878bc14a12072d81a4524",
|
||||||
|
Loading…
Reference in New Issue
Block a user