From 6361ec750b53c076894e476c3c4e2ff99abd79aa Mon Sep 17 00:00:00 2001 From: mfranz Date: Fri, 8 Jul 2005 08:17:43 +0000 Subject: [PATCH] program that generates C code from a built-in font list; used for the font definition in src/GUI/fonts.cxx --- utils/gui/Makefile.am | 4 + utils/gui/genfonts.c | 245 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 utils/gui/Makefile.am create mode 100644 utils/gui/genfonts.c diff --git a/utils/gui/Makefile.am b/utils/gui/Makefile.am new file mode 100644 index 000000000..a53ffec50 --- /dev/null +++ b/utils/gui/Makefile.am @@ -0,0 +1,4 @@ +noinst_PROGRAMS = genfonts + +genfonts_SOURCES = genfonts.c +genfonts_LDADD = $(base_LIBS) -lXext diff --git a/utils/gui/genfonts.c b/utils/gui/genfonts.c new file mode 100644 index 000000000..046e3a557 --- /dev/null +++ b/utils/gui/genfonts.c @@ -0,0 +1,245 @@ +/* + * A simple utility to generate the bitmap fonts to be used in freeglut. + * + * Copyright (c) 2005 Melchior FRANZ + * Copyright (c) 1999-2000 by Pawel W. Olszta + * Written by Pawel W. Olszta, + * Creation date: nie gru 26 21:52:36 CET 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software") + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include + + +/* we build our own alphabet ... see below */ +unsigned char alphabet[256] = " abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789`~!@#$%^&*()-_=+[{}];:,.<>/?\\\""; +int alphabet_length = 0; + +/* all undefined characters will get replaced by this one: */ +char missing = '?'; + +FILE *out = NULL; +Display *display; + +void write_font(char *fontname, char *x_fontname, int gap, int space) +{ + int i, lineWidth, maxWidth = 0, maxHeight = 0; + XFontStruct *fontStruct = NULL; + XGCValues contextValues; + XImage *image = NULL; + unsigned char *linebuffer; + Pixmap buffer; + GC context; + + fontStruct = XLoadQueryFont(display, x_fontname); + + if (fontStruct == NULL) + fprintf(stderr, "ERROR: couldn't get font `%s' using local display", x_fontname); + + maxWidth = fontStruct->max_bounds.rbearing - fontStruct->min_bounds.lbearing + gap; // + gap? + maxHeight = fontStruct->max_bounds.ascent + fontStruct->max_bounds.descent; + + linebuffer = malloc(maxWidth); + if (!linebuffer) { + fprintf(stderr, "ERROR: couldn't allocate memory"); + exit(EXIT_FAILURE); + } + + buffer = XCreatePixmap(display, RootWindow(display, DefaultScreen(display)), + maxWidth, maxHeight, 1); + + context = XCreateGC(display, buffer, 0, &contextValues); + + XSetFont(display, context, fontStruct->fid); + + for (i = 0; i < alphabet_length; i++) { + int x, y, start_x, stop_x; + + /* clear the context black */ + XSetForeground(display, context, 0x00); + XFillRectangle(display, buffer, context, 0, 0, maxWidth, maxHeight); + + /* draw the characters white */ + XSetForeground(display, context, 0xff); + + /* draw the n-th character of the alphabet */ + XDrawString(display, buffer, context, -fontStruct->min_bounds.lbearing, + fontStruct->max_bounds.ascent, (alphabet + i), 1); + + image = XGetImage(display, buffer, 0, 0, maxWidth, maxHeight, 1, XYPixmap); + + /* find the first non-empty column */ + start_x = -1; + stop_x = -1; + + for (x = 0; x < maxWidth; x++) + for (y = 0; y < maxHeight; y++) + if ((XGetPixel(image, x, y) == 1) && (start_x == -1)) + start_x = x; + + /* find the last non-empty column */ + for (x = maxWidth - 1; x >= 0; x--) + for (y = 0; y < maxHeight; y++) + if ((XGetPixel(image, x, y) == 1) && (stop_x == -1)) + stop_x = x + 1; + + stop_x += gap; + + if (alphabet[i] == ' ') + start_x = 0, stop_x = space; + /* if the size is too small, enhance it a bit */ + else if (stop_x - start_x < 1) + start_x = 0, stop_x = maxWidth - 1; + + fprintf(out, "static const GLubyte %s_Char_%03i[] = {%3i", + fontname, (unsigned)alphabet[i], stop_x-start_x); + + for (y = maxHeight - 1; y >= 0; y--) { + memset(linebuffer, 0, maxWidth); + + /* grab the rasterized character face into the line buffer */ + for (x = start_x, lineWidth = 0; x < stop_x; x++, lineWidth++) + if (XGetPixel(image, x, y)) + linebuffer[lineWidth / 8] |= 1 << (7 - (lineWidth % 8)); + + /* output the final line bitmap now */ + for (x = 0; x < (stop_x - start_x + 7) / 8; x++) + fprintf(out, ",%3i", linebuffer[x]); + } + + fprintf(out, "};\n"); + XDestroyImage(image); + } + + fprintf(out, "\nstatic const GLubyte *%s_Char_Map[] = {\n\t", fontname); + + for (i = 1; i < 256; i++) + fprintf(out, "%s_Char_%03i,%s", fontname, strchr(alphabet, (char)i) + ? (int)(unsigned char)i : (int)(unsigned char)missing, + i % 4 ? " " : "\n\t"); + + fprintf(out, "0};\n\n"); + fprintf(out, "const SFG_Font fgFont%s = {\"%s\", %i, %i, %s_Char_Map, 0.0f, 0.0f};\n\n", + fontname, x_fontname, alphabet_length, maxHeight, fontname); + + fprintf(out, "static fntBitmapFont fnt%s(fgFont%s.Characters, 1,\n\t\t" + "fgFont%s.Height, fgFont%s.xorig, fgFont%s.yorig);\n\n", + fontname, fontname, fontname, fontname, fontname); + + XFreeGC(display, context); + XFreePixmap(display, buffer); + free(linebuffer); +} + + +int main(int argc, char **argv) +{ + char *filename = NULL; + char *display_name = NULL; + int i = 1; + int A, B; + + int numfonts = 2; + struct { + char *name; + char *spec; + int gap; + int space; + } fontlist[] = { /* fontname, x_fontname, gap, space */ +// fgfs + { "Helvetica14", "-adobe-helvetica-medium-r-*-*-*-140-75-75-*-*-iso8859-1", 2, 5 }, + { "Vera12B", "-*-bitstream vera sans-bold-r-*-*-*-120-75-75-*-*-iso8859-1", 2, 4 }, + //"Helvetica14B", "-adobe-helvetica-bold-r-*-*-*-140-75-75-*-*-iso8859-1", +// freeglut/plib + { "Fixed8x13", "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 0, 4 }, + { "Fixed9x15", "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1", 0, 4 }, + { "Helvetica10", "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", 0, 4 }, + { "Helvetica12", "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", 0, 5 }, + { "Helvetica18", "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", 0, 7 }, + { "TimesRoman10", "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", 0, 5 }, + { "TimesRoman24", "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", 0, 8 }, + }; + + /* initialize the alphabet's length */ + for (A = B = 0; A < 256; A++) + if (isprint(A) || A >= 128) + alphabet[B++] = A; + alphabet[B] = 0; + alphabet_length = strlen(alphabet); + + /* make sure that the no-character character is in the alphabet */ + if (!strchr(alphabet, missing)) + fprintf(stderr, "ERROR: the \"missing\" character '%c' not found in the alphabet '%s'", + missing, alphabet); + + display_name = strdup(getenv("DISPLAY")); + filename = strdup("font.c"); + + /* + * process the command line arguments: + * + * --display ... the display to connect to + * --file ... the destination file name + */ + while (i < argc) { + if (!strcmp(argv[i], "--display")) { + assert((i + 1) < argc); + free(display_name); + display_name = strdup(argv[++i]); + + } else if (!strcmp(argv[i], "--file")) { + assert((i + 1) < argc); + free(filename); + filename = strdup(argv[++i]); + } + i++; + } + + display = XOpenDisplay(display_name); + assert(display != NULL); + + out = fopen(filename, "wt"); + assert(out != NULL); + + fprintf(out, "\n/*\n * Following fonts are defined in this file:\n *\n"); + + for (i = 0; i < numfonts; i++) + fprintf(out, " * %i. fgFont%s <%s>\n", i + 1, fontlist[i].name, fontlist[i].spec); + + fprintf(out, " */\n\n"); + + for (i = 0; i < numfonts; i++) + write_font(fontlist[i].name, fontlist[i].spec, fontlist[i].gap, fontlist[i].space); + + fclose(out); + XCloseDisplay(display); + free(filename); + free(display_name); + + return EXIT_SUCCESS; +} + +