-
Notifications
You must be signed in to change notification settings - Fork 0
/
font.go
77 lines (66 loc) · 1.24 KB
/
font.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
package captcha
import (
"encoding/gob"
"os"
)
const (
fontWidth = 15
fontHeight = 25
blackChar = 1
)
type Font struct {
data map[rune][]byte
}
var fonts = make(map[string]*Font)
var selectedFont string
func LoadFontFromFile(fname string) *Font {
f := make(map[rune][]byte)
file, err := os.Open(fname)
if err != nil {
return nil
}
dec := gob.NewDecoder(file)
err = dec.Decode(&f)
return &Font{f}
}
func AddFont(name string, f *Font) {
fonts[name] = f
if len(fonts) == 1 {
SelectFont(name)
}
}
func SelectFont(name string) {
_, ok := fonts[name]
if ok {
selectedFont = name
}
}
func Digit2Rune(d byte) rune {
switch {
case 0 <= d && d <= 9:
return rune(d) + '0'
case 10 <= d && d <= 10+byte('Z'-'A'):
return rune(d) + 'A' - 10
case 11+byte('Z'-'A') <= d && d <= 11+byte('Z'-'A')+byte('z'-'a'):
return rune(d) - 'Z' + 'A' + 'a' - 11
}
return 0
}
func Rune2Digit(c rune) byte {
switch {
case '0' <= c && c <= '9':
return byte(c - '0')
case 'A' <= c && c <= 'Z':
return byte(c - 'A' + 10)
case 'a' <= c && c <= 'z':
return byte(c - 'a' + 'Z' - 'A' + 11)
}
return 0
}
func getChar(d byte) []byte {
if selectedFont == "" {
panic("No font selected")
}
r := Digit2Rune(d)
return fonts[selectedFont].data[r]
}