|
|
@ -3339,7 +3339,7 @@ var Page = (function() { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0, ii = fonts.length; i < ii; ++i) |
|
|
|
for (var i = 0, ii = fonts.length; i < ii; ++i) |
|
|
|
fonts[i].fontDict.fontObj = fontObjs[i]; |
|
|
|
fonts[i].dict.fontObj = fontObjs[i]; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4180,59 +4180,30 @@ var PartialEvaluator = (function() { |
|
|
|
}; |
|
|
|
}; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
translateFont: function(fontDict, xref, resources) { |
|
|
|
extractEncoding: function(dict, xref, properties) { |
|
|
|
var fd; |
|
|
|
var type = properties.type; |
|
|
|
var descendant = []; |
|
|
|
if (properties.composite) { |
|
|
|
var subType = fontDict.get('Subtype'); |
|
|
|
|
|
|
|
var compositeFont = false; |
|
|
|
|
|
|
|
assertWellFormed(IsName(subType), 'invalid font Subtype'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If font is a composite
|
|
|
|
|
|
|
|
// - get the descendant font
|
|
|
|
|
|
|
|
// - set the type according to the descendant font
|
|
|
|
|
|
|
|
// - get the FontDescriptor from the descendant font
|
|
|
|
|
|
|
|
if (subType.name == 'Type0') { |
|
|
|
|
|
|
|
var df = fontDict.get('DescendantFonts'); |
|
|
|
|
|
|
|
if (!df) |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
compositeFont = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (IsRef(df)) { |
|
|
|
|
|
|
|
df = xref.fetch(df); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
descendant = xref.fetch(IsRef(df) ? df : df[0]); |
|
|
|
|
|
|
|
subType = descendant.get('Subtype'); |
|
|
|
|
|
|
|
fd = descendant.get('FontDescriptor'); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
fd = fontDict.get('FontDescriptor'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var builtInEncoding = false; |
|
|
|
|
|
|
|
var encodingMap = {}; |
|
|
|
|
|
|
|
if (compositeFont) { |
|
|
|
|
|
|
|
// Special CIDFont support
|
|
|
|
|
|
|
|
// XXX only CIDFontType2 supported for now
|
|
|
|
// XXX only CIDFontType2 supported for now
|
|
|
|
if (subType.name == 'CIDFontType2') { |
|
|
|
if (type == 'CIDFontType2') { |
|
|
|
var cidToGidMap = descendant.get('CIDToGIDMap'); |
|
|
|
var cidToGidMap = dict.get('CIDToGIDMap'); |
|
|
|
if (cidToGidMap && IsRef(cidToGidMap)) { |
|
|
|
if (!cidToGidMap || !IsRef(cidToGidMap)) |
|
|
|
// Extract the encoding from the CIDToGIDMap
|
|
|
|
return GlyphsUnicode; |
|
|
|
var glyphsStream = xref.fetchIfRef(cidToGidMap); |
|
|
|
|
|
|
|
var glyphsData = glyphsStream.getBytes(0); |
|
|
|
// Extract the encoding from the CIDToGIDMap
|
|
|
|
// Glyph ids are big-endian 2-byte values
|
|
|
|
var glyphsStream = xref.fetchIfRef(cidToGidMap); |
|
|
|
// Set this to 0 to verify the font has an encoding.
|
|
|
|
var glyphsData = glyphsStream.getBytes(0); |
|
|
|
encodingMap[0] = 0; |
|
|
|
|
|
|
|
for (var j = 0; j < glyphsData.length; j++) { |
|
|
|
// Glyph ids are big-endian 2-byte values
|
|
|
|
var glyphID = (glyphsData[j++] << 8) | glyphsData[j]; |
|
|
|
// Set this to 0 to verify the font has an encoding.
|
|
|
|
if (glyphID != 0) |
|
|
|
var encoding = properties.encoding; |
|
|
|
encodingMap[j >> 1] = glyphID; |
|
|
|
encoding[0] = 0; |
|
|
|
} |
|
|
|
for (var j = 0; j < glyphsData.length; j++) { |
|
|
|
|
|
|
|
var glyphID = (glyphsData[j++] << 8) | glyphsData[j]; |
|
|
|
|
|
|
|
if (glyphID != 0) |
|
|
|
|
|
|
|
encoding[j >> 1] = glyphID; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (type == 'CIDFontType0') { |
|
|
|
else { |
|
|
|
var encoding = xref.fetchIfRef(dict.get('Encoding')); |
|
|
|
// XXX This is a placeholder for handling of the encoding of
|
|
|
|
|
|
|
|
// CIDFontType0 fonts
|
|
|
|
|
|
|
|
var encoding = xref.fetchIfRef(fontDict.get('Encoding')); |
|
|
|
|
|
|
|
if (IsName(encoding)) { |
|
|
|
if (IsName(encoding)) { |
|
|
|
// Encoding is a predefined CMap
|
|
|
|
// Encoding is a predefined CMap
|
|
|
|
if (encoding.name == 'Identity-H') { |
|
|
|
if (encoding.name == 'Identity-H') { |
|
|
@ -4246,227 +4217,254 @@ var PartialEvaluator = (function() { |
|
|
|
'9.7.5.3'); |
|
|
|
'9.7.5.3'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
return GlyphsUnicode; |
|
|
|
var baseEncoding = null, diffEncoding = []; |
|
|
|
} |
|
|
|
if (fontDict.has('Encoding')) { |
|
|
|
|
|
|
|
var encoding = xref.fetchIfRef(fontDict.get('Encoding')); |
|
|
|
var differences = properties.differences; |
|
|
|
if (IsDict(encoding)) { |
|
|
|
var map = properties.encoding; |
|
|
|
var baseName = encoding.get('BaseEncoding'); |
|
|
|
var baseEncoding = null; |
|
|
|
if (baseName) |
|
|
|
if (dict.has('Encoding')) { |
|
|
|
baseEncoding = Encodings[baseName.name].slice(); |
|
|
|
var encoding = xref.fetchIfRef(dict.get('Encoding')); |
|
|
|
|
|
|
|
if (IsDict(encoding)) { |
|
|
|
// Load the differences between the base and original
|
|
|
|
var baseName = encoding.get('BaseEncoding'); |
|
|
|
var differences = encoding.get('Differences'); |
|
|
|
if (baseName) |
|
|
|
var index = 0; |
|
|
|
baseEncoding = Encodings[baseName.name].slice(); |
|
|
|
for (var j = 0; j < differences.length; j++) { |
|
|
|
|
|
|
|
var data = differences[j]; |
|
|
|
// Load the differences between the base and original
|
|
|
|
if (IsNum(data)) |
|
|
|
var diffEncoding = encoding.get('Differences'); |
|
|
|
index = data; |
|
|
|
var index = 0; |
|
|
|
else |
|
|
|
for (var j = 0; j < diffEncoding.length; j++) { |
|
|
|
diffEncoding[index++] = data.name; |
|
|
|
var data = diffEncoding[j]; |
|
|
|
} |
|
|
|
if (IsNum(data)) |
|
|
|
} else if (IsName(encoding)) { |
|
|
|
index = data; |
|
|
|
baseEncoding = Encodings[encoding.name].slice(); |
|
|
|
else |
|
|
|
} else { |
|
|
|
differences[index++] = data.name; |
|
|
|
error('Encoding is not a Name nor a Dict'); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (IsName(encoding)) { |
|
|
|
|
|
|
|
baseEncoding = Encodings[encoding.name].slice(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
error('Encoding is not a Name nor a Dict'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var fontType = subType.name; |
|
|
|
if (!baseEncoding) { |
|
|
|
if (!baseEncoding) { |
|
|
|
switch (type) { |
|
|
|
switch (fontType) { |
|
|
|
case 'TrueType': |
|
|
|
case 'TrueType': |
|
|
|
baseEncoding = Encodings.WinAnsiEncoding.slice(); |
|
|
|
baseEncoding = Encodings.WinAnsiEncoding.slice(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 'Type1': |
|
|
|
case 'Type1': |
|
|
|
baseEncoding = Encodings.StandardEncoding.slice(); |
|
|
|
baseEncoding = Encodings.StandardEncoding.slice(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
warn('Unknown type of font: ' + type); |
|
|
|
warn('Unknown type of font: ' + fontType); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// firstChar and width are required
|
|
|
|
// merge in the differences
|
|
|
|
// (except for 14 standard fonts)
|
|
|
|
var firstChar = properties.firstChar; |
|
|
|
var firstChar = xref.fetchIfRef(fontDict.get('FirstChar')) || 0; |
|
|
|
var lastChar = properties.lastChar; |
|
|
|
var widths = xref.fetchIfRef(fontDict.get('Widths')) || []; |
|
|
|
var glyphs = {}; |
|
|
|
|
|
|
|
for (var i = firstChar; i <= lastChar; i++) { |
|
|
|
var lastChar = xref.fetchIfRef(fontDict.get('LastChar')); |
|
|
|
var glyph = differences[i] || baseEncoding[i]; |
|
|
|
if (!lastChar) |
|
|
|
if (glyph) { |
|
|
|
lastChar = diffEncoding.length || baseEncoding.length; |
|
|
|
var index = GlyphsUnicode[glyph] || i; |
|
|
|
|
|
|
|
glyphs[glyph] = map[i] = index; |
|
|
|
// merge in the differences
|
|
|
|
|
|
|
|
var glyphsMap = {}; |
|
|
|
// If there is no file, the character mapping can't be modified
|
|
|
|
for (var i = firstChar; i <= lastChar; i++) { |
|
|
|
// but this is unlikely that there is any standard encoding with
|
|
|
|
var glyph = diffEncoding[i] || baseEncoding[i]; |
|
|
|
// chars below 0x1f, so that's fine.
|
|
|
|
if (glyph) { |
|
|
|
if (!properties.file) |
|
|
|
var index = GlyphsUnicode[glyph] || i; |
|
|
|
continue; |
|
|
|
glyphsMap[glyph] = encodingMap[i] = index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!fontFile) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (index <= 0x1f || (index >= 127 && index <= 255)) |
|
|
|
if (index <= 0x1f || (index >= 127 && index <= 255)) |
|
|
|
glyphsMap[glyph] = encodingMap[i] += kCmapGlyphOffset; |
|
|
|
glyphs[glyph] = map[i] += kCmapGlyphOffset; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (fontType == 'TrueType' && fontDict.has('ToUnicode') && |
|
|
|
if (type == 'TrueType' && dict.has('ToUnicode') && differences) { |
|
|
|
differences) { |
|
|
|
var cmapObj = xref.fetchIfRef(dict.get('ToUnicode')); |
|
|
|
var cmapObj = xref.fetchIfRef(fontDict.get('ToUnicode')); |
|
|
|
if (IsName(cmapObj)) { |
|
|
|
if (IsName(cmapObj)) { |
|
|
|
error('ToUnicode file cmap translation not implemented'); |
|
|
|
error('ToUnicode file cmap translation not implemented'); |
|
|
|
} else if (IsStream(cmapObj)) { |
|
|
|
} else if (IsStream(cmapObj)) { |
|
|
|
var tokens = []; |
|
|
|
var tokens = []; |
|
|
|
var token = ''; |
|
|
|
var token = ''; |
|
|
|
var beginArrayToken = {}; |
|
|
|
var beginArrayToken = {}; |
|
|
|
|
|
|
|
|
|
|
|
var cmap = cmapObj.getBytes(cmapObj.length); |
|
|
|
var cmap = cmapObj.getBytes(cmapObj.length); |
|
|
|
for (var i = 0; i < cmap.length; i++) { |
|
|
|
for (var i = 0; i < cmap.length; i++) { |
|
|
|
var byte = cmap[i]; |
|
|
|
var byte = cmap[i]; |
|
|
|
if (byte == 0x20 || byte == 0x0D || byte == 0x0A || |
|
|
|
if (byte == 0x20 || byte == 0x0D || byte == 0x0A || |
|
|
|
byte == 0x3C || byte == 0x5B || byte == 0x5D) { |
|
|
|
byte == 0x3C || byte == 0x5B || byte == 0x5D) { |
|
|
|
switch (token) { |
|
|
|
switch (token) { |
|
|
|
case 'usecmap': |
|
|
|
case 'usecmap': |
|
|
|
error('usecmap is not implemented'); |
|
|
|
error('usecmap is not implemented'); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'beginbfchar': |
|
|
|
case 'beginbfchar': |
|
|
|
case 'beginbfrange': |
|
|
|
case 'beginbfrange': |
|
|
|
case 'begincidchar': |
|
|
|
case 'begincidchar': |
|
|
|
case 'begincidrange': |
|
|
|
case 'begincidrange': |
|
|
|
token = ''; |
|
|
|
token = ''; |
|
|
|
tokens = []; |
|
|
|
tokens = []; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'endcidrange': |
|
|
|
case 'endcidrange': |
|
|
|
case 'endbfrange': |
|
|
|
case 'endbfrange': |
|
|
|
for (var j = 0; j < tokens.length; j += 3) { |
|
|
|
for (var j = 0; j < tokens.length; j += 3) { |
|
|
|
var startRange = tokens[j]; |
|
|
|
var startRange = tokens[j]; |
|
|
|
var endRange = tokens[j + 1]; |
|
|
|
var endRange = tokens[j + 1]; |
|
|
|
var code = tokens[j + 2]; |
|
|
|
var code = tokens[j + 2]; |
|
|
|
while (startRange < endRange) { |
|
|
|
while (startRange < endRange) { |
|
|
|
map[startRange] = code++; |
|
|
|
encodingMap[startRange] = code++; |
|
|
|
++startRange; |
|
|
|
++startRange; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'endcidchar': |
|
|
|
|
|
|
|
case 'endbfchar': |
|
|
|
|
|
|
|
for (var j = 0; j < tokens.length; j += 2) { |
|
|
|
|
|
|
|
var index = tokens[j]; |
|
|
|
|
|
|
|
var code = tokens[j + 1]; |
|
|
|
|
|
|
|
encodingMap[index] = code; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
case '': |
|
|
|
|
|
|
|
break; |
|
|
|
case 'endcidchar': |
|
|
|
|
|
|
|
case 'endbfchar': |
|
|
|
default: |
|
|
|
for (var j = 0; j < tokens.length; j += 2) { |
|
|
|
if (token[0] >= '0' && token[0] <= '9') |
|
|
|
var index = tokens[j]; |
|
|
|
token = parseInt(token, 10); // a number
|
|
|
|
var code = tokens[j + 1]; |
|
|
|
tokens.push(token); |
|
|
|
map[index] = code; |
|
|
|
token = ''; |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
switch (byte) { |
|
|
|
case '': |
|
|
|
case 0x5B: |
|
|
|
break; |
|
|
|
// begin list parsing
|
|
|
|
|
|
|
|
tokens.push(beginArrayToken); |
|
|
|
default: |
|
|
|
break; |
|
|
|
if (token[0] >= '0' && token[0] <= '9') |
|
|
|
case 0x5D: |
|
|
|
token = parseInt(token, 10); // a number
|
|
|
|
// collect array items
|
|
|
|
tokens.push(token); |
|
|
|
var items = [], item; |
|
|
|
token = ''; |
|
|
|
while (tokens.length && |
|
|
|
break; |
|
|
|
(item = tokens.pop()) != beginArrayToken) |
|
|
|
} |
|
|
|
|
|
|
|
switch (byte) { |
|
|
|
|
|
|
|
case 0x5B: |
|
|
|
|
|
|
|
// begin list parsing
|
|
|
|
|
|
|
|
tokens.push(beginArrayToken); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 0x5D: |
|
|
|
|
|
|
|
// collect array items
|
|
|
|
|
|
|
|
var items = [], item; |
|
|
|
|
|
|
|
while (tokens.length && |
|
|
|
|
|
|
|
(item = tokens.pop()) != beginArrayToken) |
|
|
|
items.unshift(item); |
|
|
|
items.unshift(item); |
|
|
|
tokens.push(items); |
|
|
|
tokens.push(items); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} else if (byte == 0x3E) { |
|
|
|
|
|
|
|
if (token.length) { |
|
|
|
|
|
|
|
// parsing hex number
|
|
|
|
|
|
|
|
tokens.push(parseInt(token, 16)); |
|
|
|
|
|
|
|
token = ''; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
token += String.fromCharCode(byte); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (byte == 0x3E) { |
|
|
|
|
|
|
|
if (token.length) { |
|
|
|
|
|
|
|
// parsing hex number
|
|
|
|
|
|
|
|
tokens.push(parseInt(token, 16)); |
|
|
|
|
|
|
|
token = ''; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
token += String.fromCharCode(byte); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!fd) { |
|
|
|
return glyphs; |
|
|
|
var baseFontName = fontDict.get('BaseFont'); |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
translateFont: function(dict, xref, resources) { |
|
|
|
|
|
|
|
var subType = dict.get('Subtype'); |
|
|
|
|
|
|
|
assertWellFormed(IsName(subType), 'invalid font Subtype'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var composite = false |
|
|
|
|
|
|
|
if (subType.name == 'Type0') { |
|
|
|
|
|
|
|
// If font is a composite
|
|
|
|
|
|
|
|
// - get the descendant font
|
|
|
|
|
|
|
|
// - set the type according to the descendant font
|
|
|
|
|
|
|
|
// - get the FontDescriptor from the descendant font
|
|
|
|
|
|
|
|
var df = dict.get('DescendantFonts'); |
|
|
|
|
|
|
|
if (!df) |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (IsRef(df)) |
|
|
|
|
|
|
|
df = xref.fetch(df); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dict = xref.fetch(IsRef(df) ? df : df[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subType = dict.get('Subtype'); |
|
|
|
|
|
|
|
assertWellFormed(IsName(subType), 'invalid font Subtype'); |
|
|
|
|
|
|
|
composite = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Before PDF 1.5 if the font was one of the base 14 fonts, having a
|
|
|
|
|
|
|
|
// FontDescriptor was not required. This case is here for compatibility.
|
|
|
|
|
|
|
|
var descriptor = xref.fetchIfRef(dict.get('FontDescriptor')); |
|
|
|
|
|
|
|
if (!descriptor) { |
|
|
|
|
|
|
|
var baseFontName = dict.get('BaseFont'); |
|
|
|
if (!IsName(baseFontName)) |
|
|
|
if (!IsName(baseFontName)) |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
// Using base font name as a font name.
|
|
|
|
// Using base font name as a font name.
|
|
|
|
baseFontName = baseFontName.name; |
|
|
|
baseFontName = baseFontName.name; |
|
|
|
|
|
|
|
var map = {}; |
|
|
|
if (/^Symbol(-?(Bold|Italic))*$/.test(baseFontName)) { |
|
|
|
if (/^Symbol(-?(Bold|Italic))*$/.test(baseFontName)) { |
|
|
|
// special case for symbols
|
|
|
|
// special case for symbols
|
|
|
|
var encoding = Encodings.symbolsEncoding; |
|
|
|
var encoding = Encodings.symbolsEncoding; |
|
|
|
for (var i = 0, n = encoding.length, j; i < n; i++) { |
|
|
|
for (var i = 0, n = encoding.length, j; i < n; i++) { |
|
|
|
if (!(j = encoding[i])) |
|
|
|
if (!(j = encoding[i])) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
encodingMap[i] = GlyphsUnicode[j] || 0; |
|
|
|
map[i] = GlyphsUnicode[j] || 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return { |
|
|
|
return { |
|
|
|
name: baseFontName, |
|
|
|
name: baseFontName, |
|
|
|
fontDict: fontDict, |
|
|
|
dict: dict, |
|
|
|
properties: { |
|
|
|
properties: { |
|
|
|
encoding: encodingMap |
|
|
|
encoding: map |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var descriptor = xref.fetch(fd); |
|
|
|
// According to the spec if 'FontDescriptor' is declared, 'FirstChar',
|
|
|
|
|
|
|
|
// 'LastChar' and 'Widths' should exists too, but some PDF encoders seems
|
|
|
|
|
|
|
|
// to ignore this rule when a variant of a standart font is used.
|
|
|
|
|
|
|
|
// TODO Fill the width array depending on which of the base font this is
|
|
|
|
|
|
|
|
// a variant.
|
|
|
|
|
|
|
|
var firstChar = xref.fetchIfRef(dict.get('FirstChar')) || 0; |
|
|
|
|
|
|
|
var lastChar = xref.fetchIfRef(dict.get('LastChar')) || 256; |
|
|
|
|
|
|
|
var widths = xref.fetchIfRef(dict.get('Widths')) || []; |
|
|
|
|
|
|
|
|
|
|
|
var fontName = xref.fetchIfRef(descriptor.get('FontName')); |
|
|
|
var fontName = xref.fetchIfRef(descriptor.get('FontName')); |
|
|
|
assertWellFormed(IsName(fontName), 'invalid font name'); |
|
|
|
assertWellFormed(IsName(fontName), 'invalid font name'); |
|
|
|
fontName = fontName.name; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3'); |
|
|
|
var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3'); |
|
|
|
var length1, length2; |
|
|
|
|
|
|
|
if (fontFile) { |
|
|
|
if (fontFile) { |
|
|
|
fontFile = xref.fetchIfRef(fontFile); |
|
|
|
fontFile = xref.fetchIfRef(fontFile); |
|
|
|
|
|
|
|
|
|
|
|
if (fontFile.dict) { |
|
|
|
if (fontFile.dict) { |
|
|
|
var fileType = fontFile.dict.get('Subtype'); |
|
|
|
var fileType = fontFile.dict.get('Subtype'); |
|
|
|
if (fileType) |
|
|
|
if (fileType) |
|
|
|
fileType = fileType.name; |
|
|
|
fileType = fileType.name; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
length1 = fontFile.dict.get('Length1'); |
|
|
|
var length1 = fontFile.dict.get('Length1'); |
|
|
|
if (!IsInt(length1)) |
|
|
|
if (!IsInt(length1)) |
|
|
|
length1 = xref.fetchIfRef(length1); |
|
|
|
length1 = xref.fetchIfRef(length1); |
|
|
|
|
|
|
|
|
|
|
|
length2 = fontFile.dict.get('Length2'); |
|
|
|
var length2 = fontFile.dict.get('Length2'); |
|
|
|
if (!IsInt(length2)) |
|
|
|
if (!IsInt(length2)) |
|
|
|
length2 = xref.fetchIfRef(length2); |
|
|
|
length2 = xref.fetchIfRef(length2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var widths = fontDict.get('Widths'); |
|
|
|
|
|
|
|
if (widths) { |
|
|
|
|
|
|
|
var glyphWidths = {}; |
|
|
|
|
|
|
|
var unicode = fontDict.get('FirstChar'); |
|
|
|
|
|
|
|
for (var i = 0, ii = widths.length; i < ii; ++i) |
|
|
|
|
|
|
|
glyphWidths[unicode++] = widths[i]; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var properties = { |
|
|
|
var properties = { |
|
|
|
type: subType.name, |
|
|
|
type: subType.name, |
|
|
|
subtype: fileType, |
|
|
|
subtype: fileType, |
|
|
|
widths: glyphWidths, |
|
|
|
file: fontFile, |
|
|
|
encoding: encodingMap, |
|
|
|
length1: length1, |
|
|
|
differences: diffEncoding, |
|
|
|
length2: length2, |
|
|
|
glyphs: glyphsMap || GlyphsUnicode, |
|
|
|
composite: composite, |
|
|
|
firstChar: fontDict.get('FirstChar'), |
|
|
|
fixedPitch: false, |
|
|
|
lastChar: fontDict.get('LastChar'), |
|
|
|
textMatrix: IDENTITY_MATRIX, |
|
|
|
|
|
|
|
firstChar: firstChar || 0, |
|
|
|
|
|
|
|
lastChar: lastChar || 256, |
|
|
|
bbox: descriptor.get('FontBBox'), |
|
|
|
bbox: descriptor.get('FontBBox'), |
|
|
|
ascent: descriptor.get('Ascent'), |
|
|
|
ascent: descriptor.get('Ascent'), |
|
|
|
descent: descriptor.get('Descent'), |
|
|
|
descent: descriptor.get('Descent'), |
|
|
@ -4474,16 +4472,23 @@ var PartialEvaluator = (function() { |
|
|
|
capHeight: descriptor.get('CapHeight'), |
|
|
|
capHeight: descriptor.get('CapHeight'), |
|
|
|
flags: descriptor.get('Flags'), |
|
|
|
flags: descriptor.get('Flags'), |
|
|
|
italicAngle: descriptor.get('ItalicAngle'), |
|
|
|
italicAngle: descriptor.get('ItalicAngle'), |
|
|
|
fixedPitch: false, |
|
|
|
differences: [], |
|
|
|
textMatrix: IDENTITY_MATRIX, |
|
|
|
widths: [], |
|
|
|
compositeFont: compositeFont, |
|
|
|
encoding: {} |
|
|
|
length1: length1, |
|
|
|
|
|
|
|
length2: length2 |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// XXX Encoding and Glyphs should point to the same object so it will
|
|
|
|
|
|
|
|
// be hard to be out of sync. The object could contains the unicode and
|
|
|
|
|
|
|
|
// the width of the glyph.
|
|
|
|
|
|
|
|
for (var i = 0; i <= widths.length; i++) |
|
|
|
|
|
|
|
properties.widths[firstChar++] = widths[i]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
properties.glyphs = this.extractEncoding(dict, xref, properties); |
|
|
|
|
|
|
|
log(properties.encoding); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
return { |
|
|
|
name: fontName, |
|
|
|
name: fontName.name, |
|
|
|
fontDict: fontDict, |
|
|
|
dict: dict, |
|
|
|
file: fontFile, |
|
|
|
file: fontFile, |
|
|
|
properties: properties |
|
|
|
properties: properties |
|
|
|
}; |
|
|
|
}; |
|
|
@ -4887,7 +4892,7 @@ var CanvasGraphics = (function() { |
|
|
|
// This is a poor simulation for Arial Narrow while font-stretch
|
|
|
|
// This is a poor simulation for Arial Narrow while font-stretch
|
|
|
|
// is not implemented (bug 3512)
|
|
|
|
// is not implemented (bug 3512)
|
|
|
|
if (current.font.narrow) { |
|
|
|
if (current.font.narrow) { |
|
|
|
textHScale += 0.2; |
|
|
|
textHScale += 0.6; |
|
|
|
charSpacing -= (0.09 * current.fontSize); |
|
|
|
charSpacing -= (0.09 * current.fontSize); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|