HRESULT graphics::brush::RadialGradientBrush::CreateDeviceDependentResource(
    ID2D1RenderTarget *pRenderTarget,
    const D2D1_RECT_F &rect,
    FLOAT opacity)
{
    HRESULT hr = S_OK;
    CComPtr<ID2D1GradientStopCollection> gradientStopCollection;
    CHK_FATAL_HRESULT(pRenderTarget->CreateGradientStopCollection(
                          &m_gradientStops.front(),
                          static_cast<UINT>(m_gradientStops.size()),
                          D2D1_GAMMA_2_2,
                          D2D1_EXTEND_MODE_CLAMP,
                          &gradientStopCollection));
    D2D1_POINT_2F center;
    D2D1_POINT_2F offset;
    FLOAT radiusX, radiusY;
    _CalculateParameters(rect, center, offset, radiusX, radiusY);

    m_brush = nullptr;
    CHK_FATAL_HRESULT(
        pRenderTarget->CreateRadialGradientBrush(
            D2D1::RadialGradientBrushProperties(
                D2D1::Point2F(0, 0),
                offset,
                radiusX,
                radiusY
            ),
            D2D1::BrushProperties(opacity,
                                  D2D1::Matrix3x2F::Translation(center.x, center.y)),
            gradientStopCollection,
            &m_brush
        ));
    m_deviceDependentResourceCreated = (m_brush != nullptr);
    return hr;
}
ID2D1Brush *graphics::brush::RadialGradientBrush::GetBrush(const D2D1_RECT_F &rect, FLOAT opacity) {
    if (m_brush != nullptr) {
        D2D1_POINT_2F center;
        D2D1_POINT_2F offset;
        FLOAT radiusX, radiusY;
        _CalculateParameters(rect, center, offset, radiusX, radiusY);
        m_brush->SetCenter(D2D1::Point2F(0, 0));
        m_brush->SetGradientOriginOffset(offset);
        m_brush->SetRadiusX(radiusX);
        m_brush->SetRadiusY(radiusY);
        m_brush->SetTransform(D2D1::Matrix3x2F::Translation(center.x, center.y));
        m_brush->SetOpacity(opacity);
        return m_brush;
    } else {
        throw std::runtime_error("brush has not been created");
    }
}