'\x00\x01' + // encodingID
string32(4 + numTables * 8); // start of the table record
- var headerSize = (12 * 2 + (ranges.length * 5 * 2));
var segCount = ranges.length + 1;
var segCount2 = segCount * 2;
var searchRange = getMaxPower2(segCount) * 2;
var searchEntry = Math.log(segCount) / Math.log(2);
var rangeShift = 2 * segCount - searchRange;
- var format314 = '\x00\x04' + // format
- string16(headerSize) + // length
- '\x00\x00' + // language
- string16(segCount2) +
- string16(searchRange) +
- string16(searchEntry) +
- string16(rangeShift);
-
// Fill up the 4 parallel arrays describing the segments.
var startCount = '';
var endCount = '';
var range = ranges[i];
var start = range[0];
var end = range[1];
- var delta = (bias - start) % 0xffff;
+ var delta = (bias - start) & 0xffff;
bias += (end - start + 1);
startCount += string16(start);
startCount += '\xFF\xFF';
idDeltas += '\x00\x01';
idRangeOffsets += '\x00\x00';
- format314 += endCount + '\x00\x00' + startCount +
- idDeltas + idRangeOffsets + glyphsIds;
- return stringToArray(cmap + format314);
+ var format314 = '\x00\x00' + // language
+ string16(segCount2) +
+ string16(searchRange) +
+ string16(searchEntry) +
+ string16(rangeShift) +
+ endCount + '\x00\x00' + startCount +
+ idDeltas + idRangeOffsets + glyphsIds;
+
+ return stringToArray(cmap +
+ '\x00\x04' + // format
+ string16(format314.length + 4) + // length
+ format314);
};
function createOS2Table(properties) {
convert: function font_convert(fontName, font, properties) {
function createNameTable(name) {
- // All the strings of the name table should be an odd number
- // of bytes
- if (name.length % 2)
- name = name.slice(0, name.length - 1);
-
var strings = [
'Original licence', // 0.Copyright
name, // 1.Font family
'uniqueID', // 3.Unique ID
name, // 4.Full font name
'Version 0.11', // 5.Version
- 'Unknown', // 6.Postscript name
+ '', // 6.Postscript name
'Unknown', // 7.Trademark
'Unknown', // 8.Manufacturer
'Unknown' // 9.Designer
platforms[i] + // platform ID
encodings[i] + // encoding ID
languages[i] + // language ID
- string16(i) + // name ID
+ string16(j) + // name ID
string16(str.length) +
string16(strOffset);
nameTable += nameRecord;
return array;
};
+ function readNumber(str, index) {
+ while (str[index++] == ' ')
+ ;
+ var start = index;
+
+ var count = 0;
+ while (str[index++] != ' ')
+ count++;
+
+ return parseFloat(str.substr(start, count) || 0);
+ };
+
this.extractFontProgram = function t1_extractFontProgram(stream) {
var eexec = decrypt(stream, kEexecEncryptionKey, 4);
var eexecStr = '';
subrs: [],
charstrings: [],
properties: {
- stemSnapH: [0, 0],
- stemSnapV: [0, 0]
+ private: {}
}
};
case '/Subrs':
subrsSection = true;
break;
- case '/StdHW':
- program.properties.stdHW = readNumberArray(eexecStr, i + 2)[0];
+ case '/BlueValues':
+ case '/OtherBlues':
+ case '/FamilyBlues':
+ case '/FamilyOtherBlues':
+ case '/StemSnapH':
+ case '/StemSnapV':
+ program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2);
break;
+ case '/StdHW':
case '/StdVW':
- program.properties.stdVW = readNumberArray(eexecStr, i + 2)[0];
+ program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2)[0];
break;
- case '/StemSnapH':
- program.properties.stemSnapH = readNumberArray(eexecStr, i + 2);
- break;
- case '/StemSnapV':
- program.properties.stemSnapV = readNumberArray(eexecStr, i + 2);
+ case '/BlueShift':
+ case '/BlueFuzz':
+ case '/BlueScale':
+ case '/LanguageGroup':
+ case '/ExpansionFactor':
+ program.properties.private[token.substring(1)] = readNumber(eexecStr, i + 1);
break;
}
} else if (c == '/') {
return '\x1c' +
String.fromCharCode((value >> 8) & 0xFF) +
String.fromCharCode(value & 0xFF);
- } else if (value >= (-2147483647-1) && value <= 2147483647) {
+ } else if (value >= (-2147483648) && value <= 2147483647) {
return '\xff' +
String.fromCharCode((value >>> 24) & 0xFF) +
String.fromCharCode((value >> 16) & 0xFF) +
var dict =
'\x00\x01\x01\x01\x30' +
'\xf8\x1b\x00' + // version
- '\xf8\x1b\x01' + // Notice
- '\xf8\x1b\x02' + // FullName
- '\xf8\x1b\x03' + // FamilyName
- '\xf8\x1b\x04' + // Weight
+ '\xf8\x1c\x01' + // Notice
+ '\xf8\x1d\x02' + // FullName
+ '\xf8\x1e\x03' + // FamilyName
+ '\xf8\x1f\x04' + // Weight
'\x1c\x00\x00\x10'; // Encoding
var boundingBox = properties.bbox;
dict += self.encodeNumber(offset) + '\x11'; // Charstrings
dict += self.encodeNumber(fields.private.length);
- var offset = offset + fields.charstrings.length;
+ offset = offset + fields.charstrings.length;
dict += self.encodeNumber(offset) + '\x12'; // Private
return dict;
'private': (function(self) {
var data =
'\x8b\x14' + // defaultWidth
- '\x8b\x15' + // nominalWidth
- self.encodeNumber(properties.stdHW || 0) + '\x0a' + // StdHW
- self.encodeNumber(properties.stdVW || 0) + '\x0b'; // StdVW
-
- var stemH = properties.stemSnapH;
- for (var i = 0; i < stemH.length; i++)
- data += self.encodeNumber(stemH[i]);
- data += '\x0c\x0c'; // StemSnapH
-
- var stemV = properties.stemSnapV;
- for (var i = 0; i < stemV.length; i++)
- data += self.encodeNumber(stemV[i]);
- data += '\x0c\x0d'; // StemSnapV
+ '\x8b\x15'; // nominalWidth
+ var fieldMap = {
+ BlueValues: '\x06',
+ OtherBlues: '\x07',
+ FamilyBlues: '\x08',
+ FamilyOtherBlues: '\x09',
+ StemSnapH: '\x0c\x0c',
+ StemSnapV: '\x0c\x0d',
+ BlueShift: '\x0c\x0a',
+ BlueFuzz: '\x0c\x0b',
+ BlueScale: '\x0c\x09',
+ LanguageGroup: '\x0c\x11',
+ ExpansionFactor: '\x0c\x18'
+ };
+ for (var field in fieldMap) {
+ if (!properties.private.hasOwnProperty(field)) continue;
+ var value = properties.private[field];
+
+ if (IsArray(value)) {
+ data += self.encodeNumber(value[0]);
+ for (var i = 1; i < value.length; i++)
+ data += self.encodeNumber(value[i] - value[i - 1]);
+ } else {
+ data += self.encodeNumber(value);
+ }
+ data += fieldMap[field];
+ }
data += self.encodeNumber(data.length + 4) + '\x13'; // Subrs offset