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"
36 #include "wx/gdicmn.h"
38 #if defined(__WXMSW__)
39 #include "wx/msw/private.h" // includes windows.h for LOGFONT
40 #include "wx/msw/winundef.h"
43 #include "wx/fontutil.h" // for wxNativeFontInfo
44 #include "wx/fontmap.h"
46 #include "wx/tokenzr.h"
48 // ============================================================================
50 // ============================================================================
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 static void AdjustFontSize(wxFont font
, wxDC
& dc
, const wxSize
& pixelSize
)
58 int currentSize
= font
.GetPointSize();
62 bool initialGoodFound
= false;
63 bool initialBadFound
= false;
65 while (currentSize
> 0)
69 // if currentSize (in points) results in a font that is smaller
70 // than required by pixelSize it is considered a good size
71 if (dc
.GetCharHeight() <= pixelSize
.GetHeight() &&
72 (!pixelSize
.GetWidth() ||
73 dc
.GetCharWidth() <= pixelSize
.GetWidth()))
75 largestGood
= currentSize
;
76 initialGoodFound
= true;
80 smallestBad
= currentSize
;
81 initialBadFound
= true;
83 if (!initialGoodFound
)
87 else if (!initialBadFound
)
93 int distance
= smallestBad
- largestGood
;
97 currentSize
= largestGood
+ distance
/ 2;
100 font
.SetPointSize(currentSize
);
103 if (currentSize
!= largestGood
)
104 font
.SetPointSize(largestGood
);
107 // ----------------------------------------------------------------------------
109 // ----------------------------------------------------------------------------
111 wxFontEncoding
wxFontBase::ms_encodingDefault
= wxFONTENCODING_SYSTEM
;
114 void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding
)
116 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
117 // and, besides, using this value here doesn't make any sense
118 wxCHECK_RET( encoding
!= wxFONTENCODING_DEFAULT
,
119 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
121 ms_encodingDefault
= encoding
;
124 wxFontBase::~wxFontBase()
126 // this destructor is required for Darwin
130 wxFont
*wxFontBase::New(int size
,
135 const wxString
& face
,
136 wxFontEncoding encoding
)
138 return new wxFont(size
, family
, style
, weight
, underlined
, face
, encoding
);
141 static inline int flags2Style(int flags
)
143 return flags
& wxFONTFLAG_ITALIC
145 : flags
& wxFONTFLAG_SLANT
147 : wxFONTSTYLE_NORMAL
;
150 static inline int flags2Weight(int flags
)
152 return flags
& wxFONTFLAG_LIGHT
154 : flags
& wxFONTFLAG_BOLD
156 : wxFONTWEIGHT_NORMAL
;
159 static inline bool flags2Underlined(int flags
)
161 return (flags
& wxFONTFLAG_UNDERLINED
) != 0;
165 wxFont
*wxFontBase::New(int pointSize
,
168 const wxString
& face
,
169 wxFontEncoding encoding
)
171 return New(pointSize
, family
, flags2Style(flags
), flags2Weight(flags
),
172 flags2Underlined(flags
), face
, encoding
);
176 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
181 const wxString
& face
,
182 wxFontEncoding encoding
)
184 #if defined(__WXMSW__)
185 return new wxFont(pixelSize
, family
, style
, weight
, underlined
,
188 wxFont
* ret
= New(10, family
, style
, weight
, underlined
, face
, encoding
);
190 ret
->AdjustFontSize(*(wxFont
*)this, dc
, pixelSize
);
196 wxFont
*wxFontBase::New(const wxSize
& pixelSize
,
199 const wxString
& face
,
200 wxFontEncoding encoding
)
202 return New(pixelSize
, family
, flags2Style(flags
), flags2Weight(flags
),
203 flags2Underlined(flags
), face
, encoding
);
206 wxSize
wxFontBase::GetPixelSize() const
209 dc
.SetFont(*(wxFont
*)this);
210 return wxSize(dc
.GetCharWidth(), dc
.GetCharHeight());
213 bool wxFontBase::IsUsingSizeInPixels() const
218 void wxFontBase::SetPixelSize( const wxSize
& pixelSize
)
221 AdjustFontSize(*(wxFont
*)this, dc
, pixelSize
);
225 wxFont
*wxFontBase::New(const wxNativeFontInfo
& info
)
227 return new wxFont(info
);
231 wxFont
*wxFontBase::New(const wxString
& strNativeFontDesc
)
233 wxNativeFontInfo fontInfo
;
234 if ( !fontInfo
.FromString(strNativeFontDesc
) )
235 return new wxFont(*wxNORMAL_FONT
);
237 return New(fontInfo
);
240 bool wxFontBase::IsFixedWidth() const
242 return GetFamily() == wxFONTFAMILY_TELETYPE
;
245 void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
247 #ifdef wxNO_NATIVE_FONTINFO
248 SetPointSize(info
.pointSize
);
249 SetFamily(info
.family
);
250 SetStyle(info
.style
);
251 SetWeight(info
.weight
);
252 SetUnderlined(info
.underlined
);
253 SetFaceName(info
.faceName
);
254 SetEncoding(info
.encoding
);
260 wxString
wxFontBase::GetNativeFontInfoDesc() const
263 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
266 fontDesc
= fontInfo
->ToString();
272 wxString
wxFontBase::GetNativeFontInfoUserDesc() const
275 const wxNativeFontInfo
*fontInfo
= GetNativeFontInfo();
278 fontDesc
= fontInfo
->ToUserString();
284 void wxFontBase::SetNativeFontInfo(const wxString
& info
)
286 wxNativeFontInfo fontInfo
;
287 if ( !info
.empty() && fontInfo
.FromString(info
) )
289 SetNativeFontInfo(fontInfo
);
293 void wxFontBase::SetNativeFontInfoUserDesc(const wxString
& info
)
295 wxNativeFontInfo fontInfo
;
296 if ( !info
.empty() && fontInfo
.FromUserString(info
) )
298 SetNativeFontInfo(fontInfo
);
302 wxFont
& wxFont::operator=(const wxFont
& font
)
307 return (wxFont
&)*this;
310 bool wxFontBase::operator==(const wxFont
& font
) const
312 // either it is the same font, i.e. they share the same common data or they
313 // have different ref datas but still describe the same font
314 return GetFontData() == font
.GetFontData() ||
317 GetPointSize() == font
.GetPointSize() &&
318 GetFamily() == font
.GetFamily() &&
319 GetStyle() == font
.GetStyle() &&
320 GetWeight() == font
.GetWeight() &&
321 GetUnderlined() == font
.GetUnderlined() &&
322 GetFaceName() == font
.GetFaceName() &&
323 GetEncoding() == font
.GetEncoding()
327 bool wxFontBase::operator!=(const wxFont
& font
) const
329 return !(*this == font
);
332 wxString
wxFontBase::GetFamilyString() const
334 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
336 switch ( GetFamily() )
338 case wxDECORATIVE
: return wxT("wxDECORATIVE");
339 case wxROMAN
: return wxT("wxROMAN");
340 case wxSCRIPT
: return wxT("wxSCRIPT");
341 case wxSWISS
: return wxT("wxSWISS");
342 case wxMODERN
: return wxT("wxMODERN");
343 case wxTELETYPE
: return wxT("wxTELETYPE");
344 default: return wxT("wxDEFAULT");
348 wxString
wxFontBase::GetStyleString() const
350 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
352 switch ( GetStyle() )
354 case wxNORMAL
: return wxT("wxNORMAL");
355 case wxSLANT
: return wxT("wxSLANT");
356 case wxITALIC
: return wxT("wxITALIC");
357 default: return wxT("wxDEFAULT");
361 wxString
wxFontBase::GetWeightString() const
363 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
365 switch ( GetWeight() )
367 case wxNORMAL
: return wxT("wxNORMAL");
368 case wxBOLD
: return wxT("wxBOLD");
369 case wxLIGHT
: return wxT("wxLIGHT");
370 default: return wxT("wxDEFAULT");
374 // ----------------------------------------------------------------------------
376 // ----------------------------------------------------------------------------
378 #ifdef wxNO_NATIVE_FONTINFO
380 // These are the generic forms of FromString()/ToString.
382 // convert to/from the string representation: format is
383 // version;pointsize;family;style;weight;underlined;facename;encoding
385 bool wxNativeFontInfo::FromString(const wxString
& s
)
389 wxStringTokenizer
tokenizer(s
, _T(";"));
391 wxString token
= tokenizer
.GetNextToken();
393 // Ignore the version for now
396 token
= tokenizer
.GetNextToken();
397 if ( !token
.ToLong(&l
) )
401 token
= tokenizer
.GetNextToken();
402 if ( !token
.ToLong(&l
) )
404 family
= (wxFontFamily
)l
;
406 token
= tokenizer
.GetNextToken();
407 if ( !token
.ToLong(&l
) )
409 style
= (wxFontStyle
)l
;
411 token
= tokenizer
.GetNextToken();
412 if ( !token
.ToLong(&l
) )
414 weight
= (wxFontWeight
)l
;
416 token
= tokenizer
.GetNextToken();
417 if ( !token
.ToLong(&l
) )
421 faceName
= tokenizer
.GetNextToken();
428 token
= tokenizer
.GetNextToken();
429 if ( !token
.ToLong(&l
) )
431 encoding
= (wxFontEncoding
)l
;
436 wxString
wxNativeFontInfo::ToString() const
440 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
453 void wxNativeFontInfo::Init()
456 family
= wxFONTFAMILY_DEFAULT
;
457 style
= wxFONTSTYLE_NORMAL
;
458 weight
= wxFONTWEIGHT_NORMAL
;
461 encoding
= wxFONTENCODING_DEFAULT
;
464 int wxNativeFontInfo::GetPointSize() const
469 wxFontStyle
wxNativeFontInfo::GetStyle() const
474 wxFontWeight
wxNativeFontInfo::GetWeight() const
479 bool wxNativeFontInfo::GetUnderlined() const
484 wxString
wxNativeFontInfo::GetFaceName() const
489 wxFontFamily
wxNativeFontInfo::GetFamily() const
494 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
499 void wxNativeFontInfo::SetPointSize(int pointsize
)
501 pointSize
= pointsize
;
504 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
509 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
514 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
516 underlined
= underlined_
;
519 void wxNativeFontInfo::SetFaceName(wxString facename_
)
521 faceName
= facename_
;
524 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
529 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
531 encoding
= encoding_
;
534 #endif // generic wxNativeFontInfo implementation
536 // conversion to/from user-readable string: this is used in the generic
537 // versions and under MSW as well because there is no standard font description
538 // format there anyhow (but there is a well-defined standard for X11 fonts used
539 // by wxGTK and wxMotif)
541 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
543 wxString
wxNativeFontInfo::ToUserString() const
547 // first put the adjectives, if any - this is English-centric, of course,
548 // but what else can we do?
549 if ( GetUnderlined() )
551 desc
<< _("underlined ");
554 switch ( GetWeight() )
557 wxFAIL_MSG( _T("unknown font weight") );
560 case wxFONTWEIGHT_NORMAL
:
563 case wxFONTWEIGHT_LIGHT
:
567 case wxFONTWEIGHT_BOLD
:
572 switch ( GetStyle() )
575 wxFAIL_MSG( _T("unknown font style") );
578 case wxFONTSTYLE_NORMAL
:
581 // we don't distinguish between the two for now anyhow...
582 case wxFONTSTYLE_ITALIC
:
583 case wxFONTSTYLE_SLANT
:
588 wxString face
= GetFaceName();
591 desc
<< _T(' ') << face
;
594 int size
= GetPointSize();
595 if ( size
!= wxNORMAL_FONT
->GetPointSize() )
597 desc
<< _T(' ') << size
;
601 wxFontEncoding enc
= GetEncoding();
602 if ( enc
!= wxFONTENCODING_DEFAULT
&& enc
!= wxFONTENCODING_SYSTEM
)
604 desc
<< _T(' ') << wxFontMapper::Get()->GetEncodingName(enc
);
606 #endif // wxUSE_FONTMAP
611 bool wxNativeFontInfo::FromUserString(const wxString
& s
)
613 // reset to the default state
616 // parse a more or less free form string
618 // TODO: we should handle at least the quoted facenames
619 wxStringTokenizer
tokenizer(s
, _T(";, "), wxTOKEN_STRTOK
);
625 wxFontEncoding encoding
;
626 #endif // wxUSE_FONTMAP
628 while ( tokenizer
.HasMoreTokens() )
630 wxString token
= tokenizer
.GetNextToken();
633 token
.Trim(true).Trim(false).MakeLower();
635 // look for the known tokens
636 if ( token
== _T("underlined") || token
== _("underlined") )
640 else if ( token
== _T("light") || token
== _("light") )
642 SetWeight(wxFONTWEIGHT_LIGHT
);
644 else if ( token
== _T("bold") || token
== _("bold") )
646 SetWeight(wxFONTWEIGHT_BOLD
);
648 else if ( token
== _T("italic") || token
== _("italic") )
650 SetStyle(wxFONTSTYLE_ITALIC
);
652 else if ( token
.ToULong(&size
) )
657 else if ( (encoding
= wxFontMapper::Get()->CharsetToEncoding(token
, false))
658 != wxFONTENCODING_DEFAULT
)
660 SetEncoding(encoding
);
662 #endif // wxUSE_FONTMAP
663 else // assume it is the face name
672 // skip the code which resets face below
676 // if we had had the facename, we shouldn't continue appending tokens
677 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
686 // we might not have flushed it inside the loop
695 #endif // generic or wxMSW or wxOS2