Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
c8bb92675b | |||
![]() |
5189fad815 | ||
![]() |
68591a3821 | ||
![]() |
d036639ee6 | ||
![]() |
d2e9a6636f | ||
![]() |
e8109737af |
33
buffer.go
33
buffer.go
@ -7,6 +7,7 @@ import (
|
||||
// Buffer is a 2-dimensional buffer
|
||||
type Buffer[T any] struct {
|
||||
data [][]T
|
||||
x, y int
|
||||
width int
|
||||
height int
|
||||
parent *Buffer[T]
|
||||
@ -24,6 +25,7 @@ func NewBuffer[T any](width, height int, defaultValue T) *Buffer[T] {
|
||||
}
|
||||
|
||||
return &Buffer[T]{
|
||||
x: 0, y: 0,
|
||||
data: b,
|
||||
width: width,
|
||||
height: height,
|
||||
@ -32,18 +34,18 @@ func NewBuffer[T any](width, height int, defaultValue T) *Buffer[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer[T]) x(x int) int {
|
||||
func (b *Buffer[T]) limX(x int) int {
|
||||
return limit(x, 0, b.width-1)
|
||||
}
|
||||
|
||||
func (b *Buffer[T]) y(y int) int {
|
||||
func (b *Buffer[T]) limY(y int) int {
|
||||
return limit(y, 0, b.height-1)
|
||||
}
|
||||
|
||||
// Set sets the value at position (x,y) to c
|
||||
func (b *Buffer[T]) Set(x, y int, v T) {
|
||||
if b.width >= 0 && b.height >= 0 {
|
||||
b.data[b.y(y)][b.x(x)] = v
|
||||
if b.width > 0 && b.height > 0 {
|
||||
b.data[b.limY(y)][b.limX(x)] = v
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,14 +69,32 @@ func (b *Buffer[T]) Height() int {
|
||||
return b.height
|
||||
}
|
||||
|
||||
// ForEach calls f for every value in this buffer
|
||||
// Offset returns the offset of b relative to its parent buffer.
|
||||
// Offset returns zeros if b has no parent
|
||||
func (b *Buffer[T]) Offset() (x, y int) {
|
||||
return b.x, b.y
|
||||
}
|
||||
|
||||
// OffsetX returns the horizontal offset of b relative to its parent buffer.
|
||||
// OffsetX returns 0 if b has no parent
|
||||
func (b *Buffer[T]) OffsetX() int {
|
||||
return b.x
|
||||
}
|
||||
|
||||
// OffsetY returns the vertical offset of b relative to its parent buffer.
|
||||
// OffsetY returns 0 if b has no parent
|
||||
func (b *Buffer[T]) OffsetY() int {
|
||||
return b.y
|
||||
}
|
||||
|
||||
// ForEachLine calls f for each line in b
|
||||
func (b *Buffer[T]) ForEachLine(f func(line int, content []T)) {
|
||||
for line, content := range b.data {
|
||||
f(line, content)
|
||||
}
|
||||
}
|
||||
|
||||
// ForEach calls f for every value in this buffer
|
||||
// ForEach calls f for every value in b
|
||||
func (b *Buffer[T]) ForEach(f func(x, y int, v T)) {
|
||||
for y, col := range b.data {
|
||||
for x, v := range col {
|
||||
@ -116,6 +136,7 @@ func (b *Buffer[T]) Sub(x, y, w, h int) *Buffer[T] {
|
||||
|
||||
// make buffer
|
||||
return &Buffer[T]{
|
||||
x: x, y: y,
|
||||
data: data,
|
||||
width: w,
|
||||
height: h,
|
||||
|
@ -19,6 +19,12 @@ func TestSub(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
b := NewBuffer(10, 10, ' ')
|
||||
b.Set(11, 0, 'a')
|
||||
b := NewBuffer(0, 0, ' ')
|
||||
b.Set(0, 0, 'a')
|
||||
}
|
||||
|
||||
func TestOffset(t *testing.T) {
|
||||
b := NewBuffer(10, 10, ' ')
|
||||
b = b.Sub(3, 3, 3, 3)
|
||||
fmt.Println(b.OffsetX(), b.OffsetY())
|
||||
}
|
||||
|
6
go.mod
6
go.mod
@ -1,3 +1,7 @@
|
||||
module git.tordarus.net/Tordarus/buf2d
|
||||
module git.tordarus.net/tordarus/buf2d
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/mattn/go-runewidth v0.0.14
|
||||
|
||||
require github.com/rivo/uniseg v0.2.0 // indirect
|
||||
|
4
go.sum
4
go.sum
@ -0,0 +1,4 @@
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
@ -2,19 +2,23 @@ package buf2d
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// WriteString writes a whole string to the buffer at position (x,y)
|
||||
// no word wrap is applied at all. If the string does not fit, it will be truncated
|
||||
func WriteString(b *Buffer[rune], str string, x, y int) {
|
||||
// WriteString writes a whole string to the buffer at position (x,y).
|
||||
// no word wrap is applied at all. If the string does not fit, it will be truncated.
|
||||
// It returns the amount of runes in str
|
||||
func WriteString(b *Buffer[rune], str string, x, y int) (width int) {
|
||||
dx := x
|
||||
for _, r := range str {
|
||||
if dx >= b.width {
|
||||
if dx >= b.Width() {
|
||||
return
|
||||
}
|
||||
b.Set(dx, y, r)
|
||||
dx++
|
||||
dx += runewidth.RuneWidth(r)
|
||||
}
|
||||
return dx - x
|
||||
}
|
||||
|
||||
// WriteMultiLineString writes a multi-line string to the buffer at position (x,y)
|
||||
|
Loading…
x
Reference in New Issue
Block a user