CMAP creation code is now more readable
This commit is contained in:
parent
a8ce1d24e9
commit
65b8158c34
115
PDFFont.js
115
PDFFont.js
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user