buffer.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2017 Zack Guo <zack.y.guo@gmail.com>. All rights reserved.
  2. // Use of this source code is governed by a MIT license that can
  3. // be found in the LICENSE file.
  4. package termui
  5. import "image"
  6. // Cell is a rune with assigned Fg and Bg
  7. type Cell struct {
  8. Ch rune
  9. Fg Attribute
  10. Bg Attribute
  11. }
  12. // Buffer is a renderable rectangle cell data container.
  13. type Buffer struct {
  14. Area image.Rectangle // selected drawing area
  15. CellMap map[image.Point]Cell
  16. }
  17. // At returns the cell at (x,y).
  18. func (b Buffer) At(x, y int) Cell {
  19. return b.CellMap[image.Pt(x, y)]
  20. }
  21. // Set assigns a char to (x,y)
  22. func (b Buffer) Set(x, y int, c Cell) {
  23. b.CellMap[image.Pt(x, y)] = c
  24. }
  25. // Bounds returns the domain for which At can return non-zero color.
  26. func (b Buffer) Bounds() image.Rectangle {
  27. x0, y0, x1, y1 := 0, 0, 0, 0
  28. for p := range b.CellMap {
  29. if p.X > x1 {
  30. x1 = p.X
  31. }
  32. if p.X < x0 {
  33. x0 = p.X
  34. }
  35. if p.Y > y1 {
  36. y1 = p.Y
  37. }
  38. if p.Y < y0 {
  39. y0 = p.Y
  40. }
  41. }
  42. return image.Rect(x0, y0, x1+1, y1+1)
  43. }
  44. // SetArea assigns a new rect area to Buffer b.
  45. func (b *Buffer) SetArea(r image.Rectangle) {
  46. b.Area.Max = r.Max
  47. b.Area.Min = r.Min
  48. }
  49. // Sync sets drawing area to the buffer's bound
  50. func (b *Buffer) Sync() {
  51. b.SetArea(b.Bounds())
  52. }
  53. // NewCell returns a new cell
  54. func NewCell(ch rune, fg, bg Attribute) Cell {
  55. return Cell{ch, fg, bg}
  56. }
  57. // Merge merges bs Buffers onto b
  58. func (b *Buffer) Merge(bs ...Buffer) {
  59. for _, buf := range bs {
  60. for p, v := range buf.CellMap {
  61. b.Set(p.X, p.Y, v)
  62. }
  63. b.SetArea(b.Area.Union(buf.Area))
  64. }
  65. }
  66. // NewBuffer returns a new Buffer
  67. func NewBuffer() Buffer {
  68. return Buffer{
  69. CellMap: make(map[image.Point]Cell),
  70. Area: image.Rectangle{}}
  71. }
  72. // Fill fills the Buffer b with ch,fg and bg.
  73. func (b Buffer) Fill(ch rune, fg, bg Attribute) {
  74. for x := b.Area.Min.X; x < b.Area.Max.X; x++ {
  75. for y := b.Area.Min.Y; y < b.Area.Max.Y; y++ {
  76. b.Set(x, y, Cell{ch, fg, bg})
  77. }
  78. }
  79. }
  80. // NewFilledBuffer returns a new Buffer filled with ch, fb and bg.
  81. func NewFilledBuffer(x0, y0, x1, y1 int, ch rune, fg, bg Attribute) Buffer {
  82. buf := NewBuffer()
  83. buf.Area.Min = image.Pt(x0, y0)
  84. buf.Area.Max = image.Pt(x1, y1)
  85. for x := buf.Area.Min.X; x < buf.Area.Max.X; x++ {
  86. for y := buf.Area.Min.Y; y < buf.Area.Max.Y; y++ {
  87. buf.Set(x, y, Cell{ch, fg, bg})
  88. }
  89. }
  90. return buf
  91. }