]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
Applied patch [ 1204244 ] [wxMSW] Use Win2K look (MS Shell Dlg 2) if possible
[wxWidgets.git] / src / msw / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/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) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "font.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
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"
37 #include "wx/log.h"
38 #include "wx/encinfo.h"
39 #endif // WX_PRECOMP
40
41 #include "wx/msw/private.h"
42
43 #include "wx/fontutil.h"
44 #include "wx/fontmap.h"
45
46 #include "wx/tokenzr.h"
47
48 #if wxUSE_EXTENDED_RTTI
49
50 wxBEGIN_ENUM( wxFontFamily )
51 wxENUM_MEMBER( wxDEFAULT )
52 wxENUM_MEMBER( wxDECORATIVE )
53 wxENUM_MEMBER( wxROMAN )
54 wxENUM_MEMBER( wxSCRIPT )
55 wxENUM_MEMBER( wxSWISS )
56 wxENUM_MEMBER( wxMODERN )
57 wxENUM_MEMBER( wxTELETYPE )
58 wxEND_ENUM( wxFontFamily )
59
60 wxBEGIN_ENUM( wxFontStyle )
61 wxENUM_MEMBER( wxNORMAL )
62 wxENUM_MEMBER( wxITALIC )
63 wxENUM_MEMBER( wxSLANT )
64 wxEND_ENUM( wxFontStyle )
65
66 wxBEGIN_ENUM( wxFontWeight )
67 wxENUM_MEMBER( wxNORMAL )
68 wxENUM_MEMBER( wxLIGHT )
69 wxENUM_MEMBER( wxBOLD )
70 wxEND_ENUM( wxFontWeight )
71
72 IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h")
73
74 wxBEGIN_PROPERTIES_TABLE(wxFont)
75 wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( Family, int , SetFamily, GetFamily, (int)wxDEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontFamily
77 wxPROPERTY( Style, int , SetStyle, GetStyle, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontStyle
78 wxPROPERTY( Weight, int , SetWeight, GetWeight, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontWeight
79 wxPROPERTY( Underlined, bool , SetUnderlined, GetUnderlined, false , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
80 wxPROPERTY( Face, wxString , SetFaceName, GetFaceName, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
81 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
82 wxEND_PROPERTIES_TABLE()
83
84 wxCONSTRUCTOR_6( wxFont , int , Size , int , Family , int , Style , int , Weight , bool , Underlined , wxString , Face )
85
86 wxBEGIN_HANDLERS_TABLE(wxFont)
87 wxEND_HANDLERS_TABLE()
88
89 #else
90 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
91 #endif
92
93
94 // ----------------------------------------------------------------------------
95 // constants
96 // ----------------------------------------------------------------------------
97
98 // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
99 static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
100
101 // ----------------------------------------------------------------------------
102 // wxFontRefData - the internal description of the font
103 // ----------------------------------------------------------------------------
104
105 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
106 {
107 public:
108 // constructors
109 wxFontRefData()
110 {
111 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
112 wxFONTWEIGHT_NORMAL, false, wxEmptyString,
113 wxFONTENCODING_DEFAULT);
114 }
115
116 wxFontRefData(int size,
117 const wxSize& pixelSize,
118 bool sizeUsingPixels,
119 int family,
120 int style,
121 int weight,
122 bool underlined,
123 const wxString& faceName,
124 wxFontEncoding encoding)
125 {
126 Init(size, pixelSize, sizeUsingPixels, family, style, weight,
127 underlined, faceName, encoding);
128 }
129
130 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
131 {
132 Init(info, hFont);
133 }
134
135 wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
136 {
137 if ( data.m_nativeFontInfoOk )
138 {
139 Init(data.m_nativeFontInfo);
140 }
141 else
142 {
143 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels,
144 data.m_family, data.m_style, data.m_weight,
145 data.m_underlined, data.m_faceName, data.m_encoding);
146 }
147 }
148
149 virtual ~wxFontRefData();
150
151 // operations
152 bool Alloc(wxFont *font);
153
154 void Free();
155
156 // all wxFont accessors
157 int GetPointSize() const
158 {
159 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
160 : m_pointSize;
161 }
162
163 wxSize GetPixelSize() const
164 {
165 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize()
166 : m_pixelSize;
167 }
168
169 bool IsUsingSizeInPixels() const
170 {
171 return m_nativeFontInfoOk ? true : m_sizeUsingPixels;
172 }
173
174 int GetFamily() const
175 {
176 return m_family;
177 }
178
179 int GetStyle() const
180 {
181 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
182 : m_style;
183 }
184
185 int GetWeight() const
186 {
187 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
188 : m_weight;
189 }
190
191 bool GetUnderlined() const
192 {
193 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
194 : m_underlined;
195 }
196
197 wxString GetFaceName() const
198 {
199 wxString s;
200 if ( m_nativeFontInfoOk )
201 s = m_nativeFontInfo.GetFaceName();
202 else
203 s = m_faceName;
204
205 return s;
206 }
207
208 wxFontEncoding GetEncoding() const
209 {
210 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
211 : m_encoding;
212 }
213
214 WXHFONT GetHFONT() const { return m_hFont; }
215
216 // ... and setters
217 void SetPointSize(int pointSize)
218 {
219 if ( m_nativeFontInfoOk )
220 {
221 m_nativeFontInfo.SetPointSize(pointSize);
222 }
223 else
224 {
225 m_pointSize = pointSize;
226 m_sizeUsingPixels = false;
227 }
228 }
229
230 void SetPixelSize(const wxSize& pixelSize)
231 {
232 if ( m_nativeFontInfoOk )
233 {
234 m_nativeFontInfo.SetPixelSize(pixelSize);
235 }
236 else
237 {
238 m_pixelSize = pixelSize;
239 m_sizeUsingPixels = true;
240 }
241 }
242
243 void SetFamily(int family)
244 {
245 m_family = family;
246 }
247
248 void SetStyle(int style)
249 {
250 if ( m_nativeFontInfoOk )
251 m_nativeFontInfo.SetStyle((wxFontStyle)style);
252 else
253 m_style = style;
254 }
255
256 void SetWeight(int weight)
257 {
258 if ( m_nativeFontInfoOk )
259 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
260 else
261 m_weight = weight;
262 }
263
264 void SetFaceName(const wxString& faceName)
265 {
266 if ( m_nativeFontInfoOk )
267 m_nativeFontInfo.SetFaceName(faceName);
268 else
269 m_faceName = faceName;
270 }
271
272 void SetUnderlined(bool underlined)
273 {
274 if ( m_nativeFontInfoOk )
275 m_nativeFontInfo.SetUnderlined(underlined);
276 else
277 m_underlined = underlined;
278 }
279
280 void SetEncoding(wxFontEncoding encoding)
281 {
282 if ( m_nativeFontInfoOk )
283 m_nativeFontInfo.SetEncoding(encoding);
284 else
285 m_encoding = encoding;
286 }
287
288 // native font info tests
289 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
290
291 const wxNativeFontInfo& GetNativeFontInfo() const
292 { return m_nativeFontInfo; }
293
294 protected:
295 // common part of all ctors
296 void Init(int size,
297 const wxSize& pixelSize,
298 bool sizeUsingPixels,
299 int family,
300 int style,
301 int weight,
302 bool underlined,
303 const wxString& faceName,
304 wxFontEncoding encoding);
305
306 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
307
308 // font characterstics
309 int m_pointSize;
310 wxSize m_pixelSize;
311 bool m_sizeUsingPixels;
312 int m_family;
313 int m_style;
314 int m_weight;
315 bool m_underlined;
316 wxString m_faceName;
317 wxFontEncoding m_encoding;
318
319 // Windows font handle
320 WXHFONT m_hFont;
321
322 // Native font info
323 wxNativeFontInfo m_nativeFontInfo;
324 bool m_nativeFontInfoOk;
325 };
326
327 // ============================================================================
328 // implementation
329 // ============================================================================
330
331 // ----------------------------------------------------------------------------
332 // wxFontRefData
333 // ----------------------------------------------------------------------------
334
335 void wxFontRefData::Init(int pointSize,
336 const wxSize& pixelSize,
337 bool sizeUsingPixels,
338 int family,
339 int style,
340 int weight,
341 bool underlined,
342 const wxString& faceName,
343 wxFontEncoding encoding)
344 {
345 m_style = style;
346 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
347 m_pixelSize = pixelSize;
348 m_sizeUsingPixels = sizeUsingPixels;
349 m_family = family;
350 m_style = style;
351 m_weight = weight;
352 m_underlined = underlined;
353 m_faceName = faceName;
354 m_encoding = encoding;
355
356 m_hFont = 0;
357
358 m_nativeFontInfoOk = false;
359 }
360
361 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
362 {
363 // hFont may be zero, or it be passed in case we really want to
364 // use the exact font created in the underlying system
365 // (for example where we can't guarantee conversion from HFONT
366 // to LOGFONT back to HFONT)
367 m_hFont = hFont;
368
369 m_nativeFontInfoOk = true;
370 m_nativeFontInfo = info;
371 // This is the best we can do since we don't have the
372 // correct information at this point.
373 m_family = wxSWISS;
374 }
375
376 wxFontRefData::~wxFontRefData()
377 {
378 Free();
379 }
380
381 bool wxFontRefData::Alloc(wxFont *font)
382 {
383 if ( !m_nativeFontInfoOk )
384 {
385 wxFillLogFont(&m_nativeFontInfo.lf, font);
386 m_nativeFontInfoOk = true;
387 }
388
389 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
390 if ( !hfont )
391 {
392 wxLogLastError(wxT("CreateFont"));
393
394 return false;
395 }
396
397 m_hFont = (WXHFONT)hfont;
398
399 return true;
400 }
401
402 void wxFontRefData::Free()
403 {
404 if ( m_hFont )
405 {
406 if ( !::DeleteObject((HFONT) m_hFont) )
407 {
408 wxLogLastError(wxT("DeleteObject(font)"));
409 }
410
411 m_hFont = 0;
412 }
413 }
414
415 // ----------------------------------------------------------------------------
416 // wxNativeFontInfo
417 // ----------------------------------------------------------------------------
418
419 void wxNativeFontInfo::Init()
420 {
421 wxZeroMemory(lf);
422 }
423
424 int wxNativeFontInfo::GetPointSize() const
425 {
426 // FIXME: using the screen here results in incorrect font size calculation
427 // for printing!
428 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
429
430 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
431 }
432
433 wxSize wxNativeFontInfo::GetPixelSize() const
434 {
435 wxSize ret;
436 ret.SetHeight(lf.lfHeight);
437 ret.SetWidth(lf.lfWidth);
438 return ret;
439 }
440
441 wxFontStyle wxNativeFontInfo::GetStyle() const
442 {
443 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
444 }
445
446 wxFontWeight wxNativeFontInfo::GetWeight() const
447 {
448 if ( lf.lfWeight <= 300 )
449 return wxFONTWEIGHT_LIGHT;
450
451 if ( lf.lfWeight >= 600 )
452 return wxFONTWEIGHT_BOLD;
453
454 return wxFONTWEIGHT_NORMAL;
455 }
456
457 bool wxNativeFontInfo::GetUnderlined() const
458 {
459 return lf.lfUnderline != 0;
460 }
461
462 wxString wxNativeFontInfo::GetFaceName() const
463 {
464 return lf.lfFaceName;
465 }
466
467 wxFontFamily wxNativeFontInfo::GetFamily() const
468 {
469 wxFontFamily family;
470
471 // extract family from pitch-and-family
472 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
473 {
474 case FF_ROMAN:
475 family = wxFONTFAMILY_ROMAN;
476 break;
477
478 default:
479 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
480 // fall through
481
482 case FF_SWISS:
483 family = wxFONTFAMILY_SWISS;
484 break;
485
486 case FF_SCRIPT:
487 family = wxFONTFAMILY_SCRIPT;
488 break;
489
490 case FF_MODERN:
491 family = wxFONTFAMILY_MODERN;
492 break;
493
494 case FF_DECORATIVE:
495 family = wxFONTFAMILY_DECORATIVE;
496 break;
497 }
498
499 return family;
500 }
501
502 wxFontEncoding wxNativeFontInfo::GetEncoding() const
503 {
504 return wxGetFontEncFromCharSet(lf.lfCharSet);
505 }
506
507 void wxNativeFontInfo::SetPointSize(int pointsize)
508 {
509 // FIXME: using the screen here results in incorrect font size calculation
510 // for printing!
511 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
512
513 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
514 }
515
516 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
517 {
518 lf.lfHeight = pixelSize.GetHeight();
519 lf.lfWidth = pixelSize.GetWidth();
520 }
521
522
523 void wxNativeFontInfo::SetStyle(wxFontStyle style)
524 {
525 switch ( style )
526 {
527 default:
528 wxFAIL_MSG( _T("unknown font style") );
529 // fall through
530
531 case wxFONTSTYLE_NORMAL:
532 lf.lfItalic = FALSE;
533 break;
534
535 case wxFONTSTYLE_ITALIC:
536 case wxFONTSTYLE_SLANT:
537 lf.lfItalic = TRUE;
538 break;
539 }
540 }
541
542 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
543 {
544 switch ( weight )
545 {
546 default:
547 wxFAIL_MSG( _T("unknown font weight") );
548 // fall through
549
550 case wxFONTWEIGHT_NORMAL:
551 lf.lfWeight = FW_NORMAL;
552 break;
553
554 case wxFONTWEIGHT_LIGHT:
555 lf.lfWeight = FW_LIGHT;
556 break;
557
558 case wxFONTWEIGHT_BOLD:
559 lf.lfWeight = FW_BOLD;
560 break;
561 }
562 }
563
564 void wxNativeFontInfo::SetUnderlined(bool underlined)
565 {
566 lf.lfUnderline = underlined;
567 }
568
569 void wxNativeFontInfo::SetFaceName(wxString facename)
570 {
571 wxStrncpy(lf.lfFaceName, facename, WXSIZEOF(lf.lfFaceName));
572 }
573
574 void wxNativeFontInfo::SetFamily(wxFontFamily family)
575 {
576 BYTE ff_family;
577 wxString facename;
578
579 switch ( family )
580 {
581 case wxSCRIPT:
582 ff_family = FF_SCRIPT;
583 facename = _T("Script");
584 break;
585
586 case wxDECORATIVE:
587 ff_family = FF_DECORATIVE;
588 facename = _T("Old English Text MT");
589 break;
590
591 case wxROMAN:
592 ff_family = FF_ROMAN;
593 facename = _T("Times New Roman");
594 break;
595
596 case wxTELETYPE:
597 case wxMODERN:
598 ff_family = FF_MODERN;
599 facename = _T("Courier New");
600 break;
601
602 case wxSWISS:
603 ff_family = FF_SWISS;
604 facename = _T("Arial");
605 break;
606
607 case wxDEFAULT:
608 default:
609 {
610 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
611 // is returned as default GUI font for compatibility
612 int verMaj;
613 ff_family = FF_SWISS;
614 if(wxGetOsVersion(&verMaj) == wxWINDOWS_NT && verMaj >= 5)
615 facename = _T("MS Shell Dlg 2");
616 else
617 facename = _T("MS Shell Dlg");
618 }
619 }
620
621 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
622
623 if ( !wxStrlen(lf.lfFaceName) )
624 {
625 SetFaceName(facename);
626 }
627 }
628
629 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
630 {
631 wxNativeEncodingInfo info;
632 if ( !wxGetNativeFontEncoding(encoding, &info) )
633 {
634 #if wxUSE_FONTMAP
635 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
636 {
637 if ( !info.facename.empty() )
638 {
639 // if we have this encoding only in some particular facename, use
640 // the facename - it is better to show the correct characters in a
641 // wrong facename than unreadable text in a correct one
642 SetFaceName(info.facename);
643 }
644 }
645 else
646 #endif // wxUSE_FONTMAP
647 {
648 // unsupported encoding, replace with the default
649 info.charset = DEFAULT_CHARSET;
650 }
651 }
652
653 lf.lfCharSet = (BYTE)info.charset;
654 }
655
656 bool wxNativeFontInfo::FromString(const wxString& s)
657 {
658 long l;
659
660 wxStringTokenizer tokenizer(s, _T(";"));
661
662 // first the version
663 wxString token = tokenizer.GetNextToken();
664 if ( token != _T('0') )
665 return false;
666
667 token = tokenizer.GetNextToken();
668 if ( !token.ToLong(&l) )
669 return false;
670 lf.lfHeight = l;
671
672 token = tokenizer.GetNextToken();
673 if ( !token.ToLong(&l) )
674 return false;
675 lf.lfWidth = l;
676
677 token = tokenizer.GetNextToken();
678 if ( !token.ToLong(&l) )
679 return false;
680 lf.lfEscapement = l;
681
682 token = tokenizer.GetNextToken();
683 if ( !token.ToLong(&l) )
684 return false;
685 lf.lfOrientation = l;
686
687 token = tokenizer.GetNextToken();
688 if ( !token.ToLong(&l) )
689 return false;
690 lf.lfWeight = l;
691
692 token = tokenizer.GetNextToken();
693 if ( !token.ToLong(&l) )
694 return false;
695 lf.lfItalic = (BYTE)l;
696
697 token = tokenizer.GetNextToken();
698 if ( !token.ToLong(&l) )
699 return false;
700 lf.lfUnderline = (BYTE)l;
701
702 token = tokenizer.GetNextToken();
703 if ( !token.ToLong(&l) )
704 return false;
705 lf.lfStrikeOut = (BYTE)l;
706
707 token = tokenizer.GetNextToken();
708 if ( !token.ToLong(&l) )
709 return false;
710 lf.lfCharSet = (BYTE)l;
711
712 token = tokenizer.GetNextToken();
713 if ( !token.ToLong(&l) )
714 return false;
715 lf.lfOutPrecision = (BYTE)l;
716
717 token = tokenizer.GetNextToken();
718 if ( !token.ToLong(&l) )
719 return false;
720 lf.lfClipPrecision = (BYTE)l;
721
722 token = tokenizer.GetNextToken();
723 if ( !token.ToLong(&l) )
724 return false;
725 lf.lfQuality = (BYTE)l;
726
727 token = tokenizer.GetNextToken();
728 if ( !token.ToLong(&l) )
729 return false;
730 lf.lfPitchAndFamily = (BYTE)l;
731
732 token = tokenizer.GetNextToken();
733 if(!token)
734 return false;
735 wxStrcpy(lf.lfFaceName, token.c_str());
736
737 return true;
738 }
739
740 wxString wxNativeFontInfo::ToString() const
741 {
742 wxString s;
743
744 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
745 0, // version, in case we want to change the format later
746 lf.lfHeight,
747 lf.lfWidth,
748 lf.lfEscapement,
749 lf.lfOrientation,
750 lf.lfWeight,
751 lf.lfItalic,
752 lf.lfUnderline,
753 lf.lfStrikeOut,
754 lf.lfCharSet,
755 lf.lfOutPrecision,
756 lf.lfClipPrecision,
757 lf.lfQuality,
758 lf.lfPitchAndFamily,
759 lf.lfFaceName);
760
761 return s;
762 }
763
764 // ----------------------------------------------------------------------------
765 // wxFont
766 // ----------------------------------------------------------------------------
767
768 void wxFont::Init()
769 {
770 }
771
772 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
773 {
774 UnRef();
775
776 m_refData = new wxFontRefData(info, hFont);
777
778 RealizeResource();
779
780 return true;
781 }
782
783 wxFont::wxFont(const wxString& fontdesc)
784 {
785 wxNativeFontInfo info;
786 if ( info.FromString(fontdesc) )
787 (void)Create(info);
788 }
789
790 /* Constructor for a font. Note that the real construction is done
791 * in wxDC::SetFont, when information is available about scaling etc.
792 */
793 bool wxFont::DoCreate(int pointSize,
794 const wxSize& pixelSize,
795 bool sizeUsingPixels,
796 int family,
797 int style,
798 int weight,
799 bool underlined,
800 const wxString& faceName,
801 wxFontEncoding encoding)
802 {
803 UnRef();
804
805 // wxDEFAULT is a valid value for the font size too so we must treat it
806 // specially here (otherwise the size would be 70 == wxDEFAULT value)
807 if ( pointSize == wxDEFAULT )
808 {
809 pointSize = wxNORMAL_FONT->GetPointSize();
810 }
811
812 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
813 family, style, weight,
814 underlined, faceName, encoding);
815
816 RealizeResource();
817
818 return true;
819 }
820
821 wxFont::~wxFont()
822 {
823 }
824
825 // ----------------------------------------------------------------------------
826 // real implementation
827 // ----------------------------------------------------------------------------
828
829 bool wxFont::RealizeResource()
830 {
831 if ( GetResourceHandle() )
832 {
833 // VZ: the old code returned false in this case, but it doesn't seem
834 // to make sense because the font _was_ created
835 return true;
836 }
837
838 return M_FONTDATA->Alloc(this);
839 }
840
841 bool wxFont::FreeResource(bool WXUNUSED(force))
842 {
843 if ( GetResourceHandle() )
844 {
845 M_FONTDATA->Free();
846
847 return true;
848 }
849
850 return false;
851 }
852
853 WXHANDLE wxFont::GetResourceHandle() const
854 {
855 return (WXHANDLE)GetHFONT();
856 }
857
858 WXHFONT wxFont::GetHFONT() const
859 {
860 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
861 }
862
863 bool wxFont::IsFree() const
864 {
865 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
866 }
867
868 void wxFont::Unshare()
869 {
870 // Don't change shared data
871 if ( !m_refData )
872 {
873 m_refData = new wxFontRefData();
874 }
875 else
876 {
877 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
878 UnRef();
879 m_refData = ref;
880 }
881 }
882
883 // ----------------------------------------------------------------------------
884 // change font attribute: we recreate font when doing it
885 // ----------------------------------------------------------------------------
886
887 void wxFont::SetPointSize(int pointSize)
888 {
889 Unshare();
890
891 M_FONTDATA->SetPointSize(pointSize);
892
893 RealizeResource();
894 }
895
896 void wxFont::SetPixelSize(const wxSize& pixelSize)
897 {
898 Unshare();
899
900 M_FONTDATA->SetPixelSize(pixelSize);
901
902 RealizeResource();
903 }
904
905 void wxFont::SetFamily(int family)
906 {
907 Unshare();
908
909 M_FONTDATA->SetFamily(family);
910
911 RealizeResource();
912 }
913
914 void wxFont::SetStyle(int style)
915 {
916 Unshare();
917
918 M_FONTDATA->SetStyle(style);
919
920 RealizeResource();
921 }
922
923 void wxFont::SetWeight(int weight)
924 {
925 Unshare();
926
927 M_FONTDATA->SetWeight(weight);
928
929 RealizeResource();
930 }
931
932 void wxFont::SetFaceName(const wxString& faceName)
933 {
934 Unshare();
935
936 M_FONTDATA->SetFaceName(faceName);
937
938 RealizeResource();
939 }
940
941 void wxFont::SetUnderlined(bool underlined)
942 {
943 Unshare();
944
945 M_FONTDATA->SetUnderlined(underlined);
946
947 RealizeResource();
948 }
949
950 void wxFont::SetEncoding(wxFontEncoding encoding)
951 {
952 Unshare();
953
954 M_FONTDATA->SetEncoding(encoding);
955
956 RealizeResource();
957 }
958
959 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
960 {
961 Unshare();
962
963 FreeResource();
964
965 *M_FONTDATA = wxFontRefData(info);
966
967 RealizeResource();
968 }
969
970 // ----------------------------------------------------------------------------
971 // accessors
972 // ----------------------------------------------------------------------------
973
974 int wxFont::GetPointSize() const
975 {
976 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
977
978 return M_FONTDATA->GetPointSize();
979 }
980
981 wxSize wxFont::GetPixelSize() const
982 {
983 return M_FONTDATA->GetPixelSize();
984 }
985
986 bool wxFont::IsUsingSizeInPixels() const
987 {
988 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
989
990 return M_FONTDATA->IsUsingSizeInPixels();
991 }
992
993 int wxFont::GetFamily() const
994 {
995 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
996
997 return M_FONTDATA->GetFamily();
998 }
999
1000 int wxFont::GetStyle() const
1001 {
1002 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1003
1004 return M_FONTDATA->GetStyle();
1005 }
1006
1007 int wxFont::GetWeight() const
1008 {
1009 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1010
1011 return M_FONTDATA->GetWeight();
1012 }
1013
1014 bool wxFont::GetUnderlined() const
1015 {
1016 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1017
1018 return M_FONTDATA->GetUnderlined();
1019 }
1020
1021 wxString wxFont::GetFaceName() const
1022 {
1023 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1024
1025 return M_FONTDATA->GetFaceName();
1026 }
1027
1028 wxFontEncoding wxFont::GetEncoding() const
1029 {
1030 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1031
1032 return M_FONTDATA->GetEncoding();
1033 }
1034
1035 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1036 {
1037 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1038 : NULL;
1039 }
1040
1041 bool wxFont::IsFixedWidth() const
1042 {
1043 if ( M_FONTDATA->HasNativeFontInfo() )
1044 {
1045 // the two low-order bits specify the pitch of the font, the rest is
1046 // family
1047 BYTE pitch =
1048 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1049
1050 return pitch == FIXED_PITCH;
1051 }
1052
1053 return wxFontBase::IsFixedWidth();
1054 }
1055