From 2c3c841719b1a96bcff8fb0b13dae134b8dd72b7 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sun, 27 Sep 2020 10:38:08 +0200 Subject: [PATCH] Implement platform-specific coordinate conversion functions Generic wxDC::DeviceToLogicalRel{X|Y}() and wxDC::LogicalToDeviceRel{X|Y}() functions don't take into account scaling applied with wxDC::SetTransformMatrix(). We need to implement in wxDCImpl and its platform-specific derivates new conversion functions that take all applied transformations into account. See #18923. --- include/wx/dc.h | 2 ++ include/wx/dcgraph.h | 2 ++ include/wx/msw/dc.h | 2 ++ src/common/dcbase.cpp | 10 ++++++++++ src/common/dcgraph.cpp | 16 ++++++++++++++++ src/msw/dc.cpp | 22 ++++++++++++++++++++++ 6 files changed, 54 insertions(+) diff --git a/include/wx/dc.h b/include/wx/dc.h index 7cf8ba7873..41f6d8212e 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -325,6 +325,8 @@ public: // coordinates conversions and transforms virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const; virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const; + virtual wxSize DeviceToLogicalRel(int x, int y) const; + virtual wxSize LogicalToDeviceRel(int x, int y) const; // bounding box diff --git a/include/wx/dcgraph.h b/include/wx/dcgraph.h index 4622a3534a..e483d58e81 100644 --- a/include/wx/dcgraph.h +++ b/include/wx/dcgraph.h @@ -124,6 +124,8 @@ public: // coordinates conversions and transforms virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE; virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE; + virtual wxSize DeviceToLogicalRel(int x, int y) const wxOVERRIDE; + virtual wxSize LogicalToDeviceRel(int x, int y) const wxOVERRIDE; // the true implementations virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index faaab34283..677eeac823 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -88,6 +88,8 @@ public: virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE; virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE; + virtual wxSize DeviceToLogicalRel(int x, int y) const wxOVERRIDE; + virtual wxSize LogicalToDeviceRel(int x, int y) const wxOVERRIDE; #if wxUSE_DC_TRANSFORM_MATRIX virtual bool CanUseTransformMatrix() const wxOVERRIDE; diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 59f61bce0a..6f351dfdc1 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -512,6 +512,16 @@ wxPoint wxDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const return wxPoint(LogicalToDeviceX(x), LogicalToDeviceY(y)); } +wxSize wxDCImpl::DeviceToLogicalRel(int x, int y) const +{ + return wxSize(DeviceToLogicalXRel(x), DeviceToLogicalYRel(y)); +} + +wxSize wxDCImpl::LogicalToDeviceRel(int x, int y) const +{ + return wxSize(LogicalToDeviceXRel(x), LogicalToDeviceYRel(y)); +} + void wxDCImpl::ComputeScaleAndOrigin() { m_scaleX = m_logicalScaleX * m_userScaleX; diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index cd6c8d206e..ff53f27331 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -613,6 +613,22 @@ wxPoint wxGCDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const return wxPoint(wxRound(px), wxRound(py)); } +wxSize wxGCDCImpl::DeviceToLogicalRel(int x, int y) const +{ + wxDouble dx = x; + wxDouble dy = y; + m_matrixCurrentInv.TransformDistance(&dx, &dy); + return wxSize(wxRound(dx), wxRound(dy)); +} + +wxSize wxGCDCImpl::LogicalToDeviceRel(int x, int y) const +{ + wxDouble dx = x; + wxDouble dy = y; + m_matrixCurrent.TransformDistance(&dx, &dy); + return wxSize(wxRound(dx), wxRound(dy)); +} + bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxColour& WXUNUSED(col), wxFloodFillStyle WXUNUSED(style)) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 6ebc77b68e..fe7fcd7737 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -2118,6 +2118,28 @@ wxPoint wxMSWDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const return wxPoint(p[0].x, p[0].y); } +wxSize wxMSWDCImpl::DeviceToLogicalRel(int x, int y) const +{ + POINT p[2]; + p[0].x = 0; + p[0].y = 0; + p[1].x = x; + p[1].y = y; + ::DPtoLP(GetHdc(), p, WXSIZEOF(p)); + return wxSize(p[1].x-p[0].x, p[1].y-p[0].y); +} + +wxSize wxMSWDCImpl::LogicalToDeviceRel(int x, int y) const +{ + POINT p[2]; + p[0].x = 0; + p[0].y = 0; + p[1].x = x; + p[1].y = y; + ::LPtoDP(GetHdc(), p, WXSIZEOF(p)); + return wxSize(p[1].x-p[0].x, p[1].y-p[0].y); +} + // ---------------------------------------------------------------------------- // Transform matrix // ----------------------------------------------------------------------------