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