made stroke and fill style code more generic
This commit is contained in:
parent
91e8935866
commit
ac8adda421
2 changed files with 46 additions and 47 deletions
73
canvas.go
73
canvas.go
|
@ -35,18 +35,11 @@ type pathPoint struct {
|
||||||
|
|
||||||
type drawState struct {
|
type drawState struct {
|
||||||
transform lm.Mat3x3
|
transform lm.Mat3x3
|
||||||
fill struct {
|
fill drawStyle
|
||||||
color glColor
|
stroke drawStyle
|
||||||
radialGradient *RadialGradient
|
|
||||||
linearGradient *LinearGradient
|
|
||||||
image *Image
|
|
||||||
}
|
|
||||||
stroke struct {
|
|
||||||
color glColor
|
|
||||||
lineWidth float32
|
|
||||||
}
|
|
||||||
font *Font
|
font *Font
|
||||||
fontSize float32
|
fontSize float32
|
||||||
|
lineWidth float32
|
||||||
lineJoin lineJoin
|
lineJoin lineJoin
|
||||||
lineEnd lineEnd
|
lineEnd lineEnd
|
||||||
|
|
||||||
|
@ -66,6 +59,13 @@ type drawState struct {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type drawStyle struct {
|
||||||
|
color glColor
|
||||||
|
radialGradient *RadialGradient
|
||||||
|
linearGradient *LinearGradient
|
||||||
|
image *Image
|
||||||
|
}
|
||||||
|
|
||||||
type lineJoin uint8
|
type lineJoin uint8
|
||||||
type lineEnd uint8
|
type lineEnd uint8
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ func New(x, y, w, h int) *Canvas {
|
||||||
fw: float32(w), fh: float32(h),
|
fw: float32(w), fh: float32(h),
|
||||||
stateStack: make([]drawState, 0, 20),
|
stateStack: make([]drawState, 0, 20),
|
||||||
}
|
}
|
||||||
cv.state.stroke.lineWidth = 1
|
cv.state.lineWidth = 1
|
||||||
cv.state.transform = lm.Mat3x3Identity()
|
cv.state.transform = lm.Mat3x3Identity()
|
||||||
return cv
|
return cv
|
||||||
}
|
}
|
||||||
|
@ -325,33 +325,40 @@ func glError() error {
|
||||||
return nil
|
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{}) {
|
func (cv *Canvas) SetFillStyle(value ...interface{}) {
|
||||||
cv.state.fill.color = glColor{}
|
cv.state.fill = parseStyle(value...)
|
||||||
cv.state.fill.linearGradient = nil
|
}
|
||||||
cv.state.fill.radialGradient = nil
|
|
||||||
cv.state.fill.image = nil
|
// 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 {
|
if len(value) == 1 {
|
||||||
switch v := value[0].(type) {
|
switch v := value[0].(type) {
|
||||||
case *LinearGradient:
|
case *LinearGradient:
|
||||||
cv.state.fill.linearGradient = v
|
style.linearGradient = v
|
||||||
return
|
return style
|
||||||
case *RadialGradient:
|
case *RadialGradient:
|
||||||
cv.state.fill.radialGradient = v
|
style.radialGradient = v
|
||||||
return
|
return style
|
||||||
case *Image:
|
case *Image:
|
||||||
cv.state.fill.image = v
|
style.image = v
|
||||||
return
|
return style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c, ok := parseColor(value...)
|
c, ok := parseColor(value...)
|
||||||
if ok {
|
if ok {
|
||||||
cv.state.fill.color = c
|
style.color = c
|
||||||
}
|
}
|
||||||
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *Canvas) useFillShader() (vertexLoc uint32) {
|
func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {
|
||||||
if lg := cv.state.fill.linearGradient; lg != nil {
|
if lg := style.linearGradient; lg != nil {
|
||||||
lg.load()
|
lg.load()
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
gli.BindTexture(gl_TEXTURE_1D, lg.tex)
|
gli.BindTexture(gl_TEXTURE_1D, lg.tex)
|
||||||
|
@ -368,7 +375,7 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
|
||||||
gli.Uniform1i(lgr.gradient, 0)
|
gli.Uniform1i(lgr.gradient, 0)
|
||||||
return lgr.vertex
|
return lgr.vertex
|
||||||
}
|
}
|
||||||
if rg := cv.state.fill.radialGradient; rg != nil {
|
if rg := style.radialGradient; rg != nil {
|
||||||
rg.load()
|
rg.load()
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
gli.BindTexture(gl_TEXTURE_1D, rg.tex)
|
gli.BindTexture(gl_TEXTURE_1D, rg.tex)
|
||||||
|
@ -388,7 +395,7 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
|
||||||
gli.Uniform1i(rgr.gradient, 0)
|
gli.Uniform1i(rgr.gradient, 0)
|
||||||
return rgr.vertex
|
return rgr.vertex
|
||||||
}
|
}
|
||||||
if img := cv.state.fill.image; img != nil {
|
if img := style.image; img != nil {
|
||||||
gli.UseProgram(ipr.id)
|
gli.UseProgram(ipr.id)
|
||||||
gli.ActiveTexture(gl_TEXTURE0)
|
gli.ActiveTexture(gl_TEXTURE0)
|
||||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||||
|
@ -405,17 +412,9 @@ func (cv *Canvas) useFillShader() (vertexLoc uint32) {
|
||||||
return sr.vertex
|
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
|
// SetLineWidth sets the line width for any line drawing calls
|
||||||
func (cv *Canvas) SetLineWidth(width float32) {
|
func (cv *Canvas) SetLineWidth(width float32) {
|
||||||
cv.state.stroke.lineWidth = width
|
cv.state.lineWidth = width
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFont sets the font and font size
|
// 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]}
|
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)
|
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.VertexAttribPointer(vertex, 2, gl_FLOAT, false, 0, nil)
|
||||||
gli.EnableVertexAttribArray(vertex)
|
gli.EnableVertexAttribArray(vertex)
|
||||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||||
|
|
12
paths.go
12
paths.go
|
@ -181,8 +181,8 @@ func (cv *Canvas) Stroke() {
|
||||||
p1 := p.tf
|
p1 := p.tf
|
||||||
|
|
||||||
v0 := p1.Sub(p0).Norm()
|
v0 := p1.Sub(p0).Norm()
|
||||||
v1 := lm.Vec2{v0[1], -v0[0]}.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.stroke.lineWidth * 0.5)
|
v0 = v0.MulF(cv.state.lineWidth * 0.5)
|
||||||
|
|
||||||
lp0 := p0.Add(v1)
|
lp0 := p0.Add(v1)
|
||||||
lp1 := p1.Add(v1)
|
lp1 := p1.Add(v1)
|
||||||
|
@ -197,7 +197,7 @@ func (cv *Canvas) Stroke() {
|
||||||
lp0 = lp0.Sub(v0)
|
lp0 = lp0.Sub(v0)
|
||||||
lp2 = lp2.Sub(v0)
|
lp2 = lp2.Sub(v0)
|
||||||
case Round:
|
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)
|
lp1 = lp1.Add(v0)
|
||||||
lp3 = lp3.Add(v0)
|
lp3 = lp3.Add(v0)
|
||||||
case Round:
|
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 {
|
func (cv *Canvas) lineJoint(p pathPoint, p0, p1, p2, l0p0, l0p1, l0p2, l0p3 lm.Vec2, tris []float32) []float32 {
|
||||||
v2 := p1.Sub(p2).Norm()
|
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 {
|
switch cv.state.lineJoin {
|
||||||
case Miter:
|
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], l0p1[0], l0p1[1], l1p1[0], l1p1[1],
|
||||||
p1[0], p1[1], l1p3[0], l1p3[1], l0p3[0], l0p3[1])
|
p1[0], p1[1], l1p3[0], l1p3[1], l0p3[0], l0p3[1])
|
||||||
case Round:
|
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
|
return tris
|
||||||
|
|
Loading…
Reference in a new issue