1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: fnt.cxx 1939 2004-08-05 00:41:53Z puggles $
22 */
23
24 #include "fntLocal.h"
25
fntFont()26 fntFont:: fntFont () {}
~fntFont()27 fntFont::~fntFont () {}
28
load(const char * fname,GLenum mag,GLenum min)29 int fntTexFont::load ( const char *fname, GLenum mag, GLenum min )
30 {
31 const char *p ;
32
33 for ( p = & fname [ strlen ( fname ) -1 ] ;
34 p != fname && *p != '.' && *p != '/' ; p-- )
35 /* Do nothing */ ;
36
37 if ( strcmp ( p, ".txf" ) == 0 ) {
38 return loadTXF ( fname, mag, min ) ;
39 }
40 else
41 {
42 ulSetError ( UL_WARNING,
43 "fnt::load: Error - Unrecognised file format for '%s'", fname ) ;
44 return FNT_FALSE ;
45 }
46 }
47
48
49
low_putch(sgVec3 curpos,float pointsize,float italic,char c)50 float fntTexFont::low_putch ( sgVec3 curpos, float pointsize,
51 float italic, char c )
52 {
53 unsigned int cc = (unsigned char) c ;
54
55 /* Auto case-convert if character is absent from font. */
56
57 if ( ! exists [ cc ] )
58 {
59 if ( cc >= 'A' && cc <= 'Z' )
60 cc = cc - 'A' + 'a' ;
61 else
62 if ( cc >= 'a' && cc <= 'z' )
63 cc = cc - 'a' + 'A' ;
64
65 if ( cc == ' ' )
66 {
67 curpos [ 0 ] += pointsize / 2.0f ;
68 return pointsize / 2.0f ;
69 }
70 }
71
72 /*
73 We might want to consider making some absent characters from
74 others (if they exist): lowercase 'l' could be made into digit '1'
75 or letter 'O' into digit '0'...or vice versa. We could also
76 make 'b', 'd', 'p' and 'q' by mirror-imaging - this would
77 save a little more texture memory in some fonts.
78 */
79
80 if ( ! exists [ cc ] )
81 return 0.0f ;
82
83 glBegin ( GL_TRIANGLE_STRIP ) ;
84 glTexCoord2f ( t_left [cc], t_bot[cc] ) ;
85 glVertex3f ( curpos[0] + v_left [cc] * pointsize,
86 curpos[1] + v_bot [cc] * pointsize,
87 curpos[2] ) ;
88
89 glTexCoord2f ( t_left [cc], t_top[cc] ) ;
90 glVertex3f ( curpos[0] + (italic + v_left [cc]) * pointsize,
91 curpos[1] + v_top [cc] * pointsize,
92 curpos[2] ) ;
93
94 glTexCoord2f ( t_right[cc], t_bot[cc] ) ;
95 glVertex3f ( curpos[0] + v_right[cc] * pointsize,
96 curpos[1] + v_bot [cc] * pointsize,
97 curpos[2] ) ;
98
99 glTexCoord2f ( t_right[cc], t_top[cc] ) ;
100 glVertex3f ( curpos[0] + (italic + v_right[cc]) * pointsize,
101 curpos[1] + v_top [cc] * pointsize,
102 curpos[2] ) ;
103 glEnd () ;
104
105 float ww = ( gap + ( fixed_pitch ? width : widths[cc] ) ) * pointsize ;
106 curpos[0] += ww ;
107 return ww ;
108 }
109
110
111
setGlyph(char c,float wid,float tex_left,float tex_right,float tex_bot,float tex_top,float vtx_left,float vtx_right,float vtx_bot,float vtx_top)112 void fntTexFont::setGlyph ( char c, float wid,
113 float tex_left, float tex_right,
114 float tex_bot , float tex_top ,
115 float vtx_left, float vtx_right,
116 float vtx_bot , float vtx_top )
117 {
118 unsigned int cc = (unsigned char) c ;
119
120 exists[cc] = FNT_TRUE ;
121
122 widths[cc] = wid;
123
124 t_left[cc] = tex_left ; t_right[cc] = tex_right ;
125 t_bot [cc] = tex_bot ; t_top [cc] = tex_top ;
126
127 v_left[cc] = vtx_left ; v_right[cc] = vtx_right ;
128 v_bot [cc] = vtx_bot ; v_top [cc] = vtx_top ;
129 }
130
131
getGlyph(char c,float * wid,float * tex_left,float * tex_right,float * tex_bot,float * tex_top,float * vtx_left,float * vtx_right,float * vtx_bot,float * vtx_top)132 int fntTexFont::getGlyph ( char c, float* wid,
133 float *tex_left, float *tex_right,
134 float *tex_bot , float *tex_top ,
135 float *vtx_left, float *vtx_right,
136 float *vtx_bot , float *vtx_top )
137 {
138 unsigned int cc = (unsigned char) c ;
139
140 if ( ! exists[cc] ) return FNT_FALSE ;
141
142 if ( wid != NULL ) *wid = widths [cc] ;
143
144 if ( tex_left != NULL ) *tex_left = t_left [cc] ;
145 if ( tex_right != NULL ) *tex_right = t_right[cc] ;
146 if ( tex_bot != NULL ) *tex_bot = t_bot [cc] ;
147 if ( tex_top != NULL ) *tex_top = t_top [cc] ;
148
149 if ( vtx_left != NULL ) *vtx_left = v_left [cc] ;
150 if ( vtx_right != NULL ) *vtx_right = v_right[cc] ;
151 if ( vtx_bot != NULL ) *vtx_bot = v_bot [cc] ;
152 if ( vtx_top != NULL ) *vtx_top = v_top [cc] ;
153
154 return FNT_TRUE ;
155 }
156
157
getBBox(const char * s,float pointsize,float italic,float * left,float * right,float * bot,float * top)158 void fntTexFont::getBBox ( const char *s,
159 float pointsize, float italic,
160 float *left, float *right,
161 float *bot , float *top )
162 {
163 float h_pos = 0.0f ;
164 float v_pos = 0.0f ;
165 float l, r, b, t ;
166
167 l = r = b = t = 0.0f ;
168
169 while ( *s != '\0' )
170 {
171 if ( *s == '\n' )
172 {
173 h_pos = 0.0f ;
174 v_pos -= 1.333f ;
175 s++ ;
176 continue ;
177 }
178
179 unsigned int cc = (unsigned char) *(s++) ;
180
181 if ( ! exists [ cc ] )
182 {
183 if ( cc >= 'A' && cc <= 'Z' )
184 cc = cc - 'A' + 'a' ;
185 else
186 if ( cc >= 'a' && cc <= 'z' )
187 cc = cc - 'a' + 'A' ;
188
189 if ( cc == ' ' )
190 {
191 r += 0.5f ;
192 h_pos += 0.5f ;
193
194 continue ;
195 }
196 }
197
198 if ( ! exists [ cc ] )
199 continue ;
200
201 if ( italic >= 0 )
202 {
203 if ( l > h_pos + v_left [cc] ) l = h_pos + v_left [cc] ;
204 if ( r < gap + h_pos + v_right[cc]+italic ) r = gap + h_pos + v_right[cc] + italic ;
205 }
206 else
207 {
208 if ( l > h_pos + v_left [cc]+italic ) l = h_pos + v_left [cc] + italic ;
209 if ( r < gap + h_pos + v_right[cc] ) r = gap + h_pos + v_right[cc] ;
210 }
211
212
213 if ( b > v_pos + v_bot [cc] ) b = v_pos + v_bot [cc] ;
214 if ( t < v_pos + v_top [cc] ) t = v_pos + v_top [cc] ;
215
216 h_pos += gap + ( fixed_pitch ? width : widths[cc] ) ;
217 }
218
219 if ( left != NULL ) *left = l * pointsize ;
220 if ( right != NULL ) *right = r * pointsize ;
221 if ( top != NULL ) *top = t * pointsize ;
222 if ( bot != NULL ) *bot = b * pointsize ;
223 }
224
225
puts(sgVec3 curpos,float pointsize,float italic,const char * s)226 void fntTexFont::puts ( sgVec3 curpos, float pointsize, float italic, const char *s )
227 {
228 SGfloat origx = curpos[0] ;
229
230 if ( ! bound )
231 bind_texture () ;
232
233 while ( *s != '\0' )
234 {
235 if (*s == '\n')
236 {
237 curpos[0] = origx ;
238 curpos[1] -= pointsize ;
239 }
240 else
241 low_putch ( curpos, pointsize, italic, *s ) ;
242
243 s++ ;
244 }
245 }
246
fntInit()247 void fntInit ()
248 {
249 /* Empty right now */
250 }
251
252
253