Merge branch 'gtk-dpi'

A bunch of improvements for per-monitor DPI support in wxGTK and
wxGraphicsContext more generally.

Closes https://github.com/wxWidgets/wxWidgets/pull/995
This commit is contained in:
Vadim Zeitlin
2018-11-10 12:15:27 +01:00
23 changed files with 241 additions and 101 deletions

View File

@@ -138,6 +138,7 @@ All (GUI):
- Add strikethrough support for fonts defined in XRC. - Add strikethrough support for fonts defined in XRC.
- Add wxDisplay::GetPPI(). - Add wxDisplay::GetPPI().
- Add wxJoystickEvent::GetButtonOrdinal() (Mick Phillips). - Add wxJoystickEvent::GetButtonOrdinal() (Mick Phillips).
- Add wxGraphicsContext::GetWindow() and implement wxGraphicsContext::GetDPI().
wxGTK: wxGTK:

View File

@@ -49,6 +49,10 @@ public:
// primary display and the only one which is always supported // primary display and the only one which is always supported
wxDisplay(unsigned n = 0); wxDisplay(unsigned n = 0);
// create display object corresponding to the display of the given window
// or the default one if the window display couldn't be found
explicit wxDisplay(const wxWindow* window);
// dtor is not virtual as this is a concrete class not meant to be derived // dtor is not virtual as this is a concrete class not meant to be derived
// from // from

View File

@@ -452,7 +452,7 @@ private:
class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject
{ {
public: public:
wxGraphicsContext(wxGraphicsRenderer* renderer); wxGraphicsContext(wxGraphicsRenderer* renderer, wxWindow* window = NULL);
virtual ~wxGraphicsContext(); virtual ~wxGraphicsContext();
@@ -490,6 +490,9 @@ public:
// create a context that can be used for measuring texts only, no drawing allowed // create a context that can be used for measuring texts only, no drawing allowed
static wxGraphicsContext * Create(); static wxGraphicsContext * Create();
// Return the window this context is associated with, if any.
wxWindow* GetWindow() const { return m_window; }
// begin a new document (relevant only for printing / pdf etc) if there is a progress dialog, message will be shown // begin a new document (relevant only for printing / pdf etc) if there is a progress dialog, message will be shown
virtual bool StartDoc( const wxString& message ); virtual bool StartDoc( const wxString& message );
@@ -788,6 +791,12 @@ protected:
wxDouble angle, wxDouble angle,
const wxGraphicsBrush& backgroundBrush); const wxGraphicsBrush& backgroundBrush);
private:
// The associated window, if any, i.e. if one was passed directly to
// Create() or the associated window of the wxDC this context was created
// from.
wxWindow* const m_window;
wxDECLARE_NO_COPY_CLASS(wxGraphicsContext); wxDECLARE_NO_COPY_CLASS(wxGraphicsContext);
wxDECLARE_ABSTRACT_CLASS(wxGraphicsContext); wxDECLARE_ABSTRACT_CLASS(wxGraphicsContext);
}; };

View File

@@ -81,8 +81,11 @@ public:
// return the depth or 0 if unknown // return the depth or 0 if unknown
virtual int GetDepth() const = 0; virtual int GetDepth() const = 0;
// return the resolution of the display, uses GetSizeMM() by default but // return the scale factor used to convert logical pixels to physical ones
// can be also overridden directly 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; virtual wxSize GetPPI() const;
// return the physical size of the display or (0, 0) if unknown: this is // return the physical size of the display or (0, 0) if unknown: this is
@@ -115,6 +118,11 @@ protected:
// create the object providing access to the display with the given index // create the object providing access to the display with the given index
wxDisplayImpl(unsigned n) : m_index(n) { } 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) // the index of this display (0 is always the primary one)
const unsigned m_index; const unsigned m_index;

View File

@@ -26,6 +26,23 @@ public:
*/ */
wxDisplay(unsigned int index = 0); wxDisplay(unsigned int index = 0);
/**
Constructor creating the display object associated with the given
window.
This is the most convenient way of finding the display on which the
given window is shown while falling back to the default display if it
is not shown at all or positioned outside of any display.
@param window
A valid, i.e. non-null, window.
@see GetFromWindow()
@since 3.1.2
*/
explicit wxDisplay(const wxWindow* window);
/** /**
Destructor. Destructor.
*/ */

View File

