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
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;
|
|
|