-
Notifications
You must be signed in to change notification settings - Fork 8
/
capture.go
79 lines (73 loc) · 2.22 KB
/
capture.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package main
import (
"fmt"
"github.com/errnoh/term.color"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"github.com/james4k/terminal"
"image"
"image/color/palette"
"image/draw"
"os"
)
var font *truetype.Font
const fontSize = 18
func init() {
fontData, err := Asset("font/Anonymous Pro Minus.ttf")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
font, err = freetype.ParseFont(fontData)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
// Capture draws virtual terminal and return paletted image
func (g *GifGenerator) Capture(state *terminal.State) (paletted *image.Paletted, err error) {
fb := font.Bounds(fontSize)
cursorX, cursorY := state.Cursor()
left, top, right, bottom := g.ScreenInfo.GetRedrawRange(g.Col, g.Row, state)
paletted = image.NewPaletted(image.Rect(left*int(fb.Max.X-fb.Min.X), top*int(fb.Max.Y-fb.Min.Y), right*int(fb.Max.X-fb.Min.X)+10, bottom*int(fb.Max.Y-fb.Min.Y)+10), palette.WebSafe)
c := freetype.NewContext()
c.SetFontSize(fontSize)
c.SetFont(font)
c.SetDst(paletted)
c.SetClip(image.Rect(0, 0, g.Col*int(fb.Max.X-fb.Min.X)+10, g.Row*int(fb.Max.Y-fb.Min.Y)+10))
for row := 0; row < g.Row; row++ {
for col := 0; col < g.Col; col++ {
ch, fg, bg := state.Cell(col, row)
var uniform *image.Uniform
// background color
if bg != terminal.DefaultBG {
if bg == terminal.DefaultFG {
uniform = image.White
} else {
uniform = image.NewUniform(color.Term256{Val: uint8(bg)})
}
}
// cursor
if state.CursorVisible() && (row == cursorY && col == cursorX) {
uniform = image.White
}
if uniform != nil {
draw.Draw(paletted, image.Rect(5+col*int(fb.Max.X-fb.Min.X), row*int(fb.Max.Y-fb.Min.Y)-int(fb.Min.Y), 5+(col+1)*int(fb.Max.X-fb.Min.X), (row+1)*int(fb.Max.Y-fb.Min.Y)-int(fb.Min.Y)), uniform, image.ZP, draw.Src)
}
// foreground color
switch fg {
case terminal.DefaultFG:
c.SetSrc(image.White)
case terminal.DefaultBG:
c.SetSrc(image.Black)
default:
c.SetSrc(image.NewUniform(color.Term256{Val: uint8(fg)}))
}
_, err = c.DrawString(string(ch), freetype.Pt(5+col*int(fb.Max.X-fb.Min.X), (row+1)*int(fb.Max.Y-fb.Min.Y)))
if err != nil {
return
}
}
}
return paletted, nil
}