|
|
@ -542,21 +542,12 @@ var Font = (function() { |
|
|
|
'\x00\x01' + // encodingID
|
|
|
|
'\x00\x01' + // encodingID
|
|
|
|
string32(4 + numTables * 8); // start of the table record
|
|
|
|
string32(4 + numTables * 8); // start of the table record
|
|
|
|
|
|
|
|
|
|
|
|
var headerSize = (12 * 2 + (ranges.length * 5 * 2)); |
|
|
|
|
|
|
|
var segCount = ranges.length + 1; |
|
|
|
var segCount = ranges.length + 1; |
|
|
|
var segCount2 = segCount * 2; |
|
|
|
var segCount2 = segCount * 2; |
|
|
|
var searchRange = getMaxPower2(segCount) * 2; |
|
|
|
var searchRange = 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; |
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
// Fill up the 4 parallel arrays describing the segments.
|
|
|
|
var startCount = ''; |
|
|
|
var startCount = ''; |
|
|
|
var endCount = ''; |
|
|
|
var endCount = ''; |
|
|
@ -568,7 +559,7 @@ var Font = (function() { |
|
|
|
var range = ranges[i]; |
|
|
|
var range = ranges[i]; |
|
|
|
var start = range[0]; |
|
|
|
var start = range[0]; |
|
|
|
var end = range[1]; |
|
|
|
var end = range[1]; |
|
|
|
var delta = (bias - start) % 0xffff; |
|
|
|
var delta = (bias - start) & 0xffff; |
|
|
|
bias += (end - start + 1); |
|
|
|
bias += (end - start + 1); |
|
|
|
|
|
|
|
|
|
|
|
startCount += string16(start); |
|
|
|
startCount += string16(start); |
|
|
@ -585,10 +576,19 @@ var Font = (function() { |
|
|
|
startCount += '\xFF\xFF'; |
|
|
|
startCount += '\xFF\xFF'; |
|
|
|
idDeltas += '\x00\x01'; |
|
|
|
idDeltas += '\x00\x01'; |
|
|
|
idRangeOffsets += '\x00\x00'; |
|
|
|
idRangeOffsets += '\x00\x00'; |
|
|
|
format314 += endCount + '\x00\x00' + startCount + |
|
|
|
|
|
|
|
|
|
|
|
var format314 = '\x00\x00' + // language
|
|
|
|
|
|
|
|
string16(segCount2) + |
|
|
|
|
|
|
|
string16(searchRange) + |
|
|
|
|
|
|
|
string16(searchEntry) + |
|
|
|
|
|
|
|
string16(rangeShift) + |
|
|
|
|
|
|
|
endCount + '\x00\x00' + startCount + |
|
|
|
idDeltas + idRangeOffsets + glyphsIds; |
|
|
|
idDeltas + idRangeOffsets + glyphsIds; |
|
|
|
|
|
|
|
|
|
|
|
return stringToArray(cmap + format314); |
|
|
|
return stringToArray(cmap + |
|
|
|
|
|
|
|
'\x00\x04' + // format
|
|
|
|
|
|
|
|
string16(format314.length + 4) + // length
|
|
|
|
|
|
|
|
format314); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
function createOS2Table(properties) { |
|
|
|
function createOS2Table(properties) { |
|
|
@ -907,11 +907,6 @@ var Font = (function() { |
|
|
|
|
|
|
|
|
|
|
|
convert: function font_convert(fontName, font, properties) { |
|
|
|
convert: function font_convert(fontName, font, properties) { |
|
|
|
function createNameTable(name) { |
|
|
|
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 = [ |
|
|
|
var strings = [ |
|
|
|
'Original licence', // 0.Copyright
|
|
|
|
'Original licence', // 0.Copyright
|
|
|
|
name, // 1.Font family
|
|
|
|
name, // 1.Font family
|
|
|
@ -919,7 +914,7 @@ var Font = (function() { |
|
|
|
'uniqueID', // 3.Unique ID
|
|
|
|
'uniqueID', // 3.Unique ID
|
|
|
|
name, // 4.Full font name
|
|
|
|
name, // 4.Full font name
|
|
|
|
'Version 0.11', // 5.Version
|
|
|
|
'Version 0.11', // 5.Version
|
|
|
|
'Unknown', // 6.Postscript name
|
|
|
|
'', // 6.Postscript name
|
|
|
|
'Unknown', // 7.Trademark
|
|
|
|
'Unknown', // 7.Trademark
|
|
|
|
'Unknown', // 8.Manufacturer
|
|
|
|
'Unknown', // 8.Manufacturer
|
|
|
|
'Unknown' // 9.Designer
|
|
|
|
'Unknown' // 9.Designer
|
|
|
@ -958,7 +953,7 @@ var Font = (function() { |
|
|
|
platforms[i] + // platform ID
|
|
|
|
platforms[i] + // platform ID
|
|
|
|
encodings[i] + // encoding ID
|
|
|
|
encodings[i] + // encoding ID
|
|
|
|
languages[i] + // language ID
|
|
|
|
languages[i] + // language ID
|
|
|
|
string16(i) + // name ID
|
|
|
|
string16(j) + // name ID
|
|
|
|
string16(str.length) + |
|
|
|
string16(str.length) + |
|
|
|
string16(strOffset); |
|
|
|
string16(strOffset); |
|
|
|
nameTable += nameRecord; |
|
|
|
nameTable += nameRecord; |
|
|
@ -1394,6 +1389,18 @@ var Type1Parser = function() { |
|
|
|
return array; |
|
|
|
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) { |
|
|
|
this.extractFontProgram = function t1_extractFontProgram(stream) { |
|
|
|
var eexec = decrypt(stream, kEexecEncryptionKey, 4); |
|
|
|
var eexec = decrypt(stream, kEexecEncryptionKey, 4); |
|
|
|
var eexecStr = ''; |
|
|
|
var eexecStr = ''; |
|
|
@ -1405,8 +1412,7 @@ var Type1Parser = function() { |
|
|
|
subrs: [], |
|
|
|
subrs: [], |
|
|
|
charstrings: [], |
|
|
|
charstrings: [], |
|
|
|
properties: { |
|
|
|
properties: { |
|
|
|
stemSnapH: [0, 0], |
|
|
|
'private': {} |
|
|
|
stemSnapV: [0, 0] |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -1448,17 +1454,24 @@ var Type1Parser = function() { |
|
|
|
case '/Subrs': |
|
|
|
case '/Subrs': |
|
|
|
subrsSection = true; |
|
|
|
subrsSection = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case '/StdHW': |
|
|
|
case '/BlueValues': |
|
|
|
program.properties.stdHW = readNumberArray(eexecStr, i + 2)[0]; |
|
|
|
case '/OtherBlues': |
|
|
|
|
|
|
|
case '/FamilyBlues': |
|
|
|
|
|
|
|
case '/FamilyOtherBlues': |
|
|
|
|
|
|
|
case '/StemSnapH': |
|
|
|
|
|
|
|
case '/StemSnapV': |
|
|
|
|
|
|
|
program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case '/StdHW': |
|
|
|
case '/StdVW': |
|
|
|
case '/StdVW': |
|
|
|
program.properties.stdVW = readNumberArray(eexecStr, i + 2)[0]; |
|
|
|
program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2)[0]; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case '/StemSnapH': |
|
|
|
case '/BlueShift': |
|
|
|
program.properties.stemSnapH = readNumberArray(eexecStr, i + 2); |
|
|
|
case '/BlueFuzz': |
|
|
|
break; |
|
|
|
case '/BlueScale': |
|
|
|
case '/StemSnapV': |
|
|
|
case '/LanguageGroup': |
|
|
|
program.properties.stemSnapV = readNumberArray(eexecStr, i + 2); |
|
|
|
case '/ExpansionFactor': |
|
|
|
|
|
|
|
program.properties.private[token.substring(1)] = readNumber(eexecStr, i + 1); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (c == '/') { |
|
|
|
} else if (c == '/') { |
|
|
@ -1648,7 +1661,7 @@ CFF.prototype = { |
|
|
|
return '\x1c' + |
|
|
|
return '\x1c' + |
|
|
|
String.fromCharCode((value >> 8) & 0xFF) + |
|
|
|
String.fromCharCode((value >> 8) & 0xFF) + |
|
|
|
String.fromCharCode(value & 0xFF); |
|
|
|
String.fromCharCode(value & 0xFF); |
|
|
|
} else if (value >= (-2147483647-1) && value <= 2147483647) { |
|
|
|
} else if (value >= (-2147483648) && value <= 2147483647) { |
|
|
|
return '\xff' + |
|
|
|
return '\xff' + |
|
|
|
String.fromCharCode((value >>> 24) & 0xFF) + |
|
|
|
String.fromCharCode((value >>> 24) & 0xFF) + |
|
|
|
String.fromCharCode((value >> 16) & 0xFF) + |
|
|
|
String.fromCharCode((value >> 16) & 0xFF) + |
|
|
@ -1775,10 +1788,10 @@ CFF.prototype = { |
|
|
|
var dict = |
|
|
|
var dict = |
|
|
|
'\x00\x01\x01\x01\x30' + |
|
|
|
'\x00\x01\x01\x01\x30' + |
|
|
|
'\xf8\x1b\x00' + // version
|
|
|
|
'\xf8\x1b\x00' + // version
|
|
|
|
'\xf8\x1b\x01' + // Notice
|
|
|
|
'\xf8\x1c\x01' + // Notice
|
|
|
|
'\xf8\x1b\x02' + // FullName
|
|
|
|
'\xf8\x1d\x02' + // FullName
|
|
|
|
'\xf8\x1b\x03' + // FamilyName
|
|
|
|
'\xf8\x1e\x03' + // FamilyName
|
|
|
|
'\xf8\x1b\x04' + // Weight
|
|
|
|
'\xf8\x1f\x04' + // Weight
|
|
|
|
'\x1c\x00\x00\x10'; // Encoding
|
|
|
|
'\x1c\x00\x00\x10'; // Encoding
|
|
|
|
|
|
|
|
|
|
|
|
var boundingBox = properties.bbox; |
|
|
|
var boundingBox = properties.bbox; |
|
|
@ -1797,7 +1810,7 @@ CFF.prototype = { |
|
|
|
dict += self.encodeNumber(offset) + '\x11'; // Charstrings
|
|
|
|
dict += self.encodeNumber(offset) + '\x11'; // Charstrings
|
|
|
|
|
|
|
|
|
|
|
|
dict += self.encodeNumber(fields.private.length); |
|
|
|
dict += self.encodeNumber(fields.private.length); |
|
|
|
var offset = offset + fields.charstrings.length; |
|
|
|
offset = offset + fields.charstrings.length; |
|
|
|
dict += self.encodeNumber(offset) + '\x12'; // Private
|
|
|
|
dict += self.encodeNumber(offset) + '\x12'; // Private
|
|
|
|
|
|
|
|
|
|
|
|
return dict; |
|
|
|
return dict; |
|
|
@ -1841,19 +1854,33 @@ CFF.prototype = { |
|
|
|
'private': (function(self) { |
|
|
|
'private': (function(self) { |
|
|
|
var data = |
|
|
|
var data = |
|
|
|
'\x8b\x14' + // defaultWidth
|
|
|
|
'\x8b\x14' + // defaultWidth
|
|
|
|
'\x8b\x15' + // nominalWidth
|
|
|
|
'\x8b\x15'; // nominalWidth
|
|
|
|
self.encodeNumber(properties.stdHW || 0) + '\x0a' + // StdHW
|
|
|
|
var fieldMap = { |
|
|
|
self.encodeNumber(properties.stdVW || 0) + '\x0b'; // StdVW
|
|
|
|
BlueValues: '\x06', |
|
|
|
|
|
|
|
OtherBlues: '\x07', |
|
|
|
var stemH = properties.stemSnapH; |
|
|
|
FamilyBlues: '\x08', |
|
|
|
for (var i = 0; i < stemH.length; i++) |
|
|
|
FamilyOtherBlues: '\x09', |
|
|
|
data += self.encodeNumber(stemH[i]); |
|
|
|
StemSnapH: '\x0c\x0c', |
|
|
|
data += '\x0c\x0c'; // StemSnapH
|
|
|
|
StemSnapV: '\x0c\x0d', |
|
|
|
|
|
|
|
BlueShift: '\x0c\x0a', |
|
|
|
var stemV = properties.stemSnapV; |
|
|
|
BlueFuzz: '\x0c\x0b', |
|
|
|
for (var i = 0; i < stemV.length; i++) |
|
|
|
BlueScale: '\x0c\x09', |
|
|
|
data += self.encodeNumber(stemV[i]); |
|
|
|
LanguageGroup: '\x0c\x11', |
|
|
|
data += '\x0c\x0d'; // StemSnapV
|
|
|
|
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
|
|
|
|
data += self.encodeNumber(data.length + 4) + '\x13'; // Subrs offset
|
|
|
|
|
|
|
|
|
|
|
|