LinearGradientAttributes SVGLinearGradientElement::collectGradientProperties() { LinearGradientAttributes attributes; HashSet<SVGGradientElement*> processedGradients; bool isLinear = true; SVGGradientElement* current = this; while (current) { if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr)) attributes.setSpreadMethod((GradientSpreadMethod) current->spreadMethod()); if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr)) attributes.setBoundingBoxMode(current->gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix()); if (!attributes.hasStops()) { const Vector<Gradient::ColorStop>& stops(current->buildStops()); if (!stops.isEmpty()) attributes.setStops(stops); } if (isLinear) { SVGLinearGradientElement* linear = static_cast<SVGLinearGradientElement*>(current); if (!attributes.hasX1() && current->hasAttribute(SVGNames::x1Attr)) attributes.setX1(linear->x1()); if (!attributes.hasY1() && current->hasAttribute(SVGNames::y1Attr)) attributes.setY1(linear->y1()); if (!attributes.hasX2() && current->hasAttribute(SVGNames::x2Attr)) attributes.setX2(linear->x2()); if (!attributes.hasY2() && current->hasAttribute(SVGNames::y2Attr)) attributes.setY2(linear->y2()); } processedGradients.add(current); // Respect xlink:href, take attributes from referenced element Node* refNode = ownerDocument()->getElementById(SVGURIReference::getTarget(current->href())); if (refNode && (refNode->hasTagName(SVGNames::linearGradientTag) || refNode->hasTagName(SVGNames::radialGradientTag))) { current = static_cast<SVGGradientElement*>(refNode); // Cycle detection if (processedGradients.contains(current)) return LinearGradientAttributes(); isLinear = current->hasTagName(SVGNames::linearGradientTag); } else current = 0; } return attributes; }
static void setGradientAttributes(SVGGradientElement& element, RadialGradientAttributes& attributes, bool isRadial = true) { if (!attributes.hasSpreadMethod() && element.hasAttribute(SVGNames::spreadMethodAttr)) attributes.setSpreadMethod(element.spreadMethod()); if (!attributes.hasGradientUnits() && element.hasAttribute(SVGNames::gradientUnitsAttr)) attributes.setGradientUnits(element.gradientUnits()); if (!attributes.hasGradientTransform() && element.hasAttribute(SVGNames::gradientTransformAttr)) { AffineTransform transform; element.gradientTransform().concatenate(transform); attributes.setGradientTransform(transform); } if (!attributes.hasStops()) { const Vector<Gradient::ColorStop>& stops(element.buildStops()); if (!stops.isEmpty()) attributes.setStops(stops); } if (isRadial) { SVGRadialGradientElement& radial = downcast<SVGRadialGradientElement>(element); if (!attributes.hasCx() && element.hasAttribute(SVGNames::cxAttr)) attributes.setCx(radial.cx()); if (!attributes.hasCy() && element.hasAttribute(SVGNames::cyAttr)) attributes.setCy(radial.cy()); if (!attributes.hasR() && element.hasAttribute(SVGNames::rAttr)) attributes.setR(radial.r()); if (!attributes.hasFx() && element.hasAttribute(SVGNames::fxAttr)) attributes.setFx(radial.fx()); if (!attributes.hasFy() && element.hasAttribute(SVGNames::fyAttr)) attributes.setFy(radial.fy()); if (!attributes.hasFr() && element.hasAttribute(SVGNames::frAttr)) attributes.setFr(radial.fr()); } }
static void setGradientAttributes(SVGGradientElement& element, LinearGradientAttributes& attributes, bool isLinear = true) { if (!attributes.hasSpreadMethod() && element.hasAttribute(SVGNames::spreadMethodAttr)) attributes.setSpreadMethod(element.spreadMethod()); if (!attributes.hasGradientUnits() && element.hasAttribute(SVGNames::gradientUnitsAttr)) attributes.setGradientUnits(element.gradientUnits()); if (!attributes.hasGradientTransform() && element.hasAttribute(SVGNames::gradientTransformAttr)) { AffineTransform transform; element.gradientTransform().concatenate(transform); attributes.setGradientTransform(transform); } if (!attributes.hasStops()) { const Vector<Gradient::ColorStop>& stops(element.buildStops()); if (!stops.isEmpty()) attributes.setStops(stops); } if (isLinear) { SVGLinearGradientElement& linear = downcast<SVGLinearGradientElement>(element); if (!attributes.hasX1() && element.hasAttribute(SVGNames::x1Attr)) attributes.setX1(linear.x1()); if (!attributes.hasY1() && element.hasAttribute(SVGNames::y1Attr)) attributes.setY1(linear.y1()); if (!attributes.hasX2() && element.hasAttribute(SVGNames::x2Attr)) attributes.setX2(linear.x2()); if (!attributes.hasY2() && element.hasAttribute(SVGNames::y2Attr)) attributes.setY2(linear.y2()); } }