@@ -1095,6 +1095,19 @@ public:
*/ */
virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY);
/**
Returns the associated window if any.
If this context was created using Create() overload taking wxWindow or
wxWindowDC, this method returns the corresponding window. Otherwise
returns @NULL.
@return A possibly @NULL window pointer.
@since 3.1.2
*/
wxWindow* GetWindow() const;
/** @} /** @}
*/ */

View File

@@ -232,9 +232,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
#endif // wxUSE_STATUSBAR #endif // wxUSE_STATUSBAR
// create child controls // create child controls
wxPanel *panel = new wxPanel(this, wxID_ANY); m_book = new wxBookCtrl(this, wxID_ANY);
m_book = new wxBookCtrl(panel, wxID_ANY);
const size_t countDpy = wxDisplay::GetCount(); const size_t countDpy = wxDisplay::GetCount();
for ( size_t nDpy = 0; nDpy < countDpy; nDpy++ ) for ( size_t nDpy = 0; nDpy < countDpy; nDpy++ )
{ {
@@ -291,6 +289,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
sizer->Add(new wxStaticText(page, wxID_ANY, sizer->Add(new wxStaticText(page, wxID_ANY,
display.IsPrimary() ? "yes" : "no")); display.IsPrimary() ? "yes" : "no"));
// add it to another sizer to have borders around it and button below
wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
sizerTop->Add(sizer, 1, wxALL | wxEXPAND, 10); sizerTop->Add(sizer, 1, wxALL | wxEXPAND, 10);
@@ -313,22 +312,19 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
sizer->Add(new wxStaticText(page, Display_CurrentMode, sizer->Add(new wxStaticText(page, Display_CurrentMode,
VideoModeToText(display.GetCurrentMode()))); VideoModeToText(display.GetCurrentMode())));
// add it to another sizer to have borders around it and button below
sizerTop->Add(new wxButton(page, Display_ResetMode, "&Reset mode"), sizerTop->Add(new wxButton(page, Display_ResetMode, "&Reset mode"),
0, wxALL | wxCENTRE, 5); 0, wxALL | wxCENTRE, 5);
#endif // wxUSE_DISPLAY #endif // wxUSE_DISPLAY
page->SetSizer(sizerTop); page->SetSizer(sizerTop);
page->Layout();
m_book->AddPage(page, m_book->AddPage(page,
wxString::Format("Display %lu", wxString::Format("Display %lu",
(unsigned long)nDpy)); (unsigned long)nDpy));
} }
wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); SetClientSize(m_book->GetBestSize());
sizer->Add(m_book, 1, wxEXPAND);
panel->SetSizer(sizer);
sizer->SetSizeHints(this);
} }
#if wxUSE_DISPLAY #if wxUSE_DISPLAY

View File

@@ -418,6 +418,15 @@ void wxGCDCImpl::SetTextBackground( const wxColour &col )
wxSize wxGCDCImpl::GetPPI() const wxSize wxGCDCImpl::GetPPI() const
{ {
if ( m_graphicContext )
{
wxDouble x, y;
m_graphicContext->GetDPI(&x, &y);
return wxSize(wxRound(x), wxRound(y));
}
// This is the same value that wxGraphicsContext::GetDPI() returns by
// default.
return wxSize(72, 72); return wxSize(72, 72);
} }

View File

