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 licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "fontutil.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  32     #include "wx/font.h" // wxFont enums 
  33     #include "wx/encinfo.h" 
  36 #include "wx/fontutil.h" 
  37 #include "wx/fontmap.h" 
  38 #include "wx/tokenzr.h" 
  40 #include "wx/module.h" 
  44 #include "pango/pango.h" 
  47 #include "wx/gtk/private.h" 
  49 #include "wx/x11/private.h" 
  52 // ---------------------------------------------------------------------------- 
  54 // ---------------------------------------------------------------------------- 
  56 void wxNativeFontInfo::Init() 
  62 wxNativeFontInfo::Init(const wxNativeFontInfo
& info
) 
  65         description 
= pango_font_description_copy(info
.description
); 
  70 void wxNativeFontInfo::Free() 
  73         pango_font_description_free(description
); 
  76 int wxNativeFontInfo::GetPointSize() const 
  78     return pango_font_description_get_size( description 
) / PANGO_SCALE
; 
  81 wxFontStyle 
wxNativeFontInfo::GetStyle() const 
  83     wxFontStyle m_style 
= wxFONTSTYLE_NORMAL
; 
  85     switch (pango_font_description_get_style( description 
)) 
  87         case PANGO_STYLE_NORMAL
: 
  88             m_style 
= wxFONTSTYLE_NORMAL
; 
  90         case PANGO_STYLE_ITALIC
: 
  91             m_style 
= wxFONTSTYLE_ITALIC
; 
  93         case PANGO_STYLE_OBLIQUE
: 
  94             m_style 
= wxFONTSTYLE_SLANT
; 
 101 wxFontWeight 
wxNativeFontInfo::GetWeight() const 
 104     // We seem to currently initialize only by string. 
 105     // In that case PANGO_FONT_MASK_WEIGHT is always set. 
 106     if (!(pango_font_description_get_set_fields(description
) & PANGO_FONT_MASK_WEIGHT
)) 
 107         return wxFONTWEIGHT_NORMAL
; 
 110     PangoWeight pango_weight 
= pango_font_description_get_weight( description 
); 
 112     // Until the API can be changed the following ranges of weight values are used: 
 113     // wxFONTWEIGHT_LIGHT:  100 .. 349 - range of 250 
 114     // wxFONTWEIGHT_NORMAL: 350 .. 599 - range of 250 
 115     // wxFONTWEIGHT_BOLD:   600 .. 900 - range of 301 (600 is "semibold" already) 
 117     if (pango_weight 
>= 600) 
 118         return wxFONTWEIGHT_BOLD
; 
 120     if (pango_weight 
< 350) 
 121         return wxFONTWEIGHT_LIGHT
; 
 123     return wxFONTWEIGHT_NORMAL
; 
 126 bool wxNativeFontInfo::GetUnderlined() const 
 131 wxString 
wxNativeFontInfo::GetFaceName() const 
 133     wxString tmp 
= wxGTK_CONV_BACK( pango_font_description_get_family( description 
) ); 
 138 wxFontFamily 
wxNativeFontInfo::GetFamily() const 
 140     return wxFONTFAMILY_SWISS
; 
 143 wxFontEncoding 
wxNativeFontInfo::GetEncoding() const 
 145     return wxFONTENCODING_SYSTEM
; 
 149 void wxNativeFontInfo::SetPointSize(int WXUNUSED(pointsize
)) 
 151     wxFAIL_MSG( _T("not implemented") ); 
 154 void wxNativeFontInfo::SetStyle(wxFontStyle 
WXUNUSED(style
)) 
 156     wxFAIL_MSG( _T("not implemented") ); 
 159 void wxNativeFontInfo::SetWeight(wxFontWeight 
WXUNUSED(weight
)) 
 161     wxFAIL_MSG( _T("not implemented") ); 
 164 void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined
)) 
 166     wxFAIL_MSG( _T("not implemented") ); 
 169 void wxNativeFontInfo::SetFaceName(wxString 
WXUNUSED(facename
)) 
 171     wxFAIL_MSG( _T("not implemented") ); 
 174 void wxNativeFontInfo::SetFamily(wxFontFamily 
WXUNUSED(family
)) 
 176     wxFAIL_MSG( _T("not implemented") ); 
 179 void wxNativeFontInfo::SetEncoding(wxFontEncoding 
WXUNUSED(encoding
)) 
 181     wxFAIL_MSG( _T("not implemented") ); 
 186 bool wxNativeFontInfo::FromString(const wxString
& s
) 
 189         pango_font_description_free( description 
); 
 191     description 
= pango_font_description_from_string( wxGTK_CONV( s 
) ); 
 196 wxString 
wxNativeFontInfo::ToString() const 
 198     char *str 
= pango_font_description_to_string( description 
); 
 199     wxString tmp 
= wxGTK_CONV_BACK(  str 
); 
 205 bool wxNativeFontInfo::FromUserString(const wxString
& s
) 
 207     return FromString( s 
); 
 210 wxString 
wxNativeFontInfo::ToUserString() const 
 215 // ---------------------------------------------------------------------------- 
 216 // wxNativeEncodingInfo 
 217 // ---------------------------------------------------------------------------- 
 219 bool wxNativeEncodingInfo::FromString(const wxString
& s
) 
 224 wxString 
wxNativeEncodingInfo::ToString() const 
 226     return wxEmptyString
; 
 229 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
) 
 234 bool wxGetNativeFontEncoding(wxFontEncoding encoding
, 
 235                              wxNativeEncodingInfo 
*info
) 
 237     // we *must* return true for default encoding as otherwise wxFontMapper 
 238     // considers that we can't load any font and aborts with wxLogFatalError! 
 239     if ( encoding 
== wxFONTENCODING_SYSTEM 
) 
 241         info
->facename
.clear(); 
 242         info
->encoding 
= wxFONTENCODING_SYSTEM
; 
 245     // pretend that we support everything, it's better than to always return 
 246     // false as the old code did 
 254         #pragma message disable nosimpint 
 257     #include <X11/Xlib.h> 
 260         #pragma message enable nosimpint 
 263     #include "wx/utils.h"       // for wxGetDisplay() 
 264 #elif defined(__WXGTK__) 
 265     // we have to declare struct tm to avoid problems with first forward 
 266     // declaring it in C code (glib.h included from gdk.h does it) and then 
 267     // defining it when time.h is included from the headers below - this is 
 268     // known not to work at least with Sun CC 6.01 
 275 // ---------------------------------------------------------------------------- 
 277 // ---------------------------------------------------------------------------- 
 279 static wxHashTable 
*g_fontHash 
= (wxHashTable
*) NULL
; 
 281 // ---------------------------------------------------------------------------- 
 283 // ---------------------------------------------------------------------------- 
 285 // define the functions to create and destroy native fonts for this toolkit 
 287     wxNativeFont 
wxLoadFont(const wxString
& fontSpec
) 
 289         return XLoadQueryFont((Display 
*)wxGetDisplay(), fontSpec
); 
 292     inline void wxFreeFont(wxNativeFont font
) 
 294         XFreeFont((Display 
*)wxGetDisplay(), (XFontStruct 
*)font
); 
 296 #elif defined(__WXGTK__) 
 297     wxNativeFont 
wxLoadFont(const wxString
& fontSpec
) 
 299         // VZ: we should use gdk_fontset_load() instead of gdk_font_load() 
 300         //     here to be able to display Japanese fonts correctly (at least 
 301         //     this is what people report) but unfortunately doing it results 
 302         //     in tons of warnings when using GTK with "normal" European 
 303         //     languages and so we can't always do it and I don't know enough 
 304         //     to determine when should this be done... (FIXME) 
 305         return gdk_font_load( wxConvertWX2MB(fontSpec
) ); 
 308     inline void wxFreeFont(wxNativeFont font
) 
 310         gdk_font_unref(font
); 
 313     #error "Unknown GUI toolkit" 
 316 static bool wxTestFontSpec(const wxString
& fontspec
); 
 318 static wxNativeFont 
wxLoadQueryFont(int pointSize
, 
 323                                     const wxString
& facename
, 
 324                                     const wxString
& xregistry
, 
 325                                     const wxString
& xencoding
, 
 326                                     wxString
* xFontName
); 
 328 // ============================================================================ 
 330 // ============================================================================ 
 332 // ---------------------------------------------------------------------------- 
 333 // wxNativeEncodingInfo 
 334 // ---------------------------------------------------------------------------- 
 336 // convert to/from the string representation: format is 
 337 //      encodingid;registry;encoding[;facename] 
 338 bool wxNativeEncodingInfo::FromString(const wxString
& s
) 
 340     // use ";", not "-" because it may be part of encoding name 
 341     wxStringTokenizer 
