Skip to content

Commit

Permalink
TTF checksums are calculated now.
Browse files Browse the repository at this point in the history
  • Loading branch information
snb2013 committed Jul 19, 2013
1 parent 572ce89 commit cc1467d
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 21 deletions.
54 changes: 38 additions & 16 deletions lib/ttf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 33,35 @@ var TABLES = [
// Various constants
var CONST = {
VERSION: 0x10000,
TABLE_COUNT: 10
TABLE_COUNT: 10,
CHECKSUM_ADJUSTMENT: 0xB1B0AFBA
};

function ulong(t) {
/*jshint bitwise:false*/
t &= 0xffffffff;
if (t < 0) {
t = 0x100000000;
}
return t;
}

function calc_checksum(buf) {
var sum = 0;
buf.seek(0);
var len = buf.byteLength;

while (buf.tell() < len) {
sum = ulong(sum buf.getUint32());
}
return sum;
}

function writeTableHeader(buf, innerName, checkSum, offset, length) {
buf.writeUint32(innerName); //inner name
buf.writeUint32(checkSum || 0); //checksum
buf.writeUint32(offset || 0); //offset
buf.writeUint32(length || 0); //length
buf.writeUint32(checkSum); //checksum
buf.writeUint32(offset); //offset
buf.writeUint32(length); //length
}

function generateTTF(font) {
Expand Down Expand Up @@ -70,15 91,11 @@ function generateTTF(font) {
});

// Add tables
var tableLengths = [];
var tableBuffers = [];
var fullTablesLength = 0;
_.forEach(TABLES, function (table) {
//store each table in its own buffer
var tableBuffer = table.create(font);
tableBuffers.push(tableBuffer);
tableLengths.push(tableBuffer.byteLength);
fullTablesLength = tableLengths[tableLengths.length - 1];
table.buffer = table.create(font);
fullTablesLength = table.buffer.byteLength;
});

//create TTF buffer
Expand All @@ -97,18 114,23 @@ function generateTTF(font) {
buf.writeUint16(entrySelector);
buf.writeUint16(rangeShift);

var i = 0;
var offset = 0;
_.forEach(TABLES, function (table) {
writeTableHeader(buf, table.innerName, 0, tablesDataOffset offset, tableLengths[i]);
offset = tableLengths[i];
i ;
writeTableHeader(buf, table.innerName, calc_checksum(table.buffer), tablesDataOffset offset, table.buffer.byteLength);
offset = table.buffer.byteLength;
});

_.forEach(tableBuffers, function (tableBuffer) {
buf.writeBytes(tableBuffer.buffer);
var headOffset = 0;
_.forEach(TABLES, function (table) {
if (table.innerName === 0x68656164) { //we must store head offset to write font checksum
headOffset = buf.tell();
}
buf.writeBytes(table.buffer.buffer);
});

// Write font checksum (corrected by magic value) into HEAD table
buf.setUint32(headOffset 8, ulong(CONST.CHECKSUM_ADJUSTMENT - calc_checksum(buf)));

return buf;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/ttf/tables/cmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 198,7 @@ function createCMapTable(font) {
bufSize = subtableHeaderBuffers[i].byteLength;
bufSize = subTableBuffers[i].byteLength;
}
bufSize = (4 - bufSize % 4) % 4; // length of a table must be a multiple of four bytes

var buf = new jDataView(bufSize);

Expand All @@ -218,6 219,11 @@ function createCMapTable(font) {
buf.writeBytes(subTableBuffers[i].buffer);
}

// Fill left space with zeros
while (buf.tell() < bufSize) {
buf.writeUint8(0);
}

// Write table offsets
for (i = 0; i < subtableHeaderBuffers.length; i ) {
buf.setUint32(8 i * 8, tableOffsets[i]);
Expand Down
3 changes: 2 additions & 1 deletion lib/ttf/tables/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 11,7 @@ function dateToUInt64(date) {

function createHeadTable(font) {

var buf = new jDataView(54); // fixed table length
var buf = new jDataView(56); // fixed table length

buf.writeInt32(0x10000); // version
buf.writeInt32(font.revision * 0x10000); // fontRevision
Expand All @@ -34,6 34,7 @@ function createHeadTable(font) {
buf.writeInt16(2); // fontDirectionHint
buf.writeInt16(font.ttf_glyph_size < 0x20000 ? 0 : 1); // indexToLocFormat, 0 for short offsets, 1 for long offsets
buf.writeInt16(0); // glyphDataFormat
buf.writeInt16(0); // 2 bytes to align table

return buf;
}
Expand Down
9 changes: 8 additions & 1 deletion lib/ttf/tables/loca.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 7,16 @@ var jDataView = require('jDataView');

function tableSize(font, isShortFormat) {
var result = (font.glyphs.length 1) * (isShortFormat ? 2 : 4); // by glyph count tail
result = (4 - result % 4) % 4; // length of a table must be a multiple of four bytes
return result;
}

function createLocaTable(font) {

var isShortFormat = font.ttf_glyph_size < 0x20000;

var buf = new jDataView(tableSize(font, isShortFormat));
var bufSize = tableSize(font, isShortFormat);
var buf = new jDataView(bufSize);

var location = 0;
// Array of offsets in GLYF table for each glyph
Expand All @@ -34,6 36,11 @@ function createLocaTable(font) {
buf.writeUint32(location);
}

// Fill left space with zeros
while (buf.tell() < bufSize) {
buf.writeUint8(0);
}

return buf;
}

Expand Down
9 changes: 8 additions & 1 deletion lib/ttf/tables/name.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 19,7 @@ function tableSize(names) {
_.forEach(names, function (name) {
result = 12 name.data.length; //name header and data
});
result = (4 - result % 4) % 4; // length of a table must be a multiple of four bytes
return result;
}

Expand Down Expand Up @@ -67,7 68,8 @@ function createNameTable(font) {

var names = getNames(font);

var buf = new jDataView(tableSize(names));
var bufSize = tableSize(names);
var buf = new jDataView(bufSize);

buf.writeUint16(0); // formatSelector
buf.writeUint16(names.length); // nameRecordsCount
Expand All @@ -93,6 95,11 @@ function createNameTable(font) {
buf.seek(offsetPosition);
buf.writeUint16(actualStringDataOffset); // offset

// Fill left space with zeros
while (buf.tell() < bufSize) {
buf.writeUint8(0);
}

return buf;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/ttf/tables/os2.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 29,7 @@ function getLastCharIndex(font) {

function createOS2Table(font) {

var buf = new jDataView(86); // fixed table length
var buf = new jDataView(88); // fixed table length

buf.writeUint16(1); //version
buf.writeInt16(font.avgWidth); // xAvgCharWidth
Expand Down Expand Up @@ -74,6 74,7 @@ function createOS2Table(font) {
buf.writeInt16(font.yMin < 0 ? -font.yMin : -font.descent); // usWinDescent
buf.writeInt32(1); // ulCodePageRange1, Latin 1
buf.writeInt32(0); // ulCodePageRange2
buf.writeInt16(0); // 2 bytes to align table

return buf;
}
Expand Down
9 changes: 8 additions & 1 deletion lib/ttf/tables/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 11,7 @@ function tableSize(font, names) {
_.forEach(names, function(name) {
result = name.length;
});
result = (4 - result % 4) % 4; // length of a table must be a multiple of four bytes
return result;
}

Expand All @@ -31,7 32,8 @@ function createPostTable(font) {
return pascalString(glyph.name);
});

var buf = new jDataView(tableSize(font, names));
var bufSize = tableSize(font, names);
var buf = new jDataView(bufSize);

buf.writeInt32(0x20000); // formatType, version 2.0
buf.writeInt32(font.italicAngle); // italicAngle
Expand All @@ -57,6 59,11 @@ function createPostTable(font) {
buf.writeBytes(name);
});

// Fill left space with zeros
while (buf.tell() < bufSize) {
buf.writeUint8(0);
}

return buf;
}

Expand Down

0 comments on commit cc1467d

Please sign in to comment.