1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFont class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "font.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
40 #include "wx/fontutil.h"
41 #include "wx/tokenzr.h"
43 #include "wx/msw/private.h"
45 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 // the default font size in points
52 static const int wxDEFAULT_FONT_SIZE
= 12;
54 // ----------------------------------------------------------------------------
55 // wxFontRefData - the internal description of the font
56 // ----------------------------------------------------------------------------
58 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
60 friend class WXDLLEXPORT wxFont
;
65 Init(wxDEFAULT_FONT_SIZE
, wxDEFAULT
, wxNORMAL
, wxNORMAL
, FALSE
,
66 "", wxFONTENCODING_DEFAULT
);
69 wxFontRefData(const wxFontRefData
& data
)
71 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
72 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
74 m_fontId
= data
.m_fontId
;
77 wxFontRefData(int size
,
82 const wxString
& faceName
,
83 wxFontEncoding encoding
)
85 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
88 wxFontRefData(const wxNativeFontInfo
& info
)
93 virtual ~wxFontRefData();
96 // common part of all ctors
102 const wxString
& faceName
,
103 wxFontEncoding encoding
);
105 void Init(const wxNativeFontInfo
& info
);
107 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
108 // DELETED by destructor
113 // font characterstics
120 wxFontEncoding m_encoding
;
122 // Windows font handle
126 wxNativeFontInfo m_nativeFontInfo
;
127 bool m_nativeFontInfoOk
;
130 // ============================================================================
132 // ============================================================================
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 void wxFontRefData::Init(int pointSize
,
143 const wxString
& faceName
,
144 wxFontEncoding encoding
)
147 m_pointSize
= pointSize
;
151 m_underlined
= underlined
;
152 m_faceName
= faceName
;
153 m_encoding
= encoding
;
160 m_nativeFontInfoOk
= FALSE
;
163 void wxFontRefData::Init(const wxNativeFontInfo
& info
)
165 // extract family from pitch-and-family
166 int lfFamily
= info
.lf
.lfPitchAndFamily
;
167 if ( lfFamily
& FIXED_PITCH
)
168 lfFamily
-= FIXED_PITCH
;
169 if ( lfFamily
& VARIABLE_PITCH
)
170 lfFamily
-= VARIABLE_PITCH
;
191 m_family
= wxDECORATIVE
;
199 switch ( info
.lf
.lfWeight
)
215 m_style
= info
.lf
.lfItalic
? wxITALIC
: wxNORMAL
;
217 m_underlined
= info
.lf
.lfUnderline
!= 0;
219 m_faceName
= info
.lf
.lfFaceName
;
221 int height
= abs(info
.lf
.lfHeight
);
223 // remember that 1pt = 1/72inch
224 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
225 m_pointSize
= (int) (((72.0*((double)height
))/(double) ppInch
) + 0.5);
227 m_encoding
= wxGetFontEncFromCharSet(info
.lf
.lfCharSet
);
234 m_nativeFontInfoOk
= TRUE
;
235 m_nativeFontInfo
= info
;
238 wxFontRefData::~wxFontRefData()
242 if ( !::DeleteObject((HFONT
) m_hFont
) )
244 wxLogLastError(wxT("DeleteObject(font)"));
250 // ----------------------------------------------------------------------------
252 // ----------------------------------------------------------------------------
254 bool wxNativeFontInfo::FromString(const wxString
& s
)
258 wxStringTokenizer
tokenizer(s
, _T(";"));
260 wxString token
= tokenizer
.GetNextToken();
262 // Ignore the version for now
265 token
= tokenizer
.GetNextToken();
266 if ( !token
.ToLong(&l
) )
270 token
= tokenizer
.GetNextToken();
271 if ( !token
.ToLong(&l
) )
275 token
= tokenizer
.GetNextToken();
276 if ( !token
.ToLong(&l
) )
280 token
= tokenizer
.GetNextToken();
281 if ( !token
.ToLong(&l
) )
283 lf
.lfOrientation
= l
;
285 token
= tokenizer
.GetNextToken();
286 if ( !token
.ToLong(&l
) )
290 token
= tokenizer
.GetNextToken();
291 if ( !token
.ToLong(&l
) )
295 token
= tokenizer
.GetNextToken();
296 if ( !token
.ToLong(&l
) )
300 token
= tokenizer
.GetNextToken();
301 if ( !token
.ToLong(&l
) )
305 token
= tokenizer
.GetNextToken();
306 if ( !token
.ToLong(&l
) )
310 token
= tokenizer
.GetNextToken();
311 if ( !token
.ToLong(&l
) )
313 lf
.lfOutPrecision
= l
;
315 token
= tokenizer
.GetNextToken();
316 if ( !token
.ToLong(&l
) )
318 lf
.lfClipPrecision
= l
;
320 token
= tokenizer
.GetNextToken();
321 if ( !token
.ToLong(&l
) )
325 token
= tokenizer
.GetNextToken();
326 if ( !token
.ToLong(&l
) )
328 lf
.lfPitchAndFamily
= l
;
330 token
= tokenizer
.GetNextToken();
333 wxStrcpy(lf
.lfFaceName
, token
.c_str());
338 wxString
wxNativeFontInfo::ToString() const
342 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
343 0, // version, in case we want to change the format later
362 // ----------------------------------------------------------------------------
364 // ----------------------------------------------------------------------------
369 wxTheFontList
->Append(this);
372 bool wxFont::Create(const wxNativeFontInfo
& info
)
376 m_refData
= new wxFontRefData(info
);
383 wxFont::wxFont(const wxString
& fontdesc
)
385 wxNativeFontInfo info
;
386 if ( info
.FromString(fontdesc
) )
390 /* Constructor for a font. Note that the real construction is done
391 * in wxDC::SetFont, when information is available about scaling etc.
393 bool wxFont::Create(int pointSize
,
398 const wxString
& faceName
,
399 wxFontEncoding encoding
)
403 // wxDEFAULT is a valid value for the font size too so we must treat it
404 // specially here (otherwise the size would be 70 == wxDEFAULT value)
405 if ( pointSize
== wxDEFAULT
)
406 pointSize
= wxDEFAULT_FONT_SIZE
;
408 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
409 underlined
, faceName
, encoding
);
419 wxTheFontList
->DeleteObject(this);
422 // ----------------------------------------------------------------------------
423 // real implementation
424 // ----------------------------------------------------------------------------
426 bool wxFont::RealizeResource()
428 if ( GetResourceHandle() )
430 // VZ: the old code returned FALSE in this case, but it doesn't seem
431 // to make sense because the font _was_ created
435 if(!M_FONTDATA
->m_nativeFontInfoOk
)
437 wxFillLogFont(&M_FONTDATA
->m_nativeFontInfo
.lf
, this);
438 M_FONTDATA
->m_nativeFontInfoOk
= TRUE
;
441 M_FONTDATA
->m_hFont
= (WXHFONT
)::CreateFontIndirect(&M_FONTDATA
->m_nativeFontInfo
.lf
);
442 M_FONTDATA
->m_faceName
= M_FONTDATA
->m_nativeFontInfo
.lf
.lfFaceName
;
443 if ( !M_FONTDATA
->m_hFont
)
445 wxLogLastError(wxT("CreateFont"));
453 bool wxFont::FreeResource(bool force
)
455 if ( GetResourceHandle() )
457 if ( !::DeleteObject((HFONT
) M_FONTDATA
->m_hFont
) )
459 wxLogLastError(wxT("DeleteObject(font)"));
462 M_FONTDATA
->m_hFont
= 0;
469 WXHANDLE
wxFont::GetResourceHandle()
474 WXHFONT
wxFont::GetHFONT() const
479 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
482 bool wxFont::IsFree() const
484 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
487 void wxFont::Unshare()
489 // Don't change shared data
492 m_refData
= new wxFontRefData();
496 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
502 // ----------------------------------------------------------------------------
503 // change font attribute: we recreate font when doing it
504 // ----------------------------------------------------------------------------
506 void wxFont::SetPointSize(int pointSize
)
510 M_FONTDATA
->m_pointSize
= pointSize
;
511 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
516 void wxFont::SetFamily(int family
)
520 M_FONTDATA
->m_family
= family
;
521 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
526 void wxFont::SetStyle(int style
)
530 M_FONTDATA
->m_style
= style
;
531 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
536 void wxFont::SetWeight(int weight
)
540 M_FONTDATA
->m_weight
= weight
;
541 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
546 void wxFont::SetFaceName(const wxString
& faceName
)
550 M_FONTDATA
->m_faceName
= faceName
;
551 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
556 void wxFont::SetUnderlined(bool underlined
)
560 M_FONTDATA
->m_underlined
= underlined
;
561 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
566 void wxFont::SetEncoding(wxFontEncoding encoding
)
570 M_FONTDATA
->m_encoding
= encoding
;
571 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
576 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
582 M_FONTDATA
->Init(info
);
587 // ----------------------------------------------------------------------------
589 // ----------------------------------------------------------------------------
591 int wxFont::GetPointSize() const
593 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
595 return M_FONTDATA
->m_pointSize
;
598 int wxFont::GetFamily() const
600 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
602 return M_FONTDATA
->m_family
;
605 int wxFont::GetFontId() const
607 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
609 return M_FONTDATA
->m_fontId
;
612 int wxFont::GetStyle() const
614 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
616 return M_FONTDATA
->m_style
;
619 int wxFont::GetWeight() const
621 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
623 return M_FONTDATA
->m_weight
;
626 bool wxFont::GetUnderlined() const
628 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
630 return M_FONTDATA
->m_underlined
;
633 wxString
wxFont::GetFaceName() const
635 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
637 return M_FONTDATA
->m_faceName
;
640 wxFontEncoding
wxFont::GetEncoding() const
642 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
644 return M_FONTDATA
->m_encoding
;
647 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
649 if( M_FONTDATA
->m_nativeFontInfoOk
)
650 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);