diff --git a/canvas.go b/canvas.go index 57c45f1..a94684f 100644 --- a/canvas.go +++ b/canvas.go @@ -36,11 +36,11 @@ type pathPoint struct { type drawState struct { transform lm.Mat3x3 fill struct { - r, g, b, a float32 + color glColor } stroke struct { - r, g, b, a float32 - lineWidth float32 + color glColor + lineWidth float32 } font *Font fontSize float32 @@ -221,19 +221,17 @@ func glError() error { // SetFillColor sets the color for any fill calls func (cv *Canvas) SetFillColor(value ...interface{}) { - r, g, b, a, ok := parseColor(value...) + c, ok := parseColor(value...) if ok { - f := &cv.state.fill - f.r, f.g, f.b, f.a = r, g, b, a + cv.state.fill.color = c } } // SetStrokeColor sets the color for any line drawing calls func (cv *Canvas) SetStrokeColor(value ...interface{}) { - r, g, b, a, ok := parseColor(value...) + c, ok := parseColor(value...) if ok { - s := &cv.state.stroke - s.r, s.g, s.b, s.a = r, g, b, a + cv.state.stroke.color = c } } @@ -334,8 +332,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) - f := cv.state.fill - gli.Uniform4f(sr.color, f.r, f.g, f.b, f.a) + c := cv.state.fill.color + gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a) gli.EnableVertexAttribArray(sr.vertex) gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4) gli.DisableVertexAttribArray(sr.vertex) diff --git a/color.go b/color.go index 48bc534..ac11657 100644 --- a/color.go +++ b/color.go @@ -7,41 +7,46 @@ import ( "strings" ) -func colorGoToGL(color color.Color) (r, g, b, a float32) { - ir, ig, ib, ia := color.RGBA() - r = float32(ir) / 65535 - g = float32(ig) / 65535 - b = float32(ib) / 65535 - a = float32(ia) / 65535 - return +type glColor struct { + r, g, b, a float32 } -func colorGLToGo(r, g, b, a float32) color.Color { - if r < 0 { - r = 0 - } else if r > 1 { - r = 1 +func colorGoToGL(color color.Color) glColor { + ir, ig, ib, ia := color.RGBA() + var c glColor + c.r = float32(ir) / 65535 + c.g = float32(ig) / 65535 + c.b = float32(ib) / 65535 + c.a = float32(ia) / 65535 + return c +} + +func colorGLToGo(c glColor) color.Color { + if c.r < 0 { + c.r = 0 + } else if c.r > 1 { + c.r = 1 } - if g < 0 { - g = 0 - } else if g > 1 { - g = 1 + if c.g < 0 { + c.g = 0 + } else if c.g > 1 { + c.g = 1 } - if b < 0 { - b = 0 - } else if b > 1 { - b = 1 + if c.b < 0 { + c.b = 0 + } else if c.b > 1 { + c.b = 1 } - if a < 0 { - a = 0 - } else if a > 1 { - a = 1 + if c.a < 0 { + c.a = 0 + } else if c.a > 1 { + c.a = 1 } return color.RGBA{ - R: uint8(r * 255), - G: uint8(g * 255), - B: uint8(b * 255), - A: uint8(a * 255), + R: uint8(c.r * 255), + G: uint8(c.g * 255), + B: uint8(c.b * 255), + A: uint8(c.a * 255), } } @@ -117,34 +122,33 @@ func parseColorComponent(value interface{}) (float32, bool) { return 0, false } -func parseColor(value ...interface{}) (r, g, b, a float32, ok bool) { - a = 1 +func parseColor(value ...interface{}) (c glColor, ok bool) { if len(value) == 1 { switch v := value[0].(type) { case color.Color: - r, g, b, a = colorGoToGL(v) + c = colorGoToGL(v) ok = true return case [3]float32: - return v[0], v[1], v[2], 1, true + return glColor{r: v[0], g: v[1], b: v[2], a: 1}, true case [4]float32: - return v[0], v[1], v[2], v[3], true + return glColor{r: v[0], g: v[1], b: v[2], a: v[3]}, true case [3]float64: - return float32(v[0]), float32(v[1]), float32(v[2]), 1, true + return glColor{r: float32(v[0]), g: float32(v[1]), b: float32(v[2]), a: 1}, true case [4]float64: - return float32(v[0]), float32(v[1]), float32(v[2]), float32(v[3]), true + return glColor{r: float32(v[0]), g: float32(v[1]), b: float32(v[2]), a: float32(v[3])}, true case [3]int: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, 1, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: 1}, true case [4]int: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, float32(v[3]) / 255, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: float32(v[3]) / 255}, true case [3]uint: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, 1, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: 1}, true case [4]uint: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, float32(v[3]) / 255, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: float32(v[3]) / 255}, true case [3]uint8: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, 1, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: 1}, true case [4]uint8: - return float32(v[0]) / 255, float32(v[1]) / 255, float32(v[2]) / 255, float32(v[3]) / 255, true + return glColor{r: float32(v[0]) / 255, g: float32(v[1]) / 255, b: float32(v[2]) / 255, a: float32(v[3]) / 255}, true case string: if len(v) == 0 { return @@ -176,7 +180,7 @@ func parseColor(value ...interface{}) (r, g, b, a float32, ok bool) { } ia = ia*16 + ia } - return float32(ir) / 255, float32(ig) / 255, float32(ib) / 255, float32(ia) / 255, true + return glColor{r: float32(ir) / 255, g: float32(ig) / 255, b: float32(ib) / 255, a: float32(ia) / 255}, true } else if len(str) == 6 || len(str) == 8 { var ir, ig, ib int ia := 255 @@ -198,7 +202,7 @@ func parseColor(value ...interface{}) (r, g, b, a float32, ok bool) { return } } - return float32(ir) / 255, float32(ig) / 255, float32(ib) / 255, float32(ia) / 255, true + return glColor{r: float32(ir) / 255, g: float32(ig) / 255, b: float32(ib) / 255, a: float32(ia) / 255}, true } else { return } @@ -207,11 +211,11 @@ func parseColor(value ...interface{}) (r, g, b, a float32, ok bool) { var ir, ig, ib, ia int n, err := fmt.Sscanf(v, "rgb(%d,%d,%d)", &ir, &ig, &ib) if err == nil && n == 3 { - return float32(ir) / 255, float32(ig) / 255, float32(ib) / 255, 1, true + return glColor{r: float32(ir) / 255, g: float32(ig) / 255, b: float32(ib) / 255, a: 1}, true } n, err = fmt.Sscanf(v, "rgba(%d,%d,%d,%d)", &ir, &ig, &ib, &ia) if err == nil && n == 4 { - return float32(ir) / 255, float32(ig) / 255, float32(ib) / 255, float32(ia) / 255, true + return glColor{r: float32(ir) / 255, g: float32(ig) / 255, b: float32(ib) / 255, a: float32(ia) / 255}, true } } } @@ -237,8 +241,8 @@ func parseColor(value ...interface{}) (r, g, b, a float32, ok bool) { } else { pa = 1 } - return pr, pg, pb, pa, true + return glColor{r: pr, g: pg, b: pb, a: pa}, true } - return 0, 0, 0, 1, false + return glColor{r: 0, g: 0, b: 0, a: 1}, false } diff --git a/paths.go b/paths.go index 35341d4..4dc7be4 100644 --- a/paths.go +++ b/paths.go @@ -166,8 +166,8 @@ func (cv *Canvas) Stroke() { gli.StencilMask(0x01) gli.UseProgram(sr.id) - s := cv.state.stroke - gli.Uniform4f(sr.color, s.r, s.g, s.b, s.a) + c := cv.state.stroke.color + gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a) gli.EnableVertexAttribArray(sr.vertex) gli.BindBuffer(gl_ARRAY_BUFFER, buf) @@ -353,8 +353,8 @@ func (cv *Canvas) Fill() { cv.activate() gli.UseProgram(sr.id) - f := cv.state.fill - gli.Uniform4f(sr.color, f.r, f.g, f.b, f.a) + c := cv.state.fill.color + gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a) gli.EnableVertexAttribArray(sr.vertex) gli.BindBuffer(gl_ARRAY_BUFFER, buf) @@ -395,8 +395,8 @@ func (cv *Canvas) clip(path []pathPoint) { gli.Clear(gl_STENCIL_BUFFER_BIT) gli.UseProgram(sr.id) - f := cv.state.fill - gli.Uniform4f(sr.color, f.r, f.g, f.b, f.a) + c := cv.state.fill.color + gli.Uniform4f(sr.color, c.r, c.g, c.b, c.a) gli.EnableVertexAttribArray(sr.vertex) gli.BindBuffer(gl_ARRAY_BUFFER, buf) diff --git a/text.go b/text.go index 838cfae..bf8a706 100644 --- a/text.go +++ b/text.go @@ -61,8 +61,7 @@ func (cv *Canvas) FillText(str string, x, y float32) { 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.setSrc(image.NewUniform(colorGLToGo(cv.state.fill.color))) 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)})