Remove the remaining closure in the src/core/cmap.js
file
With modern JavaScript we (usually) no longer need to keep old closures, which slightly reduces the size of the code.
This commit is contained in:
parent
244002502b
commit
cabc98f310
508
src/core/cmap.js
508
src/core/cmap.js
@ -444,289 +444,283 @@ class IdentityCMap extends CMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CMapFactory = (function CMapFactoryClosure() {
|
function strToInt(str) {
|
||||||
function strToInt(str) {
|
let a = 0;
|
||||||
let a = 0;
|
for (let i = 0; i < str.length; i++) {
|
||||||
for (let i = 0; i < str.length; i++) {
|
a = (a << 8) | str.charCodeAt(i);
|
||||||
a = (a << 8) | str.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return a >>> 0;
|
|
||||||
}
|
}
|
||||||
|
return a >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
function expectString(obj) {
|
function expectString(obj) {
|
||||||
if (typeof obj !== "string") {
|
if (typeof obj !== "string") {
|
||||||
throw new FormatError("Malformed CMap: expected string.");
|
throw new FormatError("Malformed CMap: expected string.");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function expectInt(obj) {
|
function expectInt(obj) {
|
||||||
if (!Number.isInteger(obj)) {
|
if (!Number.isInteger(obj)) {
|
||||||
throw new FormatError("Malformed CMap: expected int.");
|
throw new FormatError("Malformed CMap: expected int.");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseBfChar(cMap, lexer) {
|
function parseBfChar(cMap, lexer) {
|
||||||
while (true) {
|
while (true) {
|
||||||
let obj = lexer.getObj();
|
let obj = lexer.getObj();
|
||||||
if (obj === EOF) {
|
if (obj === EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isCmd(obj, "endbfchar")) {
|
if (isCmd(obj, "endbfchar")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
expectString(obj);
|
expectString(obj);
|
||||||
const src = strToInt(obj);
|
const src = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
// TODO are /dstName used?
|
||||||
|
expectString(obj);
|
||||||
|
const dst = obj;
|
||||||
|
cMap.mapOne(src, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseBfRange(cMap, lexer) {
|
||||||
|
while (true) {
|
||||||
|
let obj = lexer.getObj();
|
||||||
|
if (obj === EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isCmd(obj, "endbfrange")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
expectString(obj);
|
||||||
|
const low = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
expectString(obj);
|
||||||
|
const high = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
if (Number.isInteger(obj) || typeof obj === "string") {
|
||||||
|
const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;
|
||||||
|
cMap.mapBfRange(low, high, dstLow);
|
||||||
|
} else if (isCmd(obj, "[")) {
|
||||||
obj = lexer.getObj();
|
obj = lexer.getObj();
|
||||||
// TODO are /dstName used?
|
const array = [];
|
||||||
expectString(obj);
|
while (!isCmd(obj, "]") && obj !== EOF) {
|
||||||
const dst = obj;
|
array.push(obj);
|
||||||
cMap.mapOne(src, dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseBfRange(cMap, lexer) {
|
|
||||||
while (true) {
|
|
||||||
let obj = lexer.getObj();
|
|
||||||
if (obj === EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isCmd(obj, "endbfrange")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
expectString(obj);
|
|
||||||
const low = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
expectString(obj);
|
|
||||||
const high = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
if (Number.isInteger(obj) || typeof obj === "string") {
|
|
||||||
const dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;
|
|
||||||
cMap.mapBfRange(low, high, dstLow);
|
|
||||||
} else if (isCmd(obj, "[")) {
|
|
||||||
obj = lexer.getObj();
|
obj = lexer.getObj();
|
||||||
const array = [];
|
|
||||||
while (!isCmd(obj, "]") && obj !== EOF) {
|
|
||||||
array.push(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
}
|
|
||||||
cMap.mapBfRangeToArray(low, high, array);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
cMap.mapBfRangeToArray(low, high, array);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
throw new FormatError("Invalid bf range.");
|
|
||||||
}
|
}
|
||||||
|
throw new FormatError("Invalid bf range.");
|
||||||
|
}
|
||||||
|
|
||||||
function parseCidChar(cMap, lexer) {
|
function parseCidChar(cMap, lexer) {
|
||||||
while (true) {
|
while (true) {
|
||||||
let obj = lexer.getObj();
|
let obj = lexer.getObj();
|
||||||
|
if (obj === EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isCmd(obj, "endcidchar")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
expectString(obj);
|
||||||
|
const src = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
expectInt(obj);
|
||||||
|
const dst = obj;
|
||||||
|
cMap.mapOne(src, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCidRange(cMap, lexer) {
|
||||||
|
while (true) {
|
||||||
|
let obj = lexer.getObj();
|
||||||
|
if (obj === EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isCmd(obj, "endcidrange")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
expectString(obj);
|
||||||
|
const low = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
expectString(obj);
|
||||||
|
const high = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
expectInt(obj);
|
||||||
|
const dstLow = obj;
|
||||||
|
cMap.mapCidRange(low, high, dstLow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCodespaceRange(cMap, lexer) {
|
||||||
|
while (true) {
|
||||||
|
let obj = lexer.getObj();
|
||||||
|
if (obj === EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isCmd(obj, "endcodespacerange")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof obj !== "string") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const low = strToInt(obj);
|
||||||
|
obj = lexer.getObj();
|
||||||
|
if (typeof obj !== "string") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const high = strToInt(obj);
|
||||||
|
cMap.addCodespaceRange(obj.length, low, high);
|
||||||
|
}
|
||||||
|
throw new FormatError("Invalid codespace range.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseWMode(cMap, lexer) {
|
||||||
|
const obj = lexer.getObj();
|
||||||
|
if (Number.isInteger(obj)) {
|
||||||
|
cMap.vertical = !!obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCMapName(cMap, lexer) {
|
||||||
|
const obj = lexer.getObj();
|
||||||
|
if (obj instanceof Name) {
|
||||||
|
cMap.name = obj.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
|
||||||
|
let previous, embeddedUseCMap;
|
||||||
|
objLoop: while (true) {
|
||||||
|
try {
|
||||||
|
const obj = lexer.getObj();
|
||||||
if (obj === EOF) {
|
if (obj === EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (obj instanceof Name) {
|
||||||
if (isCmd(obj, "endcidchar")) {
|
if (obj.name === "WMode") {
|
||||||
return;
|
parseWMode(cMap, lexer);
|
||||||
}
|
} else if (obj.name === "CMapName") {
|
||||||
expectString(obj);
|
parseCMapName(cMap, lexer);
|
||||||
const src = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
expectInt(obj);
|
|
||||||
const dst = obj;
|
|
||||||
cMap.mapOne(src, dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCidRange(cMap, lexer) {
|
|
||||||
while (true) {
|
|
||||||
let obj = lexer.getObj();
|
|
||||||
if (obj === EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isCmd(obj, "endcidrange")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
expectString(obj);
|
|
||||||
const low = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
expectString(obj);
|
|
||||||
const high = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
expectInt(obj);
|
|
||||||
const dstLow = obj;
|
|
||||||
cMap.mapCidRange(low, high, dstLow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCodespaceRange(cMap, lexer) {
|
|
||||||
while (true) {
|
|
||||||
let obj = lexer.getObj();
|
|
||||||
if (obj === EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isCmd(obj, "endcodespacerange")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeof obj !== "string") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const low = strToInt(obj);
|
|
||||||
obj = lexer.getObj();
|
|
||||||
if (typeof obj !== "string") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const high = strToInt(obj);
|
|
||||||
cMap.addCodespaceRange(obj.length, low, high);
|
|
||||||
}
|
|
||||||
throw new FormatError("Invalid codespace range.");
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseWMode(cMap, lexer) {
|
|
||||||
const obj = lexer.getObj();
|
|
||||||
if (Number.isInteger(obj)) {
|
|
||||||
cMap.vertical = !!obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCMapName(cMap, lexer) {
|
|
||||||
const obj = lexer.getObj();
|
|
||||||
if (obj instanceof Name) {
|
|
||||||
cMap.name = obj.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
|
|
||||||
let previous, embeddedUseCMap;
|
|
||||||
objLoop: while (true) {
|
|
||||||
try {
|
|
||||||
const obj = lexer.getObj();
|
|
||||||
if (obj === EOF) {
|
|
||||||
break;
|
|
||||||
} else if (obj instanceof Name) {
|
|
||||||
if (obj.name === "WMode") {
|
|
||||||
parseWMode(cMap, lexer);
|
|
||||||
} else if (obj.name === "CMapName") {
|
|
||||||
parseCMapName(cMap, lexer);
|
|
||||||
}
|
|
||||||
previous = obj;
|
|
||||||
} else if (obj instanceof Cmd) {
|
|
||||||
switch (obj.cmd) {
|
|
||||||
case "endcmap":
|
|
||||||
break objLoop;
|
|
||||||
case "usecmap":
|
|
||||||
if (previous instanceof Name) {
|
|
||||||
embeddedUseCMap = previous.name;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "begincodespacerange":
|
|
||||||
parseCodespaceRange(cMap, lexer);
|
|
||||||
break;
|
|
||||||
case "beginbfchar":
|
|
||||||
parseBfChar(cMap, lexer);
|
|
||||||
break;
|
|
||||||
case "begincidchar":
|
|
||||||
parseCidChar(cMap, lexer);
|
|
||||||
break;
|
|
||||||
case "beginbfrange":
|
|
||||||
parseBfRange(cMap, lexer);
|
|
||||||
break;
|
|
||||||
case "begincidrange":
|
|
||||||
parseCidRange(cMap, lexer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
previous = obj;
|
||||||
if (ex instanceof MissingDataException) {
|
} else if (obj instanceof Cmd) {
|
||||||
throw ex;
|
switch (obj.cmd) {
|
||||||
|
case "endcmap":
|
||||||
|
break objLoop;
|
||||||
|
case "usecmap":
|
||||||
|
if (previous instanceof Name) {
|
||||||
|
embeddedUseCMap = previous.name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "begincodespacerange":
|
||||||
|
parseCodespaceRange(cMap, lexer);
|
||||||
|
break;
|
||||||
|
case "beginbfchar":
|
||||||
|
parseBfChar(cMap, lexer);
|
||||||
|
break;
|
||||||
|
case "begincidchar":
|
||||||
|
parseCidChar(cMap, lexer);
|
||||||
|
break;
|
||||||
|
case "beginbfrange":
|
||||||
|
parseBfRange(cMap, lexer);
|
||||||
|
break;
|
||||||
|
case "begincidrange":
|
||||||
|
parseCidRange(cMap, lexer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
warn("Invalid cMap data: " + ex);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
if (ex instanceof MissingDataException) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
warn("Invalid cMap data: " + ex);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!useCMap && embeddedUseCMap) {
|
if (!useCMap && embeddedUseCMap) {
|
||||||
// Load the useCMap definition from the file only if there wasn't one
|
// Load the useCMap definition from the file only if there wasn't one
|
||||||
// specified.
|
// specified.
|
||||||
useCMap = embeddedUseCMap;
|
useCMap = embeddedUseCMap;
|
||||||
|
}
|
||||||
|
if (useCMap) {
|
||||||
|
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||||
|
}
|
||||||
|
return cMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
|
||||||
|
cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);
|
||||||
|
// If there aren't any code space ranges defined clone all the parent ones
|
||||||
|
// into this cMap.
|
||||||
|
if (cMap.numCodespaceRanges === 0) {
|
||||||
|
const useCodespaceRanges = cMap.useCMap.codespaceRanges;
|
||||||
|
for (let i = 0; i < useCodespaceRanges.length; i++) {
|
||||||
|
cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
|
||||||
}
|
}
|
||||||
if (useCMap) {
|
cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
|
||||||
|
}
|
||||||
|
// Merge the map into the current one, making sure not to override
|
||||||
|
// any previously defined entries.
|
||||||
|
cMap.useCMap.forEach(function (key, value) {
|
||||||
|
if (!cMap.contains(key)) {
|
||||||
|
cMap.mapOne(key, cMap.useCMap.lookup(key));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return cMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createBuiltInCMap(name, fetchBuiltInCMap) {
|
||||||
|
if (name === "Identity-H") {
|
||||||
|
return new IdentityCMap(false, 2);
|
||||||
|
} else if (name === "Identity-V") {
|
||||||
|
return new IdentityCMap(true, 2);
|
||||||
|
}
|
||||||
|
if (!BUILT_IN_CMAPS.includes(name)) {
|
||||||
|
throw new Error("Unknown CMap name: " + name);
|
||||||
|
}
|
||||||
|
if (!fetchBuiltInCMap) {
|
||||||
|
throw new Error("Built-in CMap parameters are not provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { cMapData, compressionType } = await fetchBuiltInCMap(name);
|
||||||
|
const cMap = new CMap(true);
|
||||||
|
|
||||||
|
if (compressionType === CMapCompressionType.BINARY) {
|
||||||
|
return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
|
||||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||||
}
|
|
||||||
return cMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
|
|
||||||
cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);
|
|
||||||
// If there aren't any code space ranges defined clone all the parent ones
|
|
||||||
// into this cMap.
|
|
||||||
if (cMap.numCodespaceRanges === 0) {
|
|
||||||
const useCodespaceRanges = cMap.useCMap.codespaceRanges;
|
|
||||||
for (let i = 0; i < useCodespaceRanges.length; i++) {
|
|
||||||
cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
|
|
||||||
}
|
|
||||||
cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
|
|
||||||
}
|
|
||||||
// Merge the map into the current one, making sure not to override
|
|
||||||
// any previously defined entries.
|
|
||||||
cMap.useCMap.forEach(function (key, value) {
|
|
||||||
if (!cMap.contains(key)) {
|
|
||||||
cMap.mapOne(key, cMap.useCMap.lookup(key));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return cMap;
|
|
||||||
}
|
}
|
||||||
|
if (compressionType === CMapCompressionType.NONE) {
|
||||||
async function createBuiltInCMap(name, fetchBuiltInCMap) {
|
const lexer = new Lexer(new Stream(cMapData));
|
||||||
if (name === "Identity-H") {
|
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
|
||||||
return new IdentityCMap(false, 2);
|
|
||||||
} else if (name === "Identity-V") {
|
|
||||||
return new IdentityCMap(true, 2);
|
|
||||||
}
|
|
||||||
if (!BUILT_IN_CMAPS.includes(name)) {
|
|
||||||
throw new Error("Unknown CMap name: " + name);
|
|
||||||
}
|
|
||||||
if (!fetchBuiltInCMap) {
|
|
||||||
throw new Error("Built-in CMap parameters are not provided.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const { cMapData, compressionType } = await fetchBuiltInCMap(name);
|
|
||||||
const cMap = new CMap(true);
|
|
||||||
|
|
||||||
if (compressionType === CMapCompressionType.BINARY) {
|
|
||||||
return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
|
|
||||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (compressionType === CMapCompressionType.NONE) {
|
|
||||||
const lexer = new Lexer(new Stream(cMapData));
|
|
||||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
|
|
||||||
}
|
|
||||||
throw new Error(`Invalid CMap "compressionType" value: ${compressionType}`);
|
|
||||||
}
|
}
|
||||||
|
throw new Error(`Invalid CMap "compressionType" value: ${compressionType}`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
class CMapFactory {
|
||||||
async create(params) {
|
static async create({ encoding, fetchBuiltInCMap, useCMap }) {
|
||||||
const encoding = params.encoding;
|
if (encoding instanceof Name) {
|
||||||
const fetchBuiltInCMap = params.fetchBuiltInCMap;
|
return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
|
||||||
const useCMap = params.useCMap;
|
} else if (encoding instanceof BaseStream) {
|
||||||
|
const parsedCMap = await parseCMap(
|
||||||
|
/* cMap = */ new CMap(),
|
||||||
|
/* lexer = */ new Lexer(encoding),
|
||||||
|
fetchBuiltInCMap,
|
||||||
|
useCMap
|
||||||
|
);
|
||||||
|
|
||||||
if (encoding instanceof Name) {
|
if (parsedCMap.isIdentityCMap) {
|
||||||
return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
|
return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
|
||||||
} else if (encoding instanceof BaseStream) {
|
|
||||||
const parsedCMap = await parseCMap(
|
|
||||||
/* cMap = */ new CMap(),
|
|
||||||
/* lexer = */ new Lexer(encoding),
|
|
||||||
fetchBuiltInCMap,
|
|
||||||
useCMap
|
|
||||||
);
|
|
||||||
|
|
||||||
if (parsedCMap.isIdentityCMap) {
|
|
||||||
return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
|
|
||||||
}
|
|
||||||
return parsedCMap;
|
|
||||||
}
|
}
|
||||||
throw new Error("Encoding required.");
|
return parsedCMap;
|
||||||
},
|
}
|
||||||
};
|
throw new Error("Encoding required.");
|
||||||
})();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export { CMap, CMapFactory, IdentityCMap };
|
export { CMap, CMapFactory, IdentityCMap };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user