Merge pull request #13084 from Snuffleupagus/type1-class

Enable the ESLint `no-var` rule in a few font-parsing files, and convert `src/core/type1_parser.js` to use "standard" classes
This commit is contained in:
Tim van der Meij 2021-03-13 13:15:53 +01:00 committed by GitHub
commit 17c0bf0473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 413 additions and 416 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable no-var */
import { import {
bytesToString, bytesToString,
@ -26,7 +25,7 @@ import { getGlyphsUnicode } from "./glyphlist.js";
import { StandardEncoding } from "./encodings.js"; import { StandardEncoding } from "./encodings.js";
import { Stream } from "./stream.js"; import { Stream } from "./stream.js";
var FontRendererFactory = (function FontRendererFactoryClosure() { const FontRendererFactory = (function FontRendererFactoryClosure() {
function getLong(data, offset) { function getLong(data, offset) {
return ( return (
(data[offset] << 24) | (data[offset] << 24) |
@ -52,15 +51,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} }
function parseCmap(data, start, end) { function parseCmap(data, start, end) {
var offset = const offset =
getUshort(data, start + 2) === 1 getUshort(data, start + 2) === 1
? getLong(data, start + 8) ? getLong(data, start + 8)
: getLong(data, start + 16); : getLong(data, start + 16);
var format = getUshort(data, start + offset); const format = getUshort(data, start + offset);
var ranges, p, i; let ranges, p, i;
if (format === 4) { if (format === 4) {
getUshort(data, start + offset + 2); // length getUshort(data, start + offset + 2); // length
var segCount = getUshort(data, start + offset + 6) >> 1; const segCount = getUshort(data, start + offset + 6) >> 1;
p = start + offset + 14; p = start + offset + 14;
ranges = []; ranges = [];
for (i = 0; i < segCount; i++, p += 2) { for (i = 0; i < segCount; i++, p += 2) {
@ -74,12 +73,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
ranges[i].idDelta = getUshort(data, p); ranges[i].idDelta = getUshort(data, p);
} }
for (i = 0; i < segCount; i++, p += 2) { for (i = 0; i < segCount; i++, p += 2) {
var idOffset = getUshort(data, p); let idOffset = getUshort(data, p);
if (idOffset === 0) { if (idOffset === 0) {
continue; continue;
} }
ranges[i].ids = []; ranges[i].ids = [];
for (var j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) { for (let j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {
ranges[i].ids[j] = getUshort(data, p + idOffset); ranges[i].ids[j] = getUshort(data, p + idOffset);
idOffset += 2; idOffset += 2;
} }
@ -87,7 +86,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
return ranges; return ranges;
} else if (format === 12) { } else if (format === 12) {
getLong(data, start + offset + 4); // length getLong(data, start + offset + 4); // length
var groups = getLong(data, start + offset + 12); const groups = getLong(data, start + offset + 12);
p = start + offset + 16; p = start + offset + 16;
ranges = []; ranges = [];
for (i = 0; i < groups; i++) { for (i = 0; i < groups; i++) {
@ -104,13 +103,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} }
function parseCff(data, start, end, seacAnalysisEnabled) { function parseCff(data, start, end, seacAnalysisEnabled) {
var properties = {}; const properties = {};
var parser = new CFFParser( const parser = new CFFParser(
new Stream(data, start, end - start), new Stream(data, start, end - start),
properties, properties,
seacAnalysisEnabled seacAnalysisEnabled
); );
var cff = parser.parse(); const cff = parser.parse();
return { return {
glyphs: cff.charStrings.objects, glyphs: cff.charStrings.objects,
subrs: subrs:
@ -125,7 +124,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} }
function parseGlyfTable(glyf, loca, isGlyphLocationsLong) { function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
var itemSize, itemDecode; let itemSize, itemDecode;
if (isGlyphLocationsLong) { if (isGlyphLocationsLong) {
itemSize = 4; itemSize = 4;
itemDecode = function fontItemDecodeLong(data, offset) { itemDecode = function fontItemDecodeLong(data, offset) {
@ -142,10 +141,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
return (data[offset] << 9) | (data[offset + 1] << 1); return (data[offset] << 9) | (data[offset + 1] << 1);
}; };
} }
var glyphs = []; const glyphs = [];
var startOffset = itemDecode(loca, 0); let startOffset = itemDecode(loca, 0);
for (var j = itemSize; j < loca.length; j += itemSize) { for (let j = itemSize; j < loca.length; j += itemSize) {
var endOffset = itemDecode(loca, j); const endOffset = itemDecode(loca, j);
glyphs.push(glyf.subarray(startOffset, endOffset)); glyphs.push(glyf.subarray(startOffset, endOffset));
startOffset = endOffset; startOffset = endOffset;
} }
@ -153,12 +152,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} }
function lookupCmap(ranges, unicode) { function lookupCmap(ranges, unicode) {
var code = unicode.codePointAt(0), const code = unicode.codePointAt(0);
gid = 0; let gid = 0,
var l = 0, l = 0,
r = ranges.length - 1; r = ranges.length - 1;
while (l < r) { while (l < r) {
var c = (l + r + 1) >> 1; const c = (l + r + 1) >> 1;
if (code < ranges[c].start) { if (code < ranges[c].start) {
r = c - 1; r = c - 1;
} else { } else {
@ -188,19 +187,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
cmds.push({ cmd: "quadraticCurveTo", args: [xa, ya, x, y] }); cmds.push({ cmd: "quadraticCurveTo", args: [xa, ya, x, y] });
} }
var i = 0; let i = 0;
var numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16; const numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
var flags; let flags;
var x = 0, let x = 0,
y = 0; y = 0;
i += 10; i += 10;
if (numberOfContours < 0) { if (numberOfContours < 0) {
// composite glyph // composite glyph
do { do {
flags = (code[i] << 8) | code[i + 1]; flags = (code[i] << 8) | code[i + 1];
var glyphIndex = (code[i + 2] << 8) | code[i + 3]; const glyphIndex = (code[i + 2] << 8) | code[i + 3];
i += 4; i += 4;
var arg1, arg2; let arg1, arg2;
if (flags & 0x01) { if (flags & 0x01) {
arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16; arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16; arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16;
@ -216,7 +215,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
x = 0; x = 0;
y = 0; // TODO "they are points" ? y = 0; // TODO "they are points" ?
} }
var scaleX = 1, let scaleX = 1,
scaleY = 1, scaleY = 1,
scale01 = 0, scale01 = 0,
scale10 = 0; scale10 = 0;
@ -235,7 +234,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
scaleY = ((code[i + 6] << 24) | (code[i + 7] << 16)) / 1073741824; scaleY = ((code[i + 6] << 24) | (code[i + 7] << 16)) / 1073741824;
i += 8; i += 8;
} }
var subglyph = font.glyphs[glyphIndex]; const subglyph = font.glyphs[glyphIndex];
if (subglyph) { if (subglyph) {
cmds.push({ cmd: "save" }); cmds.push({ cmd: "save" });
cmds.push({ cmds.push({
@ -248,19 +247,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} while (flags & 0x20); } while (flags & 0x20);
} else { } else {
// simple glyph // simple glyph
var endPtsOfContours = []; const endPtsOfContours = [];
var j, jj; let j, jj;
for (j = 0; j < numberOfContours; j++) { for (j = 0; j < numberOfContours; j++) {
endPtsOfContours.push((code[i] << 8) | code[i + 1]); endPtsOfContours.push((code[i] << 8) | code[i + 1]);
i += 2; i += 2;
} }
var instructionLength = (code[i] << 8) | code[i + 1]; const instructionLength = (code[i] << 8) | code[i + 1];
i += 2 + instructionLength; // skipping the instructions i += 2 + instructionLength; // skipping the instructions
var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1; const numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
var points = []; const points = [];
while (points.length < numberOfPoints) { while (points.length < numberOfPoints) {
flags = code[i++]; flags = code[i++];
var repeat = 1; let repeat = 1;
if (flags & 0x08) { if (flags & 0x08) {
repeat += code[i++]; repeat += code[i++];
} }
@ -299,12 +298,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
points[j].y = y; points[j].y = y;
} }
var startPoint = 0; let startPoint = 0;
for (i = 0; i < numberOfContours; i++) { for (i = 0; i < numberOfContours; i++) {
var endPoint = endPtsOfContours[i]; const endPoint = endPtsOfContours[i];
// contours might have implicit points, which is located in the middle // contours might have implicit points, which is located in the middle
// between two neighboring off-curve points // between two neighboring off-curve points
var contour = points.slice(startPoint, endPoint + 1); const contour = points.slice(startPoint, endPoint + 1);
if (contour[0].flags & 1) { if (contour[0].flags & 1) {
contour.push(contour[0]); // using start point at the contour end contour.push(contour[0]); // using start point at the contour end
} else if (contour[contour.length - 1].flags & 1) { } else if (contour[contour.length - 1].flags & 1) {
@ -312,7 +311,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
contour.unshift(contour[contour.length - 1]); contour.unshift(contour[contour.length - 1]);
} else { } else {
// start and end are off-curve points, creating implicit one // start and end are off-curve points, creating implicit one
var p = { const p = {
flags: 1, flags: 1,
x: (contour[0].x + contour[contour.length - 1].x) / 2, x: (contour[0].x + contour[contour.length - 1].x) / 2,
y: (contour[0].y + contour[contour.length - 1].y) / 2, y: (contour[0].y + contour[contour.length - 1].y) / 2,
@ -357,17 +356,17 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
cmds.push({ cmd: "bezierCurveTo", args: [x1, y1, x2, y2, x, y] }); cmds.push({ cmd: "bezierCurveTo", args: [x1, y1, x2, y2, x, y] });
} }
var stack = []; const stack = [];
var x = 0, let x = 0,
y = 0; y = 0;
var stems = 0; let stems = 0;
function parse(code) { function parse(code) {
var i = 0; let i = 0;
while (i < code.length) { while (i < code.length) {
var stackClean = false; let stackClean = false;
var v = code[i++]; let v = code[i++];
var xa, xb, ya, yb, y1, y2, y3, n, subrCode; let xa, xb, ya, yb, y1, y2, y3, n, subrCode;
switch (v) { switch (v) {
case 1: // hstem case 1: // hstem
stems += stack.length >> 1; stems += stack.length >> 1;
@ -495,7 +494,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
bezierCurveTo(xa, y2, xb, y3, x, y); bezierCurveTo(xa, y2, xb, y3, x, y);
break; break;
case 37: // flex1 case 37: // flex1
var x0 = x, const x0 = x,
y0 = y; y0 = y;
xa = x + stack.shift(); xa = x + stack.shift();
ya = y + stack.shift(); ya = y + stack.shift();
@ -523,13 +522,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
break; break;
case 14: // endchar case 14: // endchar
if (stack.length >= 4) { if (stack.length >= 4) {
var achar = stack.pop(); const achar = stack.pop();
var bchar = stack.pop(); const bchar = stack.pop();
y = stack.pop(); y = stack.pop();
x = stack.pop(); x = stack.pop();
cmds.push({ cmd: "save" }); cmds.push({ cmd: "save" });
cmds.push({ cmd: "translate", args: [x, y] }); cmds.push({ cmd: "translate", args: [x, y] });
var cmap = lookupCmap( let cmap = lookupCmap(
font.cmap, font.cmap,
String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]]) String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]])
); );
@ -830,13 +829,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
return { return {
create: function FontRendererFactory_create(font, seacAnalysisEnabled) { create: function FontRendererFactory_create(font, seacAnalysisEnabled) {
var data = new Uint8Array(font.data); const data = new Uint8Array(font.data);
var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm; let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
var numTables = getUshort(data, 4); const numTables = getUshort(data, 4);
for (var i = 0, p = 12; i < numTables; i++, p += 16) { for (let i = 0, p = 12; i < numTables; i++, p += 16) {
var tag = bytesToString(data.subarray(p, p + 4)); const tag = bytesToString(data.subarray(p, p + 4));
var offset = getLong(data, p + 8); const offset = getLong(data, p + 8);
var length = getLong(data, p + 12); const length = getLong(data, p + 12);
switch (tag) { switch (tag) {
case "cmap": case "cmap":
cmap = parseCmap(data, offset, offset + length); cmap = parseCmap(data, offset, offset + length);
@ -858,7 +857,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
} }
if (glyf) { if (glyf) {
var fontMatrix = !unitsPerEm const fontMatrix = !unitsPerEm
? font.fontMatrix ? font.fontMatrix
: [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0]; : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
return new TrueTypeCompiled( return new TrueTypeCompiled(

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable no-var */
import { getEncoding } from "./encodings.js"; import { getEncoding } from "./encodings.js";
import { isWhiteSpace } from "./core_utils.js"; import { isWhiteSpace } from "./core_utils.js";
@ -21,7 +20,7 @@ import { warn } from "../shared/util.js";
// Hinting is currently disabled due to unknown problems on windows // Hinting is currently disabled due to unknown problems on windows
// in tracemonkey and various other pdfs with type1 fonts. // in tracemonkey and various other pdfs with type1 fonts.
var HINTING_ENABLED = false; const HINTING_ENABLED = false;
/* /*
* CharStrings are encoded following the the CharString Encoding sequence * CharStrings are encoded following the the CharString Encoding sequence
@ -61,8 +60,8 @@ var HINTING_ENABLED = false;
* to be encoded and this encoding technique helps to minimize the length of * to be encoded and this encoding technique helps to minimize the length of
* the charStrings. * the charStrings.
*/ */
var Type1CharString = (function Type1CharStringClosure() { const Type1CharString = (function Type1CharStringClosure() {
var COMMAND_MAP = { const COMMAND_MAP = {
hstem: [1], hstem: [1],
vstem: [3], vstem: [3],
vmoveto: [4], vmoveto: [4],
@ -81,7 +80,8 @@ var Type1CharString = (function Type1CharStringClosure() {
}; };
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
function Type1CharString() { class Type1CharString {
constructor() {
this.width = 0; this.width = 0;
this.lsb = 0; this.lsb = 0;
this.flexing = false; this.flexing = false;
@ -89,17 +89,12 @@ var Type1CharString = (function Type1CharStringClosure() {
this.stack = []; this.stack = [];
} }
Type1CharString.prototype = { convert(encoded, subrs, seacAnalysisEnabled) {
convert: function Type1CharString_convert( const count = encoded.length;
encoded, let error = false;
subrs, let wx, sbx, subrNumber;
seacAnalysisEnabled for (let i = 0; i < count; i++) {
) { let value = encoded[i];
var count = encoded.length;
var error = false;
var wx, sbx, subrNumber;
for (var i = 0; i < count; i++) {
var value = encoded[i];
if (value < 32) { if (value < 32) {
if (value === 12) { if (value === 12) {
value = (value << 8) + encoded[++i]; value = (value << 8) + encoded[++i];
@ -127,7 +122,7 @@ var Type1CharString = (function Type1CharStringClosure() {
} }
// Add the dx for flex and but also swap the values so they are // Add the dx for flex and but also swap the values so they are
// the right order. // the right order.
var dy = this.stack.pop(); const dy = this.stack.pop();
this.stack.push(0, dy); this.stack.push(0, dy);
break; break;
} }
@ -252,7 +247,7 @@ var Type1CharString = (function Type1CharStringClosure() {
// vhea tables reconstruction -- ignoring it. // vhea tables reconstruction -- ignoring it.
this.stack.pop(); // wy this.stack.pop(); // wy
wx = this.stack.pop(); wx = this.stack.pop();
var sby = this.stack.pop(); const sby = this.stack.pop();
sbx = this.stack.pop(); sbx = this.stack.pop();
this.lsb = sbx; this.lsb = sbx;
this.width = wx; this.width = wx;
@ -264,8 +259,8 @@ var Type1CharString = (function Type1CharStringClosure() {
error = true; error = true;
break; break;
} }
var num2 = this.stack.pop(); const num2 = this.stack.pop();
var num1 = this.stack.pop(); const num1 = this.stack.pop();
this.stack.push(num1 / num2); this.stack.push(num1 / num2);
break; break;
case (12 << 8) + 16: // callothersubr case (12 << 8) + 16: // callothersubr
@ -274,9 +269,9 @@ var Type1CharString = (function Type1CharStringClosure() {
break; break;
} }
subrNumber = this.stack.pop(); subrNumber = this.stack.pop();
var numArgs = this.stack.pop(); const numArgs = this.stack.pop();
if (subrNumber === 0 && numArgs === 3) { if (subrNumber === 0 && numArgs === 3) {
var flexArgs = this.stack.splice(this.stack.length - 17, 17); const flexArgs = this.stack.splice(this.stack.length - 17, 17);
this.stack.push( this.stack.push(
flexArgs[2] + flexArgs[0], // bcp1x + rpx flexArgs[2] + flexArgs[0], // bcp1x + rpx
flexArgs[3] + flexArgs[1], // bcp1y + rpy flexArgs[3] + flexArgs[1], // bcp1y + rpy
@ -332,16 +327,16 @@ var Type1CharString = (function Type1CharStringClosure() {
this.stack.push(value); this.stack.push(value);
} }
return error; return error;
}, }
executeCommand(howManyArgs, command, keepStack) { executeCommand(howManyArgs, command, keepStack) {
var stackLength = this.stack.length; const stackLength = this.stack.length;
if (howManyArgs > stackLength) { if (howManyArgs > stackLength) {
return true; return true;
} }
var start = stackLength - howManyArgs; const start = stackLength - howManyArgs;
for (var i = start; i < stackLength; i++) { for (let i = start; i < stackLength; i++) {
var value = this.stack[i]; let value = this.stack[i];
if (Number.isInteger(value)) { if (Number.isInteger(value)) {
this.output.push(28, (value >> 8) & 0xff, value & 0xff); this.output.push(28, (value >> 8) & 0xff, value & 0xff);
} else { } else {
@ -363,8 +358,8 @@ var Type1CharString = (function Type1CharStringClosure() {
this.stack.length = 0; this.stack.length = 0;
} }
return false; return false;
}, }
}; }
return Type1CharString; return Type1CharString;
})(); })();
@ -377,14 +372,14 @@ var Type1CharString = (function Type1CharStringClosure() {
* of PostScript, but it is possible in most cases to extract what we need * of PostScript, but it is possible in most cases to extract what we need
* without a full parse. * without a full parse.
*/ */
var Type1Parser = (function Type1ParserClosure() { const Type1Parser = (function Type1ParserClosure() {
/* /*
* Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence
* of Plaintext Bytes. The function took a key as a parameter which can be * of Plaintext Bytes. The function took a key as a parameter which can be
* for decrypting the eexec block of for decoding charStrings. * for decrypting the eexec block of for decoding charStrings.
*/ */
var EEXEC_ENCRYPT_KEY = 55665; const EEXEC_ENCRYPT_KEY = 55665;
var CHAR_STRS_ENCRYPT_KEY = 4330; const CHAR_STRS_ENCRYPT_KEY = 4330;
function isHexDigit(code) { function isHexDigit(code) {
return ( return (
@ -398,18 +393,18 @@ var Type1Parser = (function Type1ParserClosure() {
if (discardNumber >= data.length) { if (discardNumber >= data.length) {
return new Uint8Array(0); return new Uint8Array(0);
} }
var r = key | 0, const c1 = 52845,
c1 = 52845, c2 = 22719;
c2 = 22719, let r = key | 0,
i, i,
j; j;
for (i = 0; i < discardNumber; i++) { for (i = 0; i < discardNumber; i++) {
r = ((data[i] + r) * c1 + c2) & ((1 << 16) - 1); r = ((data[i] + r) * c1 + c2) & ((1 << 16) - 1);
} }
var count = data.length - discardNumber; const count = data.length - discardNumber;
var decrypted = new Uint8Array(count); const decrypted = new Uint8Array(count);
for (i = discardNumber, j = 0; j < count; i++, j++) { for (i = discardNumber, j = 0; j < count; i++, j++) {
var value = data[i]; const value = data[i];
decrypted[j] = value ^ (r >> 8); decrypted[j] = value ^ (r >> 8);
r = ((value + r) * c1 + c2) & ((1 << 16) - 1); r = ((value + r) * c1 + c2) & ((1 << 16) - 1);
} }
@ -417,25 +412,25 @@ var Type1Parser = (function Type1ParserClosure() {
} }
function decryptAscii(data, key, discardNumber) { function decryptAscii(data, key, discardNumber) {
var r = key | 0, const c1 = 52845,
c1 = 52845,
c2 = 22719; c2 = 22719;
var count = data.length, let r = key | 0;
const count = data.length,
maybeLength = count >>> 1; maybeLength = count >>> 1;
var decrypted = new Uint8Array(maybeLength); const decrypted = new Uint8Array(maybeLength);
var i, j; let i, j;
for (i = 0, j = 0; i < count; i++) { for (i = 0, j = 0; i < count; i++) {
var digit1 = data[i]; const digit1 = data[i];
if (!isHexDigit(digit1)) { if (!isHexDigit(digit1)) {
continue; continue;
} }
i++; i++;
var digit2; let digit2;
while (i < count && !isHexDigit((digit2 = data[i]))) { while (i < count && !isHexDigit((digit2 = data[i]))) {
i++; i++;
} }
if (i < count) { if (i < count) {
var value = parseInt(String.fromCharCode(digit1, digit2), 16); const value = parseInt(String.fromCharCode(digit1, digit2), 16);
decrypted[j++] = value ^ (r >> 8); decrypted[j++] = value ^ (r >> 8);
r = ((value + r) * c1 + c2) & ((1 << 16) - 1); r = ((value + r) * c1 + c2) & ((1 << 16) - 1);
} }
@ -456,10 +451,11 @@ var Type1Parser = (function Type1ParserClosure() {
} }
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
function Type1Parser(stream, encrypted, seacAnalysisEnabled) { class Type1Parser {
constructor(stream, encrypted, seacAnalysisEnabled) {
if (encrypted) { if (encrypted) {
var data = stream.getBytes(); const data = stream.getBytes();
var isBinary = !( const isBinary = !(
(isHexDigit(data[0]) || isWhiteSpace(data[0])) && (isHexDigit(data[0]) || isWhiteSpace(data[0])) &&
isHexDigit(data[1]) && isHexDigit(data[1]) &&
isHexDigit(data[2]) && isHexDigit(data[2]) &&
@ -481,47 +477,45 @@ var Type1Parser = (function Type1ParserClosure() {
this.nextChar(); this.nextChar();
} }
Type1Parser.prototype = { readNumberArray() {
readNumberArray: function Type1Parser_readNumberArray() {
this.getToken(); // read '[' or '{' (arrays can start with either) this.getToken(); // read '[' or '{' (arrays can start with either)
var array = []; const array = [];
while (true) { while (true) {
var token = this.getToken(); const token = this.getToken();
if (token === null || token === "]" || token === "}") { if (token === null || token === "]" || token === "}") {
break; break;
} }
array.push(parseFloat(token || 0)); array.push(parseFloat(token || 0));
} }
return array; return array;
}, }
readNumber: function Type1Parser_readNumber() { readNumber() {
var token = this.getToken(); const token = this.getToken();
return parseFloat(token || 0); return parseFloat(token || 0);
}, }
readInt: function Type1Parser_readInt() { readInt() {
// Use '| 0' to prevent setting a double into length such as the double // Use '| 0' to prevent setting a double into length such as the double
// does not flow into the loop variable. // does not flow into the loop variable.
var token = this.getToken(); const token = this.getToken();
return parseInt(token || 0, 10) | 0; return parseInt(token || 0, 10) | 0;
}, }
readBoolean: function Type1Parser_readBoolean() {
var token = this.getToken();
readBoolean() {
const token = this.getToken();
// Use 1 and 0 since that's what type2 charstrings use. // Use 1 and 0 since that's what type2 charstrings use.
return token === "true" ? 1 : 0; return token === "true" ? 1 : 0;
}, }
nextChar: function Type1_nextChar() { nextChar() {
return (this.currentChar = this.stream.getByte()); return (this.currentChar = this.stream.getByte());
}, }
getToken: function Type1Parser_getToken() { getToken() {
// Eat whitespace and comments. // Eat whitespace and comments.
var comment = false; let comment = false;
var ch = this.currentChar; let ch = this.currentChar;
while (true) { while (true) {
if (ch === -1) { if (ch === -1) {
return null; return null;
@ -542,42 +536,42 @@ var Type1Parser = (function Type1ParserClosure() {
this.nextChar(); this.nextChar();
return String.fromCharCode(ch); return String.fromCharCode(ch);
} }
var token = ""; let token = "";
do { do {
token += String.fromCharCode(ch); token += String.fromCharCode(ch);
ch = this.nextChar(); ch = this.nextChar();
} while (ch >= 0 && !isWhiteSpace(ch) && !isSpecial(ch)); } while (ch >= 0 && !isWhiteSpace(ch) && !isSpecial(ch));
return token; return token;
}, }
readCharStrings: function Type1Parser_readCharStrings(bytes, lenIV) { readCharStrings(bytes, lenIV) {
if (lenIV === -1) { if (lenIV === -1) {
// This isn't in the spec, but Adobe's tx program handles -1 // This isn't in the spec, but Adobe's tx program handles -1
// as plain text. // as plain text.
return bytes; return bytes;
} }
return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV); return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
}, }
/* /*
* Returns an object containing a Subrs array and a CharStrings * Returns an object containing a Subrs array and a CharStrings
* array extracted from and eexec encrypted block of data * array extracted from and eexec encrypted block of data
*/ */
extractFontProgram: function Type1Parser_extractFontProgram(properties) { extractFontProgram(properties) {
var stream = this.stream; const stream = this.stream;
var subrs = [], const subrs = [],
charstrings = []; charstrings = [];
var privateData = Object.create(null); const privateData = Object.create(null);
privateData.lenIV = 4; privateData.lenIV = 4;
var program = { const program = {
subrs: [], subrs: [],
charstrings: [], charstrings: [],
properties: { properties: {
privateData, privateData,
}, },
}; };
var token, length, data, lenIV, encoded; let token, length, data, lenIV, encoded;
while ((token = this.getToken()) !== null) { while ((token = this.getToken()) !== null) {
if (token !== "/") { if (token !== "/") {
continue; continue;
@ -600,7 +594,7 @@ var Type1Parser = (function Type1ParserClosure() {
if (token !== "/") { if (token !== "/") {
continue; continue;
} }
var glyph = this.getToken(); const glyph = this.getToken();
length = this.readInt(); length = this.readInt();
this.getToken(); // read in 'RD' or '-|' this.getToken(); // read in 'RD' or '-|'
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0); data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
@ -639,7 +633,7 @@ var Type1Parser = (function Type1ParserClosure() {
case "OtherBlues": case "OtherBlues":
case "FamilyBlues": case "FamilyBlues":
case "FamilyOtherBlues": case "FamilyOtherBlues":
var blueArray = this.readNumberArray(); const blueArray = this.readNumberArray();
// *Blue* values may contain invalid data: disables reading of // *Blue* values may contain invalid data: disables reading of
// those values when hinting is disabled. // those values when hinting is disabled.
if ( if (
@ -672,16 +666,16 @@ var Type1Parser = (function Type1ParserClosure() {
} }
} }
for (var i = 0; i < charstrings.length; i++) { for (let i = 0; i < charstrings.length; i++) {
glyph = charstrings[i].glyph; const glyph = charstrings[i].glyph;
encoded = charstrings[i].encoded; encoded = charstrings[i].encoded;
var charString = new Type1CharString(); const charString = new Type1CharString();
var error = charString.convert( const error = charString.convert(
encoded, encoded,
subrs, subrs,
this.seacAnalysisEnabled this.seacAnalysisEnabled
); );
var output = charString.output; let output = charString.output;
if (error) { if (error) {
// It seems when FreeType encounters an error while evaluating a glyph // It seems when FreeType encounters an error while evaluating a glyph
// that it completely ignores the glyph so we'll mimic that behaviour // that it completely ignores the glyph so we'll mimic that behaviour
@ -718,10 +712,10 @@ var Type1Parser = (function Type1ParserClosure() {
} }
return program; return program;
}, }
extractFontHeader: function Type1Parser_extractFontHeader(properties) { extractFontHeader(properties) {
var token; let token;
while ((token = this.getToken()) !== null) { while ((token = this.getToken()) !== null) {
if (token !== "/") { if (token !== "/") {
continue; continue;
@ -729,21 +723,21 @@ var Type1Parser = (function Type1ParserClosure() {
token = this.getToken(); token = this.getToken();
switch (token) { switch (token) {
case "FontMatrix": case "FontMatrix":
var matrix = this.readNumberArray(); const matrix = this.readNumberArray();
properties.fontMatrix = matrix; properties.fontMatrix = matrix;
break; break;
case "Encoding": case "Encoding":
var encodingArg = this.getToken(); const encodingArg = this.getToken();
var encoding; let encoding;
if (!/^\d+$/.test(encodingArg)) { if (!/^\d+$/.test(encodingArg)) {
// encoding name is specified // encoding name is specified
encoding = getEncoding(encodingArg); encoding = getEncoding(encodingArg);
} else { } else {
encoding = []; encoding = [];
var size = parseInt(encodingArg, 10) | 0; const size = parseInt(encodingArg, 10) | 0;
this.getToken(); // read in 'array' this.getToken(); // read in 'array'
for (var j = 0; j < size; j++) { for (let j = 0; j < size; j++) {
token = this.getToken(); token = this.getToken();
// skipping till first dup or def (e.g. ignoring for statement) // skipping till first dup or def (e.g. ignoring for statement)
while (token !== "dup" && token !== "def") { while (token !== "dup" && token !== "def") {
@ -755,9 +749,9 @@ var Type1Parser = (function Type1ParserClosure() {
if (token === "def") { if (token === "def") {
break; // read all array data break; // read all array data
} }
var index = this.readInt(); const index = this.readInt();
this.getToken(); // read in '/' this.getToken(); // read in '/'
var glyph = this.getToken(); const glyph = this.getToken();
encoding[index] = glyph; encoding[index] = glyph;
this.getToken(); // read the in 'put' this.getToken(); // read the in 'put'
} }
@ -765,7 +759,7 @@ var Type1Parser = (function Type1ParserClosure() {
properties.builtInEncoding = encoding; properties.builtInEncoding = encoding;
break; break;
case "FontBBox": case "FontBBox":
var fontBBox = this.readNumberArray(); const fontBBox = this.readNumberArray();
// adjusting ascent/descent // adjusting ascent/descent
properties.ascent = Math.max(fontBBox[3], fontBBox[1]); properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
properties.descent = Math.min(fontBBox[1], fontBBox[3]); properties.descent = Math.min(fontBBox[1], fontBBox[3]);
@ -773,8 +767,8 @@ var Type1Parser = (function Type1ParserClosure() {
break; break;
} }
} }
}, }
}; }
return Type1Parser; return Type1Parser;
})(); })();