Add wxDisplayImpl::GetScaleFactor() and implement it for wxGTK

We need to account for the scale factor under GTK+ (and, presumably,
under macOS) to compute the correct PPI value as it must use the number
of physical and not logical pixels.
This commit is contained in:
Vadim Zeitlin
2018-10-29 17:41:37 +01:00
parent 43d2b1db0e
commit f09b9dbfa2
3 changed files with 28 additions and 4 deletions

View File

@@ -81,8 +81,11 @@ public:
// return the depth or 0 if unknown
virtual int GetDepth() const = 0;
// return the resolution of the display, uses GetSizeMM() by default but
// can be also overridden directly
// 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 physical size of the display or (0, 0) if unknown: this is

View File

@@ -195,9 +195,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode)
wxSize wxDisplayImpl::GetPPI() const
{
const wxSize pixels = GetGeometry().GetSize();
const wxSize mm = GetSizeMM();
if ( !mm.x || !mm.y )
{
// Physical size is unknown, return a special value indicating that we
@@ -205,6 +203,10 @@ wxSize wxDisplayImpl::GetPPI() const
return wxSize(0, 0);
}
// We need physical pixels here, not logical ones returned by
// GetGeometry(), to compute the real DPI.
const wxSize pixels = GetGeometry().GetSize()*GetScaleFactor();
return wxSize(wxRound((pixels.x * inches2mm) / mm.x),
wxRound((pixels.y * inches2mm) / mm.y));
}

View File

@@ -46,6 +46,7 @@ public:
virtual wxRect GetGeometry() const wxOVERRIDE;
virtual wxRect GetClientArea() const wxOVERRIDE;
virtual int GetDepth() const wxOVERRIDE;
virtual double GetScaleFactor() const wxOVERRIDE;
virtual wxSize GetSizeMM() const wxOVERRIDE;
#if wxUSE_DISPLAY
@@ -121,6 +122,11 @@ int wxDisplayImplGTK::GetDepth() const
return 24;
}
double wxDisplayImplGTK::GetScaleFactor() const
{
return gdk_monitor_get_scale_factor(m_monitor);
}
wxSize wxDisplayImplGTK::GetSizeMM() const
{
return wxSize
@@ -222,6 +228,9 @@ public:
virtual wxRect GetGeometry() const wxOVERRIDE;
virtual wxRect GetClientArea() const wxOVERRIDE;
virtual int GetDepth() const wxOVERRIDE;
#if GTK_CHECK_VERSION(3,10,0)
virtual double GetScaleFactor() const wxOVERRIDE;
#endif // GTK+ 3.10
virtual wxSize GetSizeMM() const wxOVERRIDE;
#if wxUSE_DISPLAY
@@ -293,6 +302,16 @@ int wxDisplayImplGTK::GetDepth() const
return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK()));
}
#if GTK_CHECK_VERSION(3,10,0)
double wxDisplayImplGTK::GetScaleFactor() const
{
if ( gtk_check_version(3,10,0) == NULL )
return gdk_screen_get_monitor_scale_factor(m_screen, m_index);
return 1.0;
}
#endif // GTK+ 3.10
wxSize wxDisplayImplGTK::GetSizeMM() const
{
// At least in some configurations, gdk_screen_xxx_mm() functions return