commit 2b37461b54ceaf4485943941833d4f7e9648e22f Author: Timon Ringwald Date: Thu Oct 1 13:14:36 2020 +0200 initial commit diff --git a/buffer.go b/buffer.go new file mode 100644 index 0000000..af46f28 --- /dev/null +++ b/buffer.go @@ -0,0 +1,100 @@ +package buf2d + +import ( + "strings" +) + +// Buffer is a 2-dimensional rune buffer +type Buffer struct { + data [][]rune + width int + height int + parent *Buffer +} + +// NewBuffer makes a new buffer with the given dimensions +func NewBuffer(width, height int) *Buffer { + b := make([][]rune, width) + for x := range b { + b[x] = make([]rune, height) + for y := range b[x] { + b[x][y] = ' ' + } + } + + return &Buffer{ + data: b, + width: width, + height: height, + parent: nil, + } +} + +func (b *Buffer) Set(x, y int, c rune) { + b.data[x][y] = c +} + +func (b *Buffer) Get(x, y int) rune { + return b.data[x][y] +} + +func (b *Buffer) Size() (w, h int) { + return b.width, b.height +} + +func (b *Buffer) Width() int { + return b.width +} + +func (b *Buffer) Height() int { + return b.height +} + +// Draw calls drawFunc for every rune in this buffer +func (b *Buffer) Draw(drawFunc func(x, y int, c rune)) { + for x, row := range b.data { + for y, char := range row { + drawFunc(x, y, char) + } + } +} + +func (b *Buffer) String() string { + s := new(strings.Builder) + for ri, row := range b.data { + for _, char := range row { + s.WriteRune(char) + } + if ri != len(b.data)-1 { + s.WriteRune('\n') + } + } + return s.String() +} + +// Sub returns a buffer which is completely contained in this buffer +// Modifying the main buffer or the sub buffer will modify the other one as well +// This method can be used recursively +// If the given dimensions don't fit in the parent buffer, it will be truncated +func (b *Buffer) Sub(x, y, w, h int) *Buffer { + // sanitize inputs + x = limit(x, 0, b.width-1) + y = limit(y, 0, b.height-1) + w = limit(w, 1, b.width-x) + h = limit(h, 1, b.height-y) + + // make slice references + data := make([][]rune, w) + for dx := x; dx < x+w-1; dx++ { + row := b.data[dx] + data[dx] = row[y : y+w] + } + + // make buffer + return &Buffer{ + data: data, + width: w, + height: h, + parent: b, + } +} diff --git a/buffer_sub_test.go b/buffer_sub_test.go new file mode 100644 index 0000000..c5df613 --- /dev/null +++ b/buffer_sub_test.go @@ -0,0 +1,16 @@ +package buf2d + +import ( + "fmt" + "testing" +) + +func TestSub(t *testing.T) { + b := NewBuffer(10, 10) + s := b.Sub(1, 1, b.Width()-1, b.Height()-1) + b.Set(5, 5, 'a') + s.Set(5, 5, 'b') + + fmt.Println(b) + fmt.Println(s) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..42c54d9 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.tordarus.net/tordarus/buf2d + +go 1.15 diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..0c3a776 --- /dev/null +++ b/utils.go @@ -0,0 +1,19 @@ +package buf2d + +func limit(v, min, max int) int { + return getmax(getmin(v, max), min) +} + +func getmax(x, y int) int { + if x > y { + return x + } + return y +} + +func getmin(x, y int) int { + if x < y { + return x + } + return y +}