@@ -12,43 +12,57 @@ import (
1212// attributes and hyperlink.
1313type Segment = Cell
1414
15- // Screen represents an interface for a grid of cells that can be written to
16- // and read from.
15+ // Screen represents a screen grid of cells.
1716type Screen interface {
1817 // Width returns the width of the grid.
1918 Width () int
2019
2120 // Height returns the height of the grid.
2221 Height () int
2322
24- // SetCell writes a cell to the grid at the given position. It returns true
25- // if the cell was written successfully.
26- SetCell (x , y int , c Cell ) bool
27-
2823 // Cell returns the cell at the given position.
2924 Cell (x , y int ) (Cell , bool )
3025
31- // Resize resizes the grid to the given width and height.
32- Resize (width , height int )
26+ // Draw writes a cell to the grid at the given position. It returns true if
27+ // the cell was written successfully.
28+ Draw (x , y int , c Cell ) bool
3329}
3430
35- // SetContent writes the given data to the grid starting from the first cell.
36- func SetContent (d Screen , m Method , content string ) []int {
37- return setContent (d , content , m )
31+ // Paint writes the given data to the canvas. If rect is not nil, it only
32+ // writes to the rectangle. Otherwise, it writes to the whole canvas.
33+ func Paint (d Screen , m Method , content string , rect * Rectangle ) []int {
34+ if rect == nil {
35+ rect = & Rectangle {0 , 0 , d .Width (), d .Height ()}
36+ }
37+ return setContent (d , content , m , * rect )
3838}
3939
40- // Render returns a string representation of the grid with ANSI escape sequences.
41- func Render (d Screen ) string {
42- return RenderWithProfile (d , colorprofile .TrueColor )
40+ // RenderOptions represents options for rendering a canvas.
41+ type RenderOptions struct {
42+ // Profile is the color profile to use when rendering the canvas.
43+ Profile colorprofile.Profile
44+ }
45+
46+ // RenderOption is a function that configures a RenderOptions.
47+ type RenderOption func (* RenderOptions )
48+
49+ // WithRenderProfile sets the color profile to use when rendering the canvas.
50+ func WithRenderProfile (p colorprofile.Profile ) RenderOption {
51+ return func (o * RenderOptions ) {
52+ o .Profile = p
53+ }
4354}
4455
45- // RenderWithProfile returns a string representation of the grid with ANSI escape
46- // sequences converting styles and colors to the given color profile.
47- func RenderWithProfile (d Screen , p colorprofile.Profile ) string {
56+ // Render returns a string representation of the grid with ANSI escape sequences.
57+ func Render (d Screen , opts ... RenderOption ) string {
58+ var opt RenderOptions
59+ for _ , o := range opts {
60+ o (& opt )
61+ }
4862 var buf bytes.Buffer
4963 height := d .Height ()
5064 for y := 0 ; y < height ; y ++ {
51- _ , line := RenderLineWithProfile (d , y , p )
65+ _ , line := renderLine (d , y , opt )
5266 buf .WriteString (line )
5367 if y < height - 1 {
5468 buf .WriteString ("\r \n " )
@@ -59,14 +73,15 @@ func RenderWithProfile(d Screen, p colorprofile.Profile) string {
5973
6074// RenderLine returns a string representation of the yth line of the grid along
6175// with the width of the line.
62- func RenderLine (d Screen , n int ) (w int , line string ) {
63- return RenderLineWithProfile (d , n , colorprofile .TrueColor )
76+ func RenderLine (d Screen , n int , opts ... RenderOption ) (w int , line string ) {
77+ var opt RenderOptions
78+ for _ , o := range opts {
79+ o (& opt )
80+ }
81+ return renderLine (d , n , opt )
6482}
6583
66- // RenderLineWithProfile returns a string representation of the nth line of the
67- // grid along with the width of the line converting styles and colors to the
68- // given color profile.
69- func RenderLineWithProfile (d Screen , n int , p colorprofile.Profile ) (w int , line string ) {
84+ func renderLine (d Screen , n int , opt RenderOptions ) (w int , line string ) {
7085 var pen Style
7186 var link Link
7287 var buf bytes.Buffer
@@ -87,8 +102,8 @@ func RenderLineWithProfile(d Screen, n int, p colorprofile.Profile) (w int, line
87102 for x := 0 ; x < d .Width (); x ++ {
88103 if cell , ok := d .Cell (x , n ); ok && cell .Width > 0 {
89104 // Convert the cell's style and link to the given color profile.
90- cellStyle := cell .Style .Convert (p )
91- cellLink := cell .Link .Convert (p )
105+ cellStyle := cell .Style .Convert (opt . Profile )
106+ cellLink := cell .Link .Convert (opt . Profile )
92107 if cellStyle .Empty () && ! pen .Empty () {
93108 writePending ()
94109 buf .WriteString (ansi .ResetStyle ) //nolint:errcheck
@@ -134,15 +149,26 @@ func RenderLineWithProfile(d Screen, n int, p colorprofile.Profile) (w int, line
134149 return w , strings .TrimRight (buf .String (), " " ) // Trim trailing spaces
135150}
136151
137- // Fill fills the grid with the given cell.
138- func Fill (d Screen , c Cell ) {
139- for y := 0 ; y < d .Height (); y ++ {
140- for x := 0 ; x < d .Width (); x ++ {
141- d .SetCell (x , y , c ) //nolint:errcheck
152+ // Fill fills the canvas with the given cell. If rect is not nil, it only fills
153+ // the rectangle. Otherwise, it fills the whole canvas.
154+ func Fill (d Screen , c Cell , rect * Rectangle ) {
155+ if rect == nil {
156+ rect = & Rectangle {0 , 0 , d .Width (), d .Height ()}
157+ }
158+
159+ for y := rect .Y ; y < rect .Y + rect .Height ; y ++ {
160+ for x := rect .X ; x < rect .X + rect .Width ; x += c .Width {
161+ d .Draw (x , y , c ) //nolint:errcheck
142162 }
143163 }
144164}
145165
166+ // Clear clears the canvas with space cells. If rect is not nil, it only clears
167+ // the rectangle. Otherwise, it clears the whole canvas.
168+ func Clear (d Screen , rect * Rectangle ) {
169+ Fill (d , spaceCell , rect )
170+ }
171+
146172// Equal returns whether two grids are equal.
147173func Equal (a , b Screen ) bool {
148174 if a .Width () != b .Width () || a .Height () != b .Height () {
0 commit comments