From 61e19bee43b5a0bfbeeef9e02aebda80413e5457 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 26 Nov 2017 13:29:43 +0100 Subject: [PATCH] Build a fallback `ToUnicode` map for simple fonts (issue 8229) In some fonts, the included `ToUnicode` data is incomplete causing text-selection to not work properly. For simple fonts that contain encoding data, we can manually build a `ToUnicode` map to attempt to improve things. Please note that since we're currently using the `ToUnicode` data during glyph mapping, in an attempt to avoid rendering regressions, I purposely didn't want to amend to original `ToUnicode` data for this text-selection edge-case. Instead, I opted for the current solution, which will (hopefully) give slightly better text-extraction results in PDF file with incomplete `ToUnicode` data. According to the PDF specification, see [section 9.10.2](http://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G8.1873172): > A conforming reader can use these methods, in the priority given, to map a character code to a Unicode value. > ... Reading that paragraph literally, it doesn't seem too unreasonable to use *different* methods for different charcodes. Fixes 8229. --- src/core/evaluator.js | 8 ++++++++ src/core/fonts.js | 8 +++++--- test/pdfs/.gitignore | 1 + test/pdfs/issue8229.pdf | Bin 0 -> 20854 bytes test/test_manifest.json | 7 +++++++ 5 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/pdfs/issue8229.pdf diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 1883db8de..b78b3bc13 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2021,6 +2021,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // Section 9.10.2 Mapping Character Codes to Unicode Values if (properties.hasIncludedToUnicodeMap) { + // Some fonts contain incomplete ToUnicode data, causing issues with + // text-extraction. For simple fonts, containing encoding information, + // use a fallback ToUnicode map to improve this (fixes issue8229.pdf). + if (!properties.composite && properties.hasEncoding) { + properties.fallbackToUnicode = + this._buildSimpleFontToUnicode(properties); + } + return Promise.resolve(properties.toUnicode); } diff --git a/src/core/fonts.js b/src/core/fonts.js index 475be25a3..2afa54d1d 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -211,9 +211,9 @@ var Glyph = (function GlyphClosure() { })(); var ToUnicodeMap = (function ToUnicodeMapClosure() { - function ToUnicodeMap(cmap) { + function ToUnicodeMap(cmap = []) { // The elements of this._map can be integers or strings, depending on how - // |cmap| was created. + // `cmap` was created. this._map = cmap; } @@ -516,6 +516,7 @@ var Font = (function FontClosure() { this.defaultEncoding = properties.defaultEncoding; this.toUnicode = properties.toUnicode; + this.fallbackToUnicode = properties.fallbackToUnicode || new ToUnicodeMap(); this.toFontChar = []; @@ -2766,7 +2767,8 @@ var Font = (function FontClosure() { width = isNum(width) ? width : this.defaultWidth; var vmetric = this.vmetrics && this.vmetrics[widthCode]; - var unicode = this.toUnicode.get(charcode) || charcode; + let unicode = this.toUnicode.get(charcode) || + this.fallbackToUnicode.get(charcode) || charcode; if (typeof unicode === 'number') { unicode = String.fromCharCode(unicode); } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index bed1b9c37..8fd4fc0d6 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -53,6 +53,7 @@ !issue8061.pdf !issue8088.pdf !issue8125.pdf +!issue8229.pdf !issue8372.pdf !issue8424.pdf !issue8480.pdf diff --git a/test/pdfs/issue8229.pdf b/test/pdfs/issue8229.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e50487b12cac549a03efa6575906b6fd777be1db GIT binary patch literal 20854 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