// Drawing tile content into tile surfaces using D2D batching
HRESULT Application::DrawDCompTileSurfaces()
{
    HRESULT hr = S_OK;

    // Defining tile colors
    D2D1_COLOR_F dcompTileSurfaceBackgroundColors [] =
    {
        D2D1::ColorF(D2D1::ColorF::LightBlue),
        D2D1::ColorF(D2D1::ColorF::BlueViolet),
        D2D1::ColorF(D2D1::ColorF::Blue),
        D2D1::ColorF(D2D1::ColorF::Cyan)
    };

    D2D1_COLOR_F dcompTileSurfaceForegroundColors [] =
    {
        D2D1::ColorF(D2D1::ColorF::Black),
        D2D1::ColorF(D2D1::ColorF::Black),
        D2D1::ColorF(D2D1::ColorF::Black),
        D2D1::ColorF(D2D1::ColorF::Black),
    };

    // Defining tile content
    const wchar_t *dcompTileSurfaceTexts [] =
    {
        L"1",
        L"2",
        L"3",
        L"4"
    };

    UINT dcompTileSurfaceWidth = 2 * _hWndClientWidth / 8;
    UINT dcompTileSurfaceHeight = 2 * _hWndClientHeight / 8;

    // Drawing content for all tile surfaces
    for (int i = 0; SUCCEEDED(hr) && i < 4; ++i)
    {
        Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dDeviceContext;
        POINT updateOffset = { 0 };

        // Begin draw is using a D2D device context for D2D batching
        hr = _dcompTileSurfaces[i]->BeginDraw(nullptr, __uuidof(ID2D1DeviceContext) , reinterpret_cast<void **>(d2dDeviceContext.GetAddressOf()), &updateOffset);

        ShowMessageBoxIfFailed(hr, L"pDCompSurface->BeginDraw");

        if (SUCCEEDED(hr))
        {
            Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> d2dBackgroundBrush;

            if (SUCCEEDED(hr))
            {
                hr = d2dDeviceContext->CreateSolidColorBrush(dcompTileSurfaceBackgroundColors[i], &d2dBackgroundBrush);

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->CreateSolidColorBrush");
            }

            Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> d2dForegroundBrush;

            if (SUCCEEDED(hr))
            {
                hr = d2dDeviceContext->CreateSolidColorBrush(dcompTileSurfaceForegroundColors[i], &d2dForegroundBrush);

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->CreateSolidColorBrush");
            }

            Microsoft::WRL::ComPtr<IDWriteTextFormat> dwriteTextFormat;

            if (SUCCEEDED(hr))
            {
                hr = _dwriteFactory->CreateTextFormat(L"Verdana", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
                    DWRITE_FONT_STRETCH_NORMAL, 72.0f, L"en-us", &dwriteTextFormat);

                ShowMessageBoxIfFailed(hr, L"dwriteFactory->CreateTextFormat");
            }

            if (SUCCEEDED(hr))
            {
                hr = dwriteTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);

                ShowMessageBoxIfFailed(hr, L"dwriteTextFormat->SetTextAlignment");
            }

            if (SUCCEEDED(hr))
            {
                hr = dwriteTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

                ShowMessageBoxIfFailed(hr, L"dwriteTextFormat->SetParagraphAlignment");
            }

            if (SUCCEEDED(hr))
            {
                D2D1_RECT_F dcompTileSurfaceRect = D2D1::RectF(
                    updateOffset.x + 0.0f * dcompTileSurfaceWidth,
                    updateOffset.y + 0.0f * dcompTileSurfaceHeight,
                    updateOffset.x + 1.0f * dcompTileSurfaceWidth,
                    updateOffset.y + 1.0f * dcompTileSurfaceHeight
                    );

                d2dDeviceContext->FillRectangle(
                    dcompTileSurfaceRect,
                    d2dBackgroundBrush.Get());

                d2dDeviceContext->DrawText(
                    dcompTileSurfaceTexts[i],
                    wcslen(dcompTileSurfaceTexts[i]),
                    dwriteTextFormat.Get(),
                    &dcompTileSurfaceRect,
                    d2dForegroundBrush.Get());

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->EndDraw");
            }
        }

        if (SUCCEEDED(hr))
        {
            hr = _dcompTileSurfaces[i]->EndDraw();

            ShowMessageBoxIfFailed(hr, L"pDCompSurface->EndDraw");
        }
    }

    return hr;
}
// Defining text properties and drawing text into the DComp text surface
HRESULT Application::DrawDCompTextSurface()
{
    HRESULT hr = S_OK;

    UINT dcompTextSurfaceWidth = 7 * _hWndClientWidth / 8;
    UINT dcompTextSurfaceHeight = 2 * _hWndClientHeight / 8;

    if (SUCCEEDED(hr))
    {
        Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dDeviceContext;
        POINT updateOffset = { 0 };

        hr = _dcompTextSurface->BeginDraw(nullptr, __uuidof(ID2D1DeviceContext) , reinterpret_cast<void **>(d2dDeviceContext.GetAddressOf()), &updateOffset);

        ShowMessageBoxIfFailed(hr, L"_dcompTextSurface->BeginDraw");

        if (SUCCEEDED(hr))
        {
            Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> d2dBackgroundBrush;

            if (SUCCEEDED(hr))
            {
                hr = d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &d2dBackgroundBrush);

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->CreateSolidColorBrush");
            }

            Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> d2dForegroundBrush;

            if (SUCCEEDED(hr))
            {
                hr = d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &d2dForegroundBrush);

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->CreateSolidColorBrush");
            }

            Microsoft::WRL::ComPtr<IDWriteTextFormat> dwriteTextFormat;

            if (SUCCEEDED(hr))
            {
                hr = _dwriteFactory->CreateTextFormat(L"Verdana", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
                    DWRITE_FONT_STRETCH_NORMAL, 12.0f, L"en-us", &dwriteTextFormat);

                ShowMessageBoxIfFailed(hr, L"dwriteFactory->CreateTextFormat");
            }

            if (SUCCEEDED(hr))
            {
                hr = dwriteTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_JUSTIFIED);

                ShowMessageBoxIfFailed(hr, L"dwriteTextFormat->SetTextAlignment");
            }

            if (SUCCEEDED(hr))
            {
                hr = dwriteTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);

                ShowMessageBoxIfFailed(hr, L"dwriteTextFormat->SetParagraphAlignment");
            }

            if (SUCCEEDED(hr))
            {
                const wchar_t dcompTileSurfaceText [] = L"This sample demonstrates how to use DirectComposition to apply backface visibility and utilize performance optmization feature known as D2D Batching. Tiles 2 & 3 show backface visible while 1 & 4 show the backface hidden. \n\n"
                    L"Step 1. Tap or click any tile below \n"
                    L"Step 2. Reset by selecting background \n";

                D2D1_RECT_F dcompTextSurfaceRect = D2D1::RectF(
                    updateOffset.x + 0.0f * dcompTextSurfaceWidth,
                    updateOffset.y + 0.0f * dcompTextSurfaceHeight,
                    updateOffset.x + 1.0f * dcompTextSurfaceWidth,
                    updateOffset.y + 1.0f * dcompTextSurfaceHeight
                    );

                d2dDeviceContext->FillRectangle(
                    dcompTextSurfaceRect,
                    d2dBackgroundBrush.Get());

                d2dDeviceContext->DrawText(
                    dcompTileSurfaceText,
                    wcslen(dcompTileSurfaceText),
                    dwriteTextFormat.Get(),
                    &dcompTextSurfaceRect,
                    d2dForegroundBrush.Get());

                ShowMessageBoxIfFailed(hr, L"d2dDeviceContext->EndDraw");
            }
        }

        if (SUCCEEDED(hr))
        {
            hr = _dcompTextSurface->EndDraw();

            ShowMessageBoxIfFailed(hr, L"_dcompTextSurface->EndDraw");
        }
    }

    return hr;
}