#include "pch.h" #include "LinearGradientView.h" #if __has_include("LinearGradientView.g.cpp") #include "LinearGradientView.g.cpp" #endif #include "Utils.h" using namespace winrt; using namespace Microsoft::ReactNative; namespace winrt::RNSVG::implementation { void LinearGradientView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) { const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)}; for (auto const &pair : propertyMap) { auto const &propertyName{pair.first}; auto const &propertyValue{pair.second}; if (propertyName == "x1") { m_x1 = propertyValue.To(); } else if (propertyName == "y1") { m_y1 = propertyValue.To(); } else if (propertyName == "x2") { m_x2 = propertyValue.To(); } else if (propertyName == "y2") { m_y2 = propertyValue.To(); } else if (propertyName == "gradient") { m_stops = Utils::JSValueAsStops(propertyValue); } else if (propertyName == "gradientUnits") { m_gradientUnits = Utils::JSValueAsBrushUnits(propertyValue); } else if (propertyName == "gradientTransform") { m_transform = Utils::JSValueAsD2DTransform(propertyValue); if (propertyValue.IsNull()) { m_transform = D2D1::Matrix3x2F::Identity(); } } } __super::UpdateProperties(reader, forceUpdate, invalidate); SaveDefinition(); } void LinearGradientView::Unload() { m_stops.clear(); __super::Unload(); } void LinearGradientView::CreateBrush() { auto const root{SvgRoot()}; com_ptr deviceContext{get_self(root.DeviceContext())->Get()}; winrt::com_ptr stopCollection; winrt::check_hresult(deviceContext->CreateGradientStopCollection(&m_stops[0], static_cast(m_stops.size()), stopCollection.put())); Size size{root.CanvasSize()}; D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES brushProperties; brushProperties.startPoint = {0, 0}; brushProperties.endPoint = {size.Width, size.Height}; winrt::com_ptr linearBrush; winrt::check_hresult(deviceContext->CreateLinearGradientBrush(brushProperties, stopCollection.get(), linearBrush.put())); SetPoints(linearBrush.get(), {0, 0, size.Width, size.Height}); linearBrush->SetTransform(m_transform); m_brush = make(linearBrush.as()); } void LinearGradientView::UpdateBounds() { if (m_gradientUnits == "objectBoundingBox") { com_ptr brush{get_self(m_brush)->Get().as()}; SetPoints(brush.get(), m_bounds); } } void LinearGradientView::SetPoints(ID2D1LinearGradientBrush *brush, D2D1_RECT_F bounds) { float width{D2DHelpers::WidthFromD2DRect(bounds)}; float height{D2DHelpers::HeightFromD2DRect(bounds)}; float x1{Utils::GetAbsoluteLength(m_x1, width) + bounds.left}; float y1{Utils::GetAbsoluteLength(m_y1, height) + bounds.top}; float x2{Utils::GetAbsoluteLength(m_x2, width) + bounds.left}; float y2{Utils::GetAbsoluteLength(m_y2, height) + bounds.top}; brush->SetStartPoint({x1, y1}); brush->SetEndPoint({x2, y2}); } } // namespace winrt::RNSVG::implementation