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 SVGLinearGradientElement::buildGradient() const { LinearGradientAttributes attributes = collectGradientProperties(); // If we didn't find any gradient containing stop elements, ignore the request. if (attributes.stops().isEmpty()) return; RefPtr<SVGPaintServerLinearGradient> linearGradient = WTF::static_pointer_cast<SVGPaintServerLinearGradient>(m_resource); linearGradient->setGradientStops(attributes.stops()); linearGradient->setBoundingBoxMode(attributes.boundingBoxMode()); linearGradient->setGradientSpreadMethod(attributes.spreadMethod()); linearGradient->setGradientTransform(attributes.gradientTransform()); linearGradient->setGradientStart(FloatPoint::narrowPrecision(attributes.x1(), attributes.y1())); linearGradient->setGradientEnd(FloatPoint::narrowPrecision(attributes.x2(), attributes.y2())); }
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())); }
void SVGLinearGradientElement::buildGradient() const { LinearGradientAttributes attributes = collectGradientProperties(); RefPtr<SVGPaintServerLinearGradient> linearGradient = WTF::static_pointer_cast<SVGPaintServerLinearGradient>(m_resource); FloatPoint startPoint; FloatPoint endPoint; if (attributes.boundingBoxMode()) { startPoint = FloatPoint(attributes.x1().valueAsPercentage(), attributes.y1().valueAsPercentage()); endPoint = FloatPoint(attributes.x2().valueAsPercentage(), attributes.y2().valueAsPercentage()); } else { startPoint = FloatPoint(attributes.x1().value(this), attributes.y1().value(this)); endPoint = FloatPoint(attributes.x2().value(this), attributes.y2().value(this)); } RefPtr<Gradient> gradient = Gradient::create(startPoint, endPoint); gradient->setSpreadMethod(attributes.spreadMethod()); Vector<SVGGradientStop> m_stops = attributes.stops(); float previousOffset = 0.0f; for (unsigned i = 0; i < m_stops.size(); ++i) { float offset = std::min(std::max(previousOffset, m_stops[i].first), 1.0f); previousOffset = offset; gradient->addColorStop(offset, m_stops[i].second); } linearGradient->setGradient(gradient); if (attributes.stops().isEmpty()) return; // This code should go away. PaintServers should go away too. // Only this code should care about bounding boxes linearGradient->setBoundingBoxMode(attributes.boundingBoxMode()); linearGradient->setGradientStops(attributes.stops()); // These should possibly be supported on Gradient linearGradient->setGradientTransform(attributes.gradientTransform()); linearGradient->setGradientStart(startPoint); linearGradient->setGradientEnd(endPoint); }