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
|
package widget
import (
"log"
"sync"
"image"
"image/color"
"image/draw"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
"golang.org/x/image/font/opentype"
"golang.org/x/image/math/fixed"
)
var (
FONT = goregular.TTF
FONT_SIZE = 15
DPI = 72
PADDING = 3
)
var face *concurrentFace
func init() {
fnt, err := opentype.Parse(FONT)
if err != nil {
log.Fatal(err)
}
fce, err := opentype.NewFace(fnt, &opentype.FaceOptions{
Size: float64(FONT_SIZE),
DPI: float64(DPI),
})
if err != nil {
log.Fatal(err)
}
face = &concurrentFace{sync.Mutex{}, fce}
}
func TextWidth(nchars int) int {
return nchars*FONT_SIZE + 2*PADDING // very rough estimation
}
func TextHeight() int {
return FONT_SIZE + 2*PADDING
}
func drawText(text []byte, dst draw.Image, r image.Rectangle, fg, bg color.Color) {
drawer := font.Drawer{
Src: &image.Uniform{fg},
Face: face,
Dot: fixed.P(0, 0),
}
// background
draw.Draw(dst, r, &image.Uniform{bg}, image.ZP, draw.Src)
// text image
bounds := textBounds(text, drawer)
textImg := image.NewRGBA(bounds)
draw.Draw(textImg, bounds, &image.Uniform{bg}, image.ZP, draw.Src)
drawer.Dst = textImg
drawer.DrawBytes(text)
// draw text image over background
left := image.Pt(bounds.Min.X, (bounds.Min.Y+bounds.Max.Y)/2)
target := image.Pt(r.Min.X, (r.Min.Y+r.Max.Y)/2)
delta := target.Sub(left)
draw.Draw(dst, bounds.Add(delta).Intersect(r), drawer.Dst, bounds.Min, draw.Src)
}
func textBounds(text []byte, drawer font.Drawer) image.Rectangle {
b, _ := drawer.BoundBytes(text)
return image.Rect(
b.Min.X.Floor(),
b.Min.Y.Floor(),
b.Max.X.Ceil(),
b.Max.Y.Ceil(),
)
}
|