"hlineto": 6,
"vlineto": 7,
"rrcurveto": 8,
+ "callsubr": 10,
+ "return": 11,
"endchar": 14,
"rmoveto": 21,
"hmoveto": 22,
"hvcurveto": 31,
},
- flattenCharstring: function flattenCharstring(charstring, subrs) {
+ flattenCharstring: function flattenCharstring(charstring) {
var i = 0;
while (true) {
var obj = charstring[i];
if (obj.charAt) {
switch (obj) {
- case "callsubr":
- var subr = subrs[charstring[i - 1]];
- if (subr.length > 1) {
- subr = this.flattenCharstring(subr, subrs);
- subr.pop();
- charstring.splice(i - 1, 2, subr);
- } else {
- charstring.splice(i - 1, 2);
- }
- i -= 1;
- break;
-
case "callothersubr":
var index = charstring[i - 1];
var count = charstring[i - 2];
var data = charstring[i - 3];
- // XXX The callothersubr needs to support at least the 3 defaults
- // otherSubrs of the spec
- if (index != 3)
- error("callothersubr for index: " + index + " (" + charstring + ")");
-
- if (!data) {
- charstring.splice(i - 2, 4, "pop", 3);
- i -= 3;
- } else {
- // 5 to remove the arguments, the callothersubr call and the pop command
- charstring.splice(i - 3, 5, 3);
+ // If the flex mechanishm is not used in a font program, Adobe
+ // state that that entries 0, 1 and 2 can simply be replace by
+ // {}, which means that we can simply ignore them.
+ if (index < 3) {
i -= 3;
+ continue;
+ }
+
+ // This is the same things about hint replacment, if it is not used
+ // entry 3 can be replaced by {}
+ if (index == 3) {
+ if (!data) {
+ charstring.splice(i - 2, 4, "pop", 3);
+ i -= 3;
+ } else {
+ // 5 to remove the arguments, the callothersubr call and the pop command
+ charstring.splice(i - 3, 5, 3);
+ i -= 3;
+ }
}
break;
i -= 2;
break;
- case "pop":
- if (i)
- charstring.splice(i - 2, 2);
- else
- charstring.splice(i - 1, 1);
- i -= 1;
- break;
-
-
case "hsbw":
var charWidthVector = charstring[i - 1];
var leftSidebearing = charstring[i - 2];
var glyphsCount = charstrings.length;
for (var i = 0; i < glyphsCount; i++) {
var charstring = charstrings[i].charstring;
- glyphs.push(this.flattenCharstring(charstring.slice(), subrs));
+ glyphs.push(this.flattenCharstring(charstring.slice()));
}
// Create a CFF font data
247, 32, 11,
247, 10, 161, 147, 154, 150, 143, 12, 13,
139, 12, 14,
- 28, 0, 55, 19
+ 28, 0, 55, 19 // Subrs offset
]);
cff.set(privateData, currentOffset);
currentOffset += privateData.length;
- // Dump shit at the end of the file
- var shit = [
- 0x00, 0x01, 0x01, 0x01,
- 0x13, 0x5D, 0x65, 0x64,
- 0x5E, 0x5B, 0xAF, 0x66,
- 0xBA, 0xBB, 0xB1, 0xB0,
- 0xB9, 0xBA, 0x65, 0xB2,
- 0x5C, 0x1F, 0x0B
- ];
- cff.set(shit, currentOffset);
- currentOffset += shit.length;
+ // Local Subrs
+ var flattenedSubrs = [];
+
+ var bias = 0;
+ var subrsCount = subrs.length;
+ if (subrsCount < 1240)
+ bias = 107;
+ else if (subrsCount < 33900)
+ bias = 1131;
+ else
+ bias = 32768;
+
+ // Add a bunch of empty subrs to deal with the Type2 bias
+ for (var i = 0; i < bias; i++)
+ flattenedSubrs.push([0x0B]);
+
+ for (var i = 0; i < subrsCount; i++) {
+ var subr = subrs[i];
+ flattenedSubrs.push(this.flattenCharstring(subr));
+ }
+
+ var subrsData = this.createCFFIndexHeader(flattenedSubrs, true);
+ cff.set(subrsData, currentOffset);
+ currentOffset += subrsData.length;
var fontData = [];
for (var i = 0; i < currentOffset; i++)