diff options
Diffstat (limited to 'examples/go-dashboard/src/github.com/mum4k/termdash/private/canvas/buffer/buffer.go')
-rw-r--r-- | examples/go-dashboard/src/github.com/mum4k/termdash/private/canvas/buffer/buffer.go | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/examples/go-dashboard/src/github.com/mum4k/termdash/private/canvas/buffer/buffer.go b/examples/go-dashboard/src/github.com/mum4k/termdash/private/canvas/buffer/buffer.go deleted file mode 100644 index 5c21dd0ba..000000000 --- a/examples/go-dashboard/src/github.com/mum4k/termdash/private/canvas/buffer/buffer.go +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2018 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package buffer implements a 2-D buffer of cells. -package buffer - -import ( - "fmt" - "image" - - "github.com/mum4k/termdash/cell" - "github.com/mum4k/termdash/private/area" - "github.com/mum4k/termdash/private/runewidth" -) - -// NewCells breaks the provided text into cells and applies the options. -func NewCells(text string, opts ...cell.Option) []*Cell { - var res []*Cell - for _, r := range text { - res = append(res, NewCell(r, opts...)) - } - return res -} - -// Cell represents a single cell on the terminal. -type Cell struct { - // Rune is the rune stored in the cell. - Rune rune - - // Opts are the cell options. - Opts *cell.Options -} - -// String implements fmt.Stringer. -func (c *Cell) String() string { - return fmt.Sprintf("{%q}", c.Rune) -} - -// NewCell returns a new cell. -func NewCell(r rune, opts ...cell.Option) *Cell { - return &Cell{ - Rune: r, - Opts: cell.NewOptions(opts...), - } -} - -// Copy returns a copy the cell. -func (c *Cell) Copy() *Cell { - return &Cell{ - Rune: c.Rune, - Opts: cell.NewOptions(c.Opts), - } -} - -// Apply applies the provided options to the cell. -func (c *Cell) Apply(opts ...cell.Option) { - for _, opt := range opts { - opt.Set(c.Opts) - } -} - -// Buffer is a 2-D buffer of cells. -// The axes increase right and down. -// Uninitialized buffer is invalid, use New to create an instance. -// Don't set cells directly, use the SetCell method instead which safely -// handles limits and wide unicode characters. -type Buffer [][]*Cell - -// New returns a new Buffer of the provided size. -func New(size image.Point) (Buffer, error) { - if size.X <= 0 { - return nil, fmt.Errorf("invalid buffer width (size.X): %d, must be a positive number", size.X) - } - if size.Y <= 0 { - return nil, fmt.Errorf("invalid buffer height (size.Y): %d, must be a positive number", size.Y) - } - - b := make([][]*Cell, size.X) - for col := range b { - b[col] = make([]*Cell, size.Y) - for row := range b[col] { - b[col][row] = NewCell(0) - } - } - return b, nil -} - -// SetCell sets the rune of the specified cell in the buffer. Returns the -// number of cells the rune occupies, wide runes can occupy multiple cells when -// printed on the terminal. See http://www.unicode.org/reports/tr11/. -// Use the options to specify which attributes to modify, if an attribute -// option isn't specified, the attribute retains its previous value. -func (b Buffer) SetCell(p image.Point, r rune, opts ...cell.Option) (int, error) { - partial, err := b.IsPartial(p) - if err != nil { - return -1, err - } - if partial { - return -1, fmt.Errorf("cannot set rune %q at point %v, it is a partial cell occupied by a wide rune in the previous cell", r, p) - } - - remW, err := b.RemWidth(p) - if err != nil { - return -1, err - } - rw := runewidth.RuneWidth(r) - if rw == 0 { - // Even if the rune is invisible, like the zero-value rune, it still - // occupies at least the target cell. - rw = 1 - } - if rw > remW { - return -1, fmt.Errorf("cannot set rune %q of width %d at point %v, only have %d remaining cells at this line", r, rw, p, remW) - } - - c := b[p.X][p.Y] - c.Rune = r - c.Apply(opts...) - return rw, nil -} - -// IsPartial returns true if the cell at the specified point holds a part of a -// full width rune from a previous cell. See -// http://www.unicode.org/reports/tr11/. -func (b Buffer) IsPartial(p image.Point) (bool, error) { - size := b.Size() - ar, err := area.FromSize(size) - if err != nil { - return false, err - } - - if !p.In(ar) { - return false, fmt.Errorf("point %v falls outside of the area %v occupied by the buffer", p, ar) - } - - if p.X == 0 && p.Y == 0 { - return false, nil - } - - prevP := image.Point{p.X - 1, p.Y} - if prevP.X < 0 { - prevP = image.Point{size.X - 1, p.Y - 1} - } - - prevR := b[prevP.X][prevP.Y].Rune - switch rw := runewidth.RuneWidth(prevR); rw { - case 0, 1: - return false, nil - case 2: - return true, nil - default: - return false, fmt.Errorf("buffer cell %v contains rune %q which has an unsupported rune with %d", prevP, prevR, rw) - } -} - -// RemWidth returns the remaining width (horizontal row of cells) available -// from and inclusive of the specified point. -func (b Buffer) RemWidth(p image.Point) (int, error) { - size := b.Size() - ar, err := area.FromSize(size) - if err != nil { - return -1, err - } - - if !p.In(ar) { - return -1, fmt.Errorf("point %v falls outside of the area %v occupied by the buffer", p, ar) - } - return size.X - p.X, nil -} - -// Size returns the size of the buffer. -func (b Buffer) Size() image.Point { - return image.Point{ - len(b), - len(b[0]), - } -} |