added save and restore functions for draw state

This commit is contained in:
Thomas Friedel 2018-01-29 15:32:17 +01:00
parent 8a66ff2166
commit 6480345a60
3 changed files with 65 additions and 27 deletions

View file

@ -14,6 +14,23 @@ type Canvas struct {
x, y, w, h int
fx, fy, fw, fh float32
path []pathPoint
text struct {
target *image.RGBA
tex uint32
}
state drawState
stateStack []drawState
}
type pathPoint struct {
pos lm.Vec2
move bool
}
type drawState struct {
transform lm.Mat3x3
fill struct {
r, g, b, a float32
}
@ -21,18 +38,17 @@ type Canvas struct {
r, g, b, a float32
lineWidth float32
}
path []pathPoint
text struct {
font *Font
size float32
target *image.RGBA
tex uint32
}
}
type pathPoint struct {
pos lm.Vec2
move bool
fontSize float32
/*
The current transformation matrix.
The current clipping region.
The current dash list.
The current values of the following attributes: strokeStyle, fillStyle, globalAlpha,
lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX,
shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font,
textAlign, textBaseline, direction, imageSmoothingEnabled
*/
}
// New creates a new canvas with the given viewport coordinates.
@ -44,8 +60,9 @@ func New(x, y, w, h int) *Canvas {
x: x, y: y, w: w, h: h,
fx: float32(x), fy: float32(y),
fw: float32(w), fh: float32(h),
stateStack: make([]drawState, 0, 20),
}
cv.stroke.lineWidth = 1
cv.state.stroke.lineWidth = 1
return cv
}
@ -157,7 +174,8 @@ func glError() error {
func (cv *Canvas) SetFillColor(value ...interface{}) {
r, g, b, a, ok := parseColor(value...)
if ok {
cv.fill.r, cv.fill.g, cv.fill.b, cv.fill.a = r, g, b, a
f := &cv.state.fill
f.r, f.g, f.b, f.a = r, g, b, a
}
}
@ -165,19 +183,35 @@ func (cv *Canvas) SetFillColor(value ...interface{}) {
func (cv *Canvas) SetStrokeColor(value ...interface{}) {
r, g, b, a, ok := parseColor(value...)
if ok {
cv.stroke.r, cv.stroke.g, cv.stroke.b, cv.stroke.a = r, g, b, a
s := &cv.state.stroke
s.r, s.g, s.b, s.a = r, g, b, a
}
}
// SetLineWidth sets the line width for any line drawing calls
func (cv *Canvas) SetLineWidth(width float32) {
cv.stroke.lineWidth = width
cv.state.stroke.lineWidth = width
}
// SetFont sets the font and font size
func (cv *Canvas) SetFont(font *Font, size float32) {
cv.text.font = font
cv.text.size = size
cv.state.font = font
cv.state.fontSize = size
}
// Save saves the current draw state to a stack
func (cv *Canvas) Save() {
cv.stateStack = append(cv.stateStack, cv.state)
}
// Restore restores the last draw state from the stack if available
func (cv *Canvas) Restore() {
l := len(cv.stateStack)
if l <= 0 {
return
}
cv.state = cv.stateStack[l-1]
cv.stateStack = cv.stateStack[:l-1]
}
// FillRect fills a rectangle with the active color
@ -194,7 +228,8 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
gli.VertexAttribPointer(sr.vertex, 2, gl_FLOAT, false, 0, nil)
gli.Uniform4f(sr.color, cv.fill.r, cv.fill.g, cv.fill.b, cv.fill.a)
f := cv.state.fill
gli.Uniform4f(sr.color, f.r, f.g, f.b, f.a)
gli.EnableVertexAttribArray(sr.vertex)
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
gli.DisableVertexAttribArray(sr.vertex)

View file

@ -69,7 +69,8 @@ func (cv *Canvas) Stroke() {
gli.Clear(gl_STENCIL_BUFFER_BIT)
gli.UseProgram(sr.id)
gli.Uniform4f(sr.color, cv.stroke.r, cv.stroke.g, cv.stroke.b, cv.stroke.a)
s := cv.state.stroke
gli.Uniform4f(sr.color, s.r, s.g, s.b, s.a)
gli.EnableVertexAttribArray(sr.vertex)
gli.BindBuffer(gl_ARRAY_BUFFER, buf)
@ -86,8 +87,8 @@ func (cv *Canvas) Stroke() {
p1 := p.pos
v1 := p1.Sub(p0).Norm()
v2 := lm.Vec2{v1[1], -v1[0]}.MulF(cv.stroke.lineWidth * 0.5)
v1 = v1.MulF(cv.stroke.lineWidth * 0.5)
v2 := lm.Vec2{v1[1], -v1[0]}.MulF(cv.state.stroke.lineWidth * 0.5)
v1 = v1.MulF(cv.state.stroke.lineWidth * 0.5)
x0f, y0f := cv.vecToGL(p0.Sub(v1).Add(v2))
x1f, y1f := cv.vecToGL(p1.Add(v1).Add(v2))
@ -122,7 +123,8 @@ func (cv *Canvas) Fill() {
cv.activate()
gli.UseProgram(sr.id)
gli.Uniform4f(sr.color, cv.fill.r, cv.fill.g, cv.fill.b, cv.fill.a)
f := cv.state.fill
gli.Uniform4f(sr.color, f.r, f.g, f.b, f.a)
gli.EnableVertexAttribArray(sr.vertex)
gli.BindBuffer(gl_ARRAY_BUFFER, buf)

View file

@ -59,9 +59,10 @@ func (cv *Canvas) FillText(str string, x, y float32) {
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_RGBA, int32(cv.w), int32(cv.h), 0, gl_RGBA, gl_UNSIGNED_BYTE, nil)
}
fontRenderingContext.setFont(cv.text.font.font)
fontRenderingContext.setFontSize(float64(cv.text.size))
fontRenderingContext.setSrc(image.NewUniform(colorGLToGo(cv.fill.r, cv.fill.g, cv.fill.b, cv.fill.a)))
fontRenderingContext.setFont(cv.state.font.font)
fontRenderingContext.setFontSize(float64(cv.state.fontSize))
f := cv.state.fill
fontRenderingContext.setSrc(image.NewUniform(colorGLToGo(f.r, f.g, f.b, f.a)))
fontRenderingContext.setDst(cv.text.target)
fontRenderingContext.setClip(cv.text.target.Bounds())
_, bounds, _ := fontRenderingContext.drawString(str, fixed.Point26_6{X: fixed.Int26_6(x*64 + 0.5), Y: fixed.Int26_6(y*64 + 0.5)})