]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
Fix wxAffineMatrix2D::Translate() to multiply on the left.
[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/msw/private.h"
35 #endif // WX_PRECOMP
36
37 #include "wx/encinfo.h"
38 #include "wx/fontutil.h"
39 #include "wx/fontmap.h"
40
41 #ifndef __WXWINCE__
42 #include "wx/sysopt.h"
43 #endif
44
45 #include "wx/scopeguard.h"
46 #include "wx/tokenzr.h"
47
48 // ----------------------------------------------------------------------------
49 // constants
50 // ----------------------------------------------------------------------------
51
52 // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
53 static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
54
55 // ----------------------------------------------------------------------------
56 // wxFontRefData - the internal description of the font
57 // ----------------------------------------------------------------------------
58
59 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
60 {
61 public:
62 // constructors
63 wxFontRefData()
64 {
65 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
66 wxFONTWEIGHT_NORMAL, false, wxEmptyString,
67 wxFONTENCODING_DEFAULT);
68 }
69
70 wxFontRefData(int size,
71 const wxSize& pixelSize,
72 bool sizeUsingPixels,
73 wxFontFamily family,
74 wxFontStyle style,
75 wxFontWeight weight,
76 bool underlined,
77 const wxString& faceName,
78 wxFontEncoding encoding)
79 {
80 Init(size, pixelSize, sizeUsingPixels, family, style, weight,
81 underlined, faceName, encoding);
82 }
83
84 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
85 {
86 Init(info, hFont);
87 }
88
89 wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
90 {
91 Init(data.m_nativeFontInfo);
92 }
93
94 virtual ~wxFontRefData();
95
96 // operations
97 bool Alloc();
98
99 void Free();
100
101 // all wxFont accessors
102 int GetPointSize() const
103 {
104 return m_nativeFontInfo.GetPointSize();
105 }
106
107 wxSize GetPixelSize() const
108 {
109 return m_nativeFontInfo.GetPixelSize();
110 }
111
112 bool IsUsingSizeInPixels() const
113 {
114 return m_sizeUsingPixels;
115 }
116
117 wxFontFamily GetFamily() const
118 {
119 return m_nativeFontInfo.GetFamily();
120 }
121
122 wxFontStyle GetStyle() const
123 {
124 return m_nativeFontInfo.GetStyle();
125 }
126
127 wxFontWeight GetWeight() const
128 {
129 return m_nativeFontInfo.GetWeight();
130 }
131
132 bool GetUnderlined() const
133 {
134 return m_nativeFontInfo.GetUnderlined();
135 }
136
137 wxString GetFaceName() const
138 {
139 wxString facename = m_nativeFontInfo.GetFaceName();
140 if ( facename.empty() )
141 {
142 facename = GetMSWFaceName();
143 if ( !facename.empty() )
144 {
145 // cache the face name, it shouldn't change unless the family
146 // does and wxNativeFontInfo::SetFamily() resets the face name
147 const_cast<wxFontRefData *>(this)->SetFaceName(facename);
148 }
149 }
150
151 return facename;
152 }
153
154 wxFontEncoding GetEncoding() const
155 {
156 return m_nativeFontInfo.GetEncoding();
157 }
158
159 WXHFONT GetHFONT() const
160 {
161 AllocIfNeeded();
162
163 return (WXHFONT)m_hFont;
164 }
165
166 bool HasHFONT() const
167 {
168 return m_hFont != 0;
169 }
170
171 // ... and setters: notice that all of them invalidate the currently
172 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
173 // new one
174 void SetPointSize(int pointSize)
175 {
176 Free();
177
178 m_nativeFontInfo.SetPointSize(pointSize);
179 m_sizeUsingPixels = false;
180 }
181
182 void SetPixelSize(const wxSize& pixelSize)
183 {
184 wxCHECK_RET( pixelSize.GetWidth() >= 0, "negative font width" );
185 wxCHECK_RET( pixelSize.GetHeight() != 0, "zero font height" );
186
187 Free();
188
189 m_nativeFontInfo.SetPixelSize(pixelSize);
190 m_sizeUsingPixels = true;
191 }
192
193 void SetFamily(wxFontFamily family)
194 {
195 Free();
196
197 m_nativeFontInfo.SetFamily(family);
198 }
199
200 void SetStyle(wxFontStyle style)
201 {
202 Free();
203
204 m_nativeFontInfo.SetStyle(style);
205 }
206
207 void SetWeight(wxFontWeight weight)
208 {
209 Free();
210
211 m_nativeFontInfo.SetWeight(weight);
212 }
213
214 bool SetFaceName(const wxString& faceName)
215 {
216 Free();
217
218 return m_nativeFontInfo.SetFaceName(faceName);
219 }
220
221 void SetUnderlined(bool underlined)
222 {
223 Free();
224
225 m_nativeFontInfo.SetUnderlined(underlined);
226 }
227
228 void SetEncoding(wxFontEncoding encoding)
229 {
230 Free();
231
232 m_nativeFontInfo.SetEncoding(encoding);
233 }
234
235 const wxNativeFontInfo& GetNativeFontInfo() const
236 {
237 // we need to create the font now to get the corresponding LOGFONT if
238 // it hadn't been done yet
239 AllocIfNeeded();
240
241 // ensure that we have a valid face name in our font information:
242 // GetFaceName() will try to retrieve it from our HFONT and save it if
243 // it was successful
244 (void)GetFaceName();
245
246 return m_nativeFontInfo;
247 }
248
249 void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
250 {
251 Free();
252
253 m_nativeFontInfo = nativeFontInfo;
254 }
255
256 protected:
257 // common part of all ctors
258 void Init(int size,
259 const wxSize& pixelSize,
260 bool sizeUsingPixels,
261 wxFontFamily family,
262 wxFontStyle style,
263 wxFontWeight weight,
264 bool underlined,
265 const wxString& faceName,
266 wxFontEncoding encoding);
267
268 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
269
270 void AllocIfNeeded() const
271 {
272 if ( !m_hFont )
273 const_cast<wxFontRefData *>(this)->Alloc();
274 }
275
276 // retrieve the face name really being used by the font: this is used to
277 // get the face name selected by the system when we don't specify it (but
278 // use just the family for example)
279 wxString GetMSWFaceName() const
280 {
281 ScreenHDC hdc;
282 SelectInHDC selectFont(hdc, (HFONT)GetHFONT());
283
284 UINT otmSize = GetOutlineTextMetrics(hdc, 0, NULL);
285 if ( !otmSize )
286 {
287 wxLogLastError("GetOutlineTextMetrics(NULL)");
288 return wxString();
289 }
290
291 OUTLINETEXTMETRIC * const
292 otm = static_cast<OUTLINETEXTMETRIC *>(malloc(otmSize));
293 wxON_BLOCK_EXIT1( free, otm );
294
295 otm->otmSize = otmSize;
296 if ( !GetOutlineTextMetrics(hdc, otmSize, otm) )
297 {
298 wxLogLastError("GetOutlineTextMetrics()");
299 return wxString();
300 }
301
302 // in spite of its type, the otmpFamilyName field of OUTLINETEXTMETRIC
303 // gives an offset in _bytes_ of the face (not family!) name from the
304 // struct start while the name itself is an array of TCHARs
305 //
306 // FWIW otmpFaceName contains the same thing as otmpFamilyName followed
307 // by a possible " Italic" or " Bold" or something else suffix
308 return reinterpret_cast<wxChar *>(otm) +
309 wxPtrToUInt(otm->otmpFamilyName)/sizeof(wxChar);
310 }
311
312 // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size?
313 bool m_sizeUsingPixels;
314
315 // Windows font handle, created on demand in GetHFONT()
316 HFONT m_hFont;
317
318 // Native font info
319 wxNativeFontInfo m_nativeFontInfo;
320 };
321
322 #define M_FONTDATA ((wxFontRefData*)m_refData)
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 wxFontFamily family,
336 wxFontStyle style,
337 wxFontWeight weight,
338 bool underlined,
339 const wxString& faceName,
340 wxFontEncoding encoding)
341 {
342 m_hFont = NULL;
343
344 m_sizeUsingPixels = sizeUsingPixels;
345 if ( m_sizeUsingPixels )
346 SetPixelSize(pixelSize);
347 else
348 SetPointSize(pointSize);
349
350 SetStyle(style);
351 SetWeight(weight);
352 SetUnderlined(underlined);
353
354 // set the family/facename
355 SetFamily(family);
356 if ( !faceName.empty() )
357 SetFaceName(faceName);
358
359 // deal with encoding now (it may override the font family and facename
360 // so do it after setting them)
361 SetEncoding(encoding);
362 }
363
364 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
365 {
366 // hFont may be zero, or it be passed in case we really want to
367 // use the exact font created in the underlying system
368 // (for example where we can't guarantee conversion from HFONT
369 // to LOGFONT back to HFONT)
370 m_hFont = (HFONT)hFont;
371 m_nativeFontInfo = info;
372
373 // TODO: m_sizeUsingPixels?
374 }
375
376 wxFontRefData::~wxFontRefData()
377 {
378 Free();
379 }
380
381 bool wxFontRefData::Alloc()
382 {
383 m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
384 if ( !m_hFont )
385 {
386 wxLogLastError(wxT("CreateFont"));
387 return false;
388 }
389
390 return true;
391 }
392
393 void wxFontRefData::Free()
394 {
395 if ( m_hFont )
396 {
397 if ( !::DeleteObject(m_hFont) )
398 {
399 wxLogLastError(wxT("DeleteObject(font)"));
400 }
401
402 m_hFont = 0;
403 }
404 }
405
406 // ----------------------------------------------------------------------------
407 // wxNativeFontInfo
408 // ----------------------------------------------------------------------------
409
410 void wxNativeFontInfo::Init()
411 {
412 wxZeroMemory(lf);
413
414 // we get better font quality if we use PROOF_QUALITY instead of
415 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
416 // then so we allow to set a global option to choose between quality and
417 // wider font selection
418 #ifdef __WXWINCE__
419 lf.lfQuality = CLEARTYPE_QUALITY;
420 #else
421 lf.lfQuality = wxSystemOptions::GetOptionInt("msw.font.no-proof-quality")
422 ? DEFAULT_QUALITY
423 : PROOF_QUALITY;
424 #endif
425 }
426
427 int wxNativeFontInfo::GetPointSize() const
428 {
429 // FIXME: using the screen here results in incorrect font size calculation
430 // for printing!
431 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
432
433 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
434 return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5);
435 }
436
437 wxSize wxNativeFontInfo::GetPixelSize() const
438 {
439 wxSize ret;
440 ret.SetHeight(abs((int)lf.lfHeight));
441 ret.SetWidth(lf.lfWidth);
442 return ret;
443 }
444
445 wxFontStyle wxNativeFontInfo::GetStyle() const
446 {
447 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
448 }
449
450 wxFontWeight wxNativeFontInfo::GetWeight() const
451 {
452 if ( lf.lfWeight <= 300 )
453 return wxFONTWEIGHT_LIGHT;
454
455 if ( lf.lfWeight >= 600 )
456 return wxFONTWEIGHT_BOLD;
457
458 return wxFONTWEIGHT_NORMAL;
459 }
460
461 bool wxNativeFontInfo::GetUnderlined() const
462 {
463 return lf.lfUnderline != 0;
464 }
465
466 wxString wxNativeFontInfo::GetFaceName() const
467 {
468 return lf.lfFaceName;
469 }
470
471 wxFontFamily wxNativeFontInfo::GetFamily() const
472 {
473 wxFontFamily family;
474
475 // extract family from pitch-and-family
476 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
477 {
478 case 0:
479 family = wxFONTFAMILY_UNKNOWN;
480 break;
481
482 case FF_ROMAN:
483 family = wxFONTFAMILY_ROMAN;
484 break;
485
486 case FF_SWISS:
487 family = wxFONTFAMILY_SWISS;
488 break;
489
490 case FF_SCRIPT:
491 family = wxFONTFAMILY_SCRIPT;
492 break;
493
494 case FF_MODERN:
495 family = wxFONTFAMILY_MODERN;
496 break;
497
498 case FF_DECORATIVE:
499 family = wxFONTFAMILY_DECORATIVE;
500 break;
501
502 default:
503 wxFAIL_MSG( "unknown LOGFONT::lfFamily value" );
504 family = wxFONTFAMILY_UNKNOWN;
505 // just to avoid a warning
506 }
507
508 return family;
509 }
510
511 wxFontEncoding wxNativeFontInfo::GetEncoding() const
512 {
513 return wxGetFontEncFromCharSet(lf.lfCharSet);
514 }
515
516 void wxNativeFontInfo::SetPointSize(int pointsize)
517 {
518 // FIXME: using the screen here results in incorrect font size calculation
519 // for printing!
520 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
521
522 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
523 }
524
525 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
526 {
527 // MSW accepts both positive and negative heights here but they mean
528 // different things: positive specifies the cell height while negative
529 // specifies the character height. We used to just pass the value to MSW
530 // unchanged but changed the behaviour for positive values in 2.9.1 to
531 // match other ports and, more importantly, the expected behaviour. So now
532 // passing the negative height doesn't make sense at all any more but we
533 // still accept it for compatibility with the existing code which worked
534 // around the wrong interpretation of the height argument in older wxMSW
535 // versions by passing a negative value explicitly itself.
536 lf.lfHeight = -abs(pixelSize.GetHeight());
537 lf.lfWidth = pixelSize.GetWidth();
538 }
539
540 void wxNativeFontInfo::SetStyle(wxFontStyle style)
541 {
542 switch ( style )
543 {
544 default:
545 wxFAIL_MSG( "unknown font style" );
546 // fall through
547
548 case wxFONTSTYLE_NORMAL:
549 lf.lfItalic = FALSE;
550 break;
551
552 case wxFONTSTYLE_ITALIC:
553 case wxFONTSTYLE_SLANT:
554 lf.lfItalic = TRUE;
555 break;
556 }
557 }
558
559 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
560 {
561 switch ( weight )
562 {
563 default:
564 wxFAIL_MSG( "unknown font weight" );
565 // fall through
566
567 case wxFONTWEIGHT_NORMAL:
568 lf.lfWeight = FW_NORMAL;
569 break;
570
571 case wxFONTWEIGHT_LIGHT:
572 lf.lfWeight = FW_LIGHT;
573 break;
574
575 case wxFONTWEIGHT_BOLD:
576 lf.lfWeight = FW_BOLD;
577 break;
578 }
579 }
580
581 void wxNativeFontInfo::SetUnderlined(bool underlined)
582 {
583 lf.lfUnderline = underlined;
584 }
585
586 bool wxNativeFontInfo::SetFaceName(const wxString& facename)
587 {
588 wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
589 return true;
590 }
591
592 void wxNativeFontInfo::SetFamily(wxFontFamily family)
593 {
594 BYTE ff_family = FF_DONTCARE;
595
596 switch ( family )
597 {
598 case wxFONTFAMILY_SCRIPT:
599 ff_family = FF_SCRIPT;
600 break;
601
602 case wxFONTFAMILY_DECORATIVE:
603 ff_family = FF_DECORATIVE;
604 break;
605
606 case wxFONTFAMILY_ROMAN:
607 ff_family = FF_ROMAN;
608 break;
609
610 case wxFONTFAMILY_TELETYPE:
611 case wxFONTFAMILY_MODERN:
612 ff_family = FF_MODERN;
613 break;
614
615 case wxFONTFAMILY_SWISS:
616 case wxFONTFAMILY_DEFAULT:
617 ff_family = FF_SWISS;
618 break;
619
620 case wxFONTFAMILY_UNKNOWN:
621 wxFAIL_MSG( "invalid font family" );
622 return;
623 }
624
625 wxCHECK_RET( ff_family != FF_DONTCARE, "unknown wxFontFamily" );
626
627 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
628
629 // reset the facename so that CreateFontIndirect() will automatically choose a
630 // face name based only on the font family.
631 lf.lfFaceName[0] = '\0';
632 }
633
634 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
635 {
636 wxNativeEncodingInfo info;
637 if ( !wxGetNativeFontEncoding(encoding, &info) )
638 {
639 #if wxUSE_FONTMAP
640 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
641 {
642 if ( !info.facename.empty() )
643 {
644 // if we have this encoding only in some particular facename, use
645 // the facename - it is better to show the correct characters in a
646 // wrong facename than unreadable text in a correct one
647 SetFaceName(info.facename);
648 }
649 }
650 else
651 #endif // wxUSE_FONTMAP
652 {
653 // unsupported encoding, replace with the default
654 info.charset = DEFAULT_CHARSET;
655 }
656 }
657
658 lf.lfCharSet = (BYTE)info.charset;
659 }
660
661 bool wxNativeFontInfo::FromString(const wxString& s)
662 {
663 long l;
664
665 wxStringTokenizer tokenizer(s, wxS(";"), wxTOKEN_RET_EMPTY_ALL);
666
667 // first the version
668 wxString token = tokenizer.GetNextToken();
669 if ( token != wxS('0') )
670 return false;
671
672 token = tokenizer.GetNextToken();
673 if ( !token.ToLong(&l) )
674 return false;
675 lf.lfHeight = l;
676
677 token = tokenizer.GetNextToken();
678 if ( !token.ToLong(&l) )
679 return false;
680 lf.lfWidth = l;
681
682 token = tokenizer.GetNextToken();
683 if ( !token.ToLong(&l) )
684 return false;
685 lf.lfEscapement = l;
686
687 token = tokenizer.GetNextToken();
688 if ( !token.ToLong(&l) )
689 return false;
690 lf.lfOrientation = l;
691
692 token = tokenizer.GetNextToken();
693 if ( !token.ToLong(&l) )
694 return false;
695 lf.lfWeight = l;
696
697 token = tokenizer.GetNextToken();
698 if ( !token.ToLong(&l) )
699 return false;
700 lf.lfItalic = (BYTE)l;
701
702 token = tokenizer.GetNextToken();
703 if ( !token.ToLong(&l) )
704 return false;
705 lf.lfUnderline = (BYTE)l;
706
707 token = tokenizer.GetNextToken();
708 if ( !token.ToLong(&l) )
709 return false;
710 lf.lfStrikeOut = (BYTE)l;
711
712 token = tokenizer.GetNextToken();
713 if ( !token.ToLong(&l) )
714 return false;
715 lf.lfCharSet = (BYTE)l;
716
717 token = tokenizer.GetNextToken();
718 if ( !token.ToLong(&l) )
719 return false;
720 lf.lfOutPrecision = (BYTE)l;
721
722 token = tokenizer.GetNextToken();
723 if ( !token.ToLong(&l) )
724 return false;
725 lf.lfClipPrecision = (BYTE)l;
726
727 token = tokenizer.GetNextToken();
728 if ( !token.ToLong(&l) )
729 return false;
730 lf.lfQuality = (BYTE)l;
731
732 token = tokenizer.GetNextToken();
733 if ( !token.ToLong(&l) )
734 return false;
735 lf.lfPitchAndFamily = (BYTE)l;
736
737 if ( !tokenizer.HasMoreTokens() )
738 return false;
739
740 // the face name may be empty
741 SetFaceName(tokenizer.GetNextToken());
742
743 return true;
744 }
745
746 wxString wxNativeFontInfo::ToString() const
747 {
748 wxString s;
749
750 s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
751 0, // version, in case we want to change the format later
752 lf.lfHeight,
753 lf.lfWidth,
754 lf.lfEscapement,
755 lf.lfOrientation,
756 lf.lfWeight,
757 lf.lfItalic,
758 lf.lfUnderline,
759 lf.lfStrikeOut,
760 lf.lfCharSet,
761 lf.lfOutPrecision,
762 lf.lfClipPrecision,
763 lf.lfQuality,
764 lf.lfPitchAndFamily,
765 lf.lfFaceName);
766
767 return s;
768 }
769
770 // ----------------------------------------------------------------------------
771 // wxFont
772 // ----------------------------------------------------------------------------
773
774 wxFont::wxFont(const wxString& fontdesc)
775 {
776 wxNativeFontInfo info;
777 if ( info.FromString(fontdesc) )
778 (void)Create(info);
779 }
780
781 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
782 {
783 UnRef();
784
785 m_refData = new wxFontRefData(info, hFont);
786
787 return RealizeResource();
788 }
789
790 bool wxFont::DoCreate(int pointSize,
791 const wxSize& pixelSize,
792 bool sizeUsingPixels,
793 wxFontFamily family,
794 wxFontStyle style,
795 wxFontWeight weight,
796 bool underlined,
797 const wxString& faceName,
798 wxFontEncoding encoding)
799 {
800 UnRef();
801
802 // wxDEFAULT is a valid value for the font size too so we must treat it
803 // specially here (otherwise the size would be 70 == wxDEFAULT value)
804 if ( pointSize == wxDEFAULT )
805 {
806 pointSize = wxNORMAL_FONT->GetPointSize();
807 }
808
809 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
810 family, style, weight,
811 underlined, faceName, encoding);
812
813 return RealizeResource();
814 }
815
816 wxFont::~wxFont()
817 {
818 }
819
820 // ----------------------------------------------------------------------------
821 // real implementation
822 // ----------------------------------------------------------------------------
823
824 wxGDIRefData *wxFont::CreateGDIRefData() const
825 {
826 return new wxFontRefData();
827 }
828
829 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
830 {
831 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
832 }
833
834 bool wxFont::RealizeResource()
835 {
836 // NOTE: the GetHFONT() call automatically triggers a reallocation of
837 // the HFONT if necessary (will do nothing if we already have the resource);
838 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
839 return GetHFONT() != NULL;
840 }
841
842 bool wxFont::FreeResource(bool WXUNUSED(force))
843 {
844 if ( !M_FONTDATA )
845 return false;
846
847 M_FONTDATA->Free();
848
849 return true;
850 }
851
852 WXHANDLE wxFont::GetResourceHandle() const
853 {
854 return (WXHANDLE)GetHFONT();
855 }
856
857 WXHFONT wxFont::GetHFONT() const
858 {
859 // NOTE: wxFontRefData::GetHFONT() will automatically call
860 // wxFontRefData::Alloc() if necessary
861 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
862 }
863
864 bool wxFont::IsFree() const
865 {
866 return M_FONTDATA && !M_FONTDATA->HasHFONT();
867 }
868
869 // ----------------------------------------------------------------------------
870 // change font attribute: we recreate font when doing it
871 // ----------------------------------------------------------------------------
872
873 void wxFont::SetPointSize(int pointSize)
874 {
875 AllocExclusive();
876
877 M_FONTDATA->Free();
878 M_FONTDATA->SetPointSize(pointSize);
879 }
880
881 void wxFont::SetPixelSize(const wxSize& pixelSize)
882 {
883 AllocExclusive();
884
885 M_FONTDATA->SetPixelSize(pixelSize);
886 }
887
888 void wxFont::SetFamily(wxFontFamily family)
889 {
890 AllocExclusive();
891
892 M_FONTDATA->SetFamily(family);
893 }
894
895 void wxFont::SetStyle(wxFontStyle style)
896 {
897 AllocExclusive();
898
899 M_FONTDATA->SetStyle(style);
900 }
901
902 void wxFont::SetWeight(wxFontWeight weight)
903 {
904 AllocExclusive();
905
906 M_FONTDATA->SetWeight(weight);
907 }
908
909 bool wxFont::SetFaceName(const wxString& faceName)
910 {
911 AllocExclusive();
912
913 if ( !M_FONTDATA->SetFaceName(faceName) )
914 return false;
915
916 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
917 // to retrieve a LOGFONT and then compare lf.lfFaceName
918 // with given facename is not reliable at all:
919 // Windows copies the facename given to ::CreateFontIndirect()
920 // without any validity check.
921 // Thus we use wxFontBase::SetFaceName to check if facename
922 // is valid...
923 return wxFontBase::SetFaceName(faceName);
924 }
925
926 void wxFont::SetUnderlined(bool underlined)
927 {
928 AllocExclusive();
929
930 M_FONTDATA->SetUnderlined(underlined);
931 }
932
933 void wxFont::SetEncoding(wxFontEncoding encoding)
934 {
935 AllocExclusive();
936
937 M_FONTDATA->SetEncoding(encoding);
938 }
939
940 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
941 {
942 AllocExclusive();
943
944 M_FONTDATA->SetNativeFontInfo(info);
945 }
946
947 // ----------------------------------------------------------------------------
948 // accessors
949 // ----------------------------------------------------------------------------
950
951 int wxFont::GetPointSize() const
952 {
953 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
954
955 return M_FONTDATA->GetPointSize();
956 }
957
958 wxSize wxFont::GetPixelSize() const
959 {
960 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
961
962 return M_FONTDATA->GetPixelSize();
963 }
964
965 bool wxFont::IsUsingSizeInPixels() const
966 {
967 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
968
969 return M_FONTDATA->IsUsingSizeInPixels();
970 }
971
972 wxFontFamily wxFont::DoGetFamily() const
973 {
974 return M_FONTDATA->GetFamily();
975 }
976
977 wxFontStyle wxFont::GetStyle() const
978 {
979 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
980
981 return M_FONTDATA->GetStyle();
982 }
983
984 wxFontWeight wxFont::GetWeight() const
985 {
986 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
987
988 return M_FONTDATA->GetWeight();
989 }
990
991 bool wxFont::GetUnderlined() const
992 {
993 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
994
995 return M_FONTDATA->GetUnderlined();
996 }
997
998 wxString wxFont::GetFaceName() const
999 {
1000 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1001
1002 return M_FONTDATA->GetFaceName();
1003 }
1004
1005 wxFontEncoding wxFont::GetEncoding() const
1006 {
1007 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1008
1009 return M_FONTDATA->GetEncoding();
1010 }
1011
1012 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1013 {
1014 return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL;
1015 }
1016
1017 bool wxFont::IsFixedWidth() const
1018 {
1019 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1020
1021 // LOGFONT doesn't contain the correct pitch information so we need to call
1022 // GetTextMetrics() to get it
1023 ScreenHDC hdc;
1024 SelectInHDC selectFont(hdc, M_FONTDATA->GetHFONT());
1025
1026 TEXTMETRIC tm;
1027 if ( !::GetTextMetrics(hdc, &tm) )
1028 {
1029 wxLogLastError(wxT("GetTextMetrics"));
1030 return false;
1031 }
1032
1033 // Quoting MSDN description of TMPF_FIXED_PITCH: "Note very carefully that
1034 // those meanings are the opposite of what the constant name implies."
1035 return !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
1036 }