Skip to content

Commit

Permalink
mappings are back.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pomax committed Mar 2, 2014
1 parent 31a4b2f commit 7023b2d
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 86 deletions.
8 changes: 5 additions & 3 deletions index.html
Expand Up @@ -79,8 +79,8 @@ <h2>Peeking under the CFF bonnet.</h2>

<!-- scripts last, to make sure the page is "done" as much as possible, first -->
<script>require(
["builder", "buildTables", "addStyleSheet", "mapper"],
function(builder, buildTables, addStyleSheet, mapper) {
["builder", "buildTables", "addStyleSheet"],
function(builder, buildTables, addStyleSheet) {
"use strict";

var y = -120;
Expand All @@ -97,7 +97,9 @@ <h2>Peeking under the CFF bonnet.</h2>

var font = builder.build(options);
addStyleSheet(font, "customfont", "custom");
buildTables(font, window, "#tables", "custom font", "The byte layout views for our small, custom font.");
var mappings = font.getMappings();
console.log(mappings);
buildTables(font, mappings, window, "#tables", "custom font", "The byte layout views for our small, custom font.");

});</script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion src/SFNT/DirectoryEntry.js
Expand Up @@ -8,7 +8,7 @@ define(["struct"], function(struct) {
}
};

DirectoryEntry.prototype = new struct([
DirectoryEntry.prototype = new struct("DirectoryEntry", [
["tag", "CHARARRAY", "4-byte identifier"]
, ["checkSum", "ULONG", "sum-as-ULONGs for this table"]
, ["offset", "ULONG", "offset to this table from the beginning of the file"]
Expand Down
36 changes: 34 additions & 2 deletions src/SFNT/SFNT.js
@@ -1,4 +1,4 @@
define(["dataBuilding", "tables", "SFNTHeader", "DirectoryEntry"], function(dataBuilding, tables, SFNTHeader, DirectoryEntry) {
define(["dataBuilding", "tables", "SFNTHeader", "DirectoryEntry", "Mapper"], function(dataBuilding, tables, SFNTHeader, DirectoryEntry, Mapper) {
"use strict";

var header = SFNTHeader("CFF");
Expand All @@ -21,6 +21,7 @@ define(["dataBuilding", "tables", "SFNTHeader", "DirectoryEntry"], function(data
post: tables.post
};
this.header = new header();
this.fontStructs = false;
};

SFNT.prototype = {
Expand Down Expand Up @@ -107,9 +108,40 @@ define(["dataBuilding", "tables", "SFNTHeader", "DirectoryEntry"], function(data
// table is based on the final serialized font data.
var font = headerBlock.concat(directoryBlock).concat(dataBlock);
var checksum = dataBuilding.computeChecksum(font);
var checkSumAdjustment = 0xB1B0AFBA - checksum;
this.stub.head.checkSumAdjustment = checkSumAdjustment;

// the data layout in this font can now be properly mapped,
// if the user wants to call the getMappings() function.
this.fontStructs = {
header: header,
directoryOrder: sorted,
directory: tags,
tableOrder: preferred
};

// return the font with the correct checksumadjustment.
return font.slice(0, offsets["head"] + 8)
.concat(dataBuilding.encoder.ULONG(0xB1B0AFBA - checksum))
.concat(dataBuilding.encoder.ULONG(checkSumAdjustment))
.concat(font.slice(offsets["head"] + 12));
},
getMappings: function() {
if(this.fontStructs === false) return false;
var mapper = new Mapper();
var self = this;
var offset = 0;
this.fontStructs.header.toData(offset, mapper);
offset = mapper.last().end;
this.fontStructs.directoryOrder.forEach(function(tag) {
self.fontStructs.directory[tag].toData(offset, mapper);
offset = mapper.last().end;
});
this.fontStructs.tableOrder.forEach(function(tag) {
self.stub[tag].toData(offset, mapper);
offset = mapper.last().end;
});
mapper.sort();
return mapper.mappings;
}
};

Expand Down
1 change: 0 additions & 1 deletion src/SFNT/tables/CFF_.js
Expand Up @@ -43,7 +43,6 @@ define(["struct", "dataBuilding"], function(struct, dataBuilder){
for(i=0; i<cff.length; i++) {
s = e;
e += serialize(cff[i]).length;
//mapper.addMapping(cff[i][0], s, e, "cff");
}
};

Expand Down
24 changes: 3 additions & 21 deletions src/SFNT/tables/cmap.js
@@ -1,4 +1,4 @@
define(["struct", "EncodingRecord", "subtables"], function(struct, EncodingRecord, subtables){
define(["struct", "makeStructy", "EncodingRecord", "subtables"], function(struct, makeStructy, EncodingRecord, subtables){
"use strict";

var cmap = function(input) {
Expand Down Expand Up @@ -36,24 +36,7 @@ define(["struct", "EncodingRecord", "subtables"], function(struct, EncodingRecor
};

cmap.prototype.finalise = function() {

var encodingrecords = (function(encodingrecords) {
encodingrecords.toJSON = function() {
return this.map(function(r) { return r.toJSON(); });
};
encodingrecords.toString = function() {
return JSON.stringify(this.toJSON(), false, 2);
}
encodingrecords.toData = function() {
var data = [];
this.forEach(function(r) {
data = data.concat(r.toData());
});
return data;
};
return encodingrecords;
}([]));

var encodingrecords = [];
var offset = 4 + (this.numTables * 8); // sizeOf(EncodingRecord) is 8
for(var i=0; i<this.numTables; i++) {
encodingrecords.push(new EncodingRecord({
Expand All @@ -63,9 +46,8 @@ define(["struct", "EncodingRecord", "subtables"], function(struct, EncodingRecor
}));
offset += this.tables[i].length;
}

this.subTables = this.tables;
this.encodingRecords = encodingrecords;
this.encodingRecords = makeStructy(encodingrecords);
};

return cmap;
Expand Down
2 changes: 1 addition & 1 deletion src/SFNT/tables/cmaps/format.4.js
Expand Up @@ -75,7 +75,7 @@ define(["struct", "Segments"], function(struct, Segments){
this.glyphIdArray = glyphIdArray;

// set up the toString, toJSON, and toData functions.
// FIXME: this should be necessary with properly written code.
// FIXME: this shouldn't be necessary with properly written code.
[endCount, startCount, idDelta, idRangeOffset, glyphIdArray].forEach(function(arr) {
arr.toData = function() { return arr; };
arr.toJSON = function() { return { data: arr}; };
Expand Down
15 changes: 8 additions & 7 deletions src/builder.js
@@ -1,6 +1,6 @@
define(
["SFNT", "formGlobals", "asChars", "asGlyphIDs", "addLabelSubstitution", "mapper"],
function(SFNT, formGlobals, asChars, asGlyphIDs, addLabelSubstitution, mapper) {
["SFNT", "formGlobals", "asChars", "asGlyphIDs", "addLabelSubstitution"],
function(SFNT, formGlobals, asChars, asGlyphIDs, addLabelSubstitution) {

"use strict";

Expand Down Expand Up @@ -134,11 +134,12 @@ define(
*/
addLabelSubstitution(font, globals)

Object.keys(font).forEach(function(table) {
if(font[table].toData) {
console.log(table, font[table].toData().length);
}
});

// Object.keys(font).forEach(function(table) {
// if(font[table].toData) {
// console.log(table, font[table].toData().length);
// }
// });


return sfnt;
Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Expand Up @@ -10,7 +10,7 @@

// Font-related filed
extend(".", ["builder", "formGlobals"]);
extend("utils", ["atou", "buildTables", "convertOutline", "dataBuilding", "mapper", "shimFname", "struct", "toWOFF", "addStyleSheet", "asHex", "asChars", "asNumbers", "asGlyphIDs", "makeStructy", "addLabelSubstitution"]);
extend("utils", ["atou", "buildTables", "convertOutline", "dataBuilding", "Mapper", "shimFname", "struct", "toWOFF", "addStyleSheet", "asHex", "asChars", "asNumbers", "asGlyphIDs", "makeStructy", "addLabelSubstitution"]);
extend("SFNT", ["SFNT", "SFNTHeader", "DirectoryEntry", "tables"]);
extend("SFNT/tables", ["BASE", "CFF_", "cmap", "GDEF", "GPOS", "GSUB", "head", "hhea", "hmtx", "JSTF", "maxp", "name", "OS_2", "post"]);
extend("SFNT/tables/common", ["CoverageFormat", "FeatureList", "FeatureRecord", "FeatureTable", "LangSysTable", "LookupList", "LookupTable", "RangeRecord", "ScriptList", "ScriptRecord", "ScriptTable"]);
Expand Down
12 changes: 6 additions & 6 deletions src/utils/buildTables.js
@@ -1,14 +1,14 @@
define(["toWOFF", "asHex", "asChars"], function(toWOFF, asHex, asChars) {
"use strict";

return function buildTables(font, context, selector, cssFontFamily, tableCaption) {
return function buildTables(font, mappings, context, selector, cssFontFamily, tableCaption) {

// top element
var top = document.querySelector(selector);
var create = function(v) { return document.createElement(v); };

// array to HTML table function
function makeTable(data, limit) {
function makeTable(data, mappings, limit) {
limit = limit || 16;
var tdCount = 0;
var table = create("table");
Expand Down Expand Up @@ -65,10 +65,10 @@ define(["toWOFF", "asHex", "asChars"], function(toWOFF, asHex, asChars) {
return table;
}

function formTables(font, hexmap, charmap) {
function formTables(font, mappings, hexmap, charmap) {
top.classList.add("tables");
top.appendChild(makeTable(hexmap));
top.appendChild(makeTable(charmap));
top.appendChild(makeTable(hexmap, mappings));
top.appendChild(makeTable(charmap, mappings));

var downloads = create("div");
downloads.classList.add("downloads");
Expand Down Expand Up @@ -96,7 +96,7 @@ define(["toWOFF", "asHex", "asChars"], function(toWOFF, asHex, asChars) {
var binary = font.toData();
var hexmap = binary.map(asHex);
var charmap = binary.map(asChars);
formTables(font, hexmap, charmap);
formTables(font, mappings, hexmap, charmap);
};

});
Expand Down
11 changes: 8 additions & 3 deletions src/utils/makeStructy.js
Expand Up @@ -3,9 +3,14 @@ define(function() {
array.toJSON = function() {
return this.map(function(r) { return r.toJSON(); });
};
array.toData = function() {
var data = [];
this.forEach(function(r) { data = data.concat(r.toData()); });
array.toData = function(offset, mappings) {
offset = offset || 0;
var data = [], val;
this.forEach(function(r) {
val = r.toData(offset, mappings);
data = data.concat(val);
offset += val.length;
});
return data;
};
array.toString = function() {
Expand Down
59 changes: 30 additions & 29 deletions src/utils/mapper.js
@@ -1,38 +1,39 @@
define(function() {
"use strict";

var mappings, locked, offset = 0;

var reset = function reset() {
mappings = [];
};

var addMapping = function addMapping(options) {
if(locked || !mappings) return;
var mapping = {
name: options.name || '',
start: offset,
end: offset + options.length,
type: options.type || '',
description: options.description || '',
value: options.value || false
};
// offset += options.length;
mappings.push(mapping);
return mapping;
};

var lock = function lock() {
locked = true;
var Mapper = function() {
this.mappings = [];
};

return {
reset: reset,
lock: lock,
addMapping: addMapping,
getMappings: function() {
return mappings;
Mapper.prototype = {
reset: function reset() {
this.mappings = [];
},
addMapping: function addMapping(offset, options) {
var mapping = {
name: options.name || '',
start: offset,
end: offset + options.length,
type: options.type || '',
description: options.description || '',
value: options.value !== undefined ? options.value instanceof Array ? "<structured>" : options.value : false
};
this.mappings.push(mapping);
return mapping;
},
last: function() {
return this.mappings[this.mappings.length-1];
},
sort: function() {
this.mappings.sort(function(a,b) {
// order by start offsets
var diff = a.start - b.start;
// but, if they're the same: the longest mapping comes first
if(diff === 0) { return b.end - a.end; }
return diff;
});
}
};

return Mapper;
});
25 changes: 14 additions & 11 deletions src/utils/struct.js
@@ -1,4 +1,4 @@
define(["dataBuilding", "mapper"], function(dataBuilder, mapper) {
define(["dataBuilding"], function(dataBuilder) {
"use strict";

var encoder = dataBuilder.encoder,
Expand Down Expand Up @@ -36,9 +36,6 @@ define(["dataBuilding", "mapper"], function(dataBuilder, mapper) {
Object.defineProperty(self, fieldName, {
// decode the stored value
get: function() {
if(self.values[fieldName] && self.values[fieldName].encode) {
return self.values[fieldName];
}
return self.values[fieldName] !== undefined ? decoder[fieldType](self.values[fieldName]) : "-";
},
// store values so that they're already encoded correctly
Expand Down Expand Up @@ -101,14 +98,15 @@ define(["dataBuilding", "mapper"], function(dataBuilder, mapper) {
toString: function() {
return JSON.stringify(this.toJSON(), false, 2);
},
toData: function() {
toData: function(offset, mapper) {
offset = offset || 0;
var self = this,
data = [],
val;
Object.keys(this.fields).forEach(function(field) {
if(self.fields[field] === "LITERAL") {
if(self.values[field].toData) {
val = self.values[field].toData();
val = self.values[field].toData(offset, mapper);
}
else {
val = self.values[field];
Expand All @@ -117,11 +115,16 @@ define(["dataBuilding", "mapper"], function(dataBuilder, mapper) {
else {
val = self.values[field];
}
mapper.addMapping({
length: val.length,
name: (self.name ? self.name : '') + ":" + field,
value: self[field]
});

if(mapper) {
mapper.addMapping(offset, {
length: val.length,
name: (self.name ? self.name : '') + ":" + field,
value: self[field]
});
}
offset += val.length;

data = data.concat(val);
});
return data;
Expand Down

0 comments on commit 7023b2d

Please sign in to comment.