diff --git a/postscript-go/TestPostscript.png b/postscript-go/TestPostscript.png
index f6b7f61..c103be2 100644
Binary files a/postscript-go/TestPostscript.png and b/postscript-go/TestPostscript.png differ
diff --git a/postscript-go/src/pkg/postscript/operators_control.go b/postscript-go/src/pkg/postscript/operators_control.go
index d0d6755..08877d1 100644
--- a/postscript-go/src/pkg/postscript/operators_control.go
+++ b/postscript-go/src/pkg/postscript/operators_control.go
@@ -50,6 +50,14 @@ func foroperator(interpreter *Interpreter) {
}
}
+func repeat(interpreter *Interpreter) {
+ proc := NewProcedure(interpreter.PopProcedureDefinition())
+ times := interpreter.PopInt()
+ for i := 0; i <= times; i++ {
+ proc.Execute(interpreter)
+ }
+}
+
// any stopped bool -> Establish context for catching stop
func stopped(interpreter *Interpreter) {
value := interpreter.Pop()
@@ -67,5 +75,6 @@ func initControlOperators(interpreter *Interpreter) {
interpreter.SystemDefine("if", NewOperator(ifoperator))
interpreter.SystemDefine("ifelse", NewOperator(ifelse))
interpreter.SystemDefine("for", NewOperator(foroperator))
+ interpreter.SystemDefine("repeat", NewOperator(repeat))
interpreter.SystemDefine("stopped", NewOperator(stopped))
}
diff --git a/postscript-go/src/pkg/postscript/operators_graphics.go b/postscript-go/src/pkg/postscript/operators_graphics.go
index 129ce52..66a2f27 100644
--- a/postscript-go/src/pkg/postscript/operators_graphics.go
+++ b/postscript-go/src/pkg/postscript/operators_graphics.go
@@ -71,6 +71,15 @@ func rcurveto(interpreter *Interpreter) {
interpreter.GetGraphicContext().RCubicCurveTo(cx1, cy1, cx2, cy2, cx3, cy3)
}
+func arc(interpreter *Interpreter) {
+ angle2 := interpreter.PopFloat() * (math.Pi / 180.0)
+ angle1 := interpreter.PopFloat() * (math.Pi / 180.0)
+ r := interpreter.PopFloat()
+ y := interpreter.PopFloat()
+ x := interpreter.PopFloat()
+ interpreter.GetGraphicContext().ArcTo(x, y, r, r, angle1, angle2 - angle1)
+}
+
func clippath(interpreter *Interpreter) {
log.Printf("clippath not yet implemented")
}
@@ -280,37 +289,135 @@ func matrix(interpreter *Interpreter) {
interpreter.Push(draw2d.NewIdentityMatrix())
}
+func initmatrix(interpreter *Interpreter) {
+ interpreter.Push(draw2d.NewIdentityMatrix())
+}
+
+func identmatrix(interpreter *Interpreter) {
+ tr := interpreter.Pop().(draw2d.MatrixTransform)
+ ident := draw2d.NewIdentityMatrix()
+ copy(tr[:], ident[:])
+ interpreter.Push(tr)
+}
+
+func defaultmatrix(interpreter *Interpreter) {
+ tr := interpreter.Pop().(draw2d.MatrixTransform)
+ ident := draw2d.NewIdentityMatrix()
+ copy(tr[:], ident[:])
+ interpreter.Push(tr)
+}
+
+func currentmatrix(interpreter *Interpreter) {
+ tr := interpreter.Pop().(draw2d.MatrixTransform)
+ ctm := interpreter.GetGraphicContext().GetMatrixTransform()
+ copy(tr[:], ctm[:])
+ interpreter.Push(tr)
+}
+
+func setmatrix(interpreter *Interpreter) {
+ tr := interpreter.Pop().(draw2d.MatrixTransform)
+ interpreter.GetGraphicContext().SetMatrixTransform(tr)
+}
+
+func concat(interpreter *Interpreter) {
+ tr := interpreter.Pop().(draw2d.MatrixTransform)
+ interpreter.GetGraphicContext().ComposeMatrixTransform(tr)
+}
+func concatmatrix(interpreter *Interpreter) {
+ tr3 := interpreter.Pop().(draw2d.MatrixTransform)
+ tr2 := interpreter.Pop().(draw2d.MatrixTransform)
+ tr1 := interpreter.Pop().(draw2d.MatrixTransform)
+ result := tr1.Multiply(tr2)
+ copy(tr3[:], result[:])
+ interpreter.Push(tr3)
+}
+
func transform(interpreter *Interpreter) {
- y := interpreter.PopFloat()
+ value := interpreter.Pop()
+ matrix, ok := value.(draw2d.MatrixTransform)
+ var y float
+ if(!ok) {
+ matrix = interpreter.GetGraphicContext().GetMatrixTransform()
+ y = value.(float)
+ } else {
+ y = interpreter.PopFloat()
+ }
x := interpreter.PopFloat()
- interpreter.GetGraphicContext().GetMatrixTransform().Transform(&x, &y)
+ matrix.Transform(&x, &y)
interpreter.Push(x)
interpreter.Push(y)
}
func itransform(interpreter *Interpreter) {
- y := interpreter.PopFloat()
+ value := interpreter.Pop()
+ matrix, ok := value.(draw2d.MatrixTransform)
+ var y float
+ if(!ok) {
+ matrix = interpreter.GetGraphicContext().GetMatrixTransform()
+ y = value.(float)
+ } else {
+ y = interpreter.PopFloat()
+ }
x := interpreter.PopFloat()
- interpreter.GetGraphicContext().GetMatrixTransform().InverseTransform(&x, &y)
+ matrix.InverseTransform(&x, &y)
interpreter.Push(x)
interpreter.Push(y)
}
func translate(interpreter *Interpreter) {
- y := interpreter.PopFloat()
+ value := interpreter.Pop()
+ matrix, ok := value.(draw2d.MatrixTransform)
+ var y float
+ if(!ok) {
+ matrix = interpreter.GetGraphicContext().GetMatrixTransform()
+ y = value.(float)
+ } else {
+ y = interpreter.PopFloat()
+ }
x := interpreter.PopFloat()
- interpreter.GetGraphicContext().Translate(x, y)
+ if(!ok) {
+ interpreter.GetGraphicContext().Translate(x, y)
+ } else {
+ matrix = draw2d.NewTranslationMatrix(x, y).Multiply(matrix)
+ interpreter.Push(matrix)
+ }
}
func rotate(interpreter *Interpreter) {
- angle := interpreter.PopFloat()
- interpreter.GetGraphicContext().Rotate(angle * (math.Pi / 180.0))
+ value := interpreter.Pop()
+ matrix, ok := value.(draw2d.MatrixTransform)
+ var angle float
+ if(!ok) {
+ matrix = interpreter.GetGraphicContext().GetMatrixTransform()
+ angle = value.(float) * math.Pi / 180
+ } else {
+ angle = interpreter.PopFloat() * math.Pi / 180
+ }
+ if(!ok) {
+ interpreter.GetGraphicContext().Rotate(angle)
+ } else {
+ matrix = draw2d.NewRotationMatrix(angle).Multiply(matrix)
+ interpreter.Push(matrix)
+ }
}
func scale(interpreter *Interpreter) {
- y := interpreter.PopFloat()
+ value := interpreter.Pop()
+ matrix, ok := value.(draw2d.MatrixTransform)
+ var y float
+ if(!ok) {
+ matrix = interpreter.GetGraphicContext().GetMatrixTransform()
+ y = value.(float)
+ } else {
+ y = interpreter.PopFloat()
+ }
x := interpreter.PopFloat()
- interpreter.GetGraphicContext().Scale(x, y)
+ if(!ok) {
+ interpreter.GetGraphicContext().Scale(x, y)
+ } else {
+ matrix = draw2d.NewScaleMatrix(x, y).Multiply(matrix)
+ interpreter.Push(matrix)
+ }
}
@@ -346,6 +453,14 @@ func initDrawingOperators(interpreter *Interpreter) {
// Coordinate System and Matrix operators
interpreter.SystemDefine("matrix", NewOperator(matrix))
+ interpreter.SystemDefine("initmatrix", NewOperator(initmatrix))
+ interpreter.SystemDefine("identmatrix", NewOperator(identmatrix))
+ interpreter.SystemDefine("defaultmatrix", NewOperator(defaultmatrix))
+ interpreter.SystemDefine("currentmatrix", NewOperator(currentmatrix))
+ interpreter.SystemDefine("setmatrix", NewOperator(setmatrix))
+ interpreter.SystemDefine("concat", NewOperator(concat))
+ interpreter.SystemDefine("concatmatrix", NewOperator(concatmatrix))
+
interpreter.SystemDefine("transform", NewOperator(transform))
interpreter.SystemDefine("itransform", NewOperator(itransform))
interpreter.SystemDefine("translate", NewOperator(translate))
@@ -362,5 +477,6 @@ func initDrawingOperators(interpreter *Interpreter) {
interpreter.SystemDefine("rlineto", NewOperator(rlineto))
interpreter.SystemDefine("curveto", NewOperator(curveto))
interpreter.SystemDefine("rcurveto", NewOperator(rcurveto))
+ interpreter.SystemDefine("arc", NewOperator(arc))
interpreter.SystemDefine("clippath", NewOperator(clippath))
}
diff --git a/postscript-go/src/pkg/postscript/operators_math.go b/postscript-go/src/pkg/postscript/operators_math.go
index 5267ed2..ea1a7ae 100644
--- a/postscript-go/src/pkg/postscript/operators_math.go
+++ b/postscript-go/src/pkg/postscript/operators_math.go
@@ -91,13 +91,13 @@ func atan(interpreter *Interpreter) {
}
//angle cos real -> Return cosine of angle degrees
func cos(interpreter *Interpreter) {
- a := interpreter.PopFloat()
- interpreter.Push(float(math.Cos(float64(a))) * (180.0 / math.Pi))
+ a := interpreter.PopFloat() * math.Pi / 180
+ interpreter.Push(float(math.Cos(float64(a ))))
}
//angle sin real -> Return sine of angle degrees
func sin(interpreter *Interpreter) {
- a := interpreter.PopFloat()
- interpreter.Push(float(math.Sin(float64(a))) * (180.0 / math.Pi))
+ a := interpreter.PopFloat() * math.Pi / 180
+ interpreter.Push(float(math.Sin(float64(a))))
}
//base exponent exp real -> Raise base to exponent power
func exp(interpreter *Interpreter) {
@@ -117,7 +117,7 @@ func log10(interpreter *Interpreter) {
}
//– rand int Generate pseudo-random integer
func randInt(interpreter *Interpreter) {
- interpreter.Push(rand.Int())
+ interpreter.Push(float(rand.Int()))
}
var randGenerator *rand.Rand
diff --git a/postscript-go/src/pkg/postscript/operators_relational.go b/postscript-go/src/pkg/postscript/operators_relational.go
index 0f43169..c1e708b 100644
--- a/postscript-go/src/pkg/postscript/operators_relational.go
+++ b/postscript-go/src/pkg/postscript/operators_relational.go
@@ -16,14 +16,26 @@ func ne(interpreter *Interpreter) {
interpreter.Push(value1 != value2)
}
+func not(interpreter *Interpreter) {
+ b := interpreter.PopBoolean()
+ interpreter.Push(!b)
+}
+
func lt(interpreter *Interpreter) {
f2 := interpreter.PopFloat()
f1 := interpreter.PopFloat()
interpreter.Push(f1 < f2)
}
+func gt(interpreter *Interpreter) {
+ f2 := interpreter.PopFloat()
+ f1 := interpreter.PopFloat()
+ interpreter.Push(f1 > f2)
+}
func initRelationalOperators(interpreter *Interpreter) {
interpreter.SystemDefine("eq", NewOperator(eq))
interpreter.SystemDefine("ne", NewOperator(ne))
+ interpreter.SystemDefine("not", NewOperator(not))
interpreter.SystemDefine("lt", NewOperator(lt))
+ interpreter.SystemDefine("gt", NewOperator(gt))
}
diff --git a/postscript-go/test_files/3dcolor.ps b/postscript-go/test_files/3dcolor.ps
new file mode 100644
index 0000000..1b31d08
--- /dev/null
+++ b/postscript-go/test_files/3dcolor.ps
@@ -0,0 +1,57 @@
+%!PS
+/B {bind} bind def
+/D {def} def
+/Q {bind def} B D
+/E {exch def} Q
+/S {gsave} Q
+/R {grestore} Q
+/P 20 D
+/N P 1 sub D
+/I 1 P div D
+initclip clippath pathbbox newpath
+72 sub /URy E 72 sub /URx E 72 add /LLy E 72 add /LLx E
+/Sq5 5 sqrt D
+/F 2 Sq5 add D
+/Wx URx LLx sub D /Wy URy LLy sub D
+/Xx Wx 4 div D /Xy Wy F div D /X Xx Xy le {Xx}{Xy}ifelse D
+Wx X 4 mul sub 2 div LLx add X 2 mul add Wy X F mul sub 2 div LLy add translate
+/X X Sq5 mul D
+X dup scale
+0.1 X div setlinewidth
+S
+[ 1 .5 0 1 0 0 ] concat
+0 1 N {I mul /A E
+ 0 1 N {I mul /B E
+ S A B translate
+ newpath 0 0 moveto I 0 rlineto 0 I rlineto I neg 0 rlineto
+ closepath
+ S I B add 1 1 A sub setrgbcolor fill R stroke % Green
+ R
+ } for
+ } for
+R
+S
+[ -1 .5 0 1 0 0 ] concat
+0 1 N {I mul /A E
+ 0 1 N {I mul /B E
+ S A B translate
+ newpath 0 0 moveto I 0 rlineto 0 I rlineto I neg 0 rlineto
+ closepath
+ S I B add 1 A sub 1 setrgbcolor fill R stroke % Blue
+ R
+ } for
+ } for
+R
+S
+[ 1 .5 -1 0.5 0 1 ] concat
+0 1 N {I mul /A E
+ 0 1 N {I mul /B E
+ S A B translate
+ newpath 0 0 moveto I 0 rlineto 0 I rlineto I neg 0 rlineto
+ closepath
+ S 1 1 B sub 1 A sub setrgbcolor fill R stroke % Red
+ R
+ } for
+ } for
+R
+showpage
diff --git a/postscript-go/test_files/Koch.ps b/postscript-go/test_files/Koch.ps
new file mode 100644
index 0000000..539432c
--- /dev/null
+++ b/postscript-go/test_files/Koch.ps
@@ -0,0 +1,76 @@
+%%% Start of L-system definition
+
+/STARTK { FK plusK plusK FK plusK plusK FK} def
+/FK {
+ dup 0 eq
+ { DK } % if the recursion order ends, draw forward
+ {
+ 1 sub % recurse
+ 4 {dup} repeat % dup the number of parameters (order) needed.
+ FK minusK FK plusK plusK FK minusK FK }
+ ifelse
+ pop % pop the dup'd order
+} bind def
+
+/angleK 60 def
+
+/minusK { % rotation to the right
+ angleK neg rotate
+} bind def
+
+/plusK { % rotation to the left
+ angleK rotate
+} bind def
+
+%%% End of L-System definition
+
+/DK { sizeK 3 orderK exp div 0 rlineto } bind def
+/thicknessK {1 orderK dup mul div} bind def
+
+%%% Scaling factors
+
+/orderK 3 def
+/sizeK 300 def
+
+%%% Draws a Koch's snowflake of radius 180 at 0 0
+
+/Koch180 {
+ gsave
+ newpath
+ thicknessK setlinewidth
+ 200 300 60 cos mul add
+ neg
+ 200 100 60 sin mul add
+ neg
+ translate
+ 200 200 moveto
+ orderK orderK orderK STARTK
+ stroke
+ closepath
+ grestore
+} def % receives nothing
+
+%%% Draws an arbitrary Koch's snowflake
+
+/Koch {
+ /orderK exch store
+ gsave
+ 3 1 roll
+ translate
+ 180 div dup scale
+ rand 360 mod rotate
+ Koch180
+ grestore
+} def % Receives x y size order
+
+
+%%% Sample, bounded by an arc
+
+ 400 400 100 3 Koch
+ newpath
+ 400 400
+ 100 0 360 arc
+ stroke
+ closepath
+
+showpage
\ No newline at end of file
diff --git a/postscript-go/test_files/Mand.ps b/postscript-go/test_files/Mand.ps
new file mode 100644
index 0000000..1f0d427
--- /dev/null
+++ b/postscript-go/test_files/Mand.ps
@@ -0,0 +1,68 @@
+%!PS-Adobe-2.0
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% Mandelbrot set via PostScript code. Not optimized %
+% in any way. Centered in A4 paper. Escape time, B&W %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+/fun {
+ 4 3 roll % y c1 c2 x
+ dup dup % y c1 c2 x x x
+ mul % y c1 c2 x x^2
+ 5 4 roll % c1 c2 x x^2 y
+ dup dup mul % c1 c2 x x^2 y y^2
+ 2 index exch sub % c1 c2 x x^2 y (x^2-y^2)
+ 6 1 roll 2 index % (x^2-y^2) c1 c2 x x^2 y x
+ 2 mul mul % (x^2-y^2) c1 c2 x x^2 2xy
+ 6 1 roll % 2xy (x^2-y^2) c1 c2 x x^2
+ pop pop 4 1 roll % c2 2xy (x^2-y^2) c1
+ dup 5 1 roll add % c1 c2 2xy (x^2-y^2+c1)
+ 4 1 roll % (x^2-y^2+c1) c1 c2 2xy
+ 1 index % (x^2-y^2+c1) c1 c2 2xy c2
+ add 4 3 roll % c1 c2 (2xy+c2) (x^2-y^2+c1)
+ exch 4 2 roll % (x^2-y^2+c1) (2xy+c2) c1 c2
+} def
+
+/res 500 def
+/iter 50 def
+
+
+300 300 translate
+90 rotate
+-150 -260 translate
+0 1 res {
+ /x exch def
+ 0 1 res {
+ /y exch def
+ 0 0
+ -2.5 4 x mul res div add
+ 2 4 y mul res div sub
+ iter -1 0 {
+ /n exch store
+ fun
+ 2 index dup mul
+ 4 index dup mul
+ add sqrt
+ 4 gt
+ {exit} if
+ } for
+ pop pop pop pop
+
+
+ n 0 gt
+ {1 setgray
+ x y 0.7 0 360 arc
+ fill
+ }
+ {
+ 0 setgray
+ x y 0.5 0 360 arc
+ fill
+ } ifelse
+ } for
+ }for
+showpage
+
+
\ No newline at end of file
diff --git a/postscript-go/test_files/bell_206.ps b/postscript-go/test_files/bell_206.ps
new file mode 100644
index 0000000..d3e1d0e
--- /dev/null
+++ b/postscript-go/test_files/bell_206.ps
@@ -0,0 +1,3537 @@
+%!PS-Adobe-3.0
+%%Creator: GIMP PostScript file plugin V 1.11 by Peter Kirchgessner
+%%Title: C:\Documents and Settings\burkardt\My Documents\bell_206.ps
+%%CreationDate: Fri Feb 08 10:41:12 2002
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%Pages: 1
+%%BoundingBox: 14 14 275 815
+%%EndComments
+%%BeginProlog
+% Use own dictionary to avoid conflicts
+10 dict begin
+%%EndProlog
+%%Page: 1 1
+% Translate for offset
+14.173228 14.173228 translate
+% Translate to begin of first scanline
+0.000000 800.000000 translate
+260.000000 -800.000000 scale
+% Image geometry
+260 800 8
+% Transformation matrix
+[ 260 0 0 800 0 0 ]
+% Strings to hold RGB-samples per scanline
+/rstr 260 string def
+/gstr 260 string def
+/bstr 260 string def
+{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
+{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
+true 3
+%%BeginData: 188979 ASCII Bytes
+colorimage
+JcELb!c9aT_Z,,~>
+JcELb!c9aT_Z,,~>
+JcELb!c9gV_Z,,~>
+JcELb!b+i-_Z,,~>
+JcELb!b+i-_Z,,~>
+JcELb!b+i/_Z,,~>
+JcELb",]cGTu6n\~>
+JcELb",]cGTu6n\~>
+JcELb",]cGTu6n\~>
+JcELb"JJL_:$T[sJ,~>
+JcELb"JJL_:$T[sJ,~>
+JcELb"JJL_:$on!J,~>
+JcELb!4i)&!,][SJ,~>
+JcELb!4i)&!,][SJ,~>
+JcELb!4i)&!,][SJ,~>
+JcELb"k$(<:/&LCs*t~>
+JcELb"k$(<:/&LCs*t~>
+JcELb"k$(<:/&LCs*t~>
+JcELb!:]t]!`!A"`rCP~>
+JcELb!:]t]!`!A"`rCP~>
+JcELb!:]t]!`!A"`rCP~>
+JcELb#5M"f9MJ*]`rCP~>
+JcELb#5M"f9MJ*]`rCP~>
+JcELb#5M"f9MJ*]`rCP~>
+JcELb#Q7Xr9MLs7lGrpT~>
+JcELb#Q7Xr9MLs7lGrpT~>
+JcELb#Q7Xr9MLs9mDo6W~>
+JcEIa!+Pq$"/UTuoZ7&_~>
+JcEIa!+Pq$"/UTuoZ7&_~>
+JcEIa!+Pq$"/UTuoZ7&_~>
+JcEIa#C0!:9nhjk`lS11~>
+JcEIa#C0!:9nhjk`lS11~>
+JcEIa#CB-<9nhsp`lS11~>
+JcEIa#a%eS9kOF.8b'q&J,~>
+JcEIa#a%eS9kOF.8b'q&J,~>
+JcEIa#a%eS9kOF.8b'q&J,~>
+JcEIa!2]Zg"B56jBp$O;J,~>
+JcEIa!2]Zg"B>6iBp$O;J,~>
+JcEIa!2]Zg"BGBlC6?X Q4Y_MY,