]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
Several changes and updates
[wxWidgets.git] / src / msw / font.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
0c5d3e1c
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
0c5d3e1c 21 #pragma implementation "font.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
0c5d3e1c 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
0c5d3e1c
VZ
32 #include <stdio.h>
33 #include "wx/setup.h"
34 #include "wx/list.h"
35 #include "wx/utils.h"
36 #include "wx/app.h"
37 #include "wx/font.h"
38#endif // WX_PRECOMP
2bda0e17
KB
39
40#include "wx/msw/private.h"
2bda0e17
KB
41
42#if !USE_SHARED_LIBRARIES
0c5d3e1c 43 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
2bda0e17 44
0c5d3e1c
VZ
45 #if wxUSE_PORTABLE_FONTS_IN_MSW
46 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
47 #endif
2bda0e17
KB
48#endif
49
0c5d3e1c
VZ
50// ----------------------------------------------------------------------------
51// wxFontRefData - the internal description of the font
52// ----------------------------------------------------------------------------
2bda0e17 53
0c5d3e1c 54class WXDLLEXPORT wxFontRefData: public wxGDIRefData
2bda0e17 55{
0c5d3e1c
VZ
56friend class WXDLLEXPORT wxFont;
57
58public:
59 wxFontRefData()
60 {
74b31181
VZ
61 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
62 "", wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
63 }
64
65 wxFontRefData(const wxFontRefData& data)
66 {
67 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
68 data.m_underlined, data.m_faceName, data.m_encoding);
69
70 m_fontId = data.m_fontId;
71 }
72
73 wxFontRefData(int size,
74 int family,
75 int style,
76 int weight,
77 bool underlined,
78 const wxString& faceName,
79 wxFontEncoding encoding)
80 {
81 Init(size, family, style, weight, underlined, faceName, encoding);
82 }
2bda0e17 83
0c5d3e1c
VZ
84 virtual ~wxFontRefData();
85
86protected:
87 // common part of all ctors
88 void Init(int size,
89 int family,
90 int style,
91 int weight,
92 bool underlined,
93 const wxString& faceName,
94 wxFontEncoding encoding);
95
96 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
97 // DELETED by destructor
98 bool m_temporary;
99
100 int m_fontId;
101
102 // font characterstics
103 int m_pointSize;
104 int m_family;
105 int m_style;
106 int m_weight;
107 bool m_underlined;
108 wxString m_faceName;
109 wxFontEncoding m_encoding;
110
111 // Windows font handle
112 WXHFONT m_hFont;
113};
114
115// ============================================================================
116// implementation
117// ============================================================================
118
119// ----------------------------------------------------------------------------
120// wxFontRefData
121// ----------------------------------------------------------------------------
122
123void wxFontRefData::Init(int pointSize,
124 int family,
125 int style,
126 int weight,
127 bool underlined,
128 const wxString& faceName,
129 wxFontEncoding encoding)
b823f5a1 130{
0c5d3e1c
VZ
131 m_style = style;
132 m_pointSize = pointSize;
133 m_family = family;
134 m_style = style;
135 m_weight = weight;
136 m_underlined = underlined;
137 m_faceName = faceName;
138 m_encoding = encoding;
139
140 m_fontId = 0;
b823f5a1 141 m_temporary = FALSE;
0c5d3e1c 142
b823f5a1
JS
143 m_hFont = 0;
144}
145
0c5d3e1c 146wxFontRefData::~wxFontRefData()
2bda0e17
KB
147{
148 if ( m_hFont )
0c5d3e1c
VZ
149 {
150 if ( !::DeleteObject((HFONT) m_hFont) )
151 {
152 wxLogLastError("DeleteObject(font)");
153 }
154 }
2bda0e17
KB
155}
156
0c5d3e1c
VZ
157// ----------------------------------------------------------------------------
158// wxFont
159// ----------------------------------------------------------------------------
160
161void wxFont::Init()
2bda0e17
KB
162{
163 if ( wxTheFontList )
164 wxTheFontList->Append(this);
165}
166
167/* Constructor for a font. Note that the real construction is done
168 * in wxDC::SetFont, when information is available about scaling etc.
169 */
0c5d3e1c
VZ
170bool wxFont::Create(int pointSize,
171 int family,
172 int style,
173 int weight,
174 bool underlined,
175 const wxString& faceName,
176 wxFontEncoding encoding)
2bda0e17 177{
0c5d3e1c
VZ
178 UnRef();
179 m_refData = new wxFontRefData(pointSize, family, style, weight,
180 underlined, faceName, encoding);
2bda0e17 181
0c5d3e1c 182 RealizeResource();
2bda0e17 183
0c5d3e1c 184 return TRUE;
2bda0e17
KB
185}
186
187wxFont::~wxFont()
188{
0c5d3e1c
VZ
189 if ( wxTheFontList )
190 wxTheFontList->DeleteObject(this);
2bda0e17
KB
191}
192
0c5d3e1c
VZ
193// ----------------------------------------------------------------------------
194// real implementation
195// ----------------------------------------------------------------------------
196
197bool wxFont::RealizeResource()
2bda0e17 198{
0c5d3e1c
VZ
199 if ( GetResourceHandle() )
200 {
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(_T("Calling wxFont::RealizeResource() twice"));
204
205 return TRUE;
206 }
207
2bda0e17
KB
208 BYTE ff_italic;
209 int ff_weight = 0;
210 int ff_family = 0;
0c5d3e1c 211 wxString ff_face;
2bda0e17
KB
212
213 switch (M_FONTDATA->m_family)
214 {
0c5d3e1c
VZ
215 case wxSCRIPT: ff_family = FF_SCRIPT ;
216 ff_face = _T("Script") ;
217 break ;
218 case wxDECORATIVE: ff_family = FF_DECORATIVE;
219 break;
220 case wxROMAN: ff_family = FF_ROMAN;
221 ff_face = _T("Times New Roman") ;
222 break;
223 case wxTELETYPE:
224 case wxMODERN: ff_family = FF_MODERN;
225 ff_face = _T("Courier New") ;
226 break;
227 case wxSWISS: ff_family = FF_SWISS;
228 ff_face = _T("Arial") ;
229 break;
230 case wxDEFAULT:
231 default: ff_family = FF_SWISS;
232 ff_face = _T("Arial") ;
2bda0e17
KB
233 }
234
235 if (M_FONTDATA->m_style == wxITALIC || M_FONTDATA->m_style == wxSLANT)
0c5d3e1c 236 ff_italic = 1;
2bda0e17 237 else
0c5d3e1c 238 ff_italic = 0;
2bda0e17
KB
239
240 if (M_FONTDATA->m_weight == wxNORMAL)
0c5d3e1c 241 ff_weight = FW_NORMAL;
2bda0e17 242 else if (M_FONTDATA->m_weight == wxLIGHT)
0c5d3e1c 243 ff_weight = FW_LIGHT;
2bda0e17 244 else if (M_FONTDATA->m_weight == wxBOLD)
0c5d3e1c 245 ff_weight = FW_BOLD;
2bda0e17 246
837e5743 247 const wxChar* pzFace = (const wxChar*) ff_face;
34da0970 248 if (!M_FONTDATA->m_faceName.IsNull())
837e5743 249 pzFace = (const wxChar*) M_FONTDATA->m_faceName ;
2bda0e17 250
0c5d3e1c
VZ
251 /* Always calculate fonts using the screen DC (is this the best strategy?)
252 * There may be confusion if a font is selected into a printer
253 * DC (say), because the height will be calculated very differently.
2bda0e17
KB
254 // What sort of display is it?
255 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
256
257 int nHeight;
0c5d3e1c 258
2bda0e17
KB
259 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
260 {
0c5d3e1c
VZ
261 // Have to get screen DC Caps, because a metafile will return 0.
262 HDC dc2 = ::GetDC(NULL);
263 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72;
264 ::ReleaseDC(NULL, dc2);
2bda0e17
KB
265 }
266 else
267 {
0c5d3e1c 268 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
2bda0e17 269 }
0c5d3e1c 270 */
2bda0e17
KB
271 // Have to get screen DC Caps, because a metafile will return 0.
272 HDC dc2 = ::GetDC(NULL);
273 int ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
274 ::ReleaseDC(NULL, dc2);
275
276 // New behaviour: apparently ppInch varies according to
277 // Large/Small Fonts setting in Windows. This messes
278 // up fonts. So, set ppInch to a constant 96 dpi.
279 ppInch = 96;
0c5d3e1c 280
1f112209 281#if wxFONT_SIZE_COMPATIBILITY
2bda0e17
KB
282 // Incorrect, but compatible with old wxWindows behaviour
283 int nHeight = (M_FONTDATA->m_pointSize*ppInch/72);
284#else
285 // Correct for Windows compatibility
286 int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72);
287#endif
288
289 bool ff_underline = M_FONTDATA->m_underlined;
290
291 M_FONTDATA->m_hFont = (WXHFONT) CreateFont(nHeight, 0, 0, 0,ff_weight,ff_italic,(BYTE)ff_underline,
0c5d3e1c
VZ
292 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
293 PROOF_QUALITY, DEFAULT_PITCH | ff_family, pzFace);
b2aef89b 294#ifdef WXDEBUG_CREATE
48a84964 295 if (m_hFont==NULL) wxError(_T("Cannot create font"),_T("Internal Error")) ;
2bda0e17
KB
296#endif
297 return (M_FONTDATA->m_hFont != (WXHFONT) NULL);
2bda0e17
KB
298}
299
300bool wxFont::FreeResource(bool force)
301{
0c5d3e1c
VZ
302 if ( GetResourceHandle() )
303 {
304 if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
305 {
306 wxLogLastError("DeleteObject(font)");
307 }
308
309 M_FONTDATA->m_hFont = 0;
310
311 return TRUE;
312 }
313 return FALSE;
2bda0e17
KB
314}
315
b823f5a1 316WXHANDLE wxFont::GetResourceHandle()
2bda0e17 317{
0c5d3e1c
VZ
318 if ( !M_FONTDATA )
319 return 0;
320 else
321 return (WXHANDLE)M_FONTDATA->m_hFont ;
2bda0e17
KB
322}
323
e90babdf 324bool wxFont::IsFree() const
2bda0e17 325{
0c5d3e1c 326 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
2bda0e17
KB
327}
328
b823f5a1
JS
329void wxFont::Unshare()
330{
331 // Don't change shared data
0c5d3e1c 332 if ( !m_refData )
b823f5a1
JS
333 {
334 m_refData = new wxFontRefData();
335 }
336 else
337 {
0c5d3e1c 338 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
b823f5a1
JS
339 UnRef();
340 m_refData = ref;
341 }
342}
343
0c5d3e1c
VZ
344// ----------------------------------------------------------------------------
345// change font attribute: we recreate font when doing it
346// ----------------------------------------------------------------------------
347
debe6624 348void wxFont::SetPointSize(int pointSize)
2bda0e17 349{
b823f5a1
JS
350 Unshare();
351
2bda0e17 352 M_FONTDATA->m_pointSize = pointSize;
b823f5a1
JS
353
354 RealizeResource();
2bda0e17
KB
355}
356
debe6624 357void wxFont::SetFamily(int family)
2bda0e17 358{
b823f5a1
JS
359 Unshare();
360
2bda0e17 361 M_FONTDATA->m_family = family;
b823f5a1
JS
362
363 RealizeResource();
2bda0e17
KB
364}
365
debe6624 366void wxFont::SetStyle(int style)
2bda0e17 367{
b823f5a1
JS
368 Unshare();
369
2bda0e17 370 M_FONTDATA->m_style = style;
b823f5a1
JS
371
372 RealizeResource();
2bda0e17
KB
373}
374
debe6624 375void wxFont::SetWeight(int weight)
2bda0e17 376{
b823f5a1
JS
377 Unshare();
378
2bda0e17 379 M_FONTDATA->m_weight = weight;
b823f5a1
JS
380
381 RealizeResource();
2bda0e17
KB
382}
383
384void wxFont::SetFaceName(const wxString& faceName)
385{
b823f5a1
JS
386 Unshare();
387
2bda0e17 388 M_FONTDATA->m_faceName = faceName;
b823f5a1
JS
389
390 RealizeResource();
2bda0e17
KB
391}
392
debe6624 393void wxFont::SetUnderlined(bool underlined)
2bda0e17 394{
b823f5a1
JS
395 Unshare();
396
2bda0e17 397 M_FONTDATA->m_underlined = underlined;
b823f5a1
JS
398
399 RealizeResource();
2bda0e17
KB
400}
401
0c5d3e1c 402void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 403{
0c5d3e1c
VZ
404 Unshare();
405
406 M_FONTDATA->m_encoding = encoding;
407
408 RealizeResource();
409}
410
411// ----------------------------------------------------------------------------
412// accessors
413// ----------------------------------------------------------------------------
414
415int wxFont::GetPointSize() const
416{
417 return M_FONTDATA->m_pointSize;
418}
419
420int wxFont::GetFamily() const
421{
422 return M_FONTDATA->m_family;
2bda0e17
KB
423}
424
0c5d3e1c 425int wxFont::GetFontId() const
2bda0e17 426{
0c5d3e1c 427 return M_FONTDATA->m_fontId;
2bda0e17
KB
428}
429
0c5d3e1c 430int wxFont::GetStyle() const
2bda0e17 431{
0c5d3e1c 432 return M_FONTDATA->m_style;
2bda0e17
KB
433}
434
0c5d3e1c 435int wxFont::GetWeight() const
2bda0e17 436{
0c5d3e1c 437 return M_FONTDATA->m_weight;
2bda0e17
KB
438}
439
0c5d3e1c
VZ
440bool wxFont::GetUnderlined() const
441{
442 return M_FONTDATA->m_underlined;
443}
444
445wxString wxFont::GetFaceName() const
446{
447 wxString str;
448 if ( M_FONTDATA )
449 str = M_FONTDATA->m_faceName ;
450 return str;
451}
452
453wxFontEncoding wxFont::GetEncoding() const
454{
455 return M_FONTDATA->m_encoding;
456}