styleSheet.insertRule(rule, styleSheet.length);
},
- _createOpenTypeHeader: function font_createOpenTypeHeader(aNumTables) {
+ _createOpenTypeHeader: function font_createOpenTypeHeader(aFile, aOffsets, aNumTables) {
// sfnt version (4 bytes)
var version = [0x4F, 0x54, 0x54, 0X4F];
// rangeShift (2 bytes)
var rangeShift = numTables * 16 - searchRange;
- return [].concat(version,
- FontsUtils.integerToBytes(numTables, 2),
- FontsUtils.integerToBytes(searchRange, 2),
- FontsUtils.integerToBytes(entrySelector, 2),
- FontsUtils.integerToBytes(rangeShift, 2));
+ var header = [].concat(version,
+ FontsUtils.integerToBytes(numTables, 2),
+ FontsUtils.integerToBytes(searchRange, 2),
+ FontsUtils.integerToBytes(entrySelector, 2),
+ FontsUtils.integerToBytes(rangeShift, 2));
+ aFile.set(header, aOffsets.currentOffset);
+ aOffsets.currentOffset += header.length;
+ aOffsets.virtualOffset += header.length;
},
- _createTableEntry: function font_createTableEntry(aTag, aOffset, aData) {
+ _createTableEntry: function font_createTableEntry(aFile, aOffsets, aTag, aData) {
// tag
var tag = [
aTag.charCodeAt(0),
];
// offset
- var offset = aOffset;
+ var offset = aOffsets.virtualOffset;
// Per spec tables must be 4-bytes align so add some 0x00 if needed
while (aData.length & 3)
// checksum
var checksum = FontsUtils.bytesToInteger(tag) + offset + length;
- return [].concat(tag,
- FontsUtils.integerToBytes(checksum, 4),
- FontsUtils.integerToBytes(offset, 4),
- FontsUtils.integerToBytes(length, 4));
+ var tableEntry = [].concat(tag,
+ FontsUtils.integerToBytes(checksum, 4),
+ FontsUtils.integerToBytes(offset, 4),
+ FontsUtils.integerToBytes(length, 4));
+ aFile.set(tableEntry, aOffsets.currentOffset);
+ aOffsets.currentOffset += tableEntry.length;
+ aOffsets.virtualOffset += aData.length;
},
_createCMAPTable: function font_createCMAPTable(aGlyphs) {
cover: function font_cover(aFont) {
var otf = new Uint8Array(kMaxFontFileSize);
- var aFontData = aFont.data;
- var currentOffset = 0;
- var numTables = 9;
- //var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post];
- var header = this._createOpenTypeHeader(numTables);
- otf.set(header, currentOffset);
- currentOffset += header.length;
+ // Required Tables
+ var CFF = aFont.data,
+ OS2 = [],
+ cmap = [],
+ head = [],
+ hhea = [],
+ hmtx = [],
+ maxp = [],
+ name = [],
+ post = [];
+ var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
+
+ // The offsets object holds at the same time a representation of where
+ // to write the table entry information about a table and another offset
+ // representing the offset where to draw the actual data of a particular
+ // table
+ var offsets = {
+ currentOffset: 0,
+ virtualOffset: tables.length * (4 * 4)
+ };
+
+ // For files with only one font the offset table is the first thing of the
+ // file
+ this._createOpenTypeHeader(otf, offsets, tables.length);
- var baseOffset = numTables * (4 * 4) + currentOffset;
- var virtualOffset = baseOffset;
- var tableEntry = this._createTableEntry("CFF ", virtualOffset, aFontData);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += aFontData.length;
+ // XXX It is probable that in a future we want to get rid of this glue
+ // between the CFF and the OTF format in order to be able to embed TrueType
+ // data.
+ this._createTableEntry(otf, offsets, "CFF ", CFF);
- var OS2 = [
+ /** OS/2 */
+ OS2 = [
0x00, 0x03, // version
0x02, 0x24, // xAvgCharWidth
0x01, 0xF4, // usWeightClass
0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63)
0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95)
0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127)
- 0x47, 0x49, 0x60, 0x20, // achVendID
+ 0x2A, 0x32, 0x31, 0x2A, // achVendID
0x00, 0x20, // fsSelection
0x00, 0x2D, // usFirstCharIndex
0x00, 0x7A, // usLastCharIndex
0x00, 0xCD, // usBreakChar
0x00, 0x02 // usMaxContext
];
+ this._createTableEntry(otf, offsets, "OS/2", OS2);
- var tableEntry = this._createTableEntry("OS/2", virtualOffset, OS2);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += OS2.length;
-
- /** CMAP */
+ //XXX Getting charstrings here seems wrong since this is another CFF glue
var charstrings = aFont.getOrderedCharStrings(aFont.font);
- var cmap = this._createCMAPTable(charstrings);
- var tableEntry = this._createTableEntry("cmap", virtualOffset, cmap);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += cmap.length;
-
+ /** CMAP */
+ cmap = this._createCMAPTable(charstrings);
+ this._createTableEntry(otf, offsets, "cmap", cmap);
/** HEAD */
-
- var head = [
+ head = [
0x00, 0x01, 0x00, 0x00, // Version number
0x00, 0x00, 0x50, 0x00, // fontRevision
0x00, 0x00, 0x00, 0x00, // checksumAdjustement
0x00, 0x00, // indexToLocFormat
0x00, 0x00 // glyphDataFormat
];
- var tableEntry = this._createTableEntry("head", virtualOffset, head);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += head.length;
-
+ this._createTableEntry(otf, offsets, "head", head);
/** HHEA */
-
- var hhea = [
- 0x00, 0x01, 0x00, 0x00, // Version number
- 0x00, 0x00, // Typographic Ascent
- 0x00, 0x00, // Typographic Descent
- 0x00, 0x00, // Line Gap
- 0xFF, 0xFF, // advanceWidthMax
- 0x00, 0x00, // minLeftSidebearing
- 0x00, 0x00, // minRightSidebearing
- 0x00, 0x00, // xMaxExtent
- 0x00, 0x00, // caretSlopeRise
- 0x00, 0x00, // caretSlopeRun
- 0x00, 0x00, // caretOffset
- 0x00, 0x00, // -reserved-
- 0x00, 0x00, // -reserved-
- 0x00, 0x00, // -reserved-
- 0x00, 0x00, // -reserved-
- 0x00, 0x00 // metricDataFormat
- ];
- hhea = hhea.concat(FontsUtils.integerToBytes(charstrings.length, 2)); // numberOfHMetrics
-
- var tableEntry = this._createTableEntry("hhea", virtualOffset, hhea);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += hhea.length;
+ hhea = [].concat(
+ [
+ 0x00, 0x01, 0x00, 0x00, // Version number
+ 0x00, 0x00, // Typographic Ascent
+ 0x00, 0x00, // Typographic Descent
+ 0x00, 0x00, // Line Gap
+ 0xFF, 0xFF, // advanceWidthMax
+ 0x00, 0x00, // minLeftSidebearing
+ 0x00, 0x00, // minRightSidebearing
+ 0x00, 0x00, // xMaxExtent
+ 0x00, 0x00, // caretSlopeRise
+ 0x00, 0x00, // caretSlopeRun
+ 0x00, 0x00, // caretOffset
+ 0x00, 0x00, // -reserved-
+ 0x00, 0x00, // -reserved-
+ 0x00, 0x00, // -reserved-
+ 0x00, 0x00, // -reserved-
+ 0x00, 0x00 // metricDataFormat
+ ],
+ FontsUtils.integerToBytes(charstrings.length, 2) // numberOfHMetrics
+ );
+ this._createTableEntry(otf, offsets, "hhea", hhea);
/** HMTX */
-
- var hmtx = [0x01, 0xF4, 0x00, 0x00];
+ hmtx = [0x01, 0xF4, 0x00, 0x00];
for (var i = 0; i < charstrings.length; i++) {
+ // XXX this can easily broke
var charstring = charstrings[i].charstring;
var width = FontsUtils.integerToBytes(charstring[1], 2);
var lsb = FontsUtils.integerToBytes(charstring[0], 2);
hmtx = hmtx.concat(width, lsb);
}
-
- var tableEntry = this._createTableEntry("hmtx", virtualOffset, hmtx);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += hmtx.length;
-
+ this._createTableEntry(otf, offsets, "hmtx", hmtx);
/** MAXP */
-
- var maxp = [
- 0x00, 0x00, 0x50, 0x00, // Version number
- ].concat(FontsUtils.integerToBytes(charstrings.length + 1, 2)); // Num of glyphs (+1 to pass the sanitizer...)
-
- var tableEntry = this._createTableEntry("maxp", virtualOffset, maxp);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += maxp.length;
-
+ maxp = [].concat(
+ [
+ 0x00, 0x00, 0x50, 0x00, // Version number
+ ],
+ FontsUtils.integerToBytes(charstrings.length + 1, 2) // Num of glyphs (+1 to pass the sanitizer...)
+ );
+ this._createTableEntry(otf, offsets, "maxp", maxp);
/** NAME */
-
- var name = [
+ name = [
0x00, 0x00, // format
0x00, 0x00, // Number of names Record
- 0x00, 0x00 // Storage
+ 0x00, 0x00 // Storage
];
- var tableEntry = this._createTableEntry("name", virtualOffset, name);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += name.length;
-
+ this._createTableEntry(otf, offsets, "name", name);
/** POST */
-
// XXX get those info from the Font dict!
- var post = [
+ post = [
0x00, 0x03, 0x00, 0x00, // Version number
0x00, 0x00, 0x01, 0x00, // italicAngle
0x00, 0x00, // underlinePosition
0x00, 0x00, 0x00, 0x00, // minMemType1
0x00, 0x00, 0x00, 0x00 // maxMemType1
];
- var tableEntry = this._createTableEntry("post", virtualOffset, post);
- otf.set(tableEntry, currentOffset);
- currentOffset += tableEntry.length;
- virtualOffset += post.length;
-
- // Set the CFF data
- otf.set(aFontData, currentOffset);
- currentOffset += aFontData.length;
+ this._createTableEntry(otf, offsets, "post", post);
- var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post];
+ // Once all the table entry are written, this is time to dump the data!
+ var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
- otf.set(table, currentOffset);
- currentOffset += table.length;
+ otf.set(table, offsets.currentOffset);
+ offsets.currentOffset += table.length;
}
var fontData = [];
- for (var i = 0; i < currentOffset; i++)
+ for (var i = 0; i < offsets.currentOffset; i++)
fontData.push(otf[i]);
writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf");