1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // ============================================================================ 
  12 // ============================================================================ 
  14 // ---------------------------------------------------------------------------- 
  16 // ---------------------------------------------------------------------------- 
  19     #pragma implementation "font.h" 
  23 #include "wx/fontutil.h" 
  24 #include "wx/cmndata.h" 
  27 #include "wx/gdicmn.h" 
  28 #include "wx/tokenzr.h" 
  29 #include "wx/settings.h" 
  34 #include <gdk/gdkprivate.h> 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 class wxFontRefData 
: public wxObjectRefData
 
  44     wxFontRefData(int size 
= wxDEFAULT
, 
  45                   int family 
= wxDEFAULT
, 
  46                   int style 
= wxDEFAULT
, 
  47                   int weight 
= wxDEFAULT
, 
  48                   bool underlined 
= FALSE
, 
  49                   const wxString
& faceName 
= wxEmptyString
, 
  50                   wxFontEncoding encoding 
= wxFONTENCODING_DEFAULT
); 
  51     wxFontRefData( const wxFontRefData
& data 
); 
  52     virtual ~wxFontRefData(); 
  55     // common part of all ctors 
  56     void Init(int pointSize
, 
  61               const wxString
& faceName
, 
  62               wxFontEncoding encoding
); 
  65     wxList          m_scaled_xfonts
; 
  72     wxFontEncoding  m_encoding
; 
  74     wxNativeFontInfo m_nativeFontInfo
; 
  79 // ============================================================================ 
  81 // ============================================================================ 
  83 // ---------------------------------------------------------------------------- 
  85 // ---------------------------------------------------------------------------- 
  87 void wxFontRefData::Init(int pointSize
, 
  92                          const wxString
& faceName
, 
  93                          wxFontEncoding encoding
) 
  95     if (family 
== wxDEFAULT
) 
 100     m_faceName 
= faceName
; 
 102     if (style 
== wxDEFAULT
) 
 107     if (weight 
== wxDEFAULT
) 
 112     if (pointSize 
== wxDEFAULT
) 
 115         m_pointSize 
= pointSize
; 
 117     m_underlined 
= underlined
; 
 118     m_encoding 
= encoding
; 
 121 wxFontRefData::wxFontRefData( const wxFontRefData
& data 
) 
 122     : m_scaled_xfonts(wxKEY_INTEGER
) 
 124     Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
, 
 125          data
.m_underlined
, data
.m_faceName
, data
.m_encoding
); 
 128 wxFontRefData::wxFontRefData(int size
, int family
, int style
, 
 129                              int weight
, bool underlined
, 
 130                              const wxString
& faceName
, 
 131                              wxFontEncoding encoding
) 
 132     : m_scaled_xfonts(wxKEY_INTEGER
) 
 134     Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
); 
 137 wxFontRefData::~wxFontRefData() 
 139     wxNode 
*node 
= m_scaled_xfonts
.First(); 
 142         GdkFont 
*font 
= (GdkFont
*)node
->Data(); 
 143         wxNode 
*next 
= node
->Next(); 
 144         gdk_font_unref( font 
); 
 149 // ---------------------------------------------------------------------------- 
 151 // ---------------------------------------------------------------------------- 
 153 bool wxNativeFontInfo::FromString(const wxString
& s
) 
 155     wxStringTokenizer 
tokenizer(s
, _T(";")); 
 157     wxString token 
= tokenizer
.GetNextToken(); 
 159     //  Ignore the version for now 
 162     xFontName 
= tokenizer
.GetNextToken(); 
 169 wxString 
wxNativeFontInfo::ToString() const 
 173     s
.Printf(_T("%d;%s"), 
 180 // ---------------------------------------------------------------------------- 
 182 // ---------------------------------------------------------------------------- 
 184 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
) 
 189         wxTheFontList
->Append( this ); 
 192 wxFont::wxFont(const wxNativeFontInfo
& info
) 
 196     Create(info
.xFontName
); 
 199 bool wxFont::Create(const wxNativeFontInfo
& info
) 
 201     return Create(info
.xFontName
); 
 204 bool wxFont::Create( int pointSize
, 
 209                      const wxString
& face
, 
 210                      wxFontEncoding encoding
) 
 212     m_refData 
= new wxFontRefData(pointSize
, family
, style
, weight
, 
 213                                   underlined
, face
, encoding
); 
 218 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
) 
 222          *this = wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
); 
 226     m_refData 
= new wxFontRefData(); 
 228     M_FONTDATA
->m_nativeFontInfo
.xFontName 
= fontname
;  // X font name 
 232     wxStringTokenizer 
