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