altos/test: Adjust CRC error rate after FEC fix
[fw/altos] / src / stm / ao-parse-font.5c
1 #!/usr/bin/env nickle
2 #
3 # Parse a 14-segment font file
4 # and construct the bitmasks for each
5 # character. Output is in the same
6 # format as the input:
7 #       [5] = 0x1212,
8 # /*
9 # CHAR 37 '%'
10 #              
11 #       |    / 
12 #       |   /  
13 #              
14 #         /   |
15 #        /    |
16 #              
17 # */
18 #
19 # Note that there can only be tabs before the glyph image
20 # as spaces are significant in the image itself.
21 #
22
23 typedef struct {
24         int             c;
25         bool[14]        bits;
26 } glyph;
27
28 exception done();
29
30 glyph read_glyph(file f) {
31         int     c;
32
33         for (;;) {
34                 if (File::end(f))
35                         raise done();
36                 string  l = File::fgets(f);
37                 if (File::sscanf(l, "CHAR %d", &c) == 1)
38                         break;
39         }
40
41         string strip_tab(string x) {
42                 int i = 0;
43                 while (i < String::length(x) && x[i] == '\t')
44                         i++;
45                 string n = String::substr(x, i, String::length(x) - i);
46                 while (String::length(n) < 7)
47                         n = n + " ";
48                 return n;
49         }
50
51         string[7] lines = { [i] = strip_tab(File::fgets(f)) };
52
53         glyph   g = { .c = c };
54
55         g.bits[0] = lines[0][1] == '-';
56
57         g.bits[1] = lines[1][0] == '|';
58         g.bits[2] = lines[1][1] == '\\';
59         g.bits[3] = lines[1][3] == '|';
60         g.bits[4] = lines[1][5] == '/';
61         g.bits[5] = lines[1][6] == '|';
62
63         g.bits[6] = lines[3][1] == '-';
64         g.bits[7] = lines[3][4] == '-';
65
66         g.bits[8] = lines[5][0] == '|';
67         g.bits[9] = lines[5][1] == '/';
68         g.bits[10] = lines[5][3] == '|';
69         g.bits[11] = lines[5][5] == '\\';
70         g.bits[12] = lines[5][6] == '|';
71
72         g.bits[13] = lines[6][1] == '-';
73         return g;
74 }
75
76 string[*] glyph_image(glyph g) {
77         int[7][7] chars = { { ' ' ... } ... };
78
79         if (g.bits[0])
80                 for (int c = 1; c < 6; c++)
81                         chars[0][c] = '-';
82
83         if (g.bits[1])
84                 for (int r = 1; r < 3; r++)
85                         chars[r][0] = '|';
86         if (g.bits[2])
87                 for (int p = 1; p < 3; p++)
88                         chars[p][p] = '\\';
89         if (g.bits[3])
90                 for (int p = 1; p < 3; p++)
91                         chars[p][3] = '|';
92         if (g.bits[4])
93                 for (int p = 1; p < 3; p++)
94                         chars[p][6-p] = '/';
95         if (g.bits[5])
96                 for (int p = 1; p < 3; p++)
97                         chars[p][6] = '|';
98
99         if (g.bits[6])
100                 for (int p = 1; p < 3; p++)
101                         chars[3][p] = '-';
102         if (g.bits[7])
103                 for (int p = 4; p < 6; p++)
104                         chars[3][p] = '-';
105
106         if (g.bits[8])
107                 for (int r = 4; r < 6; r++)
108                         chars[r][0] = '|';
109         if (g.bits[9])
110                 for (int p = 4; p < 6; p++)
111                         chars[p][6-p] = '/';
112         if (g.bits[10])
113                 for (int p = 4; p < 6; p++)
114                         chars[p][3] = '|';
115         if (g.bits[11])
116                 for (int p = 4; p < 6; p++)
117                         chars[p][p] = '\\';
118         if (g.bits[12])
119                 for (int p = 4; p < 6; p++)
120                         chars[p][6] = '|';
121
122         if (g.bits[13])
123                 for (int c = 1; c < 6; c++)
124                         chars[6][c] = '-';
125                 
126         return (string[7]) { [i] = String::new(chars[i]) };
127
128 }
129
130 int glyph_value(glyph g) {
131         int     v = 0;
132
133         for (int b = 0; b < 14; b++)
134                 if (g.bits[b])
135                         v |= (1 << b);
136         return v;
137 }
138
139 void write_glyph(file f, glyph g) {
140         File::fprintf (f, "CHAR %d '%s'\n", g.c, g.c == 127 ? "DEL" : String::new(g.c));
141         string[7] lines = glyph_image(g);
142         for (int i = 0; i < 7; i++)
143                 File::fprintf (f, "\t%s\n", lines[i]);
144 }
145
146 autoload Sort;
147
148 glyph[*] read_font(file f) {
149         glyph[128 - 32] font = { [i] = read_glyph(f) };
150
151         Sort::qsort(&font, bool func (glyph a, glyph b) = (a.c > b.c));
152         return font;
153 }
154
155 glyph[*] font;
156 void init () {
157         twixt (file f = File::open("ao_lcd_font_bits.h", "r"); File::close(f)) {
158                 font = read_font(f);
159         }
160 }
161
162 void dump() {
163         twixt(file f = File::open("ao_lcd_font_bits.h.new", "w"); File::close(f)) {
164                 for (int i = 0; i < dim(font); i++) {
165                         File::fprintf (f, "\t[%d] = 0x%04x,\n", i, glyph_value(font[i]));
166                         File::fprintf (f, "/*\n");
167                         write_glyph(f, font[i]);
168                         File::fprintf (f, "*/\n\n");
169                 }
170         }
171 }
172
173 init();
174 dump();