Convert CMap and IdentityCMap to ES6 classes

Also changes `var` to `let`/`const` in code already touched in the patch.
This commit is contained in:
Jonas Jenwald 2018-07-08 22:41:52 +02:00
parent b773b356af
commit bf6d45f85a

View File

@ -14,8 +14,8 @@
*/ */
import { import {
CMapCompressionType, FormatError, isString, MissingDataException, CMapCompressionType, FormatError, isString, MissingDataException, unreachable,
unreachable, Util, warn warn
} from '../shared/util'; } from '../shared/util';
import { isCmd, isEOF, isName, isStream } from './primitives'; import { isCmd, isEOF, isName, isStream } from './primitives';
import { Lexer } from './parser'; import { Lexer } from './parser';
@ -194,8 +194,8 @@ var BUILT_IN_CMAPS = [
'WP-Symbol']; 'WP-Symbol'];
// CMap, not to be confused with TrueType's cmap. // CMap, not to be confused with TrueType's cmap.
var CMap = (function CMapClosure() { class CMap {
function CMap(builtInCMap) { constructor(builtInCMap = false) {
// Codespace ranges are stored as follows: // Codespace ranges are stored as follows:
// [[1BytePairs], [2BytePairs], [3BytePairs], [4BytePairs]] // [[1BytePairs], [2BytePairs], [3BytePairs], [4BytePairs]]
// where nBytePairs are ranges e.g. [low1, high1, low2, high2, ...] // where nBytePairs are ranges e.g. [low1, high1, low2, high2, ...]
@ -211,204 +211,193 @@ var CMap = (function CMapClosure() {
this.useCMap = null; this.useCMap = null;
this.builtInCMap = builtInCMap; this.builtInCMap = builtInCMap;
} }
CMap.prototype = {
addCodespaceRange(n, low, high) {
this.codespaceRanges[n - 1].push(low, high);
this.numCodespaceRanges++;
},
mapCidRange(low, high, dstLow) { addCodespaceRange(n, low, high) {
while (low <= high) { this.codespaceRanges[n - 1].push(low, high);
this._map[low++] = dstLow++; this.numCodespaceRanges++;
} }
},
mapBfRange(low, high, dstLow) { mapCidRange(low, high, dstLow) {
var lastByte = dstLow.length - 1; while (low <= high) {
while (low <= high) { this._map[low++] = dstLow++;
this._map[low++] = dstLow; }
// Only the last byte has to be incremented. }
dstLow = dstLow.substr(0, lastByte) +
String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
}
},
mapBfRangeToArray(low, high, array) { mapBfRange(low, high, dstLow) {
var i = 0, ii = array.length; var lastByte = dstLow.length - 1;
while (low <= high && i < ii) { while (low <= high) {
this._map[low] = array[i++]; this._map[low++] = dstLow;
++low; // Only the last byte has to be incremented.
} dstLow = dstLow.substr(0, lastByte) +
}, String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
}
}
// This is used for both bf and cid chars. mapBfRangeToArray(low, high, array) {
mapOne(src, dst) { let i = 0, ii = array.length;
this._map[src] = dst; while (low <= high && i < ii) {
}, this._map[low] = array[i++];
++low;
}
}
lookup(code) { // This is used for both bf and cid chars.
return this._map[code]; mapOne(src, dst) {
}, this._map[src] = dst;
}
contains(code) { lookup(code) {
return this._map[code] !== undefined; return this._map[code];
}, }
forEach(callback) { contains(code) {
// Most maps have fewer than 65536 entries, and for those we use normal return this._map[code] !== undefined;
// array iteration. But really sparse tables are possible -- e.g. with }
// indices in the *billions*. For such tables we use for..in, which isn't
// ideal because it stringifies the indices for all present elements, but forEach(callback) {
// it does avoid iterating over every undefined entry. // Most maps have fewer than 65536 entries, and for those we use normal
let map = this._map; // array iteration. But really sparse tables are possible -- e.g. with
let length = map.length; // indices in the *billions*. For such tables we use for..in, which isn't
if (length <= 0x10000) { // ideal because it stringifies the indices for all present elements, but
for (let i = 0; i < length; i++) { // it does avoid iterating over every undefined entry.
if (map[i] !== undefined) { let map = this._map;
callback(i, map[i]); let length = map.length;
} if (length <= 0x10000) {
} for (let i = 0; i < length; i++) {
} else { if (map[i] !== undefined) {
for (let i in map) {
callback(i, map[i]); callback(i, map[i]);
} }
} }
}, } else {
for (let i in map) {
charCodeOf(value) { callback(i, map[i]);
// `Array.prototype.indexOf` is *extremely* inefficient for arrays which
// are both very sparse and very large (see issue8372.pdf).
let map = this._map;
if (map.length <= 0x10000) {
return map.indexOf(value);
} }
for (let charCode in map) { }
if (map[charCode] === value) { }
return (charCode | 0);
charCodeOf(value) {
// `Array.prototype.indexOf` is *extremely* inefficient for arrays which
// are both very sparse and very large (see issue8372.pdf).
const map = this._map;
if (map.length <= 0x10000) {
return map.indexOf(value);
}
for (let charCode in map) {
if (map[charCode] === value) {
return (charCode | 0);
}
}
return -1;
}
getMap() {
return this._map;
}
readCharCode(str, offset, out) {
let c = 0;
const codespaceRanges = this.codespaceRanges;
// 9.7.6.2 CMap Mapping
// The code length is at most 4.
for (let n = 0, nn = codespaceRanges.length; n < nn; n++) {
c = ((c << 8) | str.charCodeAt(offset + n)) >>> 0;
// Check each codespace range to see if it falls within.
const codespaceRange = codespaceRanges[n];
for (let k = 0, kk = codespaceRange.length; k < kk;) {
const low = codespaceRange[k++];
const high = codespaceRange[k++];
if (c >= low && c <= high) {
out.charcode = c;
out.length = n + 1;
return;
} }
} }
return -1; }
}, out.charcode = 0;
out.length = 1;
}
getMap() { get length() {
return this._map; return this._map.length;
}, }
readCharCode(str, offset, out) { get isIdentityCMap() {
var c = 0; if (!(this.name === 'Identity-H' || this.name === 'Identity-V')) {
var codespaceRanges = this.codespaceRanges; return false;
var codespaceRangesLen = this.codespaceRanges.length; }
// 9.7.6.2 CMap Mapping if (this._map.length !== 0x10000) {
// The code length is at most 4. return false;
for (var n = 0; n < codespaceRangesLen; n++) { }
c = ((c << 8) | str.charCodeAt(offset + n)) >>> 0; for (let i = 0; i < 0x10000; i++) {
// Check each codespace range to see if it falls within. if (this._map[i] !== i) {
var codespaceRange = codespaceRanges[n];
for (var k = 0, kk = codespaceRange.length; k < kk;) {
var low = codespaceRange[k++];
var high = codespaceRange[k++];
if (c >= low && c <= high) {
out.charcode = c;
out.length = n + 1;
return;
}
}
}
out.charcode = 0;
out.length = 1;
},
get length() {
return this._map.length;
},
get isIdentityCMap() {
if (!(this.name === 'Identity-H' || this.name === 'Identity-V')) {
return false; return false;
} }
if (this._map.length !== 0x10000) { }
return false; return true;
} }
for (var i = 0; i < 0x10000; i++) { }
if (this._map[i] !== i) {
return false;
}
}
return true;
},
};
return CMap;
})();
// A special case of CMap, where the _map array implicitly has a length of // A special case of CMap, where the _map array implicitly has a length of
// 65536 and each element is equal to its index. // 65536 and each element is equal to its index.
var IdentityCMap = (function IdentityCMapClosure() { class IdentityCMap extends CMap {
function IdentityCMap(vertical, n) { constructor(vertical, n) {
CMap.call(this); super();
this.vertical = vertical; this.vertical = vertical;
this.addCodespaceRange(n, 0, 0xffff); this.addCodespaceRange(n, 0, 0xffff);
} }
Util.inherit(IdentityCMap, CMap, {});
IdentityCMap.prototype = { mapCidRange(low, high, dstLow) {
addCodespaceRange: CMap.prototype.addCodespaceRange, unreachable('should not call mapCidRange');
}
mapCidRange(low, high, dstLow) { mapBfRange(low, high, dstLow) {
unreachable('should not call mapCidRange'); unreachable('should not call mapBfRange');
}, }
mapBfRange(low, high, dstLow) { mapBfRangeToArray(low, high, array) {
unreachable('should not call mapBfRange'); unreachable('should not call mapBfRangeToArray');
}, }
mapBfRangeToArray(low, high, array) { mapOne(src, dst) {
unreachable('should not call mapBfRangeToArray'); unreachable('should not call mapCidOne');
}, }
mapOne(src, dst) { lookup(code) {
unreachable('should not call mapCidOne'); return (Number.isInteger(code) && code <= 0xffff) ? code : undefined;
}, }
lookup(code) { contains(code) {
return (Number.isInteger(code) && code <= 0xffff) ? code : undefined; return Number.isInteger(code) && code <= 0xffff;
}, }
contains(code) { forEach(callback) {
return Number.isInteger(code) && code <= 0xffff; for (let i = 0; i <= 0xffff; i++) {
}, callback(i, i);
}
}
forEach(callback) { charCodeOf(value) {
for (var i = 0; i <= 0xffff; i++) { return (Number.isInteger(value) && value <= 0xffff) ? value : -1;
callback(i, i); }
}
},
charCodeOf(value) { getMap() {
return (Number.isInteger(value) && value <= 0xffff) ? value : -1; // Sometimes identity maps must be instantiated, but it's rare.
}, const map = new Array(0x10000);
for (let i = 0; i <= 0xffff; i++) {
map[i] = i;
}
return map;
}
getMap() { get length() {
// Sometimes identity maps must be instantiated, but it's rare. return 0x10000;
var map = new Array(0x10000); }
for (var i = 0; i <= 0xffff; i++) {
map[i] = i;
}
return map;
},
readCharCode: CMap.prototype.readCharCode, get isIdentityCMap() {
unreachable('should not access .isIdentityCMap');
get length() { }
return 0x10000; }
},
get isIdentityCMap() {
unreachable('should not access .isIdentityCMap');
},
};
return IdentityCMap;
})();
var BinaryCMapReader = (function BinaryCMapReaderClosure() { var BinaryCMapReader = (function BinaryCMapReaderClosure() {
function hexToInt(a, size) { function hexToInt(a, size) {