@@ -871,7 +871,7 @@ int wxStandardDialogLayoutAdapter::DoMustScroll(wxDialog* dialog, wxSize& window
wxSize minWindowSize = dialog->GetSizer()->GetMinSize(); wxSize minWindowSize = dialog->GetSizer()->GetMinSize();
windowSize = dialog->GetSize(); windowSize = dialog->GetSize();
windowSize = wxSize(wxMax(windowSize.x, minWindowSize.x), wxMax(windowSize.y, minWindowSize.y)); windowSize = wxSize(wxMax(windowSize.x, minWindowSize.x), wxMax(windowSize.y, minWindowSize.y));
displaySize = wxDisplay(wxDisplay::GetFromWindow(dialog)).GetClientArea().GetSize(); displaySize = wxDisplay(dialog).GetClientArea().GetSize();
int flags = 0; int flags = 0;

View File

@@ -85,6 +85,13 @@ wxDisplay::wxDisplay(unsigned n)
m_impl = Factory().GetDisplay(n); m_impl = Factory().GetDisplay(n);
} }
wxDisplay::wxDisplay(const wxWindow* window)
{
const int n = GetFromWindow(window);
m_impl = Factory().GetDisplay(n != wxNOT_FOUND ? n : 0);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// static functions forwarded to wxDisplayFactory // static functions forwarded to wxDisplayFactory
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -193,20 +200,29 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode)
// wxDisplayImpl implementation // wxDisplayImpl implementation
// ============================================================================ // ============================================================================
wxSize wxDisplayImpl::GetPPI() const /* static */
wxSize wxDisplayImpl::ComputePPI(int pxX, int pxY, int mmX, int mmY)
{ {
const wxSize pixels = GetGeometry().GetSize(); if ( !mmX || !mmY )
const wxSize mm = GetSizeMM();
if ( !mm.x || !mm.y )
{ {
// Physical size is unknown, return a special value indicating that we // Physical size is unknown, return a special value indicating that we
// can't compute the resolution -- what else can we do? // can't compute the resolution -- what else can we do?
return wxSize(0, 0); return wxSize(0, 0);
} }
return wxSize(wxRound((pixels.x * inches2mm) / mm.x), return wxSize(wxRound((pxX * inches2mm) / mmX),
wxRound((pixels.y * inches2mm) / mm.y)); 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);
} }
// ============================================================================ // ============================================================================
@@ -224,6 +240,8 @@ wxDisplayFactory::~wxDisplayFactory()
int wxDisplayFactory::GetFromWindow(const wxWindow *window) int wxDisplayFactory::GetFromWindow(const wxWindow *window)
{ {
wxCHECK_MSG( window, wxNOT_FOUND, "window can't be NULL" );
// consider that the window belongs to the display containing its centre // consider that the window belongs to the display containing its centre
const wxRect r(window->GetScreenRect()); const wxRect r(window->GetScreenRect());
return GetFromPoint(wxPoint(r.x + r.width/2, r.y + r.height/2)); return GetFromPoint(wxPoint(r.x + r.width/2, r.y + r.height/2));

View File

@@ -31,6 +31,8 @@
#include "wx/log.h" #include "wx/log.h"
#endif #endif
#include "wx/display.h"
#ifdef __WXMSW__ #ifdef __WXMSW__
#include "wx/msw/enhmeta.h" #include "wx/msw/enhmeta.h"
#endif #endif
@@ -565,12 +567,14 @@ void * wxGraphicsBitmap::GetNativeBitmap() const
wxIMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject); wxIMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject);
wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer,
wxGraphicsObject(renderer), wxWindow* window)
: wxGraphicsObject(renderer),
m_antialias(wxANTIALIAS_DEFAULT), m_antialias(wxANTIALIAS_DEFAULT),
m_composition(wxCOMPOSITION_OVER), m_composition(wxCOMPOSITION_OVER),
m_interpolation(wxINTERPOLATION_DEFAULT), m_interpolation(wxINTERPOLATION_DEFAULT),
m_enableOffset(false) m_enableOffset(false),
m_window(window)
{ {
} }
@@ -618,8 +622,19 @@ wxDouble wxGraphicsContext::GetAlpha() const
void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY)
{ {
*dpiX = 72.0; if ( m_window )
*dpiY = 72.0; {
const wxSize ppi = wxDisplay(m_window).GetPPI();
*dpiX = ppi.x;
*dpiY = ppi.y;
}
else
{
// Use some standard DPI value, it doesn't make much sense for the
// contexts not using any pixels anyhow.
*dpiX = 72.0;
*dpiY = 72.0;
}
} }
// sets the pen // sets the pen

View File

@@ -930,15 +930,9 @@ wxSize wxSizer::ComputeFittingClientSize(wxWindow *window)
return tlw->GetClientSize(); return tlw->GetClientSize();
} }
// limit the window to the size of the display it is on // limit the window to the size of the display it is on (or the main
int disp = wxDisplay::GetFromWindow(window); // one if the window display can't be determined)
if ( disp == wxNOT_FOUND ) sizeMax = wxDisplay(window).GetClientArea().GetSize();
{
// or, if we don't know which one it is, of the main one
disp = 0;
}
sizeMax = wxDisplay(disp).GetClientArea().GetSize();
// If determining the display size failed, skip the max size checks as // If determining the display size failed, skip the max size checks as
// we really don't want to create windows of (0, 0) size. // we really don't want to create windows of (0, 0) size.

View File

