You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
4.0 KiB
90 lines
4.0 KiB
'use strict'; |
|
|
|
// See documentation here: http://www.microsoft.com/typography/otspec/os2.htm |
|
|
|
var _ = require('lodash'); |
|
var identifier = require('../utils.js').identifier; |
|
var ByteBuffer = require('microbuffer'); |
|
|
|
//get first glyph unicode |
|
function getFirstCharIndex(font) { |
|
return Math.max(0, Math.min(0xffff, Math.abs(_.minBy(Object.keys(font.codePoints), function (point) { |
|
return parseInt(point, 10); |
|
})))); |
|
} |
|
|
|
//get last glyph unicode |
|
function getLastCharIndex(font) { |
|
return Math.max(0, Math.min(0xffff, Math.abs(_.maxBy(Object.keys(font.codePoints), function (point) { |
|
return parseInt(point, 10); |
|
})))); |
|
} |
|
|
|
// OpenType spec: https://docs.microsoft.com/en-us/typography/opentype/spec/os2 |
|
function createOS2Table(font) { |
|
|
|
// use at least 2 for ligatures and kerning |
|
var maxContext = font.ligatures.map(function (l) { |
|
return l.unicode.length; |
|
}).reduce(function (a, b) { |
|
return Math.max(a, b); |
|
}, 2); |
|
|
|
var buf = new ByteBuffer(96); |
|
|
|
// Version 5 is not supported in the Android 5 browser. |
|
buf.writeUint16(4); // version |
|
buf.writeInt16(font.avgWidth); // xAvgCharWidth |
|
buf.writeUint16(font.weightClass); // usWeightClass |
|
buf.writeUint16(font.widthClass); // usWidthClass |
|
buf.writeInt16(font.fsType); // fsType |
|
buf.writeInt16(font.ySubscriptXSize); // ySubscriptXSize |
|
buf.writeInt16(font.ySubscriptYSize); //ySubscriptYSize |
|
buf.writeInt16(font.ySubscriptXOffset); // ySubscriptXOffset |
|
buf.writeInt16(font.ySubscriptYOffset); // ySubscriptYOffset |
|
buf.writeInt16(font.ySuperscriptXSize); // ySuperscriptXSize |
|
buf.writeInt16(font.ySuperscriptYSize); // ySuperscriptYSize |
|
buf.writeInt16(font.ySuperscriptXOffset); // ySuperscriptXOffset |
|
buf.writeInt16(font.ySuperscriptYOffset); // ySuperscriptYOffset |
|
buf.writeInt16(font.yStrikeoutSize); // yStrikeoutSize |
|
buf.writeInt16(font.yStrikeoutPosition); // yStrikeoutPosition |
|
buf.writeInt16(font.familyClass); // sFamilyClass |
|
buf.writeUint8(font.panose.familyType); // panose.bFamilyType |
|
buf.writeUint8(font.panose.serifStyle); // panose.bSerifStyle |
|
buf.writeUint8(font.panose.weight); // panose.bWeight |
|
buf.writeUint8(font.panose.proportion); // panose.bProportion |
|
buf.writeUint8(font.panose.contrast); // panose.bContrast |
|
buf.writeUint8(font.panose.strokeVariation); // panose.bStrokeVariation |
|
buf.writeUint8(font.panose.armStyle); // panose.bArmStyle |
|
buf.writeUint8(font.panose.letterform); // panose.bLetterform |
|
buf.writeUint8(font.panose.midline); // panose.bMidline |
|
buf.writeUint8(font.panose.xHeight); // panose.bXHeight |
|
// TODO: This field is used to specify the Unicode blocks or ranges based on the 'cmap' table. |
|
buf.writeUint32(0); // ulUnicodeRange1 |
|
buf.writeUint32(0); // ulUnicodeRange2 |
|
buf.writeUint32(0); // ulUnicodeRange3 |
|
buf.writeUint32(0); // ulUnicodeRange4 |
|
buf.writeUint32(identifier('PfEd')); // achVendID, equal to PfEd |
|
buf.writeUint16(font.fsSelection); // fsSelection |
|
buf.writeUint16(getFirstCharIndex(font)); // usFirstCharIndex |
|
buf.writeUint16(getLastCharIndex(font)); // usLastCharIndex |
|
buf.writeInt16(font.ascent); // sTypoAscender |
|
buf.writeInt16(font.descent); // sTypoDescender |
|
buf.writeInt16(font.lineGap); // lineGap |
|
// Enlarge win acscent/descent to avoid clipping |
|
// WinAscent - WinDecent should at least be equal to TypoAscender - TypoDescender + TypoLineGap: |
|
// https://www.high-logic.com/font-editor/fontcreator/tutorials/font-metrics-vertical-line-spacing |
|
buf.writeInt16(Math.max(font.yMax, font.ascent + font.lineGap)); // usWinAscent |
|
buf.writeInt16(-Math.min(font.yMin, font.descent)); // usWinDescent |
|
buf.writeInt32(1); // ulCodePageRange1, Latin 1 |
|
buf.writeInt32(0); // ulCodePageRange2 |
|
buf.writeInt16(font.xHeight); // sxHeight |
|
buf.writeInt16(font.capHeight); // sCapHeight |
|
buf.writeUint16(0); // usDefaultChar, pointing to missing glyph (always id=0) |
|
buf.writeUint16(0); // usBreakChar, code=32 isn't guaranteed to be a space in icon fonts |
|
buf.writeUint16(maxContext); // usMaxContext, use at least 2 for ligatures and kerning |
|
|
|
return buf; |
|
} |
|
|
|
module.exports = createOS2Table;
|
|
|