Implement wxPolygonFillMode in GDI+ and D2D graphics contexts
Honour "fillStyle" parameter, which was previously ignored. Closes https://github.com/wxWidgets/wxWidgets/pull/1478
This commit is contained in:
parent
4b227835ac
commit
d10ed0b991
@ -1857,7 +1857,7 @@ void wxGDIPlusContext::StrokeLines( size_t n, const wxPoint2DDouble *points)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGDIPlusContext::DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode WXUNUSED(fillStyle) )
|
void wxGDIPlusContext::DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode fillStyle )
|
||||||
{
|
{
|
||||||
if (m_composition == wxCOMPOSITION_DEST)
|
if (m_composition == wxCOMPOSITION_DEST)
|
||||||
return;
|
return;
|
||||||
@ -1871,7 +1871,8 @@ void wxGDIPlusContext::DrawLines( size_t n, const wxPoint2DDouble *points, wxPol
|
|||||||
|
|
||||||
} // for (int i = 0; i < n; i++)
|
} // for (int i = 0; i < n; i++)
|
||||||
if ( !m_brush.IsNull() )
|
if ( !m_brush.IsNull() )
|
||||||
m_context->FillPolygon( ((wxGDIPlusBrushData*)m_brush.GetRefData())->GetGDIPlusBrush() , cpoints , n ) ;
|
m_context->FillPolygon( ((wxGDIPlusBrushData*)m_brush.GetRefData())->GetGDIPlusBrush() , cpoints , n ,
|
||||||
|
fillStyle == wxODDEVEN_RULE ? FillModeAlternate : FillModeWinding ) ;
|
||||||
if ( !m_pen.IsNull() )
|
if ( !m_pen.IsNull() )
|
||||||
m_context->DrawLines( ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen() , cpoints , n ) ;
|
m_context->DrawLines( ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen() , cpoints , n ) ;
|
||||||
delete[] cpoints;
|
delete[] cpoints;
|
||||||
|
@ -1143,6 +1143,16 @@ public :
|
|||||||
|
|
||||||
~wxD2DPathData();
|
~wxD2DPathData();
|
||||||
|
|
||||||
|
void SetFillMode(D2D1_FILL_MODE fillMode)
|
||||||
|
{
|
||||||
|
m_fillMode = fillMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
D2D1_FILL_MODE GetFillMode() const
|
||||||
|
{
|
||||||
|
return m_fillMode;
|
||||||
|
}
|
||||||
|
|
||||||
ID2D1PathGeometry* GetPathGeometry();
|
ID2D1PathGeometry* GetPathGeometry();
|
||||||
|
|
||||||
// This closes the geometry sink, ensuring all the figures are stored inside
|
// This closes the geometry sink, ensuring all the figures are stored inside
|
||||||
@ -1202,7 +1212,7 @@ private:
|
|||||||
|
|
||||||
void EndFigure(D2D1_FIGURE_END figureEnd);
|
void EndFigure(D2D1_FIGURE_END figureEnd);
|
||||||
|
|
||||||
ID2D1Geometry* GetFullGeometry() const;
|
ID2D1Geometry* GetFullGeometry(D2D1_FILL_MODE fillMode) const;
|
||||||
|
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
bool IsStateSafeForFlush() const;
|
bool IsStateSafeForFlush() const;
|
||||||
@ -1238,6 +1248,8 @@ private :
|
|||||||
D2D1_POINT_2F m_figureLogStart;
|
D2D1_POINT_2F m_figureLogStart;
|
||||||
|
|
||||||
bool m_geometryWritable;
|
bool m_geometryWritable;
|
||||||
|
|
||||||
|
D2D1_FILL_MODE m_fillMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1253,7 +1265,8 @@ wxD2DPathData::wxD2DPathData(wxGraphicsRenderer* renderer, ID2D1Factory* d2dFact
|
|||||||
m_figureStart(D2D1::Point2F(0.0f, 0.0f)),
|
m_figureStart(D2D1::Point2F(0.0f, 0.0f)),
|
||||||
m_figureLogStartSet(false),
|
m_figureLogStartSet(false),
|
||||||
m_figureLogStart(D2D1::Point2F(0.0f, 0.0f)),
|
m_figureLogStart(D2D1::Point2F(0.0f, 0.0f)),
|
||||||
m_geometryWritable(true)
|
m_geometryWritable(true),
|
||||||
|
m_fillMode(D2D1_FILL_MODE_ALTERNATE)
|
||||||
{
|
{
|
||||||
m_direct2dfactory->CreatePathGeometry(&m_pathGeometry);
|
m_direct2dfactory->CreatePathGeometry(&m_pathGeometry);
|
||||||
// To properly initialize path geometry there is also
|
// To properly initialize path geometry there is also
|
||||||
@ -1419,7 +1432,7 @@ void wxD2DPathData::EndFigure(D2D1_FIGURE_END figureEnd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1Geometry* wxD2DPathData::GetFullGeometry() const
|
ID2D1Geometry* wxD2DPathData::GetFullGeometry(D2D1_FILL_MODE fillMode) const
|
||||||
{
|
{
|
||||||
// Our final path geometry is represented by geometry group
|
// Our final path geometry is represented by geometry group
|
||||||
// which contains all transformed geometries plus current geometry.
|
// which contains all transformed geometries plus current geometry.
|
||||||
@ -1435,7 +1448,7 @@ ID2D1Geometry* wxD2DPathData::GetFullGeometry() const
|
|||||||
|
|
||||||
// And use this array as a source to create geometry group.
|
// And use this array as a source to create geometry group.
|
||||||
m_combinedGeometry.reset();
|
m_combinedGeometry.reset();
|
||||||
HRESULT hr = m_direct2dfactory->CreateGeometryGroup(D2D1_FILL_MODE_ALTERNATE,
|
HRESULT hr = m_direct2dfactory->CreateGeometryGroup(fillMode,
|
||||||
pGeometries, numGeometries+1, &m_combinedGeometry);
|
pGeometries, numGeometries+1, &m_combinedGeometry);
|
||||||
wxFAILED_HRESULT_MSG(hr);
|
wxFAILED_HRESULT_MSG(hr);
|
||||||
delete []pGeometries;
|
delete []pGeometries;
|
||||||
@ -1830,7 +1843,7 @@ void wxD2DPathData::CloseSubpath()
|
|||||||
|
|
||||||
void* wxD2DPathData::GetNativePath() const
|
void* wxD2DPathData::GetNativePath() const
|
||||||
{
|
{
|
||||||
return GetFullGeometry();
|
return GetFullGeometry(GetFillMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxD2DPathData::Transform(const wxGraphicsMatrixData* matrix)
|
void wxD2DPathData::Transform(const wxGraphicsMatrixData* matrix)
|
||||||
@ -1920,7 +1933,7 @@ void wxD2DPathData::Transform(const wxGraphicsMatrixData* matrix)
|
|||||||
void wxD2DPathData::GetBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble *h) const
|
void wxD2DPathData::GetBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble *h) const
|
||||||
{
|
{
|
||||||
D2D1_RECT_F bounds;
|
D2D1_RECT_F bounds;
|
||||||
ID2D1Geometry *curGeometry = GetFullGeometry();
|
ID2D1Geometry *curGeometry = GetFullGeometry(GetFillMode());
|
||||||
HRESULT hr = curGeometry->GetBounds(D2D1::Matrix3x2F::Identity(), &bounds);
|
HRESULT hr = curGeometry->GetBounds(D2D1::Matrix3x2F::Identity(), &bounds);
|
||||||
wxCHECK_HRESULT_RET(hr);
|
wxCHECK_HRESULT_RET(hr);
|
||||||
// Check if bounds are empty
|
// Check if bounds are empty
|
||||||
@ -1934,10 +1947,11 @@ void wxD2DPathData::GetBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble *h) c
|
|||||||
if (h) *h = bounds.bottom - bounds.top;
|
if (h) *h = bounds.bottom - bounds.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxD2DPathData::Contains(wxDouble x, wxDouble y, wxPolygonFillMode WXUNUSED(fillStyle)) const
|
bool wxD2DPathData::Contains(wxDouble x, wxDouble y, wxPolygonFillMode fillStyle) const
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
ID2D1Geometry *curGeometry = GetFullGeometry();
|
D2D1_FILL_MODE fillMode = (fillStyle == wxODDEVEN_RULE) ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING;
|
||||||
|
ID2D1Geometry *curGeometry = GetFullGeometry(fillMode);
|
||||||
curGeometry->FillContainsPoint(D2D1::Point2F(x, y), D2D1::Matrix3x2F::Identity(), &result);
|
curGeometry->FillContainsPoint(D2D1::Point2F(x, y), D2D1::Matrix3x2F::Identity(), &result);
|
||||||
return result != FALSE;
|
return result != FALSE;
|
||||||
}
|
}
|
||||||
@ -3939,7 +3953,7 @@ void wxD2DContext::StrokePath(const wxGraphicsPath& p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxD2DContext::FillPath(const wxGraphicsPath& p , wxPolygonFillMode WXUNUSED(fillStyle))
|
void wxD2DContext::FillPath(const wxGraphicsPath& p , wxPolygonFillMode fillStyle)
|
||||||
{
|
{
|
||||||
if (m_composition == wxCOMPOSITION_DEST)
|
if (m_composition == wxCOMPOSITION_DEST)
|
||||||
return;
|
return;
|
||||||
@ -3948,6 +3962,7 @@ void wxD2DContext::FillPath(const wxGraphicsPath& p , wxPolygonFillMode WXUNUSED
|
|||||||
AdjustRenderTargetSize();
|
AdjustRenderTargetSize();
|
||||||
|
|
||||||
wxD2DPathData* pathData = wxGetD2DPathData(p);
|
wxD2DPathData* pathData = wxGetD2DPathData(p);
|
||||||
|
pathData->SetFillMode(fillStyle == wxODDEVEN_RULE ? D2D1_FILL_MODE_ALTERNATE : D2D1_FILL_MODE_WINDING);
|
||||||
pathData->Flush();
|
pathData->Flush();
|
||||||
|
|
||||||
if (!m_brush.IsNull())
|
if (!m_brush.IsNull())
|
||||||
|
Loading…
Reference in New Issue
Block a user