123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // This program was used to encode the data for stb_simple_font.h
- #define STB_DEFINE
- #include "stb.h"
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
- int w,h;
- uint8 *data;
- int last_x[2], last_y[2];
- int num_seg[2], non_empty;
- #if 0
- typedef struct
- {
- unsigned short first_segment;
- unsigned char advance;
- } chardata;
- typedef struct
- {
- unsigned char x:4;
- unsigned char y:4;
- unsigned char len:3;
- unsigned char dir:1;
- } segment;
- segment *segments;
- void add_seg(int x, int y, int len, int horizontal)
- {
- segment s;
- s.x = x;
- s.y = y;
- s.len = len;
- s.dir = horizontal;
- assert(s.x == x);
- assert(s.y == y);
- assert(s.len == len);
- stb_arr_push(segments, s);
- }
- #else
- typedef struct
- {
- unsigned char first_segment:8;
- unsigned char first_v_segment:8;
- unsigned char advance:5;
- unsigned char voff:1;
- } chardata;
- #define X_LIMIT 1
- #define LEN_LIMIT 7
- typedef struct
- {
- unsigned char dx:1;
- unsigned char y:4;
- unsigned char len:3;
- } segment;
- segment *segments;
- segment *vsegments;
- void add_seg(int x, int y, int len, int horizontal)
- {
- segment s;
- while (x - last_x[horizontal] > X_LIMIT) {
- add_seg(last_x[horizontal] + X_LIMIT, 0, 0, horizontal);
- }
- while (len > LEN_LIMIT) {
- add_seg(x, y, LEN_LIMIT, horizontal);
- len -= LEN_LIMIT;
- x += LEN_LIMIT*horizontal;
- y += LEN_LIMIT*!horizontal;
- }
- s.dx = x - last_x[horizontal];
- s.y = y;
- s.len = len;
- non_empty += len != 0;
- //assert(s.x == x);
- assert(s.y == y);
- assert(s.len == len);
- ++num_seg[horizontal];
- if (horizontal)
- stb_arr_push(segments, s);
- else
- stb_arr_push(vsegments, s);
- last_x[horizontal] = x;
- }
- void print_segments(segment *s)
- {
- int i, hpos;
- printf(" ");
- hpos = 4;
- for (i=0; i < stb_arr_len(s); ++i) {
- // repack for portability
- unsigned char seg = s[i].len + s[i].dx*8 + s[i].y*16;
- hpos += printf("%d,", seg);
- if (hpos > 72 && i+1 < stb_arr_len(s)) {
- hpos = 4;
- printf("\n ");
- }
- }
- printf("\n");
- }
- #endif
- chardata charinfo[128];
- int parse_char(int x, chardata *c, int offset)
- {
- int start_x = x, end_x, top_y = 0, y;
- c->first_segment = stb_arr_len(segments);
- c->first_v_segment = stb_arr_len(vsegments) - offset;
- assert(c->first_segment == stb_arr_len(segments));
- assert(c->first_v_segment + offset == stb_arr_len(vsegments));
- // find advance distance
- end_x = x+1;
- while (data[end_x*3] == 255)
- ++end_x;
- c->advance = end_x - start_x + 1;
- last_x[0] = last_x[1] = 0;
- last_y[0] = last_y[1] = 0;
- for (y=2; y < h; ++y) {
- for (x=start_x; x < end_x; ++x) {
- if (data[y*3*w+x*3+1] < 255) {
- top_y = y;
- break;
- }
- }
- if (top_y)
- break;
- }
- c->voff = top_y > 2;
- if (top_y > 2)
- top_y = 3;
- for (x=start_x; x < end_x; ++x) {
- int y;
- for (y=2; y < h; ++y) {
- if (data[y*3*w+x*3+1] < 255) {
- if (data[y*3*w+x*3+0] == 255) { // red
- int len=0;
- while (y+len < h && data[(y+len)*3*w+x*3+0] == 255 && data[(y+len)*3*w+x*3+1] == 0) {
- data[(y+len)*3*w+x*3+0] = 0;
- ++len;
- }
- add_seg(x-start_x,y-top_y,len,0);
- }
- if (data[y*3*w+x*3+2] == 255) { // blue
- int len=0;
- while (x+len < end_x && data[y*3*w+(x+len)*3+2] == 255 && data[y*3*w+(x+len)*3+1] == 0) {
- data[y*3*w+(x+len)*3+2] = 0;
- ++len;
- }
- add_seg(x-start_x,y-top_y,len,1);
- }
- }
- }
- }
- return end_x;
- }
- int main(int argc, char **argv)
- {
- int c, x=0;
- data = stbi_load("easy_font_raw.png", &w, &h, 0, 3);
- for (c=32; c < 127; ++c) {
- x = parse_char(x, &charinfo[c], 0);
- printf("%3d -- %3d %3d\n", c, charinfo[c].first_segment, charinfo[c].first_v_segment);
- }
- printf("===\n");
- printf("%d %d %d\n", num_seg[0], num_seg[1], non_empty);
- printf("%d\n", sizeof(segments[0]) * stb_arr_len(segments));
- printf("%d\n", sizeof(segments[0]) * stb_arr_len(segments) + sizeof(segments[0]) * stb_arr_len(vsegments) + sizeof(charinfo[32])*95);
- printf("struct {\n"
- " unsigned char advance;\n"
- " unsigned char h_seg;\n"
- " unsigned char v_seg;\n"
- "} stb_easy_font_charinfo[96] = {\n");
- charinfo[c].first_segment = stb_arr_len(segments);
- charinfo[c].first_v_segment = stb_arr_len(vsegments);
- for (c=32; c < 128; ++c) {
- if ((c & 3) == 0) printf(" ");
- printf("{ %2d,%3d,%3d },",
- charinfo[c].advance + 16*charinfo[c].voff,
- charinfo[c].first_segment,
- charinfo[c].first_v_segment);
- if ((c & 3) == 3) printf("\n"); else printf(" ");
- }
- printf("};\n\n");
- printf("unsigned char stb_easy_font_hseg[%d] = {\n", stb_arr_len(segments));
- print_segments(segments);
- printf("};\n\n");
- printf("unsigned char stb_easy_font_vseg[%d] = {\n", stb_arr_len(vsegments));
- print_segments(vsegments);
- printf("};\n");
- return 0;
- }
|