You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							211 lines
						
					
					
						
							5.0 KiB
						
					
					
				
			
		
		
	
	
							211 lines
						
					
					
						
							5.0 KiB
						
					
					
				| // 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; | |
| }
 | |
| 
 |