Simplify PPI and scale factor handling in wxDisplay

Don't try computing the PPI ourselves from the physical size and the
number of pixels, this doesn't work and nobody else does it like this.

Just assume that we're using standard PPI by default and use
toolkit-specific functions for the platforms with support for high DPI.
This commit is contained in:
Vadim Zeitlin
2020-08-14 15:17:59 +02:00
parent 4e6df3f7b2
commit bcb101b9e9
4 changed files with 13 additions and 85 deletions

View File

@@ -115,13 +115,11 @@ public:
// return the scale factor used to convert logical pixels to physical ones
virtual double GetScaleFactor() const { return 1.0; }
// return the resolution of the display, uses GetSize(), GetScaleFactor()
// and GetSizeMM() by default but can be also overridden directly
virtual wxSize GetPPI() const;
// return the resolution of the display, by default uses GetScaleFactor(),
// but can be also overridden directly, as is done in wxMSW
virtual wxSize GetPPI() const { return wxDisplay::GetStdPPI()*GetScaleFactor(); }
// return the physical size of the display or (0, 0) if unknown: this is
// only used by GetPPI() implementation in the base class, so if GetPPI()
// is overridden, this one doesn't have to be implemented
// return the physical size of the display or (0, 0) if unknown
virtual wxSize GetSizeMM() const { return wxSize(0, 0); }
// return the name (may be empty)
@@ -149,11 +147,6 @@ protected:
// create the object providing access to the display with the given index
wxDisplayImpl(unsigned n) : m_index(n) { }
// Compute PPI from the sizes in pixels and mm.
//
// Return (0, 0) if physical size (in mm) is not known, i.e. 0.
static wxSize ComputePPI(int pxX, int pxY, int mmX, int mmY);
// the index of this display (0 is always the primary one)
const unsigned m_index;

View File

@@ -153,19 +153,7 @@ double wxDisplay::GetScaleFactor() const
{
wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") );
#ifdef wxHAVE_DPI_INDEPENDENT_PIXELS
// Use wxDisplayImpl::GetScaleFactor() directly, it should be implemented
// correctly for the platforms doing pixel scaling and using it simpler and
// more efficient than using GetPPI().
return m_impl->GetScaleFactor();
#else
// Under the other platforms, we just compute the DPI ratio ourselves.
//
// We 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.
return m_impl->GetPPI().y / (double)GetStdPPIValue();
#endif
}
int wxDisplay::GetDepth() const
@@ -226,35 +214,6 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode)
return *gs_factory;
}
// ============================================================================
// wxDisplayImpl implementation
// ============================================================================
/* static */
wxSize wxDisplayImpl::ComputePPI(int pxX, int pxY, int mmX, int mmY)
{
if ( !mmX || !mmY )
{
// Physical size is unknown, return a special value indicating that we
// can't compute the resolution -- what else can we do?
return wxSize(0, 0);
}
return wxSize(wxRound((pxX * inches2mm) / mmX),
wxRound((pxY * inches2mm) / mmY));
}
wxSize wxDisplayImpl::GetPPI() const
{
const wxSize mm = GetSizeMM();
// We need physical pixels here, not logical ones returned by
// GetGeometry(), to compute the real DPI.
const wxSize pixels = GetGeometry().GetSize()*GetScaleFactor();
return ComputePPI(pixels.x, pixels.y, mm.x, mm.y);
}
// ============================================================================
// wxDisplayFactory implementation
// ============================================================================

View File

@@ -255,7 +255,6 @@ public:
#if GTK_CHECK_VERSION(3,10,0)
virtual double GetScaleFactor() const wxOVERRIDE;
#endif // GTK+ 3.10
virtual wxSize GetPPI() const wxOVERRIDE;
virtual wxSize GetSizeMM() const wxOVERRIDE;
#if wxUSE_DISPLAY
@@ -350,36 +349,6 @@ double wxDisplayImplGTK::GetScaleFactor() const
return 1.0;
}
wxSize wxDisplayImplGTK::GetPPI() const
{
// The useful value of PPI is the scaled value of the default PPI and not
// the actual PPI computed by dividing the number of pixels by the physical
// screen size: this is what everyone else uses, and so we should do it
// too.
return wxDisplay::GetStdPPI()*GetScaleFactor();
}
#else // GTK+ < 3.10
wxSize wxDisplayImplGTK::GetPPI() const
{
// Try the base class version which uses our GetSizeMM() and returns
// per-display PPI value if it works.
wxSize ppi = wxDisplayImpl::GetPPI();
if ( !ppi.x || !ppi.y )
{
// But if it didn't work, fall back to the global DPI value common to
// all displays -- this is still better than nothing and more
// compatible with the previous wxWidgets versions.
ppi = ComputePPI(gdk_screen_width(), gdk_screen_height(),
gdk_screen_width_mm(), gdk_screen_height_mm());
}
return ppi;
}
#endif // GTK+ 3.10
wxSize wxDisplayImplGTK::GetSizeMM() const
@@ -403,9 +372,9 @@ wxSize wxDisplayImplGTK::GetSizeMM() const
// When we have only a single display, we can use global GTK+ functions.
// Note that at least in some configurations, these functions return valid
// values when gdk_screen_get_monitor_xxx_mm() only return -1, so it's
// always worth fallng back on them, but we can't do it when using
// always worth falling back on them, but we can't do it when using
// multiple displays because they combine the sizes of all displays in this
// case, which would result in a completely wrong value for GetPPI().
// case, which would result in a completely wrong value.
if ( !(sizeMM.x && sizeMM.y) && gdk_screen_get_n_monitors(m_screen) == 1 )
{
sizeMM.x = gdk_screen_width_mm();

View File

@@ -141,6 +141,7 @@ public:
virtual wxRect GetClientArea() const wxOVERRIDE;
virtual int GetDepth() const wxOVERRIDE;
virtual wxSize GetPPI() const wxOVERRIDE;
virtual double GetScaleFactor() const wxOVERRIDE;
virtual wxString GetName() const wxOVERRIDE;
virtual bool IsPrimary() const wxOVERRIDE;
@@ -332,6 +333,12 @@ wxSize wxDisplayMSW::GetPPI() const
return IsPrimary() ? wxDisplayImplSingleMSW().GetPPI() : wxSize(0, 0);
}
double wxDisplayMSW::GetScaleFactor() const
{
const int ppi = GetPPI().y;
return ppi ? ppi / (double)wxDisplay::GetStdPPIValue() : 1.0;
}
wxString wxDisplayMSW::GetName() const
{
return m_info.monInfo.szDevice;