1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        unix/fontutil.cpp 
   3 // Purpose:     Font helper functions for X11 (GDK/X) 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) Vadim Zeitlin 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "fontutil.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  36         #pragma message disable nosimpint 
  42         #pragma message enable nosimpint 
  45     #include "wx/utils.h"       // for wxGetDisplay() 
  46 #elif defined(__WXGTK__) 
  47     // we have to declare struct tm to avoid problems with first forward 
  48     // declaring it in C code (glib.h included from gdk.h does it) and then 
  49     // defining it when time.h is included from the headers below - this is 
  50     // known not to work at least with Sun CC 6.01 
  56 #include "wx/fontutil.h" 
  57 #include "wx/fontmap.h" 
  58 #include "wx/tokenzr.h" 
  60 #include "wx/module.h" 
  62 // ---------------------------------------------------------------------------- 
  64 // ---------------------------------------------------------------------------- 
  66 static wxHashTable 
*g_fontHash 
= (wxHashTable
*) NULL
; 
  68 // ---------------------------------------------------------------------------- 
  70 // ---------------------------------------------------------------------------- 
  72 // define the functions to create and destroy native fonts for this toolkit 
  74     wxNativeFont 
wxLoadFont(const wxString
& fontSpec
) 
  76         return XLoadQueryFont((Display 
*)wxGetDisplay(), fontSpec
); 
  79     inline void wxFreeFont(wxNativeFont font
) 
  81         XFreeFont((Display 
*)wxGetDisplay(), (XFontStruct 
*)font
); 
  83 #elif defined(__WXGTK__) 
  84     wxNativeFont 
wxLoadFont(const wxString
& fontSpec
) 
  86        return gdk_font_load( wxConvertWX2MB(fontSpec
) ); 
  89     inline void wxFreeFont(wxNativeFont font
) 
  94     #error "Unknown GUI toolkit" 
  97 static bool wxTestFontSpec(const wxString
& fontspec
); 
  99 static wxNativeFont 
wxLoadQueryFont(int pointSize
, 
 104                                     const wxString
& facename
, 
 105                                     const wxString
& xregistry
, 
 106                                     const wxString
& xencoding
, 
 107                                     wxString
* xFontName
); 
 109 // ============================================================================ 
 111 // ============================================================================ 
 113 // ---------------------------------------------------------------------------- 
 114 // wxNativeEncodingInfo 
 115 // ---------------------------------------------------------------------------- 
 117 // convert to/from the string representation: format is 
 118 //      encodingid;registry;encoding[;facename] 
 119 bool wxNativeEncodingInfo::FromString(const wxString
& s
) 
 121     // use ";", not "-" because it may be part of encoding name 
 122     wxStringTokenizer 
tokenizer(s
, _T(";")); 
 124     wxString encid 
= tokenizer
.GetNextToken(); 
 126     if ( !encid
.ToLong(&enc
) ) 
 128     encoding 
= (wxFontEncoding
)enc
; 
 130     xregistry 
= tokenizer
.GetNextToken(); 
 134     xencoding 
= tokenizer
.GetNextToken(); 
 139     facename 
= tokenizer
.GetNextToken(); 
 144 wxString 
wxNativeEncodingInfo::ToString() const 
 147     s 
<< (long)encoding 
<< _T(';') << xregistry 
<< _T(';') << xencoding
; 
 150         s 
<< _T(';') << facename
; 
 156 // ---------------------------------------------------------------------------- 
 158 // ---------------------------------------------------------------------------- 
 160 void wxNativeFontInfo::Init() 
 165 bool wxNativeFontInfo::FromString(const wxString
& s
) 
 167     wxStringTokenizer 
tokenizer(s
, _T(";")); 
 170     wxString token 
= tokenizer
.GetNextToken(); 
 171     if ( token 
!= _T('0') ) 
 174     xFontName 
= tokenizer
.GetNextToken(); 
 176     // this should be the end 
 177     if ( tokenizer
.HasMoreTokens() ) 
 180     return FromXFontName(xFontName
); 
 183 wxString 
