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