Make Type1 glyphs use the default width they declare

This commit is contained in:
Vivien Nicolas 2011-06-15 09:21:59 +02:00
parent 3fbeeccb96
commit 0ad010ecbd

View File

@ -1375,10 +1375,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
* as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format',
* chapter 8. * chapter 8.
*/ */
this.flattenCharstring = function(aCharstring, aDefaultWidth, aSubrs) { this.flattenCharstring = function(aCharstring, aSubrs) {
operandStack.clear(); operandStack.clear();
executionStack.clear(); executionStack.clear();
executionStack.push(aCharstring); executionStack.push(aCharstring.slice());
var leftSidebearing = 0; var leftSidebearing = 0;
var lastPoint = 0; var lastPoint = 0;
@ -1392,24 +1392,13 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
switch (obj) { switch (obj) {
case "hsbw": case "hsbw":
var charWidthVector = operandStack.pop(); var charWidthVector = operandStack.pop();
leftSidebearing = operandStack.pop(); var leftSidebearing = operandStack.pop();
operandStack.push(charWidthVector);
if (charWidthVector != aDefaultWidth)
operandStack.push(charWidthVector - aDefaultWidth);
break;
case "rmoveto":
var dy = operandStack.pop();
var dx = operandStack.pop();
if (leftSidebearing) { if (leftSidebearing) {
dx += leftSidebearing; operandStack.push(leftSidebearing);
leftSidebearing = 0; operandStack.push("hmoveto");
} }
operandStack.push(dx);
operandStack.push(dy);
operandStack.push("rmoveto");
break; break;
case "div": case "div":
@ -1445,12 +1434,13 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
break; break;
case "callothersubr": case "callothersubr":
// XXX need to be improved
var index = operandStack.pop(); var index = operandStack.pop();
var count = operandStack.pop(); var count = operandStack.pop();
var data = operandStack.pop(); var data = operandStack.pop();
// XXX The callothersubr needs to support at least the 3 defaults
// otherSubrs of the spec
if (index != 3) if (index != 3)
dump("callothersubr for index: " + index); error("callothersubr for index: " + index);
operandStack.push(3); operandStack.push(3);
operandStack.push("callothersubr"); operandStack.push("callothersubr");
break; break;
@ -1490,25 +1480,6 @@ var CFF = function(aFontFile) {
}; };
CFF.prototype = { CFF.prototype = {
getDefaultWidth: function(aCharstrings) {
var defaultWidth = 0;
var defaultUsedCount = 0;
var widths = {};
for (var i = 0; i < aCharstrings.length; i++) {
var width = aCharstrings[i].charstring[1];
var usedCount = (widths[width] || 0) + 1;
if (usedCount > defaultUsedCount) {
defaultUsedCount = usedCount;
defaultWidth = width;
}
widths[width] = usedCount;
}
return parseInt(defaultWidth);
},
createCFFIndexHeader: function(aObjects, aIsByte) { createCFFIndexHeader: function(aObjects, aIsByte) {
var data = []; var data = [];
@ -1602,7 +1573,6 @@ CFF.prototype = {
}; };
var charstrings = this.getOrderedCharStrings(aFont); var charstrings = this.getOrderedCharStrings(aFont);
var defaultWidth = this.getDefaultWidth(charstrings);
var charstringsCount = 0; var charstringsCount = 0;
var charstringsDataLength = 0; var charstringsDataLength = 0;
@ -1617,7 +1587,7 @@ CFF.prototype = {
error("glyphs already exists!"); error("glyphs already exists!");
glyphsChecker[glyph] = true; glyphsChecker[glyph] = true;
var flattened = parser.flattenCharstring(charstring, defaultWidth, subrs); var flattened = parser.flattenCharstring(charstring, subrs);
glyphs.push(flattened); glyphs.push(flattened);
charstringsCount++; charstringsCount++;
charstringsDataLength += flattened.length; charstringsDataLength += flattened.length;
@ -1712,8 +1682,6 @@ CFF.prototype = {
charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why? charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why?
var fontBBox = aFont.get("FontBBox");
//Top Dict Index //Top Dict Index
var topDictIndex = [ var topDictIndex = [
0x00, 0x01, 0x01, 0x01, 0x30, 0x00, 0x01, 0x01, 0x01, 0x30,
@ -1724,6 +1692,7 @@ CFF.prototype = {
248, 31, 4 // Weight 248, 31, 4 // Weight
]; ];
var fontBBox = aFont.get("FontBBox");
for (var i = 0; i < fontBBox.length; i++) for (var i = 0; i < fontBBox.length; i++)
topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i])); topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i]));
topDictIndex.push(5) // FontBBox; topDictIndex.push(5) // FontBBox;
@ -1768,19 +1737,22 @@ CFF.prototype = {
currentOffset += charstringsIndex.length; currentOffset += charstringsIndex.length;
// Private Data // Private Data
var privateData = [ var defaultWidth = this.encodeNumber(0);
248, 136, 20, var privateData = [].concat(
248, 136, 21, defaultWidth, [20],
defaultWidth, [21],
[
119, 159, 248, 97, 159, 247, 87, 159, 6, 119, 159, 248, 97, 159, 247, 87, 159, 6,
30, 10, 3, 150, 37, 255, 12, 9, 30, 10, 3, 150, 37, 255, 12, 9,
139, 12, 10, 139, 12,
172, 10, 10, 172, 10,
172, 150, 143, 146, 150, 146, 12, 12, 172, 150, 143, 146, 150, 146, 12, 12,
247, 32, 11, 247, 32, 11,
247, 10, 161, 147, 154, 150, 143, 12, 13, 247, 10, 161, 147, 154, 150, 143, 12, 13,
139, 12, 14, 139, 12, 14,
28, 0, 55, 19 28, 0, 55, 19
]; ]);
privateData = privateData.join(" ").split(" ");
cff.set(privateData, currentOffset); cff.set(privateData, currentOffset);
currentOffset += privateData.length; currentOffset += privateData.length;