altos/stm-vga: Implement VGA out from the STM processor
[fw/altos] / src / draw / font-convert
1 #!/usr/bin/nickle
2
3 typedef struct {
4         int[]   bytes;
5         int     width;
6         int     height;
7         int     encoding;
8         int     location;
9 } glyph_t;
10
11 typedef struct {
12         glyph_t[...]    glyphs;
13         int             default_char;
14 } font_t;
15
16 glyph_t
17 read_glyph(file f)
18 {
19         glyph_t glyph = { .encoding = -1, .bytes = (int[...]){}, .width = 0 };
20
21         while (!File::end(f)) {
22                 string  l = fgets(f);
23
24                 string[*] tokens = String::split(l, " ");
25                 if (dim(tokens) == 0)
26                         continue;
27
28                 switch (tokens[0]) {
29                 case "ENCODING":
30                         glyph.encoding = atoi(tokens[1]);
31                         break;
32                 case "BBX":
33                         glyph.width = atoi(tokens[1]);
34                         glyph.height = atoi(tokens[2]);
35                         break;
36                 case "ENDCHAR":
37                         return glyph;
38                 case "BITMAP":
39                         while (!File::end(f)) {
40                                 string l = fgets(f);
41                                 if (l == "ENDCHAR")
42                                         return glyph;
43                                 glyph.bytes[dim(glyph.bytes)] = atoi(l, 16);
44                         }
45                         break;
46                 }
47         }
48         return glyph;
49 }
50
51 font_t read_font(file f) {
52         font_t  font = { .glyphs = {}, .default_char = -1 };
53
54         while (!File::end(f)) {
55                 string l = File::fgets(f);
56
57                 string[*] tokens = String::split(l, " ");
58                 if (tokens[0] == "DEFAULT_CHAR")
59                         font.default_char = atoi(tokens[1]);
60                 if (tokens[0] == "CHARS")
61                         break;
62         }
63         while (!File::end(f)) {
64                 glyph_t glyph = read_glyph(f);
65                 if (glyph.encoding == -1)
66                         break;
67                 font.glyphs[dim(font.glyphs)] = glyph;
68         }
69         return font;
70 }
71
72 int
73 flip_byte(int x)
74 {
75         int     dest = 0;
76
77         for (int i = 0; i < 8; i++)
78                 dest |= ((x >> (7 - i)) & 1) << i;
79         return dest;
80 }
81
82 void print_font(font_t font) {
83         int     width = font.glyphs[0].width;
84         int     height = font.glyphs[0].height;
85         int[256] pos = { -1 ... };
86         int[...] bytes;
87
88         if (false) {
89         for (int i = 1; i < dim(font.glyphs); i++) {
90                 if (font.glyphs[i].width != width ||
91                    font.glyphs[i].height != height)
92                 {
93                         File::fprintf(stderr, "font not constant size, glyph %d is %dx%d\n",
94                                       font.glyphs[i].encoding, font.glyphs[i].width, font.glyphs[i].height);
95                         exit(1);
96                 }
97         }
98         }
99
100         if (font.default_char == -1)
101                 font.default_char = font.glyphs[0].encoding;
102
103         /* build byte array */
104         for (int i = 0; i < dim(font.glyphs); i++) {
105                 pos[font.glyphs[i].encoding] = dim(bytes);
106                 for (int b = 0; b < dim(font.glyphs[i].bytes); b++)
107                         bytes[dim(bytes)] = font.glyphs[i].bytes[b];
108         }
109
110         /* Fill in default glyph */
111         for (int i = 0; i < dim(pos); i++)
112                 if (pos[i] == -1)
113                         pos[i] = pos[font.default_char];
114
115         printf("static uint8_t glyph_bytes[] = {");
116         for (int b = 0; b < dim(bytes); b++) {
117                 if ((b & 15) == 0)
118                         printf("\n\t");
119                 printf("0x%02x, ", flip_byte(bytes[b]));
120         }
121         printf("\n};\n\n");
122
123         printf("static uint16_t glyph_pos[] = {");
124         for (int i = 0; i < dim(pos); i++) {
125                 if ((i & 7) == 0)
126                         printf("\n\t");
127                 printf("%4d, ", pos[i]);
128         }
129         printf("\n};\n\n");
130
131         printf("#define GLYPH_WIDTH %d\n", width);
132         printf("#define GLYPH_HEIGHT %d\n", height);
133 }
134
135 twixt (file f = File::open(argv[1], "r"); File::close(f)) {
136        font_t font = read_font(f);
137        print_font(font);
138 }