void SVGRadialGradientElement::buildGradient() const { RadialGradientAttributes attributes = collectGradientProperties(); RefPtr<SVGPaintServerRadialGradient> radialGradient = WTF::static_pointer_cast<SVGPaintServerRadialGradient>(m_resource); double adjustedFocusX = attributes.fx(); double adjustedFocusY = attributes.fy(); double fdx = attributes.fx() - attributes.cx(); double fdy = attributes.fy() - attributes.cy(); // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and // r, set (fx, fy) to the point of intersection of the line through // (fx, fy) and the circle. if (sqrt(fdx * fdx + fdy * fdy) > attributes.r()) { double angle = atan2(attributes.fy() * 100.0, attributes.fx() * 100.0); adjustedFocusX = cos(angle) * attributes.r(); adjustedFocusY = sin(angle) * attributes.r(); } FloatPoint focalPoint = FloatPoint::narrowPrecision(attributes.fx(), attributes.fy()); FloatPoint centerPoint = FloatPoint::narrowPrecision(attributes.cx(), attributes.cy()); RefPtr<Gradient> gradient = Gradient::create( FloatPoint::narrowPrecision(adjustedFocusX, adjustedFocusY), 0.f, // SVG does not support a "focus radius" centerPoint, narrowPrecisionToFloat(attributes.r())); gradient->setSpreadMethod(attributes.spreadMethod()); Vector<SVGGradientStop> stops = attributes.stops(); float previousOffset = 0.0f; for (unsigned i = 0; i < stops.size(); ++i) { float offset = std::min(std::max(previousOffset, stops[i].first), 1.0f); previousOffset = offset; gradient->addColorStop(offset, stops[i].second); } radialGradient->setGradient(gradient); if (attributes.stops().isEmpty()) return; radialGradient->setBoundingBoxMode(attributes.boundingBoxMode()); radialGradient->setGradientTransform(attributes.gradientTransform()); radialGradient->setGradientCenter(centerPoint); radialGradient->setGradientFocal(focalPoint); radialGradient->setGradientRadius(narrowPrecisionToFloat(attributes.r())); radialGradient->setGradientStops(attributes.stops()); }
void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const { SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradientElement); RadialGradientAttributes attributes = radialGradientElement->collectGradientProperties(); // Determine gradient focal/center points and radius FloatPoint focalPoint; FloatPoint centerPoint; float radius; radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius); gradientData->gradient = Gradient::create(focalPoint, 0.0f, // SVG does not support a "focus radius" centerPoint, radius); gradientData->gradient->setSpreadMethod(attributes.spreadMethod()); // Record current gradient transform gradientData->transform = attributes.gradientTransform(); gradientData->boundingBoxMode = attributes.boundingBoxMode(); // Add stops addStops(gradientData, attributes.stops()); }
void SVGRadialGradientElement::buildGradient() const { RadialGradientAttributes attributes = collectGradientProperties(); // If we didn't find any gradient containing stop elements, ignore the request. if (attributes.stops().isEmpty()) return; RefPtr<SVGPaintServerRadialGradient> radialGradient = WTF::static_pointer_cast<SVGPaintServerRadialGradient>(m_resource); radialGradient->setGradientStops(attributes.stops()); radialGradient->setBoundingBoxMode(attributes.boundingBoxMode()); radialGradient->setGradientSpreadMethod(attributes.spreadMethod()); radialGradient->setGradientTransform(attributes.gradientTransform()); radialGradient->setGradientCenter(FloatPoint::narrowPrecision(attributes.cx(), attributes.cy())); radialGradient->setGradientFocal(FloatPoint::narrowPrecision(attributes.fx(), attributes.fy())); radialGradient->setGradientRadius(narrowPrecisionToFloat(attributes.r())); }