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.
107 lines
2.8 KiB
107 lines
2.8 KiB
2 years ago
|
'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;
|