wxNativeFontInfo::ToString() const 
 186     return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str()); 
 189 bool wxNativeFontInfo::FromUserString(const wxString
& s
) 
 191     return FromXFontName(s
); 
 194 wxString 
wxNativeFontInfo::ToUserString() const 
 196     return GetXFontName(); 
 199 bool wxNativeFontInfo::HasElements() const 
 201     // we suppose that the foundry is never empty, so if it is it means that we 
 202     // had never parsed the XLFD 
 203     return !fontElements
[0].empty(); 
 206 wxString 
wxNativeFontInfo::GetXFontComponent(wxXLFDField field
) const 
 208     wxCHECK_MSG( field 
< wxXLFD_MAX
, _T(""), _T("invalid XLFD field") ); 
 210     if ( !HasElements() ) 
 213         if ( !((wxNativeFontInfo 
*)this)->FromXFontName(xFontName
) ) 
 217     return fontElements
[field
]; 
 220 bool wxNativeFontInfo::FromXFontName(const wxString
& fontname
) 
 222     // TODO: we should be able to handle the font aliases here, but how? 
 223     wxStringTokenizer 
tokenizer(fontname
, _T("-")); 
 225     // skip the leading, usually empty field (font name registry) 
 226     if ( !tokenizer
.HasMoreTokens() ) 
 229     (void)tokenizer
.GetNextToken(); 
 231     for ( size_t n 
= 0; n 
< WXSIZEOF(fontElements
); n
++ ) 
 233         if ( !tokenizer
.HasMoreTokens() ) 
 235             // not enough elements in the XLFD - or maybe an alias 
 239         fontElements
[n
] = tokenizer
.GetNextToken(); 
 242     // this should be all 
 243     return !tokenizer
.HasMoreTokens(); 
 246 wxString 
wxNativeFontInfo::GetXFontName() const 
 248     if ( xFontName
.empty() ) 
 250         for ( size_t n 
= 0; n 
< WXSIZEOF(fontElements
); n
++ ) 
 252             // replace the non specified elements with '*' except for the 
 253             // additional style which is usually just omitted 
 254             wxString elt 
= fontElements
[n
]; 
 255             if ( elt
.empty() && n 
!= wxXLFD_ADDSTYLE 
) 
 261             ((wxNativeFontInfo 
*)this)->xFontName 
<< _T('-') << elt
; 
 269 wxNativeFontInfo::SetXFontComponent(wxXLFDField field
, const wxString
& value
) 
 271     wxCHECK_RET( field 
< wxXLFD_MAX
, _T("invalid XLFD field") ); 
 273     // this class should be initialized with a valid font spec first and only 
 274     // then the fields may be modified! 
 275     wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") ); 
 277     if ( !HasElements() ) 
 280         if ( !((wxNativeFontInfo 
*)this)->FromXFontName(xFontName
) ) 
 282             wxFAIL_MSG( _T("can't set font element for invalid XLFD") ); 
 288     fontElements
[field
] = value
; 
 290     // invalidate the XFLD, it doesn't correspond to the font elements any more 
 294 void wxNativeFontInfo::SetXFontName(const wxString
& xFontName_
) 
 296     // invalidate the font elements, GetXFontComponent() will reparse the XLFD 
 297     fontElements
[0].clear(); 
 299     xFontName 
= xFontName_
; 
 304 // ---------------------------------------------------------------------------- 
 306 // ---------------------------------------------------------------------------- 
 308 bool wxGetNativeFontEncoding(wxFontEncoding encoding
, 
 309                              wxNativeEncodingInfo 
*info
) 
 311     wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") ); 
 313     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
 315         encoding 
= wxFont::GetDefaultEncoding(); 
 320         case wxFONTENCODING_ISO8859_1
: 
 321         case wxFONTENCODING_ISO8859_2
: 
 322         case wxFONTENCODING_ISO8859_3
