add cmap writer
This commit is contained in:
parent
5a169e7467
commit
ed475288e8
@ -151,7 +151,6 @@ define(
|
||||
* -0x10000..-0x7FFF values are stored with offset.
|
||||
*
|
||||
* @param {number} delta delta
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
function encodeDelta(delta) {
|
||||
@ -168,43 +167,46 @@ define(
|
||||
* @return {Array} 码表
|
||||
*/
|
||||
function getSegments(unicodes, bound) {
|
||||
|
||||
var prevGlyph = null;
|
||||
var result = [];
|
||||
var segment = {};
|
||||
|
||||
var delta;
|
||||
var prevEndCode = 0;
|
||||
var prevDelta = -1;
|
||||
|
||||
unicodes.forEach(function (glyph) {
|
||||
|
||||
if (bound === undefined || glyph.unicode <= bound) {
|
||||
// Initialize first segment or add new segment if code "hole" is found
|
||||
if (prevGlyph === null || glyph.unicode !== prevGlyph.unicode + 1) {
|
||||
// 初始化编码头部,这里unicode和graph id 都必须连续
|
||||
if (prevGlyph === null
|
||||
|| glyph.unicode !== prevGlyph.unicode + 1
|
||||
|| glyph.id !== prevGlyph.id + 1
|
||||
) {
|
||||
if (prevGlyph !== null) {
|
||||
segment.end = prevGlyph.unicode;
|
||||
delta = prevEndCode - segment.start + prevDelta + 1;
|
||||
segment.delta = encodeDelta(delta);
|
||||
prevEndCode = segment.end;
|
||||
prevDelta = delta;
|
||||
result.push(segment);
|
||||
segment = {};
|
||||
segment = {
|
||||
start: glyph.unicode,
|
||||
startId: glyph.id,
|
||||
delta: encodeDelta(glyph.id - glyph.unicode)
|
||||
};
|
||||
}
|
||||
segment.start = glyph.unicode;
|
||||
}
|
||||
prevGlyph = glyph;
|
||||
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;
|
||||
delta = prevEndCode - segment.start + prevDelta + 1;
|
||||
segment.delta = delta > 0x7FFF
|
||||
? delta - 0x10000
|
||||
: (delta < -0x7FFF ? delta + 0x10000 : delta);
|
||||
result.push(segment);
|
||||
}
|
||||
|
||||
// 返回编码范围
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -318,13 +320,10 @@ define(
|
||||
writer.writeUint32(0); // language
|
||||
writer.writeUint32(segments.length); // nGroups
|
||||
|
||||
var startCode = 0;
|
||||
|
||||
segments.forEach(function(segment) {
|
||||
writer.writeUint32(segment.start);
|
||||
writer.writeUint32(segment.end);
|
||||
writer.writeUint32(startCode);
|
||||
startCode += segment.end - segment.start + 1;
|
||||
writer.writeUint32(segment.startId);
|
||||
});
|
||||
|
||||
return writer;
|
||||
@ -440,6 +439,9 @@ define(
|
||||
}
|
||||
});
|
||||
|
||||
unicodes = unicodes.sort(function(a, b) {
|
||||
return a.unicode - b.unicode;
|
||||
});
|
||||
|
||||
ttf.support.cmap.unicodes = unicodes;
|
||||
ttf.support.cmap.format4Segments = getSegments(unicodes, 0xFFFF);
|
||||
|
@ -16,6 +16,7 @@ define(
|
||||
var Directory = require('./table/directory');
|
||||
var supportTables = require('./table/support');
|
||||
var Reader = require('./reader');
|
||||
var readWindowsAllCodes =require('./util/readWindowsAllCodes');
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
@ -52,66 +53,6 @@ define(
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取ttf中windows字符表的字符
|
||||
*
|
||||
* @return {Object} 字符字典索引,key:unicode,value:glyf index
|
||||
*
|
||||
* @see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
|
||||
*/
|
||||
function readWindowsAllCodes(ttf) {
|
||||
// 读取windows unicode 编码段
|
||||
var usc2Arr = ttf.cmap.tables.filter(function(item) {
|
||||
return item.platformID == 3 && item.encodingID == 1 && item.format == 4;
|
||||
});
|
||||
|
||||
if(usc2Arr.length) {
|
||||
// 只取第一个format
|
||||
var format4 = usc2Arr[0];
|
||||
var segCount = format4.segCountX2 / 2;
|
||||
|
||||
var codes = {};
|
||||
|
||||
// graphIdArray 和idRangeOffset的偏移量
|
||||
var graphIdArrayIndexOffset = (format4.glyphIdArrayOffset - format4.idRangeOffsetOffset) / 2;
|
||||
|
||||
for (var i = 0; i < segCount; ++i) {
|
||||
// 读取单个字符
|
||||
for(
|
||||
var start = format4.startCode[i], end = format4.endCode[i];
|
||||
start <= end;
|
||||
++start
|
||||
) {
|
||||
// range offset = 0
|
||||
if(format4.idRangeOffset[i] === 0) {
|
||||
codes[start] = (start + format4.idDelta[i]) % 65536;
|
||||
}
|
||||
// rely on to glyphIndexArray
|
||||
else {
|
||||
var index = i + format4.idRangeOffset[i] / 2
|
||||
+ (start - format4.startCode[i])
|
||||
- graphIdArrayIndexOffset;
|
||||
|
||||
var graphId = format4.glyphIdArray[index];
|
||||
if(graphId !== 0) {
|
||||
codes[start] = (graphId + format4.idDelta[i]) % 65536;
|
||||
}
|
||||
else {
|
||||
codes[start] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联glyf相关的信息
|
||||
*/
|
||||
|
@ -97,7 +97,8 @@ define(
|
||||
cmapTbl.offset = 0;
|
||||
ttf.cmap = cmapTbl.read(cmapReader, ttf);
|
||||
|
||||
console.log(ttf);
|
||||
var readWindowsAllCodes = require('./util/readWindowsAllCodes');
|
||||
console.log(readWindowsAllCodes(ttf));
|
||||
|
||||
throw 'test';
|
||||
|
||||
|
74
src/ttf/util/readWindowsAllCodes.js
Normal file
74
src/ttf/util/readWindowsAllCodes.js
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @file
|
||||
* @author mengke01
|
||||
* @date
|
||||
* @description
|
||||
* 读取windows支持的字符集
|
||||
*/
|
||||
|
||||
|
||||
define(
|
||||
function(require) {
|
||||
|
||||
/**
|
||||
* 读取ttf中windows字符表的字符
|
||||
*
|
||||
* @return {Object} 字符字典索引,key:unicode,value:glyf index
|
||||
*
|
||||
* @see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
|
||||
*/
|
||||
function readWindowsAllCodes(ttf) {
|
||||
// 读取windows unicode 编码段
|
||||
var usc2Arr = ttf.cmap.tables.filter(function(item) {
|
||||
return item.platformID == 3 && item.encodingID == 1 && item.format == 4;
|
||||
});
|
||||
|
||||
if(usc2Arr.length) {
|
||||
// 只取第一个format
|
||||
var format4 = usc2Arr[0];
|
||||
var segCount = format4.segCountX2 / 2;
|
||||
|
||||
var codes = {};
|
||||
|
||||
// graphIdArray 和idRangeOffset的偏移量
|
||||
var graphIdArrayIndexOffset = (format4.glyphIdArrayOffset - format4.idRangeOffsetOffset) / 2;
|
||||
|
||||
for (var i = 0; i < segCount; ++i) {
|
||||
// 读取单个字符
|
||||
for(
|
||||
var start = format4.startCode[i], end = format4.endCode[i];
|
||||
start <= end;
|
||||
++start
|
||||
) {
|
||||
// range offset = 0
|
||||
if(format4.idRangeOffset[i] === 0) {
|
||||
codes[start] = (start + format4.idDelta[i]) % 0x10000;
|
||||
}
|
||||
// rely on to glyphIndexArray
|
||||
else {
|
||||
var index = i + format4.idRangeOffset[i] / 2
|
||||
+ (start - format4.startCode[i])
|
||||
- graphIdArrayIndexOffset;
|
||||
|
||||
var graphId = format4.glyphIdArray[index];
|
||||
if(graphId !== 0) {
|
||||
codes[start] = (graphId + format4.idDelta[i]) % 0x10000;
|
||||
}
|
||||
else {
|
||||
codes[start] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return readWindowsAllCodes;
|
||||
}
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user