-
Notifications
You must be signed in to change notification settings - Fork 0
/
reader.go
99 lines (91 loc) · 1.9 KB
/
reader.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
package bitmapfont
import (
"bufio"
"log"
"os"
"strconv"
"strings"
)
type FontReader struct {
font *Font
}
func NewFontReader() *FontReader {
return new(FontReader)
}
func (r *FontReader) ReadFile(filename string) (*Font, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
r.font = NewFont()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
spaceSeparated := strings.Split(scanner.Text(), " ")
tag := spaceSeparated[0]
props := spaceSeparated[1:]
kvs, err := parseKeyValues(props)
if err != nil {
return nil, err
}
r.buildFont(tag, kvs)
}
return r.font, nil
}
func (r *FontReader) buildFont(tag string, kvs map[string]value) {
switch tag {
case "info":
r.font.info = buildInfo(kvs)
case "common":
r.font.Common = buildCommon(kvs)
case "page":
r.font.page = buildPage(kvs)
case "char":
r.font.addChar(buildChar(kvs))
case "kerning":
r.font.addKerning(buildKerning(kvs))
}
}
type value struct {
intValue int
stringValue string
intArray []int
}
func (v value) f32() float32 {
return float32(v.intValue)
}
func parseKeyValues(props []string) (map[string]value, error) {
kvs := map[string]value{}
for _, each := range props {
if len(each) > 0 {
kv := strings.SplitN(each, "=", 2) // value may contain "="
if len(kv) != 2 {
log.Printf("unexpected non-key-value:[%q]\n", each)
continue
}
v := value{}
if strings.HasPrefix(kv[1], "\"") {
v.stringValue = strings.Trim(kv[1], "\"")
} else if strings.Contains(kv[1], ",") {
nums := strings.Split(kv[1], ",")
ints := []int{}
for _, other := range nums {
i, err := strconv.Atoi(other)
if err != nil {
return kvs, err
}
ints = append(ints, i)
}
v.intArray = ints
} else {
i, err := strconv.Atoi(kv[1])
if err != nil {
return kvs, err
}
v.intValue = i
}
kvs[kv[0]] = v
}
}
return kvs, nil
}