|
|
@ -241,7 +241,77 @@ var Font = (function () { |
|
|
|
styleSheet.insertRule(rule, styleSheet.length); |
|
|
|
styleSheet.insertRule(rule, styleSheet.length); |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
_createCMAPTable: function font_createCMAPTable(aGlyphs) { |
|
|
|
convert: function font_convert(aFont, aProperties) { |
|
|
|
|
|
|
|
var otf = new Uint8Array(kMaxFontFileSize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function s2a(s) { |
|
|
|
|
|
|
|
var a = []; |
|
|
|
|
|
|
|
for (var i = 0; i < s.length; ++i) |
|
|
|
|
|
|
|
a[i] = s.charCodeAt(i); |
|
|
|
|
|
|
|
return a; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function s16(value) { |
|
|
|
|
|
|
|
return String.fromCharCode(value >> 8) + String.fromCharCode(value & 0xff); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createOpenTypeHeader(aFile, aOffsets, numTables) { |
|
|
|
|
|
|
|
var header = ""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sfnt version (4 bytes)
|
|
|
|
|
|
|
|
header += "\x4F\x54\x54\x4F"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// numTables (2 bytes)
|
|
|
|
|
|
|
|
header += s16(numTables); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// searchRange (2 bytes)
|
|
|
|
|
|
|
|
var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables); |
|
|
|
|
|
|
|
var searchRange = tablesMaxPower2 * 16; |
|
|
|
|
|
|
|
header += s16(searchRange); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// entrySelector (2 bytes)
|
|
|
|
|
|
|
|
header += s16(Math.log(tablesMaxPower2) / Math.log(2)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// rangeShift (2 bytes)
|
|
|
|
|
|
|
|
header += s16(numTables * 16 - searchRange); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
aFile.set(s2a(header), aOffsets.currentOffset); |
|
|
|
|
|
|
|
aOffsets.currentOffset += header.length; |
|
|
|
|
|
|
|
aOffsets.virtualOffset += header.length; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createTableEntry(aFile, aOffsets, aTag, aData) { |
|
|
|
|
|
|
|
// tag
|
|
|
|
|
|
|
|
var tag = [ |
|
|
|
|
|
|
|
aTag.charCodeAt(0), |
|
|
|
|
|
|
|
aTag.charCodeAt(1), |
|
|
|
|
|
|
|
aTag.charCodeAt(2), |
|
|
|
|
|
|
|
aTag.charCodeAt(3) |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// offset
|
|
|
|
|
|
|
|
var offset = aOffsets.virtualOffset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Per spec tables must be 4-bytes align so add some 0x00 if needed
|
|
|
|
|
|
|
|
while (aData.length & 3) |
|
|
|
|
|
|
|
aData.push(0x00); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// length
|
|
|
|
|
|
|
|
var length = aData.length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// checksum
|
|
|
|
|
|
|
|
var checksum = FontsUtils.bytesToInteger(tag) + offset + length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createCMAPTable(aGlyphs) { |
|
|
|
var characters = new Uint16Array(kMaxGlyphsCount); |
|
|
|
var characters = new Uint16Array(kMaxGlyphsCount); |
|
|
|
for (var i = 0; i < aGlyphs.length; i++) |
|
|
|
for (var i = 0; i < aGlyphs.length; i++) |
|
|
|
characters[aGlyphs[i].unicode] = i + 1; |
|
|
|
characters[aGlyphs[i].unicode] = i + 1; |
|
|
@ -321,76 +391,6 @@ var Font = (function () { |
|
|
|
|
|
|
|
|
|
|
|
return cmap.concat(endCount, [0x00, 0x00], startCount, |
|
|
|
return cmap.concat(endCount, [0x00, 0x00], startCount, |
|
|
|
idDeltas, idRangeOffsets, glyphsIdsArray); |
|
|
|
idDeltas, idRangeOffsets, glyphsIdsArray); |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
convert: function font_convert(aFont, aProperties) { |
|
|
|
|
|
|
|
var otf = new Uint8Array(kMaxFontFileSize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function s2a(s) { |
|
|
|
|
|
|
|
var a = []; |
|
|
|
|
|
|
|
for (var i = 0; i < s.length; ++i) |
|
|
|
|
|
|
|
a[i] = s.charCodeAt(i); |
|
|
|
|
|
|
|
return a; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function s16(value) { |
|
|
|
|
|
|
|
return String.fromCharCode(value >> 8) + String.fromCharCode(value & 0xff); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createOpenTypeHeader(aFile, aOffsets, numTables) { |
|
|
|
|
|
|
|
var header = ""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sfnt version (4 bytes)
|
|
|
|
|
|
|
|
header += "\x4F\x54\x54\x4F"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// numTables (2 bytes)
|
|
|
|
|
|
|
|
header += s16(numTables); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// searchRange (2 bytes)
|
|
|
|
|
|
|
|
var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables); |
|
|
|
|
|
|
|
var searchRange = tablesMaxPower2 * 16; |
|
|
|
|
|
|
|
header += s16(searchRange); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// entrySelector (2 bytes)
|
|
|
|
|
|
|
|
header += s16(Math.log(tablesMaxPower2) / Math.log(2)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// rangeShift (2 bytes)
|
|
|
|
|
|
|
|
header += s16(numTables * 16 - searchRange); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
aFile.set(s2a(header), aOffsets.currentOffset); |
|
|
|
|
|
|
|
aOffsets.currentOffset += header.length; |
|
|
|
|
|
|
|
aOffsets.virtualOffset += header.length; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createTableEntry(aFile, aOffsets, aTag, aData) { |
|
|
|
|
|
|
|
// tag
|
|
|
|
|
|
|
|
var tag = [ |
|
|
|
|
|
|
|
aTag.charCodeAt(0), |
|
|
|
|
|
|
|
aTag.charCodeAt(1), |
|
|
|
|
|
|
|
aTag.charCodeAt(2), |
|
|
|
|
|
|
|
aTag.charCodeAt(3) |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// offset
|
|
|
|
|
|
|
|
var offset = aOffsets.virtualOffset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Per spec tables must be 4-bytes align so add some 0x00 if needed
|
|
|
|
|
|
|
|
while (aData.length & 3) |
|
|
|
|
|
|
|
aData.push(0x00); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// length
|
|
|
|
|
|
|
|
var length = aData.length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// checksum
|
|
|
|
|
|
|
|
var checksum = FontsUtils.bytesToInteger(tag) + offset + length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Required Tables
|
|
|
|
// Required Tables
|
|
|
@ -469,7 +469,7 @@ var Font = (function () { |
|
|
|
var charstrings = aFont.getOrderedCharStrings(aProperties.glyphs); |
|
|
|
var charstrings = aFont.getOrderedCharStrings(aProperties.glyphs); |
|
|
|
|
|
|
|
|
|
|
|
/** CMAP */ |
|
|
|
/** CMAP */ |
|
|
|
cmap = this._createCMAPTable(charstrings); |
|
|
|
cmap = createCMAPTable(charstrings); |
|
|
|
createTableEntry(otf, offsets, "cmap", cmap); |
|
|
|
createTableEntry(otf, offsets, "cmap", cmap); |
|
|
|
|
|
|
|
|
|
|
|
/** HEAD */ |
|
|
|
/** HEAD */ |
|
|
|