diff --git a/src/canvas.js b/src/canvas.js index cc6d50ded..32c171216 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -1196,20 +1196,20 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { // Marked content markPoint: function CanvasGraphics_markPoint(tag) { - TODO('Marked content'); + // TODO Marked content. }, markPointProps: function CanvasGraphics_markPointProps(tag, properties) { - TODO('Marked content'); + // TODO Marked content. }, beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { - TODO('Marked content'); + // TODO Marked content. }, beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( tag, properties) { - TODO('Marked content'); + // TODO Marked content. }, endMarkedContent: function CanvasGraphics_endMarkedContent() { - TODO('Marked content'); + // TODO Marked content. }, // Compatibility diff --git a/src/core.js b/src/core.js index 409ae060d..2b9481041 100644 --- a/src/core.js +++ b/src/core.js @@ -52,8 +52,16 @@ function getPdf(arg, callback) { if ('progress' in params) xhr.onprogress = params.progress || undefined; - if ('error' in params) - xhr.onerror = params.error || undefined; + var calledErrorBack = false; + + if ('error' in params) { + xhr.onerror = function errorBack() { + if (!calledErrorBack) { + calledErrorBack = true; + params.error(); + } + } + } xhr.onreadystatechange = function getPdfOnreadystatechange(e) { if (xhr.readyState === 4) { @@ -61,7 +69,8 @@ function getPdf(arg, callback) { var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response); callback(data); - } else if (params.error) { + } else if (params.error && !calledErrorBack) { + calledErrorBack = true; params.error(e); } } diff --git a/src/fonts.js b/src/fonts.js index c955c4d1a..7b2dfbd4a 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -3391,8 +3391,8 @@ var Type1Parser = function type1Parser() { '1': 'vstem', '2': 'hstem', + '6': 'endchar', // seac // Type1 only command with command not (yet) built-in ,throw an error - '6': -1, // seac '7': -1, // sbw '11': 'sub', @@ -3422,6 +3422,43 @@ var Type1Parser = function type1Parser() { var kEscapeCommand = 12; + // Breaks up the stack by arguments and also calculates the value. + function breakUpArgs(stack, numArgs) { + var args = []; + var index = stack.length - 1; + for (var i = 0; i < numArgs; i++) { + if (index < 0) { + args.unshift({ arg: [0], + value: 0, + offset: 0 }); + warn('Malformed charstring stack: not enough values on stack.'); + continue; + } + var token = stack[index]; + if (token === 'div') { + var a = stack[index - 2]; + var b = stack[index - 1]; + if (!isInt(a) || !isInt(b)) { + warn('Malformed charsting stack: expected ints on stack for div.'); + a = 0; + b = 1; + } + args.unshift({ arg: [a, b, 'div'], + value: a / b, + offset: index - 2 }); + index -= 3; + } else if (isInt(token)) { + args.unshift({ arg: stack.slice(index, index + 1), + value: token, + offset: index }); + index--; + } else { + warn('Malformed charsting stack: found bad token ' + token + '.'); + } + } + return args; + } + function decodeCharString(array) { var charstring = []; var lsb = 0; @@ -3464,6 +3501,12 @@ var Type1Parser = function type1Parser() { // pop or setcurrentpoint commands can be ignored // since we are not doing callothersubr continue; + } else if (escape == 6) { + // seac is like type 2's special endchar but it doesn't use the + // first argument asb, so remove it. + var args = breakUpArgs(charstring, 5); + var arg0 = args[0]; + charstring.splice(arg0.offset, arg0.arg.length); } else if (!kHintingEnabled && (escape == 1 || escape == 2)) { charstring.push('drop', 'drop', 'drop', 'drop', 'drop', 'drop'); continue; @@ -3471,25 +3514,17 @@ var Type1Parser = function type1Parser() { command = charStringDictionary['12'][escape]; } else { - // TODO Clean this code if (value == 13) { // hsbw - if (charstring.length == 2) { - lsb = charstring[0]; - width = charstring[1]; - charstring.splice(0, 1); - } else if (charstring.length == 4 && charstring[3] == 'div') { - lsb = charstring[0]; - width = charstring[1] / charstring[2]; - charstring.splice(0, 1); - } else if (charstring.length == 4 && charstring[2] == 'div') { - lsb = charstring[0] / charstring[1]; - width = charstring[3]; - charstring.splice(0, 3); - } else { - error('Unsupported hsbw format: ' + charstring); - } - - charstring.push(lsb, 'hmoveto'); + var args = breakUpArgs(charstring, 2); + var arg0 = args[0]; + var arg1 = args[1]; + lsb = arg0.value; + width = arg1.value; + // To convert to type2 we have to move the width value to the first + // part of the charstring and then use hmoveto with lsb. + charstring = arg1.arg; + charstring = charstring.concat(arg0.arg); + charstring.push('hmoveto'); continue; } else if (value == 10) { // callsubr if (charstring[charstring.length - 1] < 3) { // subr #0..2 diff --git a/test/pdfs/issue818.pdf.link b/test/pdfs/issue818.pdf.link new file mode 100644 index 000000000..c7ed0236a --- /dev/null +++ b/test/pdfs/issue818.pdf.link @@ -0,0 +1 @@ +http://www.effi.org/system/files?file=effi-siv-251110.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index ffcf10bed..1b372e906 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -633,5 +633,13 @@ "pageLimit": 2, "link": true, "type": "eq" + }, + { "id": "issue818", + "file": "pdfs/issue818.pdf", + "md5": "dd2f8a5bd65164ad74da2b45a6ca90cc", + "rounds": 1, + "pageLimit": 1, + "link": true, + "type": "eq" } ]