@@ -249,8 +249,7 @@ void wxTopLevelWindowBase::DoCentre(int dir)
// we need the display rect anyhow so store it first: notice that we should // we need the display rect anyhow so store it first: notice that we should
// be centered on the same display as our parent window, the display of // be centered on the same display as our parent window, the display of
// this window itself is not really defined yet // this window itself is not really defined yet
int nDisplay = wxDisplay::GetFromWindow(GetParent() ? GetParent() : this); wxDisplay dpy(GetParent() ? GetParent() : this);
wxDisplay dpy(nDisplay == wxNOT_FOUND ? 0 : nDisplay);
const wxRect rectDisplay(dpy.GetClientArea()); const wxRect rectDisplay(dpy.GetClientArea());
// what should we centre this window on? // what should we centre this window on?

View File

@@ -1830,7 +1830,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC&
#endif #endif
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc ) wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc )
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, dc.GetWindow())
{ {
int width, height; int width, height;
dc.GetSize( &width, &height ); dc.GetSize( &width, &height );
@@ -2244,7 +2244,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
} }
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window) wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, window)
#ifdef __WXMSW__ #ifdef __WXMSW__
, m_mswWindowHDC(GetHwndOf(window)) , m_mswWindowHDC(GetHwndOf(window))
#endif #endif

View File

@@ -318,11 +318,7 @@ private:
// Use GetFromWindow() and not GetFromPoint() here to try to get the // Use GetFromWindow() and not GetFromPoint() here to try to get the
// correct display even if the tip point itself is not visible. // correct display even if the tip point itself is not visible.
int dpy = wxDisplay::GetFromWindow(GetParent()); const wxRect rectDpy = wxDisplay(GetParent()).GetClientArea();
if ( dpy == wxNOT_FOUND )
dpy = 0; // What else can we do?
const wxRect rectDpy = wxDisplay(dpy).GetClientArea();
#ifdef __WXMAC__ #ifdef __WXMAC__
return pos.y > rectDpy.height/2 ? wxTipKind_Bottom : wxTipKind_Top; return pos.y > rectDpy.height/2 ? wxTipKind_Bottom : wxTipKind_Top;

View File

@@ -15,6 +15,7 @@
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/dcmemory.h" #include "wx/dcmemory.h"
#include "wx/dcscreen.h" #include "wx/dcscreen.h"
#include "wx/display.h"
#include "wx/gdicmn.h" #include "wx/gdicmn.h"
#include "wx/icon.h" #include "wx/icon.h"
#include "wx/gtk/dc.h" #include "wx/gtk/dc.h"
@@ -238,7 +239,7 @@ wxSize wxGTKCairoDCImpl::GetPPI() const
{ {
if ( m_window ) if ( m_window )
{ {
return wxGetDisplayPPI(); return wxDisplay(m_window).GetPPI();
} }
// For a non-window-based DC the concept of PPI doesn't make much sense // For a non-window-based DC the concept of PPI doesn't make much sense

View File

@@ -46,6 +46,7 @@ public:
virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetGeometry() const wxOVERRIDE;
virtual wxRect GetClientArea() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE;
virtual int GetDepth() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE;
virtual double GetScaleFactor() const wxOVERRIDE;
virtual wxSize GetSizeMM() const wxOVERRIDE; virtual wxSize GetSizeMM() const wxOVERRIDE;
#if wxUSE_DISPLAY #if wxUSE_DISPLAY
@@ -121,6 +122,11 @@ int wxDisplayImplGTK::GetDepth() const
return 24; return 24;
} }
double wxDisplayImplGTK::GetScaleFactor() const
{
return gdk_monitor_get_scale_factor(m_monitor);
}
wxSize wxDisplayImplGTK::GetSizeMM() const wxSize wxDisplayImplGTK::GetSizeMM() const
{ {
return wxSize return wxSize
@@ -222,6 +228,10 @@ public:
virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetGeometry() const wxOVERRIDE;
virtual wxRect GetClientArea() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE;
virtual int GetDepth() 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 GetPPI() const wxOVERRIDE;
virtual wxSize GetSizeMM() const wxOVERRIDE; virtual wxSize GetSizeMM() const wxOVERRIDE;
#if wxUSE_DISPLAY #if wxUSE_DISPLAY
@@ -293,16 +303,36 @@ int wxDisplayImplGTK::GetDepth() const
return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK())); return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK()));
} }
wxSize wxDisplayImplGTK::GetSizeMM() const #if GTK_CHECK_VERSION(3,10,0)
double wxDisplayImplGTK::GetScaleFactor() const
{ {
// At least in some configurations, gdk_screen_xxx_mm() functions return if ( gtk_check_version(3,10,0) == NULL )
// valid values when gdk_screen_get_monitor_xxx_mm() only return -1, so return gdk_screen_get_monitor_scale_factor(m_screen, m_index);
// handle this case specially.
if ( IsPrimary() ) return 1.0;
}
#endif // 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 )
{ {
return wxSize(gdk_screen_width_mm(), gdk_screen_height_mm()); // 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;
}
wxSize wxDisplayImplGTK::GetSizeMM() const
{
wxSize sizeMM; wxSize sizeMM;
#if GTK_CHECK_VERSION(2,14,0) #if GTK_CHECK_VERSION(2,14,0)
if ( wx_is_at_least_gtk2(14) ) if ( wx_is_at_least_gtk2(14) )
@@ -318,6 +348,19 @@ wxSize wxDisplayImplGTK::GetSizeMM() const
sizeMM.y = rc; sizeMM.y = rc;
} }
#endif // GTK+ 2.14 #endif // GTK+ 2.14
// 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
// multiple displays because they combine the sizes of all displays in this
// case, which would result in a completely wrong value for GetPPI().
if ( !(sizeMM.x && sizeMM.y) && gdk_screen_get_n_monitors(m_screen) == 1 )
{
sizeMM.x = gdk_screen_width_mm();
sizeMM.y = gdk_screen_height_mm();
}
return sizeMM; return sizeMM;
} }

