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.
 
 
 
 
 

106 lines
2.8 KiB

'use strict';
// 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;