draw2d/postscript/operators_graphics.go

483 lines
14 KiB
Go
Raw Normal View History

2010-12-13 12:01:24 +00:00
// Copyright 2010 The postscript-go Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
2010-12-13 19:13:10 +00:00
// Graphics operators
package postscript
import (
"image"
"draw2d.googlecode.com/hg/draw2d"
"math"
2010-12-13 19:13:10 +00:00
"log"
)
//Path Construction Operators
func newpath(interpreter *Interpreter) {
interpreter.GetGraphicContext().BeginPath()
}
func closepath(interpreter *Interpreter) {
interpreter.GetGraphicContext().Close()
}
func currentpoint(interpreter *Interpreter) {
x, y := interpreter.GetGraphicContext().LastPoint()
interpreter.Push(x)
interpreter.Push(y)
}
func moveto(interpreter *Interpreter) {
y := interpreter.PopFloat()
x := interpreter.PopFloat()
interpreter.GetGraphicContext().MoveTo(x, y)
}
func rmoveto(interpreter *Interpreter) {
y := interpreter.PopFloat()
x := interpreter.PopFloat()
interpreter.GetGraphicContext().RMoveTo(x, y)
}
func lineto(interpreter *Interpreter) {
y := interpreter.PopFloat()
x := interpreter.PopFloat()
interpreter.GetGraphicContext().LineTo(x, y)
}
func rlineto(interpreter *Interpreter) {
y := interpreter.PopFloat()
x := interpreter.PopFloat()
interpreter.GetGraphicContext().RLineTo(x, y)
}
func curveto(interpreter *Interpreter) {
cy3 := interpreter.PopFloat()
cx3 := interpreter.PopFloat()
cy2 := interpreter.PopFloat()
cx2 := interpreter.PopFloat()
cy1 := interpreter.PopFloat()
cx1 := interpreter.PopFloat()
interpreter.GetGraphicContext().CubicCurveTo(cx1, cy1, cx2, cy2, cx3, cy3)
}
func rcurveto(interpreter *Interpreter) {
cy3 := interpreter.PopFloat()
cx3 := interpreter.PopFloat()
cy2 := interpreter.PopFloat()
cx2 := interpreter.PopFloat()
cy1 := interpreter.PopFloat()
cx1 := interpreter.PopFloat()
interpreter.GetGraphicContext().RCubicCurveTo(cx1, cy1, cx2, cy2, cx3, cy3)
}
2010-12-13 23:01:03 +00:00
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)
2010-12-13 23:01:03 +00:00
}
func clippath(interpreter *Interpreter) {
2010-12-13 19:13:10 +00:00
log.Printf("clippath not yet implemented")
}
func stroke(interpreter *Interpreter) {
interpreter.GetGraphicContext().Stroke()
}
func fill(interpreter *Interpreter) {
interpreter.GetGraphicContext().Fill()
}
func gsave(interpreter *Interpreter) {
interpreter.GetGraphicContext().Save()
}
func grestore(interpreter *Interpreter) {
interpreter.GetGraphicContext().Restore()
}
func setgray(interpreter *Interpreter) {
gray := interpreter.PopFloat()
color := image.RGBAColor{uint8(gray * 0xff), uint8(gray * 0xff), uint8(gray * 0xff), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
func setrgbcolor(interpreter *Interpreter) {
blue := interpreter.PopFloat()
green := interpreter.PopFloat()
red := interpreter.PopFloat()
color := image.RGBAColor{uint8(red * 0xff), uint8(green * 0xff), uint8(blue * 0xff), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
func hsbtorgb(hue, saturation, brightness float64) (red, green, blue int) {
var fr, fg, fb float64
if saturation == 0 {
fr, fg, fb = brightness, brightness, brightness
} else {
H := (hue - math.Floor(hue)) * 6
I := int(math.Floor(H))
F := H - float64(I)
M := brightness * (1 - saturation)
N := brightness * (1 - saturation*F)
K := brightness * (1 - saturation*(1-F))
switch I {
case 0:
fr = brightness
fg = K
fb = M
case 1:
fr = N
fg = brightness
fb = M
case 2:
fr = M
fg = brightness
fb = K
case 3:
fr = M
fg = N
fb = brightness
case 4:
fr = K
fg = M
fb = brightness
case 5:
fr = brightness
fg = M
fb = N
default:
fr, fb, fg = 0, 0, 0
}
}
red = int(fr*255. + 0.5)
green = int(fg*255. + 0.5)
blue = int(fb*255. + 0.5)
return
}
func sethsbcolor(interpreter *Interpreter) {
brightness := interpreter.PopFloat()
saturation := interpreter.PopFloat()
hue := interpreter.PopFloat()
red, green, blue := hsbtorgb(hue, saturation, brightness)
color := image.RGBAColor{uint8(red), uint8(green), uint8(blue), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
func setcmybcolor(interpreter *Interpreter) {
black := interpreter.PopFloat()
yellow := interpreter.PopFloat()
magenta := interpreter.PopFloat()
cyan := interpreter.PopFloat()
/* cyan = cyan / 255.0;
magenta = magenta / 255.0;
yellow = yellow / 255.0;
black = black / 255.0; */
red := cyan*(1.0-black) + black
green := magenta*(1.0-black) + black
blue := yellow*(1.0-black) + black
red = (1.0-red)*255.0 + 0.5
green = (1.0-green)*255.0 + 0.5
blue = (1.0-blue)*255.0 + 0.5
color := image.RGBAColor{uint8(red), uint8(green), uint8(blue), 0xff}
interpreter.GetGraphicContext().SetStrokeColor(color)
interpreter.GetGraphicContext().SetFillColor(color)
}
func setdash(interpreter *Interpreter) {
offset := interpreter.PopInt()
dash := interpreter.PopArray()
2010-12-13 19:13:10 +00:00
log.Printf("setdash not yet implemented dash: %v, offset: %d \n", dash, offset)
}
func setlinejoin(interpreter *Interpreter) {
linejoin := interpreter.PopInt()
switch linejoin {
case 0:
interpreter.GetGraphicContext().SetLineJoin(draw2d.MiterJoin)
case 1:
interpreter.GetGraphicContext().SetLineJoin(draw2d.RoundJoin)
case 2:
interpreter.GetGraphicContext().SetLineJoin(draw2d.BevelJoin)
}
}
func setlinecap(interpreter *Interpreter) {
linecap := interpreter.PopInt()
switch linecap {
case 0:
interpreter.GetGraphicContext().SetLineCap(draw2d.ButtCap)
case 1:
interpreter.GetGraphicContext().SetLineCap(draw2d.RoundCap)
case 2:
interpreter.GetGraphicContext().SetLineCap(draw2d.SquareCap)
}
}
func setmiterlimit(interpreter *Interpreter) {
interpreter.PopInt()
2010-12-13 19:13:10 +00:00
log.Printf("setmiterlimit not yet implemented")
}
func setlinewidth(interpreter *Interpreter) {
interpreter.GetGraphicContext().SetLineWidth(interpreter.PopFloat())
}
func showpage(interpreter *Interpreter) {
2010-12-13 19:13:10 +00:00
log.Printf("showpage may be an implementation specific, override show page to generate multi page images")
}
func show(interpreter *Interpreter) {
s := interpreter.PopString()
interpreter.GetGraphicContext().FillString(s)
2010-12-13 19:13:10 +00:00
log.Printf("show not really implemented")
}
//ax ay string ashow -> Add (ax , ay) to width of each glyph while showing string
func ashow(interpreter *Interpreter) {
log.Printf("ashow not really implemented")
s := interpreter.PopString()
interpreter.PopFloat()
interpreter.PopFloat()
interpreter.GetGraphicContext().FillString(s)
}
func findfont(interpreter *Interpreter) {
2010-12-13 19:13:10 +00:00
log.Printf("findfont not yet implemented")
}
func scalefont(interpreter *Interpreter) {
2010-12-13 19:13:10 +00:00
log.Printf("scalefont not yet implemented")
}
func setfont(interpreter *Interpreter) {
2010-12-13 19:13:10 +00:00
log.Printf("setfont not yet implemented")
}
func stringwidth(interpreter *Interpreter) {
interpreter.Push(10.0)
interpreter.Push(10.0)
2010-12-13 19:13:10 +00:00
log.Printf("stringwidth not yet implemented")
}
func setflat(interpreter *Interpreter) {
interpreter.Pop()
2010-12-13 19:13:10 +00:00
log.Printf("setflat not yet implemented")
}
func currentflat(interpreter *Interpreter) {
interpreter.Push(1.0)
2010-12-13 19:13:10 +00:00
log.Printf("currentflat not yet implemented")
}
// Coordinate System and Matrix operators
func matrix(interpreter *Interpreter) {
interpreter.Push(draw2d.NewIdentityMatrix())
}
2010-12-13 23:01:03 +00:00
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) {
2010-12-13 23:01:03 +00:00
value := interpreter.Pop()
matrix, ok := value.(draw2d.MatrixTransform)
var y float64
if !ok {
2010-12-13 23:01:03 +00:00
matrix = interpreter.GetGraphicContext().GetMatrixTransform()
y = value.(float64)
2010-12-13 23:01:03 +00:00
} else {
y = interpreter.PopFloat()
}
x := interpreter.PopFloat()
2010-12-13 23:01:03 +00:00
matrix.Transform(&x, &y)
interpreter.Push(x)
interpreter.Push(y)
}
func itransform(interpreter *Interpreter) {
2010-12-13 23:01:03 +00:00
value := interpreter.Pop()
matrix, ok := value.(draw2d.MatrixTransform)
var y float64
if !ok {
2010-12-13 23:01:03 +00:00
matrix = interpreter.GetGraphicContext().GetMatrixTransform()
y = value.(float64)
2010-12-13 23:01:03 +00:00
} else {
y = interpreter.PopFloat()
}
x := interpreter.PopFloat()
2010-12-13 23:01:03 +00:00
matrix.InverseTransform(&x, &y)
interpreter.Push(x)
interpreter.Push(y)
}
func translate(interpreter *Interpreter) {
2010-12-13 23:01:03 +00:00
value := interpreter.Pop()
matrix, ok := value.(draw2d.MatrixTransform)
var y float64
if !ok {
2010-12-13 23:01:03 +00:00
matrix = interpreter.GetGraphicContext().GetMatrixTransform()
y = value.(float64)
2010-12-13 23:01:03 +00:00
} else {
y = interpreter.PopFloat()
}
x := interpreter.PopFloat()
if !ok {
2010-12-13 23:01:03 +00:00
interpreter.GetGraphicContext().Translate(x, y)
} else {
matrix = draw2d.NewTranslationMatrix(x, y).Multiply(matrix)
interpreter.Push(matrix)
}
}
func rotate(interpreter *Interpreter) {
2010-12-13 23:01:03 +00:00
value := interpreter.Pop()
matrix, ok := value.(draw2d.MatrixTransform)
var angle float64
if !ok {
2010-12-13 23:01:03 +00:00
matrix = interpreter.GetGraphicContext().GetMatrixTransform()
angle = value.(float64) * math.Pi / 180
2010-12-13 23:01:03 +00:00
} else {
angle = interpreter.PopFloat() * math.Pi / 180
}
if !ok {
2010-12-13 23:01:03 +00:00
interpreter.GetGraphicContext().Rotate(angle)
} else {
matrix = draw2d.NewRotationMatrix(angle).Multiply(matrix)
interpreter.Push(matrix)
}
}
func scale(interpreter *Interpreter) {
2010-12-13 23:01:03 +00:00
value := interpreter.Pop()
matrix, ok := value.(draw2d.MatrixTransform)
var y float64
if !ok {
2010-12-13 23:01:03 +00:00
matrix = interpreter.GetGraphicContext().GetMatrixTransform()
y = value.(float64)
2010-12-13 23:01:03 +00:00
} else {
y = interpreter.PopFloat()
}
x := interpreter.PopFloat()
if !ok {
2010-12-13 23:01:03 +00:00
interpreter.GetGraphicContext().Scale(x, y)
} else {
matrix = draw2d.NewScaleMatrix(x, y).Multiply(matrix)
interpreter.Push(matrix)
}
}
func initDrawingOperators(interpreter *Interpreter) {
interpreter.SystemDefine("stroke", NewOperator(stroke))
interpreter.SystemDefine("fill", NewOperator(fill))
interpreter.SystemDefine("show", NewOperator(show))
2010-12-13 19:13:10 +00:00
interpreter.SystemDefine("ashow", NewOperator(ashow))
interpreter.SystemDefine("showpage", NewOperator(showpage))
interpreter.SystemDefine("findfont", NewOperator(findfont))
interpreter.SystemDefine("scalefont", NewOperator(scalefont))
interpreter.SystemDefine("setfont", NewOperator(setfont))
interpreter.SystemDefine("stringwidth", NewOperator(stringwidth))
// Graphic state operators
interpreter.SystemDefine("gsave", NewOperator(gsave))
interpreter.SystemDefine("grestore", NewOperator(grestore))
interpreter.SystemDefine("setrgbcolor", NewOperator(setrgbcolor))
interpreter.SystemDefine("sethsbcolor", NewOperator(sethsbcolor))
interpreter.SystemDefine("setcmybcolor", NewOperator(setcmybcolor))
interpreter.SystemDefine("setcmykcolor", NewOperator(setcmybcolor))
interpreter.SystemDefine("setgray", NewOperator(setgray))
interpreter.SystemDefine("setdash", NewOperator(setdash))
interpreter.SystemDefine("setlinejoin", NewOperator(setlinejoin))
interpreter.SystemDefine("setlinecap", NewOperator(setlinecap))
interpreter.SystemDefine("setmiterlimit", NewOperator(setmiterlimit))
interpreter.SystemDefine("setlinewidth", NewOperator(setlinewidth))
// Graphic state operators device dependent
interpreter.SystemDefine("setflat", NewOperator(setflat))
interpreter.SystemDefine("currentflat", NewOperator(currentflat))
// Coordinate System and Matrix operators
2010-12-13 19:13:10 +00:00
interpreter.SystemDefine("matrix", NewOperator(matrix))
2010-12-13 23:01:03 +00:00
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))
interpreter.SystemDefine("rotate", NewOperator(rotate))
interpreter.SystemDefine("scale", NewOperator(scale))
//Path Construction Operators
interpreter.SystemDefine("newpath", NewOperator(newpath))
interpreter.SystemDefine("closepath", NewOperator(closepath))
interpreter.SystemDefine("currentpoint", NewOperator(currentpoint))
interpreter.SystemDefine("moveto", NewOperator(moveto))
interpreter.SystemDefine("rmoveto", NewOperator(rmoveto))
interpreter.SystemDefine("lineto", NewOperator(lineto))
interpreter.SystemDefine("rlineto", NewOperator(rlineto))
interpreter.SystemDefine("curveto", NewOperator(curveto))
interpreter.SystemDefine("rcurveto", NewOperator(rcurveto))
2010-12-13 23:01:03 +00:00
interpreter.SystemDefine("arc", NewOperator(arc))
interpreter.SystemDefine("clippath", NewOperator(clippath))
}