From 05a61612c9b96b61ca9917def47eb59b7bd195c8 Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Thu, 4 Apr 2013 10:13:04 +0000 Subject: [PATCH] can now set the font used for a menu set default font using glutSetOption(GLUT_MENU_FONT,...) and set font of current menu using glutSetMenuFont() git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1582 7f0cb862-5218-0410-a997-914c9d46530a --- include/GL/freeglut_ext.h | 7 +++ progs/demos/CallbackMaker/CallbackMaker.c | 7 +++ src/fg_ext.c | 1 + src/fg_font.c | 66 +++++++++++++++++++++++------ src/fg_init.c | 1 + src/fg_internal.h | 2 + src/fg_menu.c | 64 +++++++++++++++++++--------- src/fg_state.c | 13 ++++++ src/fg_structure.c | 1 + src/freeglutdll.def.in | 1 + 10 files changed, 128 insertions(+), 35 deletions(-) diff --git a/include/GL/freeglut_ext.h b/include/GL/freeglut_ext.h index 1e0f444..3826e46 100644 --- a/include/GL/freeglut_ext.h +++ b/include/GL/freeglut_ext.h @@ -88,6 +88,8 @@ #define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205 +#define GLUT_MENU_FONT 0x0206 /* TOOD: now glutSetOption only */ + /* * New tokens for glutInitDisplayMode. * Only one GLUT_AUXn bit may be used at a time. @@ -136,6 +138,11 @@ FGAPI void FGAPIENTRY glutFullScreenToggle( void ); FGAPI void FGAPIENTRY glutLeaveFullScreen( void ); /* + * Menu functions + */ +FGAPI void FGAPIENTRY glutSetMenuFont( void* font ); + +/* * Window-specific callback functions, see freeglut_callbacks.c */ FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) ); diff --git a/progs/demos/CallbackMaker/CallbackMaker.c b/progs/demos/CallbackMaker/CallbackMaker.c index e280148..0cee827 100644 --- a/progs/demos/CallbackMaker/CallbackMaker.c +++ b/progs/demos/CallbackMaker/CallbackMaker.c @@ -640,6 +640,8 @@ main(int argc, char *argv[]) * what we demonstrate here. */ glutSetKeyRepeat(GLUT_KEY_REPEAT_ON); + /* global setting: default font for any menus created after this call (we call it again below to demo) */ + glutSetOption(GLUT_MENU_FONT,(int)GLUT_BITMAP_HELVETICA_12); /* Set other global callback (global as in not associated with any specific menu or window) */ glutIdleFunc ( Idle ); @@ -664,6 +666,9 @@ main(int argc, char *argv[]) glutAddMenuEntry( "Sub menu A3 (03)", 13 ); glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */ + /* change font for any menus created after this call */ + glutSetOption(GLUT_MENU_FONT,(int)GLUT_BITMAP_8_BY_13); + subMenuB = glutCreateMenu( MenuCallback ); glutAddMenuEntry( "Sub menu B1 (04)", 14 ); glutAddMenuEntry( "Sub menu B2 (05)", 15 ); @@ -682,6 +687,8 @@ main(int argc, char *argv[]) glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */ glutAttachMenu( GLUT_LEFT_BUTTON ); + /* You can also change the font of the current menu: */ + glutSetMenuFont(GLUT_BITMAP_TIMES_ROMAN_10); /* Position second window right next to the first */ diff --git a/src/fg_ext.c b/src/fg_ext.c index 5e61e36..8432232 100644 --- a/src/fg_ext.c +++ b/src/fg_ext.c @@ -172,6 +172,7 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName ) CHECK_NAME(glutMenuDestroyFunc); CHECK_NAME(glutFullScreenToggle); CHECK_NAME(glutLeaveFullScreen); + CHECK_NAME(glutSetMenuFont); CHECK_NAME(glutSetOption); CHECK_NAME(glutGetModeValues); CHECK_NAME(glutSetWindowData); diff --git a/src/fg_font.c b/src/fg_font.c index 507397e..c0f0479 100644 --- a/src/fg_font.c +++ b/src/fg_font.c @@ -56,7 +56,7 @@ extern SFG_StrokeFont fgStrokeMonoRoman; * Matches a font ID with a SFG_Font structure pointer. * This was changed to match the GLUT header style. */ -static SFG_Font* fghFontByID( void* font ) +SFG_Font* fghFontByID( void* font ) { if( font == GLUT_BITMAP_8_BY_13 ) return &fgFontFixed8x13; @@ -73,7 +73,6 @@ static SFG_Font* fghFontByID( void* font ) if( font == GLUT_BITMAP_TIMES_ROMAN_24 ) return &fgFontTimesRoman24; - fgWarning( "font 0x%08x not found", font ); return 0; } @@ -88,7 +87,6 @@ static SFG_StrokeFont* fghStrokeByID( void* font ) if( font == GLUT_STROKE_MONO_ROMAN ) return &fgStrokeMonoRoman; - fgWarning( "stroke font 0x%08x not found", font ); return 0; } @@ -104,8 +102,12 @@ void FGAPIENTRY glutBitmapCharacter( void* fontID, int character ) SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapCharacter" ); font = fghFontByID( fontID ); + if (!font) + { + fgWarning("glutBitmapCharacter: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); + return; + } freeglut_return_if_fail( ( character >= 1 )&&( character < 256 ) ); - freeglut_return_if_fail( font ); /* * Find the character we want to draw (???) @@ -135,7 +137,11 @@ void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string ) SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" ); font = fghFontByID( fontID ); - freeglut_return_if_fail( font ); + if (!font) + { + fgWarning("glutBitmapString: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); + return; + } if ( !string || ! *string ) return; @@ -182,9 +188,13 @@ int FGAPIENTRY glutBitmapWidth( void* fontID, int character ) { SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" ); - font = fghFontByID( fontID ); freeglut_return_val_if_fail( character > 0 && character < 256, 0 ); - freeglut_return_val_if_fail( font, 0 ); + font = fghFontByID( fontID ); + if (!font) + { + fgWarning("glutBitmapWidth: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); + return 0; + } return *( font->Characters[ character ] ); } @@ -198,7 +208,11 @@ int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string ) SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" ); font = fghFontByID( fontID ); - freeglut_return_val_if_fail( font, 0 ); + if (!font) + { + fgWarning("glutBitmapLength: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); + return 0; + } if ( !string || ! *string ) return 0; @@ -227,7 +241,11 @@ int FGAPIENTRY glutBitmapHeight( void* fontID ) SFG_Font* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" ); font = fghFontByID( fontID ); - freeglut_return_val_if_fail( font, 0 ); + if (!font) + { + fgWarning("glutBitmapHeight: bitmap font 0x%08x not found. Make sure you're not passing a stroke font.\n",fontID); + return 0; + } return font->Height; } @@ -242,9 +260,13 @@ void FGAPIENTRY glutStrokeCharacter( void* fontID, int character ) SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeCharacter" ); font = fghStrokeByID( fontID ); + if (!font) + { + fgWarning("glutStrokeCharacter: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); + return; + } 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 ); @@ -272,7 +294,11 @@ void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string ) SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeString" ); font = fghStrokeByID( fontID ); - freeglut_return_if_fail( font ); + if (!font) + { + fgWarning("glutStrokeString: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); + return; + } if ( !string || ! *string ) return; @@ -322,11 +348,15 @@ int FGAPIENTRY glutStrokeWidth( void* fontID, int character ) SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" ); font = fghStrokeByID( fontID ); + if (!font) + { + fgWarning("glutStrokeWidth: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); + return 0; + } 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 ); @@ -344,7 +374,11 @@ int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string ) SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" ); font = fghStrokeByID( fontID ); - freeglut_return_val_if_fail( font, 0 ); + if (!font) + { + fgWarning("glutStrokeLength: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); + return 0; + } if ( !string || ! *string ) return 0; @@ -377,7 +411,11 @@ GLfloat FGAPIENTRY glutStrokeHeight( void* fontID ) SFG_StrokeFont* font; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" ); font = fghStrokeByID( fontID ); - freeglut_return_val_if_fail( font, 0.0 ); + if (!font) + { + fgWarning("glutStrokeHeight: stroke font 0x%08x not found. Make sure you're not passing a bitmap font.\n",fontID); + return 0.f; + } return font->Height; } diff --git a/src/fg_init.c b/src/fg_init.c index 752439e..0b6e29d 100644 --- a/src/fg_init.c +++ b/src/fg_init.c @@ -73,6 +73,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */ 0, /* ActiveMenus */ NULL, /* MenuStateCallback */ NULL, /* MenuStatusCallback */ + FREEGLUT_MENU_FONT, { -1, -1, GL_TRUE }, /* GameModeSize */ -1, /* GameModeDepth */ -1, /* GameModeRefresh */ diff --git a/src/fg_internal.h b/src/fg_internal.h index 2d2ab0b..1b671c3 100644 --- a/src/fg_internal.h +++ b/src/fg_internal.h @@ -306,6 +306,7 @@ struct tagSFG_State int ActiveMenus; /* Num. of currently active menus */ FGCBMenuState MenuStateCallback; /* Menu callbacks are global */ FGCBMenuStatus MenuStatusCallback; + void* MenuFont; /* Font to be used for newly created menus */ SFG_XYUse GameModeSize; /* Game mode screen's dimensions */ int GameModeDepth; /* The pixel depth for game mode */ @@ -640,6 +641,7 @@ struct tagSFG_Menu FGCBMenu Callback; /* The menu callback */ FGCBDestroy Destroy; /* Destruction callback */ GLboolean IsActive; /* Is the menu selected? */ + void* Font; /* Font to be used for displaying this menu */ int Width; /* Menu box width in pixels */ int Height; /* Menu box height in pixels */ int X, Y; /* Menu box raster position */ diff --git a/src/fg_menu.c b/src/fg_menu.c index 0247a88..8af9697 100644 --- a/src/fg_menu.c +++ b/src/fg_menu.c @@ -43,8 +43,8 @@ * GLUT apparently uses host-system menus rather than building its own. * freeglut is building its own menus from scratch.) * - * FREEGLUT_MENU_HEIGHT gives the height of ONE menu box. This should be - * the distances between two adjacent menu entries. It should scale + * FREEGLUT_MENUENTRY_HEIGHT gives the height of ONE menu box. This should + * be the distances between two adjacent menu entries. It should scale * automatically with the font choice, so you needn't alter it---unless you * use a stroked font. * @@ -56,8 +56,8 @@ */ /* See platform-specific header files for menu font and color definitions */ -#define FREEGLUT_MENU_HEIGHT (glutBitmapHeight(FREEGLUT_MENU_FONT) + \ - FREEGLUT_MENU_BORDER) +#define FREEGLUT_MENUENTRY_HEIGHT(font) (glutBitmapHeight(font) + \ + FREEGLUT_MENU_BORDER) #define FREEGLUT_MENU_BORDER 2 @@ -77,6 +77,7 @@ static float menu_pen_hback [4] = FREEGLUT_MENU_PEN_HBACK_COLORS; extern GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ); extern void fghPlatformGetCursorPos(const SFG_Window *window, GLboolean client, SFG_XYUse *mouse_pos); +extern SFG_Font* fghFontByID( void* font ); /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ @@ -187,7 +188,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu ) ( y >= FREEGLUT_MENU_BORDER ) && ( y < menu->Height - FREEGLUT_MENU_BORDER ) ) { - int menuID = ( y - FREEGLUT_MENU_BORDER ) / FREEGLUT_MENU_HEIGHT; + int menuID = ( y - FREEGLUT_MENU_BORDER ) / FREEGLUT_MENUENTRY_HEIGHT(menu->Font); /* The mouse cursor is somewhere over our box, check it out. */ menuEntry = fghFindMenuEntry( menu, menuID + 1 ); @@ -235,7 +236,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu ) fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y); menuEntry->SubMenu->X = menu->X + menu->Width; menuEntry->SubMenu->Y = menu->Y + - menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT; + menuEntry->Ordinal * FREEGLUT_MENUENTRY_HEIGHT(menu->Font); if( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > max_x ) menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width; @@ -243,7 +244,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu ) if( menuEntry->SubMenu->Y + menuEntry->SubMenu->Height > max_y ) { menuEntry->SubMenu->Y -= ( menuEntry->SubMenu->Height - - FREEGLUT_MENU_HEIGHT - + FREEGLUT_MENUENTRY_HEIGHT(menu->Font) - 2 * FREEGLUT_MENU_BORDER ); if( menuEntry->SubMenu->Y < 0 ) menuEntry->SubMenu->Y = 0; @@ -348,13 +349,13 @@ static void fghDisplayMenuBox( SFG_Menu* menu ) glColor4fv( menu_pen_hback ); glBegin( GL_QUADS ); glVertex2i( border, - (menuID + 0)*FREEGLUT_MENU_HEIGHT + border ); + (menuID + 0)*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border ); glVertex2i( menu->Width - border, - (menuID + 0)*FREEGLUT_MENU_HEIGHT + border ); + (menuID + 0)*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border ); glVertex2i( menu->Width - border, - (menuID + 1)*FREEGLUT_MENU_HEIGHT + border ); + (menuID + 1)*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border ); glVertex2i( border, - (menuID + 1)*FREEGLUT_MENU_HEIGHT + border ); + (menuID + 1)*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border ); glEnd( ); } } @@ -375,25 +376,25 @@ static void fghDisplayMenuBox( SFG_Menu* menu ) /* Try to center the text - JCJ 31 July 2003*/ glRasterPos2i( 2 * border, - ( i + 1 )*FREEGLUT_MENU_HEIGHT - - ( int )( FREEGLUT_MENU_HEIGHT*0.3 - border ) + ( i + 1 )*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) - + ( int )( FREEGLUT_MENUENTRY_HEIGHT(menu->Font)*0.3 - border ) ); /* Have the label drawn, character after character: */ - glutBitmapString( FREEGLUT_MENU_FONT, + glutBitmapString( menu->Font, (unsigned char *)menuEntry->Text); /* If it's a submenu, draw a right arrow */ if( menuEntry->SubMenu ) { - int width = glutBitmapWidth( FREEGLUT_MENU_FONT, '_' ); + int width = glutBitmapWidth( menu->Font, '_' ); int x_base = menu->Width - 2 - width; - int y_base = i*FREEGLUT_MENU_HEIGHT + border; + int y_base = i*FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border; glBegin( GL_TRIANGLES ); glVertex2i( x_base, y_base + 2*border); glVertex2i( menu->Width - 2, y_base + - ( FREEGLUT_MENU_HEIGHT + border) / 2 ); - glVertex2i( x_base, y_base + FREEGLUT_MENU_HEIGHT - border ); + ( FREEGLUT_MENUENTRY_HEIGHT(menu->Font) + border) / 2 ); + glVertex2i( x_base, y_base + FREEGLUT_MENUENTRY_HEIGHT(menu->Font) - border ); glEnd( ); } @@ -771,7 +772,7 @@ void fghCalculateMenuBoxSize( void ) { /* Update the menu entry's width value */ menuEntry->Width = glutBitmapLength( - FREEGLUT_MENU_FONT, + fgStructure.CurrentMenu->Font, (unsigned char *)menuEntry->Text ); @@ -781,7 +782,7 @@ void fghCalculateMenuBoxSize( void ) */ if (menuEntry->SubMenu ) menuEntry->Width += glutBitmapLength( - FREEGLUT_MENU_FONT, + fgStructure.CurrentMenu->Font, (unsigned char *)"_" ); @@ -789,7 +790,7 @@ void fghCalculateMenuBoxSize( void ) if( menuEntry->Width > width ) width = menuEntry->Width; - height += FREEGLUT_MENU_HEIGHT; + height += FREEGLUT_MENUENTRY_HEIGHT(fgStructure.CurrentMenu->Font); } /* Store the menu's box size now: */ @@ -908,6 +909,27 @@ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID ) } /* + * Changes the current menu's font + */ +void FGAPIENTRY glutSetMenuFont( void* fontID ) +{ + SFG_Font* font; + FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetMenuFont" ); + freeglut_return_if_fail( fgStructure.CurrentMenu ); + + if (fgGetActiveMenu()) + fgError("Menu manipulation not allowed while menus in use."); + + font = fghFontByID( fontID ); + if (!font) + fgWarning("glutChangeMenuFont: bitmap font 0x%08x not found. Make sure you're not passing a stroke font. Ignoring...\n",fontID); + freeglut_return_if_fail( font ); + + fgStructure.CurrentMenu->Font = fontID; + fghCalculateMenuBoxSize( ); +} + +/* * Changes the specified menu item in the current menu into a menu entry */ void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ) diff --git a/src/fg_state.c b/src/fg_state.c index 9ddfdd9..6a9387d 100644 --- a/src/fg_state.c +++ b/src/fg_state.c @@ -44,6 +44,7 @@ extern int fgPlatformGlutGet ( GLenum eWhat ); extern int fgPlatformGlutDeviceGet ( GLenum eWhat ); extern int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size); +extern SFG_Font* fghFontByID( void* font ); /* -- LOCAL DEFINITIONS ---------------------------------------------------- */ @@ -120,6 +121,18 @@ void FGAPIENTRY glutSetOption( GLenum eWhat, int value ) fgStructure.CurrentWindow->State.VisualizeNormals = value; break; + case GLUT_MENU_FONT: + { + void* fontID = (void*)value; + SFG_Font* font; + font = fghFontByID( fontID ); + if (!font) + fgWarning("glutSetOption(GLUT_MENU_FONT,...): bitmap font 0x%08x not found. Make sure you're not passing a stroke font. Ignoring...\n",fontID); + else + fgState.MenuFont = fontID; + } + break; + default: fgWarning( "glutSetOption(): missing enum handle %d", eWhat ); break; diff --git a/src/fg_structure.c b/src/fg_structure.c index 1d6c3a6..2a65b69 100644 --- a/src/fg_structure.c +++ b/src/fg_structure.c @@ -132,6 +132,7 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) menu->ID = ++fgStructure.MenuID; menu->Callback = menuCallback; menu->ActiveEntry = NULL; + menu->Font = fgState.MenuFont; fgListInit( &menu->Entries ); fgListAppend( &fgStructure.Menus, &menu->Node ); diff --git a/src/freeglutdll.def.in b/src/freeglutdll.def.in index d0c50c3..bb2c75e 100644 --- a/src/freeglutdll.def.in +++ b/src/freeglutdll.def.in @@ -144,6 +144,7 @@ EXPORTS glutExit glutFullScreenToggle glutLeaveFullScreen + glutSetMenuFont glutGetModeValues glutInitContextFlags glutInitContextVersion -- 1.7.10.4