made stroke and fill style code more generic

This commit is contained in:
Thomas Friedel 2018-02-09 11:41:57 +01:00
parent 91e8935866
commit ac8adda421
2 changed files with 46 additions and 47 deletions

View file

@ -35,18 +35,11 @@ type pathPoint struct {
type drawState struct {
transform lm.Mat3x3
fill struct {
color glColor
radialGradient *RadialGradient
linearGradient *LinearGradient
image *Image
}
stroke struct {
color glColor
lineWidth float32
}
fill drawStyle
stroke drawStyle
font *Font
fontSize float32
lineWidth float32
lineJoin lineJoin
lineEnd lineEnd
@ -66,6 +59,13 @@ type drawState struct {
*/
}
type drawStyle struct {
color glColor
radialGradient *RadialGradient
linearGradient *LinearGradient
image *Image
}
type lineJoin uint8
type lineEnd uint8
@ -88,7 +88,7 @@ func New(x, y, w, h int) *Canvas {
fw: float32(w), fh: float32(h),
stateStack: make([]drawState, 0, 20),
}
cv.state.stroke.lineWidth = 1
cv.state.lineWidth = 1
cv.state.transform = lm.Mat3x3Identity()
return cv
}
@ -325,33 +325,40 @@ func glError() error {
return nil
}
// SetFillStyle sets the color or gradient for any fill calls
// SetFillStyle sets the color, gradient, or image for any fill calls
func (cv *Canvas) SetFillStyle(value ...interface{}) {
cv.state.fill.color = glColor{}
cv.state.fill.linearGradient = nil
cv.state.fill.radialGradient = nil
cv.state.fill.image = nil
cv.state.fill = parseStyle(value...)
}
// SetStrokeStyle sets the color, gradient, or image for any line drawing calls
func (cv *Canvas) SetStrokeStyle(value ...interface{}) {
cv.state.stroke = parseStyle(value...)
}
func parseStyle(value ...interface{}) drawStyle {
var style drawStyle
if len(value) == 1 {
switch v := value[0].(type) {
case *LinearGradient:
cv.state.fill.linearGradient = v
return
style.linearGradient = v
return style
case *RadialGradient:
cv.state.fill.radialGradient = v
return
style.radialGradient = v
return style
case *Image:
cv.state.fill.image = v
return
style.image = v
return style
}
}
c, ok := parseColor(value...)
if ok {
cv.state.fill.color = c
style.color = c
}
return style
}
func (cv *Canvas) useFillShader() (vertexLoc uint32) {
if lg := cv.state.fill.linearGradient; lg != nil {
func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
if lg := style.linearGradient; lg != nil {
lg.load()
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_1D, lg.tex)
@ -368,7 +375,7 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
gli.Uniform1i(lgr.gradient, 0)
return lgr.vertex
}
if rg := cv.state.fill.radialGradient; rg != nil {
if rg := style.radialGradient; rg != nil {
rg.load()
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_1D, rg.tex)
@ -388,7 +395,7 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
gli.Uniform1i(rgr.gradient, 0)
return rgr.vertex
}
if img := cv.state.fill.image; img != nil {
if img := style.image; img != nil {
gli.UseProgram(ipr.id)
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
@ -405,17 +412,9 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
return sr.vertex
}
// SetStrokeColor sets the color for any line drawing calls
func (cv *Canvas) SetStrokeColor(value ...interface{}) {
c, ok := parseColor(value...)
if ok {
cv.state.stroke.color = c
}
}
// SetLineWidth sets the line width for any line drawing calls
func (cv *Canvas) SetLineWidth(width float32) {
cv.state.stroke.lineWidth = width
cv.state.lineWidth = width
}
// SetFont sets the font and font size
@ -507,7 +506,7 @@ func (cv *Canvas) FillRect(x, y, w, h float32) {
data := [8]float32{p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]}
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
vertex := cv.useFillShader()
vertex := cv.useShader(&cv.state.fill)
gli.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, nil)
gli.EnableVertexAttribArray(vertex)
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)

View file

@ -181,8 +181,8 @@ func (cv *Canvas) Stroke() {
p1 := p.tf
v0 := p1.Sub(p0).Norm()
v1 := lm.Vec2{v0[1], -v0[0]}.MulF(cv.state.stroke.lineWidth * 0.5)
v0 = v0.MulF(cv.state.stroke.lineWidth * 0.5)
v1 := lm.Vec2{v0[1], -v0[0]}.MulF(cv.state.lineWidth * 0.5)
v0 = v0.MulF(cv.state.lineWidth * 0.5)
lp0 := p0.Add(v1)
lp1 := p1.Add(v1)
@ -197,7 +197,7 @@ func (cv *Canvas) Stroke() {
lp0 = lp0.Sub(v0)
lp2 = lp2.Sub(v0)
case Round:
tris = cv.addCircleTris(p0, cv.state.stroke.lineWidth*0.5, tris)
tris = cv.addCircleTris(p0, cv.state.lineWidth*0.5, tris)
}
}
@ -209,7 +209,7 @@ func (cv *Canvas) Stroke() {
lp1 = lp1.Add(v0)
lp3 = lp3.Add(v0)
case Round:
tris = cv.addCircleTris(p1, cv.state.stroke.lineWidth*0.5, tris)
tris = cv.addCircleTris(p1, cv.state.lineWidth*0.5, tris)
}
}
@ -257,7 +257,7 @@ func (cv *Canvas) Stroke() {
func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.Vec2, tris []float32) []float32 {
v2 := p1.Sub(p2).Norm()
v3 := lm.Vec2{v2[1], -v2[0]}.MulF(cv.state.stroke.lineWidth * 0.5)
v3 := lm.Vec2{v2[1], -v2[0]}.MulF(cv.state.lineWidth * 0.5)
switch cv.state.lineJoin {
case Miter:
@ -282,7 +282,7 @@ func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.V
p1[0], p1[1], l0p1[0], l0p1[1], l1p1[0], l1p1[1],
p1[0], p1[1], l1p3[0], l1p3[1], l0p3[0], l0p3[1])
case Round:
tris = cv.addCircleTris(p1, cv.state.stroke.lineWidth*0.5, tris)
tris = cv.addCircleTris(p1, cv.state.lineWidth*0.5, tris)
}
return tris