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