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"
44 #include "wx/tokenzr.h"
46 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 // the default font size in points
53 static const int wxDEFAULT_FONT_SIZE
= 12;
55 // ----------------------------------------------------------------------------
56 // wxFontRefData - the internal description of the font
57 // ----------------------------------------------------------------------------
59 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
61 friend class WXDLLEXPORT wxFont
;
66 Init(wxDEFAULT_FONT_SIZE
, wxDEFAULT
, wxNORMAL
, wxNORMAL
, FALSE
,
67 "", wxFONTENCODING_DEFAULT
);
70 wxFontRefData(const wxFontRefData
& data
)
72 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
73 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
75 m_fontId
= data
.m_fontId
;
78 wxFontRefData(int size
,
83 const wxString
& faceName
,
84 wxFontEncoding encoding
)
86 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
89 wxFontRefData(const wxNativeFontInfo
& info
)
94 virtual ~wxFontRefData();
97 // common part of all ctors
103 const wxString
& faceName
,
104 wxFontEncoding encoding
);
106 void Init(const wxNativeFontInfo
& info
);
108 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
109 // DELETED by destructor
114 // font characterstics
121 wxFontEncoding m_encoding
;
123 // Windows font handle
127 wxNativeFontInfo m_nativeFontInfo
;
128 bool m_nativeFontInfoOk
;
131 // ============================================================================
133 // ============================================================================
135 // ----------------------------------------------------------------------------
137 // ----------------------------------------------------------------------------
139 void wxFontRefData::Init(int pointSize
,
144 const wxString
& faceName
,
145 wxFontEncoding encoding
)
148 m_pointSize
= pointSize
;
152 m_underlined
= underlined
;
153 m_faceName
= faceName
;
154 m_encoding
= encoding
;
161 m_nativeFontInfoOk
= FALSE
;
164 void wxFontRefData::Init(const wxNativeFontInfo
& info
)
166 // extract family from pitch-and-family
167 int lfFamily
= info
.lf
.lfPitchAndFamily
;
168 if ( lfFamily
& FIXED_PITCH
)
169 lfFamily
-= FIXED_PITCH
;
170 if ( lfFamily
& VARIABLE_PITCH
)
171 lfFamily
-= VARIABLE_PITCH
;
192 m_family
= wxDECORATIVE
;
200 switch ( info
.lf
.lfWeight
)
216 m_style
= info
.lf
.lfItalic
? wxITALIC
: wxNORMAL
;
218 m_underlined
= info
.lf
.lfUnderline
!= 0;
220 m_faceName
= info
.lf
.lfFaceName
;
222 int height
= abs(info
.lf
.lfHeight
);
224 // remember that 1pt = 1/72inch
225 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
226 m_pointSize
= (int) (((72.0*((double)height
))/(double) ppInch
) + 0.5);
228 m_encoding
= wxGetFontEncFromCharSet(info
.lf
.lfCharSet
);
235 m_nativeFontInfoOk
= TRUE
;
236 m_nativeFontInfo
= info
;
239 wxFontRefData::~wxFontRefData()
243 if ( !::DeleteObject((HFONT
) m_hFont
) )
245 wxLogLastError(wxT("DeleteObject(font)"));
251 // ----------------------------------------------------------------------------
253 // ----------------------------------------------------------------------------
255 bool wxNativeFontInfo::FromString(const wxString
& s
)
259 wxStringTokenizer
tokenizer(s
, _T(";"));
261 wxString token
= tokenizer
.GetNextToken();
263 // Ignore the version for now
266 token
= tokenizer
.GetNextToken();
267 if ( !token
.ToLong(&l
) )
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
) )
284 lf
.lfOrientation
= l
;
286 token
= tokenizer
.GetNextToken();
287 if ( !token
.ToLong(&l
) )
291 token
= tokenizer
.GetNextToken();
292 if ( !token
.ToLong(&l
) )
294 lf
.lfItalic
= (BYTE
)l
;
296 token
= tokenizer
.GetNextToken();
297 if ( !token
.ToLong(&l
) )
299 lf
.lfUnderline
= (BYTE
)l
;
301 token
= tokenizer
.GetNextToken();
302 if ( !token
.ToLong(&l
) )
304 lf
.lfStrikeOut
= (BYTE
)l
;
306 token
= tokenizer
.GetNextToken();
307 if ( !token
.ToLong(&l
) )
309 lf
.lfCharSet
= (BYTE
)l
;
311 token
= tokenizer
.GetNextToken();
312 if ( !token
.ToLong(&l
) )
314 lf
.lfOutPrecision
= (BYTE
)l
;
316 token
= tokenizer
.GetNextToken();
317 if ( !token
.ToLong(&l
) )
319 lf
.lfClipPrecision
= (BYTE
)l
;
321 token
= tokenizer
.GetNextToken();
322 if ( !token
.ToLong(&l
) )
324 lf
.lfQuality
= (BYTE
)l
;
326 token
= tokenizer
.GetNextToken();
327 if ( !token
.ToLong(&l
) )
329 lf
.lfPitchAndFamily
= (BYTE
)l
;
331 token
= tokenizer
.GetNextToken();
334 wxStrcpy(lf
.lfFaceName
, token
.c_str());
339 wxString
wxNativeFontInfo::ToString() const
343 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
344 0, // version, in case we want to change the format later
363 // ----------------------------------------------------------------------------
365 // ----------------------------------------------------------------------------
370 wxTheFontList
->Append(this);
373 bool wxFont::Create(const wxNativeFontInfo
& info
)
377 m_refData
= new wxFontRefData(info
);
384 wxFont::wxFont(const wxString
& fontdesc
)
386 wxNativeFontInfo info
;
387 if ( info
.FromString(fontdesc
) )
391 /* Constructor for a font. Note that the real construction is done
392 * in wxDC::SetFont, when information is available about scaling etc.
394 bool wxFont::Create(int pointSize
,
399 const wxString
& faceName
,
400 wxFontEncoding encoding
)
404 // wxDEFAULT is a valid value for the font size too so we must treat it
405 // specially here (otherwise the size would be 70 == wxDEFAULT value)
406 if ( pointSize
== wxDEFAULT
)
407 pointSize
= wxDEFAULT_FONT_SIZE
;
409 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
410 underlined
, faceName
, encoding
);
420 wxTheFontList
->DeleteObject(this);
423 // ----------------------------------------------------------------------------
424 // real implementation
425 // ----------------------------------------------------------------------------
427 bool wxFont::RealizeResource()
429 if ( GetResourceHandle() )
431 // VZ: the old code returned FALSE in this case, but it doesn't seem
432 // to make sense because the font _was_ created
436 if(!M_FONTDATA
->m_nativeFontInfoOk
)
438 wxFillLogFont(&M_FONTDATA
->m_nativeFontInfo
.lf
, this);
439 M_FONTDATA
->m_nativeFontInfoOk
= TRUE
;
442 M_FONTDATA
->m_hFont
= (WXHFONT
)::CreateFontIndirect(&M_FONTDATA
->m_nativeFontInfo
.lf
);
443 M_FONTDATA
->m_faceName
= M_FONTDATA
->m_nativeFontInfo
.lf
.lfFaceName
;
444 if ( !M_FONTDATA
->m_hFont
)
446 wxLogLastError(wxT("CreateFont"));
454 bool wxFont::FreeResource(bool WXUNUSED(force
))
456 if ( GetResourceHandle() )
458 if ( !::DeleteObject((HFONT
) M_FONTDATA
->m_hFont
) )
460 wxLogLastError(wxT("DeleteObject(font)"));
463 M_FONTDATA
->m_hFont
= 0;
470 WXHANDLE
wxFont::GetResourceHandle()
475 WXHFONT
wxFont::GetHFONT() const
480 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
483 bool wxFont::IsFree() const
485 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
488 void wxFont::Unshare()
490 // Don't change shared data
493 m_refData
= new wxFontRefData();
497 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
503 // ----------------------------------------------------------------------------
504 // change font attribute: we recreate font when doing it
505 // ----------------------------------------------------------------------------
507 void wxFont::SetPointSize(int pointSize
)
511 M_FONTDATA
->m_pointSize
= pointSize
;
512 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
517 void wxFont::SetFamily(int family
)
521 M_FONTDATA
->m_family
= family
;
522 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
527 void wxFont::SetStyle(int style
)
531 M_FONTDATA
->m_style
= style
;
532 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
537 void wxFont::SetWeight(int weight
)
541 M_FONTDATA
->m_weight
= weight
;
542 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
547 void wxFont::SetFaceName(const wxString
& faceName
)
551 M_FONTDATA
->m_faceName
= faceName
;
552 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
557 void wxFont::SetUnderlined(bool underlined
)
561 M_FONTDATA
->m_underlined
= underlined
;
562 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
567 void wxFont::SetEncoding(wxFontEncoding encoding
)
571 M_FONTDATA
->m_encoding
= encoding
;
572 M_FONTDATA
->m_nativeFontInfoOk
= FALSE
;
577 void wxFont::SetNativeFontInfo(const wxNativeFontInfo
& info
)
583 M_FONTDATA
->Init(info
);
588 // ----------------------------------------------------------------------------
590 // ----------------------------------------------------------------------------
592 int wxFont::GetPointSize() const
594 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
596 return M_FONTDATA
->m_pointSize
;
599 int wxFont::GetFamily() const
601 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
603 return M_FONTDATA
->m_family
;
606 int wxFont::GetFontId() const
608 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
610 return M_FONTDATA
->m_fontId
;
613 int wxFont::GetStyle() const
615 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
617 return M_FONTDATA
->m_style
;
620 int wxFont::GetWeight() const
622 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
624 return M_FONTDATA
->m_weight
;
627 bool wxFont::GetUnderlined() const
629 wxCHECK_MSG( Ok(), FALSE
, wxT("invalid font") );
631 return M_FONTDATA
->m_underlined
;
634 wxString
wxFont::GetFaceName() const
636 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
638 return M_FONTDATA
->m_faceName
;
641 wxFontEncoding
wxFont::GetEncoding() const
643 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
645 return M_FONTDATA
->m_encoding
;
648 // ----------------------------------------------------------------------------
650 // ----------------------------------------------------------------------------
652 bool wxNativeFontInfo::FromString(const wxString
& s
)
656 wxStringTokenizer
tokenizer(s
, _T(";"));
658 wxString token
= tokenizer
.GetNextToken();
660 // Ignore the version for now
663 token
= tokenizer
.GetNextToken();
664 if ( !token
.ToLong(&l
) )
668 token
= tokenizer
.GetNextToken();
669 if ( !token
.ToLong(&l
) )
673 token
= tokenizer
.GetNextToken();
674 if ( !token
.ToLong(&l
) )
678 token
= tokenizer
.GetNextToken();
679 if ( !token
.ToLong(&l
) )
681 lf
.lfOrientation
= l
;
683 token
= tokenizer
.GetNextToken();
684 if ( !token
.ToLong(&l
) )
688 token
= tokenizer
.GetNextToken();
689 if ( !token
.ToLong(&l
) )
691 lf
.lfItalic
= (BYTE
)l
;
693 token
= tokenizer
.GetNextToken();
694 if ( !token
.ToLong(&l
) )
696 lf
.lfUnderline
= (BYTE
)l
;
698 token
= tokenizer
.GetNextToken();
699 if ( !token
.ToLong(&l
) )
701 lf
.lfStrikeOut
= (BYTE
)l
;
703 token
= tokenizer
.GetNextToken();
704 if ( !token
.ToLong(&l
) )
706 lf
.lfCharSet
= (BYTE
)l
;
708 token
= tokenizer
.GetNextToken();
709 if ( !token
.ToLong(&l
) )
711 lf
.lfOutPrecision
= (BYTE
)l
;
713 token
= tokenizer
.GetNextToken();
714 if ( !token
.ToLong(&l
) )
716 lf
.lfClipPrecision
= (BYTE
)l
;
718 token
= tokenizer
.GetNextToken();
719 if ( !token
.ToLong(&l
) )
721 lf
.lfQuality
= (BYTE
)l
;
723 token
= tokenizer
.GetNextToken();
724 if ( !token
.ToLong(&l
) )
726 lf
.lfPitchAndFamily
= (BYTE
)l
;
728 token
= tokenizer
.GetNextToken();
731 wxStrcpy(lf
.lfFaceName
, token
.c_str());
736 wxString
wxNativeFontInfo::ToString() const
740 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
741 0, // version, in case we want to change the format later