From 646676b8dbf8ab504ac8a275fe9a63a403a3190b Mon Sep 17 00:00:00 2001 From: Eric Sandall Date: Mon, 23 Jun 2003 23:40:12 +0000 Subject: [PATCH] Changed all references to the 'freeglut-1.3' directory to 'src', copied 'freeglut-1.3' to 'src' and added all files from 'src' to the repository (TODO #34). git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@98 7f0cb862-5218-0410-a997-914c9d46530a --- ChangeLog | 2 + Makefile.am | 2 +- TODO | 2 +- configure.in | 2 +- freeglut.dsp | 42 +- freeglut.kdevprj | 48 +- freeglut13.dsp | 36 +- freeglut13.plg | 8 +- freeglut_static.dsp | 42 +- freeglutdll.dsp | 42 +- src/Makefile.am | 42 + src/freeglut_callbacks.c | 333 +++++ src/freeglut_cursor.c | 189 +++ src/freeglut_display.c | 138 ++ src/freeglut_ext.c | 199 +++ src/freeglut_font.c | 480 +++++++ src/freeglut_font_data.c | 824 +++++++++++ src/freeglut_gamemode.c | 558 ++++++++ src/freeglut_geometry.c | 1049 ++++++++++++++ src/freeglut_init.c | 1120 +++++++++++++++ src/freeglut_internal.h | 705 ++++++++++ src/freeglut_joystick.c | 605 ++++++++ src/freeglut_main.c | 1797 ++++++++++++++++++++++++ src/freeglut_menu.c | 860 ++++++++++++ src/freeglut_misc.c | 244 ++++ src/freeglut_overlay.c | 51 + src/freeglut_state.c | 704 ++++++++++ src/freeglut_stroke_mono_roman.c | 2823 +++++++++++++++++++++++++++++++++++++ src/freeglut_stroke_roman.c | 2824 ++++++++++++++++++++++++++++++++++++++ src/freeglut_structure.c | 721 ++++++++++ src/freeglut_teapot.c | 247 ++++ src/freeglut_videoresize.c | 56 + src/freeglut_window.c | 1189 ++++++++++++++++ src/freeglutdll.def | 132 ++ src/templates/cpp_template | 17 + src/templates/header_template | 17 + tests/Makefile.am | 2 +- 37 files changed, 18039 insertions(+), 113 deletions(-) create mode 100644 src/Makefile.am create mode 100644 src/freeglut_callbacks.c create mode 100644 src/freeglut_cursor.c create mode 100644 src/freeglut_display.c create mode 100644 src/freeglut_ext.c create mode 100644 src/freeglut_font.c create mode 100644 src/freeglut_font_data.c create mode 100644 src/freeglut_gamemode.c create mode 100644 src/freeglut_geometry.c create mode 100644 src/freeglut_init.c create mode 100644 src/freeglut_internal.h create mode 100644 src/freeglut_joystick.c create mode 100644 src/freeglut_main.c create mode 100644 src/freeglut_menu.c create mode 100644 src/freeglut_misc.c create mode 100644 src/freeglut_overlay.c create mode 100644 src/freeglut_state.c create mode 100644 src/freeglut_stroke_mono_roman.c create mode 100644 src/freeglut_stroke_roman.c create mode 100644 src/freeglut_structure.c create mode 100644 src/freeglut_teapot.c create mode 100644 src/freeglut_videoresize.c create mode 100644 src/freeglut_window.c create mode 100644 src/freeglutdll.def create mode 100644 src/templates/cpp_template create mode 100644 src/templates/header_template diff --git a/ChangeLog b/ChangeLog index c548d79..a5c5995 100644 --- a/ChangeLog +++ b/ChangeLog @@ -166,3 +166,5 @@ October 24, 2002: (60) Added autogen.sh (#30 from todo.txt) (70) Updated aclocal.m4 with aclocal 1.7.3 (was created with aclocal 1.5) + +(71) Changed all references to the 'freeglut-1.3' directory to 'src', copied 'freeglut-1.3' to 'src' and added all files to the repository (TODO #34). diff --git a/Makefile.am b/Makefile.am index 2c25549..fdc20d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce makefile.im -SUBDIRS = freeglut-1.3 include genfonts tests +SUBDIRS = src include genfonts tests AUTOMAKE_OPTIONS = gnu EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL NEWS README TODO freeglut.lsm \ diff --git a/TODO b/TODO index 74c4dbd..e871a03 100644 --- a/TODO +++ b/TODO @@ -52,7 +52,7 @@ autoconf *Fixed*(33) Also from Eero Pajarre: A patch to prevent "freeglut" from adjusting for the window border thickness in game mode. -(34) Change the name of the source directory from "freeglut-1.3" to "src". +*Fixed*(34) Change the name of the source directory from "freeglut-1.3" to "src". diff --git a/configure.in b/configure.in index c53d2a7..ce5c570 100644 --- a/configure.in +++ b/configure.in @@ -27,4 +27,4 @@ dnl Checks for library functions. AC_CHECK_LIBM AC_SUBST(LIBM) -AC_OUTPUT(Makefile freeglut-1.3/Makefile include/Makefile include/GL/Makefile genfonts/Makefile tests/Makefile ) +AC_OUTPUT(Makefile src/Makefile include/Makefile include/GL/Makefile genfonts/Makefile tests/Makefile ) diff --git a/freeglut.dsp b/freeglut.dsp index a27eb3a..c0b5ec9 100644 --- a/freeglut.dsp +++ b/freeglut.dsp @@ -90,83 +90,83 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_callbacks.c" +SOURCE=".\src\freeglut_callbacks.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_cursor.c" +SOURCE=".\src\freeglut_cursor.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_display.c" +SOURCE=".\src\freeglut_display.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_font.c" +SOURCE=".\src\freeglut_font.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_font_data.c" +SOURCE=".\src\freeglut_font_data.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_gamemode.c" +SOURCE=".\src\freeglut_gamemode.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_geometry.c" +SOURCE=".\src\freeglut_geometry.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_init.c" +SOURCE=".\src\freeglut_init.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_joystick.c" +SOURCE=".\src\freeglut_joystick.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_main.c" +SOURCE=".\src\freeglut_main.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_menu.c" +SOURCE=".\src\freeglut_menu.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_misc.c" +SOURCE=".\src\freeglut_misc.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_overlay.c" +SOURCE=".\src\freeglut_overlay.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_state.c" +SOURCE=".\src\freeglut_state.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_stroke_mono_roman.c" +SOURCE=".\src\freeglut_stroke_mono_roman.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_stroke_roman.c" +SOURCE=".\src\freeglut_stroke_roman.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_structure.c" +SOURCE=".\src\freeglut_structure.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_teapot.c" +SOURCE=".\src\freeglut_teapot.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_videoresize.c" +SOURCE=".\src\freeglut_videoresize.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_window.c" +SOURCE=".\src\freeglut_window.c" # End Source File # End Group # Begin Group "Header Files" @@ -182,7 +182,7 @@ SOURCE=.\include\GL\freeglut_ext.h # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_internal.h" +SOURCE=".\src\freeglut_internal.h" # End Source File # Begin Source File diff --git a/freeglut.kdevprj b/freeglut.kdevprj index 88edf33..b4d4cf7 100644 --- a/freeglut.kdevprj +++ b/freeglut.kdevprj @@ -9,23 +9,23 @@ files=include/GL/freeglut.h,include/GL/freeglut_internal.h, sub_dirs= type=normal [Workspace_1] -openfiles=Nienazwany.h,Nienazwany.cpp,/home/olszta/freeglut/include/GL/freeglut_internal.h,/home/olszta/freeglut/freeglut-1.3/freeglut_callbacks.c,/home/olszta/freeglut/freeglut-1.3/freeglut_gamemode.c,/home/olszta/freeglut/freeglut-1.3/freeglut_init.c,/home/olszta/freeglut/freeglut-1.3/freeglut_main.c,/home/olszta/freeglut/freeglut-1.3/freeglut_window.c,/home/olszta/freeglut/freeglut-1.3/freeglut_misc.c,/home/olszta/freeglut/include/GL/freeglut.h,/home/olszta/freeglut/freeglut-1.3/freeglut_cursor.c,/home/olszta/freeglut/freeglut-1.3/freeglut_geometry.c,/home/olszta/freeglut/freeglut-1.3/freeglut_font_data.c,/home/olszta/freeglut/freeglut-1.3/freeglut_videoresize.c,/home/olszta/freeglut/freeglut-1.3/freeglut_teapot.c,/home/olszta/freeglut/freeglut-1.3/freeglut_structure.c,/home/olszta/freeglut/freeglut-1.3/freeglut_state.c, +openfiles=Nienazwany.h,Nienazwany.cpp,/home/olszta/freeglut/include/GL/freeglut_internal.h,/home/olszta/freeglut/src/freeglut_callbacks.c,/home/olszta/freeglut/src/freeglut_gamemode.c,/home/olszta/freeglut/src/freeglut_init.c,/home/olszta/freeglut/src/freeglut_main.c,/home/olszta/freeglut/src/freeglut_window.c,/home/olszta/freeglut/src/freeglut_misc.c,/home/olszta/freeglut/include/GL/freeglut.h,/home/olszta/freeglut/src/freeglut_cursor.c,/home/olszta/freeglut/src/freeglut_geometry.c,/home/olszta/freeglut/src/freeglut_font_data.c,/home/olszta/freeglut/src/freeglut_videoresize.c,/home/olszta/freeglut/src/freeglut_teapot.c,/home/olszta/freeglut/src/freeglut_structure.c,/home/olszta/freeglut/src/freeglut_state.c, show_outputview=true show_treeview=true header_file=/home/olszta/freeglut/include/GL/freeglut.h -cpp_file=/home/olszta/freeglut/freeglut-1.3/freeglut_state.c +cpp_file=/home/olszta/freeglut/src/freeglut_state.c browser_file=file:/usr/doc/kde/HTML/default/kdevelop/welcome/index.html [COPYING] install_location= dist=true install=false type=DATA -[freeglut-1.3/freeglut_videoresize.c] +[src/freeglut_videoresize.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/docs/Makefile.am] +[src/docs/Makefile.am] type=normal sub_dirs= [Config for BinMakefileAm] @@ -35,8 +35,8 @@ cxxflags=-O0 -g3 -Wall [po/Makefile.am] type=po sub_dirs= -[freeglut-1.3/Makefile.am] -files=freeglut-1.3/freeglut_callbacks.c,freeglut-1.3/freeglut_cursor.c,freeglut-1.3/freeglut_display.c,freeglut-1.3/freeglut_font.c,freeglut-1.3/freeglut_font_data.c,freeglut-1.3/freeglut_gamemode.c,freeglut-1.3/freeglut_geometry.c,freeglut-1.3/freeglut_init.c,freeglut-1.3/freeglut_joystick.c,freeglut-1.3/freeglut_main.c,freeglut-1.3/freeglut_menu.c,freeglut-1.3/freeglut_misc.c,freeglut-1.3/freeglut_overlay.c,freeglut-1.3/freeglut_state.c,freeglut-1.3/freeglut_structure.c,freeglut-1.3/freeglut_teapot.c,freeglut-1.3/freeglut_videoresize.c,freeglut-1.3/freeglut_window.c, +[src/Makefile.am] +files=src/freeglut_callbacks.c,src/freeglut_cursor.c,src/freeglut_display.c,src/freeglut_font.c,src/freeglut_font_data.c,src/freeglut_gamemode.c,src/freeglut_geometry.c,src/freeglut_init.c,src/freeglut_joystick.c,src/freeglut_main.c,src/freeglut_menu.c,src/freeglut_misc.c,src/freeglut_overlay.c,src/freeglut_state.c,src/freeglut_structure.c,src/freeglut_teapot.c,src/freeglut_videoresize.c,src/freeglut_window.c, type=prog_main sub_dirs= [freeglut.kdevprj] @@ -49,12 +49,12 @@ install_location= dist=true install=false type=DATA -[freeglut-1.3/freeglut_gamemode.c] +[src/freeglut_gamemode.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_menu.c] +[src/freeglut_menu.c] install_location= dist=true install=false @@ -65,30 +65,30 @@ Others=*, groups=Headers,Sources,GNU,Others, Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l, Headers=*.h,*.hxx,*.hpp,*.H, -[freeglut-1.3/docs/en/Makefile.am] +[src/docs/en/Makefile.am] type=normal sub_dirs= -[freeglut-1.3/freeglut_font.c] +[src/freeglut_font.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_window.c] +[src/freeglut_window.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_main.c] +[src/freeglut_main.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_state.c] +[src/freeglut_state.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_callbacks.c] +[src/freeglut_callbacks.c] install_location= dist=true install=false @@ -98,7 +98,7 @@ install_location= dist=true install=false type=HEADER -[freeglut-1.3/freeglut_structure.c] +[src/freeglut_structure.c] install_location= dist=true install=false @@ -108,17 +108,17 @@ install_location= dist=true install=false type=DATA -[freeglut-1.3/freeglut_geometry.c] +[src/freeglut_geometry.c] install_location= dist=true install=false type=SOURCE [General] -makefiles=Makefile.am,freeglut-1.3/Makefile.am,freeglut-1.3/docs/Makefile.am,freeglut-1.3/docs/en/Makefile.am,po/Makefile.am,include/Makefile.am, +makefiles=Makefile.am,src/Makefile.am,src/docs/Makefile.am,src/docs/en/Makefile.am,po/Makefile.am,include/Makefile.am, version_control=None project_type=normal_empty author=Pawel W. Olszta -sub_dir=freeglut-1.3/ +sub_dir=src/ lfv_open_groups=Headers,Sources, workspace=1 project_name=freeglut @@ -135,17 +135,17 @@ install_location= dist=true install=false type=DATA -[freeglut-1.3/freeglut_init.c] +[src/freeglut_init.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_display.c] +[src/freeglut_display.c] install_location= dist=true install=false type=SOURCE -[freeglut-1.3/freeglut_overlay.c] +[src/freeglut_overlay.c] install_location= dist=true install=false @@ -155,7 +155,7 @@ install_location= dist=true install=false type=DATA -[freeglut-1.3/freeglut_misc.c] +[src/freeglut_misc.c] install_location= dist=true install=false @@ -163,8 +163,8 @@ type=SOURCE [Makefile.am] files=freeglut.kdevprj,AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,freeglut.lsm, type=normal -sub_dirs=freeglut-1.3,include, -[freeglut-1.3/freeglut_cursor.c] +sub_dirs=src,include, +[src/freeglut_cursor.c] install_location= dist=true install=false diff --git a/freeglut13.dsp b/freeglut13.dsp index c585da1..2d0495e 100755 --- a/freeglut13.dsp +++ b/freeglut13.dsp @@ -91,75 +91,75 @@ LINK32=link.exe # PROP Default_Filter "*.c" # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_callbacks.c" +SOURCE=".\src\freeglut_callbacks.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_cursor.c" +SOURCE=".\src\freeglut_cursor.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_display.c" +SOURCE=".\src\freeglut_display.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_font.c" +SOURCE=".\src\freeglut_font.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_font_data.c" +SOURCE=".\src\freeglut_font_data.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_gamemode.c" +SOURCE=".\src\freeglut_gamemode.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_geometry.c" +SOURCE=".\src\freeglut_geometry.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_init.c" +SOURCE=".\src\freeglut_init.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_joystick.c" +SOURCE=".\src\freeglut_joystick.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_main.c" +SOURCE=".\src\freeglut_main.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_menu.c" +SOURCE=".\src\freeglut_menu.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_misc.c" +SOURCE=".\src\freeglut_misc.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_overlay.c" +SOURCE=".\src\freeglut_overlay.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_state.c" +SOURCE=".\src\freeglut_state.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_structure.c" +SOURCE=".\src\freeglut_structure.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_teapot.c" +SOURCE=".\src\freeglut_teapot.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_videoresize.c" +SOURCE=".\src\freeglut_videoresize.c" # End Source File # Begin Source File -SOURCE=".\freeglut-1.3\freeglut_window.c" +SOURCE=".\src\freeglut_window.c" # End Source File # End Group # Begin Group "Headers" diff --git a/freeglut13.plg b/freeglut13.plg index f8c5ceb..2c77efb 100755 --- a/freeglut13.plg +++ b/freeglut13.plg @@ -12,9 +12,9 @@ Project's tools are: "" with flags "" Creating temp file "C:\WINDOWS\TEMP\RSP170.TMP" with contents Creating command line "cl.exe @C:\WINDOWS\TEMP\RSP170.TMP" Creating temp file "C:\WINDOWS\TEMP\RSP0171.TMP" with contents + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-callbacks" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * All of the callbacks setting methods can be generalized to this: + */ +#define SET_CALLBACK(a) if( fgStructure.Window == NULL ) return;\ + fgStructure.Window->Callbacks.a = callback; + +/* + * Sets the Display callback for the current window + */ +void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ) +{ + SET_CALLBACK( Display ); +} + +/* + * Sets the Reshape callback for the current window + */ +void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( Reshape ); +} + +/* + * Sets the Keyboard callback for the current window + */ +void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ) +{ + SET_CALLBACK( Keyboard ); +} + +/* + * Sets the Special callback for the current window + */ +void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ) +{ + SET_CALLBACK( Special ); +} + +/* + * Sets the global idle callback + */ +void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ) +{ + freeglut_assert_ready; + + /* + * The global idle callback pointer is stored in fgState structure + */ + fgState.IdleCallback = callback; +} + +/* + * Sets the Timer callback for the current window + */ +void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ), int timerID ) +{ + SFG_Timer* timer; + + freeglut_assert_ready; + + /* + * Create a new freeglut timer hook structure + */ + timer = calloc( sizeof(SFG_Timer), 1 ); + + /* + * Remember the callback address and timer hook's ID + */ + timer->Callback = callback; + timer->ID = timerID; + + /* + * When will the time out happen (in terms of window's timer) + */ + timer->TriggerTime = fgElapsedTime() + timeOut; + + /* + * Have the new hook attached to the current window + */ + fgListAppend( &fgState.Timers, &timer->Node ); +} + +/* + * Sets the Visibility callback for the current window. + * + * I had to peer to GLUT sources to clean up the mess. + * Can anyone please explain me what is going on here?!? + */ +static void fghVisibility( int status ) +{ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Window != NULL ); + freeglut_return_if_fail( fgStructure.Window->Callbacks.Visibility != NULL ); + + if( status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED ) + fgStructure.Window->Callbacks.Visibility( GLUT_NOT_VISIBLE ); + else + fgStructure.Window->Callbacks.Visibility( GLUT_VISIBLE ); +} + +void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ) +{ + SET_CALLBACK( Visibility ); + + if( callback ) + glutWindowStatusFunc( fghVisibility ); + else + glutWindowStatusFunc( NULL ); +} + +/* + * Sets the keyboard key release callback for the current window + */ +void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ) +{ + SET_CALLBACK( KeyboardUp ); +} + +/* + * Sets the special key release callback for the current window + */ +void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ) +{ + SET_CALLBACK( SpecialUp ); +} + +/* + * Sets the joystick callback and polling rate for the current window + */ +void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ) +{ + SET_CALLBACK( Joystick ); + + freeglut_return_if_fail( fgStructure.Window != NULL ); + + /* + * Do not forget setting the joystick poll rate + */ + fgStructure.Window->State.JoystickPollRate = pollInterval; + + /* + * Make sure the joystick polling routine gets called as early as possible: + */ + fgStructure.Window->State.JoystickLastPoll = + fgElapsedTime() - fgStructure.Window->State.JoystickPollRate; + + if( fgStructure.Window->State.JoystickLastPoll < 0 ) + fgStructure.Window->State.JoystickLastPoll = 0; +} + +/* + * Sets the mouse callback for the current window + */ +void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ) +{ + SET_CALLBACK( Mouse ); +} + +/* + * Sets the mouse motion callback for the current window (one or more buttons are pressed) + */ +void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( Motion ); +} + +/* + * Sets the passive mouse motion callback for the current window (no mouse buttons are pressed) + */ +void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( Passive ); +} + +/* + * Window mouse entry/leave callback + */ +void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ) +{ + SET_CALLBACK( Entry ); +} + +/* + * Window destruction callbacks + */ +void FGAPIENTRY glutCloseFunc( void (* callback)( void ) ) +{ + SET_CALLBACK( Destroy ); +} + +void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) ) +{ + glutCloseFunc( callback ); +} + +/* A. Donev: Destruction callback for menus */ +void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ) +{ + if( fgStructure.Menu == NULL ) return; + fgStructure.Menu->Destroy = callback; +} + +/* + * Deprecated version of glutMenuStatusFunc callback setting method + */ +void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ) +{ + freeglut_assert_ready; + + fgState.MenuStateCallback = callback; +} + +/* + * Sets the global menu status callback for the current window + */ +void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ) +{ + freeglut_assert_ready; + + fgState.MenuStatusCallback = callback; +} + +/* + * Sets the overlay display callback for the current window + */ +void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ) +{ + SET_CALLBACK( OverlayDisplay ); +} + +/* + * Sets the window status callback for the current window + */ +void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ) +{ + SET_CALLBACK( WindowStatus ); +} + +/* + * Sets the spaceball motion callback for the current window + */ +void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ) +{ + SET_CALLBACK( SpaceMotion ); +} + +/* + * Sets the spaceball rotate callback for the current window + */ +void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ) +{ + SET_CALLBACK( SpaceRotation ); +} + +/* + * Sets the spaceball button callback for the current window + */ +void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( SpaceButton ); +} + +/* + * Sets the button box callback for the current window + */ +void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( ButtonBox ); +} + +/* + * Sets the dials box callback for the current window + */ +void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( Dials ); +} + +/* + * Sets the tablet motion callback for the current window + */ +void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ) +{ + SET_CALLBACK( TabletMotion ); +} + +/* + * Sets the tablet buttons callback for the current window + */ +void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ) +{ + SET_CALLBACK( TabletButton ); +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_cursor.c b/src/freeglut_cursor.c new file mode 100644 index 0000000..9d519c0 --- /dev/null +++ b/src/freeglut_cursor.c @@ -0,0 +1,189 @@ +/* + * freeglut_cursor.c + * + * The mouse cursor related stuff. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-cursor" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +#if TARGET_HOST_UNIX_X11 + #include +#endif + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * fgDisplayCursor() -- this waits for better times + * glutSetCursor() -- both X and Win32 mappings are incomplete + * + * It would be good to use custom mouse cursor shapes, and introduce + * an option to display them using glBitmap() and/or texture mapping, + * apart from the windowing system version. + */ + +/* -- INTERNAL FUNCTIONS --------------------------------------------------- */ + +/* + * Display the mouse cursor using OpenGL calls + */ +void fgDisplayCursor( void ) +{ + /* + * Do nothing for the moment + */ +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Set the cursor image to be used for the current window + */ +void FGAPIENTRY glutSetCursor( int cursorID ) +{ + /* + * Make sure freeglut is ready and there is a current window set + */ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + { + Cursor cursor; + + /* + * For now we'll limit ourselves to the X cursor fonts... + */ +# define MAP_CURSOR(a,b) case a: cursor = XCreateFontCursor( fgDisplay.Display, b ); break; + + switch( cursorID ) + { + MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, XC_left_ptr ); + MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, XC_right_ptr ); + MAP_CURSOR( GLUT_CURSOR_INFO, XC_question_arrow ); + MAP_CURSOR( GLUT_CURSOR_DESTROY, XC_target ); + MAP_CURSOR( GLUT_CURSOR_HELP, XC_question_arrow ); + MAP_CURSOR( GLUT_CURSOR_CYCLE, XC_circle ); + MAP_CURSOR( GLUT_CURSOR_SPRAY, XC_spraycan ); + MAP_CURSOR( GLUT_CURSOR_WAIT, XC_watch ); + MAP_CURSOR( GLUT_CURSOR_TEXT, XC_draft_large ); + MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, XC_crosshair ); + MAP_CURSOR( GLUT_CURSOR_NONE, XC_trek ); + + default: + MAP_CURSOR( GLUT_CURSOR_UP_DOWN, XC_arrow ); + } + + /* + * Define a window's cursor now + */ + XDefineCursor( fgDisplay.Display, fgStructure.Window->Window.Handle, cursor ); + } + +#elif TARGET_HOST_WIN32 + /* + * This is a temporary solution only... + */ + /* Set the cursor AND change it for this window class. */ +# define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \ + SetClassLong(fgStructure.Window->Window.Handle,GCL_HCURSOR,(LONG)LoadCursor(NULL,b)); \ + break; + /* Nuke the cursor AND change it for this window class. */ +# define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \ + SetClassLong(fgStructure.Window->Window.Handle,GCL_HCURSOR,(LONG)NULL); \ + break; + + switch( cursorID ) + { + MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL ); + MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT ); + MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_UPARROW ); + MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS ); + /* MAP_CURSOR( GLUT_CURSOR_NONE, IDC_NO ); */ + ZAP_CURSOR( GLUT_CURSOR_NONE, NULL ); + + default: + MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_ARROW ); + } + +#endif + + /* + * Remember the currently selected cursor + */ + fgStructure.Window->State.Cursor = cursorID; +} + +/* + * Moves the mouse pointer to given window coordinates + */ +void FGAPIENTRY glutWarpPointer( int x, int y ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Move the mouse pointer to given window coordinates + */ + XWarpPointer( + fgDisplay.Display, + None, + fgStructure.Window->Window.Handle, + 0, 0, 0, 0, + x, y + ); + + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + { + POINT coords = { x, y }; + + /* + * First of all, we need to find the new screen-relative coordinates of the mouse cursor + */ + ClientToScreen( fgStructure.Window->Window.Handle, &coords ); + + /* + * Now set the new mouse cursor position... + */ + SetCursorPos( coords.x, coords.y ); + } + +#endif +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_display.c b/src/freeglut_display.c new file mode 100644 index 0000000..de19841 --- /dev/null +++ b/src/freeglut_display.c @@ -0,0 +1,138 @@ +/* + * freeglut_display.c + * + * Display message posting, context buffer swapping. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-display" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Marks the current window to have the redisplay performed when possible... + */ +void FGAPIENTRY glutPostRedisplay( void ) +{ + /* + * Is there a current window set? + */ + freeglut_assert_ready; freeglut_assert_window; + + /* + * Just mark the window as one that we need to redisplay... + */ + fgStructure.Window->State.Redisplay = TRUE; +} + +/* + * Swaps the buffers for the current window (if any) + */ +void FGAPIENTRY glutSwapBuffers( void ) +{ + /* + * As long as we've got a current window set... + */ + freeglut_assert_ready; freeglut_assert_window; + + /* + * Have the mouse cursor and/or the menus drawn for the current window + */ + fgDisplayMenu(); + fgDisplayCursor(); + + /* + * Make sure the current context is flushed + */ + glFlush(); + + /* + * If it's single-buffered, we shouldn't be here. + */ + if ( ! fgStructure.Window->Window.DoubleBuffered ) return ; + +#if TARGET_HOST_UNIX_X11 + /* + * Issue the glXSwapBuffers call and be done with it + */ + glXSwapBuffers( fgDisplay.Display, fgStructure.Window->Window.Handle ); + +#elif TARGET_HOST_WIN32 + /* + * Swap the window's buffers + */ + SwapBuffers( fgStructure.Window->Window.Device ); + +#endif + + /* GLUT_FPS env var support */ + if (fgState.FPSInterval) { + GLint t = glutGet(GLUT_ELAPSED_TIME); + fgState.SwapCount++; + if (fgState.SwapTime == 0) + fgState.SwapTime = t; + else if (t - fgState.SwapTime > fgState.FPSInterval) { + float time = 0.001f * (t - fgState.SwapTime); + float fps = (float) fgState.SwapCount / time; + fprintf(stderr, "freeglut: %d frames in %.2f seconds = %.2f FPS\n", + fgState.SwapCount, time, fps); + fgState.SwapTime = t; + fgState.SwapCount = 0; + } + } +} + +/* + * Mark appropriate window to be displayed + */ +void FGAPIENTRY glutPostWindowRedisplay( int windowID ) +{ + SFG_Window* window; + + freeglut_assert_ready; + + /* + * Try looking for the window + */ + window = fgWindowByID( windowID ); + + /* + * If failed, return + */ + freeglut_return_if_fail( window != NULL ); + + /* + * Otherwise mark the window for being redisplayed + */ + window->State.Redisplay = TRUE; +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_ext.c b/src/freeglut_ext.c new file mode 100644 index 0000000..f6a5dad --- /dev/null +++ b/src/freeglut_ext.c @@ -0,0 +1,199 @@ +/* + * freeglut_ext.c + * + * Functions related to OpenGL extensions. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 9 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-ext" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + + +struct name_address_pair { + const char *name; + void *address; +}; + +static struct name_address_pair glut_functions[] = { + { "glutInit", (void *) glutInit }, + { "glutInitDisplayMode", (void *) glutInitDisplayMode }, + { "glutInitDisplayString", (void *) glutInitDisplayString }, + { "glutInitWindowPosition", (void *) glutInitWindowPosition }, + { "glutInitWindowSize", (void *) glutInitWindowSize }, + { "glutMainLoop", (void *) glutMainLoop }, + { "glutCreateWindow", (void *) glutCreateWindow }, + { "glutCreateSubWindow", (void *) glutCreateSubWindow }, + { "glutDestroyWindow", (void *) glutDestroyWindow }, + { "glutPostRedisplay", (void *) glutPostRedisplay }, + { "glutPostWindowRedisplay", (void *) glutPostWindowRedisplay }, + { "glutSwapBuffers", (void *) glutSwapBuffers }, + { "glutGetWindow", (void *) glutGetWindow }, + { "glutSetWindow", (void *) glutSetWindow }, + { "glutSetWindowTitle", (void *) glutSetWindowTitle }, + { "glutSetIconTitle", (void *) glutSetIconTitle }, + { "glutPositionWindow", (void *) glutPositionWindow }, + { "glutReshapeWindow", (void *) glutReshapeWindow }, + { "glutPopWindow", (void *) glutPopWindow }, + { "glutPushWindow", (void *) glutPushWindow }, + { "glutIconifyWindow", (void *) glutIconifyWindow }, + { "glutShowWindow", (void *) glutShowWindow }, + { "glutHideWindow", (void *) glutHideWindow }, + { "glutFullScreen", (void *) glutFullScreen }, + { "glutSetCursor", (void *) glutSetCursor }, + { "glutWarpPointer", (void *) glutWarpPointer }, + { "glutEstablishOverlay", (void *) glutEstablishOverlay }, + { "glutRemoveOverlay", (void *) glutRemoveOverlay }, + { "glutUseLayer", (void *) glutUseLayer }, + { "glutPostOverlayRedisplay", (void *) glutPostOverlayRedisplay }, + { "glutPostWindowOverlayRedisplay", (void *) glutPostWindowOverlayRedisplay }, + { "glutShowOverlay", (void *) glutShowOverlay }, + { "glutHideOverlay", (void *) glutHideOverlay }, + { "glutCreateMenu", (void *) glutCreateMenu }, + { "glutDestroyMenu", (void *) glutDestroyMenu }, + { "glutGetMenu", (void *) glutGetMenu }, + { "glutSetMenu", (void *) glutSetMenu }, + { "glutAddMenuEntry", (void *) glutAddMenuEntry }, + { "glutAddSubMenu", (void *) glutAddSubMenu }, + { "glutChangeToMenuEntry", (void *) glutChangeToMenuEntry }, + { "glutChangeToSubMenu", (void *) glutChangeToSubMenu }, + { "glutRemoveMenuItem", (void *) glutRemoveMenuItem }, + { "glutAttachMenu", (void *) glutAttachMenu }, + { "glutDetachMenu", (void *) glutDetachMenu }, + { "glutDisplayFunc", (void *) glutDisplayFunc }, + { "glutReshapeFunc", (void *) glutReshapeFunc }, + { "glutKeyboardFunc", (void *) glutKeyboardFunc }, + { "glutMouseFunc", (void *) glutMouseFunc }, + { "glutMotionFunc", (void *) glutMotionFunc }, + { "glutPassiveMotionFunc", (void *) glutPassiveMotionFunc }, + { "glutEntryFunc", (void *) glutEntryFunc }, + { "glutVisibilityFunc", (void *) glutVisibilityFunc }, + { "glutIdleFunc", (void *) glutIdleFunc }, + { "glutTimerFunc", (void *) glutTimerFunc }, + { "glutMenuStateFunc", (void *) glutMenuStateFunc }, + { "glutSpecialFunc", (void *) glutSpecialFunc }, + { "glutSpaceballMotionFunc", (void *) glutSpaceballMotionFunc }, + { "glutSpaceballRotateFunc", (void *) glutSpaceballRotateFunc }, + { "glutSpaceballButtonFunc", (void *) glutSpaceballButtonFunc }, + { "glutButtonBoxFunc", (void *) glutButtonBoxFunc }, + { "glutDialsFunc", (void *) glutDialsFunc }, + { "glutTabletMotionFunc", (void *) glutTabletMotionFunc }, + { "glutTabletButtonFunc", (void *) glutTabletButtonFunc }, + { "glutMenuStatusFunc", (void *) glutMenuStatusFunc }, + { "glutOverlayDisplayFunc", (void *) glutOverlayDisplayFunc }, + { "glutWindowStatusFunc", (void *) glutWindowStatusFunc }, + { "glutKeyboardUpFunc", (void *) glutKeyboardUpFunc }, + { "glutSpecialUpFunc", (void *) glutSpecialUpFunc }, + { "glutJoystickFunc", (void *) glutJoystickFunc }, + { "glutSetColor", (void *) glutSetColor }, + { "glutGetColor", (void *) glutGetColor }, + { "glutCopyColormap", (void *) glutCopyColormap }, + { "glutGet", (void *) glutGet }, + { "glutDeviceGet", (void *) glutDeviceGet }, + { "glutExtensionSupported", (void *) glutExtensionSupported }, + { "glutGetModifiers", (void *) glutGetModifiers }, + { "glutLayerGet", (void *) glutLayerGet }, + { "glutBitmapCharacter", (void *) glutBitmapCharacter }, + { "glutBitmapWidth", (void *) glutBitmapWidth }, + { "glutStrokeCharacter", (void *) glutStrokeCharacter }, + { "glutStrokeWidth", (void *) glutStrokeWidth }, + { "glutBitmapLength", (void *) glutBitmapLength }, + { "glutStrokeLength", (void *) glutStrokeLength }, + { "glutWireSphere", (void *) glutWireSphere }, + { "glutSolidSphere", (void *) glutSolidSphere }, + { "glutWireCone", (void *) glutWireCone }, + { "glutSolidCone", (void *) glutSolidCone }, + { "glutWireCube", (void *) glutWireCube }, + { "glutSolidCube", (void *) glutSolidCube }, + { "glutWireTorus", (void *) glutWireTorus }, + { "glutSolidTorus", (void *) glutSolidTorus }, + { "glutWireDodecahedron", (void *) glutWireDodecahedron }, + { "glutSolidDodecahedron", (void *) glutSolidDodecahedron }, + { "glutWireTeapot", (void *) glutWireTeapot }, + { "glutSolidTeapot", (void *) glutSolidTeapot }, + { "glutWireOctahedron", (void *) glutWireOctahedron }, + { "glutSolidOctahedron", (void *) glutSolidOctahedron }, + { "glutWireTetrahedron", (void *) glutWireTetrahedron }, + { "glutSolidTetrahedron", (void *) glutSolidTetrahedron }, + { "glutWireIcosahedron", (void *) glutWireIcosahedron }, + { "glutSolidIcosahedron", (void *) glutSolidIcosahedron }, + { "glutVideoResizeGet", (void *) glutVideoResizeGet }, + { "glutSetupVideoResizing", (void *) glutSetupVideoResizing }, + { "glutStopVideoResizing", (void *) glutStopVideoResizing }, + { "glutVideoResize", (void *) glutVideoResize }, + { "glutVideoPan", (void *) glutVideoPan }, + { "glutReportErrors", (void *) glutReportErrors }, + { "glutIgnoreKeyRepeat", (void *) glutIgnoreKeyRepeat }, + { "glutSetKeyRepeat", (void *) glutSetKeyRepeat }, + { "glutForceJoystickFunc", (void *) glutForceJoystickFunc }, + { "glutGameModeString", (void *) glutGameModeString }, + { "glutEnterGameMode", (void *) glutEnterGameMode }, + { "glutLeaveGameMode", (void *) glutLeaveGameMode }, + { "glutGameModeGet", (void *) glutGameModeGet }, + /* freeglut extensions */ + { "glutMainLoopEvent", (void *) glutMainLoopEvent }, + { "glutLeaveMainLoop", (void *) glutLeaveMainLoop }, + { "glutCloseFunc", (void *) glutCloseFunc }, + { "glutWMCloseFunc", (void *) glutWMCloseFunc }, + { "glutMenuDestroyFunc", (void *) glutMenuDestroyFunc }, + { "glutSetOption", (void *) glutSetOption }, + { "glutSetWindowData", (void *) glutSetWindowData }, + { "glutGetWindowData", (void *) glutGetWindowData }, + { "glutSetMenuData", (void *) glutSetMenuData }, + { "glutGetMenuData", (void *) glutGetMenuData }, + { "glutBitmapHeight", (void *) glutBitmapHeight }, + { "glutStrokeHeight", (void *) glutStrokeHeight }, + { "glutBitmapString", (void *) glutBitmapString }, + { "glutStrokeString", (void *) glutStrokeString }, + { "glutWireRhombicDodecahedron", (void *) glutWireRhombicDodecahedron }, + { "glutSolidRhombicDodecahedron", (void *) glutSolidRhombicDodecahedron }, + { "glutWireSierpinskiSponge ", (void *) glutWireSierpinskiSponge }, + { "glutSolidSierpinskiSponge ", (void *) glutSolidSierpinskiSponge }, + { "glutGetProcAddress", (void *) glutGetProcAddress }, + { NULL, NULL } +}; + + +void * FGAPIENTRY glutGetProcAddress(const char *procName) +{ + /* Try GLUT functions first */ + int i; + for (i = 0; glut_functions[i].name; i++) { + if (strcmp(glut_functions[i].name, procName) == 0) + return glut_functions[i].address; + } + + /* Try core GL functions */ +#if TARGET_HOST_WIN32 + return (void *) wglGetProcAddress((LPCSTR) procName); +#elif TARGET_HOST_UNIX_X11 && defined(GLX_ARB_get_proc_address) + return (void *) glXGetProcAddressARB((const GLubyte *) procName); +#else + return NULL; +#endif +} diff --git a/src/freeglut_font.c b/src/freeglut_font.c new file mode 100644 index 0000000..46e2219 --- /dev/null +++ b/src/freeglut_font.c @@ -0,0 +1,480 @@ +/* + * freeglut_font.c + * + * Bitmap and stroke fonts displaying. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-font" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * Test things out ... + */ + +/* -- IMPORT DECLARATIONS -------------------------------------------------- */ + +/* + * These are the font faces defined in freeglut_font_data.c file: + */ +extern SFG_Font fgFontFixed8x13; +extern SFG_Font fgFontFixed9x15; +extern SFG_Font fgFontHelvetica10; +extern SFG_Font fgFontHelvetica12; +extern SFG_Font fgFontHelvetica18; +extern SFG_Font fgFontTimesRoman10; +extern SFG_Font fgFontTimesRoman24; +extern SFG_StrokeFont fgStrokeRoman; +extern SFG_StrokeFont fgStrokeMonoRoman; + +/* + * This is for GLUT binary compatibility, as suggested by Steve Baker + */ +#if TARGET_HOST_UNIX_X11 + void* glutStrokeRoman; + void* glutStrokeMonoRoman; + void* glutBitmap9By15; + void* glutBitmap8By13; + void* glutBitmapTimesRoman10; + void* glutBitmapTimesRoman24; + void* glutBitmapHelvetica10; + void* glutBitmapHelvetica12; + void* glutBitmapHelvetica18; +#endif + + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * 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 ) +{ + /* + * Try matching the font ID and the font data structure + */ + if( font == GLUT_BITMAP_8_BY_13 ) return( &fgFontFixed8x13 ); + if( font == GLUT_BITMAP_9_BY_15 ) return( &fgFontFixed9x15 ); + if( font == GLUT_BITMAP_HELVETICA_10 ) return( &fgFontHelvetica10 ); + if( font == GLUT_BITMAP_HELVETICA_12 ) return( &fgFontHelvetica12 ); + if( font == GLUT_BITMAP_HELVETICA_18 ) return( &fgFontHelvetica18 ); + if( font == GLUT_BITMAP_TIMES_ROMAN_10 ) return( &fgFontTimesRoman10 ); + if( font == GLUT_BITMAP_TIMES_ROMAN_24 ) return( &fgFontTimesRoman24 ); + + /* + * This probably is the library user's fault + */ + fgError( "font 0x%08x not found", font ); + + return 0; +} + +/* + * Matches a font ID with a SFG_StrokeFont structure pointer. + * This was changed to match the GLUT header style. + */ +static SFG_StrokeFont* fghStrokeByID( void* font ) +{ + /* + * Try matching the font ID and the font data structure + */ + if( font == GLUT_STROKE_ROMAN ) return( &fgStrokeRoman ); + if( font == GLUT_STROKE_MONO_ROMAN ) return( &fgStrokeMonoRoman ); + + /* + * This probably is the library user's fault + */ + fgError( "stroke font 0x%08x not found", font ); + + return 0; +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Draw a bitmap character + */ +void FGAPIENTRY glutBitmapCharacter( void* fontID, int character ) +{ + const GLubyte* face; + + /* + * First of all we'll need a font to use + */ + SFG_Font* font = fghFontByID( fontID ); + + /* + * Make sure the character we want to output is valid + */ + freeglut_return_if_fail( character >= 0 && character < 256 ); + + /* + * Then find the character we want to draw + */ + face = font->Characters[ character - 1 ]; + + /* + * Save the old pixel store settings + */ + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); + + /* + * Set up the pixel unpacking ways + */ + glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE ); + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + /* + * We'll use a glBitmap call to draw the font. + */ + glBitmap( + face[ 0 ], font->Height, /* The bitmap's width and height */ + font->xorig, font->yorig, /* The origin -- what on earth? */ + (float)(face[ 0 ]), 0.0, /* The raster advance -- inc. x */ + (face + 1) /* The packed bitmap data... */ + ); + + /* + * Restore the old pixel store settings + */ + glPopClientAttrib(); +} + +void FGAPIENTRY glutBitmapString( void* fontID, const char *string ) +{ + int c; + int numchar = strlen ( string ) ; + + /* + * First of all we'll need a font to use + */ + SFG_Font* font = fghFontByID( fontID ); + + float raster_position[4] ; + glGetFloatv ( GL_CURRENT_RASTER_POSITION, raster_position ) ; + + /* + * Save the old pixel store settings + */ + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); + + /* + * Set up the pixel unpacking ways + */ + glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE ); + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + /* + * Step through the string, drawing each character. + * A carriage return 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' ) + { + raster_position[1] -= (float)font->Height ; + glRasterPos4fv ( raster_position ) ; + } + else /* Not a carriage return, draw the bitmap character */ + { + const GLubyte* face = font->Characters[ string[ c ] - 1 ] ; + + /* + * We'll use a glBitmap call to draw the font. + */ + glBitmap( + face[ 0 ], font->Height, /* The bitmap's width and height */ + font->xorig, font->yorig, /* The origin -- what on earth? */ + (float)(face[ 0 ]), 0.0, /* The raster advance -- inc. x */ + (face + 1) /* The packed bitmap data... */ + ) ; + } + } + + /* + * Restore the old pixel store settings + */ + glPopClientAttrib(); +} + +/* + * Returns the width in pixels of a font's character + */ +int FGAPIENTRY glutBitmapWidth( void* fontID, int character ) +{ + /* + * First of all, grab the font we need + */ + SFG_Font* font = fghFontByID( fontID ); + + /* + * Make sure the character we want to output is valid + */ + freeglut_return_val_if_fail( character > 0 && character < 256, 0 ); + + /* + * Scan the font looking for the specified character + */ + return( *(font->Characters[ character - 1 ]) ); +} + +/* + * Return the width of a string drawn using a bitmap font + */ +int FGAPIENTRY glutBitmapLength( void* fontID, const char* string ) +{ + int c, length = 0, this_line_length = 0; + + /* + * First of all, grab the font we need + */ + SFG_Font* font = fghFontByID( fontID ); + + /* + * Step through the characters in the string, adding up the width of each one + */ + int numchar = strlen ( string ) ; + for( c = 0; c < numchar; c++ ) + { + if ( string[ c ] == '\n' ) /* Carriage return, reset the length of this line */ + { + if ( length < this_line_length ) length = this_line_length ; + this_line_length = 0 ; + } + else /* Not a carriage return, increment the length of this line */ + this_line_length += *(font->Characters[ string[ c ] - 1 ]) ; + } + + if ( length < this_line_length ) length = this_line_length ; + + /* + * Return the result now + */ + return( length ); +} + +/* + * Returns the height of a bitmap font + */ +int FGAPIENTRY glutBitmapHeight( void* fontID ) +{ + /* + * See which font are we queried about + */ + SFG_Font* font = fghFontByID( fontID ); + + /* + * Return the character set's height + */ + return( font->Height ); +} + +/* + * Draw a stroke character + */ +void FGAPIENTRY glutStrokeCharacter( void* fontID, int character ) +{ + const SFG_StrokeChar *schar; + const SFG_StrokeStrip *strip; + int i, j; + + /* + * First of all we'll need a font to use + */ + SFG_StrokeFont* font = fghStrokeByID( fontID ); + + /* + * Make sure the character we want to output is valid + */ + freeglut_return_if_fail( character >= 0 && character < font->Quantity ); + + schar = font->Characters[character]; + + freeglut_return_if_fail( schar ); + + strip = schar->Strips; + + for (i = 0; i < schar->Number; i++, strip++) + { + glBegin(GL_LINE_STRIP); + for(j = 0; j < strip->Number; j++) + { + glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y); + } + glEnd(); + } + glTranslatef(schar->Right, 0.0, 0.0); +} + +void FGAPIENTRY glutStrokeString( void* fontID, const char *string ) +{ + int c, i, j; + int numchar = strlen ( string ) ; + float length = 0.0 ; + + /* + * First of all we'll need a font to use + */ + SFG_StrokeFont* font = fghStrokeByID( fontID ); + + /* + * Step through the string, drawing each character. + * A carriage return 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 ] >= 0 ) && ( string[ c ] < font->Quantity ) ) + { + if ( string[c] == '\n' ) + { + glTranslatef ( -length, -(float)(font->Height), 0.0 ) ; + length = 0.0 ; + } + else /* Not a carriage return, draw the bitmap character */ + { + const SFG_StrokeChar *schar = font->Characters[string[c]]; + if ( schar != NULL ) + { + const SFG_StrokeStrip *strip = schar->Strips; + + for (i = 0; i < schar->Number; i++, strip++) + { + glBegin(GL_LINE_STRIP); + for(j = 0; j < strip->Number; j++) + glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y); + + glEnd(); + } + + length += schar->Right ; + glTranslatef(schar->Right, 0.0, 0.0); + } + } + } + } +} + +/* + * Return the width in pixels of a stroke character + */ +int FGAPIENTRY glutStrokeWidth( void* fontID, int character ) +{ + const SFG_StrokeChar *schar; + /* + * First of all we'll need a font to use + */ + SFG_StrokeFont* font = fghStrokeByID( fontID ); + + /* + * Make sure the character we want to output is valid + */ + freeglut_return_val_if_fail( character >= 0 && character < font->Quantity, 0 ); + + schar = font->Characters[character]; + + freeglut_return_val_if_fail( schar, 0 ); + + return ((int)(schar->Right + 0.5)); +} + +/* + * Return the width of a string drawn using a stroke font + */ +int FGAPIENTRY glutStrokeLength( void* fontID, const char* string ) +{ + int c; + float length = 0.0; + float this_line_length = 0.0 ; + + /* + * First of all we'll need a font to use + */ + SFG_StrokeFont* font = fghStrokeByID( fontID ); + + /* + * Step through the characters in the string, adding up the width of each one + */ + int numchar = strlen ( string ) ; + for( c = 0; c < numchar; c++ ) + { + if ( ( string[ c ] >= 0 ) && ( string[ c ] < font->Quantity ) ) + { + if ( string[ c ] == '\n' ) /* Carriage return, reset the length of this line */ + { + if ( length < this_line_length ) length = this_line_length ; + this_line_length = 0.0 ; + } + else /* Not a carriage return, increment the length of this line */ + { + const SFG_StrokeChar *schar = font->Characters[string[c]]; + if ( schar != NULL ) + this_line_length += schar->Right ; + } + } + } + + if ( length < this_line_length ) length = this_line_length ; + + /* + * Return the result now + */ + return( (int)(length+0.5) ); +} + +/* + * Returns the height of a stroke font + */ +GLfloat FGAPIENTRY glutStrokeHeight( void* fontID ) +{ + /* + * See which font are we queried about + */ + SFG_StrokeFont* font = fghStrokeByID( fontID ); + + /* + * Return the character set's height + */ + return( font->Height ); +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_font_data.c b/src/freeglut_font_data.c new file mode 100644 index 0000000..c18a15e --- /dev/null +++ b/src/freeglut_font_data.c @@ -0,0 +1,824 @@ +/* + * freeglut_font_data.c + * + * This file has been automatically generated by the genfonts utility. + * + * Copyright (c) 1999-2000 by Pawel W. Olszta + * Written by Pawel W. Olszta, + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Sotware. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * Following fonts are defined in this file: + * + * 1. fgFontFixed8x13 <-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1> + * 2. fgFontFixed9x15 <-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1> + * 3. fgFontHelvetica10 <-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1> + * 4. fgFontHelvetica12 <-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1> + * 5. fgFontHelvetica18 <-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1> + * 6. fgFontTimesRoman10 <-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1> + * 7. fgFontTimesRoman24 <-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1> + */ + +static const GLubyte Fixed8x13_Character_032[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* blank */ +static const GLubyte Fixed8x13_Character_097[] = { 8, 0, 0,116,140,132,124, 4,120, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte Fixed8x13_Character_098[] = { 8, 0, 0,184,196,132,132,196,184,128,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_099[] = { 8, 0, 0,120,132,128,128,132,120, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_100[] = { 8, 0, 0,116,140,132,132,140,116, 4, 4, 4, 0, 0}; +static const GLubyte Fixed8x13_Character_101[] = { 8, 0, 0,120,132,128,252,132,120, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_102[] = { 8, 0, 0, 64, 64, 64, 64,248, 64, 64, 68, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_103[] = { 8,120,132,120,128,112,136,136,116, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_104[] = { 8, 0, 0,132,132,132,132,196,184,128,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_105[] = { 8, 0, 0,248, 32, 32, 32, 32, 96, 0, 32, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_106[] = { 8,112,136,136, 8, 8, 8, 8, 24, 0, 8, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_107[] = { 8, 0, 0,132,136,144,224,144,136,128,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_108[] = { 8, 0, 0,248, 32, 32, 32, 32, 32, 32, 32, 96, 0, 0}; +static const GLubyte Fixed8x13_Character_109[] = { 8, 0, 0,130,146,146,146,146,236, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_110[] = { 8, 0, 0,132,132,132,132,196,184, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_111[] = { 8, 0, 0,120,132,132,132,132,120, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_112[] = { 8,128,128,128,184,196,132,196,184, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_113[] = { 8, 4, 4, 4,116,140,132,140,116, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_114[] = { 8, 0, 0, 64, 64, 64, 64, 68,184, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_115[] = { 8, 0, 0,120,132, 24, 96,132,120, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_116[] = { 8, 0, 0, 56, 68, 64, 64, 64,248, 64, 64, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_117[] = { 8, 0, 0,116,136,136,136,136,136, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_119[] = { 8, 0, 0, 68,170,146,146,130,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_118[] = { 8, 0, 0, 32, 80, 80,136,136,136, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_120[] = { 8, 0, 0,132, 72, 48, 48, 72,132, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_121[] = { 8,120,132, 4,116,140,132,132,132, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_122[] = { 8, 0, 0,252, 64, 32, 16, 8,252, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte Fixed8x13_Character_065[] = { 8, 0, 0,132,132,132,252,132,132,132, 72, 48, 0, 0}; /* "A" */ +static const GLubyte Fixed8x13_Character_066[] = { 8, 0, 0,252, 66, 66, 66,124, 66, 66, 66,252, 0, 0}; +static const GLubyte Fixed8x13_Character_067[] = { 8, 0, 0,120,132,128,128,128,128,128,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_068[] = { 8, 0, 0,252, 66, 66, 66, 66, 66, 66, 66,252, 0, 0}; +static const GLubyte Fixed8x13_Character_069[] = { 8, 0, 0,252,128,128,128,240,128,128,128,252, 0, 0}; +static const GLubyte Fixed8x13_Character_070[] = { 8, 0, 0,128,128,128,128,240,128,128,128,252, 0, 0}; +static const GLubyte Fixed8x13_Character_071[] = { 8, 0, 0,116,140,132,156,128,128,128,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_072[] = { 8, 0, 0,132,132,132,132,252,132,132,132,132, 0, 0}; +static const GLubyte Fixed8x13_Character_073[] = { 8, 0, 0,248, 32, 32, 32, 32, 32, 32, 32,248, 0, 0}; +static const GLubyte Fixed8x13_Character_074[] = { 8, 0, 0,112,136, 8, 8, 8, 8, 8, 8, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_075[] = { 8, 0, 0,132,136,144,160,192,160,144,136,132, 0, 0}; +static const GLubyte Fixed8x13_Character_076[] = { 8, 0, 0,252,128,128,128,128,128,128,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_077[] = { 8, 0, 0,130,130,130,146,146,170,198,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_078[] = { 8, 0, 0,132,132,132,140,148,164,196,132,132, 0, 0}; +static const GLubyte Fixed8x13_Character_079[] = { 8, 0, 0,120,132,132,132,132,132,132,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_080[] = { 8, 0, 0,128,128,128,128,248,132,132,132,248, 0, 0}; +static const GLubyte Fixed8x13_Character_081[] = { 8, 0, 4,120,148,164,132,132,132,132,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_082[] = { 8, 0, 0,132,136,144,160,248,132,132,132,248, 0, 0}; +static const GLubyte Fixed8x13_Character_083[] = { 8, 0, 0,120,132, 4, 4,120,128,128,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_084[] = { 8, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0}; +static const GLubyte Fixed8x13_Character_085[] = { 8, 0, 0,120,132,132,132,132,132,132,132,132, 0, 0}; +static const GLubyte Fixed8x13_Character_087[] = { 8, 0, 0, 68,170,146,146,146,130,130,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_086[] = { 8, 0, 0, 16, 40, 40, 40, 68, 68, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_088[] = { 8, 0, 0,130,130, 68, 40, 16, 40, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_089[] = { 8, 0, 0, 16, 16, 16, 16, 16, 40, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_090[] = { 8, 0, 0,252,128,128, 64, 32, 16, 8, 4,252, 0, 0}; /* "Z" */ +static const GLubyte Fixed8x13_Character_048[] = { 8, 0, 0, 48, 72,132,132,132,132,132, 72, 48, 0, 0}; /* "0" */ +static const GLubyte Fixed8x13_Character_049[] = { 8, 0, 0,248, 32, 32, 32, 32, 32,160, 96, 32, 0, 0}; +static const GLubyte Fixed8x13_Character_050[] = { 8, 0, 0,252,128, 64, 48, 8, 4,132,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_051[] = { 8, 0, 0,120,132, 4, 4, 56, 16, 8, 4,252, 0, 0}; +static const GLubyte Fixed8x13_Character_052[] = { 8, 0, 0, 8, 8,252,136,136, 72, 40, 24, 8, 0, 0}; +static const GLubyte Fixed8x13_Character_053[] = { 8, 0, 0,120,132, 4, 4,196,184,128,128,252, 0, 0}; +static const GLubyte Fixed8x13_Character_054[] = { 8, 0, 0,120,132,132,196,184,128,128, 64, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_055[] = { 8, 0, 0, 64, 64, 32, 32, 16, 16, 8, 4,252, 0, 0}; +static const GLubyte Fixed8x13_Character_056[] = { 8, 0, 0,120,132,132,132,120,132,132,132,120, 0, 0}; +static const GLubyte Fixed8x13_Character_057[] = { 8, 0, 0,112, 8, 4, 4,116,140,132,132,120, 0, 0}; /* "9" */ +static const GLubyte Fixed8x13_Character_096[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 16, 96,224, 0, 0}; /* "`" */ +static const GLubyte Fixed8x13_Character_126[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,144,168, 72, 0, 0}; /* "~" */ +static const GLubyte Fixed8x13_Character_033[] = { 8, 0, 0,128, 0,128,128,128,128,128,128,128, 0, 0}; /* "!" */ +static const GLubyte Fixed8x13_Character_064[] = { 8, 0, 0,120,128,148,172,164,156,132,132,120, 0, 0}; /* "@" */ +static const GLubyte Fixed8x13_Character_035[] = { 8, 0, 0, 0, 72, 72,252, 72,252, 72, 72, 0, 0, 0}; /* "#" */ +static const GLubyte Fixed8x13_Character_036[] = { 8, 0, 0, 0, 32,240, 40,112,160,120, 32, 0, 0, 0}; /* "$" */ +static const GLubyte Fixed8x13_Character_037[] = { 8, 0, 0,136, 84, 72, 32, 16, 16, 72,164, 68, 0, 0}; /* "%" */ +static const GLubyte Fixed8x13_Character_094[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,136, 80, 32, 0, 0}; /* "^" */ +static const GLubyte Fixed8x13_Character_038[] = { 8, 0, 0,116,136,148, 96,144,144, 96, 0, 0, 0, 0}; /* "&" */ +static const GLubyte Fixed8x13_Character_042[] = { 8, 0, 0, 0, 0, 72, 48,252, 48, 72, 0, 0, 0, 0}; /* "*" */ +static const GLubyte Fixed8x13_Character_040[] = { 8, 0, 0, 32, 64, 64,128,128,128, 64, 64, 32, 0, 0}; /* "(" */ +static const GLubyte Fixed8x13_Character_041[] = { 8, 0, 0,128, 64, 64, 32, 32, 32, 64, 64,128, 0, 0}; /* ")" */ +static const GLubyte Fixed8x13_Character_045[] = { 8, 0, 0, 0, 0, 0, 0,252, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte Fixed8x13_Character_095[] = { 8, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte Fixed8x13_Character_061[] = { 8, 0, 0, 0, 0,252, 0, 0,252, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte Fixed8x13_Character_043[] = { 8, 0, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0}; /* "+" */ +static const GLubyte Fixed8x13_Character_091[] = { 8, 0, 0,240,128,128,128,128,128,128,128,240, 0, 0}; /* "[" */ +static const GLubyte Fixed8x13_Character_123[] = { 8, 0, 0, 56, 64, 64, 32,192, 32, 64, 64, 56, 0, 0}; /* "{" */ +static const GLubyte Fixed8x13_Character_125[] = { 8, 0, 0,224, 16, 16, 32, 24, 32, 16, 16,224, 0, 0}; /* "}" */ +static const GLubyte Fixed8x13_Character_093[] = { 8, 0, 0,240, 16, 16, 16, 16, 16, 16, 16,240, 0, 0}; /* "]" */ +static const GLubyte Fixed8x13_Character_059[] = { 8, 0,128, 96,112, 0, 0, 32,112, 32, 0, 0, 0, 0}; /* ";" */ +static const GLubyte Fixed8x13_Character_058[] = { 8, 0, 64,224, 64, 0, 0, 64,224, 64, 0, 0, 0, 0}; /* ":" */ +static const GLubyte Fixed8x13_Character_044[] = { 8, 0,128, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte Fixed8x13_Character_046[] = { 8, 0, 64,224, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte Fixed8x13_Character_060[] = { 8, 0, 0, 8, 16, 32, 64,128, 64, 32, 16, 8, 0, 0}; /* "<" */ +static const GLubyte Fixed8x13_Character_062[] = { 8, 0, 0,128, 64, 32, 16, 8, 16, 32, 64,128, 0, 0}; /* ">" */ +static const GLubyte Fixed8x13_Character_047[] = { 8, 0, 0,128,128, 64, 32, 16, 8, 4, 2, 2, 0, 0}; /* "/" */ +static const GLubyte Fixed8x13_Character_063[] = { 8, 0, 0, 16, 0, 16, 16, 8, 4,132,132,120, 0, 0}; /* "?" */ +static const GLubyte Fixed8x13_Character_092[] = { 8, 0, 0, 2, 2, 4, 8, 16, 32, 64,128,128, 0, 0}; /* "\" */ +static const GLubyte Fixed8x13_Character_034[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0,144,144,144, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte Fixed8x13_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 0, 0}; /* """ */ +static const GLubyte Fixed8x13_Character_124[] = { 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0}; /* """ */ + + +/* The font characters mapping: */ +static const GLubyte* Fixed8x13_Character_Map[] = {Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_032,Fixed8x13_Character_033,Fixed8x13_Character_034,Fixed8x13_Character_035,Fixed8x13_Character_036,Fixed8x13_Character_037,Fixed8x13_Character_038,Fixed8x13_Character_039,Fixed8x13_Character_040, + Fixed8x13_Character_041,Fixed8x13_Character_042,Fixed8x13_Character_043,Fixed8x13_Character_044,Fixed8x13_Character_045,Fixed8x13_Character_046,Fixed8x13_Character_047,Fixed8x13_Character_048,Fixed8x13_Character_049,Fixed8x13_Character_050,Fixed8x13_Character_051,Fixed8x13_Character_052,Fixed8x13_Character_053,Fixed8x13_Character_054,Fixed8x13_Character_055,Fixed8x13_Character_056,Fixed8x13_Character_057,Fixed8x13_Character_058,Fixed8x13_Character_059,Fixed8x13_Character_060,Fixed8x13_Character_061,Fixed8x13_Character_062,Fixed8x13_Character_063,Fixed8x13_Character_064,Fixed8x13_Character_065,Fixed8x13_Character_066,Fixed8x13_Character_067,Fixed8x13_Character_068,Fixed8x13_Character_069,Fixed8x13_Character_070,Fixed8x13_Character_071,Fixed8x13_Character_072,Fixed8x13_Character_073,Fixed8x13_Character_074,Fixed8x13_Character_075,Fixed8x13_Character_076,Fixed8x13_Character_077,Fixed8x13_Character_078,Fixed8x13_Character_079,Fixed8x13_Character_080,Fixed8x13_Character_081,Fixed8x13_Character_082, + Fixed8x13_Character_083,Fixed8x13_Character_084,Fixed8x13_Character_085,Fixed8x13_Character_086,Fixed8x13_Character_087,Fixed8x13_Character_088,Fixed8x13_Character_089,Fixed8x13_Character_090,Fixed8x13_Character_091,Fixed8x13_Character_092,Fixed8x13_Character_093,Fixed8x13_Character_094,Fixed8x13_Character_095,Fixed8x13_Character_096,Fixed8x13_Character_097,Fixed8x13_Character_098,Fixed8x13_Character_099,Fixed8x13_Character_100,Fixed8x13_Character_101,Fixed8x13_Character_102,Fixed8x13_Character_103,Fixed8x13_Character_104,Fixed8x13_Character_105,Fixed8x13_Character_106,Fixed8x13_Character_107,Fixed8x13_Character_108,Fixed8x13_Character_109,Fixed8x13_Character_110,Fixed8x13_Character_111,Fixed8x13_Character_112,Fixed8x13_Character_113,Fixed8x13_Character_114,Fixed8x13_Character_115,Fixed8x13_Character_116,Fixed8x13_Character_117,Fixed8x13_Character_118,Fixed8x13_Character_119,Fixed8x13_Character_120,Fixed8x13_Character_121,Fixed8x13_Character_122,Fixed8x13_Character_123,Fixed8x13_Character_124, + Fixed8x13_Character_125,Fixed8x13_Character_126,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, + Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, + Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042, + Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontFixed8x13 = { "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 93, 13, Fixed8x13_Character_Map, -1.0f, 2.0f }; + +static const GLubyte Fixed9x15_Character_032[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* blank */ +static const GLubyte Fixed9x15_Character_097[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,134, 0,130, 0,126, 0, 2, 0, 2, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte Fixed9x15_Character_098[] = { 9, 0, 0, 0, 0, 0, 0,188, 0,194, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_099[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_100[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,134, 0,130, 0,130, 0,130, 0,134, 0,122, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_101[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,128, 0,128, 0,254, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_102[] = { 9, 0, 0, 0, 0, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0,248, 0, 32, 0, 32, 0, 34, 0, 34, 0, 28, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_103[] = { 9,124, 0,130, 0,130, 0,124, 0,128, 0,120, 0,132, 0,132, 0,132, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_104[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_105[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,224, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_106[] = { 9,120, 0,132, 0,132, 0,132, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 28, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_107[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,140, 0,176, 0,192, 0,176, 0,140, 0,130, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_108[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,224, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_109[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,146, 0,146, 0,146, 0,146, 0,146, 0,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_110[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,194, 0,188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_111[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_112[] = { 9,128, 0,128, 0,128, 0,188, 0,194, 0,130, 0,130, 0,130, 0,194, 0,188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_113[] = { 9, 2, 0, 2, 0, 2, 0,122, 0,134, 0,130, 0,130, 0,130, 0,134, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_114[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 64, 0, 64, 0, 66, 0, 98, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_115[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0,124, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_116[] = { 9, 0, 0, 0, 0, 0, 0, 28, 0, 34, 0, 32, 0, 32, 0, 32, 0, 32, 0,252, 0, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_117[] = { 9, 0, 0, 0, 0, 0, 0,122, 0,132, 0,132, 0,132, 0,132, 0,132, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_119[] = { 9, 0, 0, 0, 0, 0, 0, 68, 0,170, 0,146, 0,146, 0,146, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_118[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 40, 0, 40, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_120[] = { 9, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 40, 0, 16, 0, 40, 0, 68, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_121[] = { 9,120, 0,132, 0, 4, 0,116, 0,140, 0,132, 0,132, 0,132, 0,132, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_122[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte Fixed9x15_Character_065[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0, 68, 0, 40, 0, 16, 0, 0, 0, 0, 0}; /* "A" */ +static const GLubyte Fixed9x15_Character_066[] = { 9, 0, 0, 0, 0, 0, 0,252, 0, 66, 0, 66, 0, 66, 0, 66, 0,124, 0, 66, 0, 66, 0, 66, 0,252, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_067[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_068[] = { 9, 0, 0, 0, 0, 0, 0,252, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0, 66, 0,252, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_069[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 64, 0, 64, 0, 64, 0, 64, 0,120, 0, 64, 0, 64, 0, 64, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_070[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0,120, 0, 64, 0, 64, 0, 64, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_071[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,142, 0,128, 0,128, 0,128, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_072[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_073[] = { 9, 0, 0, 0, 0, 0, 0,248, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0,248, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_074[] = { 9, 0, 0, 0, 0, 0, 0,120, 0,132, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 30, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_075[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,132, 0,136, 0,144, 0,160, 0,224, 0,144, 0,136, 0,132, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_076[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_077[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,146, 0,146, 0,170, 0,170, 0,198, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_078[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,134, 0,138, 0,146, 0,162, 0,194, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_079[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_080[] = { 9, 0, 0, 0, 0, 0, 0,128, 0,128, 0,128, 0,128, 0,128, 0,252, 0,130, 0,130, 0,130, 0,252, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_081[] = { 9, 0, 0, 6, 0, 8, 0,124, 0,146, 0,162, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_082[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,132, 0,136, 0,144, 0,252, 0,130, 0,130, 0,130, 0,252, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_083[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0, 2, 0, 12, 0,112, 0,128, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_084[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_085[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_087[] = { 9, 0, 0, 0, 0, 0, 0, 68, 0,170, 0,146, 0,146, 0,146, 0,146, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_086[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 40, 0, 40, 0, 40, 0, 68, 0, 68, 0, 68, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_088[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0, 68, 0, 40, 0, 16, 0, 16, 0, 40, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_089[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 40, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_090[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0}; /* "Z" */ +static const GLubyte Fixed9x15_Character_048[] = { 9, 0, 0, 0, 0, 0, 0, 56, 0, 68, 0,130, 0,130, 0,130, 0,130, 0,130, 0,130, 0, 68, 0, 56, 0, 0, 0, 0, 0}; /* "0" */ +static const GLubyte Fixed9x15_Character_049[] = { 9, 0, 0, 0, 0, 0, 0,254, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,144, 0, 80, 0, 48, 0, 16, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_050[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0, 64, 0, 48, 0, 8, 0, 4, 0, 2, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_051[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0, 2, 0, 2, 0, 28, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_052[] = { 9, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0,254, 0,132, 0, 68, 0, 36, 0, 20, 0, 12, 0, 4, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_053[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0, 2, 0, 2, 0, 2, 0,194, 0,188, 0,128, 0,128, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_054[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,130, 0,130, 0,130, 0,194, 0,188, 0,128, 0,128, 0, 64, 0, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_055[] = { 9, 0, 0, 0, 0, 0, 0, 64, 0, 64, 0, 32, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0, 2, 0,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_056[] = { 9, 0, 0, 0, 0, 0, 0, 56, 0, 68, 0,130, 0,130, 0, 68, 0, 56, 0, 68, 0,130, 0, 68, 0, 56, 0, 0, 0, 0, 0}; +static const GLubyte Fixed9x15_Character_057[] = { 9, 0, 0, 0, 0, 0, 0,120, 0, 4, 0, 2, 0, 2, 0,122, 0,134, 0,130, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "9" */ +static const GLubyte Fixed9x15_Character_096[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 64, 0,192, 0, 0, 0, 0, 0}; /* "`" */ +static const GLubyte Fixed9x15_Character_126[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 0,146, 0, 98, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte Fixed9x15_Character_033[] = { 9, 0, 0, 0, 0, 0, 0,128, 0,128, 0, 0, 0, 0, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 0, 0}; /* "!" */ +static const GLubyte Fixed9x15_Character_064[] = { 9, 0, 0, 0, 0, 0, 0,124, 0,128, 0,128, 0,154, 0,166, 0,162, 0,158, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte Fixed9x15_Character_035[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 72, 0,252, 0, 72, 0, 72, 0,252, 0, 72, 0, 72, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ +static const GLubyte Fixed9x15_Character_036[] = { 9, 0, 0, 0, 0, 16, 0,124, 0,146, 0, 18, 0, 18, 0, 20, 0, 56, 0, 80, 0,144, 0,146, 0,124, 0, 16, 0, 0, 0}; /* "$" */ +static const GLubyte Fixed9x15_Character_037[] = { 9, 0, 0, 0, 0, 0, 0,132, 0, 74, 0, 74, 0, 36, 0, 16, 0, 16, 0, 72, 0,164, 0,164, 0, 66, 0, 0, 0, 0, 0}; /* "%" */ +static const GLubyte Fixed9x15_Character_094[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 40, 0, 16, 0, 0, 0, 0, 0}; /* "^" */ +static const GLubyte Fixed9x15_Character_038[] = { 9, 0, 0, 0, 0, 0, 0, 98, 0,148, 0,136, 0,148, 0, 98, 0, 96, 0,144, 0,144, 0,144, 0, 96, 0, 0, 0, 0, 0}; /* "&" */ +static const GLubyte Fixed9x15_Character_042[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0,146, 0, 84, 0, 56, 0, 84, 0,146, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "*" */ +static const GLubyte Fixed9x15_Character_040[] = { 9, 0, 0, 0, 0, 32, 0, 64, 0, 64, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 64, 0, 64, 0, 32, 0, 0, 0}; /* "(" */ +static const GLubyte Fixed9x15_Character_041[] = { 9, 0, 0, 0, 0,128, 0, 64, 0, 64, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 64, 0, 64, 0,128, 0, 0, 0}; /* ")" */ +static const GLubyte Fixed9x15_Character_045[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte Fixed9x15_Character_095[] = { 9, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte Fixed9x15_Character_061[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte Fixed9x15_Character_043[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0,254, 0, 16, 0, 16, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte Fixed9x15_Character_091[] = { 9, 0, 0, 0, 0,240, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,128, 0,240, 0, 0, 0}; /* "[" */ +static const GLubyte Fixed9x15_Character_123[] = { 9, 0, 0, 0, 0, 56, 0, 64, 0, 64, 0, 64, 0, 32, 0,192, 0,192, 0, 32, 0, 64, 0, 64, 0, 64, 0, 56, 0, 0, 0}; /* "{" */ +static const GLubyte Fixed9x15_Character_125[] = { 9, 0, 0, 0, 0,224, 0, 16, 0, 16, 0, 16, 0, 32, 0, 24, 0, 24, 0, 32, 0, 16, 0, 16, 0, 16, 0,224, 0, 0, 0}; /* "}" */ +static const GLubyte Fixed9x15_Character_093[] = { 9, 0, 0, 0, 0,240, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0,240, 0, 0, 0}; /* "]" */ +static const GLubyte Fixed9x15_Character_059[] = { 9,128, 0, 64, 0, 64, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte Fixed9x15_Character_058[] = { 9, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte Fixed9x15_Character_044[] = { 9,128, 0, 64, 0, 64, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte Fixed9x15_Character_046[] = { 9, 0, 0, 0, 0, 0, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte Fixed9x15_Character_060[] = { 9, 0, 0, 0, 0, 0, 0, 8, 0, 16, 0, 32, 0, 64, 0,128, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte Fixed9x15_Character_062[] = { 9, 0, 0, 0, 0, 0, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 8, 0, 16, 0, 32, 0, 64, 0,128, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte Fixed9x15_Character_047[] = { 9, 0, 0, 0, 0, 0, 0,128, 0, 64, 0, 64, 0, 32, 0, 16, 0, 16, 0, 8, 0, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0}; /* "/" */ +static const GLubyte Fixed9x15_Character_063[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 16, 0, 8, 0, 4, 0, 2, 0,130, 0,130, 0,124, 0, 0, 0, 0, 0}; /* "?" */ +static const GLubyte Fixed9x15_Character_092[] = { 9, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 4, 0, 8, 0, 16, 0, 16, 0, 32, 0, 64, 0, 64, 0,128, 0, 0, 0, 0, 0}; /* "\" */ +static const GLubyte Fixed9x15_Character_034[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144, 0,144, 0,144, 0, 0, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte Fixed9x15_Character_039[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0, 0, 0, 0, 0}; /* "'" */ +static const GLubyte Fixed9x15_Character_124[] = { 9, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 0, 0, 0, 0}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* Fixed9x15_Character_Map[] = {Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_032,Fixed9x15_Character_033,Fixed9x15_Character_034,Fixed9x15_Character_035,Fixed9x15_Character_036,Fixed9x15_Character_037,Fixed9x15_Character_038,Fixed9x15_Character_039,Fixed9x15_Character_040, + Fixed9x15_Character_041,Fixed9x15_Character_042,Fixed9x15_Character_043,Fixed9x15_Character_044,Fixed9x15_Character_045,Fixed9x15_Character_046,Fixed9x15_Character_047,Fixed9x15_Character_048,Fixed9x15_Character_049,Fixed9x15_Character_050,Fixed9x15_Character_051,Fixed9x15_Character_052,Fixed9x15_Character_053,Fixed9x15_Character_054,Fixed9x15_Character_055,Fixed9x15_Character_056,Fixed9x15_Character_057,Fixed9x15_Character_058,Fixed9x15_Character_059,Fixed9x15_Character_060,Fixed9x15_Character_061,Fixed9x15_Character_062,Fixed9x15_Character_063,Fixed9x15_Character_064,Fixed9x15_Character_065,Fixed9x15_Character_066,Fixed9x15_Character_067,Fixed9x15_Character_068,Fixed9x15_Character_069,Fixed9x15_Character_070,Fixed9x15_Character_071,Fixed9x15_Character_072,Fixed9x15_Character_073,Fixed9x15_Character_074,Fixed9x15_Character_075,Fixed9x15_Character_076,Fixed9x15_Character_077,Fixed9x15_Character_078,Fixed9x15_Character_079,Fixed9x15_Character_080,Fixed9x15_Character_081,Fixed9x15_Character_082, + Fixed9x15_Character_083,Fixed9x15_Character_084,Fixed9x15_Character_085,Fixed9x15_Character_086,Fixed9x15_Character_087,Fixed9x15_Character_088,Fixed9x15_Character_089,Fixed9x15_Character_090,Fixed9x15_Character_091,Fixed9x15_Character_092,Fixed9x15_Character_093,Fixed9x15_Character_094,Fixed9x15_Character_095,Fixed9x15_Character_096,Fixed9x15_Character_097,Fixed9x15_Character_098,Fixed9x15_Character_099,Fixed9x15_Character_100,Fixed9x15_Character_101,Fixed9x15_Character_102,Fixed9x15_Character_103,Fixed9x15_Character_104,Fixed9x15_Character_105,Fixed9x15_Character_106,Fixed9x15_Character_107,Fixed9x15_Character_108,Fixed9x15_Character_109,Fixed9x15_Character_110,Fixed9x15_Character_111,Fixed9x15_Character_112,Fixed9x15_Character_113,Fixed9x15_Character_114,Fixed9x15_Character_115,Fixed9x15_Character_116,Fixed9x15_Character_117,Fixed9x15_Character_118,Fixed9x15_Character_119,Fixed9x15_Character_120,Fixed9x15_Character_121,Fixed9x15_Character_122,Fixed9x15_Character_123,Fixed9x15_Character_124, + Fixed9x15_Character_125,Fixed9x15_Character_126,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, + Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, + Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042, + Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontFixed9x15 = { "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1", 93, 15, Fixed9x15_Character_Map, -1.0f, 3.0f }; + +static const GLubyte Helvetica10_Character_032[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ +static const GLubyte Helvetica10_Character_097[] = { 5, 0, 0,104,144,144,112, 16,224, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte Helvetica10_Character_098[] = { 6, 0, 0,176,200,136,136,200,176,128,128, 0, 0, 0}; /* "b" */ +static const GLubyte Helvetica10_Character_099[] = { 5, 0, 0, 96,144,128,128,144, 96, 0, 0, 0, 0, 0}; /* "c" */ +static const GLubyte Helvetica10_Character_100[] = { 6, 0, 0,104,152,136,136,152,104, 8, 8, 0, 0, 0}; /* "d" */ +static const GLubyte Helvetica10_Character_101[] = { 5, 0, 0, 96,144,128,240,144, 96, 0, 0, 0, 0, 0}; /* "e" */ +static const GLubyte Helvetica10_Character_102[] = { 4, 0, 0, 64, 64, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ +static const GLubyte Helvetica10_Character_103[] = { 6,112, 8,104,152,136,136,152,104, 0, 0, 0, 0, 0}; /* "g" */ +static const GLubyte Helvetica10_Character_104[] = { 6, 0, 0,136,136,136,136,200,176,128,128, 0, 0, 0}; /* "h" */ +static const GLubyte Helvetica10_Character_105[] = { 2, 0, 0,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "i" */ +static const GLubyte Helvetica10_Character_106[] = { 2, 0,128,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "j" */ +static const GLubyte Helvetica10_Character_107[] = { 5, 0, 0,144,144,160,192,160,144,128,128, 0, 0, 0}; /* "k" */ +static const GLubyte Helvetica10_Character_108[] = { 2, 0, 0,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "l" */ +static const GLubyte Helvetica10_Character_109[] = { 8, 0, 0,146,146,146,146,146,236, 0, 0, 0, 0, 0}; /* "m" */ +static const GLubyte Helvetica10_Character_110[] = { 6, 0, 0,136,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "n" */ +static const GLubyte Helvetica10_Character_111[] = { 6, 0, 0,112,136,136,136,136,112, 0, 0, 0, 0, 0}; /* "o" */ +static const GLubyte Helvetica10_Character_112[] = { 6,128,128,176,200,136,136,200,176, 0, 0, 0, 0, 0}; /* "p" */ +static const GLubyte Helvetica10_Character_113[] = { 6, 8, 8,104,152,136,136,152,104, 0, 0, 0, 0, 0}; /* "q" */ +static const GLubyte Helvetica10_Character_114[] = { 4, 0, 0,128,128,128,128,192,160, 0, 0, 0, 0, 0}; /* "r" */ +static const GLubyte Helvetica10_Character_115[] = { 5, 0, 0, 96,144, 16, 96,144, 96, 0, 0, 0, 0, 0}; /* "s" */ +static const GLubyte Helvetica10_Character_116[] = { 4, 0, 0, 96, 64, 64, 64, 64,224, 64, 64, 0, 0, 0}; /* "t" */ +static const GLubyte Helvetica10_Character_117[] = { 5, 0, 0,112,144,144,144,144,144, 0, 0, 0, 0, 0}; /* "u" */ +static const GLubyte Helvetica10_Character_118[] = { 6, 0, 0, 32, 32, 80, 80,136,136, 0, 0, 0, 0, 0}; /* "v" */ +static const GLubyte Helvetica10_Character_119[] = { 8, 0, 0, 40, 40, 84, 84,146,146, 0, 0, 0, 0, 0}; /* "w" */ +static const GLubyte Helvetica10_Character_120[] = { 6, 0, 0,136,136, 80, 32, 80,136, 0, 0, 0, 0, 0}; /* "x" */ +static const GLubyte Helvetica10_Character_121[] = { 5,128, 64, 64, 96,160,160,144,144, 0, 0, 0, 0, 0}; /* "y" */ +static const GLubyte Helvetica10_Character_122[] = { 5, 0, 0,240,128, 64, 32, 16,240, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte Helvetica10_Character_065[] = { 7, 0, 0,130,130,124, 68, 40, 40, 16, 16, 0, 0, 0}; /* "A" */ +static const GLubyte Helvetica10_Character_066[] = { 7, 0, 0,240,136,136,136,240,136,136,240, 0, 0, 0}; /* "B" */ +static const GLubyte Helvetica10_Character_067[] = { 8, 0, 0,120,132,128,128,128,128,132,120, 0, 0, 0}; /* "C" */ +static const GLubyte Helvetica10_Character_068[] = { 8, 0, 0,240,136,132,132,132,132,136,240, 0, 0, 0}; /* "D" */ +static const GLubyte Helvetica10_Character_069[] = { 7, 0, 0,248,128,128,128,248,128,128,248, 0, 0, 0}; /* "E" */ +static const GLubyte Helvetica10_Character_070[] = { 6, 0, 0,128,128,128,128,240,128,128,248, 0, 0, 0}; /* "F" */ +static const GLubyte Helvetica10_Character_071[] = { 8, 0, 0,116,140,132,140,128,128,132,120, 0, 0, 0}; /* "G" */ +static const GLubyte Helvetica10_Character_072[] = { 8, 0, 0,132,132,132,132,252,132,132,132, 0, 0, 0}; /* "H" */ +static const GLubyte Helvetica10_Character_073[] = { 3, 0, 0,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "I" */ +static const GLubyte Helvetica10_Character_074[] = { 5, 0, 0, 96,144, 16, 16, 16, 16, 16, 16, 0, 0, 0}; /* "J" */ +static const GLubyte Helvetica10_Character_075[] = { 7, 0, 0,136,136,144,144,224,160,144,136, 0, 0, 0}; /* "K" */ +static const GLubyte Helvetica10_Character_076[] = { 6, 0, 0,240,128,128,128,128,128,128,128, 0, 0, 0}; /* "L" */ +static const GLubyte Helvetica10_Character_077[] = { 9, 0, 0, 0, 0,146, 0,146, 0,146, 0,170, 0,170, 0,198, 0,198, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ +static const GLubyte Helvetica10_Character_078[] = { 8, 0, 0,140,140,148,148,164,164,196,196, 0, 0, 0}; /* "N" */ +static const GLubyte Helvetica10_Character_079[] = { 8, 0, 0,120,132,132,132,132,132,132,120, 0, 0, 0}; /* "O" */ +static const GLubyte Helvetica10_Character_080[] = { 7, 0, 0,128,128,128,128,240,136,136,240, 0, 0, 0}; /* "P" */ +static const GLubyte Helvetica10_Character_081[] = { 8, 0, 2,124,140,148,132,132,132,132,120, 0, 0, 0}; /* "Q" */ +static const GLubyte Helvetica10_Character_082[] = { 7, 0, 0,136,136,136,136,240,136,136,240, 0, 0, 0}; /* "R" */ +static const GLubyte Helvetica10_Character_083[] = { 7, 0, 0,112,136,136, 8,112,128,136,112, 0, 0, 0}; /* "S" */ +static const GLubyte Helvetica10_Character_084[] = { 5, 0, 0, 32, 32, 32, 32, 32, 32, 32,248, 0, 0, 0}; /* "T" */ +static const GLubyte Helvetica10_Character_085[] = { 8, 0, 0,120,132,132,132,132,132,132,132, 0, 0, 0}; /* "U" */ +static const GLubyte Helvetica10_Character_086[] = { 7, 0, 0, 16, 40, 40, 68, 68, 68,130,130, 0, 0, 0}; /* "V" */ +static const GLubyte Helvetica10_Character_087[] = { 9, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 85, 0, 73, 0, 73, 0,136,128,136,128, 0, 0, 0, 0, 0, 0}; /* "W" */ +static const GLubyte Helvetica10_Character_088[] = { 7, 0, 0,136,136, 80, 80, 32, 80,136,136, 0, 0, 0}; /* "X" */ +static const GLubyte Helvetica10_Character_089[] = { 7, 0, 0, 16, 16, 16, 40, 40, 68, 68,130, 0, 0, 0}; /* "Y" */ +static const GLubyte Helvetica10_Character_090[] = { 7, 0, 0,248,128, 64, 32, 32, 16, 8,248, 0, 0, 0}; /* "Z" */ +static const GLubyte Helvetica10_Character_048[] = { 6, 0, 0,112,136,136,136,136,136,136,112, 0, 0, 0}; /* "0" */ +static const GLubyte Helvetica10_Character_049[] = { 6, 0, 0, 64, 64, 64, 64, 64, 64,192, 64, 0, 0, 0}; /* "1" */ +static const GLubyte Helvetica10_Character_050[] = { 6, 0, 0,248,128, 64, 48, 8, 8,136,112, 0, 0, 0}; /* "2" */ +static const GLubyte Helvetica10_Character_051[] = { 6, 0, 0,112,136, 8, 8, 48, 8,136,112, 0, 0, 0}; /* "3" */ +static const GLubyte Helvetica10_Character_052[] = { 6, 0, 0, 16, 16,248,144, 80, 80, 48, 16, 0, 0, 0}; /* "4" */ +static const GLubyte Helvetica10_Character_053[] = { 6, 0, 0,112,136, 8, 8,240,128,128,248, 0, 0, 0}; /* "5" */ +static const GLubyte Helvetica10_Character_054[] = { 6, 0, 0,112,136,136,200,176,128,136,112, 0, 0, 0}; /* "6" */ +static const GLubyte Helvetica10_Character_055[] = { 6, 0, 0, 64, 64, 32, 32, 16, 16, 8,248, 0, 0, 0}; /* "7" */ +static const GLubyte Helvetica10_Character_056[] = { 6, 0, 0,112,136,136,136,112,136,136,112, 0, 0, 0}; /* "8" */ +static const GLubyte Helvetica10_Character_057[] = { 6, 0, 0,112,136, 8,104,152,136,136,112, 0, 0, 0}; /* "9" */ +static const GLubyte Helvetica10_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0,128,128, 64, 0, 0, 0}; /* "`" */ +static const GLubyte Helvetica10_Character_126[] = { 7, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte Helvetica10_Character_033[] = { 3, 0, 0,128, 0,128,128,128,128,128,128, 0, 0, 0}; /* "!" */ +static const GLubyte Helvetica10_Character_064[] = { 11, 62, 0, 64, 0,155, 0,164,128,164,128,162, 64,146, 64, 77, 64, 32,128, 31, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte Helvetica10_Character_035[] = { 6, 0, 0, 80, 80,248, 40,124, 40, 40, 0, 0, 0, 0}; /* "#" */ +static const GLubyte Helvetica10_Character_036[] = { 6, 0, 32,112,168, 40,112,160,168,112, 32, 0, 0, 0}; /* "$" */ +static const GLubyte Helvetica10_Character_037[] = { 9, 0, 0, 0, 0, 38, 0, 41, 0, 22, 0, 16, 0, 8, 0,104, 0,148, 0,100, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ +static const GLubyte Helvetica10_Character_094[] = { 6, 0, 0, 0, 0, 0,136, 80, 80, 32, 32, 0, 0, 0}; /* "^" */ +static const GLubyte Helvetica10_Character_038[] = { 8, 0, 0,100,152,152,164, 96, 80, 80, 32, 0, 0, 0}; /* "&" */ +static const GLubyte Helvetica10_Character_042[] = { 4, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ +static const GLubyte Helvetica10_Character_040[] = { 4, 32, 64, 64,128,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ +static const GLubyte Helvetica10_Character_041[] = { 4,128, 64, 64, 32, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ +static const GLubyte Helvetica10_Character_045[] = { 7, 0, 0, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte Helvetica10_Character_095[] = { 6,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte Helvetica10_Character_061[] = { 5, 0, 0, 0, 0,240, 0,240, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte Helvetica10_Character_043[] = { 6, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte Helvetica10_Character_091[] = { 3,192,128,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ +static const GLubyte Helvetica10_Character_123[] = { 3, 32, 64, 64, 64, 64,128, 64, 64, 64, 32, 0, 0, 0}; /* "{" */ +static const GLubyte Helvetica10_Character_125[] = { 3,128, 64, 64, 64, 64, 32, 64, 64, 64,128, 0, 0, 0}; /* "}" */ +static const GLubyte Helvetica10_Character_093[] = { 3,192, 64, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ +static const GLubyte Helvetica10_Character_059[] = { 3,128, 64, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte Helvetica10_Character_058[] = { 3, 0, 0,128, 0, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte Helvetica10_Character_044[] = { 3,128, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte Helvetica10_Character_046[] = { 3, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte Helvetica10_Character_060[] = { 6, 0, 0, 0, 32, 64,128, 64, 32, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte Helvetica10_Character_062[] = { 6, 0, 0, 0,128, 64, 32, 64,128, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte Helvetica10_Character_047[] = { 3, 0, 0,128,128, 64, 64, 64, 64, 32, 32, 0, 0, 0}; /* "/" */ +static const GLubyte Helvetica10_Character_063[] = { 6, 0, 0, 64, 0, 64, 64, 32, 16,144, 96, 0, 0, 0}; /* "?" */ +static const GLubyte Helvetica10_Character_092[] = { 3, 0, 0, 32, 32, 64, 64, 64, 64,128,128, 0, 0, 0}; /* "\" */ +static const GLubyte Helvetica10_Character_034[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0,160,160, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte Helvetica10_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0,128, 64, 64, 0, 0, 0}; /* "'" */ +static const GLubyte Helvetica10_Character_124[] = { 3, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* Helvetica10_Character_Map[] = {Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_032,Helvetica10_Character_033,Helvetica10_Character_034,Helvetica10_Character_035,Helvetica10_Character_036,Helvetica10_Character_037, + Helvetica10_Character_038,Helvetica10_Character_039,Helvetica10_Character_040,Helvetica10_Character_041,Helvetica10_Character_042,Helvetica10_Character_043,Helvetica10_Character_044,Helvetica10_Character_045,Helvetica10_Character_046,Helvetica10_Character_047,Helvetica10_Character_048,Helvetica10_Character_049,Helvetica10_Character_050,Helvetica10_Character_051,Helvetica10_Character_052,Helvetica10_Character_053,Helvetica10_Character_054,Helvetica10_Character_055,Helvetica10_Character_056,Helvetica10_Character_057,Helvetica10_Character_058,Helvetica10_Character_059,Helvetica10_Character_060,Helvetica10_Character_061,Helvetica10_Character_062,Helvetica10_Character_063,Helvetica10_Character_064,Helvetica10_Character_065,Helvetica10_Character_066,Helvetica10_Character_067,Helvetica10_Character_068,Helvetica10_Character_069,Helvetica10_Character_070,Helvetica10_Character_071,Helvetica10_Character_072,Helvetica10_Character_073,Helvetica10_Character_074,Helvetica10_Character_075,Helvetica10_Character_076, + Helvetica10_Character_077,Helvetica10_Character_078,Helvetica10_Character_079,Helvetica10_Character_080,Helvetica10_Character_081,Helvetica10_Character_082,Helvetica10_Character_083,Helvetica10_Character_084,Helvetica10_Character_085,Helvetica10_Character_086,Helvetica10_Character_087,Helvetica10_Character_088,Helvetica10_Character_089,Helvetica10_Character_090,Helvetica10_Character_091,Helvetica10_Character_092,Helvetica10_Character_093,Helvetica10_Character_094,Helvetica10_Character_095,Helvetica10_Character_096,Helvetica10_Character_097,Helvetica10_Character_098,Helvetica10_Character_099,Helvetica10_Character_100,Helvetica10_Character_101,Helvetica10_Character_102,Helvetica10_Character_103,Helvetica10_Character_104,Helvetica10_Character_105,Helvetica10_Character_106,Helvetica10_Character_107,Helvetica10_Character_108,Helvetica10_Character_109,Helvetica10_Character_110,Helvetica10_Character_111,Helvetica10_Character_112,Helvetica10_Character_113,Helvetica10_Character_114,Helvetica10_Character_115, + Helvetica10_Character_116,Helvetica10_Character_117,Helvetica10_Character_118,Helvetica10_Character_119,Helvetica10_Character_120,Helvetica10_Character_121,Helvetica10_Character_122,Helvetica10_Character_123,Helvetica10_Character_124,Helvetica10_Character_125,Helvetica10_Character_126,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, + Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, + Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042, + Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontHelvetica10 = { "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", 93, 13, Helvetica10_Character_Map, -1.0f, 2.0f }; + +static const GLubyte Helvetica12_Character_032[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ +static const GLubyte Helvetica12_Character_097[] = { 7, 0, 0, 0,116,136,136,120, 8,136,112, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte Helvetica12_Character_098[] = { 7, 0, 0, 0,176,200,136,136,136,200,176,128,128, 0, 0, 0}; /* "b" */ +static const GLubyte Helvetica12_Character_099[] = { 7, 0, 0, 0,112,136,128,128,128,136,112, 0, 0, 0, 0, 0}; /* "c" */ +static const GLubyte Helvetica12_Character_100[] = { 7, 0, 0, 0,104,152,136,136,136,152,104, 8, 8, 0, 0, 0}; /* "d" */ +static const GLubyte Helvetica12_Character_101[] = { 7, 0, 0, 0,112,136,128,248,136,136,112, 0, 0, 0, 0, 0}; /* "e" */ +static const GLubyte Helvetica12_Character_102[] = { 3, 0, 0, 0, 64, 64, 64, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ +static const GLubyte Helvetica12_Character_103[] = { 7,112,136, 8,104,152,136,136,136,152,104, 0, 0, 0, 0, 0}; /* "g" */ +static const GLubyte Helvetica12_Character_104[] = { 7, 0, 0, 0,136,136,136,136,136,200,176,128,128, 0, 0, 0}; /* "h" */ +static const GLubyte Helvetica12_Character_105[] = { 3, 0, 0, 0,128,128,128,128,128,128,128, 0,128, 0, 0, 0}; /* "i" */ +static const GLubyte Helvetica12_Character_106[] = { 3,128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 64, 0, 0, 0}; /* "j" */ +static const GLubyte Helvetica12_Character_107[] = { 6, 0, 0, 0,136,144,160,192,192,160,144,128,128, 0, 0, 0}; /* "k" */ +static const GLubyte Helvetica12_Character_108[] = { 3, 0, 0, 0,128,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "l" */ +static const GLubyte Helvetica12_Character_109[] = { 9, 0, 0, 0, 0, 0, 0,146, 0,146, 0,146, 0,146, 0,146, 0,218, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "m" */ +static const GLubyte Helvetica12_Character_110[] = { 7, 0, 0, 0,136,136,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "n" */ +static const GLubyte Helvetica12_Character_111[] = { 7, 0, 0, 0,112,136,136,136,136,136,112, 0, 0, 0, 0, 0}; /* "o" */ +static const GLubyte Helvetica12_Character_112[] = { 7,128,128,128,176,200,136,136,136,200,176, 0, 0, 0, 0, 0}; /* "p" */ +static const GLubyte Helvetica12_Character_113[] = { 7, 8, 8, 8,104,152,136,136,136,152,104, 0, 0, 0, 0, 0}; /* "q" */ +static const GLubyte Helvetica12_Character_114[] = { 4, 0, 0, 0,128,128,128,128,128,192,160, 0, 0, 0, 0, 0}; /* "r" */ +static const GLubyte Helvetica12_Character_115[] = { 6, 0, 0, 0, 96,144, 16, 96,128,144, 96, 0, 0, 0, 0, 0}; /* "s" */ +static const GLubyte Helvetica12_Character_116[] = { 4, 0, 0, 0, 96, 64, 64, 64, 64, 64,224, 64, 64, 0, 0, 0}; /* "t" */ +static const GLubyte Helvetica12_Character_117[] = { 7, 0, 0, 0,104,152,136,136,136,136,136, 0, 0, 0, 0, 0}; /* "u" */ +static const GLubyte Helvetica12_Character_118[] = { 7, 0, 0, 0, 32, 32, 80, 80,136,136,136, 0, 0, 0, 0, 0}; /* "v" */ +static const GLubyte Helvetica12_Character_119[] = { 10, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 85, 0, 73, 0, 73, 0,136,128,136,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "w" */ +static const GLubyte Helvetica12_Character_120[] = { 6, 0, 0, 0,132,132, 72, 48, 48, 72,132, 0, 0, 0, 0, 0}; /* "x" */ +static const GLubyte Helvetica12_Character_121[] = { 7,128, 64, 32, 32, 80, 80,144,136,136,136, 0, 0, 0, 0, 0}; /* "y" */ +static const GLubyte Helvetica12_Character_122[] = { 6, 0, 0, 0,240,128, 64, 64, 32, 16,240, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte Helvetica12_Character_065[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,124, 0, 68, 0, 68, 0, 40, 0, 40, 0, 16, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ +static const GLubyte Helvetica12_Character_066[] = { 8, 0, 0, 0,248,132,132,132,248,132,132,132,248, 0, 0, 0}; /* "B" */ +static const GLubyte Helvetica12_Character_067[] = { 9, 0, 0, 0, 0, 0, 0, 60, 0, 66, 0,128, 0,128, 0,128, 0,128, 0,128, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ +static const GLubyte Helvetica12_Character_068[] = { 9, 0, 0, 0, 0, 0, 0,248, 0,132, 0,130, 0,130, 0,130, 0,130, 0,130, 0,132, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ +static const GLubyte Helvetica12_Character_069[] = { 8, 0, 0, 0,252,128,128,128,252,128,128,128,252, 0, 0, 0}; /* "E" */ +static const GLubyte Helvetica12_Character_070[] = { 8, 0, 0, 0,128,128,128,128,248,128,128,128,252, 0, 0, 0}; /* "F" */ +static const GLubyte Helvetica12_Character_071[] = { 9, 0, 0, 0, 0, 0, 0, 58, 0, 70, 0,130, 0,130, 0,142, 0,128, 0,128, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ +static const GLubyte Helvetica12_Character_072[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,130, 0,130, 0,130, 0,254, 0,130, 0,130, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ +static const GLubyte Helvetica12_Character_073[] = { 3, 0, 0, 0,128,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "I" */ +static const GLubyte Helvetica12_Character_074[] = { 7, 0, 0, 0,112,136,136, 8, 8, 8, 8, 8, 8, 0, 0, 0}; /* "J" */ +static const GLubyte Helvetica12_Character_075[] = { 8, 0, 0, 0,130,132,136,144,224,160,144,136,132, 0, 0, 0}; /* "K" */ +static const GLubyte Helvetica12_Character_076[] = { 7, 0, 0, 0,248,128,128,128,128,128,128,128,128, 0, 0, 0}; /* "L" */ +static const GLubyte Helvetica12_Character_077[] = { 11, 0, 0, 0, 0, 0, 0,136,128,136,128,148,128,148,128,162,128,162,128,193,128,193,128,128,128, 0, 0, 0, 0, 0, 0}; /* "M" */ +static const GLubyte Helvetica12_Character_078[] = { 9, 0, 0, 0, 0, 0, 0,130, 0,134, 0,138, 0,138, 0,146, 0,162, 0,162, 0,194, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ +static const GLubyte Helvetica12_Character_079[] = { 10, 0, 0, 0, 0, 0, 0, 60, 0, 66, 0,129, 0,129, 0,129, 0,129, 0,129, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ +static const GLubyte Helvetica12_Character_080[] = { 8, 0, 0, 0,128,128,128,128,248,132,132,132,248, 0, 0, 0}; /* "P" */ +static const GLubyte Helvetica12_Character_081[] = { 10, 0, 0, 0, 0, 0, 0, 61, 0, 66, 0,133, 0,137, 0,129, 0,129, 0,129, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ +static const GLubyte Helvetica12_Character_082[] = { 8, 0, 0, 0,132,132,132,136,248,132,132,132,248, 0, 0, 0}; /* "R" */ +static const GLubyte Helvetica12_Character_083[] = { 8, 0, 0, 0,120,132,132, 4, 24, 96,128,132,120, 0, 0, 0}; /* "S" */ +static const GLubyte Helvetica12_Character_084[] = { 7, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0, 0}; /* "T" */ +static const GLubyte Helvetica12_Character_085[] = { 8, 0, 0, 0,120,132,132,132,132,132,132,132,132, 0, 0, 0}; /* "U" */ +static const GLubyte Helvetica12_Character_086[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 40, 0, 40, 0, 68, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ +static const GLubyte Helvetica12_Character_087[] = { 11, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 85, 0, 85, 0, 73, 0,136,128,136,128,136,128, 0, 0, 0, 0, 0, 0}; /* "W" */ +static const GLubyte Helvetica12_Character_088[] = { 9, 0, 0, 0, 0, 0, 0,130, 0, 68, 0, 68, 0, 40, 0, 16, 0, 40, 0, 68, 0, 68, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ +static const GLubyte Helvetica12_Character_089[] = { 9, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 0, 40, 0, 68, 0, 68, 0,130, 0,130, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ +static const GLubyte Helvetica12_Character_090[] = { 9, 0, 0, 0, 0, 0, 0,254, 0,128, 0, 64, 0, 32, 0, 16, 0, 8, 0, 4, 0, 2, 0,254, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ +static const GLubyte Helvetica12_Character_048[] = { 7, 0, 0, 0,112,136,136,136,136,136,136,136,112, 0, 0, 0}; /* "0" */ +static const GLubyte Helvetica12_Character_049[] = { 7, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32,224, 32, 0, 0, 0}; /* "1" */ +static const GLubyte Helvetica12_Character_050[] = { 7, 0, 0, 0,248,128,128, 64, 32, 16, 8,136,112, 0, 0, 0}; /* "2" */ +static const GLubyte Helvetica12_Character_051[] = { 7, 0, 0, 0,112,136,136, 8, 8, 48, 8,136,112, 0, 0, 0}; /* "3" */ +static const GLubyte Helvetica12_Character_052[] = { 7, 0, 0, 0, 8, 8,252,136, 72, 40, 40, 24, 8, 0, 0, 0}; /* "4" */ +static const GLubyte Helvetica12_Character_053[] = { 7, 0, 0, 0,112,136,136, 8, 8,240,128,128,248, 0, 0, 0}; /* "5" */ +static const GLubyte Helvetica12_Character_054[] = { 7, 0, 0, 0,112,136,136,136,200,176,128,136,112, 0, 0, 0}; /* "6" */ +static const GLubyte Helvetica12_Character_055[] = { 7, 0, 0, 0, 64, 64, 32, 32, 32, 16, 16, 8,248, 0, 0, 0}; /* "7" */ +static const GLubyte Helvetica12_Character_056[] = { 7, 0, 0, 0,112,136,136,136,136,112,136,136,112, 0, 0, 0}; /* "8" */ +static const GLubyte Helvetica12_Character_057[] = { 7, 0, 0, 0,112,136, 8, 8,120,136,136,136,112, 0, 0, 0}; /* "9" */ +static const GLubyte Helvetica12_Character_096[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,128, 64, 0, 0, 0}; /* "`" */ +static const GLubyte Helvetica12_Character_126[] = { 8, 0, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte Helvetica12_Character_033[] = { 3, 0, 0, 0,128, 0,128,128,128,128,128,128,128, 0, 0, 0}; /* "!" */ +static const GLubyte Helvetica12_Character_064[] = { 12, 0, 0, 0, 0, 62, 0, 64, 0,155, 0,166,128,162, 64,162, 64,146, 64, 77, 64, 96,128, 31, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte Helvetica12_Character_035[] = { 7, 0, 0, 0, 80, 80, 80,252, 40,252, 40, 40, 0, 0, 0, 0}; /* "#" */ +static const GLubyte Helvetica12_Character_036[] = { 7, 0, 0, 32,112,168,168, 40,112,160,168,112, 32, 0, 0, 0}; /* "$" */ +static const GLubyte Helvetica12_Character_037[] = { 11, 0, 0, 0, 0, 0, 0, 35, 0, 20,128, 20,128, 19, 0, 8, 0,104, 0,148, 0,148, 0, 98, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ +static const GLubyte Helvetica12_Character_094[] = { 6, 0, 0, 0, 0, 0, 0, 0, 0,136, 80, 32, 0, 0, 0, 0}; /* "^" */ +static const GLubyte Helvetica12_Character_038[] = { 9, 0, 0, 0, 0, 0, 0,114, 0,140, 0,132, 0,138, 0, 80, 0, 48, 0, 72, 0, 72, 0, 48, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ +static const GLubyte Helvetica12_Character_042[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ +static const GLubyte Helvetica12_Character_040[] = { 4, 32, 64, 64,128,128,128,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ +static const GLubyte Helvetica12_Character_041[] = { 4,128, 64, 64, 32, 32, 32, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ +static const GLubyte Helvetica12_Character_045[] = { 8, 0, 0, 0, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte Helvetica12_Character_095[] = { 7, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte Helvetica12_Character_061[] = { 7, 0, 0, 0, 0, 0,248, 0,248, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte Helvetica12_Character_043[] = { 7, 0, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte Helvetica12_Character_091[] = { 3,192,128,128,128,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ +static const GLubyte Helvetica12_Character_123[] = { 4, 48, 64, 64, 64, 64, 64,128, 64, 64, 64, 64, 48, 0, 0, 0}; /* "{" */ +static const GLubyte Helvetica12_Character_125[] = { 4,192, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32,192, 0, 0, 0}; /* "}" */ +static const GLubyte Helvetica12_Character_093[] = { 3,192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ +static const GLubyte Helvetica12_Character_059[] = { 3, 0,128, 64, 64, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte Helvetica12_Character_058[] = { 3, 0, 0, 0,128, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte Helvetica12_Character_044[] = { 4, 0,128, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte Helvetica12_Character_046[] = { 3, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte Helvetica12_Character_060[] = { 7, 0, 0, 0, 0, 12, 48,192, 48, 12, 0, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte Helvetica12_Character_062[] = { 7, 0, 0, 0, 0,192, 48, 12, 48,192, 0, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte Helvetica12_Character_047[] = { 4, 0, 0, 0,128,128,128, 64, 64, 64, 32, 32, 32, 0, 0, 0}; /* "/" */ +static const GLubyte Helvetica12_Character_063[] = { 7, 0, 0, 0, 32, 0, 32, 32, 16, 16,136,136,112, 0, 0, 0}; /* "?" */ +static const GLubyte Helvetica12_Character_092[] = { 4, 0, 0, 0, 32, 32, 32, 64, 64, 64,128,128,128, 0, 0, 0}; /* "\" */ +static const GLubyte Helvetica12_Character_034[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,160,160, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte Helvetica12_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 64, 0, 0}; /* "'" */ +static const GLubyte Helvetica12_Character_124[] = { 3, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 0}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* Helvetica12_Character_Map[] = {Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_032,Helvetica12_Character_033,Helvetica12_Character_034,Helvetica12_Character_035,Helvetica12_Character_036,Helvetica12_Character_037, + Helvetica12_Character_038,Helvetica12_Character_039,Helvetica12_Character_040,Helvetica12_Character_041,Helvetica12_Character_042,Helvetica12_Character_043,Helvetica12_Character_044,Helvetica12_Character_045,Helvetica12_Character_046,Helvetica12_Character_047,Helvetica12_Character_048,Helvetica12_Character_049,Helvetica12_Character_050,Helvetica12_Character_051,Helvetica12_Character_052,Helvetica12_Character_053,Helvetica12_Character_054,Helvetica12_Character_055,Helvetica12_Character_056,Helvetica12_Character_057,Helvetica12_Character_058,Helvetica12_Character_059,Helvetica12_Character_060,Helvetica12_Character_061,Helvetica12_Character_062,Helvetica12_Character_063,Helvetica12_Character_064,Helvetica12_Character_065,Helvetica12_Character_066,Helvetica12_Character_067,Helvetica12_Character_068,Helvetica12_Character_069,Helvetica12_Character_070,Helvetica12_Character_071,Helvetica12_Character_072,Helvetica12_Character_073,Helvetica12_Character_074,Helvetica12_Character_075,Helvetica12_Character_076, + Helvetica12_Character_077,Helvetica12_Character_078,Helvetica12_Character_079,Helvetica12_Character_080,Helvetica12_Character_081,Helvetica12_Character_082,Helvetica12_Character_083,Helvetica12_Character_084,Helvetica12_Character_085,Helvetica12_Character_086,Helvetica12_Character_087,Helvetica12_Character_088,Helvetica12_Character_089,Helvetica12_Character_090,Helvetica12_Character_091,Helvetica12_Character_092,Helvetica12_Character_093,Helvetica12_Character_094,Helvetica12_Character_095,Helvetica12_Character_096,Helvetica12_Character_097,Helvetica12_Character_098,Helvetica12_Character_099,Helvetica12_Character_100,Helvetica12_Character_101,Helvetica12_Character_102,Helvetica12_Character_103,Helvetica12_Character_104,Helvetica12_Character_105,Helvetica12_Character_106,Helvetica12_Character_107,Helvetica12_Character_108,Helvetica12_Character_109,Helvetica12_Character_110,Helvetica12_Character_111,Helvetica12_Character_112,Helvetica12_Character_113,Helvetica12_Character_114,Helvetica12_Character_115, + Helvetica12_Character_116,Helvetica12_Character_117,Helvetica12_Character_118,Helvetica12_Character_119,Helvetica12_Character_120,Helvetica12_Character_121,Helvetica12_Character_122,Helvetica12_Character_123,Helvetica12_Character_124,Helvetica12_Character_125,Helvetica12_Character_126,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, + Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, + Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042, + Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontHelvetica12 = { "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", 93, 15, Helvetica12_Character_Map, -1.0f, 3.0f }; + +static const GLubyte Helvetica18_Character_032[] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ +static const GLubyte Helvetica18_Character_097[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,118, 0,238, 0,198, 0,198, 0,230, 0,126, 0, 14, 0,198, 0,238, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte Helvetica18_Character_098[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,222, 0,255, 0,227, 0,193,128,193,128,193,128,193,128,227, 0,255, 0,222, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "b" */ +static const GLubyte Helvetica18_Character_099[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0,127, 0, 99, 0,192, 0,192, 0,192, 0,192, 0, 99, 0,127, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "c" */ +static const GLubyte Helvetica18_Character_100[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128, 1,128, 1,128, 1,128, 1,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "d" */ +static const GLubyte Helvetica18_Character_101[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,127, 0,227, 0,192, 0,192, 0,255, 0,195, 0,195, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "e" */ +static const GLubyte Helvetica18_Character_102[] = { 6, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 60, 28, 0, 0, 0, 0}; /* "f" */ +static const GLubyte Helvetica18_Character_103[] = { 11, 28, 0,127, 0, 99, 0, 1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 97,128,127,128, 61,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "g" */ +static const GLubyte Helvetica18_Character_104[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,227, 0,223, 0,206, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "h" */ +static const GLubyte Helvetica18_Character_105[] = { 4, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192, 0, 0,192,192, 0, 0, 0, 0}; /* "i" */ +static const GLubyte Helvetica18_Character_106[] = { 4,224,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, 0, 0, 0}; /* "j" */ +static const GLubyte Helvetica18_Character_107[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,199, 0,198, 0,206, 0,204, 0,216, 0,248, 0,240, 0,216, 0,204, 0,198, 0,192, 0,192, 0,192, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "k" */ +static const GLubyte Helvetica18_Character_108[] = { 4, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "l" */ +static const GLubyte Helvetica18_Character_109[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,231, 48,222,240,204, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "m" */ +static const GLubyte Helvetica18_Character_110[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,227, 0,223, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "n" */ +static const GLubyte Helvetica18_Character_111[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0,127, 0, 99, 0,193,128,193,128,193,128,193,128, 99, 0,127, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "o" */ +static const GLubyte Helvetica18_Character_112[] = { 11,192, 0,192, 0,192, 0,192, 0,222, 0,255, 0,227, 0,193,128,193,128,193,128,193,128,227, 0,255, 0,222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "p" */ +static const GLubyte Helvetica18_Character_113[] = { 11, 1,128, 1,128, 1,128, 1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "q" */ +static const GLubyte Helvetica18_Character_114[] = { 6, 0, 0, 0, 0,192,192,192,192,192,192,192,224,216,216, 0, 0, 0, 0, 0, 0, 0, 0}; /* "r" */ +static const GLubyte Helvetica18_Character_115[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,252, 0,198, 0, 6, 0, 62, 0,252, 0,192, 0,198, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "s" */ +static const GLubyte Helvetica18_Character_116[] = { 6, 0, 0, 0, 0, 24, 56, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 48, 0, 0, 0, 0, 0}; /* "t" */ +static const GLubyte Helvetica18_Character_117[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,115, 0,251, 0,199, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "u" */ +static const GLubyte Helvetica18_Character_118[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 60, 0, 36, 0,102, 0,102, 0,102, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "v" */ +static const GLubyte Helvetica18_Character_119[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 25,128, 25,128, 57,192, 41, 64,105, 96,102, 96,102, 96,198, 48,198, 48,198, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "w" */ +static const GLubyte Helvetica18_Character_120[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,195, 0,231, 0,102, 0, 60, 0, 24, 0, 24, 0, 60, 0,102, 0,231, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "x" */ +static const GLubyte Helvetica18_Character_121[] = { 10,112, 0,112, 0, 24, 0, 24, 0, 24, 0, 24, 0, 60, 0, 36, 0,102, 0,102, 0,102, 0,195, 0,195, 0,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "y" */ +static const GLubyte Helvetica18_Character_122[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0,254, 0,254, 0,192, 0, 96, 0, 48, 0, 24, 0, 12, 0, 6, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte Helvetica18_Character_065[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192, 48,192, 48, 96, 96, 96, 96,127,224, 63,192, 48,192, 48,192, 25,128, 25,128, 15, 0, 15, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ +static const GLubyte Helvetica18_Character_066[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,192,192,224,192, 96,192, 96,192,224,255,192,255,128,193,128,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "B" */ +static const GLubyte Helvetica18_Character_067[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 15,128, 63,224,112,112, 96, 48,224, 0,192, 0,192, 0,192, 0,192, 0,224, 0, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ +static const GLubyte Helvetica18_Character_068[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255,128,193,192,192,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ +static const GLubyte Helvetica18_Character_069[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,128,192, 0,192, 0,192, 0,192, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,255,128,255,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "E" */ +static const GLubyte Helvetica18_Character_070[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,255,128,255,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "F" */ +static const GLubyte Helvetica18_Character_071[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 15,176, 63,240,112,112, 96, 48,224, 48,193,240,193,240,192, 0,192, 0,224, 48, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ +static const GLubyte Helvetica18_Character_072[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,255,224,255,224,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ +static const GLubyte Helvetica18_Character_073[] = { 6, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "I" */ +static const GLubyte Helvetica18_Character_074[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,231, 0,195, 0,195, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "J" */ +static const GLubyte Helvetica18_Character_075[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192,112,192,224,193,192,195,128,199, 0,206, 0,252, 0,248, 0,220, 0,206, 0,199, 0,195,128,193,192,192,224, 0, 0, 0, 0, 0, 0, 0, 0}; /* "K" */ +static const GLubyte Helvetica18_Character_076[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "L" */ +static const GLubyte Helvetica18_Character_077[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0,195, 12,195, 12,199,140,196,140,204,204,204,204,216,108,216,108,240, 60,240, 60,224, 28,224, 28,192, 12,192, 12, 0, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ +static const GLubyte Helvetica18_Character_078[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,192,224,193,224,193,224,195, 96,198, 96,198, 96,204, 96,204, 96,216, 96,240, 96,240, 96,224, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ +static const GLubyte Helvetica18_Character_079[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 15,128, 63,224,112,112, 96, 48,224, 56,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ +static const GLubyte Helvetica18_Character_080[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,255, 0,255,128,193,192,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "P" */ +static const GLubyte Helvetica18_Character_081[] = { 15, 0, 0, 0, 0, 0, 0, 0, 48, 15,176, 63,224,112,240, 97,176,225,184,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ +static const GLubyte Helvetica18_Character_082[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,192,192,192,192,192,192,192,192,193,128,193,128,255, 0,255,128,193,192,192,192,192,192,193,192,255,128,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "R" */ +static const GLubyte Helvetica18_Character_083[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,127,192,224,224,192, 96, 0, 96, 0,224, 3,192, 31, 0,124, 0,224, 0,192, 96,224,224,127,192, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "S" */ +static const GLubyte Helvetica18_Character_084[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0,255,192,255,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* "T" */ +static const GLubyte Helvetica18_Character_085[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0,127,192, 96,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "U" */ +static const GLubyte Helvetica18_Character_086[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 15, 0, 15, 0, 25,128, 25,128, 25,128, 48,192, 48,192, 48,192, 96, 96, 96, 96, 96, 96,192, 48,192, 48, 0, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ +static const GLubyte Helvetica18_Character_087[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 24, 24, 0, 28, 56, 0, 52, 44, 0, 54,108, 0, 54,108, 0,102,102, 0,102,102, 0, 98, 70, 0, 99,198, 0,195,195, 0,193,131, 0,193,131, 0,193,131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "W" */ +static const GLubyte Helvetica18_Character_088[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0,192, 96,224,224, 96,192,113,192, 49,128, 27, 0, 14, 0, 14, 0, 27, 0, 49,128,113,192, 96,192,224,224,192, 96, 0, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ +static const GLubyte Helvetica18_Character_089[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 15, 0, 25,128, 48,192, 48,192, 96, 96, 96, 96,192, 48,192, 48, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ +static const GLubyte Helvetica18_Character_090[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0,255,192,255,192,192, 0, 96, 0, 48, 0, 24, 0, 28, 0, 12, 0, 6, 0, 3, 0, 1,128, 0,192,255,192,255,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ +static const GLubyte Helvetica18_Character_048[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,102, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,195, 0,102, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "0" */ +static const GLubyte Helvetica18_Character_049[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0,248, 0,248, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "1" */ +static const GLubyte Helvetica18_Character_050[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 0,192, 0,224, 0,112, 0, 56, 0, 28, 0, 14, 0, 7, 0, 3, 0,195, 0,254, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "2" */ +static const GLubyte Helvetica18_Character_051[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,199, 0,195, 0, 3, 0, 7, 0, 30, 0, 28, 0, 6, 0,195, 0,195, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "3" */ +static const GLubyte Helvetica18_Character_052[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0,255,128,255,128,195, 0, 99, 0, 51, 0, 51, 0, 27, 0, 15, 0, 7, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "4" */ +static const GLubyte Helvetica18_Character_053[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,124, 0,254, 0,199, 0,195, 0, 3, 0, 3, 0,199, 0,254, 0,252, 0,192, 0,192, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "5" */ +static const GLubyte Helvetica18_Character_054[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,227, 0,195, 0,195, 0,195, 0,254, 0,220, 0,192, 0,192, 0, 99, 0,127, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "6" */ +static const GLubyte Helvetica18_Character_055[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 96, 0, 48, 0, 48, 0, 48, 0, 24, 0, 24, 0, 12, 0, 12, 0, 6, 0, 3, 0,255, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "7" */ +static const GLubyte Helvetica18_Character_056[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0,126, 0,231, 0,195, 0,195, 0,102, 0,126, 0,102, 0,195, 0,195, 0,231, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "8" */ +static const GLubyte Helvetica18_Character_057[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,124, 0,254, 0,198, 0, 3, 0, 3, 0, 59, 0,127, 0,195, 0,195, 0,195, 0,199, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "9" */ +static const GLubyte Helvetica18_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192,128,128, 64, 0, 0, 0, 0}; /* "`" */ +static const GLubyte Helvetica18_Character_126[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 0,126, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte Helvetica18_Character_033[] = { 6, 0, 0, 0, 0,192,192, 0, 0,128,128,192,192,192,192,192,192,192,192, 0, 0, 0, 0}; /* "!" */ +static const GLubyte Helvetica18_Character_064[] = { 18, 0, 0, 0, 7,224, 0, 31,240, 0, 56, 0, 0,112, 0, 0,103,112, 0,207,248, 0,204,204, 0,204,102, 0,204,102, 0,204, 99, 0,198, 51, 0,103,115, 0, 99,179, 0, 48, 6, 0, 28, 14, 0, 15,252, 0, 3,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte Helvetica18_Character_035[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 36, 0, 36, 0,255,128,255,128, 18, 0, 18, 0, 18, 0,127,192,127,192, 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ +static const GLubyte Helvetica18_Character_036[] = { 10, 0, 0, 0, 0, 8, 0, 8, 0, 62, 0,127, 0,235,128,201,128, 9,128, 15, 0, 62, 0,120, 0,232, 0,200, 0,203, 0,127, 0, 62, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "$" */ +static const GLubyte Helvetica18_Character_037[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 24,120, 24,252, 12,204, 12,204, 6,252, 6,120, 3, 0,123, 0,253,128,205,128,204,192,252,192,120, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ +static const GLubyte Helvetica18_Character_094[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130, 0,198, 0,108, 0, 56, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "^" */ +static const GLubyte Helvetica18_Character_038[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 60,112,126,224,231,192,195,128,195,192,198,192,238,192,124, 0, 60, 0,102, 0,102, 0,126, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ +static const GLubyte Helvetica18_Character_042[] = { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,112,112,248, 32, 32, 0, 0, 0, 0}; /* "*" */ +static const GLubyte Helvetica18_Character_040[] = { 6, 16, 48, 96, 96,192,192,192,192,192,192,192,192,192,192, 96, 96, 48, 16, 0, 0, 0, 0}; /* "(" */ +static const GLubyte Helvetica18_Character_041[] = { 6,128,192, 96, 96, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 96, 96,192,128, 0, 0, 0, 0}; /* ")" */ +static const GLubyte Helvetica18_Character_045[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte Helvetica18_Character_095[] = { 10,255,248,255,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte Helvetica18_Character_061[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 0,254, 0, 0, 0, 0, 0,254, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte Helvetica18_Character_043[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 24, 0, 24, 0,255, 0,255, 0, 24, 0, 24, 0, 24, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte Helvetica18_Character_091[] = { 5,240,240,192,192,192,192,192,192,192,192,192,192,192,192,192,192,240,240, 0, 0, 0, 0}; /* "[" */ +static const GLubyte Helvetica18_Character_123[] = { 7, 12, 24, 48, 48, 48, 48, 48, 48, 96,192, 96, 48, 48, 48, 48, 48, 24, 12, 0, 0, 0, 0}; /* "{" */ +static const GLubyte Helvetica18_Character_125[] = { 7,192, 96, 48, 48, 48, 48, 48, 48, 24, 12, 24, 48, 48, 48, 48, 48, 96,192, 0, 0, 0, 0}; /* "}" */ +static const GLubyte Helvetica18_Character_093[] = { 5,240,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,240,240, 0, 0, 0, 0}; /* "]" */ +static const GLubyte Helvetica18_Character_059[] = { 5, 0,128, 64, 64,192,192, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte Helvetica18_Character_058[] = { 5, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte Helvetica18_Character_044[] = { 5, 0,128, 64, 64,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte Helvetica18_Character_046[] = { 5, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte Helvetica18_Character_060[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 15, 0, 60, 0,112, 0,192, 0,112, 0, 60, 0, 15, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte Helvetica18_Character_062[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,240, 0, 60, 0, 14, 0, 3, 0, 14, 0, 60, 0,240, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte Helvetica18_Character_047[] = { 5, 0, 0, 0, 0,192,192, 64, 64, 96, 96, 32, 32, 48, 48, 16, 16, 24, 24, 0, 0, 0, 0}; /* "/" */ +static const GLubyte Helvetica18_Character_063[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 48, 0, 0, 0, 0, 0, 48, 0, 48, 0, 48, 0, 56, 0, 28, 0, 14, 0,198, 0,198, 0,254, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "?" */ +static const GLubyte Helvetica18_Character_092[] = { 5, 0, 0, 0, 0, 24, 24, 16, 16, 48, 48, 32, 32, 96, 96, 64, 64,192,192, 0, 0, 0, 0}; /* "\" */ +static const GLubyte Helvetica18_Character_034[] = { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,144,144,216,216,216, 0, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte Helvetica18_Character_039[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64, 64,192,192, 0, 0, 0, 0}; /* "'" */ +static const GLubyte Helvetica18_Character_124[] = { 4, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* Helvetica18_Character_Map[] = {Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_032,Helvetica18_Character_033,Helvetica18_Character_034,Helvetica18_Character_035,Helvetica18_Character_036,Helvetica18_Character_037, + Helvetica18_Character_038,Helvetica18_Character_039,Helvetica18_Character_040,Helvetica18_Character_041,Helvetica18_Character_042,Helvetica18_Character_043,Helvetica18_Character_044,Helvetica18_Character_045,Helvetica18_Character_046,Helvetica18_Character_047,Helvetica18_Character_048,Helvetica18_Character_049,Helvetica18_Character_050,Helvetica18_Character_051,Helvetica18_Character_052,Helvetica18_Character_053,Helvetica18_Character_054,Helvetica18_Character_055,Helvetica18_Character_056,Helvetica18_Character_057,Helvetica18_Character_058,Helvetica18_Character_059,Helvetica18_Character_060,Helvetica18_Character_061,Helvetica18_Character_062,Helvetica18_Character_063,Helvetica18_Character_064,Helvetica18_Character_065,Helvetica18_Character_066,Helvetica18_Character_067,Helvetica18_Character_068,Helvetica18_Character_069,Helvetica18_Character_070,Helvetica18_Character_071,Helvetica18_Character_072,Helvetica18_Character_073,Helvetica18_Character_074,Helvetica18_Character_075,Helvetica18_Character_076, + Helvetica18_Character_077,Helvetica18_Character_078,Helvetica18_Character_079,Helvetica18_Character_080,Helvetica18_Character_081,Helvetica18_Character_082,Helvetica18_Character_083,Helvetica18_Character_084,Helvetica18_Character_085,Helvetica18_Character_086,Helvetica18_Character_087,Helvetica18_Character_088,Helvetica18_Character_089,Helvetica18_Character_090,Helvetica18_Character_091,Helvetica18_Character_092,Helvetica18_Character_093,Helvetica18_Character_094,Helvetica18_Character_095,Helvetica18_Character_096,Helvetica18_Character_097,Helvetica18_Character_098,Helvetica18_Character_099,Helvetica18_Character_100,Helvetica18_Character_101,Helvetica18_Character_102,Helvetica18_Character_103,Helvetica18_Character_104,Helvetica18_Character_105,Helvetica18_Character_106,Helvetica18_Character_107,Helvetica18_Character_108,Helvetica18_Character_109,Helvetica18_Character_110,Helvetica18_Character_111,Helvetica18_Character_112,Helvetica18_Character_113,Helvetica18_Character_114,Helvetica18_Character_115, + Helvetica18_Character_116,Helvetica18_Character_117,Helvetica18_Character_118,Helvetica18_Character_119,Helvetica18_Character_120,Helvetica18_Character_121,Helvetica18_Character_122,Helvetica18_Character_123,Helvetica18_Character_124,Helvetica18_Character_125,Helvetica18_Character_126,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, + Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, + Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042, + Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontHelvetica18 = { "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", 93, 22, Helvetica18_Character_Map, -1.0f, 4.0f }; + +static const GLubyte TimesRoman10_Character_032[] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ +static const GLubyte TimesRoman10_Character_097[] = { 4, 0, 0, 0,224,160, 96, 32,192, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte TimesRoman10_Character_098[] = { 5, 0, 0, 0,224,144,144,144,224,128,128, 0, 0, 0}; /* "b" */ +static const GLubyte TimesRoman10_Character_099[] = { 4, 0, 0, 0, 96,128,128,128, 96, 0, 0, 0, 0, 0}; /* "c" */ +static const GLubyte TimesRoman10_Character_100[] = { 5, 0, 0, 0,104,144,144,144,112, 16, 48, 0, 0, 0}; /* "d" */ +static const GLubyte TimesRoman10_Character_101[] = { 4, 0, 0, 0, 96,128,192,160, 96, 0, 0, 0, 0, 0}; /* "e" */ +static const GLubyte TimesRoman10_Character_102[] = { 4, 0, 0, 0,224, 64, 64, 64,224, 64, 48, 0, 0, 0}; /* "f" */ +static const GLubyte TimesRoman10_Character_103[] = { 5, 0,224,144, 96, 64,160,160,112, 0, 0, 0, 0, 0}; /* "g" */ +static const GLubyte TimesRoman10_Character_104[] = { 5, 0, 0, 0,216,144,144,144,224,128,128, 0, 0, 0}; /* "h" */ +static const GLubyte TimesRoman10_Character_105[] = { 3, 0, 0, 0, 64, 64, 64, 64,192, 0, 64, 0, 0, 0}; /* "i" */ +static const GLubyte TimesRoman10_Character_106[] = { 3, 0,128, 64, 64, 64, 64, 64,192, 0, 64, 0, 0, 0}; /* "j" */ +static const GLubyte TimesRoman10_Character_107[] = { 5, 0, 0, 0,152,144,224,160,144,128,128, 0, 0, 0}; /* "k" */ +static const GLubyte TimesRoman10_Character_108[] = { 4, 0, 0, 0,224, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "l" */ +static const GLubyte TimesRoman10_Character_109[] = { 8, 0, 0, 0,219,146,146,146,236, 0, 0, 0, 0, 0}; /* "m" */ +static const GLubyte TimesRoman10_Character_110[] = { 5, 0, 0, 0,216,144,144,144,224, 0, 0, 0, 0, 0}; /* "n" */ +static const GLubyte TimesRoman10_Character_111[] = { 5, 0, 0, 0, 96,144,144,144, 96, 0, 0, 0, 0, 0}; /* "o" */ +static const GLubyte TimesRoman10_Character_112[] = { 5, 0,192,128,224,144,144,144,224, 0, 0, 0, 0, 0}; /* "p" */ +static const GLubyte TimesRoman10_Character_113[] = { 5, 0, 56, 16,112,144,144,144,112, 0, 0, 0, 0, 0}; /* "q" */ +static const GLubyte TimesRoman10_Character_114[] = { 4, 0, 0, 0,224, 64, 64, 96,160, 0, 0, 0, 0, 0}; /* "r" */ +static const GLubyte TimesRoman10_Character_115[] = { 4, 0, 0, 0,224, 32, 96,128,224, 0, 0, 0, 0, 0}; /* "s" */ +static const GLubyte TimesRoman10_Character_116[] = { 4, 0, 0, 0, 48, 64, 64, 64,224, 64, 0, 0, 0, 0}; /* "t" */ +static const GLubyte TimesRoman10_Character_117[] = { 5, 0, 0, 0,104,144,144,144,144, 0, 0, 0, 0, 0}; /* "u" */ +static const GLubyte TimesRoman10_Character_118[] = { 5, 0, 0, 0, 32, 96, 80,144,216, 0, 0, 0, 0, 0}; /* "v" */ +static const GLubyte TimesRoman10_Character_119[] = { 8, 0, 0, 0, 40,108, 84,146,219, 0, 0, 0, 0, 0}; /* "w" */ +static const GLubyte TimesRoman10_Character_120[] = { 6, 0, 0, 0,216, 80, 32, 80,216, 0, 0, 0, 0, 0}; /* "x" */ +static const GLubyte TimesRoman10_Character_121[] = { 5, 0, 64, 64, 32, 48, 80, 72,220, 0, 0, 0, 0, 0}; /* "y" */ +static const GLubyte TimesRoman10_Character_122[] = { 5, 0, 0, 0,240,144, 64, 32,240, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte TimesRoman10_Character_065[] = { 8, 0, 0, 0,238, 68,124, 40, 40, 56, 16, 0, 0, 0}; /* "A" */ +static const GLubyte TimesRoman10_Character_066[] = { 6, 0, 0, 0,240, 72, 72,112, 72, 72,240, 0, 0, 0}; /* "B" */ +static const GLubyte TimesRoman10_Character_067[] = { 7, 0, 0, 0,120,196,128,128,128,196,124, 0, 0, 0}; /* "C" */ +static const GLubyte TimesRoman10_Character_068[] = { 7, 0, 0, 0,248, 76, 68, 68, 68, 76,248, 0, 0, 0}; /* "D" */ +static const GLubyte TimesRoman10_Character_069[] = { 6, 0, 0, 0,248, 72, 64,112, 64, 72,248, 0, 0, 0}; /* "E" */ +static const GLubyte TimesRoman10_Character_070[] = { 6, 0, 0, 0,224, 64, 64,112, 64, 72,248, 0, 0, 0}; /* "F" */ +static const GLubyte TimesRoman10_Character_071[] = { 7, 0, 0, 0,120,196,132,156,128,196,124, 0, 0, 0}; /* "G" */ +static const GLubyte TimesRoman10_Character_072[] = { 8, 0, 0, 0,238, 68, 68,124, 68, 68,238, 0, 0, 0}; /* "H" */ +static const GLubyte TimesRoman10_Character_073[] = { 4, 0, 0, 0,224, 64, 64, 64, 64, 64,224, 0, 0, 0}; /* "I" */ +static const GLubyte TimesRoman10_Character_074[] = { 4, 0, 0, 0,192,160, 32, 32, 32, 32,112, 0, 0, 0}; /* "J" */ +static const GLubyte TimesRoman10_Character_075[] = { 7, 0, 0, 0,236, 72, 80, 96, 80, 72,236, 0, 0, 0}; /* "K" */ +static const GLubyte TimesRoman10_Character_076[] = { 6, 0, 0, 0,248, 72, 64, 64, 64, 64,224, 0, 0, 0}; /* "L" */ +static const GLubyte TimesRoman10_Character_077[] = { 10, 0, 0, 0, 0, 0, 0,235,128, 73, 0, 85, 0, 85, 0, 99, 0, 99, 0,227,128, 0, 0, 0, 0, 0, 0}; /* "M" */ +static const GLubyte TimesRoman10_Character_078[] = { 8, 0, 0, 0,228, 76, 76, 84, 84,100,238, 0, 0, 0}; /* "N" */ +static const GLubyte TimesRoman10_Character_079[] = { 7, 0, 0, 0,120,204,132,132,132,204,120, 0, 0, 0}; /* "O" */ +static const GLubyte TimesRoman10_Character_080[] = { 6, 0, 0, 0,224, 64, 64,112, 72, 72,240, 0, 0, 0}; /* "P" */ +static const GLubyte TimesRoman10_Character_081[] = { 7, 0, 12, 24,112,204,132,132,132,204,120, 0, 0, 0}; /* "Q" */ +static const GLubyte TimesRoman10_Character_082[] = { 7, 0, 0, 0,236, 72, 80,112, 72, 72,240, 0, 0, 0}; /* "R" */ +static const GLubyte TimesRoman10_Character_083[] = { 5, 0, 0, 0,224,144, 16, 96,192,144,112, 0, 0, 0}; /* "S" */ +static const GLubyte TimesRoman10_Character_084[] = { 6, 0, 0, 0,112, 32, 32, 32, 32,168,248, 0, 0, 0}; /* "T" */ +static const GLubyte TimesRoman10_Character_085[] = { 8, 0, 0, 0, 56,108, 68, 68, 68, 68,238, 0, 0, 0}; /* "U" */ +static const GLubyte TimesRoman10_Character_086[] = { 8, 0, 0, 0, 16, 16, 40, 40,108, 68,238, 0, 0, 0}; /* "V" */ +static const GLubyte TimesRoman10_Character_087[] = { 10, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 85, 0, 85, 0,201,128,136,128,221,192, 0, 0, 0, 0, 0, 0}; /* "W" */ +static const GLubyte TimesRoman10_Character_088[] = { 8, 0, 0, 0,238, 68, 40, 16, 40, 68,238, 0, 0, 0}; /* "X" */ +static const GLubyte TimesRoman10_Character_089[] = { 8, 0, 0, 0, 56, 16, 16, 40, 40, 68,238, 0, 0, 0}; /* "Y" */ +static const GLubyte TimesRoman10_Character_090[] = { 6, 0, 0, 0,248,136, 64, 32, 16,136,248, 0, 0, 0}; /* "Z" */ +static const GLubyte TimesRoman10_Character_048[] = { 5, 0, 0, 0, 96,144,144,144,144,144, 96, 0, 0, 0}; /* "0" */ +static const GLubyte TimesRoman10_Character_049[] = { 5, 0, 0, 0,224, 64, 64, 64, 64,192, 64, 0, 0, 0}; /* "1" */ +static const GLubyte TimesRoman10_Character_050[] = { 5, 0, 0, 0,240, 64, 32, 32, 16,144, 96, 0, 0, 0}; /* "2" */ +static const GLubyte TimesRoman10_Character_051[] = { 5, 0, 0, 0,224, 16, 16, 96, 16,144, 96, 0, 0, 0}; /* "3" */ +static const GLubyte TimesRoman10_Character_052[] = { 5, 0, 0, 0, 16, 16,248,144, 80, 48, 16, 0, 0, 0}; /* "4" */ +static const GLubyte TimesRoman10_Character_053[] = { 5, 0, 0, 0,224,144, 16, 16,224, 64,112, 0, 0, 0}; /* "5" */ +static const GLubyte TimesRoman10_Character_054[] = { 5, 0, 0, 0, 96,144,144,144,224, 64, 48, 0, 0, 0}; /* "6" */ +static const GLubyte TimesRoman10_Character_055[] = { 5, 0, 0, 0, 64, 64, 64, 32, 32,144,240, 0, 0, 0}; /* "7" */ +static const GLubyte TimesRoman10_Character_056[] = { 5, 0, 0, 0, 96,144,144, 96,144,144, 96, 0, 0, 0}; /* "8" */ +static const GLubyte TimesRoman10_Character_057[] = { 5, 0, 0, 0,192, 32,112,144,144,144, 96, 0, 0, 0}; /* "9" */ +static const GLubyte TimesRoman10_Character_096[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0,192,128, 0, 0, 0}; /* "`" */ +static const GLubyte TimesRoman10_Character_126[] = { 7, 0, 0, 0, 0, 0,152,100, 0, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte TimesRoman10_Character_033[] = { 3, 0, 0, 0,128, 0,128,128,128,128,128, 0, 0, 0}; /* "!" */ +static const GLubyte TimesRoman10_Character_064[] = { 9, 0, 0, 62, 0, 64, 0,146, 0,173, 0,165, 0,165, 0,157, 0, 66, 0, 60, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte TimesRoman10_Character_035[] = { 5, 0, 0, 0, 80, 80,248, 80,248, 80, 80, 0, 0, 0}; /* "#" */ +static const GLubyte TimesRoman10_Character_036[] = { 5, 0, 0, 32,224,144, 16, 96,128,144,112, 32, 0, 0}; /* "$" */ +static const GLubyte TimesRoman10_Character_037[] = { 8, 0, 0, 0, 68, 42, 42, 86,168,164,126, 0, 0, 0}; /* "%" */ +static const GLubyte TimesRoman10_Character_094[] = { 5, 0, 0, 0, 0, 0, 0, 0,160,160, 64, 0, 0, 0}; /* "^" */ +static const GLubyte TimesRoman10_Character_038[] = { 8, 0, 0, 0,118,141,152,116,110, 80, 48, 0, 0, 0}; /* "&" */ +static const GLubyte TimesRoman10_Character_042[] = { 5, 0, 0, 0, 0, 0, 0, 0,160, 64,160, 0, 0, 0}; /* "*" */ +static const GLubyte TimesRoman10_Character_040[] = { 4, 0, 32, 64, 64,128,128,128, 64, 64, 32, 0, 0, 0}; /* "(" */ +static const GLubyte TimesRoman10_Character_041[] = { 4, 0,128, 64, 64, 32, 32, 32, 64, 64,128, 0, 0, 0}; /* ")" */ +static const GLubyte TimesRoman10_Character_045[] = { 7, 0, 0, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte TimesRoman10_Character_095[] = { 5,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte TimesRoman10_Character_061[] = { 6, 0, 0, 0, 0,248, 0,248, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte TimesRoman10_Character_043[] = { 6, 0, 0, 0, 32, 32,248, 32, 32, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte TimesRoman10_Character_091[] = { 3, 0,192,128,128,128,128,128,128,128,192, 0, 0, 0}; /* "[" */ +static const GLubyte TimesRoman10_Character_123[] = { 4, 0, 32, 64, 64, 64,128, 64, 64, 64, 32, 0, 0, 0}; /* "{" */ +static const GLubyte TimesRoman10_Character_125[] = { 4, 0,128, 64, 64, 64, 32, 64, 64, 64,128, 0, 0, 0}; /* "}" */ +static const GLubyte TimesRoman10_Character_093[] = { 3, 0,192, 64, 64, 64, 64, 64, 64, 64,192, 0, 0, 0}; /* "]" */ +static const GLubyte TimesRoman10_Character_059[] = { 3, 0,128,128,128, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte TimesRoman10_Character_058[] = { 3, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte TimesRoman10_Character_044[] = { 3, 0,128,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte TimesRoman10_Character_046[] = { 3, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte TimesRoman10_Character_060[] = { 5, 0, 0, 0, 32, 64,128, 64, 32, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte TimesRoman10_Character_062[] = { 5, 0, 0, 0,128, 64, 32, 64,128, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte TimesRoman10_Character_047[] = { 3, 0, 0, 0,128,128, 64, 64, 64, 32, 32, 0, 0, 0}; /* "/" */ +static const GLubyte TimesRoman10_Character_063[] = { 4, 0, 0, 0, 64, 0, 64, 64, 32,160,224, 0, 0, 0}; /* "?" */ +static const GLubyte TimesRoman10_Character_092[] = { 3, 0, 0, 0, 32, 32, 64, 64, 64,128,128, 0, 0, 0}; /* "\" */ +static const GLubyte TimesRoman10_Character_034[] = { 4, 0, 0, 0, 0, 0, 0, 0, 0,160,160, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte TimesRoman10_Character_039[] = { 3, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64,192, 0, 0}; /* "'" */ +static const GLubyte TimesRoman10_Character_124[] = { 2,128,128,128,128,128,128,128,128,128,128,128,128,128}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* TimesRoman10_Character_Map[] = {TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_032,TimesRoman10_Character_033,TimesRoman10_Character_034,TimesRoman10_Character_035, +TimesRoman10_Character_036,TimesRoman10_Character_037,TimesRoman10_Character_038,TimesRoman10_Character_039,TimesRoman10_Character_040,TimesRoman10_Character_041,TimesRoman10_Character_042,TimesRoman10_Character_043,TimesRoman10_Character_044,TimesRoman10_Character_045,TimesRoman10_Character_046,TimesRoman10_Character_047,TimesRoman10_Character_048,TimesRoman10_Character_049,TimesRoman10_Character_050,TimesRoman10_Character_051,TimesRoman10_Character_052,TimesRoman10_Character_053,TimesRoman10_Character_054,TimesRoman10_Character_055,TimesRoman10_Character_056,TimesRoman10_Character_057,TimesRoman10_Character_058,TimesRoman10_Character_059,TimesRoman10_Character_060,TimesRoman10_Character_061,TimesRoman10_Character_062,TimesRoman10_Character_063,TimesRoman10_Character_064,TimesRoman10_Character_065,TimesRoman10_Character_066,TimesRoman10_Character_067,TimesRoman10_Character_068,TimesRoman10_Character_069,TimesRoman10_Character_070,TimesRoman10_Character_071,TimesRoman10_Character_072, +TimesRoman10_Character_073,TimesRoman10_Character_074,TimesRoman10_Character_075,TimesRoman10_Character_076,TimesRoman10_Character_077,TimesRoman10_Character_078,TimesRoman10_Character_079,TimesRoman10_Character_080,TimesRoman10_Character_081,TimesRoman10_Character_082,TimesRoman10_Character_083,TimesRoman10_Character_084,TimesRoman10_Character_085,TimesRoman10_Character_086,TimesRoman10_Character_087,TimesRoman10_Character_088,TimesRoman10_Character_089,TimesRoman10_Character_090,TimesRoman10_Character_091,TimesRoman10_Character_092,TimesRoman10_Character_093,TimesRoman10_Character_094,TimesRoman10_Character_095,TimesRoman10_Character_096,TimesRoman10_Character_097,TimesRoman10_Character_098,TimesRoman10_Character_099,TimesRoman10_Character_100,TimesRoman10_Character_101,TimesRoman10_Character_102,TimesRoman10_Character_103,TimesRoman10_Character_104,TimesRoman10_Character_105,TimesRoman10_Character_106,TimesRoman10_Character_107,TimesRoman10_Character_108,TimesRoman10_Character_109, +TimesRoman10_Character_110,TimesRoman10_Character_111,TimesRoman10_Character_112,TimesRoman10_Character_113,TimesRoman10_Character_114,TimesRoman10_Character_115,TimesRoman10_Character_116,TimesRoman10_Character_117,TimesRoman10_Character_118,TimesRoman10_Character_119,TimesRoman10_Character_120,TimesRoman10_Character_121,TimesRoman10_Character_122,TimesRoman10_Character_123,TimesRoman10_Character_124,TimesRoman10_Character_125,TimesRoman10_Character_126,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, +TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, +TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042, +TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontTimesRoman10 = { "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", 93, 13, TimesRoman10_Character_Map, 0.0f, 3.0f }; + +static const GLubyte TimesRoman24_Character_032[] = { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* " " */ +static const GLubyte TimesRoman24_Character_097[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113,128,251, 0,199, 0,195, 0,195, 0, 99, 0, 59, 0, 15, 0, 3, 0, 99, 0,103, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "a" */ +static const GLubyte TimesRoman24_Character_098[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,110, 0, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "b" */ +static const GLubyte TimesRoman24_Character_099[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,127, 0,112,128,224, 0,192, 0,192, 0,192, 0,192, 0,192, 0, 65,128, 99,128, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "c" */ +static const GLubyte TimesRoman24_Character_100[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,192,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128, 1,128, 1,128, 1,128, 1,128, 3,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "d" */ +static const GLubyte TimesRoman24_Character_101[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,127, 0,112,128,224, 0,192, 0,192, 0,192, 0,255,128,193,128, 65,128, 99, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "e" */ +static const GLubyte TimesRoman24_Character_102[] = { 7, 0, 0, 0, 0, 0, 0,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,254, 48, 48, 48, 22, 14, 0, 0, 0, 0, 0}; /* "f" */ +static const GLubyte TimesRoman24_Character_103[] = { 12, 0, 0, 63, 0,241,192,192, 96,192, 32, 96, 96, 63,192,127, 0, 96, 0, 48, 0, 62, 0, 51, 0, 97,128, 97,128, 97,128, 97,128, 51, 0, 31,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "g" */ +static const GLubyte TimesRoman24_Character_104[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,103, 0, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "h" */ +static const GLubyte TimesRoman24_Character_105[] = { 6, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224, 0, 0, 0, 96, 96, 0, 0, 0, 0, 0}; /* "i" */ +static const GLubyte TimesRoman24_Character_106[] = { 6, 0,192,224, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,112, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0}; /* "j" */ +static const GLubyte TimesRoman24_Character_107[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,243,224, 97,192, 99,128,103, 0,110, 0,108, 0,120, 0,104, 0,100, 0,102, 0, 99, 0,103,192, 96, 0, 96, 0, 96, 0, 96, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "k" */ +static const GLubyte TimesRoman24_Character_108[] = { 6, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224, 0, 0, 0, 0, 0}; /* "l" */ +static const GLubyte TimesRoman24_Character_109[] = { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,227,192, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128,113,227,128,111,159, 0,231, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "m" */ +static const GLubyte TimesRoman24_Character_110[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "n" */ +static const GLubyte TimesRoman24_Character_111[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,115,128, 97,128,192,192,192,192,192,192,192,192,192,192,192,192, 97,128,115,128, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "o" */ +static const GLubyte TimesRoman24_Character_112[] = { 12, 0, 0,240, 0, 96, 0, 96, 0, 96, 0, 96, 0,110, 0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "p" */ +static const GLubyte TimesRoman24_Character_113[] = { 12, 0, 0, 3,192, 1,128, 1,128, 1,128, 1,128, 29,128,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "q" */ +static const GLubyte TimesRoman24_Character_114[] = { 8, 0, 0, 0, 0, 0, 0,240, 96, 96, 96, 96, 96, 96, 96, 96,118,110,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "r" */ +static const GLubyte TimesRoman24_Character_115[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 0,198, 0,131, 0, 3, 0, 7, 0, 30, 0,124, 0,112, 0,224, 0,194, 0,102, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "s" */ +static const GLubyte TimesRoman24_Character_116[] = { 7, 0, 0, 0, 0, 0, 0, 28, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48,254,112, 48, 16, 0, 0, 0, 0, 0, 0, 0}; /* "t" */ +static const GLubyte TimesRoman24_Character_117[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,224, 62,192,113,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,225,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "u" */ +static const GLubyte TimesRoman24_Character_118[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 14, 0, 14, 0, 26, 0, 25, 0, 25, 0, 49, 0, 48,128, 48,128, 96,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "v" */ +static const GLubyte TimesRoman24_Character_119[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 16, 0, 14, 56, 0, 14, 56, 0, 26, 40, 0, 26,100, 0, 25,100, 0, 49,100, 0, 48,194, 0, 48,194, 0, 96,194, 0, 96,195, 0,241,231,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "w" */ +static const GLubyte TimesRoman24_Character_120[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241,224, 96,192, 33,128, 51,128, 27, 0, 14, 0, 12, 0, 26, 0, 57, 0, 49,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "x" */ +static const GLubyte TimesRoman24_Character_121[] = { 11, 0, 0,224, 0,240, 0, 24, 0, 8, 0, 12, 0, 4, 0, 14, 0, 14, 0, 26, 0, 25, 0, 25, 0, 49, 0, 48,128, 48,128, 96,128, 96,192,241,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "y" */ +static const GLubyte TimesRoman24_Character_122[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0,195, 0, 97, 0,112, 0, 48, 0, 56, 0, 24, 0, 28, 0, 14, 0,134, 0,195, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "z" */ +static const GLubyte TimesRoman24_Character_065[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31,128, 48, 6, 0, 16, 6, 0, 16, 12, 0, 24, 12, 0, 8, 12, 0, 15,248, 0, 12, 24, 0, 4, 24, 0, 4, 48, 0, 6, 48, 0, 2, 48, 0, 2, 96, 0, 1, 96, 0, 1,192, 0, 1,192, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "A" */ +static const GLubyte TimesRoman24_Character_066[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,224, 48,120, 48, 24, 48, 12, 48, 12, 48, 12, 48, 24, 48, 56, 63,224, 48, 64, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "B" */ +static const GLubyte TimesRoman24_Character_067[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 30, 56, 56, 8, 96, 4, 96, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0,192, 0, 96, 4, 96, 4, 56, 12, 28, 60, 7,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "C" */ +static const GLubyte TimesRoman24_Character_068[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,192, 0, 48,112, 0, 48, 56, 0, 48, 12, 0, 48, 12, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 12, 0, 48, 12, 0, 48, 56, 0, 48,112, 0,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "D" */ +static const GLubyte TimesRoman24_Character_069[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248, 48, 24, 48, 8, 48, 8, 48, 0, 48, 0, 48, 64, 48, 64, 63,192, 48, 64, 48, 64, 48, 0, 48, 0, 48, 16, 48, 16, 48, 48,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "E" */ +static const GLubyte TimesRoman24_Character_070[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 32, 48, 32, 63,224, 48, 32, 48, 32, 48, 0, 48, 0, 48, 16, 48, 16, 48, 48,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "F" */ +static const GLubyte TimesRoman24_Character_071[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 30, 56, 0, 56, 28, 0, 96, 12, 0, 96, 12, 0,192, 12, 0,192, 12, 0,192, 63, 0,192, 0, 0,192, 0, 0,192, 0, 0,192, 0, 0, 96, 4, 0, 96, 4, 0, 56, 12, 0, 28, 60, 0, 7,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "G" */ +static const GLubyte TimesRoman24_Character_072[] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31,128, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 63,254, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0, 48, 6, 0,252, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "H" */ +static const GLubyte TimesRoman24_Character_073[] = { 8, 0, 0, 0, 0, 0, 0,252, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,252, 0, 0, 0, 0, 0}; /* "I" */ +static const GLubyte TimesRoman24_Character_074[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,204, 0,198, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "J" */ +static const GLubyte TimesRoman24_Character_075[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 31, 0, 48, 14, 0, 48, 28, 0, 48, 56, 0, 48,112, 0, 48,224, 0, 49,192, 0, 51,128, 0, 63, 0, 0, 62, 0, 0, 51, 0, 0, 49,128, 0, 48,192, 0, 48, 96, 0, 48, 48, 0, 48, 24, 0,252,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "K" */ +static const GLubyte TimesRoman24_Character_076[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248, 48, 24, 48, 8, 48, 8, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "L" */ +static const GLubyte TimesRoman24_Character_077[] = { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 33,248, 32, 96, 96, 32, 96, 96, 32,208, 96, 32,208, 96, 33,136, 96, 33,136, 96, 35, 8, 96, 35, 4, 96, 38, 4, 96, 38, 2, 96, 44, 2, 96, 44, 2, 96, 56, 1, 96, 56, 1, 96, 48, 0,224,240, 0,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "M" */ +static const GLubyte TimesRoman24_Character_078[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248, 12, 0, 32, 28, 0, 32, 28, 0, 32, 52, 0, 32,100, 0, 32,100, 0, 32,196, 0, 33,132, 0, 33,132, 0, 35, 4, 0, 38, 4, 0, 38, 4, 0, 44, 4, 0, 56, 4, 0, 56, 4, 0, 48, 4, 0,240, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "N" */ +static const GLubyte TimesRoman24_Character_079[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 28, 56, 0, 56, 28, 0, 96, 6, 0, 96, 6, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0, 96, 6, 0, 96, 6, 0, 56, 28, 0, 28, 56, 0, 7,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "O" */ +static const GLubyte TimesRoman24_Character_080[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 48, 0, 63,192, 48,112, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "P" */ +static const GLubyte TimesRoman24_Character_081[] = { 18, 0, 0, 0, 0, 15, 0, 0, 56, 0, 0,112, 0, 0,224, 0, 1,192, 0, 7,224, 0, 28, 56, 0, 56, 28, 0, 96, 6, 0, 96, 6, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0,192, 3, 0, 96, 6, 0, 96, 6, 0, 56, 28, 0, 28, 56, 0, 7,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Q" */ +static const GLubyte TimesRoman24_Character_082[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 30, 48, 28, 48, 56, 48,112, 48, 96, 48,192, 49,192, 51,128, 63,192, 48,112, 48, 48, 48, 56, 48, 24, 48, 56, 48, 48, 48,112,255,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "R" */ +static const GLubyte TimesRoman24_Character_083[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,158, 0,241,128,192,192,128, 96,128, 96, 0, 96, 0,224, 3,192, 15,128, 30, 0,120, 0,224, 0,192, 64,192, 64,192,192, 99,192, 30, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "S" */ +static const GLubyte TimesRoman24_Character_084[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15,192, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,131, 4,131, 4,195, 12,255,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "T" */ +static const GLubyte TimesRoman24_Character_085[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 0, 28, 48, 0, 24, 8, 0, 48, 8, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0, 48, 4, 0,252, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "U" */ +static const GLubyte TimesRoman24_Character_086[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,128, 0, 1,128, 0, 1,128, 0, 3,192, 0, 3, 64, 0, 3, 96, 0, 6, 32, 0, 6, 32, 0, 6, 48, 0, 12, 16, 0, 12, 24, 0, 24, 8, 0, 24, 8, 0, 24, 12, 0, 48, 4, 0, 48, 6, 0,252, 31,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "V" */ +static const GLubyte TimesRoman24_Character_087[] = { 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,131, 0, 1,131, 0, 1,131,128, 3,135,128, 3, 70,128, 3, 70,192, 6, 70, 64, 6, 76, 64, 6, 76, 96, 12, 44, 96, 12, 44, 32, 24, 44, 32, 24, 24, 48, 24, 24, 16, 48, 24, 16, 48, 24, 24,252,126,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "W" */ +static const GLubyte TimesRoman24_Character_088[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 15,192, 48, 3,128, 24, 7, 0, 8, 14, 0, 4, 12, 0, 6, 24, 0, 2, 56, 0, 1,112, 0, 0,224, 0, 0,192, 0, 1,192, 0, 3,160, 0, 3, 16, 0, 6, 8, 0, 14, 12, 0, 28, 6, 0,126, 15,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "X" */ +static const GLubyte TimesRoman24_Character_089[] = { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,224, 1,128, 1,128, 1,128, 1,128, 1,128, 1,128, 3,192, 3, 64, 6, 96, 6, 32, 12, 48, 28, 16, 24, 24, 56, 8, 48, 12,252, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Y" */ +static const GLubyte TimesRoman24_Character_090[] = { 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,248,224, 24,112, 8, 48, 8, 56, 0, 24, 0, 28, 0, 14, 0, 6, 0, 7, 0, 3, 0, 3,128, 1,192,128,192,128,224,192,112,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "Z" */ +static const GLubyte TimesRoman24_Character_048[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 51, 0, 97,128, 97,128,225,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 97,128, 97,128, 51, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "0" */ +static const GLubyte TimesRoman24_Character_049[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0,120, 0, 24, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "1" */ +static const GLubyte TimesRoman24_Character_050[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,128,255,192, 96, 64, 48, 0, 24, 0, 12, 0, 4, 0, 6, 0, 3, 0, 3, 0, 1,128, 1,128,129,128,129,128, 67,128,127, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "2" */ +static const GLubyte TimesRoman24_Character_051[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,230, 0,195, 0, 1, 0, 1,128, 1,128, 1,128, 3,128, 7, 0, 30, 0, 12, 0, 6, 0,131, 0,131, 0, 71, 0,126, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "3" */ +static const GLubyte TimesRoman24_Character_052[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0,255,192,255,192,195, 0, 67, 0, 99, 0, 35, 0, 51, 0, 19, 0, 27, 0, 11, 0, 7, 0, 7, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "4" */ +static const GLubyte TimesRoman24_Character_053[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0,227,128,193,128, 0,192, 0,192, 0,192, 0,192, 1,192, 3,128, 15,128,126, 0,120, 0, 96, 0, 32, 0, 32, 0, 31,128, 31,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "5" */ +static const GLubyte TimesRoman24_Character_054[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,123,128, 97,128,224,192,192,192,192,192,192,192,192,192,193,128,243,128,238, 0, 96, 0,112, 0, 48, 0, 24, 0, 14, 0, 3,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "6" */ +static const GLubyte TimesRoman24_Character_055[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 24, 0, 12, 0, 12, 0, 12, 0, 4, 0, 6, 0, 6, 0, 2, 0, 3, 0, 3, 0, 1, 0, 1,128,129,128,192,192,255,192,127,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "7" */ +static const GLubyte TimesRoman24_Character_056[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,115,128,225,128,192,192,192,192,192,192, 65,192, 97,128, 55, 0, 30, 0, 30, 0, 51, 0, 97,128, 97,128, 97,128, 51, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "8" */ +static const GLubyte TimesRoman24_Character_057[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 28, 0, 6, 0, 3, 0, 3,128, 1,128, 29,128,115,192, 97,192,192,192,192,192,192,192,192,192,193,192, 97,128,119,128, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "9" */ +static const GLubyte TimesRoman24_Character_096[] = { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,224,128,192, 96, 0, 0, 0, 0, 0}; /* "`" */ +static const GLubyte TimesRoman24_Character_126[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131,128,199,192,124, 96, 56, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "~" */ +static const GLubyte TimesRoman24_Character_033[] = { 8, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192, 0, 0, 0, 0, 0}; /* "!" */ +static const GLubyte TimesRoman24_Character_064[] = { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 0, 14, 12, 0, 24, 0, 0, 48, 0, 0, 97,222, 0, 99,123, 0,198, 57,128,198, 24,128,198, 24,192,198, 24, 64,198, 12, 64,195, 12, 64,195,140, 64,225,252, 64, 96,236,192,112, 0,128, 56, 1,128, 28, 3, 0, 15, 14, 0, 3,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "@" */ +static const GLubyte TimesRoman24_Character_035[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 34, 0, 34, 0, 34, 0, 34, 0,255,192,255,192, 17, 0, 17, 0, 17, 0,127,224,127,224, 8,128, 8,128, 8,128, 8,128, 8,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "#" */ +static const GLubyte TimesRoman24_Character_036[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 63, 0,229,192,196,192,132, 96,132, 96, 4, 96, 4,224, 7,192, 7,128, 30, 0, 60, 0,116, 0,100, 0,100, 32,100, 96, 52,224, 31,128, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0}; /* "$" */ +static const GLubyte TimesRoman24_Character_037[] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 60, 0, 24,114, 0, 12, 97, 0, 4, 96,128, 6, 96,128, 3, 48,128, 1, 25,128, 1,143, 0,120,192, 0,228, 64, 0,194, 96, 0,193, 48, 0,193, 16, 0, 97, 24, 0, 51,252, 0, 30, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "%" */ +static const GLubyte TimesRoman24_Character_094[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,193,128, 65, 0, 99, 0, 34, 0, 54, 0, 20, 0, 28, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "^" */ +static const GLubyte TimesRoman24_Character_038[] = { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 0,127,126, 0,225,225, 0,192,192, 0,193,192, 0,193,160, 0, 99, 32, 0, 55, 16, 0, 30, 24, 0, 14, 62, 0, 15, 0, 0, 29,128, 0, 24,192, 0, 24, 64, 0, 24, 64, 0, 12,192, 0, 7,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "&" */ +static const GLubyte TimesRoman24_Character_042[] = { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 28, 0,201,128,235,128, 28, 0,235,128,201,128, 28, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "*" */ +static const GLubyte TimesRoman24_Character_040[] = { 8, 0, 4, 8, 16, 48, 32, 96, 96,192,192,192,192,192,192,192,192, 96, 96, 32, 48, 16, 8, 4, 0, 0, 0, 0, 0}; /* "(" */ +static const GLubyte TimesRoman24_Character_041[] = { 8, 0,128, 64, 32, 48, 16, 24, 24, 12, 12, 12, 12, 12, 12, 12, 12, 24, 24, 16, 48, 32, 64,128, 0, 0, 0, 0, 0}; /* ")" */ +static const GLubyte TimesRoman24_Character_045[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,240,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "-" */ +static const GLubyte TimesRoman24_Character_095[] = { 13, 0, 0,255,248,255,248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "_" */ +static const GLubyte TimesRoman24_Character_061[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,240,255,240, 0, 0, 0, 0,255,240,255,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "=" */ +static const GLubyte TimesRoman24_Character_043[] = { 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0,255,240,255,240, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "+" */ +static const GLubyte TimesRoman24_Character_091[] = { 8, 0, 0,248,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,248, 0, 0, 0, 0, 0}; /* "[" */ +static const GLubyte TimesRoman24_Character_123[] = { 10, 0, 0, 7, 0, 12, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 16, 0, 48, 0, 32, 0,192, 0, 32, 0, 48, 0, 16, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 12, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "{" */ +static const GLubyte TimesRoman24_Character_125[] = { 10, 0, 0,224, 0, 48, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 8, 0, 12, 0, 4, 0, 3, 0, 4, 0, 12, 0, 8, 0, 24, 0, 24, 0, 24, 0, 24, 0, 24, 0, 48, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "}" */ +static const GLubyte TimesRoman24_Character_093[] = { 8, 0, 0,248, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,248, 0, 0, 0, 0, 0}; /* "]" */ +static const GLubyte TimesRoman24_Character_059[] = { 7, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ";" */ +static const GLubyte TimesRoman24_Character_058[] = { 6, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ":" */ +static const GLubyte TimesRoman24_Character_044[] = { 7, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "," */ +static const GLubyte TimesRoman24_Character_046[] = { 6, 0, 0, 0, 0, 0, 0,192,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "." */ +static const GLubyte TimesRoman24_Character_060[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 1,192, 7, 0, 28, 0,112, 0,192, 0,112, 0, 28, 0, 7, 0, 1,192, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "<" */ +static const GLubyte TimesRoman24_Character_062[] = { 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 0,112, 0, 28, 0, 7, 0, 1,192, 0, 96, 1,192, 7, 0, 28, 0,112, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ">" */ +static const GLubyte TimesRoman24_Character_047[] = { 7, 0, 0, 0,192,192,192, 96, 96, 32, 48, 48, 16, 24, 24, 8, 12, 12, 4, 6, 6, 3, 3, 3, 0, 0, 0, 0, 0}; /* "/" */ +static const GLubyte TimesRoman24_Character_063[] = { 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 48, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 24, 0, 24, 0, 12, 0, 14, 0, 7, 0,195, 0,195, 0,131, 0,198, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* "?" */ +static const GLubyte TimesRoman24_Character_092[] = { 7, 0, 0, 0, 0, 0, 0, 6, 6, 4, 12, 12, 8, 24, 24, 16, 48, 48, 32, 96, 96, 64,192,192, 0, 0, 0, 0, 0}; /* "\" */ +static const GLubyte TimesRoman24_Character_034[] = { 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 0,204, 0,204, 0,204, 0,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* """ */ + +/* Missing Characters filled in by John Fay by hand ... */ +static const GLubyte TimesRoman24_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 96, 32,224,192, 0, 0, 0, 0, 0}; /* "'" */ +static const GLubyte TimesRoman24_Character_124[] = { 6, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0}; /* "|" */ + + +/* The font characters mapping: */ +static const GLubyte* TimesRoman24_Character_Map[] = {TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_032,TimesRoman24_Character_033,TimesRoman24_Character_034,TimesRoman24_Character_035, +TimesRoman24_Character_036,TimesRoman24_Character_037,TimesRoman24_Character_038,TimesRoman24_Character_039,TimesRoman24_Character_040,TimesRoman24_Character_041,TimesRoman24_Character_042,TimesRoman24_Character_043,TimesRoman24_Character_044,TimesRoman24_Character_045,TimesRoman24_Character_046,TimesRoman24_Character_047,TimesRoman24_Character_048,TimesRoman24_Character_049,TimesRoman24_Character_050,TimesRoman24_Character_051,TimesRoman24_Character_052,TimesRoman24_Character_053,TimesRoman24_Character_054,TimesRoman24_Character_055,TimesRoman24_Character_056,TimesRoman24_Character_057,TimesRoman24_Character_058,TimesRoman24_Character_059,TimesRoman24_Character_060,TimesRoman24_Character_061,TimesRoman24_Character_062,TimesRoman24_Character_063,TimesRoman24_Character_064,TimesRoman24_Character_065,TimesRoman24_Character_066,TimesRoman24_Character_067,TimesRoman24_Character_068,TimesRoman24_Character_069,TimesRoman24_Character_070,TimesRoman24_Character_071,TimesRoman24_Character_072, +TimesRoman24_Character_073,TimesRoman24_Character_074,TimesRoman24_Character_075,TimesRoman24_Character_076,TimesRoman24_Character_077,TimesRoman24_Character_078,TimesRoman24_Character_079,TimesRoman24_Character_080,TimesRoman24_Character_081,TimesRoman24_Character_082,TimesRoman24_Character_083,TimesRoman24_Character_084,TimesRoman24_Character_085,TimesRoman24_Character_086,TimesRoman24_Character_087,TimesRoman24_Character_088,TimesRoman24_Character_089,TimesRoman24_Character_090,TimesRoman24_Character_091,TimesRoman24_Character_092,TimesRoman24_Character_093,TimesRoman24_Character_094,TimesRoman24_Character_095,TimesRoman24_Character_096,TimesRoman24_Character_097,TimesRoman24_Character_098,TimesRoman24_Character_099,TimesRoman24_Character_100,TimesRoman24_Character_101,TimesRoman24_Character_102,TimesRoman24_Character_103,TimesRoman24_Character_104,TimesRoman24_Character_105,TimesRoman24_Character_106,TimesRoman24_Character_107,TimesRoman24_Character_108,TimesRoman24_Character_109, +TimesRoman24_Character_110,TimesRoman24_Character_111,TimesRoman24_Character_112,TimesRoman24_Character_113,TimesRoman24_Character_114,TimesRoman24_Character_115,TimesRoman24_Character_116,TimesRoman24_Character_117,TimesRoman24_Character_118,TimesRoman24_Character_119,TimesRoman24_Character_120,TimesRoman24_Character_121,TimesRoman24_Character_122,TimesRoman24_Character_123,TimesRoman24_Character_124,TimesRoman24_Character_125,TimesRoman24_Character_126,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, +TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, +TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042, +TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,NULL}; + +/* The font structure: */ +const SFG_Font fgFontTimesRoman24 = { "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", 93, 28, TimesRoman24_Character_Map, -1.0f, 6.0f }; + +/*** END OF FILE ***/ + diff --git a/src/freeglut_gamemode.c b/src/freeglut_gamemode.c new file mode 100644 index 0000000..d6c6a25 --- /dev/null +++ b/src/freeglut_gamemode.c @@ -0,0 +1,558 @@ +/* + * freeglut_gamemode.c + * + * The game mode handling code. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-gamemode" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * glutGameModeString() -- missing + * glutEnterGameMode() -- X11 version + * glutLeaveGameMode() -- is that correct? + * glutGameModeGet() -- is that correct? + */ + + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * Remembers the current visual settings, so that + * we can change them and restore later... + */ +void fghRememberState( void ) +{ +#if TARGET_HOST_UNIX_X11 + + /* + * This highly depends on the XFree86 extensions, not approved as X Consortium standards + */ +# ifdef X_XF86VidModeGetModeLine + + /* + * Query the current display settings: + */ + XF86VidModeGetModeLine( + fgDisplay.Display, + fgDisplay.Screen, + &fgDisplay.DisplayModeClock, + &fgDisplay.DisplayMode + ); + +# else +# warning fghRememberState: missing XFree86 video mode extensions, game mode will not change screen resolution when activated +# endif + +#elif TARGET_HOST_WIN32 + +/* DEVMODE devMode; */ + + /* + * Grab the current desktop settings... + */ + +/* hack to get around my stupid cross-gcc headers */ +#define FREEGLUT_ENUM_CURRENT_SETTINGS -1 + + EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, &fgDisplay.DisplayMode ); + + /* + * Make sure we will be restoring all settings needed + */ + fgDisplay.DisplayMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + +#endif +} + +/* + * Restores the previously remembered visual settings + */ +void fghRestoreState( void ) +{ +#if TARGET_HOST_UNIX_X11 + + /* + * This highly depends on the XFree86 extensions, not approved as X Consortium standards + */ +# ifdef X_XF86VidModeGetAllModeLines + + XF86VidModeModeInfo** displayModes; + int i, displayModesCount; + + /* + * Query for all the display available... + */ + XF86VidModeGetAllModeLines( + fgDisplay.Display, + fgDisplay.Screen, + &displayModesCount, + &displayModes + ); + + /* + * Check every of the modes looking for one that matches our demands + */ + for( i=0; ihdisplay == fgDisplay.DisplayMode.hdisplay && + displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay && + displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock ) + { + /* + * OKi, this is the display mode we have been looking for... + */ + XF86VidModeSwitchToMode( + fgDisplay.Display, + fgDisplay.Screen, + displayModes[ i ] + ); + + /* + * In case this will be the last X11 call we do before exit, + * we've to flush the X11 output queue to be sure the command + * is really brought onto it's way to the X server. + * The application should not do this because it + * would not be platform independent then. + */ + XFlush(fgDisplay.Display); + + return; + } + } + +# else +# warning fghRestoreState: missing XFree86 video mode extensions, game mode will not change screen resolution when activated +# endif + +#elif TARGET_HOST_WIN32 + + /* + * Restore the previously rememebered desktop display settings + */ + ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 ); + +#endif +} + +/* + * Checks the display mode settings against user's preferences + */ +GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh ) +{ + /* + * The desired values should be stored in fgState structure... + */ + return( (width == fgState.GameModeSize.X) && (height == fgState.GameModeSize.Y) && + (depth == fgState.GameModeDepth) && (refresh == fgState.GameModeRefresh) ); +} + +/* + * Changes the current display mode to match user's settings + */ +GLboolean fghChangeDisplayMode( GLboolean haveToTest ) +{ +#if TARGET_HOST_UNIX_X11 + + /* + * This highly depends on the XFree86 extensions, not approved as X Consortium standards + */ +# ifdef X_XF86VidModeGetAllModeLines + + XF86VidModeModeInfo** displayModes; + int i, displayModesCount; + + /* + * Query for all the display available... + */ + XF86VidModeGetAllModeLines( + fgDisplay.Display, + fgDisplay.Screen, + &displayModesCount, + &displayModes + ); + + /* + * Check every of the modes looking for one that matches our demands + */ + for( i=0; ihdisplay, displayModes[ i ]->vdisplay, + fgState.GameModeDepth, fgState.GameModeRefresh ) ) + { + if( haveToTest ) + return( TRUE ); + /* + * OKi, this is the display mode we have been looking for... + */ + XF86VidModeSwitchToMode( + fgDisplay.Display, + fgDisplay.Screen, + displayModes[ i ] + ); + + /* + * Set the viewport's origin to (0,0) (the game mode window's top-left corner) + */ + XF86VidModeSetViewPort( + fgDisplay.Display, + fgDisplay.Screen, + 0, + 0 + ); + + /* + * Return successfull... + */ + return( TRUE ); + } + } + + /* + * Something must have went wrong + */ + return( FALSE ); + +# else +# warning fghChangeDisplayMode: missing XFree86 video mode extensions, game mode will not change screen resolution when activated +# endif + +#elif TARGET_HOST_WIN32 + + unsigned int displayModes = 0, mode = 0xffffffff; + GLboolean success = FALSE; +/* HDC desktopDC; */ + DEVMODE devMode; + + /* + * Enumerate the available display modes + * Try to get a complete match + */ + while( EnumDisplaySettings( NULL, displayModes, &devMode ) == TRUE ) + { + /* + * Does the enumerated display mode match the user's preferences? + */ + if( fghCheckDisplayMode( devMode.dmPelsWidth, devMode.dmPelsHeight, + devMode.dmBitsPerPel, devMode.dmDisplayFrequency ) ) + { + /* + * OKi, we've found a matching display mode, remember its number and break + */ + mode = displayModes; + break; + } + + /* + * Switch to the next display mode, if any + */ + displayModes++; + } + + if ( mode == 0xffffffff ) + { + /* then try without Display Frequency */ + displayModes = 0; + + /* + * Enumerate the available display modes + */ + while( EnumDisplaySettings( NULL, displayModes, &devMode ) == TRUE ) + { + /* then try without Display Frequency */ + + if( fghCheckDisplayMode( devMode.dmPelsWidth, devMode.dmPelsHeight, + devMode.dmBitsPerPel, fgState.GameModeRefresh)) + { + /* + * OKi, we've found a matching display mode, remember its number and break + */ + mode = displayModes; + break; + } + + /* + * Switch to the next display mode, if any + */ + displayModes++; + } + } + + /* + * Did we find a matching display mode? + */ + if( mode != 0xffffffff ) + { + int retVal = DISP_CHANGE_SUCCESSFUL; + + /* + * Mark the values we want to modify in the display change call + */ + devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + + /* + * Change the current display mode (possibly in test mode only) + */ + retVal = ChangeDisplaySettings( &devMode, haveToTest ? CDS_TEST : 0 ); + + /* + * I don't know if it's really needed, but looks nice: + */ + success = (retVal == DISP_CHANGE_SUCCESSFUL) || (retVal == DISP_CHANGE_NOTUPDATED); + + /* + * If it was not a test, remember the current screen settings + */ + if( !haveToTest && success ) + { + fgState.GameModeSize.X = devMode.dmPelsWidth; + fgState.GameModeSize.Y = devMode.dmPelsHeight; + fgState.GameModeDepth = devMode.dmBitsPerPel; + fgState.GameModeRefresh = devMode.dmDisplayFrequency; + } + } + + /* + * Otherwise we must have failed somewhere + */ + return( success ); + +#endif +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Sets the game mode display string + */ +void FGAPIENTRY glutGameModeString( const char* string ) +{ + int width = 640, height = 480, depth = 16, refresh = 72; + + /* + * This one seems a bit easier than glutInitDisplayString. The bad thing + * about it that I was unable to find the game mode string definition, so + * that I assumed it is: "[width]x[height]:[depth]@[refresh rate]", which + * appears in all GLUT game mode programs I have seen to date. + */ + if( sscanf( string, "%ix%i:%i@%i", &width, &height, &depth, &refresh ) != 4 ) + if( sscanf( string, "%ix%i:%i", &width, &height, &depth ) != 3 ) + if( sscanf( string, "%ix%i@%i", &width, &height, &refresh ) != 3 ) + if( sscanf( string, "%ix%i", &width, &height ) != 2 ) + if( sscanf( string, ":%i@%i", &depth, &refresh ) != 2 ) + if( sscanf( string, ":%i", &depth ) != 1 ) + if( sscanf( string, "@%i", &refresh ) != 1 ) + fgWarning( "unable to parse game mode string `%s'", string ); + + /* + * Hopefully it worked, and if not, we still have the default values + */ + fgState.GameModeSize.X = width; + fgState.GameModeSize.Y = height; + fgState.GameModeDepth = depth; + fgState.GameModeRefresh = refresh; +} + +/* + * Enters the game mode + */ +int FGAPIENTRY glutEnterGameMode( void ) +{ + /* + * Check if a game mode window already exists... + */ + if( fgStructure.GameMode != NULL ) + { + /* + * ...if so, delete it before proceeding... + */ + fgAddToWindowDestroyList( fgStructure.GameMode, TRUE ); + } + else + { + /* + * ...otherwise remember the current resolution, etc. + */ + fghRememberState(); + } + + /* + * We are ready to change the current screen's resolution now + */ + if( fghChangeDisplayMode( FALSE ) == FALSE ) + { + fgWarning( "failed to change screen settings" ); + return( FALSE ); + } + + /* + * Finally, have the game mode window created + */ + fgStructure.GameMode = fgCreateWindow( + NULL, "FREEGLUT", 0, 0, fgState.GameModeSize.X, fgState.GameModeSize.Y, TRUE + ); + +#if TARGET_HOST_UNIX_X11 + + /* + * Move the mouse pointer over the game mode window + */ + XSetInputFocus( + fgDisplay.Display, + fgStructure.GameMode->Window.Handle, + RevertToNone, + CurrentTime + ); + + /* + * Confine the mouse pointer to the window's client area + */ + XGrabPointer( + fgDisplay.Display, + fgStructure.GameMode->Window.Handle, + TRUE, + ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|PointerMotionMask, + GrabModeAsync, GrabModeAsync, + fgStructure.GameMode->Window.Handle, + None, + CurrentTime + ); + + /* + * Grab the keyboard, too + */ + XGrabKeyboard( + fgDisplay.Display, + fgStructure.GameMode->Window.Handle, + FALSE, + GrabModeAsync, GrabModeAsync, + CurrentTime + ); + +#endif + + /* + * Return successfull + */ + return( TRUE ); +} + +/* + * Leaves the game mode + */ +void FGAPIENTRY glutLeaveGameMode( void ) +{ + freeglut_return_if_fail( fgStructure.GameMode != NULL ); + + /* + * First of all, have the game mode window destroyed + */ + fgAddToWindowDestroyList( fgStructure.GameMode, TRUE ); + +#if TARGET_HOST_UNIX_X11 + + /* + * Ungrab the mouse and keyboard + */ + XUngrabPointer( fgDisplay.Display, CurrentTime ); + XUngrabKeyboard( fgDisplay.Display, CurrentTime ); + +#endif + + /* + * Then, have the desktop visual settings restored + */ + fghRestoreState(); +} + +/* + * Returns information concerning the freeglut game mode + */ +int FGAPIENTRY glutGameModeGet( GLenum eWhat ) +{ + /* + * See why are we bothered + */ + switch( eWhat ) + { + case GLUT_GAME_MODE_ACTIVE: + /* + * Check if the game mode is currently active + */ + return( fgStructure.GameMode != NULL ); + + case GLUT_GAME_MODE_POSSIBLE: + /* + * Check if the current game mode settings are valid + */ + return( fghChangeDisplayMode( TRUE ) ); + + case GLUT_GAME_MODE_WIDTH: + /* + * The game mode screen width + */ + return( fgState.GameModeSize.X ); + + case GLUT_GAME_MODE_HEIGHT: + /* + * The game mode screen height + */ + return( fgState.GameModeSize.Y ); + + case GLUT_GAME_MODE_PIXEL_DEPTH: + /* + * The game mode pixel depth + */ + return( fgState.GameModeDepth ); + + case GLUT_GAME_MODE_REFRESH_RATE: + /* + * The game mode refresh rate + */ + return( fgState.GameModeRefresh ); + + case GLUT_GAME_MODE_DISPLAY_CHANGED: + /* + * This is true if the game mode has been activated successfully.. + */ + return( fgStructure.GameMode != NULL ); + } + + return( -1 ); +} + +/*** END OF FILE ***/ + + + + diff --git a/src/freeglut_geometry.c b/src/freeglut_geometry.c new file mode 100644 index 0000000..23ba7d6 --- /dev/null +++ b/src/freeglut_geometry.c @@ -0,0 +1,1049 @@ +/* + * freeglut_geometry.c + * + * Freeglut geometry rendering methods. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-geometry" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * Following functions have been contributed by Andreas Umbach. + * + * glutWireCube() -- looks OK + * glutSolidCube() -- OK + * glutWireSphere() -- OK + * glutSolidSphere() -- OK + * + * Following functions have been implemented by Pawel and modified by John Fay: + * + * glutWireCone() -- looks OK + * glutSolidCone() -- looks OK + * + * Those functions have been implemented by John Fay. + * + * glutWireTorus() -- looks OK + * glutSolidTorus() -- looks OK + * glutWireDodecahedron() -- looks OK + * glutSolidDodecahedron() -- looks OK + * glutWireOctahedron() -- looks OK + * glutSolidOctahedron() -- looks OK + * glutWireTetrahedron() -- looks OK + * glutSolidTetrahedron() -- looks OK + * glutWireIcosahedron() -- looks OK + * glutSolidIcosahedron() -- looks OK + */ + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Draws a wireframed cube. Code contributed by Andreas Umbach + */ +void FGAPIENTRY glutWireCube( GLdouble dSize ) +{ + double size = dSize * 0.5; + +# define V(a,b,c) glVertex3d( a size, b size, c size ); +# define N(a,b,c) glNormal3d( a, b, c ); + + /* + * PWO: I dared to convert the code to use macros... + */ + glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd(); + glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd(); + glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd(); + +# undef V +# undef N +} + +/* + * Draws a solid cube. Code contributed by Andreas Umbach + */ +void FGAPIENTRY glutSolidCube( GLdouble dSize ) +{ + double size = dSize * 0.5; + +# define V(a,b,c) glVertex3d( a size, b size, c size ); +# define N(a,b,c) glNormal3d( a, b, c ); + + /* + * PWO: Again, I dared to convert the code to use macros... + */ + glBegin( GL_QUADS ); + N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); + N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); + N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); + N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); + N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); + N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); + glEnd(); + +# undef V +# undef N +} + +/* + * Draws a wire sphere. Code contributed by Andreas Umbach + */ +void FGAPIENTRY glutWireSphere( GLdouble dRadius, GLint slices, GLint stacks ) +{ + double radius = dRadius, phi, psi, dpsi, dphi; + double *vertex; + int i, j; + double cphi, sphi, cpsi, spsi ; + + /* + * Allocate the vertices array + */ + vertex = calloc( sizeof(double), 3 * slices * (stacks - 1) ); + + glPushMatrix(); + glScaled( radius, radius, radius ); + + dpsi = M_PI / (stacks + 1); + dphi = 2 * M_PI / slices; + psi = dpsi; + + for( j=0; j + */ +void FGAPIENTRY glutSolidSphere( GLdouble dRadius, GLint slices, GLint stacks ) +{ + double radius = dRadius, phi, psi, dpsi, dphi; + double *next, *tmp, *row; + int i, j; + double cphi, sphi, cpsi, spsi ; + + glPushMatrix(); + /* glScalef( radius, radius, radius ); */ + + row = calloc( sizeof(double), slices * 3 ); + next = calloc( sizeof(double), slices * 3 ); + + dpsi = M_PI / (stacks + 1); + dphi = 2 * M_PI / slices; + psi = dpsi; + phi = 0; + + /* init first line + do polar cap */ + glBegin( GL_TRIANGLE_FAN ); + glNormal3d( 0.0, 0.0, 1.0 ); + glVertex3d( 0.0, 0.0, radius ); + + for( i=0; i=0; i-- ) + { + glNormal3dv(row + 3 * i); + glVertex3d( + radius * *(row + 3 * i + 0), + radius * *(row + 3 * i + 1), + radius * *(row + 3 * i + 2) + ); + } + + glEnd(); + + free(row); + free(next); + glPopMatrix(); +} + +/* + * Draws a wire cone + */ +void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ) +{ + double alt = height / (double) (stacks + 1); + double angle = M_PI / (double) slices * 2.0; + double slope = ( height / base ); + double sBase = base ; + double sinNormal = ( base / sqrt ( height * height + base * base )) ; + double cosNormal = ( height / sqrt ( height * height + base * base )) ; + + double *vertices = NULL; + int i, j; + + /* + * We need 'slices' points on a circle + */ + vertices = calloc( sizeof(double), 2 * (slices + 1) ); + + for( j=0; j + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-init" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * fgDeinitialize() -- Win32's OK, X11 needs the OS-specific deinitialization done + * glutInitDisplayString() -- display mode string parsing + * + * Wouldn't it be cool to use gettext() for error messages? I just love bash saying + * "nie znaleziono pliku" instead of "file not found" :) Is gettext easily portable? + */ + +/* -- GLOBAL VARIABLES ----------------------------------------------------- */ + +/* + * A structure pointed by g_pDisplay holds all information + * regarding the display, screen, root window etc. + */ +SFG_Display fgDisplay; + +/* + * The settings for the current freeglut session + */ +SFG_State fgState = { { -1, -1, FALSE }, /* Position */ + { 300, 300, TRUE }, /* Size */ + GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH, /* DisplayMode */ + FALSE, /* ForceDirectContext */ + TRUE, /* TryDirectContext */ + FALSE, /* ForceIconic */ + FALSE, /* GLDebugSwitch */ + FALSE, /* XSyncSwitch */ + TRUE, /* IgnoreKeyRepeat */ + 0, /* FPSInterval */ + 0, /* SwapCount */ + 0, /* SwapTime */ +#ifdef TARGET_HOST_WIN32 + { 0, FALSE }, /* Time */ +#else + { { 0, 0 }, FALSE }, +#endif + { NULL, NULL }, /* Timers */ + NULL, /* IdleCallback */ + NULL, /* MenuStateCallback */ + NULL, /* MenuStatusCallback */ + { 640, 480, TRUE }, /* GameModeSize */ + 16, /* GameModeDepth */ + 72, /* GameModeRefresh */ + GLUT_ACTION_EXIT, /* ActionOnWindowClose */ + GLUT_EXEC_STATE_INIT /* ExecState */ +}; + + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * A call to this function should initialize all the display stuff... + */ +void fgInitialize( const char* displayName ) +{ +#if TARGET_HOST_UNIX_X11 + /* + * Have the display created + */ + fgDisplay.Display = XOpenDisplay( displayName ); + + if( fgDisplay.Display == NULL ) + { + /* + * Failed to open a display. That's no good. + */ + fgError( "failed to open display '%s'", XDisplayName( displayName ) ); + } + + /* + * Check for the OpenGL GLX extension availability: + */ + if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) ) + { + /* + * GLX extensions have not been found... + */ + fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) ); + } + + /* + * Grab the default screen for the display we have just opened + */ + fgDisplay.Screen = DefaultScreen( fgDisplay.Display ); + + /* + * The same applying to the root window + */ + fgDisplay.RootWindow = RootWindow( + fgDisplay.Display, + fgDisplay.Screen + ); + + /* + * Grab the logical screen's geometry + */ + fgDisplay.ScreenWidth = DisplayWidth( + fgDisplay.Display, + fgDisplay.Screen + ); + + fgDisplay.ScreenHeight = DisplayHeight( + fgDisplay.Display, + fgDisplay.Screen + ); + + /* + * Grab the physical screen's geometry + */ + fgDisplay.ScreenWidthMM = DisplayWidthMM( + fgDisplay.Display, + fgDisplay.Screen + ); + + fgDisplay.ScreenHeightMM = DisplayHeightMM( + fgDisplay.Display, + fgDisplay.Screen + ); + + /* + * The display's connection number + */ + fgDisplay.Connection = ConnectionNumber( fgDisplay.Display ); + + /* + * Create the window deletion atom + */ + fgDisplay.DeleteWindow = XInternAtom( + fgDisplay.Display, + "WM_DELETE_WINDOW", + FALSE + ); + +#elif TARGET_HOST_WIN32 + + WNDCLASS wc; + ATOM atom; + + /* + * What we need to do is to initialize the fgDisplay global structure here... + */ + fgDisplay.Instance = GetModuleHandle( NULL ); + + /* + * Check if the freeglut window class has been registered before... + */ + atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc ); + + /* + * ...nope, it has not, and we have to do it right now: + */ + if( atom == 0 ) + { + /* + * Make sure the unitialized fields are reset to zero + */ + ZeroMemory( &wc, sizeof(WNDCLASS) ); + + /* + * Each of the windows should have its own device context... + */ + wc.style = CS_OWNDC; + wc.lpfnWndProc = fgWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = fgDisplay.Instance; + wc.hIcon = LoadIcon( fgDisplay.Instance, "GLUT_ICON" ); + if (!wc.hIcon) + wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); + + wc.hCursor = LoadCursor( NULL, IDC_ARROW ); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "FREEGLUT"; + + /* + * Register the window class + */ + atom = RegisterClass( &wc ); + assert( atom != 0 ); + } + + /* + * The screen dimensions can be obtained via GetSystemMetrics() calls + */ + fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN ); + fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN ); + + { + /* + * Checking the display's size in millimeters isn't too hard, too: + */ + HWND desktop = GetDesktopWindow(); + HDC context = GetDC( desktop ); + + /* + * Grab the appropriate values now (HORZSIZE and VERTSIZE respectably): + */ + fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE ); + fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE ); + + /* + * Whoops, forgot to release the device context :) + */ + ReleaseDC( desktop, context ); + } + +#endif + + /* + * Have the joystick device initialized now + */ + fgJoystickInit( 0 ); +} + +/* + * Perform the freeglut deinitialization... + */ +void fgDeinitialize( void ) +{ + SFG_Timer *timer; + + /* + * Check if initialization has been performed before + */ + if( !fgState.Time.Set ) + { + fgWarning( "fgDeinitialize(): fgState.Timer is null => no valid initialization has been performed" ); + return; + } + + /* + * Perform the freeglut structure deinitialization + */ + fgDestroyStructure(); + + /* + * Delete all the timers and their storage list + */ + while ( (timer = fgState.Timers.First) != NULL ) + { + fgListRemove ( &fgState.Timers, &timer->Node ) ; + free ( timer ) ; + } + + /* + * Deinitialize the joystick device + */ + fgJoystickClose(); + + /* + * Reset the state structure + */ + + fgState.Position.X = -1 ; + fgState.Position.Y = -1 ; + fgState.Position.Use = FALSE ; + + fgState.Size.X = 300 ; + fgState.Size.Y = 300 ; + fgState.Size.Use = TRUE ; + + /* + * The default display mode to be used + */ + fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH; + + fgState.ForceDirectContext = FALSE; + fgState.TryDirectContext = TRUE; + fgState.ForceIconic = FALSE; + fgState.GLDebugSwitch = FALSE; + fgState.XSyncSwitch = FALSE; + fgState.ActionOnWindowClose = GLUT_ACTION_EXIT ; + fgState.ExecState = GLUT_EXEC_STATE_INIT ; + + /* + * Assume we want to ignore the automatic key repeat + */ + fgState.IgnoreKeyRepeat = TRUE; + + /* + * Set the default game mode settings + */ + fgState.GameModeSize.X = 640; + fgState.GameModeSize.Y = 480; + fgState.GameModeDepth = 16; + fgState.GameModeRefresh = 72; + + fgState.Time.Set = FALSE ; + + fgState.Timers.First = fgState.Timers.Last = NULL ; + fgState.IdleCallback = NULL ; + fgState.MenuStateCallback = (FGCBmenuState)NULL ; + fgState.MenuStatusCallback = (FGCBmenuStatus)NULL ; + + /* + * FPS display + */ + fgState.SwapCount = 0; + fgState.SwapTime = 0; + fgState.FPSInterval = 0; + + +#if TARGET_HOST_UNIX_X11 + + /* + * Make sure all X-client data we have created will be destroyed on display closing + */ + XSetCloseDownMode( fgDisplay.Display, DestroyAll ); + + /* + * Close the display connection, destroying all windows we have created so far + */ + XCloseDisplay( fgDisplay.Display ); + +#endif +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Perform initialization. This usually happens on the program startup + * and restarting after glutMainLoop termination... + */ +void FGAPIENTRY glutInit( int* pargc, char** argv ) +{ + char* displayName = NULL; + int i, j, argc = *pargc; + + /* + * Do not allow multiple initialization of the library + */ + if( fgState.Time.Set ) + { + /* + * We can't have multiple initialization performed + */ + fgError( "illegal glutInit() reinitialization attemp" ); + } + + /* + * Have the internal freeglut structure initialized now + */ + fgCreateStructure(); + + /* + * Remember the function's call time + */ +#if TARGET_HOST_UNIX_X11 + gettimeofday(&fgState.Time.Value, NULL); +#elif TARGET_HOST_WIN32 + fgState.Time.Value = timeGetTime(); +#endif + fgState.Time.Set = TRUE; + + /* check if GLUT_FPS env var is set */ + { + const char *fps = getenv("GLUT_FPS"); + if (fps) { + sscanf(fps, "%d", &fgState.FPSInterval); + if (fgState.FPSInterval <= 0) + fgState.FPSInterval = 5000; /* 5000 milliseconds */ + } + } + + /* + * Grab the environment variable indicating the X display to use. + * This is harmless under Win32, so let's let it stay here... + */ +#if TARGET_HOST_WIN32 + if ( !getenv ( "DISPLAY" ) ) + displayName = strdup ( "" ) ; + else +#endif + displayName = strdup( getenv( "DISPLAY" ) ); + + /* + * Have the program arguments parsed. + */ + for( i=1; i= argc ) + fgError( "-display parameter must be followed by display name" ); + + /* + * Release the previous display name (the one from app's environment) + */ + free( displayName ); + + /* + * Make a working copy of the name for us to use + */ + displayName = strdup( argv[ i ] ); + + /* + * Have both arguments removed + */ + argv[ i - 1 ] = NULL; + argv[ i ] = NULL; + (* pargc) -= 2; + } + + /* + * The geometry settings + */ + else if( strcmp( argv[ i ], "-geometry" ) == 0 ) + { + int result, x, y; + unsigned int w, h; + + /* + * Again, check if there is at least one more argument + */ + if ( ++i >= argc ) + fgError( "-geometry parameter must be followed by window geometry settings" ); + + /* + * Otherwise scan the geometry settings... + */ + result = sscanf ( argv[i], "%dx%d+%d+%d", &x, &y, &w, &h ); + + /* + * Check what we have been supplied with... + */ + if ( result > 3 ) + fgState.Size.Y = h ; + + if ( result > 2 ) + fgState.Size.X = w ; + + if( result > 1 ) + { + if( y < 0 ) + fgState.Position.Y = fgDisplay.ScreenHeight + y - fgState.Size.Y; + else + fgState.Position.Y = y; + } + + if( result > 0 ) + { + if( x < 0 ) + fgState.Position.X = fgDisplay.ScreenWidth + x - fgState.Size.X; + else + fgState.Position.X = x; + } + + /* + * Have both arguments removed + */ + argv[ i - 1 ] = NULL; + argv[ i ] = NULL; + (* pargc) -= 2; + } + + /* + * The direct/indirect OpenGL contexts settings + */ + else if( strcmp( argv[ i ], "-direct" ) == 0) + { + /* + * We try to force direct rendering... + */ + if( fgState.TryDirectContext == FALSE ) + fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" ); + + fgState.ForceDirectContext = TRUE; + argv[ i ] = NULL; + (* pargc)--; + } + else if( strcmp( argv[ i ], "-indirect" ) == 0 ) + { + /* + * We try to force indirect rendering... + */ + if( fgState.ForceDirectContext == TRUE ) + fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" ); + + fgState.TryDirectContext = FALSE; + argv[ i ] = NULL; + (* pargc)--; + } + + /* + * The '-iconic' parameter makes all new top-level + * windows created in iconified state... + */ + else if( strcmp( argv[ i ], "-iconic" ) == 0 ) + { + fgState.ForceIconic = TRUE; + argv[ i ] = NULL; + (* pargc)--; + } + + /* + * The '-gldebug' option activates some OpenGL state debugging features + */ + else if( strcmp( argv[ i ], "-gldebug" ) == 0 ) + { + fgState.GLDebugSwitch = TRUE; + argv[ i ] = NULL; + (* pargc)--; + } + + /* + * The '-sync' option activates X protocol synchronization (for debugging purposes) + */ + else if( strcmp( argv[ i ], "-sync" ) == 0 ) + { + fgState.XSyncSwitch = TRUE; + argv[ i ] = NULL; + (* pargc)--; + } + } + + /* + * Have the arguments list compacted now + */ + j = 2 ; + for( i = 1; i < *pargc; i++, j++ ) + { + if( argv[ i ] == NULL ) + { + while ( argv[j] == NULL ) j++ ; /* Guaranteed to end because there are "*pargc" arguments left */ + argv[i] = argv[j] ; + } + } + + /* + * Have the display created now. As I am too lazy to implement + * the program arguments parsing, we will have the DISPLAY + * environment variable used for opening the X display: + */ + fgInitialize( displayName ); + + /* + * Check for the minus one settings for both position and size... + */ + if( fgState.Position.X < 0 || fgState.Position.Y < 0 ) + fgState.Position.Use = FALSE; + + if( fgState.Size.X < 0 || fgState.Size.Y < 0 ) + fgState.Size.Use = FALSE; + + /* + * Do not forget about releasing the display name string + */ + free( displayName ); +} + +/* + * Sets the default initial window position for new windows + */ +void FGAPIENTRY glutInitWindowPosition( int x, int y ) +{ + /* + * The settings can be disables when both coordinates are negative + */ + if( (x >= 0) && (y >= 0) ) + { + /* + * We want to specify the initial position of each of the windows + */ + fgState.Position.X = x; + fgState.Position.Y = y; + fgState.Position.Use = TRUE; + } + else + { + /* + * The initial position of each of the windows is specified by the wm + */ + fgState.Position.X = -1; + fgState.Position.Y = -1; + fgState.Position.Use = FALSE; + } +} + +/* + * Sets the default initial window size for new windows + */ +void FGAPIENTRY glutInitWindowSize( int width, int height ) +{ + /* + * The settings can be disables when both values are negative + */ + if( (width > 0) && (height > 0) ) + { + /* + * We want to specify the initial size of each of the windows + */ + fgState.Size.X = width; + fgState.Size.Y = height; + fgState.Size.Use = TRUE; + } + else + { + /* + * The initial size of each of the windows is specified by the wm (officially this is an error condition) + */ + fgState.Size.X = -1; + fgState.Size.Y = -1; + fgState.Size.Use = FALSE; + } +} + +/* + * Sets the default display mode for all new windows + */ +void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode ) +{ + /* + * We will make use of this value when creating a new OpenGL context... + */ + fgState.DisplayMode = displayMode; +} + + +/* -- INIT DISPLAY STRING PARSING ------------------------------------------ */ + +#if 0 /* FIXME: CJP */ +/* + * There is a discrete number of comparison operators we can encounter: + * + * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~" + */ +#define FG_NONE 0x0000 +#define FG_EQUAL 0x0001 +#define FG_NOT_EQUAL 0x0002 +#define FG_LESS 0x0003 +#define FG_MORE 0x0004 +#define FG_LESS_OR_EQUAL 0x0005 +#define FG_MORE_OR_EQUAL 0x0006 +#define FG_CLOSEST 0x0007 + +/* + * The caller can feed us with a number of capability tokens: + * + * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" | "depth" | "double" | + * "green" | "index" | "num" | "red" | "rgba" | "rgb" | "luminance" | "stencil" | + * "single" | "stereo" | "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" | + * "xgrayscale" | "xstaticcolor" | "xpseudocolor" | "xtruecolor" | "xdirectcolor" + */ +static gchar* g_Tokens[] = +{ + "none", "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green", + "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples", + "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor", + "xtruecolor", "xdirectcolor", NULL +}; + +/* + * The structure to hold the parsed display string tokens + */ +typedef struct tagSFG_Capability SFG_Capability; +struct tagSFG_Capability +{ + gint capability; /* the capability token enumerator */ + gint comparison; /* the comparison operator used */ + gint value; /* the value we're comparing to */ +}; + +/* + * The scanner configuration for the init display string + */ +static GScannerConfig fgInitDisplayStringScannerConfig = +{ + ( " \t\r\n" ) /* cset_skip_characters */, + ( + G_CSET_a_2_z + "_" + G_CSET_A_2_Z + ) /* cset_identifier_first */, + ( + G_CSET_a_2_z + "_0123456789" + G_CSET_A_2_Z + G_CSET_LATINS + G_CSET_LATINC + "<>!=~" + ) /* cset_identifier_nth */, + ( "#\n" ) /* cpair_comment_single */, + FALSE /* case_sensitive */, + TRUE /* skip_comment_multi */, + TRUE /* skip_comment_single */, + TRUE /* scan_comment_multi */, + TRUE /* scan_identifier */, + FALSE /* scan_identifier_1char */, + FALSE /* scan_identifier_NULL */, + TRUE /* scan_symbols */, + FALSE /* scan_binary */, + TRUE /* scan_octal */, + TRUE /* scan_float */, + TRUE /* scan_hex */, + FALSE /* scan_hex_dollar */, + TRUE /* scan_string_sq */, + TRUE /* scan_string_dq */, + TRUE /* numbers_2_int */, + FALSE /* int_2_float */, + FALSE /* identifier_2_string */, + TRUE /* char_2_token */, + FALSE /* symbol_2_token */, + FALSE /* scope_0_fallback */, +}; + +/* + * Sets the default display mode for all new windows using a string + */ +void FGAPIENTRY glutInitDisplayString( char* displayMode ) +{ + /* + * display_string ::= (switch) + * switch ::= capability [comparison value] + * comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~" + * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" | + * "depth" | "double" | "green" | "index" | "num" | "red" | "rgba" | + * "rgb" | "luminance" | "stencil" | "single" | "stereo" | + * "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" | + * "xgrayscale" | "xstaticcolor" | "xpseudocolor" | + * "xtruecolor" | "xdirectcolor" + * value ::= 0..9 [value] + * + * The display string grammar. This should be EBNF, but I couldn't find the definitions so, to + * clarify: (expr) means 0 or more times the expression, [expr] means 0 or 1 times expr. + * + * Create a new GLib lexical analyzer to process the display mode string + */ + GScanner* scanner = g_scanner_new( &fgInitDisplayStringScannerConfig ); + GList* caps = NULL; + gint i; + + /* + * Fail if the display mode string is empty or the scanner failed to initialize + */ + freeglut_return_if_fail( (scanner != NULL) && (strlen( displayMode ) > 0) ); + + /* + * Set the scanner's input name (for debugging) + */ + scanner->input_name = "glutInitDisplayString"; + + /* + * Start the lexical analysis of the extensions string + */ + g_scanner_input_text( scanner, displayMode, strlen( displayMode ) ); + + /* + * While there are any more tokens to be checked... + */ + while( !g_scanner_eof( scanner ) ) + { + /* + * Actually we're expecting only string tokens + */ + GTokenType tokenType = g_scanner_get_next_token( scanner ); + + /* + * We are looking for identifiers + */ + if( tokenType == G_TOKEN_IDENTIFIER ) + { + gchar* capability = NULL; /* the capability identifier string (always present) */ + gint capID = 0; /* the capability identifier value (from g_Tokens) */ + gint comparison = 0; /* the comparison operator value, see definitions */ + gchar* valueString = NULL; /* if the previous one is present, this is needed */ + gint value = 0; /* the integer value converted using a strtol call */ + SFG_Capability* capStruct; /* the capability description structure */ + + /* + * OK. The general rule of thumb that we always should be getting a capability identifier + * string (see the grammar description). If it is followed by a comparison identifier, then + * there must follow an integer value we're comparing the capability to... + * + * Have the current token analyzed with that in mind... + */ + for( i=0; i<(gint) strlen( scanner->value.v_identifier ); i++ ) + { + gchar c = scanner->value.v_identifier[ i ]; + + if( (c == '=') || (c == '!') || (c == '<') || (c == '>') || (c == '~') ) + break; + } + + /* + * Here we go with the length of the capability identifier string. + * In the worst of cases, it is as long as the token identifier. + */ + capability = g_strndup( scanner->value.v_identifier, i ); + + /* + * OK. Is there a chance for comparison and value identifiers to follow? + * Note: checking against i+1 as this handles two cases: single character + * comparison operator and first of value's digits, which must always be + * there, or the two-character comparison operators. + */ + if( (i + 1) < (gint) strlen( scanner->value.v_identifier ) ) + { + /* + * Yeah, indeed, it is the i-th character to start the identifier, then. + */ + gchar c1 = scanner->value.v_identifier[ i + 0 ]; + gchar c2 = scanner->value.v_identifier[ i + 1 ]; + + if( (c1 == '=') ) { i += 1; comparison = FG_EQUAL; } else + if( (c1 == '!') && (c2 == '=') ) { i += 2; comparison = FG_NOT_EQUAL; } else + if( (c1 == '<') && (c2 == '=') ) { i += 2; comparison = FG_LESS_OR_EQUAL; } else + if( (c1 == '>') && (c2 == '=') ) { i += 2; comparison = FG_MORE_OR_EQUAL; } else + if( (c1 == '<') ) { i += 1; comparison = FG_LESS; } else + if( (c1 == '>') ) { i += 1; comparison = FG_MORE; } else + if( (c1 == '~') ) { i += 1; comparison = FG_CLOSEST; } else + g_warning( "invalid comparison operator in token `%s'", scanner->value.v_identifier ); + } + + /* + * Grab the value string that must follow the comparison operator... + */ + if( comparison != FG_NONE && i < (gint) strlen( scanner->value.v_identifier ) ) + valueString = strdup( scanner->value.v_identifier + i ); + + /* + * If there was a value string, convert it to integer... + */ + if( comparison != FG_NONE && strlen( valueString ) > 0 ) + value = strtol( valueString, NULL, 0 ); + + /* + * Now we need to match the capability string and its ID + */ + for( i=0; g_Tokens[ i ]!=NULL; i++ ) + { + if( strcmp( capability, g_Tokens[ i ] ) == 0 ) + { + /* + * Looks like we've found the one we were looking for + */ + capID = i; + break; + } + } + + /* + * Create a new capability description structure + */ + capStruct = g_new0( SFG_Capability, 1 ); + + /* + * Fill in the cap's values, as we have parsed it: + */ + capStruct->capability = capID; + capStruct->comparison = comparison; + capStruct->value = value; + + /* + * Add the new capabaility to the caps list + */ + caps = g_list_append( caps, capStruct ); + + /* + * Clean up the local mess and keep rolling on + */ + g_free( valueString ); + g_free( capability ); + } + } + + /* + * Now that we have converted the string into somewhat more machine-friendly + * form, proceed with matching the frame buffer configuration... + * + * The caps list could be passed to a function that would try finding the closest + * matching pixel format, visual, frame buffer configuration or whatever. It would + * be good to convert the glutInitDisplayMode() to use the same method. + */ +#if 0 + g_message( "found %i capability preferences", g_list_length( caps ) ); + + g_message( "token `%s': cap: %i, com: %i, val: %i", + scanner->value.v_identifier, + capStruct->capability, + capStruct->comparison, + capStruct->value + ); +#endif + + /* + * Free the capabilities we have parsed + */ + for( i=0; i<(gint) g_list_length( caps ); i++ ) + g_free( g_list_nth( caps, i )->data ); + + /* + * Destroy the capabilities list itself + */ + g_list_free( caps ); + + /* + * Free the lexical scanner now... + */ + g_scanner_destroy( scanner ); +} +#endif + +#define NUM_TOKENS 28 +static char* Tokens[] = +{ + "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green", + "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples", + "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor", + "xtruecolor", "xdirectcolor" +}; + +static int TokenLengths[] = +{ + 5, 4, 3, 4, 6, 10, 5, 6, 5, + 5, 3, 3, 4, 3, 9, 7, 6, 6, 7, + 4, 8, 7, 11, 10, 12, 12, + 10, 12 +}; + +void FGAPIENTRY glutInitDisplayString( const char* displayMode ) +{ + int glut_state_flag = 0 ; + /* + * Unpack a lot of options from a character string. The options are delimited by blanks or tabs. + */ + char *token ; + int len = strlen ( displayMode ) ; + char *buffer = malloc ( (len+1) * sizeof(char) ) ; + memcpy ( buffer, displayMode, len ) ; + buffer[len] = '\0' ; + + token = strtok ( buffer, " \t" ) ; + while ( token ) + { + /* + * Process this token + */ + int i ; + for ( i = 0; i < NUM_TOKENS; i++ ) + { + if ( strncmp ( token, Tokens[i], TokenLengths[i] ) == 0 ) break ; + } + + switch ( i ) + { + case 0 : /* "alpha": Alpha color buffer precision in bits */ + glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */ + break ; + + case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer precision in bits */ + break ; + + case 2 : /* "acc": Red, green, and blue accumulation buffer precision in bits with zero bits alpha */ + glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */ + break ; + + case 3 : /* "blue": Blue color buffer precision in bits */ + break ; + + case 4 : /* "buffer": Number of bits in the color index color buffer */ + break ; + + case 5 : /* "conformant": Boolean indicating if the frame buffer configuration is conformant or not */ + break ; + + case 6 : /* "depth": Number of bits of precsion in the depth buffer */ + glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */ + break ; + + case 7 : /* "double": Boolean indicating if the color buffer is double buffered */ + glut_state_flag |= GLUT_DOUBLE ; + break ; + + case 8 : /* "green": Green color buffer precision in bits */ + break ; + + case 9 : /* "index": Boolean if the color model is color index or not */ + glut_state_flag |= GLUT_INDEX ; + break ; + + case 10 : /* "num": A special capability name indicating where the value represents the Nth frame buffer configuration matching the description string */ + break ; + + case 11 : /* "red": Red color buffer precision in bits */ + break ; + + case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in the RGBA color buffer */ + glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */ + break ; + + case 13 : /* "rgb": Number of bits of red, green, and blue in the RGBA color buffer with zero bits alpha */ + glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */ + break ; + + case 14 : /* "luminance": Number of bits of red in the RGBA and zero bits of green, blue (alpha not specified) of color buffer precision */ + glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */ + break ; + + case 15 : /* "stencil": Number of bits in the stencil buffer */ + glut_state_flag |= GLUT_STENCIL ; /* Somebody fix this for me! */ + break ; + + case 16 : /* "single": Boolean indicate the color buffer is single buffered */ + glut_state_flag |= GLUT_SINGLE ; + break ; + + case 17 : /* "stereo": Boolean indicating the color buffer supports OpenGL-style stereo */ + glut_state_flag |= GLUT_STEREO ; + break ; + + case 18 : /* "samples": Indicates the number of multisamples to use based on GLX's SGIS_multisample extension (for antialiasing) */ + glut_state_flag |= GLUT_MULTISAMPLE ; /* Somebody fix this for me! */ + break ; + + case 19 : /* "slow": Boolean indicating if the frame buffer configuration is slow or not */ + break ; + + case 20 : /* "win32pdf": matches the Win32 Pixel Format Descriptor by number */ +#ifdef TARGET_HOST_WIN32 +#endif + break ; + + case 21 : /* "xvisual": matches the X visual ID by number */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 22 : /* "xstaticgray": boolean indicating if the frame buffer configuration's X visual is of type StaticGray */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 23 : /* "xgrayscale": boolean indicating if the frame buffer configuration's X visual is of type GrayScale */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 24 : /* "xstaticcolor": boolean indicating if the frame buffer configuration's X visual is of type StaticColor */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 25 : /* "xpseudocolor": boolean indicating if the frame buffer configuration's X visual is of type PseudoColor */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 26 : /* "xtruecolor": boolean indicating if the frame buffer configuration's X visual is of type TrueColor */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 27 : /* "xdirectcolor": boolean indicating if the frame buffer configuration's X visual is of type DirectColor */ +#ifdef TARGET_HOST_UNIX_X11 +#endif + break ; + + case 28 : /* Unrecognized */ + printf ( "WARNING - Display string token not recognized: %s\n", token ) ; + break ; + } + + token = strtok ( NULL, " \t" ) ; + } + + free ( buffer ) ; + + /* + * We will make use of this value when creating a new OpenGL context... + */ + fgState.DisplayMode = glut_state_flag; +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h new file mode 100644 index 0000000..5b9df43 --- /dev/null +++ b/src/freeglut_internal.h @@ -0,0 +1,705 @@ +/* + * freeglut_internal.h + * + * The freeglut library private include file. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef FREEGLUT_INTERNAL_H +#define FREEGLUT_INTERNAL_H + +/* XXX Update these for each release! */ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 4 +#define VERSION_PATCH 0 + +/* + * Freeglut is meant to be available under all Unix/X11 and Win32 platforms. + */ +#if !defined(_WIN32) +# define TARGET_HOST_UNIX_X11 1 +# define TARGET_HOST_WIN32 0 +#else +# define TARGET_HOST_UNIX_X11 0 +# define TARGET_HOST_WIN32 1 +#endif + +#define FREEGLUT_MAX_MENUS 3 +#define FREEGLUT_DEBUG 1 + +#if FREEGLUT_DEBUG + #undef G_DISABLE_ASSERT + #undef G_DISABLE_CHECKS +#else + #define G_DISABLE_ASSERT + #define G_DISABLE_CHECKS +#endif + +/* + * Somehow all Win32 include headers depend on this one: + */ +#if TARGET_HOST_WIN32 +#include +#include + +#define strdup _strdup +#endif + +/* + * Those files should be available on every platform. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#if TARGET_HOST_UNIX_X11 +#include +#endif + +/* + * The system-dependant include files should go here: + */ +#if TARGET_HOST_UNIX_X11 + #include + #include + #include + #include + + #ifndef __sgi + #include + #endif +#endif + +/* + * Microsoft VisualC++ 5.0's does not define the PI + */ +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ + +/* + * Freeglut callbacks type definitions + */ +typedef void (* FGCBdisplay )( void ); +typedef void (* FGCBreshape )( int, int ); +typedef void (* FGCBvisibility )( int ); +typedef void (* FGCBkeyboard )( unsigned char, int, int ); +typedef void (* FGCBspecial )( int, int, int ); +typedef void (* FGCBmouse )( int, int, int, int ); +typedef void (* FGCBmotion )( int, int ); +typedef void (* FGCBpassive )( int, int ); +typedef void (* FGCBentry )( int ); +typedef void (* FGCBwindowStatus )( int ); +typedef void (* FGCBselect )( int, int, int ); +typedef void (* FGCBjoystick )( unsigned int, int, int, int ); +typedef void (* FGCBkeyboardUp )( unsigned char, int, int ); +typedef void (* FGCBspecialUp )( int, int, int ); +typedef void (* FGCBoverlayDisplay)( void ); +typedef void (* FGCBspaceMotion )( int, int, int ); +typedef void (* FGCBspaceRotate )( int, int, int ); +typedef void (* FGCBspaceButton )( int, int ); +typedef void (* FGCBdials )( int, int ); +typedef void (* FGCBbuttonBox )( int, int ); +typedef void (* FGCBtabletMotion )( int, int ); +typedef void (* FGCBtabletButton )( int, int, int, int ); +typedef void (* FGCBdestroy )( void ); + +/* + * The global callbacks type definitions + */ +typedef void (* FGCBidle )( void ); +typedef void (* FGCBtimer )( int ); +typedef void (* FGCBmenuState )( int ); +typedef void (* FGCBmenuStatus )( int, int, int ); + +/* + * The callback used when creating/using menus + */ +typedef void (* FGCBmenu )( int ); + + +/* + * A list structure + */ +typedef struct tagSFG_List SFG_List; +struct tagSFG_List +{ + void *First; + void *Last; +}; + +/* + * A list node structure + */ +typedef struct tagSFG_Node SFG_Node; +struct tagSFG_Node +{ + void *Next; + void *Prev; +}; + +/* + * A helper structure holding two ints and a boolean + */ +typedef struct tagSFG_XYUse SFG_XYUse; +struct tagSFG_XYUse +{ + GLint X, Y; /* The two integers... */ + GLboolean Use; /* ...and a single boolean. */ +}; + +/* + * A helper structure holding a timeval and a boolean + */ +typedef struct tagSFG_Time SFG_Time; +struct tagSFG_Time +{ +#ifdef WIN32 + DWORD Value; +#else + struct timeval Value; +#endif + GLboolean Set; +}; + +/* + * An enumeration containing the state of the GLUT execution: initializing, running, or stopping + */ +typedef enum { + GLUT_EXEC_STATE_INIT, + GLUT_EXEC_STATE_RUNNING, + GLUT_EXEC_STATE_STOP +} fgExecutionState ; + +/* + * This structure holds different freeglut settings + */ +typedef struct tagSFG_State SFG_State; +struct tagSFG_State +{ + SFG_XYUse Position; /* The default windows' position */ + SFG_XYUse Size; /* The default windows' size */ + unsigned int DisplayMode; /* The display mode for new windows */ + + GLboolean ForceDirectContext; /* Should we force direct contexts? */ + GLboolean TryDirectContext; /* What about giving a try to? */ + + GLboolean ForceIconic; /* All new top windows are iconified */ + + GLboolean GLDebugSwitch; /* OpenGL state debugging switch */ + GLboolean XSyncSwitch; /* X11 sync protocol switch */ + + GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat... */ + + GLuint FPSInterval; /* Interval between FPS printfs */ + GLuint SwapCount; /* Count of glutSwapBuffer calls */ + GLuint SwapTime; /* Time of last SwapBuffers */ + + SFG_Time Time; /* The time that glutInit was called */ + SFG_List Timers; /* The freeglut timer hooks */ + + FGCBidle IdleCallback; /* The global idle callback */ + + FGCBmenuState MenuStateCallback; /* Menu callbacks are global */ + FGCBmenuStatus MenuStatusCallback; + + SFG_XYUse GameModeSize; /* The game mode screen's dimensions */ + int GameModeDepth; /* The pixel depth for game mode */ + int GameModeRefresh; /* The refresh rate for game mode */ + + int ActionOnWindowClose ; /* Action when user clicks "x" on window header bar */ + + fgExecutionState ExecState ; /* Current state of the GLUT execution */ +}; + +/* + * The structure used by display initialization in freeglut_init.c + */ +typedef struct tagSFG_Display SFG_Display; +struct tagSFG_Display +{ +#if TARGET_HOST_UNIX_X11 + Display* Display; /* The display we are being run in. */ + int Screen; /* The screen we are about to use. */ + Window RootWindow; /* The screen's root window. */ + int Connection; /* The display's connection number */ + Atom DeleteWindow; /* The window deletion atom */ + +#ifdef X_XF86VidModeGetModeLine + XF86VidModeModeLine DisplayMode; /* Current screen's display settings */ + int DisplayModeClock; /* The display mode's refresh rate */ +#endif + +#elif TARGET_HOST_WIN32 + HINSTANCE Instance; /* The application's instance */ + DEVMODE DisplayMode; /* Desktop's display settings */ + +#endif + + int ScreenWidth; /* The screen's width in pixels */ + int ScreenHeight; /* The screen's height in pixels */ + int ScreenWidthMM; /* The screen's width in milimeters */ + int ScreenHeightMM; /* The screen's height in milimeters */ +}; + + +/* + * The user can create any number of timer hooks + */ +typedef struct tagSFG_Timer SFG_Timer; +struct tagSFG_Timer +{ + SFG_Node Node; + int ID; /* The timer ID integer */ + FGCBtimer Callback; /* The timer callback */ + long TriggerTime; /* The timer trigger time */ +}; + +/* + * A window and its OpenGL context. The contents of this structure + * are highly dependant on the target operating system we aim at... + */ +typedef struct tagSFG_Context SFG_Context; +struct tagSFG_Context +{ +#if TARGET_HOST_UNIX_X11 + Window Handle; /* The window's handle */ + GLXContext Context; /* The OpenGL context */ + XVisualInfo* VisualInfo; /* The window's visual information */ + +#elif TARGET_HOST_WIN32 + HWND Handle; /* The window's handle */ + HDC Device; /* The window's device context */ + HGLRC Context; /* The window's WGL context */ + +#endif + + int DoubleBuffered; /* Treat the window as double-buffered */ +}; + +/* + * Window's state description. This structure should be kept portable. + */ +typedef struct tagSFG_WindowState SFG_WindowState; +struct tagSFG_WindowState +{ + int Width; /* Window's width in pixels */ + int Height; /* The same about the height */ + + GLboolean Redisplay; /* Do we have to redisplay? */ + GLboolean Visible; /* Is the window visible now */ + + int Cursor; /* The currently selected cursor */ + int Modifiers; /* The current ALT/SHIFT/CTRL state */ + + long JoystickPollRate; /* The joystick polling rate */ + long JoystickLastPoll; /* When the last poll has happened */ + + int MouseX, MouseY; /* The most recent mouse position */ + + GLboolean IsGameMode; /* Is this the game mode window? */ + +#if TARGET_HOST_WIN32 + GLboolean NeedToResize; /* Do we need to explicitly resize? */ +#endif +}; + +/* + * The window callbacks the user can supply us with. Should be kept portable. + */ +typedef struct tagSFG_WindowCallbacks SFG_WindowCallbacks; +struct tagSFG_WindowCallbacks +{ + /* + * Following callbacks are fully supported right now + * and are ready to be tested for GLUT conformance: + */ + FGCBdisplay Display; + FGCBreshape Reshape; + FGCBkeyboard Keyboard; + FGCBkeyboardUp KeyboardUp; + FGCBspecial Special; + FGCBspecialUp SpecialUp; + FGCBmouse Mouse; + FGCBmotion Motion; + FGCBpassive Passive; + FGCBentry Entry; + FGCBvisibility Visibility; + FGCBwindowStatus WindowStatus; + FGCBjoystick Joystick; + FGCBdestroy Destroy; + + /* + * Those callbacks are being ignored for the moment + */ + FGCBselect Select; + FGCBoverlayDisplay OverlayDisplay; + FGCBspaceMotion SpaceMotion; + FGCBspaceRotate SpaceRotation; + FGCBspaceButton SpaceButton; + FGCBdials Dials; + FGCBbuttonBox ButtonBox; + FGCBtabletMotion TabletMotion; + FGCBtabletButton TabletButton; +}; + +/* + * This structure describes a menu + */ +typedef struct tagSFG_Menu SFG_Menu; +struct tagSFG_Menu +{ + SFG_Node Node; + void *UserData ; /* A. Donev: User data passed back at callback */ + int ID; /* The global menu ID */ + SFG_List Entries; /* The menu entries list */ + FGCBmenu Callback; /* The menu callback */ + FGCBdestroy Destroy; /* A. Donev: Destruction callback */ + GLboolean IsActive; /* Is the menu selected? */ + int Width; /* Menu box width in pixels */ + int Height; /* Menu box height in pixels */ + int X, Y; /* Menu box raster position */ +}; + +/* + * This is a menu entry + */ +typedef struct tagSFG_MenuEntry SFG_MenuEntry; +struct tagSFG_MenuEntry +{ + SFG_Node Node; + int ID; /* The menu entry ID (local) */ + int Ordinal; /* The menu's ordinal number */ + char* Text; /* The text to be displayed */ + SFG_Menu* SubMenu; /* Optional sub-menu tree */ + GLboolean IsActive; /* Is the entry highlighted? */ + int Width; /* Label's width in pixels */ +}; + +/* + * A window, making part of freeglut windows hierarchy. Should be kept portable. + */ +typedef struct tagSFG_Window SFG_Window; +struct tagSFG_Window +{ + SFG_Node Node; + int ID; /* Window's ID number */ + + SFG_Context Window; /* Window and OpenGL context */ + SFG_WindowState State; /* The window state */ + SFG_WindowCallbacks Callbacks; /* The window callbacks */ + void *UserData ; /* A. Donev: A pointer to user data used in rendering */ + + SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */ + SFG_Menu* ActiveMenu; /* The window's active menu */ + + SFG_Window* Parent; /* The parent to this window */ + SFG_List Children; /* The subwindows d.l. list */ +}; + +/* + * A linked list structure of windows + */ +typedef struct tagSFG_WindowList SFG_WindowList ; +struct tagSFG_WindowList +{ + SFG_Window *window ; + GLboolean needToClose ; + SFG_WindowList *next ; +} ; + +/* + * This holds information about all the windows, menus etc. + */ +typedef struct tagSFG_Structure SFG_Structure; +struct tagSFG_Structure +{ + SFG_List Windows; /* The global windows list */ + SFG_List Menus; /* The global menus list */ + + SFG_Window* Window; /* The currently active win. */ + SFG_Menu* Menu; /* Same, but menu... */ + + SFG_Window* GameMode; /* The game mode window */ + + int WindowID; /* The new current window ID */ + int MenuID; /* The new current menu ID */ +}; + +/* + * This structure is used for the enumeration purposes. + * You can easily extend its functionalities by declaring + * a structure containing enumerator's contents and custom + * data, then casting its pointer to (SFG_Enumerator *). + */ +typedef struct tagSFG_Enumerator SFG_Enumerator; +struct tagSFG_Enumerator +{ + GLboolean found; /* Used to terminate search */ + void* data; /* Custom data pointer */ +}; +typedef void (* FGCBenumerator )( SFG_Window *, SFG_Enumerator * ); + +/* + * The bitmap font structure + */ +typedef struct tagSFG_Font SFG_Font; +struct tagSFG_Font +{ + char* Name; /* The source font name */ + int Quantity; /* Number of chars in font */ + int Height; /* Height of the characters */ + const GLubyte** Characters; /* The characters mapping */ + + float xorig, yorig ; /* The origin of the character relative to the draw location */ +}; + +/* + * The stroke font structures + */ + +typedef struct tagSFG_StrokeVertex SFG_StrokeVertex; +struct tagSFG_StrokeVertex +{ + GLfloat X, Y; +}; + +typedef struct tagSFG_StrokeStrip SFG_StrokeStrip; +struct tagSFG_StrokeStrip +{ + int Number; + const SFG_StrokeVertex* Vertices; +}; + +typedef struct tagSFG_StrokeChar SFG_StrokeChar; +struct tagSFG_StrokeChar +{ + GLfloat Right; + int Number; + const SFG_StrokeStrip* Strips; +}; + +typedef struct tagSFG_StrokeFont SFG_StrokeFont; +struct tagSFG_StrokeFont +{ + char* Name; /* The source font name */ + int Quantity; /* Number of chars in font */ + GLfloat Height; /* Height of the characters */ + const SFG_StrokeChar** Characters; /* The characters mapping */ +}; + +/* -- GLOBAL VARIABLES EXPORTS --------------------------------------------- */ + +/* + * Freeglut display related stuff (initialized once per session) + */ +extern SFG_Display fgDisplay; + +/* + * Freeglut internal structure + */ +extern SFG_Structure fgStructure; + +/* + * The current freeglut settings + */ +extern SFG_State fgState; + + +/* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */ + +/* + * A call to this function makes us sure that the Display and Structure + * subsystems have been properly initialized and are ready to be used + */ +#define freeglut_assert_ready assert( fgState.Time.Set ); + +/* + * Following definitions are somewhat similiar to GLib's, + * but do not generate any log messages: + */ +#define freeglut_return_if_fail( expr ) if( !(expr) ) return; +#define freeglut_return_val_if_fail( expr, val ) if( !(expr) ) return( val ); + +/* + * A call to those macros assures us that there is a current + * window and menu set, respectively: + */ +#define freeglut_assert_window assert( fgStructure.Window != NULL ); +#define freeglut_assert_menu assert( fgStructure.Menu != NULL ); + +/* + * The initialize and deinitialize functions get called on glutInit() + * and glutMainLoop() end respectively. They should create/clean up + * everything inside of the freeglut + */ +void fgInitialize( const char* displayName ); +void fgDeinitialize( void ); + +/* + * Those two functions are used to create/destroy the freeglut internal + * structures. This actually happens when calling glutInit() and when + * quitting the glutMainLoop() (which actually happens, when all windows + * have been closed). + */ +void fgCreateStructure( void ); +void fgDestroyStructure( void ); + +/* + * A helper function to check if a display mode is possible to use + */ +#if TARGET_HOST_UNIX_X11 +XVisualInfo* fgChooseVisual( void ); +#endif + +/* + * The window procedure for Win32 events handling + */ +#if TARGET_HOST_WIN32 +LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ); +#endif + +/* + * Window creation, opening, closing and destruction. + * Defined in freeglut_structure.c, freeglut_window.c. + */ +SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, int w, int h, GLboolean gameMode ); +void fgSetWindow ( SFG_Window *window ) ; +void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow ); +void fgCloseWindow( SFG_Window* window ); +void fgAddToWindowDestroyList ( SFG_Window* window, GLboolean needToClose ) ; +void fgCloseWindows () ; +void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ); + +/* + * Menu creation and destruction. Defined in freeglut_structure.c + */ +SFG_Menu* fgCreateMenu( FGCBmenu menuCallback ); +void fgDestroyMenu( SFG_Menu* menu ); + +/* + * Joystick device management functions, defined in freeglut_joystick.c + */ +void fgJoystickInit( int ident ); +void fgJoystickClose( void ); +void fgJoystickPollWindow( SFG_Window* window ); + +/* + * Helper function to enumerate through all registered windows + * and one to enumerate all of a window's subwindows... + * + * The GFunc callback for those functions will be defined as: + * + * void enumCallback( gpointer window, gpointer enumerator ); + * + * where window is the enumerated (sub)window pointer (SFG_Window *), + * and userData is the a custom user-supplied pointer. Functions + * are defined and exported from freeglut_structure.c file. + */ +void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator ); +void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enumerator* enumerator ); + +/* + * fgWindowByHandle returns a (SFG_Window *) value pointing to the + * first window in the queue matching the specified window handle. + * The function is defined in freeglut_structure.c file. + */ +#if TARGET_HOST_UNIX_X11 + SFG_Window* fgWindowByHandle( Window hWindow ); +#elif TARGET_HOST_WIN32 + + SFG_Window* fgWindowByHandle( HWND hWindow ); +#endif + +/* + * This function is similiar to the previous one, except it is + * looking for a specified (sub)window identifier. The function + * is defined in freeglut_structure.c file. + */ +SFG_Window* fgWindowByID( int windowID ); + +/* + * Looks up a menu given its ID. This is easier that fgWindowByXXX + * as all menus are placed in a single doubly linked list... + */ +SFG_Menu* fgMenuByID( int menuID ); + +/* + * The menu activation and deactivation the code. This is the meat + * of the menu user interface handling code... + */ +void fgActivateMenu( SFG_Window* window, int button ); +void fgExecuteMenuCallback( SFG_Menu* menu ) ; +GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ; +void fgDeactivateMenu( SFG_Window *window ); + +/* + * This function gets called just before the buffers swap, so that + * freeglut can display the pull-down menus via OpenGL. The function + * is defined in freeglut_menu.c file. + */ +void fgDisplayMenu( void ); + +/* + * Display the mouse cursor using OpenGL calls. The function + * is defined in freeglut_cursor.c file. + */ +void fgDisplayCursor( void ); + +/* + * Elapsed time as per glutGet(GLUT_ELAPSED_TIME). + */ +long fgElapsedTime( void ); + +/* + * List functions + */ +void fgListInit(SFG_List *list); +void fgListAppend(SFG_List *list, SFG_Node *node); +void fgListRemove(SFG_List *list, SFG_Node *node); +int fgListLength(SFG_List *list); + +/* + * Error Messages functions + */ +void fgError( const char *fmt, ... ); +void fgWarning( const char *fmt, ... ); + +#endif /* FREEGLUT_INTERNAL_H */ + +/*** END OF FILE ***/ diff --git a/src/freeglut_joystick.c b/src/freeglut_joystick.c new file mode 100644 index 0000000..a47d491 --- /dev/null +++ b/src/freeglut_joystick.c @@ -0,0 +1,605 @@ +/* + * freeglut_joystick.c + * + * Joystick handling code + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Steve Baker, + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * PWO: this is not exactly what Steve Baker has done for PLIB, as I had to convert + * it from C++ to C. And I've also reformatted it a bit (that's my little + * personal deviation :]) I don't really know if it is still portable... + * Steve: could you please add some comments to the code? :) + * + * FreeBSD port - courtesy of Stephen Montgomery-Smith + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-joystick" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * PWO: I don't like it at all. It's a mess. Could it be cleared? + */ +#ifdef WIN32 +# include +# if defined( __CYGWIN32__ ) || defined( __CYGWIN__ ) +# define NEAR /* */ +# define FAR /* */ +# endif +# include +# include +#else +# include +# include +# ifdef __FreeBSD__ +# include +# define JS_DATA_TYPE joystick +# define JS_RETURN (sizeof(struct JS_DATA_TYPE)) +# elif defined(__linux__) +# include +# include +# include + + /* + * Check the joystick driver version + */ +# ifdef JS_VERSION +# if JS_VERSION >= 0x010000 +# define JS_NEW +# endif +# endif +# else +# ifndef JS_DATA_TYPE + + /* + * Not Windoze and no joystick driver... + * + * Well - we'll put these values in and that should + * allow the code to at least compile. The JS open + * routine should error out and shut off all the code + * downstream anyway + */ + struct JS_DATA_TYPE + { + int buttons; + int x; + int y; + }; + +# define JS_RETURN (sizeof(struct JS_DATA_TYPE)) +# endif +# endif +#endif + +#ifdef WIN32 +# define _JS_MAX_AXES 6 +#else +# ifdef __FreeBSD__ +# define _JS_MAX_AXES 2 +# else +# define _JS_MAX_AXES 6 +# endif +#endif + +typedef struct tagSFG_Joystick SFG_Joystick; +struct tagSFG_Joystick +{ +#ifdef __FreeBSD__ + int id; +#endif + +#ifdef WIN32 + JOYINFOEX js; + UINT js_id; +#else +# ifdef JS_NEW + struct js_event js; + int tmp_buttons; + float tmp_axes[ _JS_MAX_AXES ]; +# else + struct JS_DATA_TYPE js; +# endif + + char fname[ 128 ]; + int fd; +#endif + + GLboolean error; + int num_axes; + int num_buttons; + + float dead_band[ _JS_MAX_AXES ]; + float saturate [ _JS_MAX_AXES ]; + float center [ _JS_MAX_AXES ]; + float max [ _JS_MAX_AXES ]; + float min [ _JS_MAX_AXES ]; +}; + +/* + * The static joystick structure pointer + */ +static SFG_Joystick* fgJoystick = NULL; + +/* + * Read the raw joystick data + */ +static void fghJoystickRawRead ( SFG_Joystick* joy, int* buttons, float* axes ) +{ +#ifdef WIN32 + MMRESULT status; +#else + int status; +#endif + + int i; + + if( joy->error ) + { + if( buttons ) + *buttons = 0 ; + + if( axes ) + for( i=0; inum_axes; i++ ) + axes[ i ] = 1500.0f; + + return; + } + +#ifdef WIN32 + status = joyGetPosEx( joy->js_id, &joy->js ); + + if( status != JOYERR_NOERROR ) + { + joy->error = TRUE; + return; + } + + if( buttons ) + *buttons = joy->js.dwButtons; + + if( axes ) + { + /* + * WARNING - Fall through case clauses!! + */ + switch( joy->num_axes ) + { + case 6: axes[5] = (float) joy->js.dwVpos; + case 5: axes[4] = (float) joy->js.dwUpos; + case 4: axes[3] = (float) joy->js.dwRpos; + case 3: axes[2] = (float) joy->js.dwZpos; + case 2: axes[1] = (float) joy->js.dwYpos; + case 1: axes[0] = (float) joy->js.dwXpos; + } + } +#else +# ifdef JS_NEW + + while( 1 ) + { + status = read( joy->fd, &joy->js, sizeof(struct js_event) ); + + if( status != sizeof(struct js_event) ) + { + if( errno == EAGAIN ) + { + /* + * Use the old values + */ + if( buttons ) *buttons = joy->tmp_buttons; + if( axes ) memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes ); + return; + } + + fgWarning( "%s", joy->fname ); + joy->error = TRUE; + return; + } + + switch( joy->js.type & ~JS_EVENT_INIT ) + { + case JS_EVENT_BUTTON: + if ( joy->js.value == 0 ) /* clear the flag */ + joy->tmp_buttons &= ~(1 << joy->js.number); + else + joy->tmp_buttons |= (1 << joy->js.number); + break; + + case JS_EVENT_AXIS: + joy->tmp_axes[ joy->js.number ] = (float) joy->js.value; + + if( axes ) + memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes ); + break; + } + + if( buttons ) + *buttons = joy->tmp_buttons; + } +# else + + status = read( joy->fd, &joy->js, JS_RETURN ); + + if( status != JS_RETURN ) + { + g_warning( joy->fname ); + joy->error = TRUE; + return; + } + + if( buttons ) +# ifdef __FreeBSD__ + *buttons = (joy->js.b1 ? 1 : 0) | (joy->js.b2 ? 2 : 0); +# else + *buttons = joy->js.buttons; +# endif + + if( axes ) + { + axes[ 0 ] = (float) joy->js.x; + axes[ 1 ] = (float) joy->js.y; + } +# endif +#endif +} + +/* + * Correct the joystick axis data + */ +static float fghJoystickFudgeAxis( SFG_Joystick* joy, float value, int axis ) +{ + if( value < joy->center[ axis ] ) + { + float xx = (value - joy->center[ axis ]) / (joy->center[ axis ] - joy->min[ axis ]); + + if( xx < -joy->saturate[ axis ] ) + return( -1.0f ); + + if( xx > -joy->dead_band [ axis ] ) + return( 0.0f ); + + xx = (xx + joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]); + + return( ( xx < -1.0f ) ? -1.0f : xx ); + } + else + { + float xx = (value - joy->center [ axis ]) / (joy->max[ axis ] - joy->center[ axis ]); + + if( xx > joy->saturate[ axis ] ) + return 1.0f ; + + if( xx < joy->dead_band[ axis ] ) + return 0.0f ; + + xx = (xx - joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]); + + return( ( xx > 1.0f ) ? 1.0f : xx ); + } +} + +/* + * Read the corrected joystick data + */ +static void fghJoystickRead( SFG_Joystick* joy, int* buttons, float* axes ) +{ + float raw_axes[ _JS_MAX_AXES ]; + int i; + + if( joy->error ) + { + if( buttons ) + *buttons = 0; + + if( axes ) + for ( i=0; inum_axes ; i++ ) + axes[ i ] = 0.0f ; + } + + fghJoystickRawRead( joy, buttons, raw_axes ); + + if( axes ) + for( i=0 ; inum_axes ; i++ ) + axes[ i ] = fghJoystickFudgeAxis( joy, raw_axes[ i ], i ); +} + +/* + * Happy happy happy joy joy joy (happy new year toudi :D) + */ +static void fghJoystickOpen( SFG_Joystick* joy ) +{ +#ifdef WIN32 + JOYCAPS jsCaps; + int i; + + joy->js.dwFlags = JOY_RETURNALL; + joy->js.dwSize = sizeof( joy->js ); + + memset( &jsCaps, 0, sizeof(jsCaps) ); + + joy->error = (joyGetDevCaps( joy->js_id, &jsCaps, sizeof(jsCaps) ) != JOYERR_NOERROR); + joy->num_axes = (jsCaps.wNumAxes < _JS_MAX_AXES ) ? jsCaps.wNumAxes : _JS_MAX_AXES; + + /* + * WARNING - Fall through case clauses!! + */ + switch( joy->num_axes ) + { + case 6 : joy->min[ 5 ] = (float) jsCaps.wVmin; joy->max[ 5 ] = (float) jsCaps.wVmax; + case 5 : joy->min[ 4 ] = (float) jsCaps.wUmin; joy->max[ 4 ] = (float) jsCaps.wUmax; + case 4 : joy->min[ 3 ] = (float) jsCaps.wRmin; joy->max[ 3 ] = (float) jsCaps.wRmax; + case 3 : joy->min[ 2 ] = (float) jsCaps.wZmin; joy->max[ 2 ] = (float) jsCaps.wZmax; + case 2 : joy->min[ 1 ] = (float) jsCaps.wYmin; joy->max[ 1 ] = (float) jsCaps.wYmax; + case 1 : joy->min[ 0 ] = (float) jsCaps.wXmin; joy->max[ 0 ] = (float) jsCaps.wXmax; break; + + /* + * I guess we have no axes at all + */ + default: joy->error = TRUE; break; + } + + /* + * Guess all the rest judging on the axes extremals + */ + for( i=0 ; inum_axes ; i++ ) + { + joy->center [ i ] = (joy->max[i] + joy->min[i]) * 0.5f; + joy->dead_band[ i ] = 0.0f; + joy->saturate [ i ] = 1.0f; + } + +#else +# ifdef __FreeBSD__ + int buttons[ _JS_MAX_AXES ]; + float axes[ _JS_MAX_AXES ]; + int noargs, in_no_axes; + char joyfname[ 1024 ]; + FILE* joyfile; +# else +# ifndef JS_NEW + int counter; +# endif +# endif + int i; + + /* + * Default for older Linux systems. + */ + joy->num_axes = 2; + joy->num_buttons = 32; + +# ifdef JS_NEW + for( i=0 ; i<_JS_MAX_AXES ; i++ ) + joy->tmp_axes[ i ] = 0.0f ; + + joy->tmp_buttons = 0 ; +# endif + + joy->fd = open( joy->fname, O_RDONLY ); + + joy->error = (joy->fd < 0); + + if( joy->error ) + return; + +# ifdef __FreeBSD__ + fghJoystickRawRead(joy, buttons, axes ); + joy->error = axes[ 0 ] < -1000000000.0f; + if( joy->error ) + return ; + + sprintf( joyfname, "%s/.joy%drc", g_getenv( "HOME" ), joy->id ); + + joyfile = fopen( joyfname, "r" ); + joy->error = (joyfile == NULL); + if( joy->error ) + return; + + noargs = fscanf( + joyfile, "%d%f%f%f%f%f%f", + &in_no_axes, + &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ], + &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] + ); + + joy->error = (noargs != 7) || (in_no_axes != _JS_MAX_AXES); + fclose( joyfile ); + if( joy->error ) + return; + + for( i=0 ; i<_JS_MAX_AXES ; i++ ) + { + joy->dead_band[ i ] = 0.0f; + joy->saturate [ i ] = 1.0f; + } +# else + + /* + * Set the correct number of axes for the linux driver + */ +# ifdef JS_NEW + ioctl( joy->fd, JSIOCGAXES , &joy->num_axes ); + ioctl( joy->fd, JSIOCGBUTTONS, &joy->num_buttons ); + fcntl( joy->fd, F_SETFL, O_NONBLOCK ); + +# endif + + /* + * The Linux driver seems to return 512 for all axes + * when no stick is present - but there is a chance + * that could happen by accident - so it's gotta happen + * on both axes for at least 100 attempts. + * + * PWO: shouldn't be that done somehow wiser on the kernel level? + */ +# ifndef JS_NEW + counter = 0 ; + + do + { + fghJoystickRawRead( joy, NULL, joy->center ); + counter++; + } while( !joy->error && counter < 100 && joy->center[ 0 ] == 512.0f && joy->center[ 1 ] == 512.0f ); + + if( counter >= 100 ) + joy->error = TRUE; +# endif + + for( i=0 ; i<_JS_MAX_AXES ; i++ ) + { +# ifdef JS_NEW + joy->max [ i ] = 32767.0f; + joy->center[ i ] = 0.0f; + joy->min [ i ] = -32767.0f; +# else + joy->max[ i ] = joy->center[ i ] * 2.0f; + joy->min[ i ] = 0.0f; +# endif + joy->dead_band[ i ] = 0.0f ; + joy->saturate [ i ] = 1.0f ; + } +# endif +#endif +} + +/* + * + */ +void fgJoystickInit( int ident ) +{ + /* + * Make sure we don't get reinitialized + */ + if( fgJoystick != NULL ) + fgError( "illegal attemp to initialize joystick device" ); + + /* + * Have the global joystick structure created + */ + fgJoystick = calloc( sizeof(SFG_Joystick), 1 ); + +#ifdef WIN32 + switch( ident ) + { + case 0: fgJoystick->js_id = JOYSTICKID1; fghJoystickOpen( fgJoystick ); break; + case 1: fgJoystick->js_id = JOYSTICKID2; fghJoystickOpen( fgJoystick ); break; + default: fgJoystick->num_axes = 0; fgJoystick->error = TRUE; break; + } +#else + +# ifdef __FreeBSD__ + fgJoystick->id = ident; + sprintf( fgJoystick->fname, "/dev/joy%d", ident ); +# else + sprintf( fgJoystick->fname, "/dev/js%d", ident ); +# endif + + /* + * Let's try opening the joystick device now: + */ + fghJoystickOpen( fgJoystick ); +#endif +} + +/* + * + */ +void fgJoystickClose( void ) +{ + if( fgJoystick == NULL ) + fgError( "illegal attempt to deinitialize joystick device" ); + +#ifndef WIN32 + if( fgJoystick->error != TRUE ) + close( fgJoystick->fd ); +#endif + + free ( fgJoystick ) ; + fgJoystick = NULL ; /* show joystick has been deinitialized */ +} + +/* + * Polls the joystick and executes the joystick callback hooked to the + * window specified in the function's parameter: + */ +void fgJoystickPollWindow( SFG_Window* window ) +{ + float axes[ _JS_MAX_AXES ]; + int buttons; + + /* + * Make sure the joystick device is initialized, the window seems valid + * and that there is a joystick callback hooked to it: + */ + freeglut_return_if_fail( fgJoystick != NULL && window != NULL ); + freeglut_return_if_fail( window->Callbacks.Joystick != NULL ); + + /* + * Poll the joystick now: + */ + fghJoystickRead( fgJoystick, &buttons, axes ); + + /* + * Execute the freeglut joystick callback now + */ + window->Callbacks.Joystick( + buttons, + (int) (axes[ 0 ] * 1000.0f), + (int) (axes[ 1 ] * 1000.0f), + (int) (axes[ 2 ] * 1000.0f) + ); +} + +/* + * PWO: These jsJoystick class methods have not been implemented. + * We might consider adding such functions to freeglut-2.0. + */ +#if 0 + int getNumAxes () { return num_axes ; } + int notWorking () { return error ; } + + float getDeadBand ( int axis ) { return dead_band [ axis ] ; } + void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; } + + float getSaturation ( int axis ) { return saturate [ axis ] ; } + void setSaturation ( int axis, float st ) { saturate [ axis ] = st ; } + + void setMinRange ( float *axes ) { memcpy ( min , axes, num_axes * sizeof(float) ) ; } + void setMaxRange ( float *axes ) { memcpy ( max , axes, num_axes * sizeof(float) ) ; } + void setCenter ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; } + + void getMinRange ( float *axes ) { memcpy ( axes, min , num_axes * sizeof(float) ) ; } + void getMaxRange ( float *axes ) { memcpy ( axes, max , num_axes * sizeof(float) ) ; } + void getCenter ( float *axes ) { memcpy ( axes, center, num_axes * sizeof(float) ) ; } +#endif + +/*** END OF FILE ***/ + + + + diff --git a/src/freeglut_main.c b/src/freeglut_main.c new file mode 100644 index 0000000..1c11f0d --- /dev/null +++ b/src/freeglut_main.c @@ -0,0 +1,1797 @@ +/* + * freeglut_main.c + * + * The windows message processing methods. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-main" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * There are some issues concerning window redrawing under X11, and maybe + * some events are not handled. The Win32 version lacks some more features, + * but seems acceptable for not demanding purposes. + * + * Need to investigate why the X11 version breaks out with an error when + * closing a window (using the window manager, not glutDestroyWindow)... + */ + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * Calls a window's redraw method. This is used when + * a redraw is forced by the incoming window messages. + */ + +static void fghRedrawWindowByHandle +#if TARGET_HOST_UNIX_X11 + ( Window handle ) +#elif TARGET_HOST_WIN32 + ( HWND handle ) +#endif +{ + /* + * Find the window we have to redraw... + */ + SFG_Window* window = fgWindowByHandle( handle ); + freeglut_return_if_fail( window != NULL ); + + /* + * Check if there is a display callback hooked to it + */ + freeglut_return_if_fail( window->Callbacks.Display != NULL ); + + /* + * Return if the window is not visible + */ + freeglut_return_if_fail( window->State.Visible == TRUE ); + + /* + * Set the window as the current one. + */ + fgSetWindow( window ); + + /* + * Do not exagerate with the redisplaying + */ + window->State.Redisplay = FALSE; + + /* + * Have the callback executed now. The buffers should + * be swapped by the glutSwapBuffers() execution inside + * the callback itself. + */ + + window->Callbacks.Display(); +} + +/* + * Handle a window configuration change. When no reshape + * callback is hooked, the viewport size is updated to + * match the new window size. + */ +static void fghReshapeWindowByHandle +#if TARGET_HOST_UNIX_X11 + ( Window handle, int width, int height ) +#elif TARGET_HOST_WIN32 + ( HWND handle, int width, int height ) +#endif +{ + /* + * Find the window that received the reshape event + */ + SFG_Window* window = fgWindowByHandle( handle ); + freeglut_return_if_fail( window != NULL ); + + /* + * Remember about setting the current window... + */ + fgSetWindow( window ); + + /* + * Check if there is a reshape callback hooked + */ + if( window->Callbacks.Reshape != NULL ) + { + /* + * OKi, have it called immediately + */ + window->Callbacks.Reshape( width, height ); + } + else + { + /* + * Otherwise just resize the viewport + */ + glViewport( 0, 0, width, height ); + } + + /* + * Force a window redraw. In Windows at least this is only a partial solution: if the + * window is increasing in size in either dimension, the already-drawn part does not get + * drawn again and things look funny. But without this we get this bad behaviour whenever + * we resize the window. + */ + window->State.Redisplay = TRUE ; +} + +/* + * A static helper function to execute display callback for a window + */ +static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) +{ +#if TARGET_HOST_UNIX_X11 + /* + * Check if there is an idle callback hooked + */ + if( (window->Callbacks.Display != NULL) && + (window->State.Redisplay == TRUE) && + (window->State.Visible == TRUE) ) + { + /* + * OKi, this is the case: have the window set as the current one + */ + fgSetWindow( window ); + + /* + * Do not exagerate with the redisplaying + */ + window->State.Redisplay = FALSE; + + /* + * And execute the display callback immediately after + */ + window->Callbacks.Display(); + } + +#elif TARGET_HOST_WIN32 + + /* + * Do we need to explicitly resize the window? + */ + if( window->State.NeedToResize ) + { + fgSetWindow( window ); + + fghReshapeWindowByHandle( + window->Window.Handle, + glutGet( GLUT_WINDOW_WIDTH ), + glutGet( GLUT_WINDOW_HEIGHT ) + ); + + /* + * Never ever do that again: + */ + window->State.NeedToResize = FALSE; + } + + /* + * This is done in a bit different way under Windows + */ + if( (window->Callbacks.Display != NULL) && + (window->State.Redisplay == TRUE) && + (window->State.Visible == TRUE) ) + { + /* + * Do not exagerate with the redisplaying + */ + window->State.Redisplay = FALSE; + + RedrawWindow( + window->Window.Handle, NULL, NULL, + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW + ); + } + +#endif + + /* + * Process this window's children (if any) + */ + fgEnumSubWindows( window, fghcbDisplayWindow, enumerator ); +} + +/* + * Make all windows perform a display call + */ +static void fghDisplayAll( void ) +{ + SFG_Enumerator enumerator; + + /* + * Uses a method very similiar for fgWindowByHandle... + */ + enumerator.found = FALSE; + enumerator.data = NULL; + + /* + * Start the enumeration now: + */ + fgEnumWindows( fghcbDisplayWindow, &enumerator ); +} + +/* + * Window enumerator callback to check for the joystick polling code + */ +static void fghcbCheckJoystickPolls( SFG_Window *window, SFG_Enumerator *enumerator ) +{ + long int checkTime = fgElapsedTime(); + + /* + * Check if actually need to do the poll for the currently enumerated window: + */ + if( window->State.JoystickLastPoll + window->State.JoystickPollRate >= checkTime ) + { + /* + * Yeah, that's it. Poll the joystick... + */ + fgJoystickPollWindow( window ); + + /* + * ...and reset the polling counters: + */ + window->State.JoystickLastPoll = checkTime; + } + + /* + * Process this window's children (if any) + */ + fgEnumSubWindows( window, fghcbCheckJoystickPolls, enumerator ); +} + +/* + * Check all windows for joystick polling + */ +static void fghCheckJoystickPolls( void ) +{ + SFG_Enumerator enumerator; + + /* + * Uses a method very similiar for fgWindowByHandle... + */ + enumerator.found = FALSE; + enumerator.data = NULL; + + /* + * Start the enumeration now: + */ + fgEnumWindows( fghcbCheckJoystickPolls, &enumerator ); +} + +/* + * Check the global timers + */ +static void fghCheckTimers( void ) +{ + long checkTime = fgElapsedTime(); + SFG_Timer *timer, *next; + SFG_List timedOut; + + fgListInit(&timedOut); + + /* + * For every timer that is waiting for triggering + */ + for( timer = fgState.Timers.First; timer; timer = next ) + { + next = timer->Node.Next; + + /* + * Check for the timeout: + */ + if( timer->TriggerTime <= checkTime ) + { + /* + * Add the timer to the timed out timers list + */ + fgListRemove( &fgState.Timers, &timer->Node ); + fgListAppend( &timedOut, &timer->Node ); + } + } + + /* + * Now feel free to execute all the hooked and timed out timer callbacks + * And delete the timed out timers... + */ + while ( (timer = timedOut.First) ) + { + if( timer->Callback != NULL ) + timer->Callback( timer->ID ); + fgListRemove( &timedOut, &timer->Node ); + free( timer ); + } +} + + +/* + * Elapsed Time + */ +long fgElapsedTime( void ) +{ +#if TARGET_HOST_UNIX_X11 + struct timeval now; + long elapsed; + + gettimeofday( &now, NULL ); + + elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000; + elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000; + + return( elapsed ); +#elif TARGET_HOST_WIN32 + return (timeGetTime() - fgState.Time.Value); +#endif +} + +/* + * Error Messages. + */ +void fgError( const char *fmt, ... ) +{ + va_list ap; + + va_start( ap, fmt ); + + fprintf( stderr, "freeglut: "); + vfprintf( stderr, fmt, ap ); + fprintf( stderr, "\n" ); + + va_end( ap ); + + exit( 1 ); +} + +void fgWarning( const char *fmt, ... ) +{ + va_list ap; + + va_start( ap, fmt ); + + fprintf( stderr, "freeglut: "); + vfprintf( stderr, fmt, ap ); + fprintf( stderr, "\n" ); + + va_end( ap ); +} + +/* + * Clean up on exit + */ +static void fgCleanUpGlutsMess( void ) +{ + int i; + + i = 0; + + if ( fgStructure.Windows.First != NULL ) + { + SFG_Window *win = fgStructure.Windows.First ; + glEnd(); + glFinish(); + glFlush(); + while ( win != NULL ) + { + SFG_Window *temp_win = win->Node.Next ; + fgDestroyWindow ( win, FALSE ) ; + win = temp_win ; + } + } + +#if 0 + /* these are pointers to external handles */ + + __glutWindowListSize = 0; + __glutStaleWindowList = NULL; + __glutWindowList = NULL; + __glutCurrentWindow = NULL; + + /* make sure we no longer have a GL context */ + + if ( wglGetCurrentContext() != NULL ) + { + wglDeleteContext( wglGetCurrentContext() ); + } + + hInstance = GetModuleHandle(NULL); + UnregisterClass( classname, hInstance ); + + /* clean up allocated timer memory */ + + tList = __glutTimerList; + i = 0; + + while ( __glutTimerList ) + { + i++; + tList = __glutTimerList; + + if ( __glutTimerList ) + __glutTimerList = __glutTimerList->next; + + if ( tList ) + free( tList ); + } +#endif +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Executes a single iteration in the freeglut processing loop. + */ +void FGAPIENTRY glutMainLoopEvent( void ) +{ +#if TARGET_HOST_UNIX_X11 + SFG_Window* window; + XEvent event; + int modifiers; + + /* + * This code was repeated constantly, so here it goes into a definition: + */ +# define GETWINDOW(a) window = fgWindowByHandle( event.a.window );if( window == NULL ) break; +# define GETMOUSE(a) window->State.MouseX = event.a.x; window->State.MouseY = event.a.y; + + /* + * Make sure the display has been created etc. + */ + freeglut_assert_ready; + + /* + * Do we have any event messages pending? + */ + if( XPending( fgDisplay.Display ) ) + { + /* + * Grab the next event to be processed... + */ + XNextEvent( fgDisplay.Display, &event ); + window = fgWindowByHandle ( event.xany.window ) ; + + /* + * Check the event's type + */ + switch( event.type ) + { + case CreateNotify: + /* + * The window creation confirmation + */ + break; + + case DestroyNotify: + /* + * This is sent to confirm the XDestroyWindow call. + */ + /* + * Call the window closure callback, remove from the structure, etc. + */ + fgStructure.Window = window ; +/* fgAddToWindowDestroyList ( window, FALSE ); */ + + break; + + case ClientMessage: + /* + * Destroy the window when the WM_DELETE_WINDOW message arrives + */ + if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.DeleteWindow ) + { + fgStructure.Window = window ; + + /* + * Call the XWindows functions to close the window + */ + fgCloseWindow ( window ) ; + + /* + * Call the window closure callback, remove from the structure, etc. + */ + fgAddToWindowDestroyList ( window, FALSE ); + } + break; + + case UnmapNotify: + /* + * A window of ours has been unmapped... + */ + break; + + case Expose: + /* + * We are too dumb to process partial exposes... + */ + if( event.xexpose.count == 0 ) + fghRedrawWindowByHandle( window->Window.Handle ); + break; + + case ConfigureNotify: + /* + * The window gets resized + */ + fghReshapeWindowByHandle( + event.xconfigure.window, + event.xconfigure.width, + event.xconfigure.height + ); + break; + + case MappingNotify: + /* + * Have the client's keyboard knowledge updated (xlib.ps, + * page 206, says that's a good thing to do) + */ + XRefreshKeyboardMapping( (XMappingEvent *) &event ); + break; + + case VisibilityNotify: + { + /* + * The window's visiblity might have changed + */ + /* + * Break now if no window status callback has been hooked to that window + */ + if( window->Callbacks.WindowStatus == NULL ) + break; + + /* + * We're going to send a callback to a window. Make it current. + */ + fgSetWindow( window ); + + /* + * Sending this event, the X server can notify us that the window has just + * acquired one of the three possible visibility states: VisibilityUnobscured, + * VisibilityPartiallyObscured or VisibilityFullyObscured + */ + switch( event.xvisibility.state ) + { + case VisibilityUnobscured: + /* + * We are fully visible... + */ + window->Callbacks.WindowStatus( GLUT_FULLY_RETAINED ); + window->State.Visible = TRUE; + break; + + case VisibilityPartiallyObscured: + /* + * The window is partially visible + */ + window->Callbacks.WindowStatus( GLUT_PARTIALLY_RETAINED ); + window->State.Visible = TRUE; + break; + + case VisibilityFullyObscured: + /* + * The window is totally obscured + */ + window->Callbacks.WindowStatus( GLUT_FULLY_COVERED ); + window->State.Visible = FALSE; + break; + } + } + break; + + case EnterNotify: + { + /* + * Mouse is over one of our windows + */ + GETMOUSE( xcrossing ); + + /* + * Is there an entry callback hooked to the window? + */ + if( window->Callbacks.Entry != NULL ) + { + /* + * Yeah. Notify the window about having the mouse cursor over + */ + window->Callbacks.Entry( GLUT_ENTERED ); + } + } + break; + + case LeaveNotify: + { + /* + * Mouse is no longer over one of our windows + */ + GETMOUSE( xcrossing ); + + /* + * Is there an entry callback hooked to the window? + */ + if( window->Callbacks.Entry != NULL ) + { + /* + * Yeah. Notify the window about having the mouse cursor over + */ + window->Callbacks.Entry( GLUT_LEFT ); + } + } + break; + + case MotionNotify: + { + /* + * The mouse cursor was moved... + */ + GETMOUSE( xmotion ); + + /* + * Set the current window + */ + fgStructure.Window = window ; + + /* + * What kind of a movement was it? + */ + if( (event.xmotion.state & Button1Mask) || (event.xmotion.state & Button2Mask) || + (event.xmotion.state & Button3Mask) || (event.xmotion.state & Button4Mask) || + (event.xmotion.state & Button5Mask) ) + { + /* + * A mouse button was pressed during the movement... + * Is there a motion callback hooked to the window? + */ + if( window->Callbacks.Motion != NULL ) + { + /* + * Yup. Have it executed immediately + */ + window->Callbacks.Motion( event.xmotion.x, event.xmotion.y ); + } + } + else + { + /* + * Otherwise it was a passive movement... + */ + if( window->Callbacks.Passive != NULL ) + { + /* + * That's right, and there is a passive callback, too. + */ + window->Callbacks.Passive( event.xmotion.x, event.xmotion.y ); + } + } + } + break; + + case ButtonRelease: + case ButtonPress: + { + GLboolean pressed = TRUE ; + int button; + + if ( event.type == ButtonRelease ) pressed = FALSE ; + + /* + * A mouse button has been pressed or released. Traditionally, + * break if the window was found within the freeglut structures. + */ + GETMOUSE( xbutton ); + + /* + * GLUT API assumes that you can't have more than three mouse buttons, so: + */ + switch( event.xbutton.button ) + { + /* + * WARNING: this might be wrong, if we only have two mouse buttons, + * Button2 might mean the right button, isn't that right? + */ + case Button1: button = GLUT_LEFT_BUTTON; break; + case Button2: button = GLUT_MIDDLE_BUTTON; break; + case Button3: button = GLUT_RIGHT_BUTTON; break; + default: button = -1; break; + } + + /* + * Skip the unwanted mouse buttons... + */ + if( button == -1 ) + break; + + /* + * Do not execute the application's mouse callback if a menu is hooked to this button. + * In that case an appropriate private call should be generated. + * Near as I can tell, this is the menu behaviour: + * - Down-click the menu button, menu not active: activate the menu with its upper left-hand corner at the mouse location. + * - Down-click any button outside the menu, menu active: deactivate the menu + * - Down-click any button inside the menu, menu active: select the menu entry and deactivate the menu + * - Up-click the menu button, menu not active: nothing happens + * - Up-click the menu button outside the menu, menu active: nothing happens + * - Up-click the menu button inside the menu, menu active: select the menu entry and deactivate the menu + */ + if ( window->ActiveMenu != NULL ) /* Window has an active menu, it absorbs any mouse click */ + { + if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE ) /* Inside the menu, invoke the callback and deactivate the menu*/ + { + /* Save the current window and menu and set the current window to the window whose menu this is */ + SFG_Window *save_window = fgStructure.Window ; + SFG_Menu *save_menu = fgStructure.Menu ; + fgSetWindow ( window ) ; + fgStructure.Menu = window->ActiveMenu ; + + /* Execute the menu callback */ + fgExecuteMenuCallback ( window->ActiveMenu ) ; + fgDeactivateMenu ( window ) ; + + /* Restore the current window and menu */ + fgSetWindow ( save_window ) ; + fgStructure.Menu = save_menu ; + } + else /* Outside the menu, deactivate the menu if it's a downclick */ + { + if ( pressed == TRUE ) fgDeactivateMenu ( window ) ; + } + + /* + * Let's make the window redraw as a result of the mouse click and menu activity. + */ + window->State.Redisplay = TRUE ; + + break ; + } + + /* + * No active menu, let's check whether we need to activate one. + */ + if ( ( window->Menu[ button ] != NULL ) && ( pressed == TRUE ) ) + { + /* + * Let's make the window redraw as a result of the mouse click. + */ + window->State.Redisplay = TRUE ; + + /* + * Activate the appropriate menu structure... + */ + fgActivateMenu( window, button ); + + break; + } + + /* + * Check if there is a mouse callback hooked to the window + */ + if( window->Callbacks.Mouse == NULL ) + break; + + /* + * Set the current window + */ + fgSetWindow( window ); + + /* + * Remember the current modifiers state + */ + modifiers = 0; + if (event.xbutton.state & (ShiftMask|LockMask)) + modifiers |= GLUT_ACTIVE_SHIFT; + if (event.xbutton.state & ControlMask) + modifiers |= GLUT_ACTIVE_CTRL; + if (event.xbutton.state & Mod1Mask) + modifiers |= GLUT_ACTIVE_ALT; + window->State.Modifiers = modifiers; + + /* + * Finally execute the mouse callback + */ + window->Callbacks.Mouse( + button, + event.type == ButtonPress ? GLUT_DOWN : GLUT_UP, + event.xbutton.x, + event.xbutton.y + ); + + /* + * Trash the modifiers state + */ + window->State.Modifiers = 0xffffffff; + } + break; + + case KeyRelease: + case KeyPress: + { + FGCBkeyboard keyboard_cb; + FGCBspecial special_cb; + + /* + * A key has been pressed, find the window that had the focus: + */ + GETMOUSE( xkey ); + + if( event.type == KeyPress ) + { + keyboard_cb = window->Callbacks.Keyboard; + special_cb = window->Callbacks.Special; + } + else + { + keyboard_cb = window->Callbacks.KeyboardUp; + special_cb = window->Callbacks.SpecialUp; + } + + /* + * Is there a keyboard/special callback hooked for this window? + */ + if( (keyboard_cb != NULL) || (special_cb != NULL) ) + { + XComposeStatus composeStatus; + char asciiCode[ 32 ]; + KeySym keySym; + int len; + + /* + * Check for the ASCII/KeySym codes associated with the event: + */ + len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus ); + + /* + * Get ready to calling the keyboard/special callbacks + */ + fgSetWindow( window ); + + /* + * GLUT API tells us to have two separate callbacks... + */ + if( len > 0 ) + { + /* + * ...one for the ASCII translateable keypresses... + */ + if( keyboard_cb != NULL ) + { + /* + * Remember the current modifiers state + */ + modifiers = 0; + if (event.xkey.state & (ShiftMask|LockMask)) + modifiers |= GLUT_ACTIVE_SHIFT; + if (event.xkey.state & ControlMask) + modifiers |= GLUT_ACTIVE_CTRL; + if (event.xkey.state & Mod1Mask) + modifiers |= GLUT_ACTIVE_ALT; + window->State.Modifiers = modifiers; + + /* + * Execute the callback + */ + keyboard_cb( asciiCode[ 0 ], event.xkey.x, event.xkey.y ); + + /* + * Trash the modifiers state + */ + window->State.Modifiers = 0xffffffff; + } + } + else + { + int special = -1; + + /* + * ...and one for all the others, which need to be translated to GLUT_KEY_Xs... + */ + switch( keySym ) + { + /* + * First the function keys come: + */ + case XK_F1: special = GLUT_KEY_F1; break; + case XK_F2: special = GLUT_KEY_F2; break; + case XK_F3: special = GLUT_KEY_F3; break; + case XK_F4: special = GLUT_KEY_F4; break; + case XK_F5: special = GLUT_KEY_F5; break; + case XK_F6: special = GLUT_KEY_F6; break; + case XK_F7: special = GLUT_KEY_F7; break; + case XK_F8: special = GLUT_KEY_F8; break; + case XK_F9: special = GLUT_KEY_F9; break; + case XK_F10: special = GLUT_KEY_F10; break; + case XK_F11: special = GLUT_KEY_F11; break; + case XK_F12: special = GLUT_KEY_F12; break; + + /* + * Then the arrows and stuff: + */ + case XK_Left: special = GLUT_KEY_LEFT; break; + case XK_Right: special = GLUT_KEY_RIGHT; break; + case XK_Up: special = GLUT_KEY_UP; break; + case XK_Down: special = GLUT_KEY_DOWN; break; + + case XK_KP_Prior: + case XK_Prior: special = GLUT_KEY_PAGE_UP; break; + case XK_KP_Next: + case XK_Next: special = GLUT_KEY_PAGE_DOWN; break; + case XK_KP_Home: + case XK_Home: special = GLUT_KEY_HOME; break; + case XK_KP_End: + case XK_End: special = GLUT_KEY_END; break; + case XK_KP_Insert: + case XK_Insert: special = GLUT_KEY_INSERT; break; + } + + /* + * Execute the callback (if one has been specified), + * given that the special code seems to be valid... + */ + if( (special_cb != NULL) && (special != -1) ) + { + /* + * Remember the current modifiers state + */ + modifiers = 0; + if (event.xkey.state & (ShiftMask|LockMask)) + modifiers |= GLUT_ACTIVE_SHIFT; + if (event.xkey.state & ControlMask) + modifiers |= GLUT_ACTIVE_CTRL; + if (event.xkey.state & Mod1Mask) + modifiers |= GLUT_ACTIVE_ALT; + window->State.Modifiers = modifiers; + + special_cb( special, event.xkey.x, event.xkey.y ); + + /* + * Trash the modifiers state + */ + window->State.Modifiers = 0xffffffff; + } + } + } + } + break; + } + } + else + { + /* + * Have all the timers checked. + */ + fghCheckTimers(); + + /* + * Poll the joystick and notify all windows that want to be notified... + */ + fghCheckJoystickPolls(); + + /* + * No messages in the queue, which means we are idling... + */ + if( fgState.IdleCallback != NULL ) + fgState.IdleCallback(); + + /* + * Remember about displaying all the windows that have + * been marked for a redisplay (possibly in the idle call): + */ + fghDisplayAll(); + } + +#elif TARGET_HOST_WIN32 + + MSG stMsg; + + /* + * The windows processing is considerably smaller + */ + if( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) ) + { + /* + * Grab the message now, checking for WM_QUIT + */ + if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 ) + fgState.ExecState = GLUT_EXEC_STATE_STOP ; + + /* + * Translate virtual-key messages and send them to the window... + */ + TranslateMessage( &stMsg ); + DispatchMessage( &stMsg ); + } + else + { + /* + * Have all the timers checked. + */ + fghCheckTimers(); + + /* + * Poll the joystick and notify all windows that want to be notified... + */ + fghCheckJoystickPolls(); + + /* + * No messages in the queue, which means we are idling... + */ + if( fgState.IdleCallback != NULL ) + fgState.IdleCallback(); + + /* + * Remember about displaying all the windows that have + * been marked for a redisplay (possibly in the idle call): + */ + fghDisplayAll(); + } +#endif +} + +/* + * Enters the freeglut processing loop. Stays until the "ExecState" changes to "GLUT_EXEC_STATE_STOP". + */ +void FGAPIENTRY glutMainLoop( void ) +{ +#if TARGET_HOST_WIN32 + SFG_Window *window = fgStructure.Windows.First ; +#endif + + /* + * Make sure the display has been created etc. + */ + freeglut_assert_ready; + +#if TARGET_HOST_WIN32 + /* + * Processing before the main loop: If there is a window which is open and which + * has a visibility callback, call it. I know this is an ugly hack, but I'm not sure + * what else to do about it. Ideally we should leave something uninitialized in the + * create window code and initialize it in the main loop, and have that initialization + * create a "WM_ACTIVATE" message. Then we would put the visibility callback code in + * the "case WM_ACTIVATE" block below. - John Fay -- 10/24/02 + */ + while ( window != NULL ) + { + if ( window->Callbacks.Visibility != NULL ) + window->Callbacks.Visibility ( window->State.Visible ) ; + + window = window->Node.Next ; + } +#endif + + /* + * Set freeglut to be running + */ + fgState.ExecState = GLUT_EXEC_STATE_RUNNING ; + + /* + * Enter the main loop itself. Inside the loop, process events and check for loop exit. + */ + while ( fgState.ExecState == GLUT_EXEC_STATE_RUNNING ) + { + glutMainLoopEvent () ; + + /* + * If an event caused a window to be closed, do the actual closing here + */ + fgCloseWindows () ; + + /* + * If there are no more windows open, stop execution + */ + if ( fgStructure.Windows.First == NULL ) + fgState.ExecState = GLUT_EXEC_STATE_STOP ; + } + + + /* + * If we got here by the user closing a window or by the application closing down, there may still be windows open. + */ + fgCleanUpGlutsMess () ; + + /* + * Check whether we return to the calling program or simply exit + */ + if ( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT ) + exit ( 0 ) ; + + /* + * When this loop terminates, destroy the display, state and structure + * of a freeglut session, so that another glutInit() call can happen + */ + fgDeinitialize(); +} + +/* + * Leaves the freeglut processing loop. + */ +void FGAPIENTRY glutLeaveMainLoop( void ) +{ + fgState.ExecState = GLUT_EXEC_STATE_STOP ; +} + +/* + * The window procedure for handling Win32 events + */ +#if TARGET_HOST_WIN32 +LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + SFG_Window* window = fgWindowByHandle( hWnd ); + PAINTSTRUCT ps; + LONG lRet = 1; + + if ( ( window == NULL ) && ( uMsg != WM_CREATE ) ) + return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ); + +/* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ) ; */ + /* + * Check what type of message are we receiving + */ + switch( uMsg ) + { + case WM_CREATE: + /* + * The window structure is passed as the creation structure paramter... + */ + window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams); + assert( window != NULL ); + + /* + * We can safely store the window's handle now: + */ + window->Window.Handle = hWnd; + + /* + * Get the window's device context + */ + window->Window.Device = GetDC( hWnd ); + + /* + * Setup the pixel format of our window + */ + fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE ); + + /* + * Create the OpenGL rendering context now + */ + window->Window.Context = wglCreateContext( window->Window.Device ); + + /* + * Still, we'll be needing to explicitly resize the window + */ + window->State.NeedToResize = TRUE; + + /* + * Finally, have the window's device context released + */ + ReleaseDC( window->Window.Handle, window->Window.Device ); + break; + + case WM_SIZE: + /* + * We got resized... But check if the window has been already added... + */ + fghReshapeWindowByHandle( hWnd, LOWORD(lParam), HIWORD(lParam) ); + break; +#if 0 + case WM_SETFOCUS: + printf("WM_SETFOCUS: %p\n", window ); + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break; + + case WM_ACTIVATE: + if (LOWORD(wParam) != WA_INACTIVE) + { + /* glutSetCursor( fgStructure.Window->State.Cursor ); */ + printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window, window->State.Cursor ); + + glutSetCursor( window->State.Cursor ); + } + + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break; +#endif + + case WM_SETCURSOR: + /* + * Windows seems to need reminding to erase the cursor for NONE. + */ +#if 0 + if ((LOWORD(lParam) == HTCLIENT) && + (fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE)) + SetCursor( NULL ); +#else + /* Set the cursor AND change it for this window class. */ +# define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \ + break; + /* Nuke the cursor AND change it for this window class. */ +# define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \ + break; + + if (LOWORD(lParam) == HTCLIENT) + switch( window->State.Cursor ) + { + MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW ); + MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP ); + MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL ); + MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS ); + MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT ); + MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_UPARROW ); + MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS ); + /* MAP_CURSOR( GLUT_CURSOR_NONE, IDC_NO ); */ + ZAP_CURSOR( GLUT_CURSOR_NONE, NULL ); + + default: + MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_ARROW ); + } +#endif + else + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break; + + case WM_SHOWWINDOW: + /* + * We are now Visible! + */ + window->State.Visible = TRUE; + window->State.Redisplay = TRUE; + break; + + case WM_PAINT: + /* + * Start the painting job + */ + + BeginPaint( hWnd, &ps ); + + /* + * Call the engine's main frame drawing method + */ + fghRedrawWindowByHandle( hWnd ); + + /* + * End the painting job, release the device context + */ + EndPaint( hWnd, &ps ); + break; + + case WM_CLOSE: + /* + * Make sure we don't close a window with current context active + */ + if( fgStructure.Window == window ) + { + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( window->Window.Context ); + } + + /* + * Put on a linked list of windows to be removed after all the callbacks have returned + */ + fgAddToWindowDestroyList ( window, FALSE ) ; + + /* + * Proceed with the window destruction + */ + DestroyWindow( hWnd ); + break; + + case WM_DESTROY: + /* + * The window already got destroyed, so don't bother with it. + */ + return( 0 ); + + case WM_MOUSEMOVE: + { + /* + * The mouse cursor has moved. Remember the new mouse cursor's position + */ + window->State.MouseX = LOWORD( lParam ); + window->State.MouseY = HIWORD( lParam ); + + /* + * Fallback if there's an active menu hooked to this window + */ + if( window->ActiveMenu != NULL ) + { + /* + * Let's make the window redraw as a result of the mouse motion. + */ + window->State.Redisplay = TRUE ; + + break; + } + + /* + * Remember the current modifiers state. + */ + window->State.Modifiers = + ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | + ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | + ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); + + /* + * Check if any of the mouse buttons is pressed... + */ + if( (wParam & MK_LBUTTON) || (wParam & MK_MBUTTON) || (wParam & MK_RBUTTON) ) + { + /* + * Yeah, indeed. We need to use the motion callback then: + */ + if( window->Callbacks.Motion != NULL ) + { + /* + * Make sure the current window is set... + */ + fgSetWindow( window ); + + /* + * Execute the active mouse motion callback now + */ + window->Callbacks.Motion( window->State.MouseX, window->State.MouseY ); + } + } + else + { + /* + * All mouse buttons are up, execute the passive mouse motion callback + */ + if( window->Callbacks.Passive != NULL ) + { + /* + * Make sure the current window is set + */ + fgSetWindow( window ); + + /* + * Execute the passive mouse motion callback + */ + window->Callbacks.Passive( window->State.MouseX, window->State.MouseY ); + } + } + + /* + * Thrash the current modifiers state now + */ + window->State.Modifiers = 0xffffffff; + } + break; + + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + { + GLboolean pressed = TRUE; + int button; + + /* + * The mouse cursor has moved. Remember the new mouse cursor's position + */ + window->State.MouseX = LOWORD( lParam ); + window->State.MouseY = HIWORD( lParam ); + + /* + * We're curious about the GLUT API button name... + */ + switch( uMsg ) + { + case WM_LBUTTONDOWN: pressed = TRUE; button = GLUT_LEFT_BUTTON; break; + case WM_MBUTTONDOWN: pressed = TRUE; button = GLUT_MIDDLE_BUTTON; break; + case WM_RBUTTONDOWN: pressed = TRUE; button = GLUT_RIGHT_BUTTON; break; + case WM_LBUTTONUP: pressed = FALSE; button = GLUT_LEFT_BUTTON; break; + case WM_MBUTTONUP: pressed = FALSE; button = GLUT_MIDDLE_BUTTON; break; + case WM_RBUTTONUP: pressed = FALSE; button = GLUT_RIGHT_BUTTON; break; + default: pressed = FALSE; button = -1; break; + } + + /* + * The left and right mouse buttons might have been swapped... + */ + if( GetSystemMetrics( SM_SWAPBUTTON ) ) + if( button == GLUT_LEFT_BUTTON ) button = GLUT_RIGHT_BUTTON; + else if( button == GLUT_RIGHT_BUTTON ) button = GLUT_LEFT_BUTTON; + + /* + * Hey, what's up with you? + */ + if( button == -1 ) + return( DefWindowProc( hWnd, uMsg, lParam, wParam ) ); + + /* + * Do not execute the application's mouse callback if a menu is hooked to this button. + * In that case an appropriate private call should be generated. + * Near as I can tell, this is the menu behaviour: + * - Down-click the menu button, menu not active: activate the menu with its upper left-hand corner at the mouse location. + * - Down-click any button outside the menu, menu active: deactivate the menu + * - Down-click any button inside the menu, menu active: select the menu entry and deactivate the menu + * - Up-click the menu button, menu not active: nothing happens + * - Up-click the menu button outside the menu, menu active: nothing happens + * - Up-click the menu button inside the menu, menu active: select the menu entry and deactivate the menu + */ + if ( window->ActiveMenu != NULL ) /* Window has an active menu, it absorbs any mouse click */ + { + if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE ) /* Inside the menu, invoke the callback and deactivate the menu*/ + { + /* Save the current window and menu and set the current window to the window whose menu this is */ + SFG_Window *save_window = fgStructure.Window ; + SFG_Menu *save_menu = fgStructure.Menu ; + fgSetWindow ( window ) ; + fgStructure.Menu = window->ActiveMenu ; + + /* Execute the menu callback */ + fgExecuteMenuCallback ( window->ActiveMenu ) ; + fgDeactivateMenu ( window ) ; + + /* Restore the current window and menu */ + fgSetWindow ( save_window ) ; + fgStructure.Menu = save_menu ; + } + else /* Outside the menu, deactivate the menu if it's a downclick */ + { + if ( pressed == TRUE ) fgDeactivateMenu ( window ) ; + } + + /* + * Let's make the window redraw as a result of the mouse click and menu activity. + */ + window->State.Redisplay = TRUE ; + + break ; + } + + /* + * No active menu, let's check whether we need to activate one. + */ + if ( ( window->Menu[ button ] != NULL ) && ( pressed == TRUE ) ) + { + /* + * Let's make the window redraw as a result of the mouse click. + */ + window->State.Redisplay = TRUE ; + + /* + * Activate the appropriate menu structure... + */ + fgActivateMenu( window, button ); + + break; + } + + /* + * Check if there is a mouse callback hooked to the window + */ + if( window->Callbacks.Mouse == NULL ) + break; + + /* + * Set the current window + */ + fgSetWindow( window ); + + /* + * Remember the current modifiers state. + */ + window->State.Modifiers = + ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | + ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | + ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); + + /* + * Finally execute the mouse callback + */ + window->Callbacks.Mouse( + button, + pressed == TRUE ? GLUT_DOWN : GLUT_UP, + window->State.MouseX, + window->State.MouseY + ); + + /* + * Trash the modifiers state + */ + window->State.Modifiers = 0xffffffff; + } + break; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + { + int keypress = -1; + POINT mouse_pos ; + + /* + * Ignore the automatic key repetition if needed: + */ + if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) ) + break; + + /* + * Set the current window + */ + fgSetWindow( window ); + + /* + * Remember the current modifiers state. This is done here in order + * to make sure the VK_DELETE keyboard callback is executed properly. + */ + window->State.Modifiers = + ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | + ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | + ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); + + /* + * Set the mouse position + */ + GetCursorPos ( &mouse_pos ) ; + ScreenToClient ( window->Window.Handle, &mouse_pos ) ; + + window->State.MouseX = mouse_pos.x ; + window->State.MouseY = mouse_pos.y ; + + /* + * Convert the Win32 keystroke codes to GLUTtish way + */ +# define KEY(a,b) case a: keypress = b; break; + + switch( wParam ) + { + /* + * Most of the special characters can be handled automagically... + */ + KEY( VK_F1, GLUT_KEY_F1 ); KEY( VK_F2, GLUT_KEY_F2 ); + KEY( VK_F3, GLUT_KEY_F3 ); KEY( VK_F4, GLUT_KEY_F4 ); + KEY( VK_F5, GLUT_KEY_F5 ); KEY( VK_F6, GLUT_KEY_F6 ); + KEY( VK_F7, GLUT_KEY_F7 ); KEY( VK_F8, GLUT_KEY_F8 ); + KEY( VK_F9, GLUT_KEY_F9 ); KEY( VK_F10, GLUT_KEY_F10 ); + KEY( VK_F11, GLUT_KEY_F11 ); KEY( VK_F12, GLUT_KEY_F12 ); + KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); + KEY( VK_HOME, GLUT_KEY_HOME ); KEY( VK_END, GLUT_KEY_END ); + KEY( VK_LEFT, GLUT_KEY_LEFT ); KEY( VK_UP, GLUT_KEY_UP ); + KEY( VK_RIGHT, GLUT_KEY_RIGHT ); KEY( VK_DOWN, GLUT_KEY_DOWN ); + KEY( VK_INSERT, GLUT_KEY_INSERT ); + + /* + * ...yet there is a small exception we need to have handled... + */ + case VK_DELETE: + /* + * The delete key should be treated as an ASCII keypress: + */ + if( window->Callbacks.Keyboard != NULL ) + window->Callbacks.Keyboard( 127, window->State.MouseX, window->State.MouseY ); + } + + /* + * Execute the special callback, if present, given the conversion was a success: + */ + if( (keypress != -1) && (window->Callbacks.Special != NULL) ) + { + /* + * Have the special callback executed: + */ + window->Callbacks.Special( keypress, window->State.MouseX, window->State.MouseY ); + } + + /* + * Thrash the modifiers register now + */ + window->State.Modifiers = 0xffffffff; + } + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + { + int keypress = -1; + POINT mouse_pos ; + + /* + * Set the current window + */ + fgSetWindow( window ); + + /* + * Remember the current modifiers state. This is done here in order + * to make sure the VK_DELETE keyboard callback is executed properly. + */ + window->State.Modifiers = + ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | + ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | + ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); + + /* + * Set the mouse position + */ + GetCursorPos ( &mouse_pos ) ; + ScreenToClient ( window->Window.Handle, &mouse_pos ) ; + + window->State.MouseX = mouse_pos.x ; + window->State.MouseY = mouse_pos.y ; + + /* + * Convert the Win32 keystroke codes to GLUTtish way. "KEY(a,b)" was defined under "WM_KEYDOWN" + */ + + switch( wParam ) + { + /* + * Most of the special characters can be handled automagically... + */ + KEY( VK_F1, GLUT_KEY_F1 ); KEY( VK_F2, GLUT_KEY_F2 ); + KEY( VK_F3, GLUT_KEY_F3 ); KEY( VK_F4, GLUT_KEY_F4 ); + KEY( VK_F5, GLUT_KEY_F5 ); KEY( VK_F6, GLUT_KEY_F6 ); + KEY( VK_F7, GLUT_KEY_F7 ); KEY( VK_F8, GLUT_KEY_F8 ); + KEY( VK_F9, GLUT_KEY_F9 ); KEY( VK_F10, GLUT_KEY_F10 ); + KEY( VK_F11, GLUT_KEY_F11 ); KEY( VK_F12, GLUT_KEY_F12 ); + KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); + KEY( VK_HOME, GLUT_KEY_HOME ); KEY( VK_END, GLUT_KEY_END ); + KEY( VK_LEFT, GLUT_KEY_LEFT ); KEY( VK_UP, GLUT_KEY_UP ); + KEY( VK_RIGHT, GLUT_KEY_RIGHT ); KEY( VK_DOWN, GLUT_KEY_DOWN ); + KEY( VK_INSERT, GLUT_KEY_INSERT ); + + /* + * ...yet there is a small exception we need to have handled... + */ + case VK_DELETE: + /* + * The delete key should be treated as an ASCII keypress: + */ + if( window->Callbacks.KeyboardUp != NULL ) + window->Callbacks.KeyboardUp( 127, window->State.MouseX, window->State.MouseY ); + + break ; + default: + { + /* + * Call the KeyboardUp callback for a regular character if there is one. + */ + BYTE state[ 256 ]; + WORD code[ 2 ]; + + GetKeyboardState(state); + + if ( ToAscii( wParam, 0, state, code, 0 ) == 1 ) + wParam=code[ 0 ]; + + if( window->Callbacks.KeyboardUp != NULL ) + window->Callbacks.KeyboardUp( (char)wParam, window->State.MouseX, window->State.MouseY ); + } + } + + /* + * Execute the special callback, if present, given the conversion was a success: + */ + if( (keypress != -1) && (window->Callbacks.SpecialUp != NULL) ) + { + /* + * Have the special callback executed: + */ + window->Callbacks.SpecialUp( keypress, window->State.MouseX, window->State.MouseY ); + } + + /* + * Thrash the modifiers register now + */ + window->State.Modifiers = 0xffffffff; + } + break; + + case WM_SYSCHAR: + case WM_CHAR: + { + /* + * Ignore the automatic key repetition if needed: + */ + if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) ) + break; + + /* + * Clear to go with the keyboard callback, if registered: + */ + if( window->Callbacks.Keyboard != NULL ) + { + /* + * Remember the current modifiers state + */ + window->State.Modifiers = + ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | + ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | + ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); + + /* + * Have the special callback executed: + */ + window->Callbacks.Keyboard( (char)wParam, window->State.MouseX, window->State.MouseY ); + + /* + * Thrash the modifiers register now + */ + window->State.Modifiers = 0xffffffff; + } + } + break; + + case WM_CAPTURECHANGED : /* User has finished resizing the window, force a redraw */ + if ( window->Callbacks.Display ) + window->Callbacks.Display () ; + +/* lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; */ + break ; + + /* + * Other messages that I have seen and which are not handled already + */ + case WM_SETTEXT : /* 0x000c */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Pass it on to "DefWindowProc" to set the window text */ + break ; + + case WM_GETTEXT : /* 0x000d */ + /* Ideally we would copy the title of the window into "lParam" */ +/* strncpy ( (char *)lParam, "Window Title", wParam ) ; + lRet = ( wParam > 12 ) ? 12 : wParam ; */ /* the number of characters copied */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break ; + + case WM_GETTEXTLENGTH : /* 0x000e */ + /* Ideally we would get the length of the title of the window */ + lRet = 12 ; /* the number of characters in "Window Title\0" (see above) */ + break ; + + case WM_ERASEBKGND : /* 0x0014 */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break ; + + case WM_SYNCPAINT : /* 0x0088 */ + /* Another window has moved, need to update this one */ + window->State.Redisplay = TRUE ; + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Help screen says this message must be passed to "DefWindowProc" */ + break ; + + case WM_NCPAINT : /* 0x0085 */ + /* Need to update the border of this window */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Pass it on to "DefWindowProc" to repaint a standard border */ + break ; + + default: + /* + * Handle unhandled messages + */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break; + } + + return( lRet ); +} +#endif + +/*** END OF FILE ***/ diff --git a/src/freeglut_menu.c b/src/freeglut_menu.c new file mode 100644 index 0000000..921deec --- /dev/null +++ b/src/freeglut_menu.c @@ -0,0 +1,860 @@ +/* + * freeglut_menu.c + * + * Pull-down menu creation and handling. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-menu" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * It would be cool if the submenu entries were somehow marked, for example with a dings + * on the right menu border or something like that. Think about the possibility of doing + * the menu on layers *or* using the native window system instead of OpenGL. + */ + +/* -- DEFINITIONS ---------------------------------------------------------- */ + +/* + * We'll be using freeglut fonts to draw the menu + */ +#define FREEGLUT_MENU_FONT GLUT_BITMAP_8_BY_13 +#define FREEGLUT_MENU_HEIGHT 15 +#define FREEGLUT_MENU_BORDER 8 + + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * Private static function to find a menu entry by index + */ +static SFG_MenuEntry *fghFindMenuEntry( SFG_Menu* menu, int index ) +{ + SFG_MenuEntry *entry; + int i = 1; + + for( entry = menu->Entries.First; entry; entry = entry->Node.Next) + { + if (i == index) + break; + ++i; + } + + return entry; +} + +/* + * Private static function to check for the current menu/sub menu activity state + */ +static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu ) +{ + SFG_MenuEntry* menuEntry; + int x, y; + + /* + * First of all check any of the active sub menus... + */ + for( menuEntry = menu->Entries.First; menuEntry; + menuEntry = menuEntry->Node.Next ) + { + /* + * Is that an active sub menu by any case? + */ + if( menuEntry->SubMenu != NULL && menuEntry->IsActive == TRUE ) + { + /* + * OK, have the sub-menu checked, too. If it returns TRUE, it will mean + * that it caught the mouse cursor and we do not need to regenerate + * the activity list, and so our parents do... + */ + if( fghCheckMenuStatus( window, menuEntry->SubMenu ) == TRUE ) + return( TRUE ); + } + } + + /* + * That much about our sub menus, let's get to checking the current menu: + */ + x = window->State.MouseX - menu->X; + y = window->State.MouseY - menu->Y; + + /* + * Mark all menu entries inactive... + */ + for( menuEntry = menu->Entries.First; menuEntry; + menuEntry = menuEntry->Node.Next ) + { + menuEntry->IsActive = FALSE; + } + + menu->IsActive = FALSE; + + /* + * Check if the mouse cursor is contained within the current menu box + */ + if( x >= 0 && x < menu->Width && y >= 0 && y < menu->Height ) + { + /* + * Calculation of the highlighted menu item is easy enough now: + */ + int menuID = y / FREEGLUT_MENU_HEIGHT; + + /* + * The mouse cursor is somewhere over our box, check it out. + */ + menuEntry = fghFindMenuEntry( menu, menuID + 1 ); + assert( menuEntry != NULL ); + + /* + * Mark the menu as active... + */ + menuEntry->IsActive = TRUE; + menuEntry->Ordinal = menuID; + + /* + * Don't forget about marking the current menu as active, too: + */ + menu->IsActive = TRUE; + + /* + * OKi, we have marked that entry as active, but it would be also + * nice to have its contents updated, in case it's a sub menu. + * Also, ignore the return value of the check function: + */ + if( menuEntry->SubMenu != NULL ) + { + /* + * Set up the initial menu position now... + */ + + menuEntry->SubMenu->X = menu->X + menu->Width ; + menuEntry->SubMenu->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ; + + /* + * Make sure the submenu stays within the window + */ + if ( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > glutGet ( GLUT_WINDOW_WIDTH ) ) + { + menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width ; + if ( menuEntry->SubMenu->X < 0 ) + menuEntry->SubMenu->X = glutGet ( GLUT_WINDOW_WIDTH ) - menuEntry->SubMenu->Width ; + } + + /* + * ...then check the submenu's state: + */ + fghCheckMenuStatus( window, menuEntry->SubMenu ); + + /* + * Even if the submenu turned up inactive, activate it because its parent entry is active + */ + menuEntry->SubMenu->IsActive = TRUE ; + } + + /* + * Report back that we have caught the menu cursor + */ + return( TRUE ); + } + + /* + * Looks like the menu cursor is somewhere else... + */ + return( FALSE ); +} + +/* + * Displays a menu box and all of its submenus (if they are active) + */ +static void fghDisplayMenuBox( SFG_Menu* menu ) +{ + SFG_MenuEntry *menuEntry; + int i; + + /* + * Have the menu box drawn first. The +- values are + * here just to make it more nice-looking... + */ + glColor4f( 0.0f, 0.0f, 0.0f, 1.0f ); + glBegin( GL_QUADS ); + glVertex2i( menu->X , menu->Y - 1 ); + glVertex2i( menu->X + menu->Width, menu->Y - 1 ); + glVertex2i( menu->X + menu->Width, menu->Y + 4 + menu->Height ); + glVertex2i( menu->X , menu->Y + 4 + menu->Height ); + glEnd(); + + glColor4f( 0.3f, 0.4f, 0.5f, 1.0f ); + glBegin( GL_QUADS ); + glVertex2i( menu->X - 2 , menu->Y + 1 ); + glVertex2i( menu->X - 2 + menu->Width, menu->Y + 1 ); + glVertex2i( menu->X - 2 + menu->Width, menu->Y + 2 + menu->Height ); + glVertex2i( menu->X - 2 , menu->Y + 2 + menu->Height ); + glEnd(); + + /* + * Check if any of the submenus is currently active... + */ + for( menuEntry = menu->Entries.First; menuEntry; + menuEntry = menuEntry->Node.Next ) + { + /* + * Has the menu been marked as active, maybe? + */ + if( menuEntry->IsActive == TRUE ) + { + /* + * That's truly right, and we need to have it highlighted. + * There is an assumption that mouse cursor didn't move + * since the last check of menu activity state: + */ + int menuID = menuEntry->Ordinal; + + /* + * So have the highlight drawn... + */ + glColor4f( 0.2f, 0.3f, 0.4f, 1.0f ); + glBegin( GL_QUADS ); + glVertex2i( menu->X - 2 , menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 ); + glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 ); + glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 ); + glVertex2i( menu->X - 2 , menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 ); + glEnd(); + } + } + + /* + * Print the menu entries now... + */ + glColor4f( 1, 1, 1, 1 ); + + for( menuEntry = menu->Entries.First, i=0; menuEntry; + menuEntry = menuEntry->Node.Next, ++i ) + { + /* + * Move the raster into position... + */ + glRasterPos2i( + menu->X + FREEGLUT_MENU_BORDER, + menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT + ); + + /* + * Have the label drawn, character after character: + */ + glutBitmapString( FREEGLUT_MENU_FONT, menuEntry->Text); + + /* + * If it's a submenu, draw a right arrow + */ + if ( menuEntry->SubMenu != NULL ) + { + GLubyte arrow_char [] = { 0, 0, 32, 48, 56, 60, 62, 63, 62, 60, 56, 48, 32, 0, 0 } ; + int width = glutBitmapWidth ( FREEGLUT_MENU_FONT, ' ' ) ; + + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); + + /* + * Set up the pixel unpacking ways + */ + glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE ); + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 ); + glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + glRasterPos2i ( menu->X + menu->Width - 2 - width, + menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT ) ; + glBitmap ( width, FREEGLUT_MENU_HEIGHT, 0, 0, 0.0, 0.0, arrow_char ) ; + glPopClientAttrib(); + } + } + + /* + * Now we are ready to check if any of our children needs to be redrawn: + */ + for( menuEntry = menu->Entries.First; menuEntry; + menuEntry = menuEntry->Node.Next ) + { + /* + * Is that an active sub menu by any case? + */ + if( menuEntry->SubMenu != NULL && menuEntry->IsActive == TRUE ) + { + /* + * Yeah, indeed. Have it redrawn now: + */ + fghDisplayMenuBox( menuEntry->SubMenu ); + } + } +} + +/* + * Displays the currently active menu for the current window + */ +void fgDisplayMenu( void ) +{ + SFG_Window* window = fgStructure.Window; + SFG_Menu* menu = NULL; + + /* + * Make sure there is a current window available + */ + freeglut_assert_window; + + /* + * Check if there is an active menu attached to this window... + */ + menu = window->ActiveMenu; + + /* + * Did we find an active window? + */ + freeglut_return_if_fail( menu != NULL ); + /* + * Prepare the OpenGL state to do the rendering first: + */ + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT ); + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_TEXTURE_2D ); + glDisable( GL_LIGHTING ); + glDisable( GL_CULL_FACE ); + + /* + * We'll use an orthogonal projection matrix to draw the menu: + */ + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( + 0, glutGet( GLUT_WINDOW_WIDTH ), + glutGet( GLUT_WINDOW_HEIGHT ), 0, + -1, 1 + ); + + /* + * Model-view matix gets reset to identity: + */ + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + /* + * First of all, have the exact menu status check: + */ + fghCheckMenuStatus( window, menu ); + + /* + * The status has been updated and we're ready to have the menu drawn now: + */ + fghDisplayMenuBox( menu ); + + /* + * Restore the old OpenGL settings now + */ + glPopAttrib(); + + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} + +/* + * Activates a menu pointed by the function argument + */ +void fgActivateMenu( SFG_Window* window, int button ) +{ + int x, y; + + /* + * We'll be referencing this menu a lot, so remember its address: + */ + SFG_Menu* menu = window->Menu[ button ]; + + /* + * Mark the menu as active, so that it gets displayed: + */ + window->ActiveMenu = menu; + menu->IsActive = TRUE ; + + /* + * Grab the mouse cursor position respective to the current window + */ + x = window->State.MouseX; + y = window->State.MouseY; + + /* + * Set up the initial menu position now: + */ + menu->X = x ; + menu->Y = y ; + + fgSetWindow ( window ) ; + + if( x > ( glutGet( GLUT_WINDOW_WIDTH ) - menu->Width ) ) + menu->X = glutGet( GLUT_WINDOW_WIDTH ) - menu->Width; + if( y > ( glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height) ) + menu->Y = glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height; +} + +/* + * Check whether an active menu absorbs a mouse click + */ +GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) +{ + /* + * Near as I can tell, this is the active menu behaviour: + * - Down-click any button outside the menu, menu active: deactivate the menu + * - Down-click any button inside the menu, menu active: select the menu entry and deactivate the menu + * - Up-click the menu button outside the menu, menu active: nothing happens + * - Up-click the menu button inside the menu, menu active: select the menu entry and deactivate the menu + * Since menus can have submenus, we need to check this recursively. + */ + return fghCheckMenuStatus ( window, menu ) ; +} + +/* + * Function to check for menu entry selection on menu deactivation + */ +void fgExecuteMenuCallback( SFG_Menu* menu ) +{ + SFG_MenuEntry *menuEntry; + + /* + * First of all check any of the active sub menus... + */ + for( menuEntry = menu->Entries.First; menuEntry; menuEntry = menuEntry->Node.Next) + { + /* + * Is this menu entry active? + */ + if( menuEntry->IsActive == TRUE ) + { + /* + * If there is not a sub menu, execute the menu callback and return... + */ + if( menuEntry->SubMenu == NULL ) + { + /* + * ...certainly given that there is one... + */ + if( menu->Callback != NULL ) + menu->Callback( menuEntry->ID ); + + return; + } + + /* + * Otherwise recurse into the submenu. + */ + fgExecuteMenuCallback( menuEntry->SubMenu ); + + /* + * There is little sense in dwelling the search on + */ + return; + } + } +} + +/* + * Deactivates a menu pointed by the function argument. + */ +void fgDeactivateMenu( SFG_Window *window ) +{ + /* + * Check if there is an active menu attached to this window... + */ + SFG_Menu* menu = window->ActiveMenu; + + /* + * Did we find an active window? + */ + freeglut_return_if_fail( menu != NULL ); + + /* + * Forget about having that menu active anymore, now: + */ + window->ActiveMenu = NULL; + menu->IsActive = FALSE ; +} + +/* + * Recalculates current menu's box size + */ +void fghCalculateMenuBoxSize( void ) +{ + SFG_MenuEntry* menuEntry; + int width = 0, height = 0; + + /* + * Make sure there is a current menu set + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + + /* + * The menu's box size depends on the menu entries: + */ + for( menuEntry = fgStructure.Menu->Entries.First; menuEntry; + menuEntry = menuEntry->Node.Next) + { + /* + * Update the menu entry's width value + */ + menuEntry->Width = glutBitmapLength( FREEGLUT_MENU_FONT, menuEntry->Text ); + + /* + * Check if it's the biggest we've found + */ + if( menuEntry->Width > width ) + width = menuEntry->Width; + + height += FREEGLUT_MENU_HEIGHT; + } + + /* + * Store the menu's box size now: + */ + fgStructure.Menu->Height = height; + fgStructure.Menu->Width = width + 2 * FREEGLUT_MENU_BORDER ; +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Creates a new menu object, adding it to the freeglut structure + */ +int FGAPIENTRY glutCreateMenu( void (* callback)( int ) ) +{ + /* + * The menu object creation code resides in freeglut_structure.c + */ + return( fgCreateMenu( callback )->ID ); +} + +/* + * Destroys a menu object, removing all references to it + */ +void FGAPIENTRY glutDestroyMenu( int menuID ) +{ + SFG_Menu* menu = fgMenuByID( menuID ); + + freeglut_assert_ready; freeglut_return_if_fail( menu != NULL ); + + /* + * The menu object destruction code resides in freeglut_structure.c + */ + fgDestroyMenu( menu ); +} + +/* + * Returns the ID number of the currently active menu + */ +int FGAPIENTRY glutGetMenu( void ) +{ + freeglut_assert_ready; + + /* + * Is there a current menu set? + */ + if( fgStructure.Menu != NULL ) + { + /* + * Yes, there is indeed... + */ + return( fgStructure.Menu->ID ); + } + + /* + * No, there is no current menu at all + */ + return( 0 ); +} + +/* + * Sets the current menu given its menu ID + */ +void FGAPIENTRY glutSetMenu( int menuID ) +{ + SFG_Menu* menu = fgMenuByID( menuID ); + + freeglut_assert_ready; freeglut_return_if_fail( menu != NULL ); + + /* + * The current menu pointer is stored in fgStructure.Menu + */ + fgStructure.Menu = menu; +} + +/* + * Adds a menu entry to the bottom of the current menu + */ +void FGAPIENTRY glutAddMenuEntry( const char* label, int value ) +{ + SFG_MenuEntry* menuEntry = calloc( sizeof(SFG_MenuEntry), 1 ); + + /* + * Make sure there is a current menu set + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + + /* + * Fill in the appropriate values... + */ + menuEntry->Text = strdup( label ); + menuEntry->ID = value; + + /* + * Have the new menu entry attached to the current menu + */ + fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node ); + + /* + * Update the menu's dimensions now + */ + fghCalculateMenuBoxSize(); +} + +/* + * Add a sub menu to the bottom of the current menu + */ +void FGAPIENTRY glutAddSubMenu( const char* label, int subMenuID ) +{ + SFG_MenuEntry* menuEntry = calloc( sizeof(SFG_MenuEntry), 1 ); + SFG_Menu* subMenu = fgMenuByID( subMenuID ); + + /* + * Make sure there is a current menu and the sub menu + * we want to attach actually exists... + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + freeglut_return_if_fail( subMenu != NULL ); + + /* + * Fill in the appropriate values + */ + menuEntry->Text = strdup( label ); + menuEntry->SubMenu = subMenu; + menuEntry->ID = -1; + + /* + * Have the new menu entry attached to the current menu + */ + fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node ); + + /* + * Update the menu's dimensions now + */ + fghCalculateMenuBoxSize(); +} + +/* + * Changes the specified menu item in the current menu into a menu entry + */ +void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ) +{ + SFG_MenuEntry* menuEntry = NULL; + + /* + * Make sure there is a current menu set... + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + + /* + * Get n-th menu entry in the current menu, starting from one: + */ + menuEntry = fghFindMenuEntry( fgStructure.Menu, item ); + + /* + * Make sure the menu entry exists + */ + freeglut_return_if_fail( menuEntry != NULL ); + + /* + * We want it to become a normal menu entry, so: + */ + if( menuEntry->Text != NULL ) + free( menuEntry->Text ); + + menuEntry->Text = strdup( label ); + menuEntry->ID = value; + menuEntry->SubMenu = NULL; + + /* + * Update the menu's dimensions now + */ + fghCalculateMenuBoxSize(); +} + +/* + * Changes the specified menu item in the current menu into a sub-menu trigger. + */ +void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int subMenuID ) +{ + SFG_Menu* subMenu = fgMenuByID( subMenuID ); + SFG_MenuEntry* menuEntry = NULL; + + /* + * Make sure there is a current menu set and the sub menu exists... + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + freeglut_return_if_fail( subMenu != NULL ); + + /* + * Get n-th menu entry in the current menu, starting from one: + */ + menuEntry = fghFindMenuEntry( fgStructure.Menu, item ); + + /* + * Make sure the menu entry exists + */ + freeglut_return_if_fail( menuEntry != NULL ); + + /* + * We want it to become a sub menu entry, so: + */ + if( menuEntry->Text != NULL ) + free( menuEntry->Text ); + + menuEntry->Text = strdup( label ); + menuEntry->SubMenu = subMenu; + menuEntry->ID = -1; + + /* + * Update the menu's dimensions now + */ + fghCalculateMenuBoxSize(); +} + +/* + * Removes the specified menu item from the current menu + */ +void FGAPIENTRY glutRemoveMenuItem( int item ) +{ + SFG_MenuEntry* menuEntry; + + /* + * Make sure there is a current menu set + */ + freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL ); + + /* + * Get n-th menu entry in the current menu, starting from one: + */ + menuEntry = fghFindMenuEntry( fgStructure.Menu, item ); + + /* + * Make sure the menu entry exists + */ + freeglut_return_if_fail( menuEntry != NULL ); + + /* + * Removing a menu entry is quite simple... + */ + fgListRemove( &fgStructure.Menu->Entries, &menuEntry->Node ); + + /* + * Free the entry label string, too + */ + free( menuEntry->Text ); + + free( menuEntry ); + + /* + * Update the menu's dimensions now + */ + fghCalculateMenuBoxSize(); +} + +/* + * Attaches a menu to the current window + */ +void FGAPIENTRY glutAttachMenu( int button ) +{ + freeglut_assert_ready; + + /* + * There must be a current window and a current menu set: + */ + freeglut_return_if_fail( fgStructure.Window != NULL || fgStructure.Menu != NULL ); + + /* + * Make sure the button value is valid (0, 1 or 2, see freeglut.h) + */ + freeglut_return_if_fail( button == GLUT_LEFT_BUTTON || button == GLUT_MIDDLE_BUTTON || button == GLUT_RIGHT_BUTTON ); + + /* + * It is safe now to attach the menu + */ + fgStructure.Window->Menu[ button ] = fgStructure.Menu; +} + +/* + * Detaches a menu from the current window + */ +void FGAPIENTRY glutDetachMenu( int button ) +{ + freeglut_assert_ready; + + /* + * There must be a current window set: + */ + freeglut_return_if_fail( fgStructure.Window != NULL ); + + /* + * Make sure the button value is valid (0, 1 or 2, see freeglut.h) + */ + freeglut_return_if_fail( button != 0 && button != 1 && button != 2 ); + + /* + * It is safe now to detach the menu + */ + fgStructure.Window->Menu[ button ] = NULL; +} + +/* + * A.Donev: Set and retrieve the menu's user data + */ +void* FGAPIENTRY glutGetMenuData( void ) +{ + return(fgStructure.Menu->UserData); +} + +void FGAPIENTRY glutSetMenuData(void* data) +{ + fgStructure.Menu->UserData=data; +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_misc.c b/src/freeglut_misc.c new file mode 100644 index 0000000..496ca45 --- /dev/null +++ b/src/freeglut_misc.c @@ -0,0 +1,244 @@ +/* + * freeglut_misc.c + * + * Functions that didn't fit anywhere else... + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 9 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-misc" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * glutSetColor() -- + * glutGetColor() -- + * glutCopyColormap() -- + * glutSetKeyRepeat() -- this is evil and should be removed from API + */ + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * This functions checks if an OpenGL extension is supported or not + */ +int FGAPIENTRY glutExtensionSupported( const char* extension ) +{ + const char *extensions; + const char *ptr; + int len = strlen ( extension ) ; + + /* + * Make sure there is a current window, and thus -- a current context available + */ + freeglut_assert_ready; + freeglut_return_val_if_fail( fgStructure.Window != NULL, 0 ); + + /* + * Note it is safe to query the extensions + */ + extensions = glGetString(GL_EXTENSIONS); + + freeglut_return_val_if_fail( extensions != NULL, 0 ); + + /* + * Check if the extension itself looks valid + */ + if ( strchr ( extension, ' ' ) != NULL ) + return( 0 ); + + /* + * Look for our extension + */ + for (ptr = extensions; *ptr;) + { + /* + * Is it the current extension? + */ + if ( strncmp ( extension, extensions, len ) == 0 ) + return 1 ; + + /* + * No, go find the next extension. They are separated from each other by one or more blank spaces. + */ + ptr = strchr ( ptr + len, ' ' ) ; + + /* + * If we ran off the end of the "extensions" character string, we didn't find it. Return failure. + */ + if ( !ptr ) return 0 ; + + while ( *ptr == ' ' ) + ptr++ ; + } + + return 0 ; +} + +/* + * This function reports all the OpenGL errors that happened till now + */ +void FGAPIENTRY glutReportErrors( void ) +{ + GLenum error = glGetError(); + + /* + * Keep reporting errors as long as there are any... + */ + while( error != GL_NO_ERROR ) + { + /* + * Print the current error + */ +# undef G_LOG_DOMAIN +# define G_LOG_DOMAIN ((gchar *) 0) + + fgWarning( "GL error: %s", gluErrorString( error ) ); + +# undef G_LOG_DOMAIN +# define G_LOG_DOMAIN "freeglut_misc.c" + + /* + * Grab the next error value + */ + error = glGetError(); + }; +} + +/* + * Turns the ignore key auto repeat feature on and off + */ +void FGAPIENTRY glutIgnoreKeyRepeat( int ignore ) /* DEPRECATED 11/4/02 - Do not use */ +{ + /* + * This is simple and not damaging... + */ + fgState.IgnoreKeyRepeat = ignore ? TRUE : FALSE; +} + +/* + * Hints the window system whether to generate key auto repeat, or not. This is evil. + */ +void FGAPIENTRY glutSetKeyRepeat( int repeatMode ) +{ +#if TARGET_HOST_UNIX_X11 + + freeglut_assert_ready; + + /* + * This is really evil, but let's have this done. + */ + switch( repeatMode ) + { + case GLUT_KEY_REPEAT_OFF: XAutoRepeatOff( fgDisplay.Display ); break; + case GLUT_KEY_REPEAT_ON: XAutoRepeatOn( fgDisplay.Display ); break; + case GLUT_KEY_REPEAT_DEFAULT: + { + XKeyboardState keyboardState; + + /* + * Query the current keyboard state + */ + XGetKeyboardControl( fgDisplay.Display, &keyboardState ); + + /* + * Set the auto key repeat basing on the global settings + */ + glutSetKeyRepeat( + keyboardState.global_auto_repeat == AutoRepeatModeOn ? + GLUT_KEY_REPEAT_ON : GLUT_KEY_REPEAT_OFF + ); + } + break; + + default: + /* + * Whoops, this was not expected at all + */ + break; + } + +#endif +} + +/* + * Forces the joystick callback to be executed + */ +void FGAPIENTRY glutForceJoystickFunc( void ) +{ + freeglut_assert_ready; + + /* + * Is there a current window selected? + */ + freeglut_return_if_fail( fgStructure.Window != NULL ); + + /* + * Check if there is a joystick callback hooked to the current window + */ + freeglut_return_if_fail( fgStructure.Window->Callbacks.Joystick != NULL ); + + /* + * Poll the joystick now, using the current window's joystick callback + */ + fgJoystickPollWindow( fgStructure.Window ); +} + +/* + * + */ +void FGAPIENTRY glutSetColor( int nColor, GLfloat red, GLfloat green, GLfloat blue ) +{ + /* + * + */ +} + +/* + * + */ +GLfloat FGAPIENTRY glutGetColor( int color, int component ) +{ + /* + * + */ + return( 0.0f ); +} + +/* + * + */ +void FGAPIENTRY glutCopyColormap( int window ) +{ + /* + * + */ +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_overlay.c b/src/freeglut_overlay.c new file mode 100644 index 0000000..14c42c2 --- /dev/null +++ b/src/freeglut_overlay.c @@ -0,0 +1,51 @@ +/* + * freeglut_overlay.c + * + * Overlay management functions (as defined by GLUT API) + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-overlay" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * NOTE: functions declared in this file probably will not be implemented. + */ + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +void FGAPIENTRY glutEstablishOverlay( void ) { /* Not implemented */ } +void FGAPIENTRY glutRemoveOverlay( void ) { /* Not implemented */ } +void FGAPIENTRY glutUseLayer( GLenum layer ) { /* Not implemented */ } +void FGAPIENTRY glutPostOverlayRedisplay( void ) { /* Not implemented */ } +void FGAPIENTRY glutPostWindowOverlayRedisplay( int ID ) { /* Not implemented */ } +void FGAPIENTRY glutShowOverlay( void ) { /* Not implemented */ } +void FGAPIENTRY glutHideOverlay( void ) { /* Not implemented */ } + +/*** END OF FILE ***/ diff --git a/src/freeglut_state.c b/src/freeglut_state.c new file mode 100644 index 0000000..cb40f05 --- /dev/null +++ b/src/freeglut_state.c @@ -0,0 +1,704 @@ +/* + * freeglut_state.c + * + * Freeglut state query methods. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-state" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * glutGet() -- X11 tests passed, but check if all enums handled (what about Win32?) + * glutDeviceGet() -- X11 tests passed, but check if all enums handled (what about Win32?) + * glutGetModifiers() -- OK, but could also remove the limitation + * glutLayerGet() -- what about GLUT_NORMAL_DAMAGED? + * + * The fail-on-call policy will help adding the most needed things imho. + */ + +/* -- LOCAL DEFINITIONS ---------------------------------------------------- */ + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +#if TARGET_HOST_UNIX_X11 +/* + * Queries the GL context about some attributes + */ +static int fghGetConfig( int attribute ) +{ + int returnValue ; + + /* + * Return nothing if there is no current window set + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + /* + * glXGetConfig should work fine + */ + glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue ); + + + /* + * Have the query results returned + */ + return ( returnValue ) ; +} +#endif + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * General settings assignment method + */ +void FGAPIENTRY glutSetOption( GLenum eWhat, int value ) +{ + freeglut_assert_ready; + + /* + * Check what is the caller querying for. In chronological code add order. + */ + switch( eWhat ) + { + case GLUT_INIT_WINDOW_X: fgState.Position.X = (GLint)value ; + break ; + case GLUT_INIT_WINDOW_Y: fgState.Position.Y = (GLint)value ; + break ; + case GLUT_INIT_WINDOW_WIDTH: fgState.Size.X = (GLint)value ; + break ; + case GLUT_INIT_WINDOW_HEIGHT: fgState.Size.Y = (GLint)value ; + break ; + case GLUT_INIT_DISPLAY_MODE: fgState.DisplayMode = (unsigned int)value ; + break ; + + case GLUT_ACTION_ON_WINDOW_CLOSE: fgState.ActionOnWindowClose = value ; + break ; + + case GLUT_WINDOW_CURSOR: + if( fgStructure.Window != NULL ) fgStructure.Window->State.Cursor = value ; + break ; + + default: + /* + * Just have it reported, so that we can see what needs to be implemented + */ + fgWarning( "glutSetOption(): missing enum handle %i\n", eWhat ); + break; + } +} + +/* + * General settings query method + */ +int FGAPIENTRY glutGet( GLenum eWhat ) +{ + int returnValue ; + GLboolean boolValue ; + + if ( eWhat == GLUT_INIT_STATE ) + return ( fgState.Time.Set ) ; + + freeglut_assert_ready; + + /* + * Check what is the caller querying for. In chronological code add order. + */ + switch( eWhat ) + { + case GLUT_ELAPSED_TIME: + /* + * This is easy and nicely portable, as we are using GLib... + */ + return( fgElapsedTime() ); + + /* + * Following values are stored in fgState and fgDisplay global structures + */ + case GLUT_SCREEN_WIDTH: return( fgDisplay.ScreenWidth ); + case GLUT_SCREEN_HEIGHT: return( fgDisplay.ScreenHeight ); + case GLUT_SCREEN_WIDTH_MM: return( fgDisplay.ScreenWidthMM ); + case GLUT_SCREEN_HEIGHT_MM: return( fgDisplay.ScreenHeightMM ); + case GLUT_INIT_WINDOW_X: return( fgState.Position.X ); + case GLUT_INIT_WINDOW_Y: return( fgState.Position.Y ); + case GLUT_INIT_WINDOW_WIDTH: return( fgState.Size.X ); + case GLUT_INIT_WINDOW_HEIGHT: return( fgState.Size.Y ); + case GLUT_INIT_DISPLAY_MODE: return( fgState.DisplayMode ); + + /* + * The window/context specific queries are handled mostly by fghGetConfig(). + */ + case GLUT_WINDOW_NUM_SAMPLES: + /* + * Multisampling. Return what I know about multisampling. + */ + return( 0 ); + +#if TARGET_HOST_UNIX_X11 + /* + * The rest of GLX queries under X are general enough to use a macro to check them + */ +# define GLX_QUERY(a,b) case a: return( fghGetConfig( b ) ); + + GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); + GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); + GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); + GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); + GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); + GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); + GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); + GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); + GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); + GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); + GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); + GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); + GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); + GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); + +# undef GLX_QUERY + + /* + * Colormap size is handled in a bit different way than all the rest + */ + case GLUT_WINDOW_COLORMAP_SIZE: + /* + * Check for the visual type + */ + if( (fghGetConfig( GLX_RGBA )) || (fgStructure.Window == NULL) ) + { + /* + * We've got a RGBA visual, so there is no colormap at all. + * The other possibility is that we have no current window set. + */ + return( 0 ); + } + + /* + * Otherwise return the number of entries in the colormap + */ + return( fgStructure.Window->Window.VisualInfo->visual->map_entries ); + + /* + * Those calls are somewhat similiar, as they use XGetWindowAttributes() function + */ + case GLUT_WINDOW_X: + case GLUT_WINDOW_Y: + case GLUT_WINDOW_WIDTH: + case GLUT_WINDOW_HEIGHT: + case GLUT_WINDOW_BORDER_WIDTH : + case GLUT_WINDOW_HEADER_HEIGHT : + { + XWindowAttributes winAttributes; + + /* + * Return zero if there is no current window set + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + /* + * Grab the current window's attributes now + */ + XGetWindowAttributes( + fgDisplay.Display, + fgStructure.Window->Window.Handle, + &winAttributes + ); + + /* + * See which window attribute to return + */ + switch ( eWhat ) + { + case GLUT_WINDOW_X: return winAttributes.x ; + case GLUT_WINDOW_Y: return winAttributes.y ; + case GLUT_WINDOW_WIDTH: return winAttributes.width ; + case GLUT_WINDOW_HEIGHT: return winAttributes.height ; + case GLUT_WINDOW_BORDER_WIDTH : return winAttributes.border_width ; + case GLUT_WINDOW_HEADER_HEIGHT : return winAttributes.border_width * 3 ; /* a kludge for now */ + } + } + + /* + * I do not know yet if there will be a fgChooseVisual() function for Win32 + */ + case GLUT_DISPLAY_MODE_POSSIBLE: + /* + * Check if the current display mode is possible + */ + return( fgChooseVisual() == NULL ? 0 : 1 ); + + /* + * This is system-dependant + */ + case GLUT_WINDOW_FORMAT_ID: + /* + * Return the visual ID, if there is a current window naturally: + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + return( fgStructure.Window->Window.VisualInfo->visualid ); + +#elif TARGET_HOST_WIN32 + + /* + * Handle the OpenGL inquiries + */ + case GLUT_WINDOW_RGBA: + glGetBooleanv ( GL_RGBA_MODE, &boolValue ) ; /* True if color buffers store RGBA */ + returnValue = boolValue ? 1 : 0 ; + return ( returnValue ) ; + case GLUT_WINDOW_DOUBLEBUFFER: + glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ) ; /* True if front and back buffers exist */ + returnValue = boolValue ? 1 : 0 ; + return ( returnValue ) ; + case GLUT_WINDOW_STEREO: + glGetBooleanv ( GL_STEREO, &boolValue ) ; /* True if left and right buffers exist */ + returnValue = boolValue ? 1 : 0 ; + return ( returnValue ) ; + + case GLUT_WINDOW_RED_SIZE: + glGetIntegerv ( GL_RED_BITS, &returnValue ) ; /* Number of bits per red component in color buffers */ + return ( returnValue ) ; + case GLUT_WINDOW_GREEN_SIZE: + glGetIntegerv ( GL_GREEN_BITS, &returnValue ) ; /* Number of bits per green component in color buffers */ + return ( returnValue ) ; + case GLUT_WINDOW_BLUE_SIZE: + glGetIntegerv ( GL_BLUE_BITS, &returnValue ) ; /* Number of bits per blue component in color buffers */ + return ( returnValue ) ; + case GLUT_WINDOW_ALPHA_SIZE: + glGetIntegerv ( GL_ALPHA_BITS, &returnValue ) ; /* Number of bits per alpha component in color buffers */ + return ( returnValue ) ; + case GLUT_WINDOW_ACCUM_RED_SIZE: + glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ) ; /* Number of bits per red component in the accumulation buffer */ + return ( returnValue ) ; + case GLUT_WINDOW_ACCUM_GREEN_SIZE: + glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ) ; /* Number of bits per green component in the accumulation buffer */ + return ( returnValue ) ; + case GLUT_WINDOW_ACCUM_BLUE_SIZE: + glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ) ; /* Number of bits per blue component in the accumulation buffer */ + return ( returnValue ) ; + case GLUT_WINDOW_ACCUM_ALPHA_SIZE: + glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ) ; /* Number of bits per alpha component in the accumulation buffer */ + return ( returnValue ) ; + case GLUT_WINDOW_DEPTH_SIZE: + glGetIntegerv ( GL_DEPTH_BITS, &returnValue ) ; /* Number of depth-buffer bitplanes */ + return ( returnValue ) ; + + case GLUT_WINDOW_BUFFER_SIZE: + returnValue = 1 ; /* ????? */ + return ( returnValue ) ; + case GLUT_WINDOW_STENCIL_SIZE: + returnValue = 0 ; /* ????? */ + return ( returnValue ) ; + + /* + * Window position and size + */ + case GLUT_WINDOW_X: + case GLUT_WINDOW_Y: + case GLUT_WINDOW_WIDTH: + case GLUT_WINDOW_HEIGHT: + { + /* + * There is considerable confusion about the "right thing to do" concerning window + * size and position. GLUT itself is not consistent between Windows and Linux; since + * platform independence is a virtue for "freeglut", we decided to break with GLUT's + * behaviour. + * Under Linux, it is apparently not possible to get the window border sizes in order + * to subtract them off the window's initial position until some time after the window + * has been created. Therefore we decided on the following behaviour, both under + * Windows and under Linux: + * - When you create a window with position (x,y) and size (w,h), the upper left hand + * corner of the outside of the window is at (x,y) and the size of the drawable area + * is (w,h). + * - When you query the size and position of the window--as is happening here for + * Windows--"freeglut" will return the size of the drawable area--the (w,h) that you + * specified when you created the window--and the coordinates of the upper left hand + * corner of the drawable area--which is NOT the (x,y) you specified. + */ + + RECT winRect; + + /* + * Check if there is a window to be queried for dimensions: + */ + freeglut_return_val_if_fail( fgStructure.Window != NULL, 0 ); + + /* + * We need to call GetWindowRect() first... + * (this returns the pixel coordinates of the outside of the window) + */ + GetWindowRect( fgStructure.Window->Window.Handle, &winRect ); + + /* + * ...then we've got to correct the results we've just received... + */ + if (fgStructure.GameMode != fgStructure.Window && + fgStructure.Window->Parent == NULL ) + { + winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ); + winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ); + winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ); + winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ); + } + + /* + * ...and finally return the caller the desired value: + */ + switch( eWhat ) + { + case GLUT_WINDOW_X: return( winRect.left ); + case GLUT_WINDOW_Y: return( winRect.top ); + case GLUT_WINDOW_WIDTH: return( winRect.right - winRect.left ); + case GLUT_WINDOW_HEIGHT: return( winRect.bottom - winRect.top ); + } + } + break; + + case GLUT_WINDOW_BORDER_WIDTH : + return ( GetSystemMetrics( SM_CXSIZEFRAME ) ) ; + + case GLUT_WINDOW_HEADER_HEIGHT : + return ( GetSystemMetrics( SM_CYCAPTION ) ) ; + + case GLUT_DISPLAY_MODE_POSSIBLE: + /* + * Check if the current display mode is possible + */ + return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) ); + + case GLUT_WINDOW_FORMAT_ID: + /* + * Return the pixel format of the current window + */ + if( fgStructure.Window != NULL ) + return( GetPixelFormat( fgStructure.Window->Window.Device ) ); + + /* + * If the current window does not exist, fail: + */ + return( 0 ); + +#endif + + /* + * The window structure queries + */ + case GLUT_WINDOW_PARENT: + /* + * Return the ID number of current window's parent, if any + */ + if( fgStructure.Window == NULL ) return( 0 ); + if( fgStructure.Window->Parent == NULL ) return( 0 ); + + return( fgStructure.Window->Parent->ID ); + + case GLUT_WINDOW_NUM_CHILDREN: + /* + * Return the number of children attached to the current window + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + return( fgListLength( &fgStructure.Window->Children ) ); + + case GLUT_WINDOW_CURSOR: + /* + * Return the currently selected window cursor + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + return( fgStructure.Window->State.Cursor ); + + case GLUT_MENU_NUM_ITEMS: + /* + * Return the number of menu entries in the current menu + */ + if( fgStructure.Menu == NULL ) + return( 0 ); + + return( fgListLength( &fgStructure.Menu->Entries ) ); + + case GLUT_ACTION_ON_WINDOW_CLOSE: + return fgState.ActionOnWindowClose; + + case GLUT_VERSION: + return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH; + + default: + /* + * Just have it reported, so that we can see what needs to be implemented + */ + fgWarning( "glutGet(): missing enum handle %i\n", eWhat ); + break; + } + + /* + * If nothing happens, then we are in deep trouble... + */ + return( -1 ); +} + +/* + * Returns various device information. + */ +int FGAPIENTRY glutDeviceGet( GLenum eWhat ) +{ + freeglut_assert_ready; + + /* + * See why are we bothered... + * + * WARNING: we are mostly lying in this function. + */ + switch( eWhat ) + { + case GLUT_HAS_KEYBOARD: + /* + * We always have a keyboard present on PC machines... + */ + return( TRUE ); + +#if TARGET_HOST_UNIX_X11 + + case GLUT_HAS_MOUSE: + /* + * Hey, my Atari 65XE hasn't had a mouse! + */ + return( TRUE ); + + case GLUT_NUM_MOUSE_BUTTONS: + /* + * Return the number of mouse buttons available. This is a big guess. + */ + return( 3 ); + +#elif TARGET_HOST_WIN32 + + case GLUT_HAS_MOUSE: + /* + * The Windows can be booted without a mouse. + * It would be nice to have this reported. + */ + return( GetSystemMetrics( SM_MOUSEPRESENT ) ); + + case GLUT_NUM_MOUSE_BUTTONS: + /* + * We are much more fortunate under Win32 about this... + */ + return( GetSystemMetrics( SM_CMOUSEBUTTONS ) ); + +#endif + + case GLUT_JOYSTICK_POLL_RATE: + case GLUT_HAS_JOYSTICK: + case GLUT_JOYSTICK_BUTTONS: + case GLUT_JOYSTICK_AXES: + /* + * WARNING: THIS IS A BIG LIE! + */ + return( 0 ); + + case GLUT_HAS_SPACEBALL: + case GLUT_HAS_DIAL_AND_BUTTON_BOX: + case GLUT_HAS_TABLET: + /* + * Sounds cool. And unuseful. + */ + return( FALSE ); + + case GLUT_NUM_SPACEBALL_BUTTONS: + case GLUT_NUM_BUTTON_BOX_BUTTONS: + case GLUT_NUM_DIALS: + case GLUT_NUM_TABLET_BUTTONS: + /* + * Zero is not the answer. Zero is the question. Continuum is the answer. + */ + return( 0 ); + + case GLUT_DEVICE_IGNORE_KEY_REPEAT: + /* + * Return what we think about the key auto repeat settings + */ + return( fgState.IgnoreKeyRepeat ); + + case GLUT_DEVICE_KEY_REPEAT: + /* + * WARNING: THIS IS A BIG LIE! + */ + return( GLUT_KEY_REPEAT_DEFAULT ); + + default: + /* + * Complain. + */ + fgWarning( "glutDeviceGet(): missing enum handle %i\n", eWhat ); + break; + } + + /* + * And now -- the failure. + */ + return( -1 ); +} + +/* + * This should return the current state of ALT, SHIFT and CTRL keys. + */ +int FGAPIENTRY glutGetModifiers( void ) +{ + /* + * Fail if there is no current window or called outside an input callback + */ + if( fgStructure.Window == NULL ) + return( 0 ); + + if( fgStructure.Window->State.Modifiers == 0xffffffff ) + { + fgWarning( "glutGetModifiers() called outside an input callback" ); + return( 0 ); + } + + /* + * Return the current modifiers state otherwise + */ + return( fgStructure.Window->State.Modifiers ); +} + +/* + * Return the state of the GLUT API overlay subsystem. A misery ;-) + */ +int FGAPIENTRY glutLayerGet( GLenum eWhat ) +{ + freeglut_assert_ready; + + /* + * This is easy as layers are not implemented ;-) + */ + switch( eWhat ) + { + +#if TARGET_HOST_UNIX_X11 + + case GLUT_OVERLAY_POSSIBLE: + /* + * Nope, overlays are not possible. + */ + return( FALSE ); + + case GLUT_LAYER_IN_USE: + /* + * The normal plane is always in use + */ + return( GLUT_NORMAL ); + + case GLUT_HAS_OVERLAY: + /* + * No window is allowed to have an overlay + */ + return( FALSE ); + + case GLUT_TRANSPARENT_INDEX: + /* + * Return just anything, which is always defined as zero + */ + return( 0 ); + + case GLUT_NORMAL_DAMAGED: + /* + * Actually I do not know. Maybe. + */ + return( FALSE ); + + case GLUT_OVERLAY_DAMAGED: + /* + * Return minus one to mark that no layer is in use + */ + return( -1 ); + +#elif TARGET_HOST_WIN32 + + case GLUT_OVERLAY_POSSIBLE: + /* + * Check if an overlay display mode is possible + */ + return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) ); + + case GLUT_LAYER_IN_USE: + /* + * The normal plane is always in use + */ + return( GLUT_NORMAL ); + + case GLUT_HAS_OVERLAY: + /* + * No window is allowed to have an overlay + */ + return( FALSE ); + + case GLUT_TRANSPARENT_INDEX: + /* + * Return just anything, which is always defined as zero + */ + return( 0 ); + + case GLUT_NORMAL_DAMAGED: + /* + * Actually I do not know. Maybe. + */ + return( FALSE ); + + case GLUT_OVERLAY_DAMAGED: + /* + * Return minus one to mark that no layer is in use + */ + return( -1 ); +#endif + + default: + /* + * Complain to the user about the obvious bug + */ + fgWarning( "glutLayerGet(): missing enum handle %i\n", eWhat ); + break; + } + + /* + * And fail. That's good. Programs do love failing. + */ + return( -1 ); +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_stroke_mono_roman.c b/src/freeglut_stroke_mono_roman.c new file mode 100644 index 0000000..1c6aa4f --- /dev/null +++ b/src/freeglut_stroke_mono_roman.c @@ -0,0 +1,2823 @@ + +/* This file has been automatically generated by the genstroke utility. */ + +#include "freeglut_internal.h" +#ifdef TARGET_HOST_WIN32 +#pragma warning ( once:4305 ) +#endif +/* char: 0x20 */ + +static const SFG_StrokeStrip ch32st[] = +{ + { 0, NULL } +}; + +static const SFG_StrokeChar ch32 = {104.762,0,ch32st}; + +/* char: 0x21 */ + +static const SFG_StrokeVertex ch33st0[] = +{ + {52.381,100}, + {52.381,33.3333} +}; + +static const SFG_StrokeVertex ch33st1[] = +{ + {52.381,9.5238}, + {47.6191,4.7619}, + {52.381,0}, + {57.1429,4.7619}, + {52.381,9.5238} +}; + +static const SFG_StrokeStrip ch33st[] = +{ + {2,ch33st0}, + {5,ch33st1} +}; + +static const SFG_StrokeChar ch33 = {104.762,2,ch33st}; + +/* char: 0x22 */ + +static const SFG_StrokeVertex ch34st0[] = +{ + {33.3334,100}, + {33.3334,66.6667} +}; + +static const SFG_StrokeVertex ch34st1[] = +{ + {71.4286,100}, + {71.4286,66.6667} +}; + +static const SFG_StrokeStrip ch34st[] = +{ + {2,ch34st0}, + {2,ch34st1} +}; + +static const SFG_StrokeChar ch34 = {104.762,2,ch34st}; + +/* char: 0x23 */ + +static const SFG_StrokeVertex ch35st0[] = +{ + {54.7619,119.048}, + {21.4286,-33.3333} +}; + +static const SFG_StrokeVertex ch35st1[] = +{ + {83.3334,119.048}, + {50,-33.3333} +}; + +static const SFG_StrokeVertex ch35st2[] = +{ + {21.4286,57.1429}, + {88.0952,57.1429} +}; + +static const SFG_StrokeVertex ch35st3[] = +{ + {16.6667,28.5714}, + {83.3334,28.5714} +}; + +static const SFG_StrokeStrip ch35st[] = +{ + {2,ch35st0}, + {2,ch35st1}, + {2,ch35st2}, + {2,ch35st3} +}; + +static const SFG_StrokeChar ch35 = {104.762,4,ch35st}; + +/* char: 0x24 */ + +static const SFG_StrokeVertex ch36st0[] = +{ + {42.8571,119.048}, + {42.8571,-19.0476} +}; + +static const SFG_StrokeVertex ch36st1[] = +{ + {61.9047,119.048}, + {61.9047,-19.0476} +}; + +static const SFG_StrokeVertex ch36st2[] = +{ + {85.7143,85.7143}, + {76.1905,95.2381}, + {61.9047,100}, + {42.8571,100}, + {28.5714,95.2381}, + {19.0476,85.7143}, + {19.0476,76.1905}, + {23.8095,66.6667}, + {28.5714,61.9048}, + {38.0952,57.1429}, + {66.6666,47.619}, + {76.1905,42.8571}, + {80.9524,38.0952}, + {85.7143,28.5714}, + {85.7143,14.2857}, + {76.1905,4.7619}, + {61.9047,0}, + {42.8571,0}, + {28.5714,4.7619}, + {19.0476,14.2857} +}; + +static const SFG_StrokeStrip ch36st[] = +{ + {2,ch36st0}, + {2,ch36st1}, + {20,ch36st2} +}; + +static const SFG_StrokeChar ch36 = {104.762,3,ch36st}; + +/* char: 0x25 */ + +static const SFG_StrokeVertex ch37st0[] = +{ + {95.2381,100}, + {9.5238,0} +}; + +static const SFG_StrokeVertex ch37st1[] = +{ + {33.3333,100}, + {42.8571,90.4762}, + {42.8571,80.9524}, + {38.0952,71.4286}, + {28.5714,66.6667}, + {19.0476,66.6667}, + {9.5238,76.1905}, + {9.5238,85.7143}, + {14.2857,95.2381}, + {23.8095,100}, + {33.3333,100}, + {42.8571,95.2381}, + {57.1428,90.4762}, + {71.4286,90.4762}, + {85.7143,95.2381}, + {95.2381,100} +}; + +static const SFG_StrokeVertex ch37st2[] = +{ + {76.1905,33.3333}, + {66.6667,28.5714}, + {61.9048,19.0476}, + {61.9048,9.5238}, + {71.4286,0}, + {80.9524,0}, + {90.4762,4.7619}, + {95.2381,14.2857}, + {95.2381,23.8095}, + {85.7143,33.3333}, + {76.1905,33.3333} +}; + +static const SFG_StrokeStrip ch37st[] = +{ + {2,ch37st0}, + {16,ch37st1}, + {11,ch37st2} +}; + +static const SFG_StrokeChar ch37 = {104.762,3,ch37st}; + +/* char: 0x26 */ + +static const SFG_StrokeVertex ch38st0[] = +{ + {100,57.1429}, + {100,61.9048}, + {95.2381,66.6667}, + {90.4762,66.6667}, + {85.7143,61.9048}, + {80.9524,52.381}, + {71.4286,28.5714}, + {61.9048,14.2857}, + {52.3809,4.7619}, + {42.8571,0}, + {23.8095,0}, + {14.2857,4.7619}, + {9.5238,9.5238}, + {4.7619,19.0476}, + {4.7619,28.5714}, + {9.5238,38.0952}, + {14.2857,42.8571}, + {47.619,61.9048}, + {52.3809,66.6667}, + {57.1429,76.1905}, + {57.1429,85.7143}, + {52.3809,95.2381}, + {42.8571,100}, + {33.3333,95.2381}, + {28.5714,85.7143}, + {28.5714,76.1905}, + {33.3333,61.9048}, + {42.8571,47.619}, + {66.6667,14.2857}, + {76.1905,4.7619}, + {85.7143,0}, + {95.2381,0}, + {100,4.7619}, + {100,9.5238} +}; + +static const SFG_StrokeStrip ch38st[] = +{ + {34,ch38st0} +}; + +static const SFG_StrokeChar ch38 = {104.762,1,ch38st}; + +/* char: 0x27 */ + +static const SFG_StrokeVertex ch39st0[] = +{ + {52.381,100}, + {52.381,66.6667} +}; + +static const SFG_StrokeStrip ch39st[] = +{ + {2,ch39st0} +}; + +static const SFG_StrokeChar ch39 = {104.762,1,ch39st}; + +/* char: 0x28 */ + +static const SFG_StrokeVertex ch40st0[] = +{ + {69.0476,119.048}, + {59.5238,109.524}, + {50,95.2381}, + {40.4762,76.1905}, + {35.7143,52.381}, + {35.7143,33.3333}, + {40.4762,9.5238}, + {50,-9.5238}, + {59.5238,-23.8095}, + {69.0476,-33.3333} +}; + +static const SFG_StrokeStrip ch40st[] = +{ + {10,ch40st0} +}; + +static const SFG_StrokeChar ch40 = {104.762,1,ch40st}; + +/* char: 0x29 */ + +static const SFG_StrokeVertex ch41st0[] = +{ + {35.7143,119.048}, + {45.2381,109.524}, + {54.7619,95.2381}, + {64.2857,76.1905}, + {69.0476,52.381}, + {69.0476,33.3333}, + {64.2857,9.5238}, + {54.7619,-9.5238}, + {45.2381,-23.8095}, + {35.7143,-33.3333} +}; + +static const SFG_StrokeStrip ch41st[] = +{ + {10,ch41st0} +}; + +static const SFG_StrokeChar ch41 = {104.762,1,ch41st}; + +/* char: 0x2a */ + +static const SFG_StrokeVertex ch42st0[] = +{ + {52.381,71.4286}, + {52.381,14.2857} +}; + +static const SFG_StrokeVertex ch42st1[] = +{ + {28.5715,57.1429}, + {76.1905,28.5714} +}; + +static const SFG_StrokeVertex ch42st2[] = +{ + {76.1905,57.1429}, + {28.5715,28.5714} +}; + +static const SFG_StrokeStrip ch42st[] = +{ + {2,ch42st0}, + {2,ch42st1}, + {2,ch42st2} +}; + +static const SFG_StrokeChar ch42 = {104.762,3,ch42st}; + +/* char: 0x2b */ + +static const SFG_StrokeVertex ch43st0[] = +{ + {52.3809,85.7143}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch43st1[] = +{ + {9.5238,42.8571}, + {95.2381,42.8571} +}; + +static const SFG_StrokeStrip ch43st[] = +{ + {2,ch43st0}, + {2,ch43st1} +}; + +static const SFG_StrokeChar ch43 = {104.762,2,ch43st}; + +/* char: 0x2c */ + +static const SFG_StrokeVertex ch44st0[] = +{ + {57.1429,4.7619}, + {52.381,0}, + {47.6191,4.7619}, + {52.381,9.5238}, + {57.1429,4.7619}, + {57.1429,-4.7619}, + {52.381,-14.2857}, + {47.6191,-19.0476} +}; + +static const SFG_StrokeStrip ch44st[] = +{ + {8,ch44st0} +}; + +static const SFG_StrokeChar ch44 = {104.762,1,ch44st}; + +/* char: 0x2d */ + +static const SFG_StrokeVertex ch45st0[] = +{ + {9.5238,42.8571}, + {95.2381,42.8571} +}; + +static const SFG_StrokeStrip ch45st[] = +{ + {2,ch45st0} +}; + +static const SFG_StrokeChar ch45 = {104.762,1,ch45st}; + +/* char: 0x2e */ + +static const SFG_StrokeVertex ch46st0[] = +{ + {52.381,9.5238}, + {47.6191,4.7619}, + {52.381,0}, + {57.1429,4.7619}, + {52.381,9.5238} +}; + +static const SFG_StrokeStrip ch46st[] = +{ + {5,ch46st0} +}; + +static const SFG_StrokeChar ch46 = {104.762,1,ch46st}; + +/* char: 0x2f */ + +static const SFG_StrokeVertex ch47st0[] = +{ + {19.0476,-14.2857}, + {85.7143,100} +}; + +static const SFG_StrokeStrip ch47st[] = +{ + {2,ch47st0} +}; + +static const SFG_StrokeChar ch47 = {104.762,1,ch47st}; + +/* char: 0x30 */ + +static const SFG_StrokeVertex ch48st0[] = +{ + {47.619,100}, + {33.3333,95.2381}, + {23.8095,80.9524}, + {19.0476,57.1429}, + {19.0476,42.8571}, + {23.8095,19.0476}, + {33.3333,4.7619}, + {47.619,0}, + {57.1428,0}, + {71.4286,4.7619}, + {80.9524,19.0476}, + {85.7143,42.8571}, + {85.7143,57.1429}, + {80.9524,80.9524}, + {71.4286,95.2381}, + {57.1428,100}, + {47.619,100} +}; + +static const SFG_StrokeStrip ch48st[] = +{ + {17,ch48st0} +}; + +static const SFG_StrokeChar ch48 = {104.762,1,ch48st}; + +/* char: 0x31 */ + +static const SFG_StrokeVertex ch49st0[] = +{ + {40.4762,80.9524}, + {50,85.7143}, + {64.2857,100}, + {64.2857,0} +}; + +static const SFG_StrokeStrip ch49st[] = +{ + {4,ch49st0} +}; + +static const SFG_StrokeChar ch49 = {104.762,1,ch49st}; + +/* char: 0x32 */ + +static const SFG_StrokeVertex ch50st0[] = +{ + {23.8095,76.1905}, + {23.8095,80.9524}, + {28.5714,90.4762}, + {33.3333,95.2381}, + {42.8571,100}, + {61.9047,100}, + {71.4286,95.2381}, + {76.1905,90.4762}, + {80.9524,80.9524}, + {80.9524,71.4286}, + {76.1905,61.9048}, + {66.6666,47.619}, + {19.0476,0}, + {85.7143,0} +}; + +static const SFG_StrokeStrip ch50st[] = +{ + {14,ch50st0} +}; + +static const SFG_StrokeChar ch50 = {104.762,1,ch50st}; + +/* char: 0x33 */ + +static const SFG_StrokeVertex ch51st0[] = +{ + {28.5714,100}, + {80.9524,100}, + {52.3809,61.9048}, + {66.6666,61.9048}, + {76.1905,57.1429}, + {80.9524,52.381}, + {85.7143,38.0952}, + {85.7143,28.5714}, + {80.9524,14.2857}, + {71.4286,4.7619}, + {57.1428,0}, + {42.8571,0}, + {28.5714,4.7619}, + {23.8095,9.5238}, + {19.0476,19.0476} +}; + +static const SFG_StrokeStrip ch51st[] = +{ + {15,ch51st0} +}; + +static const SFG_StrokeChar ch51 = {104.762,1,ch51st}; + +/* char: 0x34 */ + +static const SFG_StrokeVertex ch52st0[] = +{ + {64.2857,100}, + {16.6667,33.3333}, + {88.0952,33.3333} +}; + +static const SFG_StrokeVertex ch52st1[] = +{ + {64.2857,100}, + {64.2857,0} +}; + +static const SFG_StrokeStrip ch52st[] = +{ + {3,ch52st0}, + {2,ch52st1} +}; + +static const SFG_StrokeChar ch52 = {104.762,2,ch52st}; + +/* char: 0x35 */ + +static const SFG_StrokeVertex ch53st0[] = +{ + {76.1905,100}, + {28.5714,100}, + {23.8095,57.1429}, + {28.5714,61.9048}, + {42.8571,66.6667}, + {57.1428,66.6667}, + {71.4286,61.9048}, + {80.9524,52.381}, + {85.7143,38.0952}, + {85.7143,28.5714}, + {80.9524,14.2857}, + {71.4286,4.7619}, + {57.1428,0}, + {42.8571,0}, + {28.5714,4.7619}, + {23.8095,9.5238}, + {19.0476,19.0476} +}; + +static const SFG_StrokeStrip ch53st[] = +{ + {17,ch53st0} +}; + +static const SFG_StrokeChar ch53 = {104.762,1,ch53st}; + +/* char: 0x36 */ + +static const SFG_StrokeVertex ch54st0[] = +{ + {78.5714,85.7143}, + {73.8096,95.2381}, + {59.5238,100}, + {50,100}, + {35.7143,95.2381}, + {26.1905,80.9524}, + {21.4286,57.1429}, + {21.4286,33.3333}, + {26.1905,14.2857}, + {35.7143,4.7619}, + {50,0}, + {54.7619,0}, + {69.0476,4.7619}, + {78.5714,14.2857}, + {83.3334,28.5714}, + {83.3334,33.3333}, + {78.5714,47.619}, + {69.0476,57.1429}, + {54.7619,61.9048}, + {50,61.9048}, + {35.7143,57.1429}, + {26.1905,47.619}, + {21.4286,33.3333} +}; + +static const SFG_StrokeStrip ch54st[] = +{ + {23,ch54st0} +}; + +static const SFG_StrokeChar ch54 = {104.762,1,ch54st}; + +/* char: 0x37 */ + +static const SFG_StrokeVertex ch55st0[] = +{ + {85.7143,100}, + {38.0952,0} +}; + +static const SFG_StrokeVertex ch55st1[] = +{ + {19.0476,100}, + {85.7143,100} +}; + +static const SFG_StrokeStrip ch55st[] = +{ + {2,ch55st0}, + {2,ch55st1} +}; + +static const SFG_StrokeChar ch55 = {104.762,2,ch55st}; + +/* char: 0x38 */ + +static const SFG_StrokeVertex ch56st0[] = +{ + {42.8571,100}, + {28.5714,95.2381}, + {23.8095,85.7143}, + {23.8095,76.1905}, + {28.5714,66.6667}, + {38.0952,61.9048}, + {57.1428,57.1429}, + {71.4286,52.381}, + {80.9524,42.8571}, + {85.7143,33.3333}, + {85.7143,19.0476}, + {80.9524,9.5238}, + {76.1905,4.7619}, + {61.9047,0}, + {42.8571,0}, + {28.5714,4.7619}, + {23.8095,9.5238}, + {19.0476,19.0476}, + {19.0476,33.3333}, + {23.8095,42.8571}, + {33.3333,52.381}, + {47.619,57.1429}, + {66.6666,61.9048}, + {76.1905,66.6667}, + {80.9524,76.1905}, + {80.9524,85.7143}, + {76.1905,95.2381}, + {61.9047,100}, + {42.8571,100} +}; + +static const SFG_StrokeStrip ch56st[] = +{ + {29,ch56st0} +}; + +static const SFG_StrokeChar ch56 = {104.762,1,ch56st}; + +/* char: 0x39 */ + +static const SFG_StrokeVertex ch57st0[] = +{ + {83.3334,66.6667}, + {78.5714,52.381}, + {69.0476,42.8571}, + {54.7619,38.0952}, + {50,38.0952}, + {35.7143,42.8571}, + {26.1905,52.381}, + {21.4286,66.6667}, + {21.4286,71.4286}, + {26.1905,85.7143}, + {35.7143,95.2381}, + {50,100}, + {54.7619,100}, + {69.0476,95.2381}, + {78.5714,85.7143}, + {83.3334,66.6667}, + {83.3334,42.8571}, + {78.5714,19.0476}, + {69.0476,4.7619}, + {54.7619,0}, + {45.2381,0}, + {30.9524,4.7619}, + {26.1905,14.2857} +}; + +static const SFG_StrokeStrip ch57st[] = +{ + {23,ch57st0} +}; + +static const SFG_StrokeChar ch57 = {104.762,1,ch57st}; + +/* char: 0x3a */ + +static const SFG_StrokeVertex ch58st0[] = +{ + {52.381,66.6667}, + {47.6191,61.9048}, + {52.381,57.1429}, + {57.1429,61.9048}, + {52.381,66.6667} +}; + +static const SFG_StrokeVertex ch58st1[] = +{ + {52.381,9.5238}, + {47.6191,4.7619}, + {52.381,0}, + {57.1429,4.7619}, + {52.381,9.5238} +}; + +static const SFG_StrokeStrip ch58st[] = +{ + {5,ch58st0}, + {5,ch58st1} +}; + +static const SFG_StrokeChar ch58 = {104.762,2,ch58st}; + +/* char: 0x3b */ + +static const SFG_StrokeVertex ch59st0[] = +{ + {52.381,66.6667}, + {47.6191,61.9048}, + {52.381,57.1429}, + {57.1429,61.9048}, + {52.381,66.6667} +}; + +static const SFG_StrokeVertex ch59st1[] = +{ + {57.1429,4.7619}, + {52.381,0}, + {47.6191,4.7619}, + {52.381,9.5238}, + {57.1429,4.7619}, + {57.1429,-4.7619}, + {52.381,-14.2857}, + {47.6191,-19.0476} +}; + +static const SFG_StrokeStrip ch59st[] = +{ + {5,ch59st0}, + {8,ch59st1} +}; + +static const SFG_StrokeChar ch59 = {104.762,2,ch59st}; + +/* char: 0x3c */ + +static const SFG_StrokeVertex ch60st0[] = +{ + {90.4762,85.7143}, + {14.2857,42.8571}, + {90.4762,0} +}; + +static const SFG_StrokeStrip ch60st[] = +{ + {3,ch60st0} +}; + +static const SFG_StrokeChar ch60 = {104.762,1,ch60st}; + +/* char: 0x3d */ + +static const SFG_StrokeVertex ch61st0[] = +{ + {9.5238,57.1429}, + {95.2381,57.1429} +}; + +static const SFG_StrokeVertex ch61st1[] = +{ + {9.5238,28.5714}, + {95.2381,28.5714} +}; + +static const SFG_StrokeStrip ch61st[] = +{ + {2,ch61st0}, + {2,ch61st1} +}; + +static const SFG_StrokeChar ch61 = {104.762,2,ch61st}; + +/* char: 0x3e */ + +static const SFG_StrokeVertex ch62st0[] = +{ + {14.2857,85.7143}, + {90.4762,42.8571}, + {14.2857,0} +}; + +static const SFG_StrokeStrip ch62st[] = +{ + {3,ch62st0} +}; + +static const SFG_StrokeChar ch62 = {104.762,1,ch62st}; + +/* char: 0x3f */ + +static const SFG_StrokeVertex ch63st0[] = +{ + {23.8095,76.1905}, + {23.8095,80.9524}, + {28.5714,90.4762}, + {33.3333,95.2381}, + {42.8571,100}, + {61.9047,100}, + {71.4285,95.2381}, + {76.1905,90.4762}, + {80.9524,80.9524}, + {80.9524,71.4286}, + {76.1905,61.9048}, + {71.4285,57.1429}, + {52.3809,47.619}, + {52.3809,33.3333} +}; + +static const SFG_StrokeVertex ch63st1[] = +{ + {52.3809,9.5238}, + {47.619,4.7619}, + {52.3809,0}, + {57.1428,4.7619}, + {52.3809,9.5238} +}; + +static const SFG_StrokeStrip ch63st[] = +{ + {14,ch63st0}, + {5,ch63st1} +}; + +static const SFG_StrokeChar ch63 = {104.762,2,ch63st}; + +/* char: 0x40 */ + +static const SFG_StrokeVertex ch64st0[] = +{ + {64.2857,52.381}, + {54.7619,57.1429}, + {45.2381,57.1429}, + {40.4762,47.619}, + {40.4762,42.8571}, + {45.2381,33.3333}, + {54.7619,33.3333}, + {64.2857,38.0952} +}; + +static const SFG_StrokeVertex ch64st1[] = +{ + {64.2857,57.1429}, + {64.2857,38.0952}, + {69.0476,33.3333}, + {78.5714,33.3333}, + {83.3334,42.8571}, + {83.3334,47.619}, + {78.5714,61.9048}, + {69.0476,71.4286}, + {54.7619,76.1905}, + {50,76.1905}, + {35.7143,71.4286}, + {26.1905,61.9048}, + {21.4286,47.619}, + {21.4286,42.8571}, + {26.1905,28.5714}, + {35.7143,19.0476}, + {50,14.2857}, + {54.7619,14.2857}, + {69.0476,19.0476} +}; + +static const SFG_StrokeStrip ch64st[] = +{ + {8,ch64st0}, + {19,ch64st1} +}; + +static const SFG_StrokeChar ch64 = {104.762,2,ch64st}; + +/* char: 0x41 */ + +static const SFG_StrokeVertex ch65st0[] = +{ + {52.3809,100}, + {14.2857,0} +}; + +static const SFG_StrokeVertex ch65st1[] = +{ + {52.3809,100}, + {90.4762,0} +}; + +static const SFG_StrokeVertex ch65st2[] = +{ + {28.5714,33.3333}, + {76.1905,33.3333} +}; + +static const SFG_StrokeStrip ch65st[] = +{ + {2,ch65st0}, + {2,ch65st1}, + {2,ch65st2} +}; + +static const SFG_StrokeChar ch65 = {104.762,3,ch65st}; + +/* char: 0x42 */ + +static const SFG_StrokeVertex ch66st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch66st1[] = +{ + {19.0476,100}, + {61.9047,100}, + {76.1905,95.2381}, + {80.9524,90.4762}, + {85.7143,80.9524}, + {85.7143,71.4286}, + {80.9524,61.9048}, + {76.1905,57.1429}, + {61.9047,52.381} +}; + +static const SFG_StrokeVertex ch66st2[] = +{ + {19.0476,52.381}, + {61.9047,52.381}, + {76.1905,47.619}, + {80.9524,42.8571}, + {85.7143,33.3333}, + {85.7143,19.0476}, + {80.9524,9.5238}, + {76.1905,4.7619}, + {61.9047,0}, + {19.0476,0} +}; + +static const SFG_StrokeStrip ch66st[] = +{ + {2,ch66st0}, + {9,ch66st1}, + {10,ch66st2} +}; + +static const SFG_StrokeChar ch66 = {104.762,3,ch66st}; + +/* char: 0x43 */ + +static const SFG_StrokeVertex ch67st0[] = +{ + {88.0952,76.1905}, + {83.3334,85.7143}, + {73.8096,95.2381}, + {64.2857,100}, + {45.2381,100}, + {35.7143,95.2381}, + {26.1905,85.7143}, + {21.4286,76.1905}, + {16.6667,61.9048}, + {16.6667,38.0952}, + {21.4286,23.8095}, + {26.1905,14.2857}, + {35.7143,4.7619}, + {45.2381,0}, + {64.2857,0}, + {73.8096,4.7619}, + {83.3334,14.2857}, + {88.0952,23.8095} +}; + +static const SFG_StrokeStrip ch67st[] = +{ + {18,ch67st0} +}; + +static const SFG_StrokeChar ch67 = {104.762,1,ch67st}; + +/* char: 0x44 */ + +static const SFG_StrokeVertex ch68st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch68st1[] = +{ + {19.0476,100}, + {52.3809,100}, + {66.6666,95.2381}, + {76.1905,85.7143}, + {80.9524,76.1905}, + {85.7143,61.9048}, + {85.7143,38.0952}, + {80.9524,23.8095}, + {76.1905,14.2857}, + {66.6666,4.7619}, + {52.3809,0}, + {19.0476,0} +}; + +static const SFG_StrokeStrip ch68st[] = +{ + {2,ch68st0}, + {12,ch68st1} +}; + +static const SFG_StrokeChar ch68 = {104.762,2,ch68st}; + +/* char: 0x45 */ + +static const SFG_StrokeVertex ch69st0[] = +{ + {21.4286,100}, + {21.4286,0} +}; + +static const SFG_StrokeVertex ch69st1[] = +{ + {21.4286,100}, + {83.3334,100} +}; + +static const SFG_StrokeVertex ch69st2[] = +{ + {21.4286,52.381}, + {59.5238,52.381} +}; + +static const SFG_StrokeVertex ch69st3[] = +{ + {21.4286,0}, + {83.3334,0} +}; + +static const SFG_StrokeStrip ch69st[] = +{ + {2,ch69st0}, + {2,ch69st1}, + {2,ch69st2}, + {2,ch69st3} +}; + +static const SFG_StrokeChar ch69 = {104.762,4,ch69st}; + +/* char: 0x46 */ + +static const SFG_StrokeVertex ch70st0[] = +{ + {21.4286,100}, + {21.4286,0} +}; + +static const SFG_StrokeVertex ch70st1[] = +{ + {21.4286,100}, + {83.3334,100} +}; + +static const SFG_StrokeVertex ch70st2[] = +{ + {21.4286,52.381}, + {59.5238,52.381} +}; + +static const SFG_StrokeStrip ch70st[] = +{ + {2,ch70st0}, + {2,ch70st1}, + {2,ch70st2} +}; + +static const SFG_StrokeChar ch70 = {104.762,3,ch70st}; + +/* char: 0x47 */ + +static const SFG_StrokeVertex ch71st0[] = +{ + {88.0952,76.1905}, + {83.3334,85.7143}, + {73.8096,95.2381}, + {64.2857,100}, + {45.2381,100}, + {35.7143,95.2381}, + {26.1905,85.7143}, + {21.4286,76.1905}, + {16.6667,61.9048}, + {16.6667,38.0952}, + {21.4286,23.8095}, + {26.1905,14.2857}, + {35.7143,4.7619}, + {45.2381,0}, + {64.2857,0}, + {73.8096,4.7619}, + {83.3334,14.2857}, + {88.0952,23.8095}, + {88.0952,38.0952} +}; + +static const SFG_StrokeVertex ch71st1[] = +{ + {64.2857,38.0952}, + {88.0952,38.0952} +}; + +static const SFG_StrokeStrip ch71st[] = +{ + {19,ch71st0}, + {2,ch71st1} +}; + +static const SFG_StrokeChar ch71 = {104.762,2,ch71st}; + +/* char: 0x48 */ + +static const SFG_StrokeVertex ch72st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch72st1[] = +{ + {85.7143,100}, + {85.7143,0} +}; + +static const SFG_StrokeVertex ch72st2[] = +{ + {19.0476,52.381}, + {85.7143,52.381} +}; + +static const SFG_StrokeStrip ch72st[] = +{ + {2,ch72st0}, + {2,ch72st1}, + {2,ch72st2} +}; + +static const SFG_StrokeChar ch72 = {104.762,3,ch72st}; + +/* char: 0x49 */ + +static const SFG_StrokeVertex ch73st0[] = +{ + {52.381,100}, + {52.381,0} +}; + +static const SFG_StrokeStrip ch73st[] = +{ + {2,ch73st0} +}; + +static const SFG_StrokeChar ch73 = {104.762,1,ch73st}; + +/* char: 0x4a */ + +static const SFG_StrokeVertex ch74st0[] = +{ + {76.1905,100}, + {76.1905,23.8095}, + {71.4286,9.5238}, + {66.6667,4.7619}, + {57.1429,0}, + {47.6191,0}, + {38.0953,4.7619}, + {33.3334,9.5238}, + {28.5715,23.8095}, + {28.5715,33.3333} +}; + +static const SFG_StrokeStrip ch74st[] = +{ + {10,ch74st0} +}; + +static const SFG_StrokeChar ch74 = {104.762,1,ch74st}; + +/* char: 0x4b */ + +static const SFG_StrokeVertex ch75st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch75st1[] = +{ + {85.7143,100}, + {19.0476,33.3333} +}; + +static const SFG_StrokeVertex ch75st2[] = +{ + {42.8571,57.1429}, + {85.7143,0} +}; + +static const SFG_StrokeStrip ch75st[] = +{ + {2,ch75st0}, + {2,ch75st1}, + {2,ch75st2} +}; + +static const SFG_StrokeChar ch75 = {104.762,3,ch75st}; + +/* char: 0x4c */ + +static const SFG_StrokeVertex ch76st0[] = +{ + {23.8095,100}, + {23.8095,0} +}; + +static const SFG_StrokeVertex ch76st1[] = +{ + {23.8095,0}, + {80.9524,0} +}; + +static const SFG_StrokeStrip ch76st[] = +{ + {2,ch76st0}, + {2,ch76st1} +}; + +static const SFG_StrokeChar ch76 = {104.762,2,ch76st}; + +/* char: 0x4d */ + +static const SFG_StrokeVertex ch77st0[] = +{ + {14.2857,100}, + {14.2857,0} +}; + +static const SFG_StrokeVertex ch77st1[] = +{ + {14.2857,100}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch77st2[] = +{ + {90.4762,100}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch77st3[] = +{ + {90.4762,100}, + {90.4762,0} +}; + +static const SFG_StrokeStrip ch77st[] = +{ + {2,ch77st0}, + {2,ch77st1}, + {2,ch77st2}, + {2,ch77st3} +}; + +static const SFG_StrokeChar ch77 = {104.762,4,ch77st}; + +/* char: 0x4e */ + +static const SFG_StrokeVertex ch78st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch78st1[] = +{ + {19.0476,100}, + {85.7143,0} +}; + +static const SFG_StrokeVertex ch78st2[] = +{ + {85.7143,100}, + {85.7143,0} +}; + +static const SFG_StrokeStrip ch78st[] = +{ + {2,ch78st0}, + {2,ch78st1}, + {2,ch78st2} +}; + +static const SFG_StrokeChar ch78 = {104.762,3,ch78st}; + +/* char: 0x4f */ + +static const SFG_StrokeVertex ch79st0[] = +{ + {42.8571,100}, + {33.3333,95.2381}, + {23.8095,85.7143}, + {19.0476,76.1905}, + {14.2857,61.9048}, + {14.2857,38.0952}, + {19.0476,23.8095}, + {23.8095,14.2857}, + {33.3333,4.7619}, + {42.8571,0}, + {61.9047,0}, + {71.4286,4.7619}, + {80.9524,14.2857}, + {85.7143,23.8095}, + {90.4762,38.0952}, + {90.4762,61.9048}, + {85.7143,76.1905}, + {80.9524,85.7143}, + {71.4286,95.2381}, + {61.9047,100}, + {42.8571,100} +}; + +static const SFG_StrokeStrip ch79st[] = +{ + {21,ch79st0} +}; + +static const SFG_StrokeChar ch79 = {104.762,1,ch79st}; + +/* char: 0x50 */ + +static const SFG_StrokeVertex ch80st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch80st1[] = +{ + {19.0476,100}, + {61.9047,100}, + {76.1905,95.2381}, + {80.9524,90.4762}, + {85.7143,80.9524}, + {85.7143,66.6667}, + {80.9524,57.1429}, + {76.1905,52.381}, + {61.9047,47.619}, + {19.0476,47.619} +}; + +static const SFG_StrokeStrip ch80st[] = +{ + {2,ch80st0}, + {10,ch80st1} +}; + +static const SFG_StrokeChar ch80 = {104.762,2,ch80st}; + +/* char: 0x51 */ + +static const SFG_StrokeVertex ch81st0[] = +{ + {42.8571,100}, + {33.3333,95.2381}, + {23.8095,85.7143}, + {19.0476,76.1905}, + {14.2857,61.9048}, + {14.2857,38.0952}, + {19.0476,23.8095}, + {23.8095,14.2857}, + {33.3333,4.7619}, + {42.8571,0}, + {61.9047,0}, + {71.4286,4.7619}, + {80.9524,14.2857}, + {85.7143,23.8095}, + {90.4762,38.0952}, + {90.4762,61.9048}, + {85.7143,76.1905}, + {80.9524,85.7143}, + {71.4286,95.2381}, + {61.9047,100}, + {42.8571,100} +}; + +static const SFG_StrokeVertex ch81st1[] = +{ + {57.1428,19.0476}, + {85.7143,-9.5238} +}; + +static const SFG_StrokeStrip ch81st[] = +{ + {21,ch81st0}, + {2,ch81st1} +}; + +static const SFG_StrokeChar ch81 = {104.762,2,ch81st}; + +/* char: 0x52 */ + +static const SFG_StrokeVertex ch82st0[] = +{ + {19.0476,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch82st1[] = +{ + {19.0476,100}, + {61.9047,100}, + {76.1905,95.2381}, + {80.9524,90.4762}, + {85.7143,80.9524}, + {85.7143,71.4286}, + {80.9524,61.9048}, + {76.1905,57.1429}, + {61.9047,52.381}, + {19.0476,52.381} +}; + +static const SFG_StrokeVertex ch82st2[] = +{ + {52.3809,52.381}, + {85.7143,0} +}; + +static const SFG_StrokeStrip ch82st[] = +{ + {2,ch82st0}, + {10,ch82st1}, + {2,ch82st2} +}; + +static const SFG_StrokeChar ch82 = {104.762,3,ch82st}; + +/* char: 0x53 */ + +static const SFG_StrokeVertex ch83st0[] = +{ + {85.7143,85.7143}, + {76.1905,95.2381}, + {61.9047,100}, + {42.8571,100}, + {28.5714,95.2381}, + {19.0476,85.7143}, + {19.0476,76.1905}, + {23.8095,66.6667}, + {28.5714,61.9048}, + {38.0952,57.1429}, + {66.6666,47.619}, + {76.1905,42.8571}, + {80.9524,38.0952}, + {85.7143,28.5714}, + {85.7143,14.2857}, + {76.1905,4.7619}, + {61.9047,0}, + {42.8571,0}, + {28.5714,4.7619}, + {19.0476,14.2857} +}; + +static const SFG_StrokeStrip ch83st[] = +{ + {20,ch83st0} +}; + +static const SFG_StrokeChar ch83 = {104.762,1,ch83st}; + +/* char: 0x54 */ + +static const SFG_StrokeVertex ch84st0[] = +{ + {52.3809,100}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch84st1[] = +{ + {19.0476,100}, + {85.7143,100} +}; + +static const SFG_StrokeStrip ch84st[] = +{ + {2,ch84st0}, + {2,ch84st1} +}; + +static const SFG_StrokeChar ch84 = {104.762,2,ch84st}; + +/* char: 0x55 */ + +static const SFG_StrokeVertex ch85st0[] = +{ + {19.0476,100}, + {19.0476,28.5714}, + {23.8095,14.2857}, + {33.3333,4.7619}, + {47.619,0}, + {57.1428,0}, + {71.4286,4.7619}, + {80.9524,14.2857}, + {85.7143,28.5714}, + {85.7143,100} +}; + +static const SFG_StrokeStrip ch85st[] = +{ + {10,ch85st0} +}; + +static const SFG_StrokeChar ch85 = {104.762,1,ch85st}; + +/* char: 0x56 */ + +static const SFG_StrokeVertex ch86st0[] = +{ + {14.2857,100}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch86st1[] = +{ + {90.4762,100}, + {52.3809,0} +}; + +static const SFG_StrokeStrip ch86st[] = +{ + {2,ch86st0}, + {2,ch86st1} +}; + +static const SFG_StrokeChar ch86 = {104.762,2,ch86st}; + +/* char: 0x57 */ + +static const SFG_StrokeVertex ch87st0[] = +{ + {4.7619,100}, + {28.5714,0} +}; + +static const SFG_StrokeVertex ch87st1[] = +{ + {52.3809,100}, + {28.5714,0} +}; + +static const SFG_StrokeVertex ch87st2[] = +{ + {52.3809,100}, + {76.1905,0} +}; + +static const SFG_StrokeVertex ch87st3[] = +{ + {100,100}, + {76.1905,0} +}; + +static const SFG_StrokeStrip ch87st[] = +{ + {2,ch87st0}, + {2,ch87st1}, + {2,ch87st2}, + {2,ch87st3} +}; + +static const SFG_StrokeChar ch87 = {104.762,4,ch87st}; + +/* char: 0x58 */ + +static const SFG_StrokeVertex ch88st0[] = +{ + {19.0476,100}, + {85.7143,0} +}; + +static const SFG_StrokeVertex ch88st1[] = +{ + {85.7143,100}, + {19.0476,0} +}; + +static const SFG_StrokeStrip ch88st[] = +{ + {2,ch88st0}, + {2,ch88st1} +}; + +static const SFG_StrokeChar ch88 = {104.762,2,ch88st}; + +/* char: 0x59 */ + +static const SFG_StrokeVertex ch89st0[] = +{ + {14.2857,100}, + {52.3809,52.381}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch89st1[] = +{ + {90.4762,100}, + {52.3809,52.381} +}; + +static const SFG_StrokeStrip ch89st[] = +{ + {3,ch89st0}, + {2,ch89st1} +}; + +static const SFG_StrokeChar ch89 = {104.762,2,ch89st}; + +/* char: 0x5a */ + +static const SFG_StrokeVertex ch90st0[] = +{ + {85.7143,100}, + {19.0476,0} +}; + +static const SFG_StrokeVertex ch90st1[] = +{ + {19.0476,100}, + {85.7143,100} +}; + +static const SFG_StrokeVertex ch90st2[] = +{ + {19.0476,0}, + {85.7143,0} +}; + +static const SFG_StrokeStrip ch90st[] = +{ + {2,ch90st0}, + {2,ch90st1}, + {2,ch90st2} +}; + +static const SFG_StrokeChar ch90 = {104.762,3,ch90st}; + +/* char: 0x5b */ + +static const SFG_StrokeVertex ch91st0[] = +{ + {35.7143,119.048}, + {35.7143,-33.3333} +}; + +static const SFG_StrokeVertex ch91st1[] = +{ + {40.4762,119.048}, + {40.4762,-33.3333} +}; + +static const SFG_StrokeVertex ch91st2[] = +{ + {35.7143,119.048}, + {69.0476,119.048} +}; + +static const SFG_StrokeVertex ch91st3[] = +{ + {35.7143,-33.3333}, + {69.0476,-33.3333} +}; + +static const SFG_StrokeStrip ch91st[] = +{ + {2,ch91st0}, + {2,ch91st1}, + {2,ch91st2}, + {2,ch91st3} +}; + +static const SFG_StrokeChar ch91 = {104.762,4,ch91st}; + +/* char: 0x5c */ + +static const SFG_StrokeVertex ch92st0[] = +{ + {19.0476,100}, + {85.7143,-14.2857} +}; + +static const SFG_StrokeStrip ch92st[] = +{ + {2,ch92st0} +}; + +static const SFG_StrokeChar ch92 = {104.762,1,ch92st}; + +/* char: 0x5d */ + +static const SFG_StrokeVertex ch93st0[] = +{ + {64.2857,119.048}, + {64.2857,-33.3333} +}; + +static const SFG_StrokeVertex ch93st1[] = +{ + {69.0476,119.048}, + {69.0476,-33.3333} +}; + +static const SFG_StrokeVertex ch93st2[] = +{ + {35.7143,119.048}, + {69.0476,119.048} +}; + +static const SFG_StrokeVertex ch93st3[] = +{ + {35.7143,-33.3333}, + {69.0476,-33.3333} +}; + +static const SFG_StrokeStrip ch93st[] = +{ + {2,ch93st0}, + {2,ch93st1}, + {2,ch93st2}, + {2,ch93st3} +}; + +static const SFG_StrokeChar ch93 = {104.762,4,ch93st}; + +/* char: 0x5e */ + +static const SFG_StrokeVertex ch94st0[] = +{ + {52.3809,109.524}, + {14.2857,42.8571} +}; + +static const SFG_StrokeVertex ch94st1[] = +{ + {52.3809,109.524}, + {90.4762,42.8571} +}; + +static const SFG_StrokeStrip ch94st[] = +{ + {2,ch94st0}, + {2,ch94st1} +}; + +static const SFG_StrokeChar ch94 = {104.762,2,ch94st}; + +/* char: 0x5f */ + +static const SFG_StrokeVertex ch95st0[] = +{ + {0,-33.3333}, + {104.762,-33.3333}, + {104.762,-28.5714}, + {0,-28.5714}, + {0,-33.3333} +}; + +static const SFG_StrokeStrip ch95st[] = +{ + {5,ch95st0} +}; + +static const SFG_StrokeChar ch95 = {104.762,1,ch95st}; + +/* char: 0x60 */ + +static const SFG_StrokeVertex ch96st0[] = +{ + {42.8572,100}, + {66.6667,71.4286} +}; + +static const SFG_StrokeVertex ch96st1[] = +{ + {42.8572,100}, + {38.0953,95.2381}, + {66.6667,71.4286} +}; + +static const SFG_StrokeStrip ch96st[] = +{ + {2,ch96st0}, + {3,ch96st1} +}; + +static const SFG_StrokeChar ch96 = {104.762,2,ch96st}; + +/* char: 0x61 */ + +static const SFG_StrokeVertex ch97st0[] = +{ + {80.9524,66.6667}, + {80.9524,0} +}; + +static const SFG_StrokeVertex ch97st1[] = +{ + {80.9524,52.381}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch97st[] = +{ + {2,ch97st0}, + {14,ch97st1} +}; + +static const SFG_StrokeChar ch97 = {104.762,2,ch97st}; + +/* char: 0x62 */ + +static const SFG_StrokeVertex ch98st0[] = +{ + {23.8095,100}, + {23.8095,0} +}; + +static const SFG_StrokeVertex ch98st1[] = +{ + {23.8095,52.381}, + {33.3333,61.9048}, + {42.8571,66.6667}, + {57.1428,66.6667}, + {66.6666,61.9048}, + {76.1905,52.381}, + {80.9524,38.0952}, + {80.9524,28.5714}, + {76.1905,14.2857}, + {66.6666,4.7619}, + {57.1428,0}, + {42.8571,0}, + {33.3333,4.7619}, + {23.8095,14.2857} +}; + +static const SFG_StrokeStrip ch98st[] = +{ + {2,ch98st0}, + {14,ch98st1} +}; + +static const SFG_StrokeChar ch98 = {104.762,2,ch98st}; + +/* char: 0x63 */ + +static const SFG_StrokeVertex ch99st0[] = +{ + {80.9524,52.381}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch99st[] = +{ + {14,ch99st0} +}; + +static const SFG_StrokeChar ch99 = {104.762,1,ch99st}; + +/* char: 0x64 */ + +static const SFG_StrokeVertex ch100st0[] = +{ + {80.9524,100}, + {80.9524,0} +}; + +static const SFG_StrokeVertex ch100st1[] = +{ + {80.9524,52.381}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch100st[] = +{ + {2,ch100st0}, + {14,ch100st1} +}; + +static const SFG_StrokeChar ch100 = {104.762,2,ch100st}; + +/* char: 0x65 */ + +static const SFG_StrokeVertex ch101st0[] = +{ + {23.8095,38.0952}, + {80.9524,38.0952}, + {80.9524,47.619}, + {76.1905,57.1429}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch101st[] = +{ + {17,ch101st0} +}; + +static const SFG_StrokeChar ch101 = {104.762,1,ch101st}; + +/* char: 0x66 */ + +static const SFG_StrokeVertex ch102st0[] = +{ + {71.4286,100}, + {61.9048,100}, + {52.381,95.2381}, + {47.6191,80.9524}, + {47.6191,0} +}; + +static const SFG_StrokeVertex ch102st1[] = +{ + {33.3334,66.6667}, + {66.6667,66.6667} +}; + +static const SFG_StrokeStrip ch102st[] = +{ + {5,ch102st0}, + {2,ch102st1} +}; + +static const SFG_StrokeChar ch102 = {104.762,2,ch102st}; + +/* char: 0x67 */ + +static const SFG_StrokeVertex ch103st0[] = +{ + {80.9524,66.6667}, + {80.9524,-9.5238}, + {76.1905,-23.8095}, + {71.4285,-28.5714}, + {61.9047,-33.3333}, + {47.619,-33.3333}, + {38.0952,-28.5714} +}; + +static const SFG_StrokeVertex ch103st1[] = +{ + {80.9524,52.381}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch103st[] = +{ + {7,ch103st0}, + {14,ch103st1} +}; + +static const SFG_StrokeChar ch103 = {104.762,2,ch103st}; + +/* char: 0x68 */ + +static const SFG_StrokeVertex ch104st0[] = +{ + {26.1905,100}, + {26.1905,0} +}; + +static const SFG_StrokeVertex ch104st1[] = +{ + {26.1905,47.619}, + {40.4762,61.9048}, + {50,66.6667}, + {64.2857,66.6667}, + {73.8095,61.9048}, + {78.5715,47.619}, + {78.5715,0} +}; + +static const SFG_StrokeStrip ch104st[] = +{ + {2,ch104st0}, + {7,ch104st1} +}; + +static const SFG_StrokeChar ch104 = {104.762,2,ch104st}; + +/* char: 0x69 */ + +static const SFG_StrokeVertex ch105st0[] = +{ + {47.6191,100}, + {52.381,95.2381}, + {57.1429,100}, + {52.381,104.762}, + {47.6191,100} +}; + +static const SFG_StrokeVertex ch105st1[] = +{ + {52.381,66.6667}, + {52.381,0} +}; + +static const SFG_StrokeStrip ch105st[] = +{ + {5,ch105st0}, + {2,ch105st1} +}; + +static const SFG_StrokeChar ch105 = {104.762,2,ch105st}; + +/* char: 0x6a */ + +static const SFG_StrokeVertex ch106st0[] = +{ + {57.1429,100}, + {61.9048,95.2381}, + {66.6667,100}, + {61.9048,104.762}, + {57.1429,100} +}; + +static const SFG_StrokeVertex ch106st1[] = +{ + {61.9048,66.6667}, + {61.9048,-14.2857}, + {57.1429,-28.5714}, + {47.6191,-33.3333}, + {38.0953,-33.3333} +}; + +static const SFG_StrokeStrip ch106st[] = +{ + {5,ch106st0}, + {5,ch106st1} +}; + +static const SFG_StrokeChar ch106 = {104.762,2,ch106st}; + +/* char: 0x6b */ + +static const SFG_StrokeVertex ch107st0[] = +{ + {26.1905,100}, + {26.1905,0} +}; + +static const SFG_StrokeVertex ch107st1[] = +{ + {73.8095,66.6667}, + {26.1905,19.0476} +}; + +static const SFG_StrokeVertex ch107st2[] = +{ + {45.2381,38.0952}, + {78.5715,0} +}; + +static const SFG_StrokeStrip ch107st[] = +{ + {2,ch107st0}, + {2,ch107st1}, + {2,ch107st2} +}; + +static const SFG_StrokeChar ch107 = {104.762,3,ch107st}; + +/* char: 0x6c */ + +static const SFG_StrokeVertex ch108st0[] = +{ + {52.381,100}, + {52.381,0} +}; + +static const SFG_StrokeStrip ch108st[] = +{ + {2,ch108st0} +}; + +static const SFG_StrokeChar ch108 = {104.762,1,ch108st}; + +/* char: 0x6d */ + +static const SFG_StrokeVertex ch109st0[] = +{ + {0,66.6667}, + {0,0} +}; + +static const SFG_StrokeVertex ch109st1[] = +{ + {0,47.619}, + {14.2857,61.9048}, + {23.8095,66.6667}, + {38.0952,66.6667}, + {47.619,61.9048}, + {52.381,47.619}, + {52.381,0} +}; + +static const SFG_StrokeVertex ch109st2[] = +{ + {52.381,47.619}, + {66.6667,61.9048}, + {76.1905,66.6667}, + {90.4762,66.6667}, + {100,61.9048}, + {104.762,47.619}, + {104.762,0} +}; + +static const SFG_StrokeStrip ch109st[] = +{ + {2,ch109st0}, + {7,ch109st1}, + {7,ch109st2} +}; + +static const SFG_StrokeChar ch109 = {104.762,3,ch109st}; + +/* char: 0x6e */ + +static const SFG_StrokeVertex ch110st0[] = +{ + {26.1905,66.6667}, + {26.1905,0} +}; + +static const SFG_StrokeVertex ch110st1[] = +{ + {26.1905,47.619}, + {40.4762,61.9048}, + {50,66.6667}, + {64.2857,66.6667}, + {73.8095,61.9048}, + {78.5715,47.619}, + {78.5715,0} +}; + +static const SFG_StrokeStrip ch110st[] = +{ + {2,ch110st0}, + {7,ch110st1} +}; + +static const SFG_StrokeChar ch110 = {104.762,2,ch110st}; + +/* char: 0x6f */ + +static const SFG_StrokeVertex ch111st0[] = +{ + {45.2381,66.6667}, + {35.7143,61.9048}, + {26.1905,52.381}, + {21.4286,38.0952}, + {21.4286,28.5714}, + {26.1905,14.2857}, + {35.7143,4.7619}, + {45.2381,0}, + {59.5238,0}, + {69.0476,4.7619}, + {78.5714,14.2857}, + {83.3334,28.5714}, + {83.3334,38.0952}, + {78.5714,52.381}, + {69.0476,61.9048}, + {59.5238,66.6667}, + {45.2381,66.6667} +}; + +static const SFG_StrokeStrip ch111st[] = +{ + {17,ch111st0} +}; + +static const SFG_StrokeChar ch111 = {104.762,1,ch111st}; + +/* char: 0x70 */ + +static const SFG_StrokeVertex ch112st0[] = +{ + {23.8095,66.6667}, + {23.8095,-33.3333} +}; + +static const SFG_StrokeVertex ch112st1[] = +{ + {23.8095,52.381}, + {33.3333,61.9048}, + {42.8571,66.6667}, + {57.1428,66.6667}, + {66.6666,61.9048}, + {76.1905,52.381}, + {80.9524,38.0952}, + {80.9524,28.5714}, + {76.1905,14.2857}, + {66.6666,4.7619}, + {57.1428,0}, + {42.8571,0}, + {33.3333,4.7619}, + {23.8095,14.2857} +}; + +static const SFG_StrokeStrip ch112st[] = +{ + {2,ch112st0}, + {14,ch112st1} +}; + +static const SFG_StrokeChar ch112 = {104.762,2,ch112st}; + +/* char: 0x71 */ + +static const SFG_StrokeVertex ch113st0[] = +{ + {80.9524,66.6667}, + {80.9524,-33.3333} +}; + +static const SFG_StrokeVertex ch113st1[] = +{ + {80.9524,52.381}, + {71.4285,61.9048}, + {61.9047,66.6667}, + {47.619,66.6667}, + {38.0952,61.9048}, + {28.5714,52.381}, + {23.8095,38.0952}, + {23.8095,28.5714}, + {28.5714,14.2857}, + {38.0952,4.7619}, + {47.619,0}, + {61.9047,0}, + {71.4285,4.7619}, + {80.9524,14.2857} +}; + +static const SFG_StrokeStrip ch113st[] = +{ + {2,ch113st0}, + {14,ch113st1} +}; + +static const SFG_StrokeChar ch113 = {104.762,2,ch113st}; + +/* char: 0x72 */ + +static const SFG_StrokeVertex ch114st0[] = +{ + {33.3334,66.6667}, + {33.3334,0} +}; + +static const SFG_StrokeVertex ch114st1[] = +{ + {33.3334,38.0952}, + {38.0953,52.381}, + {47.6191,61.9048}, + {57.1429,66.6667}, + {71.4286,66.6667} +}; + +static const SFG_StrokeStrip ch114st[] = +{ + {2,ch114st0}, + {5,ch114st1} +}; + +static const SFG_StrokeChar ch114 = {104.762,2,ch114st}; + +/* char: 0x73 */ + +static const SFG_StrokeVertex ch115st0[] = +{ + {78.5715,52.381}, + {73.8095,61.9048}, + {59.5238,66.6667}, + {45.2381,66.6667}, + {30.9524,61.9048}, + {26.1905,52.381}, + {30.9524,42.8571}, + {40.4762,38.0952}, + {64.2857,33.3333}, + {73.8095,28.5714}, + {78.5715,19.0476}, + {78.5715,14.2857}, + {73.8095,4.7619}, + {59.5238,0}, + {45.2381,0}, + {30.9524,4.7619}, + {26.1905,14.2857} +}; + +static const SFG_StrokeStrip ch115st[] = +{ + {17,ch115st0} +}; + +static const SFG_StrokeChar ch115 = {104.762,1,ch115st}; + +/* char: 0x74 */ + +static const SFG_StrokeVertex ch116st0[] = +{ + {47.6191,100}, + {47.6191,19.0476}, + {52.381,4.7619}, + {61.9048,0}, + {71.4286,0} +}; + +static const SFG_StrokeVertex ch116st1[] = +{ + {33.3334,66.6667}, + {66.6667,66.6667} +}; + +static const SFG_StrokeStrip ch116st[] = +{ + {5,ch116st0}, + {2,ch116st1} +}; + +static const SFG_StrokeChar ch116 = {104.762,2,ch116st}; + +/* char: 0x75 */ + +static const SFG_StrokeVertex ch117st0[] = +{ + {26.1905,66.6667}, + {26.1905,19.0476}, + {30.9524,4.7619}, + {40.4762,0}, + {54.7619,0}, + {64.2857,4.7619}, + {78.5715,19.0476} +}; + +static const SFG_StrokeVertex ch117st1[] = +{ + {78.5715,66.6667}, + {78.5715,0} +}; + +static const SFG_StrokeStrip ch117st[] = +{ + {7,ch117st0}, + {2,ch117st1} +}; + +static const SFG_StrokeChar ch117 = {104.762,2,ch117st}; + +/* char: 0x76 */ + +static const SFG_StrokeVertex ch118st0[] = +{ + {23.8095,66.6667}, + {52.3809,0} +}; + +static const SFG_StrokeVertex ch118st1[] = +{ + {80.9524,66.6667}, + {52.3809,0} +}; + +static const SFG_StrokeStrip ch118st[] = +{ + {2,ch118st0}, + {2,ch118st1} +}; + +static const SFG_StrokeChar ch118 = {104.762,2,ch118st}; + +/* char: 0x77 */ + +static const SFG_StrokeVertex ch119st0[] = +{ + {14.2857,66.6667}, + {33.3333,0} +}; + +static const SFG_StrokeVertex ch119st1[] = +{ + {52.3809,66.6667}, + {33.3333,0} +}; + +static const SFG_StrokeVertex ch119st2[] = +{ + {52.3809,66.6667}, + {71.4286,0} +}; + +static const SFG_StrokeVertex ch119st3[] = +{ + {90.4762,66.6667}, + {71.4286,0} +}; + +static const SFG_StrokeStrip ch119st[] = +{ + {2,ch119st0}, + {2,ch119st1}, + {2,ch119st2}, + {2,ch119st3} +}; + +static const SFG_StrokeChar ch119 = {104.762,4,ch119st}; + +/* char: 0x78 */ + +static const SFG_StrokeVertex ch120st0[] = +{ + {26.1905,66.6667}, + {78.5715,0} +}; + +static const SFG_StrokeVertex ch120st1[] = +{ + {78.5715,66.6667}, + {26.1905,0} +}; + +static const SFG_StrokeStrip ch120st[] = +{ + {2,ch120st0}, + {2,ch120st1} +}; + +static const SFG_StrokeChar ch120 = {104.762,2,ch120st}; + +/* char: 0x79 */ + +static const SFG_StrokeVertex ch121st0[] = +{ + {26.1905,66.6667}, + {54.7619,0} +}; + +static const SFG_StrokeVertex ch121st1[] = +{ + {83.3334,66.6667}, + {54.7619,0}, + {45.2381,-19.0476}, + {35.7143,-28.5714}, + {26.1905,-33.3333}, + {21.4286,-33.3333} +}; + +static const SFG_StrokeStrip ch121st[] = +{ + {2,ch121st0}, + {6,ch121st1} +}; + +static const SFG_StrokeChar ch121 = {104.762,2,ch121st}; + +/* char: 0x7a */ + +static const SFG_StrokeVertex ch122st0[] = +{ + {78.5715,66.6667}, + {26.1905,0} +}; + +static const SFG_StrokeVertex ch122st1[] = +{ + {26.1905,66.6667}, + {78.5715,66.6667} +}; + +static const SFG_StrokeVertex ch122st2[] = +{ + {26.1905,0}, + {78.5715,0} +}; + +static const SFG_StrokeStrip ch122st[] = +{ + {2,ch122st0}, + {2,ch122st1}, + {2,ch122st2} +}; + +static const SFG_StrokeChar ch122 = {104.762,3,ch122st}; + +/* char: 0x7b */ + +static const SFG_StrokeVertex ch123st0[] = +{ + {64.2857,119.048}, + {54.7619,114.286}, + {50,109.524}, + {45.2381,100}, + {45.2381,90.4762}, + {50,80.9524}, + {54.7619,76.1905}, + {59.5238,66.6667}, + {59.5238,57.1429}, + {50,47.619} +}; + +static const SFG_StrokeVertex ch123st1[] = +{ + {54.7619,114.286}, + {50,104.762}, + {50,95.2381}, + {54.7619,85.7143}, + {59.5238,80.9524}, + {64.2857,71.4286}, + {64.2857,61.9048}, + {59.5238,52.381}, + {40.4762,42.8571}, + {59.5238,33.3333}, + {64.2857,23.8095}, + {64.2857,14.2857}, + {59.5238,4.7619}, + {54.7619,0}, + {50,-9.5238}, + {50,-19.0476}, + {54.7619,-28.5714} +}; + +static const SFG_StrokeVertex ch123st2[] = +{ + {50,38.0952}, + {59.5238,28.5714}, + {59.5238,19.0476}, + {54.7619,9.5238}, + {50,4.7619}, + {45.2381,-4.7619}, + {45.2381,-14.2857}, + {50,-23.8095}, + {54.7619,-28.5714}, + {64.2857,-33.3333} +}; + +static const SFG_StrokeStrip ch123st[] = +{ + {10,ch123st0}, + {17,ch123st1}, + {10,ch123st2} +}; + +static const SFG_StrokeChar ch123 = {104.762,3,ch123st}; + +/* char: 0x7c */ + +static const SFG_StrokeVertex ch124st0[] = +{ + {52.381,119.048}, + {52.381,-33.3333} +}; + +static const SFG_StrokeStrip ch124st[] = +{ + {2,ch124st0} +}; + +static const SFG_StrokeChar ch124 = {104.762,1,ch124st}; + +/* char: 0x7d */ + +static const SFG_StrokeVertex ch125st0[] = +{ + {40.4762,119.048}, + {50,114.286}, + {54.7619,109.524}, + {59.5238,100}, + {59.5238,90.4762}, + {54.7619,80.9524}, + {50,76.1905}, + {45.2381,66.6667}, + {45.2381,57.1429}, + {54.7619,47.619} +}; + +static const SFG_StrokeVertex ch125st1[] = +{ + {50,114.286}, + {54.7619,104.762}, + {54.7619,95.2381}, + {50,85.7143}, + {45.2381,80.9524}, + {40.4762,71.4286}, + {40.4762,61.9048}, + {45.2381,52.381}, + {64.2857,42.8571}, + {45.2381,33.3333}, + {40.4762,23.8095}, + {40.4762,14.2857}, + {45.2381,4.7619}, + {50,0}, + {54.7619,-9.5238}, + {54.7619,-19.0476}, + {50,-28.5714} +}; + +static const SFG_StrokeVertex ch125st2[] = +{ + {54.7619,38.0952}, + {45.2381,28.5714}, + {45.2381,19.0476}, + {50,9.5238}, + {54.7619,4.7619}, + {59.5238,-4.7619}, + {59.5238,-14.2857}, + {54.7619,-23.8095}, + {50,-28.5714}, + {40.4762,-33.3333} +}; + +static const SFG_StrokeStrip ch125st[] = +{ + {10,ch125st0}, + {17,ch125st1}, + {10,ch125st2} +}; + +static const SFG_StrokeChar ch125 = {104.762,3,ch125st}; + +/* char: 0x7e */ + +static const SFG_StrokeVertex ch126st0[] = +{ + {9.5238,28.5714}, + {9.5238,38.0952}, + {14.2857,52.381}, + {23.8095,57.1429}, + {33.3333,57.1429}, + {42.8571,52.381}, + {61.9048,38.0952}, + {71.4286,33.3333}, + {80.9524,33.3333}, + {90.4762,38.0952}, + {95.2381,47.619} +}; + +static const SFG_StrokeVertex ch126st1[] = +{ + {9.5238,38.0952}, + {14.2857,47.619}, + {23.8095,52.381}, + {33.3333,52.381}, + {42.8571,47.619}, + {61.9048,33.3333}, + {71.4286,28.5714}, + {80.9524,28.5714}, + {90.4762,33.3333}, + {95.2381,47.619}, + {95.2381,57.1429} +}; + +static const SFG_StrokeStrip ch126st[] = +{ + {11,ch126st0}, + {11,ch126st1} +}; + +static const SFG_StrokeChar ch126 = {104.762,2,ch126st}; + +/* char: 0x7f */ + +static const SFG_StrokeVertex ch127st0[] = +{ + {71.4286,100}, + {33.3333,-33.3333} +}; + +static const SFG_StrokeVertex ch127st1[] = +{ + {47.619,66.6667}, + {33.3333,61.9048}, + {23.8095,52.381}, + {19.0476,38.0952}, + {19.0476,23.8095}, + {23.8095,14.2857}, + {33.3333,4.7619}, + {47.619,0}, + {57.1428,0}, + {71.4286,4.7619}, + {80.9524,14.2857}, + {85.7143,28.5714}, + {85.7143,42.8571}, + {80.9524,52.381}, + {71.4286,61.9048}, + {57.1428,66.6667}, + {47.619,66.6667} +}; + +static const SFG_StrokeStrip ch127st[] = +{ + {2,ch127st0}, + {17,ch127st1} +}; + +static const SFG_StrokeChar ch127 = {104.762,2,ch127st}; + +static const SFG_StrokeChar *chars[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39, + &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47, + &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55, + &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63, + &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71, + &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79, + &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87, + &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95, + &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103, + &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111, + &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119, + &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127 +}; + +const SFG_StrokeFont fgStrokeMonoRoman = {"MonoRoman",128,152.381,chars}; diff --git a/src/freeglut_stroke_roman.c b/src/freeglut_stroke_roman.c new file mode 100644 index 0000000..c7ecd2b --- /dev/null +++ b/src/freeglut_stroke_roman.c @@ -0,0 +1,2824 @@ + +/* This file has been automatically generated by the genstroke utility. */ + +#include "freeglut_internal.h" +#ifdef TARGET_HOST_WIN32 +#pragma warning ( once:4305 ) +#endif + +/* char: 0x20 */ + +static const SFG_StrokeStrip ch32st[] = +{ + { 0, NULL } +}; + +static const SFG_StrokeChar ch32 = {104.762,0,ch32st}; + +/* char: 0x21 */ + +static const SFG_StrokeVertex ch33st0[] = +{ + {13.3819,100}, + {13.3819,33.3333} +}; + +static const SFG_StrokeVertex ch33st1[] = +{ + {13.3819,9.5238}, + {8.62,4.7619}, + {13.3819,0}, + {18.1438,4.7619}, + {13.3819,9.5238} +}; + +static const SFG_StrokeStrip ch33st[] = +{ + {2,ch33st0}, + {5,ch33st1} +}; + +static const SFG_StrokeChar ch33 = {26.6238,2,ch33st}; + +/* char: 0x22 */ + +static const SFG_StrokeVertex ch34st0[] = +{ + {4.02,100}, + {4.02,66.6667} +}; + +static const SFG_StrokeVertex ch34st1[] = +{ + {42.1152,100}, + {42.1152,66.6667} +}; + +static const SFG_StrokeStrip ch34st[] = +{ + {2,ch34st0}, + {2,ch34st1} +}; + +static const SFG_StrokeChar ch34 = {51.4352,2,ch34st}; + +/* char: 0x23 */ + +static const SFG_StrokeVertex ch35st0[] = +{ + {41.2952,119.048}, + {7.9619,-33.3333} +}; + +static const SFG_StrokeVertex ch35st1[] = +{ + {69.8667,119.048}, + {36.5333,-33.3333} +}; + +static const SFG_StrokeVertex ch35st2[] = +{ + {7.9619,57.1429}, + {74.6286,57.1429} +}; + +static const SFG_StrokeVertex ch35st3[] = +{ + {3.2,28.5714}, + {69.8667,28.5714} +}; + +static const SFG_StrokeStrip ch35st[] = +{ + {2,ch35st0}, + {2,ch35st1}, + {2,ch35st2}, + {2,ch35st3} +}; + +static const SFG_StrokeChar ch35 = {79.4886,4,ch35st}; + +/* char: 0x24 */ + +static const SFG_StrokeVertex ch36st0[] = +{ + {28.6295,119.048}, + {28.6295,-19.0476} +}; + +static const SFG_StrokeVertex ch36st1[] = +{ + {47.6771,119.048}, + {47.6771,-19.0476} +}; + +static const SFG_StrokeVertex ch36st2[] = +{ + {71.4867,85.7143}, + {61.9629,95.2381}, + {47.6771,100}, + {28.6295,100}, + {14.3438,95.2381}, + {4.82,85.7143}, + {4.82,76.1905}, + {9.5819,66.6667}, + {14.3438,61.9048}, + {23.8676,57.1429}, + {52.439,47.619}, + {61.9629,42.8571}, + {66.7248,38.0952}, + {71.4867,28.5714}, + {71.4867,14.2857}, + {61.9629,4.7619}, + {47.6771,0}, + {28.6295,0}, + {14.3438,4.7619}, + {4.82,14.2857} +}; + +static const SFG_StrokeStrip ch36st[] = +{ + {2,ch36st0}, + {2,ch36st1}, + {20,ch36st2} +}; + +static const SFG_StrokeChar ch36 = {76.2067,3,ch36st}; + +/* char: 0x25 */ + +static const SFG_StrokeVertex ch37st0[] = +{ + {92.0743,100}, + {6.36,0} +}; + +static const SFG_StrokeVertex ch37st1[] = +{ + {30.1695,100}, + {39.6933,90.4762}, + {39.6933,80.9524}, + {34.9314,71.4286}, + {25.4076,66.6667}, + {15.8838,66.6667}, + {6.36,76.1905}, + {6.36,85.7143}, + {11.1219,95.2381}, + {20.6457,100}, + {30.1695,100}, + {39.6933,95.2381}, + {53.979,90.4762}, + {68.2648,90.4762}, + {82.5505,95.2381}, + {92.0743,100} +}; + +static const SFG_StrokeVertex ch37st2[] = +{ + {73.0267,33.3333}, + {63.5029,28.5714}, + {58.741,19.0476}, + {58.741,9.5238}, + {68.2648,0}, + {77.7886,0}, + {87.3124,4.7619}, + {92.0743,14.2857}, + {92.0743,23.8095}, + {82.5505,33.3333}, + {73.0267,33.3333} +}; + +static const SFG_StrokeStrip ch37st[] = +{ + {2,ch37st0}, + {16,ch37st1}, + {11,ch37st2} +}; + +static const SFG_StrokeChar ch37 = {96.5743,3,ch37st}; + +/* char: 0x26 */ + +static const SFG_StrokeVertex ch38st0[] = +{ + {101.218,57.1429}, + {101.218,61.9048}, + {96.4562,66.6667}, + {91.6943,66.6667}, + {86.9324,61.9048}, + {82.1705,52.381}, + {72.6467,28.5714}, + {63.1229,14.2857}, + {53.599,4.7619}, + {44.0752,0}, + {25.0276,0}, + {15.5038,4.7619}, + {10.7419,9.5238}, + {5.98,19.0476}, + {5.98,28.5714}, + {10.7419,38.0952}, + {15.5038,42.8571}, + {48.8371,61.9048}, + {53.599,66.6667}, + {58.361,76.1905}, + {58.361,85.7143}, + {53.599,95.2381}, + {44.0752,100}, + {34.5514,95.2381}, + {29.7895,85.7143}, + {29.7895,76.1905}, + {34.5514,61.9048}, + {44.0752,47.619}, + {67.8848,14.2857}, + {77.4086,4.7619}, + {86.9324,0}, + {96.4562,0}, + {101.218,4.7619}, + {101.218,9.5238} +}; + +static const SFG_StrokeStrip ch38st[] = +{ + {34,ch38st0} +}; + +static const SFG_StrokeChar ch38 = {101.758,1,ch38st}; + +/* char: 0x27 */ + +static const SFG_StrokeVertex ch39st0[] = +{ + {4.44,100}, + {4.44,66.6667} +}; + +static const SFG_StrokeStrip ch39st[] = +{ + {2,ch39st0} +}; + +static const SFG_StrokeChar ch39 = {13.62,1,ch39st}; + +/* char: 0x28 */ + +static const SFG_StrokeVertex ch40st0[] = +{ + {40.9133,119.048}, + {31.3895,109.524}, + {21.8657,95.2381}, + {12.3419,76.1905}, + {7.58,52.381}, + {7.58,33.3333}, + {12.3419,9.5238}, + {21.8657,-9.5238}, + {31.3895,-23.8095}, + {40.9133,-33.3333} +}; + +static const SFG_StrokeStrip ch40st[] = +{ + {10,ch40st0} +}; + +static const SFG_StrokeChar ch40 = {47.1733,1,ch40st}; + +/* char: 0x29 */ + +static const SFG_StrokeVertex ch41st0[] = +{ + {5.28,119.048}, + {14.8038,109.524}, + {24.3276,95.2381}, + {33.8514,76.1905}, + {38.6133,52.381}, + {38.6133,33.3333}, + {33.8514,9.5238}, + {24.3276,-9.5238}, + {14.8038,-23.8095}, + {5.28,-33.3333} +}; + +static const SFG_StrokeStrip ch41st[] = +{ + {10,ch41st0} +}; + +static const SFG_StrokeChar ch41 = {47.5333,1,ch41st}; + +/* char: 0x2a */ + +static const SFG_StrokeVertex ch42st0[] = +{ + {30.7695,71.4286}, + {30.7695,14.2857} +}; + +static const SFG_StrokeVertex ch42st1[] = +{ + {6.96,57.1429}, + {54.579,28.5714} +}; + +static const SFG_StrokeVertex ch42st2[] = +{ + {54.579,57.1429}, + {6.96,28.5714} +}; + +static const SFG_StrokeStrip ch42st[] = +{ + {2,ch42st0}, + {2,ch42st1}, + {2,ch42st2} +}; + +static const SFG_StrokeChar ch42 = {59.439,3,ch42st}; + +/* char: 0x2b */ + +static const SFG_StrokeVertex ch43st0[] = +{ + {48.8371,85.7143}, + {48.8371,0} +}; + +static const SFG_StrokeVertex ch43st1[] = +{ + {5.98,42.8571}, + {91.6943,42.8571} +}; + +static const SFG_StrokeStrip ch43st[] = +{ + {2,ch43st0}, + {2,ch43st1} +}; + +static const SFG_StrokeChar ch43 = {97.2543,2,ch43st}; + +/* char: 0x2c */ + +static const SFG_StrokeVertex ch44st0[] = +{ + {18.2838,4.7619}, + {13.5219,0}, + {8.76,4.7619}, + {13.5219,9.5238}, + {18.2838,4.7619}, + {18.2838,-4.7619}, + {13.5219,-14.2857}, + {8.76,-19.0476} +}; + +static const SFG_StrokeStrip ch44st[] = +{ + {8,ch44st0} +}; + +static const SFG_StrokeChar ch44 = {26.0638,1,ch44st}; + +/* char: 0x2d */ + +static const SFG_StrokeVertex ch45st0[] = +{ + {7.38,42.8571}, + {93.0943,42.8571} +}; + +static const SFG_StrokeStrip ch45st[] = +{ + {2,ch45st0} +}; + +static const SFG_StrokeChar ch45 = {100.754,1,ch45st}; + +/* char: 0x2e */ + +static const SFG_StrokeVertex ch46st0[] = +{ + {13.1019,9.5238}, + {8.34,4.7619}, + {13.1019,0}, + {17.8638,4.7619}, + {13.1019,9.5238} +}; + +static const SFG_StrokeStrip ch46st[] = +{ + {5,ch46st0} +}; + +static const SFG_StrokeChar ch46 = {26.4838,1,ch46st}; + +/* char: 0x2f */ + +static const SFG_StrokeVertex ch47st0[] = +{ + {7.24,-14.2857}, + {73.9067,100} +}; + +static const SFG_StrokeStrip ch47st[] = +{ + {2,ch47st0} +}; + +static const SFG_StrokeChar ch47 = {82.1067,1,ch47st}; + +/* char: 0x30 */ + +static const SFG_StrokeVertex ch48st0[] = +{ + {33.5514,100}, + {19.2657,95.2381}, + {9.7419,80.9524}, + {4.98,57.1429}, + {4.98,42.8571}, + {9.7419,19.0476}, + {19.2657,4.7619}, + {33.5514,0}, + {43.0752,0}, + {57.361,4.7619}, + {66.8848,19.0476}, + {71.6467,42.8571}, + {71.6467,57.1429}, + {66.8848,80.9524}, + {57.361,95.2381}, + {43.0752,100}, + {33.5514,100} +}; + +static const SFG_StrokeStrip ch48st[] = +{ + {17,ch48st0} +}; + +static const SFG_StrokeChar ch48 = {77.0667,1,ch48st}; + +/* char: 0x31 */ + +static const SFG_StrokeVertex ch49st0[] = +{ + {11.82,80.9524}, + {21.3438,85.7143}, + {35.6295,100}, + {35.6295,0} +}; + +static const SFG_StrokeStrip ch49st[] = +{ + {4,ch49st0} +}; + +static const SFG_StrokeChar ch49 = {66.5295,1,ch49st}; + +/* char: 0x32 */ + +static const SFG_StrokeVertex ch50st0[] = +{ + {10.1819,76.1905}, + {10.1819,80.9524}, + {14.9438,90.4762}, + {19.7057,95.2381}, + {29.2295,100}, + {48.2771,100}, + {57.801,95.2381}, + {62.5629,90.4762}, + {67.3248,80.9524}, + {67.3248,71.4286}, + {62.5629,61.9048}, + {53.039,47.619}, + {5.42,0}, + {72.0867,0} +}; + +static const SFG_StrokeStrip ch50st[] = +{ + {14,ch50st0} +}; + +static const SFG_StrokeChar ch50 = {77.6467,1,ch50st}; + +/* char: 0x33 */ + +static const SFG_StrokeVertex ch51st0[] = +{ + {14.5238,100}, + {66.9048,100}, + {38.3333,61.9048}, + {52.619,61.9048}, + {62.1429,57.1429}, + {66.9048,52.381}, + {71.6667,38.0952}, + {71.6667,28.5714}, + {66.9048,14.2857}, + {57.381,4.7619}, + {43.0952,0}, + {28.8095,0}, + {14.5238,4.7619}, + {9.7619,9.5238}, + {5,19.0476} +}; + +static const SFG_StrokeStrip ch51st[] = +{ + {15,ch51st0} +}; + +static const SFG_StrokeChar ch51 = {77.0467,1,ch51st}; + +/* char: 0x34 */ + +static const SFG_StrokeVertex ch52st0[] = +{ + {51.499,100}, + {3.88,33.3333}, + {75.3086,33.3333} +}; + +static const SFG_StrokeVertex ch52st1[] = +{ + {51.499,100}, + {51.499,0} +}; + +static const SFG_StrokeStrip ch52st[] = +{ + {3,ch52st0}, + {2,ch52st1} +}; + +static const SFG_StrokeChar ch52 = {80.1686,2,ch52st}; + +/* char: 0x35 */ + +static const SFG_StrokeVertex ch53st0[] = +{ + {62.0029,100}, + {14.3838,100}, + {9.6219,57.1429}, + {14.3838,61.9048}, + {28.6695,66.6667}, + {42.9552,66.6667}, + {57.241,61.9048}, + {66.7648,52.381}, + {71.5267,38.0952}, + {71.5267,28.5714}, + {66.7648,14.2857}, + {57.241,4.7619}, + {42.9552,0}, + {28.6695,0}, + {14.3838,4.7619}, + {9.6219,9.5238}, + {4.86,19.0476} +}; + +static const SFG_StrokeStrip ch53st[] = +{ + {17,ch53st0} +}; + +static const SFG_StrokeChar ch53 = {77.6867,1,ch53st}; + +/* char: 0x36 */ + +static const SFG_StrokeVertex ch54st0[] = +{ + {62.7229,85.7143}, + {57.961,95.2381}, + {43.6752,100}, + {34.1514,100}, + {19.8657,95.2381}, + {10.3419,80.9524}, + {5.58,57.1429}, + {5.58,33.3333}, + {10.3419,14.2857}, + {19.8657,4.7619}, + {34.1514,0}, + {38.9133,0}, + {53.199,4.7619}, + {62.7229,14.2857}, + {67.4848,28.5714}, + {67.4848,33.3333}, + {62.7229,47.619}, + {53.199,57.1429}, + {38.9133,61.9048}, + {34.1514,61.9048}, + {19.8657,57.1429}, + {10.3419,47.619}, + {5.58,33.3333} +}; + +static const SFG_StrokeStrip ch54st[] = +{ + {23,ch54st0} +}; + +static const SFG_StrokeChar ch54 = {73.8048,1,ch54st}; + +/* char: 0x37 */ + +static const SFG_StrokeVertex ch55st0[] = +{ + {72.2267,100}, + {24.6076,0} +}; + +static const SFG_StrokeVertex ch55st1[] = +{ + {5.56,100}, + {72.2267,100} +}; + +static const SFG_StrokeStrip ch55st[] = +{ + {2,ch55st0}, + {2,ch55st1} +}; + +static const SFG_StrokeChar ch55 = {77.2267,2,ch55st}; + +/* char: 0x38 */ + +static const SFG_StrokeVertex ch56st0[] = +{ + {29.4095,100}, + {15.1238,95.2381}, + {10.3619,85.7143}, + {10.3619,76.1905}, + {15.1238,66.6667}, + {24.6476,61.9048}, + {43.6952,57.1429}, + {57.981,52.381}, + {67.5048,42.8571}, + {72.2667,33.3333}, + {72.2667,19.0476}, + {67.5048,9.5238}, + {62.7429,4.7619}, + {48.4571,0}, + {29.4095,0}, + {15.1238,4.7619}, + {10.3619,9.5238}, + {5.6,19.0476}, + {5.6,33.3333}, + {10.3619,42.8571}, + {19.8857,52.381}, + {34.1714,57.1429}, + {53.219,61.9048}, + {62.7429,66.6667}, + {67.5048,76.1905}, + {67.5048,85.7143}, + {62.7429,95.2381}, + {48.4571,100}, + {29.4095,100} +}; + +static const SFG_StrokeStrip ch56st[] = +{ + {29,ch56st0} +}; + +static const SFG_StrokeChar ch56 = {77.6667,1,ch56st}; + +/* char: 0x39 */ + +static const SFG_StrokeVertex ch57st0[] = +{ + {68.5048,66.6667}, + {63.7429,52.381}, + {54.219,42.8571}, + {39.9333,38.0952}, + {35.1714,38.0952}, + {20.8857,42.8571}, + {11.3619,52.381}, + {6.6,66.6667}, + {6.6,71.4286}, + {11.3619,85.7143}, + {20.8857,95.2381}, + {35.1714,100}, + {39.9333,100}, + {54.219,95.2381}, + {63.7429,85.7143}, + {68.5048,66.6667}, + {68.5048,42.8571}, + {63.7429,19.0476}, + {54.219,4.7619}, + {39.9333,0}, + {30.4095,0}, + {16.1238,4.7619}, + {11.3619,14.2857} +}; + +static const SFG_StrokeStrip ch57st[] = +{ + {23,ch57st0} +}; + +static const SFG_StrokeChar ch57 = {74.0648,1,ch57st}; + +/* char: 0x3a */ + +static const SFG_StrokeVertex ch58st0[] = +{ + {14.0819,66.6667}, + {9.32,61.9048}, + {14.0819,57.1429}, + {18.8438,61.9048}, + {14.0819,66.6667} +}; + +static const SFG_StrokeVertex ch58st1[] = +{ + {14.0819,9.5238}, + {9.32,4.7619}, + {14.0819,0}, + {18.8438,4.7619}, + {14.0819,9.5238} +}; + +static const SFG_StrokeStrip ch58st[] = +{ + {5,ch58st0}, + {5,ch58st1} +}; + +static const SFG_StrokeChar ch58 = {26.2238,2,ch58st}; + +/* char: 0x3b */ + +static const SFG_StrokeVertex ch59st0[] = +{ + {12.9619,66.6667}, + {8.2,61.9048}, + {12.9619,57.1429}, + {17.7238,61.9048}, + {12.9619,66.6667} +}; + +static const SFG_StrokeVertex ch59st1[] = +{ + {17.7238,4.7619}, + {12.9619,0}, + {8.2,4.7619}, + {12.9619,9.5238}, + {17.7238,4.7619}, + {17.7238,-4.7619}, + {12.9619,-14.2857}, + {8.2,-19.0476} +}; + +static const SFG_StrokeStrip ch59st[] = +{ + {5,ch59st0}, + {8,ch59st1} +}; + +static const SFG_StrokeChar ch59 = {26.3038,2,ch59st}; + +/* char: 0x3c */ + +static const SFG_StrokeVertex ch60st0[] = +{ + {79.2505,85.7143}, + {3.06,42.8571}, + {79.2505,0} +}; + +static const SFG_StrokeStrip ch60st[] = +{ + {3,ch60st0} +}; + +static const SFG_StrokeChar ch60 = {81.6105,1,ch60st}; + +/* char: 0x3d */ + +static const SFG_StrokeVertex ch61st0[] = +{ + {5.7,57.1429}, + {91.4143,57.1429} +}; + +static const SFG_StrokeVertex ch61st1[] = +{ + {5.7,28.5714}, + {91.4143,28.5714} +}; + +static const SFG_StrokeStrip ch61st[] = +{ + {2,ch61st0}, + {2,ch61st1} +}; + +static const SFG_StrokeChar ch61 = {97.2543,2,ch61st}; + +/* char: 0x3e */ + +static const SFG_StrokeVertex ch62st0[] = +{ + {2.78,85.7143}, + {78.9705,42.8571}, + {2.78,0} +}; + +static const SFG_StrokeStrip ch62st[] = +{ + {3,ch62st0} +}; + +static const SFG_StrokeChar ch62 = {81.6105,1,ch62st}; + +/* char: 0x3f */ + +static const SFG_StrokeVertex ch63st0[] = +{ + {8.42,76.1905}, + {8.42,80.9524}, + {13.1819,90.4762}, + {17.9438,95.2381}, + {27.4676,100}, + {46.5152,100}, + {56.039,95.2381}, + {60.801,90.4762}, + {65.5629,80.9524}, + {65.5629,71.4286}, + {60.801,61.9048}, + {56.039,57.1429}, + {36.9914,47.619}, + {36.9914,33.3333} +}; + +static const SFG_StrokeVertex ch63st1[] = +{ + {36.9914,9.5238}, + {32.2295,4.7619}, + {36.9914,0}, + {41.7533,4.7619}, + {36.9914,9.5238} +}; + +static const SFG_StrokeStrip ch63st[] = +{ + {14,ch63st0}, + {5,ch63st1} +}; + +static const SFG_StrokeChar ch63 = {73.9029,2,ch63st}; + +/* char: 0x40 */ + +static const SFG_StrokeVertex ch64st0[] = +{ + {49.2171,52.381}, + {39.6933,57.1429}, + {30.1695,57.1429}, + {25.4076,47.619}, + {25.4076,42.8571}, + {30.1695,33.3333}, + {39.6933,33.3333}, + {49.2171,38.0952} +}; + +static const SFG_StrokeVertex ch64st1[] = +{ + {49.2171,57.1429}, + {49.2171,38.0952}, + {53.979,33.3333}, + {63.5029,33.3333}, + {68.2648,42.8571}, + {68.2648,47.619}, + {63.5029,61.9048}, + {53.979,71.4286}, + {39.6933,76.1905}, + {34.9314,76.1905}, + {20.6457,71.4286}, + {11.1219,61.9048}, + {6.36,47.619}, + {6.36,42.8571}, + {11.1219,28.5714}, + {20.6457,19.0476}, + {34.9314,14.2857}, + {39.6933,14.2857}, + {53.979,19.0476} +}; + +static const SFG_StrokeStrip ch64st[] = +{ + {8,ch64st0}, + {19,ch64st1} +}; + +static const SFG_StrokeChar ch64 = {74.3648,2,ch64st}; + +/* char: 0x41 */ + +static const SFG_StrokeVertex ch65st0[] = +{ + {40.5952,100}, + {2.5,0} +}; + +static const SFG_StrokeVertex ch65st1[] = +{ + {40.5952,100}, + {78.6905,0} +}; + +static const SFG_StrokeVertex ch65st2[] = +{ + {16.7857,33.3333}, + {64.4048,33.3333} +}; + +static const SFG_StrokeStrip ch65st[] = +{ + {2,ch65st0}, + {2,ch65st1}, + {2,ch65st2} +}; + +static const SFG_StrokeChar ch65 = {80.4905,3,ch65st}; + +/* char: 0x42 */ + +static const SFG_StrokeVertex ch66st0[] = +{ + {11.42,100}, + {11.42,0} +}; + +static const SFG_StrokeVertex ch66st1[] = +{ + {11.42,100}, + {54.2771,100}, + {68.5629,95.2381}, + {73.3248,90.4762}, + {78.0867,80.9524}, + {78.0867,71.4286}, + {73.3248,61.9048}, + {68.5629,57.1429}, + {54.2771,52.381} +}; + +static const SFG_StrokeVertex ch66st2[] = +{ + {11.42,52.381}, + {54.2771,52.381}, + {68.5629,47.619}, + {73.3248,42.8571}, + {78.0867,33.3333}, + {78.0867,19.0476}, + {73.3248,9.5238}, + {68.5629,4.7619}, + {54.2771,0}, + {11.42,0} +}; + +static const SFG_StrokeStrip ch66st[] = +{ + {2,ch66st0}, + {9,ch66st1}, + {10,ch66st2} +}; + +static const SFG_StrokeChar ch66 = {83.6267,3,ch66st}; + +/* char: 0x43 */ + +static const SFG_StrokeVertex ch67st0[] = +{ + {78.0886,76.1905}, + {73.3267,85.7143}, + {63.8029,95.2381}, + {54.279,100}, + {35.2314,100}, + {25.7076,95.2381}, + {16.1838,85.7143}, + {11.4219,76.1905}, + {6.66,61.9048}, + {6.66,38.0952}, + {11.4219,23.8095}, + {16.1838,14.2857}, + {25.7076,4.7619}, + {35.2314,0}, + {54.279,0}, + {63.8029,4.7619}, + {73.3267,14.2857}, + {78.0886,23.8095} +}; + +static const SFG_StrokeStrip ch67st[] = +{ + {18,ch67st0} +}; + +static const SFG_StrokeChar ch67 = {84.4886,1,ch67st}; + +/* char: 0x44 */ + +static const SFG_StrokeVertex ch68st0[] = +{ + {11.96,100}, + {11.96,0} +}; + +static const SFG_StrokeVertex ch68st1[] = +{ + {11.96,100}, + {45.2933,100}, + {59.579,95.2381}, + {69.1029,85.7143}, + {73.8648,76.1905}, + {78.6267,61.9048}, + {78.6267,38.0952}, + {73.8648,23.8095}, + {69.1029,14.2857}, + {59.579,4.7619}, + {45.2933,0}, + {11.96,0} +}; + +static const SFG_StrokeStrip ch68st[] = +{ + {2,ch68st0}, + {12,ch68st1} +}; + +static const SFG_StrokeChar ch68 = {85.2867,2,ch68st}; + +/* char: 0x45 */ + +static const SFG_StrokeVertex ch69st0[] = +{ + {11.42,100}, + {11.42,0} +}; + +static const SFG_StrokeVertex ch69st1[] = +{ + {11.42,100}, + {73.3248,100} +}; + +static const SFG_StrokeVertex ch69st2[] = +{ + {11.42,52.381}, + {49.5152,52.381} +}; + +static const SFG_StrokeVertex ch69st3[] = +{ + {11.42,0}, + {73.3248,0} +}; + +static const SFG_StrokeStrip ch69st[] = +{ + {2,ch69st0}, + {2,ch69st1}, + {2,ch69st2}, + {2,ch69st3} +}; + +static const SFG_StrokeChar ch69 = {78.1848,4,ch69st}; + +/* char: 0x46 */ + +static const SFG_StrokeVertex ch70st0[] = +{ + {11.42,100}, + {11.42,0} +}; + +static const SFG_StrokeVertex ch70st1[] = +{ + {11.42,100}, + {73.3248,100} +}; + +static const SFG_StrokeVertex ch70st2[] = +{ + {11.42,52.381}, + {49.5152,52.381} +}; + +static const SFG_StrokeStrip ch70st[] = +{ + {2,ch70st0}, + {2,ch70st1}, + {2,ch70st2} +}; + +static const SFG_StrokeChar ch70 = {78.7448,3,ch70st}; + +/* char: 0x47 */ + +static const SFG_StrokeVertex ch71st0[] = +{ + {78.4886,76.1905}, + {73.7267,85.7143}, + {64.2029,95.2381}, + {54.679,100}, + {35.6314,100}, + {26.1076,95.2381}, + {16.5838,85.7143}, + {11.8219,76.1905}, + {7.06,61.9048}, + {7.06,38.0952}, + {11.8219,23.8095}, + {16.5838,14.2857}, + {26.1076,4.7619}, + {35.6314,0}, + {54.679,0}, + {64.2029,4.7619}, + {73.7267,14.2857}, + {78.4886,23.8095}, + {78.4886,38.0952} +}; + +static const SFG_StrokeVertex ch71st1[] = +{ + {54.679,38.0952}, + {78.4886,38.0952} +}; + +static const SFG_StrokeStrip ch71st[] = +{ + {19,ch71st0}, + {2,ch71st1} +}; + +static const SFG_StrokeChar ch71 = {89.7686,2,ch71st}; + +/* char: 0x48 */ + +static const SFG_StrokeVertex ch72st0[] = +{ + {11.42,100}, + {11.42,0} +}; + +static const SFG_StrokeVertex ch72st1[] = +{ + {78.0867,100}, + {78.0867,0} +}; + +static const SFG_StrokeVertex ch72st2[] = +{ + {11.42,52.381}, + {78.0867,52.381} +}; + +static const SFG_StrokeStrip ch72st[] = +{ + {2,ch72st0}, + {2,ch72st1}, + {2,ch72st2} +}; + +static const SFG_StrokeChar ch72 = {89.0867,3,ch72st}; + +/* char: 0x49 */ + +static const SFG_StrokeVertex ch73st0[] = +{ + {10.86,100}, + {10.86,0} +}; + +static const SFG_StrokeStrip ch73st[] = +{ + {2,ch73st0} +}; + +static const SFG_StrokeChar ch73 = {21.3,1,ch73st}; + +/* char: 0x4a */ + +static const SFG_StrokeVertex ch74st0[] = +{ + {50.119,100}, + {50.119,23.8095}, + {45.3571,9.5238}, + {40.5952,4.7619}, + {31.0714,0}, + {21.5476,0}, + {12.0238,4.7619}, + {7.2619,9.5238}, + {2.5,23.8095}, + {2.5,33.3333} +}; + +static const SFG_StrokeStrip ch74st[] = +{ + {10,ch74st0} +}; + +static const SFG_StrokeChar ch74 = {59.999,1,ch74st}; + +/* char: 0x4b */ + +static const SFG_StrokeVertex ch75st0[] = +{ + {11.28,100}, + {11.28,0} +}; + +static const SFG_StrokeVertex ch75st1[] = +{ + {77.9467,100}, + {11.28,33.3333} +}; + +static const SFG_StrokeVertex ch75st2[] = +{ + {35.0895,57.1429}, + {77.9467,0} +}; + +static const SFG_StrokeStrip ch75st[] = +{ + {2,ch75st0}, + {2,ch75st1}, + {2,ch75st2} +}; + +static const SFG_StrokeChar ch75 = {79.3267,3,ch75st}; + +/* char: 0x4c */ + +static const SFG_StrokeVertex ch76st0[] = +{ + {11.68,100}, + {11.68,0} +}; + +static const SFG_StrokeVertex ch76st1[] = +{ + {11.68,0}, + {68.8229,0} +}; + +static const SFG_StrokeStrip ch76st[] = +{ + {2,ch76st0}, + {2,ch76st1} +}; + +static const SFG_StrokeChar ch76 = {71.3229,2,ch76st}; + +/* char: 0x4d */ + +static const SFG_StrokeVertex ch77st0[] = +{ + {10.86,100}, + {10.86,0} +}; + +static const SFG_StrokeVertex ch77st1[] = +{ + {10.86,100}, + {48.9552,0} +}; + +static const SFG_StrokeVertex ch77st2[] = +{ + {87.0505,100}, + {48.9552,0} +}; + +static const SFG_StrokeVertex ch77st3[] = +{ + {87.0505,100}, + {87.0505,0} +}; + +static const SFG_StrokeStrip ch77st[] = +{ + {2,ch77st0}, + {2,ch77st1}, + {2,ch77st2}, + {2,ch77st3} +}; + +static const SFG_StrokeChar ch77 = {97.2105,4,ch77st}; + +/* char: 0x4e */ + +static const SFG_StrokeVertex ch78st0[] = +{ + {11.14,100}, + {11.14,0} +}; + +static const SFG_StrokeVertex ch78st1[] = +{ + {11.14,100}, + {77.8067,0} +}; + +static const SFG_StrokeVertex ch78st2[] = +{ + {77.8067,100}, + {77.8067,0} +}; + +static const SFG_StrokeStrip ch78st[] = +{ + {2,ch78st0}, + {2,ch78st1}, + {2,ch78st2} +}; + +static const SFG_StrokeChar ch78 = {88.8067,3,ch78st}; + +/* char: 0x4f */ + +static const SFG_StrokeVertex ch79st0[] = +{ + {34.8114,100}, + {25.2876,95.2381}, + {15.7638,85.7143}, + {11.0019,76.1905}, + {6.24,61.9048}, + {6.24,38.0952}, + {11.0019,23.8095}, + {15.7638,14.2857}, + {25.2876,4.7619}, + {34.8114,0}, + {53.859,0}, + {63.3829,4.7619}, + {72.9067,14.2857}, + {77.6686,23.8095}, + {82.4305,38.0952}, + {82.4305,61.9048}, + {77.6686,76.1905}, + {72.9067,85.7143}, + {63.3829,95.2381}, + {53.859,100}, + {34.8114,100} +}; + +static const SFG_StrokeStrip ch79st[] = +{ + {21,ch79st0} +}; + +static const SFG_StrokeChar ch79 = {88.8305,1,ch79st}; + +/* char: 0x50 */ + +static const SFG_StrokeVertex ch80st0[] = +{ + {12.1,100}, + {12.1,0} +}; + +static const SFG_StrokeVertex ch80st1[] = +{ + {12.1,100}, + {54.9571,100}, + {69.2429,95.2381}, + {74.0048,90.4762}, + {78.7667,80.9524}, + {78.7667,66.6667}, + {74.0048,57.1429}, + {69.2429,52.381}, + {54.9571,47.619}, + {12.1,47.619} +}; + +static const SFG_StrokeStrip ch80st[] = +{ + {2,ch80st0}, + {10,ch80st1} +}; + +static const SFG_StrokeChar ch80 = {85.6667,2,ch80st}; + +/* char: 0x51 */ + +static const SFG_StrokeVertex ch81st0[] = +{ + {33.8714,100}, + {24.3476,95.2381}, + {14.8238,85.7143}, + {10.0619,76.1905}, + {5.3,61.9048}, + {5.3,38.0952}, + {10.0619,23.8095}, + {14.8238,14.2857}, + {24.3476,4.7619}, + {33.8714,0}, + {52.919,0}, + {62.4429,4.7619}, + {71.9667,14.2857}, + {76.7286,23.8095}, + {81.4905,38.0952}, + {81.4905,61.9048}, + {76.7286,76.1905}, + {71.9667,85.7143}, + {62.4429,95.2381}, + {52.919,100}, + {33.8714,100} +}; + +static const SFG_StrokeVertex ch81st1[] = +{ + {48.1571,19.0476}, + {76.7286,-9.5238} +}; + +static const SFG_StrokeStrip ch81st[] = +{ + {21,ch81st0}, + {2,ch81st1} +}; + +static const SFG_StrokeChar ch81 = {88.0905,2,ch81st}; + +/* char: 0x52 */ + +static const SFG_StrokeVertex ch82st0[] = +{ + {11.68,100}, + {11.68,0} +}; + +static const SFG_StrokeVertex ch82st1[] = +{ + {11.68,100}, + {54.5371,100}, + {68.8229,95.2381}, + {73.5848,90.4762}, + {78.3467,80.9524}, + {78.3467,71.4286}, + {73.5848,61.9048}, + {68.8229,57.1429}, + {54.5371,52.381}, + {11.68,52.381} +}; + +static const SFG_StrokeVertex ch82st2[] = +{ + {45.0133,52.381}, + {78.3467,0} +}; + +static const SFG_StrokeStrip ch82st[] = +{ + {2,ch82st0}, + {10,ch82st1}, + {2,ch82st2} +}; + +static const SFG_StrokeChar ch82 = {82.3667,3,ch82st}; + +/* char: 0x53 */ + +static const SFG_StrokeVertex ch83st0[] = +{ + {74.6667,85.7143}, + {65.1429,95.2381}, + {50.8571,100}, + {31.8095,100}, + {17.5238,95.2381}, + {8,85.7143}, + {8,76.1905}, + {12.7619,66.6667}, + {17.5238,61.9048}, + {27.0476,57.1429}, + {55.619,47.619}, + {65.1429,42.8571}, + {69.9048,38.0952}, + {74.6667,28.5714}, + {74.6667,14.2857}, + {65.1429,4.7619}, + {50.8571,0}, + {31.8095,0}, + {17.5238,4.7619}, + {8,14.2857} +}; + +static const SFG_StrokeStrip ch83st[] = +{ + {20,ch83st0} +}; + +static const SFG_StrokeChar ch83 = {80.8267,1,ch83st}; + +/* char: 0x54 */ + +static const SFG_StrokeVertex ch84st0[] = +{ + {35.6933,100}, + {35.6933,0} +}; + +static const SFG_StrokeVertex ch84st1[] = +{ + {2.36,100}, + {69.0267,100} +}; + +static const SFG_StrokeStrip ch84st[] = +{ + {2,ch84st0}, + {2,ch84st1} +}; + +static const SFG_StrokeChar ch84 = {71.9467,2,ch84st}; + +/* char: 0x55 */ + +static const SFG_StrokeVertex ch85st0[] = +{ + {11.54,100}, + {11.54,28.5714}, + {16.3019,14.2857}, + {25.8257,4.7619}, + {40.1114,0}, + {49.6352,0}, + {63.921,4.7619}, + {73.4448,14.2857}, + {78.2067,28.5714}, + {78.2067,100} +}; + +static const SFG_StrokeStrip ch85st[] = +{ + {10,ch85st0} +}; + +static const SFG_StrokeChar ch85 = {89.4867,1,ch85st}; + +/* char: 0x56 */ + +static const SFG_StrokeVertex ch86st0[] = +{ + {2.36,100}, + {40.4552,0} +}; + +static const SFG_StrokeVertex ch86st1[] = +{ + {78.5505,100}, + {40.4552,0} +}; + +static const SFG_StrokeStrip ch86st[] = +{ + {2,ch86st0}, + {2,ch86st1} +}; + +static const SFG_StrokeChar ch86 = {81.6105,2,ch86st}; + +/* char: 0x57 */ + +static const SFG_StrokeVertex ch87st0[] = +{ + {2.22,100}, + {26.0295,0} +}; + +static const SFG_StrokeVertex ch87st1[] = +{ + {49.839,100}, + {26.0295,0} +}; + +static const SFG_StrokeVertex ch87st2[] = +{ + {49.839,100}, + {73.6486,0} +}; + +static const SFG_StrokeVertex ch87st3[] = +{ + {97.4581,100}, + {73.6486,0} +}; + +static const SFG_StrokeStrip ch87st[] = +{ + {2,ch87st0}, + {2,ch87st1}, + {2,ch87st2}, + {2,ch87st3} +}; + +static const SFG_StrokeChar ch87 = {100.518,4,ch87st}; + +/* char: 0x58 */ + +static const SFG_StrokeVertex ch88st0[] = +{ + {2.5,100}, + {69.1667,0} +}; + +static const SFG_StrokeVertex ch88st1[] = +{ + {69.1667,100}, + {2.5,0} +}; + +static const SFG_StrokeStrip ch88st[] = +{ + {2,ch88st0}, + {2,ch88st1} +}; + +static const SFG_StrokeChar ch88 = {72.3667,2,ch88st}; + +/* char: 0x59 */ + +static const SFG_StrokeVertex ch89st0[] = +{ + {1.52,100}, + {39.6152,52.381}, + {39.6152,0} +}; + +static const SFG_StrokeVertex ch89st1[] = +{ + {77.7105,100}, + {39.6152,52.381} +}; + +static const SFG_StrokeStrip ch89st[] = +{ + {3,ch89st0}, + {2,ch89st1} +}; + +static const SFG_StrokeChar ch89 = {79.6505,2,ch89st}; + +/* char: 0x5a */ + +static const SFG_StrokeVertex ch90st0[] = +{ + {69.1667,100}, + {2.5,0} +}; + +static const SFG_StrokeVertex ch90st1[] = +{ + {2.5,100}, + {69.1667,100} +}; + +static const SFG_StrokeVertex ch90st2[] = +{ + {2.5,0}, + {69.1667,0} +}; + +static const SFG_StrokeStrip ch90st[] = +{ + {2,ch90st0}, + {2,ch90st1}, + {2,ch90st2} +}; + +static const SFG_StrokeChar ch90 = {73.7467,3,ch90st}; + +/* char: 0x5b */ + +static const SFG_StrokeVertex ch91st0[] = +{ + {7.78,119.048}, + {7.78,-33.3333} +}; + +static const SFG_StrokeVertex ch91st1[] = +{ + {12.5419,119.048}, + {12.5419,-33.3333} +}; + +static const SFG_StrokeVertex ch91st2[] = +{ + {7.78,119.048}, + {41.1133,119.048} +}; + +static const SFG_StrokeVertex ch91st3[] = +{ + {7.78,-33.3333}, + {41.1133,-33.3333} +}; + +static const SFG_StrokeStrip ch91st[] = +{ + {2,ch91st0}, + {2,ch91st1}, + {2,ch91st2}, + {2,ch91st3} +}; + +static const SFG_StrokeChar ch91 = {46.1133,4,ch91st}; + +/* char: 0x5c */ + +static const SFG_StrokeVertex ch92st0[] = +{ + {5.84,100}, + {72.5067,-14.2857} +}; + +static const SFG_StrokeStrip ch92st[] = +{ + {2,ch92st0} +}; + +static const SFG_StrokeChar ch92 = {78.2067,1,ch92st}; + +/* char: 0x5d */ + +static const SFG_StrokeVertex ch93st0[] = +{ + {33.0114,119.048}, + {33.0114,-33.3333} +}; + +static const SFG_StrokeVertex ch93st1[] = +{ + {37.7733,119.048}, + {37.7733,-33.3333} +}; + +static const SFG_StrokeVertex ch93st2[] = +{ + {4.44,119.048}, + {37.7733,119.048} +}; + +static const SFG_StrokeVertex ch93st3[] = +{ + {4.44,-33.3333}, + {37.7733,-33.3333} +}; + +static const SFG_StrokeStrip ch93st[] = +{ + {2,ch93st0}, + {2,ch93st1}, + {2,ch93st2}, + {2,ch93st3} +}; + +static const SFG_StrokeChar ch93 = {46.3933,4,ch93st}; + +/* char: 0x5e */ + +static const SFG_StrokeVertex ch94st0[] = +{ + {44.0752,109.524}, + {5.98,42.8571} +}; + +static const SFG_StrokeVertex ch94st1[] = +{ + {44.0752,109.524}, + {82.1705,42.8571} +}; + +static const SFG_StrokeStrip ch94st[] = +{ + {2,ch94st0}, + {2,ch94st1} +}; + +static const SFG_StrokeChar ch94 = {90.2305,2,ch94st}; + +/* char: 0x5f */ + +static const SFG_StrokeVertex ch95st0[] = +{ + {-1.1,-33.3333}, + {103.662,-33.3333}, + {103.662,-28.5714}, + {-1.1,-28.5714}, + {-1.1,-33.3333} +}; + +static const SFG_StrokeStrip ch95st[] = +{ + {5,ch95st0} +}; + +static const SFG_StrokeChar ch95 = {104.062,1,ch95st}; + +/* char: 0x60 */ + +static const SFG_StrokeVertex ch96st0[] = +{ + {33.0219,100}, + {56.8314,71.4286} +}; + +static const SFG_StrokeVertex ch96st1[] = +{ + {33.0219,100}, + {28.26,95.2381}, + {56.8314,71.4286} +}; + +static const SFG_StrokeStrip ch96st[] = +{ + {2,ch96st0}, + {3,ch96st1} +}; + +static const SFG_StrokeChar ch96 = {83.5714,2,ch96st}; + +/* char: 0x61 */ + +static const SFG_StrokeVertex ch97st0[] = +{ + {63.8229,66.6667}, + {63.8229,0} +}; + +static const SFG_StrokeVertex ch97st1[] = +{ + {63.8229,52.381}, + {54.299,61.9048}, + {44.7752,66.6667}, + {30.4895,66.6667}, + {20.9657,61.9048}, + {11.4419,52.381}, + {6.68,38.0952}, + {6.68,28.5714}, + {11.4419,14.2857}, + {20.9657,4.7619}, + {30.4895,0}, + {44.7752,0}, + {54.299,4.7619}, + {63.8229,14.2857} +}; + +static const SFG_StrokeStrip ch97st[] = +{ + {2,ch97st0}, + {14,ch97st1} +}; + +static const SFG_StrokeChar ch97 = {66.6029,2,ch97st}; + +/* char: 0x62 */ + +static const SFG_StrokeVertex ch98st0[] = +{ + {8.76,100}, + {8.76,0} +}; + +static const SFG_StrokeVertex ch98st1[] = +{ + {8.76,52.381}, + {18.2838,61.9048}, + {27.8076,66.6667}, + {42.0933,66.6667}, + {51.6171,61.9048}, + {61.141,52.381}, + {65.9029,38.0952}, + {65.9029,28.5714}, + {61.141,14.2857}, + {51.6171,4.7619}, + {42.0933,0}, + {27.8076,0}, + {18.2838,4.7619}, + {8.76,14.2857} +}; + +static const SFG_StrokeStrip ch98st[] = +{ + {2,ch98st0}, + {14,ch98st1} +}; + +static const SFG_StrokeChar ch98 = {70.4629,2,ch98st}; + +/* char: 0x63 */ + +static const SFG_StrokeVertex ch99st0[] = +{ + {62.6629,52.381}, + {53.139,61.9048}, + {43.6152,66.6667}, + {29.3295,66.6667}, + {19.8057,61.9048}, + {10.2819,52.381}, + {5.52,38.0952}, + {5.52,28.5714}, + {10.2819,14.2857}, + {19.8057,4.7619}, + {29.3295,0}, + {43.6152,0}, + {53.139,4.7619}, + {62.6629,14.2857} +}; + +static const SFG_StrokeStrip ch99st[] = +{ + {14,ch99st0} +}; + +static const SFG_StrokeChar ch99 = {68.9229,1,ch99st}; + +/* char: 0x64 */ + +static const SFG_StrokeVertex ch100st0[] = +{ + {61.7829,100}, + {61.7829,0} +}; + +static const SFG_StrokeVertex ch100st1[] = +{ + {61.7829,52.381}, + {52.259,61.9048}, + {42.7352,66.6667}, + {28.4495,66.6667}, + {18.9257,61.9048}, + {9.4019,52.381}, + {4.64,38.0952}, + {4.64,28.5714}, + {9.4019,14.2857}, + {18.9257,4.7619}, + {28.4495,0}, + {42.7352,0}, + {52.259,4.7619}, + {61.7829,14.2857} +}; + +static const SFG_StrokeStrip ch100st[] = +{ + {2,ch100st0}, + {14,ch100st1} +}; + +static const SFG_StrokeChar ch100 = {70.2629,2,ch100st}; + +/* char: 0x65 */ + +static const SFG_StrokeVertex ch101st0[] = +{ + {5.72,38.0952}, + {62.8629,38.0952}, + {62.8629,47.619}, + {58.101,57.1429}, + {53.339,61.9048}, + {43.8152,66.6667}, + {29.5295,66.6667}, + {20.0057,61.9048}, + {10.4819,52.381}, + {5.72,38.0952}, + {5.72,28.5714}, + {10.4819,14.2857}, + {20.0057,4.7619}, + {29.5295,0}, + {43.8152,0}, + {53.339,4.7619}, + {62.8629,14.2857} +}; + +static const SFG_StrokeStrip ch101st[] = +{ + {17,ch101st0} +}; + +static const SFG_StrokeChar ch101 = {68.5229,1,ch101st}; + +/* char: 0x66 */ + +static const SFG_StrokeVertex ch102st0[] = +{ + {38.7752,100}, + {29.2514,100}, + {19.7276,95.2381}, + {14.9657,80.9524}, + {14.9657,0} +}; + +static const SFG_StrokeVertex ch102st1[] = +{ + {0.68,66.6667}, + {34.0133,66.6667} +}; + +static const SFG_StrokeStrip ch102st[] = +{ + {5,ch102st0}, + {2,ch102st1} +}; + +static const SFG_StrokeChar ch102 = {38.6552,2,ch102st}; + +/* char: 0x67 */ + +static const SFG_StrokeVertex ch103st0[] = +{ + {62.5029,66.6667}, + {62.5029,-9.5238}, + {57.741,-23.8095}, + {52.979,-28.5714}, + {43.4552,-33.3333}, + {29.1695,-33.3333}, + {19.6457,-28.5714} +}; + +static const SFG_StrokeVertex ch103st1[] = +{ + {62.5029,52.381}, + {52.979,61.9048}, + {43.4552,66.6667}, + {29.1695,66.6667}, + {19.6457,61.9048}, + {10.1219,52.381}, + {5.36,38.0952}, + {5.36,28.5714}, + {10.1219,14.2857}, + {19.6457,4.7619}, + {29.1695,0}, + {43.4552,0}, + {52.979,4.7619}, + {62.5029,14.2857} +}; + +static const SFG_StrokeStrip ch103st[] = +{ + {7,ch103st0}, + {14,ch103st1} +}; + +static const SFG_StrokeChar ch103 = {70.9829,2,ch103st}; + +/* char: 0x68 */ + +static const SFG_StrokeVertex ch104st0[] = +{ + {9.6,100}, + {9.6,0} +}; + +static const SFG_StrokeVertex ch104st1[] = +{ + {9.6,47.619}, + {23.8857,61.9048}, + {33.4095,66.6667}, + {47.6952,66.6667}, + {57.219,61.9048}, + {61.981,47.619}, + {61.981,0} +}; + +static const SFG_StrokeStrip ch104st[] = +{ + {2,ch104st0}, + {7,ch104st1} +}; + +static const SFG_StrokeChar ch104 = {71.021,2,ch104st}; + +/* char: 0x69 */ + +static const SFG_StrokeVertex ch105st0[] = +{ + {10.02,100}, + {14.7819,95.2381}, + {19.5438,100}, + {14.7819,104.762}, + {10.02,100} +}; + +static const SFG_StrokeVertex ch105st1[] = +{ + {14.7819,66.6667}, + {14.7819,0} +}; + +static const SFG_StrokeStrip ch105st[] = +{ + {5,ch105st0}, + {2,ch105st1} +}; + +static const SFG_StrokeChar ch105 = {28.8638,2,ch105st}; + +/* char: 0x6a */ + +static const SFG_StrokeVertex ch106st0[] = +{ + {17.3876,100}, + {22.1495,95.2381}, + {26.9114,100}, + {22.1495,104.762}, + {17.3876,100} +}; + +static const SFG_StrokeVertex ch106st1[] = +{ + {22.1495,66.6667}, + {22.1495,-14.2857}, + {17.3876,-28.5714}, + {7.8638,-33.3333}, + {-1.66,-33.3333} +}; + +static const SFG_StrokeStrip ch106st[] = +{ + {5,ch106st0}, + {5,ch106st1} +}; + +static const SFG_StrokeChar ch106 = {36.2314,2,ch106st}; + +/* char: 0x6b */ + +static const SFG_StrokeVertex ch107st0[] = +{ + {9.6,100}, + {9.6,0} +}; + +static const SFG_StrokeVertex ch107st1[] = +{ + {57.219,66.6667}, + {9.6,19.0476} +}; + +static const SFG_StrokeVertex ch107st2[] = +{ + {28.6476,38.0952}, + {61.981,0} +}; + +static const SFG_StrokeStrip ch107st[] = +{ + {2,ch107st0}, + {2,ch107st1}, + {2,ch107st2} +}; + +static const SFG_StrokeChar ch107 = {62.521,3,ch107st}; + +/* char: 0x6c */ + +static const SFG_StrokeVertex ch108st0[] = +{ + {10.02,100}, + {10.02,0} +}; + +static const SFG_StrokeStrip ch108st[] = +{ + {2,ch108st0} +}; + +static const SFG_StrokeChar ch108 = {19.34,1,ch108st}; + +/* char: 0x6d */ + +static const SFG_StrokeVertex ch109st0[] = +{ + {9.6,66.6667}, + {9.6,0} +}; + +static const SFG_StrokeVertex ch109st1[] = +{ + {9.6,47.619}, + {23.8857,61.9048}, + {33.4095,66.6667}, + {47.6952,66.6667}, + {57.219,61.9048}, + {61.981,47.619}, + {61.981,0} +}; + +static const SFG_StrokeVertex ch109st2[] = +{ + {61.981,47.619}, + {76.2667,61.9048}, + {85.7905,66.6667}, + {100.076,66.6667}, + {109.6,61.9048}, + {114.362,47.619}, + {114.362,0} +}; + +static const SFG_StrokeStrip ch109st[] = +{ + {2,ch109st0}, + {7,ch109st1}, + {7,ch109st2} +}; + +static const SFG_StrokeChar ch109 = {123.962,3,ch109st}; + +/* char: 0x6e */ + +static const SFG_StrokeVertex ch110st0[] = +{ + {9.18,66.6667}, + {9.18,0} +}; + +static const SFG_StrokeVertex ch110st1[] = +{ + {9.18,47.619}, + {23.4657,61.9048}, + {32.9895,66.6667}, + {47.2752,66.6667}, + {56.799,61.9048}, + {61.561,47.619}, + {61.561,0} +}; + +static const SFG_StrokeStrip ch110st[] = +{ + {2,ch110st0}, + {7,ch110st1} +}; + +static const SFG_StrokeChar ch110 = {70.881,2,ch110st}; + +/* char: 0x6f */ + +static const SFG_StrokeVertex ch111st0[] = +{ + {28.7895,66.6667}, + {19.2657,61.9048}, + {9.7419,52.381}, + {4.98,38.0952}, + {4.98,28.5714}, + {9.7419,14.2857}, + {19.2657,4.7619}, + {28.7895,0}, + {43.0752,0}, + {52.599,4.7619}, + {62.1229,14.2857}, + {66.8848,28.5714}, + {66.8848,38.0952}, + {62.1229,52.381}, + {52.599,61.9048}, + {43.0752,66.6667}, + {28.7895,66.6667} +}; + +static const SFG_StrokeStrip ch111st[] = +{ + {17,ch111st0} +}; + +static const SFG_StrokeChar ch111 = {71.7448,1,ch111st}; + +/* char: 0x70 */ + +static const SFG_StrokeVertex ch112st0[] = +{ + {9.46,66.6667}, + {9.46,-33.3333} +}; + +static const SFG_StrokeVertex ch112st1[] = +{ + {9.46,52.381}, + {18.9838,61.9048}, + {28.5076,66.6667}, + {42.7933,66.6667}, + {52.3171,61.9048}, + {61.841,52.381}, + {66.6029,38.0952}, + {66.6029,28.5714}, + {61.841,14.2857}, + {52.3171,4.7619}, + {42.7933,0}, + {28.5076,0}, + {18.9838,4.7619}, + {9.46,14.2857} +}; + +static const SFG_StrokeStrip ch112st[] = +{ + {2,ch112st0}, + {14,ch112st1} +}; + +static const SFG_StrokeChar ch112 = {70.8029,2,ch112st}; + +/* char: 0x71 */ + +static const SFG_StrokeVertex ch113st0[] = +{ + {61.9829,66.6667}, + {61.9829,-33.3333} +}; + +static const SFG_StrokeVertex ch113st1[] = +{ + {61.9829,52.381}, + {52.459,61.9048}, + {42.9352,66.6667}, + {28.6495,66.6667}, + {19.1257,61.9048}, + {9.6019,52.381}, + {4.84,38.0952}, + {4.84,28.5714}, + {9.6019,14.2857}, + {19.1257,4.7619}, + {28.6495,0}, + {42.9352,0}, + {52.459,4.7619}, + {61.9829,14.2857} +}; + +static const SFG_StrokeStrip ch113st[] = +{ + {2,ch113st0}, + {14,ch113st1} +}; + +static const SFG_StrokeChar ch113 = {70.7429,2,ch113st}; + +/* char: 0x72 */ + +static const SFG_StrokeVertex ch114st0[] = +{ + {9.46,66.6667}, + {9.46,0} +}; + +static const SFG_StrokeVertex ch114st1[] = +{ + {9.46,38.0952}, + {14.2219,52.381}, + {23.7457,61.9048}, + {33.2695,66.6667}, + {47.5552,66.6667} +}; + +static const SFG_StrokeStrip ch114st[] = +{ + {2,ch114st0}, + {5,ch114st1} +}; + +static const SFG_StrokeChar ch114 = {49.4952,2,ch114st}; + +/* char: 0x73 */ + +static const SFG_StrokeVertex ch115st0[] = +{ + {57.081,52.381}, + {52.319,61.9048}, + {38.0333,66.6667}, + {23.7476,66.6667}, + {9.4619,61.9048}, + {4.7,52.381}, + {9.4619,42.8571}, + {18.9857,38.0952}, + {42.7952,33.3333}, + {52.319,28.5714}, + {57.081,19.0476}, + {57.081,14.2857}, + {52.319,4.7619}, + {38.0333,0}, + {23.7476,0}, + {9.4619,4.7619}, + {4.7,14.2857} +}; + +static const SFG_StrokeStrip ch115st[] = +{ + {17,ch115st0} +}; + +static const SFG_StrokeChar ch115 = {62.321,1,ch115st}; + +/* char: 0x74 */ + +static const SFG_StrokeVertex ch116st0[] = +{ + {14.8257,100}, + {14.8257,19.0476}, + {19.5876,4.7619}, + {29.1114,0}, + {38.6352,0} +}; + +static const SFG_StrokeVertex ch116st1[] = +{ + {0.54,66.6667}, + {33.8733,66.6667} +}; + +static const SFG_StrokeStrip ch116st[] = +{ + {5,ch116st0}, + {2,ch116st1} +}; + +static const SFG_StrokeChar ch116 = {39.3152,2,ch116st}; + +/* char: 0x75 */ + +static const SFG_StrokeVertex ch117st0[] = +{ + {9.46,66.6667}, + {9.46,19.0476}, + {14.2219,4.7619}, + {23.7457,0}, + {38.0314,0}, + {47.5552,4.7619}, + {61.841,19.0476} +}; + +static const SFG_StrokeVertex ch117st1[] = +{ + {61.841,66.6667}, + {61.841,0} +}; + +static const SFG_StrokeStrip ch117st[] = +{ + {7,ch117st0}, + {2,ch117st1} +}; + +static const SFG_StrokeChar ch117 = {71.161,2,ch117st}; + +/* char: 0x76 */ + +static const SFG_StrokeVertex ch118st0[] = +{ + {1.8,66.6667}, + {30.3714,0} +}; + +static const SFG_StrokeVertex ch118st1[] = +{ + {58.9429,66.6667}, + {30.3714,0} +}; + +static const SFG_StrokeStrip ch118st[] = +{ + {2,ch118st0}, + {2,ch118st1} +}; + +static const SFG_StrokeChar ch118 = {60.6029,2,ch118st}; + +/* char: 0x77 */ + +static const SFG_StrokeVertex ch119st0[] = +{ + {2.5,66.6667}, + {21.5476,0} +}; + +static const SFG_StrokeVertex ch119st1[] = +{ + {40.5952,66.6667}, + {21.5476,0} +}; + +static const SFG_StrokeVertex ch119st2[] = +{ + {40.5952,66.6667}, + {59.6429,0} +}; + +static const SFG_StrokeVertex ch119st3[] = +{ + {78.6905,66.6667}, + {59.6429,0} +}; + +static const SFG_StrokeStrip ch119st[] = +{ + {2,ch119st0}, + {2,ch119st1}, + {2,ch119st2}, + {2,ch119st3} +}; + +static const SFG_StrokeChar ch119 = {80.4905,4,ch119st}; + +/* char: 0x78 */ + +static const SFG_StrokeVertex ch120st0[] = +{ + {1.66,66.6667}, + {54.041,0} +}; + +static const SFG_StrokeVertex ch120st1[] = +{ + {54.041,66.6667}, + {1.66,0} +}; + +static const SFG_StrokeStrip ch120st[] = +{ + {2,ch120st0}, + {2,ch120st1} +}; + +static const SFG_StrokeChar ch120 = {56.401,2,ch120st}; + +/* char: 0x79 */ + +static const SFG_StrokeVertex ch121st0[] = +{ + {6.5619,66.6667}, + {35.1333,0} +}; + +static const SFG_StrokeVertex ch121st1[] = +{ + {63.7048,66.6667}, + {35.1333,0}, + {25.6095,-19.0476}, + {16.0857,-28.5714}, + {6.5619,-33.3333}, + {1.8,-33.3333} +}; + +static const SFG_StrokeStrip ch121st[] = +{ + {2,ch121st0}, + {6,ch121st1} +}; + +static const SFG_StrokeChar ch121 = {66.0648,2,ch121st}; + +/* char: 0x7a */ + +static const SFG_StrokeVertex ch122st0[] = +{ + {56.821,66.6667}, + {4.44,0} +}; + +static const SFG_StrokeVertex ch122st1[] = +{ + {4.44,66.6667}, + {56.821,66.6667} +}; + +static const SFG_StrokeVertex ch122st2[] = +{ + {4.44,0}, + {56.821,0} +}; + +static const SFG_StrokeStrip ch122st[] = +{ + {2,ch122st0}, + {2,ch122st1}, + {2,ch122st2} +}; + +static const SFG_StrokeChar ch122 = {61.821,3,ch122st}; + +/* char: 0x7b */ + +static const SFG_StrokeVertex ch123st0[] = +{ + {31.1895,119.048}, + {21.6657,114.286}, + {16.9038,109.524}, + {12.1419,100}, + {12.1419,90.4762}, + {16.9038,80.9524}, + {21.6657,76.1905}, + {26.4276,66.6667}, + {26.4276,57.1429}, + {16.9038,47.619} +}; + +static const SFG_StrokeVertex ch123st1[] = +{ + {21.6657,114.286}, + {16.9038,104.762}, + {16.9038,95.2381}, + {21.6657,85.7143}, + {26.4276,80.9524}, + {31.1895,71.4286}, + {31.1895,61.9048}, + {26.4276,52.381}, + {7.38,42.8571}, + {26.4276,33.3333}, + {31.1895,23.8095}, + {31.1895,14.2857}, + {26.4276,4.7619}, + {21.6657,0}, + {16.9038,-9.5238}, + {16.9038,-19.0476}, + {21.6657,-28.5714} +}; + +static const SFG_StrokeVertex ch123st2[] = +{ + {16.9038,38.0952}, + {26.4276,28.5714}, + {26.4276,19.0476}, + {21.6657,9.5238}, + {16.9038,4.7619}, + {12.1419,-4.7619}, + {12.1419,-14.2857}, + {16.9038,-23.8095}, + {21.6657,-28.5714}, + {31.1895,-33.3333} +}; + +static const SFG_StrokeStrip ch123st[] = +{ + {10,ch123st0}, + {17,ch123st1}, + {10,ch123st2} +}; + +static const SFG_StrokeChar ch123 = {41.6295,3,ch123st}; + +/* char: 0x7c */ + +static const SFG_StrokeVertex ch124st0[] = +{ + {11.54,119.048}, + {11.54,-33.3333} +}; + +static const SFG_StrokeStrip ch124st[] = +{ + {2,ch124st0} +}; + +static const SFG_StrokeChar ch124 = {23.78,1,ch124st}; + +/* char: 0x7d */ + +static const SFG_StrokeVertex ch125st0[] = +{ + {9.18,119.048}, + {18.7038,114.286}, + {23.4657,109.524}, + {28.2276,100}, + {28.2276,90.4762}, + {23.4657,80.9524}, + {18.7038,76.1905}, + {13.9419,66.6667}, + {13.9419,57.1429}, + {23.4657,47.619} +}; + +static const SFG_StrokeVertex ch125st1[] = +{ + {18.7038,114.286}, + {23.4657,104.762}, + {23.4657,95.2381}, + {18.7038,85.7143}, + {13.9419,80.9524}, + {9.18,71.4286}, + {9.18,61.9048}, + {13.9419,52.381}, + {32.9895,42.8571}, + {13.9419,33.3333}, + {9.18,23.8095}, + {9.18,14.2857}, + {13.9419,4.7619}, + {18.7038,0}, + {23.4657,-9.5238}, + {23.4657,-19.0476}, + {18.7038,-28.5714} +}; + +static const SFG_StrokeVertex ch125st2[] = +{ + {23.4657,38.0952}, + {13.9419,28.5714}, + {13.9419,19.0476}, + {18.7038,9.5238}, + {23.4657,4.7619}, + {28.2276,-4.7619}, + {28.2276,-14.2857}, + {23.4657,-23.8095}, + {18.7038,-28.5714}, + {9.18,-33.3333} +}; + +static const SFG_StrokeStrip ch125st[] = +{ + {10,ch125st0}, + {17,ch125st1}, + {10,ch125st2} +}; + +static const SFG_StrokeChar ch125 = {41.4695,3,ch125st}; + +/* char: 0x7e */ + +static const SFG_StrokeVertex ch126st0[] = +{ + {2.92,28.5714}, + {2.92,38.0952}, + {7.6819,52.381}, + {17.2057,57.1429}, + {26.7295,57.1429}, + {36.2533,52.381}, + {55.301,38.0952}, + {64.8248,33.3333}, + {74.3486,33.3333}, + {83.8724,38.0952}, + {88.6343,47.619} +}; + +static const SFG_StrokeVertex ch126st1[] = +{ + {2.92,38.0952}, + {7.6819,47.619}, + {17.2057,52.381}, + {26.7295,52.381}, + {36.2533,47.619}, + {55.301,33.3333}, + {64.8248,28.5714}, + {74.3486,28.5714}, + {83.8724,33.3333}, + {88.6343,47.619}, + {88.6343,57.1429} +}; + +static const SFG_StrokeStrip ch126st[] = +{ + {11,ch126st0}, + {11,ch126st1} +}; + +static const SFG_StrokeChar ch126 = {91.2743,2,ch126st}; + +/* char: 0x7f */ + +static const SFG_StrokeVertex ch127st0[] = +{ + {52.381,100}, + {14.2857,-33.3333} +}; + +static const SFG_StrokeVertex ch127st1[] = +{ + {28.5714,66.6667}, + {14.2857,61.9048}, + {4.7619,52.381}, + {0,38.0952}, + {0,23.8095}, + {4.7619,14.2857}, + {14.2857,4.7619}, + {28.5714,0}, + {38.0952,0}, + {52.381,4.7619}, + {61.9048,14.2857}, + {66.6667,28.5714}, + {66.6667,42.8571}, + {61.9048,52.381}, + {52.381,61.9048}, + {38.0952,66.6667}, + {28.5714,66.6667} +}; + +static const SFG_StrokeStrip ch127st[] = +{ + {2,ch127st0}, + {17,ch127st1} +}; + +static const SFG_StrokeChar ch127 = {66.6667,2,ch127st}; + +static const SFG_StrokeChar *chars[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39, + &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47, + &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55, + &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63, + &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71, + &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79, + &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87, + &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95, + &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103, + &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111, + &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119, + &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127 +}; + +const SFG_StrokeFont fgStrokeRoman = {"Roman",128,152.381,chars}; diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c new file mode 100644 index 0000000..6b54d50 --- /dev/null +++ b/src/freeglut_structure.c @@ -0,0 +1,721 @@ +/* + * freeglut_structure.c + * + * Windows and menus need tree structure + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Sat Dec 18 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-structure" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + + +/* -- GLOBAL EXPORTS ------------------------------------------------------- */ + +/* + * The SFG_Structure container holds information about windows and menus + * created between glutInit() and glutMainLoop() return. + */ +SFG_Structure fgStructure; + + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * This private function creates, opens and adds to the hierarchy + * a freeglut window complete with OpenGL context and stuff... + * + * If parent is set to NULL, the window created will be a topmost one. + */ +SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, int w, int h, GLboolean gameMode ) +{ + /* + * Have the window object created + */ + SFG_Window* window = calloc( sizeof(SFG_Window), 1 ); + int fakeArgc = 0; + + /* + * If the freeglut internals haven't been initialized yet, + * do it now. Hack's idea courtesy of Chris Purnell... + */ + if( !fgState.Time.Set ) + glutInit( &fakeArgc, NULL ); + + /* + * Initialize the object properties + */ + window->ID = ++fgStructure.WindowID; + + /* + * Initialize the children list + */ + fgListInit( &window->Children ); + + /* + * Does this window have a parent? + */ + if( parent != NULL ) + { + /* + * That's quite right, attach this windows as a child window + */ + fgListAppend( &parent->Children, &window->Node ); + window->Parent = parent; + } + else + { + /* + * Otherwise add the newly created window to the topmost windows list + */ + fgListAppend( &fgStructure.Windows, &window->Node ); + } + + /* + * Set the default mouse cursor and reset the modifiers value + */ + window->State.Cursor = GLUT_CURSOR_INHERIT; + window->State.Modifiers = 0xffffffff; + + /* + * Open the window now. The fgOpenWindow() function is system + * dependant, and resides in freeglut_window.c. Uses fgState. + */ + fgOpenWindow( window, title, x, y, w, h, gameMode, (parent != NULL) ? TRUE : FALSE ); + + /* + * Return a pointer to the newly created window + */ + return( window ); +} + +/* + * This private function creates a menu and adds it to the menus list + */ +SFG_Menu* fgCreateMenu( FGCBmenu menuCallback ) +{ + /* + * Have the menu object created + */ + SFG_Menu* menu = calloc( sizeof(SFG_Menu), 1 ); + int fakeArgc = 0; + + /* + * If the freeglut internals haven't been initialized yet, + * do it now. Hack's idea courtesy of Chris Purnell... + */ + if( !fgState.Time.Set ) + glutInit( &fakeArgc, NULL ); + + /* + * Initialize the object properties: + */ + menu->ID = ++fgStructure.MenuID; + menu->Callback = menuCallback; + + /* + * Initialize the entries list + */ + fgListInit( &menu->Entries ); + + /* + * Add it to the menu structure hierarchy + */ + fgListAppend( &fgStructure.Menus, &menu->Node ); + + /* + * Newly created menus implicitly become current ones + */ + fgStructure.Menu = menu; + + /* + * Return the result to the caller + */ + return( menu ); +} + +/* + * Linked list of windows to destroy ... this is so we don't destroy a window from the middle of + * its callback. Some C compilers take an extremely dim view of this. + */ + +static SFG_WindowList* WindowsToDestroy = (SFG_WindowList*)NULL ; + +/* + * Function to add a window to the linked list of windows to destroy. Subwindows are automatically + * added because they hang from the window structure. + */ +void fgAddToWindowDestroyList ( SFG_Window* window, GLboolean needToClose ) +{ + SFG_WindowList *new_list_entry = (SFG_WindowList*)malloc ( sizeof(SFG_WindowList) ) ; + new_list_entry->window = window ; + new_list_entry->needToClose = needToClose ; + new_list_entry->next = WindowsToDestroy ; + WindowsToDestroy = new_list_entry ; + + /* + * Check if the window is the current one... + */ + if ( fgStructure.Window == window ) + fgStructure.Window = NULL; + + /* + * If the destroyed window has the highest window ID number, decrement the window ID number + */ + if ( window->ID == fgStructure.WindowID ) fgStructure.WindowID-- ; + + /* + * Check the execution state. If this has been called from "glutDestroyWindow", + * a statement in that function will reset the "ExecState" after this function returns. + */ + if ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION ) + { + /* + * Set the execution state flag to drop out of the main loop. + */ + if ( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT ) + fgState.ExecState = GLUT_EXEC_STATE_STOP ; + } +} + +/* + * Function to close down all the windows in the "WindowsToDestroy" list + */ +void fgCloseWindows () +{ + SFG_WindowList *window_ptr = WindowsToDestroy ; + WindowsToDestroy = (SFG_WindowList*)NULL ; /* In case the destroy callbacks cause more windows to be closed */ + + while ( window_ptr ) + { + SFG_WindowList *next = window_ptr->next ; + fgDestroyWindow ( window_ptr->window, window_ptr->needToClose ) ; + free ( window_ptr ) ; + window_ptr = next ; + + if ( !window_ptr ) + { + window_ptr = WindowsToDestroy ; + WindowsToDestroy = (SFG_WindowList*)NULL ; + } + } +} + +/* + * This function destroys a window and all of its subwindows. Actually, + * another function, defined in freeglut_window.c is called, but this is + * a whole different story... + */ +void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) +{ + SFG_Window* subWindow; + + assert( window != NULL ); + freeglut_assert_ready; + + /* + * Does this window have any subwindows? + */ + while ( (subWindow = window->Children.First) != NULL ) + { + /* + * Destroy the first window in the list (possibly destroying + * its subwindows too). This is not very effective, but works + */ + fgDestroyWindow( subWindow, needToClose ); + } + + /* + * If the programmer defined a destroy callback, call it + * A. Donev: But first make this the active window + */ + if ( window->Callbacks.Destroy != NULL ) + { + SFG_Window *activeWindow = fgStructure.Window ; + fgStructure.Window = window ; + window->Callbacks.Destroy () ; + fgStructure.Window = activeWindow ; + } + + /* + * Now we should remove the reference to this window from its parent + */ + if ( window->Parent != NULL ) + fgListRemove( &window->Parent->Children, &window->Node ); + else + fgListRemove( &fgStructure.Windows, &window->Node ); + + /* + * OK, this window seems disconnected from the structure enough + * in order to be closed without any bigger risks... + */ + if( needToClose == TRUE ) + fgCloseWindow( window ); + + /* + * Finally, we can delete the window's object. It hopefully does + * have everything inside it freed and we do not have to care... + */ + free( window ); +} + +/* + * This is a helper static function that removes a menu (given its pointer) + * from any windows that can be accessed from a given parent... + */ +static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu ) +{ + SFG_Window *subWindow; + int i; + + /* + * Check if the menu is attached to the current window, + * if so, have it detached (by overwriting with a NULL): + */ + for( i=0; i<3; i++ ) + { + if( window->Menu[ i ] == menu ) + window->Menu[ i ] = NULL; + } + + /* + * Call this function for all of the window's children recursively: + */ + for( subWindow = window->Children.First; subWindow; + subWindow = subWindow->Node.Next) + { + fghRemoveMenuFromWindow( subWindow, menu ); + } +} + +/* + * This is a static helper function that removes menu references + * from another menu, given two pointers to them... + */ +static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu ) +{ + SFG_MenuEntry *entry; + + for( entry = from->Entries.First; entry; entry = entry->Node.Next ) + { + if (entry->SubMenu == menu) + { + entry->SubMenu = NULL; + } + } +} + +/* + * This function destroys a menu specified by the parameter. All menus + * and windows are updated to make sure no ill pointers hang around. + */ +void fgDestroyMenu( SFG_Menu* menu ) +{ + SFG_Window *window; + SFG_Menu *from; + SFG_MenuEntry *entry; + + assert( menu != NULL ); + freeglut_assert_ready; + + /* + * First of all, have all references to this menu removed from all windows: + */ + for( window = fgStructure.Windows.First; window; window = window->Node.Next ) + { + fghRemoveMenuFromWindow( window, menu ); + } + + /* + * Now proceed with removing menu entries that lead to this menu + */ + for( from = fgStructure.Menus.First; from; from = from->Node.Next ) + { + fghRemoveMenuFromMenu( from, menu ); + } + + /* + * If the programmer defined a destroy callback, call it + * A. Donev: But first make this the active menu + */ + if ( menu->Destroy != NULL ) + { + SFG_Menu *activeMenu=fgStructure.Menu; + fgStructure.Menu = menu; + menu->Destroy () ; + fgStructure.Menu = activeMenu; + } + + /* + * Now we are pretty sure the menu is not used anywhere + * and that we can remove all of its entries + */ + while( (entry = menu->Entries.First) != NULL ) + { + fgListRemove(&menu->Entries, &entry->Node); + + /* + * There might be a string allocated, have it freed: + */ + free( entry->Text ); + + /* + * Deallocate the entry itself: + */ + free( entry ); + } + + /* + * Remove the menu from the menus list + */ + fgListRemove( &fgStructure.Menus, &menu->Node ); + + /* + * If that menu was the current one... + */ + if( fgStructure.Menu == menu ) + fgStructure.Menu = NULL; + + /* + * Have the menu structure freed + */ + free( menu ); +} + +/* + * This function should be called on glutInit(). It will prepare the internal + * structure of freeglut to be used in the application. The structure will be + * destroyed using fgDestroyStructure() on glutMainLoop() return. In that + * case further use of freeglut should be preceeded with a glutInit() call. + */ +void fgCreateStructure( void ) +{ + /* + * We will be needing two lists: the first containing windows, + * and the second containing the user-defined menus. + * Also, no current window/menu is set, as none has been created yet. + */ + + fgListInit(&fgStructure.Windows); + fgListInit(&fgStructure.Menus); +} + +/* + * This function is automatically called on glutMainLoop() return. It should deallocate + * and destroy all remnants of previous glutInit()-enforced structure initialization... + */ +void fgDestroyStructure( void ) +{ + SFG_Window *window; + SFG_Menu *menu; + + /* + * Just make sure we are not called in vain... + */ + freeglut_assert_ready; + + /* + * Make sure all windows and menus have been deallocated + */ + while( (window = fgStructure.Windows.First) != NULL ) + fgDestroyWindow( window, TRUE ); + + while( (menu = fgStructure.Menus.First) != NULL ) + fgDestroyMenu( menu ); +} + +/* + * Helper function to enumerate through all registered top-level windows + */ +void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator ) +{ + SFG_Window *window; + + assert( (enumCallback != NULL) && (enumerator != NULL) ); + freeglut_assert_ready; + + /* + * Check every of the top-level windows + */ + for( window = fgStructure.Windows.First; window; + window = window->Node.Next ) + { + /* + * Execute the callback... + */ + enumCallback( window, enumerator ); + + /* + * If it has been marked as 'found', stop searching + */ + if( enumerator->found == TRUE ) + return; + } +} + +/* + * Helper function to enumerate through all a window's subwindows (single level descent) + */ +void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enumerator* enumerator ) +{ + SFG_Window *child; + + assert( (enumCallback != NULL) && (enumerator != NULL) ); + freeglut_assert_ready; + + /* + * Check every of the window's children: + */ + for( child = window->Children.First; child; child = child->Node.Next ) + { + /* + * Execute the callback... + */ + enumCallback( child, enumerator ); + + /* + * If it has been marked as 'found', stop searching + */ + if( enumerator->found == TRUE ) + return; + } +} + +/* + * A static helper function to look for a window given its handle + */ +static void fghcbWindowByHandle( SFG_Window *window, SFG_Enumerator *enumerator ) +{ + /* + * Make sure we do not overwrite our precious results... + */ + freeglut_return_if_fail( enumerator->found == FALSE ); + +#if TARGET_HOST_UNIX_X11 + #define WBHANDLE (Window) +#elif TARGET_HOST_WIN32 + #define WBHANDLE (HWND) +#endif + + /* + * Check the window's handle. Hope this works. Looks ugly. That's for sure. + */ + if( window->Window.Handle == WBHANDLE (enumerator->data) ) + { + enumerator->found = TRUE; + enumerator->data = window; + + return; + } + + /* + * Otherwise, check this window's children + */ + fgEnumSubWindows( window, fghcbWindowByHandle, enumerator ); + +#undef WBHANDLE +} + +/* + * fgWindowByHandle returns a (SFG_Window *) value pointing to the + * first window in the queue matching the specified window handle. + * The function is defined in freeglut_structure.c file. + */ +SFG_Window* fgWindowByHandle +#if TARGET_HOST_UNIX_X11 +( Window hWindow ) +#elif TARGET_HOST_WIN32 +( HWND hWindow ) +#endif +{ + SFG_Enumerator enumerator; + + /* + * This is easy and makes use of the windows enumeration defined above + */ + enumerator.found = FALSE; + enumerator.data = (void *)hWindow; + + /* + * Start the enumeration now: + */ + fgEnumWindows( fghcbWindowByHandle, &enumerator ); + + /* + * Check if the window has been found or not: + */ + if( enumerator.found == TRUE ) + return( (SFG_Window *) enumerator.data ); + + /* + * Otherwise return NULL to mark the failure + */ + return( NULL ); +} + +/* + * A static helper function to look for a window given its ID + */ +static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator ) +{ + /* + * Make sure we do not overwrite our precious results... + */ + freeglut_return_if_fail( enumerator->found == FALSE ); + + /* + * Check the window's handle. Hope this works. Looks ugly. That's for sure. + */ + if( window->ID == (int) (enumerator->data) ) + { + enumerator->found = TRUE; + enumerator->data = window; + + return; + } + + /* + * Otherwise, check this window's children + */ + fgEnumSubWindows( window, fghcbWindowByID, enumerator ); +} + +/* + * This function is similiar to the previous one, except it is + * looking for a specified (sub)window identifier. The function + * is defined in freeglut_structure.c file. + */ +SFG_Window* fgWindowByID( int windowID ) +{ + SFG_Enumerator enumerator; + + /* + * Uses a method very similiar for fgWindowByHandle... + */ + enumerator.found = FALSE; + enumerator.data = (void *) windowID; + + /* + * Start the enumeration now: + */ + fgEnumWindows( fghcbWindowByID, &enumerator ); + + /* + * Check if the window has been found or not: + */ + if( enumerator.found == TRUE ) + return( (SFG_Window *) enumerator.data ); + + /* + * Otherwise return NULL to mark the failure + */ + return( NULL ); +} + +/* + * Looks up a menu given its ID. This is easier that fgWindowByXXX + * as all menus are placed in a single doubly linked list... + */ +SFG_Menu* fgMenuByID( int menuID ) +{ + SFG_Menu *menu = NULL; + + freeglut_assert_ready; + + /* + * It's enough to check all entries in fgStructure.Menus... + */ + for( menu = fgStructure.Menus.First; menu; menu = menu->Node.Next ) + { + /* + * Does the ID number match? + */ + if( menu->ID == menuID ) + return( menu ); + } + + /* + * We have not found the requested menu ID + */ + return( NULL ); +} + +/* + * List functions... + */ +void fgListInit(SFG_List *list) +{ + list->First = NULL; + list->Last = NULL; +} + +void fgListAppend(SFG_List *list, SFG_Node *node) +{ + SFG_Node *ln; + + if ( (ln = list->Last) != NULL ) + { + ln->Next = node; + node->Prev = ln; + } + else + { + node->Prev = NULL; + list->First = node; + } + + node->Next = NULL; + list->Last = node; +} + +void fgListRemove(SFG_List *list, SFG_Node *node) +{ + SFG_Node *ln; + + if ( (ln = node->Next) != NULL ) + ln->Prev = node->Prev; + if ( (ln = node->Prev) != NULL ) + ln->Next = node->Next; + if ( (ln = list->First) == node ) + list->First = node->Next; + if ( (ln = list->Last) == node ) + list->Last = node->Prev; +} + +int fgListLength(SFG_List *list) +{ + SFG_Node *node; + int length = 0; + + for( node = list->First; node; node = node->Next ) + ++length; + + return( length ); +} + +/*** END OF FILE ***/ diff --git a/src/freeglut_teapot.c b/src/freeglut_teapot.c new file mode 100644 index 0000000..0a3930e --- /dev/null +++ b/src/freeglut_teapot.c @@ -0,0 +1,247 @@ +/* + * freeglut_teapot.c + * + * Teapot(tm) rendering code. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 24 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Original teapot code copyright follows: + */ + +/* + * (c) Copyright 1993, Silicon Graphics, Inc. + * + * ALL RIGHTS RESERVED + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation, and that the name of Silicon + * Graphics, Inc. not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU + * "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR + * OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO + * EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE + * ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, + * INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, + * SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR + * NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY + * OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer + * Software clause at DFARS 252.227-7013 and/or in similar or + * successor clauses in the FAR or the DOD or NASA FAR + * Supplement. Unpublished-- rights reserved under the copyright + * laws of the United States. Contractor/manufacturer is Silicon + * Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA + * 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-teapot" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * Rim, body, lid, and bottom data must be reflected in x and y; + * handle and spout data across the y axis only. + */ +static int patchdata[][16] = +{ + { 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* rim */ + { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }, /* body */ + { 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 }, + { 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3 }, /* lid */ + { 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117 }, + { 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37 }, /* bottom */ + { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 }, /* handle */ + { 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67 }, + { 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 }, /* spout */ + { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 } +}; + +static double cpdata[][3] = +{ + {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0, + -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125}, + {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375, + 0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375, + 2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84, + 2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875}, + {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75, + 1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35}, + {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2, + 0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12, + 0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225}, + {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225}, + {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0, + -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5, + -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3, + 2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0, + 2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0, + 2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8}, + {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3, + -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3, + 1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2, + -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0, + 1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0, + 0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66, + 0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1}, + {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7, + -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0, + 2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375}, + {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475}, + {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4}, + {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0, + 3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8, + 3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4, + -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0, + 2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4, + 2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3, + 2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4}, + {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425, + -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425, + 0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075}, + {0.84, -1.5, 0.075} +}; + +static double tex[2][2][2] = +{ + { {0.0, 0.0}, {1.0, 0.0} }, + { {0.0, 1.0}, {1.0, 1.0} } +}; + +static void teapot( GLint grid, GLdouble scale, GLenum type ) +{ + double p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3]; + long i, j, k, l; + + glPushAttrib( GL_ENABLE_BIT | GL_EVAL_BIT ); + glEnable( GL_AUTO_NORMAL ); + glEnable( GL_NORMALIZE ); + glEnable( GL_MAP2_VERTEX_3 ); + glEnable( GL_MAP2_TEXTURE_COORD_2 ); + + glPushMatrix(); + glRotated(270.0, 1.0, 0.0, 0.0); + glScaled(0.5 * scale, 0.5 * scale, 0.5 * scale); + glTranslated(0.0, 0.0, -1.5); + + for (i = 0; i < 10; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + for (l = 0; l < 3; l++) { + p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 1) + q[j][k][l] *= -1.0; + if (i < 6) { + r[j][k][l] = + cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 0) + r[j][k][l] *= -1.0; + s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + if (l == 0) + s[j][k][l] *= -1.0; + if (l == 1) + s[j][k][l] *= -1.0; + } + } + } + } + + glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 2, 0.0, 1.0, 4, 2, + &tex[0][0][0]); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &p[0][0][0]); + glMapGrid2d(grid, 0.0, 1.0, grid, 0.0, 1.0); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &q[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + if (i < 6) { + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &r[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + &s[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + } + } + + glPopMatrix(); + glPopAttrib(); +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Renders a beautiful wired teapot... + */ +void FGAPIENTRY glutWireTeapot( GLdouble size ) +{ + /* + * We will use the general teapot rendering code + */ + teapot( 10, size, GL_LINE ); +} + +/* + * Renders a beautiful filled teapot... + */ +void FGAPIENTRY glutSolidTeapot( GLdouble size ) +{ + /* + * We will use the general teapot rendering code + */ + teapot( 7, size, GL_FILL ); +} + +/*** END OF FILE ***/ + + + + + diff --git a/src/freeglut_videoresize.c b/src/freeglut_videoresize.c new file mode 100644 index 0000000..050dbe1 --- /dev/null +++ b/src/freeglut_videoresize.c @@ -0,0 +1,56 @@ +/* + * freeglut_videoresize.c + * + * Video resize functions (as defined by GLUT API) + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-videoresize" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * NOTE: functions declared in this file probably will not be implemented. + */ + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +int FGAPIENTRY glutVideoResizeGet( GLenum eWhat ) { return( 0x00 ); } +void FGAPIENTRY glutSetupVideoResizing( void ) { /* Not implemented */ } +void FGAPIENTRY glutStopVideoResizing( void ) { /* Not implemented */ } +void FGAPIENTRY glutVideoResize( int x, int y, int w, int h ) { /* Not implemented */ } +void FGAPIENTRY glutVideoPan( int x, int y, int w, int h ) { /* Not implemented */ } + +/*** END OF FILE ***/ + + + + + + + diff --git a/src/freeglut_window.c b/src/freeglut_window.c new file mode 100644 index 0000000..9e4a9e3 --- /dev/null +++ b/src/freeglut_window.c @@ -0,0 +1,1189 @@ +/* + * freeglut_window.c + * + * Window management methods. + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define G_LOG_DOMAIN "freeglut-window" + +#include "../include/GL/freeglut.h" +#include "freeglut_internal.h" + +/* + * TODO BEFORE THE STABLE RELEASE: + * + * fgChooseVisual() -- OK, but what about glutInitDisplayString()? + * fgSetupPixelFormat -- ignores the display mode settings + * fgOpenWindow() -- check the Win32 version, -iconic handling! + * fgCloseWindow() -- check the Win32 version + * glutCreateWindow() -- see what happens when default position and size is {-1,-1} + * glutCreateSubWindow() -- see what happens when default position and size is {-1,-1} + * glutDestroyWindow() -- check the Win32 version + * glutSetWindow() -- check the Win32 version + * glutGetWindow() -- OK + * glutSetWindowTitle() -- check the Win32 version + * glutSetIconTitle() -- check the Win32 version + * glutShowWindow() -- check the Win32 version + * glutHideWindow() -- check the Win32 version + * glutIconifyWindow() -- check the Win32 version + * glutReshapeWindow() -- check the Win32 version + * glutPositionWindow() -- check the Win32 version + * glutPushWindow() -- check the Win32 version + * glutPopWindow() -- check the Win32 version + */ + +/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +/* + * Chooses a visual basing on the current display mode settings + */ +#if TARGET_HOST_UNIX_X11 +XVisualInfo* fgChooseVisual( void ) +{ + int bufferSize[] = { 16, 12, 8, 4, 2, 1 }; + GLboolean wantIndexedMode = FALSE; + int attributes[ 32 ]; + int where = 0; + + /* + * First we have to process the display mode settings... + */ +# define ATTRIB(a) attributes[where++]=a; + + /* + * Decide if we want a true or indexed color visual: + */ + if( !(fgState.DisplayMode & GLUT_INDEX) ) + { + /* + * We are sure that there will be R, B and B components requested: + */ + ATTRIB( GLX_RGBA ); + ATTRIB( GLX_RED_SIZE ); ATTRIB( 1 ); + ATTRIB( GLX_GREEN_SIZE ); ATTRIB( 1 ); + ATTRIB( GLX_BLUE_SIZE ); ATTRIB( 1 ); + + /* + * Check if the A component is required, too: + */ + if( fgState.DisplayMode & GLUT_ALPHA ) + { + ATTRIB( GLX_ALPHA_SIZE ); ATTRIB( 1 ); + } + } + else + { + /* + * We've got an indexed color request + */ + ATTRIB( GLX_BUFFER_SIZE ); ATTRIB( 8 ); + + /* + * Set the 'I want indexed mode' switch + */ + wantIndexedMode = TRUE; + } + + /* + * We can have double or single buffered contexts created + */ + if( fgState.DisplayMode & GLUT_DOUBLE ) + { + ATTRIB( GLX_DOUBLEBUFFER ); + } + + /* + * Stereoscopy seems a nice thing to have + */ + if( fgState.DisplayMode & GLUT_STEREO ) + { + ATTRIB( GLX_STEREO ); + } + + /* + * Depth buffer is almost always required + */ + if( fgState.DisplayMode & GLUT_DEPTH ) + { + ATTRIB( GLX_DEPTH_SIZE ); ATTRIB( 1 ); + } + + /* + * Stenciling support + */ + if( fgState.DisplayMode & GLUT_STENCIL ) + { + ATTRIB( GLX_STENCIL_SIZE ); ATTRIB( 1 ); + } + + /* + * And finally the accumulation buffers + */ + if( fgState.DisplayMode & GLUT_ACCUM ) + { + ATTRIB( GLX_ACCUM_RED_SIZE ); ATTRIB( 1 ); + ATTRIB( GLX_ACCUM_GREEN_SIZE ); ATTRIB( 1 ); + ATTRIB( GLX_ACCUM_BLUE_SIZE ); ATTRIB( 1 ); + + /* + * Check if the A component is required, too: + */ + if( fgState.DisplayMode & GLUT_ALPHA ) + { + ATTRIB( GLX_ACCUM_ALPHA_SIZE ); ATTRIB( 1 ); + } + } + + /* + * Push a null at the end of the list + */ + ATTRIB( None ); + + /* + * OKi now, we've got two cases -- RGB(A) and index mode visuals + */ + if( wantIndexedMode == FALSE ) + { + /* + * The easier one. And more common, too. + */ + return( glXChooseVisual( fgDisplay.Display, fgDisplay.Screen, attributes ) ); + } + else + { + XVisualInfo* visualInfo; + int i; + + /* + * In indexed mode, we need to check how many bits of depth can we achieve + */ + for( i=0; i<6; i++ ) + { + + /* + * The GLX_BUFFER_SIZE value comes always first, so: + */ + attributes[ 1 ] = bufferSize[ i ]; + + /* + * Check if such visual is possible + */ + visualInfo = glXChooseVisual( fgDisplay.Display, fgDisplay.Screen, attributes ); + + /* + * The buffer size are sorted in descendant order, so choose the first: + */ + if( visualInfo != NULL ) + return( visualInfo ); + } + + /* + * If we are still here, it means that the visual info was not found + */ + return( NULL ); + } +} +#endif + +/* + * Setup the pixel format for a Win32 window + */ +#if TARGET_HOST_WIN32 +GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ) +{ + PIXELFORMATDESCRIPTOR* ppfd, pfd; + int flags, pixelformat; + + /* + * Check if the window seems valid + */ + freeglut_return_val_if_fail( window != NULL, 0 ); + + /* + * The pixel format should allow us to draw to the window using OpenGL + */ + flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + + /* + * It might be the case for us to use double buffering + */ + if( fgState.DisplayMode & GLUT_DOUBLE ) + flags |= PFD_DOUBLEBUFFER; + + /* + * Specify which pixel format do we opt for... + */ +# pragma message( "fgSetupPixelFormat(): there is still some work to do here!" ) + + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = flags; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cRedBits = 0; + pfd.cRedShift = 0; + pfd.cGreenBits = 0; + pfd.cGreenShift = 0; + pfd.cBlueBits = 0; + pfd.cBlueShift = 0; + pfd.cAlphaBits = 0; + pfd.cAlphaShift = 0; + pfd.cAccumBits = 0; + pfd.cAccumRedBits = 0; + pfd.cAccumGreenBits = 0; + pfd.cAccumBlueBits = 0; + pfd.cAccumAlphaBits = 0; +#if 0 + pfd.cDepthBits = 32; + pfd.cStencilBits = 0; +#else + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; +#endif + pfd.cAuxBuffers = 0; + pfd.iLayerType = layer_type; + pfd.bReserved = 0; + pfd.dwLayerMask = 0; + pfd.dwVisibleMask = 0; + pfd.dwDamageMask = 0; + + /* + * Fill in the color bits... + */ + pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); + ppfd = &pfd; + + /* + * Choose the pixel format that matches our demand + */ + pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); + if( pixelformat == 0 ) + return( FALSE ); + + /* + * We might have been called to check if the pixel format exists only + */ + if( checkOnly ) + return( TRUE ); + + /* + * Finally, set the window's pixel format + */ + return ( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ) ; +} +#endif + +/* + * Sets the OpenGL context and the fgStructure "Current Window" pointer to the window + * structure passed in. + */ +void fgSetWindow ( SFG_Window *window ) +{ +#if TARGET_HOST_UNIX_X11 + /* + * Make the selected window's GLX context the current one + */ + glXMakeCurrent( + fgDisplay.Display, + window->Window.Handle, + window->Window.Context + ); + +#elif TARGET_HOST_WIN32 + /* + * Release the previous' context's device context + */ + if( fgStructure.Window != NULL ) + ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device ); + + if ( window ) + { + /* + * We will care about releasing the device context later + */ + window->Window.Device = GetDC( window->Window.Handle ); + + /* + * Set the new current context: + */ + wglMakeCurrent( + window->Window.Device, + window->Window.Context + ); + } +#endif + + /* + * Remember that we have changed the current window state + */ + fgStructure.Window = window; +} + + +/* + * Opens a window. Requires a SFG_Window object created and attached + * to the freeglut structure. OpenGL context is created here. + */ +void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow ) +{ +#if TARGET_HOST_UNIX_X11 + XSetWindowAttributes winAttr; + XTextProperty textProperty; + XSizeHints sizeHints; + XWMHints wmHints; + unsigned long mask; + + freeglut_assert_ready; + + /* + * Here we are upon the stage. Have the visual selected. + */ + window->Window.VisualInfo = fgChooseVisual(); + if ( ! window->Window.VisualInfo ) + { + /* + * The "fgChooseVisual" returned a null meaning that the visual context is not available. + * Try a couple of variations to see if they will work. + */ + if ( ! ( fgState.DisplayMode & GLUT_DOUBLE ) ) + { + /* + * Single buffering--try it doubled + */ + fgState.DisplayMode |= GLUT_DOUBLE ; + window->Window.VisualInfo = fgChooseVisual(); + } + + /* + * GLUT also checks for multi-sampling, but I don't see that anywhere else in FREEGLUT + * so I won't bother with it for the moment. + */ + } + + assert( window->Window.VisualInfo != NULL ); + + /* + * Have the windows attributes set + * + * HINT: the masks should be updated when adding/removing callbacks. + * This might speed up message processing. Is that true? + */ + winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | + ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease | + VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | + PointerMotionMask | ButtonMotionMask; + winAttr.background_pixmap = None; + winAttr.background_pixel = 0; + winAttr.border_pixel = 0; + + /* + * The color map is required, too + */ + winAttr.colormap = XCreateColormap( + fgDisplay.Display, fgDisplay.RootWindow, + window->Window.VisualInfo->visual, AllocNone + ); + + /* + * This tells the XCreateWindow() what attributes are we supplying it with + */ + mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; + + /* + * Have the window created now + */ + window->Window.Handle = XCreateWindow( + fgDisplay.Display, + window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, + x, y, w, h, 0, + window->Window.VisualInfo->depth, InputOutput, + window->Window.VisualInfo->visual, mask, + &winAttr + ); + + /* + * The GLX context creation, possibly trying the direct context rendering + */ + window->Window.Context = glXCreateContext( + fgDisplay.Display, window->Window.VisualInfo, + NULL, fgState.ForceDirectContext | fgState.TryDirectContext + ); + + /* + * Make sure the context is direct when the user wants it forced + */ + if( fgState.ForceDirectContext && !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) + fgError( "unable to force direct context rendering for window '%s'", title ); + + /* + * Set the new context as the current one. That's all about the window creation. + */ + glXMakeCurrent( + fgDisplay.Display, + window->Window.Handle, + window->Window.Context + ); + + /* + * Assume the new window is visible by default + */ + window->State.Visible = TRUE; + + /* + * For the position and size hints -- make sure we are passing valid values + */ + sizeHints.flags = 0; + + if (fgState.Position.Use == TRUE) sizeHints.flags |= USPosition; + if (fgState.Size.Use == TRUE) sizeHints.flags |= USSize; + + /* + * Fill in the size hints values now (the x, y, width and height + * settings are obsolote, are there any more WMs that support them?) + */ + sizeHints.x = x; sizeHints.y = y; + sizeHints.width = w; sizeHints.height = h; + + /* + * We can have forced all new windows start in iconified state: + */ + wmHints.flags = StateHint; + wmHints.initial_state = (fgState.ForceIconic == FALSE) ? NormalState : IconicState; + + /* + * Prepare the window and iconified window names... + */ + XStringListToTextProperty( (char **) &title, 1, &textProperty ); + + /* + * Set the window's properties now + */ + XSetWMProperties( + fgDisplay.Display, + window->Window.Handle, + &textProperty, + &textProperty, + 0, + 0, + &sizeHints, + &wmHints, + NULL + ); + + /* + * Make sure we are informed about the window deletion commands + */ + XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); + + /* + * Finally, have the window mapped to our display + */ + XMapWindow( fgDisplay.Display, window->Window.Handle ); + + /* + * In game mode, move the viewport a bit to hide the decorations. + * This code depends on the XFree86 video mode extensions. + */ + if( gameMode == TRUE ) + { + /* + * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem... + */ + XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y ); + +# ifdef X_XF86VidModeSetViewPort + + /* + * Set the newly created window as the current one... + */ + fgSetWindow( window ); + + /* + * Move the viewport a bit down and right from top-left corner to hide the decorations + */ + XF86VidModeSetViewPort( + fgDisplay.Display, + fgDisplay.Screen, + glutGet( GLUT_WINDOW_X ), + glutGet( GLUT_WINDOW_Y ) + ); + +# endif + } + +#elif TARGET_HOST_WIN32 + + WNDCLASS wc; + int flags; + ATOM atom; + + freeglut_assert_ready; + + /* + * Grab the window class we have registered on glutInit(): + */ + atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc ); + assert( atom != 0 ); + + if( gameMode == FALSE ) + { + if ( !isSubWindow ) + { + /* + * Update the window dimensions, taking account of window decorations. + * "freeglut" is to create the window with the outside of its border at (x,y) + * and with dimensions (w,h). + */ + w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; + h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); + } + + /* + * Check if the user wants us to use the default position/size + */ + if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } + if( fgState.Size .Use == FALSE ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } + + /* + * There's a small difference between creating the top, child and game mode windows + */ + flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + + if( window->Parent == NULL ) + flags |= WS_OVERLAPPEDWINDOW; + else + flags |= WS_CHILD; + } + else + { + /* + * In game mode, the story is a little bit different... + */ + assert( window->Parent == NULL ); + + /* + * Set the window creation flags appropriately to make the window entirely visible: + */ + flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + } + + /* + * Create the window now, passing the freeglut window structure as the parameter + */ + window->Window.Handle = CreateWindow( + "FREEGLUT", + title, + flags, + x, y, w, h, + (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, + (HMENU) NULL, + fgDisplay.Instance, + (LPVOID) window + ); + + /* + * Make sure window was created + */ + assert( window->Window.Handle != NULL ); + + /* + * Show and update the main window. Hide the mouse cursor. + */ + ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); + UpdateWindow( window->Window.Handle ); + ShowCursor( TRUE ); + +#endif + + /* + * Save the window's single- or double-buffering state + */ + window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ; + + /* + * If it's not double-buffered, make sure the rendering is done to the front buffer. + */ + if ( ! window->Window.DoubleBuffered ) + { + glDrawBuffer ( GL_FRONT ) ; + glReadBuffer ( GL_FRONT ) ; + } + + /* + * Set the newly created window as the current one + */ + fgSetWindow( window ); +} + +/* + * Closes a window, destroying the frame and OpenGL context + */ +void fgCloseWindow( SFG_Window* window ) +{ + freeglut_assert_ready; + +#if TARGET_HOST_UNIX_X11 + /* + * As easy as kill bunnies with axes. Destroy the context first: + */ + glXDestroyContext( fgDisplay.Display, window->Window.Context ); + + /* + * Then have the window killed: + */ + XDestroyWindow( fgDisplay.Display, window->Window.Handle ); + + /* + * Finally, flush the rests down the stream + */ + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + /* + * Send the WM_CLOSE message to the window now + */ + SendMessage( + window->Window.Handle, + WM_CLOSE, + 0, + 0 + ); + +#endif +} + + +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ + +/* + * Creates a new top-level freeglut window + */ +int FGAPIENTRY glutCreateWindow( const char* title ) +{ + /* + * Create a new window and return its unique ID number + */ + return( fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y, + fgState.Size.X, fgState.Size.Y, FALSE )->ID ); +} + +/* + * This function creates a sub window. + */ +int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) +{ + SFG_Window* window = NULL; + SFG_Window* parent = NULL; + + freeglut_assert_ready; + + /* + * Find a parent to the newly created window... + */ + parent = fgWindowByID( parentID ); + + /* + * Fail if the parent has not been found + */ + freeglut_return_val_if_fail( parent != NULL, 0 ); + + /* + * Create the new window + */ + window = fgCreateWindow( parent, "", x, y, w, h, FALSE ); + + /* + * Return the new window's ID + */ + return( window->ID ); +} + +/* + * Destroys a window and all of its subwindows + */ +void FGAPIENTRY glutDestroyWindow( int windowID ) +{ + fgExecutionState ExecState = fgState.ExecState ; + + /* + * Grab the freeglut window pointer from the structure + */ + SFG_Window* window = fgWindowByID( windowID ); + freeglut_return_if_fail( window != NULL ); + + /* + * There is a function that performs all needed steps + * defined in freeglut_structure.c. Let's use it: + */ + fgAddToWindowDestroyList( window, TRUE ); + + /* + * Since the "fgAddToWindowDestroyList" function could easily have set the "ExecState" + * to stop, let's set it back to what it was. + */ + fgState.ExecState = ExecState ; +} + +/* + * This function selects the current window + */ +void FGAPIENTRY glutSetWindow( int ID ) +{ + SFG_Window* window = NULL; + + /* + * Make sure we don't get called too early + */ + freeglut_assert_ready; + + /* + * Be wise. Be wise. Be wise. Be quick. + */ + if( fgStructure.Window != NULL ) + if( fgStructure.Window->ID == ID ) + return; + + /* + * Now we are sure there is sense in looking for the window + */ + window = fgWindowByID( ID ); + + /* + * In the case of an utter failure... + */ + if( window == NULL ) + { + /* + * ...issue a warning message and keep rolling on + */ + fgWarning( "glutSetWindow(): window ID %i not found!", ID ); + return; + } + + fgSetWindow ( window ) ; +} + +/* + * This function returns the ID number of the current window, 0 if none exists + */ +int FGAPIENTRY glutGetWindow( void ) +{ + freeglut_assert_ready; + + /* + * Do we have a current window selected? + */ + if( fgStructure.Window == NULL ) + { + /* + * Nope. Return zero to mark the state. + */ + return( 0 ); + } + + /* + * Otherwise, return the ID of the current window + */ + return( fgStructure.Window->ID ); +} + +/* + * This function makes the current window visible + */ +void FGAPIENTRY glutShowWindow( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Showing the window is done via mapping under X + */ + XMapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle ); + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + /* + * Restore the window's originial position and size + */ + ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW ); + +#endif +} + +/* + * This function hides the current window + */ +void FGAPIENTRY glutHideWindow( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * The way we hide a window depends on if we're dealing + * with a top-level or children one... + */ + if( fgStructure.Window->Parent == NULL ) + { + /* + * This is a top-level window + */ + XWithdrawWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen ); + } + else + { + /* + * Nope, it's a child window + */ + XUnmapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle ); + } + + /* + * Flush the X state now + */ + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + /* + * Hide the window + */ + ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE ); + +#endif +} + +/* + * Iconify the current window (top-level windows only) + */ +void FGAPIENTRY glutIconifyWindow( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Iconify the window and flush the X state + */ + XIconifyWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen ); + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + /* + * Minimize the current window (this should be the same as X window iconifying) + */ + ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE ); + +#endif +} + +/* + * Set the current window's title + */ +void FGAPIENTRY glutSetWindowTitle( const char* title ) +{ + freeglut_assert_ready; freeglut_assert_window; + + /* + * Works only for top-level windows + */ + if( fgStructure.Window->Parent != NULL ) + return; + +#if TARGET_HOST_UNIX_X11 + { + XTextProperty text; + + /* + * Prepare the text properties + */ + text.value = (unsigned char *) title; + text.encoding = XA_STRING; + text.format = 8; + text.nitems = strlen( title ); + + /* + * Set the title now + */ + XSetWMName( + fgDisplay.Display, + fgStructure.Window->Window.Handle, + &text + ); + + /* + * Have the X display state flushed + */ + XFlush( fgDisplay.Display ); + } + +#elif TARGET_HOST_WIN32 + /* + * This seems to be a bit easier under Win32 + */ + SetWindowText( fgStructure.Window->Window.Handle, title ); + +#endif +} + +/* + * Set the current window's iconified title + */ +void FGAPIENTRY glutSetIconTitle( const char* title ) +{ + freeglut_assert_ready; freeglut_assert_window; + + /* + * Works only for top-level windows + */ + if( fgStructure.Window->Parent != NULL ) + return; + +#if TARGET_HOST_UNIX_X11 + { + XTextProperty text; + + /* + * Prepare the text properties + */ + text.value = (unsigned char *) title; + text.encoding = XA_STRING; + text.format = 8; + text.nitems = strlen( title ); + + /* + * Set the title now + */ + XSetWMIconName( + fgDisplay.Display, + fgStructure.Window->Window.Handle, + &text + ); + + /* + * Have the X display state flushed + */ + XFlush( fgDisplay.Display ); + } + +#elif TARGET_HOST_WIN32 + /* + * This seems to be a bit easier under Win32 + */ + SetWindowText( fgStructure.Window->Window.Handle, title ); + +#endif +} + +/* + * Change the current window's size + */ +void FGAPIENTRY glutReshapeWindow( int width, int height ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Resize the window and flush the X state + */ + XResizeWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, width, height ); + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + { + RECT winRect; + int x, y ; + + /* + * First off, grab the current window's position + */ + GetWindowRect( fgStructure.Window->Window.Handle, &winRect ); + x = winRect.left ; + y = winRect.top ; + + if ( fgStructure.Window->Parent == NULL ) /* If this is not a subwindow ... */ + { + /* + * Adjust the size of the window to allow for the size of the frame + */ + width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2; + height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION ); + } + else /* This is a subwindow, get the parent window's position and subtract it off */ + { + GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ; + x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) ; + y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ; + } + + /* + * Resize the window, forcing a redraw to happen + */ + MoveWindow( + fgStructure.Window->Window.Handle, + x, + y, + width, + height, + TRUE + ); + } +#endif +} + +/* + * Change the current window's position + */ +void FGAPIENTRY glutPositionWindow( int x, int y ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Reposition the window and flush the X state + */ + XMoveWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, x, y ); + XFlush( fgDisplay.Display ); + +#elif TARGET_HOST_WIN32 + { + RECT winRect; + + /* + * First off, grab the current window's position + */ + GetWindowRect( fgStructure.Window->Window.Handle, &winRect ); + + /* + * Reposition the window, forcing a redraw to happen + */ + MoveWindow( + fgStructure.Window->Window.Handle, + x, + y, + winRect.right - winRect.left, + winRect.bottom - winRect.top, + TRUE + ); + } + +#endif +} + +/* + * Lowers the current window (by Z order change) + */ +void FGAPIENTRY glutPushWindow( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Lower the current window + */ + XLowerWindow( fgDisplay.Display, fgStructure.Window->Window.Handle ); + +#elif TARGET_HOST_WIN32 + /* + * Set the new window's Z position, not affecting the rest of the settings: + */ + SetWindowPos( + fgStructure.Window->Window.Handle, + HWND_BOTTOM, + 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE + ); + +#endif +} + +/* + * Raises the current window (by Z order change) + */ +void FGAPIENTRY glutPopWindow( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + +#if TARGET_HOST_UNIX_X11 + /* + * Raise the current window + */ + XRaiseWindow( fgDisplay.Display, fgStructure.Window->Window.Handle ); + +#elif TARGET_HOST_WIN32 + /* + * Set the new window's Z position, not affecting the rest of the settings: + */ + SetWindowPos( + fgStructure.Window->Window.Handle, + HWND_TOP, + 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE + ); + +#endif +} + +/* + * Resize the current window so that it fits the whole screen + */ +void FGAPIENTRY glutFullScreen( void ) +{ + freeglut_assert_ready; freeglut_assert_window; + + /* + * Just have the window repositioned and resized + */ + glutPositionWindow( 0, 0 ); + + glutReshapeWindow( + fgDisplay.ScreenWidth, + fgDisplay.ScreenHeight + ); +} + +/* + * A.Donev: Set and retrieve the window's user data + */ +void* FGAPIENTRY glutGetWindowData( void ) +{ + return(fgStructure.Window->UserData); +} + +void FGAPIENTRY glutSetWindowData(void* data) +{ + fgStructure.Window->UserData=data; +} + +/*** END OF FILE ***/ + + + + + + + + + diff --git a/src/freeglutdll.def b/src/freeglutdll.def new file mode 100644 index 0000000..89155b6 --- /dev/null +++ b/src/freeglutdll.def @@ -0,0 +1,132 @@ +LIBRARY freeglutdll +DESCRIPTION "Freeglut OpenGL Utility Toolkit" +VERSION 1.3 +EXPORTS + glutInit + glutInitWindowPosition + glutInitWindowSize + glutInitDisplayMode + glutInitDisplayString + glutMainLoop + glutMainLoopEvent + glutLeaveMainLoop + glutCreateWindow + glutCreateSubWindow + glutDestroyWindow + glutSetWindow + glutGetWindow + glutSetWindowTitle + glutSetIconTitle + glutReshapeWindow + glutPositionWindow + glutShowWindow + glutHideWindow + glutIconifyWindow + glutPushWindow + glutPopWindow + glutFullScreen + glutPostWindowRedisplay + glutPostRedisplay + glutSwapBuffers + glutWarpPointer + glutSetCursor + glutEstablishOverlay + glutRemoveOverlay + glutUseLayer + glutPostOverlayRedisplay + glutPostWindowOverlayRedisplay + glutShowOverlay + glutHideOverlay + glutCreateMenu + glutDestroyMenu + glutGetMenu + glutSetMenu + glutAddMenuEntry + glutAddSubMenu + glutChangeToMenuEntry + glutChangeToSubMenu + glutRemoveMenuItem + glutAttachMenu + glutDetachMenu + glutTimerFunc + glutIdleFunc + glutKeyboardFunc + glutSpecialFunc + glutReshapeFunc + glutVisibilityFunc + glutDisplayFunc + glutMouseFunc + glutMotionFunc + glutPassiveMotionFunc + glutEntryFunc + glutCloseFunc + glutWMCloseFunc + glutKeyboardUpFunc + glutSpecialUpFunc + glutJoystickFunc + glutMenuStateFunc + glutMenuStatusFunc + glutOverlayDisplayFunc + glutWindowStatusFunc + glutSpaceballMotionFunc + glutSpaceballRotateFunc + glutSpaceballButtonFunc + glutButtonBoxFunc + glutDialsFunc + glutTabletMotionFunc + glutTabletButtonFunc + glutSetOption + glutGet + glutDeviceGet + glutGetModifiers + glutLayerGet + glutBitmapCharacter + glutBitmapWidth + glutStrokeCharacter + glutStrokeWidth + glutBitmapLength + glutStrokeLength + glutBitmapHeight + glutStrokeHeight + glutBitmapString + glutStrokeString + glutWireCube + glutSolidCube + glutWireSphere + glutSolidSphere + glutWireCone + glutSolidCone + glutWireTorus + glutSolidTorus + glutWireDodecahedron + glutSolidDodecahedron + glutWireOctahedron + glutSolidOctahedron + glutWireTetrahedron + glutSolidTetrahedron + glutWireIcosahedron + glutSolidIcosahedron + glutWireRhombicDodecahedron + glutSolidRhombicDodecahedron + glutWireSierpinskiSponge + glutSolidSierpinskiSponge + glutWireTeapot + glutSolidTeapot + glutGameModeString + glutEnterGameMode + glutLeaveGameMode + glutGameModeGet + glutVideoResizeGet + glutSetupVideoResizing + glutStopVideoResizing + glutVideoResize + glutVideoPan + glutSetColor + glutGetColor + glutCopyColormap + glutIgnoreKeyRepeat + glutSetKeyRepeat + glutForceJoystickFunc + glutExtensionSupported + glutReportErrors + diff --git a/src/templates/cpp_template b/src/templates/cpp_template new file mode 100644 index 0000000..9d4d4fa --- /dev/null +++ b/src/templates/cpp_template @@ -0,0 +1,17 @@ +INVALID TEMPLATE, MOVED TO XFREE86-STYLE LICENSE + +/* + * |FILENAME| + * + * Here comes the file's contents description. + * + * Copyright (c) |YEAR| by |AUTHOR| + * Written by |AUTHOR|, <|EMAIL|> + * Creation date: |DATE| + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + diff --git a/src/templates/header_template b/src/templates/header_template new file mode 100644 index 0000000..9d4d4fa --- /dev/null +++ b/src/templates/header_template @@ -0,0 +1,17 @@ +INVALID TEMPLATE, MOVED TO XFREE86-STYLE LICENSE + +/* + * |FILENAME| + * + * Here comes the file's contents description. + * + * Copyright (c) |YEAR| by |AUTHOR| + * Written by |AUTHOR|, <|EMAIL|> + * Creation date: |DATE| + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + diff --git a/tests/Makefile.am b/tests/Makefile.am index cf66858..45467cd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,5 +2,5 @@ bin_PROGRAMS = one one_SOURCES = one.c -one_LDFLAGS = -export-dynamic -dlpreopen ../freeglut-1.3/libfreeglut-1.3.la +one_LDFLAGS = -export-dynamic -dlpreopen ../src/libfreeglut-1.3.la -- 1.7.10.4