Skip to content

Commit bce322c

Browse files
committed
Add unicode mapping in the font cmap to have correct chars when printing in pdf (bug 1778484)
It aims to fix https://bugzilla.mozilla.org/show_bug.cgi?id=1778484.
1 parent 220f980 commit bce322c

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/core/fonts.js

+32-6
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,9 @@ function convertCidString(charCode, cid, shouldThrow = false) {
433433
* font that we build
434434
* 'charCodeToGlyphId' - maps the new font char codes to glyph ids
435435
*/
436-
function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) {
436+
function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUnicode) {
437437
const newMap = Object.create(null);
438+
const completeMap = Object.create(null);
438439
const toFontChar = [];
439440
let privateUseAreaIndex = 0;
440441
let nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0];
@@ -461,12 +462,27 @@ function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) {
461462
glyphId = newGlyphZeroId;
462463
}
463464

464-
newMap[fontCharCode] = glyphId;
465+
// Fix for bug 1778484:
466+
// The charcodes are moved into the private area in to fix some rendering
467+
// issues (https://github.com/mozilla/pdf.js/pull/9340) but when printing
468+
// into pdf the generated will contains wrong chars. We can avoid that in
469+
// adding the unicode to the cmap and the print backend will then map the
470+
// glyph ids to the correct unicode.
471+
let unicode = toUnicode.get(originalCharCode);
472+
if (typeof unicode === "string") {
473+
unicode = unicode.codePointAt(0);
474+
}
475+
if (unicode) {
476+
completeMap[unicode] = glyphId;
477+
}
478+
479+
newMap[fontCharCode] = completeMap[fontCharCode] = glyphId;
465480
toFontChar[originalCharCode] = fontCharCode;
466481
}
467482
return {
468483
toFontChar,
469484
charCodeToGlyphId: newMap,
485+
completeCharCodeToGlyphId: completeMap,
470486
nextAvailableFontCharCode,
471487
};
472488
}
@@ -2914,12 +2930,16 @@ class Font {
29142930
const newMapping = adjustMapping(
29152931
charCodeToGlyphId,
29162932
hasGlyph,
2917-
glyphZeroId
2933+
glyphZeroId,
2934+
this.toUnicode
29182935
);
29192936
this.toFontChar = newMapping.toFontChar;
29202937
tables.cmap = {
29212938
tag: "cmap",
2922-
data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphsOut),
2939+
data: createCmapTable(
2940+
newMapping.completeCharCodeToGlyphId,
2941+
numGlyphsOut
2942+
),
29232943
};
29242944

29252945
if (!tables["OS/2"] || !validateOS2Table(tables["OS/2"], font)) {
@@ -2992,17 +3012,20 @@ class Font {
29923012
const mapping = font.getGlyphMapping(properties);
29933013
let newMapping = null;
29943014
let newCharCodeToGlyphId = mapping;
3015+
let newCompleteCharCodeToGlyphId = mapping;
29953016

29963017
// When `cssFontInfo` is set, the font is used to render text in the HTML
29973018
// view (e.g. with Xfa) so nothing must be moved in the private use area.
29983019
if (!properties.cssFontInfo) {
29993020
newMapping = adjustMapping(
30003021
mapping,
30013022
font.hasGlyphId.bind(font),
3002-
glyphZeroId
3023+
glyphZeroId,
3024+
this.toUnicode
30033025
);
30043026
this.toFontChar = newMapping.toFontChar;
30053027
newCharCodeToGlyphId = newMapping.charCodeToGlyphId;
3028+
newCompleteCharCodeToGlyphId = newMapping.completeCharCodeToGlyphId;
30063029
}
30073030
const numGlyphs = font.numGlyphs;
30083031

@@ -3087,7 +3110,10 @@ class Font {
30873110
// OS/2 and Windows Specific metrics
30883111
builder.addTable("OS/2", createOS2Table(properties, newCharCodeToGlyphId));
30893112
// Character to glyphs mapping
3090-
builder.addTable("cmap", createCmapTable(newCharCodeToGlyphId, numGlyphs));
3113+
builder.addTable(
3114+
"cmap",
3115+
createCmapTable(newCompleteCharCodeToGlyphId, numGlyphs)
3116+
);
30913117
// Font header
30923118
builder.addTable(
30933119
"head",

0 commit comments

Comments
 (0)