int main(int argc, char *argv[]) { int c; TexGlyphInfo tgi; int usageError = 0; char *varname, *fontname; XFontStruct *xfont; int i; if (argc == 3) { varname = argv[1]; fontname = argv[2]; } else usageError = 1; if (usageError) { fprintf(stderr, "\n"); fprintf(stderr, "usage: genfontfile variable_name X_font_name\n"); fprintf(stderr, "\n"); exit(1); } dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "could not open display\n"); exit(1); } /* find an OpenGL-capable RGB visual with depth buffer */ xfont = XLoadQueryFont(dpy, fontname); if (!xfont) { fprintf(stderr, "could not get load X font: %s\n", fontname); exit(1); } fontinfo = SuckGlyphsFromServer(dpy, xfont->fid); if (!fontinfo) { fprintf(stderr, "could not get font glyphs\n"); exit(1); } printf("static const %s[][%d] = {\n", varname, fontinfo->max_ascent + fontinfo->max_descent + 2); for (c = 32; c < 256; c++) { getMetric(fontinfo, c, &tgi); printGlyph(fontinfo, c); } printf(" };\n"); return 0; }
SetupMessageDisplayList(FontEntryPtr fontEntry, int num, char *message[]) { FontInfoPtr fontinfo = fontEntry->fontinfo; GLfloat scaleFactor; int totalHeight, maxWidth, height, width; int i; if (!fontinfo) { fontinfo = SuckGlyphsFromServer(dpy, fontEntry->xfont->fid); fontEntry->fontinfo = fontinfo; } height = fontinfo->max_ascent + fontinfo->max_descent; maxWidth = 0; for (i = 0; i < num; i++) { MakeStringDisplayList(fontinfo, message[i], base + i + 1); width = GetStringLength(fontinfo, message[i]); if (width > maxWidth) maxWidth = width; } #define SHRINK_FACTOR 25.0 /* empirical */ totalHeight = height * num - fontinfo->max_descent; if (maxWidth > totalHeight) { scaleFactor = SHRINK_FACTOR / maxWidth; } else { scaleFactor = SHRINK_FACTOR / totalHeight; } glNewList(base, GL_COMPILE); glScalef(scaleFactor, scaleFactor, 1); /* 1 in Z gives glyphs constant depth */ for (i = 0; i < num; i++) { glPushMatrix(); width = GetStringLength(fontinfo, message[i]); glTranslatef(-width / 2.0, height * (num - i - 1) - totalHeight / 2.0, 0); glCallList(base + i + 1); glPopMatrix(); } glEndList(); }
void main(int argc, char *argv[]) { int i; #ifdef IRIX_5_1_MOTIF_BUG_WORKAROUND /* * XXX Unfortunately a bug in the IRIX 5.1 Motif shared library * causes a BadMatch X protocol error if the SGI look&feel * is enabled for this program. If we detect we are on an * IRIX 5.1 system, skip the first two fallback resources which * specify using the SGI look&feel. */ struct utsname versionInfo; if(uname(&versionInfo) >= 0) { if(!strcmp(versionInfo.sysname, "IRIX") && !strncmp(versionInfo.release, "5.1", 3)) { toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, &fallbackResources[2], NULL, 0); } } if(toplevel == NULL) { toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, fallbackResources, NULL, 0); } #else toplevel = XtAppInitialize(&app, "Textfun", NULL, 0, &argc, argv, fallbackResources, NULL, 0); #endif dpy = XtDisplay(toplevel); /* find an OpenGL-capable RGB visual with depth buffer */ vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf); if (vi == NULL) { vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf); if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer"); doubleBuffer = GL_FALSE; } for (i = 0; i < NUM_FONT_ENTRIES; i++) { fontEntry[i].xfont = XLoadQueryFont(dpy, fontEntry[i].xlfd); if (i == 0 && !fontEntry[i].xfont) XtAppError(app, "could not get basic font"); } fontEntry[0].fontinfo = SuckGlyphsFromServer(dpy, fontEntry[0].xfont->fid); if (!fontEntry[0].fontinfo) XtAppError(app, "could not get font glyphs"); /* create an OpenGL rendering context */ cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE); if (cx == NULL) XtAppError(app, "could not create rendering context"); /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth, XtNcolormap, cmap, NULL); XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL); mainw = XmCreateMainWindow(toplevel, "mainw", NULL, 0); XtManageChild(mainw); /* create menu bar */ menubar = XmCreateMenuBar(mainw, "menubar", NULL, 0); XtManageChild(menubar); /* hack around Xt's ignorance of visuals */ XtSetArg(menuPaneArgs[0], XmNdepth, DefaultDepthOfScreen(XtScreen(mainw))); XtSetArg(menuPaneArgs[1], XmNcolormap, DefaultColormapOfScreen(XtScreen(mainw))); /* create File pulldown menu: Quit */ menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 2); btn = XmCreatePushButton(menupane, "Quit", NULL, 0); XtAddCallback(btn, XmNactivateCallback, quit, NULL); XtManageChild(btn); XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "File", args, 1); XtManageChild(cascade); /* create Options pulldown menu: Motion, Dolly, Rotate, Wobble */ menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 2); btn = XmCreateToggleButton(menupane, "Motion", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) toggle, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Dolly", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) dolly, NULL); XtVaSetValues(btn, XmNset, True, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Rotate", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) rotate, NULL); XtManageChild(btn); btn = XmCreateToggleButton(menupane, "Wobble", NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) wobble, NULL); XtManageChild(btn); XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "Options", args, 1); XtManageChild(cascade); XtSetArg(menuPaneArgs[2], XmNradioBehavior, True); XtSetArg(menuPaneArgs[3], XmNradioAlwaysOne, True); menupane = XmCreatePulldownMenu(menubar, "menupane", menuPaneArgs, 4); XtAddCallback(menupane, XmNentryCallback, (XtCallbackProc) fontSelect, NULL); for (i = 0; i < NUM_FONT_ENTRIES; i++) { btn = XmCreateToggleButton(menupane, fontEntry[i].name, NULL, 0); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc) neverCalled, &fontEntry[i]); if (i == 0) XtVaSetValues(btn, XmNset, True, NULL); if (!fontEntry[i].xfont) XtSetSensitive(btn, False); XtManageChild(btn); } XtSetArg(args[0], XmNsubMenuId, menupane); cascade = XmCreateCascadeButton(menubar, "Font", args, 1); XtManageChild(cascade); /* create framed drawing area for OpenGL rendering */ frame = XmCreateFrame(mainw, "frame", NULL, 0); XtManageChild(frame); glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0); XtAddCallback(glxarea, XmNexposeCallback, (XtCallbackProc) draw, NULL); XtAddCallback(glxarea, XmNresizeCallback, resize, NULL); XtAddCallback(glxarea, XmNinputCallback, input, NULL); /* set up application's window layout */ XmMainWindowSetAreas(mainw, menubar, NULL, NULL, NULL, frame); XtRealizeWidget(toplevel); /* * Once widget is realized (ie, associated with a created X window), we * can bind the OpenGL rendering context to the window. */ glXMakeCurrent(dpy, XtWindow(glxarea), cx); made_current = GL_TRUE; /* setup OpenGL state */ glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearDepth(1.0); glMatrixMode(GL_PROJECTION); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 80); glMatrixMode(GL_MODELVIEW); MakeCube(); if (argv[1] != NULL) { numMessages = argc - 1; messages = &argv[1]; } else { numMessages = NUM_DEFAULT_MESSAGES; messages = defaultMessage; } base = glGenLists(numMessages + 1); SetupMessageDisplayList(&fontEntry[0], numMessages, messages); tick(); /* start event processing */ XtAppMainLoop(app); }
int main(int argc, char *argv[]) { int texw, texh; unsigned char *texarea, *texbitmap; FILE *file; int len, stride; unsigned char *glist; int width, height; int px, py, maxheight; TexGlyphInfo tgi; int usageError = 0; char *fontname, *filename; XFontStruct *xfont; int endianness; int i, j; texw = texh = 256; glist = " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijmklmnopqrstuvwxyz?.;,!*:\"/+@#$%^&()"; fontname = "-adobe-courier-bold-r-normal--46-*-100-100-m-*-iso8859-1"; filename = "default.txf"; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-w")) { i++; texw = atoi(argv[i]); } else if (!strcmp(argv[i], "-h")) { i++; texh = atoi(argv[i]); } else if (!strcmp(argv[i], "-gap")) { i++; gap = atoi(argv[i]); } else if (!strcmp(argv[i], "-byte")) { format = TXF_FORMAT_BYTE; break; } else if (!strcmp(argv[i], "-bitmap")) { format = TXF_FORMAT_BITMAP; } else if (!strcmp(argv[i], "-glist")) { i++; glist = (unsigned char *) argv[i]; } else if (!strcmp(argv[i], "-fn")) { i++; fontname = argv[i]; } else if (!strcmp(argv[i], "-file")) { i++; filename = argv[i]; } else { usageError = 1; } } if (usageError) { putchar('\n'); printf("usage: texfontgen [options] txf-file\n"); printf(" -w # textureWidth (def=%d)\n", texw); printf(" -h # textureHeight (def=%d)\n", texh); printf(" -gap # gap between glyphs (def=%d)\n", gap); printf(" -bitmap use a bitmap encoding (default)\n"); printf(" -byte use a byte encoding (less compact)\n"); printf(" -glist ABC glyph list (def=%s)\n", glist); printf(" -fn name X font name (def=%s)\n", fontname); printf(" -file name output file for textured font (def=%s)\n", fontname); putchar('\n'); exit(1); } texarea = calloc(texw * texh, sizeof(unsigned char)); glist = (unsigned char *) nodupstring((char *) glist); dpy = XOpenDisplay(NULL); if (!dpy) { printf("could not open display\n"); exit(1); } /* find an OpenGL-capable RGB visual with depth buffer */ xfont = XLoadQueryFont(dpy, fontname); if (!xfont) { printf("could not get load X font: %s\n", fontname); exit(1); } fontinfo = SuckGlyphsFromServer(dpy, xfont->fid); if (!fontinfo) { printf("could not get font glyphs\n"); exit(1); } len = (int) strlen((char *) glist); qsort(glist, len, sizeof(unsigned char), glyphCompare); file = fopen(filename, "wb"); if (!file) { printf("could not open %s for writing\n", filename); exit(1); } fwrite("\377txf", 1, 4, file); endianness = 0x12345678; /*CONSTANTCONDITION*/ assert(sizeof(int) == 4); /* Ensure external file format size. */ fwrite(&endianness, sizeof(int), 1, file); fwrite(&format, sizeof(int), 1, file); fwrite(&texw, sizeof(int), 1, file); fwrite(&texh, sizeof(int), 1, file); fwrite(&fontinfo->max_ascent, sizeof(int), 1, file); fwrite(&fontinfo->max_descent, sizeof(int), 1, file); fwrite(&len, sizeof(int), 1, file); px = gap; py = gap; maxheight = 0; for (i = 0; i < len; i++) { if (glist[i] != 0) { /* If not already processed... */ /* Try to find a character from the glist that will fit on the remaining space on the current row. */ int foundWidthFit = 0; int c; getMetric(fontinfo, glist[i], &tgi); width = tgi.width; height = tgi.height; if (height > 0 && width > 0) { for (j = i; j < len;) { if (height > 0 && width > 0) { if (px + width + gap < texw) { foundWidthFit = 1; if (j != i) { i--; /* Step back so i loop increment leaves us at same character. */ } break; } } j++; getMetric(fontinfo, glist[j], &tgi); width = tgi.width; height = tgi.height; } /* If a fit was found, use that character; otherwise, advance a line in the texture. */ if (foundWidthFit) { if (height > maxheight) { maxheight = height; } c = j; } else { getMetric(fontinfo, glist[i], &tgi); width = tgi.width; height = tgi.height; py += maxheight + gap; px = gap; maxheight = height; if (py + height + gap >= texh) { printf("Overflowed texture space.\n"); exit(1); } c = i; } /* Place the glyph in the texture image. */ placeGlyph(fontinfo, glist[c], texarea, texw, px, py); /* Assign glyph's texture coordinate. */ tgi.x = px; tgi.y = py; /* Advance by glyph width, remaining in the current line. */ px += width + gap; } else { /* No texture image; assign invalid bogus texture coordinates. */ tgi.x = -1; tgi.y = -1; } glist[c] = 0; /* Mark processed; don't process again. */ /*CONSTANTCONDITION*/ assert(sizeof(tgi) == 12); /* Ensure external file format size. */ fwrite(&tgi, sizeof(tgi), 1, file); } } switch (format) { case TXF_FORMAT_BYTE: fwrite(texarea, texw * texh, 1, file); break; case TXF_FORMAT_BITMAP: stride = (texw + 7) >> 3; texbitmap = (unsigned char *) calloc(stride * texh, 1); for (i = 0; i < texh; i++) { for (j = 0; j < texw; j++) { if (texarea[i * texw + j] >= 128) { texbitmap[i * stride + (j >> 3)] |= 1 << (j & 7); } } } fwrite(texbitmap, stride * texh, 1, file); free(texbitmap); break; default: printf("Unknown texture font format.\n"); exit(1); }