|
|
|
@ -688,19 +688,22 @@ var MacStandardGlyphOrdering = [
@@ -688,19 +688,22 @@ var MacStandardGlyphOrdering = [
|
|
|
|
|
function getUnicodeRangeFor(value) { |
|
|
|
|
for (var i = 0, ii = UnicodeRanges.length; i < ii; i++) { |
|
|
|
|
var range = UnicodeRanges[i]; |
|
|
|
|
if (value >= range.begin && value < range.end) |
|
|
|
|
if (value >= range.begin && value < range.end) { |
|
|
|
|
return i; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function isRTLRangeFor(value) { |
|
|
|
|
var range = UnicodeRanges[13]; |
|
|
|
|
if (value >= range.begin && value < range.end) |
|
|
|
|
if (value >= range.begin && value < range.end) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
range = UnicodeRanges[11]; |
|
|
|
|
if (value >= range.begin && value < range.end) |
|
|
|
|
if (value >= range.begin && value < range.end) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2089,12 +2092,13 @@ var NormalizedUnicodes = {
@@ -2089,12 +2092,13 @@ var NormalizedUnicodes = {
|
|
|
|
|
function reverseIfRtl(chars) { |
|
|
|
|
var charsLength = chars.length; |
|
|
|
|
//reverse an arabic ligature
|
|
|
|
|
if (charsLength <= 1 || !isRTLRangeFor(chars.charCodeAt(0))) |
|
|
|
|
if (charsLength <= 1 || !isRTLRangeFor(chars.charCodeAt(0))) { |
|
|
|
|
return chars; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
var s = ''; |
|
|
|
|
for (var ii = charsLength - 1; ii >= 0; ii--) |
|
|
|
|
for (var ii = charsLength - 1; ii >= 0; ii--) { |
|
|
|
|
s += chars[ii]; |
|
|
|
|
} |
|
|
|
|
return s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2103,12 +2107,13 @@ function fontCharsToUnicode(charCodes, font) {
@@ -2103,12 +2107,13 @@ function fontCharsToUnicode(charCodes, font) {
|
|
|
|
|
var result = ''; |
|
|
|
|
for (var i = 0, ii = glyphs.length; i < ii; i++) { |
|
|
|
|
var glyph = glyphs[i]; |
|
|
|
|
if (!glyph) |
|
|
|
|
if (!glyph) { |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
var glyphUnicode = glyph.unicode; |
|
|
|
|
if (glyphUnicode in NormalizedUnicodes) |
|
|
|
|
if (glyphUnicode in NormalizedUnicodes) { |
|
|
|
|
glyphUnicode = NormalizedUnicodes[glyphUnicode]; |
|
|
|
|
} |
|
|
|
|
result += reverseIfRtl(glyphUnicode); |
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
@ -2179,8 +2184,8 @@ var Font = (function FontClosure() {
@@ -2179,8 +2184,8 @@ var Font = (function FontClosure() {
|
|
|
|
|
var type = properties.type; |
|
|
|
|
this.type = type; |
|
|
|
|
|
|
|
|
|
this.fallbackName = this.isMonospace ? 'monospace' : |
|
|
|
|
this.isSerifFont ? 'serif' : 'sans-serif'; |
|
|
|
|
this.fallbackName = (this.isMonospace ? 'monospace' : |
|
|
|
|
(this.isSerifFont ? 'serif' : 'sans-serif')); |
|
|
|
|
|
|
|
|
|
this.differences = properties.differences; |
|
|
|
|
this.widths = properties.widths; |
|
|
|
@ -2200,8 +2205,8 @@ var Font = (function FontClosure() {
@@ -2200,8 +2205,8 @@ var Font = (function FontClosure() {
|
|
|
|
|
|
|
|
|
|
if (properties.type == 'Type3') { |
|
|
|
|
for (var charCode = 0; charCode < 256; charCode++) { |
|
|
|
|
this.toFontChar[charCode] = this.differences[charCode] || |
|
|
|
|
properties.defaultEncoding[charCode]; |
|
|
|
|
this.toFontChar[charCode] = (this.differences[charCode] || |
|
|
|
|
properties.defaultEncoding[charCode]); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -2222,8 +2227,8 @@ var Font = (function FontClosure() {
@@ -2222,8 +2227,8 @@ var Font = (function FontClosure() {
|
|
|
|
|
fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName; |
|
|
|
|
|
|
|
|
|
this.bold = (fontName.search(/bold/gi) != -1); |
|
|
|
|
this.italic = (fontName.search(/oblique/gi) != -1) || |
|
|
|
|
(fontName.search(/italic/gi) != -1); |
|
|
|
|
this.italic = ((fontName.search(/oblique/gi) != -1) || |
|
|
|
|
(fontName.search(/italic/gi) != -1)); |
|
|
|
|
|
|
|
|
|
// Use 'name' instead of 'fontName' here because the original
|
|
|
|
|
// name ArialBlack for example will be replaced by Helvetica.
|
|
|
|
@ -2269,10 +2274,12 @@ var Font = (function FontClosure() {
@@ -2269,10 +2274,12 @@ var Font = (function FontClosure() {
|
|
|
|
|
|
|
|
|
|
// Some fonts might use wrong font types for Type1C or CIDFontType0C
|
|
|
|
|
var subtype = properties.subtype; |
|
|
|
|
if (subtype == 'Type1C' && (type != 'Type1' && type != 'MMType1')) |
|
|
|
|
if (subtype == 'Type1C' && (type != 'Type1' && type != 'MMType1')) { |
|
|
|
|
type = 'Type1'; |
|
|
|
|
if (subtype == 'CIDFontType0C' && type != 'CIDFontType0') |
|
|
|
|
} |
|
|
|
|
if (subtype == 'CIDFontType0C' && type != 'CIDFontType0') { |
|
|
|
|
type = 'CIDFontType0'; |
|
|
|
|
} |
|
|
|
|
// XXX: Temporarily change the type for open type so we trigger a warning.
|
|
|
|
|
// This should be removed when we add support for open type.
|
|
|
|
|
if (subtype === 'OpenType') { |
|
|
|
@ -2323,9 +2330,9 @@ var Font = (function FontClosure() {
@@ -2323,9 +2330,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
|
|
|
|
|
function stringToArray(str) { |
|
|
|
|
var array = []; |
|
|
|
|
for (var i = 0, ii = str.length; i < ii; ++i) |
|
|
|
|
for (var i = 0, ii = str.length; i < ii; ++i) { |
|
|
|
|
array[i] = str.charCodeAt(i); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
return array; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2354,34 +2361,36 @@ var Font = (function FontClosure() {
@@ -2354,34 +2361,36 @@ var Font = (function FontClosure() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
value = 2; |
|
|
|
|
for (var i = 1; i < maxPower; i++) |
|
|
|
|
for (var i = 1; i < maxPower; i++) { |
|
|
|
|
value *= 2; |
|
|
|
|
} |
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function string16(value) { |
|
|
|
|
return String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff); |
|
|
|
|
return (String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function safeString16(value) { |
|
|
|
|
// clamp value to the 16-bit int range
|
|
|
|
|
value = value > 0x7FFF ? 0x7FFF : value < -0x8000 ? -0x8000 : value; |
|
|
|
|
return String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff); |
|
|
|
|
value = (value > 0x7FFF ? 0x7FFF : (value < -0x8000 ? -0x8000 : value)); |
|
|
|
|
return (String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function string32(value) { |
|
|
|
|
return String.fromCharCode((value >> 24) & 0xff) + |
|
|
|
|
String.fromCharCode((value >> 16) & 0xff) + |
|
|
|
|
String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff); |
|
|
|
|
return (String.fromCharCode((value >> 24) & 0xff) + |
|
|
|
|
String.fromCharCode((value >> 16) & 0xff) + |
|
|
|
|
String.fromCharCode((value >> 8) & 0xff) + |
|
|
|
|
String.fromCharCode(value & 0xff)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function createOpenTypeHeader(sfnt, file, numTables) { |
|
|
|
|
// Windows hates the Mac TrueType sfnt version number
|
|
|
|
|
if (sfnt == 'true') |
|
|
|
|
if (sfnt == 'true') { |
|
|
|
|
sfnt = string32(0x00010000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// sfnt version (4 bytes)
|
|
|
|
|
var header = sfnt; |
|
|
|
@ -2412,17 +2421,19 @@ var Font = (function FontClosure() {
@@ -2412,17 +2421,19 @@ var Font = (function FontClosure() {
|
|
|
|
|
var length = data.length; |
|
|
|
|
|
|
|
|
|
// Per spec tables must be 4-bytes align so add padding as needed
|
|
|
|
|
while (data.length & 3) |
|
|
|
|
while (data.length & 3) { |
|
|
|
|
data.push(0x00); |
|
|
|
|
|
|
|
|
|
while (file.virtualOffset & 3) |
|
|
|
|
} |
|
|
|
|
while (file.virtualOffset & 3) { |
|
|
|
|
file.virtualOffset++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// checksum
|
|
|
|
|
var checksum = 0, n = data.length; |
|
|
|
|
for (var i = 0; i < n; i += 4) |
|
|
|
|
for (var i = 0; i < n; i += 4) { |
|
|
|
|
checksum = (checksum + int32(data[i], data[i + 1], data[i + 2], |
|
|
|
|
data[i + 3])) | 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var tableEntry = (tag + string32(checksum) + |
|
|
|
|
string32(offset) + string32(length)); |
|
|
|
@ -2521,7 +2532,9 @@ var Font = (function FontClosure() {
@@ -2521,7 +2532,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
codeIndices.push(codes[n].glyphId); |
|
|
|
|
++end; |
|
|
|
|
++n; |
|
|
|
|
if (end === 0xFFFF) { break; } |
|
|
|
|
if (end === 0xFFFF) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ranges.push([start, end, codeIndices]); |
|
|
|
|
} |
|
|
|
@ -2694,10 +2707,12 @@ var Font = (function FontClosure() {
@@ -2694,10 +2707,12 @@ var Font = (function FontClosure() {
|
|
|
|
|
if (charstrings) { |
|
|
|
|
for (var code in charstrings) { |
|
|
|
|
code |= 0; |
|
|
|
|
if (firstCharIndex > code || !firstCharIndex) |
|
|
|
|
if (firstCharIndex > code || !firstCharIndex) { |
|
|
|
|
firstCharIndex = code; |
|
|
|
|
if (lastCharIndex < code) |
|
|
|
|
} |
|
|
|
|
if (lastCharIndex < code) { |
|
|
|
|
lastCharIndex = code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var position = getUnicodeRangeFor(code); |
|
|
|
|
if (position < 32) { |
|
|
|
@ -2719,18 +2734,18 @@ var Font = (function FontClosure() {
@@ -2719,18 +2734,18 @@ var Font = (function FontClosure() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var bbox = properties.bbox || [0, 0, 0, 0]; |
|
|
|
|
var unitsPerEm = override.unitsPerEm || |
|
|
|
|
1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]; |
|
|
|
|
var unitsPerEm = (override.unitsPerEm || |
|
|
|
|
1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]); |
|
|
|
|
|
|
|
|
|
// if the font units differ to the PDF glyph space units
|
|
|
|
|
// then scale up the values
|
|
|
|
|
var scale = properties.ascentScaled ? 1.0 : |
|
|
|
|
unitsPerEm / PDF_GLYPH_SPACE_UNITS; |
|
|
|
|
var scale = (properties.ascentScaled ? 1.0 : |
|
|
|
|
unitsPerEm / PDF_GLYPH_SPACE_UNITS); |
|
|
|
|
|
|
|
|
|
var typoAscent = override.ascent || Math.round(scale * |
|
|
|
|
(properties.ascent || bbox[3])); |
|
|
|
|
var typoDescent = override.descent || Math.round(scale * |
|
|
|
|
(properties.descent || bbox[1])); |
|
|
|
|
var typoAscent = (override.ascent || |
|
|
|
|
Math.round(scale * (properties.ascent || bbox[3]))); |
|
|
|
|
var typoDescent = (override.descent || |
|
|
|
|
Math.round(scale * (properties.descent || bbox[1]))); |
|
|
|
|
if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) { |
|
|
|
|
typoDescent = -typoDescent; // fixing incorrect descent
|
|
|
|
|
} |
|
|
|
@ -2781,15 +2796,15 @@ var Font = (function FontClosure() {
@@ -2781,15 +2796,15 @@ var Font = (function FontClosure() {
|
|
|
|
|
|
|
|
|
|
function createPostTable(properties) { |
|
|
|
|
var angle = Math.floor(properties.italicAngle * (Math.pow(2, 16))); |
|
|
|
|
return '\x00\x03\x00\x00' + // Version number
|
|
|
|
|
string32(angle) + // italicAngle
|
|
|
|
|
'\x00\x00' + // underlinePosition
|
|
|
|
|
'\x00\x00' + // underlineThickness
|
|
|
|
|
string32(properties.fixedPitch) + // isFixedPitch
|
|
|
|
|
'\x00\x00\x00\x00' + // minMemType42
|
|
|
|
|
'\x00\x00\x00\x00' + // maxMemType42
|
|
|
|
|
'\x00\x00\x00\x00' + // minMemType1
|
|
|
|
|
'\x00\x00\x00\x00'; // maxMemType1
|
|
|
|
|
return ('\x00\x03\x00\x00' + // Version number
|
|
|
|
|
string32(angle) + // italicAngle
|
|
|
|
|
'\x00\x00' + // underlinePosition
|
|
|
|
|
'\x00\x00' + // underlineThickness
|
|
|
|
|
string32(properties.fixedPitch) + // isFixedPitch
|
|
|
|
|
'\x00\x00\x00\x00' + // minMemType42
|
|
|
|
|
'\x00\x00\x00\x00' + // maxMemType42
|
|
|
|
|
'\x00\x00\x00\x00' + // minMemType1
|
|
|
|
|
'\x00\x00\x00\x00'); // maxMemType1
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function createNameTable(name, proto) { |
|
|
|
@ -2869,8 +2884,9 @@ var Font = (function FontClosure() {
@@ -2869,8 +2884,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
exportData: function Font_exportData() { |
|
|
|
|
var data = {}; |
|
|
|
|
for (var i in this) { |
|
|
|
|
if (this.hasOwnProperty(i)) |
|
|
|
|
if (this.hasOwnProperty(i)) { |
|
|
|
|
data[i] = this[i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return data; |
|
|
|
|
}, |
|
|
|
@ -3024,7 +3040,7 @@ var Font = (function FontClosure() {
@@ -3024,7 +3040,7 @@ var Font = (function FontClosure() {
|
|
|
|
|
var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex); |
|
|
|
|
segment.offsetIndex = offsetIndex; |
|
|
|
|
offsetsCount = Math.max(offsetsCount, offsetIndex + |
|
|
|
|
segment.end - segment.start + 1); |
|
|
|
|
segment.end - segment.start + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var offsets = []; |
|
|
|
@ -3042,8 +3058,8 @@ var Font = (function FontClosure() {
@@ -3042,8 +3058,8 @@ var Font = (function FontClosure() {
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var glyphId = offsetIndex < 0 ? j : |
|
|
|
|
offsets[offsetIndex + j - start]; |
|
|
|
|
var glyphId = (offsetIndex < 0 ? |
|
|
|
|
j : offsets[offsetIndex + j - start]); |
|
|
|
|
glyphId = (glyphId + delta) & 0xFFFF; |
|
|
|
|
if (glyphId === 0) { |
|
|
|
|
continue; |
|
|
|
@ -3125,10 +3141,12 @@ var Font = (function FontClosure() {
@@ -3125,10 +3141,12 @@ var Font = (function FontClosure() {
|
|
|
|
|
if (numMissing > 0) { |
|
|
|
|
font.pos = (font.start ? font.start : 0) + metrics.offset; |
|
|
|
|
var entries = ''; |
|
|
|
|
for (var i = 0, ii = metrics.length; i < ii; i++) |
|
|
|
|
for (var i = 0, ii = metrics.length; i < ii; i++) { |
|
|
|
|
entries += String.fromCharCode(font.getByte()); |
|
|
|
|
for (var i = 0; i < numMissing; i++) |
|
|
|
|
} |
|
|
|
|
for (var i = 0; i < numMissing; i++) { |
|
|
|
|
entries += '\x00\x00'; |
|
|
|
|
} |
|
|
|
|
metrics.data = stringToArray(entries); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -3318,8 +3336,9 @@ var Font = (function FontClosure() {
@@ -3318,8 +3336,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
// to have single glyph with one point
|
|
|
|
|
var simpleGlyph = new Uint8Array( |
|
|
|
|
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); |
|
|
|
|
for (var i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) |
|
|
|
|
for (var i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { |
|
|
|
|
itemEncode(locaData, j, simpleGlyph.length); |
|
|
|
|
} |
|
|
|
|
glyf.data = simpleGlyph; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -3590,7 +3609,9 @@ var Font = (function FontClosure() {
@@ -3590,7 +3609,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
if (!inFDEF && !inELSE) { |
|
|
|
|
var offset = stack[stack.length - 1]; |
|
|
|
|
// only jumping forward to prevent infinite loop
|
|
|
|
|
if (offset > 0) { i += offset - 1; } |
|
|
|
|
if (offset > 0) { |
|
|
|
|
i += offset - 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Adjusting stack not extactly, but just enough to get function id
|
|
|
|
@ -3704,7 +3725,7 @@ var Font = (function FontClosure() {
@@ -3704,7 +3725,7 @@ var Font = (function FontClosure() {
|
|
|
|
|
var numTables = header.numTables; |
|
|
|
|
|
|
|
|
|
var tables = { 'OS/2': null, cmap: null, head: null, hhea: null, |
|
|
|
|
hmtx: null, maxp: null, name: null, post: null}; |
|
|
|
|
hmtx: null, maxp: null, name: null, post: null }; |
|
|
|
|
for (var i = 0; i < numTables; i++) { |
|
|
|
|
var table = readTableEntry(font); |
|
|
|
|
if (VALID_TABLES.indexOf(table.tag) < 0) { |
|
|
|
@ -4004,8 +4025,9 @@ var Font = (function FontClosure() {
@@ -4004,8 +4025,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
var data = []; |
|
|
|
|
|
|
|
|
|
var tableData = table.data; |
|
|
|
|
for (var j = 0, jj = tableData.length; j < jj; j++) |
|
|
|
|
for (var j = 0, jj = tableData.length; j < jj; j++) { |
|
|
|
|
data.push(tableData[j]); |
|
|
|
|
} |
|
|
|
|
createTableEntry(ttf, table.tag, data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4016,8 +4038,9 @@ var Font = (function FontClosure() {
@@ -4016,8 +4038,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
ttf.file += arrayToString(tableData); |
|
|
|
|
|
|
|
|
|
// 4-byte aligned data
|
|
|
|
|
while (ttf.file.length & 3) |
|
|
|
|
while (ttf.file.length & 3) { |
|
|
|
|
ttf.file += String.fromCharCode(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return stringToArray(ttf.file); |
|
|
|
@ -4097,46 +4120,46 @@ var Font = (function FontClosure() {
@@ -4097,46 +4120,46 @@ var Font = (function FontClosure() {
|
|
|
|
|
// Font header
|
|
|
|
|
'head': (function fontFieldsHead() { |
|
|
|
|
return stringToArray( |
|
|
|
|
'\x00\x01\x00\x00' + // Version number
|
|
|
|
|
'\x00\x00\x10\x00' + // fontRevision
|
|
|
|
|
'\x00\x00\x00\x00' + // checksumAdjustement
|
|
|
|
|
'\x5F\x0F\x3C\xF5' + // magicNumber
|
|
|
|
|
'\x00\x00' + // Flags
|
|
|
|
|
safeString16(unitsPerEm) + // unitsPerEM
|
|
|
|
|
'\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // creation date
|
|
|
|
|
'\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // modifification date
|
|
|
|
|
'\x00\x00' + // xMin
|
|
|
|
|
safeString16(properties.descent) + // yMin
|
|
|
|
|
'\x0F\xFF' + // xMax
|
|
|
|
|
safeString16(properties.ascent) + // yMax
|
|
|
|
|
string16(properties.italicAngle ? 2 : 0) + // macStyle
|
|
|
|
|
'\x00\x11' + // lowestRecPPEM
|
|
|
|
|
'\x00\x00' + // fontDirectionHint
|
|
|
|
|
'\x00\x00' + // indexToLocFormat
|
|
|
|
|
'\x00\x00'); // glyphDataFormat
|
|
|
|
|
'\x00\x01\x00\x00' + // Version number
|
|
|
|
|
'\x00\x00\x10\x00' + // fontRevision
|
|
|
|
|
'\x00\x00\x00\x00' + // checksumAdjustement
|
|
|
|
|
'\x5F\x0F\x3C\xF5' + // magicNumber
|
|
|
|
|
'\x00\x00' + // Flags
|
|
|
|
|
safeString16(unitsPerEm) + // unitsPerEM
|
|
|
|
|
'\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // creation date
|
|
|
|
|
'\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // modifification date
|
|
|
|
|
'\x00\x00' + // xMin
|
|
|
|
|
safeString16(properties.descent) + // yMin
|
|
|
|
|
'\x0F\xFF' + // xMax
|
|
|
|
|
safeString16(properties.ascent) + // yMax
|
|
|
|
|
string16(properties.italicAngle ? 2 : 0) + // macStyle
|
|
|
|
|
'\x00\x11' + // lowestRecPPEM
|
|
|
|
|
'\x00\x00' + // fontDirectionHint
|
|
|
|
|
'\x00\x00' + // indexToLocFormat
|
|
|
|
|
'\x00\x00'); // glyphDataFormat
|
|
|
|
|
})(), |
|
|
|
|
|
|
|
|
|
// Horizontal header
|
|
|
|
|
'hhea': (function fontFieldsHhea() { |
|
|
|
|
return stringToArray( |
|
|
|
|
'\x00\x01\x00\x00' + // Version number
|
|
|
|
|
safeString16(properties.ascent) + // Typographic Ascent
|
|
|
|
|
safeString16(properties.descent) + // Typographic Descent
|
|
|
|
|
'\x00\x00' + // Line Gap
|
|
|
|
|
'\xFF\xFF' + // advanceWidthMax
|
|
|
|
|
'\x00\x00' + // minLeftSidebearing
|
|
|
|
|
'\x00\x00' + // minRightSidebearing
|
|
|
|
|
'\x00\x00' + // xMaxExtent
|
|
|
|
|
safeString16(properties.capHeight) + // caretSlopeRise
|
|
|
|
|
safeString16(Math.tan(properties.italicAngle) * |
|
|
|
|
properties.xHeight) + // caretSlopeRun
|
|
|
|
|
'\x00\x00' + // caretOffset
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // metricDataFormat
|
|
|
|
|
string16(numGlyphs + 1)); // Number of HMetrics
|
|
|
|
|
'\x00\x01\x00\x00' + // Version number
|
|
|
|
|
safeString16(properties.ascent) + // Typographic Ascent
|
|
|
|
|
safeString16(properties.descent) + // Typographic Descent
|
|
|
|
|
'\x00\x00' + // Line Gap
|
|
|
|
|
'\xFF\xFF' + // advanceWidthMax
|
|
|
|
|
'\x00\x00' + // minLeftSidebearing
|
|
|
|
|
'\x00\x00' + // minRightSidebearing
|
|
|
|
|
'\x00\x00' + // xMaxExtent
|
|
|
|
|
safeString16(properties.capHeight) + // caretSlopeRise
|
|
|
|
|
safeString16(Math.tan(properties.italicAngle) * |
|
|
|
|
properties.xHeight) + // caretSlopeRun
|
|
|
|
|
'\x00\x00' + // caretOffset
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // -reserved-
|
|
|
|
|
'\x00\x00' + // metricDataFormat
|
|
|
|
|
string16(numGlyphs + 1)); // Number of HMetrics
|
|
|
|
|
})(), |
|
|
|
|
|
|
|
|
|
// Horizontal metrics
|
|
|
|
@ -4156,8 +4179,8 @@ var Font = (function FontClosure() {
@@ -4156,8 +4179,8 @@ var Font = (function FontClosure() {
|
|
|
|
|
// Maximum profile
|
|
|
|
|
'maxp': (function fontFieldsMaxp() { |
|
|
|
|
return stringToArray( |
|
|
|
|
'\x00\x00\x50\x00' + // Version number
|
|
|
|
|
string16(numGlyphs + 1)); // Num of glyphs
|
|
|
|
|
'\x00\x00\x50\x00' + // Version number
|
|
|
|
|
string16(numGlyphs + 1)); // Num of glyphs
|
|
|
|
|
})(), |
|
|
|
|
|
|
|
|
|
// Naming tables
|
|
|
|
@ -4167,9 +4190,9 @@ var Font = (function FontClosure() {
@@ -4167,9 +4190,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
'post': stringToArray(createPostTable(properties)) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
for (var field in fields) |
|
|
|
|
for (var field in fields) { |
|
|
|
|
createTableEntry(otf, field, fields[field]); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
for (var field in fields) { |
|
|
|
|
var table = fields[field]; |
|
|
|
|
otf.file += arrayToString(table); |
|
|
|
@ -4302,15 +4325,18 @@ var Font = (function FontClosure() {
@@ -4302,15 +4325,18 @@ var Font = (function FontClosure() {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// ... via toUnicode map
|
|
|
|
|
if (!charcode && 'toUnicode' in this) |
|
|
|
|
if (!charcode && 'toUnicode' in this) { |
|
|
|
|
charcode = this.toUnicode.indexOf(glyphUnicode); |
|
|
|
|
} |
|
|
|
|
// setting it to unicode if negative or undefined
|
|
|
|
|
if (charcode <= 0) |
|
|
|
|
if (charcode <= 0) { |
|
|
|
|
charcode = glyphUnicode; |
|
|
|
|
} |
|
|
|
|
// trying to get width via charcode
|
|
|
|
|
width = this.widths[charcode]; |
|
|
|
|
if (width) |
|
|
|
|
if (width) { |
|
|
|
|
break; // the non-zero width found
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
width = width || this.defaultWidth; |
|
|
|
|
// Do not shadow the property here. See discussion:
|
|
|
|
@ -4377,13 +4403,15 @@ var Font = (function FontClosure() {
@@ -4377,13 +4403,15 @@ var Font = (function FontClosure() {
|
|
|
|
|
// if we translated this string before, just grab it from the cache
|
|
|
|
|
if (charsCache) { |
|
|
|
|
glyphs = charsCache[chars]; |
|
|
|
|
if (glyphs) |
|
|
|
|
if (glyphs) { |
|
|
|
|
return glyphs; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// lazily create the translation cache
|
|
|
|
|
if (!charsCache) |
|
|
|
|
if (!charsCache) { |
|
|
|
|
charsCache = this.charsCache = Object.create(null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
glyphs = []; |
|
|
|
|
var charsCacheKey = chars; |
|
|
|
@ -4410,8 +4438,9 @@ var Font = (function FontClosure() {
@@ -4410,8 +4438,9 @@ var Font = (function FontClosure() {
|
|
|
|
|
var charcode = chars.charCodeAt(i); |
|
|
|
|
var glyph = this.charToGlyph(charcode); |
|
|
|
|
glyphs.push(glyph); |
|
|
|
|
if (charcode == 0x20) |
|
|
|
|
if (charcode == 0x20) { |
|
|
|
|
glyphs.push(null); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5234,8 +5263,9 @@ var Type1Font = function Type1Font(name, file, properties) {
@@ -5234,8 +5263,9 @@ var Type1Font = function Type1Font(name, file, properties) {
|
|
|
|
|
var eexecBlock = new Stream(file.getBytes(eexecBlockLength)); |
|
|
|
|
var eexecBlockParser = new Type1Parser(eexecBlock, true); |
|
|
|
|
var data = eexecBlockParser.extractFontProgram(); |
|
|
|
|
for (var info in data.properties) |
|
|
|
|
for (var info in data.properties) { |
|
|
|
|
properties[info] = data.properties[info]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var charstrings = data.charstrings; |
|
|
|
|
var type2Charstrings = this.getType2Charstrings(charstrings); |
|
|
|
@ -5306,17 +5336,19 @@ Type1Font.prototype = {
@@ -5306,17 +5336,19 @@ Type1Font.prototype = {
|
|
|
|
|
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { |
|
|
|
|
var bias = 0; |
|
|
|
|
var count = type1Subrs.length; |
|
|
|
|
if (count < 1133) |
|
|
|
|
if (count < 1133) { |
|
|
|
|
bias = 107; |
|
|
|
|
else if (count < 33769) |
|
|
|
|
} else if (count < 33769) { |
|
|
|
|
bias = 1131; |
|
|
|
|
else |
|
|
|
|
} else { |
|
|
|
|
bias = 32768; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add a bunch of empty subrs to deal with the Type2 bias
|
|
|
|
|
var type2Subrs = []; |
|
|
|
|
for (var i = 0; i < bias; i++) |
|
|
|
|
for (var i = 0; i < bias; i++) { |
|
|
|
|
type2Subrs.push([0x0B]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < count; i++) { |
|
|
|
|
type2Subrs.push(type1Subrs[i]); |
|
|
|
@ -5365,9 +5397,9 @@ Type1Font.prototype = {
@@ -5365,9 +5397,9 @@ Type1Font.prototype = {
|
|
|
|
|
// thought mapping names that aren't in the standard strings to .notdef
|
|
|
|
|
// was fine, however in issue818 when mapping them all to .notdef the
|
|
|
|
|
// adieresis glyph no longer worked.
|
|
|
|
|
if (index == -1) |
|
|
|
|
if (index == -1) { |
|
|
|
|
index = 0; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
charsetArray.push((index >> 8) & 0xff, index & 0xff); |
|
|
|
|
} |
|
|
|
|
cff.charset = new CFFCharset(false, 0, [], charsetArray); |
|
|
|
@ -5399,8 +5431,9 @@ Type1Font.prototype = {
@@ -5399,8 +5431,9 @@ Type1Font.prototype = {
|
|
|
|
|
]; |
|
|
|
|
for (var i = 0, ii = fields.length; i < ii; i++) { |
|
|
|
|
var field = fields[i]; |
|
|
|
|
if (!properties.privateData.hasOwnProperty(field)) |
|
|
|
|
if (!properties.privateData.hasOwnProperty(field)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
var value = properties.privateData[field]; |
|
|
|
|
if (isArray(value)) { |
|
|
|
|
// All of the private dictionary array data in CFF must be stored as
|
|
|
|
@ -5676,7 +5709,7 @@ var CFFParser = (function CFFParserClosure() {
@@ -5676,7 +5709,7 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
var hdrSize = bytes[2]; |
|
|
|
|
var offSize = bytes[3]; |
|
|
|
|
var header = new CFFHeader(major, minor, hdrSize, offSize); |
|
|
|
|
return {obj: header, endPos: hdrSize}; |
|
|
|
|
return { obj: header, endPos: hdrSize }; |
|
|
|
|
}, |
|
|
|
|
parseDict: function CFFParser_parseDict(dict) { |
|
|
|
|
var pos = 0; |
|
|
|
@ -5718,12 +5751,14 @@ var CFFParser = (function CFFParserClosure() {
@@ -5718,12 +5751,14 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
var b1 = b >> 4; |
|
|
|
|
var b2 = b & 15; |
|
|
|
|
|
|
|
|
|
if (b1 == eof) |
|
|
|
|
if (b1 == eof) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
str += lookup[b1]; |
|
|
|
|
|
|
|
|
|
if (b2 == eof) |
|
|
|
|
if (b2 == eof) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
str += lookup[b2]; |
|
|
|
|
} |
|
|
|
|
return parseFloat(str); |
|
|
|
@ -5737,8 +5772,9 @@ var CFFParser = (function CFFParserClosure() {
@@ -5737,8 +5772,9 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
while (pos < end) { |
|
|
|
|
var b = dict[pos]; |
|
|
|
|
if (b <= 21) { |
|
|
|
|
if (b === 12) |
|
|
|
|
if (b === 12) { |
|
|
|
|
b = (b << 8) | dict[++pos]; |
|
|
|
|
} |
|
|
|
|
entries.push([b, operands]); |
|
|
|
|
operands = []; |
|
|
|
|
++pos; |
|
|
|
@ -5872,14 +5908,14 @@ var CFFParser = (function CFFParserClosure() {
@@ -5872,14 +5908,14 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
stack[stackSize] = value - 139; |
|
|
|
|
stackSize++; |
|
|
|
|
} else if (value >= 247 && value <= 254) { // number (+1 bytes)
|
|
|
|
|
stack[stackSize] = value < 251 ? |
|
|
|
|
((value - 247) << 8) + data[j] + 108 : |
|
|
|
|
-((value - 251) << 8) - data[j] - 108; |
|
|
|
|
stack[stackSize] = (value < 251 ? |
|
|
|
|
((value - 247) << 8) + data[j] + 108 : |
|
|
|
|
-((value - 251) << 8) - data[j] - 108); |
|
|
|
|
j++; |
|
|
|
|
stackSize++; |
|
|
|
|
} else if (value == 255) { // number (32 bit)
|
|
|
|
|
stack[stackSize] = ((data[j] << 24) | (data[j + 1] << 16) | |
|
|
|
|
(data[j + 2] << 8) | data[j + 3]) / 65536; |
|
|
|
|
(data[j + 2] << 8) | data[j + 3]) / 65536; |
|
|
|
|
j += 4; |
|
|
|
|
stackSize++; |
|
|
|
|
} else if (value == 19 || value == 20) { |
|
|
|
@ -5958,8 +5994,9 @@ var CFFParser = (function CFFParserClosure() {
@@ -5958,8 +5994,9 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
parentDict.privateDict = privateDict; |
|
|
|
|
|
|
|
|
|
// Parse the Subrs index also since it's relative to the private dict.
|
|
|
|
|
if (!privateDict.getByName('Subrs')) |
|
|
|
|
if (!privateDict.getByName('Subrs')) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
var subrsOffset = privateDict.getByName('Subrs'); |
|
|
|
|
var relativeOffset = offset + subrsOffset; |
|
|
|
|
// Validate the offset.
|
|
|
|
@ -6001,16 +6038,18 @@ var CFFParser = (function CFFParserClosure() {
@@ -6001,16 +6038,18 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
while (charset.length <= length) { |
|
|
|
|
var id = (bytes[pos++] << 8) | bytes[pos++]; |
|
|
|
|
var count = bytes[pos++]; |
|
|
|
|
for (var i = 0; i <= count; i++) |
|
|
|
|
for (var i = 0; i <= count; i++) { |
|
|
|
|
charset.push(cid ? id++ : strings.get(id++)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
while (charset.length <= length) { |
|
|
|
|
var id = (bytes[pos++] << 8) | bytes[pos++]; |
|
|
|
|
var count = (bytes[pos++] << 8) | bytes[pos++]; |
|
|
|
|
for (var i = 0; i <= count; i++) |
|
|
|
|
for (var i = 0; i <= count; i++) { |
|
|
|
|
charset.push(cid ? id++ : strings.get(id++)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
@ -6059,8 +6098,9 @@ var CFFParser = (function CFFParserClosure() {
@@ -6059,8 +6098,9 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
switch (format & 0x7f) { |
|
|
|
|
case 0: |
|
|
|
|
var glyphsCount = bytes[pos++]; |
|
|
|
|
for (var i = 1; i <= glyphsCount; i++) |
|
|
|
|
for (var i = 1; i <= glyphsCount; i++) { |
|
|
|
|
encoding[bytes[pos++]] = i; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 1: |
|
|
|
@ -6069,8 +6109,9 @@ var CFFParser = (function CFFParserClosure() {
@@ -6069,8 +6109,9 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
for (var i = 0; i < rangesCount; i++) { |
|
|
|
|
var start = bytes[pos++]; |
|
|
|
|
var left = bytes[pos++]; |
|
|
|
|
for (var j = start; j <= start + left; j++) |
|
|
|
|
for (var j = start; j <= start + left; j++) { |
|
|
|
|
encoding[j] = gid++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -6112,8 +6153,9 @@ var CFFParser = (function CFFParserClosure() {
@@ -6112,8 +6153,9 @@ var CFFParser = (function CFFParserClosure() {
|
|
|
|
|
var first = (bytes[pos++] << 8) | bytes[pos++]; |
|
|
|
|
var fdIndex = bytes[pos++]; |
|
|
|
|
var next = (bytes[pos] << 8) | bytes[pos + 1]; |
|
|
|
|
for (var j = first; j < next; ++j) |
|
|
|
|
for (var j = first; j < next; ++j) { |
|
|
|
|
fdSelect.push(fdIndex); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Advance past the sentinel(next).
|
|
|
|
|
pos += 2; |
|
|
|
@ -6167,10 +6209,12 @@ var CFFStrings = (function CFFStringsClosure() {
@@ -6167,10 +6209,12 @@ var CFFStrings = (function CFFStringsClosure() {
|
|
|
|
|
} |
|
|
|
|
CFFStrings.prototype = { |
|
|
|
|
get: function CFFStrings_get(index) { |
|
|
|
|
if (index >= 0 && index <= 390) |
|
|
|
|
if (index >= 0 && index <= 390) { |
|
|
|
|
return CFFStandardStrings[index]; |
|
|
|
|
if (index - 391 <= this.strings.length) |
|
|
|
|
} |
|
|
|
|
if (index - 391 <= this.strings.length) { |
|
|
|
|
return this.strings[index - 391]; |
|
|
|
|
} |
|
|
|
|
return CFFStandardStrings[0]; |
|
|
|
|
}, |
|
|
|
|
add: function CFFStrings_add(value) { |
|
|
|
@ -6221,15 +6265,18 @@ var CFFDict = (function CFFDictClosure() {
@@ -6221,15 +6265,18 @@ var CFFDict = (function CFFDictClosure() {
|
|
|
|
|
CFFDict.prototype = { |
|
|
|
|
// value should always be an array
|
|
|
|
|
setByKey: function CFFDict_setByKey(key, value) { |
|
|
|
|
if (!(key in this.keyToNameMap)) |
|
|
|
|
if (!(key in this.keyToNameMap)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
// ignore empty values
|
|
|
|
|
if (value.length === 0) |
|
|
|
|
if (value.length === 0) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
var type = this.types[key]; |
|
|
|
|
// remove the array wrapping these types of values
|
|
|
|
|
if (type === 'num' || type === 'sid' || type === 'offset') |
|
|
|
|
if (type === 'num' || type === 'sid' || type === 'offset') { |
|
|
|
|
value = value[0]; |
|
|
|
|
} |
|
|
|
|
this.values[key] = value; |
|
|
|
|
return true; |
|
|
|
|
}, |
|
|
|
@ -6243,11 +6290,13 @@ var CFFDict = (function CFFDictClosure() {
@@ -6243,11 +6290,13 @@ var CFFDict = (function CFFDictClosure() {
|
|
|
|
|
return this.nameToKeyMap[name] in this.values; |
|
|
|
|
}, |
|
|
|
|
getByName: function CFFDict_getByName(name) { |
|
|
|
|
if (!(name in this.nameToKeyMap)) |
|
|
|
|
if (!(name in this.nameToKeyMap)) { |
|
|
|
|
error('Invalid dictionary name "' + name + '"'); |
|
|
|
|
} |
|
|
|
|
var key = this.nameToKeyMap[name]; |
|
|
|
|
if (!(key in this.values)) |
|
|
|
|
if (!(key in this.values)) { |
|
|
|
|
return this.defaults[key]; |
|
|
|
|
} |
|
|
|
|
return this.values[key]; |
|
|
|
|
}, |
|
|
|
|
removeByName: function CFFDict_removeByName(name) { |
|
|
|
@ -6320,8 +6369,9 @@ var CFFTopDict = (function CFFTopDictClosure() {
@@ -6320,8 +6369,9 @@ var CFFTopDict = (function CFFTopDictClosure() {
|
|
|
|
|
]; |
|
|
|
|
var tables = null; |
|
|
|
|
function CFFTopDict(strings) { |
|
|
|
|
if (tables === null) |
|
|
|
|
if (tables === null) { |
|
|
|
|
tables = CFFDict.createTables(layout); |
|
|
|
|
} |
|
|
|
|
CFFDict.call(this, tables, strings); |
|
|
|
|
this.privateDict = null; |
|
|
|
|
} |
|
|
|
@ -6352,8 +6402,9 @@ var CFFPrivateDict = (function CFFPrivateDictClosure() {
@@ -6352,8 +6402,9 @@ var CFFPrivateDict = (function CFFPrivateDictClosure() {
|
|
|
|
|
]; |
|
|
|
|
var tables = null; |
|
|
|
|
function CFFPrivateDict(strings) { |
|
|
|
|
if (tables === null) |
|
|
|
|
if (tables === null) { |
|
|
|
|
tables = CFFDict.createTables(layout); |
|
|
|
|
} |
|
|
|
|
CFFDict.call(this, tables, strings); |
|
|
|
|
this.subrsIndex = null; |
|
|
|
|
} |
|
|
|
@ -6418,8 +6469,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
@@ -6418,8 +6469,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
|
|
|
|
|
return key in this.offsets; |
|
|
|
|
}, |
|
|
|
|
track: function CFFOffsetTracker_track(key, location) { |
|
|
|
|
if (key in this.offsets) |
|
|
|
|
if (key in this.offsets) { |
|
|
|
|
error('Already tracking location of ' + key); |
|
|
|
|
} |
|
|
|
|
this.offsets[key] = location; |
|
|
|
|
}, |
|
|
|
|
offset: function CFFOffsetTracker_offset(value) { |
|
|
|
@ -6430,8 +6482,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
@@ -6430,8 +6482,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
|
|
|
|
|
setEntryLocation: function CFFOffsetTracker_setEntryLocation(key, |
|
|
|
|
values, |
|
|
|
|
output) { |
|
|
|
|
if (!(key in this.offsets)) |
|
|
|
|
if (!(key in this.offsets)) { |
|
|
|
|
error('Not tracking location of ' + key); |
|
|
|
|
} |
|
|
|
|
var data = output.data; |
|
|
|
|
var dataOffset = this.offsets[key]; |
|
|
|
|
var size = 5; |
|
|
|
@ -6443,8 +6496,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
@@ -6443,8 +6496,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
|
|
|
|
|
var offset4 = offset0 + 4; |
|
|
|
|
// It's easy to screw up offsets so perform this sanity check.
|
|
|
|
|
if (data[offset0] !== 0x1d || data[offset1] !== 0 || |
|
|
|
|
data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) |
|
|
|
|
data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) { |
|
|
|
|
error('writing to an offset that is not empty'); |
|
|
|
|
} |
|
|
|
|
var value = values[i]; |
|
|
|
|
data[offset0] = 0x1d; |
|
|
|
|
data[offset1] = (value >> 24) & 0xFF; |
|
|
|
@ -6461,9 +6515,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
@@ -6461,9 +6515,9 @@ var CFFOffsetTracker = (function CFFOffsetTrackerClosure() {
|
|
|
|
|
var CFFCompiler = (function CFFCompilerClosure() { |
|
|
|
|
function stringToArray(str) { |
|
|
|
|
var array = []; |
|
|
|
|
for (var i = 0, ii = str.length; i < ii; ++i) |
|
|
|
|
for (var i = 0, ii = str.length; i < ii; ++i) { |
|
|
|
|
array[i] = str.charCodeAt(i); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
return array; |
|
|
|
|
} |
|
|
|
|
function CFFCompiler(cff) { |
|
|
|
@ -6579,10 +6633,11 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6579,10 +6633,11 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
return output.data; |
|
|
|
|
}, |
|
|
|
|
encodeNumber: function CFFCompiler_encodeNumber(value) { |
|
|
|
|
if (parseFloat(value) == parseInt(value, 10) && !isNaN(value)) // isInt
|
|
|
|
|
if (parseFloat(value) == parseInt(value, 10) && !isNaN(value)) { // isInt
|
|
|
|
|
return this.encodeInteger(value); |
|
|
|
|
else |
|
|
|
|
} else { |
|
|
|
|
return this.encodeFloat(value); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
encodeFloat: function CFFCompiler_encodeFloat(num) { |
|
|
|
|
var value = num.toString(); |
|
|
|
@ -6645,8 +6700,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6645,8 +6700,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
}, |
|
|
|
|
compileNameIndex: function CFFCompiler_compileNameIndex(names) { |
|
|
|
|
var nameIndex = new CFFIndex(); |
|
|
|
|
for (var i = 0, ii = names.length; i < ii; ++i) |
|
|
|
|
for (var i = 0, ii = names.length; i < ii; ++i) { |
|
|
|
|
nameIndex.add(stringToArray(names[i])); |
|
|
|
|
} |
|
|
|
|
return this.compileIndex(nameIndex); |
|
|
|
|
}, |
|
|
|
|
compileTopDicts: function CFFCompiler_compileTopDicts(dicts, |
|
|
|
@ -6714,16 +6770,22 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6714,16 +6770,22 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
var order = dict.order; |
|
|
|
|
for (var i = 0; i < order.length; ++i) { |
|
|
|
|
var key = order[i]; |
|
|
|
|
if (!(key in dict.values)) |
|
|
|
|
if (!(key in dict.values)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
var values = dict.values[key]; |
|
|
|
|
var types = dict.types[key]; |
|
|
|
|
if (!isArray(types)) types = [types]; |
|
|
|
|
if (!isArray(values)) values = [values]; |
|
|
|
|
if (!isArray(types)) { |
|
|
|
|
types = [types]; |
|
|
|
|
} |
|
|
|
|
if (!isArray(values)) { |
|
|
|
|
values = [values]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove any empty dict values.
|
|
|
|
|
if (values.length === 0) |
|
|
|
|
if (values.length === 0) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (var j = 0, jj = types.length; j < jj; ++j) { |
|
|
|
|
var type = types[j]; |
|
|
|
@ -6740,15 +6802,17 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6740,15 +6802,17 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
var name = dict.keyToNameMap[key]; |
|
|
|
|
// Some offsets have the offset and the length, so just record the
|
|
|
|
|
// position of the first one.
|
|
|
|
|
if (!offsetTracker.isTracking(name)) |
|
|
|
|
if (!offsetTracker.isTracking(name)) { |
|
|
|
|
offsetTracker.track(name, out.length); |
|
|
|
|
} |
|
|
|
|
out = out.concat([0x1d, 0, 0, 0, 0]); |
|
|
|
|
break; |
|
|
|
|
case 'array': |
|
|
|
|
case 'delta': |
|
|
|
|
out = out.concat(this.encodeNumber(value)); |
|
|
|
|
for (var k = 1, kk = values.length; k < kk; ++k) |
|
|
|
|
for (var k = 1, kk = values.length; k < kk; ++k) { |
|
|
|
|
out = out.concat(this.encodeNumber(values[k])); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
error('Unknown data type of ' + type); |
|
|
|
@ -6761,8 +6825,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6761,8 +6825,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
}, |
|
|
|
|
compileStringIndex: function CFFCompiler_compileStringIndex(strings) { |
|
|
|
|
var stringIndex = new CFFIndex(); |
|
|
|
|
for (var i = 0, ii = strings.length; i < ii; ++i) |
|
|
|
|
for (var i = 0, ii = strings.length; i < ii; ++i) { |
|
|
|
|
stringIndex.add(stringToArray(strings[i])); |
|
|
|
|
} |
|
|
|
|
return this.compileIndex(stringIndex); |
|
|
|
|
}, |
|
|
|
|
compileGlobalSubrIndex: function CFFCompiler_compileGlobalSubrIndex() { |
|
|
|
@ -6783,8 +6848,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6783,8 +6848,9 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
}, |
|
|
|
|
compileTypedArray: function CFFCompiler_compileTypedArray(data) { |
|
|
|
|
var out = []; |
|
|
|
|
for (var i = 0, ii = data.length; i < ii; ++i) |
|
|
|
|
for (var i = 0, ii = data.length; i < ii; ++i) { |
|
|
|
|
out[i] = data[i]; |
|
|
|
|
} |
|
|
|
|
return out; |
|
|
|
|
}, |
|
|
|
|
compileIndex: function CFFCompiler_compileIndex(index, trackers) { |
|
|
|
@ -6795,24 +6861,27 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6795,24 +6861,27 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
|
|
|
|
|
// If there is no object, just create an index. This technically
|
|
|
|
|
// should just be [0, 0] but OTS has an issue with that.
|
|
|
|
|
if (count === 0) |
|
|
|
|
if (count === 0) { |
|
|
|
|
return [0, 0, 0]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var data = [(count >> 8) & 0xFF, count & 0xff]; |
|
|
|
|
|
|
|
|
|
var lastOffset = 1; |
|
|
|
|
for (var i = 0; i < count; ++i) |
|
|
|
|
for (var i = 0; i < count; ++i) { |
|
|
|
|
lastOffset += objects[i].length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var offsetSize; |
|
|
|
|
if (lastOffset < 0x100) |
|
|
|
|
if (lastOffset < 0x100) { |
|
|
|
|
offsetSize = 1; |
|
|
|
|
else if (lastOffset < 0x10000) |
|
|
|
|
} else if (lastOffset < 0x10000) { |
|
|
|
|
offsetSize = 2; |
|
|
|
|
else if (lastOffset < 0x1000000) |
|
|
|
|
} else if (lastOffset < 0x1000000) { |
|
|
|
|
offsetSize = 3; |
|
|
|
|
else |
|
|
|
|
} else { |
|
|
|
|
offsetSize = 4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Next byte contains the offset size use to reference object in the file
|
|
|
|
|
data.push(offsetSize); |
|
|
|
@ -6836,17 +6905,20 @@ var CFFCompiler = (function CFFCompilerClosure() {
@@ -6836,17 +6905,20 @@ var CFFCompiler = (function CFFCompilerClosure() {
|
|
|
|
|
relativeOffset & 0xFF); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (objects[i]) |
|
|
|
|
if (objects[i]) { |
|
|
|
|
relativeOffset += objects[i].length; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
var offset = data.length; |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < count; i++) { |
|
|
|
|
// Notify the tracker where the object will be offset in the data.
|
|
|
|
|
if (trackers[i]) |
|
|
|
|
if (trackers[i]) { |
|
|
|
|
trackers[i].offset(data.length); |
|
|
|
|
for (var j = 0, jj = objects[i].length; j < jj; j++) |
|
|
|
|
} |
|
|
|
|
for (var j = 0, jj = objects[i].length; j < jj; j++) { |
|
|
|
|
data.push(objects[i][j]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return data; |
|
|
|
|
} |
|
|
|
|