tokenizer(s
, _T(";")); 
 343     wxString encid 
= tokenizer
.GetNextToken(); 
 345     if ( !encid
.ToLong(&enc
) ) 
 347     encoding 
= (wxFontEncoding
)enc
; 
 349     xregistry 
= tokenizer
.GetNextToken(); 
 353     xencoding 
= tokenizer
.GetNextToken(); 
 358     facename 
= tokenizer
.GetNextToken(); 
 363 wxString 
wxNativeEncodingInfo::ToString() const 
 366     s 
<< (long)encoding 
<< _T(';') << xregistry 
<< _T(';') << xencoding
; 
 369         s 
<< _T(';') << facename
; 
 375 // ---------------------------------------------------------------------------- 
 377 // ---------------------------------------------------------------------------- 
 379 void wxNativeFontInfo::Init() 
 384 bool wxNativeFontInfo::FromString(const wxString
& s
) 
 386     wxStringTokenizer 
tokenizer(s
, _T(";")); 
 389     wxString token 
= tokenizer
.GetNextToken(); 
 390     if ( token 
!= _T('0') ) 
 393     xFontName 
= tokenizer
.GetNextToken(); 
 395     // this should be the end 
 396     if ( tokenizer
.HasMoreTokens() ) 
 399     return FromXFontName(xFontName
); 
 402 wxString 
wxNativeFontInfo::ToString() const 
 405     return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str()); 
 408 bool wxNativeFontInfo::FromUserString(const wxString
& s
) 
 410     return FromXFontName(s
); 
 413 wxString 
wxNativeFontInfo::ToUserString() const 
 415     return GetXFontName(); 
 418 bool wxNativeFontInfo::HasElements() const 
 420     // we suppose that the foundry is never empty, so if it is it means that we 
 421     // had never parsed the XLFD 
 422     return !fontElements
[0].empty(); 
 425 wxString 
wxNativeFontInfo::GetXFontComponent(wxXLFDField field
) const 
 427     wxCHECK_MSG( field 
< wxXLFD_MAX
, _T(""), _T("invalid XLFD field") ); 
 429     if ( !HasElements() ) 
 432         if ( !((wxNativeFontInfo 
*)this)->FromXFontName(xFontName
) ) 
 436     return fontElements
[field
]; 
 439 bool wxNativeFontInfo::FromXFontName(const wxString
& fontname
) 
 441     // TODO: we should be able to handle the font aliases here, but how? 
 442     wxStringTokenizer 
tokenizer(fontname
, _T("-")); 
 444     // skip the leading, usually empty field (font name registry) 
 445     if ( !tokenizer
.HasMoreTokens() ) 
 448     (void)tokenizer
.GetNextToken(); 
 450     for ( size_t n 
= 0; n 
< WXSIZEOF(fontElements
); n
++ ) 
 452         if ( !tokenizer
.HasMoreTokens() ) 
 454             // not enough elements in the XLFD - or maybe an alias 
 458         wxString field 
= tokenizer
.GetNextToken(); 
 459         if ( !field
.empty() && field 
!= _T('*') ) 
 461             // we're really initialized now 
 465         fontElements
[n
] = field
; 
 468     // this should be all 
 469     if ( tokenizer
.HasMoreTokens() ) 
 475 wxString 
wxNativeFontInfo::GetXFontName() const 
 477     if ( xFontName
.empty() ) 
 479         for ( size_t n 
= 0; n 
< WXSIZEOF(fontElements
); n
++ ) 
 481             // replace the non specified elements with '*' except for the 
 482             // additional style which is usually just omitted 
 483             wxString elt 
= fontElements
[n
]; 
 484             if ( elt
.empty() && n 
!= wxXLFD_ADDSTYLE 
) 
 490             ((wxNativeFontInfo 
*)this)->xFontName 
<< _T('-') << elt
; 
 498 wxNativeFontInfo::SetXFontComponent(wxXLFDField field
, const wxString
& value
) 
 500     wxCHECK_RET( field 
< wxXLFD_MAX
, _T("invalid XLFD field") ); 
 502     // this class should be initialized with a valid font spec first and only 
 503     // then the fields may be modified! 
 504     wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") ); 
 506     if ( !HasElements() ) 
 509         if ( !((wxNativeFontInfo 
*)this)->FromXFontName(xFontName
) ) 
 511             wxFAIL_MSG( _T("can't set font element for invalid XLFD") ); 
 517     fontElements
