4
Copyright (c) 1999 Nate Miller
6
Notice: Usage of any code in this file is subject to the rules
7
described in the LICENSE.TXT file included in this directory.
8
Reading, compiling, or otherwise using this code constitutes
9
automatic acceptance of the rules in said text file.
13
Author -- Nate 'm|d' Miller
14
Contact -- vandals1@home.com
15
Web -- http://members.home.com/vandals1
17
//#define FONT_LIB_DEBUG /* un-comment for debug regions */
18
#include "glTexFont.h"
19
#include "glTexFontTGA.h"
20
#include "glTexFontDefs.h"
21
#include "glTexFontInclude.h"
24
/* just a global for our default colors */
25
float white[] = {1.0, 1.0, 1.0, 1.0};
26
float gray[] = {0.5, 0.5, 0.5, 1.0};
28
/* the font structure we will use in the library, all values are defaults */
31
{1.0, 1.0, 1.0, 1.0}, /* white text */
32
{0.5, 0.5, 0.5, 1.0}, /* gray gradient */
33
{0.5, 0.5, 0.5, 1.0}, /* gray shadow */
34
12, /* size 12 font */
37
0, /* italic amount */
39
0,0,0,0,0, /* text region stuff */
40
0.0,0.0, /* texture inc stuff */
41
FONT_BLOCK_ROW, /* characters per row */
42
FONT_BLOCK_COL, /* characters por col */
47
tPoints contains our map for the font image. After fontMakeMap this array
48
will contain all the information to get the proper key from the font map.
56
Load the passed image name and use it for the font.
59
int fontLoad (char *name)
61
glGenTextures (1, &font.texId);
63
font.blockRow = FONT_BLOCK_ROW;
64
font.blockCol = FONT_BLOCK_COL;
68
return fontLoadTGA (name, font.texId);
74
Loads the passed image which has 'col' characters per column and 'row'
78
int fontLoadEx (char *name, int row, int col)
80
/* make sure we have valid dimensions */
81
/* if (row * col != 256)
84
glGenTextures (1, &font.texId);
91
return fontLoadTGA (name, font.texId);
97
Draws a character that is 'size' pixels in w and h.
100
void fontDrawChar (char c, int x, int y, int size, int shadow)
102
if (!font.gradient && !shadow)
103
glColor4fv (font.fgColor);
104
else if (!font.gradient && shadow)
105
glColor4fv (font.bgColor);
106
else if (font.gradient && !shadow)
107
glColor4fv (font.gdColor);
110
glTexCoord2f (tPoints[(int)c][0], tPoints[(int)c][1]);
113
glTexCoord2f (tPoints[(int)c][0] + font.tIncX, tPoints[(int)c][1]);
114
glVertex3i (x + size, y,0);
117
glColor4fv (font.fgColor);
118
else glColor4fv (font.bgColor);
120
glTexCoord2f (tPoints[(int)c][0] + font.tIncX, tPoints[(int)c][1] + font.tIncY);
121
glVertex3i (x + size + font.italic, y + size,0);
123
glTexCoord2f (tPoints[(int)c][0], tPoints[(int)c][1] + font.tIncY);
124
glVertex3i (x + font.italic, y + size,0);
131
Normal scissor region for text rendering.
134
void fontScissorNormal (int xpos, int ypos, int tabs, int carrage, int size, int len)
140
ex = len * size * tabs;
144
sy = ypos - (size * carrage);
145
ey = size * (carrage + 1);
150
glScissor (xpos, sy, ex, ey);
154
fontScissorTextRegion
156
Scissor region used setup for a text region.
159
void fontScissorTextRegion (void)
161
glScissor (font.regionX, font.regionY, font.regionW, font.regionH);
167
Resets the font color.
170
void fontForeColorReset (void)
172
fontColorCopy (white, font.fgColor);
178
Resets the shadow color.
181
void fontShadowColorReset (void)
183
fontColorCopy (gray, font.bgColor);
189
Resets the gradient color.
192
void fontGradientColorReset (void)
194
fontColorCopy (gray, font.gdColor);
200
Resets the font. Only resets variables that could possible change.
203
void fontReset (void)
215
fontForeColorReset ();
216
fontShadowColorReset ();
217
fontGradientColorReset ();
223
Sets up a font region. Only good for one fontDrawString.
226
void fontRegion (int x, int y, int w, int h)
230
font.regionY = y - h;
241
void fontSize (int size)
245
void fontzdepth(float zdepth)
253
Draws a shadow if called.
256
void fontShadow (void)
264
Draws gradient text if called.
267
void fontGradient (void)
275
Draws a character to the screen
276
Bold is just a hack, nothing special
279
void fontRenderChar (char c, int x, int y, int size)
284
fontDrawChar (c, x + 1, y + 1, size, 1);
285
else fontDrawChar (c, x + 2, y + 1, size, 1);
290
fontDrawChar (c, x, y, size, 0);
293
fontDrawChar (c, x + 1, y, size, 0);
299
Handles all the fun that comes with a \\, returns amount to advance string.
300
After this funtion *buffptr ++ will be the next character to draw or parse.
303
int fontSlashParser (char *buffPtr, int *x, int *y)
317
return fontSetColorFromToken (buffPtr);
321
return fontItalicsMode (buffPtr);
325
return fontBoldMode (buffPtr);
329
fontRenderChar (*buffPtr, *x, *y, font.size);
338
Does the actual rendering of our string.
341
void fontWalkString (char *buffPtr, int xpos, int ypos, int *vPort,float width)
343
int size = font.size;
348
int len = strlen (buffPtr);
354
xMax = vPort[0] + vPort[2];
356
carrage = fontGetCharHits (buffPtr, '\n');
357
tabs = fontGetCharHits (buffPtr, '\t');
361
else tabs *= FONT_TAB_SPACE;
365
fontScissorTextRegion ();
367
y = (font.regionY + font.regionH) - font.size;
369
fontScissorNormal (xpos, ypos, tabs, carrage, font.size, len); */
371
#ifdef FONT_LIB_DEBUG
372
glClearColor (1,0,1,1);
373
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
377
//width for each char should be calculated , we need the max line length of the paragraph
383
while (*tempC != '\0')
387
if (charCount > maxcharCount)
388
maxcharCount=charCount;
395
charCount=charCount+FONT_TAB_SPACE;
401
if (charCount > maxcharCount)
402
maxcharCount=charCount;
403
charGap=(int)(width / (float)maxcharCount);
406
for ( ; *buffPtr; *buffPtr ++, x += charGap) //size*0.7 is the distance between2 characters
412
if (x + size > (font.regionX + font.regionW))
417
if (y < font.regionY)
424
if(*buffPtr==' ') //SPACE
437
x += (size * FONT_TAB_SPACE);
441
buffPtr += fontSlashParser (buffPtr, &x, &y);
442
if (*buffPtr == '\n' || *buffPtr == '\t')
449
fontRenderChar (*buffPtr, x, y, size);
458
Renders a string at xpos, ypos.
461
void fontDrawString (int xpos, int ypos, char *s,int width,...)
464
char buffer[FONT_MAX_LEN] = {'\0'};
469
_vsntprintf (buffer, FONT_MAX_LEN - 1, s, msg);
471
vsnprintf (buffer, FONT_MAX_LEN - 1, s, msg);
475
/* get current viewport */
476
glGetIntegerv (GL_VIEWPORT, vPort);
477
/* setup various opengl things that we need */
479
fontSetModes (FONT_GET_MODES);
480
//if constant location is desired for fonts turn on these comment outs
481
/* glMatrixMode (GL_PROJECTION);
486
glOrtho (0, vPort[2], 0, vPort[3], -1, 1);
487
glMatrixMode (GL_MODELVIEW);
490
glBindTexture (GL_TEXTURE_2D, font.texId);
492
/* draw the string */
495
fontWalkString (buffer, xpos, ypos, vPort,(float)width);
497
/* glMatrixMode (GL_PROJECTION);
499
glMatrixMode (GL_MODELVIEW);
502
fontSetModes (FONT_RESTORE_MODES);
507
fontSetColorFromToken
509
Grabs a color token from a buffer and sets color.
512
int fontSetColorFromToken (char *s)
520
if (sscanf (s, "(%d %d %d)", &clr[0], &clr[1], &clr[2]) != 3)
522
fontColor (clr[0] * FONT_ITOF, clr[1] * FONT_ITOF, clr[2] * FONT_ITOF);
523
} else if (*s == 'a')
526
if (sscanf (s, "(%d %d %d %d)", &clr[0], &clr[1], &clr[2], &clr[3]) != 4)
528
fontColorA (clr[0] * FONT_ITOF, clr[1] * FONT_ITOF, clr[2] * FONT_ITOF, clr[3] * FONT_ITOF);
531
while (*s != ')' && ret ++)
540
Either turns on or off italics.
543
int fontItalicsMode (char *s)
548
font.italic = FONT_ITALIC;
559
Either turns on or off bold.
562
int fontBoldMode (char *s)
578
Returns number of times a character is found in a buffer.
581
int fontGetCharHits (char *s, char f)
598
Makes the font map which allows the correct characters to be drawn.
601
void fontMakeMap (void)
603
#define VCOPY(d,x,y) {d[0] = x; d[1] = y;}
608
font.tIncX = (float)pow (font.blockCol, -1);
609
font.tIncY = (float)pow (font.blockRow, -1);
612
for (y = 1 - font.tIncY; y >= 0; y -= font.tIncY)
613
for (x = 0; x <= 1 - font.tIncX; x += font.tIncX, i ++)
614
VCOPY (tPoints[i], x, y);
621
Sets or restores OpenGL modes that we need to use. Here to prevent the drawing
622
of text from messing up other stuff.
625
void fontSetModes (int state)
627
static int matrixMode;
628
static int polyMode[2];
629
static int lightingOn;
632
static int textureOn;
633
static int scissorOn;
637
/* grab the modes that we might need to change */
638
if (state == FONT_GET_MODES)
640
glGetIntegerv(GL_POLYGON_MODE, polyMode);
642
if (polyMode[0] != GL_FILL)
643
glPolygonMode (GL_FRONT, GL_FILL);
644
if (polyMode[1] != GL_FILL)
645
glPolygonMode (GL_BACK, GL_FILL);
647
textureOn = glIsEnabled (GL_TEXTURE_2D);
649
glEnable (GL_TEXTURE_2D);
651
depthOn = glIsEnabled (GL_DEPTH_TEST);
654
glDisable (GL_DEPTH_TEST);
656
lightingOn= glIsEnabled (GL_LIGHTING);
659
glDisable(GL_LIGHTING);
661
scissorOn= glIsEnabled (GL_SCISSOR_TEST);
664
glEnable (GL_SCISSOR_TEST);*/
666
glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
668
/* i don't know if this is correct */
669
blendOn= glIsEnabled (GL_BLEND);
670
glGetIntegerv (GL_BLEND_SRC, &blendSrc);
671
glGetIntegerv (GL_BLEND_DST, &blendDst);
674
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
675
} else if (state == FONT_RESTORE_MODES)
677
/* put everything back where it was before */
678
if (polyMode[0] != GL_FILL)
679
glPolygonMode (GL_FRONT, polyMode[0]);
680
if (polyMode[1] != GL_FILL)
681
glPolygonMode (GL_BACK, polyMode[1]);
684
glEnable(GL_LIGHTING);
686
/* i don't know if this is correct */
689
glDisable (GL_BLEND);
690
glBlendFunc (blendSrc, blendDst);
691
} else glBlendFunc (blendSrc, blendDst);
694
glEnable (GL_DEPTH_TEST);
697
glDisable (GL_TEXTURE_2D);
700
glDisable (GL_SCISSOR_TEST);
702
glMatrixMode (matrixMode);