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
)
56 int currentSize
= font
.GetPointSize();
60 bool initialGoodFound
= false;
61 bool initialBadFound
= false;
63 while (currentSize
> 0)
67 // if currentSize (in points) results in a font that is smaller
68 // than required by pixelSize it is considered a good size
69 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
70 (!pixelSize
.GetWidth() ||
71 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
73 largestGood
= currentSize
;
74 initialGoodFound
= true;
78 smallestBad
= currentSize
;
79 initialBadFound
= true;
81 if (!initialGoodFound
)
85 else if (!initialBadFound
)
91 int distance
= smallestBad
- largestGood
;
95 currentSize
= largestGood
+ distance
/ 2;
98 font
.SetPointSize(currentSize
);
101 if (currentSize
!= largestGood
)
102 font
.SetPointSize(largestGood
);
105 // ----------------------------------------------------------------------------
107 // ----------------------------------------------------------------------------
109 wxFontEncoding
wxFontBase::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
112 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding
)
114 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
115 // and, besides, using this value here doesn't make any sense
116 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
117 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
119 ms_encodingDefault
= encoding
;
122 wxFontBase::~wxFontBase()
124 // this destructor is required for Darwin
128 wxFont
*wxFontBase::New(int size
,
133 const wxString
& face
,
134 wxFontEncoding encoding
)
136 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
139 static inline int flags2Style(int flags
)
141 return flags
& wxFONTFLAG_ITALIC
143 : flags
& wxFONTFLAG_SLANT
145 : wxFONTSTYLE_NORMAL
;
148 static inline int flags2Weight(int flags
)
150 return flags
& wxFONTFLAG_LIGHT
152 : flags
& wxFONTFLAG_BOLD
154 : wxFONTWEIGHT_NORMAL
;
157 static inline bool flags2Underlined(int flags
)
159 return (flags
& wxFONTFLAG_UNDERLINED
) != 0;
163 wxFont
*wxFontBase::New(int pointSize
,
166 const wxString
& face
,
167 wxFontEncoding encoding
)
169 return New(pointSize
, family
, flags2Style(flags
), flags2Weight(flags
),
170 flags2Underlined(flags
), face
, encoding
);
174 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
179 const wxString
& face
,
180 wxFontEncoding encoding
)
182 #if defined(__WXMSW__)
183 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
186 wxFont
*self
= New(10, family
, style
, weight
, underlined
, face
, encoding
);
188 AdjustFontSize(*(wxFont
*)self
, dc
, pixelSize
);
194 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
197 const wxString
& face
,
198 wxFontEncoding encoding
)
200 return New(pixelSize
, family
, flags2Style(flags
), flags2Weight(flags
),
201 flags2Underlined(flags
), face
, encoding
);
204 wxSize
wxFontBase::GetPixelSize() const
207 dc
.SetFont(*(wxFont
*)this);
208 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
211 bool wxFontBase::IsUsingSizeInPixels() const
216 void wxFontBase::SetPixelSize( const wxSize
& pixelSize
)
219 AdjustFontSize(*(wxFont
*)this, dc
, pixelSize
);
223 wxFont
*wxFontBase::New(const wxNativeFontInfo
& info
)
225 return new wxFont(info
);
229 wxFont
*wxFontBase::New(const wxString
& strNativeFontDesc
)
231 wxNativeFontInfo fontInfo
;
232 if ( !fontInfo
.FromString(strNativeFontDesc
) )
233 return new wxFont(*wxNORMAL_FONT
);
235 return New(fontInfo
);
238 bool wxFontBase::IsFixedWidth() const
240 return GetFamily() == wxFONTFAMILY_TELETYPE
;
243 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
245 #ifdef wxNO_NATIVE_FONTINFO
246 SetPointSize(info
.pointSize
);
247 SetFamily(info
.family
);
248 SetStyle(info
.style
);
249 SetWeight(info
.weight
);
250 SetUnderlined(info
.underlined
);
251 SetFaceName(info
.faceName
);
252 SetEncoding(info
.encoding
);
258 wxString
wxFontBase::GetNativeFontInfoDesc() const
261 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
264 fontDesc
= fontInfo
->ToString();
270 wxString
wxFontBase::GetNativeFontInfoUserDesc() const
273 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
276 fontDesc
= fontInfo
->ToUserString();
282 void wxFontBase::SetNativeFontInfo(const wxString
& info
)
284 wxNativeFontInfo fontInfo
;
285 if ( !info
.empty() && fontInfo
.FromString(info
) )
287 SetNativeFontInfo(fontInfo
);
291 void wxFontBase::SetNativeFontInfoUserDesc(const wxString
& info
)
293 wxNativeFontInfo fontInfo
;
294 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
296 SetNativeFontInfo(fontInfo
);
300 wxFont
& wxFont::operator=(const wxFont
& font
)
305 return (wxFont
&)*this;
308 bool wxFontBase::operator==(const wxFont
& font
) const
310 // either it is the same font, i.e. they share the same common data or they
311 // have different ref datas but still describe the same font
312 return GetFontData() == font
.GetFontData() ||
315 GetPointSize() == font
.GetPointSize() &&
316 GetFamily() == font
.GetFamily() &&
317 GetStyle() == font
.GetStyle() &&
318 GetWeight() == font
.GetWeight() &&
319 GetUnderlined() == font
.GetUnderlined() &&
320 GetFaceName() == font
.GetFaceName() &&
321 GetEncoding() == font
.GetEncoding()
325 bool wxFontBase::operator!=(const wxFont
& font
) const
327 return !(*this == font
);
330 wxString
wxFontBase::GetFamilyString() const
332 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
334 switch ( GetFamily() )
336 case wxDECORATIVE
: return wxT("wxDECORATIVE");
337 case wxROMAN
: return wxT("wxROMAN");
338 case wxSCRIPT
: return wxT("wxSCRIPT");
339 case wxSWISS
: return wxT("wxSWISS");
340 case wxMODERN
: return wxT("wxMODERN");
341 case wxTELETYPE
: return wxT("wxTELETYPE");
342 default: return wxT("wxDEFAULT");
346 wxString
wxFontBase::GetStyleString() const
348 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
350 switch ( GetStyle() )
352 case wxNORMAL
: return wxT("wxNORMAL");
353 case wxSLANT
: return wxT("wxSLANT");
354 case wxITALIC
: return wxT("wxITALIC");
355 default: return wxT("wxDEFAULT");
359 wxString
wxFontBase::GetWeightString() const
361 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
363 switch ( GetWeight() )
365 case wxNORMAL
: return wxT("wxNORMAL");
366 case wxBOLD
: return wxT("wxBOLD");
367 case wxLIGHT
: return wxT("wxLIGHT");
368 default: return wxT("wxDEFAULT");
372 // ----------------------------------------------------------------------------
374 // ----------------------------------------------------------------------------
376 #ifdef wxNO_NATIVE_FONTINFO
378 // These are the generic forms of FromString()/ToString.
380 // convert to/from the string representation: format is
381 // version;pointsize;family;style;weight;underlined;facename;encoding
383 bool wxNativeFontInfo::FromString(const wxString
& s
)
387 wxStringTokenizer
tokenizer(s
, _T(";"));
389 wxString token
= tokenizer
.GetNextToken();
391 // Ignore the version for now
394 token
= tokenizer
.GetNextToken();
395 if ( !token
.ToLong(&l
) )
399 token
= tokenizer
.GetNextToken();
400 if ( !token
.ToLong(&l
) )
402 family
= (wxFontFamily
)l
;
404 token
= tokenizer
.GetNextToken();
405 if ( !token
.ToLong(&l
) )
407 style
= (wxFontStyle
)l
;
409 token
= tokenizer
.GetNextToken();
410 if ( !token
.ToLong(&l
) )
412 weight
= (wxFontWeight
)l
;
414 token
= tokenizer
.GetNextToken();
415 if ( !token
.ToLong(&l
) )
419 faceName
= tokenizer
.GetNextToken();
426 token
= tokenizer
.GetNextToken();
427 if ( !token
.ToLong(&l
) )
429 encoding
= (wxFontEncoding
)l
;
434 wxString
wxNativeFontInfo::ToString() const
438 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
451 void wxNativeFontInfo::Init()
454 family
= wxFONTFAMILY_DEFAULT
;
455 style
= wxFONTSTYLE_NORMAL
;
456 weight
= wxFONTWEIGHT_NORMAL
;
459 encoding
= wxFONTENCODING_DEFAULT
;
462 int wxNativeFontInfo::GetPointSize() const
467 wxFontStyle
wxNativeFontInfo::GetStyle() const
472 wxFontWeight
wxNativeFontInfo::GetWeight() const
477 bool wxNativeFontInfo::GetUnderlined() const
482 wxString
wxNativeFontInfo::GetFaceName() const
487 wxFontFamily
wxNativeFontInfo::GetFamily() const
492 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
497 void wxNativeFontInfo::SetPointSize(int pointsize
)
499 pointSize
= pointsize
;
502 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
507 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
512 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
514 underlined
= underlined_
;
517 void wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
519 faceName
= facename_
;
522 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
527 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
529 encoding
= encoding_
;
532 #endif // generic wxNativeFontInfo implementation
534 // conversion to/from user-readable string: this is used in the generic
535 // versions and under MSW as well because there is no standard font description
536 // format there anyhow (but there is a well-defined standard for X11 fonts used
537 // by wxGTK and wxMotif)
539 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
541 wxString
wxNativeFontInfo::ToUserString() const
545 // first put the adjectives, if any - this is English-centric, of course,
546 // but what else can we do?
547 if ( GetUnderlined() )
549 desc
<< _("underlined ");
552 switch ( GetWeight() )
555 wxFAIL_MSG( _T("unknown font weight") );
558 case wxFONTWEIGHT_NORMAL
:
561 case wxFONTWEIGHT_LIGHT
:
565 case wxFONTWEIGHT_BOLD
:
570 switch ( GetStyle() )
573 wxFAIL_MSG( _T("unknown font style") );
576 case wxFONTSTYLE_NORMAL
:
579 // we don't distinguish between the two for now anyhow...
580 case wxFONTSTYLE_ITALIC
:
581 case wxFONTSTYLE_SLANT
:
586 wxString face
= GetFaceName();
589 desc
<< _T(' ') << face
;
592 int size
= GetPointSize();
593 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
595 desc
<< _T(' ') << size
;
599 wxFontEncoding enc
= GetEncoding();
600 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
602 desc
<< _T(' ') << wxFontMapper::GetEncodingName(enc
);
604 #endif // wxUSE_FONTMAP
609 bool wxNativeFontInfo::FromUserString(const wxString
& s
)
611 // reset to the default state
614 // parse a more or less free form string
616 // TODO: we should handle at least the quoted facenames
617 wxStringTokenizer
tokenizer(s
, _T(";, "), wxTOKEN_STRTOK
);
623 wxFontEncoding encoding
;
624 #endif // wxUSE_FONTMAP
626 while ( tokenizer
.HasMoreTokens() )
628 wxString token
= tokenizer
.GetNextToken();
631 token
.Trim(true).Trim(false).MakeLower();
633 // look for the known tokens
634 if ( token
== _T("underlined") || token
== _("underlined") )
638 else if ( token
== _T("light") || token
== _("light") )
640 SetWeight(wxFONTWEIGHT_LIGHT
);
642 else if ( token
== _T("bold") || token
== _("bold") )
644 SetWeight(wxFONTWEIGHT_BOLD
);
646 else if ( token
== _T("italic") || token
== _("italic") )
648 SetStyle(wxFONTSTYLE_ITALIC
);
650 else if ( token
.ToULong(&size
) )
655 else if ( (encoding
= wxFontMapper::Get()->CharsetToEncoding(token
, false))
656 != wxFONTENCODING_DEFAULT
)
658 SetEncoding(encoding
);
660 #endif // wxUSE_FONTMAP
661 else // assume it is the face name
670 // skip the code which resets face below
674 // if we had had the facename, we shouldn't continue appending tokens
675 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
684 // we might not have flushed it inside the loop
693 #endif // generic or wxMSW or wxOS2