1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/x11/font.cpp 
   3 // Purpose:     wxFont class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "font.h" 
  25 #pragma message disable nosimpint 
  26 #include "wx/vms_x_fix.h" 
  30 #pragma message enable nosimpint 
  34 #include "wx/string.h" 
  36 #include "wx/gdicmn.h" 
  37 #include "wx/utils.h"       // for wxGetDisplay() 
  38 #include "wx/fontutil.h"    // for wxNativeFontInfo 
  39 #include "wx/tokenzr.h" 
  40 #include "wx/settings.h" 
  41 #include "wx/x11/private.h" 
  43 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
) 
  45 // ---------------------------------------------------------------------------- 
  47 // ---------------------------------------------------------------------------- 
  49 // For every wxFont, there must be a font for each display and scale requested. 
  50 // So these objects are stored in wxFontRefData::m_fonts 
  51 class wxXFont 
: public wxObject
 
  57     WXFontStructPtr     m_fontStruct
;   // XFontStruct 
  58     WXDisplay
*          m_display
;      // XDisplay 
  59     int                 m_scale
;        // Scale * 100 
  62 class wxFontRefData
: public wxGDIRefData
 
  67     wxFontRefData(int size 
= wxDEFAULT
, 
  68                   int family 
= wxDEFAULT
, 
  69                   int style 
= wxDEFAULT
, 
  70                   int weight 
= wxDEFAULT
, 
  71                   bool underlined 
= FALSE
, 
  72                   const wxString
& faceName 
= wxEmptyString
, 
  73                   wxFontEncoding encoding 
= wxFONTENCODING_DEFAULT
) 
  75         Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
); 
  78     wxFontRefData(const wxFontRefData
& data
) 
  80         Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
, 
  81              data
.m_underlined
, data
.m_faceName
, data
.m_encoding
); 
  87     // common part of all ctors 
  93               const wxString
& faceName
, 
  94               wxFontEncoding encoding
); 
 103     wxFontEncoding m_encoding
; 
 105     wxNativeFontInfo m_nativeFontInfo
; 
 107     // A list of wxXFonts 
 111 // ============================================================================ 
 113 // ============================================================================ 
 115 // ---------------------------------------------------------------------------- 
 117 // ---------------------------------------------------------------------------- 
 121     m_fontStruct 
= (WXFontStructPtr
) 0; 
 122     m_display 
= (WXDisplay
*) 0; 
 128     // TODO: why does freeing the font produce a segv??? 
 129     // Note that XFreeFont wasn't called in wxWin 1.68 either. 
 130     // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct; 
 131     //        XFreeFont((Display*) m_display, fontStruct); 
 134 // ---------------------------------------------------------------------------- 
 136 // ---------------------------------------------------------------------------- 
 138 void wxFontRefData::Init(int pointSize
, 
 143                          const wxString
& faceName
, 
 144                          wxFontEncoding encoding
) 
 146     if (family 
== wxDEFAULT
) 
 151     m_faceName 
= faceName
; 
 153     if (style 
== wxDEFAULT
) 
 158     if (weight 
== wxDEFAULT
) 
 163     if (pointSize 
== wxDEFAULT
) 
 166         m_pointSize 
= pointSize
; 
 168     m_underlined 
= underlined
; 
 169     m_encoding 
= encoding
; 
 172 wxFontRefData::~wxFontRefData() 
 174     wxNode
* node 
= m_fonts
.First(); 
 177         wxXFont
* f 
= (wxXFont
*) node
->Data(); 
 184 // ---------------------------------------------------------------------------- 
 186 // ---------------------------------------------------------------------------- 
 188 wxFont::wxFont(const wxNativeFontInfo
& info
) 
 192     (void)Create(info
.GetXFontName()); 
 199 bool wxFont::Create(int pointSize
, 
 204                     const wxString
& faceName
, 
 205                     wxFontEncoding encoding
) 
 208     m_refData 
= new wxFontRefData(pointSize
, family
, style
, weight
, 
 209                                   underlined
, faceName
, encoding
); 
 216 bool wxFont::Create(const wxString
& fontname
, wxFontEncoding enc
) 
 220         *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
); 
 224     m_refData 
= new wxFontRefData(); 
 226     M_FONTDATA
->m_nativeFontInfo
.SetXFontName(fontname
);  // X font name 
 230     wxStringTokenizer 
tn( fontname
, wxT("-") ); 
 232     tn
.GetNextToken();                           // skip initial empty token 
 233     tn