: 
 323         case wxFONTENCODING_ISO8859_4
: 
 324         case wxFONTENCODING_ISO8859_5
: 
 325         case wxFONTENCODING_ISO8859_6
: 
 326         case wxFONTENCODING_ISO8859_7
: 
 327         case wxFONTENCODING_ISO8859_8
: 
 328         case wxFONTENCODING_ISO8859_9
: 
 329         case wxFONTENCODING_ISO8859_10
: 
 330         case wxFONTENCODING_ISO8859_11
: 
 331         case wxFONTENCODING_ISO8859_12
: 
 332         case wxFONTENCODING_ISO8859_13
: 
 333         case wxFONTENCODING_ISO8859_14
: 
 334         case wxFONTENCODING_ISO8859_15
: 
 336                 int cp 
= encoding 
- wxFONTENCODING_ISO8859_1 
+ 1; 
 337                 info
->xregistry 
= wxT("iso8859"); 
 338                 info
->xencoding
.Printf(wxT("%d"), cp
); 
 342         case wxFONTENCODING_UTF8
: 
 343             info
->xregistry 
= wxT("iso10646"); 
 344             info
->xencoding 
= wxT("*"); 
 347         case wxFONTENCODING_KOI8
: 
 348             info
->xregistry 
= wxT("koi8"); 
 350             // we don't make distinction between koi8-r, koi8-u and koi8-ru (so far) 
 351             info
->xencoding 
= wxT("*"); 
 354         case wxFONTENCODING_CP1250
: 
 355         case wxFONTENCODING_CP1251
: 
 356         case wxFONTENCODING_CP1252
: 
 357         case wxFONTENCODING_CP1253
: 
 358         case wxFONTENCODING_CP1254
: 
 359         case wxFONTENCODING_CP1255
: 
 360         case wxFONTENCODING_CP1256
: 
 361         case wxFONTENCODING_CP1257
: 
 363                 int cp 
= encoding 
- wxFONTENCODING_CP1250 
+ 1250; 
 364                 info
->xregistry 
= wxT("microsoft"); 
 365                 info
->xencoding
.Printf(wxT("cp%d"), cp
); 
 369         case wxFONTENCODING_SYSTEM
: 
 371             info
->xencoding 
= wxT("*"); 
 375             // don't know how to translate this encoding into X fontspec 
 379     info
->encoding 
= encoding
; 
 384 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
) 
 387     fontspec
.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"), 
 388                     !info
.facename 
? _T("*") : info
.facename
.c_str(), 
 389                     info
.xregistry
.c_str(), 
 390                     info
.xencoding
.c_str()); 
 392     return wxTestFontSpec(fontspec
); 
 395 // ---------------------------------------------------------------------------- 
 396 // X-specific functions 
 397 // ---------------------------------------------------------------------------- 
 399 wxNativeFont 
wxLoadQueryNearestFont(int pointSize
, 
 404                                     const wxString 
&facename
, 
 405                                     wxFontEncoding encoding
, 
 408     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
 410         encoding 
= wxFont::GetDefaultEncoding(); 
 413     // first determine the encoding - if the font doesn't exist at all in this 
 414     // encoding, it's useless to do all other approximations (i.e. size, 
 415     // family &c don't matter much) 
 416     wxNativeEncodingInfo info
; 
 417     if ( encoding 
== wxFONTENCODING_SYSTEM 
) 
 419         // This will always work so we don't test to save time 
 420         wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM
, &info
); 
 424         if ( !wxGetNativeFontEncoding(encoding
, &info
) || 
 425              !wxTestFontEncoding(info
) ) 
 428             if ( !wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) ) 
 429 #endif // wxUSE_FONTMAP 
 431                 // unspported encoding - replace it with the default 
 433                 // NB: we can't just return 0 from here because wxGTK code doesn't 
 434                 //     check for it (i.e. it supposes that we'll always succeed), 
 435                 //     so it would provoke a crash 
 436                 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM
