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
;
64 wxFontRefData(const wxFontRefData
& data
)
66 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
67 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
69 m_fontId
= data
.m_fontId
;
72 wxFontRefData(int size
,
77 const wxString
& faceName
,
78 wxFontEncoding encoding
)
80 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
83 virtual ~wxFontRefData();
86 // common part of all ctors
92 const wxString
& faceName
,
93 wxFontEncoding encoding
);
95 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
96 // DELETED by destructor
101 // font characterstics
108 wxFontEncoding m_encoding
;
110 // Windows font handle
114 // ============================================================================
116 // ============================================================================
118 // ----------------------------------------------------------------------------
120 // ----------------------------------------------------------------------------
122 void wxFontRefData::Init(int pointSize
,
127 const wxString
& faceName
,
128 wxFontEncoding encoding
)
131 m_pointSize
= pointSize
;
135 m_underlined
= underlined
;
136 m_faceName
= faceName
;
137 m_encoding
= encoding
;
145 wxFontRefData::~wxFontRefData()
149 if ( !::DeleteObject((HFONT
) m_hFont
) )
151 wxLogLastError("DeleteObject(font)");
156 // ----------------------------------------------------------------------------
158 // ----------------------------------------------------------------------------
163 wxTheFontList
->Append(this);
166 /* Constructor for a font. Note that the real construction is done
167 * in wxDC::SetFont, when information is available about scaling etc.
169 bool wxFont::Create(int pointSize
,
174 const wxString
& faceName
,
175 wxFontEncoding encoding
)
178 m_refData
= new wxFontRefData(pointSize
, family
, style
, weight
,
179 underlined
, faceName
, encoding
);
189 wxTheFontList
->DeleteObject(this);
192 // ----------------------------------------------------------------------------
193 // real implementation
194 // ----------------------------------------------------------------------------
196 bool wxFont::RealizeResource()
198 if ( GetResourceHandle() )
200 // VZ: the old code returned FALSE in this case, but it doesn't seem
201 // to make sense because the font _was_ created
202 wxLogDebug(_T("Calling wxFont::RealizeResource() twice"));
212 switch (M_FONTDATA
->m_family
)
214 case wxSCRIPT
: ff_family
= FF_SCRIPT
;
215 ff_face
= _T("Script") ;
217 case wxDECORATIVE
: ff_family
= FF_DECORATIVE
;
219 case wxROMAN
: ff_family
= FF_ROMAN
;
220 ff_face
= _T("Times New Roman") ;
223 case wxMODERN
: ff_family
= FF_MODERN
;
224 ff_face
= _T("Courier New") ;
226 case wxSWISS
: ff_family
= FF_SWISS
;
227 ff_face
= _T("Arial") ;
230 default: ff_family
= FF_SWISS
;
231 ff_face
= _T("Arial") ;
234 if (M_FONTDATA
->m_style
== wxITALIC
|| M_FONTDATA
->m_style
== wxSLANT
)
239 if (M_FONTDATA
->m_weight
== wxNORMAL
)
240 ff_weight
= FW_NORMAL
;
241 else if (M_FONTDATA
->m_weight
== wxLIGHT
)
242 ff_weight
= FW_LIGHT
;
243 else if (M_FONTDATA
->m_weight
== wxBOLD
)
246 const wxChar
* pzFace
= (const wxChar
*) ff_face
;
247 if (!M_FONTDATA
->m_faceName
.IsNull())
248 pzFace
= (const wxChar
*) M_FONTDATA
->m_faceName
;
250 /* Always calculate fonts using the screen DC (is this the best strategy?)
251 * There may be confusion if a font is selected into a printer
252 * DC (say), because the height will be calculated very differently.
253 // What sort of display is it?
254 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
258 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
260 // Have to get screen DC Caps, because a metafile will return 0.
261 HDC dc2 = ::GetDC(NULL);
262 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72;
263 ::ReleaseDC(NULL, dc2);
267 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
270 // Have to get screen DC Caps, because a metafile will return 0.
271 HDC dc2
= ::GetDC(NULL
);
272 int ppInch
= ::GetDeviceCaps(dc2
, LOGPIXELSY
);
273 ::ReleaseDC(NULL
, dc2
);
275 // New behaviour: apparently ppInch varies according to
276 // Large/Small Fonts setting in Windows. This messes
277 // up fonts. So, set ppInch to a constant 96 dpi.
280 #if wxFONT_SIZE_COMPATIBILITY
281 // Incorrect, but compatible with old wxWindows behaviour
282 int nHeight
= (M_FONTDATA
->m_pointSize
*ppInch
/72);
284 // Correct for Windows compatibility
285 int nHeight
= - (M_FONTDATA
->m_pointSize
*ppInch
/72);
288 bool ff_underline
= M_FONTDATA
->m_underlined
;
290 M_FONTDATA
->m_hFont
= (WXHFONT
) CreateFont(nHeight
, 0, 0, 0,ff_weight
,ff_italic
,(BYTE
)ff_underline
,
291 0, ANSI_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
,
292 PROOF_QUALITY
, DEFAULT_PITCH
| ff_family
, pzFace
);
293 #ifdef WXDEBUG_CREATE
294 if (m_hFont
==NULL
) wxError(_T("Cannot create font"),_T("Internal Error")) ;
296 return (M_FONTDATA
->m_hFont
!= (WXHFONT
) NULL
);
299 bool wxFont::FreeResource(bool force
)
301 if ( GetResourceHandle() )
303 if ( !::DeleteObject((HFONT
) M_FONTDATA
->m_hFont
) )
305 wxLogLastError("DeleteObject(font)");
308 M_FONTDATA
->m_hFont
= 0;
315 WXHANDLE
wxFont::GetResourceHandle()
320 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
323 bool wxFont::IsFree() const
325 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
328 void wxFont::Unshare()
330 // Don't change shared data
333 m_refData
= new wxFontRefData();
337 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
343 // ----------------------------------------------------------------------------
344 // change font attribute: we recreate font when doing it
345 // ----------------------------------------------------------------------------
347 void wxFont::SetPointSize(int pointSize
)
351 M_FONTDATA
->m_pointSize
= pointSize
;
356 void wxFont::SetFamily(int family
)
360 M_FONTDATA
->m_family
= family
;
365 void wxFont::SetStyle(int style
)
369 M_FONTDATA
->m_style
= style
;
374 void wxFont::SetWeight(int weight
)
378 M_FONTDATA
->m_weight
= weight
;
383 void wxFont::SetFaceName(const wxString
& faceName
)
387 M_FONTDATA
->m_faceName
= faceName
;
392 void wxFont::SetUnderlined(bool underlined
)
396 M_FONTDATA
->m_underlined
= underlined
;
401 void wxFont::SetEncoding(wxFontEncoding encoding
)
405 M_FONTDATA
->m_encoding
= encoding
;
410 // ----------------------------------------------------------------------------
412 // ----------------------------------------------------------------------------
414 int wxFont::GetPointSize() const
416 return M_FONTDATA
->m_pointSize
;
419 int wxFont::GetFamily() const
421 return M_FONTDATA
->m_family
;
424 int wxFont::GetFontId() const
426 return M_FONTDATA
->m_fontId
;
429 int wxFont::GetStyle() const
431 return M_FONTDATA
->m_style
;
434 int wxFont::GetWeight() const
436 return M_FONTDATA
->m_weight
;
439 bool wxFont::GetUnderlined() const
441 return M_FONTDATA
->m_underlined
;
444 wxString
wxFont::GetFaceName() const
448 str
= M_FONTDATA
->m_faceName
;
452 wxFontEncoding
wxFont::GetEncoding() const
454 return M_FONTDATA
->m_encoding
;