UNPKG

fonteditor-core

Version:

fonts (ttf, woff, woff2, eot, svg, otf) parse, write, transform, glyph adjust.

167 lines (139 loc) 5.54 kB
/** * @file name表 * @author mengke01(kekee000@gmail.com) */ import table from './table'; import nameIdTbl from '../enum/nameId'; import string from '../util/string'; import platformTbl from '../enum/platform'; import {mac, win} from '../enum/encoding'; export default table.create( 'name', [], { read(reader) { let offset = this.offset; reader.seek(offset); const nameTbl = {}; nameTbl.format = reader.readUint16(); nameTbl.count = reader.readUint16(); nameTbl.stringOffset = reader.readUint16(); const nameRecordTbl = []; const count = nameTbl.count; let i; let nameRecord; for (i = 0; i < count; ++i) { nameRecord = {}; nameRecord.platform = reader.readUint16(); nameRecord.encoding = reader.readUint16(); nameRecord.language = reader.readUint16(); nameRecord.nameId = reader.readUint16(); nameRecord.length = reader.readUint16(); nameRecord.offset = reader.readUint16(); nameRecordTbl.push(nameRecord); } offset += nameTbl.stringOffset; // 读取字符名字 for (i = 0; i < count; ++i) { nameRecord = nameRecordTbl[i]; nameRecord.name = reader.readBytes(offset + nameRecord.offset, nameRecord.length); } const names = {}; // mac 下的english name let platform = platformTbl.Macintosh; let encoding = mac.Default; let language = 0; // 如果有windows 下的 english,则用windows下的 name if (nameRecordTbl.some((record) => record.platform === platformTbl.Microsoft && record.encoding === win.UCS2 && record.language === 1033)) { platform = platformTbl.Microsoft; encoding = win.UCS2; language = 1033; } for (i = 0; i < count; ++i) { nameRecord = nameRecordTbl[i]; if (nameRecord.platform === platform && nameRecord.encoding === encoding && nameRecord.language === language && nameIdTbl[nameRecord.nameId]) { names[nameIdTbl[nameRecord.nameId]] = language === 0 ? string.getUTF8String(nameRecord.name) : string.getUCS2String(nameRecord.name); } } return names; }, write(writer, ttf) { const nameRecordTbl = ttf.support.name; writer.writeUint16(0); // format writer.writeUint16(nameRecordTbl.length); // count writer.writeUint16(6 + nameRecordTbl.length * 12); // string offset // write name tbl header let offset = 0; nameRecordTbl.forEach((nameRecord) => { writer.writeUint16(nameRecord.platform); writer.writeUint16(nameRecord.encoding); writer.writeUint16(nameRecord.language); writer.writeUint16(nameRecord.nameId); writer.writeUint16(nameRecord.name.length); writer.writeUint16(offset); // offset offset += nameRecord.name.length; }); // write name tbl strings nameRecordTbl.forEach((nameRecord) => { writer.writeBytes(nameRecord.name); }); return writer; }, size(ttf) { const names = ttf.name; let nameRecordTbl = []; // 写入name信息 // 这里为了简化书写,仅支持英文编码字符, // 中文编码字符将被转化成url encode let size = 6; Object.keys(names).forEach((name) => { const id = nameIdTbl.names[name]; const utf8Bytes = string.toUTF8Bytes(names[name]); const usc2Bytes = string.toUCS2Bytes(names[name]); if (undefined !== id) { // mac nameRecordTbl.push({ nameId: id, platform: 1, encoding: 0, language: 0, name: utf8Bytes }); // windows nameRecordTbl.push({ nameId: id, platform: 3, encoding: 1, language: 1033, name: usc2Bytes }); // 子表大小 size += 12 * 2 + utf8Bytes.length + usc2Bytes.length; } }); const namingOrder = ['platform', 'encoding', 'language', 'nameId']; nameRecordTbl = nameRecordTbl.sort((a, b) => { let l = 0; namingOrder.some(name => { const o = a[name] - b[name]; if (o) { l = o; return true; } return false; }); return l; }); // 保存预处理信息 ttf.support.name = nameRecordTbl; return size; } } );