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); }
void SVGLinearGradientElement::calculateStartEndPoints(const LinearGradientAttributes& attributes, FloatPoint& startPoint, FloatPoint& endPoint) { // Determine gradient start/end points 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)); } }
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 writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent) { writeStandardPrefix(ts, object, indent); Element* element = static_cast<Element*>(object.node()); const AtomicString& id = element->getIdAttribute(); writeNameAndQuotedValue(ts, "id", id); RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer(); ASSERT(resource); if (resource->resourceType() == MaskerResourceType) { RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource); writeNameValuePair(ts, "maskUnits", masker->maskUnits()); writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits()); ts << "\n"; #if ENABLE(FILTERS) } else if (resource->resourceType() == FilterResourceType) { RenderSVGResourceFilter* filter = static_cast<RenderSVGResourceFilter*>(resource); writeNameValuePair(ts, "filterUnits", filter->filterUnits()); writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits()); ts << "\n"; if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives()) { if (FilterEffect* lastEffect = builder->lastEffect()) lastEffect->externalRepresentation(ts, indent + 1); } #endif } else if (resource->resourceType() == ClipperResourceType) { RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource); writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits()); ts << "\n"; } else if (resource->resourceType() == MarkerResourceType) { RenderSVGResourceMarker* marker = static_cast<RenderSVGResourceMarker*>(resource); writeNameValuePair(ts, "markerUnits", marker->markerUnits()); ts << " [ref at " << marker->referencePoint() << "]"; ts << " [angle="; if (marker->angle() == -1) ts << "auto" << "]\n"; else ts << marker->angle() << "]\n"; } else if (resource->resourceType() == PatternResourceType) { RenderSVGResourcePattern* pattern = static_cast<RenderSVGResourcePattern*>(resource); // Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may // link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties() PatternAttributes attributes = static_cast<SVGPatternElement*>(pattern->node())->collectPatternProperties(); writeNameValuePair(ts, "patternUnits", boundingBoxModeString(attributes.boundingBoxMode())); writeNameValuePair(ts, "patternContentUnits", boundingBoxModeString(attributes.boundingBoxModeContent())); AffineTransform transform = attributes.patternTransform(); if (!transform.isIdentity()) ts << " [patternTransform=" << transform << "]"; ts << "\n"; } else if (resource->resourceType() == LinearGradientResourceType) { RenderSVGResourceLinearGradient* gradient = static_cast<RenderSVGResourceLinearGradient*>(resource); // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties() SVGLinearGradientElement* linearGradientElement = static_cast<SVGLinearGradientElement*>(gradient->node()); LinearGradientAttributes attributes = linearGradientElement->collectGradientProperties(); writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode()); FloatPoint startPoint; FloatPoint endPoint; linearGradientElement->calculateStartEndPoints(attributes, startPoint, endPoint); ts << " [start=" << startPoint << "] [end=" << endPoint << "]\n"; } else if (resource->resourceType() == RadialGradientResourceType) { RenderSVGResourceRadialGradient* gradient = static_cast<RenderSVGResourceRadialGradient*>(resource); // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties() SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradient->node()); RadialGradientAttributes attributes = radialGradientElement->collectGradientProperties(); writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode()); FloatPoint focalPoint; FloatPoint centerPoint; float radius; radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius); ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "]\n"; } else ts << "\n"; writeChildren(ts, object, indent); }