CMAP creation code is now more readable

This commit is contained in:
Vivien Nicolas 2011-06-13 03:35:56 +02:00
parent a8ce1d24e9
commit 65b8158c34

View File

@ -147,6 +147,7 @@ Font.prototype = {
for (var i = 0; i < aGlyphs.length; i++) for (var i = 0; i < aGlyphs.length; i++)
data[aGlyphs[i].unicode] = i + 1; data[aGlyphs[i].unicode] = i + 1;
// Separate the glyphs into continuous range of codes, aka segment.
var ranges = []; var ranges = [];
var range = []; var range = [];
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
@ -164,80 +165,68 @@ Font.prototype = {
} }
var cmap = []; // The size in bytes of the header is equal to the size of the
var segCount = ranges.length + 1; // different fields * length of a short + (size of the 4 parallels arrays
// describing segments * length of a short).
var headerSize = (12 * 2 + (ranges.length * 4 * 2));
var segCount = ranges.length + 1;
var segCount2 = segCount * 2; var segCount2 = segCount * 2;
var searchRange = FontsUtils.getMaxPower2(segCount) * 2; var searchRange = FontsUtils.getMaxPower2(segCount) * 2;
var searchEntry = Math.log(segCount) / Math.log(2); var searchEntry = Math.log(segCount) / Math.log(2);
var rangeShift = 2 * segCount - searchRange; var rangeShift = 2 * segCount - searchRange;
cmap = cmap.concat(FontsUtils.integerToBytes(segCount2, 2)); var cmap = [].concat(
cmap = cmap.concat(FontsUtils.integerToBytes(searchRange, 2)); [
cmap = cmap.concat(FontsUtils.integerToBytes(searchEntry, 2)); 0x00, 0x00, // version
cmap = cmap.concat(FontsUtils.integerToBytes(rangeShift, 2)); 0x00, 0x01, // numTables
0x00, 0x03, // platformID
0x00, 0x01, // encodingID
0x00, 0x00, 0x00, 0x0C, // start of the table record
0x00, 0x04 // format
],
FontsUtils.integerToBytes(headerSize, 2), // length
[0x00, 0x00], // language
FontsUtils.integerToBytes(segCount2, 2),
FontsUtils.integerToBytes(searchRange, 2),
FontsUtils.integerToBytes(searchEntry, 2),
FontsUtils.integerToBytes(rangeShift, 2)
);
// End characters code with an additional 0xFFFF to finish the array // Fill up the 4 parallel arrays describing the segments.
for (var i = 0; i < ranges.length; i++) { var startCount = [];
var endCount = [];
var idDeltas = [];
var idRangeOffsets = [];
var glyphsIdsArray = [];
var bias = 0;
for (var i = 0; i < segCount - 1; i++) {
var range = ranges[i]; var range = ranges[i];
cmap = cmap.concat(FontsUtils.integerToBytes(range[range.length - 1], 2)); var start = FontsUtils.integerToBytes(range[0], 2);
}; var end = FontsUtils.integerToBytes(range[range.length - 1], 2);
cmap = cmap.concat([0xFF, 0xFF]);
// reserved pad var delta = FontsUtils.integerToBytes(((range[0] - 1) - bias) % 65536, 2);
cmap = cmap.concat([0x00, 0x00]); bias += range.length;
// Start characters code with an additional 0xFFFF to finish the array // deltas are signed shorts
for (var i = 0; i < ranges.length; i++) { delta[0] ^= 0xFF;
var range = ranges[i]; delta[1] ^= 0xFF;
cmap = cmap.concat(FontsUtils.integerToBytes(range[0], 2)); delta[1] += 1;
};
cmap = cmap.concat([0xFF, 0xFF]);
// Fill idDelta startCount.push(start[0], start[1]);
var delta = 0; endCount.push(end[0], end[1]);
var p = 0; idDeltas.push(delta[0], delta[1]);
for (var i = 0; i < ranges.length; i++) { idRangeOffsets.push(0x00, 0x00);
var range = ranges[i];
var start = range[0];
var delta = ((start - 1) - p) % 65536;
var value = FontsUtils.integerToBytes(delta, 2);
value[0] ^= 0xFF;
value[1] ^= 0xFF;
value[1] += 1;
cmap = cmap.concat([value[0], value[1]]);
p += range.length;
};
cmap = cmap.concat([0x00, 0x01]);
// Fill id Offsets with 0x00
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
cmap = cmap.concat([0x00, 0x00]);
};
cmap = cmap.concat([0x00, 0x00]);
var cmapHeader = [
0x00, 0x00, // version
0x00, 0x01, // numTables
0x00, 0x03, // platformID
0x00, 0x01, // encodingID
0x00, 0x00, 0x00, 0x0C, // start of the table record
0x00, 0x04 // format
];
cmapHeader = cmapHeader.concat(FontsUtils.integerToBytes(cmap.length + 6, 2)); // length
cmapHeader = cmapHeader.concat(0x00, 0x00); // language
// Fill up data!
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
for (var j = 0; j < range.length; j++) for (var j = 0; j < range.length; j++)
cmap = cmap.concat(range[j]); glyphsIdsArray.push(range[j]);
}; }
cmap = cmapHeader.concat(cmap); startCount.push(0xFF, 0xFF);
return cmap; endCount.push(0xFF, 0xFF);
idDeltas.push(0x00, 0x01);
idRangeOffsets.push(0x00, 0x00);
return cmap.concat(endCount, [0x00, 0x00], startCount,
idDeltas, idRangeOffsets, glyphsIdsArray);
}, },
cover: function font_cover(aFont) { cover: function font_cover(aFont) {
@ -442,7 +431,7 @@ Font.prototype = {
for (var i = 0; i < currentOffset; i++) for (var i = 0; i < currentOffset; i++)
fontData.push(otf[i]); fontData.push(otf[i]);
//writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf");
return fontData; return fontData;
} }
}; };