/* mplayer font creator for korean(euc-kr) charset This program uses gd & freetype2 library to draw each characters then write the image to stdout. Written by Sunjin Yang May 03, 2001. */ #include #include #include #include #define DEF_FONT_SIZE 16.0 #define DEF_CHAR_GAP 6 #define CHAR_SKIP(gap) (gap / 4) #define AUTHOR "Sunjin Yang " #define VERSION "0.1" struct code_range { int start, end; }; /* basic alphabet character range */ static struct code_range ascii_range = { 0x21, 0x7E }; #ifdef USE_UNIFIED_KOREAN /* Unified Hangul Code Encoding */ static struct code_range first_byte_range[] = { { 0x81, 0xFE }, { 0, 0 } }; static struct code_range second_byte_range[] = { { 0x41, 0x5A }, { 0x61, 0x7A }, { 0x81, 0x9F }, { 0xA0, 0xBF }, { 0xC0, 0xDF }, { 0xE0, 0xFE }, { 0, 0 } }; #else /* KSX 1001:1992 */ static struct code_range first_byte_range[] = { { 0xA1, 0xAC }, { 0xB0, 0xFD }, { 0, 0 } }; static struct code_range second_byte_range[] = { { 0xA1, 0xAF }, { 0xB0, 0xBF }, { 0xC0, 0xCF }, { 0xD0, 0xDF }, { 0xE0, 0xEF }, { 0xF0, 0xFE }, { 0, 0 } }; #endif #define _output(msg...) fprintf(stdout, ##msg) /* debugging macros */ #define _print(msg...) fprintf(stderr, ##msg) #define _info(msg...) { _print("mpfc: "); _print(##msg); _print("\n"); } #define _abort(msg...) { _info(##msg); exit(1); } static double size; static int gap; static char *name, *font, *eng_font, *kor_font; static int file_index; static char filename[20], str[10]; static int base_x, char_count; static gdImagePtr char_image[65536]; static gdImagePtr concat_char_images(void) { gdImagePtr ret; int width, height, i, black, white; /* get image's width & height */ height = size + (gap * 2); for (width = 0, i = 0; i < char_count; i++) width += char_image[i]->sx; ret = gdImageCreate(width, height); /* background color (first allocated) */ black = gdImageColorResolve(ret, 0, 0, 0); white = gdImageColorResolve(ret, 255, 255, 255); width = 0; for (i = 0; i < char_count; i++) { gdImageCopy(ret, char_image[i], /* dst, src */ width + 0, 0, /* dstX, dstY */ 0, 0, /* srcX, srcY */ char_image[i]->sx, char_image[i]->sy); /* size */ width += char_image[i]->sx; gdImageDestroy(char_image[i]); } char_count = 0; return ret; } static gdImagePtr create_char_image(char *s) { gdImagePtr im; int rect[8], black, white, width, height, x, y; char *err; /* obtain border rectangle so that we can size the image. */ err = gdImageStringTTF(NULL, &rect[0], 0, font, size, .0, 0, 0, s); if (err) _abort("%s\n", err); /* create an image big enough for a string plus a little whitespace. */ width = rect[2] - rect[6] + gap; height = size + (gap * 2); im = gdImageCreate(width, height); /* background color (first allocated) */ black = gdImageColorResolve(im, 0, 0, 0); white = gdImageColorResolve(im, 255, 255, 255); /* render the string, offset origin to center string. note that we use top-left coordinate for adjustment since gd origin is in top-left with y increasing downwards. */ x = (gap / 2) - rect[6]; y = (gap / 2) - rect[7] + (size + rect[7]); err = gdImageStringTTF(im, &rect[0], white, font, size, .0, x, y, s); if (err) _abort("%s\n", err); if (*s == '"') _output("'%s' ", s); else _output("\"%s\" ", s); _output("%d %d\n", base_x + CHAR_SKIP(gap), base_x + width - CHAR_SKIP(gap) - 1); base_x += width; return im; } void make_charset_font(struct code_range *first, struct code_range *second) { gdImagePtr im; FILE *fd; int i, j; base_x = 0; char_count = 0; _output("[files]\n"); //_output("alpha %s%d_a.raw\n", name, file_index); _output("alpha %s%02d_b.raw\n", name, file_index); _output("bitmap %s%02d_b.raw\n\n", name, file_index); _output("[characters]\n"); for (i = first->start; i <= first->end; i++) { str[0] = (char)i; if (!second) { str[1] = '\0'; char_image[char_count++] = create_char_image(str); } else for (j = second->start; j <= second->end; j++) { str[1] = (char)j; str[2] = '\0'; char_image[char_count++]= create_char_image(str); } } _output("\n"); /* concatenate each character images into one image. */ im = concat_char_images(); /* get filename and create one with it. */ sprintf(filename, "%s%02d_b.png", name, file_index++); fd = fopen(filename, "w+"); if (!fd) _abort(strerror(errno)); /* write image to the PNG file. */ gdImagePng(im, fd); fclose(fd); /* destroy it */ gdImageDestroy(im); } int main(int argc, char **argv) { int i, j; if (argc < 4) _abort("usage:%s name eng-ttf kor-ttf [size gap]",argv[0]); /* get program parameter like font names, size... */ name = argv[1]; eng_font = argv[2]; kor_font = argv[3]; size = DEF_FONT_SIZE; gap = DEF_CHAR_GAP; if (argc > 4) { float __s; sscanf(argv[4], "%f", &__s); size = (double)__s; } if (argc > 5) sscanf(argv[5], "%d", &gap); /* write basic font information. */ _output("[info]\n"); _output("name \"%s version %s - created by %s\"\n", name, VERSION, AUTHOR); _output("descversion 1\n"); _output("spacewidth %d\n", (int)(size / 2)); _output("charspace -%d\n", CHAR_SKIP(gap) + 1); _output("height %d\n\n", (int)size + DEF_CHAR_GAP); /* write general OSD fonts information. */ _output("[files]\n"); _output("alpha arpi_osd_a.raw\n"); _output("bitmap arpi_osd_b.raw\n\n"); _output("[characters]\n"); _output("0x01 0 36\n"); _output("0x02 35 71\n"); _output("0x03 70 106\n"); _output("0x04 116 152\n"); _output("0x05 164 200\n"); _output("0x06 209 245\n"); _output("0x07 256 292\n"); _output("0x08 305 342\n"); _output("0x09 354 400\n"); _output("0x0A 407 442\n"); _output("0x0B 457 494\n"); _output("[files]\n"); _output("alpha arpi_progress_a.raw\n"); _output("bitmap arpi_progress_b.raw\n\n"); _output("[characters]\n"); _output("0x10 4 21\n"); _output("0x11 30 41\n"); _output("0x12 50 66\n"); _output("0x13 74 85\n\n"); file_index = 0; /* create basic alphabet character set. */ font = eng_font; make_charset_font(&ascii_range, NULL); /* create korean character set. */ font = kor_font; for (i = 0; first_byte_range[i].start != 0; i++) for (j = 0; second_byte_range[j].start != 0; j++) make_charset_font(&first_byte_range[i], &second_byte_range[j]); return 0; }