]> git.mxchange.org Git - flightgear.git/blob - utils/gui/genfonts.c
fgviewer: Update fgviewer.
[flightgear.git] / utils / gui / genfonts.c
1 /*
2  * A simple utility to generate the bitmap fonts to be used in freeglut.
3  *
4  * Copyright (c) 2005 Melchior FRANZ
5  * Copyright (c) 1999-2000 by Pawel W. Olszta
6  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
7  * Creation date: nie gru 26 21:52:36 CET 1999
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software")
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29
30 #include <assert.h>
31 #include <ctype.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36
37 /* we build our own alphabet ... see below */
38 unsigned char alphabet[256] = " abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789`~!@#$%^&*()-_=+[{}];:,.<>/?\\\"";
39 int alphabet_length = 0;
40
41 /* all undefined characters will get replaced by this one: */
42 char missing = '?';
43
44 FILE *out = NULL;
45 Display *display;
46
47 void write_font(char *fontname, char *x_fontname, int gap, int space)
48 {
49         int i, lineWidth, maxWidth = 0, maxHeight = 0;
50         XFontStruct *fontStruct = NULL;
51         XGCValues contextValues;
52         XImage *image = NULL;
53         unsigned char *linebuffer;
54         Pixmap buffer;
55         GC context;
56
57         fontStruct = XLoadQueryFont(display, x_fontname);
58
59         if (fontStruct == NULL)
60                 fprintf(stderr, "ERROR: couldn't get font `%s' using local display", x_fontname);
61
62         maxWidth  = fontStruct->max_bounds.rbearing - fontStruct->min_bounds.lbearing + gap;  // + gap?
63         maxHeight = fontStruct->max_bounds.ascent   + fontStruct->max_bounds.descent;
64
65         linebuffer = malloc(maxWidth);
66         if (!linebuffer) {
67                 fprintf(stderr, "ERROR: couldn't allocate memory");
68                 exit(EXIT_FAILURE);
69         }
70
71         buffer = XCreatePixmap(display, RootWindow(display, DefaultScreen(display)),
72                         maxWidth, maxHeight, 1);
73
74         context = XCreateGC(display, buffer, 0, &contextValues);
75
76         XSetFont(display, context, fontStruct->fid);
77
78         for (i = 0; i < alphabet_length; i++) {
79                 int x, y, start_x, stop_x;
80
81                 /* clear the context black */
82                 XSetForeground(display, context, 0x00);
83                 XFillRectangle(display, buffer, context, 0, 0, maxWidth, maxHeight);
84
85                 /* draw the characters white */
86                 XSetForeground(display, context, 0xff);
87
88                 /* draw the n-th character of the alphabet */
89                 XDrawString(display, buffer, context, -fontStruct->min_bounds.lbearing,
90                                 fontStruct->max_bounds.ascent, (alphabet + i), 1);
91
92                 image = XGetImage(display, buffer, 0, 0, maxWidth, maxHeight, 1, XYPixmap);
93
94                 /* find the first non-empty column */
95                 start_x = -1;
96                 stop_x = -1;
97
98                 for (x = 0; x < maxWidth; x++)
99                         for (y = 0; y < maxHeight; y++)
100                                 if ((XGetPixel(image, x, y) == 1) && (start_x == -1))
101                                         start_x = x;
102
103                 /* find the last non-empty column */
104                 for (x = maxWidth - 1; x >= 0; x--)
105                         for (y = 0; y < maxHeight; y++)
106                                 if ((XGetPixel(image, x, y) == 1) && (stop_x == -1))
107                                         stop_x = x + 1;
108
109                 stop_x += gap;
110
111                 if (alphabet[i] == ' ')
112                         start_x = 0, stop_x = space;
113                 /* if the size is too small, enhance it a bit */
114                 else if (stop_x - start_x < 1)
115                         start_x = 0, stop_x = maxWidth - 1;
116
117                 fprintf(out, "static const GLubyte %s_Char_%03i[] = {%3i",
118                                 fontname, (unsigned)alphabet[i], stop_x-start_x);
119
120                 for (y = maxHeight - 1; y >= 0; y--) {
121                         memset(linebuffer, 0, maxWidth);
122
123                         /* grab the rasterized character face into the line buffer */
124                         for (x = start_x, lineWidth = 0; x < stop_x; x++, lineWidth++)
125                                 if (XGetPixel(image, x, y))
126                                         linebuffer[lineWidth / 8] |= 1 << (7 - (lineWidth % 8));
127
128                         /* output the final line bitmap now */
129                         for (x = 0; x < (stop_x - start_x + 7) / 8; x++)
130                                 fprintf(out, ",%3i", linebuffer[x]);
131                 }
132
133                 fprintf(out, "};\n");
134                 XDestroyImage(image);
135         }
136
137         fprintf(out, "\nstatic const GLubyte *%s_Char_Map[] = {\n\t", fontname);
138
139         for (i = 1; i < 256; i++)
140                 fprintf(out, "%s_Char_%03i,%s", fontname, strchr(alphabet, (char)i)
141                                 ? (int)(unsigned char)i : (int)(unsigned char)missing,
142                                 i % 4 ? " " : "\n\t");
143
144         fprintf(out, "0};\n\n");
145         fprintf(out, "const SFG_Font fgFont%s = {\"%s\", %i, %i, %s_Char_Map, 0.0f, 0.0f};\n\n",
146                         fontname, x_fontname, alphabet_length, maxHeight, fontname);
147
148         fprintf(out, "static fntBitmapFont fnt%s(fgFont%s.Characters, 1,\n\t\t"
149                         "fgFont%s.Height, fgFont%s.xorig, fgFont%s.yorig);\n\n",
150                         fontname, fontname, fontname, fontname, fontname);
151
152         XFreeGC(display, context);
153         XFreePixmap(display, buffer);
154         free(linebuffer);
155 }
156
157
158 int main(int argc, char **argv)
159 {
160         char *filename = NULL;
161         char *display_name = NULL;
162         int i = 1;
163         int A, B;
164
165         int numfonts = 2;
166         struct {
167                 char *name;
168                 char *spec;
169                 int gap;
170                 int space;
171         } fontlist[] = { /* fontname, x_fontname, gap, space */
172 // fgfs
173                 { "Helvetica14",  "-adobe-helvetica-medium-r-*-*-*-140-75-75-*-*-iso8859-1",       2, 5 },
174                 { "Vera12B",      "-*-bitstream vera sans-bold-r-*-*-*-120-75-75-*-*-iso8859-1",   2, 4 },
175                 //"Helvetica14B", "-adobe-helvetica-bold-r-*-*-*-140-75-75-*-*-iso8859-1",
176 // freeglut/plib
177                 { "Fixed8x13",    "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1",      0, 4 },
178                 { "Fixed9x15",    "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1",      0, 4 },
179                 { "Helvetica10",  "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", 0, 4 },
180                 { "Helvetica12",  "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", 0, 5 },
181                 { "Helvetica18",  "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", 0, 7 },
182                 { "TimesRoman10", "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1",     0, 5 },
183                 { "TimesRoman24", "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1",    0, 8 },
184         };
185
186         /* initialize the alphabet's length */
187         for (A = B = 0; A < 256; A++)
188                 if (isprint(A) || A >= 128)
189                         alphabet[B++] = A;
190         alphabet[B] = 0;
191         alphabet_length = strlen(alphabet);
192
193         /* make sure that the no-character character is in the alphabet */
194         if (!strchr(alphabet, missing))
195                 fprintf(stderr, "ERROR: the \"missing\" character '%c' not found in the alphabet '%s'",
196                                 missing, alphabet);
197
198         display_name = strdup(getenv("DISPLAY"));
199         filename = strdup("font.c");
200
201         /*
202          * process the command line arguments:
203          *
204          *       --display <DISPLAYNAME>    ... the display to connect to
205          *       --file    <FILENAME>       ... the destination file name
206          */
207         while (i < argc) {
208                 if (!strcmp(argv[i], "--display")) {
209                         assert((i + 1) < argc);
210                         free(display_name);
211                         display_name = strdup(argv[++i]);
212
213                 } else if (!strcmp(argv[i], "--file")) {
214                         assert((i + 1) < argc);
215                         free(filename);
216                         filename = strdup(argv[++i]);
217                 }
218                 i++;
219         }
220
221         display = XOpenDisplay(display_name);
222         assert(display != NULL);
223
224         out = fopen(filename, "wt");
225         assert(out != NULL);
226
227         fprintf(out, "\n/*\n * Following fonts are defined in this file:\n *\n");
228
229         for (i = 0; i < numfonts; i++)
230                 fprintf(out, " * %i. fgFont%s <%s>\n", i + 1, fontlist[i].name, fontlist[i].spec);
231
232         fprintf(out, " */\n\n");
233
234         for (i = 0; i < numfonts; i++)
235                 write_font(fontlist[i].name, fontlist[i].spec, fontlist[i].gap, fontlist[i].space);
236
237         fclose(out);
238         XCloseDisplay(display);
239         free(filename);
240         free(display_name);
241
242         return EXIT_SUCCESS;
243 }
244
245