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