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