Use a TypedArray in the createOS2Table function

This commit is contained in:
Jonas Jenwald 2026-04-13 15:29:02 +02:00
parent aa0bc24e95
commit e8ed6c6e24

View File

@ -855,47 +855,60 @@ 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) {