aboutsummaryrefslogtreecommitdiff
path: root/hershey.go
blob: a3a1fc59d05452943a6b1719e2e762f5ecfb3b95 (plain)
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
112
113
114
115
116
117
118
119
package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

type Point struct {
	X, Y int
}

type Path []Point
type Set []Path

type Glyph struct {
	Set    Set
	Width  int
	Height int
	Left   int
	Right  int
}

type Font map[rune]Glyph

func parseInt(s string) (n int) {
	s = strings.TrimSpace(s)
	n, _ = strconv.Atoi(s)
	return
}

func parsePoint(in uint8) int {
	return int(in) - int('R')
}

func parseData(s string) Set {
	var st Set
	scanner := bufio.NewScanner(strings.NewReader(s))
	scanner.Split(bufio.ScanWords)
	for scanner.Scan() {
		el := scanner.Text()
		if len(el)%2 != 0 && el[0] == 'R' {
			el = el[1:]
		}
		var ph Path
		for n := 0; n < len(el); n += 2 {
			p := Point{
				Y: parsePoint(el[n]),
				X: parsePoint(el[n+1]),
			}
			ph = append(ph, p)
		}
		st = append(st, ph)
	}
	return st
}

func loadFont(fname string) Font {
	fnt := make(Font)

	f, err := os.Open(fname)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		n := parseInt(line[0:5])
		k := parseInt(line[5:8])
		l := parsePoint(line[8])
		r := parsePoint(line[9])
		fnt[rune(n)] = Glyph{
			Set:   parseData(line[10 : 10+(k-1)*2]),
			Left:  l,
			Right: r,
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
	return fnt
}

func (p Point) String() string {
	return fmt.Sprintf("%v,%v,", p.X, p.Y)
}

func (p Path) String() (s string) {
	//s = fmt.Sprint("Y0,", p[0])
	s = fmt.Sprint("M", p[0], "D")
	for _, pt := range p[1:] {
		s += fmt.Sprint(pt)
	}
	return
}

func (st Set) String() (s string) {
	for _, p := range st {
		s += fmt.Sprint(p)
	}
	return
}

func (g Glyph) String() string {
	return fmt.Sprint(g.Set)
}

func (f Font) Select(n []int) Font {
	ret := make(Font)
	for i, p := range n {
		ret[rune(i+32)] = f[rune(p)]
	}
	return ret
}