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