mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
Add image.DrawLine / DrawLines
This commit is contained in:
parent
22e6996f74
commit
8c15b57d58
@ -26,8 +26,10 @@ const (
|
||||
)
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
screen.DrawRect(10, 10, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
|
||||
screen.DrawRect(20, 20, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
|
||||
screen.FillRect(10, 10, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
|
||||
screen.FillRect(20, 20, 100, 100, color.NRGBA{0x80, 0x80, 0xff, 0x80})
|
||||
screen.DrawLine(130, 10, 140, 150, color.NRGBA{0xff, 0x80, 0x80, 0x80})
|
||||
screen.DrawLine(140, 10, 150, 150, color.NRGBA{0xff, 0x80, 0x80, 0x80})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ const (
|
||||
FilterLinear
|
||||
)
|
||||
|
||||
func glFilter(c *opengl.Context, filter Filter) opengl.FilterType {
|
||||
func glFilter(c *opengl.Context, filter Filter) opengl.Filter {
|
||||
switch filter {
|
||||
case FilterNearest:
|
||||
return c.Nearest
|
||||
|
21
image.go
21
image.go
@ -95,15 +95,28 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// DrawLine draws a line.
|
||||
func (i *Image) DrawLine(x0, y0, x1, y1 int, clr color.Color) error {
|
||||
return i.DrawLines(&line{x0, y0, x1, y1, clr})
|
||||
}
|
||||
|
||||
// DrawLines draws lines.
|
||||
func (i *Image) DrawLines(lines Lines) (err error) {
|
||||
ui.Use(func(c *opengl.Context) {
|
||||
err = i.framebuffer.DrawLines(c, lines)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// DrawRect draws a rectangle.
|
||||
func (i *Image) DrawRect(x, y, width, height int, clr color.Color) error {
|
||||
return i.DrawRects(&rect{x, y, width, height, clr})
|
||||
func (i *Image) FillRect(x, y, width, height int, clr color.Color) error {
|
||||
return i.FillRects(&rect{x, y, width, height, clr})
|
||||
}
|
||||
|
||||
// DrawRects draws rectangles on the image.
|
||||
func (i *Image) DrawRects(rects Rects) (err error) {
|
||||
func (i *Image) FillRects(rects Rects) (err error) {
|
||||
ui.Use(func(c *opengl.Context) {
|
||||
err = i.framebuffer.DrawRects(c, rects)
|
||||
err = i.framebuffer.FillRects(c, rects)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -114,16 +114,30 @@ func (f *Framebuffer) DrawTexture(c *opengl.Context, t *Texture, quads TextureQu
|
||||
return shader.DrawTexture(c, t.native, p, quads, geo, clr)
|
||||
}
|
||||
|
||||
type Lines interface {
|
||||
Len() int
|
||||
Points(i int) (x0, y0, x1, y1 int)
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
func (f *Framebuffer) DrawLines(c *opengl.Context, lines Lines) error {
|
||||
if err := f.setAsViewport(c); err != nil {
|
||||
return err
|
||||
}
|
||||
p := f.projectionMatrix()
|
||||
return shader.DrawLines(c, p, lines)
|
||||
}
|
||||
|
||||
type Rects interface {
|
||||
Len() int
|
||||
Rect(i int) (x, y, width, height int)
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
func (f *Framebuffer) DrawRects(c *opengl.Context, rects Rects) error {
|
||||
func (f *Framebuffer) FillRects(c *opengl.Context, rects Rects) error {
|
||||
if err := f.setAsViewport(c); err != nil {
|
||||
return err
|
||||
}
|
||||
p := f.projectionMatrix()
|
||||
return shader.DrawRects(c, p, rects)
|
||||
return shader.FillRects(c, p, rects)
|
||||
}
|
||||
|
@ -85,7 +85,51 @@ func DrawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
|
||||
return nil
|
||||
}
|
||||
c.BufferSubData(c.ArrayBuffer, vertices)
|
||||
c.DrawElements(6 * num)
|
||||
c.DrawElements(c.Triangles, 6*num)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Lines interface {
|
||||
Len() int
|
||||
Points(i int) (x0, y0, x1, y1 int)
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
func DrawLines(c *opengl.Context, projectionMatrix *[4][4]float64, lines Lines) error {
|
||||
if !initialized {
|
||||
if err := initialize(c); err != nil {
|
||||
return err
|
||||
}
|
||||
initialized = true
|
||||
}
|
||||
|
||||
if lines.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
f := useProgramLines(c, glMatrix(projectionMatrix))
|
||||
defer f.FinishProgram()
|
||||
|
||||
vertices := vertices[0:0]
|
||||
num := 0
|
||||
for i := 0; i < lines.Len(); i++ {
|
||||
x0, y0, x1, y1 := lines.Points(i)
|
||||
if x0 == x1 && y0 == y1 {
|
||||
continue
|
||||
}
|
||||
r, g, b, a := lines.Color(i).RGBA()
|
||||
vertices = append(vertices,
|
||||
int16(x0), int16(y0), int16(r), int16(g), int16(b), int16(a),
|
||||
int16(x1), int16(y1), int16(r), int16(g), int16(b), int16(a),
|
||||
)
|
||||
num++
|
||||
}
|
||||
if len(vertices) == 0 {
|
||||
return nil
|
||||
}
|
||||
c.BufferSubData(c.ArrayBuffer, vertices)
|
||||
c.DrawElements(c.Lines, 2*num)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -95,7 +139,7 @@ type Rects interface {
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
func DrawRects(c *opengl.Context, projectionMatrix *[4][4]float64, rects Rects) error {
|
||||
func FillRects(c *opengl.Context, projectionMatrix *[4][4]float64, rects Rects) error {
|
||||
if !initialized {
|
||||
if err := initialize(c); err != nil {
|
||||
return err
|
||||
@ -107,7 +151,7 @@ func DrawRects(c *opengl.Context, projectionMatrix *[4][4]float64, rects Rects)
|
||||
return nil
|
||||
}
|
||||
|
||||
f := useProgramRect(c, glMatrix(projectionMatrix))
|
||||
f := useProgramRects(c, glMatrix(projectionMatrix))
|
||||
defer f.FinishProgram()
|
||||
|
||||
vertices := vertices[0:0]
|
||||
@ -131,7 +175,7 @@ func DrawRects(c *opengl.Context, projectionMatrix *[4][4]float64, rects Rects)
|
||||
return nil
|
||||
}
|
||||
c.BufferSubData(c.ArrayBuffer, vertices)
|
||||
c.DrawElements(6 * num)
|
||||
c.DrawElements(c.Triangles, 6*num)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -16,13 +16,20 @@ package shader
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||
"math"
|
||||
)
|
||||
|
||||
var (
|
||||
indexBufferLines opengl.Buffer
|
||||
indexBufferQuads opengl.Buffer
|
||||
)
|
||||
|
||||
var (
|
||||
programTexture opengl.Program
|
||||
programRect opengl.Program
|
||||
programSolid opengl.Program
|
||||
)
|
||||
|
||||
// TODO: Use math.MaxUint16??
|
||||
const quadsMaxNum = 65536 / 6
|
||||
|
||||
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
|
||||
@ -47,11 +54,11 @@ func initialize(c *opengl.Context) error {
|
||||
}
|
||||
defer c.DeleteShader(shaderFragmentTextureNative)
|
||||
|
||||
shaderFragmentRectNative, err := c.NewShader(c.FragmentShader, shader(c, shaderFragmentRect))
|
||||
shaderFragmentSolidNative, err := c.NewShader(c.FragmentShader, shader(c, shaderFragmentSolid))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.DeleteShader(shaderFragmentRectNative)
|
||||
defer c.DeleteShader(shaderFragmentSolidNative)
|
||||
|
||||
programTexture, err = c.NewProgram([]opengl.Shader{
|
||||
shaderVertexNative,
|
||||
@ -61,9 +68,9 @@ func initialize(c *opengl.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
programRect, err = c.NewProgram([]opengl.Shader{
|
||||
programSolid, err = c.NewProgram([]opengl.Shader{
|
||||
shaderVertexColorNative,
|
||||
shaderFragmentRectNative,
|
||||
shaderFragmentSolidNative,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -81,7 +88,14 @@ func initialize(c *opengl.Context) error {
|
||||
indices[6*i+4] = 4*i + 2
|
||||
indices[6*i+5] = 4*i + 3
|
||||
}
|
||||
c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw)
|
||||
indexBufferQuads = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw)
|
||||
|
||||
// TODO: Use math.MaxUint16
|
||||
indices = make([]uint16, 65536)
|
||||
for i := uint16(0); i < math.MaxUint16; i++ {
|
||||
indices[i] = i
|
||||
}
|
||||
indexBufferLines = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -101,6 +115,8 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
|
||||
}
|
||||
program := programTexture
|
||||
|
||||
c.BindElementArrayBuffer(indexBufferQuads)
|
||||
|
||||
c.UniformFloats(program, "projection_matrix", projectionMatrix)
|
||||
|
||||
ma := float32(geo.Element(0, 0))
|
||||
@ -153,12 +169,38 @@ func useProgramTexture(c *opengl.Context, projectionMatrix []float32, texture op
|
||||
}
|
||||
}
|
||||
|
||||
func useProgramRect(c *opengl.Context, projectionMatrix []float32) programFinisher {
|
||||
if !lastProgram.Equals(programRect) {
|
||||
c.UseProgram(programRect)
|
||||
lastProgram = programRect
|
||||
func useProgramLines(c *opengl.Context, projectionMatrix []float32) programFinisher {
|
||||
if !lastProgram.Equals(programSolid) {
|
||||
c.UseProgram(programSolid)
|
||||
lastProgram = programSolid
|
||||
}
|
||||
program := programRect
|
||||
program := programSolid
|
||||
|
||||
c.BindElementArrayBuffer(indexBufferLines)
|
||||
|
||||
c.UniformFloats(program, "projection_matrix", projectionMatrix)
|
||||
|
||||
c.EnableVertexAttribArray(program, "vertex")
|
||||
c.EnableVertexAttribArray(program, "color")
|
||||
|
||||
// TODO: Change to floats?
|
||||
c.VertexAttribPointer(program, "vertex", true, false, int16Size*6, 2, uintptr(int16Size*0))
|
||||
c.VertexAttribPointer(program, "color", false, true, int16Size*6, 4, uintptr(int16Size*2))
|
||||
|
||||
return func() {
|
||||
c.DisableVertexAttribArray(program, "color")
|
||||
c.DisableVertexAttribArray(program, "vertex")
|
||||
}
|
||||
}
|
||||
|
||||
func useProgramRects(c *opengl.Context, projectionMatrix []float32) programFinisher {
|
||||
if !lastProgram.Equals(programSolid) {
|
||||
c.UseProgram(programSolid)
|
||||
lastProgram = programSolid
|
||||
}
|
||||
program := programSolid
|
||||
|
||||
c.BindElementArrayBuffer(indexBufferQuads)
|
||||
|
||||
c.UniformFloats(program, "projection_matrix", projectionMatrix)
|
||||
|
||||
|
@ -25,7 +25,7 @@ const (
|
||||
shaderVertex shaderId = iota
|
||||
shaderVertexColor
|
||||
shaderFragmentTexture
|
||||
shaderFragmentRect
|
||||
shaderFragmentSolid
|
||||
)
|
||||
|
||||
func shader(c *opengl.Context, id shaderId) string {
|
||||
@ -83,7 +83,7 @@ void main(void) {
|
||||
gl_FragColor = color;
|
||||
}
|
||||
`,
|
||||
shaderFragmentRect: `
|
||||
shaderFragmentSolid: `
|
||||
varying lowp vec4 vertex_out_color;
|
||||
|
||||
void main(void) {
|
||||
|
@ -54,7 +54,7 @@ func (t *Texture) Size() (width, height int) {
|
||||
return t.width, t.height
|
||||
}
|
||||
|
||||
func NewTexture(c *opengl.Context, width, height int, filter opengl.FilterType) (*Texture, error) {
|
||||
func NewTexture(c *opengl.Context, width, height int, filter opengl.Filter) (*Texture, error) {
|
||||
w := internal.NextPowerOf2Int(width)
|
||||
h := internal.NextPowerOf2Int(height)
|
||||
if w < 4 {
|
||||
@ -70,7 +70,7 @@ func NewTexture(c *opengl.Context, width, height int, filter opengl.FilterType)
|
||||
return &Texture{native, width, height}, nil
|
||||
}
|
||||
|
||||
func NewTextureFromImage(c *opengl.Context, img image.Image, filter opengl.FilterType) (*Texture, error) {
|
||||
func NewTextureFromImage(c *opengl.Context, img image.Image, filter opengl.Filter) (*Texture, error) {
|
||||
origSize := img.Bounds().Size()
|
||||
if origSize.X < 4 {
|
||||
return nil, errors.New("width must be equal or more than 4.")
|
||||
|
@ -22,10 +22,13 @@ import (
|
||||
"github.com/go-gl/gl"
|
||||
)
|
||||
|
||||
// TODO: Why int?
|
||||
|
||||
type Texture int
|
||||
type Framebuffer int
|
||||
type Shader int
|
||||
type Program int
|
||||
type Buffer gl.Buffer
|
||||
|
||||
// TODO: Remove this after the GopherJS bug was fixed (#159)
|
||||
func (p Program) Equals(other Program) bool {
|
||||
@ -53,6 +56,8 @@ func NewContext() *Context {
|
||||
ElementArrayBuffer: gl.ELEMENT_ARRAY_BUFFER,
|
||||
DynamicDraw: gl.DYNAMIC_DRAW,
|
||||
StaticDraw: gl.STATIC_DRAW,
|
||||
Triangles: gl.TRIANGLES,
|
||||
Lines: gl.LINES,
|
||||
}
|
||||
c.init()
|
||||
return c
|
||||
@ -65,7 +70,7 @@ func (c *Context) init() {
|
||||
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
func (c *Context) NewTexture(width, height int, pixels []uint8, filter FilterType) (Texture, error) {
|
||||
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
|
||||
t := gl.GenTexture()
|
||||
if t < 0 {
|
||||
return 0, errors.New("glGenTexture failed")
|
||||
@ -231,8 +236,9 @@ func (c *Context) DisableVertexAttribArray(p Program, location string) {
|
||||
l.DisableArray()
|
||||
}
|
||||
|
||||
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageType BufferUsageType) {
|
||||
gl.GenBuffer().Bind(gl.GLenum(bufferType))
|
||||
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsage BufferUsage) Buffer {
|
||||
b := gl.GenBuffer()
|
||||
b.Bind(gl.GLenum(bufferType))
|
||||
size := 0
|
||||
ptr := v
|
||||
switch v := v.(type) {
|
||||
@ -246,7 +252,12 @@ func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageTyp
|
||||
default:
|
||||
panic("not reach")
|
||||
}
|
||||
gl.BufferData(gl.GLenum(bufferType), size, ptr, gl.GLenum(bufferUsageType))
|
||||
gl.BufferData(gl.GLenum(bufferType), size, ptr, gl.GLenum(bufferUsage))
|
||||
return Buffer(b)
|
||||
}
|
||||
|
||||
func (c *Context) BindElementArrayBuffer(b Buffer) {
|
||||
gl.Buffer(b).Bind(gl.ELEMENT_ARRAY_BUFFER)
|
||||
}
|
||||
|
||||
func (c *Context) BufferSubData(bufferType BufferType, data []int16) {
|
||||
@ -254,8 +265,8 @@ func (c *Context) BufferSubData(bufferType BufferType, data []int16) {
|
||||
gl.BufferSubData(gl.GLenum(bufferType), 0, int16Size*len(data), data)
|
||||
}
|
||||
|
||||
func (c *Context) DrawElements(len int) {
|
||||
gl.DrawElements(gl.TRIANGLES, len, gl.UNSIGNED_SHORT, uintptr(0))
|
||||
func (c *Context) DrawElements(mode Mode, len int) {
|
||||
gl.DrawElements(gl.GLenum(mode), len, gl.UNSIGNED_SHORT, uintptr(0))
|
||||
}
|
||||
|
||||
func (c *Context) Flush() {
|
||||
|
@ -39,6 +39,10 @@ type Program struct {
|
||||
js.Object
|
||||
}
|
||||
|
||||
type Buffer struct {
|
||||
js.Object
|
||||
}
|
||||
|
||||
// TODO: Remove this after the GopherJS bug was fixed (#159)
|
||||
func (p Program) Equals(other Program) bool {
|
||||
return p.Object == other.Object
|
||||
@ -62,14 +66,16 @@ type context struct {
|
||||
|
||||
func NewContext(gl *webgl.Context) *Context {
|
||||
c := &Context{
|
||||
Nearest: FilterType(gl.NEAREST),
|
||||
Linear: FilterType(gl.LINEAR),
|
||||
Nearest: Filter(gl.NEAREST),
|
||||
Linear: Filter(gl.LINEAR),
|
||||
VertexShader: ShaderType(gl.VERTEX_SHADER),
|
||||
FragmentShader: ShaderType(gl.FRAGMENT_SHADER),
|
||||
ArrayBuffer: BufferType(gl.ARRAY_BUFFER),
|
||||
ElementArrayBuffer: BufferType(gl.ELEMENT_ARRAY_BUFFER),
|
||||
DynamicDraw: BufferUsageType(gl.DYNAMIC_DRAW),
|
||||
StaticDraw: BufferUsageType(gl.STATIC_DRAW),
|
||||
DynamicDraw: BufferUsage(gl.DYNAMIC_DRAW),
|
||||
StaticDraw: BufferUsage(gl.STATIC_DRAW),
|
||||
Triangles: Mode(gl.TRIANGLES),
|
||||
Lines: Mode(gl.LINES),
|
||||
}
|
||||
c.gl = gl
|
||||
c.init()
|
||||
@ -83,7 +89,7 @@ func (c *Context) init() {
|
||||
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
func (c *Context) NewTexture(width, height int, pixels []uint8, filter FilterType) (Texture, error) {
|
||||
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
|
||||
gl := c.gl
|
||||
t := gl.CreateTexture()
|
||||
if t == nil {
|
||||
@ -284,11 +290,17 @@ func (c *Context) DisableVertexAttribArray(p Program, location string) {
|
||||
gl.DisableVertexAttribArray(int(l))
|
||||
}
|
||||
|
||||
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageType BufferUsageType) {
|
||||
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsage BufferUsage) Buffer {
|
||||
gl := c.gl
|
||||
b := gl.CreateBuffer()
|
||||
gl.BindBuffer(int(bufferType), b)
|
||||
gl.BufferData(int(bufferType), v, int(bufferUsageType))
|
||||
gl.BufferData(int(bufferType), v, int(bufferUsage))
|
||||
return Buffer{b}
|
||||
}
|
||||
|
||||
func (c *Context) BindElementArrayBuffer(b Buffer) {
|
||||
gl := c.gl
|
||||
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.Object)
|
||||
}
|
||||
|
||||
func (c *Context) BufferSubData(bufferType BufferType, data []int16) {
|
||||
@ -296,9 +308,9 @@ func (c *Context) BufferSubData(bufferType BufferType, data []int16) {
|
||||
gl.BufferSubData(int(bufferType), 0, data)
|
||||
}
|
||||
|
||||
func (c *Context) DrawElements(len int) {
|
||||
func (c *Context) DrawElements(mode Mode, len int) {
|
||||
gl := c.gl
|
||||
gl.DrawElements(gl.TRIANGLES, len, gl.UNSIGNED_SHORT, 0)
|
||||
gl.DrawElements(int(mode), len, gl.UNSIGNED_SHORT, 0)
|
||||
}
|
||||
|
||||
func (c *Context) Flush() {
|
||||
|
@ -14,19 +14,22 @@
|
||||
|
||||
package opengl
|
||||
|
||||
type FilterType int
|
||||
type Filter int
|
||||
type ShaderType int
|
||||
type BufferType int
|
||||
type BufferUsageType int
|
||||
type BufferUsage int
|
||||
type Mode int
|
||||
|
||||
type Context struct {
|
||||
Nearest FilterType
|
||||
Linear FilterType
|
||||
Nearest Filter
|
||||
Linear Filter
|
||||
VertexShader ShaderType
|
||||
FragmentShader ShaderType
|
||||
ArrayBuffer BufferType
|
||||
ElementArrayBuffer BufferType
|
||||
DynamicDraw BufferUsageType
|
||||
StaticDraw BufferUsageType
|
||||
DynamicDraw BufferUsage
|
||||
StaticDraw BufferUsage
|
||||
Triangles Mode
|
||||
Lines Mode
|
||||
context
|
||||
}
|
||||
|
29
shapes.go
29
shapes.go
@ -1,4 +1,4 @@
|
||||
// Copyright 2014 Hajime Hoshi
|
||||
// Copyright 2015 Hajime Hoshi
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -18,10 +18,35 @@ import (
|
||||
"image/color"
|
||||
)
|
||||
|
||||
// A Lines represents the set of lines.
|
||||
type Lines interface {
|
||||
Len() int
|
||||
Points(i int) (x0, y0, x1, y1 int) // TODO: Change to float64?
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
type line struct {
|
||||
x0, y0 int
|
||||
x1, y1 int
|
||||
color color.Color
|
||||
}
|
||||
|
||||
func (l *line) Len() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (l *line) Points(i int) (x0, y0, x1, y1 int) {
|
||||
return l.x0, l.y0, l.x1, l.y1
|
||||
}
|
||||
|
||||
func (l *line) Color(i int) color.Color {
|
||||
return l.color
|
||||
}
|
||||
|
||||
// A Rects represents the set of rectangles.
|
||||
type Rects interface {
|
||||
Len() int
|
||||
Rect(i int) (x, y, width, height int)
|
||||
Rect(i int) (x, y, width, height int) // TODO: Change to float64?
|
||||
Color(i int) color.Color
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user