add ttf writer

This commit is contained in:
mkwiser 2014-09-21 19:35:25 +08:00
parent b67dfa9f32
commit b4a155a6bc
3 changed files with 292 additions and 4 deletions

View File

@ -3,7 +3,7 @@
* @author mengke01
* @date
* @description
* ttf读取器
* 数据读取器
*
* thanks to
* ynakajima/ttf.js
@ -117,7 +117,7 @@ define(
var value = '';
for (var i = 0; i < length; ++i) {
var c = this.readUint8(offset + i);
value += String.fromCharCode(c > 127 ? 65533 : c);
value += String.fromCharCode(c);
}
this.offset = offset + length;
@ -208,9 +208,10 @@ define(
if(undefined == offset) {
offset = this.offset;
}
var delta = -2080198800000;// (new Date(1904, 1, 1)).getTime();
var delta = -2077545600000;// new Date(1970, 1, 1).getTime() - new Date(1904, 1, 1).getTime();
var time = this.readUint32(offset + 4, false);
var date = new Date();
date.setTime(this.readUint32(offset + 4, false));
date.setTime(time * 1000 + delta);
return date;
}
};

34
src/ttf/util/checkSum.js Normal file
View File

@ -0,0 +1,34 @@
/**
* @file checkSum.js
* @author mengke01
* @date
* @description
* table校验函数
*/
define(
function(require) {
/**
* table校验
*
* @param {ArrayBuffer|Array} buffer 表数据
* @return {number} 校验和
*/
function checkSum(buffer) {
var nLongs = Math.floor(((buffer.byteLength || buffer.length) + 3) / 4);
var array = new Int32Array(buffer);
var sum = 0, i = 0;
while (i < nLongs) {
sum += array[i++];
}
return sum;
}
return checkSum;
}
);

253
src/ttf/writter.js Normal file
View File

@ -0,0 +1,253 @@
/**
* @file writter.js
* @author mengke01
* @date
* @description
* 数据写入器
*/
define(
function(require) {
var extend = require('common/lang').extend;
var curry = require('common/lang').curry;
// 检查数组支持情况
if(typeof ArrayBuffer === 'undefined' || typeof DataView === 'undefined') {
throw 'not support ArrayBuffer and DataView';
}
// 数据类型
var dataType = {
'Int8': 1,
'Int16': 2,
'Int32': 4,
'Uint8': 1,
'Uint16': 2,
'Uint32': 4,
'Float32': 4,
'Float64': 8
};
var proto = {};
/**
* 读取指定的数据类型
*
* @param {number} size 大小
* @param {number=} offset 位移
* @param {number} value value值
* @param {boolean=} littleEndian 是否小尾
*
* @return {this}
*/
function write(type, value, offset, littleEndian) {
// 使用当前位移
if(undefined == offset) {
offset = this.offset;
}
// 使用小尾
if(undefined == littleEndian) {
littleEndian = this.littleEndian;
}
// 扩展方法
if(expandProto[write + type]) {
return this[write + type](value, offset, littleEndian);
}
else {
var size = dataType[type];
this.offset = offset + size;
this.view['set' + type](offset, value, littleEndian);
return this;
}
}
// 直接支持的数据类型
Object.keys(dataType).forEach(function(type) {
proto['write' + type] = curry(write, type);
});
/**
* 读取器
*
* @constructor
* @param {Array.<byte>} buffer 缓冲数组
* @param {number} offset 起始偏移
* @param {number} length 数组长度
* @param {boolean} bigEndian 是否大尾
*/
function Writter(buffer, offset, length, littleEndian) {
var bufferLength = buffer.byteLength || buffer.length;
this.offset = offset || 0;
this.length = length || (bufferLength - this.offset);
this.littleEndian = littleEndian || false;
this.view = new DataView(buffer, this.offset, this.length);
}
Writter.prototype = {
write: write,
/**
* 写入一个string
*
* @param {number} value 写入值
* @param {number} offset 偏移
* @param {number} length 长度
* @return {this}
*/
writeString: function(str, offset) {
if(arguments.length == 1) {
offset = this.offset;
}
var length = str.replace(/[^\x00-\xff]/g, '11').length;
if(length < 0 || offset + length > this.length) {
throw 'length out of range:' + offset + ',' + length;
}
this.seek(offset);
for (var i = 0, l = str.length, charCode; i < l; ++i) {
charCode = str.charCodeAt(i);
if (charCode > 127) {
// unicode编码可能会超出2字节, 写入与编码有关系,此处不做处理
// FIXME
this.writeUint16(charCode);
}
else {
this.writeUint8(charCode);
}
}
this.offset = offset + length;
return this;
},
/**
* 写入指定的字节数组
*
* @param {ArrayBuffer} value 写入值
* @return {this}
*/
writeBytes: function(value, offset) {
if(arguments.length == 1) {
offset = this.offset;
}
var length = value.byteLength || value.length;
if(length < 0 || offset + length > this.length) {
throw 'length out of range:' + offset + ',' + length;
}
var view = new DataView(value, 0, length);
var littleEndian = this.littleEndian;
for (var i = 0; i < length; ++i) {
this.writeUint8(view.readUint8(i, littleEndian));
}
this.offset = offset + length;
return this;
},
/**
* 跳转到指定偏移
*
* @param {number} offset 偏移
* @return {this}
*/
seek: function (offset) {
if (undefined == offset) {
this.offset = 0;
}
if (offset < 0 || offset > this.length) {
throw 'offset out of range:' + offset;
}
this._offset = Math.max(this._offset, this.offset);
this.offset = offset;
return this;
},
/**
* 跳转到写入头部位置
*
* @return {this}
*/
head: function() {
this.offset = this._offset || 0;
}
};
// 扩展方法
var expandProto = {
/**
* 写入一个字符
*
* @param {string} value 写入值
* @param {number} offset 偏移
* @return {this}
*/
writeChar: function(value, offset) {
return this.writeString(value, offset);
},
/**
* 写入fixed类型
*
* @param {number} value 写入值
* @param {number} offset 偏移
* @return {number} float
*/
writeFixed: function(value, offset) {
if(undefined == offset) {
offset = this.offset;
}
this.writeInt32(Math.ceil(val * 65536), offset);
return this;
},
/**
* 写入长日期
*
* @param {Date} value 日期对象
* @param {number} offset 偏移
*
* @return {Date} Date对象
*/
writeLongDateTime: function(value, offset) {
if(undefined == offset) {
offset = this.offset;
}
var delta = -2077545600000; // new Date(1970, 1, 1).getTime() - new Date(1904, 1, 1).getTime();
var time = Math.round((value.getTime() - delta) / 1000);
this.writeUint32(0, offset);
this.writeUint32(time, offset + 4);
return this;
}
};
extend(Writter.prototype, proto, expandProto);
return Writter;
}
);