Build NapCat Artifacts / Windows Loader Test (push) Canceled after 0s
Build NapCat Artifacts / Type Check & Test (push) Canceled after 0s
Build NapCat Artifacts / Build NapCat.Framework (push) Canceled after 0s
Build NapCat Artifacts / Build NapCat.Shell (push) Canceled after 0s
138 lines
3.8 KiB
Plaintext
138 lines
3.8 KiB
Plaintext
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = sizeof;
|
|
/**
|
|
* @file 获取cmap表的大小
|
|
* @author mengke01(kekee000@gmail.com)
|
|
*/
|
|
|
|
/**
|
|
* 获取format4 delta值
|
|
* Delta is saved in signed int in cmap format 4 subtable,
|
|
* but can be in -0xFFFF..0 interval.
|
|
* -0x10000..-0x7FFF values are stored with offset.
|
|
*
|
|
* @param {number} delta delta值
|
|
* @return {number} delta值
|
|
*/
|
|
function encodeDelta(delta) {
|
|
return delta > 0x7FFF ? delta - 0x10000 : delta < -0x7FFF ? delta + 0x10000 : delta;
|
|
}
|
|
|
|
/**
|
|
* 根据bound获取glyf segment
|
|
*
|
|
* @param {Array} glyfUnicodes glyf编码集合
|
|
* @param {number} bound 编码范围
|
|
* @return {Array} 码表
|
|
*/
|
|
function getSegments(glyfUnicodes, bound) {
|
|
var prevGlyph = null;
|
|
var result = [];
|
|
var segment = {};
|
|
glyfUnicodes.forEach(function (glyph) {
|
|
if (bound === undefined || glyph.unicode <= bound) {
|
|
// 初始化编码头部,这里unicode和graph id 都必须连续
|
|
if (prevGlyph === null || glyph.unicode !== prevGlyph.unicode + 1 || glyph.id !== prevGlyph.id + 1) {
|
|
if (prevGlyph !== null) {
|
|
segment.end = prevGlyph.unicode;
|
|
result.push(segment);
|
|
segment = {
|
|
start: glyph.unicode,
|
|
startId: glyph.id,
|
|
delta: encodeDelta(glyph.id - glyph.unicode)
|
|
};
|
|
} else {
|
|
segment.start = glyph.unicode;
|
|
segment.startId = glyph.id;
|
|
segment.delta = encodeDelta(glyph.id - glyph.unicode);
|
|
}
|
|
}
|
|
prevGlyph = glyph;
|
|
}
|
|
});
|
|
|
|
// need to finish the last segment
|
|
if (prevGlyph !== null) {
|
|
segment.end = prevGlyph.unicode;
|
|
result.push(segment);
|
|
}
|
|
|
|
// 返回编码范围
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 获取format0编码集合
|
|
*
|
|
* @param {Array} glyfUnicodes glyf编码集合
|
|
* @return {Array} 码表
|
|
*/
|
|
function getFormat0Segment(glyfUnicodes) {
|
|
var unicodes = [];
|
|
glyfUnicodes.forEach(function (u) {
|
|
if (u.unicode !== undefined && u.unicode < 256) {
|
|
unicodes.push([u.unicode, u.id]);
|
|
}
|
|
});
|
|
|
|
// 按编码排序
|
|
unicodes.sort(function (a, b) {
|
|
return a[0] - b[0];
|
|
});
|
|
return unicodes;
|
|
}
|
|
|
|
/**
|
|
* 对cmap数据进行预处理,获取大小
|
|
*
|
|
* @param {Object} ttf ttf对象
|
|
* @return {number} 大小
|
|
*/
|
|
function sizeof(ttf) {
|
|
ttf.support.cmap = {};
|
|
var glyfUnicodes = [];
|
|
ttf.glyf.forEach(function (glyph, index) {
|
|
var unicodes = glyph.unicode;
|
|
if (typeof glyph.unicode === 'number') {
|
|
unicodes = [glyph.unicode];
|
|
}
|
|
if (unicodes && unicodes.length) {
|
|
unicodes.forEach(function (unicode) {
|
|
glyfUnicodes.push({
|
|
unicode: unicode,
|
|
id: unicode !== 0xFFFF ? index : 0
|
|
});
|
|
});
|
|
}
|
|
});
|
|
glyfUnicodes = glyfUnicodes.sort(function (a, b) {
|
|
return a.unicode - b.unicode;
|
|
});
|
|
ttf.support.cmap.unicodes = glyfUnicodes;
|
|
var unicodes2Bytes = glyfUnicodes;
|
|
ttf.support.cmap.format4Segments = getSegments(unicodes2Bytes, 0xFFFF);
|
|
ttf.support.cmap.format4Size = 24 + ttf.support.cmap.format4Segments.length * 8;
|
|
ttf.support.cmap.format0Segments = getFormat0Segment(glyfUnicodes);
|
|
ttf.support.cmap.format0Size = 262;
|
|
|
|
// we need subtable 12 only if found unicodes with > 2 bytes.
|
|
var hasGLyphsOver2Bytes = unicodes2Bytes.some(function (glyph) {
|
|
return glyph.unicode > 0xFFFF;
|
|
});
|
|
if (hasGLyphsOver2Bytes) {
|
|
ttf.support.cmap.hasGLyphsOver2Bytes = hasGLyphsOver2Bytes;
|
|
var unicodes4Bytes = glyfUnicodes;
|
|
ttf.support.cmap.format12Segments = getSegments(unicodes4Bytes);
|
|
ttf.support.cmap.format12Size = 16 + ttf.support.cmap.format12Segments.length * 12;
|
|
}
|
|
var size = 4 + (hasGLyphsOver2Bytes ? 32 : 24) // cmap header
|
|
+ ttf.support.cmap.format0Size // format 0
|
|
+ ttf.support.cmap.format4Size // format 4
|
|
+ (hasGLyphsOver2Bytes ? ttf.support.cmap.format12Size : 0); // format 12
|
|
|
|
return size;
|
|
} |