4 * Bitmap and stroke fonts displaying.
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
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:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
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.
32 #define G_LOG_DOMAIN "freeglut-font"
34 #include "../include/GL/freeglut.h"
35 #include "freeglut_internal.h"
38 * TODO BEFORE THE STABLE RELEASE:
43 /* -- IMPORT DECLARATIONS -------------------------------------------------- */
46 * These are the font faces defined in freeglut_font_data.c file:
48 extern SFG_Font fgFontFixed8x13;
49 extern SFG_Font fgFontFixed9x15;
50 extern SFG_Font fgFontHelvetica10;
51 extern SFG_Font fgFontHelvetica12;
52 extern SFG_Font fgFontHelvetica18;
53 extern SFG_Font fgFontTimesRoman10;
54 extern SFG_Font fgFontTimesRoman24;
55 extern SFG_StrokeFont fgStrokeRoman;
56 extern SFG_StrokeFont fgStrokeMonoRoman;
59 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
62 * Matches a font ID with a SFG_Font structure pointer.
63 * This was changed to match the GLUT header style.
65 static SFG_Font* fghFontByID( void* font )
68 * Try matching the font ID and the font data structure
70 if( font == GLUT_BITMAP_8_BY_13 ) return( &fgFontFixed8x13 );
71 if( font == GLUT_BITMAP_9_BY_15 ) return( &fgFontFixed9x15 );
72 if( font == GLUT_BITMAP_HELVETICA_10 ) return( &fgFontHelvetica10 );
73 if( font == GLUT_BITMAP_HELVETICA_12 ) return( &fgFontHelvetica12 );
74 if( font == GLUT_BITMAP_HELVETICA_18 ) return( &fgFontHelvetica18 );
75 if( font == GLUT_BITMAP_TIMES_ROMAN_10 ) return( &fgFontTimesRoman10 );
76 if( font == GLUT_BITMAP_TIMES_ROMAN_24 ) return( &fgFontTimesRoman24 );
79 * This probably is the library user's fault
81 fgError( "font 0x%08x not found", font );
87 * Matches a font ID with a SFG_StrokeFont structure pointer.
88 * This was changed to match the GLUT header style.
90 static SFG_StrokeFont* fghStrokeByID( void* font )
93 * Try matching the font ID and the font data structure
95 if( font == GLUT_STROKE_ROMAN ) return( &fgStrokeRoman );
96 if( font == GLUT_STROKE_MONO_ROMAN ) return( &fgStrokeMonoRoman );
99 * This probably is the library user's fault
101 fgError( "stroke font 0x%08x not found", font );
107 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
110 * Draw a bitmap character
112 void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
117 * First of all we'll need a font to use
119 SFG_Font* font = fghFontByID( fontID );
122 * Make sure the character we want to output is valid
124 freeglut_return_if_fail( character >= 1 && character < 256 );
127 * Then find the character we want to draw
129 face = font->Characters[ character - 1 ];
132 * Save the old pixel store settings
134 glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
137 * Set up the pixel unpacking ways
139 glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
140 glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
141 glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
142 glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
143 glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
144 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
147 * We'll use a glBitmap call to draw the font.
150 face[ 0 ], font->Height, /* The bitmap's width and height */
151 font->xorig, font->yorig, /* The origin -- what on earth? */
152 (float)(face[ 0 ]), 0.0, /* The raster advance -- inc. x */
153 (face + 1) /* The packed bitmap data... */
157 * Restore the old pixel store settings
162 void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
165 int numchar = strlen ( string ) ;
168 * First of all we'll need a font to use
170 SFG_Font* font = fghFontByID( fontID );
172 float raster_position[4] ;
173 glGetFloatv ( GL_CURRENT_RASTER_POSITION, raster_position ) ;
176 * Save the old pixel store settings
178 glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
181 * Set up the pixel unpacking ways
183 glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
184 glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
185 glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
186 glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
187 glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
188 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
191 * Step through the string, drawing each character.
192 * A carriage return will simply translate the next character's insertion point back to the
193 * start of the line and down one line.
195 for( c = 0; c < numchar; c++ )
197 if ( string[c] == '\n' )
199 raster_position[1] -= (float)font->Height ;
200 glRasterPos4fv ( raster_position ) ;
202 else /* Not a carriage return, draw the bitmap character */
204 const GLubyte* face = font->Characters[ string[ c ] - 1 ] ;
207 * We'll use a glBitmap call to draw the font.
210 face[ 0 ], font->Height, /* The bitmap's width and height */
211 font->xorig, font->yorig, /* The origin -- what on earth? */
212 (float)(face[ 0 ]), 0.0, /* The raster advance -- inc. x */
213 (face + 1) /* The packed bitmap data... */
219 * Restore the old pixel store settings
225 * Returns the width in pixels of a font's character
227 int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
230 * First of all, grab the font we need
232 SFG_Font* font = fghFontByID( fontID );
235 * Make sure the character we want to output is valid
237 freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
240 * Scan the font looking for the specified character
242 return( *(font->Characters[ character - 1 ]) );
246 * Return the width of a string drawn using a bitmap font
248 int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
250 int c, length = 0, this_line_length = 0;
253 * First of all, grab the font we need
255 SFG_Font* font = fghFontByID( fontID );
258 * Step through the characters in the string, adding up the width of each one
260 int numchar = strlen ( string ) ;
261 for( c = 0; c < numchar; c++ )
263 if ( string[ c ] == '\n' ) /* Carriage return, reset the length of this line */
265 if ( length < this_line_length ) length = this_line_length ;
266 this_line_length = 0 ;
268 else /* Not a carriage return, increment the length of this line */
269 this_line_length += *(font->Characters[ string[ c ] - 1 ]) ;
272 if ( length < this_line_length ) length = this_line_length ;
275 * Return the result now
281 * Returns the height of a bitmap font
283 int FGAPIENTRY glutBitmapHeight( void* fontID )
286 * See which font are we queried about
288 SFG_Font* font = fghFontByID( fontID );
291 * Return the character set's height
293 return( font->Height );
297 * Draw a stroke character
299 void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
301 const SFG_StrokeChar *schar;
302 const SFG_StrokeStrip *strip;
306 * First of all we'll need a font to use
308 SFG_StrokeFont* font = fghStrokeByID( fontID );
311 * Make sure the character we want to output is valid
313 freeglut_return_if_fail( character >= 0 && character < font->Quantity );
315 schar = font->Characters[character];
317 freeglut_return_if_fail( schar );
319 strip = schar->Strips;
321 for (i = 0; i < schar->Number; i++, strip++)
323 glBegin(GL_LINE_STRIP);
324 for(j = 0; j < strip->Number; j++)
326 glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y);
330 glTranslatef(schar->Right, 0.0, 0.0);
333 void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
336 int numchar = strlen ( string ) ;
340 * First of all we'll need a font to use
342 SFG_StrokeFont* font = fghStrokeByID( fontID );
345 * Step through the string, drawing each character.
346 * A carriage return will simply translate the next character's insertion point back to the
347 * start of the line and down one line.
349 for( c = 0; c < numchar; c++ )
351 if ( string[ c ] < font->Quantity )
353 if ( string[c] == '\n' )
355 glTranslatef ( -length, -(float)(font->Height), 0.0 ) ;
358 else /* Not a carriage return, draw the bitmap character */
360 const SFG_StrokeChar *schar = font->Characters[string[c]];
363 const SFG_StrokeStrip *strip = schar->Strips;
365 for (i = 0; i < schar->Number; i++, strip++)
367 glBegin(GL_LINE_STRIP);
368 for(j = 0; j < strip->Number; j++)
369 glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y);
374 length += schar->Right ;
375 glTranslatef(schar->Right, 0.0, 0.0);
383 * Return the width in pixels of a stroke character
385 int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
387 const SFG_StrokeChar *schar;
389 * First of all we'll need a font to use
391 SFG_StrokeFont* font = fghStrokeByID( fontID );
394 * Make sure the character we want to output is valid
396 freeglut_return_val_if_fail( character >= 0 && character < font->Quantity, 0 );
398 schar = font->Characters[character];
400 freeglut_return_val_if_fail( schar, 0 );
402 return ((int)(schar->Right + 0.5));
406 * Return the width of a string drawn using a stroke font
408 int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
412 float this_line_length = 0.0 ;
415 * First of all we'll need a font to use
417 SFG_StrokeFont* font = fghStrokeByID( fontID );
420 * Step through the characters in the string, adding up the width of each one
422 int numchar = strlen ( string ) ;
423 for( c = 0; c < numchar; c++ )
425 if ( string[ c ] < font->Quantity )
427 if ( string[ c ] == '\n' ) /* Carriage return, reset the length of this line */
429 if ( length < this_line_length ) length = this_line_length ;
430 this_line_length = 0.0 ;
432 else /* Not a carriage return, increment the length of this line */
434 const SFG_StrokeChar *schar = font->Characters[string[c]];
436 this_line_length += schar->Right ;
441 if ( length < this_line_length ) length = this_line_length ;
444 * Return the result now
446 return( (int)(length+0.5) );
450 * Returns the height of a stroke font
452 GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
455 * See which font are we queried about
457 SFG_StrokeFont* font = fghStrokeByID( fontID );
460 * Return the character set's height
462 return( font->Height );
465 /*** END OF FILE ***/