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