[field
] = value
; 
 519     // invalidate the XFLD, it doesn't correspond to the font elements any more 
 523 void wxNativeFontInfo::SetXFontName(const wxString
& xFontName_
) 
 525     // invalidate the font elements, GetXFontComponent() will reparse the XLFD 
 526     fontElements
[0].clear(); 
 528     xFontName 
= xFontName_
; 
 533 int wxNativeFontInfo::GetPointSize() const 
 535     const wxString s 
= GetXFontComponent(wxXLFD_POINTSIZE
); 
 537     // return -1 to indicate that the size is unknown 
 539     return s
.ToLong(&l
) ? l 
: -1; 
 542 wxFontStyle 
wxNativeFontInfo::GetStyle() const 
 544     const wxString s 
= GetXFontComponent(wxXLFD_SLANT
); 
 546     if ( s
.length() != 1 ) 
 548         // it is really unknown but we don't have any way to return it from 
 550         return wxFONTSTYLE_NORMAL
; 
 556             // again, unknown but consider normal by default 
 559             return wxFONTSTYLE_NORMAL
; 
 562             return wxFONTSTYLE_ITALIC
; 
 565             return wxFONTSTYLE_SLANT
; 
 569 wxFontWeight 
wxNativeFontInfo::GetWeight() const 
 571     const wxString s 
= GetXFontComponent(wxXLFD_WEIGHT
).MakeLower(); 
 572     if ( s
.find(_T("bold")) != wxString::npos 
|| s 
== _T("black") ) 
 573         return wxFONTWEIGHT_BOLD
; 
 574     else if ( s 
== _T("light") ) 
 575         return wxFONTWEIGHT_LIGHT
; 
 577     return wxFONTWEIGHT_NORMAL
; 
 580 bool wxNativeFontInfo::GetUnderlined() const 
 582     // X fonts are never underlined 
 586 wxString 
wxNativeFontInfo::GetFaceName() const 
 588     // wxWidgets facename probably more accurately corresponds to X family 
 589     return GetXFontComponent(wxXLFD_FAMILY
); 
 592 wxFontFamily 
wxNativeFontInfo::GetFamily() const 
 594     // and wxWidgets family -- to X foundry, but we have to translate it to 
 595     // wxFontFamily somehow... 
 596     wxFAIL_MSG(_T("not implemented")); // GetXFontComponent(wxXLFD_FOUNDRY); 
 598     return wxFONTFAMILY_DEFAULT
; 
 601 wxFontEncoding 
wxNativeFontInfo::GetEncoding() const 
 603     // we already have the code for this but need to refactor it first 
 604     wxFAIL_MSG( _T("not implemented") ); 
 606     return wxFONTENCODING_MAX
; 
 609 void wxNativeFontInfo::SetPointSize(int pointsize
) 
 611     SetXFontComponent(wxXLFD_POINTSIZE
, wxString::Format(_T("%d"), pointsize
)); 
 614 void wxNativeFontInfo::SetStyle(wxFontStyle style
) 
 619         case wxFONTSTYLE_ITALIC
: 
 623         case wxFONTSTYLE_SLANT
: 
 627         case wxFONTSTYLE_NORMAL
: 
 631             wxFAIL_MSG( _T("unknown wxFontStyle in wxNativeFontInfo::SetStyle") ); 
 635     SetXFontComponent(wxXLFD_SLANT
, s
); 
 638 void wxNativeFontInfo::SetWeight(wxFontWeight weight
) 
 643         case wxFONTWEIGHT_BOLD
: 
 647         case wxFONTWEIGHT_LIGHT
: 
 651         case wxFONTWEIGHT_NORMAL
: 
 656             wxFAIL_MSG( _T("unknown wxFontWeight in wxNativeFontInfo::SetWeight") ); 
 660     SetXFontComponent(wxXLFD_WEIGHT
, s
); 
 663 void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined
)) 
 665     // can't do this under X 
 668 void wxNativeFontInfo::SetFaceName(wxString facename
) 
 670     SetXFontComponent(wxXLFD_FAMILY
, facename
); 
 673 void wxNativeFontInfo::SetFamily(wxFontFamily family
) 
 675     // wxFontFamily -> X foundry, anyone? 
 676     wxFAIL_MSG( _T("not implemented") ); 
 678     // SetXFontComponent(wxXLFD_FOUNDRY, ...); 
 681 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding
) 
 683     wxNativeEncodingInfo info
