mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-04-17 18:54:04 +02:00
Merge pull request #21112 from Snuffleupagus/createNameTable-TypedArray
Use TypedArrays in the `createNameTable` function
This commit is contained in:
commit
302b4cb008
@ -302,16 +302,6 @@ function writeUint32(bytes, index, value) {
|
||||
bytes[index] = value >>> 24;
|
||||
}
|
||||
|
||||
function string16(value) {
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||
assert(
|
||||
typeof value === "number" && Math.abs(value) < 2 ** 16,
|
||||
`string16: Unexpected input "${value}".`
|
||||
);
|
||||
}
|
||||
return String.fromCharCode((value >> 8) & 0xff, value & 0xff);
|
||||
}
|
||||
|
||||
class TrueTypeTableBuilder {
|
||||
#buf;
|
||||
|
||||
@ -712,21 +702,18 @@ function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
|
||||
const searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);
|
||||
|
||||
// Fill up the 4 parallel arrays describing the segments.
|
||||
const startCount = new TrueTypeTableBuilder({}),
|
||||
endCount = new TrueTypeTableBuilder({}),
|
||||
idDeltas = new TrueTypeTableBuilder({}),
|
||||
idRangeOffsets = new TrueTypeTableBuilder({}),
|
||||
const segmentsLength = bmpLength * 2 + trailingRangesCount * 2;
|
||||
const startCount = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
|
||||
endCount = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
|
||||
idDeltas = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
|
||||
idRangeOffsets = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
|
||||
glyphsIds = new TrueTypeTableBuilder({});
|
||||
let bias = 0;
|
||||
|
||||
let range, start, end, codes;
|
||||
for (i = 0, ii = bmpLength; i < ii; i++) {
|
||||
range = ranges[i];
|
||||
start = range[0];
|
||||
end = range[1];
|
||||
const [start, end, codes] = ranges[i];
|
||||
startCount.setInt16(start);
|
||||
endCount.setInt16(end);
|
||||
codes = range[2];
|
||||
let contiguous = true;
|
||||
for (j = 1, jj = codes.length; j < jj; ++j) {
|
||||
if (codes[j] !== codes[j - 1] + 1) {
|
||||
@ -790,14 +777,13 @@ function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
|
||||
cmap31012.setInt32(4 + numTables * 8 + 4 + format314.length); // start of the table record
|
||||
|
||||
format31012 = new TrueTypeTableBuilder({});
|
||||
for (i = 0, ii = ranges.length; i < ii; i++) {
|
||||
range = ranges[i];
|
||||
start = range[0];
|
||||
codes = range[2];
|
||||
for (const range of ranges) {
|
||||
let start = range[0];
|
||||
const codes = range[2];
|
||||
let code = codes[0];
|
||||
for (j = 1, jj = codes.length; j < jj; ++j) {
|
||||
if (codes[j] !== codes[j - 1] + 1) {
|
||||
end = range[0] + j - 1;
|
||||
const end = range[0] + j - 1;
|
||||
format31012.setInt32(start); // startCharCode
|
||||
format31012.setInt32(end); // endCharCode
|
||||
format31012.setInt32(code); // startGlyphID
|
||||
@ -1019,9 +1005,7 @@ function createPostscriptName(name) {
|
||||
}
|
||||
|
||||
function createNameTable(name, proto) {
|
||||
if (!proto) {
|
||||
proto = [[], []]; // no strings and unicode strings
|
||||
}
|
||||
proto ||= [[], []]; // no strings and unicode strings
|
||||
|
||||
const strings = [
|
||||
proto[0][0] || "Original licence", // 0.Copyright
|
||||
@ -1035,51 +1019,85 @@ function createNameTable(name, proto) {
|
||||
proto[0][8] || "Unknown", // 8.Manufacturer
|
||||
proto[0][9] || "Unknown", // 9.Designer
|
||||
];
|
||||
const stringsBytes = strings.map(s => stringToBytes(s));
|
||||
|
||||
// Mac want 1-byte per character strings while Windows want
|
||||
// 2-bytes per character, so duplicate the names table
|
||||
const stringsUnicode = [];
|
||||
const stringsUnicodeBytes = new Array(strings.length);
|
||||
let i, ii, j, jj, str;
|
||||
for (i = 0, ii = strings.length; i < ii; i++) {
|
||||
str = proto[1][i] || strings[i];
|
||||
|
||||
const strBufUnicode = [];
|
||||
const strUnicode = new TrueTypeTableBuilder({
|
||||
exactLength: str.length * 2,
|
||||
});
|
||||
for (j = 0, jj = str.length; j < jj; j++) {
|
||||
strBufUnicode.push(string16(str.charCodeAt(j)));
|
||||
strUnicode.setInt16(str.charCodeAt(j));
|
||||
}
|
||||
stringsUnicode.push(strBufUnicode.join(""));
|
||||
stringsUnicodeBytes[i] = strUnicode.data;
|
||||
}
|
||||
|
||||
const names = [strings, stringsUnicode];
|
||||
const platforms = ["\x00\x01", "\x00\x03"];
|
||||
const encodings = ["\x00\x00", "\x00\x01"];
|
||||
const languages = ["\x00\x00", "\x04\x09"];
|
||||
|
||||
const namesRecordCount = strings.length * platforms.length;
|
||||
let nameTable =
|
||||
"\x00\x00" + // format
|
||||
string16(namesRecordCount) + // Number of names Record
|
||||
string16(namesRecordCount * 12 + 6); // Storage
|
||||
const namesBytes = [stringsBytes, stringsUnicodeBytes];
|
||||
const platformsBytes = [
|
||||
[0x00, 0x01],
|
||||
[0x00, 0x03],
|
||||
];
|
||||
const encodingsBytes = [
|
||||
[0x00, 0x00],
|
||||
[0x00, 0x01],
|
||||
];
|
||||
const languagesBytes = [
|
||||
[0x00, 0x00],
|
||||
[0x04, 0x09],
|
||||
];
|
||||
|
||||
// Build the name records field
|
||||
const nameRecords = [];
|
||||
let strOffset = 0;
|
||||
for (i = 0, ii = platforms.length; i < ii; i++) {
|
||||
const strs = names[i];
|
||||
for (i = 0, ii = platformsBytes.length; i < ii; i++) {
|
||||
const strs = namesBytes[i];
|
||||
for (j = 0, jj = strs.length; j < jj; j++) {
|
||||
str = strs[j];
|
||||
const nameRecord =
|
||||
platforms[i] + // platform ID
|
||||
encodings[i] + // encoding ID
|
||||
languages[i] + // language ID
|
||||
string16(j) + // name ID
|
||||
string16(str.length) +
|
||||
string16(strOffset);
|
||||
nameTable += nameRecord;
|
||||
const nameRecord = new TrueTypeTableBuilder({
|
||||
exactLength:
|
||||
6 +
|
||||
platformsBytes[i].length +
|
||||
encodingsBytes[i].length +
|
||||
languagesBytes[i].length,
|
||||
});
|
||||
nameRecord.setArray(platformsBytes[i]); // platform ID
|
||||
nameRecord.setArray(encodingsBytes[i]); // encoding ID
|
||||
nameRecord.setArray(languagesBytes[i]); // language ID
|
||||
nameRecord.setInt16(j); // name ID
|
||||
nameRecord.setInt16(str.length);
|
||||
nameRecord.setInt16(strOffset);
|
||||
|
||||
nameRecords.push(nameRecord.data);
|
||||
strOffset += str.length;
|
||||
}
|
||||
}
|
||||
|
||||
return stringToBytes(nameTable + strings.join("") + stringsUnicode.join(""));
|
||||
const namesRecordCount = stringsBytes.length * platformsBytes.length;
|
||||
const nameTable = new TrueTypeTableBuilder({
|
||||
exactLength:
|
||||
6 +
|
||||
Math.sumPrecise(nameRecords.map(arr => arr.length)) +
|
||||
Math.sumPrecise(stringsBytes.map(arr => arr.length)) +
|
||||
Math.sumPrecise(stringsUnicodeBytes.map(arr => arr.length)),
|
||||
});
|
||||
nameTable.skip(2); // format, skip redundant "\x00\x00"
|
||||
nameTable.setInt16(namesRecordCount); // Number of names Record
|
||||
nameTable.setInt16(namesRecordCount * 12 + 6); // Storage
|
||||
for (const arr of nameRecords) {
|
||||
nameTable.setArray(arr);
|
||||
}
|
||||
for (const arr of stringsBytes) {
|
||||
nameTable.setArray(arr);
|
||||
}
|
||||
for (const arr of stringsUnicodeBytes) {
|
||||
nameTable.setArray(arr);
|
||||
}
|
||||
return nameTable.data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user