Fix ESC codes duplicates for ASCII stream

This commit is contained in:
Alex X
2024-05-17 14:34:24 +03:00
parent d428a8964a
commit 6878f05e57

View File

@@ -16,28 +16,23 @@ func NewWriter(w io.Writer, foreground, background, text string) io.Writer {
// every frame - move to home // every frame - move to home
a := &writer{wr: w, buf: []byte(csiHome)} a := &writer{wr: w, buf: []byte(csiHome)}
var idx0 uint8
// https://en.wikipedia.org/wiki/ANSI_escape_code // https://en.wikipedia.org/wiki/ANSI_escape_code
switch foreground { switch foreground {
case "": case "":
case "8": case "8":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
if idx := xterm256color(r, g, b, 8); idx != idx0 { idx := xterm256color(r, g, b, 8)
idx0 = idx a.appendEsc(fmt.Sprintf("\033[%dm", 30+idx))
a.buf = append(a.buf, fmt.Sprintf("\033[%dm", 30+idx)...)
}
} }
case "256": case "256":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
if idx := xterm256color(r, g, b, 255); idx != idx0 { idx := xterm256color(r, g, b, 255)
idx0 = idx a.appendEsc(fmt.Sprintf("\033[38;5;%dm", idx))
a.buf = append(a.buf, fmt.Sprintf("\033[38;5;%dm", idx)...)
}
} }
case "rgb": case "rgb":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
a.buf = append(a.buf, fmt.Sprintf("\033[38;2;%d;%d;%dm", r, g, b)...) a.appendEsc(fmt.Sprintf("\033[38;2;%d;%d;%dm", r, g, b))
} }
default: default:
a.buf = append(a.buf, "\033["+foreground+"m"...) a.buf = append(a.buf, "\033["+foreground+"m"...)
@@ -47,21 +42,17 @@ func NewWriter(w io.Writer, foreground, background, text string) io.Writer {
case "": case "":
case "8": case "8":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
if idx := xterm256color(r, g, b, 8); idx != idx0 { idx := xterm256color(r, g, b, 8)
idx0 = idx a.appendEsc(fmt.Sprintf("\033[%dm", 40+idx))
a.buf = append(a.buf, fmt.Sprintf("\033[%dm", 40+idx)...)
}
} }
case "256": case "256":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
if idx := xterm256color(r, g, b, 255); idx != idx0 { idx := xterm256color(r, g, b, 255)
idx0 = idx a.appendEsc(fmt.Sprintf("\033[48;5;%dm", idx))
a.buf = append(a.buf, fmt.Sprintf("\033[48;5;%dm", idx)...)
}
} }
case "rgb": case "rgb":
a.color = func(r, g, b uint8) { a.color = func(r, g, b uint8) {
a.buf = append(a.buf, fmt.Sprintf("\033[48;2;%d;%d;%dm", r, g, b)...) a.appendEsc(fmt.Sprintf("\033[48;2;%d;%d;%dm", r, g, b))
} }
default: default:
a.buf = append(a.buf, "\033["+background+"m"...) a.buf = append(a.buf, "\033["+background+"m"...)
@@ -104,6 +95,7 @@ type writer struct {
wr io.Writer wr io.Writer
buf []byte buf []byte
pre int pre int
esc string
color func(r, g, b uint8) color func(r, g, b uint8)
text func(r, g, b uint32) text func(r, g, b uint32)
} }
@@ -122,7 +114,6 @@ func (a *writer) Write(p []byte) (n int, err error) {
w := img.Bounds().Dx() w := img.Bounds().Dx()
h := img.Bounds().Dy() h := img.Bounds().Dy()
for y := 0; y < h; y++ { for y := 0; y < h; y++ {
for x := 0; x < w; x++ { for x := 0; x < w; x++ {
r, g, b, _ := img.At(x, y).RGBA() r, g, b, _ := img.At(x, y).RGBA()
@@ -134,7 +125,7 @@ func (a *writer) Write(p []byte) (n int, err error) {
a.buf = append(a.buf, '\n') a.buf = append(a.buf, '\n')
} }
a.buf = append(a.buf, "\033[0m"...) a.appendEsc("\033[0m")
if _, err = a.wr.Write(a.buf); err != nil { if _, err = a.wr.Write(a.buf); err != nil {
return 0, err return 0, err
@@ -145,6 +136,14 @@ func (a *writer) Write(p []byte) (n int, err error) {
return len(p), nil return len(p), nil
} }
// appendEsc - append ESC code to buffer, and skip duplicates
func (a *writer) appendEsc(s string) {
if a.esc != s {
a.esc = s
a.buf = append(a.buf, s...)
}
}
func gray(r, g, b uint32, k float32) uint8 { func gray(r, g, b uint32, k float32) uint8 {
gr := (19595*r + 38470*g + 7471*b + 1<<15) >> 24 // uint8 gr := (19595*r + 38470*g + 7471*b + 1<<15) >> 24 // uint8
return uint8(float32(gr) * k) return uint8(float32(gr) * k)