svg2ttf
Version:
Converts SVG font to TTF font
106 lines (83 loc) • 2.81 kB
JavaScript
// See documentation here: http://www.microsoft.com/typography/otspec/name.htm
var _ = require('lodash')
var ByteBuffer = require('microbuffer')
var Str = require('../../str')
var TTF_NAMES = {
COPYRIGHT: 0,
FONT_FAMILY: 1,
ID: 3,
DESCRIPTION: 10,
URL_VENDOR: 11
}
function tableSize (names) {
var result = 6 // table header
_.forEach(names, function (name) {
result += 12 + name.data.length // name header and data
})
return result
}
function getStrings (name, id) {
var result = []
var str = new Str(name)
result.push({ data: str.toUTF8Bytes(), id: id, platformID : 1, encodingID : 0, languageID : 0 }) // mac standard
result.push({ data: str.toUCS2Bytes(), id: id, platformID : 3, encodingID : 1, languageID : 0x409 }) // windows standard
return result
}
// Collect font names
function getNames (font) {
var result = []
if (font.copyright) {
result.push.apply(result, getStrings(font.copyright, TTF_NAMES.COPYRIGHT))
}
if (font.familyName) {
result.push.apply(result, getStrings(font.familyName, TTF_NAMES.FONT_FAMILY))
}
if (font.id) {
result.push.apply(result, getStrings(font.id, TTF_NAMES.ID))
}
result.push.apply(result, getStrings(font.description, TTF_NAMES.DESCRIPTION))
result.push.apply(result, getStrings(font.url, TTF_NAMES.URL_VENDOR))
_.forEach(font.sfntNames, function (sfntName) {
result.push.apply(result, getStrings(sfntName.value, sfntName.id))
})
result.sort(function (a, b) {
var orderFields = ['platformID', 'encodingID', 'languageID', 'id']
var i
for (i = 0; i < orderFields.length; i++) {
if (a[orderFields[i]] !== b[orderFields[i]]) {
return a[orderFields[i]] < b[orderFields[i]] ? -1 : 1
}
}
return 0
})
return result
}
function createNameTable (font) {
var names = getNames(font)
var buf = new ByteBuffer(tableSize(names))
buf.writeUint16(0) // formatSelector
buf.writeUint16(names.length) // nameRecordsCount
var offsetPosition = buf.tell()
buf.writeUint16(0) // offset, will be filled later
var nameOffset = 0
_.forEach(names, function (name) {
buf.writeUint16(name.platformID) // platformID
buf.writeUint16(name.encodingID) // platEncID
buf.writeUint16(name.languageID) // languageID, English (USA)
buf.writeUint16(name.id) // nameID
buf.writeUint16(name.data.length) // reclength
buf.writeUint16(nameOffset) // offset
nameOffset += name.data.length
})
var actualStringDataOffset = buf.tell()
// Array of bytes with actual string data
_.forEach(names, function (name) {
buf.writeBytes(name.data)
})
// write actual string data offset
buf.seek(offsetPosition)
buf.writeUint16(actualStringDataOffset) // offset
return buf
}
module.exports = createNameTable