// First 2 bytes contains the number of objects contained into this index
var count = aObjects.length;
+ if (count ==0)
+ return [0x00, 0x00, 0x00];
+
var bytes = this.integerToBytes(count, 2);
for (var i = 0; i < bytes.length; i++)
data.push(bytes[i]);
for (var i =0; i < count; i++) {
for (var j = 0; j < aObjects[i].length; j++)
- data.push(aIsByte ? aObjects[i][j] : aObjects[i][j].charCodeAt(0));
+ data.push(aIsByte ? aObjects[i][j] : aObjects[i].charCodeAt(j));
}
return data;
},
encodeNumber: function(aValue) {
var x = 0;
- if (aValue >= -107 && aValue <= 107) {
- return [aValue + 139];
- } else if (aValue >= 108 && aValue <= 1131) {
- x = aValue - 108;
- return [
- this.integerToBytes(x / 256 + 247, 1),
- x % 256
- ];
- } else if (aValue >= -1131 && aValue <= -108) {
- x = Math.abs(aValue) - 108;
- return [
- this.integerToBytes(x / 256 + 251, 1),
- x % 256
- ];
- } else if (aValue >= -32768 && aValue <= 32767) {
+ // XXX we don't really care about Type2 optimization here...
+ if (aValue >= -32768 && aValue <= 32767) {
return [
28,
- integerToBytes(aValue >> 8, 1),
- integerToBytes(aValue, 1)
+ this.integerToBytes(aValue >> 8, 1),
+ this.integerToBytes(aValue, 1)
];
} else if (aValue >= (-2147483647-1) && aValue <= 2147483647) {
return [
0xFF,
- integerToBytes(aValue >> 24, 1),
- integerToBytes(aValue >> 16, 1),
- integerToBytes(aValue >> 8, 1),
- integerToBytes(aValue, 1)
+ this.integerToBytes(aValue >> 24, 1),
+ this.integerToBytes(aValue >> 16, 1),
+ this.integerToBytes(aValue >> 8, 1),
+ this.integerToBytes(aValue, 1)
];
} else {
error("Value: " + aValue + " is not allowed");
var charstrings = aFont.get("CharStrings")
var defaultWidth = this.getDefaultWidth(charstrings);
- log("defaultWidth to used: " + defaultWidth);
-
var charstringsCount = 0;
var charstringsDataLength = 0;
-
var glyphs = {};
var subrs = aFont.get("Private").get("Subrs");
var parser = new Type1Parser();
charstringsCount++;
charstringsDataLength += glyphs[glyph].length;
}
-
log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")");
// Create a CFF font data
cff.set(nameIndex, currentOffset);
currentOffset += nameIndex.length;
- //Top Dict Index
- var topDictIndex = [
- 0x00, 0x01, 0x01, 0x01, 0x2A,
- 248, 27, 0, // version
- 248, 28, 1, // Notice
- 248, 29, 2, // FullName
- 248, 30, 3, // FamilyName
- 248, 20, 4, // Weigth
- 82, 251, 98, 250, 105, 249, 72, 5, // FontBBox
- 248, 136, 15, // charset (offset: 500)
- 28, 0, 0, 16, // Encoding
- 28, 7, 208, 17, // CharStrings (offset: 2000)
- 28, 0, 55, 28, 39, 16, 18 // Private (offset: 10000)
- ];
- cff.set(topDictIndex, currentOffset);
- currentOffset += topDictIndex.length;
-
- // Strings Index
- var stringsIndex = [
- 0x00, 0x04, 0x01,
- 0x01, 0x05, 0x06, 0x07, 0x08,
- 0x31, 0x2E, 0x030, 0x35, // 1.05
- 0x2B, // +
- 0x28, // (
- 0x29 // )
- ];
- cff.set(stringsIndex, currentOffset);
- currentOffset += stringsIndex.length;
-
-
- // Global Subrs Index
- var globalSubrsIndex = [
- 0x00, 0x00, 0x00
- ];
- cff.set(globalSubrsIndex, currentOffset);
- currentOffset += globalSubrsIndex.length;
-
- // Fill the space between this and the charset by '1'
- var empty = new Array(500 - currentOffset);
- for (var i = 0; i < empty.length; i++)
- empty[i] = 0x01;
- cff.set(empty, currentOffset);
- currentOffset += empty.length;
-
- //Declare the letters
- var charset = [
- 0x00
- ];
- for (var glyph in charstrings.map) {
+ // Calculate strings before writing the TopDICT index in order
+ // to calculate correct relative offsets for storing 'charset'
+ // and 'charstrings' data
+ var fontInfo = aFont.get("FontInfo");
+ var version = fontInfo.get("version");
+ var notice = fontInfo.get("Notice");
+ var fullName = fontInfo.get("FullName");
+ var familyName = fontInfo.get("FamilyName");
+ var weight = fontInfo.get("Weight");
+ var strings = [version, notice, fullName,
+ familyName, weight];
+ var stringsIndex = this.createCFFIndexHeader(strings);
+ var stringsDataLength = stringsIndex.length;
+
+ // Create the global subroutines index
+ var globalSubrsIndex = this.createCFFIndexHeader([]);
+
+ // Fill the charset header (first byte is the encoding)
+ var charset = [0x00];
+ for (var glyph in glyphs) {
var index = CFFStrings.indexOf(glyph);
var bytes = this.integerToBytes(index, 2);
charset.push(bytes[0]);
charset.push(bytes[1]);
}
- cff.set(charset, currentOffset);
- currentOffset += charset.length;
-
- // Fill the space between this and the charstrings data by '1'
- var empty = new Array(2000 - currentOffset);
- for (var i = 0; i < empty.length; i++)
- empty[i] = 0x01;
- cff.set(empty, currentOffset);
- currentOffset += empty.length;
-
+ // Convert charstrings
var getNumFor = {
"hstem": 1,
"vstem": 3,
r.push(charstring);
}
- var charStringsIndex = this.createCFFIndexHeader(r, true);
- cff.set(charStringsIndex.join(" ").split(" "), currentOffset);
- currentOffset += charStringsIndex.length;
+ var charstringsIndex = this.createCFFIndexHeader(r, true);
+ charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why?
+
+
+ var fontBBox = aFont.get("FontBBox");
+
+ //Top Dict Index
+ var topDictIndex = [
+ 0x00, 0x01, 0x01, 0x01, 0x30,
+ 248, 27, 0, // version
+ 248, 28, 1, // Notice
+ 248, 29, 2, // FullName
+ 248, 30, 3, // FamilyName
+ 248, 31, 4, // Weight
+ ];
+
+ for (var i = 0; i < fontBBox.length; i++)
+ topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i]));
+ topDictIndex.push(5) // FontBBox;
+
+ var charsetOffset = currentOffset +
+ (topDictIndex.length + (4 + 4 + 4 + 7)) +
+ stringsIndex.length +
+ globalSubrsIndex.length;
+ topDictIndex = topDictIndex.concat(this.encodeNumber(charsetOffset));
+ topDictIndex.push(15); // charset
+
+ topDictIndex = topDictIndex.concat([28, 0, 0, 16]) // Encoding
+
+ var charstringsOffset = charsetOffset + (charstringsCount * 2) + 1;
+ topDictIndex = topDictIndex.concat(this.encodeNumber(charstringsOffset));
+ topDictIndex.push(17); // charstrings
+
+ topDictIndex = topDictIndex.concat([28, 0, 55])
+ var privateOffset = charstringsOffset + charstringsIndex.length;
+ topDictIndex = topDictIndex.concat(this.encodeNumber(privateOffset));
+ topDictIndex.push(18); // Private
+ topDictIndex = topDictIndex.join(" ").split(" ");
+
+ // Top Dict Index
+ cff.set(topDictIndex, currentOffset);
+ currentOffset += topDictIndex.length;
+
+ // Strings Index
+ cff.set(stringsIndex, currentOffset);
+ currentOffset += stringsIndex.length;
+
+ // Global Subrs Index
+ cff.set(globalSubrsIndex, currentOffset);
+ currentOffset += globalSubrsIndex.length;
+
+ // Charset Index
+ cff.set(charset, currentOffset);
+ currentOffset += charset.length;
- // Fill the space between this and the private dict data by '1'
- var empty = new Array(10000 - currentOffset);
- for (var i = 0; i < empty.length; i++)
- empty[i] = 0x01;
- cff.set(empty, currentOffset);
- currentOffset += empty.length;
+ // Fill charstrings data
+ cff.set(charstringsIndex, currentOffset);
+ currentOffset += charstringsIndex.length;
// Private Data
var privateData = [