Add ToUnicodeMap class.

This commit is contained in:
Nicholas Nethercote 2014-08-06 18:02:11 -07:00
parent c6c4583956
commit 9576047f0d
2 changed files with 48 additions and 18 deletions

View File

@ -20,8 +20,8 @@
isNum, isStream, isString, JpegStream, Lexer, Metrics, isNum, isStream, isString, JpegStream, Lexer, Metrics,
MurmurHash3_64, Name, Parser, Pattern, PDFImage, PDFJS, serifFonts, MurmurHash3_64, Name, Parser, Pattern, PDFImage, PDFJS, serifFonts,
stdFontMap, symbolsFonts, getTilingPatternIR, warn, Util, Promise, stdFontMap, symbolsFonts, getTilingPatternIR, warn, Util, Promise,
RefSetCache, isRef, TextRenderingMode, CMapFactory, OPS, RefSetCache, isRef, TextRenderingMode, ToUnicodeMap, CMapFactory,
UNSUPPORTED_FEATURES, UnsupportedManager, NormalizedUnicodes, OPS, UNSUPPORTED_FEATURES, UnsupportedManager, NormalizedUnicodes,
IDENTITY_MATRIX, reverseIfRtl, createPromiseCapability, IDENTITY_MATRIX, reverseIfRtl, createPromiseCapability,
getFontType */ getFontType */
@ -1306,12 +1306,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}, },
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) { readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) {
var cmapObj = toUnicode; var cmap, cmapObj = toUnicode;
if (isName(cmapObj)) { if (isName(cmapObj)) {
return CMapFactory.create(cmapObj, cmap = CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap(); { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
return new ToUnicodeMap(cmap);
} else if (isStream(cmapObj)) { } else if (isStream(cmapObj)) {
var cmap = CMapFactory.create(cmapObj, cmap = CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap(); { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
// Convert UTF-16BE // Convert UTF-16BE
// NOTE: cmap can be a sparse array, so use forEach instead of for(;;) // NOTE: cmap can be a sparse array, so use forEach instead of for(;;)
@ -1330,7 +1331,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
cmap[i] = String.fromCharCode.apply(String, str); cmap[i] = String.fromCharCode.apply(String, str);
}); });
return cmap; return new ToUnicodeMap(cmap);
} }
return null; return null;
}, },

View File

