From 59ce1a4a3fdac2a59b32e615ce68fb2ef310946f Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Fri, 10 Nov 2023 11:48:44 +0100 Subject: [PATCH] Fix the maxp table version in font to make it visible on Windows --- src/core/fonts.js | 25 ++++++++++++++++++++++--- test/pdfs/issue16839.pdf.link | 2 ++ test/test_manifest.json | 8 ++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 test/pdfs/issue16839.pdf.link diff --git a/src/core/fonts.js b/src/core/fonts.js index 84e3dd131..2ec70e41d 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -292,6 +292,13 @@ function signedInt16(b0, b1) { return value & (1 << 15) ? value - 0x10000 : value; } +function writeUint32(bytes, index, value) { + bytes[index + 3] = value & 0xff; + bytes[index + 2] = value >>> 8; + bytes[index + 1] = value >>> 16; + bytes[index] = value >>> 24; +} + function int32(b0, b1, b2, b3) { return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; } @@ -2642,9 +2649,21 @@ class Font { } font.pos = (font.start || 0) + tables.maxp.offset; - const version = font.getInt32(); + let version = font.getInt32(); const numGlyphs = font.getUint16(); + if (version !== 0x00010000 && version !== 0x00005000) { + // https://learn.microsoft.com/en-us/typography/opentype/spec/maxp + if (tables.maxp.length === 6) { + version = 0x0005000; + } else if (tables.maxp.length >= 32) { + version = 0x00010000; + } else { + throw new FormatError(`"maxp" table has a wrong version number`); + } + writeUint32(tables.maxp.data, 0, version); + } + if (properties.scaleFactors?.length === numGlyphs && isTrueType) { const { scaleFactors } = properties; const isGlyphLocationsLong = int16( @@ -2695,7 +2714,7 @@ class Font { } let maxFunctionDefs = 0; let maxSizeOfInstructions = 0; - if (version >= 0x00010000 && tables.maxp.length >= 22) { + if (version >= 0x00010000 && tables.maxp.length >= 32) { // maxZones can be invalid font.pos += 8; const maxZones = font.getUint16(); @@ -2761,7 +2780,7 @@ class Font { // Some fonts have incorrect maxSizeOfInstructions values, so we use // the computed value instead. - if (version >= 0x00010000 && tables.maxp.length >= 22) { + if (version >= 0x00010000 && tables.maxp.length >= 32) { tables.maxp.data[26] = glyphsInfo.maxSizeOfInstructions >> 8; tables.maxp.data[27] = glyphsInfo.maxSizeOfInstructions & 255; } diff --git a/test/pdfs/issue16839.pdf.link b/test/pdfs/issue16839.pdf.link new file mode 100644 index 000000000..1bc6dab87 --- /dev/null +++ b/test/pdfs/issue16839.pdf.link @@ -0,0 +1,2 @@ +https://github.com/mozilla/pdf.js/files/12356264/250125_010823.pdf + diff --git a/test/test_manifest.json b/test/test_manifest.json index bd98b5f99..56c8ce8d3 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -8206,5 +8206,13 @@ "link": true, "type": "eq", "annotations": true + }, + { + "id": "issue16839", + "file": "pdfs/issue16839.pdf", + "md5": "413fceec0ac31e079dc487bf4c5e44d8", + "rounds": 1, + "link": true, + "type": "eq" } ]