]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
replace more __WXDEBUG__ occurrences with wxDEBUG_LEVEL
[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 if ( data.m_nativeFontInfoOk )
138 {
139 Init(data.m_nativeFontInfo);
140 }
141 else
142 {
143 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels,
144 data.m_family, data.m_style, data.m_weight,
145 data.m_underlined, data.m_faceName, data.m_encoding);
146 }
147 }
148
149 virtual ~wxFontRefData();
150
151 // operations
152 bool Alloc(const wxFont *font);
153
154 void Free();
155
156 // all wxFont accessors
157 int GetPointSize() const
158 {
159 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
160 : m_pointSize;
161 }
162
163 wxSize GetPixelSize() const
164 {
165 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize()
166 : m_pixelSize;
167 }
168
169 bool IsUsingSizeInPixels() const
170 {
171 return m_nativeFontInfoOk ? true : m_sizeUsingPixels;
172 }
173
174 wxFontFamily GetFamily() const
175 {
176 return m_family;
177 }
178
179 wxFontStyle GetStyle() const
180 {
181 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
182 : m_style;
183 }
184
185 wxFontWeight GetWeight() const
186 {
187 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
188 : m_weight;
189 }
190
191 bool GetUnderlined() const
192 {
193 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
194 : m_underlined;
195 }
196
197 wxString GetFaceName() const
198 {
199 wxString s;
200 if ( m_nativeFontInfoOk )
201 s = m_nativeFontInfo.GetFaceName();
202 else
203 s = m_faceName;
204
205 return s;
206 }
207
208 wxFontEncoding GetEncoding() const
209 {
210 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
211 : m_encoding;
212 }
213
214 WXHFONT GetHFONT(const wxFont *font) const
215 {
216 if ( !m_hFont )
217 const_cast<wxFontRefData *>(this)->Alloc(font);
218
219 return (WXHFONT)m_hFont;
220 }
221
222 bool HasHFONT() const
223 {
224 return m_hFont != 0;
225 }
226
227 // ... and setters: notice that all of them invalidate the currently
228 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
229 // new one
230 void SetPointSize(int pointSize)
231 {
232 Free();
233
234 if ( m_nativeFontInfoOk )
235 {
236 m_nativeFontInfo.SetPointSize(pointSize);
237 }
238 else
239 {
240 m_pointSize = pointSize;
241 m_sizeUsingPixels = false;
242 }
243 }
244
245 void SetPixelSize(const wxSize& pixelSize)
246 {
247 Free();
248
249 if ( m_nativeFontInfoOk )
250 {
251 m_nativeFontInfo.SetPixelSize(pixelSize);
252 }
253 else
254 {
255 m_pixelSize = pixelSize;
256 m_sizeUsingPixels = true;
257 }
258 }
259
260 void SetFamily(wxFontFamily family)
261 {
262 Free();
263
264 m_family = family;
265 }
266
267 void SetStyle(wxFontStyle style)
268 {
269 Free();
270
271 if ( m_nativeFontInfoOk )
272 m_nativeFontInfo.SetStyle((wxFontStyle)style);
273 else
274 m_style = style;
275 }
276
277 void SetWeight(wxFontWeight weight)
278 {
279 Free();
280
281 if ( m_nativeFontInfoOk )
282 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
283 else
284 m_weight = weight;
285 }
286
287 bool SetFaceName(const wxString& faceName)
288 {
289 Free();
290
291 if ( m_nativeFontInfoOk )
292 return m_nativeFontInfo.SetFaceName(faceName);
293
294 m_faceName = faceName;
295 return true;
296 }
297
298 void SetUnderlined(bool underlined)
299 {
300 Free();
301
302 if ( m_nativeFontInfoOk )
303 m_nativeFontInfo.SetUnderlined(underlined);
304 else
305 m_underlined = underlined;
306 }
307
308 void SetEncoding(wxFontEncoding encoding)
309 {
310 Free();
311
312 if ( m_nativeFontInfoOk )
313 m_nativeFontInfo.SetEncoding(encoding);
314 else
315 m_encoding = encoding;
316 }
317
318 // native font info
319 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
320
321 const wxNativeFontInfo& GetNativeFontInfo() const
322 { return m_nativeFontInfo; }
323
324 void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
325 {
326 Free();
327
328 m_nativeFontInfo = nativeFontInfo;
329 m_nativeFontInfoOk = true;
330 }
331
332 protected:
333 // common part of all ctors
334 void Init(int size,
335 const wxSize& pixelSize,
336 bool sizeUsingPixels,
337 wxFontFamily family,
338 wxFontStyle style,
339 wxFontWeight weight,
340 bool underlined,
341 const wxString& faceName,
342 wxFontEncoding encoding);
343
344 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
345
346 // font characteristics
347 int m_pointSize;
348 wxSize m_pixelSize;
349 bool m_sizeUsingPixels;
350 wxFontFamily m_family;
351 wxFontStyle m_style;
352 wxFontWeight m_weight;
353 bool m_underlined;
354 wxString m_faceName;
355 wxFontEncoding m_encoding;
356
357 // Windows font handle, created on demand in GetHFONT()
358 HFONT m_hFont;
359
360 // Native font info
361 wxNativeFontInfo m_nativeFontInfo;
362 bool m_nativeFontInfoOk;
363 };
364
365 #define M_FONTDATA ((wxFontRefData*)m_refData)
366
367 // ============================================================================
368 // implementation
369 // ============================================================================
370
371 // ----------------------------------------------------------------------------
372 // wxFontRefData
373 // ----------------------------------------------------------------------------
374
375 void wxFontRefData::Init(int pointSize,
376 const wxSize& pixelSize,
377 bool sizeUsingPixels,
378 wxFontFamily family,
379 wxFontStyle style,
380 wxFontWeight weight,
381 bool underlined,
382 const wxString& faceName,
383 wxFontEncoding encoding)
384 {
385 m_style = style;
386 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
387 m_pixelSize = pixelSize;
388 m_sizeUsingPixels = sizeUsingPixels;
389 m_family = family;
390 m_style = style;
391 m_weight = weight;
392 m_underlined = underlined;
393 m_faceName = faceName;
394 m_encoding = encoding;
395
396 m_hFont = 0;
397
398 m_nativeFontInfoOk = false;
399 }
400
401 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
402 {
403 // hFont may be zero, or it be passed in case we really want to
404 // use the exact font created in the underlying system
405 // (for example where we can't guarantee conversion from HFONT
406 // to LOGFONT back to HFONT)
407 m_hFont = (HFONT)hFont;
408
409 m_nativeFontInfoOk = true;
410 m_nativeFontInfo = info;
411
412 // This is the best we can do since we don't have the
413 // correct information at this point.
414 m_family = wxFONTFAMILY_SWISS;
415 }
416
417 wxFontRefData::~wxFontRefData()
418 {
419 Free();
420 }
421
422 bool wxFontRefData::Alloc(const wxFont *font)
423 {
424 if ( !m_nativeFontInfoOk )
425 {
426 // NOTE: we use wxNativeInfo::InitFromFont to avoid code duplication:
427 // it results in using our m_* variables (except for m_hFont and
428 // for m_nativeFontInfo obviously) for the initialization
429 // of the wxNativeInfo::lf member.
430 m_nativeFontInfo.InitFromFont(*font);
431 m_nativeFontInfoOk = true;
432 }
433
434 m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
435 if ( !m_hFont )
436 {
437 wxLogLastError(wxT("CreateFont"));
438 return false;
439 }
440
441 return true;
442 }
443
444 void wxFontRefData::Free()
445 {
446 if ( m_hFont )
447 {
448 if ( !::DeleteObject(m_hFont) )
449 {
450 wxLogLastError(wxT("DeleteObject(font)"));
451 }
452
453 m_hFont = 0;
454 }
455 }
456
457 // ----------------------------------------------------------------------------
458 // wxNativeFontInfo
459 // ----------------------------------------------------------------------------
460
461 void wxNativeFontInfo::Init()
462 {
463 wxZeroMemory(lf);
464
465 // we get better font quality if we use PROOF_QUALITY instead of
466 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
467 // then so we allow to set a global option to choose between quality and
468 // wider font selection
469 #ifdef __WXWINCE__
470 lf.lfQuality = CLEARTYPE_QUALITY;
471 #else
472 lf.lfQuality = wxSystemOptions::GetOptionInt(_T("msw.font.no-proof-quality"))
473 ? DEFAULT_QUALITY
474 : PROOF_QUALITY;
475 #endif
476 }
477
478 int wxNativeFontInfo::GetPointSize() const
479 {
480 // FIXME: using the screen here results in incorrect font size calculation
481 // for printing!
482 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
483
484 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
485 return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5);
486 }
487
488 wxSize wxNativeFontInfo::GetPixelSize() const
489 {
490 wxSize ret;
491 ret.SetHeight(abs((int)lf.lfHeight));
492 ret.SetWidth(lf.lfWidth);
493 return ret;
494 }
495
496 wxFontStyle wxNativeFontInfo::GetStyle() const
497 {
498 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
499 }
500
501 wxFontWeight wxNativeFontInfo::GetWeight() const
502 {
503 if ( lf.lfWeight <= 300 )
504 return wxFONTWEIGHT_LIGHT;
505
506 if ( lf.lfWeight >= 600 )
507 return wxFONTWEIGHT_BOLD;
508
509 return wxFONTWEIGHT_NORMAL;
510 }
511
512 bool wxNativeFontInfo::GetUnderlined() const
513 {
514 return lf.lfUnderline != 0;
515 }
516
517 wxString wxNativeFontInfo::GetFaceName() const
518 {
519 return lf.lfFaceName;
520 }
521
522 wxFontFamily wxNativeFontInfo::GetFamily() const
523 {
524 wxFontFamily family;
525
526 // extract family from pitch-and-family
527 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
528 {
529 case FF_ROMAN:
530 family = wxFONTFAMILY_ROMAN;
531 break;
532
533 default:
534 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
535 // fall through
536
537 case FF_SWISS:
538 family = wxFONTFAMILY_SWISS;
539 break;
540
541 case FF_SCRIPT:
542 family = wxFONTFAMILY_SCRIPT;
543 break;
544
545 case FF_MODERN:
546 family = wxFONTFAMILY_MODERN;
547 break;
548
549 case FF_DECORATIVE:
550 family = wxFONTFAMILY_DECORATIVE;
551 break;
552 }
553
554 return family;
555 }
556
557 wxFontEncoding wxNativeFontInfo::GetEncoding() const
558 {
559 return wxGetFontEncFromCharSet(lf.lfCharSet);
560 }
561
562 void wxNativeFontInfo::SetPointSize(int pointsize)
563 {
564 // FIXME: using the screen here results in incorrect font size calculation
565 // for printing!
566 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
567
568 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
569 }
570
571 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
572 {
573 // NOTE: although the MSW port allows for negative pixel size heights,
574 // other ports don't and since it's a very useful feature assert
575 // here if we get a negative height:
576 wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
577 "Negative values for the pixel size or zero pixel height are not allowed" );
578
579 lf.lfHeight = pixelSize.GetHeight();
580 lf.lfWidth = pixelSize.GetWidth();
581 }
582
583 void wxNativeFontInfo::SetStyle(wxFontStyle style)
584 {
585 switch ( style )
586 {
587 default:
588 wxFAIL_MSG( _T("unknown font style") );
589 // fall through
590
591 case wxFONTSTYLE_NORMAL:
592 lf.lfItalic = FALSE;
593 break;
594
595 case wxFONTSTYLE_ITALIC:
596 case wxFONTSTYLE_SLANT:
597 lf.lfItalic = TRUE;
598 break;
599 }
600 }
601
602 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
603 {
604 switch ( weight )
605 {
606 default:
607 wxFAIL_MSG( _T("unknown font weight") );
608 // fall through
609
610 case wxFONTWEIGHT_NORMAL:
611 lf.lfWeight = FW_NORMAL;
612 break;
613
614 case wxFONTWEIGHT_LIGHT:
615 lf.lfWeight = FW_LIGHT;
616 break;
617
618 case wxFONTWEIGHT_BOLD:
619 lf.lfWeight = FW_BOLD;
620 break;
621 }
622 }
623
624 void wxNativeFontInfo::SetUnderlined(bool underlined)
625 {
626 lf.lfUnderline = underlined;
627 }
628
629 bool wxNativeFontInfo::SetFaceName(const wxString& facename)
630 {
631 wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
632 return true;
633 }
634
635 void wxNativeFontInfo::SetFamily(wxFontFamily family)
636 {
637 BYTE ff_family;
638 wxArrayString facename;
639
640 // the list of fonts associated with a family was partially
641 // taken from http://www.codestyle.org/css/font-family
642
643 switch ( family )
644 {
645 case wxSCRIPT:
646 ff_family = FF_SCRIPT;
647 facename.Add(_T("Script"));
648 facename.Add(_T("Brush Script MT"));
649 facename.Add(_T("Comic Sans MS"));
650 facename.Add(_T("Lucida Handwriting"));
651 break;
652
653 case wxDECORATIVE:
654 ff_family = FF_DECORATIVE;
655 facename.Add(_T("Old English Text MT"));
656 facename.Add(_T("Comic Sans MS"));
657 facename.Add(_T("Lucida Handwriting"));
658 break;
659
660 case wxROMAN:
661 ff_family = FF_ROMAN;
662 facename.Add(_T("Times New Roman"));
663 facename.Add(_T("Georgia"));
664 facename.Add(_T("Garamond"));
665 facename.Add(_T("Bookman Old Style"));
666 facename.Add(_T("Book Antiqua"));
667 break;
668
669 case wxTELETYPE:
670 case wxMODERN:
671 ff_family = FF_MODERN;
672 facename.Add(_T("Courier New"));
673 facename.Add(_T("Lucida Console"));
674 facename.Add(_T("Andale Mono"));
675 facename.Add(_T("OCR A Extended"));
676 facename.Add(_T("Terminal"));
677 break;
678
679 case wxSWISS:
680 ff_family = FF_SWISS;
681 facename.Add(_T("Arial"));
682 facename.Add(_T("Century Gothic"));
683 facename.Add(_T("Lucida Sans Unicode"));
684 facename.Add(_T("Tahoma"));
685 facename.Add(_T("Trebuchet MS"));
686 facename.Add(_T("Verdana"));
687 break;
688
689 case wxDEFAULT:
690 default:
691 {
692 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
693 // is returned as default GUI font for compatibility
694 int verMaj;
695 ff_family = FF_SWISS;
696 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
697 facename.Add(_T("MS Shell Dlg 2"));
698 else
699 facename.Add(_T("MS Shell Dlg"));
700
701 // Quoting the MSDN:
702 // "MS Shell Dlg is a mapping mechanism that enables
703 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
704 // support locales that have characters that are not contained in code
705 // page 1252. It is not a font but a face name for a nonexistent font."
706 }
707 }
708
709 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
710
711 if ( !wxStrlen(lf.lfFaceName) )
712 {
713 SetFaceName(facename);
714 }
715 }
716
717 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
718 {
719 wxNativeEncodingInfo info;
720 if ( !wxGetNativeFontEncoding(encoding, &info) )
721 {
722 #if wxUSE_FONTMAP
723 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
724 {
725 if ( !info.facename.empty() )
726 {
727 // if we have this encoding only in some particular facename, use
728 // the facename - it is better to show the correct characters in a
729 // wrong facename than unreadable text in a correct one
730 SetFaceName(info.facename);
731 }
732 }
733 else
734 #endif // wxUSE_FONTMAP
735 {
736 // unsupported encoding, replace with the default
737 info.charset = DEFAULT_CHARSET;
738 }
739 }
740
741 lf.lfCharSet = (BYTE)info.charset;
742 }
743
744 bool wxNativeFontInfo::FromString(const wxString& s)
745 {
746 long l;
747
748 wxStringTokenizer tokenizer(s, _T(";"));
749
750 // first the version
751 wxString token = tokenizer.GetNextToken();
752 if ( token != _T('0') )
753 return false;
754
755 token = tokenizer.GetNextToken();
756 if ( !token.ToLong(&l) )
757 return false;
758 lf.lfHeight = l;
759
760 token = tokenizer.GetNextToken();
761 if ( !token.ToLong(&l) )
762 return false;
763 lf.lfWidth = l;
764
765 token = tokenizer.GetNextToken();
766 if ( !token.ToLong(&l) )
767 return false;
768 lf.lfEscapement = l;
769
770 token = tokenizer.GetNextToken();
771 if ( !token.ToLong(&l) )
772 return false;
773 lf.lfOrientation = l;
774
775 token = tokenizer.GetNextToken();
776 if ( !token.ToLong(&l) )
777 return false;
778 lf.lfWeight = l;
779
780 token = tokenizer.GetNextToken();
781 if ( !token.ToLong(&l) )
782 return false;
783 lf.lfItalic = (BYTE)l;
784
785 token = tokenizer.GetNextToken();
786 if ( !token.ToLong(&l) )
787 return false;
788 lf.lfUnderline = (BYTE)l;
789
790 token = tokenizer.GetNextToken();
791 if ( !token.ToLong(&l) )
792 return false;
793 lf.lfStrikeOut = (BYTE)l;
794
795 token = tokenizer.GetNextToken();
796 if ( !token.ToLong(&l) )
797 return false;
798 lf.lfCharSet = (BYTE)l;
799
800 token = tokenizer.GetNextToken();
801 if ( !token.ToLong(&l) )
802 return false;
803 lf.lfOutPrecision = (BYTE)l;
804
805 token = tokenizer.GetNextToken();
806 if ( !token.ToLong(&l) )
807 return false;
808 lf.lfClipPrecision = (BYTE)l;
809
810 token = tokenizer.GetNextToken();
811 if ( !token.ToLong(&l) )
812 return false;
813 lf.lfQuality = (BYTE)l;
814
815 token = tokenizer.GetNextToken();
816 if ( !token.ToLong(&l) )
817 return false;
818 lf.lfPitchAndFamily = (BYTE)l;
819
820 token = tokenizer.GetNextToken();
821 if(!token)
822 return false;
823 wxStrcpy(lf.lfFaceName, token.c_str());
824
825 return true;
826 }
827
828 wxString wxNativeFontInfo::ToString() const
829 {
830 wxString s;
831
832 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
833 0, // version, in case we want to change the format later
834 lf.lfHeight,
835 lf.lfWidth,
836 lf.lfEscapement,
837 lf.lfOrientation,
838 lf.lfWeight,
839 lf.lfItalic,
840 lf.lfUnderline,
841 lf.lfStrikeOut,
842 lf.lfCharSet,
843 lf.lfOutPrecision,
844 lf.lfClipPrecision,
845 lf.lfQuality,
846 lf.lfPitchAndFamily,
847 (const wxChar*)lf.lfFaceName);
848
849 return s;
850 }
851
852 // ----------------------------------------------------------------------------
853 // wxFont
854 // ----------------------------------------------------------------------------
855
856 wxFont::wxFont(const wxString& fontdesc)
857 {
858 wxNativeFontInfo info;
859 if ( info.FromString(fontdesc) )
860 (void)Create(info);
861 }
862
863 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
864 {
865 UnRef();
866
867 m_refData = new wxFontRefData(info, hFont);
868
869 return RealizeResource();
870 }
871
872 bool wxFont::DoCreate(int pointSize,
873 const wxSize& pixelSize,
874 bool sizeUsingPixels,
875 wxFontFamily family,
876 wxFontStyle style,
877 wxFontWeight weight,
878 bool underlined,
879 const wxString& faceName,
880 wxFontEncoding encoding)
881 {
882 UnRef();
883
884 // wxDEFAULT is a valid value for the font size too so we must treat it
885 // specially here (otherwise the size would be 70 == wxDEFAULT value)
886 if ( pointSize == wxDEFAULT )
887 {
888 pointSize = wxNORMAL_FONT->GetPointSize();
889 }
890
891 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
892 family, style, weight,
893 underlined, faceName, encoding);
894
895 return RealizeResource();
896 }
897
898 wxFont::~wxFont()
899 {
900 }
901
902 // ----------------------------------------------------------------------------
903 // real implementation
904 // ----------------------------------------------------------------------------
905
906 wxGDIRefData *wxFont::CreateGDIRefData() const
907 {
908 return new wxFontRefData();
909 }
910
911 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
912 {
913 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
914 }
915
916 bool wxFont::RealizeResource()
917 {
918 // NOTE: the GetHFONT() call automatically triggers a reallocation of
919 // the HFONT if necessary (will do nothing if we already have the resource);
920 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
921 return GetHFONT() != NULL;
922 }
923
924 bool wxFont::FreeResource(bool WXUNUSED(force))
925 {
926 if ( !M_FONTDATA )
927 return false;
928
929 M_FONTDATA->Free();
930
931 return true;
932 }
933
934 WXHANDLE wxFont::GetResourceHandle() const
935 {
936 return (WXHANDLE)GetHFONT();
937 }
938
939 WXHFONT wxFont::GetHFONT() const
940 {
941 // NOTE: wxFontRefData::GetHFONT() will automatically call
942 // wxFontRefData::Alloc() if necessary
943 return M_FONTDATA ? M_FONTDATA->GetHFONT(this) : 0;
944 }
945
946 bool wxFont::IsFree() const
947 {
948 return M_FONTDATA && !M_FONTDATA->HasHFONT();
949 }
950
951 // ----------------------------------------------------------------------------
952 // change font attribute: we recreate font when doing it
953 // ----------------------------------------------------------------------------
954
955 void wxFont::SetPointSize(int pointSize)
956 {
957 AllocExclusive();
958
959 M_FONTDATA->Free();
960 M_FONTDATA->SetPointSize(pointSize);
961 }
962
963 void wxFont::SetPixelSize(const wxSize& pixelSize)
964 {
965 AllocExclusive();
966
967 M_FONTDATA->SetPixelSize(pixelSize);
968 }
969
970 void wxFont::SetFamily(wxFontFamily family)
971 {
972 AllocExclusive();
973
974 M_FONTDATA->SetFamily(family);
975 }
976
977 void wxFont::SetStyle(wxFontStyle style)
978 {
979 AllocExclusive();
980
981 M_FONTDATA->SetStyle(style);
982 }
983
984 void wxFont::SetWeight(wxFontWeight weight)
985 {
986 AllocExclusive();
987
988 M_FONTDATA->SetWeight(weight);
989 }
990
991 bool wxFont::SetFaceName(const wxString& faceName)
992 {
993 AllocExclusive();
994
995 if ( !M_FONTDATA->SetFaceName(faceName) )
996 return false;
997
998 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
999 // to retrieve a LOGFONT and then compare lf.lfFaceName
1000 // with given facename is not reliable at all:
1001 // Windows copies the facename given to ::CreateFontIndirect()
1002 // without any validity check.
1003 // Thus we use wxFontBase::SetFaceName to check if facename
1004 // is valid...
1005 return wxFontBase::SetFaceName(faceName);
1006 }
1007
1008 void wxFont::SetUnderlined(bool underlined)
1009 {
1010 AllocExclusive();
1011
1012 M_FONTDATA->SetUnderlined(underlined);
1013 }
1014
1015 void wxFont::SetEncoding(wxFontEncoding encoding)
1016 {
1017 AllocExclusive();
1018
1019 M_FONTDATA->SetEncoding(encoding);
1020 }
1021
1022 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
1023 {
1024 AllocExclusive();
1025
1026 M_FONTDATA->SetNativeFontInfo(info);
1027 }
1028
1029 // ----------------------------------------------------------------------------
1030 // accessors
1031 // ----------------------------------------------------------------------------
1032
1033 int wxFont::GetPointSize() const
1034 {
1035 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1036
1037 return M_FONTDATA->GetPointSize();
1038 }
1039
1040 wxSize wxFont::GetPixelSize() const
1041 {
1042 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
1043
1044 return M_FONTDATA->GetPixelSize();
1045 }
1046
1047 bool wxFont::IsUsingSizeInPixels() const
1048 {
1049 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1050
1051 return M_FONTDATA->IsUsingSizeInPixels();
1052 }
1053
1054 wxFontFamily wxFont::GetFamily() const
1055 {
1056 wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
1057
1058 return M_FONTDATA->GetFamily();
1059 }
1060
1061 wxFontStyle wxFont::GetStyle() const
1062 {
1063 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
1064
1065 return M_FONTDATA->GetStyle();
1066 }
1067
1068 wxFontWeight wxFont::GetWeight() const
1069 {
1070 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
1071
1072 return M_FONTDATA->GetWeight();
1073 }
1074
1075 bool wxFont::GetUnderlined() const
1076 {
1077 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1078
1079 return M_FONTDATA->GetUnderlined();
1080 }
1081
1082 wxString wxFont::GetFaceName() const
1083 {
1084 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1085
1086 return M_FONTDATA->GetFaceName();
1087 }
1088
1089 wxFontEncoding wxFont::GetEncoding() const
1090 {
1091 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1092
1093 return M_FONTDATA->GetEncoding();
1094 }
1095
1096 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1097 {
1098 return IsOk() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1099 : NULL;
1100 }
1101
1102 wxString wxFont::GetNativeFontInfoDesc() const
1103 {
1104 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1105
1106 // be sure we have an HFONT associated...
1107 const_cast<wxFont*>(this)->RealizeResource();
1108 return wxFontBase::GetNativeFontInfoDesc();
1109 }
1110
1111 wxString wxFont::GetNativeFontInfoUserDesc() const
1112 {
1113 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
1114
1115 // be sure we have an HFONT associated...
1116 const_cast<wxFont*>(this)->RealizeResource();
1117 return wxFontBase::GetNativeFontInfoUserDesc();
1118 }
1119
1120 bool wxFont::IsFixedWidth() const
1121 {
1122 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1123
1124 if ( M_FONTDATA->HasNativeFontInfo() )
1125 {
1126 // the two low-order bits specify the pitch of the font, the rest is
1127 // family
1128 BYTE pitch =
1129 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1130
1131 return pitch == FIXED_PITCH;
1132 }
1133
1134 return wxFontBase::IsFixedWidth();
1135 }