; 
 684     if ( wxGetNativeFontEncoding(encoding
, &info
) ) 
 686         SetXFontComponent(wxXLFD_ENCODING
, info
.xencoding
); 
 687         SetXFontComponent(wxXLFD_REGISTRY
, info
.xregistry
); 
 691 // ---------------------------------------------------------------------------- 
 693 // ---------------------------------------------------------------------------- 
 695 bool wxGetNativeFontEncoding(wxFontEncoding encoding
, 
 696                              wxNativeEncodingInfo 
*info
) 
 698     wxCHECK_MSG( info
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") ); 
 700     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
 702         encoding 
= wxFont::GetDefaultEncoding(); 
 707         case wxFONTENCODING_ISO8859_1
: 
 708         case wxFONTENCODING_ISO8859_2
: 
 709         case wxFONTENCODING_ISO8859_3
: 
 710         case wxFONTENCODING_ISO8859_4
: 
 711         case wxFONTENCODING_ISO8859_5
: 
 712         case wxFONTENCODING_ISO8859_6
: 
 713         case wxFONTENCODING_ISO8859_7
: 
 714         case wxFONTENCODING_ISO8859_8
: 
 715         case wxFONTENCODING_ISO8859_9
: 
 716         case wxFONTENCODING_ISO8859_10
: 
 717         case wxFONTENCODING_ISO8859_11
: 
 718         case wxFONTENCODING_ISO8859_12
: 
 719         case wxFONTENCODING_ISO8859_13
: 
 720         case wxFONTENCODING_ISO8859_14
: 
 721         case wxFONTENCODING_ISO8859_15
: 
 723                 int cp 
= encoding 
- wxFONTENCODING_ISO8859_1 
+ 1; 
 724                 info
->xregistry 
= wxT("iso8859"); 
 725                 info
->xencoding
.Printf(wxT("%d"), cp
); 
 729         case wxFONTENCODING_UTF8
: 
 730             info
->xregistry 
= wxT("iso10646"); 
 731             info
->xencoding 
= wxT("*"); 
 734         case wxFONTENCODING_GB2312
: 
 735             info
->xregistry 
= wxT("GB2312");   // or the otherway round? 
 736             info
->xencoding 
= wxT("*"); 
 739         case wxFONTENCODING_KOI8
: 
 740         case wxFONTENCODING_KOI8_U
: 
 741             info
->xregistry 
= wxT("koi8"); 
 743             // we don't make distinction between koi8-r, koi8-u and koi8-ru (so far) 
 744             info
->xencoding 
= wxT("*"); 
 747         case wxFONTENCODING_CP1250
: 
 748         case wxFONTENCODING_CP1251
: 
 749         case wxFONTENCODING_CP1252
: 
 750         case wxFONTENCODING_CP1253
: 
 751         case wxFONTENCODING_CP1254
: 
 752         case wxFONTENCODING_CP1255
: 
 753         case wxFONTENCODING_CP1256
: 
 754         case wxFONTENCODING_CP1257
: 
 756                 int cp 
= encoding 
- wxFONTENCODING_CP1250 
+ 1250; 
 757                 info
->xregistry 
= wxT("microsoft"); 
 758                 info
->xencoding
.Printf(wxT("cp%d"), cp
); 
 762         case wxFONTENCODING_SYSTEM
: 
 764             info
->xencoding 
= wxT("*"); 
 768             // don't know how to translate this encoding into X fontspec 
 772     info
->encoding 
= encoding
; 
 777 bool wxTestFontEncoding(const wxNativeEncodingInfo
& info
) 
 780     fontspec
.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"), 
 781                     !info
.facename 
? _T("*") : info
.facename
.c_str(), 
 782                     info
.xregistry
.c_str(), 
 783                     info
.xencoding
.c_str()); 
 785     return wxTestFontSpec(fontspec
); 
 788 // ---------------------------------------------------------------------------- 
 789 // X-specific functions 
 790 // ---------------------------------------------------------------------------- 
 792 wxNativeFont 
