Comment dessiner et remplir une forme complexe

Direct2D fournit l’interface ID2D1PathGeometry pour décrire des formes complexes pouvant contenir des courbes, des arcs et des lignes. Cette rubrique explique comment définir et restituer une géométrie de chemin d’accès.

Pour définir une géométrie de chemin d’accès, utilisez d’abord la méthode ID2D1Factory::CreatePathGeometry pour créer la géométrie de chemin d’accès, puis utilisez la méthode Open de la géométrie du chemin d’accès pour récupérer un ID2D1GeometrySink. Vous pouvez ensuite ajouter des lignes, des courbes et des arcs en appelant les différentes méthodes Add du récepteur.

L’exemple suivant crée un ID2D1PathGeometry, récupère un récepteur et l’utilise pour définir une forme de sablier.

ID2D1GeometrySink *pSink = NULL;

// Create a path geometry.
if (SUCCEEDED(hr))
{
    hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry);

    if (SUCCEEDED(hr))
    {
        // Write to the path geometry using the geometry sink.
        hr = m_pPathGeometry->Open(&pSink);

        if (SUCCEEDED(hr))
        {
            pSink->BeginFigure(
                D2D1::Point2F(0, 0),
                D2D1_FIGURE_BEGIN_FILLED
                );

            pSink->AddLine(D2D1::Point2F(200, 0));

            pSink->AddBezier(
                D2D1::BezierSegment(
                    D2D1::Point2F(150, 50),
                    D2D1::Point2F(150, 150),
                    D2D1::Point2F(200, 200))
                );

            pSink->AddLine(D2D1::Point2F(0, 200));

            pSink->AddBezier(
                D2D1::BezierSegment(
                    D2D1::Point2F(50, 150),
                    D2D1::Point2F(50, 50),
                    D2D1::Point2F(0, 0))
                );

            pSink->EndFigure(D2D1_FIGURE_END_CLOSED);

            hr = pSink->Close();
        }
        SafeRelease(&pSink);
    }
}

Notez qu’une id2D1PathGeometry est une ressource indépendante de l’appareil et peut donc être créée une seule fois et conservée pendant la durée de vie de l’application. (Pour plus d’informations sur les différents types de ressources, consultez Vue d’ensemble des ressources.)

L’exemple suivant crée deux pinceaux qui seront utilisés pour peindre le contour et le remplissage de la géométrie du chemin.

if (SUCCEEDED(hr))
{
    // Create a black brush.
    hr = m_pRenderTarget->CreateSolidColorBrush(
        D2D1::ColorF(D2D1::ColorF::Black),
        &m_pBlackBrush
        );
}

if (SUCCEEDED(hr))
{
    // Create a linear gradient.
    static const D2D1_GRADIENT_STOP stops[] =
    {
        {   0.f,  { 0.f, 1.f, 1.f, 0.25f }  },
        {   1.f,  { 0.f, 0.f, 1.f, 1.f }  },
    };

    hr = m_pRenderTarget->CreateGradientStopCollection(
        stops,
        ARRAYSIZE(stops),
        &pGradientStops
        );

    if (SUCCEEDED(hr))
    {
        hr = m_pRenderTarget->CreateLinearGradientBrush(
            D2D1::LinearGradientBrushProperties(
                D2D1::Point2F(100, 0),
                D2D1::Point2F(100, 200)),
            D2D1::BrushProperties(),
            pGradientStops,
            &m_pLGBrush
            );
    }

    SafeRelease(&pGradientStops);
}

Le dernier exemple utilise les méthodes DrawGeometry et FillGeometry pour peindre le contour et l’intérieur de la géométrie. Cet exemple génère la sortie illustrée dans l’illustration suivante.

illustration d’une géométrie en forme de sablier

void DemoApp::RenderGeometryExample()
{
    // Translate subsequent drawings by 20 device-independent pixels.
    m_pRenderTarget->SetTransform(
        D2D1::Matrix3x2F::Translation(20.f, 20.f)
        );

    // Draw the hour glass geometry at the upper left corner of the client area.
    m_pRenderTarget->DrawGeometry(m_pPathGeometry, m_pBlackBrush, 10.f);
    m_pRenderTarget->FillGeometry(m_pPathGeometry, m_pLGBrush);
}

Le code a été omis dans cet exemple. Pour plus d’informations sur les géométries, consultez Vue d’ensemble des géométries.