diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /thirdparty/stb/tools/easy_font_maker.c | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'thirdparty/stb/tools/easy_font_maker.c')
| -rw-r--r-- | thirdparty/stb/tools/easy_font_maker.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/thirdparty/stb/tools/easy_font_maker.c b/thirdparty/stb/tools/easy_font_maker.c new file mode 100644 index 0000000..f1b4836 --- /dev/null +++ b/thirdparty/stb/tools/easy_font_maker.c @@ -0,0 +1,211 @@ +// 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; +} |