wxLoadQueryNearestFont(int pointSize
, 
 797                                     const wxString 
&facename
, 
 798                                     wxFontEncoding encoding
, 
 801     if ( encoding 
== wxFONTENCODING_DEFAULT 
) 
 803         encoding 
= wxFont::GetDefaultEncoding(); 
 806     // first determine the encoding - if the font doesn't exist at all in this 
 807     // encoding, it's useless to do all other approximations (i.e. size, 
 808     // family &c don't matter much) 
 809     wxNativeEncodingInfo info
; 
 810     if ( encoding 
== wxFONTENCODING_SYSTEM 
) 
 812         // This will always work so we don't test to save time 
 813         wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM
, &info
); 
 817         if ( !wxGetNativeFontEncoding(encoding
, &info
) || 
 818              !wxTestFontEncoding(info
) ) 
 821             if ( !wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) ) 
 822 #endif // wxUSE_FONTMAP 
 824                 // unspported encoding - replace it with the default 
 826                 // NB: we can't just return 0 from here because wxGTK code doesn't 
 827                 //     check for it (i.e. it supposes that we'll always succeed), 
 828                 //     so it would provoke a crash 
 829                 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM
, &info
); 
 834     // OK, we have the correct xregistry/xencoding in info structure 
 835     wxNativeFont font 
= 0; 
 837     // if we already have the X font name, try to use it 
 838     if( xFontName 
&& !xFontName
->IsEmpty() ) 
 841         //  Make sure point size is correct for scale factor. 
 843         wxStringTokenizer 
tokenizer(*xFontName
, _T("-"), wxTOKEN_RET_DELIMS
); 
 844         wxString newFontName
; 
 846         for(int i 
= 0; i 
< 8; i
++) 
 847           newFontName 
+= tokenizer
.NextToken(); 
 849         (void) tokenizer
.NextToken(); 
 851         newFontName 
+= wxString::Format(wxT("%d-"), pointSize
); 
 853         while(tokenizer
.HasMoreTokens()) 
 854           newFontName 
+= tokenizer
.GetNextToken(); 
 856         font 
= wxLoadFont(newFontName
); 
 859           *xFontName 
= newFontName
; 
 864         // search up and down by stepsize 10 
 865         int max_size 
= pointSize 
+ 20 * (1 + (pointSize
/180)); 
 866         int min_size 
= pointSize 
- 20 * (1 + (pointSize
/180)); 
 868         int i
, round
; // counters 
 870         // first round: search for equal, then for smaller and for larger size with the given weight and style 
 871         int testweight 
= weight
; 
 872         int teststyle 
= style
; 
 874         for ( round 
= 0; round 
< 3; round
++ ) 
 876             // second round: use normal weight 
 879                 if ( testweight 
!= wxNORMAL 
) 
 881                     testweight 
= wxNORMAL
; 
 885                     ++round
; // fall through to third round 
 889             // third round: ... and use normal style 
 892                 if ( teststyle 
!= wxNORMAL 
) 
 894                     teststyle 
= wxNORMAL
; 
 901             // Search for equal or smaller size (approx.) 
 902             for ( i 
= pointSize
; !font 
&& i 
>= 10 && i 
>= min_size
; i 
-= 10 ) 
 904                 font 
