added stb, more binaryout changes"
[henge/apc.git] / stb / tools / easy_font_maker.c
1 // This program was used to encode the data for stb_simple_font.h
2
3 #define STB_DEFINE
4 #include "stb.h"
5 #define STB_IMAGE_IMPLEMENTATION
6 #include "stb_image.h"
7
8 int w,h;
9 uint8 *data;
10
11 int last_x[2], last_y[2];
12 int num_seg[2], non_empty;
13 #if 0
14 typedef struct
15 {
16 unsigned short first_segment;
17 unsigned char advance;
18 } chardata;
19
20 typedef struct
21 {
22 unsigned char x:4;
23 unsigned char y:4;
24 unsigned char len:3;
25 unsigned char dir:1;
26 } segment;
27
28 segment *segments;
29
30 void add_seg(int x, int y, int len, int horizontal)
31 {
32 segment s;
33 s.x = x;
34 s.y = y;
35 s.len = len;
36 s.dir = horizontal;
37 assert(s.x == x);
38 assert(s.y == y);
39 assert(s.len == len);
40 stb_arr_push(segments, s);
41 }
42 #else
43 typedef struct
44 {
45 unsigned char first_segment:8;
46 unsigned char first_v_segment:8;
47 unsigned char advance:5;
48 unsigned char voff:1;
49 } chardata;
50
51 #define X_LIMIT 1
52 #define LEN_LIMIT 7
53
54 typedef struct
55 {
56 unsigned char dx:1;
57 unsigned char y:4;
58 unsigned char len:3;
59 } segment;
60
61 segment *segments;
62 segment *vsegments;
63
64 void add_seg(int x, int y, int len, int horizontal)
65 {
66 segment s;
67
68 while (x - last_x[horizontal] > X_LIMIT) {
69 add_seg(last_x[horizontal] + X_LIMIT, 0, 0, horizontal);
70 }
71 while (len > LEN_LIMIT) {
72 add_seg(x, y, LEN_LIMIT, horizontal);
73 len -= LEN_LIMIT;
74 x += LEN_LIMIT*horizontal;
75 y += LEN_LIMIT*!horizontal;
76 }
77
78 s.dx = x - last_x[horizontal];
79 s.y = y;
80 s.len = len;
81 non_empty += len != 0;
82 //assert(s.x == x);
83 assert(s.y == y);
84 assert(s.len == len);
85 ++num_seg[horizontal];
86 if (horizontal)
87 stb_arr_push(segments, s);
88 else
89 stb_arr_push(vsegments, s);
90 last_x[horizontal] = x;
91 }
92
93 void print_segments(segment *s)
94 {
95 int i, hpos;
96 printf(" ");
97 hpos = 4;
98 for (i=0; i < stb_arr_len(s); ++i) {
99 // repack for portability
100 unsigned char seg = s[i].len + s[i].dx*8 + s[i].y*16;
101 hpos += printf("%d,", seg);
102 if (hpos > 72 && i+1 < stb_arr_len(s)) {
103 hpos = 4;
104 printf("\n ");
105 }
106 }
107 printf("\n");
108 }
109
110 #endif
111
112 chardata charinfo[128];
113
114 int parse_char(int x, chardata *c, int offset)
115 {
116 int start_x = x, end_x, top_y = 0, y;
117
118 c->first_segment = stb_arr_len(segments);
119 c->first_v_segment = stb_arr_len(vsegments) - offset;
120 assert(c->first_segment == stb_arr_len(segments));
121 assert(c->first_v_segment + offset == stb_arr_len(vsegments));
122
123 // find advance distance
124 end_x = x+1;
125 while (data[end_x*3] == 255)
126 ++end_x;
127 c->advance = end_x - start_x + 1;
128
129 last_x[0] = last_x[1] = 0;
130 last_y[0] = last_y[1] = 0;
131
132 for (y=2; y < h; ++y) {
133 for (x=start_x; x < end_x; ++x) {
134 if (data[y*3*w+x*3+1] < 255) {
135 top_y = y;
136 break;
137 }
138 }
139 if (top_y)
140 break;
141 }
142 c->voff = top_y > 2;
143 if (top_y > 2)
144 top_y = 3;
145
146 for (x=start_x; x < end_x; ++x) {
147 int y;
148 for (y=2; y < h; ++y) {
149 if (data[y*3*w+x*3+1] < 255) {
150 if (data[y*3*w+x*3+0] == 255) { // red
151 int len=0;
152 while (y+len < h && data[(y+len)*3*w+x*3+0] == 255 && data[(y+len)*3*w+x*3+1] == 0) {
153 data[(y+len)*3*w+x*3+0] = 0;
154 ++len;
155 }
156 add_seg(x-start_x,y-top_y,len,0);
157 }
158 if (data[y*3*w+x*3+2] == 255) { // blue
159 int len=0;
160 while (x+len < end_x && data[y*3*w+(x+len)*3+2] == 255 && data[y*3*w+(x+len)*3+1] == 0) {
161 data[y*3*w+(x+len)*3+2] = 0;
162 ++len;
163 }
164 add_seg(x-start_x,y-top_y,len,1);
165 }
166 }
167 }
168 }
169 return end_x;
170 }
171
172
173 int main(int argc, char **argv)
174 {
175 int c, x=0;
176 data = stbi_load("easy_font_raw.png", &w, &h, 0, 3);
177 for (c=32; c < 127; ++c) {
178 x = parse_char(x, &charinfo[c], 0);
179 printf("%3d -- %3d %3d\n", c, charinfo[c].first_segment, charinfo[c].first_v_segment);
180 }
181 printf("===\n");
182 printf("%d %d %d\n", num_seg[0], num_seg[1], non_empty);
183 printf("%d\n", sizeof(segments[0]) * stb_arr_len(segments));
184 printf("%d\n", sizeof(segments[0]) * stb_arr_len(segments) + sizeof(segments[0]) * stb_arr_len(vsegments) + sizeof(charinfo[32])*95);
185
186 printf("struct {\n"
187 " unsigned char advance;\n"
188 " unsigned char h_seg;\n"
189 " unsigned char v_seg;\n"
190 "} stb_easy_font_charinfo[96] = {\n");
191 charinfo[c].first_segment = stb_arr_len(segments);
192 charinfo[c].first_v_segment = stb_arr_len(vsegments);
193 for (c=32; c < 128; ++c) {
194 if ((c & 3) == 0) printf(" ");
195 printf("{ %2d,%3d,%3d },",
196 charinfo[c].advance + 16*charinfo[c].voff,
197 charinfo[c].first_segment,
198 charinfo[c].first_v_segment);
199 if ((c & 3) == 3) printf("\n"); else printf(" ");
200 }
201 printf("};\n\n");
202
203 printf("unsigned char stb_easy_font_hseg[%d] = {\n", stb_arr_len(segments));
204 print_segments(segments);
205 printf("};\n\n");
206
207 printf("unsigned char stb_easy_font_vseg[%d] = {\n", stb_arr_len(vsegments));
208 print_segments(vsegments);
209 printf("};\n");
210 return 0;
211 }