freeglut_font.c
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:12k
源码类别:

游戏引擎

开发平台:

Visual 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. #include <GL/freeglut.h>
  28. #include "freeglut_internal.h"
  29. /*
  30.  * TODO BEFORE THE STABLE RELEASE:
  31.  *
  32.  *  Test things out ...
  33.  */
  34. /* -- IMPORT DECLARATIONS -------------------------------------------------- */
  35. /*
  36.  * These are the font faces defined in freeglut_font_data.c file:
  37.  */
  38. extern SFG_Font fgFontFixed8x13;
  39. extern SFG_Font fgFontFixed9x15;
  40. extern SFG_Font fgFontHelvetica10;
  41. extern SFG_Font fgFontHelvetica12;
  42. extern SFG_Font fgFontHelvetica18;
  43. extern SFG_Font fgFontTimesRoman10;
  44. extern SFG_Font fgFontTimesRoman24;
  45. extern SFG_StrokeFont fgStrokeRoman;
  46. extern SFG_StrokeFont fgStrokeMonoRoman;
  47. /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
  48. /*
  49.  * Matches a font ID with a SFG_Font structure pointer.
  50.  * This was changed to match the GLUT header style.
  51.  */
  52. static SFG_Font* fghFontByID( void* font )
  53. {
  54.     if( font == GLUT_BITMAP_8_BY_13        )
  55.         return &fgFontFixed8x13;
  56.     if( font == GLUT_BITMAP_9_BY_15        )
  57.         return &fgFontFixed9x15;
  58.     if( font == GLUT_BITMAP_HELVETICA_10   )
  59.         return &fgFontHelvetica10;
  60.     if( font == GLUT_BITMAP_HELVETICA_12   )
  61.         return &fgFontHelvetica12;
  62.     if( font == GLUT_BITMAP_HELVETICA_18   )
  63.         return &fgFontHelvetica18;
  64.     if( font == GLUT_BITMAP_TIMES_ROMAN_10 )
  65.         return &fgFontTimesRoman10;
  66.     if( font == GLUT_BITMAP_TIMES_ROMAN_24 )
  67.         return &fgFontTimesRoman24;
  68.     fgWarning( "font 0x%08x not found", font );
  69.     return 0;
  70. }
  71. /*
  72.  * Matches a font ID with a SFG_StrokeFont structure pointer.
  73.  * This was changed to match the GLUT header style.
  74.  */
  75. static SFG_StrokeFont* fghStrokeByID( void* font )
  76. {
  77.     if( font == GLUT_STROKE_ROMAN      )
  78.         return &fgStrokeRoman;
  79.     if( font == GLUT_STROKE_MONO_ROMAN )
  80.         return &fgStrokeMonoRoman;
  81.     fgWarning( "stroke font 0x%08x not found", font );
  82.     return 0;
  83. }
  84. /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
  85. /*
  86.  * Draw a bitmap character
  87.  */
  88. void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
  89. {
  90.     const GLubyte* face;
  91.     SFG_Font* font;
  92.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapCharacter" );
  93.     font = fghFontByID( fontID );
  94.     freeglut_return_if_fail( ( character >= 1 )&&( character < 256 ) );
  95.     freeglut_return_if_fail( font );
  96.     /*
  97.      * Find the character we want to draw (???)
  98.      */
  99.     face = font->Characters[ character ];
  100.     glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
  101.     glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
  102.     glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE );
  103.     glPixelStorei( GL_UNPACK_ROW_LENGTH,  0        );
  104.     glPixelStorei( GL_UNPACK_SKIP_ROWS,   0        );
  105.     glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0        );
  106.     glPixelStorei( GL_UNPACK_ALIGNMENT,   1        );
  107.     glBitmap(
  108.         face[ 0 ], font->Height,      /* The bitmap's width and height  */
  109.         font->xorig, font->yorig,     /* The origin in the font glyph   */
  110.         ( float )( face[ 0 ] ), 0.0,  /* The raster advance -- inc. x,y */
  111.         ( face + 1 )                  /* The packed bitmap data...      */
  112.     );
  113.     glPopClientAttrib( );
  114. }
  115. void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
  116. {
  117.     unsigned char c;
  118.     float x = 0.0f ;
  119.     SFG_Font* font;
  120.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" );
  121.     font = fghFontByID( fontID );
  122.     freeglut_return_if_fail( font );
  123.     if ( !string || ! *string )
  124.         return;
  125.     glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
  126.     glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
  127.     glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE );
  128.     glPixelStorei( GL_UNPACK_ROW_LENGTH,  0        );
  129.     glPixelStorei( GL_UNPACK_SKIP_ROWS,   0        );
  130.     glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0        );
  131.     glPixelStorei( GL_UNPACK_ALIGNMENT,   1        );
  132.     /*
  133.      * Step through the string, drawing each character.
  134.      * A newline will simply translate the next character's insertion
  135.      * point back to the start of the line and down one line.
  136.      */
  137.     while( ( c = *string++) )
  138.         if( c == 'n' )
  139.         {
  140.             glBitmap ( 0, 0, 0, 0, -x, (float) -font->Height, NULL );
  141.             x = 0.0f;
  142.         }
  143.         else  /* Not an EOL, draw the bitmap character */
  144.         {
  145.             const GLubyte* face = font->Characters[ c ];
  146.             glBitmap(
  147.                 face[ 0 ], font->Height,     /* Bitmap's width and height    */
  148.                 font->xorig, font->yorig,    /* The origin in the font glyph */
  149.                 ( float )( face[ 0 ] ), 0.0, /* The raster advance; inc. x,y */
  150.                 ( face + 1 )                 /* The packed bitmap data...    */
  151.             );
  152.             x += ( float )( face[ 0 ] );
  153.         }
  154.     glPopClientAttrib( );
  155. }
  156. /*
  157.  * Returns the width in pixels of a font's character
  158.  */
  159. int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
  160. {
  161.     SFG_Font* font;
  162.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" );
  163.     font = fghFontByID( fontID );
  164.     freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
  165.     freeglut_return_val_if_fail( font, 0 );
  166.     return *( font->Characters[ character ] );
  167. }
  168. /*
  169.  * Return the width of a string drawn using a bitmap font
  170.  */
  171. int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
  172. {
  173.     unsigned char c;
  174.     int length = 0, this_line_length = 0;
  175.     SFG_Font* font;
  176.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" );
  177.     font = fghFontByID( fontID );
  178.     freeglut_return_val_if_fail( font, 0 );
  179.     if ( !string || ! *string )
  180.         return 0;
  181.     while( ( c = *string++) )
  182.     {
  183.         if( c != 'n' )/* Not an EOL, increment length of line */
  184.             this_line_length += *( font->Characters[ c ]);
  185.         else  /* EOL; reset the length of this line */
  186.         {
  187.             if( length < this_line_length )
  188.                 length = this_line_length;
  189.             this_line_length = 0;
  190.         }
  191.     }
  192.     if ( length < this_line_length )
  193.         length = this_line_length;
  194.     return length;
  195. }
  196. /*
  197.  * Returns the height of a bitmap font
  198.  */
  199. int FGAPIENTRY glutBitmapHeight( void* fontID )
  200. {
  201.     SFG_Font* font;
  202.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" );
  203.     font = fghFontByID( fontID );
  204.     freeglut_return_val_if_fail( font, 0 );
  205.     return font->Height;
  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.     SFG_StrokeFont* font;
  216.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeCharacter" );
  217.     font = fghStrokeByID( fontID );
  218.     freeglut_return_if_fail( character >= 0 );
  219.     freeglut_return_if_fail( character < font->Quantity );
  220.     freeglut_return_if_fail( font );
  221.     schar = font->Characters[ character ];
  222.     freeglut_return_if_fail( schar );
  223.     strip = schar->Strips;
  224.     for( i = 0; i < schar->Number; i++, strip++ )
  225.     {
  226.         glBegin( GL_LINE_STRIP );
  227.         for( j = 0; j < strip->Number; j++ )
  228.             glVertex2f( strip->Vertices[ j ].X, strip->Vertices[ j ].Y );
  229.         glEnd( );
  230. glBegin( GL_POINTS );
  231.         for( j = 0; j < strip->Number; j++ )
  232.             glVertex2f( strip->Vertices[ j ].X, strip->Vertices[ j ].Y );
  233. glEnd( );
  234.     }
  235.     glTranslatef( schar->Right, 0.0, 0.0 );
  236. }
  237. void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
  238. {
  239.     unsigned char c;
  240.     int i, j;
  241.     float length = 0.0;
  242.     SFG_StrokeFont* font;
  243.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeString" );
  244.     font = fghStrokeByID( fontID );
  245.     freeglut_return_if_fail( font );
  246.     if ( !string || ! *string )
  247.         return;
  248.     /*
  249.      * Step through the string, drawing each character.
  250.      * A newline will simply translate the next character's insertion
  251.      * point back to the start of the line and down one line.
  252.      */
  253.     while( ( c = *string++) )
  254.         if( c < font->Quantity )
  255.         {
  256.             if( c == 'n' )
  257.             {
  258.                 glTranslatef ( -length, -( float )( font->Height ), 0.0 );
  259.                 length = 0.0;
  260.             }
  261.             else  /* Not an EOL, draw the bitmap character */
  262.             {
  263.                 const SFG_StrokeChar *schar = font->Characters[ c ];
  264.                 if( schar )
  265.                 {
  266.                     const SFG_StrokeStrip *strip = schar->Strips;
  267.                     for( i = 0; i < schar->Number; i++, strip++ )
  268.                     {
  269.                         glBegin( GL_LINE_STRIP );
  270.                         for( j = 0; j < strip->Number; j++ )
  271.                             glVertex2f( strip->Vertices[ j ].X,
  272.                                         strip->Vertices[ j ].Y);
  273.                         glEnd( );
  274.                     }
  275.                     length += schar->Right;
  276.                     glTranslatef( schar->Right, 0.0, 0.0 );
  277.                 }
  278.             }
  279.         }
  280. }
  281. /*
  282.  * Return the width in pixels of a stroke character
  283.  */
  284. int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
  285. {
  286.     const SFG_StrokeChar *schar;
  287.     SFG_StrokeFont* font;
  288.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" );
  289.     font = fghStrokeByID( fontID );
  290.     freeglut_return_val_if_fail( ( character >= 0 ) &&
  291.                                  ( character < font->Quantity ),
  292.                                  0
  293.     );
  294.     freeglut_return_val_if_fail( font, 0 );
  295.     schar = font->Characters[ character ];
  296.     freeglut_return_val_if_fail( schar, 0 );
  297.     return ( int )( schar->Right + 0.5 );
  298. }
  299. /*
  300.  * Return the width of a string drawn using a stroke font
  301.  */
  302. int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
  303. {
  304.     unsigned char c;
  305.     float length = 0.0;
  306.     float this_line_length = 0.0;
  307.     SFG_StrokeFont* font;
  308.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" );
  309.     font = fghStrokeByID( fontID );
  310.     freeglut_return_val_if_fail( font, 0 );
  311.     if ( !string || ! *string )
  312.         return 0;
  313.     while( ( c = *string++) )
  314.         if( c < font->Quantity )
  315.         {
  316.             if( c == 'n' ) /* EOL; reset the length of this line */
  317.             {
  318.                 if( length < this_line_length )
  319.                     length = this_line_length;
  320.                 this_line_length = 0.0;
  321.             }
  322.             else  /* Not an EOL, increment the length of this line */
  323.             {
  324.                 const SFG_StrokeChar *schar = font->Characters[ c ];
  325.                 if( schar )
  326.                     this_line_length += schar->Right;
  327.             }
  328.         }
  329.     if( length < this_line_length )
  330.         length = this_line_length;
  331.     return( int )( length + 0.5 );
  332. }
  333. /*
  334.  * Returns the height of a stroke font
  335.  */
  336. GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
  337. {
  338.     SFG_StrokeFont* font;
  339.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" );
  340.     font = fghStrokeByID( fontID );
  341.     freeglut_return_val_if_fail( font, 0.0 );
  342.     return font->Height;
  343. }
  344. /*** END OF FILE ***/