Starts playing with the execution stack
This commit is contained in:
parent
e936f305d7
commit
e739bcc515
148
PDFFont.js
148
PDFFont.js
@ -155,9 +155,19 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
peek: function() {
|
peek: function() {
|
||||||
|
if (!this.length)
|
||||||
|
return null;
|
||||||
return this.__innerStack__[this.__innerStack__.length - 1];
|
return this.__innerStack__[this.__innerStack__.length - 1];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toString: function() {
|
||||||
|
log("=== Start Dumping operandStack ===");
|
||||||
|
var str = [];
|
||||||
|
for (var i = 0; i < this.__innerStack__.length; i++)
|
||||||
|
log(this.__innerStack__[i]);
|
||||||
|
log("=== End Dumping operandStack ===");
|
||||||
|
},
|
||||||
|
|
||||||
get length() {
|
get length() {
|
||||||
return this.__innerStack__.length;
|
return this.__innerStack__.length;
|
||||||
}
|
}
|
||||||
@ -194,9 +204,15 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
peek: function() {
|
peek: function() {
|
||||||
|
if (!this.length)
|
||||||
|
return null;
|
||||||
return this.__innerStack__[this.__innerStack__.length - 1];
|
return this.__innerStack__[this.__innerStack__.length - 1];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get: function(aIndex) {
|
||||||
|
return this.__innerStack__[aIndex];
|
||||||
|
},
|
||||||
|
|
||||||
get length() {
|
get length() {
|
||||||
return this.__innerStack__.length;
|
return this.__innerStack__.length;
|
||||||
}
|
}
|
||||||
@ -212,7 +228,42 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
* object off the execution stack and resumes executing the suspended object
|
* object off the execution stack and resumes executing the suspended object
|
||||||
* beneath it.
|
* beneath it.
|
||||||
*/
|
*/
|
||||||
var executionStack = [];
|
var executionStack = {
|
||||||
|
__innerStack__: [],
|
||||||
|
|
||||||
|
push: function(aProcedure) {
|
||||||
|
this.__innerStack__.push(aProcedure);
|
||||||
|
},
|
||||||
|
|
||||||
|
pop: function() {
|
||||||
|
return this.__innerStack__.pop();
|
||||||
|
},
|
||||||
|
|
||||||
|
peek: function() {
|
||||||
|
if (!this.length)
|
||||||
|
return null;
|
||||||
|
return this.__innerStack__[this.__innerStack__.length - 1];
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function(aIndex) {
|
||||||
|
return this.__innerStack__[aIndex];
|
||||||
|
},
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this.__innerStack__.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextInStack() {
|
||||||
|
var currentProcedure = executionStack.peek();
|
||||||
|
if (currentProcedure) {
|
||||||
|
var command = currentProcedure.shift();
|
||||||
|
if (!currentProcedure.length)
|
||||||
|
executionStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lexer.getObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -222,29 +273,65 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
* The method thrown an error if it encounters an unknown token.
|
* The method thrown an error if it encounters an unknown token.
|
||||||
*/
|
*/
|
||||||
this.getObj = function() {
|
this.getObj = function() {
|
||||||
var obj = lexer.getObj();
|
var obj = nextInStack();
|
||||||
|
|
||||||
if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") &&
|
if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") &&
|
||||||
!IsCmd(obj, "}") && !IsCmd(obj, "]")) {
|
!IsCmd(obj, "}") && !IsCmd(obj, "]")) {
|
||||||
|
dump("Adding: " + obj);
|
||||||
operandStack.peek().push(obj);
|
operandStack.peek().push(obj);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "{") || IsCmd(obj, "[")) {
|
} else if (IsCmd(obj, "{") || IsCmd(obj, "[")) {
|
||||||
dump("Start Array: " + obj);
|
dump("Start" + (obj.cmd == "{" ? " Executable " : " ") + "Array");
|
||||||
operandStack.push([]);
|
operandIsArray ? operandStack.peek().push([]) : operandStack.push([]);
|
||||||
operandIsArray++;
|
operandIsArray++;
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "}") || IsCmd(obj, "]")) {
|
} else if (IsCmd(obj, "}") || IsCmd(obj, "]")) {
|
||||||
dump("End Array: " + obj);
|
dump("End" + (obj.cmd == "}" ? " Executable " : " ") + "Array");
|
||||||
operandIsArray--;
|
operandIsArray--;
|
||||||
this.getObj();
|
this.getObj();
|
||||||
|
} else if (IsCmd(obj, "if")) {
|
||||||
|
log("if");
|
||||||
|
var procedure = operandStack.pop();
|
||||||
|
var bool = operandStack.pop();
|
||||||
|
if (!IsBool(bool)) {
|
||||||
|
executionStack.push(bool);
|
||||||
|
log(".....");
|
||||||
|
this.getObj();
|
||||||
|
}
|
||||||
|
log(bool);
|
||||||
|
if (bool)
|
||||||
|
executionStack.push(procedure);
|
||||||
|
|
||||||
|
this.getObj();
|
||||||
|
} else if (IsCmd(obj, "ifelse")) {
|
||||||
|
log("ifelse");
|
||||||
|
var procedure1 = operandStack.pop();
|
||||||
|
var procedure2 = operandStack.pop();
|
||||||
|
var bool = !!operandStack.pop();
|
||||||
|
operandStack.push(bool ? procedure1 : procedure2);
|
||||||
|
this.getObj();
|
||||||
} else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) {
|
} else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) {
|
||||||
//dump("Value: " + obj);
|
dump("Value: " + obj);
|
||||||
operandStack.push(obj);
|
operandStack.push(obj);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "dup")) {
|
} else if (IsCmd(obj, "dup")) {
|
||||||
dump("Duplicate");
|
dump("Duplicate");
|
||||||
operandStack.push(operandStack.peek());
|
operandStack.push(operandStack.peek());
|
||||||
this.getObj();
|
this.getObj();
|
||||||
|
} else if (IsCmd(obj, "put") || IsCmd(obj, "NP")) {
|
||||||
|
operandStack.toString();
|
||||||
|
|
||||||
|
var data = operandStack.pop();
|
||||||
|
var indexOrKey = operandStack.pop();
|
||||||
|
var object = operandStack.pop();
|
||||||
|
log(object);
|
||||||
|
log("put " + data + " in " + obj + "[" + indexOrKey + "]");
|
||||||
|
|
||||||
|
if (object.set)
|
||||||
|
object.set(indexOrKey, data);
|
||||||
|
else
|
||||||
|
object[indexOrKey] = data;
|
||||||
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "currentdict")) {
|
} else if (IsCmd(obj, "currentdict")) {
|
||||||
dump("currentdict");
|
dump("currentdict");
|
||||||
operandStack.push(dictionaryStack.peek());
|
operandStack.push(dictionaryStack.peek());
|
||||||
@ -254,13 +341,18 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
operandStack.push(systemDict);
|
operandStack.push(systemDict);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") ||
|
} else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") ||
|
||||||
IsCmd(obj, "currentfile") || IsCmd(obj, "NP")) {
|
IsCmd(obj, "noaccess") || IsCmd(obj, "currentfile")) {
|
||||||
// Do nothing for the moment
|
// Do nothing for the moment
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsName(obj)) {
|
} else if (IsName(obj)) {
|
||||||
//dump("Name: " + obj.name);
|
//dump("Name: " + obj.name);
|
||||||
operandStack.push(obj.name);
|
operandStack.push(obj.name);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
|
} else if (IsCmd(obj, "array")) {
|
||||||
|
var size = operandStack.pop();
|
||||||
|
var array = new Array(size);
|
||||||
|
operandStack.push(array);
|
||||||
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "dict")) {
|
} else if (IsCmd(obj, "dict")) {
|
||||||
dump("Dict: " + obj);
|
dump("Dict: " + obj);
|
||||||
var size = operandStack.pop();
|
var size = operandStack.pop();
|
||||||
@ -275,10 +367,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
dump("Ending a dictionary");
|
dump("Ending a dictionary");
|
||||||
dictionaryStack.pop();
|
dictionaryStack.pop();
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "def")) {
|
} else if (IsCmd(obj, "def") || IsCmd(obj, "ND")) {
|
||||||
var value = operandStack.pop();
|
var value = operandStack.pop();
|
||||||
var key = operandStack.pop();
|
var key = operandStack.pop();
|
||||||
dump("def: " + key + " = " + value);
|
log("def: " + key + " = " + value);
|
||||||
dictionaryStack.peek().set(key, value);
|
dictionaryStack.peek().set(key, value);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "eexec")) {
|
} else if (IsCmd(obj, "eexec")) {
|
||||||
@ -292,8 +384,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
dump("known");
|
dump("known");
|
||||||
var name = operandStack.pop();
|
var name = operandStack.pop();
|
||||||
var dict = operandStack.pop();
|
var dict = operandStack.pop();
|
||||||
// returns dict.hasKey(name);
|
operandStack.push(!!dict.get(name));
|
||||||
|
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "RD")) {
|
} else if (IsCmd(obj, "RD")) {
|
||||||
dump("RD");
|
dump("RD");
|
||||||
@ -311,21 +402,50 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
|
|||||||
dictionaryStack.peek().set(key, charStream);
|
dictionaryStack.peek().set(key, charStream);
|
||||||
|
|
||||||
var decodedCharString = decodeCharString(charStream);
|
var decodedCharString = decodeCharString(charStream);
|
||||||
log(decodedCharString);
|
dump(decodedCharString);
|
||||||
|
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "LenIV")) {
|
} else if (IsCmd(obj, "LenIV")) {
|
||||||
error("LenIV: argh! we need to modify the length of discard characters for charStrings");
|
error("LenIV: argh! we need to modify the length of discard characters for charStrings");
|
||||||
} else if (IsCmd(obj, "closefile")) {
|
} else if (IsCmd(obj, "closefile")) {
|
||||||
// End of binary data;
|
// End of binary data;
|
||||||
|
} else if (IsCmd(obj, "index")) {
|
||||||
|
var operands = [];
|
||||||
|
var size = operandStack.pop();
|
||||||
|
for (var i = 0; i < size; i++)
|
||||||
|
operands.push(operandStack.pop());
|
||||||
|
|
||||||
|
var newOperand = operandStack.peek();
|
||||||
|
|
||||||
|
for (var i = 0; i < operands.length; i++)
|
||||||
|
operandStack.push(operands.pop());
|
||||||
|
|
||||||
|
operandStack.push(newOperand);
|
||||||
|
this.getObj();
|
||||||
} else if (IsCmd(obj, "StandardEncoding")) {
|
} else if (IsCmd(obj, "StandardEncoding")) {
|
||||||
// For some reason the value is considered as a command, maybe it is
|
// For some reason the value is considered as a command, maybe it is
|
||||||
// because of the uppercae 'S'
|
// because of the uppercae 'S'
|
||||||
operandStack.push(obj.cmd);
|
operandStack.push(obj.cmd);
|
||||||
this.getObj();
|
this.getObj();
|
||||||
} else {
|
} else {
|
||||||
dump(obj);
|
var command = null;
|
||||||
error("Unknow token while parsing font");
|
if (IsCmd(obj)) {
|
||||||
|
for (var i = 0; i < dictionaryStack.length; i++) {
|
||||||
|
command = dictionaryStack.get(i).get(obj.cmd);
|
||||||
|
if (command)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command) {
|
||||||
|
// XXX add the command to the execution stack
|
||||||
|
this.getObj();
|
||||||
|
} else {
|
||||||
|
log("operandStack: " + operandStack);
|
||||||
|
log("dictionaryStack: " + dictionaryStack);
|
||||||
|
dump(obj);
|
||||||
|
error("Unknow token while parsing font");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return operandStack.peek();
|
return operandStack.peek();
|
||||||
|
Loading…
Reference in New Issue
Block a user