mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-05 06:35:48 +02:00
Merge pull request #21100 from Snuffleupagus/createTables-TypedArray
Use TypedArrays when building even more TrueType tables
This commit is contained in:
commit
7f7ac949ff
@ -21,6 +21,7 @@ import {
|
|||||||
info,
|
info,
|
||||||
shadow,
|
shadow,
|
||||||
string32,
|
string32,
|
||||||
|
stringToBytes,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { CFFCompiler, CFFParser } from "./cff_parser.js";
|
import { CFFCompiler, CFFParser } from "./cff_parser.js";
|
||||||
@ -340,6 +341,17 @@ function setSafeInt16(view, pos, val) {
|
|||||||
return pos + 2;
|
return pos + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setInt32(view, pos, val) {
|
||||||
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||||
|
assert(
|
||||||
|
typeof val === "number" && Math.abs(val) < 2 ** 32,
|
||||||
|
`setInt32: Unexpected input "${val}".`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
view.setInt32(pos, val);
|
||||||
|
return pos + 4;
|
||||||
|
}
|
||||||
|
|
||||||
function isTrueTypeFile(file) {
|
function isTrueTypeFile(file) {
|
||||||
const header = file.peekBytes(4),
|
const header = file.peekBytes(4),
|
||||||
str = bytesToString(header);
|
str = bytesToString(header);
|
||||||
@ -730,13 +742,13 @@ function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
|
|||||||
string32(format31012.length / 12); // nGroups
|
string32(format31012.length / 12); // nGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return stringToBytes(
|
||||||
cmap +
|
cmap +
|
||||||
"\x00\x04" + // format
|
"\x00\x04" + // format
|
||||||
string16(format314.length + 4) + // length
|
string16(format314.length + 4) + // length
|
||||||
format314 +
|
format314 +
|
||||||
header31012 +
|
header31012 +
|
||||||
format31012
|
format31012
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,62 +856,78 @@ function createOS2Table(properties, charstrings, override) {
|
|||||||
const winAscent = override.yMax || typoAscent;
|
const winAscent = override.yMax || typoAscent;
|
||||||
const winDescent = -override.yMin || -typoDescent;
|
const winDescent = -override.yMin || -typoDescent;
|
||||||
|
|
||||||
return (
|
const data = new Uint8Array(96),
|
||||||
"\x00\x03" + // version
|
view = new DataView(data.buffer);
|
||||||
"\x02\x24" + // xAvgCharWidth
|
let pos = 0;
|
||||||
"\x01\xF4" + // usWeightClass
|
|
||||||
"\x00\x05" + // usWidthClass
|
pos = setArray(data, pos, [0x00, 0x03]); // version
|
||||||
"\x00\x00" + // fstype (0 to let the font loads via font-face on IE)
|
pos = setArray(data, pos, [0x02, 0x24]); // xAvgCharWidth
|
||||||
"\x02\x8A" + // ySubscriptXSize
|
pos = setArray(data, pos, [0x01, 0xf4]); // usWeightClass
|
||||||
"\x02\xBB" + // ySubscriptYSize
|
pos = setArray(data, pos, [0x00, 0x05]); // usWidthClass
|
||||||
"\x00\x00" + // ySubscriptXOffset
|
pos += 2; // fstype (0 to improve browser compatibility), skip redundant "\x00\x00"
|
||||||
"\x00\x8C" + // ySubscriptYOffset
|
pos = setArray(data, pos, [0x02, 0x8a]); // ySubscriptXSize
|
||||||
"\x02\x8A" + // ySuperScriptXSize
|
pos = setArray(data, pos, [0x02, 0xbb]); // ySubscriptYSize
|
||||||
"\x02\xBB" + // ySuperScriptYSize
|
pos += 2; // ySubscriptXOffset, skip redundant "\x00\x00"
|
||||||
"\x00\x00" + // ySuperScriptXOffset
|
pos = setArray(data, pos, [0x00, 0x8c]); // ySubscriptYOffset
|
||||||
"\x01\xDF" + // ySuperScriptYOffset
|
pos = setArray(data, pos, [0x02, 0x8a]); // ySuperScriptXSize
|
||||||
"\x00\x31" + // yStrikeOutSize
|
pos = setArray(data, pos, [0x02, 0xbb]); // ySuperScriptYSize
|
||||||
"\x01\x02" + // yStrikeOutPosition
|
pos += 2; // ySuperScriptXOffset, skip redundant "\x00\x00"
|
||||||
"\x00\x00" + // sFamilyClass
|
pos = setArray(data, pos, [0x01, 0xdf]); // ySuperScriptYOffset
|
||||||
"\x00\x00\x06" +
|
pos = setArray(data, pos, [0x00, 0x31]); // yStrikeOutSize
|
||||||
String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) +
|
pos = setArray(data, pos, [0x01, 0x02]); // yStrikeOutPosition
|
||||||
"\x00\x00\x00\x00\x00\x00" + // Panose
|
pos += 2; // sFamilyClass, skip redundant "\x00\x00"
|
||||||
string32(ulUnicodeRange1) + // ulUnicodeRange1 (Bits 0-31)
|
pos = setArray(data, pos, [
|
||||||
string32(ulUnicodeRange2) + // ulUnicodeRange2 (Bits 32-63)
|
0x00,
|
||||||
string32(ulUnicodeRange3) + // ulUnicodeRange3 (Bits 64-95)
|
0x00,
|
||||||
string32(ulUnicodeRange4) + // ulUnicodeRange4 (Bits 96-127)
|
0x06,
|
||||||
"\x2A\x32\x31\x2A" + // achVendID
|
properties.fixedPitch ? 0x09 : 0x00,
|
||||||
string16(properties.italicAngle ? 1 : 0) + // fsSelection
|
0x00,
|
||||||
string16(firstCharIndex || properties.firstChar) + // usFirstCharIndex
|
0x00,
|
||||||
string16(lastCharIndex || properties.lastChar) + // usLastCharIndex
|
0x00,
|
||||||
string16(typoAscent) + // sTypoAscender
|
0x00,
|
||||||
string16(typoDescent) + // sTypoDescender
|
0x00,
|
||||||
"\x00\x64" + // sTypoLineGap (7%-10% of the unitsPerEM value)
|
0x00,
|
||||||
string16(winAscent) + // usWinAscent
|
]); // Panose
|
||||||
string16(winDescent) + // usWinDescent
|
pos = setInt32(view, pos, ulUnicodeRange1); // ulUnicodeRange1 (Bits 0-31)
|
||||||
"\x00\x00\x00\x00" + // ulCodePageRange1 (Bits 0-31)
|
pos = setInt32(view, pos, ulUnicodeRange2); // ulUnicodeRange2 (Bits 32-63)
|
||||||
"\x00\x00\x00\x00" + // ulCodePageRange2 (Bits 32-63)
|
pos = setInt32(view, pos, ulUnicodeRange3); // ulUnicodeRange3 (Bits 64-95)
|
||||||
string16(properties.xHeight) + // sxHeight
|
pos = setInt32(view, pos, ulUnicodeRange4); // ulUnicodeRange4 (Bits 96-127)
|
||||||
string16(properties.capHeight) + // sCapHeight
|
pos = setArray(data, pos, [0x2a, 0x32, 0x31, 0x2a]); // achVendID
|
||||||
string16(0) + // usDefaultChar
|
pos = setInt16(view, pos, properties.italicAngle ? 1 : 0); // fsSelection
|
||||||
string16(firstCharIndex || properties.firstChar) + // usBreakChar
|
pos = setInt16(view, pos, firstCharIndex || properties.firstChar); // usFirstCharIndex
|
||||||
"\x00\x03" // usMaxContext
|
pos = setInt16(view, pos, lastCharIndex || properties.lastChar); // usLastCharIndex
|
||||||
);
|
pos = setInt16(view, pos, typoAscent); // sTypoAscender
|
||||||
|
pos = setInt16(view, pos, typoDescent); // sTypoDescender
|
||||||
|
pos = setArray(data, pos, [0x00, 0x64]); // sTypoLineGap (7%-10% of the unitsPerEM value)
|
||||||
|
pos = setInt16(view, pos, winAscent); // usWinAscent
|
||||||
|
pos = setInt16(view, pos, winDescent); // usWinDescent
|
||||||
|
pos += 4; // ulCodePageRange1 (Bits 0-31), skip redundant "\x00\x00\x00\x00"
|
||||||
|
pos += 4; // ulCodePageRange2 (Bits 32-63), skip redundant "\x00\x00\x00\x00"
|
||||||
|
pos = setInt16(view, pos, properties.xHeight); // sxHeight
|
||||||
|
pos = setInt16(view, pos, properties.capHeight); // sCapHeight
|
||||||
|
pos += 2; // usDefaultChar, skip redundant "\x00\x00"
|
||||||
|
pos = setInt16(view, pos, firstCharIndex || properties.firstChar); // usBreakChar
|
||||||
|
setArray(data, pos, [0x00, 0x03]); // usMaxContext
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPostTable(properties) {
|
function createPostTable(properties) {
|
||||||
const angle = Math.floor(properties.italicAngle * 2 ** 16);
|
const data = new Uint8Array(32),
|
||||||
return (
|
view = new DataView(data.buffer);
|
||||||
"\x00\x03\x00\x00" + // Version number
|
let pos = 0;
|
||||||
string32(angle) + // italicAngle
|
|
||||||
"\x00\x00" + // underlinePosition
|
pos = setArray(data, pos, [0x00, 0x03, 0x00, 0x00]); // Version number
|
||||||
"\x00\x00" + // underlineThickness
|
pos = setInt32(view, pos, Math.floor(properties.italicAngle * 2 ** 16)); // italicAngle
|
||||||
string32(properties.fixedPitch ? 1 : 0) + // isFixedPitch
|
pos += 2; // underlinePosition, skip redundant "\x00\x00"
|
||||||
"\x00\x00\x00\x00" + // minMemType42
|
pos += 2; // underlineThickness, skip redundant "\x00\x00"
|
||||||
"\x00\x00\x00\x00" + // maxMemType42
|
setInt32(view, pos, properties.fixedPitch ? 1 : 0); // isFixedPitch
|
||||||
"\x00\x00\x00\x00" + // minMemType1
|
// minMemType42, skip redundant "\x00\x00\x00\x00"
|
||||||
"\x00\x00\x00\x00" // maxMemType1
|
// maxMemType42, skip redundant "\x00\x00\x00\x00"
|
||||||
);
|
// minMemType1, skip redundant "\x00\x00\x00\x00"
|
||||||
|
// maxMemType1, skip redundant "\x00\x00\x00\x00"
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPostscriptName(name) {
|
function createPostscriptName(name) {
|
||||||
@ -968,8 +996,7 @@ function createNameTable(name, proto) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nameTable += strings.join("") + stringsUnicode.join("");
|
return stringToBytes(nameTable + strings.join("") + stringsUnicode.join(""));
|
||||||
return nameTable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -63,15 +63,7 @@ class OpenTypeFileBuilder {
|
|||||||
// write the table data first (mostly for checksum)
|
// write the table data first (mostly for checksum)
|
||||||
for (let i = 0; i < numTables; i++) {
|
for (let i = 0; i < numTables; i++) {
|
||||||
const table = tables.get(tablesNames[i]);
|
const table = tables.get(tablesNames[i]);
|
||||||
let tableOffset = tableOffsets[i];
|
file.set(table, tableOffsets[i]);
|
||||||
|
|
||||||
if (table instanceof Uint8Array) {
|
|
||||||
file.set(table, tableOffset);
|
|
||||||
} else if (typeof table === "string") {
|
|
||||||
for (let j = 0, jj = table.length; j < jj; j++) {
|
|
||||||
file[tableOffset++] = table.charCodeAt(j) & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sfnt version (4 bytes)
|
// sfnt version (4 bytes)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user