termui/drawille/drawille.go

91 lines
1.8 KiB
Go
Raw Normal View History

2019-06-19 03:30:44 +08:00
package drawille
import (
"image"
)
const BRAILLE_OFFSET = '\u2800'
var BRAILLE = [4][2]rune{
{'\u0001', '\u0008'},
{'\u0002', '\u0010'},
{'\u0004', '\u0020'},
{'\u0040', '\u0080'},
}
type Color int
type Cell struct {
Rune rune
Color Color
}
type Canvas struct {
CellMap map[image.Point]Cell
}
func NewCanvas() *Canvas {
return &Canvas{
CellMap: make(map[image.Point]Cell),
}
}
func (self *Canvas) SetPoint(p image.Point, color Color) {
point := image.Pt(p.X/2, p.Y/4)
self.CellMap[point] = Cell{
self.CellMap[point].Rune | BRAILLE[p.Y%4][p.X%2],
color,
}
}
func (self *Canvas) SetLine(p0, p1 image.Point, color Color) {
for _, p := range line(p0, p1) {
self.SetPoint(p, color)
}
}
func (self *Canvas) GetCells() map[image.Point]Cell {
cellMap := make(map[image.Point]Cell)
for point, cell := range self.CellMap {
cellMap[point] = Cell{cell.Rune + BRAILLE_OFFSET, cell.Color}
}
return cellMap
}
func line(p0, p1 image.Point) []image.Point {
points := []image.Point{}
leftPoint, rightPoint := p0, p1
if leftPoint.X > rightPoint.X {
leftPoint, rightPoint = rightPoint, leftPoint
}
xDistance := absInt(leftPoint.X - rightPoint.X)
yDistance := absInt(leftPoint.Y - rightPoint.Y)
slope := float64(yDistance) / float64(xDistance)
slopeSign := 1
if rightPoint.Y < leftPoint.Y {
slopeSign = -1
}
targetYCoordinate := float64(leftPoint.Y)
currentYCoordinate := leftPoint.Y
for i := leftPoint.X; i < rightPoint.X; i++ {
points = append(points, image.Pt(i, currentYCoordinate))
targetYCoordinate += (slope * float64(slopeSign))
for currentYCoordinate != int(targetYCoordinate) {
points = append(points, image.Pt(i, currentYCoordinate))
currentYCoordinate += slopeSign
}
}
return points
}
func absInt(x int) int {
if x >= 0 {
return x
}
return -x
}