Equalizer 1.0
|
00001 00002 /* Copyright (c) 2008-2011, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 00004 * This library is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU Lesser General Public License version 2.1 as published 00006 * by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, but WITHOUT 00009 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00010 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00011 * details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this library; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00016 */ 00017 00018 // HACK: Get rid of deprecated warning for aglUseFont 00019 // -Wno-deprecated-declarations would do as well, but here it is more isolated 00020 #include <eq/defines.h> 00021 00022 #ifdef AGL 00023 # include <AvailabilityMacros.h> 00024 # undef DEPRECATED_ATTRIBUTE 00025 # define DEPRECATED_ATTRIBUTE 00026 #endif 00027 00028 #include "bitmapFont.h" 00029 00030 #include "objectManager.h" 00031 00032 #ifdef GLX 00033 # include <eq/glXTypes.h> 00034 #endif 00035 #include <eq/os.h> 00036 #include <co/base/debug.h> 00037 #include <co/base/lock.h> 00038 #include <co/base/log.h> 00039 #include <co/base/scopedMutex.h> 00040 00041 namespace eq 00042 { 00043 namespace util 00044 { 00045 00046 template< class OMT > 00047 BitmapFont< OMT >::BitmapFont( ObjectManager< OMT >& gl, const OMT& key ) 00048 // We create a new shared object manager. Typically we are exited by 00049 // the last user, at which point the given OM may have been deleted 00050 : _gl( &gl ) 00051 , _key( key ) 00052 { 00053 } 00054 00055 template< class OMT > 00056 BitmapFont< OMT >::~BitmapFont() 00057 { 00058 const GLuint lists = _gl.getList( _key ); 00059 if( lists != ObjectManager< OMT >::INVALID ) 00060 EQWARN << "OpenGL BitmapFont was not freed" << std::endl; 00061 } 00062 00063 template< class OMT > 00064 bool BitmapFont< OMT >::init( const WindowSystem ws, const std::string& name, 00065 const uint32_t size ) 00066 { 00067 switch( ws ) 00068 { 00069 case WINDOW_SYSTEM_GLX: 00070 return _initGLX( name, size ); 00071 case WINDOW_SYSTEM_WGL: 00072 return _initWGL( name, size ); 00073 case WINDOW_SYSTEM_AGL: 00074 return _initAGL( name, size ); 00075 default: 00076 return false; 00077 } 00078 00079 EQASSERTINFO( _gl.getList( _key ) != ObjectManager< OMT >::INVALID, 00080 "Font initialization failed" ); 00081 } 00082 00083 template< class OMT > 00084 void BitmapFont< OMT >::exit() 00085 { 00086 _setupLists( 0 ); 00087 } 00088 00089 #ifdef GLX 00090 template< class OMT > 00091 bool BitmapFont< OMT >::_initGLX( const std::string& name, const uint32_t size ) 00092 { 00093 Display* display = XGetCurrentDisplay(); 00094 EQASSERT( display ); 00095 if( !display ) 00096 { 00097 EQWARN << "No current X11 display, use eq::XSetCurrentDisplay()" 00098 << std::endl; 00099 return false; 00100 } 00101 00102 // see xfontsel 00103 std::stringstream font; 00104 font << "-*-"; 00105 00106 if( name.empty( )) 00107 font << "times"; 00108 else 00109 font << name; 00110 font << "-*-r-*-*-" << size << "-*-*-*-*-*-*-*"; 00111 00112 // X11 font initialization is not thread safe. Using a mutex here is not 00113 // performance-critical 00114 static co::base::Lock lock; 00115 co::base::ScopedMutex<> mutex( lock ); 00116 00117 XFontStruct* fontStruct = XLoadQueryFont( display, font.str().c_str( )); 00118 if( !fontStruct ) 00119 { 00120 EQWARN << "Can't load font " << font.str() << ", using fixed" 00121 << std::endl; 00122 fontStruct = XLoadQueryFont( display, "fixed" ); 00123 } 00124 00125 EQASSERT( fontStruct ); 00126 00127 const GLuint lists = _setupLists( 127 ); 00128 glXUseXFont( fontStruct->fid, 0, 127, lists ); 00129 00130 XFreeFont( display, fontStruct ); 00131 return true; 00132 } 00133 #else 00134 template< class OMT > 00135 bool BitmapFont< OMT >::_initGLX( const std::string&, const uint32_t ) 00136 { 00137 return false; 00138 } 00139 #endif 00140 00141 #ifdef WGL 00142 template< class OMT > 00143 bool BitmapFont< OMT >::_initWGL( const std::string& name, const uint32_t size ) 00144 { 00145 HDC dc = wglGetCurrentDC(); 00146 if( !dc ) 00147 { 00148 EQWARN << "No WGL device context current" << std::endl; 00149 return false; 00150 } 00151 00152 LOGFONT font; 00153 memset( &font, 0, sizeof( font )); 00154 font.lfHeight = -static_cast< LONG >( size ); 00155 font.lfWeight = FW_NORMAL; 00156 font.lfCharSet = ANSI_CHARSET; 00157 font.lfOutPrecision = OUT_DEFAULT_PRECIS; 00158 font.lfClipPrecision = CLIP_DEFAULT_PRECIS; 00159 font.lfQuality = DEFAULT_QUALITY; 00160 font.lfPitchAndFamily = FF_DONTCARE | DEFAULT_QUALITY; 00161 00162 if( name.empty( )) 00163 strncpy( font.lfFaceName, "Times New Roman", LF_FACESIZE ); 00164 else 00165 strncpy( font.lfFaceName, name.c_str(), LF_FACESIZE ); 00166 00167 font.lfFaceName[ LF_FACESIZE-1 ] = '\0'; 00168 00169 HFONT newFont = CreateFontIndirect( &font ); 00170 if( !newFont ) 00171 { 00172 EQWARN << "Can't load font " << name << ", using Times New Roman" 00173 << std::endl; 00174 00175 strncpy( font.lfFaceName, "Times New Roman", LF_FACESIZE ); 00176 newFont = CreateFontIndirect( &font ); 00177 } 00178 EQASSERT( newFont ); 00179 00180 HFONT oldFont = static_cast< HFONT >( SelectObject( dc, newFont )); 00181 00182 const GLuint lists = _setupLists( 256 ); 00183 const bool ret = wglUseFontBitmaps( dc, 0 , 255, lists ); 00184 00185 SelectObject( dc, oldFont ); 00186 //DeleteObject( newFont ); 00187 00188 if( !ret ) 00189 _setupLists( 0 ); 00190 00191 return ret; 00192 } 00193 #else 00194 template< class OMT > 00195 bool BitmapFont< OMT >::_initWGL( const std::string&, const uint32_t ) 00196 { 00197 return false; 00198 } 00199 #endif 00200 00201 #ifdef AGL 00202 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00203 template< class OMT > 00204 bool BitmapFont< OMT >::_initAGL( const std::string& name, const uint32_t size ) 00205 { 00206 AGLContext context = aglGetCurrentContext(); 00207 EQASSERT( context ); 00208 if( !context ) 00209 { 00210 EQWARN << "No AGL context current" << std::endl; 00211 return false; 00212 } 00213 00214 CFStringRef cfFontName; 00215 if( name.empty( )) 00216 cfFontName = CFStringCreateWithCString( kCFAllocatorDefault, "Georgia", 00217 kCFStringEncodingMacRoman ); 00218 else 00219 cfFontName = 00220 CFStringCreateWithCString( kCFAllocatorDefault, name.c_str(), 00221 kCFStringEncodingMacRoman ); 00222 00223 ATSFontFamilyRef font = ATSFontFamilyFindFromName( cfFontName, 00224 kATSOptionFlagsDefault ); 00225 CFRelease( cfFontName ); 00226 00227 if( font == 0 ) 00228 { 00229 EQWARN << "Can't load font " << name << ", using Georgia" << std::endl; 00230 cfFontName = 00231 CFStringCreateWithCString( kCFAllocatorDefault, "Georgia", 00232 kCFStringEncodingMacRoman ); 00233 00234 font = ATSFontFamilyFindFromName( cfFontName, kATSOptionFlagsDefault ); 00235 CFRelease( cfFontName ); 00236 } 00237 EQASSERT( font ); 00238 00239 const GLuint lists = _setupLists( 127 ); 00240 if( !aglUseFont( context, font, normal, size, 0, 256, (long)lists )) 00241 { 00242 _setupLists( 0 ); 00243 return false; 00244 } 00245 00246 return true; 00247 } 00248 #pragma GCC diagnostic warning "-Wdeprecated-declarations" 00249 #else 00250 template< class OMT > 00251 bool BitmapFont< OMT >::_initAGL( const std::string&, const uint32_t ) 00252 { 00253 return false; 00254 } 00255 #endif 00256 00257 template< class OMT > 00258 uint32_t BitmapFont< OMT >::_setupLists( const int num ) 00259 { 00260 GLuint lists = _gl.getList( _key ); 00261 if( lists != ObjectManager< OMT >::INVALID ) 00262 _gl.deleteList( _key ); 00263 00264 if( num == 0 ) 00265 lists = ObjectManager< OMT >::INVALID; 00266 else 00267 { 00268 lists = _gl.newList( _key, num ); 00269 EQASSERT( lists != ObjectManager< OMT >::INVALID ); 00270 } 00271 return lists; 00272 } 00273 00274 template< class OMT > 00275 void BitmapFont< OMT >::draw( const std::string& text ) const 00276 { 00277 const GLuint lists = _gl.getList( _key ); 00278 EQASSERTINFO( lists != ObjectManager< OMT >::INVALID, 00279 "Font not initialized" ); 00280 00281 if( lists != ObjectManager< OMT >::INVALID ) 00282 { 00283 glListBase( lists ); 00284 glCallLists( GLsizei( text.size( )), GL_UNSIGNED_BYTE, text.c_str( )); 00285 glListBase( 0 ); 00286 } 00287 } 00288 } 00289 }