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/msw/private.h"
42 #if !USE_SHARED_LIBRARIES
43 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
45 #if wxUSE_PORTABLE_FONTS_IN_MSW
46 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory
, wxObject
)
50 // ----------------------------------------------------------------------------
51 // wxFontRefData - the internal description of the font
52 // ----------------------------------------------------------------------------
54 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
56 friend class WXDLLEXPORT wxFont
;
61 Init(12, wxDEFAULT
, wxNORMAL
, wxNORMAL
, FALSE
,
62 "", wxFONTENCODING_DEFAULT
);
65 wxFontRefData(const wxFontRefData
& data
)
67 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
68 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
70 m_fontId
= data
.m_fontId
;
73 wxFontRefData(int size
,
78 const wxString
& faceName
,
79 wxFontEncoding encoding
)
81 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
84 virtual ~wxFontRefData();
87 // common part of all ctors
93 const wxString
& faceName
,
94 wxFontEncoding encoding
);
96 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
97 // DELETED by destructor
102 // font characterstics
109 wxFontEncoding m_encoding
;
111 // Windows font handle
115 // ============================================================================
117 // ============================================================================
119 // ----------------------------------------------------------------------------
121 // ----------------------------------------------------------------------------
123 void wxFontRefData::Init(int pointSize
,
128 const wxString
& faceName
,
129 wxFontEncoding encoding
)
132 m_pointSize
= pointSize
;
136 m_underlined
= underlined
;
137 m_faceName
= faceName
;
138 m_encoding
= encoding
;
146 wxFontRefData::~wxFontRefData()
150 if ( !::DeleteObject((HFONT
) m_hFont
) )
152 wxLogLastError("DeleteObject(font)");
157 // ----------------------------------------------------------------------------
159 // ----------------------------------------------------------------------------
164 wxTheFontList
->Append(this);
167 /* Constructor for a font. Note that the real construction is done
168 * in wxDC::SetFont, when information is available about scaling etc.
170 bool wxFont::Create(int pointSize
,
175 const wxString
& faceName
,
176 wxFontEncoding encoding
)
179 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
180 underlined
, faceName
, encoding
);
190 wxTheFontList
->DeleteObject(this);
193 // ----------------------------------------------------------------------------
194 // real implementation
195 // ----------------------------------------------------------------------------
197 bool wxFont::RealizeResource()
199 if ( GetResourceHandle() )
201 // VZ: the old code returned FALSE in this case, but it doesn't seem
202 // to make sense because the font _was_ created
203 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
211 switch ( M_FONTDATA
->m_family
)
214 ff_family
= FF_SCRIPT
;
215 ff_face
= wxT("Script") ;
219 ff_family
= FF_DECORATIVE
;
223 ff_family
= FF_ROMAN
;
224 ff_face
= wxT("Times New Roman") ;
229 ff_family
= FF_MODERN
;
230 ff_face
= wxT("Courier New") ;
234 ff_family
= FF_SWISS
;
235 ff_face
= wxT("Arial") ;
240 ff_family
= FF_SWISS
;
241 ff_face
= wxT("Arial") ;
245 switch ( M_FONTDATA
->m_style
)
253 wxFAIL_MSG(wxT("unknown font slant"));
261 switch ( M_FONTDATA
->m_weight
)
264 wxFAIL_MSG(wxT("unknown font weight"));
268 ff_weight
= FW_NORMAL
;
272 ff_weight
= FW_LIGHT
;
280 const wxChar
* pzFace
;
281 if ( M_FONTDATA
->m_faceName
.IsEmpty() )
284 pzFace
= M_FONTDATA
->m_faceName
;
287 /* Always calculate fonts using the screen DC (is this the best strategy?)
288 * There may be confusion if a font is selected into a printer
289 * DC (say), because the height will be calculated very differently.
291 // What sort of display is it?
292 int technology
= ::GetDeviceCaps(dc
, TECHNOLOGY
);
296 if (technology
!= DT_RASDISPLAY
&& technology
!= DT_RASPRINTER
)
298 // Have to get screen DC Caps, because a metafile will return 0.
299 HDC dc2
= ::GetDC(NULL
);
300 nHeight
= M_FONTDATA
->m_pointSize
*GetDeviceCaps(dc2
, LOGPIXELSY
)/72;
301 ::ReleaseDC(NULL
, dc2
);
305 nHeight
= M_FONTDATA
->m_pointSize
*GetDeviceCaps(dc
, LOGPIXELSY
)/72;
310 // Have to get screen DC Caps, because a metafile will return 0.
311 HDC dc2
= ::GetDC(NULL
);
312 ppInch
= ::GetDeviceCaps(dc2
, LOGPIXELSY
);
313 ::ReleaseDC(NULL
, dc2
);
316 // New behaviour: apparently ppInch varies according to Large/Small Fonts
317 // setting in Windows. This messes up fonts. So, set ppInch to a constant
319 static const int ppInch
= 96;
321 #if wxFONT_SIZE_COMPATIBILITY
322 // Incorrect, but compatible with old wxWindows behaviour
323 int nHeight
= (M_FONTDATA
->m_pointSize
*ppInch
/72);
325 // Correct for Windows compatibility
326 int nHeight
= - (M_FONTDATA
->m_pointSize
*ppInch
/72);
329 BYTE ff_underline
= M_FONTDATA
->m_underlined
;
331 DWORD charset
= wxCharsetFromEncoding(GetEncoding());
332 HFONT hFont
= ::CreateFont
335 0, // width (choose best)
339 ff_italic
, // italic?
340 ff_underline
, // underlined?
343 OUT_DEFAULT_PRECIS
, // precision
344 CLIP_DEFAULT_PRECIS
, // clip precision
345 PROOF_QUALITY
, // quality of match
346 DEFAULT_PITCH
| // fixed or variable
347 ff_family
, // family id
351 M_FONTDATA
->m_hFont
= (WXHFONT
)hFont
;
354 wxLogLastError("CreateFont");
360 bool wxFont::FreeResource(bool force
)
362 if ( GetResourceHandle() )
364 if ( !::DeleteObject((HFONT
) M_FONTDATA
->m_hFont
) )
366 wxLogLastError("DeleteObject(font)");
369 M_FONTDATA
->m_hFont
= 0;
376 WXHANDLE
wxFont::GetResourceHandle()
381 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
384 bool wxFont::IsFree() const
386 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
389 void wxFont::Unshare()
391 // Don't change shared data
394 m_refData
= new wxFontRefData();
398 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
404 // ----------------------------------------------------------------------------
405 // change font attribute: we recreate font when doing it
406 // ----------------------------------------------------------------------------
408 void wxFont::SetPointSize(int pointSize
)
412 M_FONTDATA
->m_pointSize
= pointSize
;
417 void wxFont::SetFamily(int family
)
421 M_FONTDATA
->m_family
= family
;
426 void wxFont::SetStyle(int style
)
430 M_FONTDATA
->m_style
= style
;
435 void wxFont::SetWeight(int weight
)
439 M_FONTDATA
->m_weight
= weight
;
444 void wxFont::SetFaceName(const wxString
& faceName
)
448 M_FONTDATA
->m_faceName
= faceName
;
453 void wxFont::SetUnderlined(bool underlined
)
457 M_FONTDATA
->m_underlined
= underlined
;
462 void wxFont::SetEncoding(wxFontEncoding encoding
)
466 M_FONTDATA
->m_encoding
= encoding
;
471 // ----------------------------------------------------------------------------
473 // ----------------------------------------------------------------------------
475 int wxFont::GetPointSize() const
477 return M_FONTDATA
->m_pointSize
;
480 int wxFont::GetFamily() const
482 return M_FONTDATA
->m_family
;
485 int wxFont::GetFontId() const
487 return M_FONTDATA
->m_fontId
;
490 int wxFont::GetStyle() const
492 return M_FONTDATA
->m_style
;
495 int wxFont::GetWeight() const
497 return M_FONTDATA
->m_weight
;
500 bool wxFont::GetUnderlined() const
502 return M_FONTDATA
->m_underlined
;
505 wxString
wxFont::GetFaceName() const
509 str
= M_FONTDATA
->m_faceName
;
513 wxFontEncoding
wxFont::GetEncoding() const
515 return M_FONTDATA
->m_encoding
;
518 // ----------------------------------------------------------------------------
520 // ----------------------------------------------------------------------------
522 int wxCharsetFromEncoding(wxFontEncoding encoding
, bool *exact
)
524 if ( encoding
== wxFONTENCODING_DEFAULT
)
526 encoding
= wxFont::GetDefaultEncoding();
535 case wxFONTENCODING_ISO8859_1
:
536 case wxFONTENCODING_ISO8859_15
:
537 case wxFONTENCODING_CP1250
:
538 charset
= ANSI_CHARSET
;
541 #if !defined(__WIN16__)
542 case wxFONTENCODING_ISO8859_2
:
543 case wxFONTENCODING_CP1252
:
544 charset
= EASTEUROPE_CHARSET
;
547 case wxFONTENCODING_ISO8859_4
:
548 case wxFONTENCODING_ISO8859_10
:
549 charset
= BALTIC_CHARSET
;
552 case wxFONTENCODING_ISO8859_5
:
553 case wxFONTENCODING_CP1251
:
554 charset
= RUSSIAN_CHARSET
;
557 case wxFONTENCODING_ISO8859_6
:
558 charset
= ARABIC_CHARSET
;
561 case wxFONTENCODING_ISO8859_7
:
562 charset
= GREEK_CHARSET
;
565 case wxFONTENCODING_ISO8859_8
:
566 charset
= HEBREW_CHARSET
;
569 case wxFONTENCODING_ISO8859_9
:
570 charset
= TURKISH_CHARSET
;
573 case wxFONTENCODING_ISO8859_11
:
574 charset
= THAI_CHARSET
;
576 #endif // BC++ 16-bit
578 case wxFONTENCODING_CP437
:
579 charset
= OEM_CHARSET
;
587 case wxFONTENCODING_SYSTEM
:
588 charset
= ANSI_CHARSET
;