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