Fixed creating wxGraphicsContext with Direct2D renderer.

When render target to draw to a DC (created with ID2D1Factory::CreateDCRenderTarget method) is bound to the device context with ID2D1DCRenderTarget::BindDC method then not only the logical size of a DC needs to be taken into account but also the origin of this DC.
To get proper drawing output the coordinates of all drawing operations should be internally adjusted by this initial origin.
This corrective translation should be used only internally by wxGraphicsContext object and shouldn't be exposed through e.g. GetTransform() function and therefore it is stored separately (in a dedicated variable) and "subtracted" from actual transformation settings for reporting purposes.

See #17564
This commit is contained in:
Artur Wieczorek
2016-06-11 22:28:22 +02:00
parent 3eae97d2d7
commit a735371b0e

View File

@@ -3179,6 +3179,8 @@ protected:
hr = renderTarget->BindDC(m_hdc, &r);
wxCHECK_HRESULT_RET(hr);
renderTarget->SetTransform(
D2D1::Matrix3x2F::Translation(-r.left, -r.top));
m_nativeResource = renderTarget;
}
@@ -3414,6 +3416,7 @@ private:
ID2D1RenderTarget* m_cachedRenderTarget;
D2D1::Matrix3x2F m_initTransform;
private:
wxDECLARE_NO_COPY_CLASS(wxD2DContext);
};
@@ -3694,7 +3697,9 @@ void wxD2DContext::SetTransform(const wxGraphicsMatrix& matrix)
{
EnsureInitialized();
GetRenderTarget()->SetTransform(wxGetD2DMatrixData(matrix)->GetMatrix3x2F());
D2D1::Matrix3x2F m;
m.SetProduct(wxGetD2DMatrixData(matrix)->GetMatrix3x2F(), m_initTransform);
GetRenderTarget()->SetTransform(&m);
}
wxGraphicsMatrix wxD2DContext::GetTransform() const
@@ -3704,6 +3709,16 @@ wxGraphicsMatrix wxD2DContext::GetTransform() const
if (GetRenderTarget() != NULL)
{
GetRenderTarget()->GetTransform(&transformMatrix);
if ( m_initTransform.IsInvertible() )
{
D2D1::Matrix3x2F invMatrix = m_initTransform;
invMatrix.Invert();
D2D1::Matrix3x2F m;
m.SetProduct(transformMatrix, invMatrix);
transformMatrix = m;
}
}
else
{
@@ -3825,7 +3840,7 @@ void wxD2DContext::EnsureInitialized()
if (!m_renderTargetHolder->IsResourceAcquired())
{
m_cachedRenderTarget = m_renderTargetHolder->GetD2DResource();
GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
GetRenderTarget()->GetTransform(&m_initTransform);
GetRenderTarget()->BeginDraw();
}
else