]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
fix GetTLWParentIfNotBeingDeleted() to work correctly even if an intermediate non...
[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 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #include "wx/font.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/list.h"
31 #include "wx/utils.h"
32 #include "wx/app.h"
33 #include "wx/log.h"
34 #include "wx/encinfo.h"
35 #endif // WX_PRECOMP
36
37 #include "wx/msw/private.h"
38
39 #include "wx/fontutil.h"
40 #include "wx/fontmap.h"
41
42 #ifndef __WXWINCE__
43 #include "wx/sysopt.h"
44 #endif
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(const 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 wxFont *font) const
215 {
216 if ( !m_hFont )
217 wx_const_cast(wxFontRefData *, this)->Alloc(font);
218
219 return (WXHFONT)m_hFont;
220 }
221
222 bool HasHFONT() const
223 {
224 return m_hFont != 0;
225 }
226
227 // ... and setters: notice that all of them invalidate the currently
228 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
229 // new one
230 void SetPointSize(int pointSize)
231 {
232 Free();
233
234 if ( m_nativeFontInfoOk )
235 {
236 m_nativeFontInfo.SetPointSize(pointSize);
237 }
238 else
239 {
240 m_pointSize = pointSize;
241 m_sizeUsingPixels = false;
242 }
243 }
244
245 void SetPixelSize(const wxSize& pixelSize)
246 {
247 Free();
248
249 if ( m_nativeFontInfoOk )
250 {
251 m_nativeFontInfo.SetPixelSize(pixelSize);
252 }
253 else
254 {
255 m_pixelSize = pixelSize;
256 m_sizeUsingPixels = true;
257 }
258 }
259
260 void SetFamily(int family)
261 {
262 Free();
263
264 m_family = family;
265 }
266
267 void SetStyle(int style)
268 {
269 Free();
270
271 if ( m_nativeFontInfoOk )
272 m_nativeFontInfo.SetStyle((wxFontStyle)style);
273 else
274 m_style = style;
275 }
276
277 void SetWeight(int weight)
278 {
279 Free();
280
281 if ( m_nativeFontInfoOk )
282 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
283 else
284 m_weight = weight;
285 }
286
287 bool SetFaceName(const wxString& faceName)
288 {
289 Free();
290
291 if ( m_nativeFontInfoOk )
292 return m_nativeFontInfo.SetFaceName(faceName);
293
294 m_faceName = faceName;
295 return true;
296 }
297
298 void SetUnderlined(bool underlined)
299 {
300 Free();
301
302 if ( m_nativeFontInfoOk )
303 m_nativeFontInfo.SetUnderlined(underlined);
304 else
305 m_underlined = underlined;
306 }
307
308 void SetEncoding(wxFontEncoding encoding)
309 {
310 Free();
311
312 if ( m_nativeFontInfoOk )
313 m_nativeFontInfo.SetEncoding(encoding);
314 else
315 m_encoding = encoding;
316 }
317
318 // native font info
319 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
320
321 const wxNativeFontInfo& GetNativeFontInfo() const
322 { return m_nativeFontInfo; }
323
324 void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
325 {
326 Free();
327
328 m_nativeFontInfo = nativeFontInfo;
329 m_nativeFontInfoOk = true;
330 }
331
332 protected:
333 // common part of all ctors
334 void Init(int size,
335 const wxSize& pixelSize,
336 bool sizeUsingPixels,
337 int family,
338 int style,
339 int weight,
340 bool underlined,
341 const wxString& faceName,
342 wxFontEncoding encoding);
343
344 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
345
346 // font characteristics
347 int m_pointSize;
348 wxSize m_pixelSize;
349 bool m_sizeUsingPixels;
350 int m_family;
351 int m_style;
352 int m_weight;
353 bool m_underlined;
354 wxString m_faceName;
355 wxFontEncoding m_encoding;
356
357 // Windows font handle, created on demand in GetHFONT()
358 HFONT m_hFont;
359
360 // Native font info
361 wxNativeFontInfo m_nativeFontInfo;
362 bool m_nativeFontInfoOk;
363 };
364
365 #define M_FONTDATA ((wxFontRefData*)m_refData)
366
367 // ============================================================================
368 // implementation
369 // ============================================================================
370
371 // ----------------------------------------------------------------------------
372 // wxFontRefData
373 // ----------------------------------------------------------------------------
374
375 void wxFontRefData::Init(int pointSize,
376 const wxSize& pixelSize,
377 bool sizeUsingPixels,
378 int family,
379 int style,
380 int weight,
381 bool underlined,
382 const wxString& faceName,
383 wxFontEncoding encoding)
384 {
385 m_style = style;
386 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
387 m_pixelSize = pixelSize;
388 m_sizeUsingPixels = sizeUsingPixels;
389 m_family = family;
390 m_style = style;
391 m_weight = weight;
392 m_underlined = underlined;
393 m_faceName = faceName;
394 m_encoding = encoding;
395
396 m_hFont = 0;
397
398 m_nativeFontInfoOk = false;
399 }
400
401 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
402 {
403 // hFont may be zero, or it be passed in case we really want to
404 // use the exact font created in the underlying system
405 // (for example where we can't guarantee conversion from HFONT
406 // to LOGFONT back to HFONT)
407 m_hFont = (HFONT)hFont;
408
409 m_nativeFontInfoOk = true;
410 m_nativeFontInfo = info;
411 // This is the best we can do since we don't have the
412 // correct information at this point.
413 m_family = wxSWISS;
414 }
415
416 wxFontRefData::~wxFontRefData()
417 {
418 Free();
419 }
420
421 bool wxFontRefData::Alloc(const wxFont *font)
422 {
423 if ( !m_nativeFontInfoOk )
424 {
425 wxFillLogFont(&m_nativeFontInfo.lf, font);
426 m_nativeFontInfoOk = true;
427 }
428
429 m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
430 if ( !m_hFont )
431 {
432 wxLogLastError(wxT("CreateFont"));
433 return false;
434 }
435
436 return true;
437 }
438
439 void wxFontRefData::Free()
440 {
441 if ( m_hFont )
442 {
443 if ( !::DeleteObject(m_hFont) )
444 {
445 wxLogLastError(wxT("DeleteObject(font)"));
446 }
447
448 m_hFont = 0;
449 }
450 }
451
452 // ----------------------------------------------------------------------------
453 // wxNativeFontInfo
454 // ----------------------------------------------------------------------------
455
456 void wxNativeFontInfo::Init()
457 {
458 wxZeroMemory(lf);
459
460 // we get better font quality if we use PROOF_QUALITY instead of
461 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
462 // then so we allow to set a global option to choose between quality and
463 // wider font selection
464 #ifdef __WXWINCE__
465 lf.lfQuality = CLEARTYPE_QUALITY;
466 #else
467 lf.lfQuality = wxSystemOptions::GetOptionInt(_T("msw.font.no-proof-quality"))
468 ? DEFAULT_QUALITY
469 : PROOF_QUALITY;
470 #endif
471 }
472
473 int wxNativeFontInfo::GetPointSize() const
474 {
475 // FIXME: using the screen here results in incorrect font size calculation
476 // for printing!
477 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
478
479 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
480 return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5);
481 }
482
483 wxSize wxNativeFontInfo::GetPixelSize() const
484 {
485 wxSize ret;
486 ret.SetHeight(abs((int)lf.lfHeight));
487 ret.SetWidth(lf.lfWidth);
488 return ret;
489 }
490
491 wxFontStyle wxNativeFontInfo::GetStyle() const
492 {
493 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
494 }
495
496 wxFontWeight wxNativeFontInfo::GetWeight() const
497 {
498 if ( lf.lfWeight <= 300 )
499 return wxFONTWEIGHT_LIGHT;
500
501 if ( lf.lfWeight >= 600 )
502 return wxFONTWEIGHT_BOLD;
503
504 return wxFONTWEIGHT_NORMAL;
505 }
506
507 bool wxNativeFontInfo::GetUnderlined() const
508 {
509 return lf.lfUnderline != 0;
510 }
511
512 wxString wxNativeFontInfo::GetFaceName() const
513 {
514 return lf.lfFaceName;
515 }
516
517 wxFontFamily wxNativeFontInfo::GetFamily() const
518 {
519 wxFontFamily family;
520
521 // extract family from pitch-and-family
522 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
523 {
524 case FF_ROMAN:
525 family = wxFONTFAMILY_ROMAN;
526 break;
527
528 default:
529 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
530 // fall through
531
532 case FF_SWISS:
533 family = wxFONTFAMILY_SWISS;
534 break;
535
536 case FF_SCRIPT:
537 family = wxFONTFAMILY_SCRIPT;
538 break;
539
540 case FF_MODERN:
541 family = wxFONTFAMILY_MODERN;
542 break;
543
544 case FF_DECORATIVE:
545 family = wxFONTFAMILY_DECORATIVE;
546 break;
547 }
548
549 return family;
550 }
551
552 wxFontEncoding wxNativeFontInfo::GetEncoding() const
553 {
554 return wxGetFontEncFromCharSet(lf.lfCharSet);
555 }
556
557 void wxNativeFontInfo::SetPointSize(int pointsize)
558 {
559 // FIXME: using the screen here results in incorrect font size calculation
560 // for printing!
561 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
562
563 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
564 }
565
566 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
567 {
568 lf.lfHeight = pixelSize.GetHeight();
569 lf.lfWidth = pixelSize.GetWidth();
570 }
571
572
573 void wxNativeFontInfo::SetStyle(wxFontStyle style)
574 {
575 switch ( style )
576 {
577 default:
578 wxFAIL_MSG( _T("unknown font style") );
579 // fall through
580
581 case wxFONTSTYLE_NORMAL:
582 lf.lfItalic = FALSE;
583 break;
584
585 case wxFONTSTYLE_ITALIC:
586 case wxFONTSTYLE_SLANT:
587 lf.lfItalic = TRUE;
588 break;
589 }
590 }
591
592 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
593 {
594 switch ( weight )
595 {
596 default:
597 wxFAIL_MSG( _T("unknown font weight") );
598 // fall through
599
600 case wxFONTWEIGHT_NORMAL:
601 lf.lfWeight = FW_NORMAL;
602 break;
603
604 case wxFONTWEIGHT_LIGHT:
605 lf.lfWeight = FW_LIGHT;
606 break;
607
608 case wxFONTWEIGHT_BOLD:
609 lf.lfWeight = FW_BOLD;
610 break;
611 }
612 }
613
614 void wxNativeFontInfo::SetUnderlined(bool underlined)
615 {
616 lf.lfUnderline = underlined;
617 }
618
619 bool wxNativeFontInfo::SetFaceName(const wxString& facename)
620 {
621 size_t len = WXSIZEOF(lf.lfFaceName);
622 wxStrncpy(lf.lfFaceName, facename, len);
623 lf.lfFaceName[len - 1] = '\0'; // truncate the face name
624 return true;
625 }
626
627 void wxNativeFontInfo::SetFamily(wxFontFamily family)
628 {
629 BYTE ff_family;
630 wxArrayString facename;
631
632 // the list of fonts associated with a family was partially
633 // taken from http://www.codestyle.org/css/font-family
634
635 switch ( family )
636 {
637 case wxSCRIPT:
638 ff_family = FF_SCRIPT;
639 facename.Add(_T("Script"));
640 facename.Add(_T("Brush Script MT"));
641 facename.Add(_T("Comic Sans MS"));
642 facename.Add(_T("Lucida Handwriting"));
643 break;
644
645 case wxDECORATIVE:
646 ff_family = FF_DECORATIVE;
647 facename.Add(_T("Old English Text MT"));
648 facename.Add(_T("Comic Sans MS"));
649 facename.Add(_T("Lucida Handwriting"));
650 break;
651
652 case wxROMAN:
653 ff_family = FF_ROMAN;
654 facename.Add(_T("Times New Roman"));
655 facename.Add(_T("Georgia"));
656 facename.Add(_T("Garamond"));
657 facename.Add(_T("Bookman Old Style"));
658 facename.Add(_T("Book Antiqua"));
659 break;
660
661 case wxTELETYPE:
662 case wxMODERN:
663 ff_family = FF_MODERN;
664 facename.Add(_T("Courier New"));
665 facename.Add(_T("Lucida Console"));
666 facename.Add(_T("Andale Mono"));
667 facename.Add(_T("OCR A Extended"));
668 facename.Add(_T("Terminal"));
669 break;
670
671 case wxSWISS:
672 ff_family = FF_SWISS;
673 facename.Add(_T("Arial"));
674 facename.Add(_T("Century Gothic"));
675 facename.Add(_T("Lucida Sans Unicode"));
676 facename.Add(_T("Tahoma"));
677 facename.Add(_T("Trebuchet MS"));
678 facename.Add(_T("Verdana"));
679 break;
680
681 case wxDEFAULT:
682 default:
683 {
684 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
685 // is returned as default GUI font for compatibility
686 int verMaj;
687 ff_family = FF_SWISS;
688 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
689 facename.Add(_T("MS Shell Dlg 2"));
690 else
691 facename.Add(_T("MS Shell Dlg"));
692
693 // Quoting the MSDN:
694 // "MS Shell Dlg is a mapping mechanism that enables
695 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
696 // support locales that have characters that are not contained in code
697 // page 1252. It is not a font but a face name for a nonexistent font."
698 }
699 }
700
701 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
702
703 if ( !wxStrlen(lf.lfFaceName) )
704 {
705 SetFaceName(facename);
706 }
707 }
708
709 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
710 {
711 wxNativeEncodingInfo info;
712 if ( !wxGetNativeFontEncoding(encoding, &info) )
713 {
714 #if wxUSE_FONTMAP
715 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
716 {
717 if ( !info.facename.empty() )
718 {
719 // if we have this encoding only in some particular facename, use
720 // the facename - it is better to show the correct characters in a
721 // wrong facename than unreadable text in a correct one
722 SetFaceName(info.facename);
723 }
724 }
725 else
726 #endif // wxUSE_FONTMAP
727 {
728 // unsupported encoding, replace with the default
729 info.charset = DEFAULT_CHARSET;
730 }
731 }
732
733 lf.lfCharSet = (BYTE)info.charset;
734 }
735
736 bool wxNativeFontInfo::FromString(const wxString& s)
737 {
738 long l;
739
740 wxStringTokenizer tokenizer(s, _T(";"));
741
742 // first the version
743 wxString token = tokenizer.GetNextToken();
744 if ( token != _T('0') )
745 return false;
746
747 token = tokenizer.GetNextToken();
748 if ( !token.ToLong(&l) )
749 return false;
750 lf.lfHeight = l;
751
752 token = tokenizer.GetNextToken();
753 if ( !token.ToLong(&l) )
754 return false;
755 lf.lfWidth = l;
756
757 token = tokenizer.GetNextToken();
758 if ( !token.ToLong(&l) )
759 return false;
760 lf.lfEscapement = l;
761
762 token = tokenizer.GetNextToken();
763 if ( !token.ToLong(&l) )
764 return false;
765 lf.lfOrientation = l;
766
767 token = tokenizer.GetNextToken();
768 if ( !token.ToLong(&l) )
769 return false;
770 lf.lfWeight = l;
771
772 token = tokenizer.GetNextToken();
773 if ( !token.ToLong(&l) )
774 return false;
775 lf.lfItalic = (BYTE)l;
776
777 token = tokenizer.GetNextToken();
778 if ( !token.ToLong(&l) )
779 return false;
780 lf.lfUnderline = (BYTE)l;
781
782 token = tokenizer.GetNextToken();
783 if ( !token.ToLong(&l) )
784 return false;
785 lf.lfStrikeOut = (BYTE)l;
786
787 token = tokenizer.GetNextToken();
788 if ( !token.ToLong(&l) )
789 return false;
790 lf.lfCharSet = (BYTE)l;
791
792 token = tokenizer.GetNextToken();
793 if ( !token.ToLong(&l) )
794 return false;
795 lf.lfOutPrecision = (BYTE)l;
796
797 token = tokenizer.GetNextToken();
798 if ( !token.ToLong(&l) )
799 return false;
800 lf.lfClipPrecision = (BYTE)l;
801
802 token = tokenizer.GetNextToken();
803 if ( !token.ToLong(&l) )
804 return false;
805 lf.lfQuality = (BYTE)l;
806
807 token = tokenizer.GetNextToken();
808 if ( !token.ToLong(&l) )
809 return false;
810 lf.lfPitchAndFamily = (BYTE)l;
811
812 token = tokenizer.GetNextToken();
813 if(!token)
814 return false;
815 wxStrcpy(lf.lfFaceName, token.c_str());
816
817 return true;
818 }
819
820 wxString wxNativeFontInfo::ToString() const
821 {
822 wxString s;
823
824 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
825 0, // version, in case we want to change the format later
826 lf.lfHeight,
827 lf.lfWidth,
828 lf.lfEscapement,
829 lf.lfOrientation,
830 lf.lfWeight,
831 lf.lfItalic,
832 lf.lfUnderline,
833 lf.lfStrikeOut,
834 lf.lfCharSet,
835 lf.lfOutPrecision,
836 lf.lfClipPrecision,
837 lf.lfQuality,
838 lf.lfPitchAndFamily,
839 (const wxChar*)lf.lfFaceName);
840
841 return s;
842 }
843
844 // ----------------------------------------------------------------------------
845 // wxFont
846 // ----------------------------------------------------------------------------
847
848 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
849 {
850 UnRef();
851
852 m_refData = new wxFontRefData(info, hFont);
853
854 return RealizeResource();
855 }
856
857 wxFont::wxFont(const wxString& fontdesc)
858 {
859 wxNativeFontInfo info;
860 if ( info.FromString(fontdesc) )
861 (void)Create(info);
862 }
863
864 bool wxFont::DoCreate(int pointSize,
865 const wxSize& pixelSize,
866 bool sizeUsingPixels,
867 int family,
868 int style,
869 int weight,
870 bool underlined,
871 const wxString& faceName,
872 wxFontEncoding encoding)
873 {
874 UnRef();
875
876 // wxDEFAULT is a valid value for the font size too so we must treat it
877 // specially here (otherwise the size would be 70 == wxDEFAULT value)
878 if ( pointSize == wxDEFAULT )
879 {
880 pointSize = wxNORMAL_FONT->GetPointSize();
881 }
882
883 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
884 family, style, weight,
885 underlined, faceName, encoding);
886
887 return RealizeResource();
888 }
889
890 wxFont::~wxFont()
891 {
892 }
893
894 // ----------------------------------------------------------------------------
895 // real implementation
896 // ----------------------------------------------------------------------------
897
898 wxGDIRefData *wxFont::CreateGDIRefData() const
899 {
900 return new wxFontRefData();
901 }
902
903 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
904 {
905 return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data));
906 }
907
908 bool wxFont::RealizeResource()
909 {
910 // don't do anything if we already have a valid font
911 if ( GetHFONT() )
912 return true;
913
914 return M_FONTDATA->Alloc(this);
915 }
916
917 bool wxFont::FreeResource(bool WXUNUSED(force))
918 {
919 if ( !GetHFONT() )
920 return false;
921
922 M_FONTDATA->Free();
923
924 return true;
925 }
926
927 WXHANDLE wxFont::GetResourceHandle() const
928 {
929 return (WXHANDLE)GetHFONT();
930 }
931
932 WXHFONT wxFont::GetHFONT() const
933 {
934 return M_FONTDATA ? M_FONTDATA->GetHFONT(this) : 0;
935 }
936
937 bool wxFont::IsFree() const
938 {
939 return M_FONTDATA && !M_FONTDATA->HasHFONT();
940 }
941
942 // ----------------------------------------------------------------------------
943 // change font attribute: we recreate font when doing it
944 // ----------------------------------------------------------------------------
945
946 void wxFont::SetPointSize(int pointSize)
947 {
948 AllocExclusive();
949
950 M_FONTDATA->Free();
951 M_FONTDATA->SetPointSize(pointSize);
952 }
953
954 void wxFont::SetPixelSize(const wxSize& pixelSize)
955 {
956 AllocExclusive();
957
958 M_FONTDATA->SetPixelSize(pixelSize);
959 }
960
961 void wxFont::SetFamily(int family)
962 {
963 AllocExclusive();
964
965 M_FONTDATA->SetFamily(family);
966 }
967
968 void wxFont::SetStyle(int style)
969 {
970 AllocExclusive();
971
972 M_FONTDATA->SetStyle(style);
973 }
974
975 void wxFont::SetWeight(int weight)
976 {
977 AllocExclusive();
978
979 M_FONTDATA->SetWeight(weight);
980 }
981
982 bool wxFont::SetFaceName(const wxString& faceName)
983 {
984 AllocExclusive();
985
986 if ( !M_FONTDATA->SetFaceName(faceName) )
987 return false;
988
989 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
990 // to retrieve a LOGFONT and then compare lf.lfFaceName
991 // with given facename is not reliable at all:
992 // Windows copies the facename given to ::CreateFontIndirect()
993 // without any validity check.
994 // Thus we use wxFontBase::SetFaceName to check if facename
995 // is valid...
996 return wxFontBase::SetFaceName(faceName);
997 }
998
999 void wxFont::SetUnderlined(bool underlined)
1000 {
1001 AllocExclusive();
1002
1003 M_FONTDATA->SetUnderlined(underlined);
1004 }
1005
1006 void wxFont::SetEncoding(wxFontEncoding encoding)
1007 {
1008 AllocExclusive();
1009
1010 M_FONTDATA->SetEncoding(encoding);
1011 }
1012
1013 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
1014 {
1015 AllocExclusive();
1016
1017 M_FONTDATA->SetNativeFontInfo(info);
1018 }
1019
1020 // ----------------------------------------------------------------------------
1021 // accessors
1022 // ----------------------------------------------------------------------------
1023
1024 int wxFont::GetPointSize() const
1025 {
1026 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1027
1028 return M_FONTDATA->GetPointSize();
1029 }
1030
1031 wxSize wxFont::GetPixelSize() const
1032 {
1033 wxCHECK_MSG( Ok(), wxDefaultSize, wxT("invalid font") );
1034
1035 return M_FONTDATA->GetPixelSize();
1036 }
1037
1038 bool wxFont::IsUsingSizeInPixels() const
1039 {
1040 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1041
1042 return M_FONTDATA->IsUsingSizeInPixels();
1043 }
1044
1045 int wxFont::GetFamily() const
1046 {
1047 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1048
1049 return M_FONTDATA->GetFamily();
1050 }
1051
1052 int wxFont::GetStyle() const
1053 {
1054 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1055
1056 return M_FONTDATA->GetStyle();
1057 }
1058
1059 int wxFont::GetWeight() const
1060 {
1061 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1062
1063 return M_FONTDATA->GetWeight();
1064 }
1065
1066 bool wxFont::GetUnderlined() const
1067 {
1068 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1069
1070 return M_FONTDATA->GetUnderlined();
1071 }
1072
1073 wxString wxFont::GetFaceName() const
1074 {
1075 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1076
1077 return M_FONTDATA->GetFaceName();
1078 }
1079
1080 wxFontEncoding wxFont::GetEncoding() const
1081 {
1082 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1083
1084 return M_FONTDATA->GetEncoding();
1085 }
1086
1087 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1088 {
1089 return Ok() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1090 : NULL;
1091 }
1092
1093 wxString wxFont::GetNativeFontInfoDesc() const
1094 {
1095 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1096
1097 // be sure we have an HFONT associated...
1098 wxConstCast(this, wxFont)->RealizeResource();
1099 return wxFontBase::GetNativeFontInfoDesc();
1100 }
1101
1102 wxString wxFont::GetNativeFontInfoUserDesc() const
1103 {
1104 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1105
1106 // be sure we have an HFONT associated...
1107 wxConstCast(this, wxFont)->RealizeResource();
1108 return wxFontBase::GetNativeFontInfoUserDesc();
1109 }
1110
1111 bool wxFont::IsFixedWidth() const
1112 {
1113 if ( M_FONTDATA->HasNativeFontInfo() )
1114 {
1115 // the two low-order bits specify the pitch of the font, the rest is
1116 // family
1117 BYTE pitch =
1118 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1119
1120 return pitch == FIXED_PITCH;
1121 }
1122
1123 return wxFontBase::IsFixedWidth();
1124 }