diff --git a/canvas/braille/braille.go b/canvas/braille/braille.go index 915fb28..178f78e 100644 --- a/canvas/braille/braille.go +++ b/canvas/braille/braille.go @@ -225,6 +225,23 @@ func (c *Canvas) SetCellOpts(cellPoint image.Point, opts ...cell.Option) error { return nil } +// SetAreaCellOpts is like SetCellOpts, but sets the specified options on all +// the cells within the provided area. +func (c *Canvas) SetAreaCellOpts(cellArea image.Rectangle, opts ...cell.Option) error { + haveArea := c.regular.Area() + if !cellArea.In(haveArea) { + return fmt.Errorf("unable to set cell options in area %v, it must fit inside the available cell area is %v", cellArea, haveArea) + } + for col := haveArea.Min.X; col < haveArea.Max.X; col++ { + for row := haveArea.Min.Y; row < haveArea.Max.Y; row++ { + if err := c.SetCellOpts(image.Point{col, row}, opts...); err != nil { + return err + } + } + } + return nil +} + // Apply applies the canvas to the corresponding area of the terminal. // Guarantees to stay within limits of the area the canvas was created with. func (c *Canvas) Apply(t terminalapi.Terminal) error { diff --git a/canvas/braille/braille_test.go b/canvas/braille/braille_test.go index d58665f..518baea 100644 --- a/canvas/braille/braille_test.go +++ b/canvas/braille/braille_test.go @@ -286,6 +286,43 @@ func TestBraille(t *testing.T) { return ft }, }, + { + desc: "SetAreaCellOptions fails on area too large", + ar: image.Rect(0, 0, 1, 1), + pixelOps: func(c *Canvas) error { + return c.SetAreaCellOpts(image.Rect(0, 0, 2, 2), cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue)) + }, + wantErr: true, + }, + { + desc: "SetCellOptions sets the cell options", + ar: image.Rect(0, 0, 3, 3), + pixelOps: func(c *Canvas) error { + return c.SetAreaCellOpts(image.Rect(0, 0, 2, 2), cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue)) + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + cvs := testcanvas.MustNew(ft.Area()) + + for _, p := range []image.Point{ + {0, 0}, + {0, 1}, + {0, 2}, + {1, 0}, + {1, 1}, + {1, 2}, + {2, 0}, + {2, 1}, + {2, 2}, + } { + c := testcanvas.MustCell(cvs, p) + testcanvas.MustSetCell(cvs, p, c.Rune, cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue)) + } + testcanvas.MustApply(cvs, ft) + return ft + }, + }, + { desc: "set pixel 0,0", ar: image.Rect(0, 0, 1, 1), diff --git a/canvas/braille/testbraille/testbraille.go b/canvas/braille/testbraille/testbraille.go index 3743dbc..7f3d82a 100644 --- a/canvas/braille/testbraille/testbraille.go +++ b/canvas/braille/testbraille/testbraille.go @@ -68,3 +68,10 @@ func MustSetCellOpts(bc *braille.Canvas, cellPoint image.Point, opts ...cell.Opt panic(fmt.Sprintf("bc.SetCellOpts => unexpected error: %v", err)) } } + +// MustSetAreaCellOpts sets the cell options in the area or panics. +func MustSetAreaCellOpts(bc *braille.Canvas, cellArea image.Rectangle, opts ...cell.Option) { + if err := bc.SetAreaCellOpts(cellArea, opts...); err != nil { + panic(fmt.Sprintf("bc.SetAreaCellOpts => unexpected error: %v", err)) + } +}