From 125b2c18ea92a0a4d6ad7022eda62c4c0cce8c00 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 16 Oct 2016 14:48:00 +0200 Subject: [PATCH 01/12] Adjust font of wxDC to DPI of associated window --- src/msw/dc.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 9652af4ccf..72e89c9acd 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -1438,7 +1438,18 @@ void wxMSWDCImpl::DoDrawRotatedText(const wxString& text, // NB: don't take DEFAULT_GUI_FONT (a.k.a. wxSYS_DEFAULT_GUI_FONT) // because it's not TrueType and so can't have non zero // orientation/escapement - wxFont font = m_font.IsOk() ? m_font : *wxSWISS_FONT; + wxFont font; + if ( m_font.IsOk() ) + { + font = m_font; + } + else // Use default font appropriate for rotated text. + { + font = *wxSWISS_FONT; + if ( m_window ) + font.WXAdjustToPPI(m_window->GetDPI()); + } + LOGFONT lf; if ( ::GetObject(GetHfontOf(font), sizeof(lf), &lf) == 0 ) { @@ -1565,7 +1576,11 @@ void wxMSWDCImpl::SetFont(const wxFont& font) if ( font.IsOk() ) { - HGDIOBJ hfont = ::SelectObject(GetHdc(), GetHfontOf(font)); + wxFont f(font); + if ( m_window ) + f.WXAdjustToPPI(m_window->GetDPI()); + + HGDIOBJ hfont = ::SelectObject(GetHdc(), GetHfontOf(f)); if ( hfont == HGDI_ERROR ) { wxLogLastError(wxT("SelectObject(font)")); @@ -1575,7 +1590,7 @@ void wxMSWDCImpl::SetFont(const wxFont& font) if ( !m_oldFont ) m_oldFont = (WXHFONT)hfont; - m_font = font; + m_font = f; } } else // invalid font, reset the current font From 62c5b2d8d1cdcfcee9746ddf88fcc47927110cf0 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 16 Oct 2016 17:29:51 +0200 Subject: [PATCH 02/12] Support DPI change in wxStyledTextCtrl Change to zoom-level and margin width based on the active DPI. Send wxDPIChangedEvent to all controls and windows. --- include/wx/stc/stc.h | 1 + src/stc/stc.cpp | 26 +++++++++++++++++++++++++- src/stc/stc.cpp.in | 26 +++++++++++++++++++++++++- src/stc/stc.h.in | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/wx/stc/stc.h b/include/wx/stc/stc.h index 0ab59936ef..0bc3ea10d3 100644 --- a/include/wx/stc/stc.h +++ b/include/wx/stc/stc.h @@ -5479,6 +5479,7 @@ protected: void OnKeyDown(wxKeyEvent& evt); void OnLoseFocus(wxFocusEvent& evt); void OnGainFocus(wxFocusEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnSysColourChanged(wxSysColourChangedEvent& evt); void OnEraseBackground(wxEraseEvent& evt); void OnMenu(wxCommandEvent& evt); diff --git a/src/stc/stc.cpp b/src/stc/stc.cpp index a397d65673..226839a2c6 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -159,6 +159,7 @@ wxBEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown) EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus) EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus) + EVT_DPI_CHANGED (wxStyledTextCtrl::OnDPIChanged) EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged) EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground) EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu) @@ -239,6 +240,16 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, SetFontQuality(wxSTC_EFF_QUALITY_DEFAULT); #endif +#ifdef __WXMSW__ + // Set zoom for DPI + double baseDPI = ::GetDeviceCaps(WindowHDC(parent->GetHWND()), LOGPIXELSY); + double activeDPI = parent->GetDPI().y; + + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); +#endif + return true; } @@ -5432,6 +5443,19 @@ void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) { } +void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) +{ + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, evt.GetNewDPI().y, evt.GetOldDPI().y); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); + + for ( int i = 0; i < SC_MAX_MARGIN; ++i ) + { + SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y)); + } +} + + void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) { m_swx->DoSysColourChange(); } @@ -5467,7 +5491,7 @@ wxSize wxStyledTextCtrl::DoGetBestSize() const { // What would be the best size for a wxSTC? // Just give a reasonable minimum until something else can be figured out. - return wxSize(200,100); + return FromDIP(wxSize(200,100)); } diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 7a211c5545..83d8f4bf4c 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -159,6 +159,7 @@ wxBEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown) EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus) EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus) + EVT_DPI_CHANGED (wxStyledTextCtrl::OnDPIChanged) EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged) EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground) EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu) @@ -239,6 +240,16 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, SetFontQuality(wxSTC_EFF_QUALITY_DEFAULT); #endif +#ifdef __WXMSW__ + // Set zoom for DPI + double baseDPI = ::GetDeviceCaps(WindowHDC(parent->GetHWND()), LOGPIXELSY); + double activeDPI = parent->GetDPI().y; + + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); +#endif + return true; } @@ -959,6 +970,19 @@ void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) { } +void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) +{ + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, evt.GetNewDPI().y, evt.GetOldDPI().y); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); + + for ( int i = 0; i < SC_MAX_MARGIN; ++i ) + { + SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y)); + } +} + + void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) { m_swx->DoSysColourChange(); } @@ -994,7 +1018,7 @@ wxSize wxStyledTextCtrl::DoGetBestSize() const { // What would be the best size for a wxSTC? // Just give a reasonable minimum until something else can be figured out. - return wxSize(200,100); + return FromDIP(wxSize(200,100)); } diff --git a/src/stc/stc.h.in b/src/stc/stc.h.in index 0713ec6212..925f4b9b1d 100644 --- a/src/stc/stc.h.in +++ b/src/stc/stc.h.in @@ -597,6 +597,7 @@ protected: void OnKeyDown(wxKeyEvent& evt); void OnLoseFocus(wxFocusEvent& evt); void OnGainFocus(wxFocusEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnSysColourChanged(wxSysColourChangedEvent& evt); void OnEraseBackground(wxEraseEvent& evt); void OnMenu(wxCommandEvent& evt); From a1c3fa0468936ae28b29b0180cbd7c69163346dd Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 13 Jan 2019 15:28:10 +0100 Subject: [PATCH 03/12] Fix wxPropertyGrid row height on DPI change Fix collapse button size of wxPropertyGrid in High DPI. --- include/wx/propgrid/propgrid.h | 2 ++ src/propgrid/propgrid.cpp | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 5b2c5a52d0..0e9daa0ad7 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -1766,6 +1766,8 @@ protected: void OnSysColourChanged( wxSysColourChangedEvent &event ); + void OnDPIChanged(wxDPIChangedEvent& event); + void OnTLPClose( wxCloseEvent& event ); protected: diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 7102b85170..b2944a98d5 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -260,6 +260,7 @@ wxBEGIN_EVENT_TABLE(wxPropertyGrid, wxControl) EVT_SET_FOCUS(wxPropertyGrid::OnFocusEvent) EVT_KILL_FOCUS(wxPropertyGrid::OnFocusEvent) EVT_SYS_COLOUR_CHANGED(wxPropertyGrid::OnSysColourChanged) + EVT_DPI_CHANGED(wxPropertyGrid::OnDPIChanged) EVT_MOTION(wxPropertyGrid::OnMouseMove) EVT_LEFT_DOWN(wxPropertyGrid::OnMouseClick) EVT_LEFT_UP(wxPropertyGrid::OnMouseUp) @@ -453,9 +454,9 @@ void wxPropertyGrid::Init2() m_cursorSizeWE = new wxCursor( wxCURSOR_SIZEWE ); // adjust bitmap icon y position so they are centered - m_vspacing = wxPG_DEFAULT_VSPACING; + m_vspacing = FromDIP(wxPG_DEFAULT_VSPACING); - CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); + CalculateFontAndBitmapStuff( m_vspacing ); // Allocate cell data m_propertyDefaultCell.SetEmptyData(); @@ -1167,7 +1168,7 @@ void wxPropertyGrid::SetExtraStyle( long exStyle ) // returns the best acceptable minimal size wxSize wxPropertyGrid::DoGetBestSize() const { - int lineHeight = wxMax(15, m_lineHeight); + int lineHeight = wxMax(FromDIP(15), m_lineHeight); // don't make the grid too tall (limit height to 10 items) but don't // make it too small neither @@ -1301,7 +1302,7 @@ void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) m_fontHeight = y; #if wxPG_USE_RENDERER_NATIVE - m_iconWidth = wxPG_ICON_WIDTH; + m_iconWidth = FromDIP(wxPG_ICON_WIDTH); #elif wxPG_ICON_WIDTH // scale icon m_iconWidth = (m_fontHeight * wxPG_ICON_WIDTH) / 13; @@ -1356,6 +1357,13 @@ void wxPropertyGrid::OnSysColourChanged( wxSysColourChangedEvent &WXUNUSED(event } } +void wxPropertyGrid::OnDPIChanged(wxDPIChangedEvent &WXUNUSED(event)) +{ + m_vspacing = FromDIP(wxPG_DEFAULT_VSPACING); + CalculateFontAndBitmapStuff(m_vspacing); + Refresh(); +} + // ----------------------------------------------------------------------- static wxColour wxPGAdjustColour(const wxColour& src, int ra, From 87a97054f2ca89e2932df9d91da1bd526faa85cf Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 13 Jan 2019 15:45:06 +0100 Subject: [PATCH 04/12] Allow to retrieve the wxWindow associated with a wxBufferedPaintDC When a wxBufferedPaintDC is created, the base classes does not initialize the m_window variable with the used wxWindow. Only the associated m_paintdc initializes this variable. Add a protected function that allows to set the wxWindow of a wxDC so GetWindow() will return the window. This fixes the font size of custom attributes in wxDataViewCtrl when the DPI changes. --- include/wx/dc.h | 5 +++++ include/wx/dcbuffer.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/include/wx/dc.h b/include/wx/dc.h index 847b7f64e5..cc0a48238e 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -269,6 +269,8 @@ public: wxWindow* GetWindow() const { return m_window; } + void SetWindow(wxWindow* w) { m_window = w; } + virtual bool IsOk() const { return m_ok; } // query capabilities @@ -1364,6 +1366,9 @@ protected: wxDCImpl * const m_pimpl; + void SetWindow(wxWindow* w) + { return m_pimpl->SetWindow(w); } + private: wxDECLARE_ABSTRACT_CLASS(wxDC); wxDECLARE_NO_COPY_CLASS(wxDC); diff --git a/include/wx/dcbuffer.h b/include/wx/dcbuffer.h index 4a29fda820..8fc23d66cd 100644 --- a/include/wx/dcbuffer.h +++ b/include/wx/dcbuffer.h @@ -153,6 +153,8 @@ public: wxBufferedPaintDC(wxWindow *window, wxBitmap& buffer, int style = wxBUFFER_CLIENT_AREA) : m_paintdc(window) { + SetWindow(window); + // If we're buffering the virtual window, scale the paint DC as well if (style & wxBUFFER_VIRTUAL_AREA) window->PrepareDC( m_paintdc ); @@ -167,6 +169,8 @@ public: wxBufferedPaintDC(wxWindow *window, int style = wxBUFFER_CLIENT_AREA) : m_paintdc(window) { + SetWindow(window); + // If we're using the virtual window, scale the paint DC as well if (style & wxBUFFER_VIRTUAL_AREA) window->PrepareDC( m_paintdc ); From abb20c414d2da84355fe9e637ddbe23f2f6a4682 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 13 Jan 2019 15:53:59 +0100 Subject: [PATCH 05/12] Fix font size of wxMenuItem with custom font on DPI change Recalculate MenuDrawData sizes after the DPI changes, and reset the maximum accelerator width. --- src/msw/menuitem.cpp | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 3163cd5575..e18f457317 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -29,7 +29,6 @@ #include "wx/stockitem.h" #ifndef WX_PRECOMP - #include "wx/app.h" #include "wx/dcmemory.h" #include "wx/font.h" #include "wx/bitmap.h" @@ -235,28 +234,41 @@ public: bool Theme; // is data initialized for FullTheme? - static const MenuDrawData* Get() + int dpi; // DPI used for calculating sizes + + static const MenuDrawData* Get(wxMenu* menu) { + const wxWindow* window = menu->GetWindow(); // notice that s_menuData can't be created as a global variable because // it needs a window to initialize and no windows exist at the time of // globals initialization yet if ( !ms_instance ) { - static MenuDrawData s_menuData; + static MenuDrawData s_menuData(window); ms_instance = &s_menuData; } #if wxUSE_UXTHEME bool theme = MenuLayout() == FullTheme; if ( ms_instance->Theme != theme ) - ms_instance->Init(); + { + ms_instance->Init(window); + } + else #endif // wxUSE_UXTHEME + { + if ( ms_instance->dpi != window->GetDPI().y ) + { + ms_instance->Init(window); + menu->ResetMaxAccelWidth(); + } + } return ms_instance; } - MenuDrawData() + MenuDrawData(const wxWindow* window) { - Init(); + Init(window); } @@ -296,17 +308,16 @@ public: } private: - void Init(); + void Init(wxWindow const* window); static MenuDrawData* ms_instance; }; MenuDrawData* MenuDrawData::ms_instance = NULL; -void MenuDrawData::Init() +void MenuDrawData::Init(wxWindow const* window) { #if wxUSE_UXTHEME - const wxWindow* window = wxTheApp ? wxTheApp->GetTopWindow() : NULL; if ( IsUxThemeActive() ) { wxUxThemeHandle hTheme(window, L"MENU"); @@ -348,7 +359,8 @@ void MenuDrawData::Init() wxUxThemeFont themeFont; ::GetThemeSysFont(hTheme, TMT_MENUFONT, themeFont.GetPtr()); - Font = wxFont(wxNativeFontInfo(themeFont.GetLOGFONT(), window)); + // Use NULL window for wxNativeFontInfo, height it is already at the correct ppi + Font = wxFont(wxNativeFontInfo(themeFont.GetLOGFONT(), NULL)); Theme = true; @@ -407,6 +419,7 @@ void MenuDrawData::Init() AlwaysShowCues = value == 1; + dpi = window->GetDPI().y; } } // anonymous namespace @@ -783,7 +796,7 @@ wxString wxMenuItem::GetName() const bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) { - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); if ( IsOwnerDrawn() ) { @@ -875,7 +888,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction WXUNUSED(act), wxODStatus stat) { - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); @@ -1167,7 +1180,7 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) { wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU"); - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); // rect for background must be without check margins RECT rcBg = *rc; @@ -1234,7 +1247,8 @@ void wxMenuItem::GetFontToUse(wxFont& font) const { font = GetFont(); if ( !font.IsOk() ) - font = MenuDrawData::Get()->Font; + font = MenuDrawData::Get(GetMenu())->Font; + font.WXAdjustToPPI(GetMenu()->GetWindow()->GetDPI()); } void wxMenuItem::GetColourToUse(wxODStatus stat, wxColour& colText, wxColour& colBack) const From 6fb86323f5223eca5085a609df0beda00954cc81 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Tue, 1 Oct 2019 23:41:14 +0200 Subject: [PATCH 06/12] Use associated window in wxMSWDCImpl::GetPPI() --- src/msw/dc.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 72e89c9acd..999d724996 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -2452,10 +2452,24 @@ void wxMSWDCImpl::DoGetSizeMM(int *w, int *h) const wxSize wxMSWDCImpl::GetPPI() const { - int x = ::GetDeviceCaps(GetHdc(), LOGPIXELSX); - int y = ::GetDeviceCaps(GetHdc(), LOGPIXELSY); + // As documented by MSDN, GetDeviceCaps() returns the same value for all + // HDCs on the system, and so can't be used to retrieve the correct value + // for the HDCs associated with the windows on monitors other than the + // primary one if they use different DPI. Hence prefer to get this + // information from the associated window, if possible. + wxSize ppi; + if ( m_window ) + { + ppi = m_window->GetDPI(); + } - return wxSize(x, y); + if ( !ppi.x || !ppi.y ) + { + ppi.x = ::GetDeviceCaps(GetHdc(), LOGPIXELSX); + ppi.y = ::GetDeviceCaps(GetHdc(), LOGPIXELSY); + } + + return ppi; } double wxMSWDCImpl::GetContentScaleFactor() const From 64f49633961df29c22727f2e8ef47841ee9e9e40 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Fri, 4 Oct 2019 23:01:56 +0200 Subject: [PATCH 07/12] Correctly use pixelSize in wxGraphicsContext::CreateFont It is documented as using pixel size, and this is also used in all other contexts. For clarity, rename all parameters to sizeInPixels. This partially reverts d5020362ffb99608eacd2492d621cad20b1075a7 --- src/common/graphcmn.cpp | 4 ++-- src/msw/graphics.cpp | 32 ++++++++++++++++---------------- src/msw/graphicsd2d.cpp | 10 ++++------ 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 540dc4042e..e0db708881 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -948,12 +948,12 @@ wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColou } wxGraphicsFont -wxGraphicsContext::CreateFont(double size, +wxGraphicsContext::CreateFont(double sizeInPixels, const wxString& facename, int flags, const wxColour& col) const { - return GetRenderer()->CreateFont(size, facename, flags, col); + return GetRenderer()->CreateFont(sizeInPixels, facename, flags, col); } wxGraphicsBitmap wxGraphicsContext::CreateBitmap( const wxBitmap& bmp ) const diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index eaced69010..0e53578ac0 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -345,14 +345,14 @@ public: const wxColour& col ); wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col); // This ctor takes ownership of the brush. wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush); @@ -365,17 +365,17 @@ private : // Common part of all ctors, flags here is a combination of values of // FontStyle GDI+ enum. void Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush); // Common part of ctors taking wxColour. void Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col) { - Init(name, size, style, new SolidBrush(wxColourToColor(col))); + Init(name, sizeInPixels, style, new SolidBrush(wxColourToColor(col))); } Brush* m_textBrush; @@ -656,7 +656,7 @@ public : virtual wxGraphicsFont CreateFont( const wxFont& font, const wxColour& col) wxOVERRIDE; - virtual wxGraphicsFont CreateFont(double size, + virtual wxGraphicsFont CreateFont(double sizeInPixels, const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; @@ -1105,7 +1105,7 @@ extern const wxArrayString& wxGetPrivateFontFileNames(); void wxGDIPlusFontData::Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush) { @@ -1127,7 +1127,7 @@ wxGDIPlusFontData::Init(const wxString& name, int rc = gs_pFontFamily[j].GetFamilyName(familyName); if ( rc == 0 && name == familyName ) { - m_font = new Font(&gs_pFontFamily[j], size, style, UnitPoint); + m_font = new Font(&gs_pFontFamily[j], sizeInPixels, style, UnitPixel); break; } } @@ -1136,7 +1136,7 @@ wxGDIPlusFontData::Init(const wxString& name, if ( !m_font ) #endif // wxUSE_PRIVATE_FONTS { - m_font = new Font(name.wc_str(), size, style, UnitPoint); + m_font = new Font(name.wc_str(), sizeInPixels, style, UnitPixel); } m_textBrush = textBrush; @@ -1157,27 +1157,27 @@ wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, if ( font.GetWeight() == wxFONTWEIGHT_BOLD ) style |= FontStyleBold; - Init(font.GetFaceName(), font.GetFractionalPointSize(), style, col); + Init(font.GetFaceName(), (REAL)(font.GetPixelSize().GetHeight()), style, col); } wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col) : wxGraphicsObjectRefData(renderer) { - Init(name, size, style, col); + Init(name, sizeInPixels, style, col); } wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* brush) : wxGraphicsObjectRefData(renderer) { - Init(name, size, style, brush); + Init(name, sizeInPixels, style, brush); } wxGDIPlusFontData::~wxGDIPlusFontData() @@ -2732,7 +2732,7 @@ wxGDIPlusRenderer::CreateFont( const wxFont &font, } wxGraphicsFont -wxGDIPlusRenderer::CreateFont(double size, +wxGDIPlusRenderer::CreateFont(double sizeInPixels, const wxString& facename, int flags, const wxColour& col) @@ -2752,7 +2752,7 @@ wxGDIPlusRenderer::CreateFont(double size, wxGraphicsFont f; - f.SetRefData(new wxGDIPlusFontData(this, facename, size, style, col)); + f.SetRefData(new wxGDIPlusFontData(this, facename, sizeInPixels, style, col)); return f; } diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 19fa4b1411..912c5116ab 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -2876,9 +2876,7 @@ wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, c m_font->GetWeight(), m_font->GetStyle(), m_font->GetStretch(), - // We need to use DIP units for the font size, with 1dip = 1/96in, - // while wxFont uses points with 1pt = 1/72in. - font.GetFractionalPointSize()*96/72, + (FLOAT)(font.GetPixelSize().GetHeight()), L"en-us", &m_textFormat); @@ -4651,7 +4649,7 @@ public : wxGraphicsFont CreateFont(const wxFont& font, const wxColour& col) wxOVERRIDE; wxGraphicsFont CreateFont( - double size, const wxString& facename, + double sizeInPixels, const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; @@ -4904,12 +4902,12 @@ wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col } wxGraphicsFont wxD2DRenderer::CreateFont( - double size, const wxString& facename, + double sizeInPixels, const wxString& facename, int flags, const wxColour& col) { return CreateFont( - wxFontInfo(size).AllFlags(flags).FaceName(facename), + wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), col); } From c538e8f9d605c46abd81005d72cea8478e2a364f Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Fri, 4 Oct 2019 23:02:09 +0200 Subject: [PATCH 08/12] Add wxGraphicsRenderer::CreateFontAtDPI to support font with fractional pixel-size --- include/wx/graphics.h | 5 +++- interface/wx/graphics.h | 13 ++++++++- src/common/graphcmn.cpp | 6 +++-- src/generic/graphicc.cpp | 11 ++++++++ src/msw/graphics.cpp | 38 +++++++++++++++++++------- src/msw/graphicsd2d.cpp | 53 ++++++++++++++++++++++++++----------- src/osx/carbon/graphics.cpp | 11 ++++++++ src/qt/graphics.cpp | 11 ++++++++ 8 files changed, 118 insertions(+), 30 deletions(-) diff --git a/include/wx/graphics.h b/include/wx/graphics.h index 059d11c62d..415b8c9e83 100644 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -727,7 +727,7 @@ public: } // returns the resolution of the graphics context in device points per inch - virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); + virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY) const; #if 0 // sets the current alpha on this context @@ -1038,6 +1038,9 @@ public: const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) = 0; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col = *wxBLACK) = 0; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0; diff --git a/interface/wx/graphics.h b/interface/wx/graphics.h index 7e09c7d6ee..16b294209a 100644 --- a/interface/wx/graphics.h +++ b/interface/wx/graphics.h @@ -1116,7 +1116,7 @@ public: /** Returns the resolution of the graphics context in device points per inch. */ - virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); + virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY) const; /** Returns the associated window if any. @@ -1459,6 +1459,17 @@ public: int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) = 0; + /** + Creates a native graphics font from a wxFont and a text colour. + + The specified DPI is used to convert the (fractional) wxFont point-size + to a fractional pixel-size. + + @since 3.1.3 + */ + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col = *wxBLACK) = 0; /** Creates a native brush with a linear gradient. diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index e0db708881..bc44f0b270 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -619,7 +619,7 @@ wxDouble wxGraphicsContext::GetAlpha() const } #endif -void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) +void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) const { if ( m_window ) { @@ -944,7 +944,9 @@ wxGraphicsContext::CreateRadialGradientBrush( wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColour &col ) const { - return GetRenderer()->CreateFont(font,col); + wxRealPoint dpi; + GetDPI(&dpi.x, &dpi.y); + return GetRenderer()->CreateFontAtDPI(font, dpi, col); } wxGraphicsFont diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index c6586c98e8..60c09fa4da 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -3009,6 +3009,9 @@ public : const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) wxOVERRIDE; @@ -3238,6 +3241,14 @@ wxCairoRenderer::CreateFont(double sizeInPixels, return font; } +wxGraphicsFont +wxCairoRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp ) { wxGraphicsBitmap p; diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 0e53578ac0..6bbf407a73 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -342,6 +342,7 @@ class wxGDIPlusFontData : public wxGraphicsObjectRefData public: wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, + const wxRealPoint& dpi, const wxColour& col ); wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, @@ -661,6 +662,10 @@ public : int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; + // create a graphics bitmap from a native bitmap virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) wxOVERRIDE; @@ -1144,6 +1149,7 @@ wxGDIPlusFontData::Init(const wxString& name, wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, + const wxRealPoint& dpi, const wxColour& col ) : wxGraphicsObjectRefData( renderer ) { @@ -1157,7 +1163,11 @@ wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, if ( font.GetWeight() == wxFONTWEIGHT_BOLD ) style |= FontStyleBold; - Init(font.GetFaceName(), (REAL)(font.GetPixelSize().GetHeight()), style, col); + REAL fontSize = (REAL)(!dpi.y + ? font.GetPixelSize().GetHeight() + : (font.GetFractionalPointSize() * dpi.y / 72.0f)); + + Init(font.GetFaceName(), fontSize, style, col); } wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer, @@ -2720,15 +2730,7 @@ wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font, const wxColour &col ) { - ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont); - if ( font.IsOk() ) - { - wxGraphicsFont p; - p.SetRefData(new wxGDIPlusFontData( this, font, col )); - return p; - } - else - return wxNullGraphicsFont; + return CreateFontAtDPI(font, wxRealPoint(), col); } wxGraphicsFont @@ -2756,6 +2758,22 @@ wxGDIPlusRenderer::CreateFont(double sizeInPixels, return f; } +wxGraphicsFont +wxGDIPlusRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) +{ + ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont); + if ( font.IsOk() ) + { + wxGraphicsFont p; + p.SetRefData(new wxGDIPlusFontData( this, font, dpi, col )); + return p; + } + else + return wxNullGraphicsFont; +} + wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap ) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap); diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 912c5116ab..ce6aaeeedc 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -2792,7 +2792,7 @@ wxD2DPenData* wxGetD2DPenData(const wxGraphicsPen& pen) class wxD2DFontData : public wxGraphicsObjectRefData { public: - wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxColor& color); + wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxRealPoint& dpi, const wxColor& color); wxCOMPtr CreateTextLayout(const wxString& text) const; @@ -2817,7 +2817,7 @@ private: bool m_strikethrough; }; -wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxColor& color) : +wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxRealPoint& dpi, const wxColor& color) : wxGraphicsObjectRefData(renderer), m_brushData(renderer, wxBrush(color)), m_underlined(font.GetUnderlined()), m_strikethrough(font.GetStrikethrough()) { @@ -2870,13 +2870,17 @@ wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, c hr = familyNames->GetString(0, name, length+1); wxCHECK_HRESULT_RET(hr); + FLOAT fontSize = (FLOAT)(!dpi.y + ? font.GetPixelSize().GetHeight() + : (font.GetFractionalPointSize() * dpi.y / 72.0f)); + hr = wxDWriteFactory()->CreateTextFormat( name, NULL, m_font->GetWeight(), m_font->GetStyle(), m_font->GetStretch(), - (FLOAT)(font.GetPixelSize().GetHeight()), + fontSize, L"en-us", &m_textFormat); @@ -3644,7 +3648,7 @@ public: void Flush() wxOVERRIDE; - void GetDPI(wxDouble* dpiX, wxDouble* dpiY) wxOVERRIDE; + void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; wxD2DContextSupplier::ContextType GetContext() wxOVERRIDE { @@ -4570,7 +4574,7 @@ void wxD2DContext::Flush() GetRenderTarget()->SetTransform(&currTransform); } -void wxD2DContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) +void wxD2DContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const { FLOAT x, y; GetRenderTarget()->GetDpi(&x, &y); @@ -4653,6 +4657,10 @@ public : int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; + // create a graphics bitmap from a native bitmap wxGraphicsBitmap CreateBitmapFromNativeBitmap(void* bitmap) wxOVERRIDE; @@ -4886,7 +4894,30 @@ wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col) { - wxD2DFontData* fontData = new wxD2DFontData(this, font, col); + return CreateFontAtDPI(font, wxRealPoint(), col); +} + +wxGraphicsFont wxD2DRenderer::CreateFont( + double sizeInPixels, const wxString& facename, + int flags, + const wxColour& col) +{ + // Use the same DPI as wxFont will use in SetPixelSize, so these cancel + // each other out and we are left with the actual pixel size. + ScreenHDC hdc; + wxRealPoint dpi(::GetDeviceCaps(hdc, LOGPIXELSX), + ::GetDeviceCaps(hdc, LOGPIXELSY)); + + return CreateFontAtDPI( + wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), + dpi, col); +} + +wxGraphicsFont wxD2DRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) +{ + wxD2DFontData* fontData = new wxD2DFontData(this, font, dpi, col); if ( !fontData->GetFont() ) { // Apparently a non-TrueType font is given and hence @@ -4901,16 +4932,6 @@ wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col return graphicsFont; } -wxGraphicsFont wxD2DRenderer::CreateFont( - double sizeInPixels, const wxString& facename, - int flags, - const wxColour& col) -{ - return CreateFont( - wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), - col); -} - // create a sub-image from a native image representation wxGraphicsBitmap wxD2DRenderer::CreateSubBitmap(const wxGraphicsBitmap& bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h) { diff --git a/src/osx/carbon/graphics.cpp b/src/osx/carbon/graphics.cpp index 2ded6cf21f..1b3012d5d9 100644 --- a/src/osx/carbon/graphics.cpp +++ b/src/osx/carbon/graphics.cpp @@ -2778,6 +2778,9 @@ public : const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) wxOVERRIDE ; @@ -3073,6 +3076,14 @@ wxMacCoreGraphicsRenderer::CreateFont(double sizeInPixels, return f; } +wxGraphicsFont +wxMacCoreGraphicsRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + // // CoreGraphics Helper Methods // diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index c427099b08..9e0614807d 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -1154,6 +1154,9 @@ public: const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap(const wxBitmap& bitmap) wxOVERRIDE; @@ -1321,6 +1324,14 @@ wxGraphicsFont wxQtGraphicsRenderer::CreateFont( return font; } +wxGraphicsFont +wxQtGraphicsRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + wxGraphicsBitmap wxQtGraphicsRenderer::CreateBitmap(const wxBitmap& bmp) { wxGraphicsBitmap p; From 8ceadd3029024b827464010985221e2276585b54 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Tue, 8 Oct 2019 21:07:43 +0200 Subject: [PATCH 09/12] Improve wxD2DContext::GetDPI and wxGDIPlusContext::GetDPI If there is a valid wxWindow, use its DPI. Otherwise use a dedicated function of the context to get the DPI. Don't use the common wxGraphicsContext::GetDPI because this will return hard-coded 72 when there is no valid wxWindow. --- src/msw/graphics.cpp | 21 +++++++++++++++++++++ src/msw/graphicsd2d.cpp | 23 +++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 6bbf407a73..d3a981c60d 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -458,6 +458,7 @@ public: virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const wxOVERRIDE; virtual bool ShouldOffset() const wxOVERRIDE; virtual void GetSize( wxDouble* width, wxDouble *height ); + virtual void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; Graphics* GetGraphics() const { return m_context; } @@ -2397,6 +2398,26 @@ void wxGDIPlusContext::GetSize( wxDouble* width, wxDouble *height ) *height = m_height; } +void wxGDIPlusContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const +{ + if ( GetWindow() ) + { + const wxSize dpi = GetWindow()->GetDPI(); + + if ( dpiX ) + *dpiX = dpi.x; + if ( dpiY ) + *dpiY = dpi.y; + } + else + { + if ( dpiX ) + *dpiX = GetGraphics()->GetDpiX(); + if ( dpiY ) + *dpiY = GetGraphics()->GetDpiY(); + } +} + //----------------------------------------------------------------------------- // wxGDIPlusPrintingContext implementation //----------------------------------------------------------------------------- diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index ce6aaeeedc..b84bfa0d1d 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -4576,10 +4576,25 @@ void wxD2DContext::Flush() void wxD2DContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const { - FLOAT x, y; - GetRenderTarget()->GetDpi(&x, &y); - if (dpiX != NULL) *dpiX = x; - if (dpiY != NULL) *dpiY = y; + if ( GetWindow() ) + { + const wxSize dpi = GetWindow()->GetDPI(); + + if ( dpiX ) + *dpiX = dpi.x; + if ( dpiY ) + *dpiY = dpi.y; + } + else + { + FLOAT x, y; + GetRenderTarget()->GetDpi(&x, &y); + + if ( dpiX ) + *dpiX = x; + if ( dpiY ) + *dpiY = y; + } } //----------------------------------------------------------------------------- From 5547473acd0221c740e28d17e9279513762f0701 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Wed, 9 Oct 2019 22:40:44 +0200 Subject: [PATCH 10/12] Remove wxGDIPlusPrintingContext::SetFont, override DPI instead --- src/msw/graphics.cpp | 47 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index d3a981c60d..4af45bb4b0 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -536,40 +536,7 @@ class wxGDIPlusPrintingContext : public wxGDIPlusContext public: wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, const wxDC& dc ); - // Override to scale the font proportionally to the DPI. - virtual void SetFont(const wxGraphicsFont& font) wxOVERRIDE - { - // The casts here are safe because we're only supposed to be passed - // fonts created by this renderer. - Font* const f = static_cast(font.GetRefData())->GetGDIPlusFont(); - Brush* const b = static_cast(font.GetRefData())->GetGDIPlusBrush(); - - // To scale the font, we need to create a new one which means - // retrieving all the parameters originally used to create the font. - FontFamily ffamily; - f->GetFamily(&ffamily); - - WCHAR familyName[LF_FACESIZE]; - ffamily.GetFamilyName(familyName); - - wxGraphicsFont fontScaled; - fontScaled.SetRefData(new wxGDIPlusFontData - ( - GetRenderer(), - familyName, - f->GetSize() / m_fontScaleRatio, - f->GetStyle(), - b->Clone() - )); - wxGDIPlusContext::SetFont(fontScaled); - } - -private: - // This is logically const ratio between this context DPI and the standard - // one which is used for scaling the fonts used with this context: without - // this, the fonts wouldn't have the correct size, even though we - // explicitly create them using UnitPoint units. - wxDouble m_fontScaleRatio; + void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; }; //----------------------------------------------------------------------------- @@ -2438,10 +2405,16 @@ wxGDIPlusPrintingContext::wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer // wxEnhMetaFileDC). REAL dpiRatio = 100.0 / context->GetDpiY(); context->SetPageScale(dpiRatio); +} - // We use this modifier when measuring fonts. It is needed because the - // page scale is modified above. - m_fontScaleRatio = context->GetDpiY() / 96.0; +void wxGDIPlusPrintingContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const +{ + // override to use same scaling as wxWindowsPrintPreview::DetermineScaling + ScreenHDC hdc; + if ( dpiX ) + *dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX); + if ( dpiY ) + *dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY); } //----------------------------------------------------------------------------- From a0359a23ffa06039165d53b3f8ec6e496b1ff027 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 10 Oct 2019 20:26:19 +0200 Subject: [PATCH 11/12] Fix wxSTC compilation without precompilead headers Get and release the HDC, instead of using WindowHDC. Because stc.cpp is used on all platforms, don't include wxMSW specific wx/msw/private.h. Also use const int for the variables. --- src/stc/stc.cpp | 12 +++++++----- src/stc/stc.cpp.in | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/stc/stc.cpp b/src/stc/stc.cpp index 226839a2c6..df2bd96efb 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -241,12 +241,14 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, #endif #ifdef __WXMSW__ - // Set zoom for DPI - double baseDPI = ::GetDeviceCaps(WindowHDC(parent->GetHWND()), LOGPIXELSY); - double activeDPI = parent->GetDPI().y; + // Set initial zoom for active DPI + const HDC hdc = ::GetDC(parent->GetHWND()); + const int baseDPI = ::GetDeviceCaps(hdc, LOGPIXELSY); + const int activeDPI = parent->GetDPI().y; + ::ReleaseDC(parent->GetHWND(), hdc); - int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); - int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + const int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + const int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); #endif diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 83d8f4bf4c..d2a256e20c 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -241,12 +241,14 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, #endif #ifdef __WXMSW__ - // Set zoom for DPI - double baseDPI = ::GetDeviceCaps(WindowHDC(parent->GetHWND()), LOGPIXELSY); - double activeDPI = parent->GetDPI().y; + // Set initial zoom for active DPI + const HDC hdc = ::GetDC(parent->GetHWND()); + const int baseDPI = ::GetDeviceCaps(hdc, LOGPIXELSY); + const int activeDPI = parent->GetDPI().y; + ::ReleaseDC(parent->GetHWND(), hdc); - int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); - int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + const int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + const int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); #endif From 591136c7bc603f6fdafb91aeea4f2e32ed320f6e Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Fri, 11 Oct 2019 19:22:07 +0200 Subject: [PATCH 12/12] Improve button heights at high DPI on wxMSW Don't use FromDIP together with ConvertDialogToPixels, because the font height is already adjusted to the DPI. Also limit the button height at higher DPI. Because the height determined by ConvertDialogToPixels is higher than standard buttons use on Windows. Closes #18528 --- src/msw/anybutton.cpp | 11 +++++++++-- src/msw/gauge.cpp | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/msw/anybutton.cpp b/src/msw/anybutton.cpp index 76021aa0ae..b5e97de827 100644 --- a/src/msw/anybutton.cpp +++ b/src/msw/anybutton.cpp @@ -431,8 +431,15 @@ wxSize wxMSWButton::IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size // // Note that we intentionally don't use GetDefaultSize() here, because // it's inexact -- dialog units depend on this dialog's font. - const wxSize sizeDef = btn->ConvertDialogToPixels(btn->FromDIP(wxSize(50, 14))); - + wxSize sizeDef = btn->ConvertDialogToPixels(wxSize(50, 14)); + if ( btn->GetContentScaleFactor() > 1.0 ) + { + // At higher DPI, the returned height is too big compared to + // standard Windows buttons (like Save, Open, OK). FromDIP(25) + // matches the size of the buttons in standard Windows dialogs, see + // https://trac.wxwidgets.org/ticket/18528 for the discussion. + sizeDef.y = btn->FromDIP(25); + } sizeBtn.IncTo(sizeDef); } else // wxBU_EXACTFIT case diff --git a/src/msw/gauge.cpp b/src/msw/gauge.cpp index af7cefdee5..ac03441790 100644 --- a/src/msw/gauge.cpp +++ b/src/msw/gauge.cpp @@ -122,9 +122,9 @@ wxSize wxGauge::DoGetBestSize() const // the smaller one. if (HasFlag(wxGA_VERTICAL)) - return ConvertDialogToPixels(FromDIP(wxSize(8, 107))); + return ConvertDialogToPixels(wxSize(8, 107)); else - return ConvertDialogToPixels(FromDIP(wxSize(107, 8))); + return ConvertDialogToPixels(wxSize(107, 8)); } // ----------------------------------------------------------------------------