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 // remember that 1pt = 1/72inch
222 int height
= abs(info
.lf
.lfHeight
);
225 HDC dc
= ::GetDC(NULL
);
226 static const int ppInch
= GetDeviceCaps(dc
, LOGPIXELSY
);
227 ::ReleaseDC(NULL
, dc
);
229 static const int ppInch
= 96;
231 m_pointSize
= (int) (((72.0*((double)height
))/(double) ppInch
) + 0.5);
233 m_encoding
= wxGetFontEncFromCharSet(info
.lf
.lfCharSet
);
240 m_nativeFontInfoOk
= TRUE
;
241 m_nativeFontInfo
= info
;
244 wxFontRefData::~wxFontRefData()
248 if ( !::DeleteObject((HFONT
) m_hFont
) )
250 wxLogLastError(wxT("DeleteObject(font)"));
256 // ----------------------------------------------------------------------------
258 // ----------------------------------------------------------------------------
260 bool wxNativeFontInfo::FromString(const wxString
& s
)
264 wxStringTokenizer
tokenizer(s
, _T(";"));
266 wxString token
= tokenizer
.GetNextToken();
268 // Ignore the version for now
271 token
= tokenizer
.GetNextToken();
272 if ( !token
.ToLong(&l
) )
276 token
= tokenizer
.GetNextToken();
277 if ( !token
.ToLong(&l
) )
281 token
= tokenizer
.GetNextToken();
282 if ( !token
.ToLong(&l
) )
286 token
= tokenizer
.GetNextToken();
287 if ( !token
.ToLong(&l
) )
289 lf
.lfOrientation
= l
;
291 token
= tokenizer
.GetNextToken();
292 if ( !token
.ToLong(&l
) )
296 token
= tokenizer
.GetNextToken();
297 if ( !token
.ToLong(&l
) )
301 token
= tokenizer
.GetNextToken();
302 if ( !token
.ToLong(&l
) )
306 token
= tokenizer
.GetNextToken();
307 if ( !token
.ToLong(&l
) )
311 token
= tokenizer
.GetNextToken();
312 if ( !token
.ToLong(&l
) )
316 token
= tokenizer
.GetNextToken();
317 if ( !token
.ToLong(&l
) )
319 lf
.lfOutPrecision
= l
;
321 token
= tokenizer
.GetNextToken();
322 if ( !token
.ToLong(&l
) )
324 lf
.lfClipPrecision
= l
;
326 token
= tokenizer
.GetNextToken();
327 if ( !token
.ToLong(&l
) )
331 token
= tokenizer
.GetNextToken();
332 if ( !token
.ToLong(&l
) )
334 lf
.lfPitchAndFamily
= l
;
336 token
= tokenizer
.GetNextToken();
339 wxStrcpy(lf
.lfFaceName
, token
.c_str());
344 wxString
wxNativeFontInfo::ToString() const
348 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
349 0, // version, in case we want to change the format later
368 // ----------------------------------------------------------------------------
370 // ----------------------------------------------------------------------------
375 wxTheFontList
->Append(this);
378 bool wxFont::Create(const wxNativeFontInfo
& info
)
382 m_refData
= new wxFontRefData(info
);
389 wxFont::wxFont(const wxString
& fontdesc
)
391 wxNativeFontInfo info
;
392 if ( info
.FromString(fontdesc
) )
396 /* Constructor for a font. Note that the real construction is done
397 * in wxDC::SetFont, when information is available about scaling etc.
399 bool wxFont::Create(int pointSize
,
404 const wxString
& faceName
,
405 wxFontEncoding encoding
)
409 // wxDEFAULT is a valid value for the font size too so we must treat it
410 // specially here (otherwise the size would be 70 == wxDEFAULT value)
411 if ( pointSize
== wxDEFAULT
)
412 pointSize
= wxDEFAULT_FONT_SIZE
;
414 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
415 underlined
, faceName
, encoding
);
425 wxTheFontList
->DeleteObject(this);
428 // ----------------------------------------------------------------------------
429 // real implementation
430 // ----------------------------------------------------------------------------
432 bool wxFont::RealizeResource()
434 if ( GetResourceHandle() )
436 // VZ: the old code returned FALSE in this case, but it doesn't seem
437 // to make sense because the font _was_ created
441 if(!M_FONTDATA
->m_nativeFontInfoOk
)
443 wxFillLogFont(&M_FONTDATA
->m_nativeFontInfo
.lf
, this);
444 M_FONTDATA
->m_nativeFontInfoOk
= TRUE
;
447 M_FONTDATA
->m_hFont
= (WXHFONT
)::CreateFontIndirect(&M_FONTDATA
->m_nativeFontInfo
.lf
);
448 M_FONTDATA
->m_faceName
= M_FONTDATA
->m_nativeFontInfo
.lf
.lfFaceName
;
449 if ( !M_FONTDATA
->m_hFont
)
451 wxLogLastError(wxT("CreateFont"));
459 bool wxFont::FreeResource(bool force
)
461 if ( GetResourceHandle() )
463 if ( !::DeleteObject((HFONT
) M_FONTDATA
->m_hFont
) )
465 wxLogLastError(wxT("DeleteObject(font)"));
468 M_FONTDATA
->m_hFont
= 0;
475 WXHANDLE
wxFont::GetResourceHandle()
480 WXHFONT
wxFont::GetHFONT() const
485 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
488 bool wxFont::IsFree() const
490 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
493 void wxFont::Unshare()
495 // Don't change shared data
498 m_refData
= new wxFontRefData();
502 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
508 // ----------------------------------------------------------------------------
509 // change font attribute: we recreate font when doing it
510 // ----------------------------------------------------------------------------
512 void wxFont::SetPointSize(int pointSize
)
516 M_FONTDATA
->m_pointSize
= pointSize
;
517 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
522 void wxFont::SetFamily(int family
)
526 M_FONTDATA
->m_family
= family
;
527 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
532 void wxFont::SetStyle(int style
)
536 M_FONTDATA
->m_style
= style
;
537 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
542 void wxFont::SetWeight(int weight
)
546 M_FONTDATA
->m_weight
= weight
;
547 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
552 void wxFont::SetFaceName(const wxString
& faceName
)
556 M_FONTDATA
->m_faceName
= faceName
;
557 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
562 void wxFont::SetUnderlined(bool underlined
)
566 M_FONTDATA
->m_underlined
= underlined
;
567 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
572 void wxFont::SetEncoding(wxFontEncoding encoding
)
576 M_FONTDATA
->m_encoding
= encoding
;
577 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
582 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
588 M_FONTDATA
->Init(info
);
593 // ----------------------------------------------------------------------------
595 // ----------------------------------------------------------------------------
597 int wxFont::GetPointSize() const
599 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
601 return M_FONTDATA
->m_pointSize
;
604 int wxFont::GetFamily() const
606 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
608 return M_FONTDATA
->m_family
;
611 int wxFont::GetFontId() const
613 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
615 return M_FONTDATA
->m_fontId
;
618 int wxFont::GetStyle() const
620 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
622 return M_FONTDATA
->m_style
;
625 int wxFont::GetWeight() const
627 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
629 return M_FONTDATA
->m_weight
;
632 bool wxFont::GetUnderlined() const
634 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
636 return M_FONTDATA
->m_underlined
;
639 wxString
wxFont::GetFaceName() const
641 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
643 return M_FONTDATA
->m_faceName
;
646 wxFontEncoding
wxFont::GetEncoding() const
648 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
650 return M_FONTDATA
->m_encoding
;
653 wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
655 if( M_FONTDATA
->m_nativeFontInfoOk
)
656 return new wxNativeFontInfo(M_FONTDATA
->m_nativeFontInfo
);