Implement platform-specific coordinate conversion functions
Generic wxDC::DeviceToLogical{X|Y}() and wxDC::LogicalToDevice{X|Y}() functions don't take into account transformations applied with wxDC::SetTransformMatrix() so conversion results are invalid if wxDC is transformed with both e.g. wxDC::SetUserScale() and wxDC::SetTransformMatrix(). We need to implement functions in wxDCImpl and its platform-specific derivates to do this conversion with taking into account all applied transformations. See #18916.
This commit is contained in:
@@ -323,6 +323,10 @@ public:
|
|||||||
// flushing the content of this dc immediately eg onto screen
|
// flushing the content of this dc immediately eg onto screen
|
||||||
virtual void Flush() { }
|
virtual void Flush() { }
|
||||||
|
|
||||||
|
// coordinates conversions and transforms
|
||||||
|
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const;
|
||||||
|
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const;
|
||||||
|
|
||||||
// bounding box
|
// bounding box
|
||||||
|
|
||||||
virtual void CalcBoundingBox(wxCoord x, wxCoord y)
|
virtual void CalcBoundingBox(wxCoord x, wxCoord y)
|
||||||
|
@@ -121,6 +121,10 @@ public:
|
|||||||
virtual void ResetTransformMatrix() wxOVERRIDE;
|
virtual void ResetTransformMatrix() wxOVERRIDE;
|
||||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||||
|
|
||||||
|
// coordinates conversions and transforms
|
||||||
|
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE;
|
||||||
|
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE;
|
||||||
|
|
||||||
// the true implementations
|
// the true implementations
|
||||||
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
|
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
|
||||||
wxFloodFillStyle style = wxFLOOD_SURFACE) wxOVERRIDE;
|
wxFloodFillStyle style = wxFLOOD_SURFACE) wxOVERRIDE;
|
||||||
@@ -225,6 +229,7 @@ protected:
|
|||||||
bool m_logicalFunctionSupported;
|
bool m_logicalFunctionSupported;
|
||||||
wxGraphicsMatrix m_matrixOriginal;
|
wxGraphicsMatrix m_matrixOriginal;
|
||||||
wxGraphicsMatrix m_matrixCurrent;
|
wxGraphicsMatrix m_matrixCurrent;
|
||||||
|
wxGraphicsMatrix m_matrixCurrentInv;
|
||||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||||
wxAffineMatrix2D m_matrixExtTransform;
|
wxAffineMatrix2D m_matrixExtTransform;
|
||||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||||
|
@@ -86,6 +86,9 @@ public:
|
|||||||
virtual void SetDeviceOrigin(wxCoord x, wxCoord y) wxOVERRIDE;
|
virtual void SetDeviceOrigin(wxCoord x, wxCoord y) wxOVERRIDE;
|
||||||
virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp) wxOVERRIDE;
|
virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual wxPoint DeviceToLogical(wxCoord x, wxCoord y) const wxOVERRIDE;
|
||||||
|
virtual wxPoint LogicalToDevice(wxCoord x, wxCoord y) const wxOVERRIDE;
|
||||||
|
|
||||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||||
virtual bool CanUseTransformMatrix() const wxOVERRIDE;
|
virtual bool CanUseTransformMatrix() const wxOVERRIDE;
|
||||||
virtual bool SetTransformMatrix(const wxAffineMatrix2D& matrix) wxOVERRIDE;
|
virtual bool SetTransformMatrix(const wxAffineMatrix2D& matrix) wxOVERRIDE;
|
||||||
|
@@ -502,6 +502,16 @@ wxCoord wxDCImpl::LogicalToDeviceYRel(wxCoord y) const
|
|||||||
return wxRound((double)(y) * m_scaleY);
|
return wxRound((double)(y) * m_scaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxPoint wxDCImpl::DeviceToLogical(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
return wxPoint(DeviceToLogicalX(x), DeviceToLogicalY(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint wxDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
return wxPoint(LogicalToDeviceX(x), LogicalToDeviceY(y));
|
||||||
|
}
|
||||||
|
|
||||||
void wxDCImpl::ComputeScaleAndOrigin()
|
void wxDCImpl::ComputeScaleAndOrigin()
|
||||||
{
|
{
|
||||||
m_scaleX = m_logicalScaleX * m_userScaleX;
|
m_scaleX = m_logicalScaleX * m_userScaleX;
|
||||||
|
@@ -487,6 +487,8 @@ void wxGCDCImpl::ComputeScaleAndOrigin()
|
|||||||
m_matrixCurrent.Concat(mtxExt);
|
m_matrixCurrent.Concat(mtxExt);
|
||||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||||
m_graphicContext->ConcatTransform( m_matrixCurrent );
|
m_graphicContext->ConcatTransform( m_matrixCurrent );
|
||||||
|
m_matrixCurrentInv = m_matrixCurrent;
|
||||||
|
m_matrixCurrentInv.Invert();
|
||||||
m_isClipBoxValid = false;
|
m_isClipBoxValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -594,6 +596,23 @@ void wxGCDCImpl::ResetTransformMatrix()
|
|||||||
|
|
||||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||||
|
|
||||||
|
// coordinates conversions and transforms
|
||||||
|
wxPoint wxGCDCImpl::DeviceToLogical(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
wxDouble px = x;
|
||||||
|
wxDouble py = y;
|
||||||
|
m_matrixCurrentInv.TransformPoint(&px, &py);
|
||||||
|
return wxPoint(wxRound(px), wxRound(py));
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint wxGCDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
wxDouble px = x;
|
||||||
|
wxDouble py = y;
|
||||||
|
m_matrixCurrent.TransformPoint(&px, &py);
|
||||||
|
return wxPoint(wxRound(px), wxRound(py));
|
||||||
|
}
|
||||||
|
|
||||||
bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
|
bool wxGCDCImpl::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
|
||||||
const wxColour& WXUNUSED(col),
|
const wxColour& WXUNUSED(col),
|
||||||
wxFloodFillStyle WXUNUSED(style))
|
wxFloodFillStyle WXUNUSED(style))
|
||||||
|
@@ -2100,6 +2100,24 @@ void wxMSWDCImpl::SetDeviceOrigin(wxCoord x, wxCoord y)
|
|||||||
m_isClipBoxValid = false;
|
m_isClipBoxValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxPoint wxMSWDCImpl::DeviceToLogical(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
POINT p[1];
|
||||||
|
p[0].x = x;
|
||||||
|
p[0].y = y;
|
||||||
|
::DPtoLP(GetHdc(), p, WXSIZEOF(p));
|
||||||
|
return wxPoint(p[0].x, p[0].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint wxMSWDCImpl::LogicalToDevice(wxCoord x, wxCoord y) const
|
||||||
|
{
|
||||||
|
POINT p[1];
|
||||||
|
p[0].x = x;
|
||||||
|
p[0].y = y;
|
||||||
|
::LPtoDP(GetHdc(), p, WXSIZEOF(p));
|
||||||
|
return wxPoint(p[0].x, p[0].y);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Transform matrix
|
// Transform matrix
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user