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