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:
commit
17c0bf0473
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* eslint-disable no-var */
|
||||
|
||||
import {
|
||||
bytesToString,
|
||||
@ -26,7 +25,7 @@ import { getGlyphsUnicode } from "./glyphlist.js";
|
||||
import { StandardEncoding } from "./encodings.js";
|
||||
import { Stream } from "./stream.js";
|
||||
|
||||
var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
const FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
function getLong(data, offset) {
|
||||
return (
|
||||
(data[offset] << 24) |
|
||||
@ -52,15 +51,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
|
||||
function parseCmap(data, start, end) {
|
||||
var offset =
|
||||
const offset =
|
||||
getUshort(data, start + 2) === 1
|
||||
? getLong(data, start + 8)
|
||||
: getLong(data, start + 16);
|
||||
var format = getUshort(data, start + offset);
|
||||
var ranges, p, i;
|
||||
const format = getUshort(data, start + offset);
|
||||
let ranges, p, i;
|
||||
if (format === 4) {
|
||||
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;
|
||||
ranges = [];
|
||||
for (i = 0; i < segCount; i++, p += 2) {
|
||||
@ -74,12 +73,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
ranges[i].idDelta = getUshort(data, p);
|
||||
}
|
||||
for (i = 0; i < segCount; i++, p += 2) {
|
||||
var idOffset = getUshort(data, p);
|
||||
let idOffset = getUshort(data, p);
|
||||
if (idOffset === 0) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
idOffset += 2;
|
||||
}
|
||||
@ -87,7 +86,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
return ranges;
|
||||
} else if (format === 12) {
|
||||
getLong(data, start + offset + 4); // length
|
||||
var groups = getLong(data, start + offset + 12);
|
||||
const groups = getLong(data, start + offset + 12);
|
||||
p = start + offset + 16;
|
||||
ranges = [];
|
||||
for (i = 0; i < groups; i++) {
|
||||
@ -104,13 +103,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
|
||||
function parseCff(data, start, end, seacAnalysisEnabled) {
|
||||
var properties = {};
|
||||
var parser = new CFFParser(
|
||||
const properties = {};
|
||||
const parser = new CFFParser(
|
||||
new Stream(data, start, end - start),
|
||||
properties,
|
||||
seacAnalysisEnabled
|
||||
);
|
||||
var cff = parser.parse();
|
||||
const cff = parser.parse();
|
||||
return {
|
||||
glyphs: cff.charStrings.objects,
|
||||
subrs:
|
||||
@ -125,7 +124,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
|
||||
function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
|
||||
var itemSize, itemDecode;
|
||||
let itemSize, itemDecode;
|
||||
if (isGlyphLocationsLong) {
|
||||
itemSize = 4;
|
||||
itemDecode = function fontItemDecodeLong(data, offset) {
|
||||
@ -142,10 +141,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
return (data[offset] << 9) | (data[offset + 1] << 1);
|
||||
};
|
||||
}
|
||||
var glyphs = [];
|
||||
var startOffset = itemDecode(loca, 0);
|
||||
for (var j = itemSize; j < loca.length; j += itemSize) {
|
||||
var endOffset = itemDecode(loca, j);
|
||||
const glyphs = [];
|
||||
let startOffset = itemDecode(loca, 0);
|
||||
for (let j = itemSize; j < loca.length; j += itemSize) {
|
||||
const endOffset = itemDecode(loca, j);
|
||||
glyphs.push(glyf.subarray(startOffset, endOffset));
|
||||
startOffset = endOffset;
|
||||
}
|
||||
@ -153,12 +152,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
|
||||
function lookupCmap(ranges, unicode) {
|
||||
var code = unicode.codePointAt(0),
|
||||
gid = 0;
|
||||
var l = 0,
|
||||
const code = unicode.codePointAt(0);
|
||||
let gid = 0,
|
||||
l = 0,
|
||||
r = ranges.length - 1;
|
||||
while (l < r) {
|
||||
var c = (l + r + 1) >> 1;
|
||||
const c = (l + r + 1) >> 1;
|
||||
if (code < ranges[c].start) {
|
||||
r = c - 1;
|
||||
} else {
|
||||
@ -188,19 +187,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
cmds.push({ cmd: "quadraticCurveTo", args: [xa, ya, x, y] });
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
var numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
|
||||
var flags;
|
||||
var x = 0,
|
||||
let i = 0;
|
||||
const numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
|
||||
let flags;
|
||||
let x = 0,
|
||||
y = 0;
|
||||
i += 10;
|
||||
if (numberOfContours < 0) {
|
||||
// composite glyph
|
||||
do {
|
||||
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;
|
||||
var arg1, arg2;
|
||||
let arg1, arg2;
|
||||
if (flags & 0x01) {
|
||||
arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
|
||||
arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16;
|
||||
@ -216,7 +215,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
x = 0;
|
||||
y = 0; // TODO "they are points" ?
|
||||
}
|
||||
var scaleX = 1,
|
||||
let scaleX = 1,
|
||||
scaleY = 1,
|
||||
scale01 = 0,
|
||||
scale10 = 0;
|
||||
@ -235,7 +234,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
scaleY = ((code[i + 6] << 24) | (code[i + 7] << 16)) / 1073741824;
|
||||
i += 8;
|
||||
}
|
||||
var subglyph = font.glyphs[glyphIndex];
|
||||
const subglyph = font.glyphs[glyphIndex];
|
||||
if (subglyph) {
|
||||
cmds.push({ cmd: "save" });
|
||||
cmds.push({
|
||||
@ -248,19 +247,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
} while (flags & 0x20);
|
||||
} else {
|
||||
// simple glyph
|
||||
var endPtsOfContours = [];
|
||||
var j, jj;
|
||||
const endPtsOfContours = [];
|
||||
let j, jj;
|
||||
for (j = 0; j < numberOfContours; j++) {
|
||||
endPtsOfContours.push((code[i] << 8) | code[i + 1]);
|
||||
i += 2;
|
||||
}
|
||||
var instructionLength = (code[i] << 8) | code[i + 1];
|
||||
const instructionLength = (code[i] << 8) | code[i + 1];
|
||||
i += 2 + instructionLength; // skipping the instructions
|
||||
var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
|
||||
var points = [];
|
||||
const numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
|
||||
const points = [];
|
||||
while (points.length < numberOfPoints) {
|
||||
flags = code[i++];
|
||||
var repeat = 1;
|
||||
let repeat = 1;
|
||||
if (flags & 0x08) {
|
||||
repeat += code[i++];
|
||||
}
|
||||
@ -299,12 +298,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
points[j].y = y;
|
||||
}
|
||||
|
||||
var startPoint = 0;
|
||||
let startPoint = 0;
|
||||
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
|
||||
// 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) {
|
||||
contour.push(contour[0]); // using start point at the contour end
|
||||
} else if (contour[contour.length - 1].flags & 1) {
|
||||
@ -312,7 +311,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
contour.unshift(contour[contour.length - 1]);
|
||||
} else {
|
||||
// start and end are off-curve points, creating implicit one
|
||||
var p = {
|
||||
const p = {
|
||||
flags: 1,
|
||||
x: (contour[0].x + contour[contour.length - 1].x) / 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] });
|
||||
}
|
||||
|
||||
var stack = [];
|
||||
var x = 0,
|
||||
const stack = [];
|
||||
let x = 0,
|
||||
y = 0;
|
||||
var stems = 0;
|
||||
let stems = 0;
|
||||
|
||||
function parse(code) {
|
||||
var i = 0;
|
||||
let i = 0;
|
||||
while (i < code.length) {
|
||||
var stackClean = false;
|
||||
var v = code[i++];
|
||||
var xa, xb, ya, yb, y1, y2, y3, n, subrCode;
|
||||
let stackClean = false;
|
||||
let v = code[i++];
|
||||
let xa, xb, ya, yb, y1, y2, y3, n, subrCode;
|
||||
switch (v) {
|
||||
case 1: // hstem
|
||||
stems += stack.length >> 1;
|
||||
@ -495,7 +494,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
bezierCurveTo(xa, y2, xb, y3, x, y);
|
||||
break;
|
||||
case 37: // flex1
|
||||
var x0 = x,
|
||||
const x0 = x,
|
||||
y0 = y;
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
@ -523,13 +522,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
break;
|
||||
case 14: // endchar
|
||||
if (stack.length >= 4) {
|
||||
var achar = stack.pop();
|
||||
var bchar = stack.pop();
|
||||
const achar = stack.pop();
|
||||
const bchar = stack.pop();
|
||||
y = stack.pop();
|
||||
x = stack.pop();
|
||||
cmds.push({ cmd: "save" });
|
||||
cmds.push({ cmd: "translate", args: [x, y] });
|
||||
var cmap = lookupCmap(
|
||||
let cmap = lookupCmap(
|
||||
font.cmap,
|
||||
String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]])
|
||||
);
|
||||
@ -830,13 +829,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
|
||||
return {
|
||||
create: function FontRendererFactory_create(font, seacAnalysisEnabled) {
|
||||
var data = new Uint8Array(font.data);
|
||||
var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
|
||||
var numTables = getUshort(data, 4);
|
||||
for (var i = 0, p = 12; i < numTables; i++, p += 16) {
|
||||
var tag = bytesToString(data.subarray(p, p + 4));
|
||||
var offset = getLong(data, p + 8);
|
||||
var length = getLong(data, p + 12);
|
||||
const data = new Uint8Array(font.data);
|
||||
let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
|
||||
const numTables = getUshort(data, 4);
|
||||
for (let i = 0, p = 12; i < numTables; i++, p += 16) {
|
||||
const tag = bytesToString(data.subarray(p, p + 4));
|
||||
const offset = getLong(data, p + 8);
|
||||
const length = getLong(data, p + 12);
|
||||
switch (tag) {
|
||||
case "cmap":
|
||||
cmap = parseCmap(data, offset, offset + length);
|
||||
@ -858,7 +857,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
}
|
||||
|
||||
if (glyf) {
|
||||
var fontMatrix = !unitsPerEm
|
||||
const fontMatrix = !unitsPerEm
|
||||
? font.fontMatrix
|
||||
: [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
|
||||
return new TrueTypeCompiled(
|
||||
|
@ -12,7 +12,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* eslint-disable no-var */
|
||||
|
||||
import { getEncoding } from "./encodings.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
|
||||
// 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
|
||||
@ -61,8 +60,8 @@ var HINTING_ENABLED = false;
|
||||
* to be encoded and this encoding technique helps to minimize the length of
|
||||
* the charStrings.
|
||||
*/
|
||||
var Type1CharString = (function Type1CharStringClosure() {
|
||||
var COMMAND_MAP = {
|
||||
const Type1CharString = (function Type1CharStringClosure() {
|
||||
const COMMAND_MAP = {
|
||||
hstem: [1],
|
||||
vstem: [3],
|
||||
vmoveto: [4],
|
||||
@ -81,25 +80,21 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function Type1CharString() {
|
||||
this.width = 0;
|
||||
this.lsb = 0;
|
||||
this.flexing = false;
|
||||
this.output = [];
|
||||
this.stack = [];
|
||||
}
|
||||
class Type1CharString {
|
||||
constructor() {
|
||||
this.width = 0;
|
||||
this.lsb = 0;
|
||||
this.flexing = false;
|
||||
this.output = [];
|
||||
this.stack = [];
|
||||
}
|
||||
|
||||
Type1CharString.prototype = {
|
||||
convert: function Type1CharString_convert(
|
||||
encoded,
|
||||
subrs,
|
||||
seacAnalysisEnabled
|
||||
) {
|
||||
var count = encoded.length;
|
||||
var error = false;
|
||||
var wx, sbx, subrNumber;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var value = encoded[i];
|
||||
convert(encoded, subrs, seacAnalysisEnabled) {
|
||||
const count = encoded.length;
|
||||
let error = false;
|
||||
let wx, sbx, subrNumber;
|
||||
for (let i = 0; i < count; i++) {
|
||||
let value = encoded[i];
|
||||
if (value < 32) {
|
||||
if (value === 12) {
|
||||
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
|
||||
// the right order.
|
||||
var dy = this.stack.pop();
|
||||
const dy = this.stack.pop();
|
||||
this.stack.push(0, dy);
|
||||
break;
|
||||
}
|
||||
@ -252,7 +247,7 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
// vhea tables reconstruction -- ignoring it.
|
||||
this.stack.pop(); // wy
|
||||
wx = this.stack.pop();
|
||||
var sby = this.stack.pop();
|
||||
const sby = this.stack.pop();
|
||||
sbx = this.stack.pop();
|
||||
this.lsb = sbx;
|
||||
this.width = wx;
|
||||
@ -264,8 +259,8 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
var num2 = this.stack.pop();
|
||||
var num1 = this.stack.pop();
|
||||
const num2 = this.stack.pop();
|
||||
const num1 = this.stack.pop();
|
||||
this.stack.push(num1 / num2);
|
||||
break;
|
||||
case (12 << 8) + 16: // callothersubr
|
||||
@ -274,9 +269,9 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
break;
|
||||
}
|
||||
subrNumber = this.stack.pop();
|
||||
var numArgs = this.stack.pop();
|
||||
const numArgs = this.stack.pop();
|
||||
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(
|
||||
flexArgs[2] + flexArgs[0], // bcp1x + rpx
|
||||
flexArgs[3] + flexArgs[1], // bcp1y + rpy
|
||||
@ -332,16 +327,16 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
this.stack.push(value);
|
||||
}
|
||||
return error;
|
||||
},
|
||||
}
|
||||
|
||||
executeCommand(howManyArgs, command, keepStack) {
|
||||
var stackLength = this.stack.length;
|
||||
const stackLength = this.stack.length;
|
||||
if (howManyArgs > stackLength) {
|
||||
return true;
|
||||
}
|
||||
var start = stackLength - howManyArgs;
|
||||
for (var i = start; i < stackLength; i++) {
|
||||
var value = this.stack[i];
|
||||
const start = stackLength - howManyArgs;
|
||||
for (let i = start; i < stackLength; i++) {
|
||||
let value = this.stack[i];
|
||||
if (Number.isInteger(value)) {
|
||||
this.output.push(28, (value >> 8) & 0xff, value & 0xff);
|
||||
} else {
|
||||
@ -363,8 +358,8 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
this.stack.length = 0;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return Type1CharString;
|
||||
})();
|
||||
@ -377,14 +372,14 @@ var Type1CharString = (function Type1CharStringClosure() {
|
||||
* of PostScript, but it is possible in most cases to extract what we need
|
||||
* without a full parse.
|
||||
*/
|
||||
var Type1Parser = (function Type1ParserClosure() {
|
||||
const Type1Parser = (function Type1ParserClosure() {
|
||||
/*
|
||||
* 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
|
||||
* for decrypting the eexec block of for decoding charStrings.
|
||||
*/
|
||||
var EEXEC_ENCRYPT_KEY = 55665;
|
||||
var CHAR_STRS_ENCRYPT_KEY = 4330;
|
||||
const EEXEC_ENCRYPT_KEY = 55665;
|
||||
const CHAR_STRS_ENCRYPT_KEY = 4330;
|
||||
|
||||
function isHexDigit(code) {
|
||||
return (
|
||||
@ -398,18 +393,18 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
if (discardNumber >= data.length) {
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
var r = key | 0,
|
||||
c1 = 52845,
|
||||
c2 = 22719,
|
||||
const c1 = 52845,
|
||||
c2 = 22719;
|
||||
let r = key | 0,
|
||||
i,
|
||||
j;
|
||||
for (i = 0; i < discardNumber; i++) {
|
||||
r = ((data[i] + r) * c1 + c2) & ((1 << 16) - 1);
|
||||
}
|
||||
var count = data.length - discardNumber;
|
||||
var decrypted = new Uint8Array(count);
|
||||
const count = data.length - discardNumber;
|
||||
const decrypted = new Uint8Array(count);
|
||||
for (i = discardNumber, j = 0; j < count; i++, j++) {
|
||||
var value = data[i];
|
||||
const value = data[i];
|
||||
decrypted[j] = value ^ (r >> 8);
|
||||
r = ((value + r) * c1 + c2) & ((1 << 16) - 1);
|
||||
}
|
||||
@ -417,25 +412,25 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
}
|
||||
|
||||
function decryptAscii(data, key, discardNumber) {
|
||||
var r = key | 0,
|
||||
c1 = 52845,
|
||||
const c1 = 52845,
|
||||
c2 = 22719;
|
||||
var count = data.length,
|
||||
let r = key | 0;
|
||||
const count = data.length,
|
||||
maybeLength = count >>> 1;
|
||||
var decrypted = new Uint8Array(maybeLength);
|
||||
var i, j;
|
||||
const decrypted = new Uint8Array(maybeLength);
|
||||
let i, j;
|
||||
for (i = 0, j = 0; i < count; i++) {
|
||||
var digit1 = data[i];
|
||||
const digit1 = data[i];
|
||||
if (!isHexDigit(digit1)) {
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
var digit2;
|
||||
let digit2;
|
||||
while (i < count && !isHexDigit((digit2 = data[i]))) {
|
||||
i++;
|
||||
}
|
||||
if (i < count) {
|
||||
var value = parseInt(String.fromCharCode(digit1, digit2), 16);
|
||||
const value = parseInt(String.fromCharCode(digit1, digit2), 16);
|
||||
decrypted[j++] = value ^ (r >> 8);
|
||||
r = ((value + r) * c1 + c2) & ((1 << 16) - 1);
|
||||
}
|
||||
@ -456,72 +451,71 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function Type1Parser(stream, encrypted, seacAnalysisEnabled) {
|
||||
if (encrypted) {
|
||||
var data = stream.getBytes();
|
||||
var isBinary = !(
|
||||
(isHexDigit(data[0]) || isWhiteSpace(data[0])) &&
|
||||
isHexDigit(data[1]) &&
|
||||
isHexDigit(data[2]) &&
|
||||
isHexDigit(data[3]) &&
|
||||
isHexDigit(data[4]) &&
|
||||
isHexDigit(data[5]) &&
|
||||
isHexDigit(data[6]) &&
|
||||
isHexDigit(data[7])
|
||||
);
|
||||
stream = new Stream(
|
||||
isBinary
|
||||
? decrypt(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
: decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
);
|
||||
class Type1Parser {
|
||||
constructor(stream, encrypted, seacAnalysisEnabled) {
|
||||
if (encrypted) {
|
||||
const data = stream.getBytes();
|
||||
const isBinary = !(
|
||||
(isHexDigit(data[0]) || isWhiteSpace(data[0])) &&
|
||||
isHexDigit(data[1]) &&
|
||||
isHexDigit(data[2]) &&
|
||||
isHexDigit(data[3]) &&
|
||||
isHexDigit(data[4]) &&
|
||||
isHexDigit(data[5]) &&
|
||||
isHexDigit(data[6]) &&
|
||||
isHexDigit(data[7])
|
||||
);
|
||||
stream = new Stream(
|
||||
isBinary
|
||||
? decrypt(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
: decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
);
|
||||
}
|
||||
this.seacAnalysisEnabled = !!seacAnalysisEnabled;
|
||||
|
||||
this.stream = stream;
|
||||
this.nextChar();
|
||||
}
|
||||
this.seacAnalysisEnabled = !!seacAnalysisEnabled;
|
||||
|
||||
this.stream = stream;
|
||||
this.nextChar();
|
||||
}
|
||||
|
||||
Type1Parser.prototype = {
|
||||
readNumberArray: function Type1Parser_readNumberArray() {
|
||||
readNumberArray() {
|
||||
this.getToken(); // read '[' or '{' (arrays can start with either)
|
||||
var array = [];
|
||||
const array = [];
|
||||
while (true) {
|
||||
var token = this.getToken();
|
||||
const token = this.getToken();
|
||||
if (token === null || token === "]" || token === "}") {
|
||||
break;
|
||||
}
|
||||
array.push(parseFloat(token || 0));
|
||||
}
|
||||
return array;
|
||||
},
|
||||
}
|
||||
|
||||
readNumber: function Type1Parser_readNumber() {
|
||||
var token = this.getToken();
|
||||
readNumber() {
|
||||
const token = this.getToken();
|
||||
return parseFloat(token || 0);
|
||||
},
|
||||
}
|
||||
|
||||
readInt: function Type1Parser_readInt() {
|
||||
readInt() {
|
||||
// Use '| 0' to prevent setting a double into length such as the double
|
||||
// does not flow into the loop variable.
|
||||
var token = this.getToken();
|
||||
const token = this.getToken();
|
||||
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.
|
||||
return token === "true" ? 1 : 0;
|
||||
},
|
||||
}
|
||||
|
||||
nextChar: function Type1_nextChar() {
|
||||
nextChar() {
|
||||
return (this.currentChar = this.stream.getByte());
|
||||
},
|
||||
}
|
||||
|
||||
getToken: function Type1Parser_getToken() {
|
||||
getToken() {
|
||||
// Eat whitespace and comments.
|
||||
var comment = false;
|
||||
var ch = this.currentChar;
|
||||
let comment = false;
|
||||
let ch = this.currentChar;
|
||||
while (true) {
|
||||
if (ch === -1) {
|
||||
return null;
|
||||
@ -542,42 +536,42 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
this.nextChar();
|
||||
return String.fromCharCode(ch);
|
||||
}
|
||||
var token = "";
|
||||
let token = "";
|
||||
do {
|
||||
token += String.fromCharCode(ch);
|
||||
ch = this.nextChar();
|
||||
} while (ch >= 0 && !isWhiteSpace(ch) && !isSpecial(ch));
|
||||
return token;
|
||||
},
|
||||
}
|
||||
|
||||
readCharStrings: function Type1Parser_readCharStrings(bytes, lenIV) {
|
||||
readCharStrings(bytes, lenIV) {
|
||||
if (lenIV === -1) {
|
||||
// This isn't in the spec, but Adobe's tx program handles -1
|
||||
// as plain text.
|
||||
return bytes;
|
||||
}
|
||||
return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an object containing a Subrs array and a CharStrings
|
||||
* array extracted from and eexec encrypted block of data
|
||||
*/
|
||||
extractFontProgram: function Type1Parser_extractFontProgram(properties) {
|
||||
var stream = this.stream;
|
||||
extractFontProgram(properties) {
|
||||
const stream = this.stream;
|
||||
|
||||
var subrs = [],
|
||||
const subrs = [],
|
||||
charstrings = [];
|
||||
var privateData = Object.create(null);
|
||||
const privateData = Object.create(null);
|
||||
privateData.lenIV = 4;
|
||||
var program = {
|
||||
const program = {
|
||||
subrs: [],
|
||||
charstrings: [],
|
||||
properties: {
|
||||
privateData,
|
||||
},
|
||||
};
|
||||
var token, length, data, lenIV, encoded;
|
||||
let token, length, data, lenIV, encoded;
|
||||
while ((token = this.getToken()) !== null) {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
@ -600,7 +594,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
}
|
||||
var glyph = this.getToken();
|
||||
const glyph = this.getToken();
|
||||
length = this.readInt();
|
||||
this.getToken(); // read in 'RD' or '-|'
|
||||
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
|
||||
@ -639,7 +633,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
case "OtherBlues":
|
||||
case "FamilyBlues":
|
||||
case "FamilyOtherBlues":
|
||||
var blueArray = this.readNumberArray();
|
||||
const blueArray = this.readNumberArray();
|
||||
// *Blue* values may contain invalid data: disables reading of
|
||||
// those values when hinting is disabled.
|
||||
if (
|
||||
@ -672,16 +666,16 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < charstrings.length; i++) {
|
||||
glyph = charstrings[i].glyph;
|
||||
for (let i = 0; i < charstrings.length; i++) {
|
||||
const glyph = charstrings[i].glyph;
|
||||
encoded = charstrings[i].encoded;
|
||||
var charString = new Type1CharString();
|
||||
var error = charString.convert(
|
||||
const charString = new Type1CharString();
|
||||
const error = charString.convert(
|
||||
encoded,
|
||||
subrs,
|
||||
this.seacAnalysisEnabled
|
||||
);
|
||||
var output = charString.output;
|
||||
let output = charString.output;
|
||||
if (error) {
|
||||
// It seems when FreeType encounters an error while evaluating a glyph
|
||||
// that it completely ignores the glyph so we'll mimic that behaviour
|
||||
@ -718,10 +712,10 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
}
|
||||
|
||||
return program;
|
||||
},
|
||||
}
|
||||
|
||||
extractFontHeader: function Type1Parser_extractFontHeader(properties) {
|
||||
var token;
|
||||
extractFontHeader(properties) {
|
||||
let token;
|
||||
while ((token = this.getToken()) !== null) {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
@ -729,21 +723,21 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
token = this.getToken();
|
||||
switch (token) {
|
||||
case "FontMatrix":
|
||||
var matrix = this.readNumberArray();
|
||||
const matrix = this.readNumberArray();
|
||||
properties.fontMatrix = matrix;
|
||||
break;
|
||||
case "Encoding":
|
||||
var encodingArg = this.getToken();
|
||||
var encoding;
|
||||
const encodingArg = this.getToken();
|
||||
let encoding;
|
||||
if (!/^\d+$/.test(encodingArg)) {
|
||||
// encoding name is specified
|
||||
encoding = getEncoding(encodingArg);
|
||||
} else {
|
||||
encoding = [];
|
||||
var size = parseInt(encodingArg, 10) | 0;
|
||||
const size = parseInt(encodingArg, 10) | 0;
|
||||
this.getToken(); // read in 'array'
|
||||
|
||||
for (var j = 0; j < size; j++) {
|
||||
for (let j = 0; j < size; j++) {
|
||||
token = this.getToken();
|
||||
// skipping till first dup or def (e.g. ignoring for statement)
|
||||
while (token !== "dup" && token !== "def") {
|
||||
@ -755,9 +749,9 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
if (token === "def") {
|
||||
break; // read all array data
|
||||
}
|
||||
var index = this.readInt();
|
||||
const index = this.readInt();
|
||||
this.getToken(); // read in '/'
|
||||
var glyph = this.getToken();
|
||||
const glyph = this.getToken();
|
||||
encoding[index] = glyph;
|
||||
this.getToken(); // read the in 'put'
|
||||
}
|
||||
@ -765,7 +759,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
properties.builtInEncoding = encoding;
|
||||
break;
|
||||
case "FontBBox":
|
||||
var fontBBox = this.readNumberArray();
|
||||
const fontBBox = this.readNumberArray();
|
||||
// adjusting ascent/descent
|
||||
properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
|
||||
properties.descent = Math.min(fontBBox[1], fontBBox[3]);
|
||||
@ -773,8 +767,8 @@ var Type1Parser = (function Type1ParserClosure() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return Type1Parser;
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user