From e563d4858ad6e82c57c7f547b50a6ac15dd9de67 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 30 Dec 2018 01:06:19 +0100 Subject: [PATCH] Adjust the font size when DPI of window changes --- include/wx/font.h | 7 +++++++ include/wx/msw/font.h | 2 ++ include/wx/msw/window.h | 5 +++++ src/common/wincmn.cpp | 5 +++++ src/msw/font.cpp | 16 +++++++++++++++- src/msw/window.cpp | 14 ++++++++++++++ 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/wx/font.h b/include/wx/font.h index 4e986bb49f..409302d2e4 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -501,6 +501,13 @@ public: // account as well. static int GetNumericWeightOf(wxFontWeight weight); + // Some ports need to modify the font object when the DPI of the window it + // is used with changes, this function can be used to do it. + // + // Currently it is only used in wxMSW and is not considered to be part of + // wxWidgets public API. + virtual void WXAdjustToPPI(const wxSize& WXUNUSED(ppi)) { } + // this doesn't do anything and is kept for compatibility only #if WXWIN_COMPATIBILITY_2_8 wxDEPRECATED_INLINE(void SetNoAntiAliasing(bool no = true), wxUnusedVar(no);) diff --git a/include/wx/msw/font.h b/include/wx/msw/font.h index ee803d9cce..70ede34b88 100644 --- a/include/wx/msw/font.h +++ b/include/wx/msw/font.h @@ -120,6 +120,8 @@ public: virtual bool IsFixedWidth() const wxOVERRIDE; + virtual void WXAdjustToPPI(const wxSize& ppi) wxOVERRIDE; + wxDEPRECATED_MSG("use wxFONT{FAMILY,STYLE,WEIGHT}_XXX constants ie: wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD") wxFont(int size, int family, diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index cd28a4deaa..dd6c10a6b5 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -592,6 +592,11 @@ public: void MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI); protected: + // Called from MSWUpdateOnDPIChange() specifically to update the control + // font, as this may need to be done differently for some specific native + // controls. The default version updates m_font of this window. + virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI); + // this allows you to implement standard control borders without // repeating the code in different classes that are not derived from // wxControl diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 99c05f20cf..bc8a88139a 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -1726,6 +1726,8 @@ wxFont wxWindowBase::GetFont() const if ( !font.IsOk() ) font = GetClassDefaultAttributes().font; + font.WXAdjustToPPI(GetDPI()); + return font; } else @@ -1744,6 +1746,9 @@ bool wxWindowBase::SetFont(const wxFont& font) m_hasFont = font.IsOk(); m_inheritFont = m_hasFont; + if ( m_hasFont ) + m_font.WXAdjustToPPI(GetDPI()); + InvalidateBestSize(); return true; diff --git a/src/msw/font.cpp b/src/msw/font.cpp index e3e8012042..4517040e28 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -512,7 +512,8 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew) { // We don't have the correct DPI to use here, so use that of the - // primary screen. + // primary screen and rely on WXAdjustToPPI() changing it later if + // necessary. const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); lf.lfHeight = GetLogFontHeightAtPPI(pointSizeNew, ppi); @@ -899,6 +900,19 @@ void wxFont::SetPixelSize(const wxSize& pixelSize) M_FONTDATA->SetPixelSize(pixelSize); } +void wxFont::WXAdjustToPPI(const wxSize& ppi) +{ + // We only use vertical component here as we only adjust LOGFONT::lfHeight. + const int heightNew = M_FONTDATA->GetLogFontHeightAtPPI(ppi.y); + + if ( heightNew != M_FONTDATA->GetLogFontHeight() ) + { + AllocExclusive(); + + M_FONTDATA->SetLogFontHeight(heightNew); + } +} + void wxFont::SetFamily(wxFontFamily family) { AllocExclusive(); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index ec12b9cad6..f2ca075797 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -4837,6 +4837,17 @@ wxSize wxWindowMSW::GetDPI() const return dpi; } +void wxWindowMSW::MSWUpdateFontOnDPIChange(const wxSize& newDPI) +{ + if ( m_font.IsOk() ) + { + m_font.WXAdjustToPPI(newDPI); + + // WXAdjustToPPI() changes the HFONT, so reassociate it with the window. + wxSetWindowFont(GetHwnd(), m_font); + } +} + // Helper function to update the given coordinate by the scaling factor if it // is set, i.e. different from wxDefaultCoord. static void ScaleCoordIfSet(int& coord, float scaleFactor) @@ -4861,6 +4872,9 @@ wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI) InvalidateBestSize(); + // update font if necessary + MSWUpdateFontOnDPIChange(newDPI); + // update children wxWindowList::compatibility_iterator current = GetChildren().GetFirst(); while ( current )