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