From 5518c8a5440171c42792acde8fcce4b4bd26fed4 Mon Sep 17 00:00:00 2001 From: calixteman Date: Thu, 25 Dec 2025 22:55:54 +0100 Subject: [PATCH 1/2] Use CIDToGIDMap when the font is a type 2 with an OpenType font It fixes #18062. --- src/core/cff_parser.js | 3 ++ src/core/fonts.js | 60 +++++++++++++++++------------------ test/pdfs/issue18062.pdf.link | 1 + test/test_manifest.json | 8 +++++ 4 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 test/pdfs/issue18062.pdf.link diff --git a/src/core/cff_parser.js b/src/core/cff_parser.js index 0e9a91be369de..0189a6e411504 100644 --- a/src/core/cff_parser.js +++ b/src/core/cff_parser.js @@ -255,6 +255,8 @@ class CFFParser { const charStringOffset = topDict.getByName("CharStrings"); const charStringIndex = this.parseIndex(charStringOffset).obj; + cff.charStringCount = charStringIndex.count; + const fontMatrix = topDict.getByName("FontMatrix"); if (fontMatrix) { properties.fontMatrix = fontMatrix; @@ -1005,6 +1007,7 @@ class CFF { this.fdSelect = null; this.isCIDFont = false; + this.charStringCount = 0; } duplicateFirstGlyph() { diff --git a/src/core/fonts.js b/src/core/fonts.js index 532896e0acbaa..a155ac70283ab 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -60,7 +60,6 @@ import { CFFFont } from "./cff_font.js"; import { FontRendererFactory } from "./font_renderer.js"; import { getFontBasicMetrics } from "./metrics.js"; import { GlyfTable } from "./glyf.js"; -import { IdentityCMap } from "./cmap.js"; import { OpenTypeFileBuilder } from "./opentype_file_builder.js"; import { readUint32 } from "./core_utils.js"; import { Stream } from "./stream.js"; @@ -2638,27 +2637,23 @@ class Font { header = readOpenTypeHeader(font); tables = readTables(font, header.numTables); } - let cff, cffFile; const isTrueType = !tables["CFF "]; if (!isTrueType) { - const isComposite = - properties.composite && - (properties.cidToGidMap?.length > 0 || - !(properties.cMap instanceof IdentityCMap)); // OpenType font (skip composite fonts with non-default glyph mapping). if ( - (header.version === "OTTO" && !isComposite) || + (header.version === "OTTO" && !properties.composite) || !tables.head || !tables.hhea || !tables.maxp || !tables.post ) { // No major tables: throwing everything at `CFFFont`. - cffFile = new Stream(tables["CFF "].data); - cff = new CFFFont(cffFile, properties); - - return this.convert(name, cff, properties); + return this.convert( + name, + new CFFFont(new Stream(tables["CFF "].data), properties), + properties + ); } delete tables.glyf; @@ -2686,9 +2681,32 @@ class Font { throw new FormatError('Required "maxp" table is not found'); } + let numGlyphsFromCFF; + if (!isTrueType) { + try { + // Trying to repair CFF file + const parser = new CFFParser( + new Stream(tables["CFF "].data), + properties, + SEAC_ANALYSIS_ENABLED + ); + const cff = parser.parse(); + cff.duplicateFirstGlyph(); + const compiler = new CFFCompiler(cff); + tables["CFF "].data = compiler.compile(); + numGlyphsFromCFF = cff.charStringCount; + } catch { + warn("Failed to compile font " + properties.loadedName); + } + } + font.pos = (font.start || 0) + tables.maxp.offset; let version = font.getInt32(); - const numGlyphs = font.getUint16(); + const numGlyphs = numGlyphsFromCFF ?? font.getUint16(); + if (version === 0x00005000 && tables.maxp.length !== 6) { + tables.maxp.data = tables.maxp.data.subarray(0, 6); + tables.maxp.length = 6; + } if (version !== 0x00010000 && version !== 0x00005000) { // https://learn.microsoft.com/en-us/typography/opentype/spec/maxp @@ -3099,24 +3117,6 @@ class Font { } } - if (!isTrueType) { - try { - // Trying to repair CFF file - cffFile = new Stream(tables["CFF "].data); - const parser = new CFFParser( - cffFile, - properties, - SEAC_ANALYSIS_ENABLED - ); - cff = parser.parse(); - cff.duplicateFirstGlyph(); - const compiler = new CFFCompiler(cff); - tables["CFF "].data = compiler.compile(); - } catch { - warn("Failed to compile font " + properties.loadedName); - } - } - // Re-creating 'name' table if (!tables.name) { tables.name = { diff --git a/test/pdfs/issue18062.pdf.link b/test/pdfs/issue18062.pdf.link new file mode 100644 index 0000000000000..7f65a9a0fc35a --- /dev/null +++ b/test/pdfs/issue18062.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/15274065/1.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index 03f53f1394729..860497c72ebc9 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -13123,5 +13123,13 @@ "rounds": 1, "link": true, "type": "eq" + }, + { + "id": "issue18062", + "file": "pdfs/issue18062.pdf", + "md5": "b8fb6d5622f0a2f45be8e26da7de969c", + "rounds": 1, + "link": true, + "type": "eq" } ] From f385fd9783eb540d7c3f63add286255c7f0ad767 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sun, 28 Dec 2025 20:05:00 +0100 Subject: [PATCH 2/2] Bump the stable version in `pdfjs.config` --- pdfjs.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfjs.config b/pdfjs.config index 597cc9306ac16..b1d6327626aea 100644 --- a/pdfjs.config +++ b/pdfjs.config @@ -1,5 +1,5 @@ { - "stableVersion": "5.4.449", + "stableVersion": "5.4.530", "baseVersion": "1b427a3af5e0a40c296a3cafb08edbd36d973ff1", "versionPrefix": "5.4." }