commit 63f258e83e92979388721f57ff1f9500140f6ea6
parent 900ea78da3b57a7c03a76609c671676c2bd13dd1
Author: tomas <tomas@logand.com>
Date: Sat, 23 Jan 2010 14:23:42 +0100
Second commit
Diffstat:
M | wps.js | | | 794 | +++++++++++++++++++++++++++---------------------------------------------------- |
M | wps.wps | | | 411 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
2 files changed, 490 insertions(+), 715 deletions(-)
diff --git a/wps.js b/wps.js
@@ -1,252 +1,265 @@
function PdfT(V) {
- this.V = V;
- return this;
+ this.V = V;
+ return this;
}
+
function isPdfT(V) {
- return V.constructor == PdfT; // TODO better test
+ return V.constructor == PdfT; // TODO better test
}
function ps0(L, F, S) {
- var N = L.length;
- var I = 0;
- if(!S) S = [];
-
- function member(C, L) {return 0 <= L.indexOf(C);}
- function peek() {return I < N && L[I];}
- function xchar() {return I < N && L[I++];}
- function skip() {while(I < N && member(L[I], " \t\n")) I++;}
-
- function comment() {
- while("%" == peek()) {
- while(peek() && "\n" != peek())
- xchar();
- skip();
- }
- }
-
- function text() {
- xchar();
- var L = [];
- var N = 1;
- while(0 < N && peek()) {
- var C = xchar();
- switch(C) {
- case "(":
- N++;
- break;
- case ")":
- N--;
- if(N <= 0) C = false;
- break;
- case "\\":
- C = xchar();
- switch(C) {
- case "(": break;
- case ")": break;
- case "\\": break;
- case "n": C = "\n"; break;
- case "r": C = "\r"; break;
- case "t": C = "\t"; break;
- default:
- C = false;
- }
- break;
- }
- if(C !== false) L.push(C);
- }
- return new PdfT(L.join(""));
- }
-
- function symbol() {
+ var N = L.length;
+ var I = 0;
+
+ function member(C, L) {return 0 <= L.indexOf(C);}
+ function peek() {return I < N && L[I];}
+ function xchar() {return I < N && L[I++];}
+ function skip() {while(I < N && member(L[I], " \t\n")) I++;}
+
+ function comment() {
+ while("%" == peek()) {
+ while(peek() && "\n" != peek())
+ xchar();
+ skip();
+ }
+ }
+
+ function text() { // TODO hex text in <>
+ xchar();
+ var L = [];
+ var N = 1;
+ while(0 < N && peek()) {
var C = xchar();
- var N = member(C, "+-0123456789.");
- var F = "." == C;
- var L = [C];
- while(peek() && !member(peek(), "%/[]{}<>( \t\n")) {
- C = xchar();
- L.push(C);
- if(N && !member(C, "0123456789")) {
- if(!F && "." == C) F = true;
- else N = false;
- }
+ switch(C) {
+ case "(":
+ N++;
+ break;
+ case ")":
+ N--;
+ if(N <= 0) C = false;
+ break;
+ case "\\":
+ C = xchar();
+ switch(C) {
+ case "(": break;
+ case ")": break;
+ case "\\": break;
+ case "n": C = "\n"; break;
+ case "r": C = "\r"; break;
+ case "t": C = "\t"; break;
+ default:
+ C = false;
+ }
+ break;
}
- L = L.join("");
- if(1 == L.length && member(L, "+-.")) N = false;
- return N ? (F ? parseFloat(L) : parseInt(L, 10)) : L;
- }
-
- function code() {
- xchar();
- var L = [];
- while(peek()) {
- var T = token();
- if("}" == T) break;
- if(T || T == 0) L.push(T);
+ if(C !== false) L.push(C);
+ }
+ return new PdfT(L.join(""));
+ }
+
+ function symbol() {
+ var C = xchar();
+ var N = member(C, "+-0123456789.");
+ var F = "." == C;
+ var L = [C];
+ while(peek() && !member(peek(), "%/[]{}<>( \t\n")) {
+ C = xchar();
+ L.push(C);
+ if(N && !member(C, "0123456789")) {
+ if(!F && "." == C) F = true;
+ else N = false;
}
- return L;
- }
-
- function token() {
- skip();
- switch(peek()) {
- case false: return undefined;
- case "%": return comment();
- case "[": return xchar();
- case "]": return xchar();
- case "{": return code();
- case "}": return xchar();
- case "(": return text();
- default: return symbol();
- }
- }
+ }
+ L = L.join("");
+ if(1 == L.length && member(L, "+-.")) N = false;
+ return N ? (F ? parseFloat(L) : parseInt(L, 10)) : L;
+ }
+
+ function proc() { // TODO supress evaluation???
+ xchar();
+ var L = [];
+ while(peek()) {
+ var T = token();
+ if("}" == T) break;
+ if(T || T == 0) L.push(T);
+ }
+ return L;
+ }
+
+ function token() {
+ skip();
+ switch(peek()) { // TODO read dict in <<>>
+ case false: return undefined;
+ case "%": return comment();
+ case "[": return xchar();
+ case "]": return xchar();
+ case "{": return proc();
+ case "}": return xchar();
+ case "(": return text();
+ default: return symbol();
+ }
+ }
// function quoted(T) {
// return typeof T == "string" && "/" == T.charAt(0);
// }
- function parse(E) {
- var G = true;
- while(G && peek()) {
- var T = token();
- if(T || T == 0) {
- if(typeof T == "number" || typeof T == "object" || quoted(T))
- S.push(T);
- else {
- if(F[T]) F[T]();
- else throw "Unknown operator '" + T + "' " + typeof T;
- if(E == T) G = false;
- }
- }
+ function parse(E) {
+ var G = true;
+ while(G && peek()) {
+ var T = token();
+ if(T || T == 0) {
+ if(typeof T == "number" || typeof T == "object" || quoted(T))
+ S.push(T);
+ else {
+ if(F[T]) F[T]();
+ else throw "Unknown operator '" + T + "' " + typeof T;
+ if(E == T) G = false;
+ }
}
- return S;
- }
+ }
+ return S;
+ }
- return parse();
+ return parse();
}
function quoted(T) {
- return typeof T == "string" && "/" == T.charAt(0);
+ return typeof T == "string" && "/" == T.charAt(0);
}
-function wps(E, W, H, T) {
- var S = [];
- var F = {};
- var C = E.getContext("2d");
-
- E.setAttribute("width", W);
- E.setAttribute("height", H);
-
- function min(X, Y) {
- return X < Y ? X : Y;
- }
- function max(X, Y) {
- return X < Y ? Y : X;
- }
-
- // basic operators
-
- F["true"] = function() {S.push(true);};
- F["false"] = function() {S.push(false);};
- F["null"] = function() {S.push(null);};
-
- F["neg"] = function() {S.push(- S.pop());};
- F["add"] = function() {S.push(S.pop() + S.pop());};
- F["sub"] = function() {F["neg"](); F["add"]();};
- F["mul"] = function() {S.push(S.pop() * S.pop());};
- F["div"] = function() {
- var X = S.pop();
- S.push(S.pop() / X);
- };
- F["idiv"] = function() {
- var X = S.pop();
- S.push(Math.floor(S.pop() / X));
- };
- F["mod"] = function() {
- var X = S.pop();
- S.push(S.pop() % X);
- };
- // TODO sqrt, exp, ceiling, sin
- F["exch"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(Y);
- S.push(X);
- };
-
- F["dup"] = function() {var X = S.pop(); S.push(X); S.push(X);};
- F["clear"] = function() {S = [];};
- F["pop"] = function() {S.pop();};
- // TODO roll
-
- F["eq"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X == Y);
- };
- F["ne"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X != Y);
- };
- F["gt"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X > Y);
- };
- F["lt"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X < Y);
- };
- F["ge"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X >= Y);
- };
- F["le"] = function() {
- var Y = S.pop();
- var X = S.pop();
- S.push(X <= Y);
- };
-
- F["if"] = function() {
- var B = S.pop();
- var C = S.pop();
- if(C == true) run(B);
- };
- F["ifelse"] = function() {
- var N = S.pop();
- var P = S.pop();
- var C = S.pop();
- if(C == true) run(P);
- else run(N);
- };
- F["repeat"] = function() {
- var B = S.pop();
- var N = S.pop();
- for(var I = 0; I < N; I++) run(B);
- };
- F["for"] = function() {
- var B = S.pop();
- var L = S.pop();
- var K = S.pop();
- var J = S.pop();
- if(K < 0) {
- for(var I = J; L <= I; I += K) {
- S.push(I);
- run(B);
- }
- } else {
- for(var I = J; I <= L; I += K) {
- S.push(I);
- run(B);
- }
+function wps(E, T) {
+ var S = [];
+ var F = {};
+ var C = E.getContext("2d");
+
+ F["get"] = function() { // dict key -- any
+ var K = S.pop();
+ var D = S.pop();
+ // TODO other datatypes http://www.capcode.de/help/get
+ S.push(D[K.substring(1)]);
+ };
+ F["put"] = function() { // dict key any --
+ var V = S.pop();
+ var K = S.pop();
+ var D = S.pop();
+ // TODO other datatypes http://www.capcode.de/help/put
+ D[K.substring(1)] = V;
+ };
+
+ F["true"] = function() {S.push(true);};
+ F["false"] = function() {S.push(false);};
+ F["null"] = function() {S.push(null);};
+
+ F["neg"] = function() {S.push(- S.pop());};
+ F["add"] = function() {S.push(S.pop() + S.pop());};
+ F["mul"] = function() {S.push(S.pop() * S.pop());};
+ F["div"] = function() {
+ var X = S.pop();
+ S.push(S.pop() / X);
+ };
+ F["idiv"] = function() {
+ var X = S.pop();
+ S.push(Math.floor(S.pop() / X));
+ };
+ F["mod"] = function() {
+ var X = S.pop();
+ S.push(S.pop() % X);
+ };
+ // TODO sqrt, exp, ceiling, sin
+ F["exch"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(Y);
+ S.push(X);
+ };
+
+ F["dup"] = function() {var X = S.pop(); S.push(X); S.push(X);};
+ F["clear"] = function() {S.length = 0;};
+ F["pop"] = function() {S.pop();};
+ F["roll"] = function() { // n j --
+ var J = S.pop();
+ var N = S.pop();
+ var X = [];
+ var Y = [];
+ //alert("roll 1 " + N + " " + J + " " + S);
+ for(var I = 0; I < N; I++)
+ if(I < J) X.unshift(S.pop());
+ else Y.unshift(S.pop());
+ for(I = 0; I < J; I++) S.push(X.shift());
+ for(I = 0; I < N - J; I++) S.push(Y.shift());
+ //alert("roll 2 " + N + " " + J + " " + S);
+ };
+
+ F["eq"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X == Y);
+ };
+ F["ne"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X != Y);
+ };
+ F["gt"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X > Y);
+ };
+ F["lt"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X < Y);
+ };
+ F["ge"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X >= Y);
+ };
+ F["le"] = function() {
+ var Y = S.pop();
+ var X = S.pop();
+ S.push(X <= Y);
+ };
+
+ F["if"] = function() {
+ var B = S.pop();
+ var C = S.pop();
+ if(C == true) run(B);
+ };
+ F["ifelse"] = function() {
+ var N = S.pop();
+ var P = S.pop();
+ var C = S.pop();
+ if(C == true) run(P);
+ else run(N);
+ };
+ F["repeat"] = function() {
+ var B = S.pop();
+ var N = S.pop();
+ for(var I = 0; I < N; I++) run(B);
+ };
+ F["for"] = function() {
+ var B = S.pop();
+ var L = S.pop();
+ var K = S.pop();
+ var J = S.pop();
+ if(K < 0) {
+ for(var I = J; L <= I; I += K) {
+ S.push(I);
+ run(B);
}
- };
+ } else {
+ for(var I = J; I <= L; I += K) {
+ S.push(I);
+ run(B);
+ }
+ }
+ };
- F["."] = function() {alert(S.pop());};
- F["=="] = function() {alert(S[0]);};
- F["pstack"] = function() {alert(S);};
+ F["."] = function() {alert(S.pop());};
+ F["=="] = function() {alert(S[0]);};
+ F["pstack"] = function() {alert(S);};
function run(C) {
if(!C.length) S.push(C);
@@ -271,305 +284,40 @@ function wps(E, W, H, T) {
else throw "Wrong operator name " + N + " for " + C;
};
- // html5 graphic operators
-
- //transform
- //setTransform
- //createLinearGradient
- //createRadialGradient
- //createPatternI
- //createPatternC
- //createPatternV
- F["clearRect"] = function() {
- var H = S.pop();
- var W = S.pop();
- var Y = S.pop();
- var X = S.pop();
- C.clearRect(X, Y, W, H);
- };
- F["fillRect"] = function() {
- var H = S.pop();
- var W = S.pop();
- var Y = S.pop();
- var X = S.pop();
- C.fillRect(X, Y, W, H);
- };
- F["strokeRect"] = function() {
- var H = S.pop();
- var W = S.pop();
- var Y = S.pop();
- var X = S.pop();
- C.strokeRect(X, Y, W, H);
- };
- //quadraticCurveTo
- F["rect"] = function() {
- var H = S.pop();
- var W = S.pop();
- var Y = S.pop();
- var X = S.pop();
- C.strokeRect(X, Y, W, H);
- };
- //isPointInPath
- //fillText
- //strokeText
- //measureText
- //drawImageI1
- //drawImageI2
- //drawImageC1
- //drawImageC2
- //drawImageV1
- //drawImageV2
- //createImageData1
- //createImageData2
- //getImageData
- //putImageData
+ // js ffi operators
- // html5 utility operators
-
- F["gput"] = function() {
- var K = S.pop();
+ F["call"] = function() { // fn nargs -- ...
+ var A = S.pop();
+ var N = S.pop();
+ var X = [];
+ for(var I = 0; I < A; I++) {
+ // TODO fix PdfT + quoted
var V = S.pop();
- C[K.substring(1)] = isPdfT(V) ? V.V : V;
- };
- F["gget"] = function() {
- var K = S.pop();
- S.push(C[K.substring(1)]);
- };
-
- F["rgb"] = function() {
- var B = S.pop();
- var G = S.pop();
- var R = S.pop();
- S.push(new PdfT("rgba(" + R + "," + G + "," + B + ")"));
- };
- F["rgba"] = function() {
- var A = S.pop();
- var B = S.pop();
- var G = S.pop();
- var R = S.pop();
- S.push(new PdfT("rgba(" + R + "," + G + "," + B + "," + A + ")"));
- };
-
- // ps graphic operators
-
- F["gsave"] = function() {C.save();};
- F["grestore"] = function() {C.restore();};
- F["scale"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.scale(X, Y);
- };
- F["rotate"] = function() {
- var A = S.pop();
- C.rotate(A);
- };
- F["translate"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.translate(X, Y);
- };
- F["newpath"] = function() {C.beginPath();};
- F["closepath"] = function() {C.closePath();};
- F["moveto"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.moveTo(X, Y);
- };
- F["lineto"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.lineTo(X, Y);
- };
- F["arcto"] = function() {
- var R = S.pop();
- var Y2 = S.pop();
- var X2 = S.pop();
- var Y1 = S.pop();
- var X1 = S.pop();
- C.arcTo(X1, Y1, X2, Y2, R);
- };
- F["arc"] = function() {
- var A = S.pop();
- var E = S.pop();
- var B = S.pop();
- var R = S.pop();
- var Y = S.pop();
- var X = S.pop();
- C.arc(X, Y, R, B, E, A);
- };
- F["fill"] = function() {C.fill();};
- F["stroke"] = function() {C.stroke();};
- F["clip"] = function() {C.clip();};
- F["setgray"] = function() {
- var G = S.pop();
- C.fillStyle = "rgb(" + G * 255 + "," + G * 255 + "," + G * 255 + ")";
- };
-
- // TODO eps operators
-
- F["save"] = function() {S.push(true);};
- F["restore"] = function() {S.push(true);};
- F["bind"] = function() {};
- F["dict"] = function() {};
- F["load"] = function() {};
- F["begin"] = function() {};
- F["end"] = function() {};
- F["where"] = function() {};
- F["currentflat"] = function() {};
- F["setflat"] = function() {};
- F["_"] = function() {};
- F["clippath"] = function() {};
-
- // pdf graphic operators
-
- F["w"] = function() {C.lineWidth = S.pop();};
- F["J"] = function() {C.lineCap = S.pop();};
- F["j"] = function() {C.lineJoin = S.pop();};
- F["M"] = function() {C.mitterLimit = S.pop();};
- F["d"] = function() {
- var P = S.pop();
- var A = S.pop();
- alert("TODO d");
- };
- F["ri"] = function() {alert("TODO ri");};
- F["i"] = function() {alert("TODO i");};
- F["gs"] = function() {alert("TODO gs");};
-
- F["q"] = function() {C.save();};
- F["Q"] = function() {C.restore();};
- F["cm"] = function() { // TODO fix cm
- var Dy = S.pop();
- var Dx = S.pop();
- var M22 = S.pop();
- var M21 = S.pop();
- var M12 = S.pop();
- var M11 = S.pop();
- //alert(M11 +"|"+ M12 +"|"+ M21 +"|"+ M22 +"|"+ Dx +"|"+ Dy);
- //C.setTransform(M11, M12, M21, M22, Dx, Dy);
- C.transform(M11, M12, M21, M22, Dx, Dy);
- };
-
- F["m"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.beginPath(); // TODO only if not m previously
- C.moveTo(X, Y);
- };
- F["l"] = function() {
- var Y = S.pop();
- var X = S.pop();
- C.lineTo(X, Y);
- };
- F["c"] = function() {
- var Y3 = S.pop();
- var X3 = S.pop();
- var Y2 = S.pop();
- var X2 = S.pop();
- var Y1 = S.pop();
- var X1 = S.pop();
- C.bezierCurveTo(X1, Y1, X2, Y2, X3, Y3); // TODO the right c method
- };
-// F["c2"] = function() { // not in pdf
-// var Y3 = S.pop();
-// var X3 = S.pop();
-// var Y2 = S.pop();
-// var X2 = S.pop();
-// var Y1 = S.pop();
-// var X1 = S.pop();
-// C.bezierCurveTo(X1, Y1, X2, Y2, X3, Y3); // TODO the right c method
-// };
- F["v"] = function() {alert("TODO v");};
- F["y"] = function() {alert("TODO y");};
- F["h"] = function() {C.closePath();};
- F["re"] = function() {
- var Y2 = S.pop();
- var X2 = S.pop();
- var Y1 = S.pop();
- var X1 = S.pop();
- C.rect(X1, Y1, X2, Y2);
- };
-
- F["S"] = function() {C.stroke();};
- F["s"] = function() {F["h"](); F["S"]();};
- F["f"] = function() {C.fill();};
- F["F"] = function() {C.fill();};
- F["f*"] = function() {alert("TODO f*");};
- F["B"] = function() {F["f"](); F["S"]();};
- F["B*"] = function() {F["f*"](); F["S"]();};
- F["b"] = function() {F["h"](); F["B"]();};
- F["b*"] = function() {F["h"](); F["B*"]();};
- F["n"] = function() {alert("TODO n");};
-
- F["W"] = function() {C.clip();};
- F["W*"] = function() {alert("TODO W*");};
-
- F["BT"] = function() {alert("TODO BT");};
- F["ET"] = function() {alert("TODO ET");};
-
- F["Tc"] = function() {alert("TODO Tc");};
- F["Tw"] = function() {alert("TODO Tw");};
- F["Tz"] = function() {alert("TODO Tz");};
- F["TL"] = function() {alert("TODO Tf");};
- F["Tf"] = function() {
- var N = S.pop();
- var F = S.pop();
- C.font = N + "pt " + F.V;
- };
- F["Tr"] = function() {alert("TODO Tr");};
- F["Ts"] = function() {alert("TODO Ts");};
-
- F["Td"] = function() {alert("TODO Td");};
- F["TD"] = function() {alert("TODO TD");};
- F["Tm"] = function() {alert("TODO Tm");};
- F["T*"] = function() {alert("TODO T*");};
-
- F["Tj"] = function() {
- var T = S.pop();
- //alert(T.V);
- //if(C.strokeText) C.strokeText(T.V, 0, 0);
- if(C.fillText) C.fillText(T.V, 0, 0);
- };
- F["TJ"] = function() {alert("TODO TJ");};
- F["'"] = function() {alert("TODO '");};
- F["\""] = function() {alert("TODO \"");};
-
- F["d0"] = function() {alert("TODO d0");};
- F["d1"] = function() {alert("TODO d1");};
-
- F["CS"] = function() {alert("TODO CS");};
- F["cs"] = function() {alert("TODO cs");};
- F["SC"] = function() {alert("TODO SC");};
- F["SCN"] = function() {alert("TODO SCN");};
- F["sc"] = function() {alert("TODO sc");};
- F["scn"] = function() {alert("TODO scn");};
- F["G"] = function() {alert("TODO G");};
- F["g"] = function() {alert("TODO g");};
- F["RG"] = function() {alert("TODO RG");};
- F["rg"] = function() { // TODO color spaces
- var B = S.pop();
- var G = S.pop();
- var R = S.pop();
- C.fillStyle = "rgb(" + R + "," + G + "," + B + ")";
- };
- F["K"] = function() {alert("TODO K");};
- F["k"] = function() {alert("TODO k");};
-
- F["sh"] = function() {alert("TODO sh");};
-
- F["BI"] = function() {alert("TODO BI");};
- F["ID"] = function() {alert("TODO ID");};
- F["EI"] = function() {alert("TODO EI");};
-
- F["Do"] = function() {alert("TODO Do");};
-
- F["MP"] = function() {alert("TODO MP");};
- F["DP"] = function() {alert("TODO DP");};
- F["BMC"] = function() {alert("TODO BMC");};
- F["BDC"] = function() {alert("TODO BDC");};
- F["EMC"] = function() {alert("TODO EMC");};
-
- F["BX"] = function() {alert("TODO BX");};
- F["EX"] = function() {alert("TODO EX");};
+ X.unshift(isPdfT(V) ? V.V : (quoted(V) ? V.substring(1) : V));
+ }
+ alert("call " + N + " " + A);
+ N.apply(this, X);
+ };
+
+ F["gc"] = function() { // -- gc
+ S.push(C);
+ };
+
+ // html5 utility operators
+
+ F["rgb"] = function() {
+ var B = S.pop();
+ var G = S.pop();
+ var R = S.pop();
+ S.push(new PdfT("rgb(" + R + "," + G + "," + B + ")"));
+ };
+ F["rgba"] = function() {
+ var A = S.pop();
+ var B = S.pop();
+ var G = S.pop();
+ var R = S.pop();
+ S.push(new PdfT("rgba(" + R + "," + G + "," + B + "," + A + ")"));
+ };
if(T.length)
for(var I = 0; I < T.length; I++)
diff --git a/wps.wps b/wps.wps
@@ -1,207 +1,241 @@
-%%% wps.wps -- postscript and pdf operators for html 5 canvas
%%% (c) 2009 Tomas Hlavaty
-%% basic operators
-
-/sub { % num num -- num
- neg add
-} def
-
-%% html5 operators
+%% math
+
+/abs {.math (abs) 1 .call} def
+/.acos {.math (acos) 1 .call} def
+/.asin {.math (asin) 1 .call} def
+/atan {exch .math (atan) 1 .call} def
+/.atan2 {.math (atan2) 2 .call} def
+/ceiling {.math (ceil) 1 .call} def
+/cos {.math (cos) 1 .call} def
+/.exp {.math (exp) 1 .call} def
+/floor {.math (floor) 1 .call} def
+/log {.math (log) 1 .call} def
+/.max {.math (max) 2 .call} def
+/.min {.math (min) 2 .call} def
+/.pow {.math (pow) 2 .call} def
+/.random {.math (random) 0 .call} def
+/rand {.random} def % TODO follow spec
+/round {.math (round) 1 .call} def
+/sin {.math (sin) 1 .call} def
+/sqrt {.math (sqrt) 1 .call} def
+/.tan {.math (tan) 1 .call} def
+/truncate {.math (truncate) 1 .call} def % TODO Math.truncate does not exist!
+
+/.e {.math (E) get} def
+/.ln2 {.math (LN2) get} def
+/.ln10 {.math (LN10) get} def
+/.log2e {.math (LOG2E) get} def
+/.log10e {.math (LOG10E) get} def
+/.pi {.math (PI) get} def
+/.sqrt1_2 {.math (SQRT1_2) get} def
+/.sqrt2 {.math (SQRT2) get} def
+
+/sub {neg add} def
+/idiv {div .floor} def
+
+%% html5
/.gget { % key --
- gc exch
+ .gc exch
get
} def
/.gput { % any key --
- gc 3 1 roll exch
+ .gc 3 1 roll exch
put
} def
-/.gcall { % key nargs --
- gc 3 1 roll call
+/.gcall0 { % key nargs --
+ .gc 3 1 roll .call pop
+} def
+
+/.gcall1 { % key nargs -- result
+ .gc 3 1 roll .call
} def
/.gcanvas { % -- canvas
- /canvas .gget
+ (canvas) .gget
} def
/.gdim { % w h --
- .gcanvas exch /height exch put
- .gcanvas exch /width exch put
+ .gcanvas exch (height) exch put
+ .gcanvas exch (width) exch put
} def
-/gbox { % x0 y0 x1 y1 --
+/.gbox { % x0 y0 x1 y1 --
% TODO compute properly
.gdim
pop
pop
} def
-/.save {/save 0 .gcall} def
-/.restore {/restore 0 .gcall} def
+/.save {(save) 0 .gcall0} def
+/.restore {(restore) 0 .gcall0} def
/scale { % x y --
- /scale 2 .gcall
+ (scale) 2 .gcall0
} def
/rotate { % angle --
- /rotate 1 .gcall
+ (rotate) 1 .gcall0
} def
/translate { % x y --
- /translate 2 .gcall
+ (translate) 2 .gcall0
} def
-/transform { % m11 m12 m21 m22 dx dy --
- /transform 6 .gcall
+/.transform { % m11 m12 m21 m22 dx dy --
+ (transform) 6 .gcall0
} def
-/setTransform { % m11 m12 m21 m22 dx dy --
- /setTransform 6 .gcall
+/.setTransform { % m11 m12 m21 m22 dx dy --
+ (setTransform) 6 .gcall0
} def
-/createLinearGradient { % x0 y0 x1 y1 -- CanvasGradient
- /createLinearGradient 4 .gcall
+/.createLinearGradient { % x0 y0 x1 y1 -- CanvasGradient
+ (createLinearGradient) 4 .gcall1
} def
-/createRadialGradient { % x0 y0 r0 x1 y1 r1 -- CanvasGradient
- /createRadialGradient 6 .gcall
+/.createRadialGradient { % x0 y0 r0 x1 y1 r1 -- CanvasGradient
+ (createRadialGradient) 6 .gcall1
} def
-/createPattern { % image repetition -- CanvasPattern
- /createPattern 2 .gcall
+/.createPattern { % image repetition -- CanvasPattern
+ (createPattern) 2 .gcall1
} def
/.clearRect { % x y w h --
- /clearRect 4 .gcall
+ (clearRect) 4 .gcall0
} def
/.fillRect { % x y w h --
- /fillRect 4 .gcall
+ (fillRect) 4 .gcall0
} def
/.strokeRect { % x y w h --
- /strokeRect 4 .gcall
+ (strokeRect) 4 .gcall0
} def
-/.beginPath {/.beginPath 0 .gcall} def
-/.closePath {/.closePath 0 .gcall} def
+/.beginPath {(beginPath) 0 .gcall0} def
+/.closePath {(closePath) 0 .gcall0} def
/.moveTo { % x y --
- /moveTo 2 .gcall
+ (moveTo) 2 .gcall0
} def
/.lineTo { % x y --
- /lineTo 2 .gcall
+ (lineTo) 2 .gcall0
} def
-/quadraticCurveTo { % cpx cpy x y --
- /quadraticCurveTo 4 .gcall
+/.quadraticCurveTo { % cpx cpy x y --
+ (quadraticCurveTo) 4 .gcall0
} def
-/bezierCurveTo { % cp1x cp1y cp2x cp2y x y --
- /bezierCurveTo 6 .gcall
+/.bezierCurveTo { % cp1x cp1y cp2x cp2y x y --
+ (bezierCurveTo) 6 .gcall0
} def
/.arcTo { % x1 y1 x2 y2 radius --
- /arcTo 5 .gcall
+ (arcTo) 5 .gcall0
} def
-/rect { % x y w h --
- /rect 4 .gcall
+/.rect { % x y w h --
+ (rect) 4 .gcall0
} def
/arc { % x y radius startAngle endAngle anticlockwise --
- /arc 6 .gcall
+ (arc) 6 .gcall0
} def
/fill { % --
- /fill 0 .gcall
+ (fill) 0 .gcall0
} def
/stroke { % --
- /stroke 0 .gcall
+ (stroke) 0 .gcall0
} def
/clip { % --
- /clip 0 .gcall
+ (clip) 0 .gcall0
} def
-/isPointInPath { % x y -- boolean
- /isPointInPath 2 .gcall
+/.isPointInPath { % x y -- boolean
+ (isPointInPath) 2 .gcall1
} def
-/fillText { % text x y maxWidth --
- /fillText 4 .gcall
+/.fillText { % text x y maxWidth --
+ (fillText) 4 .gcall0
} def
-/strokeText { % text x y maxWidth --
- /strokeText 4 .gcall
+/.strokeText { % text x y maxWidth --
+ (strokeText) 4 .gcall0
} def
-/measureText { % text -- TextMetrics
- /measureText 1 .gcall
+/.measureText { % text -- TextMetrics
+ (measureText) 1 .gcall1
} def
-/drawImage1 { % image dx dy dw dh --
- /drawImage1 5 .gcall
+/.drawImage1 { % image dx dy dw dh --
+ (drawImage1) 5 .gcall0
} def
-/drawImage2 { % image sx sy sw sh dx dy dw dh --
- /drawImage2 9 .gcall
+/.drawImage2 { % image sx sy sw sh dx dy dw dh --
+ (drawImage2) 9 .gcall0
} def
-/createImageData1 { % imagedata -- ImageData
- /createImageData1 1 .gcall
+/.createImageData1 { % imagedata -- ImageData
+ (createImageData1) 1 .gcall1
} def
-/createImageData2 { % sw sh -- ImageData
- /createImageData2 2 .gcall
+/.createImageData2 { % sw sh -- ImageData
+ (createImageData2) 2 .gcall1
} def
-/getImageData { % sx sy sw sh --
- /getImageData 4 .gcall
+/.getImageData { % sx sy sw sh --
+ (getImageData) 4 .gcall1
} def
-/putImageData { % imagedata dx dy dirtyX dirtyY dirtyWidth dirtyHeight --
- /putImageData 7 .gcall
+/.putImageData { % imagedata dx dy dirtyX dirtyY dirtyWidth dirtyHeight --
+ (putImageData) 7 .gcall0
} def
-/getGlobalAlpha {/globalAlpha .gget} def
-/getGlobalCompositeOperation {/globalCompositeOperation .gget} def % TODO str
-/getStrokeStyle {/strokeStyle .gget} def % TODO str
-/getFillStyle {/fillStyle .gget} def % TODO str
-/.getLineWidth {/lineWidth .gget} def
-/.getLineCap {/lineCap .gget} def % TODO str
-/.getLineJoin {/lineJoin .gget} def % TODO str
-/.getMiterLimit {/miterLimit .gget} def
-/getShadowOffsetX {/shadowOffsetX .gget} def
-/getShadowOffsetY {/shadowOffsetY .gget} def
-/getShadowBlur {/shadowBlur .gget} def
-/getShadowColor {/shadowColor .gget} def % TODO str
-/.getFont {/font .gget} def % TODO str
-/getTextAlign {/textAlign .gget} def % TODO str
-/getTextBaseline {/textBaseline .gget} def % TODO str
+/.getGlobalAlpha {(globalAlpha) .gget} def
+/.getGlobalCompositeOperation {(globalCompositeOperation) .gget} def
+/.getStrokeStyle {(strokeStyle) .gget} def
+/.getFillStyle {(fillStyle) .gget} def
+/.getLineWidth {(lineWidth) .gget} def
+/.getLineCap {(lineCap) .gget} def
+/.getLineJoin {(lineJoin) .gget} def
+/.getMiterLimit {(miterLimit) .gget} def
+/.getShadowOffsetX {(shadowOffsetX) .gget} def
+/.getShadowOffsetY {(shadowOffsetY) .gget} def
+/.getShadowBlur {(shadowBlur) .gget} def
+/.getShadowColor {(shadowColor) .gget} def
+/.getFont {(font) .gget} def
+/.getTextAlign {(textAlign) .gget} def
+/.getTextBaseline {(textBaseline) .gget} def
-/setGlobalAlpha {/globalAlpha .gput} def
-/setGlobalCompositeOperation {/globalCompositeOperation .gput} def % TODO str
-/setStrokeStyle {/strokeStyle .gput} def % TODO str
-/setFillStyle {/fillStyle .gput} def % TODO str
-/.setLineWidth {/lineWidth .gput} def
-/.setLineCap {/lineCap .gput} def % TODO str
-/.setLineJoin {/lineJoin .gput} def % TODO str
-/.setMiterLimit {/miterLimit .gput} def
-/setShadowOffsetX {/shadowOffsetX .gput} def
-/setShadowOffsetY {/shadowOffsetY .gput} def
-/setShadowBlur {/shadowBlur .gput} def
-/setShadowColor {/shadowColor .gput} def % TODO str
-/.setFont {/font .gput} def % TODO str
-/setTextAlign {/textAlign .gput} def % TODO str
-/setTextBaseline {/textBaseline .gput} def % TODO str
+/.setGlobalAlpha {(globalAlpha) .gput} def
+/.setGlobalCompositeOperation {(globalCompositeOperation) .gput} def
+/.setStrokeStyle {(strokeStyle) .gput} def
+/.setFillStyle {(fillStyle) .gput} def
+/.setLineWidth {(lineWidth) .gput} def
+/.setLineCap {(lineCap) .gput} def
+/.setLineJoin {(lineJoin) .gput} def
+/.setMiterLimit {(miterLimit) .gput} def
+/.setShadowOffsetX {(shadowOffsetX) .gput} def
+/.setShadowOffsetY {(shadowOffsetY) .gput} def
+/.setShadowBlur {(shadowBlur) .gput} def
+/.setShadowColor {(shadowColor) .gput} def
+/.setFont {(font) .gput} def
+/.setTextAlign {(textAlign) .gput} def
+/.setTextBaseline {(textBaseline) .gput} def
-%% PostScript operators
+%% PostScript
+
+% TODO track state, e.g. origin x y
/gsave {.save} def
/grestore {.restore} def
@@ -251,112 +285,105 @@
/setgray { % gray --
255 mul dup dup
- rgb setFillStyle
+ .rgb .setFillStyle
} def
/setrgbcolor { % r g b --
3 {255 * 3 1 roll} repeat
- rgb setFillStyle
+ .rgb .setFillStyle
} def
/setfont { % font --
% TODO C.font = N + "pt " + F.V;
} def
-% F["save"] = function() {S.push(true);};
-% F["restore"] = function() {S.push(true);};
-% F["bind"] = function() {};
-% F["dict"] = function() {};
-% F["load"] = function() {};
-% F["begin"] = function() {};
-% F["end"] = function() {};
-% F["where"] = function() {};
-% F["currentflat"] = function() {};
-% F["setflat"] = function() {};
-% F["_"] = function() {};
-% F["clippath"] = function() {};
-
-%% PDF operators
-
-/w {
- setlinewidth
-} def
-
-/J {
- setlinecap
-} def
-
-/j {
- setlinejoin
-} def
-
-/M {
- setmitterlimit
-} def
-
-/q {gsave} def
-/Q {grestore} def
-
-/cm {
- transform
+/clippath { % --
+ % TODO
} def
-/m {
- newpath % TODO only if not m previously
- moveto
+/show { % string --
+ % TODO
+ %0 exch 0 exch .fillText
+ .fillText
} def
-/l {
+/rlineto { % x y --
+ % TODO
lineto
} def
-/c {
- bezierCurveTo
-} def
-
-/h {closepath} def
-
-/re {
- rect
-} def
-
-/S {stroke} def
-/s {h S} def
-/f {fill} def
-/F {fill} def
-/B {f S} def
-/B* {f* S} def
-/b {h B} def
-/b* {h B*} def
-/W {clip} def
-
-/Tf {
- setfont
-} def
-
-/Tj {
- fillText
-} def
-
-/rg {
- % TODO other color spaces
- 3 {255 * 3 1 roll} repeat
- rgb setFillStyle
-} def
-
-%% other operators
-
-/pi 3.141592653589 def
-
-/inch { % num --
- 72 mul
-} def
-
-%/black {0 0 0 setrgbcolor} def
-%/red {1 0 0 setrgbcolor} def
-%/green {0 1 0 setrgbcolor} def
-%/blue {0 0 1 setrgbcolor} def
-%/yellow {1 1 0 setrgbcolor} def
-%/cyan {0 1 1 setrgbcolor} def
-%/magenta {1 0 1 setrgbcolor} def
-%/white {1 1 1 setrgbcolor} def
+%% PDF
+
+/w {setlinewidth} def
+/J {setlinecap} def % TODO
+/j {setlinejoin} def % TODO
+/M {setmitterlimit} def
+/d {setdash} def % TODO
+/ri {} def % TODO
+/i {} def % TODO
+/gs {} def % TODO
+/q {gsave} def
+/Q {grestore} def
+/cm {.transform} def
+/m {newpath moveto} def % TODO only if not m previously
+/l {lineto} def
+/c {.bezierCurveTo} def
+/v {currentpoint cp2 p3 c} def % TODO fix arg order
+/y {cp1 p3 p3 c} def % TODO fix arg order
+/h {closepath} def % TODO
+/re {.rect} def % TODO really, or x y m , x+w y l , x+w y+h l , x y+h l , h
+/S {stroke} def
+/s {h S} def
+/f {fill} def % TODO
+/F {f} def
+/f* {} def % TODO
+/B {f S} def
+/B* {f* S} def
+/b {h B} def
+/b* {h B*} def
+/n {} def % TODO
+/W {clip} def % TODO
+/W* {clip} def % TODO
+/BT {} def % TODO
+/ET {} def % TODO
+/Tc {} def % TODO
+/Tw {} def % TODO
+/Tz {} def % TODO
+/TL {} def % TODO
+/Tf {setfont} def % TODO
+/Tr {} def % TODO
+/Ts {} def % TODO
+/Td {} def % TODO
+/TD {} def % TODO
+/Tm {} def % TODO
+/T* {} def % TODO
+/Tj {show} def % TODO
+/TJ {} def % TODO
+%/' {} def % TODO
+%/" {} def % TODO
+/d0 {} def % TODO
+/d1 {} def % TODO
+/CS {} def % TODO
+/cs {} def % TODO
+/SC {} def % TODO
+/SCN {} def % TODO
+/sc {} def % TODO
+/scn {} def % TODO
+/G {} def % TODO
+/g {} def % TODO
+/RG {} def % TODO
+/rg {3 {255 * 3 1 roll} repeat .rgb .setFillStyle} def % TODO
+/K {} def % TODO
+/k {} def % TODO
+/sh {} def % TODO
+/BI {} def % TODO
+/ID {} def % TODO
+/EI {} def % TODO
+/Do {} def % TODO
+/MP {} def % TODO
+/DP {} def % TODO
+/BMC {} def % TODO
+/BDC {} def % TODO
+/EMC {} def % TODO
+/BX {} def % TODO
+/EX {} def % TODO