fonteditor/src/ttf/ttfreader.js
2015-04-17 01:40:13 +08:00

177 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file ttfreader.js
* @author mengke01
* @date
* @description
* ttf定义
*
* thanks to
* ynakajima/ttf.js
* https://github.com/ynakajima/ttf.js
*/
define(
function (require) {
var Directory = require('./table/directory');
var supportTables = require('./table/support');
var Reader = require('./reader');
var postName = require('./enum/postName');
var error = require('./error');
/**
* 初始化
*
* @param {ArrayBuffer} buffer buffer对象
* @return {Object} ttf对象
*/
function read(buffer) {
var reader = new Reader(buffer, 0, buffer.byteLength, false);
var ttf = {};
// version
ttf.version = reader.readFixed(0);
if (ttf.version !== 0x1) {
error.raise(10101);
}
// num tables
ttf.numTables = reader.readUint16();
if (ttf.numTables <= 0 || ttf.numTables > 100) {
error.raise(10101);
}
// searchRenge
ttf.searchRenge = reader.readUint16();
// entrySelector
ttf.entrySelector = reader.readUint16();
// rengeShift
ttf.rengeShift = reader.readUint16();
ttf.tables = new Directory(reader.offset).read(reader, ttf);
if (!ttf.tables.glyf || !ttf.tables.head || !ttf.tables.cmap || !ttf.tables.hmtx) {
error.raise(10204);
}
// 读取支持的表数据
Object.keys(supportTables).forEach(function (tableName) {
if (ttf.tables[tableName]) {
var offset = ttf.tables[tableName].offset;
ttf[tableName] = new supportTables[tableName](offset).read(reader, ttf);
}
});
if (!ttf.glyf) {
error.raise(10201);
}
reader.dispose();
return ttf;
}
/**
* 关联glyf相关的信息
* @param {Object} ttf ttf对象
*/
function resolveGlyf(ttf) {
var codes = ttf.cmap;
var glyf = ttf.glyf;
// unicode
Object.keys(codes).forEach(function (c) {
var i = codes[c];
if (!glyf[i].unicode) {
glyf[i].unicode = [];
}
glyf[i].unicode.push(+c);
});
// advanceWidth
ttf.hmtx.forEach(function (item, i) {
glyf[i].advanceWidth = item.advanceWidth;
glyf[i].leftSideBearing = item.leftSideBearing;
});
// name
if (ttf.post && 2 === ttf.post.format) {
var nameIndex = ttf.post.glyphNameIndex;
var names = ttf.post.names;
nameIndex.forEach(function (nameIndex, i) {
if (nameIndex <= 257) {
glyf[i].name = postName[nameIndex];
}
else {
glyf[i].name = names[nameIndex - 258] || '';
}
});
}
}
/**
* 清除非必须的表
* @param {Object} ttf ttf对象
*/
function cleanTables(ttf) {
delete ttf.tables;
delete ttf.hmtx;
delete ttf.loca;
delete ttf.post.glyphNameIndex;
delete ttf.post.names;
if (!this.options.hinting) {
delete ttf.fpgm;
delete ttf.cvt;
delete ttf.prep;
ttf.glyf.forEach(function (glyf) {
delete glyf.instructions;
});
}
}
/**
* TTF的构造函数
* @param {Object} options 写入参数
* @param {boolean} hinting 保留hinting信息
* @constructor
*/
function TTFReader(options) {
this.options = options || {
hinting: false // 不保留hints信息
};
}
/**
* 获取解析后的ttf文档
* @param {ArrayBuffer} buffer buffer对象
*
* @return {Object} ttf文档
*/
TTFReader.prototype.read = function (buffer) {
this.ttf = read.call(this, buffer);
resolveGlyf.call(this, this.ttf);
cleanTables.call(this, this.ttf);
return this.ttf;
};
/**
* 注销
*/
TTFReader.prototype.dispose = function () {
delete this.ttf;
};
return TTFReader;
}
);