Adding a Frequently Asked Questions file
[freeglut] / src / freeglut_font.c
index 59c1c1f..b163f6e 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <GL/freeglut.h>
 #include "freeglut_internal.h"
 
@@ -77,8 +73,8 @@ static SFG_Font* fghFontByID( void* font )
     if( font == GLUT_BITMAP_TIMES_ROMAN_24 )
         return &fgFontTimesRoman24;
 
-    fgError( "font 0x%08x not found", font );
-    return 0; /*** NOT REACHED ***/
+    fgWarning( "font 0x%08x not found", font );
+    return 0;
 }
 
 /*
@@ -92,8 +88,8 @@ static SFG_StrokeFont* fghStrokeByID( void* font )
     if( font == GLUT_STROKE_MONO_ROMAN )
         return &fgStrokeMonoRoman;
 
-    fgError( "stroke font 0x%08x not found", font );
-    return 0; /*** NOT REACHED ***/
+    fgWarning( "stroke font 0x%08x not found", font );
+    return 0;
 }
 
 
@@ -105,14 +101,16 @@ static SFG_StrokeFont* fghStrokeByID( void* font )
 void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
 {
     const GLubyte* face;
-    SFG_Font* font = fghFontByID( fontID );
-
+    SFG_Font* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapCharacter" );
+    font = fghFontByID( fontID );
     freeglut_return_if_fail( ( character >= 1 )&&( character < 256 ) );
+    freeglut_return_if_fail( font );
 
     /*
      * Find the character we want to draw (???)
      */
-    face = font->Characters[ character - 1 ];
+    face = font->Characters[ character ];
 
     glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
     glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
@@ -132,12 +130,15 @@ void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
 
 void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
 {
-    int c;
-    int numchar = strlen( (char *) string );
-    SFG_Font* font = fghFontByID( fontID );
-    float raster_position[ 4 ];
+    unsigned char c;
+    float x = 0.0f ;
+    SFG_Font* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" );
+    font = fghFontByID( fontID );
+    freeglut_return_if_fail( font );
+    if ( !string || ! *string )
+        return;
 
-    glGetFloatv ( GL_CURRENT_RASTER_POSITION, raster_position );
     glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
     glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
     glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE );
@@ -151,15 +152,15 @@ void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
      * A newline will simply translate the next character's insertion
      * point back to the start of the line and down one line.
      */
-    for( c = 0; c < numchar; c++ )
-        if( string[c] == '\n' )
+    while( ( c = *string++) )
+        if( c == '\n' )
         {
-            raster_position[ 1 ] -= ( float )font->Height;
-            glRasterPos4fv( raster_position );
+            glBitmap ( 0, 0, 0, 0, -x, (float) -font->Height, NULL );
+            x = 0.0f;
         }
         else  /* Not an EOL, draw the bitmap character */
         {
-            const GLubyte* face = font->Characters[ string[ c ] - 1 ];
+            const GLubyte* face = font->Characters[ c ];
 
             glBitmap(
                 face[ 0 ], font->Height,     /* Bitmap's width and height    */
@@ -167,7 +168,10 @@ void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
                 ( float )( face[ 0 ] ), 0.0, /* The raster advance; inc. x,y */
                 ( face + 1 )                 /* The packed bitmap data...    */
             );
+
+            x += ( float )( face[ 0 ] );
         }
+
     glPopClientAttrib( );
 }
 
