90d38e3b517710adc06d045bd2378a81a9cce79d
[freeglut] / freeglut-1.3 / freeglut_font.c
1 /*
2  * freeglut_font.c
3  *
4  * Bitmap and stroke fonts displaying.
5  *
6  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8  * Creation date: Thu Dec 16 1999
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #define  G_LOG_DOMAIN  "freeglut-font"
33
34 #include "../include/GL/freeglut.h"
35 #include "../include/GL/freeglut_internal.h"
36
37 /*
38  * TODO BEFORE THE STABLE RELEASE:
39  *
40  *  glutStrokeCharacter()       -- stroke fonts not implemented, uses a bitmap font instead
41  *  glutStrokeWidth()           -- stroke fonts not implemented, uses a bitmap font instead
42  */
43
44 /* -- IMPORT DECLARATIONS -------------------------------------------------- */
45
46 /*
47  * These are the font faces defined in freeglut_font_data.c file:
48  */
49 extern SFG_Font fgFontFixed8x13;
50 extern SFG_Font fgFontFixed9x15;
51 extern SFG_Font fgFontHelvetica10;
52 extern SFG_Font fgFontHelvetica12;
53 extern SFG_Font fgFontHelvetica18;
54 extern SFG_Font fgFontTimesRoman10;
55 extern SFG_Font fgFontTimesRoman24;
56 extern SFG_StrokeFont fgStrokeRoman;
57 extern SFG_StrokeFont fgStrokeMonoRoman;
58
59 /*
60  * This is for GLUT binary compatibility, as suggested by Steve Baker
61  */
62 #if TARGET_HOST_UNIX_X11
63     void* glutStrokeRoman;
64     void* glutStrokeMonoRoman;
65     void* glutBitmap9By15;
66     void* glutBitmap8By13;
67     void* glutBitmapTimesRoman10;
68     void* glutBitmapTimesRoman24;
69     void* glutBitmapHelvetica10;
70     void* glutBitmapHelvetica12;
71     void* glutBitmapHelvetica18;
72 #endif
73
74
75 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
76
77 /*
78  * Matches a font ID with a SFG_Font structure pointer.
79  * This was changed to match the GLUT header style.
80  */
81 static SFG_Font* fghFontByID( void* font )
82 {
83     /*
84      * Try matching the font ID and the font data structure
85      */
86     if( font == GLUT_BITMAP_8_BY_13        ) return( &fgFontFixed8x13    );
87     if( font == GLUT_BITMAP_9_BY_15        ) return( &fgFontFixed9x15    );
88     if( font == GLUT_BITMAP_HELVETICA_10   ) return( &fgFontHelvetica10  );
89     if( font == GLUT_BITMAP_HELVETICA_12   ) return( &fgFontHelvetica12  );
90     if( font == GLUT_BITMAP_HELVETICA_18   ) return( &fgFontHelvetica18  );
91     if( font == GLUT_BITMAP_TIMES_ROMAN_10 ) return( &fgFontTimesRoman10 );
92     if( font == GLUT_BITMAP_TIMES_ROMAN_24 ) return( &fgFontTimesRoman24 );
93
94     /*
95      * This probably is the library user's fault
96      */
97     fgError( "font 0x%08x not found", font );
98
99     return 0;
100 }
101
102 /*
103  * Matches a font ID with a SFG_StrokeFont structure pointer.
104  * This was changed to match the GLUT header style.
105  */
106 static SFG_StrokeFont* fghStrokeByID( void* font )
107 {
108     /*
109      * Try matching the font ID and the font data structure
110      */
111     if( font == GLUT_STROKE_ROMAN ) return( &fgStrokeRoman );
112     if( font == GLUT_STROKE_MONO_ROMAN ) return( &fgStrokeMonoRoman );
113
114     /*
115      * This probably is the library user's fault
116      */
117     fgError( "stroke font 0x%08x not found", font );
118
119     return 0;
120 }
121
122
123 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
124
125 /*
126  * Draw a bitmap character
127  */
128 void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
129 {
130     const GLubyte* face;
131
132     /*
133      * First of all we'll need a font to use
134      */
135     SFG_Font* font = fghFontByID( fontID );
136
137     /*
138      * Make sure the character we want to output is valid
139      */
140     freeglut_return_if_fail( character >= 0 && character < font->Quantity );
141
142     /*
143      * Then find the character we want to draw
144      */
145     face = font->Characters[ character - 1 ];
146
147     /*
148      * Save the old pixel store settings
149      */
150     glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
151
152     /*
153      * Set up the pixel unpacking ways
154      */
155     glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
156     glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE );
157     glPixelStorei( GL_UNPACK_ROW_LENGTH,  0        );
158     glPixelStorei( GL_UNPACK_SKIP_ROWS,   0        );
159     glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0        );
160     glPixelStorei( GL_UNPACK_ALIGNMENT,   1        );
161
162     /*
163      * We'll use a glBitmap call to draw the font.
164      */
165     glBitmap(
166         face[ 0 ], font->Height,    /* The bitmap's width and height */
167         0, 0,                       /* The origin -- what the hell?  */
168         face[ 0 ] + 1, 0,           /* The raster advance -- inc. x  */
169         (face + 1)                  /* The packed bitmap data...     */
170     );
171
172     /*
173      * Restore the old pixel store settings
174      */
175     glPopClientAttrib();
176 }
177
178 void FGAPIENTRY glutBitmapString( void* fontID, const char *string )
179 {
180     int i;
181
182     for( i=0; i<strlen( string ); i++ )
183         glutBitmapCharacter( fontID, string[ i ] );
184 }
185
186 /*
187  * Returns the width in pixels of a font's character
188  */
189 int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
190 {
191     /*
192      * First of all, grab the font we need
193      */
194     SFG_Font* font = fghFontByID( fontID );
195
196     /*
197      * Make sure the character we want to output is valid
198      */
199     freeglut_return_val_if_fail( character > 0 && character < font->Quantity, 0 );
200
201     /*
202          * Scan the font looking for the specified character
203      */
204     return( *(font->Characters[ character - 1 ]) + 1 );
205 }
206
207 /*
208  * Draw a stroke character
209  */
210 void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
211 {
212     const SFG_StrokeChar *schar;
213     const SFG_StrokeStrip *strip;
214     int i, j;
215
216     /*
217      * First of all we'll need a font to use
218      */
219     SFG_StrokeFont* font = fghStrokeByID( fontID );
220
221     /*
222      * Make sure the character we want to output is valid
223      */
224     freeglut_return_if_fail( character >= 0 && character < font->Quantity );
225
226     schar = font->Characters[character];
227
228     strip = schar->Strips;
229
230     for (i = 0; i < schar->Number; i++, strip++)
231     {
232         glBegin(GL_LINE_STRIP);
233         for(j = 0; j < strip->Number; j++)
234         {
235             glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y);
236         }
237         glEnd();
238     }
239     glTranslatef(schar->Right, 0.0, 0.0);
240 }
241
242 /*
243  * Return the width in pixels of a stroke character
244  */
245 int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
246 {
247     /*
248      * First of all we'll need a font to use
249      */
250     SFG_StrokeFont* font = fghStrokeByID( fontID );
251
252     /*
253      * Make sure the character we want to output is valid
254      */
255     freeglut_return_if_fail( character >= 0 && character < font->Quantity );
256
257     return (font->Characters[character]->Right);
258 }
259
260 /*
261  * Return the width of a string drawn using a bitmap font
262  */
263 int FGAPIENTRY glutBitmapLength( void* fontID, const char* string )
264 {
265     int i, length = 0;
266
267     /*
268      * Using glutBitmapWidth() function to calculate the result
269      */
270     for( i=0; i<strlen( string ); i++ )
271         length += glutBitmapWidth( fontID, string[ i ] );
272
273     /*
274      * Return the result now
275      */
276     return( length );
277 }
278
279 /*
280  * Return the width of a string drawn using a stroke font
281  */
282 int FGAPIENTRY glutStrokeLength( void* fontID, const char* string )
283 {
284     int i, length = 0;
285
286     /*
287      * Using glutStrokeWidth() function to calculate the result
288      */
289     for( i=0; i<strlen( string ); i++ )
290         length += glutStrokeWidth( fontID, string[ i ] );
291
292     /*
293      * Return the result now
294      */
295     return( length );
296 }
297
298 /*
299  * Returns the height of a bitmap font
300  */
301 int FGAPIENTRY glutBitmapHeight( void* fontID )
302 {
303     /*
304      * See which font are we queried about
305      */
306     SFG_Font* font = fghFontByID( fontID );
307
308     /*
309      * Return the character set's height
310      */
311     return( font->Height );
312 }
313
314 /*
315  * Returns the height of a stroke font
316  */
317 GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
318 {
319     /*
320      * See which font are we queried about
321      */
322     SFG_StrokeFont* font = fghStrokeByID( fontID );
323
324     /*
325      * Return the character set's height
326      */
327     return( font->Height );
328 }
329
330 /*** END OF FILE ***/