View File

@@ -358,7 +358,7 @@ class wxGDIPlusContext : public wxGraphicsContext
public: public:
wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ); wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc );
wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height ); wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height );
wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ); wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd, wxWindow* window = NULL);
wxGDIPlusContext( wxGraphicsRenderer* renderer, Graphics* gr); wxGDIPlusContext( wxGraphicsRenderer* renderer, Graphics* gr);
wxGDIPlusContext(wxGraphicsRenderer* renderer); wxGDIPlusContext(wxGraphicsRenderer* renderer);
@@ -1647,7 +1647,7 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDou
} }
wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ) wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc )
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, dc.GetWindow())
{ {
wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
HDC hdc = (HDC) msw->GetHDC(); HDC hdc = (HDC) msw->GetHDC();
@@ -1656,8 +1656,10 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc
Init(new Graphics(hdc), sz.x, sz.y); Init(new Graphics(hdc), sz.x, sz.y);
} }
wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ) wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer,
: wxGraphicsContext(renderer) HWND hwnd,
wxWindow* window )
: wxGraphicsContext(renderer, window)
{ {
RECT rect = wxGetWindowRect(hwnd); RECT rect = wxGetWindowRect(hwnd);
Init(new Graphics(hwnd), rect.right - rect.left, rect.bottom - rect.top); Init(new Graphics(hwnd), rect.right - rect.left, rect.bottom - rect.top);
@@ -2492,7 +2494,7 @@ wxGraphicsContext * wxGDIPlusRenderer::CreateContextFromNativeHDC(WXHDC dc)
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window ) wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window )
{ {
ENSURE_LOADED_OR_RETURN(NULL); ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusContext(this, (HWND) window->GetHWND() ); return new wxGDIPlusContext(this, (HWND) window->GetHWND(), window );
} }
// Path // Path

View File

