X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7456f3828a7dda585e6ecb04b738aa81bb0b0428..5337ab1bb87eb9691d84e24471489808072ac9fd:/src/common/fontcmn.cpp?ds=sidebyside diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index f0d3ccf9c4..96407bbfd6 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -31,10 +31,9 @@ #include "wx/intl.h" #include "wx/dcscreen.h" #include "wx/log.h" + #include "wx/gdicmn.h" #endif // WX_PRECOMP -#include "wx/gdicmn.h" - #if defined(__WXMSW__) #include "wx/msw/private.h" // includes windows.h for LOGFONT #include "wx/msw/winundef.h" @@ -54,58 +53,27 @@ // helper functions // ---------------------------------------------------------------------------- -static void AdjustFontSize(wxFont& font, wxDC& dc, const wxSize& pixelSize) +static inline int flags2Style(int flags) { - int currentSize = 0; - int largestGood = 0; - int smallestBad = 0; - - bool initialGoodFound = false; - bool initialBadFound = false; - - // NB: this assignment was separated from the variable definition - // in order to fix a gcc v3.3.3 compiler crash - currentSize = font.GetPointSize(); - while (currentSize > 0) - { - dc.SetFont(font); - - // if currentSize (in points) results in a font that is smaller - // than required by pixelSize it is considered a good size - if (dc.GetCharHeight() <= pixelSize.GetHeight() && - (!pixelSize.GetWidth() || - dc.GetCharWidth() <= pixelSize.GetWidth())) - { - largestGood = currentSize; - initialGoodFound = true; - } - else - { - smallestBad = currentSize; - initialBadFound = true; - } - if (!initialGoodFound) - { - currentSize /= 2; - } - else if (!initialBadFound) - { - currentSize *= 2; - } - else - { - int distance = smallestBad - largestGood; - if (distance == 1) - break; - - currentSize = largestGood + distance / 2; - } + return flags & wxFONTFLAG_ITALIC + ? wxFONTSTYLE_ITALIC + : flags & wxFONTFLAG_SLANT + ? wxFONTSTYLE_SLANT + : wxFONTSTYLE_NORMAL; +} - font.SetPointSize(currentSize); - } +static inline int flags2Weight(int flags) +{ + return flags & wxFONTFLAG_LIGHT + ? wxFONTWEIGHT_LIGHT + : flags & wxFONTFLAG_BOLD + ? wxFONTWEIGHT_BOLD + : wxFONTWEIGHT_NORMAL; +} - if (currentSize != largestGood) - font.SetPointSize(largestGood); +static inline bool flags2Underlined(int flags) +{ + return (flags & wxFONTFLAG_UNDERLINED) != 0; } // ---------------------------------------------------------------------------- @@ -132,9 +100,9 @@ wxFontBase::~wxFontBase() /* static */ wxFont *wxFontBase::New(int size, - int family, - int style, - int weight, + wxFontFamily family, + wxFontStyle style, + wxFontWeight weight, bool underlined, const wxString& face, wxFontEncoding encoding) @@ -142,27 +110,17 @@ wxFont *wxFontBase::New(int size, return new wxFont(size, family, style, weight, underlined, face, encoding); } -static inline int flags2Style(int flags) -{ - return flags & wxFONTFLAG_ITALIC - ? wxFONTSTYLE_ITALIC - : flags & wxFONTFLAG_SLANT - ? wxFONTSTYLE_SLANT - : wxFONTSTYLE_NORMAL; -} - -static inline int flags2Weight(int flags) -{ - return flags & wxFONTFLAG_LIGHT - ? wxFONTWEIGHT_LIGHT - : flags & wxFONTFLAG_BOLD - ? wxFONTWEIGHT_BOLD - : wxFONTWEIGHT_NORMAL; -} - -static inline bool flags2Underlined(int flags) +/* static */ +wxFont *wxFontBase::New(const wxSize& pixelSize, + wxFontFamily family, + wxFontStyle style, + wxFontWeight weight, + bool underlined, + const wxString& face, + wxFontEncoding encoding) { - return (flags & wxFONTFLAG_UNDERLINED) != 0; + return new wxFont(pixelSize, family, style, weight, underlined, + face, encoding); } /* static */ @@ -176,26 +134,6 @@ wxFont *wxFontBase::New(int pointSize, flags2Underlined(flags), face, encoding); } -/* static */ -wxFont *wxFontBase::New(const wxSize& pixelSize, - int family, - int style, - int weight, - bool underlined, - const wxString& face, - wxFontEncoding encoding) -{ -#if defined(__WXMSW__) - return new wxFont(pixelSize, family, style, weight, underlined, - face, encoding); -#else - wxFont *self = New(10, family, style, weight, underlined, face, encoding); - wxScreenDC dc; - AdjustFontSize(*(wxFont *)self, dc, pixelSize); - return self; -#endif -} - /* static */ wxFont *wxFontBase::New(const wxSize& pixelSize, wxFontFamily family, @@ -207,24 +145,6 @@ wxFont *wxFontBase::New(const wxSize& pixelSize, flags2Underlined(flags), face, encoding); } -wxSize wxFontBase::GetPixelSize() const -{ - wxScreenDC dc; - dc.SetFont(*(wxFont *)this); - return wxSize(dc.GetCharWidth(), dc.GetCharHeight()); -} - -bool wxFontBase::IsUsingSizeInPixels() const -{ - return false; -} - -void wxFontBase::SetPixelSize( const wxSize& pixelSize ) -{ - wxScreenDC dc; - AdjustFontSize(*(wxFont *)this, dc, pixelSize); -} - /* static */ wxFont *wxFontBase::New(const wxNativeFontInfo& info) { @@ -246,6 +166,81 @@ bool wxFontBase::IsFixedWidth() const return GetFamily() == wxFONTFAMILY_TELETYPE; } +wxSize wxFontBase::GetPixelSize() const +{ + wxScreenDC dc; + dc.SetFont(*(wxFont *)this); + return wxSize(dc.GetCharWidth(), dc.GetCharHeight()); +} + +bool wxFontBase::IsUsingSizeInPixels() const +{ + return false; +} + +void wxFontBase::SetPixelSize( const wxSize& pixelSize ) +{ + wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0, + "Negative values for the pixel size or zero pixel height are not allowed" ); + + wxScreenDC dc; + + // NOTE: this algorithm for adjusting the font size is used by all + // implementations of wxFont except under wxMSW and wxGTK where + // native support to font creation using pixel-size is provided. + + int largestGood = 0; + int smallestBad = 0; + + bool initialGoodFound = false; + bool initialBadFound = false; + + // NB: this assignment was separated from the variable definition + // in order to fix a gcc v3.3.3 compiler crash + int currentSize = GetPointSize(); + while (currentSize > 0) + { + dc.SetFont(*static_cast(this)); + + // if currentSize (in points) results in a font that is smaller + // than required by pixelSize it is considered a good size + // NOTE: the pixel size width may be zero + if (dc.GetCharHeight() <= pixelSize.GetHeight() && + (pixelSize.GetWidth() == 0 || + dc.GetCharWidth() <= pixelSize.GetWidth())) + { + largestGood = currentSize; + initialGoodFound = true; + } + else + { + smallestBad = currentSize; + initialBadFound = true; + } + if (!initialGoodFound) + { + currentSize /= 2; + } + else if (!initialBadFound) + { + currentSize *= 2; + } + else + { + int distance = smallestBad - largestGood; + if (distance == 1) + break; + + currentSize = largestGood + distance / 2; + } + + SetPointSize(currentSize); + } + + if (currentSize != largestGood) + SetPointSize(largestGood); +} + void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info) { #ifdef wxNO_NATIVE_FONTINFO @@ -268,7 +263,7 @@ wxString wxFontBase::GetNativeFontInfoDesc() const if ( fontInfo ) { fontDesc = fontInfo->ToString(); - wxASSERT_MSG(!fontDesc.IsEmpty(), wxT("This should be a non-empty string!")); + wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!")); } else { @@ -285,7 +280,7 @@ wxString wxFontBase::GetNativeFontInfoUserDesc() const if ( fontInfo ) { fontDesc = fontInfo->ToUserString(); - wxASSERT_MSG(!fontDesc.IsEmpty(), wxT("This should be a non-empty string!")); + wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!")); } else { @@ -304,7 +299,6 @@ bool wxFontBase::SetNativeFontInfo(const wxString& info) return true; } - UnRef(); return false; } @@ -317,7 +311,6 @@ bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info) return true; } - UnRef(); return false; } @@ -325,10 +318,16 @@ bool wxFontBase::operator==(const wxFont& font) const { // either it is the same font, i.e. they share the same common data or they // have different ref datas but still describe the same font - return GetFontData() == font.GetFontData() || + return IsSameAs(font) || ( - Ok() == font.Ok() && + IsOk() == font.IsOk() && GetPointSize() == font.GetPointSize() && + // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses + // operator==() resulting in infinite recursion so we can't use it + // in that port +#if !defined(__WXGTK__) || defined(__WXGTK20__) + GetPixelSize() == font.GetPixelSize() && +#endif GetFamily() == font.GetFamily() && GetStyle() == font.GetStyle() && GetWeight() == font.GetWeight() && @@ -338,60 +337,59 @@ bool wxFontBase::operator==(const wxFont& font) const ); } -bool wxFontBase::operator!=(const wxFont& font) const -{ - return !(*this == font); -} - wxString wxFontBase::GetFamilyString() const { - wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") ); + wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" ); switch ( GetFamily() ) { - case wxDECORATIVE: return wxT("wxDECORATIVE"); - case wxROMAN: return wxT("wxROMAN"); - case wxSCRIPT: return wxT("wxSCRIPT"); - case wxSWISS: return wxT("wxSWISS"); - case wxMODERN: return wxT("wxMODERN"); - case wxTELETYPE: return wxT("wxTELETYPE"); - default: return wxT("wxDEFAULT"); + case wxFONTFAMILY_DECORATIVE: return "wxFONTFAMILY_DECORATIVE"; + case wxFONTFAMILY_ROMAN: return "wxFONTFAMILY_ROMAN"; + case wxFONTFAMILY_SCRIPT: return "wxFONTFAMILY_SCRIPT"; + case wxFONTFAMILY_SWISS: return "wxFONTFAMILY_SWISS"; + case wxFONTFAMILY_MODERN: return "wxFONTFAMILY_MODERN"; + case wxFONTFAMILY_TELETYPE: return "wxFONTFAMILY_TELETYPE"; + default: return "wxFONTFAMILY_DEFAULT"; } } wxString wxFontBase::GetStyleString() const { - wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") ); + wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" ); switch ( GetStyle() ) { - case wxNORMAL: return wxT("wxNORMAL"); - case wxSLANT: return wxT("wxSLANT"); - case wxITALIC: return wxT("wxITALIC"); - default: return wxT("wxDEFAULT"); + case wxFONTSTYLE_NORMAL: return "wxFONTSTYLE_NORMAL"; + case wxFONTSTYLE_SLANT: return "wxFONTSTYLE_SLANT"; + case wxFONTSTYLE_ITALIC: return "wxFONTSTYLE_ITALIC"; + default: return "wxFONTSTYLE_DEFAULT"; } } wxString wxFontBase::GetWeightString() const { - wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") ); + wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" ); switch ( GetWeight() ) { - case wxNORMAL: return wxT("wxNORMAL"); - case wxBOLD: return wxT("wxBOLD"); - case wxLIGHT: return wxT("wxLIGHT"); - default: return wxT("wxDEFAULT"); + case wxFONTWEIGHT_NORMAL: return "wxFONTWEIGHT_NORMAL"; + case wxFONTWEIGHT_BOLD: return "wxFONTWEIGHT_BOLD"; + case wxFONTWEIGHT_LIGHT: return "wxFONTWEIGHT_LIGHT"; + default: return "wxFONTWEIGHT_DEFAULT"; } } -bool wxFontBase::SetFaceName(const wxString &facename) +bool wxFontBase::SetFaceName(const wxString& facename) { +#if wxUSE_FONTENUM if (!wxFontEnumerator::IsValidFacename(facename)) { - UnRef(); // make Ok() return false + UnRef(); // make IsOk() return false return false; } +#else // !wxUSE_FONTENUM + wxUnusedVar(facename); +#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM return true; } @@ -402,8 +400,9 @@ bool wxFontBase::SetFaceName(const wxString &facename) // ---------------------------------------------------------------------------- // Up to now, there are no native implementations of this function: -void wxNativeFontInfo::SetFaceName(const wxArrayString &facenames) +void wxNativeFontInfo::SetFaceName(const wxArrayString& facenames) { +#if wxUSE_FONTENUM for (size_t i=0; i < facenames.GetCount(); i++) { if (wxFontEnumerator::IsValidFacename(facenames[i])) @@ -417,6 +416,9 @@ void wxNativeFontInfo::SetFaceName(const wxArrayString &facenames) wxString validfacename = wxFontEnumerator::GetFacenames().Item(0); wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename.c_str()); SetFaceName(validfacename); +#else // !wxUSE_FONTENUM + SetFaceName(facenames[0]); +#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM } @@ -666,7 +668,10 @@ bool wxNativeFontInfo::FromUserString(const wxString& s) wxString face; unsigned long size; - bool weightfound = false, pointsizefound = false, encodingfound = false; + bool weightfound = false, pointsizefound = false; +#if wxUSE_FONTMAP + bool encodingfound = false; +#endif while ( tokenizer.HasMoreTokens() ) { @@ -738,9 +743,15 @@ bool wxNativeFontInfo::FromUserString(const wxString& s) // NB: the check on the facename is implemented in wxFontBase::SetFaceName // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely // call here wxFontEnumerator::IsValidFacename - if (!wxFontEnumerator::IsValidFacename(face) || - !SetFaceName(face)) + if ( +#if wxUSE_FONTENUM + !wxFontEnumerator::IsValidFacename(face) || +#endif // wxUSE_FONTENUM + !SetFaceName(face) ) + { SetFaceName(wxNORMAL_FONT->GetFaceName()); + } + face.clear(); } } @@ -751,9 +762,14 @@ bool wxNativeFontInfo::FromUserString(const wxString& s) // NB: the check on the facename is implemented in wxFontBase::SetFaceName // and not in wxNativeFontInfo::SetFaceName thus we need to explicitely // call here wxFontEnumerator::IsValidFacename - if (!wxFontEnumerator::IsValidFacename(face) || - !SetFaceName(face)) - SetFaceName(wxNORMAL_FONT->GetFaceName()); + if ( +#if wxUSE_FONTENUM + !wxFontEnumerator::IsValidFacename(face) || +#endif // wxUSE_FONTENUM + !SetFaceName(face) ) + { + SetFaceName(wxNORMAL_FONT->GetFaceName()); + } } // set point size to default value if size was not given @@ -774,3 +790,26 @@ bool wxNativeFontInfo::FromUserString(const wxString& s) } #endif // generic or wxMSW or wxOS2 + + +// wxFont <-> wxString utilities, used by wxConfig +wxString wxToString(const wxFontBase& font) +{ + return font.IsOk() ? font.GetNativeFontInfoDesc() + : wxString(); +} + +bool wxFromString(const wxString& str, wxFontBase *font) +{ + wxCHECK_MSG( font, false, _T("NULL output parameter") ); + + if ( str.empty() ) + { + *font = wxNullFont; + return true; + } + + return font->SetNativeFontInfo(str); +} + +