= wxLoadQueryFont(i
, family
, teststyle
, testweight
, underlined
, 
 905                                    facename
, info
.xregistry
, info
.xencoding
, 
 909         // Search for larger size (approx.) 
 910         for ( i 
= pointSize 
+ 10; !font 
&& i 
<= max_size
; i 
+= 10 ) 
 912                 font 
= wxLoadQueryFont(i
, family
, teststyle
, testweight
, underlined
, 
 913                                    facename
, info
.xregistry
, info
.xencoding
, 
 918         // Try default family 
 919         if ( !font 
&& family 
!= wxDEFAULT 
) 
 921             font 
= wxLoadQueryFont(pointSize
, wxDEFAULT
, style
, weight
, 
 922                                    underlined
, facename
, 
 923                                    info
.xregistry
, info
.xencoding
, 
 927         // ignore size, family, style and weight but try to find font with the 
 928         // given facename and encoding 
 931             font 
= wxLoadQueryFont(120, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 932                                    underlined
, facename
, 
 933                                    info
.xregistry
, info
.xencoding
, 
 936             // ignore family as well 
 939                 font 
= wxLoadQueryFont(120, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 940                                        underlined
, wxEmptyString
, 
 941                                        info
.xregistry
, info
.xencoding
, 
 944                 // if it still failed, try to get the font of any size but 
 945                 // with the requested encoding: this can happen if the 
 946                 // encoding is only available in one size which happens to be 
 947                 // different from 120 
 950                     font 
= wxLoadQueryFont(-1, wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 951                                            FALSE
, wxEmptyString
, 
 952                                            info
.xregistry
, info
.xencoding
, 
 955                     // this should never happen as we had tested for it in the 
 956                     // very beginning, but if it does, do return something non 
 957                     // NULL or we'd crash in wxFont code 
 960                         wxFAIL_MSG( _T("this encoding should be available!") ); 
 962                         font 
= wxLoadQueryFont(-1, 
 963                                                wxDEFAULT
, wxNORMAL
, wxNORMAL
, 
 964                                                FALSE
, wxEmptyString
, 
 976 // ---------------------------------------------------------------------------- 
 978 // ---------------------------------------------------------------------------- 
 980 // returns TRUE if there are any fonts matching this font spec 
 981 static bool wxTestFontSpec(const wxString
& fontspec
) 
 983     // some X servers will fail to load this font because there are too many 
 984     // matches so we must test explicitly for this 
 985     if ( fontspec 
== _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") ) 
 990     wxNativeFont test 
= (wxNativeFont
) g_fontHash
->Get( fontspec 
); 
 996     test 
= wxLoadFont(fontspec
); 
 997     g_fontHash
->Put( fontspec
, (wxObject
*) test 
); 
1011 static wxNativeFont 
wxLoadQueryFont(int pointSize
, 
1015                                     bool WXUNUSED(underlined
), 
1016                                     const wxString
& facename
, 
1017                                     const wxString
& xregistry
, 
1018                                     const wxString
& xencoding
, 
1019                                     wxString
* xFontName
) 
1024         case wxDECORATIVE
: xfamily 
= wxT("lucida"); break; 
1025         case wxROMAN
:      xfamily 
= wxT("times");  break; 
1026         case wxMODERN
:     xfamily 
= wxT("courier"); break; 
1027         case wxSWISS
:      xfamily 
= wxT("helvetica"); break; 
1028         case wxTELETYPE
:   xfamily 
= wxT("lucidatypewriter"); break; 
1029         case wxSCRIPT
:     xfamily 
= wxT("utopia"); break; 
1030         default:           xfamily 
= wxT("*"); 
1038                  xweight 
= MWLF_WEIGHT_BOLD
; 
1043                  xweight 
= MWLF_WEIGHT_LIGHT
; 
1048                  xweight 
= MWLF_WEIGHT_NORMAL
; 
1054                  xweight 
= MWLF_WEIGHT_DEFAULT
; 
1058     GR_SCREEN_INFO screenInfo
; 
1059     GrGetScreenInfo(& screenInfo
); 
1061     int yPixelsPerCM 
= screenInfo
.ydpcm
; 
1063     // A point is 1/72 of an inch. 
1064     // An inch is 2.541 cm. 
1065     // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels) 
1066     // In fact pointSize is 10 * the normal point size so 
1069     int pixelHeight 
= (int) ( (((float)pointSize
) / 720.0) * 2.541 * (float) yPixelsPerCM
) ; 
1071     // An alternative: assume that the screen is 72 dpi. 
1072     //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ; 
1073     //int pixelHeight = (int) ((float)pointSize / 10.0) ; 
1076     logFont
.lfHeight 
= pixelHeight
; 
1077     logFont
.lfWidth 
= 0; 
1078     logFont
.lfEscapement 
= 0; 
1079     logFont
.lfOrientation 
= 0; 
1080     logFont
.lfWeight 
= xweight
; 
1081     logFont
.lfItalic 
= (style 
== wxNORMAL 
? 0 : 1) ; 
1082     logFont
.lfUnderline 
= 0; 
1083     logFont
.lfStrikeOut 
= 0; 
1084     logFont
.lfCharSet 
= MWLF_CHARSET_DEFAULT
; // TODO: select appropriate one 
1085     logFont
.lfOutPrecision 
= MWLF_TYPE_DEFAULT
; 
1086     logFont
.lfClipPrecision 
= 0; // Not used 
1087     logFont
.lfRoman 
= (family 
== wxROMAN 
? 1 : 0) ; 
1088     logFont
.lfSerif 
= (family 
== wxSWISS 
? 0 : 1) ; 
1089     logFont
.lfSansSerif 
= !logFont
.lfSerif 
; 
1090     logFont
.lfModern 
= (family 
== wxMODERN 
? 1 : 0) ; 
1091     logFont
.lfProportional 
= (family 
== wxTELETYPE 
? 0 : 1) ; 
1092     logFont
.lfOblique 
= 0; 
1093     logFont
.lfSmallCaps 
= 0; 
1094     logFont
.lfPitch 
= 0; // 0 = default 
1095     strcpy(logFont
.lfFaceName
, facename
.c_str()); 
1097     XFontStruct
* fontInfo 
= (XFontStruct
*) malloc(sizeof(XFontStruct
)); 
1098     fontInfo
->fid 
= GrCreateFont((GR_CHAR
*) facename
.c_str(), pixelHeight
, & logFont
); 
1099     GrGetFontInfo(fontInfo
->fid
, & fontInfo
->info
); 
1100     return (wxNativeFont
) fontInfo
; 
1104     if (!facename
.IsEmpty()) 
1106         fontSpec
.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"), 
1109         if ( wxTestFontSpec(fontSpec
) ) 
1113         //else: no such family, use default one instead 
1120             fontSpec
.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), 
1122             if ( wxTestFontSpec(fontSpec
) ) 
1127             // fall through - try wxITALIC now 
1130             fontSpec
.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"), 
1132             if ( wxTestFontSpec(fontSpec
) ) 
1136             else if ( style 
== wxITALIC 
) // and not wxSLANT 
1139                 fontSpec
.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), 
1141                 if ( wxTestFontSpec(fontSpec
) ) 
1147                     // no italic, no slant - leave default 
1154             wxFAIL_MSG(_T("unknown font style")); 
1155             // fall back to normal 
1167                   fontSpec
.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"), 
1169                   if ( wxTestFontSpec(fontSpec
) ) 
1171                        xweight 
= wxT("bold"); 
1174                   fontSpec
.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"), 
1176                   if ( wxTestFontSpec(fontSpec
) ) 
1178                        xweight 
= wxT("heavy"); 
1181                   fontSpec
.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"), 
1183                   if ( wxTestFontSpec(fontSpec
) ) 
1185                       xweight 
= wxT("extrabold"); 
1188                   fontSpec
.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"), 
1190                   if ( wxTestFontSpec(fontSpec
) ) 
1192                       xweight 
= wxT("demibold"); 
1195                   fontSpec
.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"), 
1197                   if ( wxTestFontSpec(fontSpec
) ) 
1199                       xweight 
= wxT("black"); 
1202                   fontSpec
.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"), 
1204                   if ( wxTestFontSpec(fontSpec
) ) 
1206                       xweight 
= wxT("ultrablack"); 
1213                   fontSpec
.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"), 
1215                   if ( wxTestFontSpec(fontSpec
) ) 
1217                        xweight 
= wxT("light"); 
1220                   fontSpec
.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"), 
1222                   if ( wxTestFontSpec(fontSpec
) ) 
1224                        xweight 
= wxT("thin"); 
1231                   fontSpec
.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"), 
1233                   if ( wxTestFontSpec(fontSpec
) ) 
1235                        xweight 
= wxT("medium"); 
1238                   fontSpec
.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"), 
1240                   if ( wxTestFontSpec(fontSpec
) ) 
1242                        xweight 
= wxT("normal"); 
1245                   fontSpec
.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"), 
1247                   if ( wxTestFontSpec(fontSpec
) ) 
1249                       xweight 
= wxT("regular"); 
1255         default:           xweight 
= wxT("*"); break; 
1258     // if pointSize is -1, don't specify any 
1260     if ( pointSize 
== -1 ) 
1266         sizeSpec
.Printf(_T("%d"), pointSize
); 
1269     // construct the X font spec from our data 
1270     fontSpec
.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"), 
1271                     xfamily
.c_str(), xweight
.c_str(), xstyle
.c_str(), 
1272                     sizeSpec
.c_str(), xregistry
.c_str(), xencoding
.c_str()); 
1275         *xFontName 
= fontSpec
; 
1277     return wxLoadFont(fontSpec
); 
1282 // ---------------------------------------------------------------------------- 
1284 // ---------------------------------------------------------------------------- 
1286 class wxFontModule 
: public wxModule
 
1293     DECLARE_DYNAMIC_CLASS(wxFontModule
) 
1296 IMPLEMENT_DYNAMIC_CLASS(wxFontModule
, wxModule
) 
1298 bool wxFontModule::OnInit() 
1300     g_fontHash 
= new wxHashTable( wxKEY_STRING 
); 
1305 void wxFontModule::OnExit() 
1309     g_fontHash 
= (wxHashTable 
*)NULL
; 
1312 #endif // GTK 2.0/1.x