, &info
); 
 441     // OK, we have the correct xregistry/xencoding in info structure 
 442     wxNativeFont font 
= 0; 
 444     // if we already have the X font name, try to use it 
 445     if( xFontName 
&& !xFontName
->IsEmpty() ) 
 448         //  Make sure point size is correct for scale factor. 
 450         wxStringTokenizer 
tokenizer(*xFontName
, _T("-"), wxTOKEN_RET_DELIMS
); 
 451         wxString newFontName
; 
 453         for(int i 
= 0; i 
< 8; i
++) 
 454           newFontName 
+= tokenizer
.NextToken(); 
 456         (void) tokenizer
.NextToken(); 
 458         newFontName 
+= wxString::Format("%d-", pointSize
); 
 460         while(tokenizer
.HasMoreTokens()) 
 461           newFontName 
+= tokenizer
.GetNextToken(); 
 463         font 
= wxLoadFont(newFontName
); 
 466           *xFontName 
= newFontName
; 
 469     // try to load exactly the font requested first 
 472         font 
= wxLoadQueryFont( pointSize
, family
, style
, weight
, 
 473                                 underlined
, facename
, 
 474                                 info
.xregistry
, info
.xencoding
, 
 480         // search up and down by stepsize 10 
 481         int max_size 
= pointSize 
+ 20 * (1 + (pointSize
/180)); 
 482         int min_size 
= pointSize 
- 20 * (1 + (pointSize
/180)); 
 486         // Search for smaller size (approx.) 
 487         for ( i 
= pointSize 
- 10; !font 
&& i 
>= 10 && i 
>= min_size
; i 
-= 10 ) 
 489             font 
= wxLoadQueryFont(i
, family
, style
, weight
, underlined
, 
 490                                    facename
, info
.xregistry
, info
.xencoding
, 
 494         // Search for larger size (approx.) 
 495         for ( i 
= pointSize 
+ 10; !font 
&& i 
<= max_size
; i 
+= 10 ) 
 497             font 
= wxLoadQueryFont(i
, family
, style
, weight
, underlined
, 
 498                                    facename
, info
.xregistry
, info
.xencoding
, 
 502         // Try default family 
 503         if ( !font 
&& family 
!= wxDEFAULT 
) 
 505             font 
= wxLoadQueryFont(pointSize
, wxDEFAULT
, style
, weight
, 
 506                                    underlined
, facename
, 
 507                                    info
.xregistry
, info
.xencoding
, 
 511         // ignore size, family, style and weight but try to find font with the 
 512         // given facename and encoding 
 515             font 
= wxLoadQueryFont(120, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 516                                    underlined
, facename
, 
 517                                    info
.xregistry
, info
.xencoding
, 
 520             // ignore family as well 
 523                 font 
= wxLoadQueryFont(120, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 524                                        underlined
, wxEmptyString
, 
 525                                        info
.xregistry
, info
.xencoding
, 
 528                 // if it still failed, try to get the font of any size but 
 529                 // with the requested encoding: this can happen if the 
 530                 // encoding is only available in one size which happens to be 
 531                 // different from 120 
 534                     font 
= wxLoadQueryFont(-1, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 535                                            FALSE
, wxEmptyString
, 
 536                                            info
.xregistry
, info
.xencoding
, 
 539                     // this should never happen as we had tested for it in the 
 540                     // very beginning, but if it does, do return something non 
 541                     // NULL or we'd crash in wxFont code 
 544                         wxFAIL_MSG( _T("this encoding should be available!") ); 
 546                         font 
= wxLoadQueryFont(-1, 
 547                                                wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 548                                                FALSE
, wxEmptyString
, 
 560 // ---------------------------------------------------------------------------- 
 562 // ---------------------------------------------------------------------------- 
 564 // returns TRUE if there are any fonts matching this font spec 
 565 static bool wxTestFontSpec(const wxString
& fontspec
) 
 567     // some X servers will fail to load this font because there are too many 
 568     // matches so we must test explicitly for this 
 569     if ( fontspec 
== _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") ) 
 574     wxNativeFont test 
= (wxNativeFont
) g_fontHash
->Get( fontspec 
); 
 580     test 
= wxLoadFont(fontspec
); 
 581     g_fontHash
->Put( fontspec
, (wxObject
*) test 
); 
 595 static wxNativeFont 
wxLoadQueryFont(int pointSize
, 
 599                                     bool WXUNUSED(underlined
), 
 600                                     const wxString
& facename
, 
 601                                     const wxString
& xregistry
, 
 602                                     const wxString
& xencoding
, 
 608         case wxDECORATIVE
: xfamily 
= wxT("lucida"); break; 
 609         case wxROMAN
:      xfamily 
= wxT("times");  break; 
 610         case wxMODERN
:     xfamily 
= wxT("courier"); break; 
 611         case wxSWISS
:      xfamily 
= wxT("helvetica"); break; 
 612         case wxTELETYPE
:   xfamily 
= wxT("lucidatypewriter"); break; 
 613         case wxSCRIPT
:     xfamily 
= wxT("utopia"); break; 
 614         default:           xfamily 
= wxT("*"); 
 622                  xweight 
= MWLF_WEIGHT_BOLD
; 
 627                  xweight 
= MWLF_WEIGHT_LIGHT
; 
 632                  xweight 
= MWLF_WEIGHT_NORMAL
; 
 638                  xweight 
= MWLF_WEIGHT_DEFAULT
; 
 642     GR_SCREEN_INFO screenInfo
; 
 643     GrGetScreenInfo(& screenInfo
); 
 645     int yPixelsPerCM 
= screenInfo
.ydpcm
; 
 647     // A point is 1/72 of an inch. 
 648     // An inch is 2.541 cm. 
 649     // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels) 
 650     // In fact pointSize is 10 * the normal point size so 
 653     int pixelHeight 
= (int) ( (((float)pointSize
) / 720.0) * 2.541 * (float) yPixelsPerCM
) ; 
 655     // An alternative: assume that the screen is 72 dpi. 
 656     //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ; 
 657     //int pixelHeight = (int) ((float)pointSize / 10.0) ; 
 660     logFont
.lfHeight 
= pixelHeight
; 
 662     logFont
.lfEscapement 
= 0; 
 663     logFont
.lfOrientation 
= 0; 
 664     logFont
.lfWeight 
= xweight
; 
 665     logFont
.lfItalic 
= (style 
== wxNORMAL 
? 0 : 1) ; 
 666     logFont
.lfUnderline 
= 0; 
 667     logFont
.lfStrikeOut 
= 0; 
 668     logFont
.lfCharSet 
= MWLF_CHARSET_DEFAULT
; // TODO: select appropriate one 
 669     logFont
.lfOutPrecision 
= MWLF_TYPE_DEFAULT
; 
 670     logFont
.lfClipPrecision 
= 0; // Not used 
 671     logFont
.lfRoman 
= (family 
== wxROMAN 
? 1 : 0) ; 
 672     logFont
.lfSerif 
= (family 
== wxSWISS 
? 0 : 1) ; 
 673     logFont
.lfSansSerif 
= !logFont
.lfSerif 
; 
 674     logFont
.lfModern 
= (family 
== wxMODERN 
? 1 : 0) ; 
 675     logFont
.lfProportional 
= (family 
== wxTELETYPE 
? 0 : 1) ; 
 676     logFont
.lfOblique 
= 0; 
 677     logFont
.lfSmallCaps 
= 0; 
 678     logFont
.lfPitch 
= 0; // 0 = default 
 679     strcpy(logFont
.lfFaceName
, facename
.c_str()); 
 681     XFontStruct
* fontInfo 
= (XFontStruct
*) malloc(sizeof(XFontStruct
)); 
 682     fontInfo
->fid 
= GrCreateFont((GR_CHAR
*) facename
.c_str(), pixelHeight
, & logFont
); 
 683     GrGetFontInfo(fontInfo
->fid
, & fontInfo
->info
); 
 684     return (wxNativeFont
) fontInfo
; 
 688     if (!facename
.IsEmpty()) 
 690         fontSpec
.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"), 
 693         if ( wxTestFontSpec(fontSpec
) ) 
 697         //else: no such family, use default one instead 
 704             fontSpec
.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), 
 706             if ( wxTestFontSpec(fontSpec
) ) 
 711             // fall through - try wxITALIC now 
 714             fontSpec
.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"), 
 716             if ( wxTestFontSpec(fontSpec
) ) 
 720             else if ( style 
== wxITALIC 
) // and not wxSLANT 
 723                 fontSpec
.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), 
 725                 if ( wxTestFontSpec(fontSpec
) ) 
 731                     // no italic, no slant - leave default 
 738             wxFAIL_MSG(_T("unknown font style")); 
 739             // fall back to normal 
 751                   fontSpec
.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"), 
 753                   if ( wxTestFontSpec(fontSpec
) ) 
 755                        xweight 
= wxT("bold"); 
 758                   fontSpec
.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"), 
 760                   if ( wxTestFontSpec(fontSpec
) ) 
 762                        xweight 
= wxT("heavy"); 
 765                   fontSpec
.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"), 
 767                   if ( wxTestFontSpec(fontSpec
) ) 
 769                       xweight 
= wxT("extrabold"); 
 772                   fontSpec
.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"), 
 774                   if ( wxTestFontSpec(fontSpec
) ) 
 776                       xweight 
= wxT("demibold"); 
 779                   fontSpec
.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"), 
 781                   if ( wxTestFontSpec(fontSpec
) ) 
 783                       xweight 
= wxT("black"); 
 786                   fontSpec
.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"), 
 788                   if ( wxTestFontSpec(fontSpec
) ) 
 790                       xweight 
= wxT("ultrablack"); 
 797                   fontSpec
.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"), 
 799                   if ( wxTestFontSpec(fontSpec
) ) 
 801                        xweight 
= wxT("light"); 
 804                   fontSpec
.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"), 
 806                   if ( wxTestFontSpec(fontSpec
) ) 
 808                        xweight 
= wxT("thin"); 
 815                   fontSpec
.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"), 
 817                   if ( wxTestFontSpec(fontSpec
) ) 
 819                        xweight 
= wxT("medium"); 
 822                   fontSpec
.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"), 
 824                   if ( wxTestFontSpec(fontSpec
) ) 
 826                        xweight 
= wxT("normal"); 
 829                   fontSpec
.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"), 
 831                   if ( wxTestFontSpec(fontSpec
) ) 
 833                       xweight 
= wxT("regular"); 
 839         default:           xweight 
= wxT("*"); break; 
 842     // if pointSize is -1, don't specify any 
 844     if ( pointSize 
== -1 ) 
 850         sizeSpec
.Printf(_T("%d"), pointSize
); 
 853     // construct the X font spec from our data 
 854     fontSpec
.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"), 
 855                     xfamily
.c_str(), xweight
.c_str(), xstyle
.c_str(), 
 856                     sizeSpec
.c_str(), xregistry
.c_str(), xencoding
.c_str()); 
 859         *xFontName 
= fontSpec
; 
 861     return wxLoadFont(fontSpec
); 
 866 // ---------------------------------------------------------------------------- 
 868 // ---------------------------------------------------------------------------- 
 870 class wxFontModule 
: public wxModule
 
 877     DECLARE_DYNAMIC_CLASS(wxFontModule
) 
 880 IMPLEMENT_DYNAMIC_CLASS(wxFontModule
, wxModule
) 
 882 bool wxFontModule::OnInit() 
 884     g_fontHash 
= new wxHashTable( wxKEY_STRING 
); 
 889 void wxFontModule::OnExit() 
 893     g_fontHash 
= (wxHashTable 
*)NULL
;