@@ -3462,9 +3462,19 @@ public:
class wxD2DContext : public wxGraphicsContext, wxD2DResourceManager class wxD2DContext : public wxGraphicsContext, wxD2DResourceManager
{ {
public: public:
wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HWND hwnd); // Create the context for the given HWND, which may be associated (if it's
// non-null) with the given wxWindow.
wxD2DContext(wxGraphicsRenderer* renderer,
ID2D1Factory* direct2dFactory,
HWND hwnd,
wxWindow* window = NULL);
wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HDC hdc, const wxSize& dcSize, // Create the context for the given HDC which may be associated (if it's
// non-null) with the given wxDC.
wxD2DContext(wxGraphicsRenderer* renderer,
ID2D1Factory* direct2dFactory,
HDC hdc,
const wxDC* dc = NULL,
D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_IGNORE); D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_IGNORE);
#if wxUSE_IMAGE #if wxUSE_IMAGE
@@ -3612,8 +3622,11 @@ private:
// wxD2DContext implementation // wxD2DContext implementation
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HWND hwnd) : wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer,
wxGraphicsContext(renderer), m_direct2dFactory(direct2dFactory), ID2D1Factory* direct2dFactory,
HWND hwnd,
wxWindow* window) :
wxGraphicsContext(renderer, window), m_direct2dFactory(direct2dFactory),
#if wxD2D_DEVICE_CONTEXT_SUPPORTED #if wxD2D_DEVICE_CONTEXT_SUPPORTED
m_renderTargetHolder(new wxD2DDeviceContextResourceHolder(direct2dFactory, hwnd)) m_renderTargetHolder(new wxD2DDeviceContextResourceHolder(direct2dFactory, hwnd))
#else #else
@@ -3626,13 +3639,21 @@ wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dF
Init(); Init();
} }
wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HDC hdc, wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer,
const wxSize& dcSize, D2D1_ALPHA_MODE alphaMode) : ID2D1Factory* direct2dFactory,
wxGraphicsContext(renderer), m_direct2dFactory(direct2dFactory), HDC hdc,
const wxDC* dc,
D2D1_ALPHA_MODE alphaMode) :
wxGraphicsContext(renderer, dc->GetWindow()), m_direct2dFactory(direct2dFactory),
m_renderTargetHolder(new wxD2DDCRenderTargetResourceHolder(direct2dFactory, hdc, alphaMode)) m_renderTargetHolder(new wxD2DDCRenderTargetResourceHolder(direct2dFactory, hdc, alphaMode))
{ {
m_width = dcSize.GetWidth(); if ( dc )
m_height = dcSize.GetHeight(); {
const wxSize dcSize = dc->GetSize();
m_width = dcSize.GetWidth();
m_height = dcSize.GetHeight();
}
Init(); Init();
} }
@@ -4593,7 +4614,7 @@ wxD2DRenderer::~wxD2DRenderer()
wxGraphicsContext* wxD2DRenderer::CreateContext(const wxWindowDC& dc) wxGraphicsContext* wxD2DRenderer::CreateContext(const wxWindowDC& dc)
{ {
return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), dc.GetSize()); return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), &dc);
} }
wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc) wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc)
@@ -4601,7 +4622,7 @@ wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc)
wxBitmap bmp = dc.GetSelectedBitmap(); wxBitmap bmp = dc.GetSelectedBitmap();
wxASSERT_MSG( bmp.IsOk(), wxS("Should select a bitmap before creating wxGraphicsContext") ); wxASSERT_MSG( bmp.IsOk(), wxS("Should select a bitmap before creating wxGraphicsContext") );
return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), dc.GetSize(), return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), &dc,
bmp.HasAlpha() ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE); bmp.HasAlpha() ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE);
} }
@@ -4633,12 +4654,12 @@ wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeWindow(void* window)
wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeHDC(WXHDC dc) wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeHDC(WXHDC dc)
{ {
return new wxD2DContext(this, m_direct2dFactory, (HDC)dc, wxSize(0, 0)); return new wxD2DContext(this, m_direct2dFactory, (HDC)dc);
} }
wxGraphicsContext* wxD2DRenderer::CreateContext(wxWindow* window) wxGraphicsContext* wxD2DRenderer::CreateContext(wxWindow* window)
{ {
return new wxD2DContext(this, m_direct2dFactory, (HWND)window->GetHWND()); return new wxD2DContext(this, m_direct2dFactory, (HWND)window->GetHWND(), window);
} }
#if wxUSE_IMAGE #if wxUSE_IMAGE

View File

