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