/*************************************************************************** guifont.cpp -- GLTT fonts management ------------------- created : Fri Aug 13 22:19:09 CEST 1999 copyright : (C) 1999 by Eric Espie email : torcs@free.fr version : $Id: guifont.cpp,v 1.4 2005/02/01 15:55:55 berniw Exp $ ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* This font manipulation is based on Brad Fish's glFont format and code. */ /* http://www.netxs.net/bfish/news.html */ #include #include #include #ifdef WIN32 #include #elif defined(__FreeBSD__) #include #else #include #endif #include #include "guifont.h" static char buf[1024]; #define FONT_NB 9 GfuiFontClass *gfuiFont[FONT_NB]; char *keySize[4] = { "size big", "size large", "size medium", "size small" }; #ifndef WIN32 #if BYTE_ORDER == BIG_ENDIAN void swap32(unsigned int *p, unsigned int size) { unsigned int i, t; for (i = 0; i < size; i += 4) { t = (unsigned int) *p; *p = (t & 0xff000000U) >> 24; *p |= (t & 0x00ff0000U) >> 8; *p |= (t & 0x0000ff00U) << 8; *p |= (t & 0x000000ffU) << 24; p++; } } #endif #endif void gfuiLoadFonts(void) { void *param; char *fontName; int size; int i; sprintf(buf, "%s%s", GetLocalDir(), GFSCR_CONF_FILE); param = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); fontName = GfParmGetStr(param, "Menu Font", "name", "b5.glf"); sprintf(buf, "data/fonts/%s", fontName); for(i = 0; i < 4; i++) { size = (int)GfParmGetNum(param, "Menu Font", keySize[i], (char*)NULL, 10.0); gfuiFont[i] = new GfuiFontClass(buf); gfuiFont[i]->create(size); } fontName = GfParmGetStr(param, "Console Font", "name", "b7.glf"); sprintf(buf, "data/fonts/%s", fontName); for(i = 0; i < 4; i++) { size = (int)GfParmGetNum(param, "Console Font", keySize[i], (char*)NULL, 10.0); gfuiFont[i+4] = new GfuiFontClass(buf); gfuiFont[i+4]->create(size); } fontName = GfParmGetStr(param, "Digital Font", "name", "digital.glf"); sprintf(buf, "data/fonts/%s", fontName); size = (int)GfParmGetNum(param, "Digital Font", keySize[0], (char*)NULL, 8.0); gfuiFont[8] = new GfuiFontClass(buf); gfuiFont[8]->create(size); //GfParmReleaseHandle(param); } GfuiFontClass::GfuiFontClass(char *FileName) { FILE *Input; char *TexBytes; int Num; uint Tex; font = NULL; size = 8.0; //Open font file if ((Input = fopen(FileName, "rb")) == NULL) { perror(FileName); return; } if ((font = (GLFONT *)malloc(sizeof(GLFONT))) == NULL) { return; } //Read glFont structure //fread(font, sizeof(GLFONT), 1, Input); fread(font, 24, 1, Input); // for IA64... #ifndef WIN32 #if BYTE_ORDER == BIG_ENDIAN swap32((unsigned int *) font, 24); #endif #endif //Get number of characters Num = font->IntEnd - font->IntStart + 1; //Allocate memory for characters if ((font->Char = (GLFONTCHAR *)malloc(sizeof(GLFONTCHAR) * Num)) == NULL) { free(font); font = NULL; fclose(Input); return; } //Read glFont characters fread(font->Char, sizeof(GLFONTCHAR), Num, Input); #ifndef WIN32 #if BYTE_ORDER == BIG_ENDIAN swap32((unsigned int *) font->Char, sizeof(GLFONTCHAR) * Num); #endif #endif //Get texture size Num = font->TexWidth * font->TexHeight * 2; //Allocate memory for texture data if ((TexBytes = (char *)malloc(Num)) == NULL) { fclose(Input); return; } //Read texture data fread(TexBytes, sizeof(char), Num, Input); fclose(Input); //Save texture number glGenTextures(1, &Tex); font->Tex = Tex; //Set texture attributes glBindTexture(GL_TEXTURE_2D, Tex); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //Create texture glTexImage2D(GL_TEXTURE_2D, 0, 2, font->TexWidth, font->TexHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (void *)TexBytes); //Clean up free(TexBytes); //Return pointer to new font return; } GfuiFontClass::~GfuiFontClass() { if (font) { glDeleteTextures(1, &font->Tex); free(font->Char); free(font); } } void GfuiFontClass::create(int point_size) { size = point_size; } int GfuiFontClass::getWidth(const char* text) { int Length, i; GLFONTCHAR *Char; float width = 0; if (font == NULL) { return 0; } //Get length of string Length = strlen(text); //Loop through characters for (i = 0; i < Length; i++) { //Get pointer to glFont character Char = &font->Char[(int)text[i] - font->IntStart]; float w2 = Char->dx * size; width = width + w2; //width += Char->dx * size; } return (int)width; } int GfuiFontClass::getHeight() const { if (font == NULL) return 0; return (const int)(font->Char[0].dy * size); } int GfuiFontClass::getDescender() const { if (font == NULL) return 0; return 0; return (const int)(font->Char[0].dy * size / 2.0); } void GfuiFontClass::output(int X, int Y, const char* text) { int Length, i; GLFONTCHAR *Char; float x = (float)X; float y = (float)Y; //Return if we don't have a valid glFont if (font == NULL) return; //Get length of string Length = strlen(text); //Begin rendering quads glBindTexture(GL_TEXTURE_2D, font->Tex); glBegin(GL_QUADS); //Loop through characters for (i = 0; i < Length; i++) { //Get pointer to glFont character Char = &font->Char[(int)text[i] - font->IntStart]; //Specify vertices and texture coordinates glTexCoord2f(Char->tx1, Char->ty1); glVertex2f(x, y + Char->dy * size); glTexCoord2f(Char->tx1, Char->ty2); glVertex2f(x, y); glTexCoord2f(Char->tx2, Char->ty2); glVertex2f(x + Char->dx * size, y); glTexCoord2f(Char->tx2, Char->ty1); glVertex2f(x + Char->dx * size, y + Char->dy * size); //Move to next character x += Char->dx*size; } //Stop rendering quads glEnd(); }