1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/fontcmn.cpp
3 // Purpose: implementation of wxFontBase methods
4 // Author: Vadim Zeitlin
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/dcscreen.h"
34 #include "wx/gdicmn.h"
36 #if defined(__WXMSW__)
37 #include "wx/msw/private.h" // includes windows.h for LOGFONT
38 #include "wx/msw/winundef.h"
41 #include "wx/fontutil.h" // for wxNativeFontInfo
42 #include "wx/fontmap.h"
44 #include "wx/tokenzr.h"
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 static void AdjustFontSize(wxFont
& font
, wxDC
& dc
, const wxSize
& pixelSize
)
60 bool initialGoodFound
= false;
61 bool initialBadFound
= false;
63 currentSize
= font
.GetPointSize();
64 while (currentSize
> 0)
68 // if currentSize (in points) results in a font that is smaller
69 // than required by pixelSize it is considered a good size
70 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
71 (!pixelSize
.GetWidth() ||
72 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
74 largestGood
= currentSize
;
75 initialGoodFound
= true;
79 smallestBad
= currentSize
;
80 initialBadFound
= true;
82 if (!initialGoodFound
)
86 else if (!initialBadFound
)
92 int distance
= smallestBad
- largestGood
;
96 currentSize
= largestGood
+ distance
/ 2;
99 font
.SetPointSize(currentSize
);
102 if (currentSize
!= largestGood
)
103 font
.SetPointSize(largestGood
);
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 wxFontEncoding wxFontBase
::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
113 void wxFontBase
::SetDefaultEncoding(wxFontEncoding encoding
)
115 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
116 // and, besides, using this value here doesn't make any sense
117 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
118 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
120 ms_encodingDefault
= encoding
;
123 wxFontBase
::~wxFontBase()
125 // this destructor is required for Darwin
129 wxFont
*wxFontBase
::New(int size
,
134 const wxString
& face
,
135 wxFontEncoding encoding
)
137 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
140 static inline int flags2Style(int flags
)
142 return flags
& wxFONTFLAG_ITALIC
144 : flags
& wxFONTFLAG_SLANT
146 : wxFONTSTYLE_NORMAL
;
149 static inline int flags2Weight(int flags
)
151 return flags
& wxFONTFLAG_LIGHT
153 : flags
& wxFONTFLAG_BOLD
155 : wxFONTWEIGHT_NORMAL
;
158 static inline bool flags2Underlined(int flags
)
160 return (flags
& wxFONTFLAG_UNDERLINED
) != 0;
164 wxFont
*wxFontBase
::New(int pointSize
,
167 const wxString
& face
,
168 wxFontEncoding encoding
)
170 return New(pointSize
, family
, flags2Style(flags
), flags2Weight(flags
),
171 flags2Underlined(flags
), face
, encoding
);
175 wxFont
*wxFontBase
::New(const wxSize
& pixelSize
,
180 const wxString
& face
,
181 wxFontEncoding encoding
)
183 #if defined(__WXMSW__)
184 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
187 wxFont
*self
= New(10, family
, style
, weight
, underlined
, face
, encoding
);
189 AdjustFontSize(*(wxFont
*)self
, dc
, pixelSize
);
195 wxFont
*wxFontBase
::New(const wxSize
& pixelSize
,
198 const wxString
& face
,
199 wxFontEncoding encoding
)
201 return New(pixelSize
, family
, flags2Style(flags
), flags2Weight(flags
),
202 flags2Underlined(flags
), face
, encoding
);
205 wxSize wxFontBase
::GetPixelSize() const
208 dc
.SetFont(*(wxFont
*)this);
209 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
212 bool wxFontBase
::IsUsingSizeInPixels() const
217 void wxFontBase
::SetPixelSize( const wxSize
& pixelSize
)
220 AdjustFontSize(*(wxFont
*)this, dc
, pixelSize
);
224 wxFont
*wxFontBase
::New(const wxNativeFontInfo
& info
)
226 return new wxFont(info
);
230 wxFont
*wxFontBase
::New(const wxString
& strNativeFontDesc
)
232 wxNativeFontInfo fontInfo
;
233 if ( !fontInfo
.FromString(strNativeFontDesc
) )
234 return new wxFont(*wxNORMAL_FONT
);
236 return New(fontInfo
);
239 bool wxFontBase
::IsFixedWidth() const
241 return GetFamily() == wxFONTFAMILY_TELETYPE
;
244 void wxFontBase
::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
246 #ifdef wxNO_NATIVE_FONTINFO
247 SetPointSize(info
.pointSize
);
248 SetFamily(info
.family
);
249 SetStyle(info
.style
);
250 SetWeight(info
.weight
);
251 SetUnderlined(info
.underlined
);
252 SetFaceName(info
.faceName
);
253 SetEncoding(info
.encoding
);
259 wxString wxFontBase
::GetNativeFontInfoDesc() const
262 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
265 fontDesc
= fontInfo
->ToString();
271 wxString wxFontBase
::GetNativeFontInfoUserDesc() const
274 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
277 fontDesc
= fontInfo
->ToUserString();
283 void wxFontBase
::SetNativeFontInfo(const wxString
& info
)
285 wxNativeFontInfo fontInfo
;
286 if ( !info
.empty() && fontInfo
.FromString(info
) )
288 SetNativeFontInfo(fontInfo
);
292 void wxFontBase
::SetNativeFontInfoUserDesc(const wxString
& info
)
294 wxNativeFontInfo fontInfo
;
295 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
297 SetNativeFontInfo(fontInfo
);
301 wxFont
& wxFont
::operator=(const wxFont
& font
)
306 return (wxFont
&)*this;
309 bool wxFontBase
::operator==(const wxFont
& font
) const
311 // either it is the same font, i.e. they share the same common data or they
312 // have different ref datas but still describe the same font
313 return GetFontData() == font
.GetFontData() ||
316 GetPointSize() == font
.GetPointSize() &&
317 GetFamily() == font
.GetFamily() &&
318 GetStyle() == font
.GetStyle() &&
319 GetWeight() == font
.GetWeight() &&
320 GetUnderlined() == font
.GetUnderlined() &&
321 GetFaceName() == font
.GetFaceName() &&
322 GetEncoding() == font
.GetEncoding()
326 bool wxFontBase
::operator!=(const wxFont
& font
) const
328 return !(*this == font
);
331 wxString wxFontBase
::GetFamilyString() const
333 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
335 switch ( GetFamily() )
337 case wxDECORATIVE
: return wxT("wxDECORATIVE");
338 case wxROMAN
: return wxT("wxROMAN");
339 case wxSCRIPT
: return wxT("wxSCRIPT");
340 case wxSWISS
: return wxT("wxSWISS");
341 case wxMODERN
: return wxT("wxMODERN");
342 case wxTELETYPE
: return wxT("wxTELETYPE");
343 default: return wxT("wxDEFAULT");
347 wxString wxFontBase
::GetStyleString() const
349 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
351 switch ( GetStyle() )
353 case wxNORMAL
: return wxT("wxNORMAL");
354 case wxSLANT
: return wxT("wxSLANT");
355 case wxITALIC
: return wxT("wxITALIC");
356 default: return wxT("wxDEFAULT");
360 wxString wxFontBase
::GetWeightString() const
362 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
364 switch ( GetWeight() )
366 case wxNORMAL
: return wxT("wxNORMAL");
367 case wxBOLD
: return wxT("wxBOLD");
368 case wxLIGHT
: return wxT("wxLIGHT");
369 default: return wxT("wxDEFAULT");
373 // ----------------------------------------------------------------------------
375 // ----------------------------------------------------------------------------
377 #ifdef wxNO_NATIVE_FONTINFO
379 // These are the generic forms of FromString()/ToString.
381 // convert to/from the string representation: format is
382 // version;pointsize;family;style;weight;underlined;facename;encoding
384 bool wxNativeFontInfo
::FromString(const wxString
& s
)
388 wxStringTokenizer
tokenizer(s
, _T(";"));
390 wxString token
= tokenizer
.GetNextToken();
392 // Ignore the version for now
395 token
= tokenizer
.GetNextToken();
396 if ( !token
.ToLong(&l
) )
400 token
= tokenizer
.GetNextToken();
401 if ( !token
.ToLong(&l
) )
403 family
= (wxFontFamily
)l
;
405 token
= tokenizer
.GetNextToken();
406 if ( !token
.ToLong(&l
) )
408 style
= (wxFontStyle
)l
;
410 token
= tokenizer
.GetNextToken();
411 if ( !token
.ToLong(&l
) )
413 weight
= (wxFontWeight
)l
;
415 token
= tokenizer
.GetNextToken();
416 if ( !token
.ToLong(&l
) )
420 faceName
= tokenizer
.GetNextToken();
427 token
= tokenizer
.GetNextToken();
428 if ( !token
.ToLong(&l
) )
430 encoding
= (wxFontEncoding
)l
;
435 wxString wxNativeFontInfo
::ToString() const
439 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
452 void wxNativeFontInfo
::Init()
455 family
= wxFONTFAMILY_DEFAULT
;
456 style
= wxFONTSTYLE_NORMAL
;
457 weight
= wxFONTWEIGHT_NORMAL
;
460 encoding
= wxFONTENCODING_DEFAULT
;
463 int wxNativeFontInfo
::GetPointSize() const
468 wxFontStyle wxNativeFontInfo
::GetStyle() const
473 wxFontWeight wxNativeFontInfo
::GetWeight() const
478 bool wxNativeFontInfo
::GetUnderlined() const
483 wxString wxNativeFontInfo
::GetFaceName() const
488 wxFontFamily wxNativeFontInfo
::GetFamily() const
493 wxFontEncoding wxNativeFontInfo
::GetEncoding() const
498 void wxNativeFontInfo
::SetPointSize(int pointsize
)
500 pointSize
= pointsize
;
503 void wxNativeFontInfo
::SetStyle(wxFontStyle style_
)
508 void wxNativeFontInfo
::SetWeight(wxFontWeight weight_
)
513 void wxNativeFontInfo
::SetUnderlined(bool underlined_
)
515 underlined
= underlined_
;
518 void wxNativeFontInfo
::SetFaceName(const wxString
& facename_
)
520 faceName
= facename_
;
523 void wxNativeFontInfo
::SetFamily(wxFontFamily family_
)
528 void wxNativeFontInfo
::SetEncoding(wxFontEncoding encoding_
)
530 encoding
= encoding_
;
533 #endif // generic wxNativeFontInfo implementation
535 // conversion to/from user-readable string: this is used in the generic
536 // versions and under MSW as well because there is no standard font description
537 // format there anyhow (but there is a well-defined standard for X11 fonts used
538 // by wxGTK and wxMotif)
540 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
542 wxString wxNativeFontInfo
::ToUserString() const
546 // first put the adjectives, if any - this is English-centric, of course,
547 // but what else can we do?
548 if ( GetUnderlined() )
550 desc
<< _("underlined ");
553 switch ( GetWeight() )
556 wxFAIL_MSG( _T("unknown font weight") );
559 case wxFONTWEIGHT_NORMAL
:
562 case wxFONTWEIGHT_LIGHT
:
566 case wxFONTWEIGHT_BOLD
:
571 switch ( GetStyle() )
574 wxFAIL_MSG( _T("unknown font style") );
577 case wxFONTSTYLE_NORMAL
:
580 // we don't distinguish between the two for now anyhow...
581 case wxFONTSTYLE_ITALIC
:
582 case wxFONTSTYLE_SLANT
:
587 wxString face
= GetFaceName();
590 desc
<< _T(' ') << face
;
593 int size
= GetPointSize();
594 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
596 desc
<< _T(' ') << size
;
600 wxFontEncoding enc
= GetEncoding();
601 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
603 desc
<< _T(' ') << wxFontMapper
::GetEncodingName(enc
);
605 #endif // wxUSE_FONTMAP
610 bool wxNativeFontInfo
::FromUserString(const wxString
& s
)
612 // reset to the default state
615 // parse a more or less free form string
617 // TODO: we should handle at least the quoted facenames
618 wxStringTokenizer
tokenizer(s
, _T(";, "), wxTOKEN_STRTOK
);
624 wxFontEncoding encoding
;
625 #endif // wxUSE_FONTMAP
627 while ( tokenizer
.HasMoreTokens() )
629 wxString token
= tokenizer
.GetNextToken();
632 token
.Trim(true).Trim(false).MakeLower();
634 // look for the known tokens
635 if ( token
== _T("underlined") || token
== _("underlined") )
639 else if ( token
== _T("light") || token
== _("light") )
641 SetWeight(wxFONTWEIGHT_LIGHT
);
643 else if ( token
== _T("bold") || token
== _("bold") )
645 SetWeight(wxFONTWEIGHT_BOLD
);
647 else if ( token
== _T("italic") || token
== _("italic") )
649 SetStyle(wxFONTSTYLE_ITALIC
);
651 else if ( token
.ToULong(&size
) )
656 else if ( (encoding
= wxFontMapper
::Get()->CharsetToEncoding(token
, false))
657 != wxFONTENCODING_DEFAULT
)
659 SetEncoding(encoding
);
661 #endif // wxUSE_FONTMAP
662 else // assume it is the face name
671 // skip the code which resets face below
675 // if we had had the facename, we shouldn't continue appending tokens
676 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
685 // we might not have flushed it inside the loop
694 #endif // generic or wxMSW or wxOS2