diff --git a/fonts.js b/fonts.js index b1c164df7..424379284 100644 --- a/fonts.js +++ b/fonts.js @@ -440,6 +440,7 @@ var Font = (function Font() { // name ArialBlack for example will be replaced by Helvetica. this.black = (name.search(/Black/g) != -1); + this.defaultWidth = properties.defaultWidth; this.loadedName = fontName.split('-')[0]; this.loading = false; return; @@ -476,6 +477,7 @@ var Font = (function Font() { this.data = data; this.type = properties.type; this.textMatrix = properties.textMatrix; + this.defaultWidth = properties.defaultWidth; this.loadedName = getUniqueName(); this.composite = properties.composite; this.loading = true; @@ -1424,15 +1426,15 @@ var Font = (function Font() { return rule; }, - charsToUnicode: function fonts_chars2Unicode(chars) { + charsToGlyphs: function fonts_chars2Glyphs(chars) { var charsCache = this.charsCache; - var str; + var glyphs; // if we translated this string before, just grab it from the cache if (charsCache) { - str = charsCache[chars]; - if (str) - return str; + glyphs = charsCache[chars]; + if (glyphs) + return glyphs; } // lazily create the translation cache @@ -1443,7 +1445,8 @@ var Font = (function Font() { var encoding = this.encoding; if (!encoding) return chars; - str = ''; + + glyphs = []; if (this.composite) { // composite fonts have multi-byte strings convert the string from @@ -1454,38 +1457,39 @@ var Font = (function Font() { // loop should never end on the last byte for (var i = 0; i < length; i++) { var charcode = int16([chars.charCodeAt(i++), chars.charCodeAt(i)]); - var unicode = encoding[charcode]; - if ('undefined' == typeof(unicode)) { + var glyph = encoding[charcode]; + if ('undefined' == typeof(glyph)) { warn('Unencoded charcode ' + charcode); - unicode = charcode; - } else { - unicode = unicode.unicode; + glyph = { + unicode: charcode, + width: this.defaultWidth + }; } - str += String.fromCharCode(unicode); + glyphs.push(glyph); + // placing null after each word break charcode (ASCII SPACE) + if (charcode == 0x20) + glyphs.push(null); } } else { for (var i = 0; i < chars.length; ++i) { var charcode = chars.charCodeAt(i); - var unicode = encoding[charcode]; - if ('undefined' == typeof(unicode)) { + var glyph = encoding[charcode]; + if ('undefined' == typeof(glyph)) { warn('Unencoded charcode ' + charcode); - unicode = charcode; - } else { - unicode = unicode.unicode; - } - - // Handle surrogate pairs - if (unicode > 0xFFFF) { - str += String.fromCharCode(unicode & 0xFFFF); - unicode >>= 16; + glyph = { + unicode: charcode, + width: this.defaultWidth + }; } - str += String.fromCharCode(unicode); + glyphs.push(glyph); + if (charcode == 0x20) + glyphs.push(null); } } // Enter the translated string into the cache - return (charsCache[chars] = str); + return (charsCache[chars] = glyphs); } }; diff --git a/pdf.js b/pdf.js index 6ce70215f..e3e5a9799 100644 --- a/pdf.js +++ b/pdf.js @@ -4301,7 +4301,6 @@ var PartialEvaluator = (function() { }; } } else if (type == 'CIDFontType0') { - encoding = xref.fetchIfRef(dict.get('Encoding')); if (IsName(encoding)) { // Encoding is a predefined CMap if (encoding.name == 'Identity-H') { @@ -4362,6 +4361,7 @@ var PartialEvaluator = (function() { // merge in the differences var firstChar = properties.firstChar; var lastChar = properties.lastChar; + var widths = properties.widths || []; var glyphs = {}; for (var i = firstChar; i <= lastChar; i++) { var glyph = differences[i]; @@ -4372,7 +4372,7 @@ var PartialEvaluator = (function() { continue; } var index = GlyphsUnicode[glyph] || i; - var width = properties.widths[i] || properties.widths[glyph]; + var width = widths[i] || widths[glyph]; map[i] = { unicode: index, width: IsNum(width) ? width : properties.defaultWidth @@ -4543,7 +4543,7 @@ var PartialEvaluator = (function() { type: type.name, encoding: map, differences: [], - widths: widths, + widths: widths || {}, defaultWidth: defaultWidth, firstChar: 0, lastChar: 256 @@ -4934,7 +4934,7 @@ var CanvasGraphics = (function() { font = font.get(fontRef.name); font = this.xref.fetchIfRef(font); if (!font) - return; + error('Referenced font is not found'); var fontObj = font.fontObj; this.current.font = fontObj; @@ -4986,22 +4986,15 @@ var CanvasGraphics = (function() { showText: function(text) { var ctx = this.ctx; var current = this.current; - var originalText = text; + var font = current.font; ctx.save(); ctx.transform.apply(ctx, current.textMatrix); ctx.scale(1, -1); - ctx.translate(current.x, -1 * current.y); + ctx.transform.apply(ctx, font.textMatrix || IDENTITY_MATRIX); - var font = current.font; - if (font) { - ctx.transform.apply(ctx, font.textMatrix || IDENTITY_MATRIX); - text = font.charsToUnicode(text); - } - - var composite = font.composite; - var encoding = font.encoding; + var glyphs = font.charsToGlyphs(text); var fontSize = current.fontSize; var charSpacing = current.charSpacing; var wordSpacing = current.wordSpacing; @@ -5009,22 +5002,23 @@ var CanvasGraphics = (function() { ctx.scale(1 / textHScale, 1); var width = 0; - for (var i = 0; i < text.length; i++) { - if (composite) { - var position = i * 2 + 1; - var charcode = (originalText.charCodeAt(position - 1) << 8) + - originalText.charCodeAt(position); - } else { - var charcode = originalText.charCodeAt(i); + for (var i = 0; i < glyphs.length; i++) { + var glyph = glyphs[i]; + if (glyph === null) { + // word break + width += wordSpacing; + continue; } - var charWidth = font.encoding[charcode].width * fontSize * 0.001; + var unicode = glyph.unicode; + var char = unicode >= 0x10000 ? + String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10), + 0xDC00 | (unicode & 0x3FF)) : String.fromCharCode(unicode); + + var charWidth = glyph.width * fontSize * 0.001; charWidth += charSpacing; - if (charcode == 32) - charWidth += wordSpacing; - ctx.fillText(text.charAt(i), 0, 0); - ctx.translate(charWidth, 0); + ctx.fillText(char, width, 0); width += charWidth; } current.x += width; diff --git a/test/pdfs/fips197.pdf.link b/test/pdfs/fips197.pdf.link new file mode 100644 index 000000000..815eb1d48 --- /dev/null +++ b/test/pdfs/fips197.pdf.link @@ -0,0 +1 @@ +http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index 66d26c4e9..44955eefa 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -127,5 +127,11 @@ "link": true, "rounds": 1, "type": "eq" + }, + { "id": "fips197", + "file": "pdfs/fips197.pdf", + "link": true, + "rounds": 1, + "type": "load" } ]