From ac005ed359e0e191cfbfa203ce4d5a894b3646c6 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 18 Jul 2012 16:23:51 -0700 Subject: [PATCH 1/3] Support more type 1 font hsbw formats. --- src/fonts.js | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index c955c4d1a..00937ea08 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -3422,6 +3422,27 @@ var Type1Parser = function type1Parser() { var kEscapeCommand = 12; + // The initial stack can have numbers expressed with the div command which + // need to be calculated before conversion. Looking at the spec it doesn't + // appear div should even be allowed as a first command but there have been + // a number of fonts that have this. + function evaluateStack(stack) { + var newStack = []; + for (var i = 0, ii = stack.length; i < ii; i++) { + var token = stack[i]; + if (token === 'div') { + var b = newStack.pop(); + var a = newStack.pop(); + newStack.push(a / b); + } else if (isInt(token)) { + newStack.push(token); + } else { + warn('Unsupported initial stack ' + stack); + } + } + return newStack; + } + function decodeCharString(array) { var charstring = []; var lsb = 0; @@ -3471,24 +3492,13 @@ 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 = evaluateStack(charstring); + if (charstring.length !== 2) + warn('Unsupported hsbw format.'); + lsb = charstring[0]; + width = charstring[1]; + charstring.splice(0, 1); charstring.push(lsb, 'hmoveto'); continue; } else if (value == 10) { // callsubr From 8fccd199484c7bd1935da23c08c7df39293d8ecd Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Thu, 19 Jul 2012 18:06:37 -0700 Subject: [PATCH 2/3] Leave div commands on stack and change evaluation. --- src/fonts.js | 57 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 00937ea08..7f005e418 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -3422,25 +3422,35 @@ var Type1Parser = function type1Parser() { var kEscapeCommand = 12; - // The initial stack can have numbers expressed with the div command which - // need to be calculated before conversion. Looking at the spec it doesn't - // appear div should even be allowed as a first command but there have been - // a number of fonts that have this. - function evaluateStack(stack) { - var newStack = []; - for (var i = 0, ii = stack.length; i < ii; i++) { - var token = stack[i]; - if (token === 'div') { - var b = newStack.pop(); - var a = newStack.pop(); - newStack.push(a / b); - } else if (isInt(token)) { - newStack.push(token); + // 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 }); + warn('Malformed charstring stack: not enough values on stack.'); + continue; + } + if (stack[index] === '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 }); + index -= 3; } else { - warn('Unsupported initial stack ' + stack); + args.unshift({ arg: stack.slice(index, index + 1), + value: stack[index] }); + index--; } } - return newStack; + return args; } function decodeCharString(array) { @@ -3493,13 +3503,14 @@ var Type1Parser = function type1Parser() { command = charStringDictionary['12'][escape]; } else { if (value == 13) { // hsbw - charstring = evaluateStack(charstring); - if (charstring.length !== 2) - warn('Unsupported hsbw format.'); - lsb = charstring[0]; - width = charstring[1]; - charstring.splice(0, 1); - charstring.push(lsb, 'hmoveto'); + var args = breakUpArgs(charstring, 2); + lsb = args[0]['value']; + width = args[1]['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 = args[1]['arg']; + charstring = charstring.concat(args[0]['arg']); + charstring.push('hmoveto'); continue; } else if (value == 10) { // callsubr if (charstring[charstring.length - 1] < 3) { // subr #0..2 From 34eb537160feb14d23285696e7a0d2eb76b31a8d Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 20 Jul 2012 13:48:48 -0700 Subject: [PATCH 3/3] Add another warning for malformed stack. Fix/add variable names. --- src/fonts.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 7f005e418..a99103f63 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -3433,7 +3433,8 @@ var Type1Parser = function type1Parser() { warn('Malformed charstring stack: not enough values on stack.'); continue; } - if (stack[index] === 'div') { + var token = stack[index]; + if (token === 'div') { var a = stack[index - 2]; var b = stack[index - 1]; if (!isInt(a) || !isInt(b)) { @@ -3444,10 +3445,12 @@ var Type1Parser = function type1Parser() { args.unshift({ arg: [a, b, 'div'], value: a / b }); index -= 3; - } else { + } else if (isInt(token)) { args.unshift({ arg: stack.slice(index, index + 1), - value: stack[index] }); + value: token }); index--; + } else { + warn('Malformed charsting stack: found bad token ' + token + '.'); } } return args; @@ -3504,12 +3507,14 @@ var Type1Parser = function type1Parser() { } else { if (value == 13) { // hsbw var args = breakUpArgs(charstring, 2); - lsb = args[0]['value']; - width = args[1]['value']; + 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 = args[1]['arg']; - charstring = charstring.concat(args[0]['arg']); + charstring = arg1.arg; + charstring = charstring.concat(arg0.arg); charstring.push('hmoveto'); continue; } else if (value == 10) { // callsubr