error:glyf

This commit is contained in:
mkwiser 2014-09-29 01:07:24 +08:00
parent a2f83e055f
commit 3bb0dd5a56
6 changed files with 7175 additions and 52 deletions

File diff suppressed because one or more lines are too long

View File

@ -57,6 +57,7 @@ define(
glyf.glyfs.forEach(function(g) {
// flags + glyfIndex
size += 4;
// a, b, c, d, e
// xy values or points
if(g.e >= -0xFF && g.e <= 0xFF && g.f >= 0xFF && g.f <= 0xFF) {
@ -92,20 +93,25 @@ define(
* @return {Array}
*/
function getFlags(glyf, glyfSupport) {
if (!glyf.contours.length) {
return glyfSupport;
}
var flags = [];
var prevFlag = -1;
var prev = {};
var xCoord = [];
var yCoord = [];
var first = true;
var x, y, flag;
var x, y, flag, repeatPoint = -1;
glyf.contours.forEach(function(contour) {
contour.forEach(function(p) {
flag = p.onCurve ? glyFlag.ONCURVE : 0;
if (first) {
x = p.x;
y = p.y
y = p.y;
}
else {
x = p.x - prev.x;
@ -113,50 +119,70 @@ define(
}
if (-0xFF <= x && x <= 0xFF) {
flag += glyFlag.XSHORT;
if (x == 0) {
if (xCoord[xCoord.length - 1] >= 0 ) {
if (!first && x == 0) {
if (xCoord[xCoord.length - 1] > 0 ) {
flag += glyFlag.XSAME;
}
else {
flag += glyFlag.XSHORT;
}
}
else if(x >= 0) {
flag += glyFlag.XSAME;
else {
flag += glyFlag.XSHORT;
if(x > 0) {
flag += glyFlag.XSAME;
}
}
x = Math.abs(x);
}
if (-0xFF <= y && y <= 0xFF) {
flag += glyFlag.YSHORT;
if (y == 0) {
if (yCoord[yCoord.length - 1] >= 0 ) {
if (!first && y == 0) {
if (yCoord[yCoord.length - 1] > 0 ) {
flag += glyFlag.YSAME;
}
else {
flag += glyFlag.YSHORT;
}
}
else if(y >= 0) {
flag += glyFlag.YSAME;
else {
flag += glyFlag.YSHORT;
if(y > 0) {
flag += glyFlag.YSAME;
}
}
y = Math.abs(y);
}
if (prevFlag == flag) {
flags[flags.length - 1] |= glyFlag.REPEAT;
// 记录重复个数
if (-1 == repeatPoint) {
repeatPoint = flags.length - 1;
flags[repeatPoint] |= glyFlag.REPEAT;
flags.push(1);
}
else {
++flags[repeatPoint + 1];
}
}
else {
repeatPoint = -1;
flags.push(flag);
prevFlag = flag;
prev = p;
if (first || 0 != x && xCoord[xCoord.length - 1] != x) {
xCoord.push(x);
}
if (first || 0 != y && yCoord[yCoord.length - 1] != y) {
yCoord.push(y);
}
}
if (first || 0 != x) {
xCoord.push(x);
}
if (first || 0 != y) {
yCoord.push(y);
}
prev = p;
first = false;
});
});
@ -204,6 +230,10 @@ define(
ttf.glyf.forEach(function(glyf, index) {
if (!glyf.compound && 0 == glyf.contours.length) {
return;
}
// header
writer.writeUint16(glyf.compound ? -1 : glyf.contours.length);
writer.writeInt16(glyf.xMin);
@ -319,7 +349,7 @@ define(
var xCoord = ttf.support.glyf[index].xCoord;
for (var i = 0, l = xCoord.length; i < l; i++) {
if (-0xFF <= xCoord[i] && xCoord[i] <= 0xFF) {
if (0 <= xCoord[i] && xCoord[i] <= 0xFF) {
writer.writeUint8(xCoord[i]);
}
else {
@ -329,7 +359,7 @@ define(
var yCoord = ttf.support.glyf[index].yCoord;
for (var i = 0, l = yCoord.length; i < l; i++) {
if (-0xFF <= yCoord[i] && yCoord[i] <= 0xFF) {
if (0 <= yCoord[i] && yCoord[i] <= 0xFF) {
writer.writeUint8(yCoord[i]);
}
else {
@ -355,7 +385,7 @@ define(
var tableSize = 0;
ttf.glyf.forEach(function(glyf) {
var glyfSupport = {};
var glyfSupport = glyf.compound ? [] : getFlags(glyf, glyfSupport);
var glyfSupport = glyf.compound ? glyfSupport : getFlags(glyf, glyfSupport);
var contoursSize = glyf.compound ? sizeofCompound(glyf) : sizeof(glyf, glyfSupport);
var size = contoursSize;
@ -375,7 +405,32 @@ define(
tableSize += size;
});
return tableSize;
ttf.support.glyf.tableSize = tableSize;
// 设置其他表的信息
var xMin = 16384, yMin = 16384, xMax = -16384, yMax = -16384;
ttf.glyf.forEach(function(glyf) {
if (glyf.xMin < xMin) {
xMin = glyf.xMin;
}
if (glyf.yMin < yMin) {
yMin = glyf.yMin;
}
if (glyf.xMax > xMax) {
xMax = glyf.xMax;
}
if (glyf.yMax > yMax) {
yMax = glyf.yMax;
}
});
ttf.head.xMin = xMin;
ttf.head.yMin = yMin;
ttf.head.xMax = xMax;
ttf.head.yMax = yMax;
ttf.head.indexToLocFormat = tableSize > 65536 ? 1 : 0;
return ttf.support.glyf.tableSize;
}
}
);

View File

@ -38,7 +38,27 @@ define(
},
write: function(writer, ttf) {
var glyfSupport = ttf.support.glyf;
var offset = ttf.support.glyf.offset || 0;
var indexToLocFormat = ttf.head.indexToLocFormat;
var sizeRatio = (indexToLocFormat === 0) ? 0.5 : 1;
var numGlyphs = ttf.glyf.length;
for (var i = 0; i < numGlyphs; ++i) {
if (indexToLocFormat) {
writer.writeUint32(offset);
}
else {
writer.writeUint16(offset);
}
offset += glyfSupport[i].size * sizeRatio;
}
return writer;
},
size: function(ttf) {
var numGlyphs = ttf.glyf.length;
return ttf.head.indexToLocFormat ? numGlyphs * 4 : numGlyphs * 2;
}
}
);

View File

@ -31,6 +31,10 @@ define(
],
{
write: function(writer, ttf) {
table.write.call(this, writer, ttf.maxp);
return writer;
},
size: function(ttf) {
var maxPoints = 0, maxContours = 0, maxCompositePoints = 0,
maxCompositeContours = 0;
ttf.glyf.forEach(function(glyf) {
@ -49,29 +53,27 @@ define(
});
var mock = {
maxp: {
version: 1.0,
numGlyphs: ttf.glyf.length,
maxPoints: maxPoints,
maxContours: maxContours,
maxCompositePoints: maxCompositePoints,
maxCompositeContours: maxCompositeContours,
maxZones: 2,
maxTwilightPoints: 0,
// It is unclear how to calculate maxStorage, maxFunctionDefs and maxInstructionDefs.
// These are magic constants now, with values exceeding values from FontForge
// see svg2ttf on github
maxStorage: 10,
maxFunctionDefs: 10,
maxStackElements: 255,
maxSizeOfInstructions: 0,
maxComponentElements: 0,
maxComponentDepth: 0
}
ttf.maxp = {
version: 1.0,
numGlyphs: ttf.glyf.length,
maxPoints: maxPoints,
maxContours: maxContours,
maxCompositePoints: maxCompositePoints,
maxCompositeContours: maxCompositeContours,
maxZones: 2,
maxTwilightPoints: 0,
// It is unclear how to calculate maxStorage, maxFunctionDefs and maxInstructionDefs.
// These are magic constants now, with values exceeding values from FontForge
// see svg2ttf on github
maxStorage: 10,
maxFunctionDefs: 10,
maxStackElements: 255,
maxSizeOfInstructions: 0,
maxComponentElements: 0,
maxComponentDepth: 0
};
table.write.call(this, writer, mock);
return writer;
return table.size.call(this, ttf);
}
}
);

View File

@ -126,6 +126,11 @@ define(
contours.push(coordinates.slice(endPtsOfContours[i - 1] + 1, endPtsOfContours[i] + 1));
}
val.contours = contours;
// FIXME for test
val.flags = flags;
val.xCoordinates = xCoordinates;
val.yCoordinates = yCoordinates;
}
}

View File

@ -10,6 +10,7 @@
define(
function(require) {
var Reader = require('./reader');
var Writer = require('./writer');
var Directory = require('./table/directory');
var supportTables = require('./table/support');
@ -50,19 +51,35 @@ define(
// 用来做写入缓存的对象,用完后删掉
ttf.support = {};
// 写入maxp
var maxpTbl = new supportTables['maxp']();
var size = maxpTbl.size(ttf);
// 写入glyf
var glyfTbl = new supportTables['glyf']();
console.log(glyfTbl.size(ttf));
var glyfWriter = new Writer(new ArrayBuffer(glyfTbl.size(ttf)));
var size = glyfTbl.size(ttf);
var glyfWriter = new Writer(new ArrayBuffer(size));
glyfTbl.write(glyfWriter, ttf);
// 写入loca
var locaTbl = new supportTables['glyf']();
var locaTbl = new supportTables['loca']();
var locaWriter = new Writer(new ArrayBuffer(locaTbl.size(ttf)));
locaTbl.write(locaWriter, ttf);
// 读取测试
var locaReader = new Reader(locaWriter.getBuffer());
locaTbl.offset = 0;
ttf.loca = locaTbl.read(locaReader, ttf);
var glyfReader = new Reader(glyfWriter.getBuffer());
glyfTbl.offset = 0;
ttf.glyfReaded = glyfTbl.read(glyfReader, ttf);
console.log(ttf.glyfReaded);
// var ttfSize = 20 + tableList.length * 16;
// ttf.tables = [];