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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "fontbase.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
35 #include "wx/dcscreen.h"
38 #include "wx/gdicmn.h"
40 #if defined(__WXMSW__)
41 #include "wx/msw/private.h" // includes windows.h for LOGFONT
42 #include "wx/msw/winundef.h"
45 #include "wx/fontutil.h" // for wxNativeFontInfo
46 #include "wx/fontmap.h"
48 #include "wx/tokenzr.h"
50 // ============================================================================
52 // ============================================================================
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 static void AdjustFontSize(wxFont
& font
, wxDC
& dc
, const wxSize
& pixelSize
)
60 int currentSize
= font
.GetPointSize();
64 bool initialGoodFound
= false;
65 bool initialBadFound
= false;
67 while (currentSize
> 0)
71 // if currentSize (in points) results in a font that is smaller
72 // than required by pixelSize it is considered a good size
73 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
74 (!pixelSize
.GetWidth() ||
75 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
77 largestGood
= currentSize
;
78 initialGoodFound
= true;
82 smallestBad
= currentSize
;
83 initialBadFound
= true;
85 if (!initialGoodFound
)
89 else if (!initialBadFound
)
95 int distance
= smallestBad
- largestGood
;
99 currentSize
= largestGood
+ distance
/ 2;
102 font
.SetPointSize(currentSize
);
105 if (currentSize
!= largestGood
)
106 font
.SetPointSize(largestGood
);
109 // ----------------------------------------------------------------------------
111 // ----------------------------------------------------------------------------
113 wxFontEncoding
wxFontBase::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
116 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding
)
118 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
119 // and, besides, using this value here doesn't make any sense
120 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
121 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
123 ms_encodingDefault
= encoding
;
126 wxFontBase::~wxFontBase()
128 // this destructor is required for Darwin
132 wxFont
*wxFontBase::New(int size
,
137 const wxString
& face
,
138 wxFontEncoding encoding
)
140 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
143 static inline int flags2Style(int flags
)
145 return flags
& wxFONTFLAG_ITALIC
147 : flags
& wxFONTFLAG_SLANT
149 : wxFONTSTYLE_NORMAL
;
152 static inline int flags2Weight(int flags
)
154 return flags
& wxFONTFLAG_LIGHT
156 : flags
& wxFONTFLAG_BOLD
158 : wxFONTWEIGHT_NORMAL
;
161 static inline bool flags2Underlined(int flags
)
163 return (flags
& wxFONTFLAG_UNDERLINED
) != 0;
167 wxFont
*wxFontBase::New(int pointSize
,
170 const wxString
& face
,
171 wxFontEncoding encoding
)
173 return New(pointSize
, family
, flags2Style(flags
), flags2Weight(flags
),
174 flags2Underlined(flags
), face
, encoding
);
178 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
183 const wxString
& face
,
184 wxFontEncoding encoding
)
186 #if defined(__WXMSW__)
187 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
190 wxFont
*self
= New(10, family
, style
, weight
, underlined
, face
, encoding
);
192 AdjustFontSize(*(wxFont
*)self
, dc
, pixelSize
);
198 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
201 const wxString
& face
,
202 wxFontEncoding encoding
)
204 return New(pixelSize
, family
, flags2Style(flags
), flags2Weight(flags
),
205 flags2Underlined(flags
), face
, encoding
);
208 wxSize
wxFontBase::GetPixelSize() const
211 dc
.SetFont(*(wxFont
*)this);
212 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
215 bool wxFontBase::IsUsingSizeInPixels() const
220 void wxFontBase::SetPixelSize( const wxSize
& pixelSize
)
223 AdjustFontSize(*(wxFont
*)this, dc
, pixelSize
);
227 wxFont
*wxFontBase::New(const wxNativeFontInfo
& info
)
229 return new wxFont(info
);
233 wxFont
*wxFontBase::New(const wxString
& strNativeFontDesc
)
235 wxNativeFontInfo fontInfo
;
236 if ( !fontInfo
.FromString(strNativeFontDesc
) )
237 return new wxFont(*wxNORMAL_FONT
);
239 return New(fontInfo
);
242 bool wxFontBase::IsFixedWidth() const
244 return GetFamily() == wxFONTFAMILY_TELETYPE
;
247 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
249 #ifdef wxNO_NATIVE_FONTINFO
250 SetPointSize(info
.pointSize
);
251 SetFamily(info
.family
);
252 SetStyle(info
.style
);
253 SetWeight(info
.weight
);
254 SetUnderlined(info
.underlined
);
255 SetFaceName(info
.faceName
);
256 SetEncoding(info
.encoding
);
262 wxString
wxFontBase::GetNativeFontInfoDesc() const
265 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
268 fontDesc
= fontInfo
->ToString();
274 wxString
wxFontBase::GetNativeFontInfoUserDesc() const
277 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
280 fontDesc
= fontInfo
->ToUserString();
286 void wxFontBase::SetNativeFontInfo(const wxString
& info
)
288 wxNativeFontInfo fontInfo
;
289 if ( !info
.empty() && fontInfo
.FromString(info
) )
291 SetNativeFontInfo(fontInfo
);
295 void wxFontBase::SetNativeFontInfoUserDesc(const wxString
& info
)
297 wxNativeFontInfo fontInfo
;
298 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
300 SetNativeFontInfo(fontInfo
);
304 wxFont
& wxFont::operator=(const wxFont
& font
)
309 return (wxFont
&)*this;
312 bool wxFontBase::operator==(const wxFont
& font
) const
314 // either it is the same font, i.e. they share the same common data or they
315 // have different ref datas but still describe the same font
316 return GetFontData() == font
.GetFontData() ||
319 GetPointSize() == font
.GetPointSize() &&
320 GetFamily() == font
.GetFamily() &&
321 GetStyle() == font
.GetStyle() &&
322 GetWeight() == font
.GetWeight() &&
323 GetUnderlined() == font
.GetUnderlined() &&
324 GetFaceName() == font
.GetFaceName() &&
325 GetEncoding() == font
.GetEncoding()
329 bool wxFontBase::operator!=(const wxFont
& font
) const
331 return !(*this == font
);
334 wxString
wxFontBase::GetFamilyString() const
336 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
338 switch ( GetFamily() )
340 case wxDECORATIVE
: return wxT("wxDECORATIVE");
341 case wxROMAN
: return wxT("wxROMAN");
342 case wxSCRIPT
: return wxT("wxSCRIPT");
343 case wxSWISS
: return wxT("wxSWISS");
344 case wxMODERN
: return wxT("wxMODERN");
345 case wxTELETYPE
: return wxT("wxTELETYPE");
346 default: return wxT("wxDEFAULT");
350 wxString
wxFontBase::GetStyleString() const
352 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
354 switch ( GetStyle() )
356 case wxNORMAL
: return wxT("wxNORMAL");
357 case wxSLANT
: return wxT("wxSLANT");
358 case wxITALIC
: return wxT("wxITALIC");
359 default: return wxT("wxDEFAULT");
363 wxString
wxFontBase::GetWeightString() const
365 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
367 switch ( GetWeight() )
369 case wxNORMAL
: return wxT("wxNORMAL");
370 case wxBOLD
: return wxT("wxBOLD");
371 case wxLIGHT
: return wxT("wxLIGHT");
372 default: return wxT("wxDEFAULT");
376 // ----------------------------------------------------------------------------
378 // ----------------------------------------------------------------------------
380 #ifdef wxNO_NATIVE_FONTINFO
382 // These are the generic forms of FromString()/ToString.
384 // convert to/from the string representation: format is
385 // version;pointsize;family;style;weight;underlined;facename;encoding
387 bool wxNativeFontInfo::FromString(const wxString
& s
)
391 wxStringTokenizer
tokenizer(s
, _T(";"));
393 wxString token
= tokenizer
.GetNextToken();
395 // Ignore the version for now
398 token
= tokenizer
.GetNextToken();
399 if ( !token
.ToLong(&l
) )
403 token
= tokenizer
.GetNextToken();
404 if ( !token
.ToLong(&l
) )
406 family
= (wxFontFamily
)l
;
408 token
= tokenizer
.GetNextToken();
409 if ( !token
.ToLong(&l
) )
411 style
= (wxFontStyle
)l
;
413 token
= tokenizer
.GetNextToken();
414 if ( !token
.ToLong(&l
) )
416 weight
= (wxFontWeight
)l
;
418 token
= tokenizer
.GetNextToken();
419 if ( !token
.ToLong(&l
) )
423 faceName
= tokenizer
.GetNextToken();
430 token
= tokenizer
.GetNextToken();
431 if ( !token
.ToLong(&l
) )
433 encoding
= (wxFontEncoding
)l
;
438 wxString
wxNativeFontInfo::ToString() const
442 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
455 void wxNativeFontInfo::Init()
458 family
= wxFONTFAMILY_DEFAULT
;
459 style
= wxFONTSTYLE_NORMAL
;
460 weight
= wxFONTWEIGHT_NORMAL
;
463 encoding
= wxFONTENCODING_DEFAULT
;
466 int wxNativeFontInfo::GetPointSize() const
471 wxFontStyle
wxNativeFontInfo::GetStyle() const
476 wxFontWeight
wxNativeFontInfo::GetWeight() const
481 bool wxNativeFontInfo::GetUnderlined() const
486 wxString
wxNativeFontInfo::GetFaceName() const
491 wxFontFamily
wxNativeFontInfo::GetFamily() const
496 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
501 void wxNativeFontInfo::SetPointSize(int pointsize
)
503 pointSize
= pointsize
;
506 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
511 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
516 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
518 underlined
= underlined_
;
521 void wxNativeFontInfo::SetFaceName(wxString facename_
)
523 faceName
= facename_
;
526 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
531 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
533 encoding
= encoding_
;
536 #endif // generic wxNativeFontInfo implementation
538 // conversion to/from user-readable string: this is used in the generic
539 // versions and under MSW as well because there is no standard font description
540 // format there anyhow (but there is a well-defined standard for X11 fonts used
541 // by wxGTK and wxMotif)
543 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
545 wxString
wxNativeFontInfo::ToUserString() const
549 // first put the adjectives, if any - this is English-centric, of course,
550 // but what else can we do?
551 if ( GetUnderlined() )
553 desc
<< _("underlined ");
556 switch ( GetWeight() )
559 wxFAIL_MSG( _T("unknown font weight") );
562 case wxFONTWEIGHT_NORMAL
:
565 case wxFONTWEIGHT_LIGHT
:
569 case wxFONTWEIGHT_BOLD
:
574 switch ( GetStyle() )
577 wxFAIL_MSG( _T("unknown font style") );
580 case wxFONTSTYLE_NORMAL
:
583 // we don't distinguish between the two for now anyhow...
584 case wxFONTSTYLE_ITALIC
:
585 case wxFONTSTYLE_SLANT
:
590 wxString face
= GetFaceName();
593 desc
<< _T(' ') << face
;
596 int size
= GetPointSize();
597 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
599 desc
<< _T(' ') << size
;
603 wxFontEncoding enc
= GetEncoding();
604 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
606 desc
<< _T(' ') << wxFontMapper::GetEncodingName(enc
);
608 #endif // wxUSE_FONTMAP
613 bool wxNativeFontInfo::FromUserString(const wxString
& s
)
615 // reset to the default state
618 // parse a more or less free form string
620 // TODO: we should handle at least the quoted facenames
621 wxStringTokenizer
tokenizer(s
, _T(";, "), wxTOKEN_STRTOK
);
627 wxFontEncoding encoding
;
628 #endif // wxUSE_FONTMAP
630 while ( tokenizer
.HasMoreTokens() )
632 wxString token
= tokenizer
.GetNextToken();
635 token
.Trim(true).Trim(false).MakeLower();
637 // look for the known tokens
638 if ( token
== _T("underlined") || token
== _("underlined") )
642 else if ( token
== _T("light") || token
== _("light") )
644 SetWeight(wxFONTWEIGHT_LIGHT
);
646 else if ( token
== _T("bold") || token
== _("bold") )
648 SetWeight(wxFONTWEIGHT_BOLD
);
650 else if ( token
== _T("italic") || token
== _("italic") )
652 SetStyle(wxFONTSTYLE_ITALIC
);
654 else if ( token
.ToULong(&size
) )
659 else if ( (encoding
= wxFontMapper::Get()->CharsetToEncoding(token
, false))
660 != wxFONTENCODING_DEFAULT
)
662 SetEncoding(encoding
);
664 #endif // wxUSE_FONTMAP
665 else // assume it is the face name
674 // skip the code which resets face below
678 // if we had had the facename, we shouldn't continue appending tokens
679 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
688 // we might not have flushed it inside the loop
697 #endif // generic or wxMSW or wxOS2