]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
Refactor wxRendererXP button drawing methods.
[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(";"), wxTOKEN_RET_EMPTY_ALL);
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 if ( !tokenizer.HasMoreTokens() )
753 return false;
754
755 // the face name may be empty
756 wxStrcpy(lf.lfFaceName, tokenizer.GetNextToken());
757
758 return true;
759 }
760
761 wxString wxNativeFontInfo::ToString() const
762 {
763 wxString s;
764
765 s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
766 0, // version, in case we want to change the format later
767 lf.lfHeight,
768 lf.lfWidth,
769 lf.lfEscapement,
770 lf.lfOrientation,
771 lf.lfWeight,
772 lf.lfItalic,
773 lf.lfUnderline,
774 lf.lfStrikeOut,
775 lf.lfCharSet,
776 lf.lfOutPrecision,
777 lf.lfClipPrecision,
778 lf.lfQuality,
779 lf.lfPitchAndFamily,
780 lf.lfFaceName);
781
782 return s;
783 }
784
785 // ----------------------------------------------------------------------------
786 // wxFont
787 // ----------------------------------------------------------------------------
788
789 wxFont::wxFont(const wxString& fontdesc)
790 {
791 wxNativeFontInfo info;
792 if ( info.FromString(fontdesc) )
793 (void)Create(info);
794 }
795
796 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
797 {
798 UnRef();
799
800 m_refData = new wxFontRefData(info, hFont);
801
802 return RealizeResource();
803 }
804
805 bool wxFont::DoCreate(int pointSize,
806 const wxSize& pixelSize,
807 bool sizeUsingPixels,
808 wxFontFamily family,
809 wxFontStyle style,
810 wxFontWeight weight,
811 bool underlined,
812 const wxString& faceName,
813 wxFontEncoding encoding)
814 {
815 UnRef();
816
817 // wxDEFAULT is a valid value for the font size too so we must treat it
818 // specially here (otherwise the size would be 70 == wxDEFAULT value)
819 if ( pointSize == wxDEFAULT )
820 {
821 pointSize = wxNORMAL_FONT->GetPointSize();
822 }
823
824 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
825 family, style, weight,
826 underlined, faceName, encoding);
827
828 return RealizeResource();
829 }
830
831 wxFont::~wxFont()
832 {
833 }
834
835 // ----------------------------------------------------------------------------
836 // real implementation
837 // ----------------------------------------------------------------------------
838
839 wxGDIRefData *wxFont::CreateGDIRefData() const
840 {
841 return new wxFontRefData();
842 }
843
844 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
845 {
846 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
847 }
848
849 bool wxFont::RealizeResource()
850 {
851 // NOTE: the GetHFONT() call automatically triggers a reallocation of
852 // the HFONT if necessary (will do nothing if we already have the resource);
853 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
854 return GetHFONT() != NULL;
855 }
856
857 bool wxFont::FreeResource(bool WXUNUSED(force))
858 {
859 if ( !M_FONTDATA )
860 return false;
861
862 M_FONTDATA->Free();
863
864 return true;
865 }
866
867 WXHANDLE wxFont::GetResourceHandle() const
868 {
869 return (WXHANDLE)GetHFONT();
870 }
871
872 WXHFONT wxFont::GetHFONT() const
873 {
874 // NOTE: wxFontRefData::GetHFONT() will automatically call
875 // wxFontRefData::Alloc() if necessary
876 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
877 }
878
879 bool wxFont::IsFree() const
880 {
881 return M_FONTDATA && !M_FONTDATA->HasHFONT();
882 }
883
884 // ----------------------------------------------------------------------------
885 // change font attribute: we recreate font when doing it
886 // ----------------------------------------------------------------------------
887
888 void wxFont::SetPointSize(int pointSize)
889 {
890 AllocExclusive();
891
892 M_FONTDATA->Free();
893 M_FONTDATA->SetPointSize(pointSize);
894 }
895
896 void wxFont::SetPixelSize(const wxSize& pixelSize)
897 {
898 AllocExclusive();
899
900 M_FONTDATA->SetPixelSize(pixelSize);
901 }
902
903 void wxFont::SetFamily(wxFontFamily family)
904 {
905 AllocExclusive();
906
907 M_FONTDATA->SetFamily(family);
908 }
909
910 void wxFont::SetStyle(wxFontStyle style)
911 {
912 AllocExclusive();
913
914 M_FONTDATA->SetStyle(style);
915 }
916
917 void wxFont::SetWeight(wxFontWeight weight)
918 {
919 AllocExclusive();
920
921 M_FONTDATA->SetWeight(weight);
922 }
923
924 bool wxFont::SetFaceName(const wxString& faceName)
925 {
926 AllocExclusive();
927
928 if ( !M_FONTDATA->SetFaceName(faceName) )
929 return false;
930
931 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
932 // to retrieve a LOGFONT and then compare lf.lfFaceName
933 // with given facename is not reliable at all:
934 // Windows copies the facename given to ::CreateFontIndirect()
935 // without any validity check.
936 // Thus we use wxFontBase::SetFaceName to check if facename
937 // is valid...
938 return wxFontBase::SetFaceName(faceName);
939 }
940
941 void wxFont::SetUnderlined(bool underlined)
942 {
943 AllocExclusive();
944
945 M_FONTDATA->SetUnderlined(underlined);
946 }
947
948 void wxFont::SetEncoding(wxFontEncoding encoding)
949 {
950 AllocExclusive();
951
952 M_FONTDATA->SetEncoding(encoding);
953 }
954
955 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
956 {
957 AllocExclusive();
958
959 M_FONTDATA->SetNativeFontInfo(info);
960 }
961
962 // ----------------------------------------------------------------------------
963 // accessors
964 // ----------------------------------------------------------------------------
965
966 int wxFont::GetPointSize() const
967 {
968 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
969
970 return M_FONTDATA->GetPointSize();
971 }
972
973 wxSize wxFont::GetPixelSize() const
974 {
975 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
976
977 return M_FONTDATA->GetPixelSize();
978 }
979
980 bool wxFont::IsUsingSizeInPixels() const
981 {
982 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
983
984 return M_FONTDATA->IsUsingSizeInPixels();
985 }
986
987 wxFontFamily wxFont::GetFamily() const
988 {
989 wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
990
991 return M_FONTDATA->GetFamily();
992 }
993
994 wxFontStyle wxFont::GetStyle() const
995 {
996 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
997
998 return M_FONTDATA->GetStyle();
999 }
1000
1001 wxFontWeight wxFont::GetWeight() const
1002 {
1003 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
1004
1005 return M_FONTDATA->GetWeight();
1006 }
1007
1008 bool wxFont::GetUnderlined() const
1009 {
1010 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1011
1012 return M_FONTDATA->GetUnderlined();
1013 }
1014
1015 wxString wxFont::GetFaceName() const
1016 {
1017 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1018
1019 return M_FONTDATA->GetFaceName();
1020 }
1021
1022 wxFontEncoding wxFont::GetEncoding() const
1023 {
1024 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1025
1026 return M_FONTDATA->GetEncoding();
1027 }
1028
1029 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1030 {
1031 return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL;
1032 }
1033
1034 wxString wxFont::GetNativeFontInfoDesc() const
1035 {
1036 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1037
1038 // be sure we have an HFONT associated...
1039 const_cast<wxFont*>(this)->RealizeResource();
1040 return wxFontBase::GetNativeFontInfoDesc();
1041 }
1042
1043 wxString wxFont::GetNativeFontInfoUserDesc() const
1044 {
1045 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1046
1047 // be sure we have an HFONT associated...
1048 const_cast<wxFont*>(this)->RealizeResource();
1049 return wxFontBase::GetNativeFontInfoUserDesc();
1050 }
1051
1052 bool wxFont::IsFixedWidth() const
1053 {
1054 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1055
1056 // the two low-order bits specify the pitch of the font, the rest is
1057 // family
1058 BYTE pitch =
1059 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1060
1061 return pitch == FIXED_PITCH;
1062 }