forked from dennwc/inkview
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
95 lines (88 loc) · 1.84 KB
/
log.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package ink
import (
"bytes"
"fmt"
"image"
)
func NewLog(r image.Rectangle, sz int) *Log {
f := OpenFont(DefaultFontMono, sz, true)
return &Log{
clip: r, font: f, h: sz,
}
}
type Log struct {
clip image.Rectangle
font *Font
lines []string // lines buffer
w int // font width (since we use monospaced font)
h int // font height
Spacing int // line spacing
}
func (l *Log) Close() {
l.font.Close()
l.lines = nil
}
func (l *Log) appendLine(line string) {
h := l.clip.Size().Y
lh := l.h + l.Spacing
n := h / lh
if h%lh != 0 {
n++
}
if dn := len(l.lines) + 1 - n; dn > 0 {
// remove exceeding lines
copy(l.lines, l.lines[dn:])
l.lines = l.lines[:len(l.lines)-dn]
}
l.lines = append(l.lines, line)
}
func (l *Log) Write(p []byte) (int, error) {
lines := bytes.Split(p, []byte{'\n'})
if len(lines) != 0 && len(l.lines) != 0 {
// append string to the last line
li := len(l.lines) - 1
last := l.lines[li]
l.lines = l.lines[:li]
l.appendLine(last + string(lines[0]))
lines = lines[1:]
}
// add new lines
for _, line := range lines {
l.appendLine(string(line))
}
return len(p), nil
}
func (l *Log) Draw() {
l.font.SetActive(Black)
if l.w == 0 {
l.w = CharWidth('a')
}
FillArea(l.clip, White)
h := l.clip.Size().Y
if h < l.h {
DrawString(l.clip.Min, "window size is too small")
return
}
for i := len(l.lines) - 1; i >= 0; i-- {
s := l.lines[i]
h -= l.h + l.Spacing
if h < 0 {
break
}
if s == "" {
continue
}
p := image.Pt(0, h)
DrawString(p.Add(l.clip.Min), s)
}
}
func (l *Log) WriteString(s string) error {
_, err := l.Write([]byte(s))
return err
}
func (l *Log) Println(args ...interface{}) error {
return l.WriteString(fmt.Sprint(args...))
}
func (l *Log) Printf(format string, args ...interface{}) error {
return l.WriteString(fmt.Sprintf(format, args...))
}