@ -2161,6 +2161,36 @@ var Glyph = (function GlyphClosure() {
return Glyph; return Glyph;
})(); })();
var ToUnicodeMap = (function ToUnicodeMapClosure() {
function ToUnicodeMap(cmap) {
// The elements of this._map can be integers or strings, depending on how
// |cmap| was created.
this._map = cmap;
}
ToUnicodeMap.prototype = {
get length() {
return this._map.length;
},
forEach: function(callback) {
for (var charCode in this._map) {
callback(charCode, this._map[charCode].charCodeAt(0));
}
},
get: function(i) {
return this._map[i];
},
charCodeOf: function(v) {
return this._map.indexOf(v);
}
};
return ToUnicodeMap;
})();
/** /**
* 'Font' is the class the outside world should use, it encapsulate all the font * 'Font' is the class the outside world should use, it encapsulate all the font
* decoding logics whatever type it is (assuming the font type is supported). * decoding logics whatever type it is (assuming the font type is supported).
@ -2259,7 +2289,7 @@ var Font = (function FontClosure() {
map[+code] = GlyphMapForStandardFonts[code]; map[+code] = GlyphMapForStandardFonts[code];
} }
this.toFontChar = map; this.toFontChar = map;
this.toUnicode = map; this.toUnicode = new ToUnicodeMap(map);
} else if (/Symbol/i.test(fontName)) { } else if (/Symbol/i.test(fontName)) {
var symbols = Encodings.SymbolSetEncoding; var symbols = Encodings.SymbolSetEncoding;
for (charCode in symbols) { for (charCode in symbols) {
@ -2278,15 +2308,14 @@ var Font = (function FontClosure() {
} }
} else { } else {
var unicodeCharCode, notCidFont = (type.indexOf('CIDFontType') === -1); var unicodeCharCode, notCidFont = (type.indexOf('CIDFontType') === -1);
for (charCode in this.toUnicode) { this.toUnicode.forEach(function(charCode, unicodeCharCode) {
unicodeCharCode = this.toUnicode[charCode].charCodeAt(0);
if (notCidFont) { if (notCidFont) {
glyphName = (properties.differences[charCode] || glyphName = (properties.differences[charCode] ||
properties.defaultEncoding[charCode]); properties.defaultEncoding[charCode]);
unicodeCharCode = (GlyphsUnicode[glyphName] || unicodeCharCode); unicodeCharCode = (GlyphsUnicode[glyphName] || unicodeCharCode);
} }
this.toFontChar[charCode] = unicodeCharCode; this.toFontChar[charCode] = unicodeCharCode;
} }.bind(this));
} }
this.loadedName = fontName.split('-')[0]; this.loadedName = fontName.split('-')[0];
this.loading = false; this.loading = false;
@ -2512,8 +2541,8 @@ var Font = (function FontClosure() {
// First try to map the value to a unicode position if a non identity map // First try to map the value to a unicode position if a non identity map
// was created. // was created.
if (!isIdentityUnicode) { if (!isIdentityUnicode) {
if (toUnicode[originalCharCode] !== undefined) { if (toUnicode.get(originalCharCode) !== undefined) {
var unicode = toUnicode[fontCharCode]; var unicode = toUnicode.get(fontCharCode);
// TODO: Try to map ligatures to the correct spot. // TODO: Try to map ligatures to the correct spot.
if (unicode.length === 1) { if (unicode.length === 1) {
fontCharCode = unicode.charCodeAt(0); fontCharCode = unicode.charCodeAt(0);
@ -3852,7 +3881,7 @@ var Font = (function FontClosure() {
var dupFirstEntry = false; var dupFirstEntry = false;
if (properties.type === 'CIDFontType2' && properties.toUnicode && if (properties.type === 'CIDFontType2' && properties.toUnicode &&
properties.toUnicode[0] > '\u0000') { properties.toUnicode.get(0) > '\u0000') {
// oracle's defect (see 3427), duplicating first entry // oracle's defect (see 3427), duplicating first entry
dupFirstEntry = true; dupFirstEntry = true;
numGlyphs++; numGlyphs++;
@ -4375,7 +4404,7 @@ var Font = (function FontClosure() {
} }
toUnicode[charcode] = String.fromCharCode(GlyphsUnicode[glyphName]); toUnicode[charcode] = String.fromCharCode(GlyphsUnicode[glyphName]);
} }
map.toUnicode = toUnicode; map.toUnicode = new ToUnicodeMap(toUnicode);
return map; return map;
} }
// If the font is a composite font that uses one of the predefined CMaps // If the font is a composite font that uses one of the predefined CMaps
@ -4419,7 +4448,7 @@ var Font = (function FontClosure() {
ucs2.charCodeAt(1)); ucs2.charCodeAt(1));
} }
}); });
map.toUnicode = toUnicode; map.toUnicode = new ToUnicodeMap(toUnicode);
return map; return map;
} }
@ -4430,7 +4459,7 @@ var Font = (function FontClosure() {
toUnicode[i] = String.fromCharCode(i); toUnicode[i] = String.fromCharCode(i);
} }
map.isIdentity = true; map.isIdentity = true;
map.toUnicode = toUnicode; map.toUnicode = new ToUnicodeMap(toUnicode);
return map; return map;
}, },
@ -4459,7 +4488,7 @@ var Font = (function FontClosure() {
} }
// ... via toUnicode map // ... via toUnicode map
if (!charcode && 'toUnicode' in this) { if (!charcode && 'toUnicode' in this) {
charcode = this.toUnicode.indexOf(glyphUnicode); charcode = this.toUnicode.charCodeOf(glyphUnicode);
} }
// setting it to unicode if negative or undefined // setting it to unicode if negative or undefined
if (charcode <= 0) { if (charcode <= 0) {
@ -4489,7 +4518,7 @@ var Font = (function FontClosure() {
width = isNum(width) ? width : this.defaultWidth; width = isNum(width) ? width : this.defaultWidth;
var vmetric = this.vmetrics && this.vmetrics[widthCode]; var vmetric = this.vmetrics && this.vmetrics[widthCode];
var unicode = this.toUnicode[charcode] || charcode; var unicode = this.toUnicode.get(charcode) || charcode;
if (typeof unicode === 'number') { if (typeof unicode === 'number') {
unicode = String.fromCharCode(unicode); unicode = String.fromCharCode(unicode);
} }