1155
|
1 /*
|
|
2
|
|
3 mplayer font creator for korean(euc-kr) charset
|
|
4
|
|
5 This program uses gd & freetype2 library to draw each characters then
|
|
6 write the image to stdout.
|
|
7
|
|
8 Written by Sunjin Yang <lethean@realtime.ssu.ac.kr> May 03, 2001.
|
|
9
|
|
10 */
|
|
11
|
|
12 #include <gd.h>
|
|
13 #include <stdio.h>
|
|
14 #include <string.h>
|
|
15 #include <errno.h>
|
|
16
|
|
17 #define DEF_FONT_SIZE 16.0
|
|
18
|
|
19 #define DEF_CHAR_GAP 6
|
|
20 #define CHAR_SKIP(gap) (gap / 4)
|
|
21
|
|
22 #define AUTHOR "Sunjin Yang <lethean@realtime.ssu.ac.kr>"
|
|
23 #define VERSION "0.1"
|
|
24
|
|
25 struct code_range {
|
|
26 int start, end;
|
|
27 };
|
|
28
|
|
29 /* basic alphabet character range */
|
|
30 static struct code_range ascii_range = { 0x21, 0x7E };
|
|
31
|
|
32 #ifdef USE_UNIFIED_KOREAN
|
|
33
|
|
34 /* Unified Hangul Code Encoding */
|
|
35 static struct code_range first_byte_range[] = {
|
|
36 { 0x81, 0xFE }, { 0, 0 }
|
|
37 };
|
|
38 static struct code_range second_byte_range[] = {
|
|
39 { 0x41, 0x5A }, { 0x61, 0x7A }, { 0x81, 0x9F }, { 0xA0, 0xBF },
|
|
40 { 0xC0, 0xDF }, { 0xE0, 0xFE }, { 0, 0 }
|
|
41 };
|
|
42
|
|
43 #else
|
|
44
|
|
45 /* KSX 1001:1992 */
|
|
46 static struct code_range first_byte_range[] = {
|
|
47 { 0xA1, 0xAC }, { 0xB0, 0xFD }, { 0, 0 }
|
|
48 };
|
|
49 static struct code_range second_byte_range[] = {
|
|
50 { 0xA1, 0xAF }, { 0xB0, 0xBF }, { 0xC0, 0xCF }, { 0xD0, 0xDF },
|
|
51 { 0xE0, 0xEF }, { 0xF0, 0xFE }, { 0, 0 }
|
|
52 };
|
|
53
|
|
54 #endif
|
|
55
|
|
56 #define _output(msg...) fprintf(stdout, ##msg)
|
|
57
|
|
58 /* debugging macros */
|
|
59 #define _print(msg...) fprintf(stderr, ##msg)
|
|
60 #define _info(msg...) { _print("mpfc: "); _print(##msg); _print("\n"); }
|
|
61 #define _abort(msg...) { _info(##msg); exit(1); }
|
|
62
|
|
63 static double size;
|
|
64 static int gap;
|
|
65 static char *name, *font, *eng_font, *kor_font;
|
|
66 static int file_index;
|
|
67 static char filename[20], str[10];
|
|
68
|
|
69 static int base_x, char_count;
|
|
70 static gdImagePtr char_image[65536];
|
|
71
|
|
72 static gdImagePtr concat_char_images(void)
|
|
73 {
|
|
74 gdImagePtr ret;
|
|
75 int width, height, i, black, white;
|
|
76
|
|
77 /* get image's width & height */
|
|
78 height = size + (gap * 2);
|
|
79 for (width = 0, i = 0; i < char_count; i++)
|
|
80 width += char_image[i]->sx;
|
|
81
|
|
82 ret = gdImageCreate(width, height);
|
|
83
|
|
84 /* background color (first allocated) */
|
|
85 black = gdImageColorResolve(ret, 0, 0, 0);
|
|
86 white = gdImageColorResolve(ret, 255, 255, 255);
|
|
87
|
|
88 width = 0;
|
|
89 for (i = 0; i < char_count; i++) {
|
|
90 gdImageCopy(ret, char_image[i], /* dst, src */
|
|
91 width + 0, 0, /* dstX, dstY */
|
|
92 0, 0, /* srcX, srcY */
|
|
93 char_image[i]->sx, char_image[i]->sy); /* size */
|
|
94 width += char_image[i]->sx;
|
|
95 gdImageDestroy(char_image[i]);
|
|
96 }
|
|
97 char_count = 0;
|
|
98
|
|
99 return ret;
|
|
100 }
|
|
101
|
|
102 static gdImagePtr create_char_image(char *s)
|
|
103 {
|
|
104 gdImagePtr im;
|
|
105 int rect[8], black, white, width, height, x, y;
|
|
106 char *err;
|
|
107
|
|
108 /* obtain border rectangle so that we can size the image. */
|
|
109 err = gdImageStringTTF(NULL, &rect[0], 0, font, size, .0, 0, 0, s);
|
|
110 if (err)
|
|
111 _abort("%s\n", err);
|
|
112
|
|
113 /* create an image big enough for a string plus a little whitespace. */
|
|
114 width = rect[2] - rect[6] + gap;
|
|
115 height = size + (gap * 2);
|
|
116 im = gdImageCreate(width, height);
|
|
117
|
|
118 /* background color (first allocated) */
|
|
119 black = gdImageColorResolve(im, 0, 0, 0);
|
|
120 white = gdImageColorResolve(im, 255, 255, 255);
|
|
121
|
|
122 /* render the string, offset origin to center string.
|
|
123 note that we use top-left coordinate for adjustment
|
|
124 since gd origin is in top-left with y increasing downwards. */
|
|
125 x = (gap / 2) - rect[6];
|
|
126 y = (gap / 2) - rect[7] + (size + rect[7]);
|
|
127 err = gdImageStringTTF(im, &rect[0], white, font, size, .0, x, y, s);
|
|
128 if (err)
|
|
129 _abort("%s\n", err);
|
|
130
|
|
131 if (*s == '"') _output("'%s' ", s); else _output("\"%s\" ", s);
|
|
132 _output("%d %d\n",
|
|
133 base_x + CHAR_SKIP(gap), base_x + width - CHAR_SKIP(gap) - 1);
|
|
134 base_x += width;
|
|
135
|
|
136 return im;
|
|
137 }
|
|
138
|
|
139 void make_charset_font(struct code_range *first, struct code_range *second)
|
|
140 {
|
|
141 gdImagePtr im;
|
|
142 FILE *fd;
|
|
143 int i, j;
|
|
144
|
|
145 base_x = 0;
|
|
146 char_count = 0;
|
|
147
|
|
148 _output("[files]\n");
|
|
149 //_output("alpha %s%d_a.raw\n", name, file_index);
|
|
150 _output("alpha %s%02d_b.raw\n", name, file_index);
|
|
151 _output("bitmap %s%02d_b.raw\n\n", name, file_index);
|
|
152 _output("[characters]\n");
|
|
153
|
|
154 for (i = first->start; i <= first->end; i++) {
|
|
155 str[0] = (char)i;
|
|
156 if (!second) {
|
|
157 str[1] = '\0';
|
|
158 char_image[char_count++] = create_char_image(str);
|
|
159 } else
|
|
160 for (j = second->start; j <= second->end; j++) {
|
|
161 str[1] = (char)j; str[2] = '\0';
|
|
162 char_image[char_count++]= create_char_image(str);
|
|
163 }
|
|
164 }
|
|
165
|
|
166 _output("\n");
|
|
167
|
|
168 /* concatenate each character images into one image. */
|
|
169 im = concat_char_images();
|
|
170
|
|
171 /* get filename and create one with it. */
|
|
172 sprintf(filename, "%s%02d_b.png", name, file_index++);
|
|
173 fd = fopen(filename, "w+");
|
|
174 if (!fd)
|
|
175 _abort(strerror(errno));
|
|
176
|
|
177 /* write image to the PNG file. */
|
|
178 gdImagePng(im, fd);
|
|
179
|
|
180 fclose(fd);
|
|
181
|
|
182 /* destroy it */
|
|
183 gdImageDestroy(im);
|
|
184 }
|
|
185
|
|
186 int main(int argc, char **argv)
|
|
187 {
|
|
188 int i, j;
|
|
189
|
|
190 if (argc < 4)
|
|
191 _abort("usage:%s name eng-ttf kor-ttf [size gap]",argv[0]);
|
|
192
|
|
193 /* get program parameter like font names, size... */
|
|
194 name = argv[1];
|
|
195 eng_font = argv[2];
|
|
196 kor_font = argv[3];
|
|
197 size = DEF_FONT_SIZE;
|
|
198 gap = DEF_CHAR_GAP;
|
|
199 if (argc > 4) {
|
|
200 float __s; sscanf(argv[4], "%f", &__s);
|
|
201 size = (double)__s;
|
|
202 }
|
|
203 if (argc > 5)
|
|
204 sscanf(argv[5], "%d", &gap);
|
|
205
|
|
206 /* write basic font information. */
|
|
207 _output("[info]\n");
|
|
208 _output("name \"%s version %s - created by %s\"\n",
|
|
209 name, VERSION, AUTHOR);
|
|
210 _output("descversion 1\n");
|
|
211 _output("spacewidth %d\n", (int)(size / 2));
|
|
212 _output("charspace -%d\n", CHAR_SKIP(gap) + 1);
|
|
213 _output("height %d\n\n", (int)size + DEF_CHAR_GAP);
|
|
214
|
|
215 /* write general OSD fonts information. */
|
|
216 _output("[files]\n");
|
|
217 _output("alpha arpi_osd_a.raw\n");
|
|
218 _output("bitmap arpi_osd_b.raw\n\n");
|
|
219 _output("[characters]\n");
|
|
220 _output("0x01 0 36\n");
|
|
221 _output("0x02 35 71\n");
|
|
222 _output("0x03 70 106\n");
|
|
223 _output("0x04 116 152\n");
|
|
224 _output("0x05 164 200\n");
|
|
225 _output("0x06 209 245\n");
|
|
226 _output("0x07 256 292\n");
|
|
227 _output("0x08 305 342\n");
|
|
228 _output("0x09 354 400\n");
|
|
229 _output("0x0A 407 442\n");
|
|
230 _output("0x0B 457 494\n");
|
|
231 _output("[files]\n");
|
|
232 _output("alpha arpi_progress_a.raw\n");
|
|
233 _output("bitmap arpi_progress_b.raw\n\n");
|
|
234 _output("[characters]\n");
|
|
235 _output("0x10 4 21\n");
|
|
236 _output("0x11 30 41\n");
|
|
237 _output("0x12 50 66\n");
|
|
238 _output("0x13 74 85\n\n");
|
|
239
|
|
240
|
|
241 file_index = 0;
|
|
242
|
|
243 /* create basic alphabet character set. */
|
|
244 font = eng_font;
|
|
245 make_charset_font(&ascii_range, NULL);
|
|
246
|
|
247 /* create korean character set. */
|
|
248 font = kor_font;
|
|
249 for (i = 0; first_byte_range[i].start != 0; i++)
|
|
250 for (j = 0; second_byte_range[j].start != 0; j++)
|
|
251 make_charset_font(&first_byte_range[i], &second_byte_range[j]);
|
|
252
|
|
253 return 0;
|
|
254 }
|
|
255
|