]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
Change wxGetCurrentUTime as wxGetCurrentMTime (milli not micro!)
[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 {
61 Init();
62 }
63
64 wxFontRefData(const wxFontRefData& data)
65 {
66 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
67 data.m_underlined, data.m_faceName, data.m_encoding);
68
69 m_fontId = data.m_fontId;
70 }
71
72 wxFontRefData(int size,
73 int family,
74 int style,
75 int weight,
76 bool underlined,
77 const wxString& faceName,
78 wxFontEncoding encoding)
79 {
80 Init(size, family, style, weight, underlined, faceName, encoding);
81 }
2bda0e17 82
0c5d3e1c
VZ
83 virtual ~wxFontRefData();
84
85protected:
86 // common part of all ctors
87 void Init(int size,
88 int family,
89 int style,
90 int weight,
91 bool underlined,
92 const wxString& faceName,
93 wxFontEncoding encoding);
94
95 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
96 // DELETED by destructor
97 bool m_temporary;
98
99 int m_fontId;
100
101 // font characterstics
102 int m_pointSize;
103 int m_family;
104 int m_style;
105 int m_weight;
106 bool m_underlined;
107 wxString m_faceName;
108 wxFontEncoding m_encoding;
109
110 // Windows font handle
111 WXHFONT m_hFont;
112};
113
114// ============================================================================
115// implementation
116// ============================================================================
117
118// ----------------------------------------------------------------------------
119// wxFontRefData
120// ----------------------------------------------------------------------------
121
122void wxFontRefData::Init(int pointSize,
123 int family,
124 int style,
125 int weight,
126 bool underlined,
127 const wxString& faceName,
128 wxFontEncoding encoding)
b823f5a1 129{
0c5d3e1c
VZ
130 m_style = style;
131 m_pointSize = pointSize;
132 m_family = family;
133 m_style = style;
134 m_weight = weight;
135 m_underlined = underlined;
136 m_faceName = faceName;
137 m_encoding = encoding;
138
139 m_fontId = 0;
b823f5a1 140 m_temporary = FALSE;
0c5d3e1c 141
b823f5a1
JS
142 m_hFont = 0;
143}
144
0c5d3e1c 145wxFontRefData::~wxFontRefData()
2bda0e17
KB
146{
147 if ( m_hFont )
0c5d3e1c
VZ
148 {
149 if ( !::DeleteObject((HFONT) m_hFont) )
150 {
151 wxLogLastError("DeleteObject(font)");
152 }
153 }
2bda0e17
KB
154}
155
0c5d3e1c
VZ
156// ----------------------------------------------------------------------------
157// wxFont
158// ----------------------------------------------------------------------------
159
160void wxFont::Init()
2bda0e17
KB
161{
162 if ( wxTheFontList )
163 wxTheFontList->Append(this);
164}
165
166/* Constructor for a font. Note that the real construction is done
167 * in wxDC::SetFont, when information is available about scaling etc.
168 */
0c5d3e1c
VZ
169bool wxFont::Create(int pointSize,
170 int family,
171 int style,
172 int weight,
173 bool underlined,
174 const wxString& faceName,
175 wxFontEncoding encoding)
2bda0e17 176{
0c5d3e1c
VZ
177 UnRef();
178 m_refData = new wxFontRefData(pointSize, family, style, weight,
179 underlined, faceName, encoding);
2bda0e17 180
0c5d3e1c 181 RealizeResource();
2bda0e17 182
0c5d3e1c 183 return TRUE;
2bda0e17
KB
184}
185
186wxFont::~wxFont()
187{
0c5d3e1c
VZ
188 if ( wxTheFontList )
189 wxTheFontList->DeleteObject(this);
2bda0e17
KB
190}
191
0c5d3e1c
VZ
192// ----------------------------------------------------------------------------
193// real implementation
194// ----------------------------------------------------------------------------
195
196bool wxFont::RealizeResource()
2bda0e17 197{
0c5d3e1c
VZ
198 if ( GetResourceHandle() )
199 {
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"));
203
204 return TRUE;
205 }
206
2bda0e17
KB
207 BYTE ff_italic;
208 int ff_weight = 0;
209 int ff_family = 0;
0c5d3e1c 210 wxString ff_face;
2bda0e17
KB
211
212 switch (M_FONTDATA->m_family)
213 {
0c5d3e1c
VZ
214 case wxSCRIPT: ff_family = FF_SCRIPT ;
215 ff_face = _T("Script") ;
216 break ;
217 case wxDECORATIVE: ff_family = FF_DECORATIVE;
218 break;
219 case wxROMAN: ff_family = FF_ROMAN;
220 ff_face = _T("Times New Roman") ;
221 break;
222 case wxTELETYPE:
223 case wxMODERN: ff_family = FF_MODERN;
224 ff_face = _T("Courier New") ;
225 break;
226 case wxSWISS: ff_family = FF_SWISS;
227 ff_face = _T("Arial") ;
228 break;
229 case wxDEFAULT:
230 default: ff_family = FF_SWISS;
231 ff_face = _T("Arial") ;
2bda0e17
KB
232 }
233
234 if (M_FONTDATA->m_style == wxITALIC || M_FONTDATA->m_style == wxSLANT)
0c5d3e1c 235 ff_italic = 1;
2bda0e17 236 else
0c5d3e1c 237 ff_italic = 0;
2bda0e17
KB
238
239 if (M_FONTDATA->m_weight == wxNORMAL)
0c5d3e1c 240 ff_weight = FW_NORMAL;
2bda0e17 241 else if (M_FONTDATA->m_weight == wxLIGHT)
0c5d3e1c 242 ff_weight = FW_LIGHT;
2bda0e17 243 else if (M_FONTDATA->m_weight == wxBOLD)
0c5d3e1c 244 ff_weight = FW_BOLD;
2bda0e17 245
837e5743 246 const wxChar* pzFace = (const wxChar*) ff_face;
34da0970 247 if (!M_FONTDATA->m_faceName.IsNull())
837e5743 248 pzFace = (const wxChar*) M_FONTDATA->m_faceName ;
2bda0e17 249
0c5d3e1c
VZ
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.
2bda0e17
KB
253 // What sort of display is it?
254 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
255
256 int nHeight;
0c5d3e1c 257
2bda0e17
KB
258 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
259 {
0c5d3e1c
VZ
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);
2bda0e17
KB
264 }
265 else
266 {
0c5d3e1c 267 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
2bda0e17 268 }
0c5d3e1c 269 */
2bda0e17
KB
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);
274
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.
278 ppInch = 96;
0c5d3e1c 279
1f112209 280#if wxFONT_SIZE_COMPATIBILITY
2bda0e17
KB
281 // Incorrect, but compatible with old wxWindows behaviour
282 int nHeight = (M_FONTDATA->m_pointSize*ppInch/72);
283#else
284 // Correct for Windows compatibility
285 int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72);
286#endif
287
288 bool ff_underline = M_FONTDATA->m_underlined;
289
290 M_FONTDATA->m_hFont = (WXHFONT) CreateFont(nHeight, 0, 0, 0,ff_weight,ff_italic,(BYTE)ff_underline,
0c5d3e1c
VZ
291 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
292 PROOF_QUALITY, DEFAULT_PITCH | ff_family, pzFace);
b2aef89b 293#ifdef WXDEBUG_CREATE
48a84964 294 if (m_hFont==NULL) wxError(_T("Cannot create font"),_T("Internal Error")) ;
2bda0e17
KB
295#endif
296 return (M_FONTDATA->m_hFont != (WXHFONT) NULL);
2bda0e17
KB
297}
298
299bool wxFont::FreeResource(bool force)
300{
0c5d3e1c
VZ
301 if ( GetResourceHandle() )
302 {
303 if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
304 {
305 wxLogLastError("DeleteObject(font)");
306 }
307
308 M_FONTDATA->m_hFont = 0;
309
310 return TRUE;
311 }
312 return FALSE;
2bda0e17
KB
313}
314
b823f5a1 315WXHANDLE wxFont::GetResourceHandle()
2bda0e17 316{
0c5d3e1c
VZ
317 if ( !M_FONTDATA )
318 return 0;
319 else
320 return (WXHANDLE)M_FONTDATA->m_hFont ;
2bda0e17
KB
321}
322
e90babdf 323bool wxFont::IsFree() const
2bda0e17 324{
0c5d3e1c 325 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
2bda0e17
KB
326}
327
b823f5a1
JS
328void wxFont::Unshare()
329{
330 // Don't change shared data
0c5d3e1c 331 if ( !m_refData )
b823f5a1
JS
332 {
333 m_refData = new wxFontRefData();
334 }
335 else
336 {
0c5d3e1c 337 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
b823f5a1
JS
338 UnRef();
339 m_refData = ref;
340 }
341}
342
0c5d3e1c
VZ
343// ----------------------------------------------------------------------------
344// change font attribute: we recreate font when doing it
345// ----------------------------------------------------------------------------
346
debe6624 347void wxFont::SetPointSize(int pointSize)
2bda0e17 348{
b823f5a1
JS
349 Unshare();
350
2bda0e17 351 M_FONTDATA->m_pointSize = pointSize;
b823f5a1
JS
352
353 RealizeResource();
2bda0e17
KB
354}
355
debe6624 356void wxFont::SetFamily(int family)
2bda0e17 357{
b823f5a1
JS
358 Unshare();
359
2bda0e17 360 M_FONTDATA->m_family = family;
b823f5a1
JS
361
362 RealizeResource();
2bda0e17
KB
363}
364
debe6624 365void wxFont::SetStyle(int style)
2bda0e17 366{
b823f5a1
JS
367 Unshare();
368
2bda0e17 369 M_FONTDATA->m_style = style;
b823f5a1
JS
370
371 RealizeResource();
2bda0e17
KB
372}
373
debe6624 374void wxFont::SetWeight(int weight)
2bda0e17 375{
b823f5a1
JS
376 Unshare();
377
2bda0e17 378 M_FONTDATA->m_weight = weight;
b823f5a1
JS
379
380 RealizeResource();
2bda0e17
KB
381}
382
383void wxFont::SetFaceName(const wxString& faceName)
384{
b823f5a1
JS
385 Unshare();
386
2bda0e17 387 M_FONTDATA->m_faceName = faceName;
b823f5a1
JS
388
389 RealizeResource();
2bda0e17
KB
390}
391
debe6624 392void wxFont::SetUnderlined(bool underlined)
2bda0e17 393{
b823f5a1
JS
394 Unshare();
395
2bda0e17 396 M_FONTDATA->m_underlined = underlined;
b823f5a1
JS
397
398 RealizeResource();
2bda0e17
KB
399}
400
0c5d3e1c 401void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 402{
0c5d3e1c
VZ
403 Unshare();
404
405 M_FONTDATA->m_encoding = encoding;
406
407 RealizeResource();
408}
409
410// ----------------------------------------------------------------------------
411// accessors
412// ----------------------------------------------------------------------------
413
414int wxFont::GetPointSize() const
415{
416 return M_FONTDATA->m_pointSize;
417}
418
419int wxFont::GetFamily() const
420{
421 return M_FONTDATA->m_family;
2bda0e17
KB
422}
423
0c5d3e1c 424int wxFont::GetFontId() const
2bda0e17 425{
0c5d3e1c 426 return M_FONTDATA->m_fontId;
2bda0e17
KB
427}
428
0c5d3e1c 429int wxFont::GetStyle() const
2bda0e17 430{
0c5d3e1c 431 return M_FONTDATA->m_style;
2bda0e17
KB
432}
433
0c5d3e1c 434int wxFont::GetWeight() const
2bda0e17 435{
0c5d3e1c 436 return M_FONTDATA->m_weight;
2bda0e17
KB
437}
438
0c5d3e1c
VZ
439bool wxFont::GetUnderlined() const
440{
441 return M_FONTDATA->m_underlined;
442}
443
444wxString wxFont::GetFaceName() const
445{
446 wxString str;
447 if ( M_FONTDATA )
448 str = M_FONTDATA->m_faceName ;
449 return str;
450}
451
452wxFontEncoding wxFont::GetEncoding() const
453{
454 return M_FONTDATA->m_encoding;
455}