]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
miscellaneous wxFont enhancements (patch 1496606):
[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 #ifndef WX_PRECOMP
28 #include "wx/list.h"
29 #include "wx/utils.h"
30 #include "wx/app.h"
31 #include "wx/font.h"
32 #include "wx/log.h"
33 #include "wx/encinfo.h"
34 #endif // WX_PRECOMP
35
36 #include "wx/msw/private.h"
37
38 #include "wx/fontutil.h"
39 #include "wx/fontmap.h"
40
41 #include "wx/tokenzr.h"
42
43 #if wxUSE_EXTENDED_RTTI
44
45 wxBEGIN_ENUM( wxFontFamily )
46 wxENUM_MEMBER( wxDEFAULT )
47 wxENUM_MEMBER( wxDECORATIVE )
48 wxENUM_MEMBER( wxROMAN )
49 wxENUM_MEMBER( wxSCRIPT )
50 wxENUM_MEMBER( wxSWISS )
51 wxENUM_MEMBER( wxMODERN )
52 wxENUM_MEMBER( wxTELETYPE )
53 wxEND_ENUM( wxFontFamily )
54
55 wxBEGIN_ENUM( wxFontStyle )
56 wxENUM_MEMBER( wxNORMAL )
57 wxENUM_MEMBER( wxITALIC )
58 wxENUM_MEMBER( wxSLANT )
59 wxEND_ENUM( wxFontStyle )
60
61 wxBEGIN_ENUM( wxFontWeight )
62 wxENUM_MEMBER( wxNORMAL )
63 wxENUM_MEMBER( wxLIGHT )
64 wxENUM_MEMBER( wxBOLD )
65 wxEND_ENUM( wxFontWeight )
66
67 IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h")
68
69 wxBEGIN_PROPERTIES_TABLE(wxFont)
70 wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
71 wxPROPERTY( Family, int , SetFamily, GetFamily, (int)wxDEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontFamily
72 wxPROPERTY( Style, int , SetStyle, GetStyle, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontStyle
73 wxPROPERTY( Weight, int , SetWeight, GetWeight, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontWeight
74 wxPROPERTY( Underlined, bool , SetUnderlined, GetUnderlined, false , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
75 wxPROPERTY( Face, wxString , SetFaceName, GetFaceName, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
77 wxEND_PROPERTIES_TABLE()
78
79 wxCONSTRUCTOR_6( wxFont , int , Size , int , Family , int , Style , int , Weight , bool , Underlined , wxString , Face )
80
81 wxBEGIN_HANDLERS_TABLE(wxFont)
82 wxEND_HANDLERS_TABLE()
83
84 #else
85 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
86 #endif
87
88
89 // ----------------------------------------------------------------------------
90 // constants
91 // ----------------------------------------------------------------------------
92
93 // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
94 static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
95
96 // ----------------------------------------------------------------------------
97 // wxFontRefData - the internal description of the font
98 // ----------------------------------------------------------------------------
99
100 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
101 {
102 public:
103 // constructors
104 wxFontRefData()
105 {
106 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
107 wxFONTWEIGHT_NORMAL, false, wxEmptyString,
108 wxFONTENCODING_DEFAULT);
109 }
110
111 wxFontRefData(int size,
112 const wxSize& pixelSize,
113 bool sizeUsingPixels,
114 int family,
115 int style,
116 int weight,
117 bool underlined,
118 const wxString& faceName,
119 wxFontEncoding encoding)
120 {
121 Init(size, pixelSize, sizeUsingPixels, family, style, weight,
122 underlined, faceName, encoding);
123 }
124
125 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
126 {
127 Init(info, hFont);
128 }
129
130 wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
131 {
132 if ( data.m_nativeFontInfoOk )
133 {
134 Init(data.m_nativeFontInfo);
135 }
136 else
137 {
138 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels,
139 data.m_family, data.m_style, data.m_weight,
140 data.m_underlined, data.m_faceName, data.m_encoding);
141 }
142 }
143
144 virtual ~wxFontRefData();
145
146 // operations
147 bool Alloc(wxFont *font);
148
149 void Free();
150
151 // all wxFont accessors
152 int GetPointSize() const
153 {
154 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
155 : m_pointSize;
156 }
157
158 wxSize GetPixelSize() const
159 {
160 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize()
161 : m_pixelSize;
162 }
163
164 bool IsUsingSizeInPixels() const
165 {
166 return m_nativeFontInfoOk ? true : m_sizeUsingPixels;
167 }
168
169 int GetFamily() const
170 {
171 return m_family;
172 }
173
174 int GetStyle() const
175 {
176 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
177 : m_style;
178 }
179
180 int GetWeight() const
181 {
182 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
183 : m_weight;
184 }
185
186 bool GetUnderlined() const
187 {
188 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
189 : m_underlined;
190 }
191
192 wxString GetFaceName() const
193 {
194 wxString s;
195 if ( m_nativeFontInfoOk )
196 s = m_nativeFontInfo.GetFaceName();
197 else
198 s = m_faceName;
199
200 return s;
201 }
202
203 wxFontEncoding GetEncoding() const
204 {
205 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
206 : m_encoding;
207 }
208
209 WXHFONT GetHFONT() const { return m_hFont; }
210
211 // ... and setters
212 void SetPointSize(int pointSize)
213 {
214 if ( m_nativeFontInfoOk )
215 {
216 m_nativeFontInfo.SetPointSize(pointSize);
217 }
218 else
219 {
220 m_pointSize = pointSize;
221 m_sizeUsingPixels = false;
222 }
223 }
224
225 void SetPixelSize(const wxSize& pixelSize)
226 {
227 if ( m_nativeFontInfoOk )
228 {
229 m_nativeFontInfo.SetPixelSize(pixelSize);
230 }
231 else
232 {
233 m_pixelSize = pixelSize;
234 m_sizeUsingPixels = true;
235 }
236 }
237
238 void SetFamily(int family)
239 {
240 m_family = family;
241 }
242
243 void SetStyle(int style)
244 {
245 if ( m_nativeFontInfoOk )
246 m_nativeFontInfo.SetStyle((wxFontStyle)style);
247 else
248 m_style = style;
249 }
250
251 void SetWeight(int weight)
252 {
253 if ( m_nativeFontInfoOk )
254 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
255 else
256 m_weight = weight;
257 }
258
259 bool SetFaceName(const wxString& faceName)
260 {
261 if ( m_nativeFontInfoOk )
262 return m_nativeFontInfo.SetFaceName(faceName);
263
264 m_faceName = faceName;
265 return true;
266 }
267
268 void SetUnderlined(bool underlined)
269 {
270 if ( m_nativeFontInfoOk )
271 m_nativeFontInfo.SetUnderlined(underlined);
272 else
273 m_underlined = underlined;
274 }
275
276 void SetEncoding(wxFontEncoding encoding)
277 {
278 if ( m_nativeFontInfoOk )
279 m_nativeFontInfo.SetEncoding(encoding);
280 else
281 m_encoding = encoding;
282 }
283
284 // native font info tests
285 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
286
287 const wxNativeFontInfo& GetNativeFontInfo() const
288 { return m_nativeFontInfo; }
289
290 protected:
291 // common part of all ctors
292 void Init(int size,
293 const wxSize& pixelSize,
294 bool sizeUsingPixels,
295 int family,
296 int style,
297 int weight,
298 bool underlined,
299 const wxString& faceName,
300 wxFontEncoding encoding);
301
302 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
303
304 // font characterstics
305 int m_pointSize;
306 wxSize m_pixelSize;
307 bool m_sizeUsingPixels;
308 int m_family;
309 int m_style;
310 int m_weight;
311 bool m_underlined;
312 wxString m_faceName;
313 wxFontEncoding m_encoding;
314
315 // Windows font handle
316 WXHFONT m_hFont;
317
318 // Native font info
319 wxNativeFontInfo m_nativeFontInfo;
320 bool m_nativeFontInfoOk;
321 };
322
323 // ============================================================================
324 // implementation
325 // ============================================================================
326
327 // ----------------------------------------------------------------------------
328 // wxFontRefData
329 // ----------------------------------------------------------------------------
330
331 void wxFontRefData::Init(int pointSize,
332 const wxSize& pixelSize,
333 bool sizeUsingPixels,
334 int family,
335 int style,
336 int weight,
337 bool underlined,
338 const wxString& faceName,
339 wxFontEncoding encoding)
340 {
341 m_style = style;
342 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
343 m_pixelSize = pixelSize;
344 m_sizeUsingPixels = sizeUsingPixels;
345 m_family = family;
346 m_style = style;
347 m_weight = weight;
348 m_underlined = underlined;
349 m_faceName = faceName;
350 m_encoding = encoding;
351
352 m_hFont = 0;
353
354 m_nativeFontInfoOk = false;
355 }
356
357 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
358 {
359 // hFont may be zero, or it be passed in case we really want to
360 // use the exact font created in the underlying system
361 // (for example where we can't guarantee conversion from HFONT
362 // to LOGFONT back to HFONT)
363 m_hFont = hFont;
364
365 m_nativeFontInfoOk = true;
366 m_nativeFontInfo = info;
367 // This is the best we can do since we don't have the
368 // correct information at this point.
369 m_family = wxSWISS;
370 }
371
372 wxFontRefData::~wxFontRefData()
373 {
374 Free();
375 }
376
377 bool wxFontRefData::Alloc(wxFont *font)
378 {
379 if ( !m_nativeFontInfoOk )
380 {
381 wxFillLogFont(&m_nativeFontInfo.lf, font);
382 m_nativeFontInfoOk = true;
383 }
384
385 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
386 if ( !hfont )
387 {
388 wxLogLastError(wxT("CreateFont"));
389 return false;
390 }
391
392 m_hFont = (WXHFONT)hfont;
393 return true;
394 }
395
396 void wxFontRefData::Free()
397 {
398 if ( m_hFont )
399 {
400 if ( !::DeleteObject((HFONT) m_hFont) )
401 {
402 wxLogLastError(wxT("DeleteObject(font)"));
403 }
404
405 m_hFont = 0;
406 }
407 }
408
409 // ----------------------------------------------------------------------------
410 // wxNativeFontInfo
411 // ----------------------------------------------------------------------------
412
413 void wxNativeFontInfo::Init()
414 {
415 wxZeroMemory(lf);
416 }
417
418 int wxNativeFontInfo::GetPointSize() const
419 {
420 // FIXME: using the screen here results in incorrect font size calculation
421 // for printing!
422 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
423
424 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
425 }
426
427 wxSize wxNativeFontInfo::GetPixelSize() const
428 {
429 wxSize ret;
430 ret.SetHeight(lf.lfHeight);
431 ret.SetWidth(lf.lfWidth);
432 return ret;
433 }
434
435 wxFontStyle wxNativeFontInfo::GetStyle() const
436 {
437 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
438 }
439
440 wxFontWeight wxNativeFontInfo::GetWeight() const
441 {
442 if ( lf.lfWeight <= 300 )
443 return wxFONTWEIGHT_LIGHT;
444
445 if ( lf.lfWeight >= 600 )
446 return wxFONTWEIGHT_BOLD;
447
448 return wxFONTWEIGHT_NORMAL;
449 }
450
451 bool wxNativeFontInfo::GetUnderlined() const
452 {
453 return lf.lfUnderline != 0;
454 }
455
456 wxString wxNativeFontInfo::GetFaceName() const
457 {
458 return lf.lfFaceName;
459 }
460
461 wxFontFamily wxNativeFontInfo::GetFamily() const
462 {
463 wxFontFamily family;
464
465 // extract family from pitch-and-family
466 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
467 {
468 case FF_ROMAN:
469 family = wxFONTFAMILY_ROMAN;
470 break;
471
472 default:
473 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
474 // fall through
475
476 case FF_SWISS:
477 family = wxFONTFAMILY_SWISS;
478 break;
479
480 case FF_SCRIPT:
481 family = wxFONTFAMILY_SCRIPT;
482 break;
483
484 case FF_MODERN:
485 family = wxFONTFAMILY_MODERN;
486 break;
487
488 case FF_DECORATIVE:
489 family = wxFONTFAMILY_DECORATIVE;
490 break;
491 }
492
493 return family;
494 }
495
496 wxFontEncoding wxNativeFontInfo::GetEncoding() const
497 {
498 return wxGetFontEncFromCharSet(lf.lfCharSet);
499 }
500
501 void wxNativeFontInfo::SetPointSize(int pointsize)
502 {
503 // FIXME: using the screen here results in incorrect font size calculation
504 // for printing!
505 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
506
507 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
508 }
509
510 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
511 {
512 lf.lfHeight = pixelSize.GetHeight();
513 lf.lfWidth = pixelSize.GetWidth();
514 }
515
516
517 void wxNativeFontInfo::SetStyle(wxFontStyle style)
518 {
519 switch ( style )
520 {
521 default:
522 wxFAIL_MSG( _T("unknown font style") );
523 // fall through
524
525 case wxFONTSTYLE_NORMAL:
526 lf.lfItalic = FALSE;
527 break;
528
529 case wxFONTSTYLE_ITALIC:
530 case wxFONTSTYLE_SLANT:
531 lf.lfItalic = TRUE;
532 break;
533 }
534 }
535
536 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
537 {
538 switch ( weight )
539 {
540 default:
541 wxFAIL_MSG( _T("unknown font weight") );
542 // fall through
543
544 case wxFONTWEIGHT_NORMAL:
545 lf.lfWeight = FW_NORMAL;
546 break;
547
548 case wxFONTWEIGHT_LIGHT:
549 lf.lfWeight = FW_LIGHT;
550 break;
551
552 case wxFONTWEIGHT_BOLD:
553 lf.lfWeight = FW_BOLD;
554 break;
555 }
556 }
557
558 void wxNativeFontInfo::SetUnderlined(bool underlined)
559 {
560 lf.lfUnderline = underlined;
561 }
562
563 bool wxNativeFontInfo::SetFaceName(const wxString& facename)
564 {
565 size_t len = WXSIZEOF(lf.lfFaceName);
566 wxStrncpy(lf.lfFaceName, facename, len);
567 lf.lfFaceName[len - 1] = '\0'; // truncate the face name
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 wxSCRIPT:
582 ff_family = FF_SCRIPT;
583 facename.Add(_T("Script"));
584 facename.Add(_T("Brush Script MT"));
585 facename.Add(_T("Comic Sans MS"));
586 facename.Add(_T("Lucida Handwriting"));
587 break;
588
589 case wxDECORATIVE:
590 ff_family = FF_DECORATIVE;
591 facename.Add(_T("Old English Text MT"));
592 facename.Add(_T("Comic Sans MS"));
593 facename.Add(_T("Lucida Handwriting"));
594 break;
595
596 case wxROMAN:
597 ff_family = FF_ROMAN;
598 facename.Add(_T("Times New Roman"));
599 facename.Add(_T("Georgia"));
600 facename.Add(_T("Garamond"));
601 facename.Add(_T("Bookman Old Style"));
602 facename.Add(_T("Book Antiqua"));
603 break;
604
605 case wxTELETYPE:
606 case wxMODERN:
607 ff_family = FF_MODERN;
608 facename.Add(_T("Courier New"));
609 facename.Add(_T("Lucida Console"));
610 facename.Add(_T("Andale Mono"));
611 facename.Add(_T("OCR A Extended"));
612 facename.Add(_T("Terminal"));
613 break;
614
615 case wxSWISS:
616 ff_family = FF_SWISS;
617 facename.Add(_T("Arial"));
618 facename.Add(_T("Century Gothic"));
619 facename.Add(_T("Lucida Sans Unicode"));
620 facename.Add(_T("Tahoma"));
621 facename.Add(_T("Trebuchet MS"));
622 facename.Add(_T("Verdana"));
623 break;
624
625 case wxDEFAULT:
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) == wxWINDOWS_NT && verMaj >= 5)
633 facename.Add(_T("MS Shell Dlg 2"));
634 else
635 facename.Add(_T("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, _T(";"));
685
686 // first the version
687 wxString token = tokenizer.GetNextToken();
688 if ( token != _T('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(_T("%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 lf.lfFaceName);
784
785 return s;
786 }
787
788 // ----------------------------------------------------------------------------
789 // wxFont
790 // ----------------------------------------------------------------------------
791
792 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
793 {
794 UnRef();
795
796 m_refData = new wxFontRefData(info, hFont);
797
798 RealizeResource();
799
800 return true;
801 }
802
803 wxFont::wxFont(const wxString& fontdesc)
804 {
805 wxNativeFontInfo info;
806 if ( info.FromString(fontdesc) )
807 (void)Create(info);
808 }
809
810 /* Constructor for a font. Note that the real construction is done
811 * in wxDC::SetFont, when information is available about scaling etc.
812 */
813 bool wxFont::DoCreate(int pointSize,
814 const wxSize& pixelSize,
815 bool sizeUsingPixels,
816 int family,
817 int style,
818 int weight,
819 bool underlined,
820 const wxString& faceName,
821 wxFontEncoding encoding)
822 {
823 UnRef();
824
825 // wxDEFAULT is a valid value for the font size too so we must treat it
826 // specially here (otherwise the size would be 70 == wxDEFAULT value)
827 if ( pointSize == wxDEFAULT )
828 {
829 pointSize = wxNORMAL_FONT->GetPointSize();
830 }
831
832 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
833 family, style, weight,
834 underlined, faceName, encoding);
835
836 RealizeResource();
837
838 return true;
839 }
840
841 wxFont::~wxFont()
842 {
843 }
844
845 // ----------------------------------------------------------------------------
846 // real implementation
847 // ----------------------------------------------------------------------------
848
849 bool wxFont::RealizeResource()
850 {
851 if ( GetResourceHandle() )
852 {
853 // VZ: the old code returned false in this case, but it doesn't seem
854 // to make sense because the font _was_ created
855 return true;
856 }
857
858 return M_FONTDATA->Alloc(this);
859 }
860
861 bool wxFont::FreeResource(bool WXUNUSED(force))
862 {
863 if ( GetResourceHandle() )
864 {
865 M_FONTDATA->Free();
866
867 return true;
868 }
869
870 return false;
871 }
872
873 WXHANDLE wxFont::GetResourceHandle() const
874 {
875 return (WXHANDLE)GetHFONT();
876 }
877
878 WXHFONT wxFont::GetHFONT() const
879 {
880 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
881 }
882
883 bool wxFont::IsFree() const
884 {
885 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
886 }
887
888 void wxFont::Unshare()
889 {
890 // Don't change shared data
891 if ( !m_refData )
892 {
893 m_refData = new wxFontRefData();
894 }
895 else
896 {
897 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
898 UnRef();
899 m_refData = ref;
900 }
901 }
902
903 // ----------------------------------------------------------------------------
904 // change font attribute: we recreate font when doing it
905 // ----------------------------------------------------------------------------
906
907 void wxFont::SetPointSize(int pointSize)
908 {
909 Unshare();
910
911 M_FONTDATA->SetPointSize(pointSize);
912
913 RealizeResource();
914 }
915
916 void wxFont::SetPixelSize(const wxSize& pixelSize)
917 {
918 Unshare();
919
920 M_FONTDATA->SetPixelSize(pixelSize);
921
922 RealizeResource();
923 }
924
925 void wxFont::SetFamily(int family)
926 {
927 Unshare();
928
929 M_FONTDATA->SetFamily(family);
930
931 RealizeResource();
932 }
933
934 void wxFont::SetStyle(int style)
935 {
936 Unshare();
937
938 M_FONTDATA->SetStyle(style);
939
940 RealizeResource();
941 }
942
943 void wxFont::SetWeight(int weight)
944 {
945 Unshare();
946
947 M_FONTDATA->SetWeight(weight);
948
949 RealizeResource();
950 }
951
952 bool wxFont::SetFaceName(const wxString& faceName)
953 {
954 Unshare();
955
956 bool refdataok = M_FONTDATA->SetFaceName(faceName);
957
958 RealizeResource();
959
960 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
961 // to retrieve a LOGFONT and then compare lf.lfFaceName
962 // with given facename is not reliable at all:
963 // Windows copies the facename given to ::CreateFontIndirect()
964 // without any validity check.
965 // Thus we use wxFontBase::SetFaceName to check if facename
966 // is valid...
967 return refdataok && wxFontBase::SetFaceName(faceName);
968 }
969
970 void wxFont::SetUnderlined(bool underlined)
971 {
972 Unshare();
973
974 M_FONTDATA->SetUnderlined(underlined);
975
976 RealizeResource();
977 }
978
979 void wxFont::SetEncoding(wxFontEncoding encoding)
980 {
981 Unshare();
982
983 M_FONTDATA->SetEncoding(encoding);
984
985 RealizeResource();
986 }
987
988 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
989 {
990 Unshare();
991
992 FreeResource();
993
994 *M_FONTDATA = wxFontRefData(info);
995
996 RealizeResource();
997 }
998
999 // ----------------------------------------------------------------------------
1000 // accessors
1001 // ----------------------------------------------------------------------------
1002
1003 int wxFont::GetPointSize() const
1004 {
1005 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1006
1007 return M_FONTDATA->GetPointSize();
1008 }
1009
1010 wxSize wxFont::GetPixelSize() const
1011 {
1012 return M_FONTDATA->GetPixelSize();
1013 }
1014
1015 bool wxFont::IsUsingSizeInPixels() const
1016 {
1017 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1018
1019 return M_FONTDATA->IsUsingSizeInPixels();
1020 }
1021
1022 int wxFont::GetFamily() const
1023 {
1024 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1025
1026 return M_FONTDATA->GetFamily();
1027 }
1028
1029 int wxFont::GetStyle() const
1030 {
1031 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1032
1033 return M_FONTDATA->GetStyle();
1034 }
1035
1036 int wxFont::GetWeight() const
1037 {
1038 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1039
1040 return M_FONTDATA->GetWeight();
1041 }
1042
1043 bool wxFont::GetUnderlined() const
1044 {
1045 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1046
1047 return M_FONTDATA->GetUnderlined();
1048 }
1049
1050 wxString wxFont::GetFaceName() const
1051 {
1052 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1053
1054 return M_FONTDATA->GetFaceName();
1055 }
1056
1057 wxFontEncoding wxFont::GetEncoding() const
1058 {
1059 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1060
1061 return M_FONTDATA->GetEncoding();
1062 }
1063
1064 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1065 {
1066 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1067 : NULL;
1068 }
1069
1070 wxString wxFont::GetNativeFontInfoDesc() const
1071 {
1072 // be sure we have an HFONT associated...
1073 wxConstCast(this, wxFont)->RealizeResource();
1074 return wxFontBase::GetNativeFontInfoDesc();
1075 }
1076
1077 wxString wxFont::GetNativeFontInfoUserDesc() const
1078 {
1079 // be sure we have an HFONT associated...
1080 wxConstCast(this, wxFont)->RealizeResource();
1081 return wxFontBase::GetNativeFontInfoUserDesc();
1082 }
1083
1084 bool wxFont::IsFixedWidth() const
1085 {
1086 if ( M_FONTDATA->HasNativeFontInfo() )
1087 {
1088 // the two low-order bits specify the pitch of the font, the rest is
1089 // family
1090 BYTE pitch =
1091 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1092
1093 return pitch == FIXED_PITCH;
1094 }
1095
1096 return wxFontBase::IsFixedWidth();
1097 }
1098