TORCS  1.3.9
The Open Racing Car Simulator
guifont.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  guifont.cpp -- GLTT fonts management
3  -------------------
4  created : Fri Aug 13 22:19:09 CEST 1999
5  copyright : (C) 1999-2024 by Eric Espie, Bernhard Wymann
6  email : berniw@bluewin.ch
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 /* This font manipulation is based on Brad Fish's glFont format and code. */
20 /* http://www.netxs.net/bfish/news.html */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #ifdef WIN32
26 #include <windows.h>
27 #elif defined(__FreeBSD__)
28 #include <machine/endian.h>
29 #elif defined(sun)
30 #define BIG_ENDIAN 1234
31 #define LITTLE_ENDIAN 4321
32 #define BYTE_ORDER LITTLE_ENDIAN
33 #else
34 #include <endian.h>
35 #endif
36 
37 #include <tgfclient.h>
38 #include <portability.h>
39 
40 #include "guifont.h"
41 
42 #define FONT_NB 9
44 const char *keySize[4] = { "size big", "size large", "size medium", "size small" };
45 
46 
47 #ifndef WIN32
48 #if BYTE_ORDER == BIG_ENDIAN
49 void swap32(unsigned int *p, unsigned int size)
50 {
51  unsigned int i, t;
52  for (i = 0; i < size; i += 4) {
53  t = (unsigned int) *p;
54  *p = (t & 0xff000000U) >> 24;
55  *p |= (t & 0x00ff0000U) >> 8;
56  *p |= (t & 0x0000ff00U) << 8;
57  *p |= (t & 0x000000ffU) << 24;
58  p++;
59  }
60 }
61 #endif
62 #endif
63 
64 
65 void gfuiLoadFonts(void)
66 {
67  void *param;
68  int size;
69  int i;
70  const int BUFSIZE = 1024;
71  char buf[BUFSIZE];
72 
73  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
75 
76  const char* fontName = GfParmGetStr(param, "Menu Font", "name", "b5.glf");
77  snprintf(buf, BUFSIZE, "data/fonts/%s", fontName);
78 
79  for(i = 0; i < 4; i++) {
80  size = (int)GfParmGetNum(param, "Menu Font", keySize[i], (char*)NULL, 10.0);
81  gfuiFont[i] = new GfuiFontClass(buf);
82  gfuiFont[i]->create(size);
83  }
84 
85  fontName = GfParmGetStr(param, "Console Font", "name", "b7.glf");
86  snprintf(buf, BUFSIZE, "data/fonts/%s", fontName);
87 
88  for(i = 0; i < 4; i++) {
89  size = (int)GfParmGetNum(param, "Console Font", keySize[i], (char*)NULL, 10.0);
90  gfuiFont[i+4] = new GfuiFontClass(buf);
91  gfuiFont[i+4]->create(size);
92  }
93 
94  fontName = GfParmGetStr(param, "Digital Font", "name", "digital.glf");
95  snprintf(buf, BUFSIZE, "data/fonts/%s", fontName);
96  size = (int)GfParmGetNum(param, "Digital Font", keySize[0], (char*)NULL, 8.0);
97  gfuiFont[8] = new GfuiFontClass(buf);
98  gfuiFont[8]->create(size);
99 
101 }
102 
103 
105 {
106  FILE *Input;
107  char *TexBytes;
108  int Num;
109  uint Tex;
110 
111  font = NULL;
112  size = 8.0;
113 
114  //Open font file
115  if ((Input = fopen(FileName, "rb")) == NULL) {
116  perror(FileName);
117  return;
118  }
119 
120  if ((font = (GLFONT *)malloc(sizeof(GLFONT))) == NULL) {
121  return;
122  }
123 
124  //Read glFont structure. On IA64 sizeof(GLFONT) gives the wrong result, so we use 24 here instead
125  fread(font, 24, 1, Input);
126 
127 #ifndef WIN32
128 #if BYTE_ORDER == BIG_ENDIAN
129  swap32((unsigned int *) font, 24);
130 #endif
131 #endif
132 
133  //Get number of characters
134  Num = font->IntEnd - font->IntStart + 1;
135 
136  //Allocate memory for characters
137  if ((font->Char = (GLFONTCHAR *)malloc(sizeof(GLFONTCHAR) * Num)) == NULL) {
138  free(font);
139  font = NULL;
140  fclose(Input);
141  return;
142  }
143 
144  //Read glFont characters
145  fread(font->Char, sizeof(GLFONTCHAR), Num, Input);
146 
147 #ifndef WIN32
148 #if BYTE_ORDER == BIG_ENDIAN
149  swap32((unsigned int *) font->Char, sizeof(GLFONTCHAR) * Num);
150 #endif
151 #endif
152 
153  //Get texture size
154  Num = font->TexWidth * font->TexHeight * 2;
155 
156  //Allocate memory for texture data
157  if ((TexBytes = (char *)malloc(Num)) == NULL) {
158  fclose(Input);
159  return;
160  }
161 
162  GfOut("font: %s, %d, %d, %d, %d, %d\n",
163  FileName,
164  font->IntStart,
165  font->IntEnd,
166  font->IntEnd - font->IntStart + 1,
167  font->TexWidth,
168  font->TexHeight
169  );
170 
171  //Read texture data
172  fread(TexBytes, sizeof(char), Num, Input);
173 
174  fclose(Input);
175 
176  //Save texture number
177  glGenTextures(1, &Tex);
178  font->Tex = Tex;
179 
180  // Set texture attributes
181  glBindTexture(GL_TEXTURE_2D, Tex);
182  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
183  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
184  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
185  // Use trilinear filtering for minification
186  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
187  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
188 
189  // Create mipmaps
190  gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, font->TexWidth,
191  font->TexHeight, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, TexBytes);
192 
193  //Clean up
194  free(TexBytes);
195 
196  //Return pointer to new font
197  return;
198 }
199 
200 
202 {
203  if (font) {
204  glDeleteTextures(1, &font->Tex);
205  free(font->Char);
206  free(font);
207  }
208 }
209 
210 
211 void GfuiFontClass::create(int point_size)
212 {
213  if (font->TexWidth > 256) {
214  // Different scaling of in new file format, to keep it compatible "58" seems to be the right factor
215  size = point_size/58.0*1024.0f/font->TexWidth;
216  } else {
217  size = point_size;
218  }
219 }
220 
221 
222 int GfuiFontClass::getWidth(const char* text)
223 {
224  int Length, i;
225  GLFONTCHAR *Char;
226  float width = 0;
227 
228  if (font == NULL) {
229  return 0;
230  }
231 
232  //Get length of string
233  Length = strlen(text);
234 
235  //Loop through characters
236  for (i = 0; i < Length; i++) {
237 
238  //Make sure character is contained in texture
239  if ((int)text[i] < font->IntStart || (int)text[i] > font->IntEnd)
240  continue;
241 
242  if (text[i] == ' ' && font->TexWidth > 256) {
243  // Use the width of "!" for space the space character, hack for broken width data of space
244  Char = &font->Char['!' - font->IntStart];
245  } else {
246  //Get pointer to glFont character
247  Char = &font->Char[(int)text[i] - font->IntStart];
248  }
249 
250  if (font->TexWidth > 256) {
251  width += Char->dx * font->TexWidth * size;
252  } else {
253  width += Char->dx * size;
254  }
255  }
256 
257  return (int)width;
258 }
259 
260 
262 {
263  if (font == NULL) return 0;
264  if (font->TexWidth > 256) {
265  return (const int)(font->Char[0].dy* font->TexHeight * size);
266  } else {
267  return (const int)(font->Char[0].dy * size);
268  }
269 }
270 
271 
273 {
274  if (font == NULL) return 0;
275  return 0;
276 // return (const int)(font->Char[0].dy * size / 2.0);
277 }
278 
279 
280 void GfuiFontClass::output(int X, int Y, const char* text)
281 {
282  int Length, i;
283  GLFONTCHAR *Char;
284  float x = (float)X;
285  float y = (float)Y;
286  float width, height;
287 
288  //Return if we don't have a valid glFont
289  if (font == NULL) return;
290 
291  //Get length of string
292  Length = strlen(text);
293 
294  //Begin rendering quads
295  glBindTexture(GL_TEXTURE_2D, font->Tex);
296  glBegin(GL_QUADS);
297 
298  //Loop through characters
299  for (i = 0; i < Length; i++)
300  {
301  //Make sure character is contained in texture
302  if ((int)text[i] < font->IntStart || (int)text[i] > font->IntEnd)
303  continue;
304 
305  if (text[i] == ' ' && font->TexWidth > 256) {
306  // Use the width of "!" for space, hack for broken width data of space character
307  Char = &font->Char['!' - font->IntStart];
308  width = (Char->dx * font->TexWidth)*size;
309  } else {
310  //Get pointer to glFont character
311  Char = &font->Char[(int)text[i] - font->IntStart];
312 
313  //Get width and height
314  if (font->TexWidth > 256) {
315  width = (Char->dx * font->TexWidth)*size;
316  height = (Char->dy * font->TexHeight)*size;
317  } else {
318  width = (Char->dx)*size;
319  height = (Char->dy)*size;
320  }
321 
322  //Specify vertices and texture coordinates
323  glTexCoord2f(Char->tx1, Char->ty1);
324  glVertex2f(x, y + height);
325  glTexCoord2f(Char->tx1, Char->ty2);
326  glVertex2f(x, y);
327  glTexCoord2f(Char->tx2, Char->ty2);
328  glVertex2f(x + width, y);
329  glTexCoord2f(Char->tx2, Char->ty1);
330  glVertex2f(x + width, y + height);
331  }
332 
333  //Move to next character
334  x += width;
335  }
336 
337  //Stop rendering quads
338  glEnd();
339 }
GLFONTCHAR * Char
Definition: guifont.h:36
void swap32(unsigned int *p, unsigned int size)
Definition: guifont.cpp:49
void output(int x, int y, const char *text)
Definition: guifont.cpp:280
int TexWidth
Definition: guifont.h:34
void * GfParmReadFile(const char *file, int mode)
Read parameter set from file and return handle to parameter set.
Definition: params.cpp:1157
#define GFPARM_RMODE_STD
if handle already openned return it
Definition: tgf.h:265
char * GetLocalDir(void)
Definition: tgf.cpp:231
int IntEnd
Definition: guifont.h:35
void GfParmReleaseHandle(void *parmHandle)
Release given parameter set handle parmHandle.
Definition: params.cpp:1834
#define GFSCR_CONF_FILE
void create(int point_size)
Definition: guifont.cpp:211
float size
Definition: guifont.h:43
Definition: Basic.h:58
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition: params.cpp:2311
The Gaming Framework API (client part).
uint Tex
Definition: guifont.h:33
const char * keySize[4]
Definition: guifont.cpp:44
float tx1
Definition: guifont.h:26
GfuiFontClass * gfuiFont[FONT_NB]
Definition: guifont.cpp:43
#define FONT_NB
Definition: guifont.cpp:42
void gfuiLoadFonts(void)
Definition: guifont.cpp:65
#define GfOut
Definition: tgf.h:373
static Point p[4]
Definition: Convex.cpp:54
Definition: Basic.h:58
float dx
Definition: guifont.h:25
Parameter header structure, a parameter can either carry a numeric or a string value, numeric value is constraint by min and max, string value by options in within.
Definition: params.cpp:63
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
Definition: params.cpp:2392
static Vector y[4]
Definition: Convex.cpp:56
int getHeight() const
Definition: guifont.cpp:261
float ty2
Definition: guifont.h:27
Definition: guifont.h:31
float dy
Definition: guifont.h:25
GfuiFontClass(char *font)
Definition: guifont.cpp:104
float tx2
Definition: guifont.h:27
int TexHeight
Definition: guifont.h:34
float ty1
Definition: guifont.h:26
int IntStart
Definition: guifont.h:35
int getWidth(const char *text)
Definition: guifont.cpp:222
#define GFPARM_RMODE_CREAT
Create the file if doesn&#39;t exist.
Definition: tgf.h:267
GLFONT * font
Definition: guifont.h:42
int getDescender() const
Definition: guifont.cpp:272