-
Notifications
You must be signed in to change notification settings - Fork 1
/
fontgen.go
111 lines (93 loc) · 1.95 KB
/
fontgen.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"encoding/gob"
"flag"
"fmt"
"image"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"io"
"log"
"os"
"os/exec"
)
var thresh int = 200
var font = flag.String("font", "Monospace", "Font name")
var size = flag.String("size", "30", "Font size")
func main() {
flag.Parse()
fname := flag.Arg(0)
if fname == "" {
usage()
os.Exit(1)
}
fm := make(map[rune][]byte)
for c := '0'; c <= '9'; c++ {
fm[c] = genChar(c)
}
for c := 'a'; c <= 'z'; c++ {
fm[c] = genChar(c)
}
for c := 'A'; c <= 'Z'; c++ {
fm[c] = genChar(c)
}
file, err := os.Create(fname)
if err != nil {
log.Fatal(err)
}
enc := gob.NewEncoder(file)
err = enc.Encode(fm)
if err != nil {
log.Fatal(err)
}
file.Close()
}
func convertImage(file io.Reader) []byte {
m, _, err := image.Decode(file)
if err != nil {
log.Fatal(err)
}
bounds := m.Bounds()
xp := bounds.Max.X - bounds.Min.X
yp := bounds.Max.Y - bounds.Min.Y
a := make([]byte, yp*xp)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
col := m.At(x, y)
r, g, b, _ := col.RGBA()
gr := (299*r + 587*g + 114*b + 500) / 1000
gr >>= 8
px := 0
if int(gr) <= thresh {
px = 1
}
idx := xp*(y-bounds.Min.Y) + x - bounds.Min.X
a[idx] = byte(px)
}
}
return a
}
func genChar(char rune) []byte {
c := fmt.Sprintf("%c", char)
cmd := genImage(c, *size, *font)
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
a := convertImage(stdout)
if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
return a
}
func genImage(letter, size, font string) *exec.Cmd {
return exec.Command("convert", "-size", "15x25", "-pointsize", size, "-background", "white", "-fill", "black", "-filter", "Point", "-font", font, "-gravity", "center", "label:"+letter, "gif:-")
}
func usage() {
fmt.Fprintf(os.Stderr, "usage: fontgen [flags] filename\n")
flag.PrintDefaults()
}