ID2D1SimplifiedGeometrySink를 확장하여 기하 도형 데이터를 검색하는 방법
ID2D1Geometry 개체는 변경할 수 없지만 경로 기하 도형 개체에서 기하 도형 데이터를 조작해야 하는 경우가 있습니다. Direct2D를 사용하면 ID2D1SimplifiedGeometrySink라는 확장 가능한 인터페이스를 제공하여 이 작업을 수행할 수 있습니다. 개념 그림의 경우 이 항목에서는 이 인터페이스를 확장하여 경로 geometry 개체에서 기하 도형 데이터를 검색하는 방법을 설명합니다.
ID2D1SimplifiedGeometrySink 인터페이스를 확장하려면
- ID2D1SimplifiedGeometrySink에서 상속되는 클래스를 구현합니다.
- 해당 클래스의 instance 만들고 ID2D1Geometry::Simplify에 전달합니다.
다음 코드 예제에서는 ID2D1SimplifiedGeometrySink 인터페이스에서 상속하는 SpecializedSink라는 클래스를 구현하는 방법을 보여 줍니다. 개념 그림의 단순성을 위해 확장된 AddLines 메서드는 기하 도형 데이터를 검색한 다음 콘솔 창에 표시합니다. 특정 데이터 요구 사항에 맞게 이 메서드를 사용자 지정할 수 있습니다.
class SpecializedSink : public ID2D1SimplifiedGeometrySink
{
public:
SpecializedSink()
: m_cRef(1)
{
}
STDMETHOD_(ULONG, AddRef)(THIS)
{
return InterlockedIncrement(reinterpret_cast<LONG volatile *>(&m_cRef));
}
STDMETHOD_(ULONG, Release)(THIS)
{
ULONG cRef = static_cast<ULONG>(
InterlockedDecrement(reinterpret_cast<LONG volatile *>(&m_cRef)));
if(0 == cRef)
{
delete this;
}
return cRef;
}
STDMETHOD(QueryInterface)(THIS_ REFIID iid, void** ppvObject)
{
HRESULT hr = S_OK;
if (__uuidof(IUnknown) == iid)
{
*ppvObject = static_cast<IUnknown*>(this);
AddRef();
}
else if (__uuidof(ID2D1SimplifiedGeometrySink) == iid)
{
*ppvObject = static_cast<ID2D1SimplifiedGeometrySink*>(this);
AddRef();
}
else
{
*ppvObject = NULL;
hr = E_NOINTERFACE;
}
return hr;
}
STDMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT * /*beziers*/,
UINT /*beziersCount*/)
{
// Customize this method to meet your specific data needs.
}
STDMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointsCount)
{
// Customize this method to meet your specific data needs.
printf("\n\nRetrieving geometry data from a derived ID2D1SimplifiedGeometrySink object:\n");
for (UINT i = 0; i < pointsCount; ++i)
{
printf("%.0f, %.0f\n", points[i].x, points[i].y);
}
}
STDMETHOD_(void, BeginFigure)(D2D1_POINT_2F startPoint,
D2D1_FIGURE_BEGIN figureBegin)
{
}
STDMETHOD_(void, EndFigure)(D2D1_FIGURE_END figureEnd)
{
}
STDMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode)
{
}
STDMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT vertexFlags)
{
}
STDMETHOD(Close)()
{
return S_OK;
}
private:
UINT m_cRef;
};
그런 다음, 데이터 집합(182, 209), (211, 251), (251, 226), (392, 360) 및 (101, 360)을 사용하여 데이터를 검색할 수 있는 채워진 경로 기하 도형(m_pGeometry)을 만듭니다.
hr = m_pD2DFactory->CreatePathGeometry(&m_pGeometry);
if(SUCCEEDED(hr))
{
ID2D1GeometrySink *pSink = NULL;
hr = m_pGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(101,360),
D2D1_FIGURE_BEGIN_FILLED
);
D2D1_POINT_2F points[5] = {
D2D1::Point2F(182,209),
D2D1::Point2F(211,251),
D2D1::Point2F(251,226),
D2D1::Point2F(392,360),
D2D1::Point2F(101,360),
};
printf("Adding the following geometry data to an ID2D1GeometrySink object:\n");
printf("182, 209\n");
printf("211, 251\n");
printf("251, 226\n");
printf("392, 360\n");
printf("101, 360\n");
pSink->AddLines(points, ARRAYSIZE(points));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
hr = pSink->Close();
pSink->Release();
마지막으로, 이 예제에서는 SpecializedSink 개체를 만든 다음 ID2D1Geometry::Simplify 메서드를 호출하여 SpecializedSink 개체와 D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES 매개 변수를 전달하여 곡선을 선 세그먼트로 평면화합니다.
SpecializedSink *pSpecializedSink = NULL;
if (SUCCEEDED(hr))
{
pSpecializedSink = new SpecializedSink();
if (!pSpecializedSink)
{
hr = E_OUTOFMEMORY;
}
}
if (SUCCEEDED(hr))
{
hr = m_pGeometry->Simplify(
D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES, // This causes any curves to be flattened into line segments.
NULL, // world transform
pSpecializedSink
);
if (SUCCEEDED(hr))
{
hr = pSpecializedSink->Close();
}
pSpecializedSink->Release();
}
프로그램은 다음 스크린샷과 같이 출력을 만듭니다.
관련 항목