]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
More small fixes
[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
b9b3ccd9 9// Licence: wxWindows licence
2bda0e17
KB
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 "wx/setup.h"
33 #include "wx/list.h"
34 #include "wx/utils.h"
35 #include "wx/app.h"
36 #include "wx/font.h"
f94dfb38 37 #include "wx/log.h"
0c5d3e1c 38#endif // WX_PRECOMP
2bda0e17 39
76e23cdb 40#include "wx/fontutil.h"
09fcd889 41#include "wx/tokenzr.h"
76e23cdb 42
2bda0e17 43#include "wx/msw/private.h"
1e6feb95 44#include "wx/tokenzr.h"
2bda0e17 45
7fee680b 46IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
2bda0e17 47
3ca6a5f0
BP
48// ----------------------------------------------------------------------------
49// constants
50// ----------------------------------------------------------------------------
51
52// the default font size in points
53static const int wxDEFAULT_FONT_SIZE = 12;
54
0c5d3e1c
VZ
55// ----------------------------------------------------------------------------
56// wxFontRefData - the internal description of the font
57// ----------------------------------------------------------------------------
2bda0e17 58
0c5d3e1c 59class WXDLLEXPORT wxFontRefData: public wxGDIRefData
2bda0e17 60{
0c5d3e1c
VZ
61friend class WXDLLEXPORT wxFont;
62
63public:
64 wxFontRefData()
65 {
3ca6a5f0 66 Init(wxDEFAULT_FONT_SIZE, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
74b31181 67 "", wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
68 }
69
70 wxFontRefData(const wxFontRefData& data)
71 {
72 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
73 data.m_underlined, data.m_faceName, data.m_encoding);
74
75 m_fontId = data.m_fontId;
76 }
77
78 wxFontRefData(int size,
79 int family,
80 int style,
81 int weight,
82 bool underlined,
83 const wxString& faceName,
84 wxFontEncoding encoding)
85 {
86 Init(size, family, style, weight, underlined, faceName, encoding);
87 }
2bda0e17 88
789034a0 89 wxFontRefData(const wxNativeFontInfo& info)
09fcd889
VZ
90 {
91 Init(info);
92 }
93
0c5d3e1c
VZ
94 virtual ~wxFontRefData();
95
96protected:
97 // common part of all ctors
98 void Init(int size,
99 int family,
100 int style,
101 int weight,
102 bool underlined,
103 const wxString& faceName,
104 wxFontEncoding encoding);
105
09fcd889
VZ
106 void Init(const wxNativeFontInfo& info);
107
0c5d3e1c
VZ
108 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
109 // DELETED by destructor
110 bool m_temporary;
111
112 int m_fontId;
113
114 // font characterstics
115 int m_pointSize;
116 int m_family;
117 int m_style;
118 int m_weight;
119 bool m_underlined;
120 wxString m_faceName;
121 wxFontEncoding m_encoding;
122
123 // Windows font handle
124 WXHFONT m_hFont;
789034a0 125
09fcd889
VZ
126 // Native font info
127 wxNativeFontInfo m_nativeFontInfo;
128 bool m_nativeFontInfoOk;
0c5d3e1c
VZ
129};
130
131// ============================================================================
132// implementation
133// ============================================================================
134
135// ----------------------------------------------------------------------------
136// wxFontRefData
137// ----------------------------------------------------------------------------
138
139void wxFontRefData::Init(int pointSize,
140 int family,
141 int style,
142 int weight,
143 bool underlined,
144 const wxString& faceName,
145 wxFontEncoding encoding)
b823f5a1 146{
b9b3ccd9
VZ
147 m_style = style;
148 m_pointSize = pointSize;
149 m_family = family;
150 m_style = style;
151 m_weight = weight;
152 m_underlined = underlined;
153 m_faceName = faceName;
0c5d3e1c
VZ
154 m_encoding = encoding;
155
b9b3ccd9
VZ
156 m_fontId = 0;
157 m_temporary = FALSE;
0c5d3e1c 158
b9b3ccd9 159 m_hFont = 0;
789034a0 160
09fcd889
VZ
161 m_nativeFontInfoOk = FALSE;
162}
163
164void wxFontRefData::Init(const wxNativeFontInfo& info)
165{
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;
172
173 switch ( lfFamily )
174 {
175 case FF_ROMAN:
176 m_family = wxROMAN;
177 break;
178
179 case FF_SWISS:
180 m_family = wxSWISS;
181 break;
182
183 case FF_SCRIPT:
184 m_family = wxSCRIPT;
185 break;
186
187 case FF_MODERN:
188 m_family = wxMODERN;
189 break;
190
191 case FF_DECORATIVE:
192 m_family = wxDECORATIVE;
193 break;
194
195 default:
196 m_family = wxSWISS;
197 }
198
199 // weight and style
200 switch ( info.lf.lfWeight )
201 {
202 case FW_LIGHT:
203 m_weight = wxLIGHT;
204 break;
205
206 default:
207 case FW_NORMAL:
208 m_weight = wxNORMAL;
209 break;
210
211 case FW_BOLD:
212 m_weight = wxBOLD;
213 break;
214 }
215
216 m_style = info.lf.lfItalic ? wxITALIC : wxNORMAL;
217
218 m_underlined = info.lf.lfUnderline != 0;
219
220 m_faceName = info.lf.lfFaceName;
221
09fcd889
VZ
222 int height = abs(info.lf.lfHeight);
223
55bd3f34
VZ
224 // remember that 1pt = 1/72inch
225 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
09fcd889 226 m_pointSize = (int) (((72.0*((double)height))/(double) ppInch) + 0.5);
789034a0 227
09fcd889 228 m_encoding = wxGetFontEncFromCharSet(info.lf.lfCharSet);
789034a0 229
09fcd889
VZ
230 m_fontId = 0;
231 m_temporary = FALSE;
232
233 m_hFont = 0;
789034a0 234
09fcd889
VZ
235 m_nativeFontInfoOk = TRUE;
236 m_nativeFontInfo = info;
b823f5a1
JS
237}
238
0c5d3e1c 239wxFontRefData::~wxFontRefData()
2bda0e17 240{
b9b3ccd9 241 if ( m_hFont )
0c5d3e1c 242 {
b9b3ccd9 243 if ( !::DeleteObject((HFONT) m_hFont) )
0c5d3e1c 244 {
f6bcfd97 245 wxLogLastError(wxT("DeleteObject(font)"));
0c5d3e1c
VZ
246 }
247 }
2bda0e17
KB
248}
249
09fcd889
VZ
250
251// ----------------------------------------------------------------------------
252// wxNativeFontInfo
253// ----------------------------------------------------------------------------
254
255bool wxNativeFontInfo::FromString(const wxString& s)
256{
257 long l;
258
259 wxStringTokenizer tokenizer(s, _T(";"));
260
261 wxString token = tokenizer.GetNextToken();
262 //
263 // Ignore the version for now
264 //
265
266 token = tokenizer.GetNextToken();
267 if ( !token.ToLong(&l) )
268 return FALSE;
269 lf.lfHeight = l;
270
271 token = tokenizer.GetNextToken();
272 if ( !token.ToLong(&l) )
273 return FALSE;
274 lf.lfWidth = l;
275
276 token = tokenizer.GetNextToken();
277 if ( !token.ToLong(&l) )
278 return FALSE;
279 lf.lfEscapement = l;
280
281 token = tokenizer.GetNextToken();
282 if ( !token.ToLong(&l) )
283 return FALSE;
284 lf.lfOrientation = l;
285
286 token = tokenizer.GetNextToken();
287 if ( !token.ToLong(&l) )
288 return FALSE;
289 lf.lfWeight = l;
290
291 token = tokenizer.GetNextToken();
292 if ( !token.ToLong(&l) )
293 return FALSE;
33ac7e6f 294 lf.lfItalic = (BYTE)l;
09fcd889
VZ
295
296 token = tokenizer.GetNextToken();
297 if ( !token.ToLong(&l) )
298 return FALSE;
33ac7e6f 299 lf.lfUnderline = (BYTE)l;
09fcd889
VZ
300
301 token = tokenizer.GetNextToken();
302 if ( !token.ToLong(&l) )
303 return FALSE;
33ac7e6f 304 lf.lfStrikeOut = (BYTE)l;
09fcd889
VZ
305
306 token = tokenizer.GetNextToken();
307 if ( !token.ToLong(&l) )
308 return FALSE;
33ac7e6f 309 lf.lfCharSet = (BYTE)l;
09fcd889
VZ
310
311 token = tokenizer.GetNextToken();
312 if ( !token.ToLong(&l) )
313 return FALSE;
33ac7e6f 314 lf.lfOutPrecision = (BYTE)l;
09fcd889
VZ
315
316 token = tokenizer.GetNextToken();
317 if ( !token.ToLong(&l) )
318 return FALSE;
33ac7e6f 319 lf.lfClipPrecision = (BYTE)l;
09fcd889
VZ
320
321 token = tokenizer.GetNextToken();
322 if ( !token.ToLong(&l) )
323 return FALSE;
33ac7e6f 324 lf.lfQuality = (BYTE)l;
09fcd889
VZ
325
326 token = tokenizer.GetNextToken();
327 if ( !token.ToLong(&l) )
328 return FALSE;
33ac7e6f 329 lf.lfPitchAndFamily = (BYTE)l;
09fcd889
VZ
330
331 token = tokenizer.GetNextToken();
332 if(!token)
333 return FALSE;
334 wxStrcpy(lf.lfFaceName, token.c_str());
335
336 return TRUE;
337}
338
339wxString wxNativeFontInfo::ToString() const
340{
341 wxString s;
342
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
345 lf.lfHeight,
346 lf.lfWidth,
347 lf.lfEscapement,
348 lf.lfOrientation,
349 lf.lfWeight,
350 lf.lfItalic,
351 lf.lfUnderline,
352 lf.lfStrikeOut,
353 lf.lfCharSet,
354 lf.lfOutPrecision,
355 lf.lfClipPrecision,
356 lf.lfQuality,
357 lf.lfPitchAndFamily,
358 lf.lfFaceName);
359
360 return s;
361}
362
0c5d3e1c
VZ
363// ----------------------------------------------------------------------------
364// wxFont
365// ----------------------------------------------------------------------------
366
367void wxFont::Init()
2bda0e17
KB
368{
369 if ( wxTheFontList )
370 wxTheFontList->Append(this);
371}
372
76e23cdb
VZ
373bool wxFont::Create(const wxNativeFontInfo& info)
374{
09fcd889
VZ
375 UnRef();
376
377 m_refData = new wxFontRefData(info);
378
379 RealizeResource();
380
381 return TRUE;
76e23cdb
VZ
382}
383
384wxFont::wxFont(const wxString& fontdesc)
385{
386 wxNativeFontInfo info;
387 if ( info.FromString(fontdesc) )
388 (void)Create(info);
389}
390
2bda0e17
KB
391/* Constructor for a font. Note that the real construction is done
392 * in wxDC::SetFont, when information is available about scaling etc.
393 */
0c5d3e1c
VZ
394bool wxFont::Create(int pointSize,
395 int family,
396 int style,
397 int weight,
398 bool underlined,
399 const wxString& faceName,
400 wxFontEncoding encoding)
2bda0e17 401{
0c5d3e1c 402 UnRef();
3ca6a5f0
BP
403
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;
408
0c5d3e1c
VZ
409 m_refData = new wxFontRefData(pointSize, family, style, weight,
410 underlined, faceName, encoding);
2bda0e17 411
0c5d3e1c 412 RealizeResource();
2bda0e17 413
0c5d3e1c 414 return TRUE;
2bda0e17
KB
415}
416
417wxFont::~wxFont()
418{
0c5d3e1c
VZ
419 if ( wxTheFontList )
420 wxTheFontList->DeleteObject(this);
2bda0e17
KB
421}
422
0c5d3e1c
VZ
423// ----------------------------------------------------------------------------
424// real implementation
425// ----------------------------------------------------------------------------
426
427bool wxFont::RealizeResource()
2bda0e17 428{
0c5d3e1c
VZ
429 if ( GetResourceHandle() )
430 {
431 // VZ: the old code returned FALSE in this case, but it doesn't seem
432 // to make sense because the font _was_ created
0c5d3e1c
VZ
433 return TRUE;
434 }
435
09fcd889
VZ
436 if(!M_FONTDATA->m_nativeFontInfoOk)
437 {
438 wxFillLogFont(&M_FONTDATA->m_nativeFontInfo.lf, this);
439 M_FONTDATA->m_nativeFontInfoOk = TRUE;
440 }
789034a0 441
09fcd889
VZ
442 M_FONTDATA->m_hFont = (WXHFONT)::CreateFontIndirect(&M_FONTDATA->m_nativeFontInfo.lf);
443 M_FONTDATA->m_faceName = M_FONTDATA->m_nativeFontInfo.lf.lfFaceName;
11c7d5b6 444 if ( !M_FONTDATA->m_hFont )
b9b3ccd9 445 {
f6bcfd97 446 wxLogLastError(wxT("CreateFont"));
11c7d5b6
VZ
447
448 return FALSE;
b9b3ccd9
VZ
449 }
450
11c7d5b6 451 return TRUE;
2bda0e17
KB
452}
453
33ac7e6f 454bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 455{
0c5d3e1c
VZ
456 if ( GetResourceHandle() )
457 {
458 if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
459 {
f6bcfd97 460 wxLogLastError(wxT("DeleteObject(font)"));
0c5d3e1c
VZ
461 }
462
463 M_FONTDATA->m_hFont = 0;
464
465 return TRUE;
466 }
467 return FALSE;
2bda0e17
KB
468}
469
b823f5a1 470WXHANDLE wxFont::GetResourceHandle()
f6bcfd97
BP
471{
472 return GetHFONT();
473}
474
475WXHFONT wxFont::GetHFONT() const
2bda0e17 476{
0c5d3e1c
VZ
477 if ( !M_FONTDATA )
478 return 0;
479 else
11c7d5b6 480 return (WXHANDLE)M_FONTDATA->m_hFont;
2bda0e17
KB
481}
482
e90babdf 483bool wxFont::IsFree() const
2bda0e17 484{
0c5d3e1c 485 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
2bda0e17
KB
486}
487
b823f5a1
JS
488void wxFont::Unshare()
489{
b9b3ccd9
VZ
490 // Don't change shared data
491 if ( !m_refData )
b823f5a1 492 {
b9b3ccd9
VZ
493 m_refData = new wxFontRefData();
494 }
b823f5a1
JS
495 else
496 {
b9b3ccd9
VZ
497 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
498 UnRef();
499 m_refData = ref;
500 }
b823f5a1
JS
501}
502
0c5d3e1c
VZ
503// ----------------------------------------------------------------------------
504// change font attribute: we recreate font when doing it
505// ----------------------------------------------------------------------------
506
debe6624 507void wxFont::SetPointSize(int pointSize)
2bda0e17 508{
b823f5a1
JS
509 Unshare();
510
2bda0e17 511 M_FONTDATA->m_pointSize = pointSize;
09fcd889 512 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
513
514 RealizeResource();
2bda0e17
KB
515}
516
debe6624 517void wxFont::SetFamily(int family)
2bda0e17 518{
b823f5a1
JS
519 Unshare();
520
2bda0e17 521 M_FONTDATA->m_family = family;
09fcd889 522 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
523
524 RealizeResource();
2bda0e17
KB
525}
526
debe6624 527void wxFont::SetStyle(int style)
2bda0e17 528{
b823f5a1
JS
529 Unshare();
530
2bda0e17 531 M_FONTDATA->m_style = style;
09fcd889 532 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
533
534 RealizeResource();
2bda0e17
KB
535}
536
debe6624 537void wxFont::SetWeight(int weight)
2bda0e17 538{
b823f5a1
JS
539 Unshare();
540
2bda0e17 541 M_FONTDATA->m_weight = weight;
09fcd889 542 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
543
544 RealizeResource();
2bda0e17
KB
545}
546
547void wxFont::SetFaceName(const wxString& faceName)
548{
b823f5a1
JS
549 Unshare();
550
2bda0e17 551 M_FONTDATA->m_faceName = faceName;
09fcd889 552 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
553
554 RealizeResource();
2bda0e17
KB
555}
556
debe6624 557void wxFont::SetUnderlined(bool underlined)
2bda0e17 558{
b823f5a1
JS
559 Unshare();
560
2bda0e17 561 M_FONTDATA->m_underlined = underlined;
09fcd889 562 M_FONTDATA->m_nativeFontInfoOk = FALSE;
b823f5a1
JS
563
564 RealizeResource();
2bda0e17
KB
565}
566
0c5d3e1c 567void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 568{
0c5d3e1c
VZ
569 Unshare();
570
571 M_FONTDATA->m_encoding = encoding;
09fcd889
VZ
572 M_FONTDATA->m_nativeFontInfoOk = FALSE;
573
574 RealizeResource();
575}
576
577void wxFont::SetNativeFontInfo(const wxNativeFontInfo& info)
578{
579 Unshare();
789034a0
VZ
580
581 FreeResource();
09fcd889
VZ
582
583 M_FONTDATA->Init(info);
0c5d3e1c
VZ
584
585 RealizeResource();
586}
587
588// ----------------------------------------------------------------------------
589// accessors
590// ----------------------------------------------------------------------------
591
592int wxFont::GetPointSize() const
593{
789034a0
VZ
594 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
595
0c5d3e1c
VZ
596 return M_FONTDATA->m_pointSize;
597}
598
599int wxFont::GetFamily() const
600{
789034a0
VZ
601 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
602
0c5d3e1c 603 return M_FONTDATA->m_family;
2bda0e17
KB
604}
605
0c5d3e1c 606int wxFont::GetFontId() const
2bda0e17 607{
789034a0
VZ
608 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
609
0c5d3e1c 610 return M_FONTDATA->m_fontId;
2bda0e17
KB
611}
612
0c5d3e1c 613int wxFont::GetStyle() const
2bda0e17 614{
789034a0
VZ
615 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
616
0c5d3e1c 617 return M_FONTDATA->m_style;
2bda0e17
KB
618}
619
0c5d3e1c 620int wxFont::GetWeight() const
2bda0e17 621{
789034a0
VZ
622 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
623
0c5d3e1c 624 return M_FONTDATA->m_weight;
2bda0e17
KB
625}
626
0c5d3e1c
VZ
627bool wxFont::GetUnderlined() const
628{
789034a0
VZ
629 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
630
0c5d3e1c
VZ
631 return M_FONTDATA->m_underlined;
632}
633
634wxString wxFont::GetFaceName() const
635{
789034a0
VZ
636 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
637
638 return M_FONTDATA->m_faceName;
0c5d3e1c
VZ
639}
640
641wxFontEncoding wxFont::GetEncoding() const
642{
789034a0
VZ
643 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
644
0c5d3e1c
VZ
645 return M_FONTDATA->m_encoding;
646}
a1d58ddc 647
e421922f 648wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 649{
e421922f
VZ
650 if( M_FONTDATA->m_nativeFontInfoOk )
651 return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo);
1e6feb95 652
e421922f 653 return 0;
09fcd889
VZ
654}
655