.GetNextToken();                           // foundry 
 236     M_FONTDATA
->m_faceName 
= tn
.GetNextToken();  // family 
 238     tmp 
= tn
.GetNextToken().MakeUpper();         // weight 
 239     if (tmp 
== wxT("BOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 240     if (tmp 
== wxT("BLACK")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 241     if (tmp 
== wxT("EXTRABOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 242     if (tmp 
== wxT("DEMIBOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 243     if (tmp 
== wxT("ULTRABOLD")) M_FONTDATA
->m_weight 
= wxBOLD
; 
 245     if (tmp 
== wxT("LIGHT")) M_FONTDATA
->m_weight 
= wxLIGHT
; 
 246     if (tmp 
== wxT("THIN")) M_FONTDATA
->m_weight 
= wxLIGHT
; 
 248     tmp 
= tn
.GetNextToken().MakeUpper();        // slant 
 249     if (tmp 
== wxT("I")) M_FONTDATA
->m_style 
= wxITALIC
; 
 250     if (tmp 
== wxT("O")) M_FONTDATA
->m_style 
= wxITALIC
; 
 252     tn
.GetNextToken();                           // set width 
 253     tn
.GetNextToken();                           // add. style 
 254     tn
.GetNextToken();                           // pixel size 
 256     tmp 
= tn
.GetNextToken();                     // pointsize 
 259         long num 
= wxStrtol (tmp
.c_str(), (wxChar 
**) NULL
, 10); 
 260         M_FONTDATA
->m_pointSize 
= (int)(num 
/ 10); 
 263     tn
.GetNextToken();                           // x-res 
 264     tn
.GetNextToken();                           // y-res 
 266     tmp 
= tn
.GetNextToken().MakeUpper();         // spacing 
 269         M_FONTDATA
->m_family 
= wxMODERN
; 
 270     else if (M_FONTDATA
->m_faceName 
== wxT("TIMES")) 
 271         M_FONTDATA
->m_family 
= wxROMAN
; 
 272     else if (M_FONTDATA
->m_faceName 
== wxT("HELVETICA")) 
 273         M_FONTDATA
->m_family 
= wxSWISS
; 
 274     else if (M_FONTDATA
->m_faceName 
== wxT("LUCIDATYPEWRITER")) 
 275         M_FONTDATA
->m_family 
= wxTELETYPE
; 
 276     else if (M_FONTDATA
->m_faceName 
== wxT("LUCIDA")) 
 277         M_FONTDATA
->m_family 
= wxDECORATIVE
; 
 278     else if (M_FONTDATA
->m_faceName 
== wxT("UTOPIA")) 
 279         M_FONTDATA
->m_family 
= wxSCRIPT
; 
 281     tn
.GetNextToken();                           // avg width 
 283     // deal with font encoding 
 284     M_FONTDATA
->m_encoding 
= enc
; 
 285     if ( M_FONTDATA
->m_encoding 
== wxFONTENCODING_SYSTEM 
) 
 287         wxString registry 
= tn
.GetNextToken().MakeUpper(), 
 288                  encoding 
= tn
.GetNextToken().MakeUpper(); 
 290         if ( registry 
== _T("ISO8859") ) 
 293             if ( wxSscanf(encoding
, wxT("%d"), &cp
) == 1 ) 
 295                 M_FONTDATA
->m_encoding 
= 
 296                     (wxFontEncoding
)(wxFONTENCODING_ISO8859_1 
+ cp 
- 1); 
 299         else if ( registry 
== _T("MICROSOFT") ) 
 302             if ( wxSscanf(encoding
, wxT("cp125%d"), &cp
) == 1 ) 
 304                 M_FONTDATA
->m_encoding 
= 
 305                     (wxFontEncoding
)(wxFONTENCODING_CP1250 
+ cp
); 
 308         else if ( registry 
== _T("KOI8") ) 
 310             M_FONTDATA
->m_encoding 
= wxFONTENCODING_KOI8
; 
 312         //else: unknown encoding - may be give a warning here? 
 323 // ---------------------------------------------------------------------------- 
 324 // change the font attributes 
 325 // ---------------------------------------------------------------------------- 
 327 void wxFont::Unshare() 
 329     // Don't change shared data 
 332         m_refData 
= new wxFontRefData(); 
 336         wxFontRefData
* ref 
= new wxFontRefData(*(wxFontRefData
*)m_refData
); 
 342 void wxFont::SetPointSize(int pointSize
) 
 346     M_FONTDATA
->m_pointSize 
= pointSize
; 
 347     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 352 void wxFont::SetFamily(int family
) 
 356     M_FONTDATA
->m_family 
= family
; 
 357     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 362 void wxFont::SetStyle(int style
) 
 366     M_FONTDATA
->m_style 
= style
; 
 367     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 372 void wxFont::SetWeight(int weight
) 
 376     M_FONTDATA
->m_weight 
= weight
; 
 377     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 382 void wxFont::SetFaceName(const wxString
& faceName
) 
 386     M_FONTDATA
->m_faceName 
= faceName
; 
 387     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 392 void wxFont::SetUnderlined(bool underlined
) 
 396     M_FONTDATA
->m_underlined 
= underlined
; 
 401 void wxFont::SetEncoding(wxFontEncoding encoding
) 
 405     M_FONTDATA
->m_encoding 
= encoding
; 
 406     M_FONTDATA
->m_nativeFontInfo
.GetXFontName().Clear(); // invalid now 
 411 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
) 
 415     M_FONTDATA
->m_nativeFontInfo 
= info
; 
 418 // ---------------------------------------------------------------------------- 
 419 // query font attributes 
 420 // ---------------------------------------------------------------------------- 
 422 int wxFont::GetPointSize() const 
 424     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 426     return M_FONTDATA
->m_pointSize
; 
 429 wxString 
wxFont::GetFaceName() const 
 431     wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") ); 
 433     return M_FONTDATA
->m_faceName 
; 
 436 int wxFont::GetFamily() const 
 438     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 440     return M_FONTDATA
->m_family
; 
 443 int wxFont::GetStyle() const 
 445     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 447     return M_FONTDATA
->m_style
; 
 450 int wxFont::GetWeight() const 
 452     wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); 
 454     return M_FONTDATA
->m_weight
; 
 457 bool wxFont::GetUnderlined() const 
 459     wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") ); 
 461     return M_FONTDATA
->m_underlined
; 
 464 wxFontEncoding 
wxFont::GetEncoding() const 
 466     wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") ); 
 468     return M_FONTDATA
->m_encoding
; 
 471 wxNativeFontInfo 
*wxFont::GetNativeFontInfo() const 
 473     wxCHECK_MSG( Ok(), (wxNativeFontInfo 
*)NULL
, wxT("invalid font") ); 
 475     if(M_FONTDATA
->m_nativeFontInfo
.GetXFontName().IsEmpty()) 
 478     return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
); 
 481 // ---------------------------------------------------------------------------- 
 482 // real implementation 
 483 // ---------------------------------------------------------------------------- 
 485 // Find an existing, or create a new, XFontStruct 
 486 // based on this wxFont and the given scale. Append the 
 487 // font to list in the private data for future reference. 
 488 wxXFont
* wxFont::GetInternalFont(double scale
, WXDisplay
* display
) const 
 491         return (wxXFont 
*)NULL
; 
 493     long intScale 
= long(scale 
* 100.0 + 0.5); // key for wxXFont 
 494     int pointSize 
= (M_FONTDATA
->m_pointSize 
* 10 * intScale
) / 100; 
 496     // search existing fonts first 
 497     wxNode
* node 
= M_FONTDATA
->m_fonts
.First(); 
 500         wxXFont
* f 
= (wxXFont
*) node
->Data(); 
 501         if ((!display 
|| (f
->m_display 
== display
)) && (f
->m_scale 
== intScale
)) 
 506     // not found, create a new one 
 507     XFontStruct 
*font 
= (XFontStruct 
*) 
 508                         wxLoadQueryNearestFont(pointSize
, 
 509                                                M_FONTDATA
->m_family
, 
 511                                                M_FONTDATA
->m_weight
, 
 512                                                M_FONTDATA
->m_underlined
, 
 514                                                M_FONTDATA
->m_encoding
); 
 518         wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") ); 
 520         return (wxXFont
*) NULL
; 
 523     wxXFont
* f 
= new wxXFont
; 
 524     f
->m_fontStruct 
= (WXFontStructPtr
)font
; 
 525     f
->m_display 
= ( display 
? display 
: wxGetDisplay() ); 
 526     f
->m_scale 
= intScale
; 
 527     M_FONTDATA
->m_fonts
.Append(f
); 
 532 WXFontStructPtr 
wxFont::GetFontStruct(double scale
, WXDisplay
* display
) const 
 534     wxXFont
* f 
= GetInternalFont(scale
, display
); 
 536     return (f 
? f
->m_fontStruct 
: (WXFontStructPtr
) 0);