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