@@ -162,10 +162,7 @@ wxMessageDialog::HookFunction(int code, WXWPARAM wParam, WXLPARAM lParam)
void wxMessageDialog::ReplaceStaticWithEdit() void wxMessageDialog::ReplaceStaticWithEdit()
{ {
// check if the message box fits the display // check if the message box fits the display
int nDisplay = wxDisplay::GetFromWindow(this); const wxRect rectDisplay = wxDisplay(this).GetClientArea();
if ( nDisplay == wxNOT_FOUND )
nDisplay = 0;
const wxRect rectDisplay = wxDisplay(nDisplay).GetClientArea();
if ( rectDisplay.Contains(GetRect()) ) if ( rectDisplay.Contains(GetRect()) )
{ {

View File

@@ -756,8 +756,7 @@ void wxTopLevelWindowMSW::DoGetPosition(int *x, int *y) const
{ {
// we must use the correct display for the translation as the // we must use the correct display for the translation as the
// task bar might be shown on one display but not the other one // task bar might be shown on one display but not the other one
int n = wxDisplay::GetFromWindow(this); wxDisplay dpy(this);
wxDisplay dpy(n == wxNOT_FOUND ? 0 : n);
const wxPoint ptOfs = dpy.GetClientArea().GetPosition() - const wxPoint ptOfs = dpy.GetClientArea().GetPosition() -
dpy.GetGeometry().GetPosition(); dpy.GetGeometry().GetPosition();
@@ -916,11 +915,7 @@ bool wxTopLevelWindowMSW::ShowFullScreen(bool show, long style)
// resize to the size of the display containing us, falling back to the // resize to the size of the display containing us, falling back to the
// primary one // primary one
int dpy = wxDisplay::GetFromWindow(this); const wxRect rect = wxDisplay(this).GetGeometry();
if ( dpy == wxNOT_FOUND )
dpy = 0;
const wxRect rect = wxDisplay(dpy).GetGeometry();
SetSize(rect); SetSize(rect);

View File

@@ -1303,7 +1303,11 @@ bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillM
class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext
{ {
public: public:
wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 ); wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer,
CGContextRef cgcontext,
wxDouble width = 0,
wxDouble height = 0,
wxWindow* window = NULL );
wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ); wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window );
@@ -1509,7 +1513,12 @@ void wxMacCoreGraphicsContext::Init()
m_interpolation = wxINTERPOLATION_DEFAULT; m_interpolation = wxINTERPOLATION_DEFAULT;
} }
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer) wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer,
CGContextRef cgcontext,
wxDouble width,
wxDouble height,
wxWindow* window )
: wxGraphicsContext(renderer, window)
{ {
Init(); Init();
SetNativeContext(cgcontext); SetNativeContext(cgcontext);
@@ -1518,7 +1527,9 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer
m_initTransform = m_cgContext ? CGContextGetCTM(m_cgContext) : CGAffineTransformIdentity; m_initTransform = m_cgContext ? CGContextGetCTM(m_cgContext) : CGAffineTransformIdentity;
} }
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer) wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer,
wxWindow* window )
: wxGraphicsContext(renderer, window)
{ {
Init(); Init();
@@ -2694,26 +2705,18 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer()
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc ) wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc )
{ {
const wxDCImpl* impl = dc.GetImpl(); wxWindow* const win = dc.GetWindow();
wxWindowDCImpl *win_impl = wxDynamicCast( impl, wxWindowDCImpl ); wxCHECK_MSG( win, NULL, "Invalid wxWindowDC" );
if (win_impl)
{
int w, h;
win_impl->GetSize( &w, &h );
CGContextRef cgctx = 0;
wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext"); const wxSize sz = win->GetSize();
if (win_impl->GetWindow())
cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef());
// having a cgctx being NULL is fine (will be created on demand) // having a cgctx being NULL is fine (will be created on demand)
// this is the case for all wxWindowDCs except wxPaintDC // this is the case for all wxWindowDCs except wxPaintDC
wxMacCoreGraphicsContext *context = CGContextRef cgctx = (CGContextRef)(win->MacGetCGContextRef());
new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h ); wxMacCoreGraphicsContext *context =
context->EnableOffset(dc.GetContentScaleFactor() < 2); new wxMacCoreGraphicsContext( this, cgctx, sz.x, sz.y, win );
return context; context->EnableOffset(dc.GetContentScaleFactor() < 2);
} return context;
return NULL;
} }
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc ) wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc )

View File

@@ -1861,8 +1861,7 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
position.x = wxRound(position.x + rc.left); position.x = wxRound(position.x + rc.left);
position.y = wxRound(position.y + rc.top); position.y = wxRound(position.y + rc.top);
const int currentDisplay = wxDisplay::GetFromWindow(relativeWin); const wxRect displayRect = wxDisplay(relativeWin).GetClientArea();
const wxRect displayRect = wxDisplay(currentDisplay).GetClientArea();
if (position.x < displayRect.GetLeft()) if (position.x < displayRect.GetLeft())
position.x = displayRect.GetLeft(); position.x = displayRect.GetLeft();