tn( fontname
, wxT("-") ); 
 234     tn
.GetNextToken();                           // skip initial empty token 
 235     tn
.GetNextToken();                           // foundry 
 238     M_FONTDATA
->m_faceName 
= tn
.GetNextToken();  // family 
 240     tmp 
= tn
.GetNextToken().MakeUpper();         // weight 
 241     if (tmp 
== wxT("BOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 242     if (tmp 
== wxT("BLACK")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 243     if (tmp 
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 244     if (tmp 
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 245     if (tmp 
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 247     if (tmp 
== wxT("LIGHT")) M_FONTDATA
->m_weight 
= wxLIGHT
; 
 248     if (tmp 
== wxT("THIN")) M_FONTDATA
->m_weight 
= wxLIGHT
; 
 250     tmp 
= tn
.GetNextToken().MakeUpper();        // slant 
 251     if (tmp 
== wxT("I")) M_FONTDATA
->m_style 
= wxITALIC
; 
 252     if (tmp 
== wxT("O")) M_FONTDATA
->m_style 
= wxITALIC
; 
 254     tn
.GetNextToken();                           // set width 
 255     tn
.GetNextToken();                           // add. style 
 256     tn
.GetNextToken();                           // pixel size 
 258     tmp 
= tn
.GetNextToken();                     // pointsize 
 261         long num 
= wxStrtol (tmp
.c_str(), (wxChar 
**) NULL
, 10); 
 262         M_FONTDATA
->m_pointSize 
= (int)(num 
/ 10); 
 265     tn
.GetNextToken();                           // x-res 
 266     tn
.GetNextToken();                           // y-res 
 268     tmp 
= tn
.GetNextToken().MakeUpper();         // spacing 
 271         M_FONTDATA
->m_family 
= wxMODERN
; 
 272     else if (M_FONTDATA
->m_faceName 
== wxT("TIMES")) 
 273         M_FONTDATA
->m_family 
= wxROMAN
; 
 274     else if (M_FONTDATA
->m_faceName 
== wxT("HELVETICA")) 
 275         M_FONTDATA
->m_family 
= wxSWISS
; 
 276     else if (M_FONTDATA
->m_faceName 
== wxT("LUCIDATYPEWRITER")) 
 277         M_FONTDATA
->m_family 
= wxTELETYPE
; 
 278     else if (M_FONTDATA
->m_faceName 
== wxT("LUCIDA")) 
 279         M_FONTDATA
->m_family 
= wxDECORATIVE
; 
 280     else if (M_FONTDATA
->m_faceName 
== wxT("UTOPIA")) 
 281         M_FONTDATA
->m_family 
= wxSCRIPT
; 
 283     tn
.GetNextToken();                           // avg width 
 285     // deal with font encoding 
 286     M_FONTDATA
->m_encoding 
= enc
; 
 287     if ( M_FONTDATA
->m_encoding 
== wxFONTENCODING_SYSTEM 
) 
 289         wxString registry 
= tn
.GetNextToken().MakeUpper(), 
 290                  encoding 
= tn
.GetNextToken().MakeUpper(); 
 292         if ( registry 
== _T("ISO8859") ) 
 295             if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 ) 
 297                 M_FONTDATA
->m_encoding 
= 
 298                     (wxFontEncoding
)(wxFONTENCODING_ISO8859_1 
+ cp 
- 1); 
 301         else if ( registry 
== _T("MICROSOFT") ) 
 304             if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 ) 
 306                 M_FONTDATA
->m_encoding 
= 
 307                     (wxFontEncoding
)(wxFONTENCODING_CP1250 
+ cp
); 
 310         else if ( registry 
== _T("KOI8") ) 
 312             M_FONTDATA
->m_encoding 
= wxFONTENCODING_KOI8
; 
 314         //else: unknown encoding - may be give a warning here? 
 321 void wxFont::Unshare() 
 325         m_refData 
= new wxFontRefData(); 
 329         wxFontRefData
* ref 
= new wxFontRefData(*(wxFontRefData
*)m_refData
); 
 338         wxTheFontList
->DeleteObject( this ); 
 341 // ---------------------------------------------------------------------------- 
 343 // ---------------------------------------------------------------------------- 
 345 int wxFont::GetPointSize() const 
 347     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 349     return M_FONTDATA
->m_pointSize
; 
 352 wxString 
wxFont::GetFaceName() const 
 354     wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") ); 
 356     return M_FONTDATA
->m_faceName
; 
 359 int wxFont::GetFamily() const 
 361     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 363     return M_FONTDATA
->m_family
; 
 366 int wxFont::GetStyle() const 
 368     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 370     return M_FONTDATA
->m_style
; 
 373 int wxFont::GetWeight() const 
 375     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 377     return M_FONTDATA
->m_weight
; 
 380 bool wxFont::GetUnderlined() const 
 382     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") ); 
 384     return M_FONTDATA
->m_underlined
; 
 388 wxFontEncoding 
wxFont::GetEncoding() const 
 390     wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") ); 
 392     return M_FONTDATA
->m_encoding
; 
 395 wxNativeFontInfo 
*wxFont::GetNativeFontInfo() const 
 397     wxCHECK_MSG( Ok(), (wxNativeFontInfo 
*)NULL
, wxT("invalid font") ); 
 399     if(M_FONTDATA
->m_nativeFontInfo
.xFontName
.IsEmpty()) 
 402     return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
); 
 406 // ---------------------------------------------------------------------------- 
 407 // change font attributes 
 408 // ---------------------------------------------------------------------------- 
 410 void wxFont::SetPointSize(int pointSize
) 
 414     M_FONTDATA
->m_pointSize 
= pointSize
; 
 415     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 418 void wxFont::SetFamily(int family
) 
 422     M_FONTDATA
->m_family 
= family
; 
 423     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 426 void wxFont::SetStyle(int style
) 
 430     M_FONTDATA
->m_style 
= style
; 
 431     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 434 void wxFont::SetWeight(int weight
) 
 438     M_FONTDATA
->m_weight 
= weight
; 
 439     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 442 void wxFont::SetFaceName(const wxString
& faceName
) 
 446     M_FONTDATA
->m_faceName 
= faceName
; 
 447     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 450 void wxFont::SetUnderlined(bool underlined
) 
 454     M_FONTDATA
->m_underlined 
= underlined
; 
 457 void wxFont::SetEncoding(wxFontEncoding encoding
) 
 461     M_FONTDATA
->m_encoding 
= encoding
; 
 462     M_FONTDATA
->m_nativeFontInfo
.xFontName
.Clear();            // invalid now 
 465 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
) 
 469     M_FONTDATA
->m_nativeFontInfo 
= info
; 
 472 // ---------------------------------------------------------------------------- 
 473 // get internal representation of font 
 474 // ---------------------------------------------------------------------------- 
 476 static GdkFont 
*g_systemDefaultGuiFont 
= (GdkFont
*) NULL
; 
 478 GdkFont 
*GtkGetDefaultGuiFont() 
 480     if (!g_systemDefaultGuiFont
) 
 482         GtkWidget 
*widget 
= gtk_button_new(); 
 483         GtkStyle 
*def 
= gtk_rc_get_style( widget 
); 
 486             g_systemDefaultGuiFont 
= gdk_font_ref( def
->font 
); 
 490             def 
= gtk_widget_get_default_style(); 
 492                 g_systemDefaultGuiFont 
= gdk_font_ref( def
->font 
); 
 494         gtk_widget_destroy( widget 
); 
 498         // already have it, but ref it once more before returning 
 499         gdk_font_ref(g_systemDefaultGuiFont
); 
 502     return g_systemDefaultGuiFont
; 
 505 GdkFont 
*wxFont::GetInternalFont( float scale 
) const 
 509         wxFAIL_MSG( wxT("invalid font") ); 
 511         return (GdkFont
*) NULL
; 
 514     long int_scale 
= long(scale 
* 100.0 + 0.5); /* key for fontlist */ 
 515     int point_scale 
= (int)((M_FONTDATA
->m_pointSize 
* 10 * int_scale
) / 100); 
 516     GdkFont 
*font 
= (GdkFont 
*) NULL
; 
 518     wxNode 
*node 
= M_FONTDATA
->m_scaled_xfonts
.Find(int_scale
); 
 521         font 
= (GdkFont
*)node
->Data(); 
 525         if (*this == wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
)) 
 527             font 
= GtkGetDefaultGuiFont(); 
 531             font 
= wxLoadQueryNearestFont( point_scale
, 
 532                                            M_FONTDATA
->m_family
, 
 534                                            M_FONTDATA
->m_weight
, 
 535                                            M_FONTDATA
->m_underlined
, 
 536                                            M_FONTDATA
->m_faceName
, 
 537                                            M_FONTDATA
->m_encoding
, 
 538                                            &M_FONTDATA
->m_nativeFontInfo
.xFontName 
); 
 541         M_FONTDATA
->m_scaled_xfonts
.Append( int_scale
, (wxObject
*)font 
); 
 544     // it's quite useless to make it a wxCHECK because we're going to crash 
 546     wxASSERT_MSG( font
, wxT("could not load any font?") );