add cmap writer

This commit is contained in:
mkwiser 2014-10-01 21:43:29 +08:00
parent 5a169e7467
commit ed475288e8
4 changed files with 102 additions and 84 deletions

View File

@ -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);

View File

@ -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} 字符字典索引keyunicodevalueglyf 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相关的信息
*/

View File

@ -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';

View File

@ -0,0 +1,74 @@
/**
* @file
* @author mengke01
* @date
* @description
* 读取windows支持的字符集
*/
define(
function(require) {
/**
* 读取ttf中windows字符表的字符
*
* @return {Object} 字符字典索引keyunicodevalueglyf 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;
}
);