diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index 7767791433..cadf89b1e5 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -44,6 +44,8 @@ #include "wx/tokenzr.h" +#include // for FLT_MAX + // debugger helper: this function can be called from a debugger to show what // the date really is extern const char *wxDumpFont(const wxFont *font) @@ -758,9 +760,9 @@ bool wxNativeFontInfo::FromString(const wxString& s) token = tokenizer.GetNextToken(); if ( !token.ToCDouble(&d) ) return false; - pointSize = static_cast(d); - if ( static_cast(pointSize) != d ) + if ( d < 0 || d > FLT_MAX ) return false; + pointSize = static_cast(d); token = tokenizer.GetNextToken(); if ( !token.ToLong(&l) ) diff --git a/src/msw/font.cpp b/src/msw/font.cpp index c54e2601ad..293c8e0324 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -43,6 +43,8 @@ #include "wx/scopeguard.h" #include "wx/tokenzr.h" +#include // for FLT_MAX + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -692,10 +694,11 @@ bool wxNativeFontInfo::FromString(const wxString& s) // lfHeight, as with v0 strings. if ( !wxIsNullDouble(d) ) { - pointSize = static_cast(d); - if ( static_cast(pointSize) != d ) + if ( d < 0 || d > FLT_MAX ) return false; + pointSize = static_cast(d); + setPointSizeFromHeight = false; } } diff --git a/src/osx/carbon/font.cpp b/src/osx/carbon/font.cpp index c1dcc0fda0..8504b4c609 100644 --- a/src/osx/carbon/font.cpp +++ b/src/osx/carbon/font.cpp @@ -31,6 +31,8 @@ #include #include +#include // for FLT_MAX + #define TRACE_CTFONT "ctfont" class WXDLLEXPORT wxFontRefData : public wxGDIRefData @@ -957,13 +959,13 @@ bool wxNativeFontInfo::FromString(const wxString& s) token = tokenizer.GetNextToken(); if ( !token.ToCDouble(&d) ) return false; + if ( d < 0 || d > FLT_MAX ) + return false; #ifdef __LP64__ // CGFloat is just double in this case. m_ctSize = d; #else // !__LP64__ m_ctSize = static_cast(d); - if ( static_cast(m_ctSize) != d ) - return false; #endif // __LP64__/!__LP64__ token = tokenizer.GetNextToken(); diff --git a/tests/font/fonttest.cpp b/tests/font/fonttest.cpp index b6cd5b60aa..f3e53ad74d 100644 --- a/tests/font/fonttest.cpp +++ b/tests/font/fonttest.cpp @@ -449,4 +449,28 @@ TEST_CASE("wxFont::NativeFontInfoUserDesc", "[font][fontinfo]") CHECK( test.GetEncoding() == temp2.GetEncoding() ); #endif } + + // Test for a bug with handling fractional font sizes in description + // strings (see #18590). + wxFont font(*wxNORMAL_FONT); + + static const float sizes[] = { 12.0f, 10.5f, 13.8f, 10.123f, 11.1f }; + for ( unsigned n = 0; n < WXSIZEOF(sizes); n++ ) + { + font.SetFractionalPointSize(sizes[n]); + + // Just setting the font can slightly change it because of rounding + // errors, so don't expect the actual size to be exactly equal to what + // we used -- but close enough. + const float sizeUsed = font.GetFractionalPointSize(); + CHECK( sizeUsed == Approx(sizes[n]).epsilon(0.001) ); + + const wxString& desc = font.GetNativeFontInfoDesc(); + INFO("Font description: " << desc); + CHECK( font.SetNativeFontInfo(desc) ); + + // Notice that here we use the exact comparison, there is no reason for + // a differently rounded size to be used. + CHECK( font.GetFractionalPointSize() == sizeUsed ); + } }