diff --git a/include/wx/window.h b/include/wx/window.h index 6be9f2e1c4..b7980dd011 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -955,10 +955,31 @@ public: // DPI-independent pixels, or DIPs, are pixel values for the standard // 96 DPI display, they are scaled to take the current resolution into - // account (i.e. by the factor returned by GetContentScaleFactor()) if - // necessary for the current platform. + // account (i.e. multiplied by the same factor as returned by + // GetContentScaleFactor()) if necessary for the current platform. + // + // Currently the conversion factor is the same for all windows but this + // will change with the monitor-specific resolution support in the + // future, so prefer using the non-static member functions. + // + // Similarly, currently in practice the factor is the same in both + // horizontal and vertical directions, but this could, in principle, + // change too, so prefer using the overloads taking wxPoint or wxSize. - wxSize FromDIP(const wxSize& sz) const; + static wxSize FromDIP(const wxSize& sz, const wxWindowBase* w); + static wxPoint FromDIP(const wxPoint& pt, const wxWindowBase* w) + { + const wxSize sz = FromDIP(wxSize(pt.x, pt.y), w); + return wxPoint(sz.x, sz.y); + } + static int FromDIP(int d, const wxWindowBase* w) + { + return FromDIP(wxSize(d, 0), w).x; + } + + wxSize FromDIP(const wxSize& sz) const { return FromDIP(sz, this); } + wxPoint FromDIP(const wxPoint& pt) const { return FromDIP(pt, this); } + int FromDIP(int d) const { return FromDIP(d, this); } // Dialog units are based on the size of the current font. @@ -1961,7 +1982,11 @@ inline wxWindow *wxWindowBase::GetGrandParent() const #ifdef wxHAVE_DPI_INDEPENDENT_PIXELS // FromDIP() becomes trivial in this case, so make it inline to avoid overhead. -inline wxSize wxWindowBase::FromDIP(const wxSize& sz) const { return sz; } +inline wxSize +wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* WXUNUSED(w)) const +{ + return sz; +} #endif // wxHAVE_DPI_INDEPENDENT_PIXELS diff --git a/interface/wx/window.h b/interface/wx/window.h index 4f3f047745..61ddf118d0 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -947,6 +947,45 @@ public: */ wxSize FromDIP(const wxSize& sz) const; + /// @overload + wxPoint FromDIP(const wxPoint& pt) const; + + /** + Convert DPI-independent distance in pixels to the value in pixels + appropriate for the current toolkit. + + This is the same as FromDIP(const wxSize& sz) overload, but assumes + that the resolution is the same in horizontal and vertical directions. + + @since 3.1.0 + */ + int FromDIP(int d) const; + + /** + Non window-specific DPI-independent pixels conversion functions. + + The display resolution depends on the window in general as different + windows can appear on different monitors using different resolutions, + however sometimes no window is available for converting the resolution + independent pixels to the physical values and in this case these static + overloads can be used with @NULL value for @a w argument. + + Using these methods is discouraged as passing @NULL will prevent your + application from correctly supporting monitors with different + resolutions even in the future wxWidgets versions which will add + support for them, and passing non-@NULL window is just a less + convenient way of calling the non-static FromDIP() method. + + @since 3.1.0 + */ + static wxSize FromDIP(const wxSize& sz, const wxWindow* w); + + /// @overload + static wxPoint FromDIP(const wxPoint& pt, const wxWindow* w); + + /// @overload + static wxSize FromDIP(const wxSize& sz, const wxWindow* w); + /** This functions returns the best acceptable minimal size for the window. diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 29ae222d3c..6b22314729 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -99,6 +99,10 @@ bool IsInCaptureStack(wxWindowBase* win); } // wxMouseCapture +// We consider 96 DPI to be the standard value, this is correct at least for +// MSW, but could conceivably need adjustment for the other platforms. +static const int BASELINE_DPI = 96; + // ---------------------------------------------------------------------------- // static data // ---------------------------------------------------------------------------- @@ -801,11 +805,7 @@ double wxWindowBase::GetContentScaleFactor() const // We also use just the vertical component of the DPI because it's the one // that counts most and, in practice, it's equal to the horizontal one // anyhow. - // - // Finally, we consider 96 DPI to be the standard value, this is correct - // at least for MSW, but could conceivably need adjustment for the other - // platforms. - return wxScreenDC().GetPPI().y / 96.; + return double(wxScreenDC().GetPPI().y) / BASELINE_DPI; } // helper of GetWindowBorderSize(): as many ports don't implement support for @@ -2867,11 +2867,14 @@ void wxWindowBase::OnInternalIdle() #ifndef wxHAVE_DPI_INDEPENDENT_PIXELS -wxSize wxWindowBase::FromDIP(const wxSize& sz) const +/* static */ +wxSize +wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* WXUNUSED(w)) { - const double scale = GetContentScaleFactor(); + const wxSize dpi = wxScreenDC().GetPPI(); - return wxSize(wxRound(scale*sz.x), wxRound(scale*sz.y)); + return wxSize(wxMulDivInt32(sz.x, dpi.x, BASELINE_DPI), + wxMulDivInt32(sz.y, dpi.y, BASELINE_DPI)); } #endif // !wxHAVE_DPI_INDEPENDENT_PIXELS