@@ -176,10 +180,12 @@ void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
  */
 int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
 {
-    SFG_Font* font = fghFontByID( fontID );
-
+    SFG_Font* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" );
+    font = fghFontByID( fontID );
     freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
-    return *( font->Characters[ character - 1 ] );
+    freeglut_return_val_if_fail( font, 0 );
+    return *( font->Characters[ character ] );
 }
 
 /*
@@ -187,14 +193,19 @@ int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
  */
 int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
 {
-    int c, length = 0, this_line_length = 0;
-    SFG_Font* font = fghFontByID( fontID );
-    int numchar = strlen( (char *) string );
-
-    for( c = 0; c < numchar; c++ )
+    unsigned char c;
+    int length = 0, this_line_length = 0;
+    SFG_Font* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" );
+    font = fghFontByID( fontID );
+    freeglut_return_val_if_fail( font, 0 );
+    if ( !string || ! *string )
+        return 0;
+
+    while( ( c = *string++) )
     {
-        if( string[ c ] != '\n' )/* Not an EOL, increment length of line */
-            this_line_length += *( font->Characters[ string[ c ] - 1 ]);
+        if( c != '\n' )/* Not an EOL, increment length of line */
+            this_line_length += *( font->Characters[ c ]);
         else  /* EOL; reset the length of this line */
         {
             if( length < this_line_length )
@@ -213,7 +224,10 @@ int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
  */
 int FGAPIENTRY glutBitmapHeight( void* fontID )
 {
-    SFG_Font* font = fghFontByID( fontID );
+    SFG_Font* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" );
+    font = fghFontByID( fontID );
+    freeglut_return_val_if_fail( font, 0 );
     return font->Height;
 }
 
@@ -225,10 +239,12 @@ void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
     const SFG_StrokeChar *schar;
     const SFG_StrokeStrip *strip;
     int i, j;
-    SFG_StrokeFont* font = fghStrokeByID( fontID );
-
+    SFG_StrokeFont* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeCharacter" );
+    font = fghStrokeByID( fontID );
     freeglut_return_if_fail( character >= 0 );
     freeglut_return_if_fail( character < font->Quantity );
+    freeglut_return_if_fail( font );
 
     schar = font->Characters[ character ];
     freeglut_return_if_fail( schar );
@@ -246,27 +262,32 @@ void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
 
 void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
 {
-    int c, i, j;
-    int numchar = strlen( (char *) string );
+    unsigned char c;
+    int i, j;
     float length = 0.0;
-    SFG_StrokeFont* font = fghStrokeByID( fontID );
+    SFG_StrokeFont* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeString" );
+    font = fghStrokeByID( fontID );
+    freeglut_return_if_fail( font );
+    if ( !string || ! *string )
+        return;
 
     /*
      * Step through the string, drawing each character.
      * A newline will simply translate the next character's insertion
      * point back to the start of the line and down one line.
      */
-    for( c = 0; c < numchar; c++ )
-        if( string[ c ] < font->Quantity )
+    while( ( c = *string++) )
+        if( c < font->Quantity )
         {
-            if( string[ c ] == '\n' )
+            if( c == '\n' )
             {
                 glTranslatef ( -length, -( float )( font->Height ), 0.0 );
                 length = 0.0;
             }
             else  /* Not an EOL, draw the bitmap character */
             {
-                const SFG_StrokeChar *schar = font->Characters[ string[ c ] ];
+                const SFG_StrokeChar *schar = font->Characters[ c ];
                 if( schar )
                 {
                     const SFG_StrokeStrip *strip = schar->Strips;
@@ -294,12 +315,14 @@ void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
 int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
 {
     const SFG_StrokeChar *schar;
-    SFG_StrokeFont* font = fghStrokeByID( fontID );
-
+    SFG_StrokeFont* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" );
+    font = fghStrokeByID( fontID );
     freeglut_return_val_if_fail( ( character >= 0 ) &&
                                  ( character < font->Quantity ),
                                  0
     );
+    freeglut_return_val_if_fail( font, 0 );
     schar = font->Characters[ character ];
     freeglut_return_val_if_fail( schar, 0 );
 
@@ -311,16 +334,20 @@ int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
  */
 int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
 {
-    int c;
+    unsigned char c;
     float length = 0.0;
     float this_line_length = 0.0;
-    SFG_StrokeFont* font = fghStrokeByID( fontID );
-    int numchar = strlen( (char *) string );
-
-    for( c = 0; c < numchar; c++ )
-        if( string[ c ] < font->Quantity )
+    SFG_StrokeFont* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" );
+    font = fghStrokeByID( fontID );
+    freeglut_return_val_if_fail( font, 0 );
+    if ( !string || ! *string )
+        return 0;
+
+    while( ( c = *string++) )
+        if( c < font->Quantity )
         {
-            if( string[ c ] == '\n' ) /* EOL; reset the length of this line */
+            if( c == '\n' ) /* EOL; reset the length of this line */
             {
                 if( length < this_line_length )
                     length = this_line_length;
@@ -328,7 +355,7 @@ int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
             }
             else  /* Not an EOL, increment the length of this line */
             {
-                const SFG_StrokeChar *schar = font->Characters[ string[ c ] ];
+                const SFG_StrokeChar *schar = font->Characters[ c ];
                 if( schar )
                     this_line_length += schar->Right;
             }
@@ -343,7 +370,10 @@ int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
  */
 GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
 {
-    SFG_StrokeFont* font = fghStrokeByID( fontID );
+    SFG_StrokeFont* font;
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" );
+    font = fghStrokeByID( fontID );
+    freeglut_return_val_if_fail( font, 0.0 );
     return font->Height;
 }