]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
add the wxFont(const wxSize& pixelSize, ...) ctor to all ports; add some wxCHECK_MSGs...
[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 wxFontFamily family,
120 wxFontStyle style,
121 wxFontWeight 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 wxFontFamily GetFamily() const
175 {
176 return m_family;
177 }
178
179 wxFontStyle GetStyle() const
180 {
181 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
182 : m_style;
183 }
184
185 wxFontWeight 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 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(wxFontFamily family)
261 {
262 Free();
263
264 m_family = family;
265 }
266
267 void SetStyle(wxFontStyle 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(wxFontWeight 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 wxFontFamily family,
338 wxFontStyle style,
339 wxFontWeight 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 wxFontFamily m_family;
351 wxFontStyle m_style;
352 wxFontWeight 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 wxFontFamily family,
379 wxFontStyle style,
380 wxFontWeight 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 = wxFONTFAMILY_SWISS;
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 // NOTE: although the MSW port allows for negative pixel size heights,
569 // other ports don't and since it's a very useful feature assert
570 // here if we get a negative height:
571 wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
572 "Negative values for the pixel size or zero pixel height are not allowed" );
573
574 lf.lfHeight = pixelSize.GetHeight();
575 lf.lfWidth = pixelSize.GetWidth();
576 }
577
578 void wxNativeFontInfo::SetStyle(wxFontStyle style)
579 {
580 switch ( style )
581 {
582 default:
583 wxFAIL_MSG( _T("unknown font style") );
584 // fall through
585
586 case wxFONTSTYLE_NORMAL:
587 lf.lfItalic = FALSE;
588 break;
589
590 case wxFONTSTYLE_ITALIC:
591 case wxFONTSTYLE_SLANT:
592 lf.lfItalic = TRUE;
593 break;
594 }
595 }
596
597 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
598 {
599 switch ( weight )
600 {
601 default:
602 wxFAIL_MSG( _T("unknown font weight") );
603 // fall through
604
605 case wxFONTWEIGHT_NORMAL:
606 lf.lfWeight = FW_NORMAL;
607 break;
608
609 case wxFONTWEIGHT_LIGHT:
610 lf.lfWeight = FW_LIGHT;
611 break;
612
613 case wxFONTWEIGHT_BOLD:
614 lf.lfWeight = FW_BOLD;
615 break;
616 }
617 }
618
619 void wxNativeFontInfo::SetUnderlined(bool underlined)
620 {
621 lf.lfUnderline = underlined;
622 }
623
624 bool wxNativeFontInfo::SetFaceName(const wxString& facename)
625 {
626 wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
627 return true;
628 }
629
630 void wxNativeFontInfo::SetFamily(wxFontFamily family)
631 {
632 BYTE ff_family;
633 wxArrayString facename;
634
635 // the list of fonts associated with a family was partially
636 // taken from http://www.codestyle.org/css/font-family
637
638 switch ( family )
639 {
640 case wxSCRIPT:
641 ff_family = FF_SCRIPT;
642 facename.Add(_T("Script"));
643 facename.Add(_T("Brush Script MT"));
644 facename.Add(_T("Comic Sans MS"));
645 facename.Add(_T("Lucida Handwriting"));
646 break;
647
648 case wxDECORATIVE:
649 ff_family = FF_DECORATIVE;
650 facename.Add(_T("Old English Text MT"));
651 facename.Add(_T("Comic Sans MS"));
652 facename.Add(_T("Lucida Handwriting"));
653 break;
654
655 case wxROMAN:
656 ff_family = FF_ROMAN;
657 facename.Add(_T("Times New Roman"));
658 facename.Add(_T("Georgia"));
659 facename.Add(_T("Garamond"));
660 facename.Add(_T("Bookman Old Style"));
661 facename.Add(_T("Book Antiqua"));
662 break;
663
664 case wxTELETYPE:
665 case wxMODERN:
666 ff_family = FF_MODERN;
667 facename.Add(_T("Courier New"));
668 facename.Add(_T("Lucida Console"));
669 facename.Add(_T("Andale Mono"));
670 facename.Add(_T("OCR A Extended"));
671 facename.Add(_T("Terminal"));
672 break;
673
674 case wxSWISS:
675 ff_family = FF_SWISS;
676 facename.Add(_T("Arial"));
677 facename.Add(_T("Century Gothic"));
678 facename.Add(_T("Lucida Sans Unicode"));
679 facename.Add(_T("Tahoma"));
680 facename.Add(_T("Trebuchet MS"));
681 facename.Add(_T("Verdana"));
682 break;
683
684 case wxDEFAULT:
685 default:
686 {
687 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
688 // is returned as default GUI font for compatibility
689 int verMaj;
690 ff_family = FF_SWISS;
691 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
692 facename.Add(_T("MS Shell Dlg 2"));
693 else
694 facename.Add(_T("MS Shell Dlg"));
695
696 // Quoting the MSDN:
697 // "MS Shell Dlg is a mapping mechanism that enables
698 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
699 // support locales that have characters that are not contained in code
700 // page 1252. It is not a font but a face name for a nonexistent font."
701 }
702 }
703
704 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
705
706 if ( !wxStrlen(lf.lfFaceName) )
707 {
708 SetFaceName(facename);
709 }
710 }
711
712 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
713 {
714 wxNativeEncodingInfo info;
715 if ( !wxGetNativeFontEncoding(encoding, &info) )
716 {
717 #if wxUSE_FONTMAP
718 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
719 {
720 if ( !info.facename.empty() )
721 {
722 // if we have this encoding only in some particular facename, use
723 // the facename - it is better to show the correct characters in a
724 // wrong facename than unreadable text in a correct one
725 SetFaceName(info.facename);
726 }
727 }
728 else
729 #endif // wxUSE_FONTMAP
730 {
731 // unsupported encoding, replace with the default
732 info.charset = DEFAULT_CHARSET;
733 }
734 }
735
736 lf.lfCharSet = (BYTE)info.charset;
737 }
738
739 bool wxNativeFontInfo::FromString(const wxString& s)
740 {
741 long l;
742
743 wxStringTokenizer tokenizer(s, _T(";"));
744
745 // first the version
746 wxString token = tokenizer.GetNextToken();
747 if ( token != _T('0') )
748 return false;
749
750 token = tokenizer.GetNextToken();
751 if ( !token.ToLong(&l) )
752 return false;
753 lf.lfHeight = l;
754
755 token = tokenizer.GetNextToken();
756 if ( !token.ToLong(&l) )
757 return false;
758 lf.lfWidth = l;
759
760 token = tokenizer.GetNextToken();
761 if ( !token.ToLong(&l) )
762 return false;
763 lf.lfEscapement = l;
764
765 token = tokenizer.GetNextToken();
766 if ( !token.ToLong(&l) )
767 return false;
768 lf.lfOrientation = l;
769
770 token = tokenizer.GetNextToken();
771 if ( !token.ToLong(&l) )
772 return false;
773 lf.lfWeight = l;
774
775 token = tokenizer.GetNextToken();
776 if ( !token.ToLong(&l) )
777 return false;
778 lf.lfItalic = (BYTE)l;
779
780 token = tokenizer.GetNextToken();
781 if ( !token.ToLong(&l) )
782 return false;
783 lf.lfUnderline = (BYTE)l;
784
785 token = tokenizer.GetNextToken();
786 if ( !token.ToLong(&l) )
787 return false;
788 lf.lfStrikeOut = (BYTE)l;
789
790 token = tokenizer.GetNextToken();
791 if ( !token.ToLong(&l) )
792 return false;
793 lf.lfCharSet = (BYTE)l;
794
795 token = tokenizer.GetNextToken();
796 if ( !token.ToLong(&l) )
797 return false;
798 lf.lfOutPrecision = (BYTE)l;
799
800 token = tokenizer.GetNextToken();
801 if ( !token.ToLong(&l) )
802 return false;
803 lf.lfClipPrecision = (BYTE)l;
804
805 token = tokenizer.GetNextToken();
806 if ( !token.ToLong(&l) )
807 return false;
808 lf.lfQuality = (BYTE)l;
809
810 token = tokenizer.GetNextToken();
811 if ( !token.ToLong(&l) )
812 return false;
813 lf.lfPitchAndFamily = (BYTE)l;
814
815 token = tokenizer.GetNextToken();
816 if(!token)
817 return false;
818 wxStrcpy(lf.lfFaceName, token.c_str());
819
820 return true;
821 }
822
823 wxString wxNativeFontInfo::ToString() const
824 {
825 wxString s;
826
827 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
828 0, // version, in case we want to change the format later
829 lf.lfHeight,
830 lf.lfWidth,
831 lf.lfEscapement,
832 lf.lfOrientation,
833 lf.lfWeight,
834 lf.lfItalic,
835 lf.lfUnderline,
836 lf.lfStrikeOut,
837 lf.lfCharSet,
838 lf.lfOutPrecision,
839 lf.lfClipPrecision,
840 lf.lfQuality,
841 lf.lfPitchAndFamily,
842 (const wxChar*)lf.lfFaceName);
843
844 return s;
845 }
846
847 // ----------------------------------------------------------------------------
848 // wxFont
849 // ----------------------------------------------------------------------------
850
851 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
852 {
853 UnRef();
854
855 m_refData = new wxFontRefData(info, hFont);
856
857 return RealizeResource();
858 }
859
860 wxFont::wxFont(const wxString& fontdesc)
861 {
862 wxNativeFontInfo info;
863 if ( info.FromString(fontdesc) )
864 (void)Create(info);
865 }
866
867 bool wxFont::DoCreate(int pointSize,
868 const wxSize& pixelSize,
869 bool sizeUsingPixels,
870 wxFontFamily family,
871 wxFontStyle style,
872 wxFontWeight weight,
873 bool underlined,
874 const wxString& faceName,
875 wxFontEncoding encoding)
876 {
877 UnRef();
878
879 // wxDEFAULT is a valid value for the font size too so we must treat it
880 // specially here (otherwise the size would be 70 == wxDEFAULT value)
881 if ( pointSize == wxDEFAULT )
882 {
883 pointSize = wxNORMAL_FONT->GetPointSize();
884 }
885
886 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
887 family, style, weight,
888 underlined, faceName, encoding);
889
890 return RealizeResource();
891 }
892
893 wxFont::~wxFont()
894 {
895 }
896
897 // ----------------------------------------------------------------------------
898 // real implementation
899 // ----------------------------------------------------------------------------
900
901 wxGDIRefData *wxFont::CreateGDIRefData() const
902 {
903 return new wxFontRefData();
904 }
905
906 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
907 {
908 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
909 }
910
911 bool wxFont::RealizeResource()
912 {
913 // don't do anything if we already have a valid font
914 if ( GetHFONT() )
915 return true;
916
917 return M_FONTDATA->Alloc(this);
918 }
919
920 bool wxFont::FreeResource(bool WXUNUSED(force))
921 {
922 if ( !GetHFONT() )
923 return false;
924
925 M_FONTDATA->Free();
926
927 return true;
928 }
929
930 WXHANDLE wxFont::GetResourceHandle() const
931 {
932 return (WXHANDLE)GetHFONT();
933 }
934
935 WXHFONT wxFont::GetHFONT() const
936 {
937 return M_FONTDATA ? M_FONTDATA->GetHFONT(this) : 0;
938 }
939
940 bool wxFont::IsFree() const
941 {
942 return M_FONTDATA && !M_FONTDATA->HasHFONT();
943 }
944
945 // ----------------------------------------------------------------------------
946 // change font attribute: we recreate font when doing it
947 // ----------------------------------------------------------------------------
948
949 void wxFont::SetPointSize(int pointSize)
950 {
951 AllocExclusive();
952
953 M_FONTDATA->Free();
954 M_FONTDATA->SetPointSize(pointSize);
955 }
956
957 void wxFont::SetPixelSize(const wxSize& pixelSize)
958 {
959 AllocExclusive();
960
961 M_FONTDATA->SetPixelSize(pixelSize);
962 }
963
964 void wxFont::SetFamily(wxFontFamily family)
965 {
966 AllocExclusive();
967
968 M_FONTDATA->SetFamily(family);
969 }
970
971 void wxFont::SetStyle(wxFontStyle style)
972 {
973 AllocExclusive();
974
975 M_FONTDATA->SetStyle(style);
976 }
977
978 void wxFont::SetWeight(wxFontWeight weight)
979 {
980 AllocExclusive();
981
982 M_FONTDATA->SetWeight(weight);
983 }
984
985 bool wxFont::SetFaceName(const wxString& faceName)
986 {
987 AllocExclusive();
988
989 if ( !M_FONTDATA->SetFaceName(faceName) )
990 return false;
991
992 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
993 // to retrieve a LOGFONT and then compare lf.lfFaceName
994 // with given facename is not reliable at all:
995 // Windows copies the facename given to ::CreateFontIndirect()
996 // without any validity check.
997 // Thus we use wxFontBase::SetFaceName to check if facename
998 // is valid...
999 return wxFontBase::SetFaceName(faceName);
1000 }
1001
1002 void wxFont::SetUnderlined(bool underlined)
1003 {
1004 AllocExclusive();
1005
1006 M_FONTDATA->SetUnderlined(underlined);
1007 }
1008
1009 void wxFont::SetEncoding(wxFontEncoding encoding)
1010 {
1011 AllocExclusive();
1012
1013 M_FONTDATA->SetEncoding(encoding);
1014 }
1015
1016 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
1017 {
1018 AllocExclusive();
1019
1020 M_FONTDATA->SetNativeFontInfo(info);
1021 }
1022
1023 // ----------------------------------------------------------------------------
1024 // accessors
1025 // ----------------------------------------------------------------------------
1026
1027 int wxFont::GetPointSize() const
1028 {
1029 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1030
1031 return M_FONTDATA->GetPointSize();
1032 }
1033
1034 wxSize wxFont::GetPixelSize() const
1035 {
1036 wxCHECK_MSG( Ok(), wxDefaultSize, wxT("invalid font") );
1037
1038 return M_FONTDATA->GetPixelSize();
1039 }
1040
1041 bool wxFont::IsUsingSizeInPixels() const
1042 {
1043 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1044
1045 return M_FONTDATA->IsUsingSizeInPixels();
1046 }
1047
1048 wxFontFamily wxFont::GetFamily() const
1049 {
1050 wxCHECK_MSG( Ok(), wxFONTFAMILY_MAX, wxT("invalid font") );
1051
1052 return M_FONTDATA->GetFamily();
1053 }
1054
1055 wxFontStyle wxFont::GetStyle() const
1056 {
1057 wxCHECK_MSG( Ok(), wxFONTSTYLE_MAX, wxT("invalid font") );
1058
1059 return M_FONTDATA->GetStyle();
1060 }
1061
1062 wxFontWeight wxFont::GetWeight() const
1063 {
1064 wxCHECK_MSG( Ok(), wxFONTWEIGHT_MAX, wxT("invalid font") );
1065
1066 return M_FONTDATA->GetWeight();
1067 }
1068
1069 bool wxFont::GetUnderlined() const
1070 {
1071 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1072
1073 return M_FONTDATA->GetUnderlined();
1074 }
1075
1076 wxString wxFont::GetFaceName() const
1077 {
1078 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1079
1080 return M_FONTDATA->GetFaceName();
1081 }
1082
1083 wxFontEncoding wxFont::GetEncoding() const
1084 {
1085 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1086
1087 return M_FONTDATA->GetEncoding();
1088 }
1089
1090 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1091 {
1092 return Ok() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1093 : NULL;
1094 }
1095
1096 wxString wxFont::GetNativeFontInfoDesc() const
1097 {
1098 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1099
1100 // be sure we have an HFONT associated...
1101 wxConstCast(this, wxFont)->RealizeResource();
1102 return wxFontBase::GetNativeFontInfoDesc();
1103 }
1104
1105 wxString wxFont::GetNativeFontInfoUserDesc() const
1106 {
1107 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1108
1109 // be sure we have an HFONT associated...
1110 wxConstCast(this, wxFont)->RealizeResource();
1111 return wxFontBase::GetNativeFontInfoUserDesc();
1112 }
1113
1114 bool wxFont::IsFixedWidth() const
1115 {
1116 if ( M_FONTDATA->HasNativeFontInfo() )
1117 {
1118 // the two low-order bits specify the pitch of the font, the rest is
1119 // family
1120 BYTE pitch =
1121 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1122
1123 return pitch == FIXED_PITCH;
1124 }
1125
1126 return wxFontBase::IsFixedWidth();
1127 }